i386.md (*movoi_internal_avx): Use standard_sse_constant_opcode for alternative 0.
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;; otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
64
65 ;; UNSPEC usage:
66
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
69 UNSPEC_GOT
70 UNSPEC_GOTOFF
71 UNSPEC_GOTPCREL
72 UNSPEC_GOTTPOFF
73 UNSPEC_TPOFF
74 UNSPEC_NTPOFF
75 UNSPEC_DTPOFF
76 UNSPEC_GOTNTPOFF
77 UNSPEC_INDNTPOFF
78 UNSPEC_PLTOFF
79 UNSPEC_MACHOPIC_OFFSET
80 UNSPEC_PCREL
81
82 ;; Prologue support
83 UNSPEC_STACK_ALLOC
84 UNSPEC_SET_GOT
85 UNSPEC_REG_SAVE
86 UNSPEC_DEF_CFA
87 UNSPEC_SET_RIP
88 UNSPEC_SET_GOT_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
90 UNSPEC_STACK_CHECK
91
92 ;; TLS support
93 UNSPEC_TP
94 UNSPEC_TLS_GD
95 UNSPEC_TLS_LD_BASE
96 UNSPEC_TLSDESC
97 UNSPEC_TLS_IE_SUN
98
99 ;; Other random patterns
100 UNSPEC_SCAS
101 UNSPEC_FNSTSW
102 UNSPEC_SAHF
103 UNSPEC_PARITY
104 UNSPEC_FSTCW
105 UNSPEC_ADD_CARRY
106 UNSPEC_FLDCW
107 UNSPEC_REP
108 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_TRUNC_NOOP
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_CALL_NEEDS_VZEROUPPER
112 UNSPEC_PAUSE
113
114 ;; For SSE/MMX support:
115 UNSPEC_FIX_NOTRUNC
116 UNSPEC_MASKMOV
117 UNSPEC_MOVMSK
118 UNSPEC_MOVNT
119 UNSPEC_MOVU
120 UNSPEC_RCP
121 UNSPEC_RSQRT
122 UNSPEC_SFENCE
123 UNSPEC_PFRCP
124 UNSPEC_PFRCPIT1
125 UNSPEC_PFRCPIT2
126 UNSPEC_PFRSQRT
127 UNSPEC_PFRSQIT1
128 UNSPEC_MFENCE
129 UNSPEC_LFENCE
130 UNSPEC_PSADBW
131 UNSPEC_LDDQU
132 UNSPEC_MS_TO_SYSV_CALL
133
134 ;; Generic math support
135 UNSPEC_COPYSIGN
136 UNSPEC_IEEE_MIN ; not commutative
137 UNSPEC_IEEE_MAX ; not commutative
138
139 ;; x87 Floating point
140 UNSPEC_SIN
141 UNSPEC_COS
142 UNSPEC_FPATAN
143 UNSPEC_FYL2X
144 UNSPEC_FYL2XP1
145 UNSPEC_FRNDINT
146 UNSPEC_FIST
147 UNSPEC_F2XM1
148 UNSPEC_TAN
149 UNSPEC_FXAM
150
151 ;; x87 Rounding
152 UNSPEC_FRNDINT_FLOOR
153 UNSPEC_FRNDINT_CEIL
154 UNSPEC_FRNDINT_TRUNC
155 UNSPEC_FRNDINT_MASK_PM
156 UNSPEC_FIST_FLOOR
157 UNSPEC_FIST_CEIL
158
159 ;; x87 Double output FP
160 UNSPEC_SINCOS_COS
161 UNSPEC_SINCOS_SIN
162 UNSPEC_XTRACT_FRACT
163 UNSPEC_XTRACT_EXP
164 UNSPEC_FSCALE_FRACT
165 UNSPEC_FSCALE_EXP
166 UNSPEC_FPREM_F
167 UNSPEC_FPREM_U
168 UNSPEC_FPREM1_F
169 UNSPEC_FPREM1_U
170
171 UNSPEC_C2_FLAG
172 UNSPEC_FXAM_MEM
173
174 ;; SSP patterns
175 UNSPEC_SP_SET
176 UNSPEC_SP_TEST
177 UNSPEC_SP_TLS_SET
178 UNSPEC_SP_TLS_TEST
179
180 ;; SSSE3
181 UNSPEC_PSHUFB
182 UNSPEC_PSIGN
183 UNSPEC_PALIGNR
184
185 ;; For SSE4A support
186 UNSPEC_EXTRQI
187 UNSPEC_EXTRQ
188 UNSPEC_INSERTQI
189 UNSPEC_INSERTQ
190
191 ;; For SSE4.1 support
192 UNSPEC_BLENDV
193 UNSPEC_INSERTPS
194 UNSPEC_DP
195 UNSPEC_MOVNTDQA
196 UNSPEC_MPSADBW
197 UNSPEC_PHMINPOSUW
198 UNSPEC_PTEST
199 UNSPEC_ROUND
200
201 ;; For SSE4.2 support
202 UNSPEC_CRC32
203 UNSPEC_PCMPESTR
204 UNSPEC_PCMPISTR
205
206 ;; For FMA4 support
207 UNSPEC_FMADDSUB
208 UNSPEC_XOP_UNSIGNED_CMP
209 UNSPEC_XOP_TRUEFALSE
210 UNSPEC_XOP_PERMUTE
211 UNSPEC_FRCZ
212
213 ;; For AES support
214 UNSPEC_AESENC
215 UNSPEC_AESENCLAST
216 UNSPEC_AESDEC
217 UNSPEC_AESDECLAST
218 UNSPEC_AESIMC
219 UNSPEC_AESKEYGENASSIST
220
221 ;; For PCLMUL support
222 UNSPEC_PCLMUL
223
224 ;; For AVX support
225 UNSPEC_PCMP
226 UNSPEC_VPERMIL
227 UNSPEC_VPERMIL2
228 UNSPEC_VPERMIL2F128
229 UNSPEC_CAST
230 UNSPEC_VTESTP
231 UNSPEC_VCVTPH2PS
232 UNSPEC_VCVTPS2PH
233
234 ;; For BMI support
235 UNSPEC_BEXTR
236
237 ;; For RDRAND support
238 UNSPEC_RDRAND
239 ])
240
241 (define_c_enum "unspecv" [
242 UNSPECV_BLOCKAGE
243 UNSPECV_STACK_PROBE
244 UNSPECV_PROBE_STACK_RANGE
245 UNSPECV_EMMS
246 UNSPECV_LDMXCSR
247 UNSPECV_STMXCSR
248 UNSPECV_FEMMS
249 UNSPECV_CLFLUSH
250 UNSPECV_ALIGN
251 UNSPECV_MONITOR
252 UNSPECV_MWAIT
253 UNSPECV_CMPXCHG
254 UNSPECV_XCHG
255 UNSPECV_LOCK
256 UNSPECV_PROLOGUE_USE
257 UNSPECV_CLD
258 UNSPECV_NOPS
259 UNSPECV_VZEROALL
260 UNSPECV_VZEROUPPER
261 UNSPECV_RDTSC
262 UNSPECV_RDTSCP
263 UNSPECV_RDPMC
264 UNSPECV_LLWP_INTRINSIC
265 UNSPECV_SLWP_INTRINSIC
266 UNSPECV_LWPVAL_INTRINSIC
267 UNSPECV_LWPINS_INTRINSIC
268 UNSPECV_RDFSBASE
269 UNSPECV_RDGSBASE
270 UNSPECV_WRFSBASE
271 UNSPECV_WRGSBASE
272 UNSPECV_SPLIT_STACK_RETURN
273 ])
274
275 ;; Constants to represent rounding modes in the ROUND instruction
276 (define_constants
277 [(ROUND_FLOOR 0x1)
278 (ROUND_CEIL 0x2)
279 (ROUND_TRUNC 0x3)
280 (ROUND_MXCSR 0x4)
281 (ROUND_NO_EXC 0x8)
282 ])
283
284 ;; Constants to represent pcomtrue/pcomfalse variants
285 (define_constants
286 [(PCOM_FALSE 0)
287 (PCOM_TRUE 1)
288 (COM_FALSE_S 2)
289 (COM_FALSE_P 3)
290 (COM_TRUE_S 4)
291 (COM_TRUE_P 5)
292 ])
293
294 ;; Constants used in the XOP pperm instruction
295 (define_constants
296 [(PPERM_SRC 0x00) /* copy source */
297 (PPERM_INVERT 0x20) /* invert source */
298 (PPERM_REVERSE 0x40) /* bit reverse source */
299 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
300 (PPERM_ZERO 0x80) /* all 0's */
301 (PPERM_ONES 0xa0) /* all 1's */
302 (PPERM_SIGN 0xc0) /* propagate sign bit */
303 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
304 (PPERM_SRC1 0x00) /* use first source byte */
305 (PPERM_SRC2 0x10) /* use second source byte */
306 ])
307
308 ;; Registers by name.
309 (define_constants
310 [(AX_REG 0)
311 (DX_REG 1)
312 (CX_REG 2)
313 (BX_REG 3)
314 (SI_REG 4)
315 (DI_REG 5)
316 (BP_REG 6)
317 (SP_REG 7)
318 (ST0_REG 8)
319 (ST1_REG 9)
320 (ST2_REG 10)
321 (ST3_REG 11)
322 (ST4_REG 12)
323 (ST5_REG 13)
324 (ST6_REG 14)
325 (ST7_REG 15)
326 (FLAGS_REG 17)
327 (FPSR_REG 18)
328 (FPCR_REG 19)
329 (XMM0_REG 21)
330 (XMM1_REG 22)
331 (XMM2_REG 23)
332 (XMM3_REG 24)
333 (XMM4_REG 25)
334 (XMM5_REG 26)
335 (XMM6_REG 27)
336 (XMM7_REG 28)
337 (MM0_REG 29)
338 (MM1_REG 30)
339 (MM2_REG 31)
340 (MM3_REG 32)
341 (MM4_REG 33)
342 (MM5_REG 34)
343 (MM6_REG 35)
344 (MM7_REG 36)
345 (R8_REG 37)
346 (R9_REG 38)
347 (R10_REG 39)
348 (R11_REG 40)
349 (R12_REG 41)
350 (R13_REG 42)
351 (XMM8_REG 45)
352 (XMM9_REG 46)
353 (XMM10_REG 47)
354 (XMM11_REG 48)
355 (XMM12_REG 49)
356 (XMM13_REG 50)
357 (XMM14_REG 51)
358 (XMM15_REG 52)
359 ])
360
361 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
362 ;; from i386.c.
363
364 ;; In C guard expressions, put expressions which may be compile-time
365 ;; constants first. This allows for better optimization. For
366 ;; example, write "TARGET_64BIT && reload_completed", not
367 ;; "reload_completed && TARGET_64BIT".
368
369 \f
370 ;; Processor type.
371 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
372 atom,generic64,amdfam10,bdver1,btver1"
373 (const (symbol_ref "ix86_schedule")))
374
375 ;; A basic instruction type. Refinements due to arguments to be
376 ;; provided in other attributes.
377 (define_attr "type"
378 "other,multi,
379 alu,alu1,negnot,imov,imovx,lea,
380 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
381 icmp,test,ibr,setcc,icmov,
382 push,pop,call,callv,leave,
383 str,bitmanip,
384 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
385 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
386 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
387 ssemuladd,sse4arg,lwp,
388 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
389 (const_string "other"))
390
391 ;; Main data type used by the insn
392 (define_attr "mode"
393 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
394 (const_string "unknown"))
395
396 ;; The CPU unit operations uses.
397 (define_attr "unit" "integer,i387,sse,mmx,unknown"
398 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
399 (const_string "i387")
400 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
401 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
402 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
403 (const_string "sse")
404 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
405 (const_string "mmx")
406 (eq_attr "type" "other")
407 (const_string "unknown")]
408 (const_string "integer")))
409
410 ;; The (bounding maximum) length of an instruction immediate.
411 (define_attr "length_immediate" ""
412 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
413 bitmanip")
414 (const_int 0)
415 (eq_attr "unit" "i387,sse,mmx")
416 (const_int 0)
417 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
418 imul,icmp,push,pop")
419 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
420 (eq_attr "type" "imov,test")
421 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
422 (eq_attr "type" "call")
423 (if_then_else (match_operand 0 "constant_call_address_operand" "")
424 (const_int 4)
425 (const_int 0))
426 (eq_attr "type" "callv")
427 (if_then_else (match_operand 1 "constant_call_address_operand" "")
428 (const_int 4)
429 (const_int 0))
430 ;; We don't know the size before shorten_branches. Expect
431 ;; the instruction to fit for better scheduling.
432 (eq_attr "type" "ibr")
433 (const_int 1)
434 ]
435 (symbol_ref "/* Update immediate_length and other attributes! */
436 gcc_unreachable (),1")))
437
438 ;; The (bounding maximum) length of an instruction address.
439 (define_attr "length_address" ""
440 (cond [(eq_attr "type" "str,other,multi,fxch")
441 (const_int 0)
442 (and (eq_attr "type" "call")
443 (match_operand 0 "constant_call_address_operand" ""))
444 (const_int 0)
445 (and (eq_attr "type" "callv")
446 (match_operand 1 "constant_call_address_operand" ""))
447 (const_int 0)
448 ]
449 (symbol_ref "ix86_attr_length_address_default (insn)")))
450
451 ;; Set when length prefix is used.
452 (define_attr "prefix_data16" ""
453 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
454 (const_int 0)
455 (eq_attr "mode" "HI")
456 (const_int 1)
457 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
458 (const_int 1)
459 ]
460 (const_int 0)))
461
462 ;; Set when string REP prefix is used.
463 (define_attr "prefix_rep" ""
464 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
465 (const_int 0)
466 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
467 (const_int 1)
468 ]
469 (const_int 0)))
470
471 ;; Set when 0f opcode prefix is used.
472 (define_attr "prefix_0f" ""
473 (if_then_else
474 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
475 (eq_attr "unit" "sse,mmx"))
476 (const_int 1)
477 (const_int 0)))
478
479 ;; Set when REX opcode prefix is used.
480 (define_attr "prefix_rex" ""
481 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
482 (const_int 0)
483 (and (eq_attr "mode" "DI")
484 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
485 (eq_attr "unit" "!mmx")))
486 (const_int 1)
487 (and (eq_attr "mode" "QI")
488 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
489 (const_int 0)))
490 (const_int 1)
491 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
492 (const_int 0))
493 (const_int 1)
494 (and (eq_attr "type" "imovx")
495 (match_operand:QI 1 "ext_QIreg_operand" ""))
496 (const_int 1)
497 ]
498 (const_int 0)))
499
500 ;; There are also additional prefixes in 3DNOW, SSSE3.
501 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
502 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
503 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
504 (define_attr "prefix_extra" ""
505 (cond [(eq_attr "type" "ssemuladd,sse4arg")
506 (const_int 2)
507 (eq_attr "type" "sseiadd1,ssecvt1")
508 (const_int 1)
509 ]
510 (const_int 0)))
511
512 ;; Prefix used: original, VEX or maybe VEX.
513 (define_attr "prefix" "orig,vex,maybe_vex"
514 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
515 (const_string "vex")
516 (const_string "orig")))
517
518 ;; VEX W bit is used.
519 (define_attr "prefix_vex_w" "" (const_int 0))
520
521 ;; The length of VEX prefix
522 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
523 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
524 ;; still prefix_0f 1, with prefix_extra 1.
525 (define_attr "length_vex" ""
526 (if_then_else (and (eq_attr "prefix_0f" "1")
527 (eq_attr "prefix_extra" "0"))
528 (if_then_else (eq_attr "prefix_vex_w" "1")
529 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
530 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
531 (if_then_else (eq_attr "prefix_vex_w" "1")
532 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
533 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
534
535 ;; Set when modrm byte is used.
536 (define_attr "modrm" ""
537 (cond [(eq_attr "type" "str,leave")
538 (const_int 0)
539 (eq_attr "unit" "i387")
540 (const_int 0)
541 (and (eq_attr "type" "incdec")
542 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
543 (ior (match_operand:SI 1 "register_operand" "")
544 (match_operand:HI 1 "register_operand" ""))))
545 (const_int 0)
546 (and (eq_attr "type" "push")
547 (not (match_operand 1 "memory_operand" "")))
548 (const_int 0)
549 (and (eq_attr "type" "pop")
550 (not (match_operand 0 "memory_operand" "")))
551 (const_int 0)
552 (and (eq_attr "type" "imov")
553 (and (not (eq_attr "mode" "DI"))
554 (ior (and (match_operand 0 "register_operand" "")
555 (match_operand 1 "immediate_operand" ""))
556 (ior (and (match_operand 0 "ax_reg_operand" "")
557 (match_operand 1 "memory_displacement_only_operand" ""))
558 (and (match_operand 0 "memory_displacement_only_operand" "")
559 (match_operand 1 "ax_reg_operand" ""))))))
560 (const_int 0)
561 (and (eq_attr "type" "call")
562 (match_operand 0 "constant_call_address_operand" ""))
563 (const_int 0)
564 (and (eq_attr "type" "callv")
565 (match_operand 1 "constant_call_address_operand" ""))
566 (const_int 0)
567 (and (eq_attr "type" "alu,alu1,icmp,test")
568 (match_operand 0 "ax_reg_operand" ""))
569 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
570 ]
571 (const_int 1)))
572
573 ;; The (bounding maximum) length of an instruction in bytes.
574 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
575 ;; Later we may want to split them and compute proper length as for
576 ;; other insns.
577 (define_attr "length" ""
578 (cond [(eq_attr "type" "other,multi,fistp,frndint")
579 (const_int 16)
580 (eq_attr "type" "fcmp")
581 (const_int 4)
582 (eq_attr "unit" "i387")
583 (plus (const_int 2)
584 (plus (attr "prefix_data16")
585 (attr "length_address")))
586 (ior (eq_attr "prefix" "vex")
587 (and (eq_attr "prefix" "maybe_vex")
588 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
589 (plus (attr "length_vex")
590 (plus (attr "length_immediate")
591 (plus (attr "modrm")
592 (attr "length_address"))))]
593 (plus (plus (attr "modrm")
594 (plus (attr "prefix_0f")
595 (plus (attr "prefix_rex")
596 (plus (attr "prefix_extra")
597 (const_int 1)))))
598 (plus (attr "prefix_rep")
599 (plus (attr "prefix_data16")
600 (plus (attr "length_immediate")
601 (attr "length_address")))))))
602
603 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
604 ;; `store' if there is a simple memory reference therein, or `unknown'
605 ;; if the instruction is complex.
606
607 (define_attr "memory" "none,load,store,both,unknown"
608 (cond [(eq_attr "type" "other,multi,str,lwp")
609 (const_string "unknown")
610 (eq_attr "type" "lea,fcmov,fpspc")
611 (const_string "none")
612 (eq_attr "type" "fistp,leave")
613 (const_string "both")
614 (eq_attr "type" "frndint")
615 (const_string "load")
616 (eq_attr "type" "push")
617 (if_then_else (match_operand 1 "memory_operand" "")
618 (const_string "both")
619 (const_string "store"))
620 (eq_attr "type" "pop")
621 (if_then_else (match_operand 0 "memory_operand" "")
622 (const_string "both")
623 (const_string "load"))
624 (eq_attr "type" "setcc")
625 (if_then_else (match_operand 0 "memory_operand" "")
626 (const_string "store")
627 (const_string "none"))
628 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
629 (if_then_else (ior (match_operand 0 "memory_operand" "")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "load")
632 (const_string "none"))
633 (eq_attr "type" "ibr")
634 (if_then_else (match_operand 0 "memory_operand" "")
635 (const_string "load")
636 (const_string "none"))
637 (eq_attr "type" "call")
638 (if_then_else (match_operand 0 "constant_call_address_operand" "")
639 (const_string "none")
640 (const_string "load"))
641 (eq_attr "type" "callv")
642 (if_then_else (match_operand 1 "constant_call_address_operand" "")
643 (const_string "none")
644 (const_string "load"))
645 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
646 (match_operand 1 "memory_operand" ""))
647 (const_string "both")
648 (and (match_operand 0 "memory_operand" "")
649 (match_operand 1 "memory_operand" ""))
650 (const_string "both")
651 (match_operand 0 "memory_operand" "")
652 (const_string "store")
653 (match_operand 1 "memory_operand" "")
654 (const_string "load")
655 (and (eq_attr "type"
656 "!alu1,negnot,ishift1,
657 imov,imovx,icmp,test,bitmanip,
658 fmov,fcmp,fsgn,
659 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
660 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
661 (match_operand 2 "memory_operand" ""))
662 (const_string "load")
663 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
664 (match_operand 3 "memory_operand" ""))
665 (const_string "load")
666 ]
667 (const_string "none")))
668
669 ;; Indicates if an instruction has both an immediate and a displacement.
670
671 (define_attr "imm_disp" "false,true,unknown"
672 (cond [(eq_attr "type" "other,multi")
673 (const_string "unknown")
674 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
675 (and (match_operand 0 "memory_displacement_operand" "")
676 (match_operand 1 "immediate_operand" "")))
677 (const_string "true")
678 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
679 (and (match_operand 0 "memory_displacement_operand" "")
680 (match_operand 2 "immediate_operand" "")))
681 (const_string "true")
682 ]
683 (const_string "false")))
684
685 ;; Indicates if an FP operation has an integer source.
686
687 (define_attr "fp_int_src" "false,true"
688 (const_string "false"))
689
690 ;; Defines rounding mode of an FP operation.
691
692 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
693 (const_string "any"))
694
695 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
696 (define_attr "use_carry" "0,1" (const_string "0"))
697
698 ;; Define attribute to indicate unaligned ssemov insns
699 (define_attr "movu" "0,1" (const_string "0"))
700
701 ;; Used to control the "enabled" attribute on a per-instruction basis.
702 (define_attr "isa" "base,noavx,avx"
703 (const_string "base"))
704
705 (define_attr "enabled" ""
706 (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
707 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
708 ]
709 (const_int 1)))
710
711 ;; Describe a user's asm statement.
712 (define_asm_attributes
713 [(set_attr "length" "128")
714 (set_attr "type" "multi")])
715
716 (define_code_iterator plusminus [plus minus])
717
718 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
719
720 ;; Base name for define_insn
721 (define_code_attr plusminus_insn
722 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
723 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
724
725 ;; Base name for insn mnemonic.
726 (define_code_attr plusminus_mnemonic
727 [(plus "add") (ss_plus "adds") (us_plus "addus")
728 (minus "sub") (ss_minus "subs") (us_minus "subus")])
729 (define_code_attr plusminus_carry_mnemonic
730 [(plus "adc") (minus "sbb")])
731
732 ;; Mark commutative operators as such in constraints.
733 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
734 (minus "") (ss_minus "") (us_minus "")])
735
736 ;; Mapping of signed max and min
737 (define_code_iterator smaxmin [smax smin])
738
739 ;; Mapping of unsigned max and min
740 (define_code_iterator umaxmin [umax umin])
741
742 ;; Base name for integer and FP insn mnemonic
743 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
744 (umax "maxu") (umin "minu")])
745 (define_code_attr maxmin_float [(smax "max") (smin "min")])
746
747 ;; Mapping of logic operators
748 (define_code_iterator any_logic [and ior xor])
749 (define_code_iterator any_or [ior xor])
750
751 ;; Base name for insn mnemonic.
752 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
753
754 ;; Mapping of shift-right operators
755 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
756
757 ;; Base name for define_insn
758 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
759
760 ;; Base name for insn mnemonic.
761 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
762
763 ;; Mapping of rotate operators
764 (define_code_iterator any_rotate [rotate rotatert])
765
766 ;; Base name for define_insn
767 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
768
769 ;; Base name for insn mnemonic.
770 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
771
772 ;; Mapping of abs neg operators
773 (define_code_iterator absneg [abs neg])
774
775 ;; Base name for x87 insn mnemonic.
776 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
777
778 ;; Used in signed and unsigned widening multiplications.
779 (define_code_iterator any_extend [sign_extend zero_extend])
780
781 ;; Various insn prefixes for signed and unsigned operations.
782 (define_code_attr u [(sign_extend "") (zero_extend "u")
783 (div "") (udiv "u")])
784 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
785
786 ;; Used in signed and unsigned divisions.
787 (define_code_iterator any_div [div udiv])
788
789 ;; Instruction prefix for signed and unsigned operations.
790 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
791 (div "i") (udiv "")])
792
793 ;; 64bit single word integer modes.
794 (define_mode_iterator SWI1248x [QI HI SI DI])
795
796 ;; 64bit single word integer modes without QImode and HImode.
797 (define_mode_iterator SWI48x [SI DI])
798
799 ;; Single word integer modes.
800 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
801
802 ;; Single word integer modes without SImode and DImode.
803 (define_mode_iterator SWI12 [QI HI])
804
805 ;; Single word integer modes without DImode.
806 (define_mode_iterator SWI124 [QI HI SI])
807
808 ;; Single word integer modes without QImode and DImode.
809 (define_mode_iterator SWI24 [HI SI])
810
811 ;; Single word integer modes without QImode.
812 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
813
814 ;; Single word integer modes without QImode and HImode.
815 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
816
817 ;; All math-dependant single and double word integer modes.
818 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
819 (HI "TARGET_HIMODE_MATH")
820 SI DI (TI "TARGET_64BIT")])
821
822 ;; Math-dependant single word integer modes.
823 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
824 (HI "TARGET_HIMODE_MATH")
825 SI (DI "TARGET_64BIT")])
826
827 ;; Math-dependant single word integer modes without DImode.
828 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
829 (HI "TARGET_HIMODE_MATH")
830 SI])
831
832 ;; Math-dependant single word integer modes without QImode.
833 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
834 SI (DI "TARGET_64BIT")])
835
836 ;; Double word integer modes.
837 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
838 (TI "TARGET_64BIT")])
839
840 ;; Double word integer modes as mode attribute.
841 (define_mode_attr DWI [(SI "DI") (DI "TI")])
842 (define_mode_attr dwi [(SI "di") (DI "ti")])
843
844 ;; Half mode for double word integer modes.
845 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
846 (DI "TARGET_64BIT")])
847
848 ;; Instruction suffix for integer modes.
849 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
850
851 ;; Pointer size prefix for integer modes (Intel asm dialect)
852 (define_mode_attr iptrsize [(QI "BYTE")
853 (HI "WORD")
854 (SI "DWORD")
855 (DI "QWORD")])
856
857 ;; Register class for integer modes.
858 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
859
860 ;; Immediate operand constraint for integer modes.
861 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
862
863 ;; General operand constraint for word modes.
864 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
865
866 ;; Immediate operand constraint for double integer modes.
867 (define_mode_attr di [(SI "iF") (DI "e")])
868
869 ;; Immediate operand constraint for shifts.
870 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
871
872 ;; General operand predicate for integer modes.
873 (define_mode_attr general_operand
874 [(QI "general_operand")
875 (HI "general_operand")
876 (SI "general_operand")
877 (DI "x86_64_general_operand")
878 (TI "x86_64_general_operand")])
879
880 ;; General sign/zero extend operand predicate for integer modes.
881 (define_mode_attr general_szext_operand
882 [(QI "general_operand")
883 (HI "general_operand")
884 (SI "general_operand")
885 (DI "x86_64_szext_general_operand")])
886
887 ;; Immediate operand predicate for integer modes.
888 (define_mode_attr immediate_operand
889 [(QI "immediate_operand")
890 (HI "immediate_operand")
891 (SI "immediate_operand")
892 (DI "x86_64_immediate_operand")])
893
894 ;; Nonmemory operand predicate for integer modes.
895 (define_mode_attr nonmemory_operand
896 [(QI "nonmemory_operand")
897 (HI "nonmemory_operand")
898 (SI "nonmemory_operand")
899 (DI "x86_64_nonmemory_operand")])
900
901 ;; Operand predicate for shifts.
902 (define_mode_attr shift_operand
903 [(QI "nonimmediate_operand")
904 (HI "nonimmediate_operand")
905 (SI "nonimmediate_operand")
906 (DI "shiftdi_operand")
907 (TI "register_operand")])
908
909 ;; Operand predicate for shift argument.
910 (define_mode_attr shift_immediate_operand
911 [(QI "const_1_to_31_operand")
912 (HI "const_1_to_31_operand")
913 (SI "const_1_to_31_operand")
914 (DI "const_1_to_63_operand")])
915
916 ;; Input operand predicate for arithmetic left shifts.
917 (define_mode_attr ashl_input_operand
918 [(QI "nonimmediate_operand")
919 (HI "nonimmediate_operand")
920 (SI "nonimmediate_operand")
921 (DI "ashldi_input_operand")
922 (TI "reg_or_pm1_operand")])
923
924 ;; SSE and x87 SFmode and DFmode floating point modes
925 (define_mode_iterator MODEF [SF DF])
926
927 ;; All x87 floating point modes
928 (define_mode_iterator X87MODEF [SF DF XF])
929
930 ;; All integer modes handled by x87 fisttp operator.
931 (define_mode_iterator X87MODEI [HI SI DI])
932
933 ;; All integer modes handled by integer x87 operators.
934 (define_mode_iterator X87MODEI12 [HI SI])
935
936 ;; All integer modes handled by SSE cvtts?2si* operators.
937 (define_mode_iterator SSEMODEI24 [SI DI])
938
939 ;; SSE instruction suffix for various modes
940 (define_mode_attr ssemodesuffix
941 [(SF "ss") (DF "sd")
942 (V8SF "ps") (V4DF "pd")
943 (V4SF "ps") (V2DF "pd")
944 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
945 (V8SI "si")])
946
947 ;; SSE vector suffix for floating point modes
948 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
949
950 ;; SSE vector mode corresponding to a scalar mode
951 (define_mode_attr ssevecmode
952 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
953
954 ;; Instruction suffix for REX 64bit operators.
955 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
956
957 ;; This mode iterator allows :P to be used for patterns that operate on
958 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
959 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
960 \f
961 ;; Scheduling descriptions
962
963 (include "pentium.md")
964 (include "ppro.md")
965 (include "k6.md")
966 (include "athlon.md")
967 (include "bdver1.md")
968 (include "geode.md")
969 (include "atom.md")
970 (include "core2.md")
971
972 \f
973 ;; Operand and operator predicates and constraints
974
975 (include "predicates.md")
976 (include "constraints.md")
977
978 \f
979 ;; Compare and branch/compare and store instructions.
980
981 (define_expand "cbranch<mode>4"
982 [(set (reg:CC FLAGS_REG)
983 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
984 (match_operand:SDWIM 2 "<general_operand>" "")))
985 (set (pc) (if_then_else
986 (match_operator 0 "ordered_comparison_operator"
987 [(reg:CC FLAGS_REG) (const_int 0)])
988 (label_ref (match_operand 3 "" ""))
989 (pc)))]
990 ""
991 {
992 if (MEM_P (operands[1]) && MEM_P (operands[2]))
993 operands[1] = force_reg (<MODE>mode, operands[1]);
994 ix86_expand_branch (GET_CODE (operands[0]),
995 operands[1], operands[2], operands[3]);
996 DONE;
997 })
998
999 (define_expand "cstore<mode>4"
1000 [(set (reg:CC FLAGS_REG)
1001 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1002 (match_operand:SWIM 3 "<general_operand>" "")))
1003 (set (match_operand:QI 0 "register_operand" "")
1004 (match_operator 1 "ordered_comparison_operator"
1005 [(reg:CC FLAGS_REG) (const_int 0)]))]
1006 ""
1007 {
1008 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1009 operands[2] = force_reg (<MODE>mode, operands[2]);
1010 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1011 operands[2], operands[3]);
1012 DONE;
1013 })
1014
1015 (define_expand "cmp<mode>_1"
1016 [(set (reg:CC FLAGS_REG)
1017 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1018 (match_operand:SWI48 1 "<general_operand>" "")))])
1019
1020 (define_insn "*cmp<mode>_ccno_1"
1021 [(set (reg FLAGS_REG)
1022 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1023 (match_operand:SWI 1 "const0_operand" "")))]
1024 "ix86_match_ccmode (insn, CCNOmode)"
1025 "@
1026 test{<imodesuffix>}\t%0, %0
1027 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1028 [(set_attr "type" "test,icmp")
1029 (set_attr "length_immediate" "0,1")
1030 (set_attr "mode" "<MODE>")])
1031
1032 (define_insn "*cmp<mode>_1"
1033 [(set (reg FLAGS_REG)
1034 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1035 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1036 "ix86_match_ccmode (insn, CCmode)"
1037 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1038 [(set_attr "type" "icmp")
1039 (set_attr "mode" "<MODE>")])
1040
1041 (define_insn "*cmp<mode>_minus_1"
1042 [(set (reg FLAGS_REG)
1043 (compare
1044 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1045 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1046 (const_int 0)))]
1047 "ix86_match_ccmode (insn, CCGOCmode)"
1048 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1049 [(set_attr "type" "icmp")
1050 (set_attr "mode" "<MODE>")])
1051
1052 (define_insn "*cmpqi_ext_1"
1053 [(set (reg FLAGS_REG)
1054 (compare
1055 (match_operand:QI 0 "general_operand" "Qm")
1056 (subreg:QI
1057 (zero_extract:SI
1058 (match_operand 1 "ext_register_operand" "Q")
1059 (const_int 8)
1060 (const_int 8)) 0)))]
1061 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1062 "cmp{b}\t{%h1, %0|%0, %h1}"
1063 [(set_attr "type" "icmp")
1064 (set_attr "mode" "QI")])
1065
1066 (define_insn "*cmpqi_ext_1_rex64"
1067 [(set (reg FLAGS_REG)
1068 (compare
1069 (match_operand:QI 0 "register_operand" "Q")
1070 (subreg:QI
1071 (zero_extract:SI
1072 (match_operand 1 "ext_register_operand" "Q")
1073 (const_int 8)
1074 (const_int 8)) 0)))]
1075 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076 "cmp{b}\t{%h1, %0|%0, %h1}"
1077 [(set_attr "type" "icmp")
1078 (set_attr "mode" "QI")])
1079
1080 (define_insn "*cmpqi_ext_2"
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 "const0_operand" "")))]
1089 "ix86_match_ccmode (insn, CCNOmode)"
1090 "test{b}\t%h0, %h0"
1091 [(set_attr "type" "test")
1092 (set_attr "length_immediate" "0")
1093 (set_attr "mode" "QI")])
1094
1095 (define_expand "cmpqi_ext_3"
1096 [(set (reg:CC FLAGS_REG)
1097 (compare:CC
1098 (subreg:QI
1099 (zero_extract:SI
1100 (match_operand 0 "ext_register_operand" "")
1101 (const_int 8)
1102 (const_int 8)) 0)
1103 (match_operand:QI 1 "immediate_operand" "")))])
1104
1105 (define_insn "*cmpqi_ext_3_insn"
1106 [(set (reg FLAGS_REG)
1107 (compare
1108 (subreg:QI
1109 (zero_extract:SI
1110 (match_operand 0 "ext_register_operand" "Q")
1111 (const_int 8)
1112 (const_int 8)) 0)
1113 (match_operand:QI 1 "general_operand" "Qmn")))]
1114 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1115 "cmp{b}\t{%1, %h0|%h0, %1}"
1116 [(set_attr "type" "icmp")
1117 (set_attr "modrm" "1")
1118 (set_attr "mode" "QI")])
1119
1120 (define_insn "*cmpqi_ext_3_insn_rex64"
1121 [(set (reg FLAGS_REG)
1122 (compare
1123 (subreg:QI
1124 (zero_extract:SI
1125 (match_operand 0 "ext_register_operand" "Q")
1126 (const_int 8)
1127 (const_int 8)) 0)
1128 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1129 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1130 "cmp{b}\t{%1, %h0|%h0, %1}"
1131 [(set_attr "type" "icmp")
1132 (set_attr "modrm" "1")
1133 (set_attr "mode" "QI")])
1134
1135 (define_insn "*cmpqi_ext_4"
1136 [(set (reg FLAGS_REG)
1137 (compare
1138 (subreg:QI
1139 (zero_extract:SI
1140 (match_operand 0 "ext_register_operand" "Q")
1141 (const_int 8)
1142 (const_int 8)) 0)
1143 (subreg:QI
1144 (zero_extract:SI
1145 (match_operand 1 "ext_register_operand" "Q")
1146 (const_int 8)
1147 (const_int 8)) 0)))]
1148 "ix86_match_ccmode (insn, CCmode)"
1149 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1150 [(set_attr "type" "icmp")
1151 (set_attr "mode" "QI")])
1152
1153 ;; These implement float point compares.
1154 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1155 ;; which would allow mix and match FP modes on the compares. Which is what
1156 ;; the old patterns did, but with many more of them.
1157
1158 (define_expand "cbranchxf4"
1159 [(set (reg:CC FLAGS_REG)
1160 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1161 (match_operand:XF 2 "nonmemory_operand" "")))
1162 (set (pc) (if_then_else
1163 (match_operator 0 "ix86_fp_comparison_operator"
1164 [(reg:CC FLAGS_REG)
1165 (const_int 0)])
1166 (label_ref (match_operand 3 "" ""))
1167 (pc)))]
1168 "TARGET_80387"
1169 {
1170 ix86_expand_branch (GET_CODE (operands[0]),
1171 operands[1], operands[2], operands[3]);
1172 DONE;
1173 })
1174
1175 (define_expand "cstorexf4"
1176 [(set (reg:CC FLAGS_REG)
1177 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1178 (match_operand:XF 3 "nonmemory_operand" "")))
1179 (set (match_operand:QI 0 "register_operand" "")
1180 (match_operator 1 "ix86_fp_comparison_operator"
1181 [(reg:CC FLAGS_REG)
1182 (const_int 0)]))]
1183 "TARGET_80387"
1184 {
1185 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1186 operands[2], operands[3]);
1187 DONE;
1188 })
1189
1190 (define_expand "cbranch<mode>4"
1191 [(set (reg:CC FLAGS_REG)
1192 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1193 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1194 (set (pc) (if_then_else
1195 (match_operator 0 "ix86_fp_comparison_operator"
1196 [(reg:CC FLAGS_REG)
1197 (const_int 0)])
1198 (label_ref (match_operand 3 "" ""))
1199 (pc)))]
1200 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1201 {
1202 ix86_expand_branch (GET_CODE (operands[0]),
1203 operands[1], operands[2], operands[3]);
1204 DONE;
1205 })
1206
1207 (define_expand "cstore<mode>4"
1208 [(set (reg:CC FLAGS_REG)
1209 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1210 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1211 (set (match_operand:QI 0 "register_operand" "")
1212 (match_operator 1 "ix86_fp_comparison_operator"
1213 [(reg:CC FLAGS_REG)
1214 (const_int 0)]))]
1215 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1216 {
1217 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1218 operands[2], operands[3]);
1219 DONE;
1220 })
1221
1222 (define_expand "cbranchcc4"
1223 [(set (pc) (if_then_else
1224 (match_operator 0 "comparison_operator"
1225 [(match_operand 1 "flags_reg_operand" "")
1226 (match_operand 2 "const0_operand" "")])
1227 (label_ref (match_operand 3 "" ""))
1228 (pc)))]
1229 ""
1230 {
1231 ix86_expand_branch (GET_CODE (operands[0]),
1232 operands[1], operands[2], operands[3]);
1233 DONE;
1234 })
1235
1236 (define_expand "cstorecc4"
1237 [(set (match_operand:QI 0 "register_operand" "")
1238 (match_operator 1 "comparison_operator"
1239 [(match_operand 2 "flags_reg_operand" "")
1240 (match_operand 3 "const0_operand" "")]))]
1241 ""
1242 {
1243 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1244 operands[2], operands[3]);
1245 DONE;
1246 })
1247
1248
1249 ;; FP compares, step 1:
1250 ;; Set the FP condition codes.
1251 ;;
1252 ;; CCFPmode compare with exceptions
1253 ;; CCFPUmode compare with no exceptions
1254
1255 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1256 ;; used to manage the reg stack popping would not be preserved.
1257
1258 (define_insn "*cmpfp_0"
1259 [(set (match_operand:HI 0 "register_operand" "=a")
1260 (unspec:HI
1261 [(compare:CCFP
1262 (match_operand 1 "register_operand" "f")
1263 (match_operand 2 "const0_operand" ""))]
1264 UNSPEC_FNSTSW))]
1265 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1266 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1267 "* return output_fp_compare (insn, operands, false, false);"
1268 [(set_attr "type" "multi")
1269 (set_attr "unit" "i387")
1270 (set (attr "mode")
1271 (cond [(match_operand:SF 1 "" "")
1272 (const_string "SF")
1273 (match_operand:DF 1 "" "")
1274 (const_string "DF")
1275 ]
1276 (const_string "XF")))])
1277
1278 (define_insn_and_split "*cmpfp_0_cc"
1279 [(set (reg:CCFP FLAGS_REG)
1280 (compare:CCFP
1281 (match_operand 1 "register_operand" "f")
1282 (match_operand 2 "const0_operand" "")))
1283 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1284 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1285 && TARGET_SAHF && !TARGET_CMOVE
1286 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
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")
1299 (cond [(match_operand:SF 1 "" "")
1300 (const_string "SF")
1301 (match_operand:DF 1 "" "")
1302 (const_string "DF")
1303 ]
1304 (const_string "XF")))])
1305
1306 (define_insn "*cmpfp_xf"
1307 [(set (match_operand:HI 0 "register_operand" "=a")
1308 (unspec:HI
1309 [(compare:CCFP
1310 (match_operand:XF 1 "register_operand" "f")
1311 (match_operand:XF 2 "register_operand" "f"))]
1312 UNSPEC_FNSTSW))]
1313 "TARGET_80387"
1314 "* return output_fp_compare (insn, operands, false, false);"
1315 [(set_attr "type" "multi")
1316 (set_attr "unit" "i387")
1317 (set_attr "mode" "XF")])
1318
1319 (define_insn_and_split "*cmpfp_xf_cc"
1320 [(set (reg:CCFP FLAGS_REG)
1321 (compare:CCFP
1322 (match_operand:XF 1 "register_operand" "f")
1323 (match_operand:XF 2 "register_operand" "f")))
1324 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1325 "TARGET_80387
1326 && TARGET_SAHF && !TARGET_CMOVE"
1327 "#"
1328 "&& reload_completed"
1329 [(set (match_dup 0)
1330 (unspec:HI
1331 [(compare:CCFP (match_dup 1)(match_dup 2))]
1332 UNSPEC_FNSTSW))
1333 (set (reg:CC FLAGS_REG)
1334 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1335 ""
1336 [(set_attr "type" "multi")
1337 (set_attr "unit" "i387")
1338 (set_attr "mode" "XF")])
1339
1340 (define_insn "*cmpfp_<mode>"
1341 [(set (match_operand:HI 0 "register_operand" "=a")
1342 (unspec:HI
1343 [(compare:CCFP
1344 (match_operand:MODEF 1 "register_operand" "f")
1345 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1346 UNSPEC_FNSTSW))]
1347 "TARGET_80387"
1348 "* return output_fp_compare (insn, operands, false, false);"
1349 [(set_attr "type" "multi")
1350 (set_attr "unit" "i387")
1351 (set_attr "mode" "<MODE>")])
1352
1353 (define_insn_and_split "*cmpfp_<mode>_cc"
1354 [(set (reg:CCFP FLAGS_REG)
1355 (compare:CCFP
1356 (match_operand:MODEF 1 "register_operand" "f")
1357 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1358 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1359 "TARGET_80387
1360 && TARGET_SAHF && !TARGET_CMOVE"
1361 "#"
1362 "&& reload_completed"
1363 [(set (match_dup 0)
1364 (unspec:HI
1365 [(compare:CCFP (match_dup 1)(match_dup 2))]
1366 UNSPEC_FNSTSW))
1367 (set (reg:CC FLAGS_REG)
1368 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1369 ""
1370 [(set_attr "type" "multi")
1371 (set_attr "unit" "i387")
1372 (set_attr "mode" "<MODE>")])
1373
1374 (define_insn "*cmpfp_u"
1375 [(set (match_operand:HI 0 "register_operand" "=a")
1376 (unspec:HI
1377 [(compare:CCFPU
1378 (match_operand 1 "register_operand" "f")
1379 (match_operand 2 "register_operand" "f"))]
1380 UNSPEC_FNSTSW))]
1381 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1382 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1383 "* return output_fp_compare (insn, operands, false, true);"
1384 [(set_attr "type" "multi")
1385 (set_attr "unit" "i387")
1386 (set (attr "mode")
1387 (cond [(match_operand:SF 1 "" "")
1388 (const_string "SF")
1389 (match_operand:DF 1 "" "")
1390 (const_string "DF")
1391 ]
1392 (const_string "XF")))])
1393
1394 (define_insn_and_split "*cmpfp_u_cc"
1395 [(set (reg:CCFPU FLAGS_REG)
1396 (compare:CCFPU
1397 (match_operand 1 "register_operand" "f")
1398 (match_operand 2 "register_operand" "f")))
1399 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1400 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1401 && TARGET_SAHF && !TARGET_CMOVE
1402 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1403 "#"
1404 "&& reload_completed"
1405 [(set (match_dup 0)
1406 (unspec:HI
1407 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1408 UNSPEC_FNSTSW))
1409 (set (reg:CC FLAGS_REG)
1410 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1411 ""
1412 [(set_attr "type" "multi")
1413 (set_attr "unit" "i387")
1414 (set (attr "mode")
1415 (cond [(match_operand:SF 1 "" "")
1416 (const_string "SF")
1417 (match_operand:DF 1 "" "")
1418 (const_string "DF")
1419 ]
1420 (const_string "XF")))])
1421
1422 (define_insn "*cmpfp_<mode>"
1423 [(set (match_operand:HI 0 "register_operand" "=a")
1424 (unspec:HI
1425 [(compare:CCFP
1426 (match_operand 1 "register_operand" "f")
1427 (match_operator 3 "float_operator"
1428 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1429 UNSPEC_FNSTSW))]
1430 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1431 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1432 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1433 "* return output_fp_compare (insn, operands, false, false);"
1434 [(set_attr "type" "multi")
1435 (set_attr "unit" "i387")
1436 (set_attr "fp_int_src" "true")
1437 (set_attr "mode" "<MODE>")])
1438
1439 (define_insn_and_split "*cmpfp_<mode>_cc"
1440 [(set (reg:CCFP FLAGS_REG)
1441 (compare:CCFP
1442 (match_operand 1 "register_operand" "f")
1443 (match_operator 3 "float_operator"
1444 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1445 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1446 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1447 && TARGET_SAHF && !TARGET_CMOVE
1448 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1449 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1450 "#"
1451 "&& reload_completed"
1452 [(set (match_dup 0)
1453 (unspec:HI
1454 [(compare:CCFP
1455 (match_dup 1)
1456 (match_op_dup 3 [(match_dup 2)]))]
1457 UNSPEC_FNSTSW))
1458 (set (reg:CC FLAGS_REG)
1459 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1460 ""
1461 [(set_attr "type" "multi")
1462 (set_attr "unit" "i387")
1463 (set_attr "fp_int_src" "true")
1464 (set_attr "mode" "<MODE>")])
1465
1466 ;; FP compares, step 2
1467 ;; Move the fpsw to ax.
1468
1469 (define_insn "x86_fnstsw_1"
1470 [(set (match_operand:HI 0 "register_operand" "=a")
1471 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1472 "TARGET_80387"
1473 "fnstsw\t%0"
1474 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1475 (set_attr "mode" "SI")
1476 (set_attr "unit" "i387")])
1477
1478 ;; FP compares, step 3
1479 ;; Get ax into flags, general case.
1480
1481 (define_insn "x86_sahf_1"
1482 [(set (reg:CC FLAGS_REG)
1483 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1484 UNSPEC_SAHF))]
1485 "TARGET_SAHF"
1486 {
1487 #ifndef HAVE_AS_IX86_SAHF
1488 if (TARGET_64BIT)
1489 return ASM_BYTE "0x9e";
1490 else
1491 #endif
1492 return "sahf";
1493 }
1494 [(set_attr "length" "1")
1495 (set_attr "athlon_decode" "vector")
1496 (set_attr "amdfam10_decode" "direct")
1497 (set_attr "bdver1_decode" "direct")
1498 (set_attr "mode" "SI")])
1499
1500 ;; Pentium Pro can do steps 1 through 3 in one go.
1501 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1502 (define_insn "*cmpfp_i_mixed"
1503 [(set (reg:CCFP FLAGS_REG)
1504 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1505 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1506 "TARGET_MIX_SSE_I387
1507 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1508 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1509 "* return output_fp_compare (insn, operands, true, false);"
1510 [(set_attr "type" "fcmp,ssecomi")
1511 (set_attr "prefix" "orig,maybe_vex")
1512 (set (attr "mode")
1513 (if_then_else (match_operand:SF 1 "" "")
1514 (const_string "SF")
1515 (const_string "DF")))
1516 (set (attr "prefix_rep")
1517 (if_then_else (eq_attr "type" "ssecomi")
1518 (const_string "0")
1519 (const_string "*")))
1520 (set (attr "prefix_data16")
1521 (cond [(eq_attr "type" "fcmp")
1522 (const_string "*")
1523 (eq_attr "mode" "DF")
1524 (const_string "1")
1525 ]
1526 (const_string "0")))
1527 (set_attr "athlon_decode" "vector")
1528 (set_attr "amdfam10_decode" "direct")
1529 (set_attr "bdver1_decode" "double")])
1530
1531 (define_insn "*cmpfp_i_sse"
1532 [(set (reg:CCFP FLAGS_REG)
1533 (compare:CCFP (match_operand 0 "register_operand" "x")
1534 (match_operand 1 "nonimmediate_operand" "xm")))]
1535 "TARGET_SSE_MATH
1536 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1537 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1538 "* return output_fp_compare (insn, operands, true, false);"
1539 [(set_attr "type" "ssecomi")
1540 (set_attr "prefix" "maybe_vex")
1541 (set (attr "mode")
1542 (if_then_else (match_operand:SF 1 "" "")
1543 (const_string "SF")
1544 (const_string "DF")))
1545 (set_attr "prefix_rep" "0")
1546 (set (attr "prefix_data16")
1547 (if_then_else (eq_attr "mode" "DF")
1548 (const_string "1")
1549 (const_string "0")))
1550 (set_attr "athlon_decode" "vector")
1551 (set_attr "amdfam10_decode" "direct")
1552 (set_attr "bdver1_decode" "double")])
1553
1554 (define_insn "*cmpfp_i_i387"
1555 [(set (reg:CCFP FLAGS_REG)
1556 (compare:CCFP (match_operand 0 "register_operand" "f")
1557 (match_operand 1 "register_operand" "f")))]
1558 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1559 && TARGET_CMOVE
1560 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1561 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1562 "* return output_fp_compare (insn, operands, true, false);"
1563 [(set_attr "type" "fcmp")
1564 (set (attr "mode")
1565 (cond [(match_operand:SF 1 "" "")
1566 (const_string "SF")
1567 (match_operand:DF 1 "" "")
1568 (const_string "DF")
1569 ]
1570 (const_string "XF")))
1571 (set_attr "athlon_decode" "vector")
1572 (set_attr "amdfam10_decode" "direct")
1573 (set_attr "bdver1_decode" "double")])
1574
1575 (define_insn "*cmpfp_iu_mixed"
1576 [(set (reg:CCFPU FLAGS_REG)
1577 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1578 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1579 "TARGET_MIX_SSE_I387
1580 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1581 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1582 "* return output_fp_compare (insn, operands, true, true);"
1583 [(set_attr "type" "fcmp,ssecomi")
1584 (set_attr "prefix" "orig,maybe_vex")
1585 (set (attr "mode")
1586 (if_then_else (match_operand:SF 1 "" "")
1587 (const_string "SF")
1588 (const_string "DF")))
1589 (set (attr "prefix_rep")
1590 (if_then_else (eq_attr "type" "ssecomi")
1591 (const_string "0")
1592 (const_string "*")))
1593 (set (attr "prefix_data16")
1594 (cond [(eq_attr "type" "fcmp")
1595 (const_string "*")
1596 (eq_attr "mode" "DF")
1597 (const_string "1")
1598 ]
1599 (const_string "0")))
1600 (set_attr "athlon_decode" "vector")
1601 (set_attr "amdfam10_decode" "direct")
1602 (set_attr "bdver1_decode" "double")])
1603
1604 (define_insn "*cmpfp_iu_sse"
1605 [(set (reg:CCFPU FLAGS_REG)
1606 (compare:CCFPU (match_operand 0 "register_operand" "x")
1607 (match_operand 1 "nonimmediate_operand" "xm")))]
1608 "TARGET_SSE_MATH
1609 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1610 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1611 "* return output_fp_compare (insn, operands, true, true);"
1612 [(set_attr "type" "ssecomi")
1613 (set_attr "prefix" "maybe_vex")
1614 (set (attr "mode")
1615 (if_then_else (match_operand:SF 1 "" "")
1616 (const_string "SF")
1617 (const_string "DF")))
1618 (set_attr "prefix_rep" "0")
1619 (set (attr "prefix_data16")
1620 (if_then_else (eq_attr "mode" "DF")
1621 (const_string "1")
1622 (const_string "0")))
1623 (set_attr "athlon_decode" "vector")
1624 (set_attr "amdfam10_decode" "direct")
1625 (set_attr "bdver1_decode" "double")])
1626
1627 (define_insn "*cmpfp_iu_387"
1628 [(set (reg:CCFPU FLAGS_REG)
1629 (compare:CCFPU (match_operand 0 "register_operand" "f")
1630 (match_operand 1 "register_operand" "f")))]
1631 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1632 && TARGET_CMOVE
1633 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1634 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1635 "* return output_fp_compare (insn, operands, true, true);"
1636 [(set_attr "type" "fcmp")
1637 (set (attr "mode")
1638 (cond [(match_operand:SF 1 "" "")
1639 (const_string "SF")
1640 (match_operand:DF 1 "" "")
1641 (const_string "DF")
1642 ]
1643 (const_string "XF")))
1644 (set_attr "athlon_decode" "vector")
1645 (set_attr "amdfam10_decode" "direct")
1646 (set_attr "bdver1_decode" "direct")])
1647 \f
1648 ;; Push/pop instructions.
1649
1650 (define_insn "*push<mode>2"
1651 [(set (match_operand:DWI 0 "push_operand" "=<")
1652 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1653 ""
1654 "#")
1655
1656 (define_split
1657 [(set (match_operand:TI 0 "push_operand" "")
1658 (match_operand:TI 1 "general_operand" ""))]
1659 "TARGET_64BIT && reload_completed
1660 && !SSE_REG_P (operands[1])"
1661 [(const_int 0)]
1662 "ix86_split_long_move (operands); DONE;")
1663
1664 (define_insn "*pushdi2_rex64"
1665 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1666 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1667 "TARGET_64BIT"
1668 "@
1669 push{q}\t%1
1670 #"
1671 [(set_attr "type" "push,multi")
1672 (set_attr "mode" "DI")])
1673
1674 ;; Convert impossible pushes of immediate to existing instructions.
1675 ;; First try to get scratch register and go through it. In case this
1676 ;; fails, push sign extended lower part first and then overwrite
1677 ;; upper part by 32bit move.
1678 (define_peephole2
1679 [(match_scratch:DI 2 "r")
1680 (set (match_operand:DI 0 "push_operand" "")
1681 (match_operand:DI 1 "immediate_operand" ""))]
1682 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1683 && !x86_64_immediate_operand (operands[1], DImode)"
1684 [(set (match_dup 2) (match_dup 1))
1685 (set (match_dup 0) (match_dup 2))])
1686
1687 ;; We need to define this as both peepholer and splitter for case
1688 ;; peephole2 pass is not run.
1689 ;; "&& 1" is needed to keep it from matching the previous pattern.
1690 (define_peephole2
1691 [(set (match_operand:DI 0 "push_operand" "")
1692 (match_operand:DI 1 "immediate_operand" ""))]
1693 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1694 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1695 [(set (match_dup 0) (match_dup 1))
1696 (set (match_dup 2) (match_dup 3))]
1697 {
1698 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1699
1700 operands[1] = gen_lowpart (DImode, operands[2]);
1701 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1702 GEN_INT (4)));
1703 })
1704
1705 (define_split
1706 [(set (match_operand:DI 0 "push_operand" "")
1707 (match_operand:DI 1 "immediate_operand" ""))]
1708 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1709 ? epilogue_completed : reload_completed)
1710 && !symbolic_operand (operands[1], DImode)
1711 && !x86_64_immediate_operand (operands[1], DImode)"
1712 [(set (match_dup 0) (match_dup 1))
1713 (set (match_dup 2) (match_dup 3))]
1714 {
1715 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1716
1717 operands[1] = gen_lowpart (DImode, operands[2]);
1718 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1719 GEN_INT (4)));
1720 })
1721
1722 (define_split
1723 [(set (match_operand:DI 0 "push_operand" "")
1724 (match_operand:DI 1 "general_operand" ""))]
1725 "!TARGET_64BIT && reload_completed
1726 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1727 [(const_int 0)]
1728 "ix86_split_long_move (operands); DONE;")
1729
1730 (define_insn "*pushsi2"
1731 [(set (match_operand:SI 0 "push_operand" "=<")
1732 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1733 "!TARGET_64BIT"
1734 "push{l}\t%1"
1735 [(set_attr "type" "push")
1736 (set_attr "mode" "SI")])
1737
1738 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1739 ;; "push a byte/word". But actually we use pushl, which has the effect
1740 ;; of rounding the amount pushed up to a word.
1741
1742 ;; For TARGET_64BIT we always round up to 8 bytes.
1743 (define_insn "*push<mode>2_rex64"
1744 [(set (match_operand:SWI124 0 "push_operand" "=X")
1745 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1746 "TARGET_64BIT"
1747 "push{q}\t%q1"
1748 [(set_attr "type" "push")
1749 (set_attr "mode" "DI")])
1750
1751 (define_insn "*push<mode>2"
1752 [(set (match_operand:SWI12 0 "push_operand" "=X")
1753 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1754 "!TARGET_64BIT"
1755 "push{l}\t%k1"
1756 [(set_attr "type" "push")
1757 (set_attr "mode" "SI")])
1758
1759 (define_insn "*push<mode>2_prologue"
1760 [(set (match_operand:P 0 "push_operand" "=<")
1761 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1762 (clobber (mem:BLK (scratch)))]
1763 ""
1764 "push{<imodesuffix>}\t%1"
1765 [(set_attr "type" "push")
1766 (set_attr "mode" "<MODE>")])
1767
1768 (define_insn "*pop<mode>1"
1769 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1770 (match_operand:P 1 "pop_operand" ">"))]
1771 ""
1772 "pop{<imodesuffix>}\t%0"
1773 [(set_attr "type" "pop")
1774 (set_attr "mode" "<MODE>")])
1775
1776 (define_insn "*pop<mode>1_epilogue"
1777 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1778 (match_operand:P 1 "pop_operand" ">"))
1779 (clobber (mem:BLK (scratch)))]
1780 ""
1781 "pop{<imodesuffix>}\t%0"
1782 [(set_attr "type" "pop")
1783 (set_attr "mode" "<MODE>")])
1784 \f
1785 ;; Move instructions.
1786
1787 (define_expand "movoi"
1788 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1789 (match_operand:OI 1 "general_operand" ""))]
1790 "TARGET_AVX"
1791 "ix86_expand_move (OImode, operands); DONE;")
1792
1793 (define_expand "movti"
1794 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1795 (match_operand:TI 1 "nonimmediate_operand" ""))]
1796 "TARGET_64BIT || TARGET_SSE"
1797 {
1798 if (TARGET_64BIT)
1799 ix86_expand_move (TImode, operands);
1800 else if (push_operand (operands[0], TImode))
1801 ix86_expand_push (TImode, operands[1]);
1802 else
1803 ix86_expand_vector_move (TImode, operands);
1804 DONE;
1805 })
1806
1807 ;; This expands to what emit_move_complex would generate if we didn't
1808 ;; have a movti pattern. Having this avoids problems with reload on
1809 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1810 ;; to have around all the time.
1811 (define_expand "movcdi"
1812 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1813 (match_operand:CDI 1 "general_operand" ""))]
1814 ""
1815 {
1816 if (push_operand (operands[0], CDImode))
1817 emit_move_complex_push (CDImode, operands[0], operands[1]);
1818 else
1819 emit_move_complex_parts (operands[0], operands[1]);
1820 DONE;
1821 })
1822
1823 (define_expand "mov<mode>"
1824 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1825 (match_operand:SWI1248x 1 "general_operand" ""))]
1826 ""
1827 "ix86_expand_move (<MODE>mode, operands); DONE;")
1828
1829 (define_insn "*mov<mode>_xor"
1830 [(set (match_operand:SWI48 0 "register_operand" "=r")
1831 (match_operand:SWI48 1 "const0_operand" ""))
1832 (clobber (reg:CC FLAGS_REG))]
1833 "reload_completed"
1834 "xor{l}\t%k0, %k0"
1835 [(set_attr "type" "alu1")
1836 (set_attr "mode" "SI")
1837 (set_attr "length_immediate" "0")])
1838
1839 (define_insn "*mov<mode>_or"
1840 [(set (match_operand:SWI48 0 "register_operand" "=r")
1841 (match_operand:SWI48 1 "const_int_operand" ""))
1842 (clobber (reg:CC FLAGS_REG))]
1843 "reload_completed
1844 && operands[1] == constm1_rtx"
1845 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1846 [(set_attr "type" "alu1")
1847 (set_attr "mode" "<MODE>")
1848 (set_attr "length_immediate" "1")])
1849
1850 (define_insn "*movoi_internal_avx"
1851 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1852 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1853 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1854 {
1855 switch (which_alternative)
1856 {
1857 case 0:
1858 return standard_sse_constant_opcode (insn, operands[1]);
1859 case 1:
1860 case 2:
1861 if (misaligned_operand (operands[0], OImode)
1862 || misaligned_operand (operands[1], OImode))
1863 return "vmovdqu\t{%1, %0|%0, %1}";
1864 else
1865 return "vmovdqa\t{%1, %0|%0, %1}";
1866 default:
1867 gcc_unreachable ();
1868 }
1869 }
1870 [(set_attr "type" "sselog1,ssemov,ssemov")
1871 (set_attr "prefix" "vex")
1872 (set_attr "mode" "OI")])
1873
1874 (define_insn "*movti_internal_rex64"
1875 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1876 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1877 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1878 {
1879 switch (which_alternative)
1880 {
1881 case 0:
1882 case 1:
1883 return "#";
1884 case 2:
1885 return standard_sse_constant_opcode (insn, operands[1]);
1886 case 3:
1887 case 4:
1888 /* TDmode values are passed as TImode on the stack. Moving them
1889 to stack may result in unaligned memory access. */
1890 if (misaligned_operand (operands[0], TImode)
1891 || misaligned_operand (operands[1], TImode))
1892 {
1893 if (get_attr_mode (insn) == MODE_V4SF)
1894 return "%vmovups\t{%1, %0|%0, %1}";
1895 else
1896 return "%vmovdqu\t{%1, %0|%0, %1}";
1897 }
1898 else
1899 {
1900 if (get_attr_mode (insn) == MODE_V4SF)
1901 return "%vmovaps\t{%1, %0|%0, %1}";
1902 else
1903 return "%vmovdqa\t{%1, %0|%0, %1}";
1904 }
1905 default:
1906 gcc_unreachable ();
1907 }
1908 }
1909 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1910 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1911 (set (attr "mode")
1912 (cond [(eq_attr "alternative" "2,3")
1913 (if_then_else
1914 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1915 (const_int 0))
1916 (const_string "V4SF")
1917 (const_string "TI"))
1918 (eq_attr "alternative" "4")
1919 (if_then_else
1920 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1921 (const_int 0))
1922 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1923 (const_int 0)))
1924 (const_string "V4SF")
1925 (const_string "TI"))]
1926 (const_string "DI")))])
1927
1928 (define_split
1929 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1930 (match_operand:TI 1 "general_operand" ""))]
1931 "reload_completed
1932 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1933 [(const_int 0)]
1934 "ix86_split_long_move (operands); DONE;")
1935
1936 (define_insn "*movti_internal_sse"
1937 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1938 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1939 "TARGET_SSE && !TARGET_64BIT
1940 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1941 {
1942 switch (which_alternative)
1943 {
1944 case 0:
1945 return standard_sse_constant_opcode (insn, operands[1]);
1946 case 1:
1947 case 2:
1948 /* TDmode values are passed as TImode on the stack. Moving them
1949 to stack may result in unaligned memory access. */
1950 if (misaligned_operand (operands[0], TImode)
1951 || misaligned_operand (operands[1], TImode))
1952 {
1953 if (get_attr_mode (insn) == MODE_V4SF)
1954 return "%vmovups\t{%1, %0|%0, %1}";
1955 else
1956 return "%vmovdqu\t{%1, %0|%0, %1}";
1957 }
1958 else
1959 {
1960 if (get_attr_mode (insn) == MODE_V4SF)
1961 return "%vmovaps\t{%1, %0|%0, %1}";
1962 else
1963 return "%vmovdqa\t{%1, %0|%0, %1}";
1964 }
1965 default:
1966 gcc_unreachable ();
1967 }
1968 }
1969 [(set_attr "type" "sselog1,ssemov,ssemov")
1970 (set_attr "prefix" "maybe_vex")
1971 (set (attr "mode")
1972 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1973 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1974 (const_int 0)))
1975 (const_string "V4SF")
1976 (and (eq_attr "alternative" "2")
1977 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1978 (const_int 0)))
1979 (const_string "V4SF")]
1980 (const_string "TI")))])
1981
1982 (define_insn "*movdi_internal_rex64"
1983 [(set (match_operand:DI 0 "nonimmediate_operand"
1984 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1985 (match_operand:DI 1 "general_operand"
1986 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1987 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1988 {
1989 switch (get_attr_type (insn))
1990 {
1991 case TYPE_SSECVT:
1992 if (SSE_REG_P (operands[0]))
1993 return "movq2dq\t{%1, %0|%0, %1}";
1994 else
1995 return "movdq2q\t{%1, %0|%0, %1}";
1996
1997 case TYPE_SSEMOV:
1998 if (get_attr_mode (insn) == MODE_TI)
1999 return "%vmovdqa\t{%1, %0|%0, %1}";
2000 /* Handle broken assemblers that require movd instead of movq. */
2001 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2002 return "%vmovd\t{%1, %0|%0, %1}";
2003 else
2004 return "%vmovq\t{%1, %0|%0, %1}";
2005
2006 case TYPE_MMXMOV:
2007 /* Handle broken assemblers that require movd instead of movq. */
2008 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2009 return "movd\t{%1, %0|%0, %1}";
2010 else
2011 return "movq\t{%1, %0|%0, %1}";
2012
2013 case TYPE_SSELOG1:
2014 return standard_sse_constant_opcode (insn, operands[1]);
2015
2016 case TYPE_MMX:
2017 return "pxor\t%0, %0";
2018
2019 case TYPE_MULTI:
2020 return "#";
2021
2022 case TYPE_LEA:
2023 return "lea{q}\t{%a1, %0|%0, %a1}";
2024
2025 default:
2026 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2027 if (get_attr_mode (insn) == MODE_SI)
2028 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2029 else if (which_alternative == 2)
2030 return "movabs{q}\t{%1, %0|%0, %1}";
2031 else
2032 return "mov{q}\t{%1, %0|%0, %1}";
2033 }
2034 }
2035 [(set (attr "type")
2036 (cond [(eq_attr "alternative" "5")
2037 (const_string "mmx")
2038 (eq_attr "alternative" "6,7,8,9,10")
2039 (const_string "mmxmov")
2040 (eq_attr "alternative" "11")
2041 (const_string "sselog1")
2042 (eq_attr "alternative" "12,13,14,15,16")
2043 (const_string "ssemov")
2044 (eq_attr "alternative" "17,18")
2045 (const_string "ssecvt")
2046 (eq_attr "alternative" "4")
2047 (const_string "multi")
2048 (match_operand:DI 1 "pic_32bit_operand" "")
2049 (const_string "lea")
2050 ]
2051 (const_string "imov")))
2052 (set (attr "modrm")
2053 (if_then_else
2054 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2055 (const_string "0")
2056 (const_string "*")))
2057 (set (attr "length_immediate")
2058 (if_then_else
2059 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2060 (const_string "8")
2061 (const_string "*")))
2062 (set (attr "prefix_rex")
2063 (if_then_else (eq_attr "alternative" "7,9")
2064 (const_string "1")
2065 (const_string "*")))
2066 (set (attr "prefix_data16")
2067 (if_then_else (eq_attr "alternative" "15")
2068 (const_string "1")
2069 (const_string "*")))
2070 (set (attr "prefix")
2071 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2072 (const_string "maybe_vex")
2073 (const_string "orig")))
2074 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2075
2076 ;; Convert impossible stores of immediate to existing instructions.
2077 ;; First try to get scratch register and go through it. In case this
2078 ;; fails, move by 32bit parts.
2079 (define_peephole2
2080 [(match_scratch:DI 2 "r")
2081 (set (match_operand:DI 0 "memory_operand" "")
2082 (match_operand:DI 1 "immediate_operand" ""))]
2083 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084 && !x86_64_immediate_operand (operands[1], DImode)"
2085 [(set (match_dup 2) (match_dup 1))
2086 (set (match_dup 0) (match_dup 2))])
2087
2088 ;; We need to define this as both peepholer and splitter for case
2089 ;; peephole2 pass is not run.
2090 ;; "&& 1" is needed to keep it from matching the previous pattern.
2091 (define_peephole2
2092 [(set (match_operand:DI 0 "memory_operand" "")
2093 (match_operand:DI 1 "immediate_operand" ""))]
2094 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2095 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2096 [(set (match_dup 2) (match_dup 3))
2097 (set (match_dup 4) (match_dup 5))]
2098 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2099
2100 (define_split
2101 [(set (match_operand:DI 0 "memory_operand" "")
2102 (match_operand:DI 1 "immediate_operand" ""))]
2103 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2104 ? epilogue_completed : reload_completed)
2105 && !symbolic_operand (operands[1], DImode)
2106 && !x86_64_immediate_operand (operands[1], DImode)"
2107 [(set (match_dup 2) (match_dup 3))
2108 (set (match_dup 4) (match_dup 5))]
2109 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2110
2111 (define_insn "*movdi_internal"
2112 [(set (match_operand:DI 0 "nonimmediate_operand"
2113 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2114 (match_operand:DI 1 "general_operand"
2115 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m ,*Ym ,*Y2"))]
2116 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2117 {
2118 switch (get_attr_type (insn))
2119 {
2120 case TYPE_SSECVT:
2121 if (SSE_REG_P (operands[0]))
2122 return "movq2dq\t{%1, %0|%0, %1}";
2123 else
2124 return "movdq2q\t{%1, %0|%0, %1}";
2125
2126 case TYPE_SSEMOV:
2127 switch (get_attr_mode (insn))
2128 {
2129 case MODE_TI:
2130 return "%vmovdqa\t{%1, %0|%0, %1}";
2131 case MODE_DI:
2132 return "%vmovq\t{%1, %0|%0, %1}";
2133 case MODE_V4SF:
2134 return "movaps\t{%1, %0|%0, %1}";
2135 case MODE_V2SF:
2136 return "movlps\t{%1, %0|%0, %1}";
2137 default:
2138 gcc_unreachable ();
2139 }
2140
2141 case TYPE_MMXMOV:
2142 return "movq\t{%1, %0|%0, %1}";
2143
2144 case TYPE_SSELOG1:
2145 return standard_sse_constant_opcode (insn, operands[1]);
2146
2147 case TYPE_MMX:
2148 return "pxor\t%0, %0";
2149
2150 case TYPE_MULTI:
2151 return "#";
2152
2153 default:
2154 gcc_unreachable ();
2155 }
2156 }
2157 [(set (attr "isa")
2158 (if_then_else (eq_attr "alternative" "9,10,11,12")
2159 (const_string "noavx")
2160 (const_string "base")))
2161 (set (attr "type")
2162 (cond [(eq_attr "alternative" "0,1")
2163 (const_string "multi")
2164 (eq_attr "alternative" "2")
2165 (const_string "mmx")
2166 (eq_attr "alternative" "3,4")
2167 (const_string "mmxmov")
2168 (eq_attr "alternative" "5,9")
2169 (const_string "sselog1")
2170 (eq_attr "alternative" "13,14")
2171 (const_string "ssecvt")
2172 ]
2173 (const_string "ssemov")))
2174 (set (attr "prefix")
2175 (if_then_else (eq_attr "alternative" "5,6,7,8")
2176 (const_string "maybe_vex")
2177 (const_string "orig")))
2178 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2179
2180 (define_split
2181 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2182 (match_operand:DI 1 "general_operand" ""))]
2183 "!TARGET_64BIT && reload_completed
2184 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2185 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2186 [(const_int 0)]
2187 "ix86_split_long_move (operands); DONE;")
2188
2189 (define_insn "*movsi_internal"
2190 [(set (match_operand:SI 0 "nonimmediate_operand"
2191 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2192 (match_operand:SI 1 "general_operand"
2193 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2194 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2195 {
2196 switch (get_attr_type (insn))
2197 {
2198 case TYPE_SSELOG1:
2199 return standard_sse_constant_opcode (insn, operands[1]);
2200
2201 case TYPE_SSEMOV:
2202 switch (get_attr_mode (insn))
2203 {
2204 case MODE_TI:
2205 return "%vmovdqa\t{%1, %0|%0, %1}";
2206 case MODE_V4SF:
2207 return "%vmovaps\t{%1, %0|%0, %1}";
2208 case MODE_SI:
2209 return "%vmovd\t{%1, %0|%0, %1}";
2210 case MODE_SF:
2211 return "%vmovss\t{%1, %0|%0, %1}";
2212 default:
2213 gcc_unreachable ();
2214 }
2215
2216 case TYPE_MMX:
2217 return "pxor\t%0, %0";
2218
2219 case TYPE_MMXMOV:
2220 if (get_attr_mode (insn) == MODE_DI)
2221 return "movq\t{%1, %0|%0, %1}";
2222 return "movd\t{%1, %0|%0, %1}";
2223
2224 case TYPE_LEA:
2225 return "lea{l}\t{%a1, %0|%0, %a1}";
2226
2227 default:
2228 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2229 return "mov{l}\t{%1, %0|%0, %1}";
2230 }
2231 }
2232 [(set (attr "type")
2233 (cond [(eq_attr "alternative" "2")
2234 (const_string "mmx")
2235 (eq_attr "alternative" "3,4,5")
2236 (const_string "mmxmov")
2237 (eq_attr "alternative" "6")
2238 (const_string "sselog1")
2239 (eq_attr "alternative" "7,8,9,10,11")
2240 (const_string "ssemov")
2241 (match_operand:DI 1 "pic_32bit_operand" "")
2242 (const_string "lea")
2243 ]
2244 (const_string "imov")))
2245 (set (attr "prefix")
2246 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2247 (const_string "orig")
2248 (const_string "maybe_vex")))
2249 (set (attr "prefix_data16")
2250 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2251 (const_string "1")
2252 (const_string "*")))
2253 (set (attr "mode")
2254 (cond [(eq_attr "alternative" "2,3")
2255 (const_string "DI")
2256 (eq_attr "alternative" "6,7")
2257 (if_then_else
2258 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2259 (const_string "V4SF")
2260 (const_string "TI"))
2261 (and (eq_attr "alternative" "8,9,10,11")
2262 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2263 (const_string "SF")
2264 ]
2265 (const_string "SI")))])
2266
2267 (define_insn "*movhi_internal"
2268 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2269 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2270 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2271 {
2272 switch (get_attr_type (insn))
2273 {
2274 case TYPE_IMOVX:
2275 /* movzwl is faster than movw on p2 due to partial word stalls,
2276 though not as fast as an aligned movl. */
2277 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2278 default:
2279 if (get_attr_mode (insn) == MODE_SI)
2280 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2281 else
2282 return "mov{w}\t{%1, %0|%0, %1}";
2283 }
2284 }
2285 [(set (attr "type")
2286 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2287 (const_int 0))
2288 (const_string "imov")
2289 (and (eq_attr "alternative" "0")
2290 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2291 (const_int 0))
2292 (eq (symbol_ref "TARGET_HIMODE_MATH")
2293 (const_int 0))))
2294 (const_string "imov")
2295 (and (eq_attr "alternative" "1,2")
2296 (match_operand:HI 1 "aligned_operand" ""))
2297 (const_string "imov")
2298 (and (ne (symbol_ref "TARGET_MOVX")
2299 (const_int 0))
2300 (eq_attr "alternative" "0,2"))
2301 (const_string "imovx")
2302 ]
2303 (const_string "imov")))
2304 (set (attr "mode")
2305 (cond [(eq_attr "type" "imovx")
2306 (const_string "SI")
2307 (and (eq_attr "alternative" "1,2")
2308 (match_operand:HI 1 "aligned_operand" ""))
2309 (const_string "SI")
2310 (and (eq_attr "alternative" "0")
2311 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2312 (const_int 0))
2313 (eq (symbol_ref "TARGET_HIMODE_MATH")
2314 (const_int 0))))
2315 (const_string "SI")
2316 ]
2317 (const_string "HI")))])
2318
2319 ;; Situation is quite tricky about when to choose full sized (SImode) move
2320 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2321 ;; partial register dependency machines (such as AMD Athlon), where QImode
2322 ;; moves issue extra dependency and for partial register stalls machines
2323 ;; that don't use QImode patterns (and QImode move cause stall on the next
2324 ;; instruction).
2325 ;;
2326 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2327 ;; register stall machines with, where we use QImode instructions, since
2328 ;; partial register stall can be caused there. Then we use movzx.
2329 (define_insn "*movqi_internal"
2330 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2331 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2332 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2333 {
2334 switch (get_attr_type (insn))
2335 {
2336 case TYPE_IMOVX:
2337 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2338 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2339 default:
2340 if (get_attr_mode (insn) == MODE_SI)
2341 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2342 else
2343 return "mov{b}\t{%1, %0|%0, %1}";
2344 }
2345 }
2346 [(set (attr "type")
2347 (cond [(and (eq_attr "alternative" "5")
2348 (not (match_operand:QI 1 "aligned_operand" "")))
2349 (const_string "imovx")
2350 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2351 (const_int 0))
2352 (const_string "imov")
2353 (and (eq_attr "alternative" "3")
2354 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2355 (const_int 0))
2356 (eq (symbol_ref "TARGET_QIMODE_MATH")
2357 (const_int 0))))
2358 (const_string "imov")
2359 (eq_attr "alternative" "3,5")
2360 (const_string "imovx")
2361 (and (ne (symbol_ref "TARGET_MOVX")
2362 (const_int 0))
2363 (eq_attr "alternative" "2"))
2364 (const_string "imovx")
2365 ]
2366 (const_string "imov")))
2367 (set (attr "mode")
2368 (cond [(eq_attr "alternative" "3,4,5")
2369 (const_string "SI")
2370 (eq_attr "alternative" "6")
2371 (const_string "QI")
2372 (eq_attr "type" "imovx")
2373 (const_string "SI")
2374 (and (eq_attr "type" "imov")
2375 (and (eq_attr "alternative" "0,1")
2376 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2377 (const_int 0))
2378 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2379 (const_int 0))
2380 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2381 (const_int 0))))))
2382 (const_string "SI")
2383 ;; Avoid partial register stalls when not using QImode arithmetic
2384 (and (eq_attr "type" "imov")
2385 (and (eq_attr "alternative" "0,1")
2386 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2387 (const_int 0))
2388 (eq (symbol_ref "TARGET_QIMODE_MATH")
2389 (const_int 0)))))
2390 (const_string "SI")
2391 ]
2392 (const_string "QI")))])
2393
2394 ;; Stores and loads of ax to arbitrary constant address.
2395 ;; We fake an second form of instruction to force reload to load address
2396 ;; into register when rax is not available
2397 (define_insn "*movabs<mode>_1"
2398 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2399 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2400 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2401 "@
2402 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2403 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2404 [(set_attr "type" "imov")
2405 (set_attr "modrm" "0,*")
2406 (set_attr "length_address" "8,0")
2407 (set_attr "length_immediate" "0,*")
2408 (set_attr "memory" "store")
2409 (set_attr "mode" "<MODE>")])
2410
2411 (define_insn "*movabs<mode>_2"
2412 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2413 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2414 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2415 "@
2416 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2417 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2418 [(set_attr "type" "imov")
2419 (set_attr "modrm" "0,*")
2420 (set_attr "length_address" "8,0")
2421 (set_attr "length_immediate" "0")
2422 (set_attr "memory" "load")
2423 (set_attr "mode" "<MODE>")])
2424
2425 (define_insn "*swap<mode>"
2426 [(set (match_operand:SWI48 0 "register_operand" "+r")
2427 (match_operand:SWI48 1 "register_operand" "+r"))
2428 (set (match_dup 1)
2429 (match_dup 0))]
2430 ""
2431 "xchg{<imodesuffix>}\t%1, %0"
2432 [(set_attr "type" "imov")
2433 (set_attr "mode" "<MODE>")
2434 (set_attr "pent_pair" "np")
2435 (set_attr "athlon_decode" "vector")
2436 (set_attr "amdfam10_decode" "double")
2437 (set_attr "bdver1_decode" "double")])
2438
2439 (define_insn "*swap<mode>_1"
2440 [(set (match_operand:SWI12 0 "register_operand" "+r")
2441 (match_operand:SWI12 1 "register_operand" "+r"))
2442 (set (match_dup 1)
2443 (match_dup 0))]
2444 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2445 "xchg{l}\t%k1, %k0"
2446 [(set_attr "type" "imov")
2447 (set_attr "mode" "SI")
2448 (set_attr "pent_pair" "np")
2449 (set_attr "athlon_decode" "vector")
2450 (set_attr "amdfam10_decode" "double")
2451 (set_attr "bdver1_decode" "double")])
2452
2453 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2454 ;; is disabled for AMDFAM10
2455 (define_insn "*swap<mode>_2"
2456 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2457 (match_operand:SWI12 1 "register_operand" "+<r>"))
2458 (set (match_dup 1)
2459 (match_dup 0))]
2460 "TARGET_PARTIAL_REG_STALL"
2461 "xchg{<imodesuffix>}\t%1, %0"
2462 [(set_attr "type" "imov")
2463 (set_attr "mode" "<MODE>")
2464 (set_attr "pent_pair" "np")
2465 (set_attr "athlon_decode" "vector")])
2466
2467 (define_expand "movstrict<mode>"
2468 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2469 (match_operand:SWI12 1 "general_operand" ""))]
2470 ""
2471 {
2472 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2473 FAIL;
2474 if (GET_CODE (operands[0]) == SUBREG
2475 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2476 FAIL;
2477 /* Don't generate memory->memory moves, go through a register */
2478 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2479 operands[1] = force_reg (<MODE>mode, operands[1]);
2480 })
2481
2482 (define_insn "*movstrict<mode>_1"
2483 [(set (strict_low_part
2484 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2485 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2486 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2487 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2488 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2489 [(set_attr "type" "imov")
2490 (set_attr "mode" "<MODE>")])
2491
2492 (define_insn "*movstrict<mode>_xor"
2493 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2494 (match_operand:SWI12 1 "const0_operand" ""))
2495 (clobber (reg:CC FLAGS_REG))]
2496 "reload_completed"
2497 "xor{<imodesuffix>}\t%0, %0"
2498 [(set_attr "type" "alu1")
2499 (set_attr "mode" "<MODE>")
2500 (set_attr "length_immediate" "0")])
2501
2502 (define_insn "*mov<mode>_extv_1"
2503 [(set (match_operand:SWI24 0 "register_operand" "=R")
2504 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2505 (const_int 8)
2506 (const_int 8)))]
2507 ""
2508 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2509 [(set_attr "type" "imovx")
2510 (set_attr "mode" "SI")])
2511
2512 (define_insn "*movqi_extv_1_rex64"
2513 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2514 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2515 (const_int 8)
2516 (const_int 8)))]
2517 "TARGET_64BIT"
2518 {
2519 switch (get_attr_type (insn))
2520 {
2521 case TYPE_IMOVX:
2522 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2523 default:
2524 return "mov{b}\t{%h1, %0|%0, %h1}";
2525 }
2526 }
2527 [(set (attr "type")
2528 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2529 (ne (symbol_ref "TARGET_MOVX")
2530 (const_int 0)))
2531 (const_string "imovx")
2532 (const_string "imov")))
2533 (set (attr "mode")
2534 (if_then_else (eq_attr "type" "imovx")
2535 (const_string "SI")
2536 (const_string "QI")))])
2537
2538 (define_insn "*movqi_extv_1"
2539 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2540 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2541 (const_int 8)
2542 (const_int 8)))]
2543 "!TARGET_64BIT"
2544 {
2545 switch (get_attr_type (insn))
2546 {
2547 case TYPE_IMOVX:
2548 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2549 default:
2550 return "mov{b}\t{%h1, %0|%0, %h1}";
2551 }
2552 }
2553 [(set (attr "type")
2554 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2555 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2556 (ne (symbol_ref "TARGET_MOVX")
2557 (const_int 0))))
2558 (const_string "imovx")
2559 (const_string "imov")))
2560 (set (attr "mode")
2561 (if_then_else (eq_attr "type" "imovx")
2562 (const_string "SI")
2563 (const_string "QI")))])
2564
2565 (define_insn "*mov<mode>_extzv_1"
2566 [(set (match_operand:SWI48 0 "register_operand" "=R")
2567 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2568 (const_int 8)
2569 (const_int 8)))]
2570 ""
2571 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2572 [(set_attr "type" "imovx")
2573 (set_attr "mode" "SI")])
2574
2575 (define_insn "*movqi_extzv_2_rex64"
2576 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2577 (subreg:QI
2578 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2579 (const_int 8)
2580 (const_int 8)) 0))]
2581 "TARGET_64BIT"
2582 {
2583 switch (get_attr_type (insn))
2584 {
2585 case TYPE_IMOVX:
2586 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2587 default:
2588 return "mov{b}\t{%h1, %0|%0, %h1}";
2589 }
2590 }
2591 [(set (attr "type")
2592 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2593 (ne (symbol_ref "TARGET_MOVX")
2594 (const_int 0)))
2595 (const_string "imovx")
2596 (const_string "imov")))
2597 (set (attr "mode")
2598 (if_then_else (eq_attr "type" "imovx")
2599 (const_string "SI")
2600 (const_string "QI")))])
2601
2602 (define_insn "*movqi_extzv_2"
2603 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2604 (subreg:QI
2605 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2606 (const_int 8)
2607 (const_int 8)) 0))]
2608 "!TARGET_64BIT"
2609 {
2610 switch (get_attr_type (insn))
2611 {
2612 case TYPE_IMOVX:
2613 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2614 default:
2615 return "mov{b}\t{%h1, %0|%0, %h1}";
2616 }
2617 }
2618 [(set (attr "type")
2619 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2620 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2621 (ne (symbol_ref "TARGET_MOVX")
2622 (const_int 0))))
2623 (const_string "imovx")
2624 (const_string "imov")))
2625 (set (attr "mode")
2626 (if_then_else (eq_attr "type" "imovx")
2627 (const_string "SI")
2628 (const_string "QI")))])
2629
2630 (define_expand "mov<mode>_insv_1"
2631 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2632 (const_int 8)
2633 (const_int 8))
2634 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2635
2636 (define_insn "*mov<mode>_insv_1_rex64"
2637 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2638 (const_int 8)
2639 (const_int 8))
2640 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2641 "TARGET_64BIT"
2642 "mov{b}\t{%b1, %h0|%h0, %b1}"
2643 [(set_attr "type" "imov")
2644 (set_attr "mode" "QI")])
2645
2646 (define_insn "*movsi_insv_1"
2647 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2648 (const_int 8)
2649 (const_int 8))
2650 (match_operand:SI 1 "general_operand" "Qmn"))]
2651 "!TARGET_64BIT"
2652 "mov{b}\t{%b1, %h0|%h0, %b1}"
2653 [(set_attr "type" "imov")
2654 (set_attr "mode" "QI")])
2655
2656 (define_insn "*movqi_insv_2"
2657 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2658 (const_int 8)
2659 (const_int 8))
2660 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2661 (const_int 8)))]
2662 ""
2663 "mov{b}\t{%h1, %h0|%h0, %h1}"
2664 [(set_attr "type" "imov")
2665 (set_attr "mode" "QI")])
2666 \f
2667 ;; Floating point push instructions.
2668
2669 (define_insn "*pushtf"
2670 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2671 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2672 "TARGET_SSE2"
2673 {
2674 /* This insn should be already split before reg-stack. */
2675 gcc_unreachable ();
2676 }
2677 [(set_attr "type" "multi")
2678 (set_attr "unit" "sse,*,*")
2679 (set_attr "mode" "TF,SI,SI")])
2680
2681 (define_split
2682 [(set (match_operand:TF 0 "push_operand" "")
2683 (match_operand:TF 1 "sse_reg_operand" ""))]
2684 "TARGET_SSE2 && reload_completed"
2685 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2686 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2687
2688 (define_split
2689 [(set (match_operand:TF 0 "push_operand" "")
2690 (match_operand:TF 1 "general_operand" ""))]
2691 "TARGET_SSE2 && reload_completed
2692 && !SSE_REG_P (operands[1])"
2693 [(const_int 0)]
2694 "ix86_split_long_move (operands); DONE;")
2695
2696 (define_insn "*pushxf"
2697 [(set (match_operand:XF 0 "push_operand" "=<,<")
2698 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2699 "optimize_function_for_speed_p (cfun)"
2700 {
2701 /* This insn should be already split before reg-stack. */
2702 gcc_unreachable ();
2703 }
2704 [(set_attr "type" "multi")
2705 (set_attr "unit" "i387,*")
2706 (set_attr "mode" "XF,SI")])
2707
2708 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2709 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2710 ;; Pushing using integer instructions is longer except for constants
2711 ;; and direct memory references (assuming that any given constant is pushed
2712 ;; only once, but this ought to be handled elsewhere).
2713
2714 (define_insn "*pushxf_nointeger"
2715 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2716 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2717 "optimize_function_for_size_p (cfun)"
2718 {
2719 /* This insn should be already split before reg-stack. */
2720 gcc_unreachable ();
2721 }
2722 [(set_attr "type" "multi")
2723 (set_attr "unit" "i387,*,*")
2724 (set_attr "mode" "XF,SI,SI")])
2725
2726 (define_split
2727 [(set (match_operand:XF 0 "push_operand" "")
2728 (match_operand:XF 1 "fp_register_operand" ""))]
2729 "reload_completed"
2730 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2731 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2732 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2733
2734 (define_split
2735 [(set (match_operand:XF 0 "push_operand" "")
2736 (match_operand:XF 1 "general_operand" ""))]
2737 "reload_completed
2738 && !FP_REG_P (operands[1])"
2739 [(const_int 0)]
2740 "ix86_split_long_move (operands); DONE;")
2741
2742 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2743 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2744 ;; On the average, pushdf using integers can be still shorter.
2745
2746 (define_insn "*pushdf"
2747 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2748 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2749 ""
2750 {
2751 /* This insn should be already split before reg-stack. */
2752 gcc_unreachable ();
2753 }
2754 [(set_attr "type" "multi")
2755 (set_attr "unit" "i387,*,*")
2756 (set_attr "mode" "DF,SI,DF")])
2757
2758 ;; %%% Kill this when call knows how to work this out.
2759 (define_split
2760 [(set (match_operand:DF 0 "push_operand" "")
2761 (match_operand:DF 1 "any_fp_register_operand" ""))]
2762 "reload_completed"
2763 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2764 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2765
2766 (define_split
2767 [(set (match_operand:DF 0 "push_operand" "")
2768 (match_operand:DF 1 "general_operand" ""))]
2769 "reload_completed
2770 && !ANY_FP_REG_P (operands[1])"
2771 [(const_int 0)]
2772 "ix86_split_long_move (operands); DONE;")
2773
2774 (define_insn "*pushsf_rex64"
2775 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2776 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2777 "TARGET_64BIT"
2778 {
2779 /* Anything else should be already split before reg-stack. */
2780 gcc_assert (which_alternative == 1);
2781 return "push{q}\t%q1";
2782 }
2783 [(set_attr "type" "multi,push,multi")
2784 (set_attr "unit" "i387,*,*")
2785 (set_attr "mode" "SF,DI,SF")])
2786
2787 (define_insn "*pushsf"
2788 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2789 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2790 "!TARGET_64BIT"
2791 {
2792 /* Anything else should be already split before reg-stack. */
2793 gcc_assert (which_alternative == 1);
2794 return "push{l}\t%1";
2795 }
2796 [(set_attr "type" "multi,push,multi")
2797 (set_attr "unit" "i387,*,*")
2798 (set_attr "mode" "SF,SI,SF")])
2799
2800 (define_split
2801 [(set (match_operand:SF 0 "push_operand" "")
2802 (match_operand:SF 1 "memory_operand" ""))]
2803 "reload_completed
2804 && MEM_P (operands[1])
2805 && (operands[2] = find_constant_src (insn))"
2806 [(set (match_dup 0)
2807 (match_dup 2))])
2808
2809 ;; %%% Kill this when call knows how to work this out.
2810 (define_split
2811 [(set (match_operand:SF 0 "push_operand" "")
2812 (match_operand:SF 1 "any_fp_register_operand" ""))]
2813 "reload_completed"
2814 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2815 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2816 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2817 \f
2818 ;; Floating point move instructions.
2819
2820 (define_expand "movtf"
2821 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2822 (match_operand:TF 1 "nonimmediate_operand" ""))]
2823 "TARGET_SSE2"
2824 {
2825 ix86_expand_move (TFmode, operands);
2826 DONE;
2827 })
2828
2829 (define_expand "mov<mode>"
2830 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2831 (match_operand:X87MODEF 1 "general_operand" ""))]
2832 ""
2833 "ix86_expand_move (<MODE>mode, operands); DONE;")
2834
2835 (define_insn "*movtf_internal"
2836 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2837 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2838 "TARGET_SSE2
2839 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2840 {
2841 switch (which_alternative)
2842 {
2843 case 0:
2844 case 1:
2845 if (get_attr_mode (insn) == MODE_V4SF)
2846 return "%vmovaps\t{%1, %0|%0, %1}";
2847 else
2848 return "%vmovdqa\t{%1, %0|%0, %1}";
2849
2850 case 2:
2851 return standard_sse_constant_opcode (insn, operands[1]);
2852
2853 case 3:
2854 case 4:
2855 return "#";
2856
2857 default:
2858 gcc_unreachable ();
2859 }
2860 }
2861 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2862 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2863 (set (attr "mode")
2864 (cond [(eq_attr "alternative" "0,2")
2865 (if_then_else
2866 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2867 (const_int 0))
2868 (const_string "V4SF")
2869 (const_string "TI"))
2870 (eq_attr "alternative" "1")
2871 (if_then_else
2872 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2873 (const_int 0))
2874 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2875 (const_int 0)))
2876 (const_string "V4SF")
2877 (const_string "TI"))]
2878 (const_string "DI")))])
2879
2880 (define_split
2881 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2882 (match_operand:TF 1 "general_operand" ""))]
2883 "reload_completed
2884 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2885 [(const_int 0)]
2886 "ix86_split_long_move (operands); DONE;")
2887
2888 (define_insn "*movxf_internal"
2889 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,Yx*r ,o")
2890 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2891 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2892 && (!can_create_pseudo_p ()
2893 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2894 || GET_CODE (operands[1]) != CONST_DOUBLE
2895 || (optimize_function_for_size_p (cfun)
2896 && standard_80387_constant_p (operands[1]) > 0)
2897 || memory_operand (operands[0], XFmode))"
2898 {
2899 switch (which_alternative)
2900 {
2901 case 0:
2902 case 1:
2903 return output_387_reg_move (insn, operands);
2904
2905 case 2:
2906 return standard_80387_constant_opcode (operands[1]);
2907
2908 case 3: case 4:
2909 return "#";
2910 default:
2911 gcc_unreachable ();
2912 }
2913 }
2914 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2915 (set_attr "mode" "XF,XF,XF,SI,SI")])
2916
2917 (define_split
2918 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2919 (match_operand:XF 1 "general_operand" ""))]
2920 "reload_completed
2921 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2922 && ! (FP_REG_P (operands[0]) ||
2923 (GET_CODE (operands[0]) == SUBREG
2924 && FP_REG_P (SUBREG_REG (operands[0]))))
2925 && ! (FP_REG_P (operands[1]) ||
2926 (GET_CODE (operands[1]) == SUBREG
2927 && FP_REG_P (SUBREG_REG (operands[1]))))"
2928 [(const_int 0)]
2929 "ix86_split_long_move (operands); DONE;")
2930
2931 (define_insn "*movdf_internal_rex64"
2932 [(set (match_operand:DF 0 "nonimmediate_operand"
2933 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2934 (match_operand:DF 1 "general_operand"
2935 "fm,f,G,rm,r,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2936 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2937 && (!can_create_pseudo_p ()
2938 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2939 || GET_CODE (operands[1]) != CONST_DOUBLE
2940 || (optimize_function_for_size_p (cfun)
2941 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2942 && standard_80387_constant_p (operands[1]) > 0)
2943 || (TARGET_SSE2 && TARGET_SSE_MATH
2944 && standard_sse_constant_p (operands[1]))))
2945 || memory_operand (operands[0], DFmode))"
2946 {
2947 switch (which_alternative)
2948 {
2949 case 0:
2950 case 1:
2951 return output_387_reg_move (insn, operands);
2952
2953 case 2:
2954 return standard_80387_constant_opcode (operands[1]);
2955
2956 case 3:
2957 case 4:
2958 return "mov{q}\t{%1, %0|%0, %1}";
2959
2960 case 5:
2961 return "movabs{q}\t{%1, %0|%0, %1}";
2962
2963 case 6:
2964 return "#";
2965
2966 case 7:
2967 return standard_sse_constant_opcode (insn, operands[1]);
2968
2969 case 8:
2970 case 9:
2971 case 10:
2972 switch (get_attr_mode (insn))
2973 {
2974 case MODE_V4SF:
2975 return "%vmovaps\t{%1, %0|%0, %1}";
2976 case MODE_V2DF:
2977 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2978 return "%vmovaps\t{%1, %0|%0, %1}";
2979 else
2980 return "%vmovapd\t{%1, %0|%0, %1}";
2981 case MODE_TI:
2982 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2983 return "%vmovaps\t{%1, %0|%0, %1}";
2984 else
2985 return "%vmovdqa\t{%1, %0|%0, %1}";
2986 case MODE_DI:
2987 return "%vmovq\t{%1, %0|%0, %1}";
2988 case MODE_DF:
2989 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2990 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2991 else
2992 return "%vmovsd\t{%1, %0|%0, %1}";
2993 case MODE_V1DF:
2994 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2995 case MODE_V2SF:
2996 return "%vmovlps\t{%1, %d0|%d0, %1}";
2997 default:
2998 gcc_unreachable ();
2999 }
3000
3001 case 11:
3002 case 12:
3003 /* Handle broken assemblers that require movd instead of movq. */
3004 return "%vmovd\t{%1, %0|%0, %1}";
3005
3006 default:
3007 gcc_unreachable();
3008 }
3009 }
3010 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3011 (set (attr "modrm")
3012 (if_then_else
3013 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3014 (const_string "0")
3015 (const_string "*")))
3016 (set (attr "length_immediate")
3017 (if_then_else
3018 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3019 (const_string "8")
3020 (const_string "*")))
3021 (set (attr "prefix")
3022 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3023 (const_string "orig")
3024 (const_string "maybe_vex")))
3025 (set (attr "prefix_data16")
3026 (if_then_else (eq_attr "mode" "V1DF")
3027 (const_string "1")
3028 (const_string "*")))
3029 (set (attr "mode")
3030 (cond [(eq_attr "alternative" "0,1,2")
3031 (const_string "DF")
3032 (eq_attr "alternative" "3,4,5,6,11,12")
3033 (const_string "DI")
3034
3035 /* For SSE1, we have many fewer alternatives. */
3036 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3037 (cond [(eq_attr "alternative" "7,8")
3038 (const_string "V4SF")
3039 ]
3040 (const_string "V2SF"))
3041
3042 /* xorps is one byte shorter. */
3043 (eq_attr "alternative" "7")
3044 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3045 (const_int 0))
3046 (const_string "V4SF")
3047 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3048 (const_int 0))
3049 (const_string "TI")
3050 ]
3051 (const_string "V2DF"))
3052
3053 /* For architectures resolving dependencies on
3054 whole SSE registers use APD move to break dependency
3055 chains, otherwise use short move to avoid extra work.
3056
3057 movaps encodes one byte shorter. */
3058 (eq_attr "alternative" "8")
3059 (cond
3060 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3061 (const_int 0))
3062 (const_string "V4SF")
3063 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3064 (const_int 0))
3065 (const_string "V2DF")
3066 ]
3067 (const_string "DF"))
3068 /* For architectures resolving dependencies on register
3069 parts we may avoid extra work to zero out upper part
3070 of register. */
3071 (eq_attr "alternative" "9")
3072 (if_then_else
3073 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3074 (const_int 0))
3075 (const_string "V1DF")
3076 (const_string "DF"))
3077 ]
3078 (const_string "DF")))])
3079
3080 ;; Possible store forwarding (partial memory) stall in alternative 4.
3081 (define_insn "*movdf_internal"
3082 [(set (match_operand:DF 0 "nonimmediate_operand"
3083 "=f,m,f,Yd*r ,o ,Y2*x,Y2*x,Y2*x,m ")
3084 (match_operand:DF 1 "general_operand"
3085 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3086 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3087 && (!can_create_pseudo_p ()
3088 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3089 || GET_CODE (operands[1]) != CONST_DOUBLE
3090 || (!TARGET_INTEGER_DFMODE_MOVES
3091 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3092 && standard_80387_constant_p (operands[1]) > 0)
3093 || (TARGET_SSE2 && TARGET_SSE_MATH
3094 && standard_sse_constant_p (operands[1])))
3095 && !memory_operand (operands[0], DFmode))
3096 || ((TARGET_INTEGER_DFMODE_MOVES
3097 || !TARGET_MEMORY_MISMATCH_STALL)
3098 && memory_operand (operands[0], DFmode)))"
3099 {
3100 switch (which_alternative)
3101 {
3102 case 0:
3103 case 1:
3104 return output_387_reg_move (insn, operands);
3105
3106 case 2:
3107 return standard_80387_constant_opcode (operands[1]);
3108
3109 case 3:
3110 case 4:
3111 return "#";
3112
3113 case 5:
3114 return standard_sse_constant_opcode (insn, operands[1]);
3115
3116 case 6:
3117 case 7:
3118 case 8:
3119 switch (get_attr_mode (insn))
3120 {
3121 case MODE_V4SF:
3122 return "%vmovaps\t{%1, %0|%0, %1}";
3123 case MODE_V2DF:
3124 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3125 return "%vmovaps\t{%1, %0|%0, %1}";
3126 else
3127 return "%vmovapd\t{%1, %0|%0, %1}";
3128 case MODE_TI:
3129 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3130 return "%vmovaps\t{%1, %0|%0, %1}";
3131 else
3132 return "%vmovdqa\t{%1, %0|%0, %1}";
3133 case MODE_DI:
3134 return "%vmovq\t{%1, %0|%0, %1}";
3135 case MODE_DF:
3136 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3137 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3138 else
3139 return "%vmovsd\t{%1, %0|%0, %1}";
3140 case MODE_V1DF:
3141 if (TARGET_AVX && REG_P (operands[0]))
3142 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3143 else
3144 return "%vmovlpd\t{%1, %0|%0, %1}";
3145 case MODE_V2SF:
3146 if (TARGET_AVX && REG_P (operands[0]))
3147 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3148 else
3149 return "%vmovlps\t{%1, %0|%0, %1}";
3150 default:
3151 gcc_unreachable ();
3152 }
3153
3154 default:
3155 gcc_unreachable ();
3156 }
3157 }
3158 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3159 (set (attr "prefix")
3160 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3161 (const_string "orig")
3162 (const_string "maybe_vex")))
3163 (set (attr "prefix_data16")
3164 (if_then_else (eq_attr "mode" "V1DF")
3165 (const_string "1")
3166 (const_string "*")))
3167 (set (attr "mode")
3168 (cond [(eq_attr "alternative" "0,1,2")
3169 (const_string "DF")
3170 (eq_attr "alternative" "3,4")
3171 (const_string "SI")
3172
3173 /* For SSE1, we have many fewer alternatives. */
3174 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3175 (cond [(eq_attr "alternative" "5,6")
3176 (const_string "V4SF")
3177 ]
3178 (const_string "V2SF"))
3179
3180 /* xorps is one byte shorter. */
3181 (eq_attr "alternative" "5")
3182 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3183 (const_int 0))
3184 (const_string "V4SF")
3185 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3186 (const_int 0))
3187 (const_string "TI")
3188 ]
3189 (const_string "V2DF"))
3190
3191 /* For architectures resolving dependencies on
3192 whole SSE registers use APD move to break dependency
3193 chains, otherwise use short move to avoid extra work.
3194
3195 movaps encodes one byte shorter. */
3196 (eq_attr "alternative" "6")
3197 (cond
3198 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3199 (const_int 0))
3200 (const_string "V4SF")
3201 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3202 (const_int 0))
3203 (const_string "V2DF")
3204 ]
3205 (const_string "DF"))
3206 /* For architectures resolving dependencies on register
3207 parts we may avoid extra work to zero out upper part
3208 of register. */
3209 (eq_attr "alternative" "7")
3210 (if_then_else
3211 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3212 (const_int 0))
3213 (const_string "V1DF")
3214 (const_string "DF"))
3215 ]
3216 (const_string "DF")))])
3217
3218 (define_split
3219 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3220 (match_operand:DF 1 "general_operand" ""))]
3221 "reload_completed
3222 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3223 && ! (ANY_FP_REG_P (operands[0]) ||
3224 (GET_CODE (operands[0]) == SUBREG
3225 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3226 && ! (ANY_FP_REG_P (operands[1]) ||
3227 (GET_CODE (operands[1]) == SUBREG
3228 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3229 [(const_int 0)]
3230 "ix86_split_long_move (operands); DONE;")
3231
3232 (define_insn "*movsf_internal"
3233 [(set (match_operand:SF 0 "nonimmediate_operand"
3234 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3235 (match_operand:SF 1 "general_operand"
3236 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3237 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3238 && (!can_create_pseudo_p ()
3239 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3240 || GET_CODE (operands[1]) != CONST_DOUBLE
3241 || (optimize_function_for_size_p (cfun)
3242 && ((!TARGET_SSE_MATH
3243 && standard_80387_constant_p (operands[1]) > 0)
3244 || (TARGET_SSE_MATH
3245 && standard_sse_constant_p (operands[1]))))
3246 || memory_operand (operands[0], SFmode))"
3247 {
3248 switch (which_alternative)
3249 {
3250 case 0:
3251 case 1:
3252 return output_387_reg_move (insn, operands);
3253
3254 case 2:
3255 return standard_80387_constant_opcode (operands[1]);
3256
3257 case 3:
3258 case 4:
3259 return "mov{l}\t{%1, %0|%0, %1}";
3260
3261 case 5:
3262 return standard_sse_constant_opcode (insn, operands[1]);
3263
3264 case 6:
3265 if (get_attr_mode (insn) == MODE_V4SF)
3266 return "%vmovaps\t{%1, %0|%0, %1}";
3267 else
3268 return "%vmovss\t{%1, %d0|%d0, %1}";
3269 case 7:
3270 if (TARGET_AVX && REG_P (operands[1]))
3271 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3272 else
3273 return "%vmovss\t{%1, %0|%0, %1}";
3274 case 8:
3275 return "%vmovss\t{%1, %0|%0, %1}";
3276
3277 case 9: case 10: case 14: case 15:
3278 return "movd\t{%1, %0|%0, %1}";
3279
3280 case 11:
3281 return "movq\t{%1, %0|%0, %1}";
3282
3283 case 12: case 13:
3284 return "%vmovd\t{%1, %0|%0, %1}";
3285
3286 default:
3287 gcc_unreachable ();
3288 }
3289 }
3290 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3291 (set (attr "prefix")
3292 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3293 (const_string "maybe_vex")
3294 (const_string "orig")))
3295 (set (attr "mode")
3296 (cond [(eq_attr "alternative" "3,4,9,10")
3297 (const_string "SI")
3298 (eq_attr "alternative" "5")
3299 (if_then_else
3300 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3301 (const_int 0))
3302 (ne (symbol_ref "TARGET_SSE2")
3303 (const_int 0)))
3304 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3305 (const_int 0)))
3306 (const_string "TI")
3307 (const_string "V4SF"))
3308 /* For architectures resolving dependencies on
3309 whole SSE registers use APS move to break dependency
3310 chains, otherwise use short move to avoid extra work.
3311
3312 Do the same for architectures resolving dependencies on
3313 the parts. While in DF mode it is better to always handle
3314 just register parts, the SF mode is different due to lack
3315 of instructions to load just part of the register. It is
3316 better to maintain the whole registers in single format
3317 to avoid problems on using packed logical operations. */
3318 (eq_attr "alternative" "6")
3319 (if_then_else
3320 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3321 (const_int 0))
3322 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3323 (const_int 0)))
3324 (const_string "V4SF")
3325 (const_string "SF"))
3326 (eq_attr "alternative" "11")
3327 (const_string "DI")]
3328 (const_string "SF")))])
3329
3330 (define_split
3331 [(set (match_operand 0 "register_operand" "")
3332 (match_operand 1 "memory_operand" ""))]
3333 "reload_completed
3334 && MEM_P (operands[1])
3335 && (GET_MODE (operands[0]) == TFmode
3336 || GET_MODE (operands[0]) == XFmode
3337 || GET_MODE (operands[0]) == DFmode
3338 || GET_MODE (operands[0]) == SFmode)
3339 && (operands[2] = find_constant_src (insn))"
3340 [(set (match_dup 0) (match_dup 2))]
3341 {
3342 rtx c = operands[2];
3343 rtx r = operands[0];
3344
3345 if (GET_CODE (r) == SUBREG)
3346 r = SUBREG_REG (r);
3347
3348 if (SSE_REG_P (r))
3349 {
3350 if (!standard_sse_constant_p (c))
3351 FAIL;
3352 }
3353 else if (FP_REG_P (r))
3354 {
3355 if (standard_80387_constant_p (c) < 1)
3356 FAIL;
3357 }
3358 else if (MMX_REG_P (r))
3359 FAIL;
3360 })
3361
3362 (define_split
3363 [(set (match_operand 0 "register_operand" "")
3364 (float_extend (match_operand 1 "memory_operand" "")))]
3365 "reload_completed
3366 && MEM_P (operands[1])
3367 && (GET_MODE (operands[0]) == TFmode
3368 || GET_MODE (operands[0]) == XFmode
3369 || GET_MODE (operands[0]) == DFmode
3370 || GET_MODE (operands[0]) == SFmode)
3371 && (operands[2] = find_constant_src (insn))"
3372 [(set (match_dup 0) (match_dup 2))]
3373 {
3374 rtx c = operands[2];
3375 rtx r = operands[0];
3376
3377 if (GET_CODE (r) == SUBREG)
3378 r = SUBREG_REG (r);
3379
3380 if (SSE_REG_P (r))
3381 {
3382 if (!standard_sse_constant_p (c))
3383 FAIL;
3384 }
3385 else if (FP_REG_P (r))
3386 {
3387 if (standard_80387_constant_p (c) < 1)
3388 FAIL;
3389 }
3390 else if (MMX_REG_P (r))
3391 FAIL;
3392 })
3393
3394 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3395 (define_split
3396 [(set (match_operand:X87MODEF 0 "register_operand" "")
3397 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3398 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3399 && (standard_80387_constant_p (operands[1]) == 8
3400 || standard_80387_constant_p (operands[1]) == 9)"
3401 [(set (match_dup 0)(match_dup 1))
3402 (set (match_dup 0)
3403 (neg:X87MODEF (match_dup 0)))]
3404 {
3405 REAL_VALUE_TYPE r;
3406
3407 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3408 if (real_isnegzero (&r))
3409 operands[1] = CONST0_RTX (<MODE>mode);
3410 else
3411 operands[1] = CONST1_RTX (<MODE>mode);
3412 })
3413
3414 (define_insn "swapxf"
3415 [(set (match_operand:XF 0 "register_operand" "+f")
3416 (match_operand:XF 1 "register_operand" "+f"))
3417 (set (match_dup 1)
3418 (match_dup 0))]
3419 "TARGET_80387"
3420 {
3421 if (STACK_TOP_P (operands[0]))
3422 return "fxch\t%1";
3423 else
3424 return "fxch\t%0";
3425 }
3426 [(set_attr "type" "fxch")
3427 (set_attr "mode" "XF")])
3428
3429 (define_insn "*swap<mode>"
3430 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3431 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3432 (set (match_dup 1)
3433 (match_dup 0))]
3434 "TARGET_80387 || reload_completed"
3435 {
3436 if (STACK_TOP_P (operands[0]))
3437 return "fxch\t%1";
3438 else
3439 return "fxch\t%0";
3440 }
3441 [(set_attr "type" "fxch")
3442 (set_attr "mode" "<MODE>")])
3443 \f
3444 ;; Zero extension instructions
3445
3446 (define_expand "zero_extendsidi2"
3447 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3448 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3449 ""
3450 {
3451 if (!TARGET_64BIT)
3452 {
3453 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3454 DONE;
3455 }
3456 })
3457
3458 (define_insn "*zero_extendsidi2_rex64"
3459 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3460 (zero_extend:DI
3461 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3462 "TARGET_64BIT"
3463 "@
3464 mov\t{%k1, %k0|%k0, %k1}
3465 #
3466 movd\t{%1, %0|%0, %1}
3467 movd\t{%1, %0|%0, %1}
3468 %vmovd\t{%1, %0|%0, %1}
3469 %vmovd\t{%1, %0|%0, %1}"
3470 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3471 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3472 (set_attr "prefix_0f" "0,*,*,*,*,*")
3473 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3474
3475 (define_split
3476 [(set (match_operand:DI 0 "memory_operand" "")
3477 (zero_extend:DI (match_dup 0)))]
3478 "TARGET_64BIT"
3479 [(set (match_dup 4) (const_int 0))]
3480 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3481
3482 ;; %%% Kill me once multi-word ops are sane.
3483 (define_insn "zero_extendsidi2_1"
3484 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3485 (zero_extend:DI
3486 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3487 (clobber (reg:CC FLAGS_REG))]
3488 "!TARGET_64BIT"
3489 "@
3490 #
3491 #
3492 #
3493 movd\t{%1, %0|%0, %1}
3494 movd\t{%1, %0|%0, %1}
3495 %vmovd\t{%1, %0|%0, %1}
3496 %vmovd\t{%1, %0|%0, %1}"
3497 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3498 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3499 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3500
3501 (define_split
3502 [(set (match_operand:DI 0 "register_operand" "")
3503 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3504 (clobber (reg:CC FLAGS_REG))]
3505 "!TARGET_64BIT && reload_completed
3506 && true_regnum (operands[0]) == true_regnum (operands[1])"
3507 [(set (match_dup 4) (const_int 0))]
3508 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3509
3510 (define_split
3511 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3512 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3513 (clobber (reg:CC FLAGS_REG))]
3514 "!TARGET_64BIT && reload_completed
3515 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3516 [(set (match_dup 3) (match_dup 1))
3517 (set (match_dup 4) (const_int 0))]
3518 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3519
3520 (define_insn "zero_extend<mode>di2"
3521 [(set (match_operand:DI 0 "register_operand" "=r")
3522 (zero_extend:DI
3523 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3524 "TARGET_64BIT"
3525 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3526 [(set_attr "type" "imovx")
3527 (set_attr "mode" "SI")])
3528
3529 (define_expand "zero_extendhisi2"
3530 [(set (match_operand:SI 0 "register_operand" "")
3531 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3532 ""
3533 {
3534 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3535 {
3536 operands[1] = force_reg (HImode, operands[1]);
3537 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3538 DONE;
3539 }
3540 })
3541
3542 (define_insn_and_split "zero_extendhisi2_and"
3543 [(set (match_operand:SI 0 "register_operand" "=r")
3544 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3545 (clobber (reg:CC FLAGS_REG))]
3546 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3547 "#"
3548 "&& reload_completed"
3549 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3550 (clobber (reg:CC FLAGS_REG))])]
3551 ""
3552 [(set_attr "type" "alu1")
3553 (set_attr "mode" "SI")])
3554
3555 (define_insn "*zero_extendhisi2_movzwl"
3556 [(set (match_operand:SI 0 "register_operand" "=r")
3557 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3558 "!TARGET_ZERO_EXTEND_WITH_AND
3559 || optimize_function_for_size_p (cfun)"
3560 "movz{wl|x}\t{%1, %0|%0, %1}"
3561 [(set_attr "type" "imovx")
3562 (set_attr "mode" "SI")])
3563
3564 (define_expand "zero_extendqi<mode>2"
3565 [(parallel
3566 [(set (match_operand:SWI24 0 "register_operand" "")
3567 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3568 (clobber (reg:CC FLAGS_REG))])])
3569
3570 (define_insn "*zero_extendqi<mode>2_and"
3571 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3572 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3573 (clobber (reg:CC FLAGS_REG))]
3574 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3575 "#"
3576 [(set_attr "type" "alu1")
3577 (set_attr "mode" "<MODE>")])
3578
3579 ;; When source and destination does not overlap, clear destination
3580 ;; first and then do the movb
3581 (define_split
3582 [(set (match_operand:SWI24 0 "register_operand" "")
3583 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3584 (clobber (reg:CC FLAGS_REG))]
3585 "reload_completed
3586 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3587 && ANY_QI_REG_P (operands[0])
3588 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3589 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3590 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3591 {
3592 operands[2] = gen_lowpart (QImode, operands[0]);
3593 ix86_expand_clear (operands[0]);
3594 })
3595
3596 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3597 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3598 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3599 (clobber (reg:CC FLAGS_REG))]
3600 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3601 "#"
3602 [(set_attr "type" "imovx,alu1")
3603 (set_attr "mode" "<MODE>")])
3604
3605 ;; For the movzbl case strip only the clobber
3606 (define_split
3607 [(set (match_operand:SWI24 0 "register_operand" "")
3608 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3609 (clobber (reg:CC FLAGS_REG))]
3610 "reload_completed
3611 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3612 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3613 [(set (match_dup 0)
3614 (zero_extend:SWI24 (match_dup 1)))])
3615
3616 ; zero extend to SImode to avoid partial register stalls
3617 (define_insn "*zero_extendqi<mode>2_movzbl"
3618 [(set (match_operand:SWI24 0 "register_operand" "=r")
3619 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3620 "reload_completed
3621 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3622 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3623 [(set_attr "type" "imovx")
3624 (set_attr "mode" "SI")])
3625
3626 ;; Rest is handled by single and.
3627 (define_split
3628 [(set (match_operand:SWI24 0 "register_operand" "")
3629 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3630 (clobber (reg:CC FLAGS_REG))]
3631 "reload_completed
3632 && true_regnum (operands[0]) == true_regnum (operands[1])"
3633 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3634 (clobber (reg:CC FLAGS_REG))])])
3635 \f
3636 ;; Sign extension instructions
3637
3638 (define_expand "extendsidi2"
3639 [(set (match_operand:DI 0 "register_operand" "")
3640 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3641 ""
3642 {
3643 if (!TARGET_64BIT)
3644 {
3645 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3646 DONE;
3647 }
3648 })
3649
3650 (define_insn "*extendsidi2_rex64"
3651 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3652 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3653 "TARGET_64BIT"
3654 "@
3655 {cltq|cdqe}
3656 movs{lq|x}\t{%1, %0|%0, %1}"
3657 [(set_attr "type" "imovx")
3658 (set_attr "mode" "DI")
3659 (set_attr "prefix_0f" "0")
3660 (set_attr "modrm" "0,1")])
3661
3662 (define_insn "extendsidi2_1"
3663 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3664 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3665 (clobber (reg:CC FLAGS_REG))
3666 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3667 "!TARGET_64BIT"
3668 "#")
3669
3670 ;; Extend to memory case when source register does die.
3671 (define_split
3672 [(set (match_operand:DI 0 "memory_operand" "")
3673 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3674 (clobber (reg:CC FLAGS_REG))
3675 (clobber (match_operand:SI 2 "register_operand" ""))]
3676 "(reload_completed
3677 && dead_or_set_p (insn, operands[1])
3678 && !reg_mentioned_p (operands[1], operands[0]))"
3679 [(set (match_dup 3) (match_dup 1))
3680 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3681 (clobber (reg:CC FLAGS_REG))])
3682 (set (match_dup 4) (match_dup 1))]
3683 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3684
3685 ;; Extend to memory case when source register does not die.
3686 (define_split
3687 [(set (match_operand:DI 0 "memory_operand" "")
3688 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3689 (clobber (reg:CC FLAGS_REG))
3690 (clobber (match_operand:SI 2 "register_operand" ""))]
3691 "reload_completed"
3692 [(const_int 0)]
3693 {
3694 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3695
3696 emit_move_insn (operands[3], operands[1]);
3697
3698 /* Generate a cltd if possible and doing so it profitable. */
3699 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3700 && true_regnum (operands[1]) == AX_REG
3701 && true_regnum (operands[2]) == DX_REG)
3702 {
3703 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3704 }
3705 else
3706 {
3707 emit_move_insn (operands[2], operands[1]);
3708 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3709 }
3710 emit_move_insn (operands[4], operands[2]);
3711 DONE;
3712 })
3713
3714 ;; Extend to register case. Optimize case where source and destination
3715 ;; registers match and cases where we can use cltd.
3716 (define_split
3717 [(set (match_operand:DI 0 "register_operand" "")
3718 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3719 (clobber (reg:CC FLAGS_REG))
3720 (clobber (match_scratch:SI 2 ""))]
3721 "reload_completed"
3722 [(const_int 0)]
3723 {
3724 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3725
3726 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3727 emit_move_insn (operands[3], operands[1]);
3728
3729 /* Generate a cltd if possible and doing so it profitable. */
3730 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3731 && true_regnum (operands[3]) == AX_REG
3732 && true_regnum (operands[4]) == DX_REG)
3733 {
3734 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3735 DONE;
3736 }
3737
3738 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3739 emit_move_insn (operands[4], operands[1]);
3740
3741 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3742 DONE;
3743 })
3744
3745 (define_insn "extend<mode>di2"
3746 [(set (match_operand:DI 0 "register_operand" "=r")
3747 (sign_extend:DI
3748 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3749 "TARGET_64BIT"
3750 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3751 [(set_attr "type" "imovx")
3752 (set_attr "mode" "DI")])
3753
3754 (define_insn "extendhisi2"
3755 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3756 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3757 ""
3758 {
3759 switch (get_attr_prefix_0f (insn))
3760 {
3761 case 0:
3762 return "{cwtl|cwde}";
3763 default:
3764 return "movs{wl|x}\t{%1, %0|%0, %1}";
3765 }
3766 }
3767 [(set_attr "type" "imovx")
3768 (set_attr "mode" "SI")
3769 (set (attr "prefix_0f")
3770 ;; movsx is short decodable while cwtl is vector decoded.
3771 (if_then_else (and (eq_attr "cpu" "!k6")
3772 (eq_attr "alternative" "0"))
3773 (const_string "0")
3774 (const_string "1")))
3775 (set (attr "modrm")
3776 (if_then_else (eq_attr "prefix_0f" "0")
3777 (const_string "0")
3778 (const_string "1")))])
3779
3780 (define_insn "*extendhisi2_zext"
3781 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3782 (zero_extend:DI
3783 (sign_extend:SI
3784 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3785 "TARGET_64BIT"
3786 {
3787 switch (get_attr_prefix_0f (insn))
3788 {
3789 case 0:
3790 return "{cwtl|cwde}";
3791 default:
3792 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3793 }
3794 }
3795 [(set_attr "type" "imovx")
3796 (set_attr "mode" "SI")
3797 (set (attr "prefix_0f")
3798 ;; movsx is short decodable while cwtl is vector decoded.
3799 (if_then_else (and (eq_attr "cpu" "!k6")
3800 (eq_attr "alternative" "0"))
3801 (const_string "0")
3802 (const_string "1")))
3803 (set (attr "modrm")
3804 (if_then_else (eq_attr "prefix_0f" "0")
3805 (const_string "0")
3806 (const_string "1")))])
3807
3808 (define_insn "extendqisi2"
3809 [(set (match_operand:SI 0 "register_operand" "=r")
3810 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3811 ""
3812 "movs{bl|x}\t{%1, %0|%0, %1}"
3813 [(set_attr "type" "imovx")
3814 (set_attr "mode" "SI")])
3815
3816 (define_insn "*extendqisi2_zext"
3817 [(set (match_operand:DI 0 "register_operand" "=r")
3818 (zero_extend:DI
3819 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3820 "TARGET_64BIT"
3821 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3822 [(set_attr "type" "imovx")
3823 (set_attr "mode" "SI")])
3824
3825 (define_insn "extendqihi2"
3826 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3827 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3828 ""
3829 {
3830 switch (get_attr_prefix_0f (insn))
3831 {
3832 case 0:
3833 return "{cbtw|cbw}";
3834 default:
3835 return "movs{bw|x}\t{%1, %0|%0, %1}";
3836 }
3837 }
3838 [(set_attr "type" "imovx")
3839 (set_attr "mode" "HI")
3840 (set (attr "prefix_0f")
3841 ;; movsx is short decodable while cwtl is vector decoded.
3842 (if_then_else (and (eq_attr "cpu" "!k6")
3843 (eq_attr "alternative" "0"))
3844 (const_string "0")
3845 (const_string "1")))
3846 (set (attr "modrm")
3847 (if_then_else (eq_attr "prefix_0f" "0")
3848 (const_string "0")
3849 (const_string "1")))])
3850 \f
3851 ;; Conversions between float and double.
3852
3853 ;; These are all no-ops in the model used for the 80387.
3854 ;; So just emit moves.
3855
3856 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3857 (define_split
3858 [(set (match_operand:DF 0 "push_operand" "")
3859 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3860 "reload_completed"
3861 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3862 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3863
3864 (define_split
3865 [(set (match_operand:XF 0 "push_operand" "")
3866 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3867 "reload_completed"
3868 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3869 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3870 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3871
3872 (define_expand "extendsfdf2"
3873 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3874 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3875 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3876 {
3877 /* ??? Needed for compress_float_constant since all fp constants
3878 are TARGET_LEGITIMATE_CONSTANT_P. */
3879 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3880 {
3881 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3882 && standard_80387_constant_p (operands[1]) > 0)
3883 {
3884 operands[1] = simplify_const_unary_operation
3885 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3886 emit_move_insn_1 (operands[0], operands[1]);
3887 DONE;
3888 }
3889 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3890 }
3891 })
3892
3893 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3894 cvtss2sd:
3895 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3896 cvtps2pd xmm2,xmm1
3897 We do the conversion post reload to avoid producing of 128bit spills
3898 that might lead to ICE on 32bit target. The sequence unlikely combine
3899 anyway. */
3900 (define_split
3901 [(set (match_operand:DF 0 "register_operand" "")
3902 (float_extend:DF
3903 (match_operand:SF 1 "nonimmediate_operand" "")))]
3904 "TARGET_USE_VECTOR_FP_CONVERTS
3905 && optimize_insn_for_speed_p ()
3906 && reload_completed && SSE_REG_P (operands[0])"
3907 [(set (match_dup 2)
3908 (float_extend:V2DF
3909 (vec_select:V2SF
3910 (match_dup 3)
3911 (parallel [(const_int 0) (const_int 1)]))))]
3912 {
3913 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3914 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3915 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3916 Try to avoid move when unpacking can be done in source. */
3917 if (REG_P (operands[1]))
3918 {
3919 /* If it is unsafe to overwrite upper half of source, we need
3920 to move to destination and unpack there. */
3921 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3922 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3923 && true_regnum (operands[0]) != true_regnum (operands[1]))
3924 {
3925 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3926 emit_move_insn (tmp, operands[1]);
3927 }
3928 else
3929 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3930 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3931 operands[3]));
3932 }
3933 else
3934 emit_insn (gen_vec_setv4sf_0 (operands[3],
3935 CONST0_RTX (V4SFmode), operands[1]));
3936 })
3937
3938 (define_insn "*extendsfdf2_mixed"
3939 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3940 (float_extend:DF
3941 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3942 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3943 {
3944 switch (which_alternative)
3945 {
3946 case 0:
3947 case 1:
3948 return output_387_reg_move (insn, operands);
3949
3950 case 2:
3951 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3952
3953 default:
3954 gcc_unreachable ();
3955 }
3956 }
3957 [(set_attr "type" "fmov,fmov,ssecvt")
3958 (set_attr "prefix" "orig,orig,maybe_vex")
3959 (set_attr "mode" "SF,XF,DF")])
3960
3961 (define_insn "*extendsfdf2_sse"
3962 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3963 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3964 "TARGET_SSE2 && TARGET_SSE_MATH"
3965 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3966 [(set_attr "type" "ssecvt")
3967 (set_attr "prefix" "maybe_vex")
3968 (set_attr "mode" "DF")])
3969
3970 (define_insn "*extendsfdf2_i387"
3971 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3972 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3973 "TARGET_80387"
3974 "* return output_387_reg_move (insn, operands);"
3975 [(set_attr "type" "fmov")
3976 (set_attr "mode" "SF,XF")])
3977
3978 (define_expand "extend<mode>xf2"
3979 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3980 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3981 "TARGET_80387"
3982 {
3983 /* ??? Needed for compress_float_constant since all fp constants
3984 are TARGET_LEGITIMATE_CONSTANT_P. */
3985 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3986 {
3987 if (standard_80387_constant_p (operands[1]) > 0)
3988 {
3989 operands[1] = simplify_const_unary_operation
3990 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3991 emit_move_insn_1 (operands[0], operands[1]);
3992 DONE;
3993 }
3994 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3995 }
3996 })
3997
3998 (define_insn "*extend<mode>xf2_i387"
3999 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4000 (float_extend:XF
4001 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4002 "TARGET_80387"
4003 "* return output_387_reg_move (insn, operands);"
4004 [(set_attr "type" "fmov")
4005 (set_attr "mode" "<MODE>,XF")])
4006
4007 ;; %%% This seems bad bad news.
4008 ;; This cannot output into an f-reg because there is no way to be sure
4009 ;; of truncating in that case. Otherwise this is just like a simple move
4010 ;; insn. So we pretend we can output to a reg in order to get better
4011 ;; register preferencing, but we really use a stack slot.
4012
4013 ;; Conversion from DFmode to SFmode.
4014
4015 (define_expand "truncdfsf2"
4016 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4017 (float_truncate:SF
4018 (match_operand:DF 1 "nonimmediate_operand" "")))]
4019 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4020 {
4021 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4022 ;
4023 else if (flag_unsafe_math_optimizations)
4024 ;
4025 else
4026 {
4027 enum ix86_stack_slot slot = (virtuals_instantiated
4028 ? SLOT_TEMP
4029 : SLOT_VIRTUAL);
4030 rtx temp = assign_386_stack_local (SFmode, slot);
4031 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4032 DONE;
4033 }
4034 })
4035
4036 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4037 cvtsd2ss:
4038 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4039 cvtpd2ps xmm2,xmm1
4040 We do the conversion post reload to avoid producing of 128bit spills
4041 that might lead to ICE on 32bit target. The sequence unlikely combine
4042 anyway. */
4043 (define_split
4044 [(set (match_operand:SF 0 "register_operand" "")
4045 (float_truncate:SF
4046 (match_operand:DF 1 "nonimmediate_operand" "")))]
4047 "TARGET_USE_VECTOR_FP_CONVERTS
4048 && optimize_insn_for_speed_p ()
4049 && reload_completed && SSE_REG_P (operands[0])"
4050 [(set (match_dup 2)
4051 (vec_concat:V4SF
4052 (float_truncate:V2SF
4053 (match_dup 4))
4054 (match_dup 3)))]
4055 {
4056 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4057 operands[3] = CONST0_RTX (V2SFmode);
4058 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4059 /* Use movsd for loading from memory, unpcklpd for registers.
4060 Try to avoid move when unpacking can be done in source, or SSE3
4061 movddup is available. */
4062 if (REG_P (operands[1]))
4063 {
4064 if (!TARGET_SSE3
4065 && true_regnum (operands[0]) != true_regnum (operands[1])
4066 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4067 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4068 {
4069 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4070 emit_move_insn (tmp, operands[1]);
4071 operands[1] = tmp;
4072 }
4073 else if (!TARGET_SSE3)
4074 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4075 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4076 }
4077 else
4078 emit_insn (gen_sse2_loadlpd (operands[4],
4079 CONST0_RTX (V2DFmode), operands[1]));
4080 })
4081
4082 (define_expand "truncdfsf2_with_temp"
4083 [(parallel [(set (match_operand:SF 0 "" "")
4084 (float_truncate:SF (match_operand:DF 1 "" "")))
4085 (clobber (match_operand:SF 2 "" ""))])])
4086
4087 (define_insn "*truncdfsf_fast_mixed"
4088 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4089 (float_truncate:SF
4090 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4091 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4092 {
4093 switch (which_alternative)
4094 {
4095 case 0:
4096 return output_387_reg_move (insn, operands);
4097 case 1:
4098 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4099 default:
4100 gcc_unreachable ();
4101 }
4102 }
4103 [(set_attr "type" "fmov,ssecvt")
4104 (set_attr "prefix" "orig,maybe_vex")
4105 (set_attr "mode" "SF")])
4106
4107 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4108 ;; because nothing we do here is unsafe.
4109 (define_insn "*truncdfsf_fast_sse"
4110 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4111 (float_truncate:SF
4112 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4113 "TARGET_SSE2 && TARGET_SSE_MATH"
4114 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4115 [(set_attr "type" "ssecvt")
4116 (set_attr "prefix" "maybe_vex")
4117 (set_attr "mode" "SF")])
4118
4119 (define_insn "*truncdfsf_fast_i387"
4120 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4121 (float_truncate:SF
4122 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4123 "TARGET_80387 && flag_unsafe_math_optimizations"
4124 "* return output_387_reg_move (insn, operands);"
4125 [(set_attr "type" "fmov")
4126 (set_attr "mode" "SF")])
4127
4128 (define_insn "*truncdfsf_mixed"
4129 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4130 (float_truncate:SF
4131 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4132 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4133 "TARGET_MIX_SSE_I387"
4134 {
4135 switch (which_alternative)
4136 {
4137 case 0:
4138 return output_387_reg_move (insn, operands);
4139 case 1:
4140 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4141
4142 default:
4143 return "#";
4144 }
4145 }
4146 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4147 (set_attr "unit" "*,*,i387,i387,i387")
4148 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4149 (set_attr "mode" "SF")])
4150
4151 (define_insn "*truncdfsf_i387"
4152 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4153 (float_truncate:SF
4154 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4155 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4156 "TARGET_80387"
4157 {
4158 switch (which_alternative)
4159 {
4160 case 0:
4161 return output_387_reg_move (insn, operands);
4162
4163 default:
4164 return "#";
4165 }
4166 }
4167 [(set_attr "type" "fmov,multi,multi,multi")
4168 (set_attr "unit" "*,i387,i387,i387")
4169 (set_attr "mode" "SF")])
4170
4171 (define_insn "*truncdfsf2_i387_1"
4172 [(set (match_operand:SF 0 "memory_operand" "=m")
4173 (float_truncate:SF
4174 (match_operand:DF 1 "register_operand" "f")))]
4175 "TARGET_80387
4176 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4177 && !TARGET_MIX_SSE_I387"
4178 "* return output_387_reg_move (insn, operands);"
4179 [(set_attr "type" "fmov")
4180 (set_attr "mode" "SF")])
4181
4182 (define_split
4183 [(set (match_operand:SF 0 "register_operand" "")
4184 (float_truncate:SF
4185 (match_operand:DF 1 "fp_register_operand" "")))
4186 (clobber (match_operand 2 "" ""))]
4187 "reload_completed"
4188 [(set (match_dup 2) (match_dup 1))
4189 (set (match_dup 0) (match_dup 2))]
4190 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4191
4192 ;; Conversion from XFmode to {SF,DF}mode
4193
4194 (define_expand "truncxf<mode>2"
4195 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4196 (float_truncate:MODEF
4197 (match_operand:XF 1 "register_operand" "")))
4198 (clobber (match_dup 2))])]
4199 "TARGET_80387"
4200 {
4201 if (flag_unsafe_math_optimizations)
4202 {
4203 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4204 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4205 if (reg != operands[0])
4206 emit_move_insn (operands[0], reg);
4207 DONE;
4208 }
4209 else
4210 {
4211 enum ix86_stack_slot slot = (virtuals_instantiated
4212 ? SLOT_TEMP
4213 : SLOT_VIRTUAL);
4214 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4215 }
4216 })
4217
4218 (define_insn "*truncxfsf2_mixed"
4219 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4220 (float_truncate:SF
4221 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4222 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4223 "TARGET_80387"
4224 {
4225 gcc_assert (!which_alternative);
4226 return output_387_reg_move (insn, operands);
4227 }
4228 [(set_attr "type" "fmov,multi,multi,multi")
4229 (set_attr "unit" "*,i387,i387,i387")
4230 (set_attr "mode" "SF")])
4231
4232 (define_insn "*truncxfdf2_mixed"
4233 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4234 (float_truncate:DF
4235 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4236 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4237 "TARGET_80387"
4238 {
4239 gcc_assert (!which_alternative);
4240 return output_387_reg_move (insn, operands);
4241 }
4242 [(set_attr "type" "fmov,multi,multi,multi")
4243 (set_attr "unit" "*,i387,i387,i387")
4244 (set_attr "mode" "DF")])
4245
4246 (define_insn "truncxf<mode>2_i387_noop"
4247 [(set (match_operand:MODEF 0 "register_operand" "=f")
4248 (float_truncate:MODEF
4249 (match_operand:XF 1 "register_operand" "f")))]
4250 "TARGET_80387 && flag_unsafe_math_optimizations"
4251 "* return output_387_reg_move (insn, operands);"
4252 [(set_attr "type" "fmov")
4253 (set_attr "mode" "<MODE>")])
4254
4255 (define_insn "*truncxf<mode>2_i387"
4256 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4257 (float_truncate:MODEF
4258 (match_operand:XF 1 "register_operand" "f")))]
4259 "TARGET_80387"
4260 "* return output_387_reg_move (insn, operands);"
4261 [(set_attr "type" "fmov")
4262 (set_attr "mode" "<MODE>")])
4263
4264 (define_split
4265 [(set (match_operand:MODEF 0 "register_operand" "")
4266 (float_truncate:MODEF
4267 (match_operand:XF 1 "register_operand" "")))
4268 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4269 "TARGET_80387 && reload_completed"
4270 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4271 (set (match_dup 0) (match_dup 2))])
4272
4273 (define_split
4274 [(set (match_operand:MODEF 0 "memory_operand" "")
4275 (float_truncate:MODEF
4276 (match_operand:XF 1 "register_operand" "")))
4277 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4278 "TARGET_80387"
4279 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4280 \f
4281 ;; Signed conversion to DImode.
4282
4283 (define_expand "fix_truncxfdi2"
4284 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4285 (fix:DI (match_operand:XF 1 "register_operand" "")))
4286 (clobber (reg:CC FLAGS_REG))])]
4287 "TARGET_80387"
4288 {
4289 if (TARGET_FISTTP)
4290 {
4291 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4292 DONE;
4293 }
4294 })
4295
4296 (define_expand "fix_trunc<mode>di2"
4297 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4298 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4299 (clobber (reg:CC FLAGS_REG))])]
4300 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4301 {
4302 if (TARGET_FISTTP
4303 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4304 {
4305 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4306 DONE;
4307 }
4308 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4309 {
4310 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4311 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4312 if (out != operands[0])
4313 emit_move_insn (operands[0], out);
4314 DONE;
4315 }
4316 })
4317
4318 ;; Signed conversion to SImode.
4319
4320 (define_expand "fix_truncxfsi2"
4321 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4322 (fix:SI (match_operand:XF 1 "register_operand" "")))
4323 (clobber (reg:CC FLAGS_REG))])]
4324 "TARGET_80387"
4325 {
4326 if (TARGET_FISTTP)
4327 {
4328 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4329 DONE;
4330 }
4331 })
4332
4333 (define_expand "fix_trunc<mode>si2"
4334 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4335 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4336 (clobber (reg:CC FLAGS_REG))])]
4337 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4338 {
4339 if (TARGET_FISTTP
4340 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4341 {
4342 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4343 DONE;
4344 }
4345 if (SSE_FLOAT_MODE_P (<MODE>mode))
4346 {
4347 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4348 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4349 if (out != operands[0])
4350 emit_move_insn (operands[0], out);
4351 DONE;
4352 }
4353 })
4354
4355 ;; Signed conversion to HImode.
4356
4357 (define_expand "fix_trunc<mode>hi2"
4358 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4359 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4360 (clobber (reg:CC FLAGS_REG))])]
4361 "TARGET_80387
4362 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4363 {
4364 if (TARGET_FISTTP)
4365 {
4366 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4367 DONE;
4368 }
4369 })
4370
4371 ;; Unsigned conversion to SImode.
4372
4373 (define_expand "fixuns_trunc<mode>si2"
4374 [(parallel
4375 [(set (match_operand:SI 0 "register_operand" "")
4376 (unsigned_fix:SI
4377 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4378 (use (match_dup 2))
4379 (clobber (match_scratch:<ssevecmode> 3 ""))
4380 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4381 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4382 {
4383 enum machine_mode mode = <MODE>mode;
4384 enum machine_mode vecmode = <ssevecmode>mode;
4385 REAL_VALUE_TYPE TWO31r;
4386 rtx two31;
4387
4388 if (optimize_insn_for_size_p ())
4389 FAIL;
4390
4391 real_ldexp (&TWO31r, &dconst1, 31);
4392 two31 = const_double_from_real_value (TWO31r, mode);
4393 two31 = ix86_build_const_vector (vecmode, true, two31);
4394 operands[2] = force_reg (vecmode, two31);
4395 })
4396
4397 (define_insn_and_split "*fixuns_trunc<mode>_1"
4398 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4399 (unsigned_fix:SI
4400 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4401 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4402 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4403 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4404 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4405 && optimize_function_for_speed_p (cfun)"
4406 "#"
4407 "&& reload_completed"
4408 [(const_int 0)]
4409 {
4410 ix86_split_convert_uns_si_sse (operands);
4411 DONE;
4412 })
4413
4414 ;; Unsigned conversion to HImode.
4415 ;; Without these patterns, we'll try the unsigned SI conversion which
4416 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4417
4418 (define_expand "fixuns_trunc<mode>hi2"
4419 [(set (match_dup 2)
4420 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4421 (set (match_operand:HI 0 "nonimmediate_operand" "")
4422 (subreg:HI (match_dup 2) 0))]
4423 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4424 "operands[2] = gen_reg_rtx (SImode);")
4425
4426 ;; When SSE is available, it is always faster to use it!
4427 (define_insn "fix_trunc<mode>di_sse"
4428 [(set (match_operand:DI 0 "register_operand" "=r,r")
4429 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4430 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4431 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4432 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4433 [(set_attr "type" "sseicvt")
4434 (set_attr "prefix" "maybe_vex")
4435 (set_attr "prefix_rex" "1")
4436 (set_attr "mode" "<MODE>")
4437 (set_attr "athlon_decode" "double,vector")
4438 (set_attr "amdfam10_decode" "double,double")
4439 (set_attr "bdver1_decode" "double,double")])
4440
4441 (define_insn "fix_trunc<mode>si_sse"
4442 [(set (match_operand:SI 0 "register_operand" "=r,r")
4443 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4444 "SSE_FLOAT_MODE_P (<MODE>mode)
4445 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4446 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4447 [(set_attr "type" "sseicvt")
4448 (set_attr "prefix" "maybe_vex")
4449 (set_attr "mode" "<MODE>")
4450 (set_attr "athlon_decode" "double,vector")
4451 (set_attr "amdfam10_decode" "double,double")
4452 (set_attr "bdver1_decode" "double,double")])
4453
4454 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4455 (define_peephole2
4456 [(set (match_operand:MODEF 0 "register_operand" "")
4457 (match_operand:MODEF 1 "memory_operand" ""))
4458 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4459 (fix:SSEMODEI24 (match_dup 0)))]
4460 "TARGET_SHORTEN_X87_SSE
4461 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4462 && peep2_reg_dead_p (2, operands[0])"
4463 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4464
4465 ;; Avoid vector decoded forms of the instruction.
4466 (define_peephole2
4467 [(match_scratch:DF 2 "Y2")
4468 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4469 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4470 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4471 [(set (match_dup 2) (match_dup 1))
4472 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4473
4474 (define_peephole2
4475 [(match_scratch:SF 2 "x")
4476 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4477 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4478 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4479 [(set (match_dup 2) (match_dup 1))
4480 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4481
4482 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4483 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4484 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4485 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4486 && TARGET_FISTTP
4487 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4488 && (TARGET_64BIT || <MODE>mode != DImode))
4489 && TARGET_SSE_MATH)
4490 && can_create_pseudo_p ()"
4491 "#"
4492 "&& 1"
4493 [(const_int 0)]
4494 {
4495 if (memory_operand (operands[0], VOIDmode))
4496 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4497 else
4498 {
4499 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4500 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4501 operands[1],
4502 operands[2]));
4503 }
4504 DONE;
4505 }
4506 [(set_attr "type" "fisttp")
4507 (set_attr "mode" "<MODE>")])
4508
4509 (define_insn "fix_trunc<mode>_i387_fisttp"
4510 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4511 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4512 (clobber (match_scratch:XF 2 "=&1f"))]
4513 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4514 && TARGET_FISTTP
4515 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4516 && (TARGET_64BIT || <MODE>mode != DImode))
4517 && TARGET_SSE_MATH)"
4518 "* return output_fix_trunc (insn, operands, true);"
4519 [(set_attr "type" "fisttp")
4520 (set_attr "mode" "<MODE>")])
4521
4522 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4523 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4524 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4525 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4526 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4527 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528 && TARGET_FISTTP
4529 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4530 && (TARGET_64BIT || <MODE>mode != DImode))
4531 && TARGET_SSE_MATH)"
4532 "#"
4533 [(set_attr "type" "fisttp")
4534 (set_attr "mode" "<MODE>")])
4535
4536 (define_split
4537 [(set (match_operand:X87MODEI 0 "register_operand" "")
4538 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4539 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4540 (clobber (match_scratch 3 ""))]
4541 "reload_completed"
4542 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4543 (clobber (match_dup 3))])
4544 (set (match_dup 0) (match_dup 2))])
4545
4546 (define_split
4547 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4548 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4549 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4550 (clobber (match_scratch 3 ""))]
4551 "reload_completed"
4552 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4553 (clobber (match_dup 3))])])
4554
4555 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4556 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4557 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4558 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4559 ;; function in i386.c.
4560 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4561 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4562 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4563 (clobber (reg:CC FLAGS_REG))]
4564 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4565 && !TARGET_FISTTP
4566 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4567 && (TARGET_64BIT || <MODE>mode != DImode))
4568 && can_create_pseudo_p ()"
4569 "#"
4570 "&& 1"
4571 [(const_int 0)]
4572 {
4573 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4574
4575 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4576 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4577 if (memory_operand (operands[0], VOIDmode))
4578 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4579 operands[2], operands[3]));
4580 else
4581 {
4582 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4583 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4584 operands[2], operands[3],
4585 operands[4]));
4586 }
4587 DONE;
4588 }
4589 [(set_attr "type" "fistp")
4590 (set_attr "i387_cw" "trunc")
4591 (set_attr "mode" "<MODE>")])
4592
4593 (define_insn "fix_truncdi_i387"
4594 [(set (match_operand:DI 0 "memory_operand" "=m")
4595 (fix:DI (match_operand 1 "register_operand" "f")))
4596 (use (match_operand:HI 2 "memory_operand" "m"))
4597 (use (match_operand:HI 3 "memory_operand" "m"))
4598 (clobber (match_scratch:XF 4 "=&1f"))]
4599 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4600 && !TARGET_FISTTP
4601 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4602 "* return output_fix_trunc (insn, operands, false);"
4603 [(set_attr "type" "fistp")
4604 (set_attr "i387_cw" "trunc")
4605 (set_attr "mode" "DI")])
4606
4607 (define_insn "fix_truncdi_i387_with_temp"
4608 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4609 (fix:DI (match_operand 1 "register_operand" "f,f")))
4610 (use (match_operand:HI 2 "memory_operand" "m,m"))
4611 (use (match_operand:HI 3 "memory_operand" "m,m"))
4612 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4613 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4614 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4615 && !TARGET_FISTTP
4616 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4617 "#"
4618 [(set_attr "type" "fistp")
4619 (set_attr "i387_cw" "trunc")
4620 (set_attr "mode" "DI")])
4621
4622 (define_split
4623 [(set (match_operand:DI 0 "register_operand" "")
4624 (fix:DI (match_operand 1 "register_operand" "")))
4625 (use (match_operand:HI 2 "memory_operand" ""))
4626 (use (match_operand:HI 3 "memory_operand" ""))
4627 (clobber (match_operand:DI 4 "memory_operand" ""))
4628 (clobber (match_scratch 5 ""))]
4629 "reload_completed"
4630 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4631 (use (match_dup 2))
4632 (use (match_dup 3))
4633 (clobber (match_dup 5))])
4634 (set (match_dup 0) (match_dup 4))])
4635
4636 (define_split
4637 [(set (match_operand:DI 0 "memory_operand" "")
4638 (fix:DI (match_operand 1 "register_operand" "")))
4639 (use (match_operand:HI 2 "memory_operand" ""))
4640 (use (match_operand:HI 3 "memory_operand" ""))
4641 (clobber (match_operand:DI 4 "memory_operand" ""))
4642 (clobber (match_scratch 5 ""))]
4643 "reload_completed"
4644 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4645 (use (match_dup 2))
4646 (use (match_dup 3))
4647 (clobber (match_dup 5))])])
4648
4649 (define_insn "fix_trunc<mode>_i387"
4650 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4651 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4652 (use (match_operand:HI 2 "memory_operand" "m"))
4653 (use (match_operand:HI 3 "memory_operand" "m"))]
4654 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4655 && !TARGET_FISTTP
4656 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4657 "* return output_fix_trunc (insn, operands, false);"
4658 [(set_attr "type" "fistp")
4659 (set_attr "i387_cw" "trunc")
4660 (set_attr "mode" "<MODE>")])
4661
4662 (define_insn "fix_trunc<mode>_i387_with_temp"
4663 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4664 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4665 (use (match_operand:HI 2 "memory_operand" "m,m"))
4666 (use (match_operand:HI 3 "memory_operand" "m,m"))
4667 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4668 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4669 && !TARGET_FISTTP
4670 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4671 "#"
4672 [(set_attr "type" "fistp")
4673 (set_attr "i387_cw" "trunc")
4674 (set_attr "mode" "<MODE>")])
4675
4676 (define_split
4677 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4678 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4679 (use (match_operand:HI 2 "memory_operand" ""))
4680 (use (match_operand:HI 3 "memory_operand" ""))
4681 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4682 "reload_completed"
4683 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4684 (use (match_dup 2))
4685 (use (match_dup 3))])
4686 (set (match_dup 0) (match_dup 4))])
4687
4688 (define_split
4689 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4690 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4691 (use (match_operand:HI 2 "memory_operand" ""))
4692 (use (match_operand:HI 3 "memory_operand" ""))
4693 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4694 "reload_completed"
4695 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4696 (use (match_dup 2))
4697 (use (match_dup 3))])])
4698
4699 (define_insn "x86_fnstcw_1"
4700 [(set (match_operand:HI 0 "memory_operand" "=m")
4701 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4702 "TARGET_80387"
4703 "fnstcw\t%0"
4704 [(set (attr "length")
4705 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4706 (set_attr "mode" "HI")
4707 (set_attr "unit" "i387")
4708 (set_attr "bdver1_decode" "vector")])
4709
4710 (define_insn "x86_fldcw_1"
4711 [(set (reg:HI FPCR_REG)
4712 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4713 "TARGET_80387"
4714 "fldcw\t%0"
4715 [(set (attr "length")
4716 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4717 (set_attr "mode" "HI")
4718 (set_attr "unit" "i387")
4719 (set_attr "athlon_decode" "vector")
4720 (set_attr "amdfam10_decode" "vector")
4721 (set_attr "bdver1_decode" "vector")])
4722 \f
4723 ;; Conversion between fixed point and floating point.
4724
4725 ;; Even though we only accept memory inputs, the backend _really_
4726 ;; wants to be able to do this between registers.
4727
4728 (define_expand "floathi<mode>2"
4729 [(set (match_operand:X87MODEF 0 "register_operand" "")
4730 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4731 "TARGET_80387
4732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4733 || TARGET_MIX_SSE_I387)")
4734
4735 ;; Pre-reload splitter to add memory clobber to the pattern.
4736 (define_insn_and_split "*floathi<mode>2_1"
4737 [(set (match_operand:X87MODEF 0 "register_operand" "")
4738 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4739 "TARGET_80387
4740 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4741 || TARGET_MIX_SSE_I387)
4742 && can_create_pseudo_p ()"
4743 "#"
4744 "&& 1"
4745 [(parallel [(set (match_dup 0)
4746 (float:X87MODEF (match_dup 1)))
4747 (clobber (match_dup 2))])]
4748 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4749
4750 (define_insn "*floathi<mode>2_i387_with_temp"
4751 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4752 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4753 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4754 "TARGET_80387
4755 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4756 || TARGET_MIX_SSE_I387)"
4757 "#"
4758 [(set_attr "type" "fmov,multi")
4759 (set_attr "mode" "<MODE>")
4760 (set_attr "unit" "*,i387")
4761 (set_attr "fp_int_src" "true")])
4762
4763 (define_insn "*floathi<mode>2_i387"
4764 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4765 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4766 "TARGET_80387
4767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4768 || TARGET_MIX_SSE_I387)"
4769 "fild%Z1\t%1"
4770 [(set_attr "type" "fmov")
4771 (set_attr "mode" "<MODE>")
4772 (set_attr "fp_int_src" "true")])
4773
4774 (define_split
4775 [(set (match_operand:X87MODEF 0 "register_operand" "")
4776 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4777 (clobber (match_operand:HI 2 "memory_operand" ""))]
4778 "TARGET_80387
4779 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4780 || TARGET_MIX_SSE_I387)
4781 && reload_completed"
4782 [(set (match_dup 2) (match_dup 1))
4783 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4784
4785 (define_split
4786 [(set (match_operand:X87MODEF 0 "register_operand" "")
4787 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4788 (clobber (match_operand:HI 2 "memory_operand" ""))]
4789 "TARGET_80387
4790 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4791 || TARGET_MIX_SSE_I387)
4792 && reload_completed"
4793 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4794
4795 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4796 [(set (match_operand:X87MODEF 0 "register_operand" "")
4797 (float:X87MODEF
4798 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4799 "TARGET_80387
4800 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4801 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4802 {
4803 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4804 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4805 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4806 {
4807 rtx reg = gen_reg_rtx (XFmode);
4808 rtx (*insn)(rtx, rtx);
4809
4810 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4811
4812 if (<X87MODEF:MODE>mode == SFmode)
4813 insn = gen_truncxfsf2;
4814 else if (<X87MODEF:MODE>mode == DFmode)
4815 insn = gen_truncxfdf2;
4816 else
4817 gcc_unreachable ();
4818
4819 emit_insn (insn (operands[0], reg));
4820 DONE;
4821 }
4822 })
4823
4824 ;; Pre-reload splitter to add memory clobber to the pattern.
4825 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4826 [(set (match_operand:X87MODEF 0 "register_operand" "")
4827 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4828 "((TARGET_80387
4829 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4830 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4831 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4832 || TARGET_MIX_SSE_I387))
4833 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4834 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4835 && ((<SSEMODEI24:MODE>mode == SImode
4836 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4837 && optimize_function_for_speed_p (cfun)
4838 && flag_trapping_math)
4839 || !(TARGET_INTER_UNIT_CONVERSIONS
4840 || optimize_function_for_size_p (cfun)))))
4841 && can_create_pseudo_p ()"
4842 "#"
4843 "&& 1"
4844 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4845 (clobber (match_dup 2))])]
4846 {
4847 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4848
4849 /* Avoid store forwarding (partial memory) stall penalty
4850 by passing DImode value through XMM registers. */
4851 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4852 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4853 && optimize_function_for_speed_p (cfun))
4854 {
4855 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4856 operands[1],
4857 operands[2]));
4858 DONE;
4859 }
4860 })
4861
4862 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4863 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4864 (float:MODEF
4865 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4866 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4867 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4868 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4869 "#"
4870 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4871 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4872 (set_attr "unit" "*,i387,*,*,*")
4873 (set_attr "athlon_decode" "*,*,double,direct,double")
4874 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4875 (set_attr "bdver1_decode" "*,*,double,direct,double")
4876 (set_attr "fp_int_src" "true")])
4877
4878 (define_insn "*floatsi<mode>2_vector_mixed"
4879 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4880 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4881 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4882 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4883 "@
4884 fild%Z1\t%1
4885 #"
4886 [(set_attr "type" "fmov,sseicvt")
4887 (set_attr "mode" "<MODE>,<ssevecmode>")
4888 (set_attr "unit" "i387,*")
4889 (set_attr "athlon_decode" "*,direct")
4890 (set_attr "amdfam10_decode" "*,double")
4891 (set_attr "bdver1_decode" "*,direct")
4892 (set_attr "fp_int_src" "true")])
4893
4894 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4895 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4896 (float:MODEF
4897 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4898 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4899 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4900 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4901 "#"
4902 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4903 (set_attr "mode" "<MODEF:MODE>")
4904 (set_attr "unit" "*,i387,*,*")
4905 (set_attr "athlon_decode" "*,*,double,direct")
4906 (set_attr "amdfam10_decode" "*,*,vector,double")
4907 (set_attr "bdver1_decode" "*,*,double,direct")
4908 (set_attr "fp_int_src" "true")])
4909
4910 (define_split
4911 [(set (match_operand:MODEF 0 "register_operand" "")
4912 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4913 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4914 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4915 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4916 && TARGET_INTER_UNIT_CONVERSIONS
4917 && reload_completed
4918 && (SSE_REG_P (operands[0])
4919 || (GET_CODE (operands[0]) == SUBREG
4920 && SSE_REG_P (operands[0])))"
4921 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4922
4923 (define_split
4924 [(set (match_operand:MODEF 0 "register_operand" "")
4925 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4926 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4927 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4928 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4929 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4930 && reload_completed
4931 && (SSE_REG_P (operands[0])
4932 || (GET_CODE (operands[0]) == SUBREG
4933 && SSE_REG_P (operands[0])))"
4934 [(set (match_dup 2) (match_dup 1))
4935 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4936
4937 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
4938 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4939 (float:MODEF
4940 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
4941 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4942 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4943 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4944 "@
4945 fild%Z1\t%1
4946 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
4947 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4948 [(set_attr "type" "fmov,sseicvt,sseicvt")
4949 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4950 (set_attr "mode" "<MODEF:MODE>")
4951 (set (attr "prefix_rex")
4952 (if_then_else
4953 (and (eq_attr "prefix" "maybe_vex")
4954 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4955 (const_string "1")
4956 (const_string "*")))
4957 (set_attr "unit" "i387,*,*")
4958 (set_attr "athlon_decode" "*,double,direct")
4959 (set_attr "amdfam10_decode" "*,vector,double")
4960 (set_attr "bdver1_decode" "*,double,direct")
4961 (set_attr "fp_int_src" "true")])
4962
4963 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
4964 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4965 (float:MODEF
4966 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
4967 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4968 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4969 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4970 "@
4971 fild%Z1\t%1
4972 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4973 [(set_attr "type" "fmov,sseicvt")
4974 (set_attr "prefix" "orig,maybe_vex")
4975 (set_attr "mode" "<MODEF:MODE>")
4976 (set (attr "prefix_rex")
4977 (if_then_else
4978 (and (eq_attr "prefix" "maybe_vex")
4979 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4980 (const_string "1")
4981 (const_string "*")))
4982 (set_attr "athlon_decode" "*,direct")
4983 (set_attr "amdfam10_decode" "*,double")
4984 (set_attr "bdver1_decode" "*,direct")
4985 (set_attr "fp_int_src" "true")])
4986
4987 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4988 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4989 (float:MODEF
4990 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4991 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4992 "TARGET_SSE2 && TARGET_SSE_MATH
4993 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4994 "#"
4995 [(set_attr "type" "sseicvt")
4996 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4997 (set_attr "athlon_decode" "double,direct,double")
4998 (set_attr "amdfam10_decode" "vector,double,double")
4999 (set_attr "bdver1_decode" "double,direct,double")
5000 (set_attr "fp_int_src" "true")])
5001
5002 (define_insn "*floatsi<mode>2_vector_sse"
5003 [(set (match_operand:MODEF 0 "register_operand" "=x")
5004 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5005 "TARGET_SSE2 && TARGET_SSE_MATH
5006 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5007 "#"
5008 [(set_attr "type" "sseicvt")
5009 (set_attr "mode" "<MODE>")
5010 (set_attr "athlon_decode" "direct")
5011 (set_attr "amdfam10_decode" "double")
5012 (set_attr "bdver1_decode" "direct")
5013 (set_attr "fp_int_src" "true")])
5014
5015 (define_split
5016 [(set (match_operand:MODEF 0 "register_operand" "")
5017 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5018 (clobber (match_operand:SI 2 "memory_operand" ""))]
5019 "TARGET_SSE2 && TARGET_SSE_MATH
5020 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5021 && reload_completed
5022 && (SSE_REG_P (operands[0])
5023 || (GET_CODE (operands[0]) == SUBREG
5024 && SSE_REG_P (operands[0])))"
5025 [(const_int 0)]
5026 {
5027 rtx op1 = operands[1];
5028
5029 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5030 <MODE>mode, 0);
5031 if (GET_CODE (op1) == SUBREG)
5032 op1 = SUBREG_REG (op1);
5033
5034 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5035 {
5036 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5037 emit_insn (gen_sse2_loadld (operands[4],
5038 CONST0_RTX (V4SImode), operands[1]));
5039 }
5040 /* We can ignore possible trapping value in the
5041 high part of SSE register for non-trapping math. */
5042 else if (SSE_REG_P (op1) && !flag_trapping_math)
5043 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5044 else
5045 {
5046 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5047 emit_move_insn (operands[2], operands[1]);
5048 emit_insn (gen_sse2_loadld (operands[4],
5049 CONST0_RTX (V4SImode), operands[2]));
5050 }
5051 emit_insn
5052 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5053 DONE;
5054 })
5055
5056 (define_split
5057 [(set (match_operand:MODEF 0 "register_operand" "")
5058 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5059 (clobber (match_operand:SI 2 "memory_operand" ""))]
5060 "TARGET_SSE2 && TARGET_SSE_MATH
5061 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5062 && reload_completed
5063 && (SSE_REG_P (operands[0])
5064 || (GET_CODE (operands[0]) == SUBREG
5065 && SSE_REG_P (operands[0])))"
5066 [(const_int 0)]
5067 {
5068 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5069 <MODE>mode, 0);
5070 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5071
5072 emit_insn (gen_sse2_loadld (operands[4],
5073 CONST0_RTX (V4SImode), operands[1]));
5074 emit_insn
5075 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5076 DONE;
5077 })
5078
5079 (define_split
5080 [(set (match_operand:MODEF 0 "register_operand" "")
5081 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5082 "TARGET_SSE2 && TARGET_SSE_MATH
5083 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5084 && reload_completed
5085 && (SSE_REG_P (operands[0])
5086 || (GET_CODE (operands[0]) == SUBREG
5087 && SSE_REG_P (operands[0])))"
5088 [(const_int 0)]
5089 {
5090 rtx op1 = operands[1];
5091
5092 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5093 <MODE>mode, 0);
5094 if (GET_CODE (op1) == SUBREG)
5095 op1 = SUBREG_REG (op1);
5096
5097 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5098 {
5099 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5100 emit_insn (gen_sse2_loadld (operands[4],
5101 CONST0_RTX (V4SImode), operands[1]));
5102 }
5103 /* We can ignore possible trapping value in the
5104 high part of SSE register for non-trapping math. */
5105 else if (SSE_REG_P (op1) && !flag_trapping_math)
5106 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5107 else
5108 gcc_unreachable ();
5109 emit_insn
5110 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5111 DONE;
5112 })
5113
5114 (define_split
5115 [(set (match_operand:MODEF 0 "register_operand" "")
5116 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5117 "TARGET_SSE2 && TARGET_SSE_MATH
5118 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5119 && reload_completed
5120 && (SSE_REG_P (operands[0])
5121 || (GET_CODE (operands[0]) == SUBREG
5122 && SSE_REG_P (operands[0])))"
5123 [(const_int 0)]
5124 {
5125 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5126 <MODE>mode, 0);
5127 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5128
5129 emit_insn (gen_sse2_loadld (operands[4],
5130 CONST0_RTX (V4SImode), operands[1]));
5131 emit_insn
5132 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5133 DONE;
5134 })
5135
5136 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5137 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5138 (float:MODEF
5139 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5140 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5141 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5142 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5143 "#"
5144 [(set_attr "type" "sseicvt")
5145 (set_attr "mode" "<MODEF:MODE>")
5146 (set_attr "athlon_decode" "double,direct")
5147 (set_attr "amdfam10_decode" "vector,double")
5148 (set_attr "bdver1_decode" "double,direct")
5149 (set_attr "fp_int_src" "true")])
5150
5151 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5152 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5153 (float:MODEF
5154 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5155 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5156 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5157 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5158 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5159 [(set_attr "type" "sseicvt")
5160 (set_attr "prefix" "maybe_vex")
5161 (set_attr "mode" "<MODEF:MODE>")
5162 (set (attr "prefix_rex")
5163 (if_then_else
5164 (and (eq_attr "prefix" "maybe_vex")
5165 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5166 (const_string "1")
5167 (const_string "*")))
5168 (set_attr "athlon_decode" "double,direct")
5169 (set_attr "amdfam10_decode" "vector,double")
5170 (set_attr "bdver1_decode" "double,direct")
5171 (set_attr "fp_int_src" "true")])
5172
5173 (define_split
5174 [(set (match_operand:MODEF 0 "register_operand" "")
5175 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5176 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5177 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5178 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5179 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5180 && reload_completed
5181 && (SSE_REG_P (operands[0])
5182 || (GET_CODE (operands[0]) == SUBREG
5183 && SSE_REG_P (operands[0])))"
5184 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5185
5186 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5187 [(set (match_operand:MODEF 0 "register_operand" "=x")
5188 (float:MODEF
5189 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5190 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5191 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5192 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5193 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5194 [(set_attr "type" "sseicvt")
5195 (set_attr "prefix" "maybe_vex")
5196 (set_attr "mode" "<MODEF:MODE>")
5197 (set (attr "prefix_rex")
5198 (if_then_else
5199 (and (eq_attr "prefix" "maybe_vex")
5200 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5201 (const_string "1")
5202 (const_string "*")))
5203 (set_attr "athlon_decode" "direct")
5204 (set_attr "amdfam10_decode" "double")
5205 (set_attr "bdver1_decode" "direct")
5206 (set_attr "fp_int_src" "true")])
5207
5208 (define_split
5209 [(set (match_operand:MODEF 0 "register_operand" "")
5210 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5211 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5212 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5213 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5214 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5215 && reload_completed
5216 && (SSE_REG_P (operands[0])
5217 || (GET_CODE (operands[0]) == SUBREG
5218 && SSE_REG_P (operands[0])))"
5219 [(set (match_dup 2) (match_dup 1))
5220 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5221
5222 (define_split
5223 [(set (match_operand:MODEF 0 "register_operand" "")
5224 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5225 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5226 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5227 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5228 && reload_completed
5229 && (SSE_REG_P (operands[0])
5230 || (GET_CODE (operands[0]) == SUBREG
5231 && SSE_REG_P (operands[0])))"
5232 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5233
5234 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5235 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5236 (float:X87MODEF
5237 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5238 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5239 "TARGET_80387
5240 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5241 "@
5242 fild%Z1\t%1
5243 #"
5244 [(set_attr "type" "fmov,multi")
5245 (set_attr "mode" "<X87MODEF:MODE>")
5246 (set_attr "unit" "*,i387")
5247 (set_attr "fp_int_src" "true")])
5248
5249 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5250 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5251 (float:X87MODEF
5252 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5253 "TARGET_80387
5254 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5255 "fild%Z1\t%1"
5256 [(set_attr "type" "fmov")
5257 (set_attr "mode" "<X87MODEF:MODE>")
5258 (set_attr "fp_int_src" "true")])
5259
5260 (define_split
5261 [(set (match_operand:X87MODEF 0 "register_operand" "")
5262 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5263 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5264 "TARGET_80387
5265 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5266 && reload_completed
5267 && FP_REG_P (operands[0])"
5268 [(set (match_dup 2) (match_dup 1))
5269 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5270
5271 (define_split
5272 [(set (match_operand:X87MODEF 0 "register_operand" "")
5273 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5274 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5275 "TARGET_80387
5276 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5277 && reload_completed
5278 && FP_REG_P (operands[0])"
5279 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5280
5281 ;; Avoid store forwarding (partial memory) stall penalty
5282 ;; by passing DImode value through XMM registers. */
5283
5284 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5285 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5286 (float:X87MODEF
5287 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5288 (clobber (match_scratch:V4SI 3 "=X,x"))
5289 (clobber (match_scratch:V4SI 4 "=X,x"))
5290 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5291 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5292 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5293 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5294 "#"
5295 [(set_attr "type" "multi")
5296 (set_attr "mode" "<X87MODEF:MODE>")
5297 (set_attr "unit" "i387")
5298 (set_attr "fp_int_src" "true")])
5299
5300 (define_split
5301 [(set (match_operand:X87MODEF 0 "register_operand" "")
5302 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5303 (clobber (match_scratch:V4SI 3 ""))
5304 (clobber (match_scratch:V4SI 4 ""))
5305 (clobber (match_operand:DI 2 "memory_operand" ""))]
5306 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5307 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5308 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5309 && reload_completed
5310 && FP_REG_P (operands[0])"
5311 [(set (match_dup 2) (match_dup 3))
5312 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5313 {
5314 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5315 Assemble the 64-bit DImode value in an xmm register. */
5316 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5317 gen_rtx_SUBREG (SImode, operands[1], 0)));
5318 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5319 gen_rtx_SUBREG (SImode, operands[1], 4)));
5320 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5321 operands[4]));
5322
5323 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5324 })
5325
5326 (define_split
5327 [(set (match_operand:X87MODEF 0 "register_operand" "")
5328 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5329 (clobber (match_scratch:V4SI 3 ""))
5330 (clobber (match_scratch:V4SI 4 ""))
5331 (clobber (match_operand:DI 2 "memory_operand" ""))]
5332 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5333 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5334 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5335 && reload_completed
5336 && FP_REG_P (operands[0])"
5337 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5338
5339 ;; Avoid store forwarding (partial memory) stall penalty by extending
5340 ;; SImode value to DImode through XMM register instead of pushing two
5341 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5342 ;; targets benefit from this optimization. Also note that fild
5343 ;; loads from memory only.
5344
5345 (define_insn "*floatunssi<mode>2_1"
5346 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5347 (unsigned_float:X87MODEF
5348 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5349 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5350 (clobber (match_scratch:SI 3 "=X,x"))]
5351 "!TARGET_64BIT
5352 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5353 && TARGET_SSE"
5354 "#"
5355 [(set_attr "type" "multi")
5356 (set_attr "mode" "<MODE>")])
5357
5358 (define_split
5359 [(set (match_operand:X87MODEF 0 "register_operand" "")
5360 (unsigned_float:X87MODEF
5361 (match_operand:SI 1 "register_operand" "")))
5362 (clobber (match_operand:DI 2 "memory_operand" ""))
5363 (clobber (match_scratch:SI 3 ""))]
5364 "!TARGET_64BIT
5365 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5366 && TARGET_SSE
5367 && reload_completed"
5368 [(set (match_dup 2) (match_dup 1))
5369 (set (match_dup 0)
5370 (float:X87MODEF (match_dup 2)))]
5371 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5372
5373 (define_split
5374 [(set (match_operand:X87MODEF 0 "register_operand" "")
5375 (unsigned_float:X87MODEF
5376 (match_operand:SI 1 "memory_operand" "")))
5377 (clobber (match_operand:DI 2 "memory_operand" ""))
5378 (clobber (match_scratch:SI 3 ""))]
5379 "!TARGET_64BIT
5380 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5381 && TARGET_SSE
5382 && reload_completed"
5383 [(set (match_dup 2) (match_dup 3))
5384 (set (match_dup 0)
5385 (float:X87MODEF (match_dup 2)))]
5386 {
5387 emit_move_insn (operands[3], operands[1]);
5388 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5389 })
5390
5391 (define_expand "floatunssi<mode>2"
5392 [(parallel
5393 [(set (match_operand:X87MODEF 0 "register_operand" "")
5394 (unsigned_float:X87MODEF
5395 (match_operand:SI 1 "nonimmediate_operand" "")))
5396 (clobber (match_dup 2))
5397 (clobber (match_scratch:SI 3 ""))])]
5398 "!TARGET_64BIT
5399 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5400 && TARGET_SSE)
5401 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5402 {
5403 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5404 {
5405 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5406 DONE;
5407 }
5408 else
5409 {
5410 enum ix86_stack_slot slot = (virtuals_instantiated
5411 ? SLOT_TEMP
5412 : SLOT_VIRTUAL);
5413 operands[2] = assign_386_stack_local (DImode, slot);
5414 }
5415 })
5416
5417 (define_expand "floatunsdisf2"
5418 [(use (match_operand:SF 0 "register_operand" ""))
5419 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5420 "TARGET_64BIT && TARGET_SSE_MATH"
5421 "x86_emit_floatuns (operands); DONE;")
5422
5423 (define_expand "floatunsdidf2"
5424 [(use (match_operand:DF 0 "register_operand" ""))
5425 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5426 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5427 && TARGET_SSE2 && TARGET_SSE_MATH"
5428 {
5429 if (TARGET_64BIT)
5430 x86_emit_floatuns (operands);
5431 else
5432 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5433 DONE;
5434 })
5435 \f
5436 ;; Add instructions
5437
5438 (define_expand "add<mode>3"
5439 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5440 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5441 (match_operand:SDWIM 2 "<general_operand>" "")))]
5442 ""
5443 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5444
5445 (define_insn_and_split "*add<dwi>3_doubleword"
5446 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5447 (plus:<DWI>
5448 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5449 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5450 (clobber (reg:CC FLAGS_REG))]
5451 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5452 "#"
5453 "reload_completed"
5454 [(parallel [(set (reg:CC FLAGS_REG)
5455 (unspec:CC [(match_dup 1) (match_dup 2)]
5456 UNSPEC_ADD_CARRY))
5457 (set (match_dup 0)
5458 (plus:DWIH (match_dup 1) (match_dup 2)))])
5459 (parallel [(set (match_dup 3)
5460 (plus:DWIH
5461 (match_dup 4)
5462 (plus:DWIH
5463 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5464 (match_dup 5))))
5465 (clobber (reg:CC FLAGS_REG))])]
5466 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5467
5468 (define_insn "*add<mode>3_cc"
5469 [(set (reg:CC FLAGS_REG)
5470 (unspec:CC
5471 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5472 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5473 UNSPEC_ADD_CARRY))
5474 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5475 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5476 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5477 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5478 [(set_attr "type" "alu")
5479 (set_attr "mode" "<MODE>")])
5480
5481 (define_insn "addqi3_cc"
5482 [(set (reg:CC FLAGS_REG)
5483 (unspec:CC
5484 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5485 (match_operand:QI 2 "general_operand" "qn,qm")]
5486 UNSPEC_ADD_CARRY))
5487 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5488 (plus:QI (match_dup 1) (match_dup 2)))]
5489 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5490 "add{b}\t{%2, %0|%0, %2}"
5491 [(set_attr "type" "alu")
5492 (set_attr "mode" "QI")])
5493
5494 (define_insn "*lea_1"
5495 [(set (match_operand:P 0 "register_operand" "=r")
5496 (match_operand:P 1 "no_seg_address_operand" "p"))]
5497 ""
5498 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5499 [(set_attr "type" "lea")
5500 (set_attr "mode" "<MODE>")])
5501
5502 (define_insn "*lea_2"
5503 [(set (match_operand:SI 0 "register_operand" "=r")
5504 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5505 "TARGET_64BIT"
5506 "lea{l}\t{%a1, %0|%0, %a1}"
5507 [(set_attr "type" "lea")
5508 (set_attr "mode" "SI")])
5509
5510 (define_insn "*lea_2_zext"
5511 [(set (match_operand:DI 0 "register_operand" "=r")
5512 (zero_extend:DI
5513 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5514 "TARGET_64BIT"
5515 "lea{l}\t{%a1, %k0|%k0, %a1}"
5516 [(set_attr "type" "lea")
5517 (set_attr "mode" "SI")])
5518
5519 (define_insn "*add<mode>_1"
5520 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5521 (plus:SWI48
5522 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5523 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5524 (clobber (reg:CC FLAGS_REG))]
5525 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5526 {
5527 switch (get_attr_type (insn))
5528 {
5529 case TYPE_LEA:
5530 return "#";
5531
5532 case TYPE_INCDEC:
5533 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5534 if (operands[2] == const1_rtx)
5535 return "inc{<imodesuffix>}\t%0";
5536 else
5537 {
5538 gcc_assert (operands[2] == constm1_rtx);
5539 return "dec{<imodesuffix>}\t%0";
5540 }
5541
5542 default:
5543 /* For most processors, ADD is faster than LEA. This alternative
5544 was added to use ADD as much as possible. */
5545 if (which_alternative == 2)
5546 {
5547 rtx tmp;
5548 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5549 }
5550
5551 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5552 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5553 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5554
5555 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5556 }
5557 }
5558 [(set (attr "type")
5559 (cond [(eq_attr "alternative" "3")
5560 (const_string "lea")
5561 (match_operand:SWI48 2 "incdec_operand" "")
5562 (const_string "incdec")
5563 ]
5564 (const_string "alu")))
5565 (set (attr "length_immediate")
5566 (if_then_else
5567 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5568 (const_string "1")
5569 (const_string "*")))
5570 (set_attr "mode" "<MODE>")])
5571
5572 ;; It may seem that nonimmediate operand is proper one for operand 1.
5573 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5574 ;; we take care in ix86_binary_operator_ok to not allow two memory
5575 ;; operands so proper swapping will be done in reload. This allow
5576 ;; patterns constructed from addsi_1 to match.
5577
5578 (define_insn "*addsi_1_zext"
5579 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5580 (zero_extend:DI
5581 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5582 (match_operand:SI 2 "general_operand" "g,0,li"))))
5583 (clobber (reg:CC FLAGS_REG))]
5584 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5585 {
5586 switch (get_attr_type (insn))
5587 {
5588 case TYPE_LEA:
5589 return "#";
5590
5591 case TYPE_INCDEC:
5592 if (operands[2] == const1_rtx)
5593 return "inc{l}\t%k0";
5594 else
5595 {
5596 gcc_assert (operands[2] == constm1_rtx);
5597 return "dec{l}\t%k0";
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 == 1)
5604 {
5605 rtx tmp;
5606 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5607 }
5608
5609 if (x86_maybe_negate_const_int (&operands[2], SImode))
5610 return "sub{l}\t{%2, %k0|%k0, %2}";
5611
5612 return "add{l}\t{%2, %k0|%k0, %2}";
5613 }
5614 }
5615 [(set (attr "type")
5616 (cond [(eq_attr "alternative" "2")
5617 (const_string "lea")
5618 (match_operand:SI 2 "incdec_operand" "")
5619 (const_string "incdec")
5620 ]
5621 (const_string "alu")))
5622 (set (attr "length_immediate")
5623 (if_then_else
5624 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5625 (const_string "1")
5626 (const_string "*")))
5627 (set_attr "mode" "SI")])
5628
5629 (define_insn "*addhi_1"
5630 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5631 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5632 (match_operand:HI 2 "general_operand" "rn,rm")))
5633 (clobber (reg:CC FLAGS_REG))]
5634 "TARGET_PARTIAL_REG_STALL
5635 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5636 {
5637 switch (get_attr_type (insn))
5638 {
5639 case TYPE_INCDEC:
5640 if (operands[2] == const1_rtx)
5641 return "inc{w}\t%0";
5642 else
5643 {
5644 gcc_assert (operands[2] == constm1_rtx);
5645 return "dec{w}\t%0";
5646 }
5647
5648 default:
5649 if (x86_maybe_negate_const_int (&operands[2], HImode))
5650 return "sub{w}\t{%2, %0|%0, %2}";
5651
5652 return "add{w}\t{%2, %0|%0, %2}";
5653 }
5654 }
5655 [(set (attr "type")
5656 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5657 (const_string "incdec")
5658 (const_string "alu")))
5659 (set (attr "length_immediate")
5660 (if_then_else
5661 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5662 (const_string "1")
5663 (const_string "*")))
5664 (set_attr "mode" "HI")])
5665
5666 (define_insn "*addhi_1_lea"
5667 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5668 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5669 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5670 (clobber (reg:CC FLAGS_REG))]
5671 "!TARGET_PARTIAL_REG_STALL
5672 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5673 {
5674 switch (get_attr_type (insn))
5675 {
5676 case TYPE_LEA:
5677 return "#";
5678
5679 case TYPE_INCDEC:
5680 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681 if (operands[2] == const1_rtx)
5682 return "inc{w}\t%0";
5683 else
5684 {
5685 gcc_assert (operands[2] == constm1_rtx);
5686 return "dec{w}\t%0";
5687 }
5688
5689 default:
5690 /* For most processors, ADD is faster than LEA. This alternative
5691 was added to use ADD as much as possible. */
5692 if (which_alternative == 2)
5693 {
5694 rtx tmp;
5695 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5696 }
5697
5698 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5699 if (x86_maybe_negate_const_int (&operands[2], HImode))
5700 return "sub{w}\t{%2, %0|%0, %2}";
5701
5702 return "add{w}\t{%2, %0|%0, %2}";
5703 }
5704 }
5705 [(set (attr "type")
5706 (cond [(eq_attr "alternative" "3")
5707 (const_string "lea")
5708 (match_operand:HI 2 "incdec_operand" "")
5709 (const_string "incdec")
5710 ]
5711 (const_string "alu")))
5712 (set (attr "length_immediate")
5713 (if_then_else
5714 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5715 (const_string "1")
5716 (const_string "*")))
5717 (set_attr "mode" "HI,HI,HI,SI")])
5718
5719 ;; %%% Potential partial reg stall on alternative 2. What to do?
5720 (define_insn "*addqi_1"
5721 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5722 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5723 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5724 (clobber (reg:CC FLAGS_REG))]
5725 "TARGET_PARTIAL_REG_STALL
5726 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5727 {
5728 int widen = (which_alternative == 2);
5729 switch (get_attr_type (insn))
5730 {
5731 case TYPE_INCDEC:
5732 if (operands[2] == const1_rtx)
5733 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5734 else
5735 {
5736 gcc_assert (operands[2] == constm1_rtx);
5737 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5738 }
5739
5740 default:
5741 if (x86_maybe_negate_const_int (&operands[2], QImode))
5742 {
5743 if (widen)
5744 return "sub{l}\t{%2, %k0|%k0, %2}";
5745 else
5746 return "sub{b}\t{%2, %0|%0, %2}";
5747 }
5748 if (widen)
5749 return "add{l}\t{%k2, %k0|%k0, %k2}";
5750 else
5751 return "add{b}\t{%2, %0|%0, %2}";
5752 }
5753 }
5754 [(set (attr "type")
5755 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5756 (const_string "incdec")
5757 (const_string "alu")))
5758 (set (attr "length_immediate")
5759 (if_then_else
5760 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5761 (const_string "1")
5762 (const_string "*")))
5763 (set_attr "mode" "QI,QI,SI")])
5764
5765 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5766 (define_insn "*addqi_1_lea"
5767 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5768 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5769 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5770 (clobber (reg:CC FLAGS_REG))]
5771 "!TARGET_PARTIAL_REG_STALL
5772 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5773 {
5774 int widen = (which_alternative == 3 || which_alternative == 4);
5775
5776 switch (get_attr_type (insn))
5777 {
5778 case TYPE_LEA:
5779 return "#";
5780
5781 case TYPE_INCDEC:
5782 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5783 if (operands[2] == const1_rtx)
5784 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5785 else
5786 {
5787 gcc_assert (operands[2] == constm1_rtx);
5788 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5789 }
5790
5791 default:
5792 /* For most processors, ADD is faster than LEA. These alternatives
5793 were added to use ADD as much as possible. */
5794 if (which_alternative == 2 || which_alternative == 4)
5795 {
5796 rtx tmp;
5797 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5798 }
5799
5800 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5801 if (x86_maybe_negate_const_int (&operands[2], QImode))
5802 {
5803 if (widen)
5804 return "sub{l}\t{%2, %k0|%k0, %2}";
5805 else
5806 return "sub{b}\t{%2, %0|%0, %2}";
5807 }
5808 if (widen)
5809 return "add{l}\t{%k2, %k0|%k0, %k2}";
5810 else
5811 return "add{b}\t{%2, %0|%0, %2}";
5812 }
5813 }
5814 [(set (attr "type")
5815 (cond [(eq_attr "alternative" "5")
5816 (const_string "lea")
5817 (match_operand:QI 2 "incdec_operand" "")
5818 (const_string "incdec")
5819 ]
5820 (const_string "alu")))
5821 (set (attr "length_immediate")
5822 (if_then_else
5823 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5824 (const_string "1")
5825 (const_string "*")))
5826 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5827
5828 (define_insn "*addqi_1_slp"
5829 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5830 (plus:QI (match_dup 0)
5831 (match_operand:QI 1 "general_operand" "qn,qnm")))
5832 (clobber (reg:CC FLAGS_REG))]
5833 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5834 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5835 {
5836 switch (get_attr_type (insn))
5837 {
5838 case TYPE_INCDEC:
5839 if (operands[1] == const1_rtx)
5840 return "inc{b}\t%0";
5841 else
5842 {
5843 gcc_assert (operands[1] == constm1_rtx);
5844 return "dec{b}\t%0";
5845 }
5846
5847 default:
5848 if (x86_maybe_negate_const_int (&operands[1], QImode))
5849 return "sub{b}\t{%1, %0|%0, %1}";
5850
5851 return "add{b}\t{%1, %0|%0, %1}";
5852 }
5853 }
5854 [(set (attr "type")
5855 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5856 (const_string "incdec")
5857 (const_string "alu1")))
5858 (set (attr "memory")
5859 (if_then_else (match_operand 1 "memory_operand" "")
5860 (const_string "load")
5861 (const_string "none")))
5862 (set_attr "mode" "QI")])
5863
5864 ;; Convert lea to the lea pattern to avoid flags dependency.
5865 (define_split
5866 [(set (match_operand 0 "register_operand" "")
5867 (plus (match_operand 1 "register_operand" "")
5868 (match_operand 2 "nonmemory_operand" "")))
5869 (clobber (reg:CC FLAGS_REG))]
5870 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5871 [(const_int 0)]
5872 {
5873 rtx pat;
5874 enum machine_mode mode = GET_MODE (operands[0]);
5875
5876 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5877 may confuse gen_lowpart. */
5878 if (mode != Pmode)
5879 {
5880 operands[1] = gen_lowpart (Pmode, operands[1]);
5881 operands[2] = gen_lowpart (Pmode, operands[2]);
5882 }
5883
5884 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5885
5886 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5887 operands[0] = gen_lowpart (SImode, operands[0]);
5888
5889 if (TARGET_64BIT && mode != Pmode)
5890 pat = gen_rtx_SUBREG (SImode, pat, 0);
5891
5892 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5893 DONE;
5894 })
5895
5896 ;; Convert lea to the lea pattern to avoid flags dependency.
5897 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5898 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5899 (define_split
5900 [(set (match_operand:DI 0 "register_operand" "")
5901 (plus:DI (match_operand:DI 1 "register_operand" "")
5902 (match_operand:DI 2 "x86_64_immediate_operand" "")))
5903 (clobber (reg:CC FLAGS_REG))]
5904 "TARGET_64BIT && reload_completed
5905 && true_regnum (operands[0]) != true_regnum (operands[1])"
5906 [(set (match_dup 0)
5907 (plus:DI (match_dup 1) (match_dup 2)))])
5908
5909 ;; Convert lea to the lea pattern to avoid flags dependency.
5910 (define_split
5911 [(set (match_operand:DI 0 "register_operand" "")
5912 (zero_extend:DI
5913 (plus:SI (match_operand:SI 1 "register_operand" "")
5914 (match_operand:SI 2 "nonmemory_operand" ""))))
5915 (clobber (reg:CC FLAGS_REG))]
5916 "TARGET_64BIT && reload_completed
5917 && ix86_lea_for_add_ok (insn, operands)"
5918 [(set (match_dup 0)
5919 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5920 {
5921 operands[1] = gen_lowpart (DImode, operands[1]);
5922 operands[2] = gen_lowpart (DImode, operands[2]);
5923 })
5924
5925 (define_insn "*add<mode>_2"
5926 [(set (reg FLAGS_REG)
5927 (compare
5928 (plus:SWI
5929 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5930 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5931 (const_int 0)))
5932 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5933 (plus:SWI (match_dup 1) (match_dup 2)))]
5934 "ix86_match_ccmode (insn, CCGOCmode)
5935 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5936 {
5937 switch (get_attr_type (insn))
5938 {
5939 case TYPE_INCDEC:
5940 if (operands[2] == const1_rtx)
5941 return "inc{<imodesuffix>}\t%0";
5942 else
5943 {
5944 gcc_assert (operands[2] == constm1_rtx);
5945 return "dec{<imodesuffix>}\t%0";
5946 }
5947
5948 default:
5949 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5950 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5951
5952 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5953 }
5954 }
5955 [(set (attr "type")
5956 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5957 (const_string "incdec")
5958 (const_string "alu")))
5959 (set (attr "length_immediate")
5960 (if_then_else
5961 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5962 (const_string "1")
5963 (const_string "*")))
5964 (set_attr "mode" "<MODE>")])
5965
5966 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5967 (define_insn "*addsi_2_zext"
5968 [(set (reg FLAGS_REG)
5969 (compare
5970 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5971 (match_operand:SI 2 "general_operand" "g"))
5972 (const_int 0)))
5973 (set (match_operand:DI 0 "register_operand" "=r")
5974 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5975 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5976 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5977 {
5978 switch (get_attr_type (insn))
5979 {
5980 case TYPE_INCDEC:
5981 if (operands[2] == const1_rtx)
5982 return "inc{l}\t%k0";
5983 else
5984 {
5985 gcc_assert (operands[2] == constm1_rtx);
5986 return "dec{l}\t%k0";
5987 }
5988
5989 default:
5990 if (x86_maybe_negate_const_int (&operands[2], SImode))
5991 return "sub{l}\t{%2, %k0|%k0, %2}";
5992
5993 return "add{l}\t{%2, %k0|%k0, %2}";
5994 }
5995 }
5996 [(set (attr "type")
5997 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5998 (const_string "incdec")
5999 (const_string "alu")))
6000 (set (attr "length_immediate")
6001 (if_then_else
6002 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6003 (const_string "1")
6004 (const_string "*")))
6005 (set_attr "mode" "SI")])
6006
6007 (define_insn "*add<mode>_3"
6008 [(set (reg FLAGS_REG)
6009 (compare
6010 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6011 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6012 (clobber (match_scratch:SWI 0 "=<r>"))]
6013 "ix86_match_ccmode (insn, CCZmode)
6014 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6015 {
6016 switch (get_attr_type (insn))
6017 {
6018 case TYPE_INCDEC:
6019 if (operands[2] == const1_rtx)
6020 return "inc{<imodesuffix>}\t%0";
6021 else
6022 {
6023 gcc_assert (operands[2] == constm1_rtx);
6024 return "dec{<imodesuffix>}\t%0";
6025 }
6026
6027 default:
6028 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6029 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6030
6031 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6032 }
6033 }
6034 [(set (attr "type")
6035 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6036 (const_string "incdec")
6037 (const_string "alu")))
6038 (set (attr "length_immediate")
6039 (if_then_else
6040 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6041 (const_string "1")
6042 (const_string "*")))
6043 (set_attr "mode" "<MODE>")])
6044
6045 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6046 (define_insn "*addsi_3_zext"
6047 [(set (reg FLAGS_REG)
6048 (compare
6049 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6050 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6051 (set (match_operand:DI 0 "register_operand" "=r")
6052 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6053 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6054 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6055 {
6056 switch (get_attr_type (insn))
6057 {
6058 case TYPE_INCDEC:
6059 if (operands[2] == const1_rtx)
6060 return "inc{l}\t%k0";
6061 else
6062 {
6063 gcc_assert (operands[2] == constm1_rtx);
6064 return "dec{l}\t%k0";
6065 }
6066
6067 default:
6068 if (x86_maybe_negate_const_int (&operands[2], SImode))
6069 return "sub{l}\t{%2, %k0|%k0, %2}";
6070
6071 return "add{l}\t{%2, %k0|%k0, %2}";
6072 }
6073 }
6074 [(set (attr "type")
6075 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6076 (const_string "incdec")
6077 (const_string "alu")))
6078 (set (attr "length_immediate")
6079 (if_then_else
6080 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6081 (const_string "1")
6082 (const_string "*")))
6083 (set_attr "mode" "SI")])
6084
6085 ; For comparisons against 1, -1 and 128, we may generate better code
6086 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6087 ; is matched then. We can't accept general immediate, because for
6088 ; case of overflows, the result is messed up.
6089 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6090 ; only for comparisons not depending on it.
6091
6092 (define_insn "*adddi_4"
6093 [(set (reg FLAGS_REG)
6094 (compare
6095 (match_operand:DI 1 "nonimmediate_operand" "0")
6096 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6097 (clobber (match_scratch:DI 0 "=rm"))]
6098 "TARGET_64BIT
6099 && ix86_match_ccmode (insn, CCGCmode)"
6100 {
6101 switch (get_attr_type (insn))
6102 {
6103 case TYPE_INCDEC:
6104 if (operands[2] == constm1_rtx)
6105 return "inc{q}\t%0";
6106 else
6107 {
6108 gcc_assert (operands[2] == const1_rtx);
6109 return "dec{q}\t%0";
6110 }
6111
6112 default:
6113 if (x86_maybe_negate_const_int (&operands[2], DImode))
6114 return "add{q}\t{%2, %0|%0, %2}";
6115
6116 return "sub{q}\t{%2, %0|%0, %2}";
6117 }
6118 }
6119 [(set (attr "type")
6120 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6121 (const_string "incdec")
6122 (const_string "alu")))
6123 (set (attr "length_immediate")
6124 (if_then_else
6125 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6126 (const_string "1")
6127 (const_string "*")))
6128 (set_attr "mode" "DI")])
6129
6130 ; For comparisons against 1, -1 and 128, we may generate better code
6131 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6132 ; is matched then. We can't accept general immediate, because for
6133 ; case of overflows, the result is messed up.
6134 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6135 ; only for comparisons not depending on it.
6136
6137 (define_insn "*add<mode>_4"
6138 [(set (reg FLAGS_REG)
6139 (compare
6140 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6141 (match_operand:SWI124 2 "const_int_operand" "n")))
6142 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6143 "ix86_match_ccmode (insn, CCGCmode)"
6144 {
6145 switch (get_attr_type (insn))
6146 {
6147 case TYPE_INCDEC:
6148 if (operands[2] == constm1_rtx)
6149 return "inc{<imodesuffix>}\t%0";
6150 else
6151 {
6152 gcc_assert (operands[2] == const1_rtx);
6153 return "dec{<imodesuffix>}\t%0";
6154 }
6155
6156 default:
6157 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6158 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6159
6160 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6161 }
6162 }
6163 [(set (attr "type")
6164 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6165 (const_string "incdec")
6166 (const_string "alu")))
6167 (set (attr "length_immediate")
6168 (if_then_else
6169 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6170 (const_string "1")
6171 (const_string "*")))
6172 (set_attr "mode" "<MODE>")])
6173
6174 (define_insn "*add<mode>_5"
6175 [(set (reg FLAGS_REG)
6176 (compare
6177 (plus:SWI
6178 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6179 (match_operand:SWI 2 "<general_operand>" "<g>"))
6180 (const_int 0)))
6181 (clobber (match_scratch:SWI 0 "=<r>"))]
6182 "ix86_match_ccmode (insn, CCGOCmode)
6183 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6184 {
6185 switch (get_attr_type (insn))
6186 {
6187 case TYPE_INCDEC:
6188 if (operands[2] == const1_rtx)
6189 return "inc{<imodesuffix>}\t%0";
6190 else
6191 {
6192 gcc_assert (operands[2] == constm1_rtx);
6193 return "dec{<imodesuffix>}\t%0";
6194 }
6195
6196 default:
6197 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6198 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6199
6200 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6201 }
6202 }
6203 [(set (attr "type")
6204 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6205 (const_string "incdec")
6206 (const_string "alu")))
6207 (set (attr "length_immediate")
6208 (if_then_else
6209 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6210 (const_string "1")
6211 (const_string "*")))
6212 (set_attr "mode" "<MODE>")])
6213
6214 (define_insn "*addqi_ext_1_rex64"
6215 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6216 (const_int 8)
6217 (const_int 8))
6218 (plus:SI
6219 (zero_extract:SI
6220 (match_operand 1 "ext_register_operand" "0")
6221 (const_int 8)
6222 (const_int 8))
6223 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6224 (clobber (reg:CC FLAGS_REG))]
6225 "TARGET_64BIT"
6226 {
6227 switch (get_attr_type (insn))
6228 {
6229 case TYPE_INCDEC:
6230 if (operands[2] == const1_rtx)
6231 return "inc{b}\t%h0";
6232 else
6233 {
6234 gcc_assert (operands[2] == constm1_rtx);
6235 return "dec{b}\t%h0";
6236 }
6237
6238 default:
6239 return "add{b}\t{%2, %h0|%h0, %2}";
6240 }
6241 }
6242 [(set (attr "type")
6243 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6244 (const_string "incdec")
6245 (const_string "alu")))
6246 (set_attr "modrm" "1")
6247 (set_attr "mode" "QI")])
6248
6249 (define_insn "addqi_ext_1"
6250 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6251 (const_int 8)
6252 (const_int 8))
6253 (plus:SI
6254 (zero_extract:SI
6255 (match_operand 1 "ext_register_operand" "0")
6256 (const_int 8)
6257 (const_int 8))
6258 (match_operand:QI 2 "general_operand" "Qmn")))
6259 (clobber (reg:CC FLAGS_REG))]
6260 "!TARGET_64BIT"
6261 {
6262 switch (get_attr_type (insn))
6263 {
6264 case TYPE_INCDEC:
6265 if (operands[2] == const1_rtx)
6266 return "inc{b}\t%h0";
6267 else
6268 {
6269 gcc_assert (operands[2] == constm1_rtx);
6270 return "dec{b}\t%h0";
6271 }
6272
6273 default:
6274 return "add{b}\t{%2, %h0|%h0, %2}";
6275 }
6276 }
6277 [(set (attr "type")
6278 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6279 (const_string "incdec")
6280 (const_string "alu")))
6281 (set_attr "modrm" "1")
6282 (set_attr "mode" "QI")])
6283
6284 (define_insn "*addqi_ext_2"
6285 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6286 (const_int 8)
6287 (const_int 8))
6288 (plus:SI
6289 (zero_extract:SI
6290 (match_operand 1 "ext_register_operand" "%0")
6291 (const_int 8)
6292 (const_int 8))
6293 (zero_extract:SI
6294 (match_operand 2 "ext_register_operand" "Q")
6295 (const_int 8)
6296 (const_int 8))))
6297 (clobber (reg:CC FLAGS_REG))]
6298 ""
6299 "add{b}\t{%h2, %h0|%h0, %h2}"
6300 [(set_attr "type" "alu")
6301 (set_attr "mode" "QI")])
6302
6303 ;; The lea patterns for non-Pmodes needs to be matched by
6304 ;; several insns converted to real lea by splitters.
6305
6306 (define_insn_and_split "*lea_general_1"
6307 [(set (match_operand 0 "register_operand" "=r")
6308 (plus (plus (match_operand 1 "index_register_operand" "l")
6309 (match_operand 2 "register_operand" "r"))
6310 (match_operand 3 "immediate_operand" "i")))]
6311 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6312 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6313 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6314 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6315 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6316 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6317 || GET_MODE (operands[3]) == VOIDmode)"
6318 "#"
6319 "&& reload_completed"
6320 [(const_int 0)]
6321 {
6322 rtx pat;
6323 operands[0] = gen_lowpart (SImode, operands[0]);
6324 operands[1] = gen_lowpart (Pmode, operands[1]);
6325 operands[2] = gen_lowpart (Pmode, operands[2]);
6326 operands[3] = gen_lowpart (Pmode, operands[3]);
6327 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6328 operands[3]);
6329 if (Pmode != SImode)
6330 pat = gen_rtx_SUBREG (SImode, pat, 0);
6331 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6332 DONE;
6333 }
6334 [(set_attr "type" "lea")
6335 (set_attr "mode" "SI")])
6336
6337 (define_insn_and_split "*lea_general_1_zext"
6338 [(set (match_operand:DI 0 "register_operand" "=r")
6339 (zero_extend:DI
6340 (plus:SI (plus:SI
6341 (match_operand:SI 1 "index_register_operand" "l")
6342 (match_operand:SI 2 "register_operand" "r"))
6343 (match_operand:SI 3 "immediate_operand" "i"))))]
6344 "TARGET_64BIT"
6345 "#"
6346 "&& reload_completed"
6347 [(set (match_dup 0)
6348 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6349 (match_dup 2))
6350 (match_dup 3)) 0)))]
6351 {
6352 operands[1] = gen_lowpart (Pmode, operands[1]);
6353 operands[2] = gen_lowpart (Pmode, operands[2]);
6354 operands[3] = gen_lowpart (Pmode, operands[3]);
6355 }
6356 [(set_attr "type" "lea")
6357 (set_attr "mode" "SI")])
6358
6359 (define_insn_and_split "*lea_general_2"
6360 [(set (match_operand 0 "register_operand" "=r")
6361 (plus (mult (match_operand 1 "index_register_operand" "l")
6362 (match_operand 2 "const248_operand" "i"))
6363 (match_operand 3 "nonmemory_operand" "ri")))]
6364 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6365 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6366 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6367 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6368 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6369 || GET_MODE (operands[3]) == VOIDmode)"
6370 "#"
6371 "&& reload_completed"
6372 [(const_int 0)]
6373 {
6374 rtx pat;
6375 operands[0] = gen_lowpart (SImode, operands[0]);
6376 operands[1] = gen_lowpart (Pmode, operands[1]);
6377 operands[3] = gen_lowpart (Pmode, operands[3]);
6378 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6379 operands[3]);
6380 if (Pmode != SImode)
6381 pat = gen_rtx_SUBREG (SImode, pat, 0);
6382 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6383 DONE;
6384 }
6385 [(set_attr "type" "lea")
6386 (set_attr "mode" "SI")])
6387
6388 (define_insn_and_split "*lea_general_2_zext"
6389 [(set (match_operand:DI 0 "register_operand" "=r")
6390 (zero_extend:DI
6391 (plus:SI (mult:SI
6392 (match_operand:SI 1 "index_register_operand" "l")
6393 (match_operand:SI 2 "const248_operand" "n"))
6394 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6395 "TARGET_64BIT"
6396 "#"
6397 "&& reload_completed"
6398 [(set (match_dup 0)
6399 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6400 (match_dup 2))
6401 (match_dup 3)) 0)))]
6402 {
6403 operands[1] = gen_lowpart (Pmode, operands[1]);
6404 operands[3] = gen_lowpart (Pmode, operands[3]);
6405 }
6406 [(set_attr "type" "lea")
6407 (set_attr "mode" "SI")])
6408
6409 (define_insn_and_split "*lea_general_3"
6410 [(set (match_operand 0 "register_operand" "=r")
6411 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6412 (match_operand 2 "const248_operand" "i"))
6413 (match_operand 3 "register_operand" "r"))
6414 (match_operand 4 "immediate_operand" "i")))]
6415 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6416 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6417 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6418 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6419 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6420 "#"
6421 "&& reload_completed"
6422 [(const_int 0)]
6423 {
6424 rtx pat;
6425 operands[0] = gen_lowpart (SImode, operands[0]);
6426 operands[1] = gen_lowpart (Pmode, operands[1]);
6427 operands[3] = gen_lowpart (Pmode, operands[3]);
6428 operands[4] = gen_lowpart (Pmode, operands[4]);
6429 pat = gen_rtx_PLUS (Pmode,
6430 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6431 operands[2]),
6432 operands[3]),
6433 operands[4]);
6434 if (Pmode != SImode)
6435 pat = gen_rtx_SUBREG (SImode, pat, 0);
6436 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6437 DONE;
6438 }
6439 [(set_attr "type" "lea")
6440 (set_attr "mode" "SI")])
6441
6442 (define_insn_and_split "*lea_general_3_zext"
6443 [(set (match_operand:DI 0 "register_operand" "=r")
6444 (zero_extend:DI
6445 (plus:SI (plus:SI
6446 (mult:SI
6447 (match_operand:SI 1 "index_register_operand" "l")
6448 (match_operand:SI 2 "const248_operand" "n"))
6449 (match_operand:SI 3 "register_operand" "r"))
6450 (match_operand:SI 4 "immediate_operand" "i"))))]
6451 "TARGET_64BIT"
6452 "#"
6453 "&& reload_completed"
6454 [(set (match_dup 0)
6455 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6456 (match_dup 2))
6457 (match_dup 3))
6458 (match_dup 4)) 0)))]
6459 {
6460 operands[1] = gen_lowpart (Pmode, operands[1]);
6461 operands[3] = gen_lowpart (Pmode, operands[3]);
6462 operands[4] = gen_lowpart (Pmode, operands[4]);
6463 }
6464 [(set_attr "type" "lea")
6465 (set_attr "mode" "SI")])
6466 \f
6467 ;; Subtract instructions
6468
6469 (define_expand "sub<mode>3"
6470 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6471 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6472 (match_operand:SDWIM 2 "<general_operand>" "")))]
6473 ""
6474 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6475
6476 (define_insn_and_split "*sub<dwi>3_doubleword"
6477 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6478 (minus:<DWI>
6479 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6480 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6481 (clobber (reg:CC FLAGS_REG))]
6482 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6483 "#"
6484 "reload_completed"
6485 [(parallel [(set (reg:CC FLAGS_REG)
6486 (compare:CC (match_dup 1) (match_dup 2)))
6487 (set (match_dup 0)
6488 (minus:DWIH (match_dup 1) (match_dup 2)))])
6489 (parallel [(set (match_dup 3)
6490 (minus:DWIH
6491 (match_dup 4)
6492 (plus:DWIH
6493 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6494 (match_dup 5))))
6495 (clobber (reg:CC FLAGS_REG))])]
6496 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6497
6498 (define_insn "*sub<mode>_1"
6499 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6500 (minus:SWI
6501 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6502 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6503 (clobber (reg:CC FLAGS_REG))]
6504 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6505 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6506 [(set_attr "type" "alu")
6507 (set_attr "mode" "<MODE>")])
6508
6509 (define_insn "*subsi_1_zext"
6510 [(set (match_operand:DI 0 "register_operand" "=r")
6511 (zero_extend:DI
6512 (minus:SI (match_operand:SI 1 "register_operand" "0")
6513 (match_operand:SI 2 "general_operand" "g"))))
6514 (clobber (reg:CC FLAGS_REG))]
6515 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6516 "sub{l}\t{%2, %k0|%k0, %2}"
6517 [(set_attr "type" "alu")
6518 (set_attr "mode" "SI")])
6519
6520 (define_insn "*subqi_1_slp"
6521 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6522 (minus:QI (match_dup 0)
6523 (match_operand:QI 1 "general_operand" "qn,qm")))
6524 (clobber (reg:CC FLAGS_REG))]
6525 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6526 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6527 "sub{b}\t{%1, %0|%0, %1}"
6528 [(set_attr "type" "alu1")
6529 (set_attr "mode" "QI")])
6530
6531 (define_insn "*sub<mode>_2"
6532 [(set (reg FLAGS_REG)
6533 (compare
6534 (minus:SWI
6535 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6536 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6537 (const_int 0)))
6538 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6539 (minus:SWI (match_dup 1) (match_dup 2)))]
6540 "ix86_match_ccmode (insn, CCGOCmode)
6541 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6542 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6543 [(set_attr "type" "alu")
6544 (set_attr "mode" "<MODE>")])
6545
6546 (define_insn "*subsi_2_zext"
6547 [(set (reg FLAGS_REG)
6548 (compare
6549 (minus:SI (match_operand:SI 1 "register_operand" "0")
6550 (match_operand:SI 2 "general_operand" "g"))
6551 (const_int 0)))
6552 (set (match_operand:DI 0 "register_operand" "=r")
6553 (zero_extend:DI
6554 (minus:SI (match_dup 1)
6555 (match_dup 2))))]
6556 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6557 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6558 "sub{l}\t{%2, %k0|%k0, %2}"
6559 [(set_attr "type" "alu")
6560 (set_attr "mode" "SI")])
6561
6562 (define_insn "*sub<mode>_3"
6563 [(set (reg FLAGS_REG)
6564 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6565 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6566 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6567 (minus:SWI (match_dup 1) (match_dup 2)))]
6568 "ix86_match_ccmode (insn, CCmode)
6569 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6570 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6571 [(set_attr "type" "alu")
6572 (set_attr "mode" "<MODE>")])
6573
6574 (define_insn "*subsi_3_zext"
6575 [(set (reg FLAGS_REG)
6576 (compare (match_operand:SI 1 "register_operand" "0")
6577 (match_operand:SI 2 "general_operand" "g")))
6578 (set (match_operand:DI 0 "register_operand" "=r")
6579 (zero_extend:DI
6580 (minus:SI (match_dup 1)
6581 (match_dup 2))))]
6582 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6583 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6584 "sub{l}\t{%2, %1|%1, %2}"
6585 [(set_attr "type" "alu")
6586 (set_attr "mode" "SI")])
6587 \f
6588 ;; Add with carry and subtract with borrow
6589
6590 (define_expand "<plusminus_insn><mode>3_carry"
6591 [(parallel
6592 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6593 (plusminus:SWI
6594 (match_operand:SWI 1 "nonimmediate_operand" "")
6595 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6596 [(match_operand 3 "flags_reg_operand" "")
6597 (const_int 0)])
6598 (match_operand:SWI 2 "<general_operand>" ""))))
6599 (clobber (reg:CC FLAGS_REG))])]
6600 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6601
6602 (define_insn "*<plusminus_insn><mode>3_carry"
6603 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6604 (plusminus:SWI
6605 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6606 (plus:SWI
6607 (match_operator 3 "ix86_carry_flag_operator"
6608 [(reg FLAGS_REG) (const_int 0)])
6609 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6610 (clobber (reg:CC FLAGS_REG))]
6611 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6612 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6613 [(set_attr "type" "alu")
6614 (set_attr "use_carry" "1")
6615 (set_attr "pent_pair" "pu")
6616 (set_attr "mode" "<MODE>")])
6617
6618 (define_insn "*addsi3_carry_zext"
6619 [(set (match_operand:DI 0 "register_operand" "=r")
6620 (zero_extend:DI
6621 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6622 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6623 [(reg FLAGS_REG) (const_int 0)])
6624 (match_operand:SI 2 "general_operand" "g")))))
6625 (clobber (reg:CC FLAGS_REG))]
6626 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6627 "adc{l}\t{%2, %k0|%k0, %2}"
6628 [(set_attr "type" "alu")
6629 (set_attr "use_carry" "1")
6630 (set_attr "pent_pair" "pu")
6631 (set_attr "mode" "SI")])
6632
6633 (define_insn "*subsi3_carry_zext"
6634 [(set (match_operand:DI 0 "register_operand" "=r")
6635 (zero_extend:DI
6636 (minus:SI (match_operand:SI 1 "register_operand" "0")
6637 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6638 [(reg FLAGS_REG) (const_int 0)])
6639 (match_operand:SI 2 "general_operand" "g")))))
6640 (clobber (reg:CC FLAGS_REG))]
6641 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6642 "sbb{l}\t{%2, %k0|%k0, %2}"
6643 [(set_attr "type" "alu")
6644 (set_attr "pent_pair" "pu")
6645 (set_attr "mode" "SI")])
6646 \f
6647 ;; Overflow setting add and subtract instructions
6648
6649 (define_insn "*add<mode>3_cconly_overflow"
6650 [(set (reg:CCC FLAGS_REG)
6651 (compare:CCC
6652 (plus:SWI
6653 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6654 (match_operand:SWI 2 "<general_operand>" "<g>"))
6655 (match_dup 1)))
6656 (clobber (match_scratch:SWI 0 "=<r>"))]
6657 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6658 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6659 [(set_attr "type" "alu")
6660 (set_attr "mode" "<MODE>")])
6661
6662 (define_insn "*sub<mode>3_cconly_overflow"
6663 [(set (reg:CCC FLAGS_REG)
6664 (compare:CCC
6665 (minus:SWI
6666 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6667 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6668 (match_dup 0)))]
6669 ""
6670 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6671 [(set_attr "type" "icmp")
6672 (set_attr "mode" "<MODE>")])
6673
6674 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6675 [(set (reg:CCC FLAGS_REG)
6676 (compare:CCC
6677 (plusminus:SWI
6678 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6679 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6680 (match_dup 1)))
6681 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6682 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6683 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6684 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6685 [(set_attr "type" "alu")
6686 (set_attr "mode" "<MODE>")])
6687
6688 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6689 [(set (reg:CCC FLAGS_REG)
6690 (compare:CCC
6691 (plusminus:SI
6692 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6693 (match_operand:SI 2 "general_operand" "g"))
6694 (match_dup 1)))
6695 (set (match_operand:DI 0 "register_operand" "=r")
6696 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6697 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6698 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6699 [(set_attr "type" "alu")
6700 (set_attr "mode" "SI")])
6701
6702 ;; The patterns that match these are at the end of this file.
6703
6704 (define_expand "<plusminus_insn>xf3"
6705 [(set (match_operand:XF 0 "register_operand" "")
6706 (plusminus:XF
6707 (match_operand:XF 1 "register_operand" "")
6708 (match_operand:XF 2 "register_operand" "")))]
6709 "TARGET_80387")
6710
6711 (define_expand "<plusminus_insn><mode>3"
6712 [(set (match_operand:MODEF 0 "register_operand" "")
6713 (plusminus:MODEF
6714 (match_operand:MODEF 1 "register_operand" "")
6715 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6716 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6717 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6718 \f
6719 ;; Multiply instructions
6720
6721 (define_expand "mul<mode>3"
6722 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6723 (mult:SWIM248
6724 (match_operand:SWIM248 1 "register_operand" "")
6725 (match_operand:SWIM248 2 "<general_operand>" "")))
6726 (clobber (reg:CC FLAGS_REG))])])
6727
6728 (define_expand "mulqi3"
6729 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6730 (mult:QI
6731 (match_operand:QI 1 "register_operand" "")
6732 (match_operand:QI 2 "nonimmediate_operand" "")))
6733 (clobber (reg:CC FLAGS_REG))])]
6734 "TARGET_QIMODE_MATH")
6735
6736 ;; On AMDFAM10
6737 ;; IMUL reg32/64, reg32/64, imm8 Direct
6738 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6739 ;; IMUL reg32/64, reg32/64, imm32 Direct
6740 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6741 ;; IMUL reg32/64, reg32/64 Direct
6742 ;; IMUL reg32/64, mem32/64 Direct
6743 ;;
6744 ;; On BDVER1, all above IMULs use DirectPath
6745
6746 (define_insn "*mul<mode>3_1"
6747 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6748 (mult:SWI48
6749 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6750 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6751 (clobber (reg:CC FLAGS_REG))]
6752 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6753 "@
6754 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6755 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6756 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6757 [(set_attr "type" "imul")
6758 (set_attr "prefix_0f" "0,0,1")
6759 (set (attr "athlon_decode")
6760 (cond [(eq_attr "cpu" "athlon")
6761 (const_string "vector")
6762 (eq_attr "alternative" "1")
6763 (const_string "vector")
6764 (and (eq_attr "alternative" "2")
6765 (match_operand 1 "memory_operand" ""))
6766 (const_string "vector")]
6767 (const_string "direct")))
6768 (set (attr "amdfam10_decode")
6769 (cond [(and (eq_attr "alternative" "0,1")
6770 (match_operand 1 "memory_operand" ""))
6771 (const_string "vector")]
6772 (const_string "direct")))
6773 (set_attr "bdver1_decode" "direct")
6774 (set_attr "mode" "<MODE>")])
6775
6776 (define_insn "*mulsi3_1_zext"
6777 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6778 (zero_extend:DI
6779 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6780 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6781 (clobber (reg:CC FLAGS_REG))]
6782 "TARGET_64BIT
6783 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6784 "@
6785 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6786 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6787 imul{l}\t{%2, %k0|%k0, %2}"
6788 [(set_attr "type" "imul")
6789 (set_attr "prefix_0f" "0,0,1")
6790 (set (attr "athlon_decode")
6791 (cond [(eq_attr "cpu" "athlon")
6792 (const_string "vector")
6793 (eq_attr "alternative" "1")
6794 (const_string "vector")
6795 (and (eq_attr "alternative" "2")
6796 (match_operand 1 "memory_operand" ""))
6797 (const_string "vector")]
6798 (const_string "direct")))
6799 (set (attr "amdfam10_decode")
6800 (cond [(and (eq_attr "alternative" "0,1")
6801 (match_operand 1 "memory_operand" ""))
6802 (const_string "vector")]
6803 (const_string "direct")))
6804 (set_attr "bdver1_decode" "direct")
6805 (set_attr "mode" "SI")])
6806
6807 ;; On AMDFAM10
6808 ;; IMUL reg16, reg16, imm8 VectorPath
6809 ;; IMUL reg16, mem16, imm8 VectorPath
6810 ;; IMUL reg16, reg16, imm16 VectorPath
6811 ;; IMUL reg16, mem16, imm16 VectorPath
6812 ;; IMUL reg16, reg16 Direct
6813 ;; IMUL reg16, mem16 Direct
6814 ;;
6815 ;; On BDVER1, all HI MULs use DoublePath
6816
6817 (define_insn "*mulhi3_1"
6818 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6819 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6820 (match_operand:HI 2 "general_operand" "K,n,mr")))
6821 (clobber (reg:CC FLAGS_REG))]
6822 "TARGET_HIMODE_MATH
6823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6824 "@
6825 imul{w}\t{%2, %1, %0|%0, %1, %2}
6826 imul{w}\t{%2, %1, %0|%0, %1, %2}
6827 imul{w}\t{%2, %0|%0, %2}"
6828 [(set_attr "type" "imul")
6829 (set_attr "prefix_0f" "0,0,1")
6830 (set (attr "athlon_decode")
6831 (cond [(eq_attr "cpu" "athlon")
6832 (const_string "vector")
6833 (eq_attr "alternative" "1,2")
6834 (const_string "vector")]
6835 (const_string "direct")))
6836 (set (attr "amdfam10_decode")
6837 (cond [(eq_attr "alternative" "0,1")
6838 (const_string "vector")]
6839 (const_string "direct")))
6840 (set_attr "bdver1_decode" "double")
6841 (set_attr "mode" "HI")])
6842
6843 ;;On AMDFAM10 and BDVER1
6844 ;; MUL reg8 Direct
6845 ;; MUL mem8 Direct
6846
6847 (define_insn "*mulqi3_1"
6848 [(set (match_operand:QI 0 "register_operand" "=a")
6849 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6850 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6851 (clobber (reg:CC FLAGS_REG))]
6852 "TARGET_QIMODE_MATH
6853 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6854 "mul{b}\t%2"
6855 [(set_attr "type" "imul")
6856 (set_attr "length_immediate" "0")
6857 (set (attr "athlon_decode")
6858 (if_then_else (eq_attr "cpu" "athlon")
6859 (const_string "vector")
6860 (const_string "direct")))
6861 (set_attr "amdfam10_decode" "direct")
6862 (set_attr "bdver1_decode" "direct")
6863 (set_attr "mode" "QI")])
6864
6865 (define_expand "<u>mul<mode><dwi>3"
6866 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6867 (mult:<DWI>
6868 (any_extend:<DWI>
6869 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6870 (any_extend:<DWI>
6871 (match_operand:DWIH 2 "register_operand" ""))))
6872 (clobber (reg:CC FLAGS_REG))])])
6873
6874 (define_expand "<u>mulqihi3"
6875 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6876 (mult:HI
6877 (any_extend:HI
6878 (match_operand:QI 1 "nonimmediate_operand" ""))
6879 (any_extend:HI
6880 (match_operand:QI 2 "register_operand" ""))))
6881 (clobber (reg:CC FLAGS_REG))])]
6882 "TARGET_QIMODE_MATH")
6883
6884 (define_insn "*<u>mul<mode><dwi>3_1"
6885 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6886 (mult:<DWI>
6887 (any_extend:<DWI>
6888 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6889 (any_extend:<DWI>
6890 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6891 (clobber (reg:CC FLAGS_REG))]
6892 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6893 "<sgnprefix>mul{<imodesuffix>}\t%2"
6894 [(set_attr "type" "imul")
6895 (set_attr "length_immediate" "0")
6896 (set (attr "athlon_decode")
6897 (if_then_else (eq_attr "cpu" "athlon")
6898 (const_string "vector")
6899 (const_string "double")))
6900 (set_attr "amdfam10_decode" "double")
6901 (set_attr "bdver1_decode" "direct")
6902 (set_attr "mode" "<MODE>")])
6903
6904 (define_insn "*<u>mulqihi3_1"
6905 [(set (match_operand:HI 0 "register_operand" "=a")
6906 (mult:HI
6907 (any_extend:HI
6908 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6909 (any_extend:HI
6910 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6911 (clobber (reg:CC FLAGS_REG))]
6912 "TARGET_QIMODE_MATH
6913 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6914 "<sgnprefix>mul{b}\t%2"
6915 [(set_attr "type" "imul")
6916 (set_attr "length_immediate" "0")
6917 (set (attr "athlon_decode")
6918 (if_then_else (eq_attr "cpu" "athlon")
6919 (const_string "vector")
6920 (const_string "direct")))
6921 (set_attr "amdfam10_decode" "direct")
6922 (set_attr "bdver1_decode" "direct")
6923 (set_attr "mode" "QI")])
6924
6925 (define_expand "<s>mul<mode>3_highpart"
6926 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6927 (truncate:SWI48
6928 (lshiftrt:<DWI>
6929 (mult:<DWI>
6930 (any_extend:<DWI>
6931 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6932 (any_extend:<DWI>
6933 (match_operand:SWI48 2 "register_operand" "")))
6934 (match_dup 4))))
6935 (clobber (match_scratch:SWI48 3 ""))
6936 (clobber (reg:CC FLAGS_REG))])]
6937 ""
6938 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6939
6940 (define_insn "*<s>muldi3_highpart_1"
6941 [(set (match_operand:DI 0 "register_operand" "=d")
6942 (truncate:DI
6943 (lshiftrt:TI
6944 (mult:TI
6945 (any_extend:TI
6946 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6947 (any_extend:TI
6948 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6949 (const_int 64))))
6950 (clobber (match_scratch:DI 3 "=1"))
6951 (clobber (reg:CC FLAGS_REG))]
6952 "TARGET_64BIT
6953 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6954 "<sgnprefix>mul{q}\t%2"
6955 [(set_attr "type" "imul")
6956 (set_attr "length_immediate" "0")
6957 (set (attr "athlon_decode")
6958 (if_then_else (eq_attr "cpu" "athlon")
6959 (const_string "vector")
6960 (const_string "double")))
6961 (set_attr "amdfam10_decode" "double")
6962 (set_attr "bdver1_decode" "direct")
6963 (set_attr "mode" "DI")])
6964
6965 (define_insn "*<s>mulsi3_highpart_1"
6966 [(set (match_operand:SI 0 "register_operand" "=d")
6967 (truncate:SI
6968 (lshiftrt:DI
6969 (mult:DI
6970 (any_extend:DI
6971 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6972 (any_extend:DI
6973 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6974 (const_int 32))))
6975 (clobber (match_scratch:SI 3 "=1"))
6976 (clobber (reg:CC FLAGS_REG))]
6977 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6978 "<sgnprefix>mul{l}\t%2"
6979 [(set_attr "type" "imul")
6980 (set_attr "length_immediate" "0")
6981 (set (attr "athlon_decode")
6982 (if_then_else (eq_attr "cpu" "athlon")
6983 (const_string "vector")
6984 (const_string "double")))
6985 (set_attr "amdfam10_decode" "double")
6986 (set_attr "bdver1_decode" "direct")
6987 (set_attr "mode" "SI")])
6988
6989 (define_insn "*<s>mulsi3_highpart_zext"
6990 [(set (match_operand:DI 0 "register_operand" "=d")
6991 (zero_extend:DI (truncate:SI
6992 (lshiftrt:DI
6993 (mult:DI (any_extend:DI
6994 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6995 (any_extend:DI
6996 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6997 (const_int 32)))))
6998 (clobber (match_scratch:SI 3 "=1"))
6999 (clobber (reg:CC FLAGS_REG))]
7000 "TARGET_64BIT
7001 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7002 "<sgnprefix>mul{l}\t%2"
7003 [(set_attr "type" "imul")
7004 (set_attr "length_immediate" "0")
7005 (set (attr "athlon_decode")
7006 (if_then_else (eq_attr "cpu" "athlon")
7007 (const_string "vector")
7008 (const_string "double")))
7009 (set_attr "amdfam10_decode" "double")
7010 (set_attr "bdver1_decode" "direct")
7011 (set_attr "mode" "SI")])
7012
7013 ;; The patterns that match these are at the end of this file.
7014
7015 (define_expand "mulxf3"
7016 [(set (match_operand:XF 0 "register_operand" "")
7017 (mult:XF (match_operand:XF 1 "register_operand" "")
7018 (match_operand:XF 2 "register_operand" "")))]
7019 "TARGET_80387")
7020
7021 (define_expand "mul<mode>3"
7022 [(set (match_operand:MODEF 0 "register_operand" "")
7023 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7024 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7025 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7026 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7027 \f
7028 ;; Divide instructions
7029
7030 ;; The patterns that match these are at the end of this file.
7031
7032 (define_expand "divxf3"
7033 [(set (match_operand:XF 0 "register_operand" "")
7034 (div:XF (match_operand:XF 1 "register_operand" "")
7035 (match_operand:XF 2 "register_operand" "")))]
7036 "TARGET_80387")
7037
7038 (define_expand "divdf3"
7039 [(set (match_operand:DF 0 "register_operand" "")
7040 (div:DF (match_operand:DF 1 "register_operand" "")
7041 (match_operand:DF 2 "nonimmediate_operand" "")))]
7042 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7043 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7044
7045 (define_expand "divsf3"
7046 [(set (match_operand:SF 0 "register_operand" "")
7047 (div:SF (match_operand:SF 1 "register_operand" "")
7048 (match_operand:SF 2 "nonimmediate_operand" "")))]
7049 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7050 || TARGET_SSE_MATH"
7051 {
7052 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7053 && flag_finite_math_only && !flag_trapping_math
7054 && flag_unsafe_math_optimizations)
7055 {
7056 ix86_emit_swdivsf (operands[0], operands[1],
7057 operands[2], SFmode);
7058 DONE;
7059 }
7060 })
7061 \f
7062 ;; Divmod instructions.
7063
7064 (define_expand "divmod<mode>4"
7065 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7066 (div:SWIM248
7067 (match_operand:SWIM248 1 "register_operand" "")
7068 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7069 (set (match_operand:SWIM248 3 "register_operand" "")
7070 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7071 (clobber (reg:CC FLAGS_REG))])])
7072
7073 ;; Split with 8bit unsigned divide:
7074 ;; if (dividend an divisor are in [0-255])
7075 ;; use 8bit unsigned integer divide
7076 ;; else
7077 ;; use original integer divide
7078 (define_split
7079 [(set (match_operand:SWI48 0 "register_operand" "")
7080 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7081 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7082 (set (match_operand:SWI48 1 "register_operand" "")
7083 (mod:SWI48 (match_dup 2) (match_dup 3)))
7084 (clobber (reg:CC FLAGS_REG))]
7085 "TARGET_USE_8BIT_IDIV
7086 && TARGET_QIMODE_MATH
7087 && can_create_pseudo_p ()
7088 && !optimize_insn_for_size_p ()"
7089 [(const_int 0)]
7090 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7091
7092 (define_insn_and_split "divmod<mode>4_1"
7093 [(set (match_operand:SWI48 0 "register_operand" "=a")
7094 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7095 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7096 (set (match_operand:SWI48 1 "register_operand" "=&d")
7097 (mod:SWI48 (match_dup 2) (match_dup 3)))
7098 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7099 (clobber (reg:CC FLAGS_REG))]
7100 ""
7101 "#"
7102 "reload_completed"
7103 [(parallel [(set (match_dup 1)
7104 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7105 (clobber (reg:CC FLAGS_REG))])
7106 (parallel [(set (match_dup 0)
7107 (div:SWI48 (match_dup 2) (match_dup 3)))
7108 (set (match_dup 1)
7109 (mod:SWI48 (match_dup 2) (match_dup 3)))
7110 (use (match_dup 1))
7111 (clobber (reg:CC FLAGS_REG))])]
7112 {
7113 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7114
7115 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7116 operands[4] = operands[2];
7117 else
7118 {
7119 /* Avoid use of cltd in favor of a mov+shift. */
7120 emit_move_insn (operands[1], operands[2]);
7121 operands[4] = operands[1];
7122 }
7123 }
7124 [(set_attr "type" "multi")
7125 (set_attr "mode" "<MODE>")])
7126
7127 (define_insn_and_split "*divmod<mode>4"
7128 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7129 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7130 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7131 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7132 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7133 (clobber (reg:CC FLAGS_REG))]
7134 ""
7135 "#"
7136 "reload_completed"
7137 [(parallel [(set (match_dup 1)
7138 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7139 (clobber (reg:CC FLAGS_REG))])
7140 (parallel [(set (match_dup 0)
7141 (div:SWIM248 (match_dup 2) (match_dup 3)))
7142 (set (match_dup 1)
7143 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7144 (use (match_dup 1))
7145 (clobber (reg:CC FLAGS_REG))])]
7146 {
7147 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7148
7149 if (<MODE>mode != HImode
7150 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7151 operands[4] = operands[2];
7152 else
7153 {
7154 /* Avoid use of cltd in favor of a mov+shift. */
7155 emit_move_insn (operands[1], operands[2]);
7156 operands[4] = operands[1];
7157 }
7158 }
7159 [(set_attr "type" "multi")
7160 (set_attr "mode" "<MODE>")])
7161
7162 (define_insn "*divmod<mode>4_noext"
7163 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7164 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7165 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7166 (set (match_operand:SWIM248 1 "register_operand" "=d")
7167 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7168 (use (match_operand:SWIM248 4 "register_operand" "1"))
7169 (clobber (reg:CC FLAGS_REG))]
7170 ""
7171 "idiv{<imodesuffix>}\t%3"
7172 [(set_attr "type" "idiv")
7173 (set_attr "mode" "<MODE>")])
7174
7175 (define_expand "divmodqi4"
7176 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7177 (div:QI
7178 (match_operand:QI 1 "register_operand" "")
7179 (match_operand:QI 2 "nonimmediate_operand" "")))
7180 (set (match_operand:QI 3 "register_operand" "")
7181 (mod:QI (match_dup 1) (match_dup 2)))
7182 (clobber (reg:CC FLAGS_REG))])]
7183 "TARGET_QIMODE_MATH"
7184 {
7185 rtx div, mod, insn;
7186 rtx tmp0, tmp1;
7187
7188 tmp0 = gen_reg_rtx (HImode);
7189 tmp1 = gen_reg_rtx (HImode);
7190
7191 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7192 in AX. */
7193 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7194 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7195
7196 /* Extract remainder from AH. */
7197 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7198 insn = emit_move_insn (operands[3], tmp1);
7199
7200 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7201 set_unique_reg_note (insn, REG_EQUAL, mod);
7202
7203 /* Extract quotient from AL. */
7204 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7205
7206 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7207 set_unique_reg_note (insn, REG_EQUAL, div);
7208
7209 DONE;
7210 })
7211
7212 ;; Divide AX by r/m8, with result stored in
7213 ;; AL <- Quotient
7214 ;; AH <- Remainder
7215 ;; Change div/mod to HImode and extend the second argument to HImode
7216 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7217 ;; combine may fail.
7218 (define_insn "divmodhiqi3"
7219 [(set (match_operand:HI 0 "register_operand" "=a")
7220 (ior:HI
7221 (ashift:HI
7222 (zero_extend:HI
7223 (truncate:QI
7224 (mod:HI (match_operand:HI 1 "register_operand" "0")
7225 (sign_extend:HI
7226 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7227 (const_int 8))
7228 (zero_extend:HI
7229 (truncate:QI
7230 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7231 (clobber (reg:CC FLAGS_REG))]
7232 "TARGET_QIMODE_MATH"
7233 "idiv{b}\t%2"
7234 [(set_attr "type" "idiv")
7235 (set_attr "mode" "QI")])
7236
7237 (define_expand "udivmod<mode>4"
7238 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7239 (udiv:SWIM248
7240 (match_operand:SWIM248 1 "register_operand" "")
7241 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7242 (set (match_operand:SWIM248 3 "register_operand" "")
7243 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7244 (clobber (reg:CC FLAGS_REG))])])
7245
7246 ;; Split with 8bit unsigned divide:
7247 ;; if (dividend an divisor are in [0-255])
7248 ;; use 8bit unsigned integer divide
7249 ;; else
7250 ;; use original integer divide
7251 (define_split
7252 [(set (match_operand:SWI48 0 "register_operand" "")
7253 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7254 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7255 (set (match_operand:SWI48 1 "register_operand" "")
7256 (umod:SWI48 (match_dup 2) (match_dup 3)))
7257 (clobber (reg:CC FLAGS_REG))]
7258 "TARGET_USE_8BIT_IDIV
7259 && TARGET_QIMODE_MATH
7260 && can_create_pseudo_p ()
7261 && !optimize_insn_for_size_p ()"
7262 [(const_int 0)]
7263 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7264
7265 (define_insn_and_split "udivmod<mode>4_1"
7266 [(set (match_operand:SWI48 0 "register_operand" "=a")
7267 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7268 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7269 (set (match_operand:SWI48 1 "register_operand" "=&d")
7270 (umod:SWI48 (match_dup 2) (match_dup 3)))
7271 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7272 (clobber (reg:CC FLAGS_REG))]
7273 ""
7274 "#"
7275 "reload_completed"
7276 [(set (match_dup 1) (const_int 0))
7277 (parallel [(set (match_dup 0)
7278 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7279 (set (match_dup 1)
7280 (umod:SWI48 (match_dup 2) (match_dup 3)))
7281 (use (match_dup 1))
7282 (clobber (reg:CC FLAGS_REG))])]
7283 ""
7284 [(set_attr "type" "multi")
7285 (set_attr "mode" "<MODE>")])
7286
7287 (define_insn_and_split "*udivmod<mode>4"
7288 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7289 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7290 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7291 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7292 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7293 (clobber (reg:CC FLAGS_REG))]
7294 ""
7295 "#"
7296 "reload_completed"
7297 [(set (match_dup 1) (const_int 0))
7298 (parallel [(set (match_dup 0)
7299 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7300 (set (match_dup 1)
7301 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7302 (use (match_dup 1))
7303 (clobber (reg:CC FLAGS_REG))])]
7304 ""
7305 [(set_attr "type" "multi")
7306 (set_attr "mode" "<MODE>")])
7307
7308 (define_insn "*udivmod<mode>4_noext"
7309 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7310 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7311 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7312 (set (match_operand:SWIM248 1 "register_operand" "=d")
7313 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7314 (use (match_operand:SWIM248 4 "register_operand" "1"))
7315 (clobber (reg:CC FLAGS_REG))]
7316 ""
7317 "div{<imodesuffix>}\t%3"
7318 [(set_attr "type" "idiv")
7319 (set_attr "mode" "<MODE>")])
7320
7321 (define_expand "udivmodqi4"
7322 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7323 (udiv:QI
7324 (match_operand:QI 1 "register_operand" "")
7325 (match_operand:QI 2 "nonimmediate_operand" "")))
7326 (set (match_operand:QI 3 "register_operand" "")
7327 (umod:QI (match_dup 1) (match_dup 2)))
7328 (clobber (reg:CC FLAGS_REG))])]
7329 "TARGET_QIMODE_MATH"
7330 {
7331 rtx div, mod, insn;
7332 rtx tmp0, tmp1;
7333
7334 tmp0 = gen_reg_rtx (HImode);
7335 tmp1 = gen_reg_rtx (HImode);
7336
7337 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7338 in AX. */
7339 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7340 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7341
7342 /* Extract remainder from AH. */
7343 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7344 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7345 insn = emit_move_insn (operands[3], tmp1);
7346
7347 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7348 set_unique_reg_note (insn, REG_EQUAL, mod);
7349
7350 /* Extract quotient from AL. */
7351 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7352
7353 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7354 set_unique_reg_note (insn, REG_EQUAL, div);
7355
7356 DONE;
7357 })
7358
7359 (define_insn "udivmodhiqi3"
7360 [(set (match_operand:HI 0 "register_operand" "=a")
7361 (ior:HI
7362 (ashift:HI
7363 (zero_extend:HI
7364 (truncate:QI
7365 (mod:HI (match_operand:HI 1 "register_operand" "0")
7366 (zero_extend:HI
7367 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7368 (const_int 8))
7369 (zero_extend:HI
7370 (truncate:QI
7371 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7372 (clobber (reg:CC FLAGS_REG))]
7373 "TARGET_QIMODE_MATH"
7374 "div{b}\t%2"
7375 [(set_attr "type" "idiv")
7376 (set_attr "mode" "QI")])
7377
7378 ;; We cannot use div/idiv for double division, because it causes
7379 ;; "division by zero" on the overflow and that's not what we expect
7380 ;; from truncate. Because true (non truncating) double division is
7381 ;; never generated, we can't create this insn anyway.
7382 ;
7383 ;(define_insn ""
7384 ; [(set (match_operand:SI 0 "register_operand" "=a")
7385 ; (truncate:SI
7386 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7387 ; (zero_extend:DI
7388 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7389 ; (set (match_operand:SI 3 "register_operand" "=d")
7390 ; (truncate:SI
7391 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7392 ; (clobber (reg:CC FLAGS_REG))]
7393 ; ""
7394 ; "div{l}\t{%2, %0|%0, %2}"
7395 ; [(set_attr "type" "idiv")])
7396 \f
7397 ;;- Logical AND instructions
7398
7399 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7400 ;; Note that this excludes ah.
7401
7402 (define_expand "testsi_ccno_1"
7403 [(set (reg:CCNO FLAGS_REG)
7404 (compare:CCNO
7405 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7406 (match_operand:SI 1 "nonmemory_operand" ""))
7407 (const_int 0)))])
7408
7409 (define_expand "testqi_ccz_1"
7410 [(set (reg:CCZ FLAGS_REG)
7411 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7412 (match_operand:QI 1 "nonmemory_operand" ""))
7413 (const_int 0)))])
7414
7415 (define_expand "testdi_ccno_1"
7416 [(set (reg:CCNO FLAGS_REG)
7417 (compare:CCNO
7418 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7419 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7420 (const_int 0)))]
7421 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7422
7423 (define_insn "*testdi_1"
7424 [(set (reg FLAGS_REG)
7425 (compare
7426 (and:DI
7427 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7428 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7429 (const_int 0)))]
7430 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7431 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7432 "@
7433 test{l}\t{%k1, %k0|%k0, %k1}
7434 test{l}\t{%k1, %k0|%k0, %k1}
7435 test{q}\t{%1, %0|%0, %1}
7436 test{q}\t{%1, %0|%0, %1}
7437 test{q}\t{%1, %0|%0, %1}"
7438 [(set_attr "type" "test")
7439 (set_attr "modrm" "0,1,0,1,1")
7440 (set_attr "mode" "SI,SI,DI,DI,DI")])
7441
7442 (define_insn "*testqi_1_maybe_si"
7443 [(set (reg FLAGS_REG)
7444 (compare
7445 (and:QI
7446 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7447 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7448 (const_int 0)))]
7449 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7450 && ix86_match_ccmode (insn,
7451 CONST_INT_P (operands[1])
7452 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7453 {
7454 if (which_alternative == 3)
7455 {
7456 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7457 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7458 return "test{l}\t{%1, %k0|%k0, %1}";
7459 }
7460 return "test{b}\t{%1, %0|%0, %1}";
7461 }
7462 [(set_attr "type" "test")
7463 (set_attr "modrm" "0,1,1,1")
7464 (set_attr "mode" "QI,QI,QI,SI")
7465 (set_attr "pent_pair" "uv,np,uv,np")])
7466
7467 (define_insn "*test<mode>_1"
7468 [(set (reg FLAGS_REG)
7469 (compare
7470 (and:SWI124
7471 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7472 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7473 (const_int 0)))]
7474 "ix86_match_ccmode (insn, CCNOmode)
7475 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7476 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7477 [(set_attr "type" "test")
7478 (set_attr "modrm" "0,1,1")
7479 (set_attr "mode" "<MODE>")
7480 (set_attr "pent_pair" "uv,np,uv")])
7481
7482 (define_expand "testqi_ext_ccno_0"
7483 [(set (reg:CCNO FLAGS_REG)
7484 (compare:CCNO
7485 (and:SI
7486 (zero_extract:SI
7487 (match_operand 0 "ext_register_operand" "")
7488 (const_int 8)
7489 (const_int 8))
7490 (match_operand 1 "const_int_operand" ""))
7491 (const_int 0)))])
7492
7493 (define_insn "*testqi_ext_0"
7494 [(set (reg FLAGS_REG)
7495 (compare
7496 (and:SI
7497 (zero_extract:SI
7498 (match_operand 0 "ext_register_operand" "Q")
7499 (const_int 8)
7500 (const_int 8))
7501 (match_operand 1 "const_int_operand" "n"))
7502 (const_int 0)))]
7503 "ix86_match_ccmode (insn, CCNOmode)"
7504 "test{b}\t{%1, %h0|%h0, %1}"
7505 [(set_attr "type" "test")
7506 (set_attr "mode" "QI")
7507 (set_attr "length_immediate" "1")
7508 (set_attr "modrm" "1")
7509 (set_attr "pent_pair" "np")])
7510
7511 (define_insn "*testqi_ext_1_rex64"
7512 [(set (reg FLAGS_REG)
7513 (compare
7514 (and:SI
7515 (zero_extract:SI
7516 (match_operand 0 "ext_register_operand" "Q")
7517 (const_int 8)
7518 (const_int 8))
7519 (zero_extend:SI
7520 (match_operand:QI 1 "register_operand" "Q")))
7521 (const_int 0)))]
7522 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7523 "test{b}\t{%1, %h0|%h0, %1}"
7524 [(set_attr "type" "test")
7525 (set_attr "mode" "QI")])
7526
7527 (define_insn "*testqi_ext_1"
7528 [(set (reg FLAGS_REG)
7529 (compare
7530 (and:SI
7531 (zero_extract:SI
7532 (match_operand 0 "ext_register_operand" "Q")
7533 (const_int 8)
7534 (const_int 8))
7535 (zero_extend:SI
7536 (match_operand:QI 1 "general_operand" "Qm")))
7537 (const_int 0)))]
7538 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7539 "test{b}\t{%1, %h0|%h0, %1}"
7540 [(set_attr "type" "test")
7541 (set_attr "mode" "QI")])
7542
7543 (define_insn "*testqi_ext_2"
7544 [(set (reg FLAGS_REG)
7545 (compare
7546 (and:SI
7547 (zero_extract:SI
7548 (match_operand 0 "ext_register_operand" "Q")
7549 (const_int 8)
7550 (const_int 8))
7551 (zero_extract:SI
7552 (match_operand 1 "ext_register_operand" "Q")
7553 (const_int 8)
7554 (const_int 8)))
7555 (const_int 0)))]
7556 "ix86_match_ccmode (insn, CCNOmode)"
7557 "test{b}\t{%h1, %h0|%h0, %h1}"
7558 [(set_attr "type" "test")
7559 (set_attr "mode" "QI")])
7560
7561 (define_insn "*testqi_ext_3_rex64"
7562 [(set (reg FLAGS_REG)
7563 (compare (zero_extract:DI
7564 (match_operand 0 "nonimmediate_operand" "rm")
7565 (match_operand:DI 1 "const_int_operand" "")
7566 (match_operand:DI 2 "const_int_operand" ""))
7567 (const_int 0)))]
7568 "TARGET_64BIT
7569 && ix86_match_ccmode (insn, CCNOmode)
7570 && INTVAL (operands[1]) > 0
7571 && INTVAL (operands[2]) >= 0
7572 /* Ensure that resulting mask is zero or sign extended operand. */
7573 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7574 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7575 && INTVAL (operands[1]) > 32))
7576 && (GET_MODE (operands[0]) == SImode
7577 || GET_MODE (operands[0]) == DImode
7578 || GET_MODE (operands[0]) == HImode
7579 || GET_MODE (operands[0]) == QImode)"
7580 "#")
7581
7582 ;; Combine likes to form bit extractions for some tests. Humor it.
7583 (define_insn "*testqi_ext_3"
7584 [(set (reg FLAGS_REG)
7585 (compare (zero_extract:SI
7586 (match_operand 0 "nonimmediate_operand" "rm")
7587 (match_operand:SI 1 "const_int_operand" "")
7588 (match_operand:SI 2 "const_int_operand" ""))
7589 (const_int 0)))]
7590 "ix86_match_ccmode (insn, CCNOmode)
7591 && INTVAL (operands[1]) > 0
7592 && INTVAL (operands[2]) >= 0
7593 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7594 && (GET_MODE (operands[0]) == SImode
7595 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7596 || GET_MODE (operands[0]) == HImode
7597 || GET_MODE (operands[0]) == QImode)"
7598 "#")
7599
7600 (define_split
7601 [(set (match_operand 0 "flags_reg_operand" "")
7602 (match_operator 1 "compare_operator"
7603 [(zero_extract
7604 (match_operand 2 "nonimmediate_operand" "")
7605 (match_operand 3 "const_int_operand" "")
7606 (match_operand 4 "const_int_operand" ""))
7607 (const_int 0)]))]
7608 "ix86_match_ccmode (insn, CCNOmode)"
7609 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7610 {
7611 rtx val = operands[2];
7612 HOST_WIDE_INT len = INTVAL (operands[3]);
7613 HOST_WIDE_INT pos = INTVAL (operands[4]);
7614 HOST_WIDE_INT mask;
7615 enum machine_mode mode, submode;
7616
7617 mode = GET_MODE (val);
7618 if (MEM_P (val))
7619 {
7620 /* ??? Combine likes to put non-volatile mem extractions in QImode
7621 no matter the size of the test. So find a mode that works. */
7622 if (! MEM_VOLATILE_P (val))
7623 {
7624 mode = smallest_mode_for_size (pos + len, MODE_INT);
7625 val = adjust_address (val, mode, 0);
7626 }
7627 }
7628 else if (GET_CODE (val) == SUBREG
7629 && (submode = GET_MODE (SUBREG_REG (val)),
7630 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7631 && pos + len <= GET_MODE_BITSIZE (submode)
7632 && GET_MODE_CLASS (submode) == MODE_INT)
7633 {
7634 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7635 mode = submode;
7636 val = SUBREG_REG (val);
7637 }
7638 else if (mode == HImode && pos + len <= 8)
7639 {
7640 /* Small HImode tests can be converted to QImode. */
7641 mode = QImode;
7642 val = gen_lowpart (QImode, val);
7643 }
7644
7645 if (len == HOST_BITS_PER_WIDE_INT)
7646 mask = -1;
7647 else
7648 mask = ((HOST_WIDE_INT)1 << len) - 1;
7649 mask <<= pos;
7650
7651 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7652 })
7653
7654 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7655 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7656 ;; this is relatively important trick.
7657 ;; Do the conversion only post-reload to avoid limiting of the register class
7658 ;; to QI regs.
7659 (define_split
7660 [(set (match_operand 0 "flags_reg_operand" "")
7661 (match_operator 1 "compare_operator"
7662 [(and (match_operand 2 "register_operand" "")
7663 (match_operand 3 "const_int_operand" ""))
7664 (const_int 0)]))]
7665 "reload_completed
7666 && QI_REG_P (operands[2])
7667 && GET_MODE (operands[2]) != QImode
7668 && ((ix86_match_ccmode (insn, CCZmode)
7669 && !(INTVAL (operands[3]) & ~(255 << 8)))
7670 || (ix86_match_ccmode (insn, CCNOmode)
7671 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7672 [(set (match_dup 0)
7673 (match_op_dup 1
7674 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7675 (match_dup 3))
7676 (const_int 0)]))]
7677 "operands[2] = gen_lowpart (SImode, operands[2]);
7678 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7679
7680 (define_split
7681 [(set (match_operand 0 "flags_reg_operand" "")
7682 (match_operator 1 "compare_operator"
7683 [(and (match_operand 2 "nonimmediate_operand" "")
7684 (match_operand 3 "const_int_operand" ""))
7685 (const_int 0)]))]
7686 "reload_completed
7687 && GET_MODE (operands[2]) != QImode
7688 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7689 && ((ix86_match_ccmode (insn, CCZmode)
7690 && !(INTVAL (operands[3]) & ~255))
7691 || (ix86_match_ccmode (insn, CCNOmode)
7692 && !(INTVAL (operands[3]) & ~127)))"
7693 [(set (match_dup 0)
7694 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7695 (const_int 0)]))]
7696 "operands[2] = gen_lowpart (QImode, operands[2]);
7697 operands[3] = gen_lowpart (QImode, operands[3]);")
7698
7699 ;; %%% This used to optimize known byte-wide and operations to memory,
7700 ;; and sometimes to QImode registers. If this is considered useful,
7701 ;; it should be done with splitters.
7702
7703 (define_expand "and<mode>3"
7704 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7705 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7706 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7707 ""
7708 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7709
7710 (define_insn "*anddi_1"
7711 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7712 (and:DI
7713 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7714 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7715 (clobber (reg:CC FLAGS_REG))]
7716 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7717 {
7718 switch (get_attr_type (insn))
7719 {
7720 case TYPE_IMOVX:
7721 {
7722 enum machine_mode mode;
7723
7724 gcc_assert (CONST_INT_P (operands[2]));
7725 if (INTVAL (operands[2]) == 0xff)
7726 mode = QImode;
7727 else
7728 {
7729 gcc_assert (INTVAL (operands[2]) == 0xffff);
7730 mode = HImode;
7731 }
7732
7733 operands[1] = gen_lowpart (mode, operands[1]);
7734 if (mode == QImode)
7735 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7736 else
7737 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7738 }
7739
7740 default:
7741 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7742 if (get_attr_mode (insn) == MODE_SI)
7743 return "and{l}\t{%k2, %k0|%k0, %k2}";
7744 else
7745 return "and{q}\t{%2, %0|%0, %2}";
7746 }
7747 }
7748 [(set_attr "type" "alu,alu,alu,imovx")
7749 (set_attr "length_immediate" "*,*,*,0")
7750 (set (attr "prefix_rex")
7751 (if_then_else
7752 (and (eq_attr "type" "imovx")
7753 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7754 (match_operand 1 "ext_QIreg_operand" "")))
7755 (const_string "1")
7756 (const_string "*")))
7757 (set_attr "mode" "SI,DI,DI,SI")])
7758
7759 (define_insn "*andsi_1"
7760 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7761 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7762 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7763 (clobber (reg:CC FLAGS_REG))]
7764 "ix86_binary_operator_ok (AND, SImode, operands)"
7765 {
7766 switch (get_attr_type (insn))
7767 {
7768 case TYPE_IMOVX:
7769 {
7770 enum machine_mode mode;
7771
7772 gcc_assert (CONST_INT_P (operands[2]));
7773 if (INTVAL (operands[2]) == 0xff)
7774 mode = QImode;
7775 else
7776 {
7777 gcc_assert (INTVAL (operands[2]) == 0xffff);
7778 mode = HImode;
7779 }
7780
7781 operands[1] = gen_lowpart (mode, operands[1]);
7782 if (mode == QImode)
7783 return "movz{bl|x}\t{%1, %0|%0, %1}";
7784 else
7785 return "movz{wl|x}\t{%1, %0|%0, %1}";
7786 }
7787
7788 default:
7789 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7790 return "and{l}\t{%2, %0|%0, %2}";
7791 }
7792 }
7793 [(set_attr "type" "alu,alu,imovx")
7794 (set (attr "prefix_rex")
7795 (if_then_else
7796 (and (eq_attr "type" "imovx")
7797 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7798 (match_operand 1 "ext_QIreg_operand" "")))
7799 (const_string "1")
7800 (const_string "*")))
7801 (set_attr "length_immediate" "*,*,0")
7802 (set_attr "mode" "SI")])
7803
7804 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7805 (define_insn "*andsi_1_zext"
7806 [(set (match_operand:DI 0 "register_operand" "=r")
7807 (zero_extend:DI
7808 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7809 (match_operand:SI 2 "general_operand" "g"))))
7810 (clobber (reg:CC FLAGS_REG))]
7811 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7812 "and{l}\t{%2, %k0|%k0, %2}"
7813 [(set_attr "type" "alu")
7814 (set_attr "mode" "SI")])
7815
7816 (define_insn "*andhi_1"
7817 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7818 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7819 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7820 (clobber (reg:CC FLAGS_REG))]
7821 "ix86_binary_operator_ok (AND, HImode, operands)"
7822 {
7823 switch (get_attr_type (insn))
7824 {
7825 case TYPE_IMOVX:
7826 gcc_assert (CONST_INT_P (operands[2]));
7827 gcc_assert (INTVAL (operands[2]) == 0xff);
7828 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7829
7830 default:
7831 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7832
7833 return "and{w}\t{%2, %0|%0, %2}";
7834 }
7835 }
7836 [(set_attr "type" "alu,alu,imovx")
7837 (set_attr "length_immediate" "*,*,0")
7838 (set (attr "prefix_rex")
7839 (if_then_else
7840 (and (eq_attr "type" "imovx")
7841 (match_operand 1 "ext_QIreg_operand" ""))
7842 (const_string "1")
7843 (const_string "*")))
7844 (set_attr "mode" "HI,HI,SI")])
7845
7846 ;; %%% Potential partial reg stall on alternative 2. What to do?
7847 (define_insn "*andqi_1"
7848 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7849 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7850 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7851 (clobber (reg:CC FLAGS_REG))]
7852 "ix86_binary_operator_ok (AND, QImode, operands)"
7853 "@
7854 and{b}\t{%2, %0|%0, %2}
7855 and{b}\t{%2, %0|%0, %2}
7856 and{l}\t{%k2, %k0|%k0, %k2}"
7857 [(set_attr "type" "alu")
7858 (set_attr "mode" "QI,QI,SI")])
7859
7860 (define_insn "*andqi_1_slp"
7861 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7862 (and:QI (match_dup 0)
7863 (match_operand:QI 1 "general_operand" "qn,qmn")))
7864 (clobber (reg:CC FLAGS_REG))]
7865 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7866 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7867 "and{b}\t{%1, %0|%0, %1}"
7868 [(set_attr "type" "alu1")
7869 (set_attr "mode" "QI")])
7870
7871 (define_split
7872 [(set (match_operand 0 "register_operand" "")
7873 (and (match_dup 0)
7874 (const_int -65536)))
7875 (clobber (reg:CC FLAGS_REG))]
7876 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7877 || optimize_function_for_size_p (cfun)"
7878 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7879 "operands[1] = gen_lowpart (HImode, operands[0]);")
7880
7881 (define_split
7882 [(set (match_operand 0 "ext_register_operand" "")
7883 (and (match_dup 0)
7884 (const_int -256)))
7885 (clobber (reg:CC FLAGS_REG))]
7886 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7887 && reload_completed"
7888 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7889 "operands[1] = gen_lowpart (QImode, operands[0]);")
7890
7891 (define_split
7892 [(set (match_operand 0 "ext_register_operand" "")
7893 (and (match_dup 0)
7894 (const_int -65281)))
7895 (clobber (reg:CC FLAGS_REG))]
7896 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7897 && reload_completed"
7898 [(parallel [(set (zero_extract:SI (match_dup 0)
7899 (const_int 8)
7900 (const_int 8))
7901 (xor:SI
7902 (zero_extract:SI (match_dup 0)
7903 (const_int 8)
7904 (const_int 8))
7905 (zero_extract:SI (match_dup 0)
7906 (const_int 8)
7907 (const_int 8))))
7908 (clobber (reg:CC FLAGS_REG))])]
7909 "operands[0] = gen_lowpart (SImode, operands[0]);")
7910
7911 (define_insn "*anddi_2"
7912 [(set (reg FLAGS_REG)
7913 (compare
7914 (and:DI
7915 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7916 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7917 (const_int 0)))
7918 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7919 (and:DI (match_dup 1) (match_dup 2)))]
7920 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7921 && ix86_binary_operator_ok (AND, DImode, operands)"
7922 "@
7923 and{l}\t{%k2, %k0|%k0, %k2}
7924 and{q}\t{%2, %0|%0, %2}
7925 and{q}\t{%2, %0|%0, %2}"
7926 [(set_attr "type" "alu")
7927 (set_attr "mode" "SI,DI,DI")])
7928
7929 (define_insn "*andqi_2_maybe_si"
7930 [(set (reg FLAGS_REG)
7931 (compare (and:QI
7932 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7933 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7934 (const_int 0)))
7935 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7936 (and:QI (match_dup 1) (match_dup 2)))]
7937 "ix86_binary_operator_ok (AND, QImode, operands)
7938 && ix86_match_ccmode (insn,
7939 CONST_INT_P (operands[2])
7940 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7941 {
7942 if (which_alternative == 2)
7943 {
7944 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7945 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7946 return "and{l}\t{%2, %k0|%k0, %2}";
7947 }
7948 return "and{b}\t{%2, %0|%0, %2}";
7949 }
7950 [(set_attr "type" "alu")
7951 (set_attr "mode" "QI,QI,SI")])
7952
7953 (define_insn "*and<mode>_2"
7954 [(set (reg FLAGS_REG)
7955 (compare (and:SWI124
7956 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7957 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7958 (const_int 0)))
7959 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7960 (and:SWI124 (match_dup 1) (match_dup 2)))]
7961 "ix86_match_ccmode (insn, CCNOmode)
7962 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7963 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7964 [(set_attr "type" "alu")
7965 (set_attr "mode" "<MODE>")])
7966
7967 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7968 (define_insn "*andsi_2_zext"
7969 [(set (reg FLAGS_REG)
7970 (compare (and:SI
7971 (match_operand:SI 1 "nonimmediate_operand" "%0")
7972 (match_operand:SI 2 "general_operand" "g"))
7973 (const_int 0)))
7974 (set (match_operand:DI 0 "register_operand" "=r")
7975 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7976 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7977 && ix86_binary_operator_ok (AND, SImode, operands)"
7978 "and{l}\t{%2, %k0|%k0, %2}"
7979 [(set_attr "type" "alu")
7980 (set_attr "mode" "SI")])
7981
7982 (define_insn "*andqi_2_slp"
7983 [(set (reg FLAGS_REG)
7984 (compare (and:QI
7985 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7986 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7987 (const_int 0)))
7988 (set (strict_low_part (match_dup 0))
7989 (and:QI (match_dup 0) (match_dup 1)))]
7990 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7991 && ix86_match_ccmode (insn, CCNOmode)
7992 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7993 "and{b}\t{%1, %0|%0, %1}"
7994 [(set_attr "type" "alu1")
7995 (set_attr "mode" "QI")])
7996
7997 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7998 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7999 ;; for a QImode operand, which of course failed.
8000 (define_insn "andqi_ext_0"
8001 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8002 (const_int 8)
8003 (const_int 8))
8004 (and:SI
8005 (zero_extract:SI
8006 (match_operand 1 "ext_register_operand" "0")
8007 (const_int 8)
8008 (const_int 8))
8009 (match_operand 2 "const_int_operand" "n")))
8010 (clobber (reg:CC FLAGS_REG))]
8011 ""
8012 "and{b}\t{%2, %h0|%h0, %2}"
8013 [(set_attr "type" "alu")
8014 (set_attr "length_immediate" "1")
8015 (set_attr "modrm" "1")
8016 (set_attr "mode" "QI")])
8017
8018 ;; Generated by peephole translating test to and. This shows up
8019 ;; often in fp comparisons.
8020 (define_insn "*andqi_ext_0_cc"
8021 [(set (reg FLAGS_REG)
8022 (compare
8023 (and:SI
8024 (zero_extract:SI
8025 (match_operand 1 "ext_register_operand" "0")
8026 (const_int 8)
8027 (const_int 8))
8028 (match_operand 2 "const_int_operand" "n"))
8029 (const_int 0)))
8030 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8031 (const_int 8)
8032 (const_int 8))
8033 (and:SI
8034 (zero_extract:SI
8035 (match_dup 1)
8036 (const_int 8)
8037 (const_int 8))
8038 (match_dup 2)))]
8039 "ix86_match_ccmode (insn, CCNOmode)"
8040 "and{b}\t{%2, %h0|%h0, %2}"
8041 [(set_attr "type" "alu")
8042 (set_attr "length_immediate" "1")
8043 (set_attr "modrm" "1")
8044 (set_attr "mode" "QI")])
8045
8046 (define_insn "*andqi_ext_1_rex64"
8047 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8048 (const_int 8)
8049 (const_int 8))
8050 (and:SI
8051 (zero_extract:SI
8052 (match_operand 1 "ext_register_operand" "0")
8053 (const_int 8)
8054 (const_int 8))
8055 (zero_extend:SI
8056 (match_operand 2 "ext_register_operand" "Q"))))
8057 (clobber (reg:CC FLAGS_REG))]
8058 "TARGET_64BIT"
8059 "and{b}\t{%2, %h0|%h0, %2}"
8060 [(set_attr "type" "alu")
8061 (set_attr "length_immediate" "0")
8062 (set_attr "mode" "QI")])
8063
8064 (define_insn "*andqi_ext_1"
8065 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8066 (const_int 8)
8067 (const_int 8))
8068 (and:SI
8069 (zero_extract:SI
8070 (match_operand 1 "ext_register_operand" "0")
8071 (const_int 8)
8072 (const_int 8))
8073 (zero_extend:SI
8074 (match_operand:QI 2 "general_operand" "Qm"))))
8075 (clobber (reg:CC FLAGS_REG))]
8076 "!TARGET_64BIT"
8077 "and{b}\t{%2, %h0|%h0, %2}"
8078 [(set_attr "type" "alu")
8079 (set_attr "length_immediate" "0")
8080 (set_attr "mode" "QI")])
8081
8082 (define_insn "*andqi_ext_2"
8083 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8084 (const_int 8)
8085 (const_int 8))
8086 (and:SI
8087 (zero_extract:SI
8088 (match_operand 1 "ext_register_operand" "%0")
8089 (const_int 8)
8090 (const_int 8))
8091 (zero_extract:SI
8092 (match_operand 2 "ext_register_operand" "Q")
8093 (const_int 8)
8094 (const_int 8))))
8095 (clobber (reg:CC FLAGS_REG))]
8096 ""
8097 "and{b}\t{%h2, %h0|%h0, %h2}"
8098 [(set_attr "type" "alu")
8099 (set_attr "length_immediate" "0")
8100 (set_attr "mode" "QI")])
8101
8102 ;; Convert wide AND instructions with immediate operand to shorter QImode
8103 ;; equivalents when possible.
8104 ;; Don't do the splitting with memory operands, since it introduces risk
8105 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8106 ;; for size, but that can (should?) be handled by generic code instead.
8107 (define_split
8108 [(set (match_operand 0 "register_operand" "")
8109 (and (match_operand 1 "register_operand" "")
8110 (match_operand 2 "const_int_operand" "")))
8111 (clobber (reg:CC FLAGS_REG))]
8112 "reload_completed
8113 && QI_REG_P (operands[0])
8114 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8115 && !(~INTVAL (operands[2]) & ~(255 << 8))
8116 && GET_MODE (operands[0]) != QImode"
8117 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8118 (and:SI (zero_extract:SI (match_dup 1)
8119 (const_int 8) (const_int 8))
8120 (match_dup 2)))
8121 (clobber (reg:CC FLAGS_REG))])]
8122 "operands[0] = gen_lowpart (SImode, operands[0]);
8123 operands[1] = gen_lowpart (SImode, operands[1]);
8124 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8125
8126 ;; Since AND can be encoded with sign extended immediate, this is only
8127 ;; profitable when 7th bit is not set.
8128 (define_split
8129 [(set (match_operand 0 "register_operand" "")
8130 (and (match_operand 1 "general_operand" "")
8131 (match_operand 2 "const_int_operand" "")))
8132 (clobber (reg:CC FLAGS_REG))]
8133 "reload_completed
8134 && ANY_QI_REG_P (operands[0])
8135 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8136 && !(~INTVAL (operands[2]) & ~255)
8137 && !(INTVAL (operands[2]) & 128)
8138 && GET_MODE (operands[0]) != QImode"
8139 [(parallel [(set (strict_low_part (match_dup 0))
8140 (and:QI (match_dup 1)
8141 (match_dup 2)))
8142 (clobber (reg:CC FLAGS_REG))])]
8143 "operands[0] = gen_lowpart (QImode, operands[0]);
8144 operands[1] = gen_lowpart (QImode, operands[1]);
8145 operands[2] = gen_lowpart (QImode, operands[2]);")
8146 \f
8147 ;; Logical inclusive and exclusive OR instructions
8148
8149 ;; %%% This used to optimize known byte-wide and operations to memory.
8150 ;; If this is considered useful, it should be done with splitters.
8151
8152 (define_expand "<code><mode>3"
8153 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8154 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8155 (match_operand:SWIM 2 "<general_operand>" "")))]
8156 ""
8157 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8158
8159 (define_insn "*<code><mode>_1"
8160 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8161 (any_or:SWI248
8162 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8163 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8164 (clobber (reg:CC FLAGS_REG))]
8165 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8166 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8167 [(set_attr "type" "alu")
8168 (set_attr "mode" "<MODE>")])
8169
8170 ;; %%% Potential partial reg stall on alternative 2. What to do?
8171 (define_insn "*<code>qi_1"
8172 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8173 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8174 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8177 "@
8178 <logic>{b}\t{%2, %0|%0, %2}
8179 <logic>{b}\t{%2, %0|%0, %2}
8180 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8181 [(set_attr "type" "alu")
8182 (set_attr "mode" "QI,QI,SI")])
8183
8184 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8185 (define_insn "*<code>si_1_zext"
8186 [(set (match_operand:DI 0 "register_operand" "=r")
8187 (zero_extend:DI
8188 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8189 (match_operand:SI 2 "general_operand" "g"))))
8190 (clobber (reg:CC FLAGS_REG))]
8191 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8192 "<logic>{l}\t{%2, %k0|%k0, %2}"
8193 [(set_attr "type" "alu")
8194 (set_attr "mode" "SI")])
8195
8196 (define_insn "*<code>si_1_zext_imm"
8197 [(set (match_operand:DI 0 "register_operand" "=r")
8198 (any_or:DI
8199 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8200 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8201 (clobber (reg:CC FLAGS_REG))]
8202 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8203 "<logic>{l}\t{%2, %k0|%k0, %2}"
8204 [(set_attr "type" "alu")
8205 (set_attr "mode" "SI")])
8206
8207 (define_insn "*<code>qi_1_slp"
8208 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8209 (any_or:QI (match_dup 0)
8210 (match_operand:QI 1 "general_operand" "qmn,qn")))
8211 (clobber (reg:CC FLAGS_REG))]
8212 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8213 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8214 "<logic>{b}\t{%1, %0|%0, %1}"
8215 [(set_attr "type" "alu1")
8216 (set_attr "mode" "QI")])
8217
8218 (define_insn "*<code><mode>_2"
8219 [(set (reg FLAGS_REG)
8220 (compare (any_or:SWI
8221 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8222 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8223 (const_int 0)))
8224 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8225 (any_or:SWI (match_dup 1) (match_dup 2)))]
8226 "ix86_match_ccmode (insn, CCNOmode)
8227 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8228 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8229 [(set_attr "type" "alu")
8230 (set_attr "mode" "<MODE>")])
8231
8232 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8233 ;; ??? Special case for immediate operand is missing - it is tricky.
8234 (define_insn "*<code>si_2_zext"
8235 [(set (reg FLAGS_REG)
8236 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8237 (match_operand:SI 2 "general_operand" "g"))
8238 (const_int 0)))
8239 (set (match_operand:DI 0 "register_operand" "=r")
8240 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8241 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8242 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8243 "<logic>{l}\t{%2, %k0|%k0, %2}"
8244 [(set_attr "type" "alu")
8245 (set_attr "mode" "SI")])
8246
8247 (define_insn "*<code>si_2_zext_imm"
8248 [(set (reg FLAGS_REG)
8249 (compare (any_or:SI
8250 (match_operand:SI 1 "nonimmediate_operand" "%0")
8251 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8252 (const_int 0)))
8253 (set (match_operand:DI 0 "register_operand" "=r")
8254 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8255 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8256 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8257 "<logic>{l}\t{%2, %k0|%k0, %2}"
8258 [(set_attr "type" "alu")
8259 (set_attr "mode" "SI")])
8260
8261 (define_insn "*<code>qi_2_slp"
8262 [(set (reg FLAGS_REG)
8263 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8264 (match_operand:QI 1 "general_operand" "qmn,qn"))
8265 (const_int 0)))
8266 (set (strict_low_part (match_dup 0))
8267 (any_or:QI (match_dup 0) (match_dup 1)))]
8268 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8269 && ix86_match_ccmode (insn, CCNOmode)
8270 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8271 "<logic>{b}\t{%1, %0|%0, %1}"
8272 [(set_attr "type" "alu1")
8273 (set_attr "mode" "QI")])
8274
8275 (define_insn "*<code><mode>_3"
8276 [(set (reg FLAGS_REG)
8277 (compare (any_or:SWI
8278 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8279 (match_operand:SWI 2 "<general_operand>" "<g>"))
8280 (const_int 0)))
8281 (clobber (match_scratch:SWI 0 "=<r>"))]
8282 "ix86_match_ccmode (insn, CCNOmode)
8283 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8284 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8285 [(set_attr "type" "alu")
8286 (set_attr "mode" "<MODE>")])
8287
8288 (define_insn "*<code>qi_ext_0"
8289 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8290 (const_int 8)
8291 (const_int 8))
8292 (any_or:SI
8293 (zero_extract:SI
8294 (match_operand 1 "ext_register_operand" "0")
8295 (const_int 8)
8296 (const_int 8))
8297 (match_operand 2 "const_int_operand" "n")))
8298 (clobber (reg:CC FLAGS_REG))]
8299 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8300 "<logic>{b}\t{%2, %h0|%h0, %2}"
8301 [(set_attr "type" "alu")
8302 (set_attr "length_immediate" "1")
8303 (set_attr "modrm" "1")
8304 (set_attr "mode" "QI")])
8305
8306 (define_insn "*<code>qi_ext_1_rex64"
8307 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8308 (const_int 8)
8309 (const_int 8))
8310 (any_or:SI
8311 (zero_extract:SI
8312 (match_operand 1 "ext_register_operand" "0")
8313 (const_int 8)
8314 (const_int 8))
8315 (zero_extend:SI
8316 (match_operand 2 "ext_register_operand" "Q"))))
8317 (clobber (reg:CC FLAGS_REG))]
8318 "TARGET_64BIT
8319 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8320 "<logic>{b}\t{%2, %h0|%h0, %2}"
8321 [(set_attr "type" "alu")
8322 (set_attr "length_immediate" "0")
8323 (set_attr "mode" "QI")])
8324
8325 (define_insn "*<code>qi_ext_1"
8326 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8327 (const_int 8)
8328 (const_int 8))
8329 (any_or:SI
8330 (zero_extract:SI
8331 (match_operand 1 "ext_register_operand" "0")
8332 (const_int 8)
8333 (const_int 8))
8334 (zero_extend:SI
8335 (match_operand:QI 2 "general_operand" "Qm"))))
8336 (clobber (reg:CC FLAGS_REG))]
8337 "!TARGET_64BIT
8338 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8339 "<logic>{b}\t{%2, %h0|%h0, %2}"
8340 [(set_attr "type" "alu")
8341 (set_attr "length_immediate" "0")
8342 (set_attr "mode" "QI")])
8343
8344 (define_insn "*<code>qi_ext_2"
8345 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8346 (const_int 8)
8347 (const_int 8))
8348 (any_or:SI
8349 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8350 (const_int 8)
8351 (const_int 8))
8352 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8353 (const_int 8)
8354 (const_int 8))))
8355 (clobber (reg:CC FLAGS_REG))]
8356 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8357 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8358 [(set_attr "type" "alu")
8359 (set_attr "length_immediate" "0")
8360 (set_attr "mode" "QI")])
8361
8362 (define_split
8363 [(set (match_operand 0 "register_operand" "")
8364 (any_or (match_operand 1 "register_operand" "")
8365 (match_operand 2 "const_int_operand" "")))
8366 (clobber (reg:CC FLAGS_REG))]
8367 "reload_completed
8368 && QI_REG_P (operands[0])
8369 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8370 && !(INTVAL (operands[2]) & ~(255 << 8))
8371 && GET_MODE (operands[0]) != QImode"
8372 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8373 (any_or:SI (zero_extract:SI (match_dup 1)
8374 (const_int 8) (const_int 8))
8375 (match_dup 2)))
8376 (clobber (reg:CC FLAGS_REG))])]
8377 "operands[0] = gen_lowpart (SImode, operands[0]);
8378 operands[1] = gen_lowpart (SImode, operands[1]);
8379 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8380
8381 ;; Since OR can be encoded with sign extended immediate, this is only
8382 ;; profitable when 7th bit is set.
8383 (define_split
8384 [(set (match_operand 0 "register_operand" "")
8385 (any_or (match_operand 1 "general_operand" "")
8386 (match_operand 2 "const_int_operand" "")))
8387 (clobber (reg:CC FLAGS_REG))]
8388 "reload_completed
8389 && ANY_QI_REG_P (operands[0])
8390 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8391 && !(INTVAL (operands[2]) & ~255)
8392 && (INTVAL (operands[2]) & 128)
8393 && GET_MODE (operands[0]) != QImode"
8394 [(parallel [(set (strict_low_part (match_dup 0))
8395 (any_or:QI (match_dup 1)
8396 (match_dup 2)))
8397 (clobber (reg:CC FLAGS_REG))])]
8398 "operands[0] = gen_lowpart (QImode, operands[0]);
8399 operands[1] = gen_lowpart (QImode, operands[1]);
8400 operands[2] = gen_lowpart (QImode, operands[2]);")
8401
8402 (define_expand "xorqi_cc_ext_1"
8403 [(parallel [
8404 (set (reg:CCNO FLAGS_REG)
8405 (compare:CCNO
8406 (xor:SI
8407 (zero_extract:SI
8408 (match_operand 1 "ext_register_operand" "")
8409 (const_int 8)
8410 (const_int 8))
8411 (match_operand:QI 2 "general_operand" ""))
8412 (const_int 0)))
8413 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8414 (const_int 8)
8415 (const_int 8))
8416 (xor:SI
8417 (zero_extract:SI
8418 (match_dup 1)
8419 (const_int 8)
8420 (const_int 8))
8421 (match_dup 2)))])])
8422
8423 (define_insn "*xorqi_cc_ext_1_rex64"
8424 [(set (reg FLAGS_REG)
8425 (compare
8426 (xor:SI
8427 (zero_extract:SI
8428 (match_operand 1 "ext_register_operand" "0")
8429 (const_int 8)
8430 (const_int 8))
8431 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8432 (const_int 0)))
8433 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8434 (const_int 8)
8435 (const_int 8))
8436 (xor:SI
8437 (zero_extract:SI
8438 (match_dup 1)
8439 (const_int 8)
8440 (const_int 8))
8441 (match_dup 2)))]
8442 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8443 "xor{b}\t{%2, %h0|%h0, %2}"
8444 [(set_attr "type" "alu")
8445 (set_attr "modrm" "1")
8446 (set_attr "mode" "QI")])
8447
8448 (define_insn "*xorqi_cc_ext_1"
8449 [(set (reg FLAGS_REG)
8450 (compare
8451 (xor:SI
8452 (zero_extract:SI
8453 (match_operand 1 "ext_register_operand" "0")
8454 (const_int 8)
8455 (const_int 8))
8456 (match_operand:QI 2 "general_operand" "qmn"))
8457 (const_int 0)))
8458 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8459 (const_int 8)
8460 (const_int 8))
8461 (xor:SI
8462 (zero_extract:SI
8463 (match_dup 1)
8464 (const_int 8)
8465 (const_int 8))
8466 (match_dup 2)))]
8467 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8468 "xor{b}\t{%2, %h0|%h0, %2}"
8469 [(set_attr "type" "alu")
8470 (set_attr "modrm" "1")
8471 (set_attr "mode" "QI")])
8472 \f
8473 ;; Negation instructions
8474
8475 (define_expand "neg<mode>2"
8476 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8477 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8478 ""
8479 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8480
8481 (define_insn_and_split "*neg<dwi>2_doubleword"
8482 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8483 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8484 (clobber (reg:CC FLAGS_REG))]
8485 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8486 "#"
8487 "reload_completed"
8488 [(parallel
8489 [(set (reg:CCZ FLAGS_REG)
8490 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8491 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8492 (parallel
8493 [(set (match_dup 2)
8494 (plus:DWIH (match_dup 3)
8495 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8496 (const_int 0))))
8497 (clobber (reg:CC FLAGS_REG))])
8498 (parallel
8499 [(set (match_dup 2)
8500 (neg:DWIH (match_dup 2)))
8501 (clobber (reg:CC FLAGS_REG))])]
8502 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8503
8504 (define_insn "*neg<mode>2_1"
8505 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8506 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8507 (clobber (reg:CC FLAGS_REG))]
8508 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8509 "neg{<imodesuffix>}\t%0"
8510 [(set_attr "type" "negnot")
8511 (set_attr "mode" "<MODE>")])
8512
8513 ;; Combine is quite creative about this pattern.
8514 (define_insn "*negsi2_1_zext"
8515 [(set (match_operand:DI 0 "register_operand" "=r")
8516 (lshiftrt:DI
8517 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8518 (const_int 32)))
8519 (const_int 32)))
8520 (clobber (reg:CC FLAGS_REG))]
8521 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8522 "neg{l}\t%k0"
8523 [(set_attr "type" "negnot")
8524 (set_attr "mode" "SI")])
8525
8526 ;; The problem with neg is that it does not perform (compare x 0),
8527 ;; it really performs (compare 0 x), which leaves us with the zero
8528 ;; flag being the only useful item.
8529
8530 (define_insn "*neg<mode>2_cmpz"
8531 [(set (reg:CCZ FLAGS_REG)
8532 (compare:CCZ
8533 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8534 (const_int 0)))
8535 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8536 (neg:SWI (match_dup 1)))]
8537 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8538 "neg{<imodesuffix>}\t%0"
8539 [(set_attr "type" "negnot")
8540 (set_attr "mode" "<MODE>")])
8541
8542 (define_insn "*negsi2_cmpz_zext"
8543 [(set (reg:CCZ FLAGS_REG)
8544 (compare:CCZ
8545 (lshiftrt:DI
8546 (neg:DI (ashift:DI
8547 (match_operand:DI 1 "register_operand" "0")
8548 (const_int 32)))
8549 (const_int 32))
8550 (const_int 0)))
8551 (set (match_operand:DI 0 "register_operand" "=r")
8552 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8553 (const_int 32)))
8554 (const_int 32)))]
8555 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8556 "neg{l}\t%k0"
8557 [(set_attr "type" "negnot")
8558 (set_attr "mode" "SI")])
8559
8560 ;; Changing of sign for FP values is doable using integer unit too.
8561
8562 (define_expand "<code><mode>2"
8563 [(set (match_operand:X87MODEF 0 "register_operand" "")
8564 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8565 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8566 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8567
8568 (define_insn "*absneg<mode>2_mixed"
8569 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8570 (match_operator:MODEF 3 "absneg_operator"
8571 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8572 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8573 (clobber (reg:CC FLAGS_REG))]
8574 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8575 "#")
8576
8577 (define_insn "*absneg<mode>2_sse"
8578 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8579 (match_operator:MODEF 3 "absneg_operator"
8580 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8581 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8582 (clobber (reg:CC FLAGS_REG))]
8583 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8584 "#")
8585
8586 (define_insn "*absneg<mode>2_i387"
8587 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8588 (match_operator:X87MODEF 3 "absneg_operator"
8589 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8590 (use (match_operand 2 "" ""))
8591 (clobber (reg:CC FLAGS_REG))]
8592 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8593 "#")
8594
8595 (define_expand "<code>tf2"
8596 [(set (match_operand:TF 0 "register_operand" "")
8597 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8598 "TARGET_SSE2"
8599 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8600
8601 (define_insn "*absnegtf2_sse"
8602 [(set (match_operand:TF 0 "register_operand" "=x,x")
8603 (match_operator:TF 3 "absneg_operator"
8604 [(match_operand:TF 1 "register_operand" "0,x")]))
8605 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8606 (clobber (reg:CC FLAGS_REG))]
8607 "TARGET_SSE2"
8608 "#")
8609
8610 ;; Splitters for fp abs and neg.
8611
8612 (define_split
8613 [(set (match_operand 0 "fp_register_operand" "")
8614 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8615 (use (match_operand 2 "" ""))
8616 (clobber (reg:CC FLAGS_REG))]
8617 "reload_completed"
8618 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8619
8620 (define_split
8621 [(set (match_operand 0 "register_operand" "")
8622 (match_operator 3 "absneg_operator"
8623 [(match_operand 1 "register_operand" "")]))
8624 (use (match_operand 2 "nonimmediate_operand" ""))
8625 (clobber (reg:CC FLAGS_REG))]
8626 "reload_completed && SSE_REG_P (operands[0])"
8627 [(set (match_dup 0) (match_dup 3))]
8628 {
8629 enum machine_mode mode = GET_MODE (operands[0]);
8630 enum machine_mode vmode = GET_MODE (operands[2]);
8631 rtx tmp;
8632
8633 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8634 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8635 if (operands_match_p (operands[0], operands[2]))
8636 {
8637 tmp = operands[1];
8638 operands[1] = operands[2];
8639 operands[2] = tmp;
8640 }
8641 if (GET_CODE (operands[3]) == ABS)
8642 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8643 else
8644 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8645 operands[3] = tmp;
8646 })
8647
8648 (define_split
8649 [(set (match_operand:SF 0 "register_operand" "")
8650 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8651 (use (match_operand:V4SF 2 "" ""))
8652 (clobber (reg:CC FLAGS_REG))]
8653 "reload_completed"
8654 [(parallel [(set (match_dup 0) (match_dup 1))
8655 (clobber (reg:CC FLAGS_REG))])]
8656 {
8657 rtx tmp;
8658 operands[0] = gen_lowpart (SImode, operands[0]);
8659 if (GET_CODE (operands[1]) == ABS)
8660 {
8661 tmp = gen_int_mode (0x7fffffff, SImode);
8662 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8663 }
8664 else
8665 {
8666 tmp = gen_int_mode (0x80000000, SImode);
8667 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8668 }
8669 operands[1] = tmp;
8670 })
8671
8672 (define_split
8673 [(set (match_operand:DF 0 "register_operand" "")
8674 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8675 (use (match_operand 2 "" ""))
8676 (clobber (reg:CC FLAGS_REG))]
8677 "reload_completed"
8678 [(parallel [(set (match_dup 0) (match_dup 1))
8679 (clobber (reg:CC FLAGS_REG))])]
8680 {
8681 rtx tmp;
8682 if (TARGET_64BIT)
8683 {
8684 tmp = gen_lowpart (DImode, operands[0]);
8685 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8686 operands[0] = tmp;
8687
8688 if (GET_CODE (operands[1]) == ABS)
8689 tmp = const0_rtx;
8690 else
8691 tmp = gen_rtx_NOT (DImode, tmp);
8692 }
8693 else
8694 {
8695 operands[0] = gen_highpart (SImode, operands[0]);
8696 if (GET_CODE (operands[1]) == ABS)
8697 {
8698 tmp = gen_int_mode (0x7fffffff, SImode);
8699 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8700 }
8701 else
8702 {
8703 tmp = gen_int_mode (0x80000000, SImode);
8704 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8705 }
8706 }
8707 operands[1] = tmp;
8708 })
8709
8710 (define_split
8711 [(set (match_operand:XF 0 "register_operand" "")
8712 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8713 (use (match_operand 2 "" ""))
8714 (clobber (reg:CC FLAGS_REG))]
8715 "reload_completed"
8716 [(parallel [(set (match_dup 0) (match_dup 1))
8717 (clobber (reg:CC FLAGS_REG))])]
8718 {
8719 rtx tmp;
8720 operands[0] = gen_rtx_REG (SImode,
8721 true_regnum (operands[0])
8722 + (TARGET_64BIT ? 1 : 2));
8723 if (GET_CODE (operands[1]) == ABS)
8724 {
8725 tmp = GEN_INT (0x7fff);
8726 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8727 }
8728 else
8729 {
8730 tmp = GEN_INT (0x8000);
8731 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8732 }
8733 operands[1] = tmp;
8734 })
8735
8736 ;; Conditionalize these after reload. If they match before reload, we
8737 ;; lose the clobber and ability to use integer instructions.
8738
8739 (define_insn "*<code><mode>2_1"
8740 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8741 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8742 "TARGET_80387
8743 && (reload_completed
8744 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8745 "f<absneg_mnemonic>"
8746 [(set_attr "type" "fsgn")
8747 (set_attr "mode" "<MODE>")])
8748
8749 (define_insn "*<code>extendsfdf2"
8750 [(set (match_operand:DF 0 "register_operand" "=f")
8751 (absneg:DF (float_extend:DF
8752 (match_operand:SF 1 "register_operand" "0"))))]
8753 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8754 "f<absneg_mnemonic>"
8755 [(set_attr "type" "fsgn")
8756 (set_attr "mode" "DF")])
8757
8758 (define_insn "*<code>extendsfxf2"
8759 [(set (match_operand:XF 0 "register_operand" "=f")
8760 (absneg:XF (float_extend:XF
8761 (match_operand:SF 1 "register_operand" "0"))))]
8762 "TARGET_80387"
8763 "f<absneg_mnemonic>"
8764 [(set_attr "type" "fsgn")
8765 (set_attr "mode" "XF")])
8766
8767 (define_insn "*<code>extenddfxf2"
8768 [(set (match_operand:XF 0 "register_operand" "=f")
8769 (absneg:XF (float_extend:XF
8770 (match_operand:DF 1 "register_operand" "0"))))]
8771 "TARGET_80387"
8772 "f<absneg_mnemonic>"
8773 [(set_attr "type" "fsgn")
8774 (set_attr "mode" "XF")])
8775
8776 ;; Copysign instructions
8777
8778 (define_mode_iterator CSGNMODE [SF DF TF])
8779 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8780
8781 (define_expand "copysign<mode>3"
8782 [(match_operand:CSGNMODE 0 "register_operand" "")
8783 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8784 (match_operand:CSGNMODE 2 "register_operand" "")]
8785 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8786 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8787 "ix86_expand_copysign (operands); DONE;")
8788
8789 (define_insn_and_split "copysign<mode>3_const"
8790 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8791 (unspec:CSGNMODE
8792 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8793 (match_operand:CSGNMODE 2 "register_operand" "0")
8794 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8795 UNSPEC_COPYSIGN))]
8796 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8797 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8798 "#"
8799 "&& reload_completed"
8800 [(const_int 0)]
8801 "ix86_split_copysign_const (operands); DONE;")
8802
8803 (define_insn "copysign<mode>3_var"
8804 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8805 (unspec:CSGNMODE
8806 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8807 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8808 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8809 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8810 UNSPEC_COPYSIGN))
8811 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8812 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8813 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8814 "#")
8815
8816 (define_split
8817 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8818 (unspec:CSGNMODE
8819 [(match_operand:CSGNMODE 2 "register_operand" "")
8820 (match_operand:CSGNMODE 3 "register_operand" "")
8821 (match_operand:<CSGNVMODE> 4 "" "")
8822 (match_operand:<CSGNVMODE> 5 "" "")]
8823 UNSPEC_COPYSIGN))
8824 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8825 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8826 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8827 && reload_completed"
8828 [(const_int 0)]
8829 "ix86_split_copysign_var (operands); DONE;")
8830 \f
8831 ;; One complement instructions
8832
8833 (define_expand "one_cmpl<mode>2"
8834 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8835 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8836 ""
8837 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8838
8839 (define_insn "*one_cmpl<mode>2_1"
8840 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8841 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8842 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8843 "not{<imodesuffix>}\t%0"
8844 [(set_attr "type" "negnot")
8845 (set_attr "mode" "<MODE>")])
8846
8847 ;; %%% Potential partial reg stall on alternative 1. What to do?
8848 (define_insn "*one_cmplqi2_1"
8849 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8850 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8851 "ix86_unary_operator_ok (NOT, QImode, operands)"
8852 "@
8853 not{b}\t%0
8854 not{l}\t%k0"
8855 [(set_attr "type" "negnot")
8856 (set_attr "mode" "QI,SI")])
8857
8858 ;; ??? Currently never generated - xor is used instead.
8859 (define_insn "*one_cmplsi2_1_zext"
8860 [(set (match_operand:DI 0 "register_operand" "=r")
8861 (zero_extend:DI
8862 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8863 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8864 "not{l}\t%k0"
8865 [(set_attr "type" "negnot")
8866 (set_attr "mode" "SI")])
8867
8868 (define_insn "*one_cmpl<mode>2_2"
8869 [(set (reg FLAGS_REG)
8870 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8871 (const_int 0)))
8872 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8873 (not:SWI (match_dup 1)))]
8874 "ix86_match_ccmode (insn, CCNOmode)
8875 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8876 "#"
8877 [(set_attr "type" "alu1")
8878 (set_attr "mode" "<MODE>")])
8879
8880 (define_split
8881 [(set (match_operand 0 "flags_reg_operand" "")
8882 (match_operator 2 "compare_operator"
8883 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8884 (const_int 0)]))
8885 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8886 (not:SWI (match_dup 3)))]
8887 "ix86_match_ccmode (insn, CCNOmode)"
8888 [(parallel [(set (match_dup 0)
8889 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8890 (const_int 0)]))
8891 (set (match_dup 1)
8892 (xor:SWI (match_dup 3) (const_int -1)))])])
8893
8894 ;; ??? Currently never generated - xor is used instead.
8895 (define_insn "*one_cmplsi2_2_zext"
8896 [(set (reg FLAGS_REG)
8897 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8898 (const_int 0)))
8899 (set (match_operand:DI 0 "register_operand" "=r")
8900 (zero_extend:DI (not:SI (match_dup 1))))]
8901 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8902 && ix86_unary_operator_ok (NOT, SImode, operands)"
8903 "#"
8904 [(set_attr "type" "alu1")
8905 (set_attr "mode" "SI")])
8906
8907 (define_split
8908 [(set (match_operand 0 "flags_reg_operand" "")
8909 (match_operator 2 "compare_operator"
8910 [(not:SI (match_operand:SI 3 "register_operand" ""))
8911 (const_int 0)]))
8912 (set (match_operand:DI 1 "register_operand" "")
8913 (zero_extend:DI (not:SI (match_dup 3))))]
8914 "ix86_match_ccmode (insn, CCNOmode)"
8915 [(parallel [(set (match_dup 0)
8916 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8917 (const_int 0)]))
8918 (set (match_dup 1)
8919 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8920 \f
8921 ;; Shift instructions
8922
8923 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8924 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8925 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8926 ;; from the assembler input.
8927 ;;
8928 ;; This instruction shifts the target reg/mem as usual, but instead of
8929 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8930 ;; is a left shift double, bits are taken from the high order bits of
8931 ;; reg, else if the insn is a shift right double, bits are taken from the
8932 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8933 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8934 ;;
8935 ;; Since sh[lr]d does not change the `reg' operand, that is done
8936 ;; separately, making all shifts emit pairs of shift double and normal
8937 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8938 ;; support a 63 bit shift, each shift where the count is in a reg expands
8939 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8940 ;;
8941 ;; If the shift count is a constant, we need never emit more than one
8942 ;; shift pair, instead using moves and sign extension for counts greater
8943 ;; than 31.
8944
8945 (define_expand "ashl<mode>3"
8946 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8947 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8948 (match_operand:QI 2 "nonmemory_operand" "")))]
8949 ""
8950 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8951
8952 (define_insn "*ashl<mode>3_doubleword"
8953 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8954 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8955 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8956 (clobber (reg:CC FLAGS_REG))]
8957 ""
8958 "#"
8959 [(set_attr "type" "multi")])
8960
8961 (define_split
8962 [(set (match_operand:DWI 0 "register_operand" "")
8963 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8964 (match_operand:QI 2 "nonmemory_operand" "")))
8965 (clobber (reg:CC FLAGS_REG))]
8966 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8967 [(const_int 0)]
8968 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8969
8970 ;; By default we don't ask for a scratch register, because when DWImode
8971 ;; values are manipulated, registers are already at a premium. But if
8972 ;; we have one handy, we won't turn it away.
8973
8974 (define_peephole2
8975 [(match_scratch:DWIH 3 "r")
8976 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8977 (ashift:<DWI>
8978 (match_operand:<DWI> 1 "nonmemory_operand" "")
8979 (match_operand:QI 2 "nonmemory_operand" "")))
8980 (clobber (reg:CC FLAGS_REG))])
8981 (match_dup 3)]
8982 "TARGET_CMOVE"
8983 [(const_int 0)]
8984 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8985
8986 (define_insn "x86_64_shld"
8987 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8988 (ior:DI (ashift:DI (match_dup 0)
8989 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8990 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8991 (minus:QI (const_int 64) (match_dup 2)))))
8992 (clobber (reg:CC FLAGS_REG))]
8993 "TARGET_64BIT"
8994 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8995 [(set_attr "type" "ishift")
8996 (set_attr "prefix_0f" "1")
8997 (set_attr "mode" "DI")
8998 (set_attr "athlon_decode" "vector")
8999 (set_attr "amdfam10_decode" "vector")
9000 (set_attr "bdver1_decode" "vector")])
9001
9002 (define_insn "x86_shld"
9003 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9004 (ior:SI (ashift:SI (match_dup 0)
9005 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9006 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9007 (minus:QI (const_int 32) (match_dup 2)))))
9008 (clobber (reg:CC FLAGS_REG))]
9009 ""
9010 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9011 [(set_attr "type" "ishift")
9012 (set_attr "prefix_0f" "1")
9013 (set_attr "mode" "SI")
9014 (set_attr "pent_pair" "np")
9015 (set_attr "athlon_decode" "vector")
9016 (set_attr "amdfam10_decode" "vector")
9017 (set_attr "bdver1_decode" "vector")])
9018
9019 (define_expand "x86_shift<mode>_adj_1"
9020 [(set (reg:CCZ FLAGS_REG)
9021 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9022 (match_dup 4))
9023 (const_int 0)))
9024 (set (match_operand:SWI48 0 "register_operand" "")
9025 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9026 (match_operand:SWI48 1 "register_operand" "")
9027 (match_dup 0)))
9028 (set (match_dup 1)
9029 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9030 (match_operand:SWI48 3 "register_operand" "r")
9031 (match_dup 1)))]
9032 "TARGET_CMOVE"
9033 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9034
9035 (define_expand "x86_shift<mode>_adj_2"
9036 [(use (match_operand:SWI48 0 "register_operand" ""))
9037 (use (match_operand:SWI48 1 "register_operand" ""))
9038 (use (match_operand:QI 2 "register_operand" ""))]
9039 ""
9040 {
9041 rtx label = gen_label_rtx ();
9042 rtx tmp;
9043
9044 emit_insn (gen_testqi_ccz_1 (operands[2],
9045 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9046
9047 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9048 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9049 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9050 gen_rtx_LABEL_REF (VOIDmode, label),
9051 pc_rtx);
9052 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9053 JUMP_LABEL (tmp) = label;
9054
9055 emit_move_insn (operands[0], operands[1]);
9056 ix86_expand_clear (operands[1]);
9057
9058 emit_label (label);
9059 LABEL_NUSES (label) = 1;
9060
9061 DONE;
9062 })
9063
9064 ;; Avoid useless masking of count operand.
9065 (define_insn_and_split "*ashl<mode>3_mask"
9066 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9067 (ashift:SWI48
9068 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9069 (subreg:QI
9070 (and:SI
9071 (match_operand:SI 2 "nonimmediate_operand" "c")
9072 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9073 (clobber (reg:CC FLAGS_REG))]
9074 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9075 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9076 == GET_MODE_BITSIZE (<MODE>mode)-1"
9077 "#"
9078 "&& 1"
9079 [(parallel [(set (match_dup 0)
9080 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9081 (clobber (reg:CC FLAGS_REG))])]
9082 {
9083 if (can_create_pseudo_p ())
9084 operands [2] = force_reg (SImode, operands[2]);
9085
9086 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9087 }
9088 [(set_attr "type" "ishift")
9089 (set_attr "mode" "<MODE>")])
9090
9091 (define_insn "*ashl<mode>3_1"
9092 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9093 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9094 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9095 (clobber (reg:CC FLAGS_REG))]
9096 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9097 {
9098 switch (get_attr_type (insn))
9099 {
9100 case TYPE_LEA:
9101 return "#";
9102
9103 case TYPE_ALU:
9104 gcc_assert (operands[2] == const1_rtx);
9105 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9106 return "add{<imodesuffix>}\t%0, %0";
9107
9108 default:
9109 if (operands[2] == const1_rtx
9110 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9111 return "sal{<imodesuffix>}\t%0";
9112 else
9113 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9114 }
9115 }
9116 [(set (attr "type")
9117 (cond [(eq_attr "alternative" "1")
9118 (const_string "lea")
9119 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9120 (const_int 0))
9121 (match_operand 0 "register_operand" ""))
9122 (match_operand 2 "const1_operand" ""))
9123 (const_string "alu")
9124 ]
9125 (const_string "ishift")))
9126 (set (attr "length_immediate")
9127 (if_then_else
9128 (ior (eq_attr "type" "alu")
9129 (and (eq_attr "type" "ishift")
9130 (and (match_operand 2 "const1_operand" "")
9131 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9132 (const_int 0)))))
9133 (const_string "0")
9134 (const_string "*")))
9135 (set_attr "mode" "<MODE>")])
9136
9137 (define_insn "*ashlsi3_1_zext"
9138 [(set (match_operand:DI 0 "register_operand" "=r,r")
9139 (zero_extend:DI
9140 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9141 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9142 (clobber (reg:CC FLAGS_REG))]
9143 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9144 {
9145 switch (get_attr_type (insn))
9146 {
9147 case TYPE_LEA:
9148 return "#";
9149
9150 case TYPE_ALU:
9151 gcc_assert (operands[2] == const1_rtx);
9152 return "add{l}\t%k0, %k0";
9153
9154 default:
9155 if (operands[2] == const1_rtx
9156 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9157 return "sal{l}\t%k0";
9158 else
9159 return "sal{l}\t{%2, %k0|%k0, %2}";
9160 }
9161 }
9162 [(set (attr "type")
9163 (cond [(eq_attr "alternative" "1")
9164 (const_string "lea")
9165 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9166 (const_int 0))
9167 (match_operand 2 "const1_operand" ""))
9168 (const_string "alu")
9169 ]
9170 (const_string "ishift")))
9171 (set (attr "length_immediate")
9172 (if_then_else
9173 (ior (eq_attr "type" "alu")
9174 (and (eq_attr "type" "ishift")
9175 (and (match_operand 2 "const1_operand" "")
9176 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9177 (const_int 0)))))
9178 (const_string "0")
9179 (const_string "*")))
9180 (set_attr "mode" "SI")])
9181
9182 (define_insn "*ashlhi3_1"
9183 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9184 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9185 (match_operand:QI 2 "nonmemory_operand" "cI")))
9186 (clobber (reg:CC FLAGS_REG))]
9187 "TARGET_PARTIAL_REG_STALL
9188 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9189 {
9190 switch (get_attr_type (insn))
9191 {
9192 case TYPE_ALU:
9193 gcc_assert (operands[2] == const1_rtx);
9194 return "add{w}\t%0, %0";
9195
9196 default:
9197 if (operands[2] == const1_rtx
9198 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9199 return "sal{w}\t%0";
9200 else
9201 return "sal{w}\t{%2, %0|%0, %2}";
9202 }
9203 }
9204 [(set (attr "type")
9205 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9206 (const_int 0))
9207 (match_operand 0 "register_operand" ""))
9208 (match_operand 2 "const1_operand" ""))
9209 (const_string "alu")
9210 ]
9211 (const_string "ishift")))
9212 (set (attr "length_immediate")
9213 (if_then_else
9214 (ior (eq_attr "type" "alu")
9215 (and (eq_attr "type" "ishift")
9216 (and (match_operand 2 "const1_operand" "")
9217 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9218 (const_int 0)))))
9219 (const_string "0")
9220 (const_string "*")))
9221 (set_attr "mode" "HI")])
9222
9223 (define_insn "*ashlhi3_1_lea"
9224 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9225 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9226 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9227 (clobber (reg:CC FLAGS_REG))]
9228 "!TARGET_PARTIAL_REG_STALL
9229 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9230 {
9231 switch (get_attr_type (insn))
9232 {
9233 case TYPE_LEA:
9234 return "#";
9235
9236 case TYPE_ALU:
9237 gcc_assert (operands[2] == const1_rtx);
9238 return "add{w}\t%0, %0";
9239
9240 default:
9241 if (operands[2] == const1_rtx
9242 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9243 return "sal{w}\t%0";
9244 else
9245 return "sal{w}\t{%2, %0|%0, %2}";
9246 }
9247 }
9248 [(set (attr "type")
9249 (cond [(eq_attr "alternative" "1")
9250 (const_string "lea")
9251 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9252 (const_int 0))
9253 (match_operand 0 "register_operand" ""))
9254 (match_operand 2 "const1_operand" ""))
9255 (const_string "alu")
9256 ]
9257 (const_string "ishift")))
9258 (set (attr "length_immediate")
9259 (if_then_else
9260 (ior (eq_attr "type" "alu")
9261 (and (eq_attr "type" "ishift")
9262 (and (match_operand 2 "const1_operand" "")
9263 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9264 (const_int 0)))))
9265 (const_string "0")
9266 (const_string "*")))
9267 (set_attr "mode" "HI,SI")])
9268
9269 (define_insn "*ashlqi3_1"
9270 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9271 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9272 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9273 (clobber (reg:CC FLAGS_REG))]
9274 "TARGET_PARTIAL_REG_STALL
9275 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9276 {
9277 switch (get_attr_type (insn))
9278 {
9279 case TYPE_ALU:
9280 gcc_assert (operands[2] == const1_rtx);
9281 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9282 return "add{l}\t%k0, %k0";
9283 else
9284 return "add{b}\t%0, %0";
9285
9286 default:
9287 if (operands[2] == const1_rtx
9288 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9289 {
9290 if (get_attr_mode (insn) == MODE_SI)
9291 return "sal{l}\t%k0";
9292 else
9293 return "sal{b}\t%0";
9294 }
9295 else
9296 {
9297 if (get_attr_mode (insn) == MODE_SI)
9298 return "sal{l}\t{%2, %k0|%k0, %2}";
9299 else
9300 return "sal{b}\t{%2, %0|%0, %2}";
9301 }
9302 }
9303 }
9304 [(set (attr "type")
9305 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9306 (const_int 0))
9307 (match_operand 0 "register_operand" ""))
9308 (match_operand 2 "const1_operand" ""))
9309 (const_string "alu")
9310 ]
9311 (const_string "ishift")))
9312 (set (attr "length_immediate")
9313 (if_then_else
9314 (ior (eq_attr "type" "alu")
9315 (and (eq_attr "type" "ishift")
9316 (and (match_operand 2 "const1_operand" "")
9317 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9318 (const_int 0)))))
9319 (const_string "0")
9320 (const_string "*")))
9321 (set_attr "mode" "QI,SI")])
9322
9323 ;; %%% Potential partial reg stall on alternative 2. What to do?
9324 (define_insn "*ashlqi3_1_lea"
9325 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9326 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9327 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9328 (clobber (reg:CC FLAGS_REG))]
9329 "!TARGET_PARTIAL_REG_STALL
9330 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9331 {
9332 switch (get_attr_type (insn))
9333 {
9334 case TYPE_LEA:
9335 return "#";
9336
9337 case TYPE_ALU:
9338 gcc_assert (operands[2] == const1_rtx);
9339 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9340 return "add{l}\t%k0, %k0";
9341 else
9342 return "add{b}\t%0, %0";
9343
9344 default:
9345 if (operands[2] == const1_rtx
9346 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9347 {
9348 if (get_attr_mode (insn) == MODE_SI)
9349 return "sal{l}\t%k0";
9350 else
9351 return "sal{b}\t%0";
9352 }
9353 else
9354 {
9355 if (get_attr_mode (insn) == MODE_SI)
9356 return "sal{l}\t{%2, %k0|%k0, %2}";
9357 else
9358 return "sal{b}\t{%2, %0|%0, %2}";
9359 }
9360 }
9361 }
9362 [(set (attr "type")
9363 (cond [(eq_attr "alternative" "2")
9364 (const_string "lea")
9365 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9366 (const_int 0))
9367 (match_operand 0 "register_operand" ""))
9368 (match_operand 2 "const1_operand" ""))
9369 (const_string "alu")
9370 ]
9371 (const_string "ishift")))
9372 (set (attr "length_immediate")
9373 (if_then_else
9374 (ior (eq_attr "type" "alu")
9375 (and (eq_attr "type" "ishift")
9376 (and (match_operand 2 "const1_operand" "")
9377 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9378 (const_int 0)))))
9379 (const_string "0")
9380 (const_string "*")))
9381 (set_attr "mode" "QI,SI,SI")])
9382
9383 (define_insn "*ashlqi3_1_slp"
9384 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9385 (ashift:QI (match_dup 0)
9386 (match_operand:QI 1 "nonmemory_operand" "cI")))
9387 (clobber (reg:CC FLAGS_REG))]
9388 "(optimize_function_for_size_p (cfun)
9389 || !TARGET_PARTIAL_FLAG_REG_STALL
9390 || (operands[1] == const1_rtx
9391 && (TARGET_SHIFT1
9392 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9393 {
9394 switch (get_attr_type (insn))
9395 {
9396 case TYPE_ALU:
9397 gcc_assert (operands[1] == const1_rtx);
9398 return "add{b}\t%0, %0";
9399
9400 default:
9401 if (operands[1] == const1_rtx
9402 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9403 return "sal{b}\t%0";
9404 else
9405 return "sal{b}\t{%1, %0|%0, %1}";
9406 }
9407 }
9408 [(set (attr "type")
9409 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9410 (const_int 0))
9411 (match_operand 0 "register_operand" ""))
9412 (match_operand 1 "const1_operand" ""))
9413 (const_string "alu")
9414 ]
9415 (const_string "ishift1")))
9416 (set (attr "length_immediate")
9417 (if_then_else
9418 (ior (eq_attr "type" "alu")
9419 (and (eq_attr "type" "ishift1")
9420 (and (match_operand 1 "const1_operand" "")
9421 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9422 (const_int 0)))))
9423 (const_string "0")
9424 (const_string "*")))
9425 (set_attr "mode" "QI")])
9426
9427 ;; Convert lea to the lea pattern to avoid flags dependency.
9428 (define_split
9429 [(set (match_operand 0 "register_operand" "")
9430 (ashift (match_operand 1 "index_register_operand" "")
9431 (match_operand:QI 2 "const_int_operand" "")))
9432 (clobber (reg:CC FLAGS_REG))]
9433 "reload_completed
9434 && true_regnum (operands[0]) != true_regnum (operands[1])"
9435 [(const_int 0)]
9436 {
9437 rtx pat;
9438 enum machine_mode mode = GET_MODE (operands[0]);
9439
9440 if (mode != Pmode)
9441 operands[1] = gen_lowpart (Pmode, operands[1]);
9442 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9443
9444 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9445
9446 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9447 operands[0] = gen_lowpart (SImode, operands[0]);
9448
9449 if (TARGET_64BIT && mode != Pmode)
9450 pat = gen_rtx_SUBREG (SImode, pat, 0);
9451
9452 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9453 DONE;
9454 })
9455
9456 ;; Convert lea to the lea pattern to avoid flags dependency.
9457 (define_split
9458 [(set (match_operand:DI 0 "register_operand" "")
9459 (zero_extend:DI
9460 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9461 (match_operand:QI 2 "const_int_operand" ""))))
9462 (clobber (reg:CC FLAGS_REG))]
9463 "TARGET_64BIT && reload_completed
9464 && true_regnum (operands[0]) != true_regnum (operands[1])"
9465 [(set (match_dup 0)
9466 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9467 {
9468 operands[1] = gen_lowpart (DImode, operands[1]);
9469 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9470 })
9471
9472 ;; This pattern can't accept a variable shift count, since shifts by
9473 ;; zero don't affect the flags. We assume that shifts by constant
9474 ;; zero are optimized away.
9475 (define_insn "*ashl<mode>3_cmp"
9476 [(set (reg FLAGS_REG)
9477 (compare
9478 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9479 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9480 (const_int 0)))
9481 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9482 (ashift:SWI (match_dup 1) (match_dup 2)))]
9483 "(optimize_function_for_size_p (cfun)
9484 || !TARGET_PARTIAL_FLAG_REG_STALL
9485 || (operands[2] == const1_rtx
9486 && (TARGET_SHIFT1
9487 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9488 && ix86_match_ccmode (insn, CCGOCmode)
9489 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9490 {
9491 switch (get_attr_type (insn))
9492 {
9493 case TYPE_ALU:
9494 gcc_assert (operands[2] == const1_rtx);
9495 return "add{<imodesuffix>}\t%0, %0";
9496
9497 default:
9498 if (operands[2] == const1_rtx
9499 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9500 return "sal{<imodesuffix>}\t%0";
9501 else
9502 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9503 }
9504 }
9505 [(set (attr "type")
9506 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9507 (const_int 0))
9508 (match_operand 0 "register_operand" ""))
9509 (match_operand 2 "const1_operand" ""))
9510 (const_string "alu")
9511 ]
9512 (const_string "ishift")))
9513 (set (attr "length_immediate")
9514 (if_then_else
9515 (ior (eq_attr "type" "alu")
9516 (and (eq_attr "type" "ishift")
9517 (and (match_operand 2 "const1_operand" "")
9518 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9519 (const_int 0)))))
9520 (const_string "0")
9521 (const_string "*")))
9522 (set_attr "mode" "<MODE>")])
9523
9524 (define_insn "*ashlsi3_cmp_zext"
9525 [(set (reg FLAGS_REG)
9526 (compare
9527 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9528 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9529 (const_int 0)))
9530 (set (match_operand:DI 0 "register_operand" "=r")
9531 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9532 "TARGET_64BIT
9533 && (optimize_function_for_size_p (cfun)
9534 || !TARGET_PARTIAL_FLAG_REG_STALL
9535 || (operands[2] == const1_rtx
9536 && (TARGET_SHIFT1
9537 || TARGET_DOUBLE_WITH_ADD)))
9538 && ix86_match_ccmode (insn, CCGOCmode)
9539 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9540 {
9541 switch (get_attr_type (insn))
9542 {
9543 case TYPE_ALU:
9544 gcc_assert (operands[2] == const1_rtx);
9545 return "add{l}\t%k0, %k0";
9546
9547 default:
9548 if (operands[2] == const1_rtx
9549 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9550 return "sal{l}\t%k0";
9551 else
9552 return "sal{l}\t{%2, %k0|%k0, %2}";
9553 }
9554 }
9555 [(set (attr "type")
9556 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9557 (const_int 0))
9558 (match_operand 2 "const1_operand" ""))
9559 (const_string "alu")
9560 ]
9561 (const_string "ishift")))
9562 (set (attr "length_immediate")
9563 (if_then_else
9564 (ior (eq_attr "type" "alu")
9565 (and (eq_attr "type" "ishift")
9566 (and (match_operand 2 "const1_operand" "")
9567 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9568 (const_int 0)))))
9569 (const_string "0")
9570 (const_string "*")))
9571 (set_attr "mode" "SI")])
9572
9573 (define_insn "*ashl<mode>3_cconly"
9574 [(set (reg FLAGS_REG)
9575 (compare
9576 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9577 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9578 (const_int 0)))
9579 (clobber (match_scratch:SWI 0 "=<r>"))]
9580 "(optimize_function_for_size_p (cfun)
9581 || !TARGET_PARTIAL_FLAG_REG_STALL
9582 || (operands[2] == const1_rtx
9583 && (TARGET_SHIFT1
9584 || TARGET_DOUBLE_WITH_ADD)))
9585 && ix86_match_ccmode (insn, CCGOCmode)"
9586 {
9587 switch (get_attr_type (insn))
9588 {
9589 case TYPE_ALU:
9590 gcc_assert (operands[2] == const1_rtx);
9591 return "add{<imodesuffix>}\t%0, %0";
9592
9593 default:
9594 if (operands[2] == const1_rtx
9595 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9596 return "sal{<imodesuffix>}\t%0";
9597 else
9598 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9599 }
9600 }
9601 [(set (attr "type")
9602 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9603 (const_int 0))
9604 (match_operand 0 "register_operand" ""))
9605 (match_operand 2 "const1_operand" ""))
9606 (const_string "alu")
9607 ]
9608 (const_string "ishift")))
9609 (set (attr "length_immediate")
9610 (if_then_else
9611 (ior (eq_attr "type" "alu")
9612 (and (eq_attr "type" "ishift")
9613 (and (match_operand 2 "const1_operand" "")
9614 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9615 (const_int 0)))))
9616 (const_string "0")
9617 (const_string "*")))
9618 (set_attr "mode" "<MODE>")])
9619
9620 ;; See comment above `ashl<mode>3' about how this works.
9621
9622 (define_expand "<shiftrt_insn><mode>3"
9623 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9624 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9625 (match_operand:QI 2 "nonmemory_operand" "")))]
9626 ""
9627 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9628
9629 ;; Avoid useless masking of count operand.
9630 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9631 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9632 (any_shiftrt:SWI48
9633 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9634 (subreg:QI
9635 (and:SI
9636 (match_operand:SI 2 "nonimmediate_operand" "c")
9637 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9638 (clobber (reg:CC FLAGS_REG))]
9639 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9640 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9641 == GET_MODE_BITSIZE (<MODE>mode)-1"
9642 "#"
9643 "&& 1"
9644 [(parallel [(set (match_dup 0)
9645 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9646 (clobber (reg:CC FLAGS_REG))])]
9647 {
9648 if (can_create_pseudo_p ())
9649 operands [2] = force_reg (SImode, operands[2]);
9650
9651 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9652 }
9653 [(set_attr "type" "ishift")
9654 (set_attr "mode" "<MODE>")])
9655
9656 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9657 [(set (match_operand:DWI 0 "register_operand" "=r")
9658 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9659 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9660 (clobber (reg:CC FLAGS_REG))]
9661 ""
9662 "#"
9663 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9664 [(const_int 0)]
9665 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9666 [(set_attr "type" "multi")])
9667
9668 ;; By default we don't ask for a scratch register, because when DWImode
9669 ;; values are manipulated, registers are already at a premium. But if
9670 ;; we have one handy, we won't turn it away.
9671
9672 (define_peephole2
9673 [(match_scratch:DWIH 3 "r")
9674 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9675 (any_shiftrt:<DWI>
9676 (match_operand:<DWI> 1 "register_operand" "")
9677 (match_operand:QI 2 "nonmemory_operand" "")))
9678 (clobber (reg:CC FLAGS_REG))])
9679 (match_dup 3)]
9680 "TARGET_CMOVE"
9681 [(const_int 0)]
9682 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9683
9684 (define_insn "x86_64_shrd"
9685 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9686 (ior:DI (ashiftrt:DI (match_dup 0)
9687 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9688 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9689 (minus:QI (const_int 64) (match_dup 2)))))
9690 (clobber (reg:CC FLAGS_REG))]
9691 "TARGET_64BIT"
9692 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9693 [(set_attr "type" "ishift")
9694 (set_attr "prefix_0f" "1")
9695 (set_attr "mode" "DI")
9696 (set_attr "athlon_decode" "vector")
9697 (set_attr "amdfam10_decode" "vector")
9698 (set_attr "bdver1_decode" "vector")])
9699
9700 (define_insn "x86_shrd"
9701 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9702 (ior:SI (ashiftrt:SI (match_dup 0)
9703 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9704 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9705 (minus:QI (const_int 32) (match_dup 2)))))
9706 (clobber (reg:CC FLAGS_REG))]
9707 ""
9708 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9709 [(set_attr "type" "ishift")
9710 (set_attr "prefix_0f" "1")
9711 (set_attr "mode" "SI")
9712 (set_attr "pent_pair" "np")
9713 (set_attr "athlon_decode" "vector")
9714 (set_attr "amdfam10_decode" "vector")
9715 (set_attr "bdver1_decode" "vector")])
9716
9717 (define_insn "ashrdi3_cvt"
9718 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9719 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9720 (match_operand:QI 2 "const_int_operand" "")))
9721 (clobber (reg:CC FLAGS_REG))]
9722 "TARGET_64BIT && INTVAL (operands[2]) == 63
9723 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9724 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9725 "@
9726 {cqto|cqo}
9727 sar{q}\t{%2, %0|%0, %2}"
9728 [(set_attr "type" "imovx,ishift")
9729 (set_attr "prefix_0f" "0,*")
9730 (set_attr "length_immediate" "0,*")
9731 (set_attr "modrm" "0,1")
9732 (set_attr "mode" "DI")])
9733
9734 (define_insn "ashrsi3_cvt"
9735 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9736 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9737 (match_operand:QI 2 "const_int_operand" "")))
9738 (clobber (reg:CC FLAGS_REG))]
9739 "INTVAL (operands[2]) == 31
9740 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9741 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9742 "@
9743 {cltd|cdq}
9744 sar{l}\t{%2, %0|%0, %2}"
9745 [(set_attr "type" "imovx,ishift")
9746 (set_attr "prefix_0f" "0,*")
9747 (set_attr "length_immediate" "0,*")
9748 (set_attr "modrm" "0,1")
9749 (set_attr "mode" "SI")])
9750
9751 (define_insn "*ashrsi3_cvt_zext"
9752 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9753 (zero_extend:DI
9754 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9755 (match_operand:QI 2 "const_int_operand" ""))))
9756 (clobber (reg:CC FLAGS_REG))]
9757 "TARGET_64BIT && INTVAL (operands[2]) == 31
9758 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9759 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9760 "@
9761 {cltd|cdq}
9762 sar{l}\t{%2, %k0|%k0, %2}"
9763 [(set_attr "type" "imovx,ishift")
9764 (set_attr "prefix_0f" "0,*")
9765 (set_attr "length_immediate" "0,*")
9766 (set_attr "modrm" "0,1")
9767 (set_attr "mode" "SI")])
9768
9769 (define_expand "x86_shift<mode>_adj_3"
9770 [(use (match_operand:SWI48 0 "register_operand" ""))
9771 (use (match_operand:SWI48 1 "register_operand" ""))
9772 (use (match_operand:QI 2 "register_operand" ""))]
9773 ""
9774 {
9775 rtx label = gen_label_rtx ();
9776 rtx tmp;
9777
9778 emit_insn (gen_testqi_ccz_1 (operands[2],
9779 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9780
9781 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9782 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9783 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9784 gen_rtx_LABEL_REF (VOIDmode, label),
9785 pc_rtx);
9786 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9787 JUMP_LABEL (tmp) = label;
9788
9789 emit_move_insn (operands[0], operands[1]);
9790 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9791 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9792 emit_label (label);
9793 LABEL_NUSES (label) = 1;
9794
9795 DONE;
9796 })
9797
9798 (define_insn "*<shiftrt_insn><mode>3_1"
9799 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9800 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9801 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9802 (clobber (reg:CC FLAGS_REG))]
9803 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9804 {
9805 if (operands[2] == const1_rtx
9806 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9807 return "<shiftrt>{<imodesuffix>}\t%0";
9808 else
9809 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9810 }
9811 [(set_attr "type" "ishift")
9812 (set (attr "length_immediate")
9813 (if_then_else
9814 (and (match_operand 2 "const1_operand" "")
9815 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9816 (const_int 0)))
9817 (const_string "0")
9818 (const_string "*")))
9819 (set_attr "mode" "<MODE>")])
9820
9821 (define_insn "*<shiftrt_insn>si3_1_zext"
9822 [(set (match_operand:DI 0 "register_operand" "=r")
9823 (zero_extend:DI
9824 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9825 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9826 (clobber (reg:CC FLAGS_REG))]
9827 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9828 {
9829 if (operands[2] == const1_rtx
9830 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9831 return "<shiftrt>{l}\t%k0";
9832 else
9833 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9834 }
9835 [(set_attr "type" "ishift")
9836 (set (attr "length_immediate")
9837 (if_then_else
9838 (and (match_operand 2 "const1_operand" "")
9839 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9840 (const_int 0)))
9841 (const_string "0")
9842 (const_string "*")))
9843 (set_attr "mode" "SI")])
9844
9845 (define_insn "*<shiftrt_insn>qi3_1_slp"
9846 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9847 (any_shiftrt:QI (match_dup 0)
9848 (match_operand:QI 1 "nonmemory_operand" "cI")))
9849 (clobber (reg:CC FLAGS_REG))]
9850 "(optimize_function_for_size_p (cfun)
9851 || !TARGET_PARTIAL_REG_STALL
9852 || (operands[1] == const1_rtx
9853 && TARGET_SHIFT1))"
9854 {
9855 if (operands[1] == const1_rtx
9856 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9857 return "<shiftrt>{b}\t%0";
9858 else
9859 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9860 }
9861 [(set_attr "type" "ishift1")
9862 (set (attr "length_immediate")
9863 (if_then_else
9864 (and (match_operand 1 "const1_operand" "")
9865 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9866 (const_int 0)))
9867 (const_string "0")
9868 (const_string "*")))
9869 (set_attr "mode" "QI")])
9870
9871 ;; This pattern can't accept a variable shift count, since shifts by
9872 ;; zero don't affect the flags. We assume that shifts by constant
9873 ;; zero are optimized away.
9874 (define_insn "*<shiftrt_insn><mode>3_cmp"
9875 [(set (reg FLAGS_REG)
9876 (compare
9877 (any_shiftrt:SWI
9878 (match_operand:SWI 1 "nonimmediate_operand" "0")
9879 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9880 (const_int 0)))
9881 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9882 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9883 "(optimize_function_for_size_p (cfun)
9884 || !TARGET_PARTIAL_FLAG_REG_STALL
9885 || (operands[2] == const1_rtx
9886 && TARGET_SHIFT1))
9887 && ix86_match_ccmode (insn, CCGOCmode)
9888 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9889 {
9890 if (operands[2] == const1_rtx
9891 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9892 return "<shiftrt>{<imodesuffix>}\t%0";
9893 else
9894 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9895 }
9896 [(set_attr "type" "ishift")
9897 (set (attr "length_immediate")
9898 (if_then_else
9899 (and (match_operand 2 "const1_operand" "")
9900 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9901 (const_int 0)))
9902 (const_string "0")
9903 (const_string "*")))
9904 (set_attr "mode" "<MODE>")])
9905
9906 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9907 [(set (reg FLAGS_REG)
9908 (compare
9909 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9910 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9911 (const_int 0)))
9912 (set (match_operand:DI 0 "register_operand" "=r")
9913 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9914 "TARGET_64BIT
9915 && (optimize_function_for_size_p (cfun)
9916 || !TARGET_PARTIAL_FLAG_REG_STALL
9917 || (operands[2] == const1_rtx
9918 && TARGET_SHIFT1))
9919 && ix86_match_ccmode (insn, CCGOCmode)
9920 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9921 {
9922 if (operands[2] == const1_rtx
9923 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9924 return "<shiftrt>{l}\t%k0";
9925 else
9926 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9927 }
9928 [(set_attr "type" "ishift")
9929 (set (attr "length_immediate")
9930 (if_then_else
9931 (and (match_operand 2 "const1_operand" "")
9932 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9933 (const_int 0)))
9934 (const_string "0")
9935 (const_string "*")))
9936 (set_attr "mode" "SI")])
9937
9938 (define_insn "*<shiftrt_insn><mode>3_cconly"
9939 [(set (reg FLAGS_REG)
9940 (compare
9941 (any_shiftrt:SWI
9942 (match_operand:SWI 1 "register_operand" "0")
9943 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9944 (const_int 0)))
9945 (clobber (match_scratch:SWI 0 "=<r>"))]
9946 "(optimize_function_for_size_p (cfun)
9947 || !TARGET_PARTIAL_FLAG_REG_STALL
9948 || (operands[2] == const1_rtx
9949 && TARGET_SHIFT1))
9950 && ix86_match_ccmode (insn, CCGOCmode)"
9951 {
9952 if (operands[2] == const1_rtx
9953 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9954 return "<shiftrt>{<imodesuffix>}\t%0";
9955 else
9956 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9957 }
9958 [(set_attr "type" "ishift")
9959 (set (attr "length_immediate")
9960 (if_then_else
9961 (and (match_operand 2 "const1_operand" "")
9962 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9963 (const_int 0)))
9964 (const_string "0")
9965 (const_string "*")))
9966 (set_attr "mode" "<MODE>")])
9967 \f
9968 ;; Rotate instructions
9969
9970 (define_expand "<rotate_insn>ti3"
9971 [(set (match_operand:TI 0 "register_operand" "")
9972 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9973 (match_operand:QI 2 "nonmemory_operand" "")))]
9974 "TARGET_64BIT"
9975 {
9976 if (const_1_to_63_operand (operands[2], VOIDmode))
9977 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9978 (operands[0], operands[1], operands[2]));
9979 else
9980 FAIL;
9981
9982 DONE;
9983 })
9984
9985 (define_expand "<rotate_insn>di3"
9986 [(set (match_operand:DI 0 "shiftdi_operand" "")
9987 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9988 (match_operand:QI 2 "nonmemory_operand" "")))]
9989 ""
9990 {
9991 if (TARGET_64BIT)
9992 ix86_expand_binary_operator (<CODE>, DImode, operands);
9993 else if (const_1_to_31_operand (operands[2], VOIDmode))
9994 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9995 (operands[0], operands[1], operands[2]));
9996 else
9997 FAIL;
9998
9999 DONE;
10000 })
10001
10002 (define_expand "<rotate_insn><mode>3"
10003 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10004 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10005 (match_operand:QI 2 "nonmemory_operand" "")))]
10006 ""
10007 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10008
10009 ;; Avoid useless masking of count operand.
10010 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10011 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10012 (any_rotate:SWI48
10013 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10014 (subreg:QI
10015 (and:SI
10016 (match_operand:SI 2 "nonimmediate_operand" "c")
10017 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10018 (clobber (reg:CC FLAGS_REG))]
10019 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10020 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10021 == GET_MODE_BITSIZE (<MODE>mode)-1"
10022 "#"
10023 "&& 1"
10024 [(parallel [(set (match_dup 0)
10025 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10026 (clobber (reg:CC FLAGS_REG))])]
10027 {
10028 if (can_create_pseudo_p ())
10029 operands [2] = force_reg (SImode, operands[2]);
10030
10031 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10032 }
10033 [(set_attr "type" "rotate")
10034 (set_attr "mode" "<MODE>")])
10035
10036 ;; Implement rotation using two double-precision
10037 ;; shift instructions and a scratch register.
10038
10039 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10040 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10041 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10042 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10043 (clobber (reg:CC FLAGS_REG))
10044 (clobber (match_scratch:DWIH 3 "=&r"))]
10045 ""
10046 "#"
10047 "reload_completed"
10048 [(set (match_dup 3) (match_dup 4))
10049 (parallel
10050 [(set (match_dup 4)
10051 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10052 (lshiftrt:DWIH (match_dup 5)
10053 (minus:QI (match_dup 6) (match_dup 2)))))
10054 (clobber (reg:CC FLAGS_REG))])
10055 (parallel
10056 [(set (match_dup 5)
10057 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10058 (lshiftrt:DWIH (match_dup 3)
10059 (minus:QI (match_dup 6) (match_dup 2)))))
10060 (clobber (reg:CC FLAGS_REG))])]
10061 {
10062 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10063
10064 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10065 })
10066
10067 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10068 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10069 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10070 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10071 (clobber (reg:CC FLAGS_REG))
10072 (clobber (match_scratch:DWIH 3 "=&r"))]
10073 ""
10074 "#"
10075 "reload_completed"
10076 [(set (match_dup 3) (match_dup 4))
10077 (parallel
10078 [(set (match_dup 4)
10079 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10080 (ashift:DWIH (match_dup 5)
10081 (minus:QI (match_dup 6) (match_dup 2)))))
10082 (clobber (reg:CC FLAGS_REG))])
10083 (parallel
10084 [(set (match_dup 5)
10085 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10086 (ashift:DWIH (match_dup 3)
10087 (minus:QI (match_dup 6) (match_dup 2)))))
10088 (clobber (reg:CC FLAGS_REG))])]
10089 {
10090 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10091
10092 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10093 })
10094
10095 (define_insn "*<rotate_insn><mode>3_1"
10096 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10097 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10098 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10099 (clobber (reg:CC FLAGS_REG))]
10100 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10101 {
10102 if (operands[2] == const1_rtx
10103 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10104 return "<rotate>{<imodesuffix>}\t%0";
10105 else
10106 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10107 }
10108 [(set_attr "type" "rotate")
10109 (set (attr "length_immediate")
10110 (if_then_else
10111 (and (match_operand 2 "const1_operand" "")
10112 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10113 (const_int 0)))
10114 (const_string "0")
10115 (const_string "*")))
10116 (set_attr "mode" "<MODE>")])
10117
10118 (define_insn "*<rotate_insn>si3_1_zext"
10119 [(set (match_operand:DI 0 "register_operand" "=r")
10120 (zero_extend:DI
10121 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10122 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10123 (clobber (reg:CC FLAGS_REG))]
10124 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10125 {
10126 if (operands[2] == const1_rtx
10127 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10128 return "<rotate>{l}\t%k0";
10129 else
10130 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10131 }
10132 [(set_attr "type" "rotate")
10133 (set (attr "length_immediate")
10134 (if_then_else
10135 (and (match_operand 2 "const1_operand" "")
10136 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10137 (const_int 0)))
10138 (const_string "0")
10139 (const_string "*")))
10140 (set_attr "mode" "SI")])
10141
10142 (define_insn "*<rotate_insn>qi3_1_slp"
10143 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10144 (any_rotate:QI (match_dup 0)
10145 (match_operand:QI 1 "nonmemory_operand" "cI")))
10146 (clobber (reg:CC FLAGS_REG))]
10147 "(optimize_function_for_size_p (cfun)
10148 || !TARGET_PARTIAL_REG_STALL
10149 || (operands[1] == const1_rtx
10150 && TARGET_SHIFT1))"
10151 {
10152 if (operands[1] == const1_rtx
10153 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10154 return "<rotate>{b}\t%0";
10155 else
10156 return "<rotate>{b}\t{%1, %0|%0, %1}";
10157 }
10158 [(set_attr "type" "rotate1")
10159 (set (attr "length_immediate")
10160 (if_then_else
10161 (and (match_operand 1 "const1_operand" "")
10162 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10163 (const_int 0)))
10164 (const_string "0")
10165 (const_string "*")))
10166 (set_attr "mode" "QI")])
10167
10168 (define_split
10169 [(set (match_operand:HI 0 "register_operand" "")
10170 (any_rotate:HI (match_dup 0) (const_int 8)))
10171 (clobber (reg:CC FLAGS_REG))]
10172 "reload_completed
10173 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10174 [(parallel [(set (strict_low_part (match_dup 0))
10175 (bswap:HI (match_dup 0)))
10176 (clobber (reg:CC FLAGS_REG))])])
10177 \f
10178 ;; Bit set / bit test instructions
10179
10180 (define_expand "extv"
10181 [(set (match_operand:SI 0 "register_operand" "")
10182 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10183 (match_operand:SI 2 "const8_operand" "")
10184 (match_operand:SI 3 "const8_operand" "")))]
10185 ""
10186 {
10187 /* Handle extractions from %ah et al. */
10188 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10189 FAIL;
10190
10191 /* From mips.md: extract_bit_field doesn't verify that our source
10192 matches the predicate, so check it again here. */
10193 if (! ext_register_operand (operands[1], VOIDmode))
10194 FAIL;
10195 })
10196
10197 (define_expand "extzv"
10198 [(set (match_operand:SI 0 "register_operand" "")
10199 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10200 (match_operand:SI 2 "const8_operand" "")
10201 (match_operand:SI 3 "const8_operand" "")))]
10202 ""
10203 {
10204 /* Handle extractions from %ah et al. */
10205 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10206 FAIL;
10207
10208 /* From mips.md: extract_bit_field doesn't verify that our source
10209 matches the predicate, so check it again here. */
10210 if (! ext_register_operand (operands[1], VOIDmode))
10211 FAIL;
10212 })
10213
10214 (define_expand "insv"
10215 [(set (zero_extract (match_operand 0 "register_operand" "")
10216 (match_operand 1 "const_int_operand" "")
10217 (match_operand 2 "const_int_operand" ""))
10218 (match_operand 3 "register_operand" ""))]
10219 ""
10220 {
10221 rtx (*gen_mov_insv_1) (rtx, rtx);
10222
10223 if (ix86_expand_pinsr (operands))
10224 DONE;
10225
10226 /* Handle insertions to %ah et al. */
10227 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10228 FAIL;
10229
10230 /* From mips.md: insert_bit_field doesn't verify that our source
10231 matches the predicate, so check it again here. */
10232 if (! ext_register_operand (operands[0], VOIDmode))
10233 FAIL;
10234
10235 gen_mov_insv_1 = (TARGET_64BIT
10236 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10237
10238 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10239 DONE;
10240 })
10241
10242 ;; %%% bts, btr, btc, bt.
10243 ;; In general these instructions are *slow* when applied to memory,
10244 ;; since they enforce atomic operation. When applied to registers,
10245 ;; it depends on the cpu implementation. They're never faster than
10246 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10247 ;; no point. But in 64-bit, we can't hold the relevant immediates
10248 ;; within the instruction itself, so operating on bits in the high
10249 ;; 32-bits of a register becomes easier.
10250 ;;
10251 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10252 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10253 ;; negdf respectively, so they can never be disabled entirely.
10254
10255 (define_insn "*btsq"
10256 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10257 (const_int 1)
10258 (match_operand:DI 1 "const_0_to_63_operand" ""))
10259 (const_int 1))
10260 (clobber (reg:CC FLAGS_REG))]
10261 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10262 "bts{q}\t{%1, %0|%0, %1}"
10263 [(set_attr "type" "alu1")
10264 (set_attr "prefix_0f" "1")
10265 (set_attr "mode" "DI")])
10266
10267 (define_insn "*btrq"
10268 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10269 (const_int 1)
10270 (match_operand:DI 1 "const_0_to_63_operand" ""))
10271 (const_int 0))
10272 (clobber (reg:CC FLAGS_REG))]
10273 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10274 "btr{q}\t{%1, %0|%0, %1}"
10275 [(set_attr "type" "alu1")
10276 (set_attr "prefix_0f" "1")
10277 (set_attr "mode" "DI")])
10278
10279 (define_insn "*btcq"
10280 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10281 (const_int 1)
10282 (match_operand:DI 1 "const_0_to_63_operand" ""))
10283 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10284 (clobber (reg:CC FLAGS_REG))]
10285 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10286 "btc{q}\t{%1, %0|%0, %1}"
10287 [(set_attr "type" "alu1")
10288 (set_attr "prefix_0f" "1")
10289 (set_attr "mode" "DI")])
10290
10291 ;; Allow Nocona to avoid these instructions if a register is available.
10292
10293 (define_peephole2
10294 [(match_scratch:DI 2 "r")
10295 (parallel [(set (zero_extract:DI
10296 (match_operand:DI 0 "register_operand" "")
10297 (const_int 1)
10298 (match_operand:DI 1 "const_0_to_63_operand" ""))
10299 (const_int 1))
10300 (clobber (reg:CC FLAGS_REG))])]
10301 "TARGET_64BIT && !TARGET_USE_BT"
10302 [(const_int 0)]
10303 {
10304 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10305 rtx op1;
10306
10307 if (HOST_BITS_PER_WIDE_INT >= 64)
10308 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10309 else if (i < HOST_BITS_PER_WIDE_INT)
10310 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10311 else
10312 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10313
10314 op1 = immed_double_const (lo, hi, DImode);
10315 if (i >= 31)
10316 {
10317 emit_move_insn (operands[2], op1);
10318 op1 = operands[2];
10319 }
10320
10321 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10322 DONE;
10323 })
10324
10325 (define_peephole2
10326 [(match_scratch:DI 2 "r")
10327 (parallel [(set (zero_extract:DI
10328 (match_operand:DI 0 "register_operand" "")
10329 (const_int 1)
10330 (match_operand:DI 1 "const_0_to_63_operand" ""))
10331 (const_int 0))
10332 (clobber (reg:CC FLAGS_REG))])]
10333 "TARGET_64BIT && !TARGET_USE_BT"
10334 [(const_int 0)]
10335 {
10336 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10337 rtx op1;
10338
10339 if (HOST_BITS_PER_WIDE_INT >= 64)
10340 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10341 else if (i < HOST_BITS_PER_WIDE_INT)
10342 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10343 else
10344 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10345
10346 op1 = immed_double_const (~lo, ~hi, DImode);
10347 if (i >= 32)
10348 {
10349 emit_move_insn (operands[2], op1);
10350 op1 = operands[2];
10351 }
10352
10353 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10354 DONE;
10355 })
10356
10357 (define_peephole2
10358 [(match_scratch:DI 2 "r")
10359 (parallel [(set (zero_extract:DI
10360 (match_operand:DI 0 "register_operand" "")
10361 (const_int 1)
10362 (match_operand:DI 1 "const_0_to_63_operand" ""))
10363 (not:DI (zero_extract:DI
10364 (match_dup 0) (const_int 1) (match_dup 1))))
10365 (clobber (reg:CC FLAGS_REG))])]
10366 "TARGET_64BIT && !TARGET_USE_BT"
10367 [(const_int 0)]
10368 {
10369 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10370 rtx op1;
10371
10372 if (HOST_BITS_PER_WIDE_INT >= 64)
10373 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10374 else if (i < HOST_BITS_PER_WIDE_INT)
10375 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10376 else
10377 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10378
10379 op1 = immed_double_const (lo, hi, DImode);
10380 if (i >= 31)
10381 {
10382 emit_move_insn (operands[2], op1);
10383 op1 = operands[2];
10384 }
10385
10386 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10387 DONE;
10388 })
10389
10390 (define_insn "*bt<mode>"
10391 [(set (reg:CCC FLAGS_REG)
10392 (compare:CCC
10393 (zero_extract:SWI48
10394 (match_operand:SWI48 0 "register_operand" "r")
10395 (const_int 1)
10396 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10397 (const_int 0)))]
10398 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10399 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10400 [(set_attr "type" "alu1")
10401 (set_attr "prefix_0f" "1")
10402 (set_attr "mode" "<MODE>")])
10403 \f
10404 ;; Store-flag instructions.
10405
10406 ;; For all sCOND expanders, also expand the compare or test insn that
10407 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10408
10409 (define_insn_and_split "*setcc_di_1"
10410 [(set (match_operand:DI 0 "register_operand" "=q")
10411 (match_operator:DI 1 "ix86_comparison_operator"
10412 [(reg FLAGS_REG) (const_int 0)]))]
10413 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10414 "#"
10415 "&& reload_completed"
10416 [(set (match_dup 2) (match_dup 1))
10417 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10418 {
10419 PUT_MODE (operands[1], QImode);
10420 operands[2] = gen_lowpart (QImode, operands[0]);
10421 })
10422
10423 (define_insn_and_split "*setcc_si_1_and"
10424 [(set (match_operand:SI 0 "register_operand" "=q")
10425 (match_operator:SI 1 "ix86_comparison_operator"
10426 [(reg FLAGS_REG) (const_int 0)]))
10427 (clobber (reg:CC FLAGS_REG))]
10428 "!TARGET_PARTIAL_REG_STALL
10429 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10430 "#"
10431 "&& reload_completed"
10432 [(set (match_dup 2) (match_dup 1))
10433 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10434 (clobber (reg:CC FLAGS_REG))])]
10435 {
10436 PUT_MODE (operands[1], QImode);
10437 operands[2] = gen_lowpart (QImode, operands[0]);
10438 })
10439
10440 (define_insn_and_split "*setcc_si_1_movzbl"
10441 [(set (match_operand:SI 0 "register_operand" "=q")
10442 (match_operator:SI 1 "ix86_comparison_operator"
10443 [(reg FLAGS_REG) (const_int 0)]))]
10444 "!TARGET_PARTIAL_REG_STALL
10445 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10446 "#"
10447 "&& reload_completed"
10448 [(set (match_dup 2) (match_dup 1))
10449 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10450 {
10451 PUT_MODE (operands[1], QImode);
10452 operands[2] = gen_lowpart (QImode, operands[0]);
10453 })
10454
10455 (define_insn "*setcc_qi"
10456 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10457 (match_operator:QI 1 "ix86_comparison_operator"
10458 [(reg FLAGS_REG) (const_int 0)]))]
10459 ""
10460 "set%C1\t%0"
10461 [(set_attr "type" "setcc")
10462 (set_attr "mode" "QI")])
10463
10464 (define_insn "*setcc_qi_slp"
10465 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10466 (match_operator:QI 1 "ix86_comparison_operator"
10467 [(reg FLAGS_REG) (const_int 0)]))]
10468 ""
10469 "set%C1\t%0"
10470 [(set_attr "type" "setcc")
10471 (set_attr "mode" "QI")])
10472
10473 ;; In general it is not safe to assume too much about CCmode registers,
10474 ;; so simplify-rtx stops when it sees a second one. Under certain
10475 ;; conditions this is safe on x86, so help combine not create
10476 ;;
10477 ;; seta %al
10478 ;; testb %al, %al
10479 ;; sete %al
10480
10481 (define_split
10482 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10483 (ne:QI (match_operator 1 "ix86_comparison_operator"
10484 [(reg FLAGS_REG) (const_int 0)])
10485 (const_int 0)))]
10486 ""
10487 [(set (match_dup 0) (match_dup 1))]
10488 "PUT_MODE (operands[1], QImode);")
10489
10490 (define_split
10491 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10492 (ne:QI (match_operator 1 "ix86_comparison_operator"
10493 [(reg FLAGS_REG) (const_int 0)])
10494 (const_int 0)))]
10495 ""
10496 [(set (match_dup 0) (match_dup 1))]
10497 "PUT_MODE (operands[1], QImode);")
10498
10499 (define_split
10500 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10501 (eq:QI (match_operator 1 "ix86_comparison_operator"
10502 [(reg FLAGS_REG) (const_int 0)])
10503 (const_int 0)))]
10504 ""
10505 [(set (match_dup 0) (match_dup 1))]
10506 {
10507 rtx new_op1 = copy_rtx (operands[1]);
10508 operands[1] = new_op1;
10509 PUT_MODE (new_op1, QImode);
10510 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10511 GET_MODE (XEXP (new_op1, 0))));
10512
10513 /* Make sure that (a) the CCmode we have for the flags is strong
10514 enough for the reversed compare or (b) we have a valid FP compare. */
10515 if (! ix86_comparison_operator (new_op1, VOIDmode))
10516 FAIL;
10517 })
10518
10519 (define_split
10520 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10521 (eq:QI (match_operator 1 "ix86_comparison_operator"
10522 [(reg FLAGS_REG) (const_int 0)])
10523 (const_int 0)))]
10524 ""
10525 [(set (match_dup 0) (match_dup 1))]
10526 {
10527 rtx new_op1 = copy_rtx (operands[1]);
10528 operands[1] = new_op1;
10529 PUT_MODE (new_op1, QImode);
10530 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10531 GET_MODE (XEXP (new_op1, 0))));
10532
10533 /* Make sure that (a) the CCmode we have for the flags is strong
10534 enough for the reversed compare or (b) we have a valid FP compare. */
10535 if (! ix86_comparison_operator (new_op1, VOIDmode))
10536 FAIL;
10537 })
10538
10539 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10540 ;; subsequent logical operations are used to imitate conditional moves.
10541 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10542 ;; it directly.
10543
10544 (define_insn "setcc_<mode>_sse"
10545 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10546 (match_operator:MODEF 3 "sse_comparison_operator"
10547 [(match_operand:MODEF 1 "register_operand" "0,x")
10548 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10549 "SSE_FLOAT_MODE_P (<MODE>mode)"
10550 "@
10551 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10552 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10553 [(set_attr "isa" "noavx,avx")
10554 (set_attr "type" "ssecmp")
10555 (set_attr "length_immediate" "1")
10556 (set_attr "prefix" "orig,vex")
10557 (set_attr "mode" "<MODE>")])
10558 \f
10559 ;; Basic conditional jump instructions.
10560 ;; We ignore the overflow flag for signed branch instructions.
10561
10562 (define_insn "*jcc_1"
10563 [(set (pc)
10564 (if_then_else (match_operator 1 "ix86_comparison_operator"
10565 [(reg FLAGS_REG) (const_int 0)])
10566 (label_ref (match_operand 0 "" ""))
10567 (pc)))]
10568 ""
10569 "%+j%C1\t%l0"
10570 [(set_attr "type" "ibr")
10571 (set_attr "modrm" "0")
10572 (set (attr "length")
10573 (if_then_else (and (ge (minus (match_dup 0) (pc))
10574 (const_int -126))
10575 (lt (minus (match_dup 0) (pc))
10576 (const_int 128)))
10577 (const_int 2)
10578 (const_int 6)))])
10579
10580 (define_insn "*jcc_2"
10581 [(set (pc)
10582 (if_then_else (match_operator 1 "ix86_comparison_operator"
10583 [(reg FLAGS_REG) (const_int 0)])
10584 (pc)
10585 (label_ref (match_operand 0 "" ""))))]
10586 ""
10587 "%+j%c1\t%l0"
10588 [(set_attr "type" "ibr")
10589 (set_attr "modrm" "0")
10590 (set (attr "length")
10591 (if_then_else (and (ge (minus (match_dup 0) (pc))
10592 (const_int -126))
10593 (lt (minus (match_dup 0) (pc))
10594 (const_int 128)))
10595 (const_int 2)
10596 (const_int 6)))])
10597
10598 ;; In general it is not safe to assume too much about CCmode registers,
10599 ;; so simplify-rtx stops when it sees a second one. Under certain
10600 ;; conditions this is safe on x86, so help combine not create
10601 ;;
10602 ;; seta %al
10603 ;; testb %al, %al
10604 ;; je Lfoo
10605
10606 (define_split
10607 [(set (pc)
10608 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10609 [(reg FLAGS_REG) (const_int 0)])
10610 (const_int 0))
10611 (label_ref (match_operand 1 "" ""))
10612 (pc)))]
10613 ""
10614 [(set (pc)
10615 (if_then_else (match_dup 0)
10616 (label_ref (match_dup 1))
10617 (pc)))]
10618 "PUT_MODE (operands[0], VOIDmode);")
10619
10620 (define_split
10621 [(set (pc)
10622 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10623 [(reg FLAGS_REG) (const_int 0)])
10624 (const_int 0))
10625 (label_ref (match_operand 1 "" ""))
10626 (pc)))]
10627 ""
10628 [(set (pc)
10629 (if_then_else (match_dup 0)
10630 (label_ref (match_dup 1))
10631 (pc)))]
10632 {
10633 rtx new_op0 = copy_rtx (operands[0]);
10634 operands[0] = new_op0;
10635 PUT_MODE (new_op0, VOIDmode);
10636 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10637 GET_MODE (XEXP (new_op0, 0))));
10638
10639 /* Make sure that (a) the CCmode we have for the flags is strong
10640 enough for the reversed compare or (b) we have a valid FP compare. */
10641 if (! ix86_comparison_operator (new_op0, VOIDmode))
10642 FAIL;
10643 })
10644
10645 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10646 ;; pass generates from shift insn with QImode operand. Actually, the mode
10647 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10648 ;; appropriate modulo of the bit offset value.
10649
10650 (define_insn_and_split "*jcc_bt<mode>"
10651 [(set (pc)
10652 (if_then_else (match_operator 0 "bt_comparison_operator"
10653 [(zero_extract:SWI48
10654 (match_operand:SWI48 1 "register_operand" "r")
10655 (const_int 1)
10656 (zero_extend:SI
10657 (match_operand:QI 2 "register_operand" "r")))
10658 (const_int 0)])
10659 (label_ref (match_operand 3 "" ""))
10660 (pc)))
10661 (clobber (reg:CC FLAGS_REG))]
10662 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10663 "#"
10664 "&& 1"
10665 [(set (reg:CCC FLAGS_REG)
10666 (compare:CCC
10667 (zero_extract:SWI48
10668 (match_dup 1)
10669 (const_int 1)
10670 (match_dup 2))
10671 (const_int 0)))
10672 (set (pc)
10673 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10674 (label_ref (match_dup 3))
10675 (pc)))]
10676 {
10677 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10678
10679 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10680 })
10681
10682 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10683 ;; also for DImode, this is what combine produces.
10684 (define_insn_and_split "*jcc_bt<mode>_mask"
10685 [(set (pc)
10686 (if_then_else (match_operator 0 "bt_comparison_operator"
10687 [(zero_extract:SWI48
10688 (match_operand:SWI48 1 "register_operand" "r")
10689 (const_int 1)
10690 (and:SI
10691 (match_operand:SI 2 "register_operand" "r")
10692 (match_operand:SI 3 "const_int_operand" "n")))])
10693 (label_ref (match_operand 4 "" ""))
10694 (pc)))
10695 (clobber (reg:CC FLAGS_REG))]
10696 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10697 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10698 == GET_MODE_BITSIZE (<MODE>mode)-1"
10699 "#"
10700 "&& 1"
10701 [(set (reg:CCC FLAGS_REG)
10702 (compare:CCC
10703 (zero_extract:SWI48
10704 (match_dup 1)
10705 (const_int 1)
10706 (match_dup 2))
10707 (const_int 0)))
10708 (set (pc)
10709 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10710 (label_ref (match_dup 4))
10711 (pc)))]
10712 {
10713 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10714
10715 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10716 })
10717
10718 (define_insn_and_split "*jcc_btsi_1"
10719 [(set (pc)
10720 (if_then_else (match_operator 0 "bt_comparison_operator"
10721 [(and:SI
10722 (lshiftrt:SI
10723 (match_operand:SI 1 "register_operand" "r")
10724 (match_operand:QI 2 "register_operand" "r"))
10725 (const_int 1))
10726 (const_int 0)])
10727 (label_ref (match_operand 3 "" ""))
10728 (pc)))
10729 (clobber (reg:CC FLAGS_REG))]
10730 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10731 "#"
10732 "&& 1"
10733 [(set (reg:CCC FLAGS_REG)
10734 (compare:CCC
10735 (zero_extract:SI
10736 (match_dup 1)
10737 (const_int 1)
10738 (match_dup 2))
10739 (const_int 0)))
10740 (set (pc)
10741 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10742 (label_ref (match_dup 3))
10743 (pc)))]
10744 {
10745 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10746
10747 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10748 })
10749
10750 ;; avoid useless masking of bit offset operand
10751 (define_insn_and_split "*jcc_btsi_mask_1"
10752 [(set (pc)
10753 (if_then_else
10754 (match_operator 0 "bt_comparison_operator"
10755 [(and:SI
10756 (lshiftrt:SI
10757 (match_operand:SI 1 "register_operand" "r")
10758 (subreg:QI
10759 (and:SI
10760 (match_operand:SI 2 "register_operand" "r")
10761 (match_operand:SI 3 "const_int_operand" "n")) 0))
10762 (const_int 1))
10763 (const_int 0)])
10764 (label_ref (match_operand 4 "" ""))
10765 (pc)))
10766 (clobber (reg:CC FLAGS_REG))]
10767 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10768 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10769 "#"
10770 "&& 1"
10771 [(set (reg:CCC FLAGS_REG)
10772 (compare:CCC
10773 (zero_extract:SI
10774 (match_dup 1)
10775 (const_int 1)
10776 (match_dup 2))
10777 (const_int 0)))
10778 (set (pc)
10779 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10780 (label_ref (match_dup 4))
10781 (pc)))]
10782 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10783
10784 ;; Define combination compare-and-branch fp compare instructions to help
10785 ;; combine.
10786
10787 (define_insn "*fp_jcc_1_387"
10788 [(set (pc)
10789 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10790 [(match_operand 1 "register_operand" "f")
10791 (match_operand 2 "nonimmediate_operand" "fm")])
10792 (label_ref (match_operand 3 "" ""))
10793 (pc)))
10794 (clobber (reg:CCFP FPSR_REG))
10795 (clobber (reg:CCFP FLAGS_REG))
10796 (clobber (match_scratch:HI 4 "=a"))]
10797 "TARGET_80387
10798 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10799 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10800 && SELECT_CC_MODE (GET_CODE (operands[0]),
10801 operands[1], operands[2]) == CCFPmode
10802 && !TARGET_CMOVE"
10803 "#")
10804
10805 (define_insn "*fp_jcc_1r_387"
10806 [(set (pc)
10807 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10808 [(match_operand 1 "register_operand" "f")
10809 (match_operand 2 "nonimmediate_operand" "fm")])
10810 (pc)
10811 (label_ref (match_operand 3 "" ""))))
10812 (clobber (reg:CCFP FPSR_REG))
10813 (clobber (reg:CCFP FLAGS_REG))
10814 (clobber (match_scratch:HI 4 "=a"))]
10815 "TARGET_80387
10816 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10817 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10818 && SELECT_CC_MODE (GET_CODE (operands[0]),
10819 operands[1], operands[2]) == CCFPmode
10820 && !TARGET_CMOVE"
10821 "#")
10822
10823 (define_insn "*fp_jcc_2_387"
10824 [(set (pc)
10825 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10826 [(match_operand 1 "register_operand" "f")
10827 (match_operand 2 "register_operand" "f")])
10828 (label_ref (match_operand 3 "" ""))
10829 (pc)))
10830 (clobber (reg:CCFP FPSR_REG))
10831 (clobber (reg:CCFP FLAGS_REG))
10832 (clobber (match_scratch:HI 4 "=a"))]
10833 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10834 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10835 && !TARGET_CMOVE"
10836 "#")
10837
10838 (define_insn "*fp_jcc_2r_387"
10839 [(set (pc)
10840 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10841 [(match_operand 1 "register_operand" "f")
10842 (match_operand 2 "register_operand" "f")])
10843 (pc)
10844 (label_ref (match_operand 3 "" ""))))
10845 (clobber (reg:CCFP FPSR_REG))
10846 (clobber (reg:CCFP FLAGS_REG))
10847 (clobber (match_scratch:HI 4 "=a"))]
10848 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10849 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10850 && !TARGET_CMOVE"
10851 "#")
10852
10853 (define_insn "*fp_jcc_3_387"
10854 [(set (pc)
10855 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10856 [(match_operand 1 "register_operand" "f")
10857 (match_operand 2 "const0_operand" "")])
10858 (label_ref (match_operand 3 "" ""))
10859 (pc)))
10860 (clobber (reg:CCFP FPSR_REG))
10861 (clobber (reg:CCFP FLAGS_REG))
10862 (clobber (match_scratch:HI 4 "=a"))]
10863 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10864 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10865 && SELECT_CC_MODE (GET_CODE (operands[0]),
10866 operands[1], operands[2]) == CCFPmode
10867 && !TARGET_CMOVE"
10868 "#")
10869
10870 (define_split
10871 [(set (pc)
10872 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10873 [(match_operand 1 "register_operand" "")
10874 (match_operand 2 "nonimmediate_operand" "")])
10875 (match_operand 3 "" "")
10876 (match_operand 4 "" "")))
10877 (clobber (reg:CCFP FPSR_REG))
10878 (clobber (reg:CCFP FLAGS_REG))]
10879 "reload_completed"
10880 [(const_int 0)]
10881 {
10882 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10883 operands[3], operands[4], NULL_RTX, NULL_RTX);
10884 DONE;
10885 })
10886
10887 (define_split
10888 [(set (pc)
10889 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10890 [(match_operand 1 "register_operand" "")
10891 (match_operand 2 "general_operand" "")])
10892 (match_operand 3 "" "")
10893 (match_operand 4 "" "")))
10894 (clobber (reg:CCFP FPSR_REG))
10895 (clobber (reg:CCFP FLAGS_REG))
10896 (clobber (match_scratch:HI 5 "=a"))]
10897 "reload_completed"
10898 [(const_int 0)]
10899 {
10900 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10901 operands[3], operands[4], operands[5], NULL_RTX);
10902 DONE;
10903 })
10904
10905 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10906 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10907 ;; with a precedence over other operators and is always put in the first
10908 ;; place. Swap condition and operands to match ficom instruction.
10909
10910 (define_insn "*fp_jcc_4_<mode>_387"
10911 [(set (pc)
10912 (if_then_else
10913 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10914 [(match_operator 1 "float_operator"
10915 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10916 (match_operand 3 "register_operand" "f,f")])
10917 (label_ref (match_operand 4 "" ""))
10918 (pc)))
10919 (clobber (reg:CCFP FPSR_REG))
10920 (clobber (reg:CCFP FLAGS_REG))
10921 (clobber (match_scratch:HI 5 "=a,a"))]
10922 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10923 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10924 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10925 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10926 && !TARGET_CMOVE"
10927 "#")
10928
10929 (define_split
10930 [(set (pc)
10931 (if_then_else
10932 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10933 [(match_operator 1 "float_operator"
10934 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10935 (match_operand 3 "register_operand" "")])
10936 (match_operand 4 "" "")
10937 (match_operand 5 "" "")))
10938 (clobber (reg:CCFP FPSR_REG))
10939 (clobber (reg:CCFP FLAGS_REG))
10940 (clobber (match_scratch:HI 6 "=a"))]
10941 "reload_completed"
10942 [(const_int 0)]
10943 {
10944 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10945
10946 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10947 operands[3], operands[7],
10948 operands[4], operands[5], operands[6], NULL_RTX);
10949 DONE;
10950 })
10951
10952 ;; %%% Kill this when reload knows how to do it.
10953 (define_split
10954 [(set (pc)
10955 (if_then_else
10956 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10957 [(match_operator 1 "float_operator"
10958 [(match_operand:X87MODEI12 2 "register_operand" "")])
10959 (match_operand 3 "register_operand" "")])
10960 (match_operand 4 "" "")
10961 (match_operand 5 "" "")))
10962 (clobber (reg:CCFP FPSR_REG))
10963 (clobber (reg:CCFP FLAGS_REG))
10964 (clobber (match_scratch:HI 6 "=a"))]
10965 "reload_completed"
10966 [(const_int 0)]
10967 {
10968 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10969 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10970
10971 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10972 operands[3], operands[7],
10973 operands[4], operands[5], operands[6], operands[2]);
10974 DONE;
10975 })
10976 \f
10977 ;; Unconditional and other jump instructions
10978
10979 (define_insn "jump"
10980 [(set (pc)
10981 (label_ref (match_operand 0 "" "")))]
10982 ""
10983 "jmp\t%l0"
10984 [(set_attr "type" "ibr")
10985 (set (attr "length")
10986 (if_then_else (and (ge (minus (match_dup 0) (pc))
10987 (const_int -126))
10988 (lt (minus (match_dup 0) (pc))
10989 (const_int 128)))
10990 (const_int 2)
10991 (const_int 5)))
10992 (set_attr "modrm" "0")])
10993
10994 (define_expand "indirect_jump"
10995 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10996 ""
10997 "")
10998
10999 (define_insn "*indirect_jump"
11000 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11001 ""
11002 "jmp\t%A0"
11003 [(set_attr "type" "ibr")
11004 (set_attr "length_immediate" "0")])
11005
11006 (define_expand "tablejump"
11007 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11008 (use (label_ref (match_operand 1 "" "")))])]
11009 ""
11010 {
11011 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11012 relative. Convert the relative address to an absolute address. */
11013 if (flag_pic)
11014 {
11015 rtx op0, op1;
11016 enum rtx_code code;
11017
11018 /* We can't use @GOTOFF for text labels on VxWorks;
11019 see gotoff_operand. */
11020 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11021 {
11022 code = PLUS;
11023 op0 = operands[0];
11024 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11025 }
11026 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11027 {
11028 code = PLUS;
11029 op0 = operands[0];
11030 op1 = pic_offset_table_rtx;
11031 }
11032 else
11033 {
11034 code = MINUS;
11035 op0 = pic_offset_table_rtx;
11036 op1 = operands[0];
11037 }
11038
11039 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11040 OPTAB_DIRECT);
11041 }
11042 })
11043
11044 (define_insn "*tablejump_1"
11045 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11046 (use (label_ref (match_operand 1 "" "")))]
11047 ""
11048 "jmp\t%A0"
11049 [(set_attr "type" "ibr")
11050 (set_attr "length_immediate" "0")])
11051 \f
11052 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11053
11054 (define_peephole2
11055 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11056 (set (match_operand:QI 1 "register_operand" "")
11057 (match_operator:QI 2 "ix86_comparison_operator"
11058 [(reg FLAGS_REG) (const_int 0)]))
11059 (set (match_operand 3 "q_regs_operand" "")
11060 (zero_extend (match_dup 1)))]
11061 "(peep2_reg_dead_p (3, operands[1])
11062 || operands_match_p (operands[1], operands[3]))
11063 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11064 [(set (match_dup 4) (match_dup 0))
11065 (set (strict_low_part (match_dup 5))
11066 (match_dup 2))]
11067 {
11068 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11069 operands[5] = gen_lowpart (QImode, operands[3]);
11070 ix86_expand_clear (operands[3]);
11071 })
11072
11073 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11074
11075 (define_peephole2
11076 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11077 (set (match_operand:QI 1 "register_operand" "")
11078 (match_operator:QI 2 "ix86_comparison_operator"
11079 [(reg FLAGS_REG) (const_int 0)]))
11080 (parallel [(set (match_operand 3 "q_regs_operand" "")
11081 (zero_extend (match_dup 1)))
11082 (clobber (reg:CC FLAGS_REG))])]
11083 "(peep2_reg_dead_p (3, operands[1])
11084 || operands_match_p (operands[1], operands[3]))
11085 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11086 [(set (match_dup 4) (match_dup 0))
11087 (set (strict_low_part (match_dup 5))
11088 (match_dup 2))]
11089 {
11090 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11091 operands[5] = gen_lowpart (QImode, operands[3]);
11092 ix86_expand_clear (operands[3]);
11093 })
11094 \f
11095 ;; Call instructions.
11096
11097 ;; The predicates normally associated with named expanders are not properly
11098 ;; checked for calls. This is a bug in the generic code, but it isn't that
11099 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11100
11101 ;; P6 processors will jump to the address after the decrement when %esp
11102 ;; is used as a call operand, so they will execute return address as a code.
11103 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11104
11105 ;; Register constraint for call instruction.
11106 (define_mode_attr c [(SI "l") (DI "r")])
11107
11108 ;; Call subroutine returning no value.
11109
11110 (define_expand "call"
11111 [(call (match_operand:QI 0 "" "")
11112 (match_operand 1 "" ""))
11113 (use (match_operand 2 "" ""))]
11114 ""
11115 {
11116 ix86_expand_call (NULL, operands[0], operands[1],
11117 operands[2], NULL, false);
11118 DONE;
11119 })
11120
11121 (define_expand "sibcall"
11122 [(call (match_operand:QI 0 "" "")
11123 (match_operand 1 "" ""))
11124 (use (match_operand 2 "" ""))]
11125 ""
11126 {
11127 ix86_expand_call (NULL, operands[0], operands[1],
11128 operands[2], NULL, true);
11129 DONE;
11130 })
11131
11132 (define_insn_and_split "*call_vzeroupper"
11133 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11134 (match_operand 1 "" ""))
11135 (unspec [(match_operand 2 "const_int_operand" "")]
11136 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11137 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11138 "#"
11139 "&& reload_completed"
11140 [(const_int 0)]
11141 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11142 [(set_attr "type" "call")])
11143
11144 (define_insn "*call"
11145 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11146 (match_operand 1 "" ""))]
11147 "!SIBLING_CALL_P (insn)"
11148 "* return ix86_output_call_insn (insn, operands[0]);"
11149 [(set_attr "type" "call")])
11150
11151 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11152 [(parallel
11153 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11154 (match_operand 1 "" ""))
11155 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11156 (clobber (reg:TI XMM6_REG))
11157 (clobber (reg:TI XMM7_REG))
11158 (clobber (reg:TI XMM8_REG))
11159 (clobber (reg:TI XMM9_REG))
11160 (clobber (reg:TI XMM10_REG))
11161 (clobber (reg:TI XMM11_REG))
11162 (clobber (reg:TI XMM12_REG))
11163 (clobber (reg:TI XMM13_REG))
11164 (clobber (reg:TI XMM14_REG))
11165 (clobber (reg:TI XMM15_REG))
11166 (clobber (reg:DI SI_REG))
11167 (clobber (reg:DI DI_REG))])
11168 (unspec [(match_operand 2 "const_int_operand" "")]
11169 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11170 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11171 "#"
11172 "&& reload_completed"
11173 [(const_int 0)]
11174 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11175 [(set_attr "type" "call")])
11176
11177 (define_insn "*call_rex64_ms_sysv"
11178 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11179 (match_operand 1 "" ""))
11180 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11181 (clobber (reg:TI XMM6_REG))
11182 (clobber (reg:TI XMM7_REG))
11183 (clobber (reg:TI XMM8_REG))
11184 (clobber (reg:TI XMM9_REG))
11185 (clobber (reg:TI XMM10_REG))
11186 (clobber (reg:TI XMM11_REG))
11187 (clobber (reg:TI XMM12_REG))
11188 (clobber (reg:TI XMM13_REG))
11189 (clobber (reg:TI XMM14_REG))
11190 (clobber (reg:TI XMM15_REG))
11191 (clobber (reg:DI SI_REG))
11192 (clobber (reg:DI DI_REG))]
11193 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11194 "* return ix86_output_call_insn (insn, operands[0]);"
11195 [(set_attr "type" "call")])
11196
11197 (define_insn_and_split "*sibcall_vzeroupper"
11198 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11199 (match_operand 1 "" ""))
11200 (unspec [(match_operand 2 "const_int_operand" "")]
11201 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11202 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11203 "#"
11204 "&& reload_completed"
11205 [(const_int 0)]
11206 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11207 [(set_attr "type" "call")])
11208
11209 (define_insn "*sibcall"
11210 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11211 (match_operand 1 "" ""))]
11212 "SIBLING_CALL_P (insn)"
11213 "* return ix86_output_call_insn (insn, operands[0]);"
11214 [(set_attr "type" "call")])
11215
11216 (define_expand "call_pop"
11217 [(parallel [(call (match_operand:QI 0 "" "")
11218 (match_operand:SI 1 "" ""))
11219 (set (reg:SI SP_REG)
11220 (plus:SI (reg:SI SP_REG)
11221 (match_operand:SI 3 "" "")))])]
11222 "!TARGET_64BIT"
11223 {
11224 ix86_expand_call (NULL, operands[0], operands[1],
11225 operands[2], operands[3], false);
11226 DONE;
11227 })
11228
11229 (define_insn_and_split "*call_pop_vzeroupper"
11230 [(parallel
11231 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11232 (match_operand:SI 1 "" ""))
11233 (set (reg:SI SP_REG)
11234 (plus:SI (reg:SI SP_REG)
11235 (match_operand:SI 2 "immediate_operand" "i")))])
11236 (unspec [(match_operand 3 "const_int_operand" "")]
11237 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11238 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11239 "#"
11240 "&& reload_completed"
11241 [(const_int 0)]
11242 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11243 [(set_attr "type" "call")])
11244
11245 (define_insn "*call_pop"
11246 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11247 (match_operand 1 "" ""))
11248 (set (reg:SI SP_REG)
11249 (plus:SI (reg:SI SP_REG)
11250 (match_operand:SI 2 "immediate_operand" "i")))]
11251 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11252 "* return ix86_output_call_insn (insn, operands[0]);"
11253 [(set_attr "type" "call")])
11254
11255 (define_insn_and_split "*sibcall_pop_vzeroupper"
11256 [(parallel
11257 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11258 (match_operand 1 "" ""))
11259 (set (reg:SI SP_REG)
11260 (plus:SI (reg:SI SP_REG)
11261 (match_operand:SI 2 "immediate_operand" "i")))])
11262 (unspec [(match_operand 3 "const_int_operand" "")]
11263 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11264 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11265 "#"
11266 "&& reload_completed"
11267 [(const_int 0)]
11268 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11269 [(set_attr "type" "call")])
11270
11271 (define_insn "*sibcall_pop"
11272 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11273 (match_operand 1 "" ""))
11274 (set (reg:SI SP_REG)
11275 (plus:SI (reg:SI SP_REG)
11276 (match_operand:SI 2 "immediate_operand" "i")))]
11277 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11278 "* return ix86_output_call_insn (insn, operands[0]);"
11279 [(set_attr "type" "call")])
11280
11281 ;; Call subroutine, returning value in operand 0
11282
11283 (define_expand "call_value"
11284 [(set (match_operand 0 "" "")
11285 (call (match_operand:QI 1 "" "")
11286 (match_operand 2 "" "")))
11287 (use (match_operand 3 "" ""))]
11288 ""
11289 {
11290 ix86_expand_call (operands[0], operands[1], operands[2],
11291 operands[3], NULL, false);
11292 DONE;
11293 })
11294
11295 (define_expand "sibcall_value"
11296 [(set (match_operand 0 "" "")
11297 (call (match_operand:QI 1 "" "")
11298 (match_operand 2 "" "")))
11299 (use (match_operand 3 "" ""))]
11300 ""
11301 {
11302 ix86_expand_call (operands[0], operands[1], operands[2],
11303 operands[3], NULL, true);
11304 DONE;
11305 })
11306
11307 (define_insn_and_split "*call_value_vzeroupper"
11308 [(set (match_operand 0 "" "")
11309 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11310 (match_operand 2 "" "")))
11311 (unspec [(match_operand 3 "const_int_operand" "")]
11312 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11313 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11314 "#"
11315 "&& reload_completed"
11316 [(const_int 0)]
11317 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11318 [(set_attr "type" "callv")])
11319
11320 (define_insn "*call_value"
11321 [(set (match_operand 0 "" "")
11322 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11323 (match_operand 2 "" "")))]
11324 "!SIBLING_CALL_P (insn)"
11325 "* return ix86_output_call_insn (insn, operands[1]);"
11326 [(set_attr "type" "callv")])
11327
11328 (define_insn_and_split "*sibcall_value_vzeroupper"
11329 [(set (match_operand 0 "" "")
11330 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11331 (match_operand 2 "" "")))
11332 (unspec [(match_operand 3 "const_int_operand" "")]
11333 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11334 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11335 "#"
11336 "&& reload_completed"
11337 [(const_int 0)]
11338 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11339 [(set_attr "type" "callv")])
11340
11341 (define_insn "*sibcall_value"
11342 [(set (match_operand 0 "" "")
11343 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11344 (match_operand 2 "" "")))]
11345 "SIBLING_CALL_P (insn)"
11346 "* return ix86_output_call_insn (insn, operands[1]);"
11347 [(set_attr "type" "callv")])
11348
11349 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11350 [(parallel
11351 [(set (match_operand 0 "" "")
11352 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11353 (match_operand 2 "" "")))
11354 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11355 (clobber (reg:TI XMM6_REG))
11356 (clobber (reg:TI XMM7_REG))
11357 (clobber (reg:TI XMM8_REG))
11358 (clobber (reg:TI XMM9_REG))
11359 (clobber (reg:TI XMM10_REG))
11360 (clobber (reg:TI XMM11_REG))
11361 (clobber (reg:TI XMM12_REG))
11362 (clobber (reg:TI XMM13_REG))
11363 (clobber (reg:TI XMM14_REG))
11364 (clobber (reg:TI XMM15_REG))
11365 (clobber (reg:DI SI_REG))
11366 (clobber (reg:DI DI_REG))])
11367 (unspec [(match_operand 3 "const_int_operand" "")]
11368 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11369 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11370 "#"
11371 "&& reload_completed"
11372 [(const_int 0)]
11373 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11374 [(set_attr "type" "callv")])
11375
11376 (define_insn "*call_value_rex64_ms_sysv"
11377 [(set (match_operand 0 "" "")
11378 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11379 (match_operand 2 "" "")))
11380 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11381 (clobber (reg:TI XMM6_REG))
11382 (clobber (reg:TI XMM7_REG))
11383 (clobber (reg:TI XMM8_REG))
11384 (clobber (reg:TI XMM9_REG))
11385 (clobber (reg:TI XMM10_REG))
11386 (clobber (reg:TI XMM11_REG))
11387 (clobber (reg:TI XMM12_REG))
11388 (clobber (reg:TI XMM13_REG))
11389 (clobber (reg:TI XMM14_REG))
11390 (clobber (reg:TI XMM15_REG))
11391 (clobber (reg:DI SI_REG))
11392 (clobber (reg:DI DI_REG))]
11393 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11394 "* return ix86_output_call_insn (insn, operands[1]);"
11395 [(set_attr "type" "callv")])
11396
11397 (define_expand "call_value_pop"
11398 [(parallel [(set (match_operand 0 "" "")
11399 (call (match_operand:QI 1 "" "")
11400 (match_operand:SI 2 "" "")))
11401 (set (reg:SI SP_REG)
11402 (plus:SI (reg:SI SP_REG)
11403 (match_operand:SI 4 "" "")))])]
11404 "!TARGET_64BIT"
11405 {
11406 ix86_expand_call (operands[0], operands[1], operands[2],
11407 operands[3], operands[4], false);
11408 DONE;
11409 })
11410
11411 (define_insn_and_split "*call_value_pop_vzeroupper"
11412 [(parallel
11413 [(set (match_operand 0 "" "")
11414 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11415 (match_operand 2 "" "")))
11416 (set (reg:SI SP_REG)
11417 (plus:SI (reg:SI SP_REG)
11418 (match_operand:SI 3 "immediate_operand" "i")))])
11419 (unspec [(match_operand 4 "const_int_operand" "")]
11420 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11421 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11422 "#"
11423 "&& reload_completed"
11424 [(const_int 0)]
11425 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11426 [(set_attr "type" "callv")])
11427
11428 (define_insn "*call_value_pop"
11429 [(set (match_operand 0 "" "")
11430 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11431 (match_operand 2 "" "")))
11432 (set (reg:SI SP_REG)
11433 (plus:SI (reg:SI SP_REG)
11434 (match_operand:SI 3 "immediate_operand" "i")))]
11435 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11436 "* return ix86_output_call_insn (insn, operands[1]);"
11437 [(set_attr "type" "callv")])
11438
11439 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11440 [(parallel
11441 [(set (match_operand 0 "" "")
11442 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11443 (match_operand 2 "" "")))
11444 (set (reg:SI SP_REG)
11445 (plus:SI (reg:SI SP_REG)
11446 (match_operand:SI 3 "immediate_operand" "i")))])
11447 (unspec [(match_operand 4 "const_int_operand" "")]
11448 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11449 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11450 "#"
11451 "&& reload_completed"
11452 [(const_int 0)]
11453 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11454 [(set_attr "type" "callv")])
11455
11456 (define_insn "*sibcall_value_pop"
11457 [(set (match_operand 0 "" "")
11458 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11459 (match_operand 2 "" "")))
11460 (set (reg:SI SP_REG)
11461 (plus:SI (reg:SI SP_REG)
11462 (match_operand:SI 3 "immediate_operand" "i")))]
11463 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11464 "* return ix86_output_call_insn (insn, operands[1]);"
11465 [(set_attr "type" "callv")])
11466
11467 ;; Call subroutine returning any type.
11468
11469 (define_expand "untyped_call"
11470 [(parallel [(call (match_operand 0 "" "")
11471 (const_int 0))
11472 (match_operand 1 "" "")
11473 (match_operand 2 "" "")])]
11474 ""
11475 {
11476 int i;
11477
11478 /* In order to give reg-stack an easier job in validating two
11479 coprocessor registers as containing a possible return value,
11480 simply pretend the untyped call returns a complex long double
11481 value.
11482
11483 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11484 and should have the default ABI. */
11485
11486 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11487 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11488 operands[0], const0_rtx,
11489 GEN_INT ((TARGET_64BIT
11490 ? (ix86_abi == SYSV_ABI
11491 ? X86_64_SSE_REGPARM_MAX
11492 : X86_64_MS_SSE_REGPARM_MAX)
11493 : X86_32_SSE_REGPARM_MAX)
11494 - 1),
11495 NULL, false);
11496
11497 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11498 {
11499 rtx set = XVECEXP (operands[2], 0, i);
11500 emit_move_insn (SET_DEST (set), SET_SRC (set));
11501 }
11502
11503 /* The optimizer does not know that the call sets the function value
11504 registers we stored in the result block. We avoid problems by
11505 claiming that all hard registers are used and clobbered at this
11506 point. */
11507 emit_insn (gen_blockage ());
11508
11509 DONE;
11510 })
11511 \f
11512 ;; Prologue and epilogue instructions
11513
11514 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11515 ;; all of memory. This blocks insns from being moved across this point.
11516
11517 (define_insn "blockage"
11518 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11519 ""
11520 ""
11521 [(set_attr "length" "0")])
11522
11523 ;; Do not schedule instructions accessing memory across this point.
11524
11525 (define_expand "memory_blockage"
11526 [(set (match_dup 0)
11527 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11528 ""
11529 {
11530 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11531 MEM_VOLATILE_P (operands[0]) = 1;
11532 })
11533
11534 (define_insn "*memory_blockage"
11535 [(set (match_operand:BLK 0 "" "")
11536 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11537 ""
11538 ""
11539 [(set_attr "length" "0")])
11540
11541 ;; As USE insns aren't meaningful after reload, this is used instead
11542 ;; to prevent deleting instructions setting registers for PIC code
11543 (define_insn "prologue_use"
11544 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11545 ""
11546 ""
11547 [(set_attr "length" "0")])
11548
11549 ;; Insn emitted into the body of a function to return from a function.
11550 ;; This is only done if the function's epilogue is known to be simple.
11551 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11552
11553 (define_expand "return"
11554 [(return)]
11555 "ix86_can_use_return_insn_p ()"
11556 {
11557 if (crtl->args.pops_args)
11558 {
11559 rtx popc = GEN_INT (crtl->args.pops_args);
11560 emit_jump_insn (gen_return_pop_internal (popc));
11561 DONE;
11562 }
11563 })
11564
11565 (define_insn "return_internal"
11566 [(return)]
11567 "reload_completed"
11568 "ret"
11569 [(set_attr "length" "1")
11570 (set_attr "atom_unit" "jeu")
11571 (set_attr "length_immediate" "0")
11572 (set_attr "modrm" "0")])
11573
11574 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11575 ;; instruction Athlon and K8 have.
11576
11577 (define_insn "return_internal_long"
11578 [(return)
11579 (unspec [(const_int 0)] UNSPEC_REP)]
11580 "reload_completed"
11581 "rep\;ret"
11582 [(set_attr "length" "2")
11583 (set_attr "atom_unit" "jeu")
11584 (set_attr "length_immediate" "0")
11585 (set_attr "prefix_rep" "1")
11586 (set_attr "modrm" "0")])
11587
11588 (define_insn "return_pop_internal"
11589 [(return)
11590 (use (match_operand:SI 0 "const_int_operand" ""))]
11591 "reload_completed"
11592 "ret\t%0"
11593 [(set_attr "length" "3")
11594 (set_attr "atom_unit" "jeu")
11595 (set_attr "length_immediate" "2")
11596 (set_attr "modrm" "0")])
11597
11598 (define_insn "return_indirect_internal"
11599 [(return)
11600 (use (match_operand:SI 0 "register_operand" "r"))]
11601 "reload_completed"
11602 "jmp\t%A0"
11603 [(set_attr "type" "ibr")
11604 (set_attr "length_immediate" "0")])
11605
11606 (define_insn "nop"
11607 [(const_int 0)]
11608 ""
11609 "nop"
11610 [(set_attr "length" "1")
11611 (set_attr "length_immediate" "0")
11612 (set_attr "modrm" "0")])
11613
11614 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11615 (define_insn "nops"
11616 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11617 UNSPECV_NOPS)]
11618 "reload_completed"
11619 {
11620 int num = INTVAL (operands[0]);
11621
11622 gcc_assert (num >= 1 && num <= 8);
11623
11624 while (num--)
11625 fputs ("\tnop\n", asm_out_file);
11626
11627 return "";
11628 }
11629 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11630 (set_attr "length_immediate" "0")
11631 (set_attr "modrm" "0")])
11632
11633 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11634 ;; branch prediction penalty for the third jump in a 16-byte
11635 ;; block on K8.
11636
11637 (define_insn "pad"
11638 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11639 ""
11640 {
11641 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11642 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11643 #else
11644 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11645 The align insn is used to avoid 3 jump instructions in the row to improve
11646 branch prediction and the benefits hardly outweigh the cost of extra 8
11647 nops on the average inserted by full alignment pseudo operation. */
11648 #endif
11649 return "";
11650 }
11651 [(set_attr "length" "16")])
11652
11653 (define_expand "prologue"
11654 [(const_int 0)]
11655 ""
11656 "ix86_expand_prologue (); DONE;")
11657
11658 (define_insn "set_got"
11659 [(set (match_operand:SI 0 "register_operand" "=r")
11660 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11661 (clobber (reg:CC FLAGS_REG))]
11662 "!TARGET_64BIT"
11663 "* return output_set_got (operands[0], NULL_RTX);"
11664 [(set_attr "type" "multi")
11665 (set_attr "length" "12")])
11666
11667 (define_insn "set_got_labelled"
11668 [(set (match_operand:SI 0 "register_operand" "=r")
11669 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11670 UNSPEC_SET_GOT))
11671 (clobber (reg:CC FLAGS_REG))]
11672 "!TARGET_64BIT"
11673 "* return output_set_got (operands[0], operands[1]);"
11674 [(set_attr "type" "multi")
11675 (set_attr "length" "12")])
11676
11677 (define_insn "set_got_rex64"
11678 [(set (match_operand:DI 0 "register_operand" "=r")
11679 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11680 "TARGET_64BIT"
11681 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11682 [(set_attr "type" "lea")
11683 (set_attr "length_address" "4")
11684 (set_attr "mode" "DI")])
11685
11686 (define_insn "set_rip_rex64"
11687 [(set (match_operand:DI 0 "register_operand" "=r")
11688 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11689 "TARGET_64BIT"
11690 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11691 [(set_attr "type" "lea")
11692 (set_attr "length_address" "4")
11693 (set_attr "mode" "DI")])
11694
11695 (define_insn "set_got_offset_rex64"
11696 [(set (match_operand:DI 0 "register_operand" "=r")
11697 (unspec:DI
11698 [(label_ref (match_operand 1 "" ""))]
11699 UNSPEC_SET_GOT_OFFSET))]
11700 "TARGET_64BIT"
11701 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11702 [(set_attr "type" "imov")
11703 (set_attr "length_immediate" "0")
11704 (set_attr "length_address" "8")
11705 (set_attr "mode" "DI")])
11706
11707 (define_expand "epilogue"
11708 [(const_int 0)]
11709 ""
11710 "ix86_expand_epilogue (1); DONE;")
11711
11712 (define_expand "sibcall_epilogue"
11713 [(const_int 0)]
11714 ""
11715 "ix86_expand_epilogue (0); DONE;")
11716
11717 (define_expand "eh_return"
11718 [(use (match_operand 0 "register_operand" ""))]
11719 ""
11720 {
11721 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11722
11723 /* Tricky bit: we write the address of the handler to which we will
11724 be returning into someone else's stack frame, one word below the
11725 stack address we wish to restore. */
11726 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11727 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11728 tmp = gen_rtx_MEM (Pmode, tmp);
11729 emit_move_insn (tmp, ra);
11730
11731 emit_jump_insn (gen_eh_return_internal ());
11732 emit_barrier ();
11733 DONE;
11734 })
11735
11736 (define_insn_and_split "eh_return_internal"
11737 [(eh_return)]
11738 ""
11739 "#"
11740 "epilogue_completed"
11741 [(const_int 0)]
11742 "ix86_expand_epilogue (2); DONE;")
11743
11744 (define_insn "leave"
11745 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11746 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11747 (clobber (mem:BLK (scratch)))]
11748 "!TARGET_64BIT"
11749 "leave"
11750 [(set_attr "type" "leave")])
11751
11752 (define_insn "leave_rex64"
11753 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11754 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11755 (clobber (mem:BLK (scratch)))]
11756 "TARGET_64BIT"
11757 "leave"
11758 [(set_attr "type" "leave")])
11759 \f
11760 ;; Handle -fsplit-stack.
11761
11762 (define_expand "split_stack_prologue"
11763 [(const_int 0)]
11764 ""
11765 {
11766 ix86_expand_split_stack_prologue ();
11767 DONE;
11768 })
11769
11770 ;; In order to support the call/return predictor, we use a return
11771 ;; instruction which the middle-end doesn't see.
11772 (define_insn "split_stack_return"
11773 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11774 UNSPECV_SPLIT_STACK_RETURN)]
11775 ""
11776 {
11777 if (operands[0] == const0_rtx)
11778 return "ret";
11779 else
11780 return "ret\t%0";
11781 }
11782 [(set_attr "atom_unit" "jeu")
11783 (set_attr "modrm" "0")
11784 (set (attr "length")
11785 (if_then_else (match_operand:SI 0 "const0_operand" "")
11786 (const_int 1)
11787 (const_int 3)))
11788 (set (attr "length_immediate")
11789 (if_then_else (match_operand:SI 0 "const0_operand" "")
11790 (const_int 0)
11791 (const_int 2)))])
11792
11793 ;; If there are operand 0 bytes available on the stack, jump to
11794 ;; operand 1.
11795
11796 (define_expand "split_stack_space_check"
11797 [(set (pc) (if_then_else
11798 (ltu (minus (reg SP_REG)
11799 (match_operand 0 "register_operand" ""))
11800 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11801 (label_ref (match_operand 1 "" ""))
11802 (pc)))]
11803 ""
11804 {
11805 rtx reg, size, limit;
11806
11807 reg = gen_reg_rtx (Pmode);
11808 size = force_reg (Pmode, operands[0]);
11809 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11810 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11811 UNSPEC_STACK_CHECK);
11812 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11813 ix86_expand_branch (GEU, reg, limit, operands[1]);
11814
11815 DONE;
11816 })
11817 \f
11818 ;; Bit manipulation instructions.
11819
11820 (define_expand "ffs<mode>2"
11821 [(set (match_dup 2) (const_int -1))
11822 (parallel [(set (reg:CCZ FLAGS_REG)
11823 (compare:CCZ
11824 (match_operand:SWI48 1 "nonimmediate_operand" "")
11825 (const_int 0)))
11826 (set (match_operand:SWI48 0 "register_operand" "")
11827 (ctz:SWI48 (match_dup 1)))])
11828 (set (match_dup 0) (if_then_else:SWI48
11829 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11830 (match_dup 2)
11831 (match_dup 0)))
11832 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11833 (clobber (reg:CC FLAGS_REG))])]
11834 ""
11835 {
11836 if (<MODE>mode == SImode && !TARGET_CMOVE)
11837 {
11838 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11839 DONE;
11840 }
11841 operands[2] = gen_reg_rtx (<MODE>mode);
11842 })
11843
11844 (define_insn_and_split "ffssi2_no_cmove"
11845 [(set (match_operand:SI 0 "register_operand" "=r")
11846 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11847 (clobber (match_scratch:SI 2 "=&q"))
11848 (clobber (reg:CC FLAGS_REG))]
11849 "!TARGET_CMOVE"
11850 "#"
11851 "&& reload_completed"
11852 [(parallel [(set (reg:CCZ FLAGS_REG)
11853 (compare:CCZ (match_dup 1) (const_int 0)))
11854 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11855 (set (strict_low_part (match_dup 3))
11856 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11857 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11858 (clobber (reg:CC FLAGS_REG))])
11859 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11860 (clobber (reg:CC FLAGS_REG))])
11861 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11862 (clobber (reg:CC FLAGS_REG))])]
11863 {
11864 operands[3] = gen_lowpart (QImode, operands[2]);
11865 ix86_expand_clear (operands[2]);
11866 })
11867
11868 (define_insn "*ffs<mode>_1"
11869 [(set (reg:CCZ FLAGS_REG)
11870 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11871 (const_int 0)))
11872 (set (match_operand:SWI48 0 "register_operand" "=r")
11873 (ctz:SWI48 (match_dup 1)))]
11874 ""
11875 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11876 [(set_attr "type" "alu1")
11877 (set_attr "prefix_0f" "1")
11878 (set_attr "mode" "<MODE>")])
11879
11880 (define_insn "ctz<mode>2"
11881 [(set (match_operand:SWI248 0 "register_operand" "=r")
11882 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11883 (clobber (reg:CC FLAGS_REG))]
11884 ""
11885 {
11886 if (TARGET_BMI)
11887 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11888 else
11889 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11890 }
11891 [(set_attr "type" "alu1")
11892 (set_attr "prefix_0f" "1")
11893 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11894 (set_attr "mode" "<MODE>")])
11895
11896 (define_expand "clz<mode>2"
11897 [(parallel
11898 [(set (match_operand:SWI248 0 "register_operand" "")
11899 (minus:SWI248
11900 (match_dup 2)
11901 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11902 (clobber (reg:CC FLAGS_REG))])
11903 (parallel
11904 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11905 (clobber (reg:CC FLAGS_REG))])]
11906 ""
11907 {
11908 if (TARGET_ABM)
11909 {
11910 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11911 DONE;
11912 }
11913 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11914 })
11915
11916 (define_insn "clz<mode>2_abm"
11917 [(set (match_operand:SWI248 0 "register_operand" "=r")
11918 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11919 (clobber (reg:CC FLAGS_REG))]
11920 "TARGET_ABM || TARGET_BMI"
11921 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11922 [(set_attr "prefix_rep" "1")
11923 (set_attr "type" "bitmanip")
11924 (set_attr "mode" "<MODE>")])
11925
11926 ;; BMI instructions.
11927 (define_insn "*bmi_andn_<mode>"
11928 [(set (match_operand:SWI48 0 "register_operand" "=r")
11929 (and:SWI48
11930 (not:SWI48
11931 (match_operand:SWI48 1 "register_operand" "r"))
11932 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11933 (clobber (reg:CC FLAGS_REG))]
11934 "TARGET_BMI"
11935 "andn\t{%2, %1, %0|%0, %1, %2}"
11936 [(set_attr "type" "bitmanip")
11937 (set_attr "mode" "<MODE>")])
11938
11939 (define_insn "bmi_bextr_<mode>"
11940 [(set (match_operand:SWI48 0 "register_operand" "=r")
11941 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11942 (match_operand:SWI48 2 "register_operand" "r")]
11943 UNSPEC_BEXTR))
11944 (clobber (reg:CC FLAGS_REG))]
11945 "TARGET_BMI"
11946 "bextr\t{%2, %1, %0|%0, %1, %2}"
11947 [(set_attr "type" "bitmanip")
11948 (set_attr "mode" "<MODE>")])
11949
11950 (define_insn "*bmi_blsi_<mode>"
11951 [(set (match_operand:SWI48 0 "register_operand" "=r")
11952 (and:SWI48
11953 (neg:SWI48
11954 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11955 (match_dup 1)))
11956 (clobber (reg:CC FLAGS_REG))]
11957 "TARGET_BMI"
11958 "blsi\t{%1, %0|%0, %1}"
11959 [(set_attr "type" "bitmanip")
11960 (set_attr "mode" "<MODE>")])
11961
11962 (define_insn "*bmi_blsmsk_<mode>"
11963 [(set (match_operand:SWI48 0 "register_operand" "=r")
11964 (xor:SWI48
11965 (plus:SWI48
11966 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11967 (const_int -1))
11968 (match_dup 1)))
11969 (clobber (reg:CC FLAGS_REG))]
11970 "TARGET_BMI"
11971 "blsmsk\t{%1, %0|%0, %1}"
11972 [(set_attr "type" "bitmanip")
11973 (set_attr "mode" "<MODE>")])
11974
11975 (define_insn "*bmi_blsr_<mode>"
11976 [(set (match_operand:SWI48 0 "register_operand" "=r")
11977 (and:SWI48
11978 (plus:SWI48
11979 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11980 (const_int -1))
11981 (match_dup 1)))
11982 (clobber (reg:CC FLAGS_REG))]
11983 "TARGET_BMI"
11984 "blsr\t{%1, %0|%0, %1}"
11985 [(set_attr "type" "bitmanip")
11986 (set_attr "mode" "<MODE>")])
11987
11988 ;; TBM instructions.
11989 (define_insn "tbm_bextri_<mode>"
11990 [(set (match_operand:SWI48 0 "register_operand" "=r")
11991 (zero_extract:SWI48
11992 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11993 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11994 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11995 (clobber (reg:CC FLAGS_REG))]
11996 "TARGET_TBM"
11997 {
11998 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11999 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12000 }
12001 [(set_attr "type" "bitmanip")
12002 (set_attr "mode" "<MODE>")])
12003
12004 (define_insn "*tbm_blcfill_<mode>"
12005 [(set (match_operand:SWI48 0 "register_operand" "=r")
12006 (and:SWI48
12007 (plus:SWI48
12008 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12009 (const_int 1))
12010 (match_dup 1)))
12011 (clobber (reg:CC FLAGS_REG))]
12012 "TARGET_TBM"
12013 "blcfill\t{%1, %0|%0, %1}"
12014 [(set_attr "type" "bitmanip")
12015 (set_attr "mode" "<MODE>")])
12016
12017 (define_insn "*tbm_blci_<mode>"
12018 [(set (match_operand:SWI48 0 "register_operand" "=r")
12019 (ior:SWI48
12020 (not:SWI48
12021 (plus:SWI48
12022 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12023 (const_int 1)))
12024 (match_dup 1)))
12025 (clobber (reg:CC FLAGS_REG))]
12026 "TARGET_TBM"
12027 "blci\t{%1, %0|%0, %1}"
12028 [(set_attr "type" "bitmanip")
12029 (set_attr "mode" "<MODE>")])
12030
12031 (define_insn "*tbm_blcic_<mode>"
12032 [(set (match_operand:SWI48 0 "register_operand" "=r")
12033 (and:SWI48
12034 (plus:SWI48
12035 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12036 (const_int 1))
12037 (not:SWI48
12038 (match_dup 1))))
12039 (clobber (reg:CC FLAGS_REG))]
12040 "TARGET_TBM"
12041 "blcic\t{%1, %0|%0, %1}"
12042 [(set_attr "type" "bitmanip")
12043 (set_attr "mode" "<MODE>")])
12044
12045 (define_insn "*tbm_blcmsk_<mode>"
12046 [(set (match_operand:SWI48 0 "register_operand" "=r")
12047 (xor:SWI48
12048 (plus:SWI48
12049 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12050 (const_int 1))
12051 (match_dup 1)))
12052 (clobber (reg:CC FLAGS_REG))]
12053 "TARGET_TBM"
12054 "blcmsk\t{%1, %0|%0, %1}"
12055 [(set_attr "type" "bitmanip")
12056 (set_attr "mode" "<MODE>")])
12057
12058 (define_insn "*tbm_blcs_<mode>"
12059 [(set (match_operand:SWI48 0 "register_operand" "=r")
12060 (ior:SWI48
12061 (plus:SWI48
12062 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12063 (const_int 1))
12064 (match_dup 1)))
12065 (clobber (reg:CC FLAGS_REG))]
12066 "TARGET_TBM"
12067 "blcs\t{%1, %0|%0, %1}"
12068 [(set_attr "type" "bitmanip")
12069 (set_attr "mode" "<MODE>")])
12070
12071 (define_insn "*tbm_blsfill_<mode>"
12072 [(set (match_operand:SWI48 0 "register_operand" "=r")
12073 (ior:SWI48
12074 (plus:SWI48
12075 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12076 (const_int -1))
12077 (match_dup 1)))
12078 (clobber (reg:CC FLAGS_REG))]
12079 "TARGET_TBM"
12080 "blsfill\t{%1, %0|%0, %1}"
12081 [(set_attr "type" "bitmanip")
12082 (set_attr "mode" "<MODE>")])
12083
12084 (define_insn "*tbm_blsic_<mode>"
12085 [(set (match_operand:SWI48 0 "register_operand" "=r")
12086 (ior:SWI48
12087 (plus:SWI48
12088 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12089 (const_int -1))
12090 (not:SWI48
12091 (match_dup 1))))
12092 (clobber (reg:CC FLAGS_REG))]
12093 "TARGET_TBM"
12094 "blsic\t{%1, %0|%0, %1}"
12095 [(set_attr "type" "bitmanip")
12096 (set_attr "mode" "<MODE>")])
12097
12098 (define_insn "*tbm_t1mskc_<mode>"
12099 [(set (match_operand:SWI48 0 "register_operand" "=r")
12100 (ior:SWI48
12101 (plus:SWI48
12102 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12103 (const_int 1))
12104 (not:SWI48
12105 (match_dup 1))))
12106 (clobber (reg:CC FLAGS_REG))]
12107 "TARGET_TBM"
12108 "t1mskc\t{%1, %0|%0, %1}"
12109 [(set_attr "type" "bitmanip")
12110 (set_attr "mode" "<MODE>")])
12111
12112 (define_insn "*tbm_tzmsk_<mode>"
12113 [(set (match_operand:SWI48 0 "register_operand" "=r")
12114 (and:SWI48
12115 (plus:SWI48
12116 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12117 (const_int -1))
12118 (not:SWI48
12119 (match_dup 1))))
12120 (clobber (reg:CC FLAGS_REG))]
12121 "TARGET_TBM"
12122 "tzmsk\t{%1, %0|%0, %1}"
12123 [(set_attr "type" "bitmanip")
12124 (set_attr "mode" "<MODE>")])
12125
12126 (define_insn "bsr_rex64"
12127 [(set (match_operand:DI 0 "register_operand" "=r")
12128 (minus:DI (const_int 63)
12129 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12130 (clobber (reg:CC FLAGS_REG))]
12131 "TARGET_64BIT"
12132 "bsr{q}\t{%1, %0|%0, %1}"
12133 [(set_attr "type" "alu1")
12134 (set_attr "prefix_0f" "1")
12135 (set_attr "mode" "DI")])
12136
12137 (define_insn "bsr"
12138 [(set (match_operand:SI 0 "register_operand" "=r")
12139 (minus:SI (const_int 31)
12140 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12141 (clobber (reg:CC FLAGS_REG))]
12142 ""
12143 "bsr{l}\t{%1, %0|%0, %1}"
12144 [(set_attr "type" "alu1")
12145 (set_attr "prefix_0f" "1")
12146 (set_attr "mode" "SI")])
12147
12148 (define_insn "*bsrhi"
12149 [(set (match_operand:HI 0 "register_operand" "=r")
12150 (minus:HI (const_int 15)
12151 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12152 (clobber (reg:CC FLAGS_REG))]
12153 ""
12154 "bsr{w}\t{%1, %0|%0, %1}"
12155 [(set_attr "type" "alu1")
12156 (set_attr "prefix_0f" "1")
12157 (set_attr "mode" "HI")])
12158
12159 (define_insn "popcount<mode>2"
12160 [(set (match_operand:SWI248 0 "register_operand" "=r")
12161 (popcount:SWI248
12162 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12163 (clobber (reg:CC FLAGS_REG))]
12164 "TARGET_POPCNT"
12165 {
12166 #if TARGET_MACHO
12167 return "popcnt\t{%1, %0|%0, %1}";
12168 #else
12169 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12170 #endif
12171 }
12172 [(set_attr "prefix_rep" "1")
12173 (set_attr "type" "bitmanip")
12174 (set_attr "mode" "<MODE>")])
12175
12176 (define_insn "*popcount<mode>2_cmp"
12177 [(set (reg FLAGS_REG)
12178 (compare
12179 (popcount:SWI248
12180 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12181 (const_int 0)))
12182 (set (match_operand:SWI248 0 "register_operand" "=r")
12183 (popcount:SWI248 (match_dup 1)))]
12184 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12185 {
12186 #if TARGET_MACHO
12187 return "popcnt\t{%1, %0|%0, %1}";
12188 #else
12189 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12190 #endif
12191 }
12192 [(set_attr "prefix_rep" "1")
12193 (set_attr "type" "bitmanip")
12194 (set_attr "mode" "<MODE>")])
12195
12196 (define_insn "*popcountsi2_cmp_zext"
12197 [(set (reg FLAGS_REG)
12198 (compare
12199 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12200 (const_int 0)))
12201 (set (match_operand:DI 0 "register_operand" "=r")
12202 (zero_extend:DI(popcount:SI (match_dup 1))))]
12203 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12204 {
12205 #if TARGET_MACHO
12206 return "popcnt\t{%1, %0|%0, %1}";
12207 #else
12208 return "popcnt{l}\t{%1, %0|%0, %1}";
12209 #endif
12210 }
12211 [(set_attr "prefix_rep" "1")
12212 (set_attr "type" "bitmanip")
12213 (set_attr "mode" "SI")])
12214
12215 (define_expand "bswap<mode>2"
12216 [(set (match_operand:SWI48 0 "register_operand" "")
12217 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12218 ""
12219 {
12220 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12221 {
12222 rtx x = operands[0];
12223
12224 emit_move_insn (x, operands[1]);
12225 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12226 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12227 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12228 DONE;
12229 }
12230 })
12231
12232 (define_insn "*bswap<mode>2_movbe"
12233 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12234 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12235 "TARGET_MOVBE
12236 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12237 "@
12238 bswap\t%0
12239 movbe\t{%1, %0|%0, %1}
12240 movbe\t{%1, %0|%0, %1}"
12241 [(set_attr "type" "bitmanip,imov,imov")
12242 (set_attr "modrm" "0,1,1")
12243 (set_attr "prefix_0f" "*,1,1")
12244 (set_attr "prefix_extra" "*,1,1")
12245 (set_attr "mode" "<MODE>")])
12246
12247 (define_insn "*bswap<mode>2_1"
12248 [(set (match_operand:SWI48 0 "register_operand" "=r")
12249 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12250 "TARGET_BSWAP"
12251 "bswap\t%0"
12252 [(set_attr "type" "bitmanip")
12253 (set_attr "modrm" "0")
12254 (set_attr "mode" "<MODE>")])
12255
12256 (define_insn "*bswaphi_lowpart_1"
12257 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12258 (bswap:HI (match_dup 0)))
12259 (clobber (reg:CC FLAGS_REG))]
12260 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12261 "@
12262 xchg{b}\t{%h0, %b0|%b0, %h0}
12263 rol{w}\t{$8, %0|%0, 8}"
12264 [(set_attr "length" "2,4")
12265 (set_attr "mode" "QI,HI")])
12266
12267 (define_insn "bswaphi_lowpart"
12268 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12269 (bswap:HI (match_dup 0)))
12270 (clobber (reg:CC FLAGS_REG))]
12271 ""
12272 "rol{w}\t{$8, %0|%0, 8}"
12273 [(set_attr "length" "4")
12274 (set_attr "mode" "HI")])
12275
12276 (define_expand "paritydi2"
12277 [(set (match_operand:DI 0 "register_operand" "")
12278 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12279 "! TARGET_POPCNT"
12280 {
12281 rtx scratch = gen_reg_rtx (QImode);
12282 rtx cond;
12283
12284 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12285 NULL_RTX, operands[1]));
12286
12287 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12288 gen_rtx_REG (CCmode, FLAGS_REG),
12289 const0_rtx);
12290 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12291
12292 if (TARGET_64BIT)
12293 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12294 else
12295 {
12296 rtx tmp = gen_reg_rtx (SImode);
12297
12298 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12299 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12300 }
12301 DONE;
12302 })
12303
12304 (define_expand "paritysi2"
12305 [(set (match_operand:SI 0 "register_operand" "")
12306 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12307 "! TARGET_POPCNT"
12308 {
12309 rtx scratch = gen_reg_rtx (QImode);
12310 rtx cond;
12311
12312 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12313
12314 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12315 gen_rtx_REG (CCmode, FLAGS_REG),
12316 const0_rtx);
12317 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12318
12319 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12320 DONE;
12321 })
12322
12323 (define_insn_and_split "paritydi2_cmp"
12324 [(set (reg:CC FLAGS_REG)
12325 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12326 UNSPEC_PARITY))
12327 (clobber (match_scratch:DI 0 "=r"))
12328 (clobber (match_scratch:SI 1 "=&r"))
12329 (clobber (match_scratch:HI 2 "=Q"))]
12330 "! TARGET_POPCNT"
12331 "#"
12332 "&& reload_completed"
12333 [(parallel
12334 [(set (match_dup 1)
12335 (xor:SI (match_dup 1) (match_dup 4)))
12336 (clobber (reg:CC FLAGS_REG))])
12337 (parallel
12338 [(set (reg:CC FLAGS_REG)
12339 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12340 (clobber (match_dup 1))
12341 (clobber (match_dup 2))])]
12342 {
12343 operands[4] = gen_lowpart (SImode, operands[3]);
12344
12345 if (TARGET_64BIT)
12346 {
12347 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12348 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12349 }
12350 else
12351 operands[1] = gen_highpart (SImode, operands[3]);
12352 })
12353
12354 (define_insn_and_split "paritysi2_cmp"
12355 [(set (reg:CC FLAGS_REG)
12356 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12357 UNSPEC_PARITY))
12358 (clobber (match_scratch:SI 0 "=r"))
12359 (clobber (match_scratch:HI 1 "=&Q"))]
12360 "! TARGET_POPCNT"
12361 "#"
12362 "&& reload_completed"
12363 [(parallel
12364 [(set (match_dup 1)
12365 (xor:HI (match_dup 1) (match_dup 3)))
12366 (clobber (reg:CC FLAGS_REG))])
12367 (parallel
12368 [(set (reg:CC FLAGS_REG)
12369 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12370 (clobber (match_dup 1))])]
12371 {
12372 operands[3] = gen_lowpart (HImode, operands[2]);
12373
12374 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12375 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12376 })
12377
12378 (define_insn "*parityhi2_cmp"
12379 [(set (reg:CC FLAGS_REG)
12380 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12381 UNSPEC_PARITY))
12382 (clobber (match_scratch:HI 0 "=Q"))]
12383 "! TARGET_POPCNT"
12384 "xor{b}\t{%h0, %b0|%b0, %h0}"
12385 [(set_attr "length" "2")
12386 (set_attr "mode" "HI")])
12387 \f
12388 ;; Thread-local storage patterns for ELF.
12389 ;;
12390 ;; Note that these code sequences must appear exactly as shown
12391 ;; in order to allow linker relaxation.
12392
12393 (define_insn "*tls_global_dynamic_32_gnu"
12394 [(set (match_operand:SI 0 "register_operand" "=a")
12395 (unspec:SI
12396 [(match_operand:SI 1 "register_operand" "b")
12397 (match_operand:SI 2 "tls_symbolic_operand" "")
12398 (match_operand:SI 3 "constant_call_address_operand" "z")]
12399 UNSPEC_TLS_GD))
12400 (clobber (match_scratch:SI 4 "=d"))
12401 (clobber (match_scratch:SI 5 "=c"))
12402 (clobber (reg:CC FLAGS_REG))]
12403 "!TARGET_64BIT && TARGET_GNU_TLS"
12404 {
12405 output_asm_insn
12406 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12407 if (TARGET_SUN_TLS)
12408 #ifdef HAVE_AS_IX86_TLSGDPLT
12409 return "call\t%a2@tlsgdplt";
12410 #else
12411 return "call\t%p3@plt";
12412 #endif
12413 return "call\t%P3";
12414 }
12415 [(set_attr "type" "multi")
12416 (set_attr "length" "12")])
12417
12418 (define_expand "tls_global_dynamic_32"
12419 [(parallel
12420 [(set (match_operand:SI 0 "register_operand" "")
12421 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12422 (match_operand:SI 1 "tls_symbolic_operand" "")
12423 (match_operand:SI 3 "constant_call_address_operand" "")]
12424 UNSPEC_TLS_GD))
12425 (clobber (match_scratch:SI 4 ""))
12426 (clobber (match_scratch:SI 5 ""))
12427 (clobber (reg:CC FLAGS_REG))])])
12428
12429 (define_insn "*tls_global_dynamic_64"
12430 [(set (match_operand:DI 0 "register_operand" "=a")
12431 (call:DI
12432 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12433 (match_operand:DI 3 "" "")))
12434 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12435 UNSPEC_TLS_GD)]
12436 "TARGET_64BIT"
12437 {
12438 fputs (ASM_BYTE "0x66\n", asm_out_file);
12439 output_asm_insn
12440 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12441 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12442 fputs ("\trex64\n", asm_out_file);
12443 if (TARGET_SUN_TLS)
12444 return "call\t%p2@plt";
12445 return "call\t%P2";
12446 }
12447 [(set_attr "type" "multi")
12448 (set_attr "length" "16")])
12449
12450 (define_expand "tls_global_dynamic_64"
12451 [(parallel
12452 [(set (match_operand:DI 0 "register_operand" "")
12453 (call:DI
12454 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12455 (const_int 0)))
12456 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12457 UNSPEC_TLS_GD)])])
12458
12459 (define_insn "*tls_local_dynamic_base_32_gnu"
12460 [(set (match_operand:SI 0 "register_operand" "=a")
12461 (unspec:SI
12462 [(match_operand:SI 1 "register_operand" "b")
12463 (match_operand:SI 2 "constant_call_address_operand" "z")]
12464 UNSPEC_TLS_LD_BASE))
12465 (clobber (match_scratch:SI 3 "=d"))
12466 (clobber (match_scratch:SI 4 "=c"))
12467 (clobber (reg:CC FLAGS_REG))]
12468 "!TARGET_64BIT && TARGET_GNU_TLS"
12469 {
12470 output_asm_insn
12471 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12472 if (TARGET_SUN_TLS)
12473 #ifdef HAVE_AS_IX86_TLSLDMPLT
12474 return "call\t%&@tlsldmplt";
12475 #else
12476 return "call\t%p2@plt";
12477 #endif
12478 return "call\t%P2";
12479 }
12480 [(set_attr "type" "multi")
12481 (set_attr "length" "11")])
12482
12483 (define_expand "tls_local_dynamic_base_32"
12484 [(parallel
12485 [(set (match_operand:SI 0 "register_operand" "")
12486 (unspec:SI
12487 [(match_operand:SI 1 "register_operand" "")
12488 (match_operand:SI 2 "constant_call_address_operand" "")]
12489 UNSPEC_TLS_LD_BASE))
12490 (clobber (match_scratch:SI 3 ""))
12491 (clobber (match_scratch:SI 4 ""))
12492 (clobber (reg:CC FLAGS_REG))])])
12493
12494 (define_insn "*tls_local_dynamic_base_64"
12495 [(set (match_operand:DI 0 "register_operand" "=a")
12496 (call:DI
12497 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12498 (match_operand:DI 2 "" "")))
12499 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12500 "TARGET_64BIT"
12501 {
12502 output_asm_insn
12503 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12504 if (TARGET_SUN_TLS)
12505 return "call\t%p1@plt";
12506 return "call\t%P1";
12507 }
12508 [(set_attr "type" "multi")
12509 (set_attr "length" "12")])
12510
12511 (define_expand "tls_local_dynamic_base_64"
12512 [(parallel
12513 [(set (match_operand:DI 0 "register_operand" "")
12514 (call:DI
12515 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12516 (const_int 0)))
12517 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12518
12519 ;; Local dynamic of a single variable is a lose. Show combine how
12520 ;; to convert that back to global dynamic.
12521
12522 (define_insn_and_split "*tls_local_dynamic_32_once"
12523 [(set (match_operand:SI 0 "register_operand" "=a")
12524 (plus:SI
12525 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12526 (match_operand:SI 2 "constant_call_address_operand" "z")]
12527 UNSPEC_TLS_LD_BASE)
12528 (const:SI (unspec:SI
12529 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12530 UNSPEC_DTPOFF))))
12531 (clobber (match_scratch:SI 4 "=d"))
12532 (clobber (match_scratch:SI 5 "=c"))
12533 (clobber (reg:CC FLAGS_REG))]
12534 ""
12535 "#"
12536 ""
12537 [(parallel
12538 [(set (match_dup 0)
12539 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12540 UNSPEC_TLS_GD))
12541 (clobber (match_dup 4))
12542 (clobber (match_dup 5))
12543 (clobber (reg:CC FLAGS_REG))])])
12544
12545 ;; Segment register for the thread base ptr load
12546 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12547
12548 ;; Load and add the thread base pointer from %<tp_seg>:0.
12549 (define_insn "*load_tp_<mode>"
12550 [(set (match_operand:P 0 "register_operand" "=r")
12551 (unspec:P [(const_int 0)] UNSPEC_TP))]
12552 ""
12553 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12554 [(set_attr "type" "imov")
12555 (set_attr "modrm" "0")
12556 (set_attr "length" "7")
12557 (set_attr "memory" "load")
12558 (set_attr "imm_disp" "false")])
12559
12560 (define_insn "*add_tp_<mode>"
12561 [(set (match_operand:P 0 "register_operand" "=r")
12562 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12563 (match_operand:P 1 "register_operand" "0")))
12564 (clobber (reg:CC FLAGS_REG))]
12565 ""
12566 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12567 [(set_attr "type" "alu")
12568 (set_attr "modrm" "0")
12569 (set_attr "length" "7")
12570 (set_attr "memory" "load")
12571 (set_attr "imm_disp" "false")])
12572
12573 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12574 ;; %rax as destination of the initial executable code sequence.
12575 (define_insn "tls_initial_exec_64_sun"
12576 [(set (match_operand:DI 0 "register_operand" "=a")
12577 (unspec:DI
12578 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12579 UNSPEC_TLS_IE_SUN))
12580 (clobber (reg:CC FLAGS_REG))]
12581 "TARGET_64BIT && TARGET_SUN_TLS"
12582 {
12583 output_asm_insn
12584 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12585 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12586 }
12587 [(set_attr "type" "multi")])
12588
12589 ;; GNU2 TLS patterns can be split.
12590
12591 (define_expand "tls_dynamic_gnu2_32"
12592 [(set (match_dup 3)
12593 (plus:SI (match_operand:SI 2 "register_operand" "")
12594 (const:SI
12595 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12596 UNSPEC_TLSDESC))))
12597 (parallel
12598 [(set (match_operand:SI 0 "register_operand" "")
12599 (unspec:SI [(match_dup 1) (match_dup 3)
12600 (match_dup 2) (reg:SI SP_REG)]
12601 UNSPEC_TLSDESC))
12602 (clobber (reg:CC FLAGS_REG))])]
12603 "!TARGET_64BIT && TARGET_GNU2_TLS"
12604 {
12605 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12606 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12607 })
12608
12609 (define_insn "*tls_dynamic_lea_32"
12610 [(set (match_operand:SI 0 "register_operand" "=r")
12611 (plus:SI (match_operand:SI 1 "register_operand" "b")
12612 (const:SI
12613 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12614 UNSPEC_TLSDESC))))]
12615 "!TARGET_64BIT && TARGET_GNU2_TLS"
12616 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12617 [(set_attr "type" "lea")
12618 (set_attr "mode" "SI")
12619 (set_attr "length" "6")
12620 (set_attr "length_address" "4")])
12621
12622 (define_insn "*tls_dynamic_call_32"
12623 [(set (match_operand:SI 0 "register_operand" "=a")
12624 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12625 (match_operand:SI 2 "register_operand" "0")
12626 ;; we have to make sure %ebx still points to the GOT
12627 (match_operand:SI 3 "register_operand" "b")
12628 (reg:SI SP_REG)]
12629 UNSPEC_TLSDESC))
12630 (clobber (reg:CC FLAGS_REG))]
12631 "!TARGET_64BIT && TARGET_GNU2_TLS"
12632 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12633 [(set_attr "type" "call")
12634 (set_attr "length" "2")
12635 (set_attr "length_address" "0")])
12636
12637 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12638 [(set (match_operand:SI 0 "register_operand" "=&a")
12639 (plus:SI
12640 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12641 (match_operand:SI 4 "" "")
12642 (match_operand:SI 2 "register_operand" "b")
12643 (reg:SI SP_REG)]
12644 UNSPEC_TLSDESC)
12645 (const:SI (unspec:SI
12646 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12647 UNSPEC_DTPOFF))))
12648 (clobber (reg:CC FLAGS_REG))]
12649 "!TARGET_64BIT && TARGET_GNU2_TLS"
12650 "#"
12651 ""
12652 [(set (match_dup 0) (match_dup 5))]
12653 {
12654 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12655 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12656 })
12657
12658 (define_expand "tls_dynamic_gnu2_64"
12659 [(set (match_dup 2)
12660 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12661 UNSPEC_TLSDESC))
12662 (parallel
12663 [(set (match_operand:DI 0 "register_operand" "")
12664 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12665 UNSPEC_TLSDESC))
12666 (clobber (reg:CC FLAGS_REG))])]
12667 "TARGET_64BIT && TARGET_GNU2_TLS"
12668 {
12669 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12670 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12671 })
12672
12673 (define_insn "*tls_dynamic_lea_64"
12674 [(set (match_operand:DI 0 "register_operand" "=r")
12675 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12676 UNSPEC_TLSDESC))]
12677 "TARGET_64BIT && TARGET_GNU2_TLS"
12678 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12679 [(set_attr "type" "lea")
12680 (set_attr "mode" "DI")
12681 (set_attr "length" "7")
12682 (set_attr "length_address" "4")])
12683
12684 (define_insn "*tls_dynamic_call_64"
12685 [(set (match_operand:DI 0 "register_operand" "=a")
12686 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12687 (match_operand:DI 2 "register_operand" "0")
12688 (reg:DI SP_REG)]
12689 UNSPEC_TLSDESC))
12690 (clobber (reg:CC FLAGS_REG))]
12691 "TARGET_64BIT && TARGET_GNU2_TLS"
12692 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12693 [(set_attr "type" "call")
12694 (set_attr "length" "2")
12695 (set_attr "length_address" "0")])
12696
12697 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12698 [(set (match_operand:DI 0 "register_operand" "=&a")
12699 (plus:DI
12700 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12701 (match_operand:DI 3 "" "")
12702 (reg:DI SP_REG)]
12703 UNSPEC_TLSDESC)
12704 (const:DI (unspec:DI
12705 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12706 UNSPEC_DTPOFF))))
12707 (clobber (reg:CC FLAGS_REG))]
12708 "TARGET_64BIT && TARGET_GNU2_TLS"
12709 "#"
12710 ""
12711 [(set (match_dup 0) (match_dup 4))]
12712 {
12713 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12714 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12715 })
12716 \f
12717 ;; These patterns match the binary 387 instructions for addM3, subM3,
12718 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12719 ;; SFmode. The first is the normal insn, the second the same insn but
12720 ;; with one operand a conversion, and the third the same insn but with
12721 ;; the other operand a conversion. The conversion may be SFmode or
12722 ;; SImode if the target mode DFmode, but only SImode if the target mode
12723 ;; is SFmode.
12724
12725 ;; Gcc is slightly more smart about handling normal two address instructions
12726 ;; so use special patterns for add and mull.
12727
12728 (define_insn "*fop_<mode>_comm_mixed"
12729 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12730 (match_operator:MODEF 3 "binary_fp_operator"
12731 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12732 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12733 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12734 && COMMUTATIVE_ARITH_P (operands[3])
12735 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12736 "* return output_387_binary_op (insn, operands);"
12737 [(set (attr "type")
12738 (if_then_else (eq_attr "alternative" "1,2")
12739 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12740 (const_string "ssemul")
12741 (const_string "sseadd"))
12742 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12743 (const_string "fmul")
12744 (const_string "fop"))))
12745 (set_attr "isa" "base,noavx,avx")
12746 (set_attr "prefix" "orig,orig,vex")
12747 (set_attr "mode" "<MODE>")])
12748
12749 (define_insn "*fop_<mode>_comm_sse"
12750 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12751 (match_operator:MODEF 3 "binary_fp_operator"
12752 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12753 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12754 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12755 && COMMUTATIVE_ARITH_P (operands[3])
12756 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12757 "* return output_387_binary_op (insn, operands);"
12758 [(set (attr "type")
12759 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12760 (const_string "ssemul")
12761 (const_string "sseadd")))
12762 (set_attr "isa" "noavx,avx")
12763 (set_attr "prefix" "orig,vex")
12764 (set_attr "mode" "<MODE>")])
12765
12766 (define_insn "*fop_<mode>_comm_i387"
12767 [(set (match_operand:MODEF 0 "register_operand" "=f")
12768 (match_operator:MODEF 3 "binary_fp_operator"
12769 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12770 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12771 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12772 && COMMUTATIVE_ARITH_P (operands[3])
12773 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12774 "* return output_387_binary_op (insn, operands);"
12775 [(set (attr "type")
12776 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12777 (const_string "fmul")
12778 (const_string "fop")))
12779 (set_attr "mode" "<MODE>")])
12780
12781 (define_insn "*fop_<mode>_1_mixed"
12782 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12783 (match_operator:MODEF 3 "binary_fp_operator"
12784 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12785 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12786 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12787 && !COMMUTATIVE_ARITH_P (operands[3])
12788 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12789 "* return output_387_binary_op (insn, operands);"
12790 [(set (attr "type")
12791 (cond [(and (eq_attr "alternative" "2,3")
12792 (match_operand:MODEF 3 "mult_operator" ""))
12793 (const_string "ssemul")
12794 (and (eq_attr "alternative" "2,3")
12795 (match_operand:MODEF 3 "div_operator" ""))
12796 (const_string "ssediv")
12797 (eq_attr "alternative" "2,3")
12798 (const_string "sseadd")
12799 (match_operand:MODEF 3 "mult_operator" "")
12800 (const_string "fmul")
12801 (match_operand:MODEF 3 "div_operator" "")
12802 (const_string "fdiv")
12803 ]
12804 (const_string "fop")))
12805 (set_attr "isa" "base,base,noavx,avx")
12806 (set_attr "prefix" "orig,orig,orig,vex")
12807 (set_attr "mode" "<MODE>")])
12808
12809 (define_insn "*rcpsf2_sse"
12810 [(set (match_operand:SF 0 "register_operand" "=x")
12811 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12812 UNSPEC_RCP))]
12813 "TARGET_SSE_MATH"
12814 "%vrcpss\t{%1, %d0|%d0, %1}"
12815 [(set_attr "type" "sse")
12816 (set_attr "atom_sse_attr" "rcp")
12817 (set_attr "prefix" "maybe_vex")
12818 (set_attr "mode" "SF")])
12819
12820 (define_insn "*fop_<mode>_1_sse"
12821 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12822 (match_operator:MODEF 3 "binary_fp_operator"
12823 [(match_operand:MODEF 1 "register_operand" "0,x")
12824 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12825 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12826 && !COMMUTATIVE_ARITH_P (operands[3])"
12827 "* return output_387_binary_op (insn, operands);"
12828 [(set (attr "type")
12829 (cond [(match_operand:MODEF 3 "mult_operator" "")
12830 (const_string "ssemul")
12831 (match_operand:MODEF 3 "div_operator" "")
12832 (const_string "ssediv")
12833 ]
12834 (const_string "sseadd")))
12835 (set_attr "isa" "noavx,avx")
12836 (set_attr "prefix" "orig,vex")
12837 (set_attr "mode" "<MODE>")])
12838
12839 ;; This pattern is not fully shadowed by the pattern above.
12840 (define_insn "*fop_<mode>_1_i387"
12841 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12842 (match_operator:MODEF 3 "binary_fp_operator"
12843 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12844 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12845 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12846 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12847 && !COMMUTATIVE_ARITH_P (operands[3])
12848 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12849 "* return output_387_binary_op (insn, operands);"
12850 [(set (attr "type")
12851 (cond [(match_operand:MODEF 3 "mult_operator" "")
12852 (const_string "fmul")
12853 (match_operand:MODEF 3 "div_operator" "")
12854 (const_string "fdiv")
12855 ]
12856 (const_string "fop")))
12857 (set_attr "mode" "<MODE>")])
12858
12859 ;; ??? Add SSE splitters for these!
12860 (define_insn "*fop_<MODEF:mode>_2_i387"
12861 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12862 (match_operator:MODEF 3 "binary_fp_operator"
12863 [(float:MODEF
12864 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12865 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12866 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12867 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12868 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12869 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12870 [(set (attr "type")
12871 (cond [(match_operand:MODEF 3 "mult_operator" "")
12872 (const_string "fmul")
12873 (match_operand:MODEF 3 "div_operator" "")
12874 (const_string "fdiv")
12875 ]
12876 (const_string "fop")))
12877 (set_attr "fp_int_src" "true")
12878 (set_attr "mode" "<X87MODEI12:MODE>")])
12879
12880 (define_insn "*fop_<MODEF:mode>_3_i387"
12881 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12882 (match_operator:MODEF 3 "binary_fp_operator"
12883 [(match_operand:MODEF 1 "register_operand" "0,0")
12884 (float:MODEF
12885 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12886 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12887 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12888 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12889 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12890 [(set (attr "type")
12891 (cond [(match_operand:MODEF 3 "mult_operator" "")
12892 (const_string "fmul")
12893 (match_operand:MODEF 3 "div_operator" "")
12894 (const_string "fdiv")
12895 ]
12896 (const_string "fop")))
12897 (set_attr "fp_int_src" "true")
12898 (set_attr "mode" "<MODE>")])
12899
12900 (define_insn "*fop_df_4_i387"
12901 [(set (match_operand:DF 0 "register_operand" "=f,f")
12902 (match_operator:DF 3 "binary_fp_operator"
12903 [(float_extend:DF
12904 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12905 (match_operand:DF 2 "register_operand" "0,f")]))]
12906 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12907 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12908 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12909 "* return output_387_binary_op (insn, operands);"
12910 [(set (attr "type")
12911 (cond [(match_operand:DF 3 "mult_operator" "")
12912 (const_string "fmul")
12913 (match_operand:DF 3 "div_operator" "")
12914 (const_string "fdiv")
12915 ]
12916 (const_string "fop")))
12917 (set_attr "mode" "SF")])
12918
12919 (define_insn "*fop_df_5_i387"
12920 [(set (match_operand:DF 0 "register_operand" "=f,f")
12921 (match_operator:DF 3 "binary_fp_operator"
12922 [(match_operand:DF 1 "register_operand" "0,f")
12923 (float_extend:DF
12924 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12925 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12926 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12927 "* return output_387_binary_op (insn, operands);"
12928 [(set (attr "type")
12929 (cond [(match_operand:DF 3 "mult_operator" "")
12930 (const_string "fmul")
12931 (match_operand:DF 3 "div_operator" "")
12932 (const_string "fdiv")
12933 ]
12934 (const_string "fop")))
12935 (set_attr "mode" "SF")])
12936
12937 (define_insn "*fop_df_6_i387"
12938 [(set (match_operand:DF 0 "register_operand" "=f,f")
12939 (match_operator:DF 3 "binary_fp_operator"
12940 [(float_extend:DF
12941 (match_operand:SF 1 "register_operand" "0,f"))
12942 (float_extend:DF
12943 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12944 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12945 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12946 "* return output_387_binary_op (insn, operands);"
12947 [(set (attr "type")
12948 (cond [(match_operand:DF 3 "mult_operator" "")
12949 (const_string "fmul")
12950 (match_operand:DF 3 "div_operator" "")
12951 (const_string "fdiv")
12952 ]
12953 (const_string "fop")))
12954 (set_attr "mode" "SF")])
12955
12956 (define_insn "*fop_xf_comm_i387"
12957 [(set (match_operand:XF 0 "register_operand" "=f")
12958 (match_operator:XF 3 "binary_fp_operator"
12959 [(match_operand:XF 1 "register_operand" "%0")
12960 (match_operand:XF 2 "register_operand" "f")]))]
12961 "TARGET_80387
12962 && COMMUTATIVE_ARITH_P (operands[3])"
12963 "* return output_387_binary_op (insn, operands);"
12964 [(set (attr "type")
12965 (if_then_else (match_operand:XF 3 "mult_operator" "")
12966 (const_string "fmul")
12967 (const_string "fop")))
12968 (set_attr "mode" "XF")])
12969
12970 (define_insn "*fop_xf_1_i387"
12971 [(set (match_operand:XF 0 "register_operand" "=f,f")
12972 (match_operator:XF 3 "binary_fp_operator"
12973 [(match_operand:XF 1 "register_operand" "0,f")
12974 (match_operand:XF 2 "register_operand" "f,0")]))]
12975 "TARGET_80387
12976 && !COMMUTATIVE_ARITH_P (operands[3])"
12977 "* return output_387_binary_op (insn, operands);"
12978 [(set (attr "type")
12979 (cond [(match_operand:XF 3 "mult_operator" "")
12980 (const_string "fmul")
12981 (match_operand:XF 3 "div_operator" "")
12982 (const_string "fdiv")
12983 ]
12984 (const_string "fop")))
12985 (set_attr "mode" "XF")])
12986
12987 (define_insn "*fop_xf_2_i387"
12988 [(set (match_operand:XF 0 "register_operand" "=f,f")
12989 (match_operator:XF 3 "binary_fp_operator"
12990 [(float:XF
12991 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12992 (match_operand:XF 2 "register_operand" "0,0")]))]
12993 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12994 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12995 [(set (attr "type")
12996 (cond [(match_operand:XF 3 "mult_operator" "")
12997 (const_string "fmul")
12998 (match_operand:XF 3 "div_operator" "")
12999 (const_string "fdiv")
13000 ]
13001 (const_string "fop")))
13002 (set_attr "fp_int_src" "true")
13003 (set_attr "mode" "<MODE>")])
13004
13005 (define_insn "*fop_xf_3_i387"
13006 [(set (match_operand:XF 0 "register_operand" "=f,f")
13007 (match_operator:XF 3 "binary_fp_operator"
13008 [(match_operand:XF 1 "register_operand" "0,0")
13009 (float:XF
13010 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13011 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13012 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13013 [(set (attr "type")
13014 (cond [(match_operand:XF 3 "mult_operator" "")
13015 (const_string "fmul")
13016 (match_operand:XF 3 "div_operator" "")
13017 (const_string "fdiv")
13018 ]
13019 (const_string "fop")))
13020 (set_attr "fp_int_src" "true")
13021 (set_attr "mode" "<MODE>")])
13022
13023 (define_insn "*fop_xf_4_i387"
13024 [(set (match_operand:XF 0 "register_operand" "=f,f")
13025 (match_operator:XF 3 "binary_fp_operator"
13026 [(float_extend:XF
13027 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13028 (match_operand:XF 2 "register_operand" "0,f")]))]
13029 "TARGET_80387"
13030 "* return output_387_binary_op (insn, operands);"
13031 [(set (attr "type")
13032 (cond [(match_operand:XF 3 "mult_operator" "")
13033 (const_string "fmul")
13034 (match_operand:XF 3 "div_operator" "")
13035 (const_string "fdiv")
13036 ]
13037 (const_string "fop")))
13038 (set_attr "mode" "<MODE>")])
13039
13040 (define_insn "*fop_xf_5_i387"
13041 [(set (match_operand:XF 0 "register_operand" "=f,f")
13042 (match_operator:XF 3 "binary_fp_operator"
13043 [(match_operand:XF 1 "register_operand" "0,f")
13044 (float_extend:XF
13045 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13046 "TARGET_80387"
13047 "* return output_387_binary_op (insn, operands);"
13048 [(set (attr "type")
13049 (cond [(match_operand:XF 3 "mult_operator" "")
13050 (const_string "fmul")
13051 (match_operand:XF 3 "div_operator" "")
13052 (const_string "fdiv")
13053 ]
13054 (const_string "fop")))
13055 (set_attr "mode" "<MODE>")])
13056
13057 (define_insn "*fop_xf_6_i387"
13058 [(set (match_operand:XF 0 "register_operand" "=f,f")
13059 (match_operator:XF 3 "binary_fp_operator"
13060 [(float_extend:XF
13061 (match_operand:MODEF 1 "register_operand" "0,f"))
13062 (float_extend:XF
13063 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13064 "TARGET_80387"
13065 "* return output_387_binary_op (insn, operands);"
13066 [(set (attr "type")
13067 (cond [(match_operand:XF 3 "mult_operator" "")
13068 (const_string "fmul")
13069 (match_operand:XF 3 "div_operator" "")
13070 (const_string "fdiv")
13071 ]
13072 (const_string "fop")))
13073 (set_attr "mode" "<MODE>")])
13074
13075 (define_split
13076 [(set (match_operand 0 "register_operand" "")
13077 (match_operator 3 "binary_fp_operator"
13078 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13079 (match_operand 2 "register_operand" "")]))]
13080 "reload_completed
13081 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13082 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13083 [(const_int 0)]
13084 {
13085 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13086 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13087 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13088 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13089 GET_MODE (operands[3]),
13090 operands[4],
13091 operands[2])));
13092 ix86_free_from_memory (GET_MODE (operands[1]));
13093 DONE;
13094 })
13095
13096 (define_split
13097 [(set (match_operand 0 "register_operand" "")
13098 (match_operator 3 "binary_fp_operator"
13099 [(match_operand 1 "register_operand" "")
13100 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13101 "reload_completed
13102 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13103 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13104 [(const_int 0)]
13105 {
13106 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13107 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13108 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13109 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13110 GET_MODE (operands[3]),
13111 operands[1],
13112 operands[4])));
13113 ix86_free_from_memory (GET_MODE (operands[2]));
13114 DONE;
13115 })
13116 \f
13117 ;; FPU special functions.
13118
13119 ;; This pattern implements a no-op XFmode truncation for
13120 ;; all fancy i386 XFmode math functions.
13121
13122 (define_insn "truncxf<mode>2_i387_noop_unspec"
13123 [(set (match_operand:MODEF 0 "register_operand" "=f")
13124 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13125 UNSPEC_TRUNC_NOOP))]
13126 "TARGET_USE_FANCY_MATH_387"
13127 "* return output_387_reg_move (insn, operands);"
13128 [(set_attr "type" "fmov")
13129 (set_attr "mode" "<MODE>")])
13130
13131 (define_insn "sqrtxf2"
13132 [(set (match_operand:XF 0 "register_operand" "=f")
13133 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13134 "TARGET_USE_FANCY_MATH_387"
13135 "fsqrt"
13136 [(set_attr "type" "fpspc")
13137 (set_attr "mode" "XF")
13138 (set_attr "athlon_decode" "direct")
13139 (set_attr "amdfam10_decode" "direct")
13140 (set_attr "bdver1_decode" "direct")])
13141
13142 (define_insn "sqrt_extend<mode>xf2_i387"
13143 [(set (match_operand:XF 0 "register_operand" "=f")
13144 (sqrt:XF
13145 (float_extend:XF
13146 (match_operand:MODEF 1 "register_operand" "0"))))]
13147 "TARGET_USE_FANCY_MATH_387"
13148 "fsqrt"
13149 [(set_attr "type" "fpspc")
13150 (set_attr "mode" "XF")
13151 (set_attr "athlon_decode" "direct")
13152 (set_attr "amdfam10_decode" "direct")
13153 (set_attr "bdver1_decode" "direct")])
13154
13155 (define_insn "*rsqrtsf2_sse"
13156 [(set (match_operand:SF 0 "register_operand" "=x")
13157 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13158 UNSPEC_RSQRT))]
13159 "TARGET_SSE_MATH"
13160 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13161 [(set_attr "type" "sse")
13162 (set_attr "atom_sse_attr" "rcp")
13163 (set_attr "prefix" "maybe_vex")
13164 (set_attr "mode" "SF")])
13165
13166 (define_expand "rsqrtsf2"
13167 [(set (match_operand:SF 0 "register_operand" "")
13168 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13169 UNSPEC_RSQRT))]
13170 "TARGET_SSE_MATH"
13171 {
13172 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13173 DONE;
13174 })
13175
13176 (define_insn "*sqrt<mode>2_sse"
13177 [(set (match_operand:MODEF 0 "register_operand" "=x")
13178 (sqrt:MODEF
13179 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13180 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13181 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13182 [(set_attr "type" "sse")
13183 (set_attr "atom_sse_attr" "sqrt")
13184 (set_attr "prefix" "maybe_vex")
13185 (set_attr "mode" "<MODE>")
13186 (set_attr "athlon_decode" "*")
13187 (set_attr "amdfam10_decode" "*")
13188 (set_attr "bdver1_decode" "*")])
13189
13190 (define_expand "sqrt<mode>2"
13191 [(set (match_operand:MODEF 0 "register_operand" "")
13192 (sqrt:MODEF
13193 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13194 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13195 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13196 {
13197 if (<MODE>mode == SFmode
13198 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13199 && flag_finite_math_only && !flag_trapping_math
13200 && flag_unsafe_math_optimizations)
13201 {
13202 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13203 DONE;
13204 }
13205
13206 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13207 {
13208 rtx op0 = gen_reg_rtx (XFmode);
13209 rtx op1 = force_reg (<MODE>mode, operands[1]);
13210
13211 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13212 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13213 DONE;
13214 }
13215 })
13216
13217 (define_insn "fpremxf4_i387"
13218 [(set (match_operand:XF 0 "register_operand" "=f")
13219 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13220 (match_operand:XF 3 "register_operand" "1")]
13221 UNSPEC_FPREM_F))
13222 (set (match_operand:XF 1 "register_operand" "=u")
13223 (unspec:XF [(match_dup 2) (match_dup 3)]
13224 UNSPEC_FPREM_U))
13225 (set (reg:CCFP FPSR_REG)
13226 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13227 UNSPEC_C2_FLAG))]
13228 "TARGET_USE_FANCY_MATH_387"
13229 "fprem"
13230 [(set_attr "type" "fpspc")
13231 (set_attr "mode" "XF")])
13232
13233 (define_expand "fmodxf3"
13234 [(use (match_operand:XF 0 "register_operand" ""))
13235 (use (match_operand:XF 1 "general_operand" ""))
13236 (use (match_operand:XF 2 "general_operand" ""))]
13237 "TARGET_USE_FANCY_MATH_387"
13238 {
13239 rtx label = gen_label_rtx ();
13240
13241 rtx op1 = gen_reg_rtx (XFmode);
13242 rtx op2 = gen_reg_rtx (XFmode);
13243
13244 emit_move_insn (op2, operands[2]);
13245 emit_move_insn (op1, operands[1]);
13246
13247 emit_label (label);
13248 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13249 ix86_emit_fp_unordered_jump (label);
13250 LABEL_NUSES (label) = 1;
13251
13252 emit_move_insn (operands[0], op1);
13253 DONE;
13254 })
13255
13256 (define_expand "fmod<mode>3"
13257 [(use (match_operand:MODEF 0 "register_operand" ""))
13258 (use (match_operand:MODEF 1 "general_operand" ""))
13259 (use (match_operand:MODEF 2 "general_operand" ""))]
13260 "TARGET_USE_FANCY_MATH_387"
13261 {
13262 rtx (*gen_truncxf) (rtx, rtx);
13263
13264 rtx label = gen_label_rtx ();
13265
13266 rtx op1 = gen_reg_rtx (XFmode);
13267 rtx op2 = gen_reg_rtx (XFmode);
13268
13269 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13270 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13271
13272 emit_label (label);
13273 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13274 ix86_emit_fp_unordered_jump (label);
13275 LABEL_NUSES (label) = 1;
13276
13277 /* Truncate the result properly for strict SSE math. */
13278 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13279 && !TARGET_MIX_SSE_I387)
13280 gen_truncxf = gen_truncxf<mode>2;
13281 else
13282 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13283
13284 emit_insn (gen_truncxf (operands[0], op1));
13285 DONE;
13286 })
13287
13288 (define_insn "fprem1xf4_i387"
13289 [(set (match_operand:XF 0 "register_operand" "=f")
13290 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13291 (match_operand:XF 3 "register_operand" "1")]
13292 UNSPEC_FPREM1_F))
13293 (set (match_operand:XF 1 "register_operand" "=u")
13294 (unspec:XF [(match_dup 2) (match_dup 3)]
13295 UNSPEC_FPREM1_U))
13296 (set (reg:CCFP FPSR_REG)
13297 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13298 UNSPEC_C2_FLAG))]
13299 "TARGET_USE_FANCY_MATH_387"
13300 "fprem1"
13301 [(set_attr "type" "fpspc")
13302 (set_attr "mode" "XF")])
13303
13304 (define_expand "remainderxf3"
13305 [(use (match_operand:XF 0 "register_operand" ""))
13306 (use (match_operand:XF 1 "general_operand" ""))
13307 (use (match_operand:XF 2 "general_operand" ""))]
13308 "TARGET_USE_FANCY_MATH_387"
13309 {
13310 rtx label = gen_label_rtx ();
13311
13312 rtx op1 = gen_reg_rtx (XFmode);
13313 rtx op2 = gen_reg_rtx (XFmode);
13314
13315 emit_move_insn (op2, operands[2]);
13316 emit_move_insn (op1, operands[1]);
13317
13318 emit_label (label);
13319 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13320 ix86_emit_fp_unordered_jump (label);
13321 LABEL_NUSES (label) = 1;
13322
13323 emit_move_insn (operands[0], op1);
13324 DONE;
13325 })
13326
13327 (define_expand "remainder<mode>3"
13328 [(use (match_operand:MODEF 0 "register_operand" ""))
13329 (use (match_operand:MODEF 1 "general_operand" ""))
13330 (use (match_operand:MODEF 2 "general_operand" ""))]
13331 "TARGET_USE_FANCY_MATH_387"
13332 {
13333 rtx (*gen_truncxf) (rtx, rtx);
13334
13335 rtx label = gen_label_rtx ();
13336
13337 rtx op1 = gen_reg_rtx (XFmode);
13338 rtx op2 = gen_reg_rtx (XFmode);
13339
13340 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13341 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13342
13343 emit_label (label);
13344
13345 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13346 ix86_emit_fp_unordered_jump (label);
13347 LABEL_NUSES (label) = 1;
13348
13349 /* Truncate the result properly for strict SSE math. */
13350 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13351 && !TARGET_MIX_SSE_I387)
13352 gen_truncxf = gen_truncxf<mode>2;
13353 else
13354 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13355
13356 emit_insn (gen_truncxf (operands[0], op1));
13357 DONE;
13358 })
13359
13360 (define_insn "*sinxf2_i387"
13361 [(set (match_operand:XF 0 "register_operand" "=f")
13362 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13363 "TARGET_USE_FANCY_MATH_387
13364 && flag_unsafe_math_optimizations"
13365 "fsin"
13366 [(set_attr "type" "fpspc")
13367 (set_attr "mode" "XF")])
13368
13369 (define_insn "*sin_extend<mode>xf2_i387"
13370 [(set (match_operand:XF 0 "register_operand" "=f")
13371 (unspec:XF [(float_extend:XF
13372 (match_operand:MODEF 1 "register_operand" "0"))]
13373 UNSPEC_SIN))]
13374 "TARGET_USE_FANCY_MATH_387
13375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13376 || TARGET_MIX_SSE_I387)
13377 && flag_unsafe_math_optimizations"
13378 "fsin"
13379 [(set_attr "type" "fpspc")
13380 (set_attr "mode" "XF")])
13381
13382 (define_insn "*cosxf2_i387"
13383 [(set (match_operand:XF 0 "register_operand" "=f")
13384 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13385 "TARGET_USE_FANCY_MATH_387
13386 && flag_unsafe_math_optimizations"
13387 "fcos"
13388 [(set_attr "type" "fpspc")
13389 (set_attr "mode" "XF")])
13390
13391 (define_insn "*cos_extend<mode>xf2_i387"
13392 [(set (match_operand:XF 0 "register_operand" "=f")
13393 (unspec:XF [(float_extend:XF
13394 (match_operand:MODEF 1 "register_operand" "0"))]
13395 UNSPEC_COS))]
13396 "TARGET_USE_FANCY_MATH_387
13397 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13398 || TARGET_MIX_SSE_I387)
13399 && flag_unsafe_math_optimizations"
13400 "fcos"
13401 [(set_attr "type" "fpspc")
13402 (set_attr "mode" "XF")])
13403
13404 ;; When sincos pattern is defined, sin and cos builtin functions will be
13405 ;; expanded to sincos pattern with one of its outputs left unused.
13406 ;; CSE pass will figure out if two sincos patterns can be combined,
13407 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13408 ;; depending on the unused output.
13409
13410 (define_insn "sincosxf3"
13411 [(set (match_operand:XF 0 "register_operand" "=f")
13412 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13413 UNSPEC_SINCOS_COS))
13414 (set (match_operand:XF 1 "register_operand" "=u")
13415 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13416 "TARGET_USE_FANCY_MATH_387
13417 && flag_unsafe_math_optimizations"
13418 "fsincos"
13419 [(set_attr "type" "fpspc")
13420 (set_attr "mode" "XF")])
13421
13422 (define_split
13423 [(set (match_operand:XF 0 "register_operand" "")
13424 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13425 UNSPEC_SINCOS_COS))
13426 (set (match_operand:XF 1 "register_operand" "")
13427 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13428 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13429 && can_create_pseudo_p ()"
13430 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13431
13432 (define_split
13433 [(set (match_operand:XF 0 "register_operand" "")
13434 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13435 UNSPEC_SINCOS_COS))
13436 (set (match_operand:XF 1 "register_operand" "")
13437 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13438 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13439 && can_create_pseudo_p ()"
13440 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13441
13442 (define_insn "sincos_extend<mode>xf3_i387"
13443 [(set (match_operand:XF 0 "register_operand" "=f")
13444 (unspec:XF [(float_extend:XF
13445 (match_operand:MODEF 2 "register_operand" "0"))]
13446 UNSPEC_SINCOS_COS))
13447 (set (match_operand:XF 1 "register_operand" "=u")
13448 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13449 "TARGET_USE_FANCY_MATH_387
13450 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13451 || TARGET_MIX_SSE_I387)
13452 && flag_unsafe_math_optimizations"
13453 "fsincos"
13454 [(set_attr "type" "fpspc")
13455 (set_attr "mode" "XF")])
13456
13457 (define_split
13458 [(set (match_operand:XF 0 "register_operand" "")
13459 (unspec:XF [(float_extend:XF
13460 (match_operand:MODEF 2 "register_operand" ""))]
13461 UNSPEC_SINCOS_COS))
13462 (set (match_operand:XF 1 "register_operand" "")
13463 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13464 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13465 && can_create_pseudo_p ()"
13466 [(set (match_dup 1)
13467 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13468
13469 (define_split
13470 [(set (match_operand:XF 0 "register_operand" "")
13471 (unspec:XF [(float_extend:XF
13472 (match_operand:MODEF 2 "register_operand" ""))]
13473 UNSPEC_SINCOS_COS))
13474 (set (match_operand:XF 1 "register_operand" "")
13475 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13476 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13477 && can_create_pseudo_p ()"
13478 [(set (match_dup 0)
13479 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13480
13481 (define_expand "sincos<mode>3"
13482 [(use (match_operand:MODEF 0 "register_operand" ""))
13483 (use (match_operand:MODEF 1 "register_operand" ""))
13484 (use (match_operand:MODEF 2 "register_operand" ""))]
13485 "TARGET_USE_FANCY_MATH_387
13486 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13487 || TARGET_MIX_SSE_I387)
13488 && flag_unsafe_math_optimizations"
13489 {
13490 rtx op0 = gen_reg_rtx (XFmode);
13491 rtx op1 = gen_reg_rtx (XFmode);
13492
13493 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13494 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13495 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13496 DONE;
13497 })
13498
13499 (define_insn "fptanxf4_i387"
13500 [(set (match_operand:XF 0 "register_operand" "=f")
13501 (match_operand:XF 3 "const_double_operand" "F"))
13502 (set (match_operand:XF 1 "register_operand" "=u")
13503 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13504 UNSPEC_TAN))]
13505 "TARGET_USE_FANCY_MATH_387
13506 && flag_unsafe_math_optimizations
13507 && standard_80387_constant_p (operands[3]) == 2"
13508 "fptan"
13509 [(set_attr "type" "fpspc")
13510 (set_attr "mode" "XF")])
13511
13512 (define_insn "fptan_extend<mode>xf4_i387"
13513 [(set (match_operand:MODEF 0 "register_operand" "=f")
13514 (match_operand:MODEF 3 "const_double_operand" "F"))
13515 (set (match_operand:XF 1 "register_operand" "=u")
13516 (unspec:XF [(float_extend:XF
13517 (match_operand:MODEF 2 "register_operand" "0"))]
13518 UNSPEC_TAN))]
13519 "TARGET_USE_FANCY_MATH_387
13520 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13521 || TARGET_MIX_SSE_I387)
13522 && flag_unsafe_math_optimizations
13523 && standard_80387_constant_p (operands[3]) == 2"
13524 "fptan"
13525 [(set_attr "type" "fpspc")
13526 (set_attr "mode" "XF")])
13527
13528 (define_expand "tanxf2"
13529 [(use (match_operand:XF 0 "register_operand" ""))
13530 (use (match_operand:XF 1 "register_operand" ""))]
13531 "TARGET_USE_FANCY_MATH_387
13532 && flag_unsafe_math_optimizations"
13533 {
13534 rtx one = gen_reg_rtx (XFmode);
13535 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13536
13537 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13538 DONE;
13539 })
13540
13541 (define_expand "tan<mode>2"
13542 [(use (match_operand:MODEF 0 "register_operand" ""))
13543 (use (match_operand:MODEF 1 "register_operand" ""))]
13544 "TARGET_USE_FANCY_MATH_387
13545 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13546 || TARGET_MIX_SSE_I387)
13547 && flag_unsafe_math_optimizations"
13548 {
13549 rtx op0 = gen_reg_rtx (XFmode);
13550
13551 rtx one = gen_reg_rtx (<MODE>mode);
13552 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13553
13554 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13555 operands[1], op2));
13556 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13557 DONE;
13558 })
13559
13560 (define_insn "*fpatanxf3_i387"
13561 [(set (match_operand:XF 0 "register_operand" "=f")
13562 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13563 (match_operand:XF 2 "register_operand" "u")]
13564 UNSPEC_FPATAN))
13565 (clobber (match_scratch:XF 3 "=2"))]
13566 "TARGET_USE_FANCY_MATH_387
13567 && flag_unsafe_math_optimizations"
13568 "fpatan"
13569 [(set_attr "type" "fpspc")
13570 (set_attr "mode" "XF")])
13571
13572 (define_insn "fpatan_extend<mode>xf3_i387"
13573 [(set (match_operand:XF 0 "register_operand" "=f")
13574 (unspec:XF [(float_extend:XF
13575 (match_operand:MODEF 1 "register_operand" "0"))
13576 (float_extend:XF
13577 (match_operand:MODEF 2 "register_operand" "u"))]
13578 UNSPEC_FPATAN))
13579 (clobber (match_scratch:XF 3 "=2"))]
13580 "TARGET_USE_FANCY_MATH_387
13581 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13582 || TARGET_MIX_SSE_I387)
13583 && flag_unsafe_math_optimizations"
13584 "fpatan"
13585 [(set_attr "type" "fpspc")
13586 (set_attr "mode" "XF")])
13587
13588 (define_expand "atan2xf3"
13589 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13590 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13591 (match_operand:XF 1 "register_operand" "")]
13592 UNSPEC_FPATAN))
13593 (clobber (match_scratch:XF 3 ""))])]
13594 "TARGET_USE_FANCY_MATH_387
13595 && flag_unsafe_math_optimizations")
13596
13597 (define_expand "atan2<mode>3"
13598 [(use (match_operand:MODEF 0 "register_operand" ""))
13599 (use (match_operand:MODEF 1 "register_operand" ""))
13600 (use (match_operand:MODEF 2 "register_operand" ""))]
13601 "TARGET_USE_FANCY_MATH_387
13602 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13603 || TARGET_MIX_SSE_I387)
13604 && flag_unsafe_math_optimizations"
13605 {
13606 rtx op0 = gen_reg_rtx (XFmode);
13607
13608 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13609 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13610 DONE;
13611 })
13612
13613 (define_expand "atanxf2"
13614 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13615 (unspec:XF [(match_dup 2)
13616 (match_operand:XF 1 "register_operand" "")]
13617 UNSPEC_FPATAN))
13618 (clobber (match_scratch:XF 3 ""))])]
13619 "TARGET_USE_FANCY_MATH_387
13620 && flag_unsafe_math_optimizations"
13621 {
13622 operands[2] = gen_reg_rtx (XFmode);
13623 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13624 })
13625
13626 (define_expand "atan<mode>2"
13627 [(use (match_operand:MODEF 0 "register_operand" ""))
13628 (use (match_operand:MODEF 1 "register_operand" ""))]
13629 "TARGET_USE_FANCY_MATH_387
13630 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13631 || TARGET_MIX_SSE_I387)
13632 && flag_unsafe_math_optimizations"
13633 {
13634 rtx op0 = gen_reg_rtx (XFmode);
13635
13636 rtx op2 = gen_reg_rtx (<MODE>mode);
13637 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13638
13639 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13640 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13641 DONE;
13642 })
13643
13644 (define_expand "asinxf2"
13645 [(set (match_dup 2)
13646 (mult:XF (match_operand:XF 1 "register_operand" "")
13647 (match_dup 1)))
13648 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13649 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13650 (parallel [(set (match_operand:XF 0 "register_operand" "")
13651 (unspec:XF [(match_dup 5) (match_dup 1)]
13652 UNSPEC_FPATAN))
13653 (clobber (match_scratch:XF 6 ""))])]
13654 "TARGET_USE_FANCY_MATH_387
13655 && flag_unsafe_math_optimizations"
13656 {
13657 int i;
13658
13659 if (optimize_insn_for_size_p ())
13660 FAIL;
13661
13662 for (i = 2; i < 6; i++)
13663 operands[i] = gen_reg_rtx (XFmode);
13664
13665 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13666 })
13667
13668 (define_expand "asin<mode>2"
13669 [(use (match_operand:MODEF 0 "register_operand" ""))
13670 (use (match_operand:MODEF 1 "general_operand" ""))]
13671 "TARGET_USE_FANCY_MATH_387
13672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13673 || TARGET_MIX_SSE_I387)
13674 && flag_unsafe_math_optimizations"
13675 {
13676 rtx op0 = gen_reg_rtx (XFmode);
13677 rtx op1 = gen_reg_rtx (XFmode);
13678
13679 if (optimize_insn_for_size_p ())
13680 FAIL;
13681
13682 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13683 emit_insn (gen_asinxf2 (op0, op1));
13684 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13685 DONE;
13686 })
13687
13688 (define_expand "acosxf2"
13689 [(set (match_dup 2)
13690 (mult:XF (match_operand:XF 1 "register_operand" "")
13691 (match_dup 1)))
13692 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13693 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13694 (parallel [(set (match_operand:XF 0 "register_operand" "")
13695 (unspec:XF [(match_dup 1) (match_dup 5)]
13696 UNSPEC_FPATAN))
13697 (clobber (match_scratch:XF 6 ""))])]
13698 "TARGET_USE_FANCY_MATH_387
13699 && flag_unsafe_math_optimizations"
13700 {
13701 int i;
13702
13703 if (optimize_insn_for_size_p ())
13704 FAIL;
13705
13706 for (i = 2; i < 6; i++)
13707 operands[i] = gen_reg_rtx (XFmode);
13708
13709 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13710 })
13711
13712 (define_expand "acos<mode>2"
13713 [(use (match_operand:MODEF 0 "register_operand" ""))
13714 (use (match_operand:MODEF 1 "general_operand" ""))]
13715 "TARGET_USE_FANCY_MATH_387
13716 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13717 || TARGET_MIX_SSE_I387)
13718 && flag_unsafe_math_optimizations"
13719 {
13720 rtx op0 = gen_reg_rtx (XFmode);
13721 rtx op1 = gen_reg_rtx (XFmode);
13722
13723 if (optimize_insn_for_size_p ())
13724 FAIL;
13725
13726 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13727 emit_insn (gen_acosxf2 (op0, op1));
13728 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13729 DONE;
13730 })
13731
13732 (define_insn "fyl2xxf3_i387"
13733 [(set (match_operand:XF 0 "register_operand" "=f")
13734 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13735 (match_operand:XF 2 "register_operand" "u")]
13736 UNSPEC_FYL2X))
13737 (clobber (match_scratch:XF 3 "=2"))]
13738 "TARGET_USE_FANCY_MATH_387
13739 && flag_unsafe_math_optimizations"
13740 "fyl2x"
13741 [(set_attr "type" "fpspc")
13742 (set_attr "mode" "XF")])
13743
13744 (define_insn "fyl2x_extend<mode>xf3_i387"
13745 [(set (match_operand:XF 0 "register_operand" "=f")
13746 (unspec:XF [(float_extend:XF
13747 (match_operand:MODEF 1 "register_operand" "0"))
13748 (match_operand:XF 2 "register_operand" "u")]
13749 UNSPEC_FYL2X))
13750 (clobber (match_scratch:XF 3 "=2"))]
13751 "TARGET_USE_FANCY_MATH_387
13752 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13753 || TARGET_MIX_SSE_I387)
13754 && flag_unsafe_math_optimizations"
13755 "fyl2x"
13756 [(set_attr "type" "fpspc")
13757 (set_attr "mode" "XF")])
13758
13759 (define_expand "logxf2"
13760 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13761 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13762 (match_dup 2)] UNSPEC_FYL2X))
13763 (clobber (match_scratch:XF 3 ""))])]
13764 "TARGET_USE_FANCY_MATH_387
13765 && flag_unsafe_math_optimizations"
13766 {
13767 operands[2] = gen_reg_rtx (XFmode);
13768 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13769 })
13770
13771 (define_expand "log<mode>2"
13772 [(use (match_operand:MODEF 0 "register_operand" ""))
13773 (use (match_operand:MODEF 1 "register_operand" ""))]
13774 "TARGET_USE_FANCY_MATH_387
13775 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13776 || TARGET_MIX_SSE_I387)
13777 && flag_unsafe_math_optimizations"
13778 {
13779 rtx op0 = gen_reg_rtx (XFmode);
13780
13781 rtx op2 = gen_reg_rtx (XFmode);
13782 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13783
13784 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13785 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13786 DONE;
13787 })
13788
13789 (define_expand "log10xf2"
13790 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13791 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13792 (match_dup 2)] UNSPEC_FYL2X))
13793 (clobber (match_scratch:XF 3 ""))])]
13794 "TARGET_USE_FANCY_MATH_387
13795 && flag_unsafe_math_optimizations"
13796 {
13797 operands[2] = gen_reg_rtx (XFmode);
13798 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13799 })
13800
13801 (define_expand "log10<mode>2"
13802 [(use (match_operand:MODEF 0 "register_operand" ""))
13803 (use (match_operand:MODEF 1 "register_operand" ""))]
13804 "TARGET_USE_FANCY_MATH_387
13805 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13806 || TARGET_MIX_SSE_I387)
13807 && flag_unsafe_math_optimizations"
13808 {
13809 rtx op0 = gen_reg_rtx (XFmode);
13810
13811 rtx op2 = gen_reg_rtx (XFmode);
13812 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13813
13814 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13815 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13816 DONE;
13817 })
13818
13819 (define_expand "log2xf2"
13820 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13821 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13822 (match_dup 2)] UNSPEC_FYL2X))
13823 (clobber (match_scratch:XF 3 ""))])]
13824 "TARGET_USE_FANCY_MATH_387
13825 && flag_unsafe_math_optimizations"
13826 {
13827 operands[2] = gen_reg_rtx (XFmode);
13828 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13829 })
13830
13831 (define_expand "log2<mode>2"
13832 [(use (match_operand:MODEF 0 "register_operand" ""))
13833 (use (match_operand:MODEF 1 "register_operand" ""))]
13834 "TARGET_USE_FANCY_MATH_387
13835 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13836 || TARGET_MIX_SSE_I387)
13837 && flag_unsafe_math_optimizations"
13838 {
13839 rtx op0 = gen_reg_rtx (XFmode);
13840
13841 rtx op2 = gen_reg_rtx (XFmode);
13842 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13843
13844 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13845 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13846 DONE;
13847 })
13848
13849 (define_insn "fyl2xp1xf3_i387"
13850 [(set (match_operand:XF 0 "register_operand" "=f")
13851 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13852 (match_operand:XF 2 "register_operand" "u")]
13853 UNSPEC_FYL2XP1))
13854 (clobber (match_scratch:XF 3 "=2"))]
13855 "TARGET_USE_FANCY_MATH_387
13856 && flag_unsafe_math_optimizations"
13857 "fyl2xp1"
13858 [(set_attr "type" "fpspc")
13859 (set_attr "mode" "XF")])
13860
13861 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13862 [(set (match_operand:XF 0 "register_operand" "=f")
13863 (unspec:XF [(float_extend:XF
13864 (match_operand:MODEF 1 "register_operand" "0"))
13865 (match_operand:XF 2 "register_operand" "u")]
13866 UNSPEC_FYL2XP1))
13867 (clobber (match_scratch:XF 3 "=2"))]
13868 "TARGET_USE_FANCY_MATH_387
13869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13870 || TARGET_MIX_SSE_I387)
13871 && flag_unsafe_math_optimizations"
13872 "fyl2xp1"
13873 [(set_attr "type" "fpspc")
13874 (set_attr "mode" "XF")])
13875
13876 (define_expand "log1pxf2"
13877 [(use (match_operand:XF 0 "register_operand" ""))
13878 (use (match_operand:XF 1 "register_operand" ""))]
13879 "TARGET_USE_FANCY_MATH_387
13880 && flag_unsafe_math_optimizations"
13881 {
13882 if (optimize_insn_for_size_p ())
13883 FAIL;
13884
13885 ix86_emit_i387_log1p (operands[0], operands[1]);
13886 DONE;
13887 })
13888
13889 (define_expand "log1p<mode>2"
13890 [(use (match_operand:MODEF 0 "register_operand" ""))
13891 (use (match_operand:MODEF 1 "register_operand" ""))]
13892 "TARGET_USE_FANCY_MATH_387
13893 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13894 || TARGET_MIX_SSE_I387)
13895 && flag_unsafe_math_optimizations"
13896 {
13897 rtx op0;
13898
13899 if (optimize_insn_for_size_p ())
13900 FAIL;
13901
13902 op0 = gen_reg_rtx (XFmode);
13903
13904 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13905
13906 ix86_emit_i387_log1p (op0, operands[1]);
13907 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13908 DONE;
13909 })
13910
13911 (define_insn "fxtractxf3_i387"
13912 [(set (match_operand:XF 0 "register_operand" "=f")
13913 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13914 UNSPEC_XTRACT_FRACT))
13915 (set (match_operand:XF 1 "register_operand" "=u")
13916 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13917 "TARGET_USE_FANCY_MATH_387
13918 && flag_unsafe_math_optimizations"
13919 "fxtract"
13920 [(set_attr "type" "fpspc")
13921 (set_attr "mode" "XF")])
13922
13923 (define_insn "fxtract_extend<mode>xf3_i387"
13924 [(set (match_operand:XF 0 "register_operand" "=f")
13925 (unspec:XF [(float_extend:XF
13926 (match_operand:MODEF 2 "register_operand" "0"))]
13927 UNSPEC_XTRACT_FRACT))
13928 (set (match_operand:XF 1 "register_operand" "=u")
13929 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13930 "TARGET_USE_FANCY_MATH_387
13931 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13932 || TARGET_MIX_SSE_I387)
13933 && flag_unsafe_math_optimizations"
13934 "fxtract"
13935 [(set_attr "type" "fpspc")
13936 (set_attr "mode" "XF")])
13937
13938 (define_expand "logbxf2"
13939 [(parallel [(set (match_dup 2)
13940 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13941 UNSPEC_XTRACT_FRACT))
13942 (set (match_operand:XF 0 "register_operand" "")
13943 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13944 "TARGET_USE_FANCY_MATH_387
13945 && flag_unsafe_math_optimizations"
13946 "operands[2] = gen_reg_rtx (XFmode);")
13947
13948 (define_expand "logb<mode>2"
13949 [(use (match_operand:MODEF 0 "register_operand" ""))
13950 (use (match_operand:MODEF 1 "register_operand" ""))]
13951 "TARGET_USE_FANCY_MATH_387
13952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13953 || TARGET_MIX_SSE_I387)
13954 && flag_unsafe_math_optimizations"
13955 {
13956 rtx op0 = gen_reg_rtx (XFmode);
13957 rtx op1 = gen_reg_rtx (XFmode);
13958
13959 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13960 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13961 DONE;
13962 })
13963
13964 (define_expand "ilogbxf2"
13965 [(use (match_operand:SI 0 "register_operand" ""))
13966 (use (match_operand:XF 1 "register_operand" ""))]
13967 "TARGET_USE_FANCY_MATH_387
13968 && flag_unsafe_math_optimizations"
13969 {
13970 rtx op0, op1;
13971
13972 if (optimize_insn_for_size_p ())
13973 FAIL;
13974
13975 op0 = gen_reg_rtx (XFmode);
13976 op1 = gen_reg_rtx (XFmode);
13977
13978 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13979 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13980 DONE;
13981 })
13982
13983 (define_expand "ilogb<mode>2"
13984 [(use (match_operand:SI 0 "register_operand" ""))
13985 (use (match_operand:MODEF 1 "register_operand" ""))]
13986 "TARGET_USE_FANCY_MATH_387
13987 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13988 || TARGET_MIX_SSE_I387)
13989 && flag_unsafe_math_optimizations"
13990 {
13991 rtx op0, op1;
13992
13993 if (optimize_insn_for_size_p ())
13994 FAIL;
13995
13996 op0 = gen_reg_rtx (XFmode);
13997 op1 = gen_reg_rtx (XFmode);
13998
13999 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14000 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14001 DONE;
14002 })
14003
14004 (define_insn "*f2xm1xf2_i387"
14005 [(set (match_operand:XF 0 "register_operand" "=f")
14006 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14007 UNSPEC_F2XM1))]
14008 "TARGET_USE_FANCY_MATH_387
14009 && flag_unsafe_math_optimizations"
14010 "f2xm1"
14011 [(set_attr "type" "fpspc")
14012 (set_attr "mode" "XF")])
14013
14014 (define_insn "*fscalexf4_i387"
14015 [(set (match_operand:XF 0 "register_operand" "=f")
14016 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14017 (match_operand:XF 3 "register_operand" "1")]
14018 UNSPEC_FSCALE_FRACT))
14019 (set (match_operand:XF 1 "register_operand" "=u")
14020 (unspec:XF [(match_dup 2) (match_dup 3)]
14021 UNSPEC_FSCALE_EXP))]
14022 "TARGET_USE_FANCY_MATH_387
14023 && flag_unsafe_math_optimizations"
14024 "fscale"
14025 [(set_attr "type" "fpspc")
14026 (set_attr "mode" "XF")])
14027
14028 (define_expand "expNcorexf3"
14029 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14030 (match_operand:XF 2 "register_operand" "")))
14031 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14032 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14033 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14034 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14035 (parallel [(set (match_operand:XF 0 "register_operand" "")
14036 (unspec:XF [(match_dup 8) (match_dup 4)]
14037 UNSPEC_FSCALE_FRACT))
14038 (set (match_dup 9)
14039 (unspec:XF [(match_dup 8) (match_dup 4)]
14040 UNSPEC_FSCALE_EXP))])]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14043 {
14044 int i;
14045
14046 if (optimize_insn_for_size_p ())
14047 FAIL;
14048
14049 for (i = 3; i < 10; i++)
14050 operands[i] = gen_reg_rtx (XFmode);
14051
14052 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14053 })
14054
14055 (define_expand "expxf2"
14056 [(use (match_operand:XF 0 "register_operand" ""))
14057 (use (match_operand:XF 1 "register_operand" ""))]
14058 "TARGET_USE_FANCY_MATH_387
14059 && flag_unsafe_math_optimizations"
14060 {
14061 rtx op2;
14062
14063 if (optimize_insn_for_size_p ())
14064 FAIL;
14065
14066 op2 = gen_reg_rtx (XFmode);
14067 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14068
14069 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14070 DONE;
14071 })
14072
14073 (define_expand "exp<mode>2"
14074 [(use (match_operand:MODEF 0 "register_operand" ""))
14075 (use (match_operand:MODEF 1 "general_operand" ""))]
14076 "TARGET_USE_FANCY_MATH_387
14077 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14078 || TARGET_MIX_SSE_I387)
14079 && flag_unsafe_math_optimizations"
14080 {
14081 rtx op0, op1;
14082
14083 if (optimize_insn_for_size_p ())
14084 FAIL;
14085
14086 op0 = gen_reg_rtx (XFmode);
14087 op1 = gen_reg_rtx (XFmode);
14088
14089 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14090 emit_insn (gen_expxf2 (op0, op1));
14091 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14092 DONE;
14093 })
14094
14095 (define_expand "exp10xf2"
14096 [(use (match_operand:XF 0 "register_operand" ""))
14097 (use (match_operand:XF 1 "register_operand" ""))]
14098 "TARGET_USE_FANCY_MATH_387
14099 && flag_unsafe_math_optimizations"
14100 {
14101 rtx op2;
14102
14103 if (optimize_insn_for_size_p ())
14104 FAIL;
14105
14106 op2 = gen_reg_rtx (XFmode);
14107 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14108
14109 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14110 DONE;
14111 })
14112
14113 (define_expand "exp10<mode>2"
14114 [(use (match_operand:MODEF 0 "register_operand" ""))
14115 (use (match_operand:MODEF 1 "general_operand" ""))]
14116 "TARGET_USE_FANCY_MATH_387
14117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14118 || TARGET_MIX_SSE_I387)
14119 && flag_unsafe_math_optimizations"
14120 {
14121 rtx op0, op1;
14122
14123 if (optimize_insn_for_size_p ())
14124 FAIL;
14125
14126 op0 = gen_reg_rtx (XFmode);
14127 op1 = gen_reg_rtx (XFmode);
14128
14129 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14130 emit_insn (gen_exp10xf2 (op0, op1));
14131 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14132 DONE;
14133 })
14134
14135 (define_expand "exp2xf2"
14136 [(use (match_operand:XF 0 "register_operand" ""))
14137 (use (match_operand:XF 1 "register_operand" ""))]
14138 "TARGET_USE_FANCY_MATH_387
14139 && flag_unsafe_math_optimizations"
14140 {
14141 rtx op2;
14142
14143 if (optimize_insn_for_size_p ())
14144 FAIL;
14145
14146 op2 = gen_reg_rtx (XFmode);
14147 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14148
14149 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14150 DONE;
14151 })
14152
14153 (define_expand "exp2<mode>2"
14154 [(use (match_operand:MODEF 0 "register_operand" ""))
14155 (use (match_operand:MODEF 1 "general_operand" ""))]
14156 "TARGET_USE_FANCY_MATH_387
14157 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14158 || TARGET_MIX_SSE_I387)
14159 && flag_unsafe_math_optimizations"
14160 {
14161 rtx op0, op1;
14162
14163 if (optimize_insn_for_size_p ())
14164 FAIL;
14165
14166 op0 = gen_reg_rtx (XFmode);
14167 op1 = gen_reg_rtx (XFmode);
14168
14169 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14170 emit_insn (gen_exp2xf2 (op0, op1));
14171 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14172 DONE;
14173 })
14174
14175 (define_expand "expm1xf2"
14176 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14177 (match_dup 2)))
14178 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14179 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14180 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14181 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14182 (parallel [(set (match_dup 7)
14183 (unspec:XF [(match_dup 6) (match_dup 4)]
14184 UNSPEC_FSCALE_FRACT))
14185 (set (match_dup 8)
14186 (unspec:XF [(match_dup 6) (match_dup 4)]
14187 UNSPEC_FSCALE_EXP))])
14188 (parallel [(set (match_dup 10)
14189 (unspec:XF [(match_dup 9) (match_dup 8)]
14190 UNSPEC_FSCALE_FRACT))
14191 (set (match_dup 11)
14192 (unspec:XF [(match_dup 9) (match_dup 8)]
14193 UNSPEC_FSCALE_EXP))])
14194 (set (match_dup 12) (minus:XF (match_dup 10)
14195 (float_extend:XF (match_dup 13))))
14196 (set (match_operand:XF 0 "register_operand" "")
14197 (plus:XF (match_dup 12) (match_dup 7)))]
14198 "TARGET_USE_FANCY_MATH_387
14199 && flag_unsafe_math_optimizations"
14200 {
14201 int i;
14202
14203 if (optimize_insn_for_size_p ())
14204 FAIL;
14205
14206 for (i = 2; i < 13; i++)
14207 operands[i] = gen_reg_rtx (XFmode);
14208
14209 operands[13]
14210 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14211
14212 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14213 })
14214
14215 (define_expand "expm1<mode>2"
14216 [(use (match_operand:MODEF 0 "register_operand" ""))
14217 (use (match_operand:MODEF 1 "general_operand" ""))]
14218 "TARGET_USE_FANCY_MATH_387
14219 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14220 || TARGET_MIX_SSE_I387)
14221 && flag_unsafe_math_optimizations"
14222 {
14223 rtx op0, op1;
14224
14225 if (optimize_insn_for_size_p ())
14226 FAIL;
14227
14228 op0 = gen_reg_rtx (XFmode);
14229 op1 = gen_reg_rtx (XFmode);
14230
14231 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14232 emit_insn (gen_expm1xf2 (op0, op1));
14233 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14234 DONE;
14235 })
14236
14237 (define_expand "ldexpxf3"
14238 [(set (match_dup 3)
14239 (float:XF (match_operand:SI 2 "register_operand" "")))
14240 (parallel [(set (match_operand:XF 0 " register_operand" "")
14241 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14242 (match_dup 3)]
14243 UNSPEC_FSCALE_FRACT))
14244 (set (match_dup 4)
14245 (unspec:XF [(match_dup 1) (match_dup 3)]
14246 UNSPEC_FSCALE_EXP))])]
14247 "TARGET_USE_FANCY_MATH_387
14248 && flag_unsafe_math_optimizations"
14249 {
14250 if (optimize_insn_for_size_p ())
14251 FAIL;
14252
14253 operands[3] = gen_reg_rtx (XFmode);
14254 operands[4] = gen_reg_rtx (XFmode);
14255 })
14256
14257 (define_expand "ldexp<mode>3"
14258 [(use (match_operand:MODEF 0 "register_operand" ""))
14259 (use (match_operand:MODEF 1 "general_operand" ""))
14260 (use (match_operand:SI 2 "register_operand" ""))]
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 {
14266 rtx op0, op1;
14267
14268 if (optimize_insn_for_size_p ())
14269 FAIL;
14270
14271 op0 = gen_reg_rtx (XFmode);
14272 op1 = gen_reg_rtx (XFmode);
14273
14274 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14275 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14276 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14277 DONE;
14278 })
14279
14280 (define_expand "scalbxf3"
14281 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14282 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14283 (match_operand:XF 2 "register_operand" "")]
14284 UNSPEC_FSCALE_FRACT))
14285 (set (match_dup 3)
14286 (unspec:XF [(match_dup 1) (match_dup 2)]
14287 UNSPEC_FSCALE_EXP))])]
14288 "TARGET_USE_FANCY_MATH_387
14289 && flag_unsafe_math_optimizations"
14290 {
14291 if (optimize_insn_for_size_p ())
14292 FAIL;
14293
14294 operands[3] = gen_reg_rtx (XFmode);
14295 })
14296
14297 (define_expand "scalb<mode>3"
14298 [(use (match_operand:MODEF 0 "register_operand" ""))
14299 (use (match_operand:MODEF 1 "general_operand" ""))
14300 (use (match_operand:MODEF 2 "general_operand" ""))]
14301 "TARGET_USE_FANCY_MATH_387
14302 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14303 || TARGET_MIX_SSE_I387)
14304 && flag_unsafe_math_optimizations"
14305 {
14306 rtx op0, op1, op2;
14307
14308 if (optimize_insn_for_size_p ())
14309 FAIL;
14310
14311 op0 = gen_reg_rtx (XFmode);
14312 op1 = gen_reg_rtx (XFmode);
14313 op2 = gen_reg_rtx (XFmode);
14314
14315 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14316 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14317 emit_insn (gen_scalbxf3 (op0, op1, op2));
14318 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14319 DONE;
14320 })
14321
14322 (define_expand "significandxf2"
14323 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14324 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14325 UNSPEC_XTRACT_FRACT))
14326 (set (match_dup 2)
14327 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14328 "TARGET_USE_FANCY_MATH_387
14329 && flag_unsafe_math_optimizations"
14330 "operands[2] = gen_reg_rtx (XFmode);")
14331
14332 (define_expand "significand<mode>2"
14333 [(use (match_operand:MODEF 0 "register_operand" ""))
14334 (use (match_operand:MODEF 1 "register_operand" ""))]
14335 "TARGET_USE_FANCY_MATH_387
14336 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14337 || TARGET_MIX_SSE_I387)
14338 && flag_unsafe_math_optimizations"
14339 {
14340 rtx op0 = gen_reg_rtx (XFmode);
14341 rtx op1 = gen_reg_rtx (XFmode);
14342
14343 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14344 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14345 DONE;
14346 })
14347 \f
14348
14349 (define_insn "sse4_1_round<mode>2"
14350 [(set (match_operand:MODEF 0 "register_operand" "=x")
14351 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14352 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14353 UNSPEC_ROUND))]
14354 "TARGET_ROUND"
14355 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14356 [(set_attr "type" "ssecvt")
14357 (set_attr "prefix_extra" "1")
14358 (set_attr "prefix" "maybe_vex")
14359 (set_attr "mode" "<MODE>")])
14360
14361 (define_insn "rintxf2"
14362 [(set (match_operand:XF 0 "register_operand" "=f")
14363 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14364 UNSPEC_FRNDINT))]
14365 "TARGET_USE_FANCY_MATH_387
14366 && flag_unsafe_math_optimizations"
14367 "frndint"
14368 [(set_attr "type" "fpspc")
14369 (set_attr "mode" "XF")])
14370
14371 (define_expand "rint<mode>2"
14372 [(use (match_operand:MODEF 0 "register_operand" ""))
14373 (use (match_operand:MODEF 1 "register_operand" ""))]
14374 "(TARGET_USE_FANCY_MATH_387
14375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14376 || TARGET_MIX_SSE_I387)
14377 && flag_unsafe_math_optimizations)
14378 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14379 && !flag_trapping_math)"
14380 {
14381 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14382 && !flag_trapping_math)
14383 {
14384 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14385 FAIL;
14386 if (TARGET_ROUND)
14387 emit_insn (gen_sse4_1_round<mode>2
14388 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14389 else
14390 ix86_expand_rint (operand0, operand1);
14391 }
14392 else
14393 {
14394 rtx op0 = gen_reg_rtx (XFmode);
14395 rtx op1 = gen_reg_rtx (XFmode);
14396
14397 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14398 emit_insn (gen_rintxf2 (op0, op1));
14399
14400 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14401 }
14402 DONE;
14403 })
14404
14405 (define_expand "round<mode>2"
14406 [(match_operand:MODEF 0 "register_operand" "")
14407 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14408 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14409 && !flag_trapping_math && !flag_rounding_math"
14410 {
14411 if (optimize_insn_for_size_p ())
14412 FAIL;
14413 if (TARGET_64BIT || (<MODE>mode != DFmode))
14414 ix86_expand_round (operand0, operand1);
14415 else
14416 ix86_expand_rounddf_32 (operand0, operand1);
14417 DONE;
14418 })
14419
14420 (define_insn_and_split "*fistdi2_1"
14421 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14422 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14423 UNSPEC_FIST))]
14424 "TARGET_USE_FANCY_MATH_387
14425 && can_create_pseudo_p ()"
14426 "#"
14427 "&& 1"
14428 [(const_int 0)]
14429 {
14430 if (memory_operand (operands[0], VOIDmode))
14431 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14432 else
14433 {
14434 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14435 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14436 operands[2]));
14437 }
14438 DONE;
14439 }
14440 [(set_attr "type" "fpspc")
14441 (set_attr "mode" "DI")])
14442
14443 (define_insn "fistdi2"
14444 [(set (match_operand:DI 0 "memory_operand" "=m")
14445 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14446 UNSPEC_FIST))
14447 (clobber (match_scratch:XF 2 "=&1f"))]
14448 "TARGET_USE_FANCY_MATH_387"
14449 "* return output_fix_trunc (insn, operands, false);"
14450 [(set_attr "type" "fpspc")
14451 (set_attr "mode" "DI")])
14452
14453 (define_insn "fistdi2_with_temp"
14454 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14455 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14456 UNSPEC_FIST))
14457 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14458 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14459 "TARGET_USE_FANCY_MATH_387"
14460 "#"
14461 [(set_attr "type" "fpspc")
14462 (set_attr "mode" "DI")])
14463
14464 (define_split
14465 [(set (match_operand:DI 0 "register_operand" "")
14466 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14467 UNSPEC_FIST))
14468 (clobber (match_operand:DI 2 "memory_operand" ""))
14469 (clobber (match_scratch 3 ""))]
14470 "reload_completed"
14471 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14472 (clobber (match_dup 3))])
14473 (set (match_dup 0) (match_dup 2))])
14474
14475 (define_split
14476 [(set (match_operand:DI 0 "memory_operand" "")
14477 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14478 UNSPEC_FIST))
14479 (clobber (match_operand:DI 2 "memory_operand" ""))
14480 (clobber (match_scratch 3 ""))]
14481 "reload_completed"
14482 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14483 (clobber (match_dup 3))])])
14484
14485 (define_insn_and_split "*fist<mode>2_1"
14486 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14487 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14488 UNSPEC_FIST))]
14489 "TARGET_USE_FANCY_MATH_387
14490 && can_create_pseudo_p ()"
14491 "#"
14492 "&& 1"
14493 [(const_int 0)]
14494 {
14495 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14496 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14497 operands[2]));
14498 DONE;
14499 }
14500 [(set_attr "type" "fpspc")
14501 (set_attr "mode" "<MODE>")])
14502
14503 (define_insn "fist<mode>2"
14504 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14505 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14506 UNSPEC_FIST))]
14507 "TARGET_USE_FANCY_MATH_387"
14508 "* return output_fix_trunc (insn, operands, false);"
14509 [(set_attr "type" "fpspc")
14510 (set_attr "mode" "<MODE>")])
14511
14512 (define_insn "fist<mode>2_with_temp"
14513 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14514 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14515 UNSPEC_FIST))
14516 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14517 "TARGET_USE_FANCY_MATH_387"
14518 "#"
14519 [(set_attr "type" "fpspc")
14520 (set_attr "mode" "<MODE>")])
14521
14522 (define_split
14523 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14524 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14525 UNSPEC_FIST))
14526 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14527 "reload_completed"
14528 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14529 (set (match_dup 0) (match_dup 2))])
14530
14531 (define_split
14532 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14533 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14534 UNSPEC_FIST))
14535 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14536 "reload_completed"
14537 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14538
14539 (define_expand "lrintxf<mode>2"
14540 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14541 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14542 UNSPEC_FIST))]
14543 "TARGET_USE_FANCY_MATH_387")
14544
14545 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14546 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14547 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14548 UNSPEC_FIX_NOTRUNC))]
14549 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14550 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14551
14552 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14553 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14554 (match_operand:MODEF 1 "register_operand" "")]
14555 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14556 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14557 && !flag_trapping_math && !flag_rounding_math"
14558 {
14559 if (optimize_insn_for_size_p ())
14560 FAIL;
14561 ix86_expand_lround (operand0, operand1);
14562 DONE;
14563 })
14564
14565 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14566 (define_insn_and_split "frndintxf2_floor"
14567 [(set (match_operand:XF 0 "register_operand" "")
14568 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14569 UNSPEC_FRNDINT_FLOOR))
14570 (clobber (reg:CC FLAGS_REG))]
14571 "TARGET_USE_FANCY_MATH_387
14572 && flag_unsafe_math_optimizations
14573 && can_create_pseudo_p ()"
14574 "#"
14575 "&& 1"
14576 [(const_int 0)]
14577 {
14578 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14579
14580 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14581 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14582
14583 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14584 operands[2], operands[3]));
14585 DONE;
14586 }
14587 [(set_attr "type" "frndint")
14588 (set_attr "i387_cw" "floor")
14589 (set_attr "mode" "XF")])
14590
14591 (define_insn "frndintxf2_floor_i387"
14592 [(set (match_operand:XF 0 "register_operand" "=f")
14593 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14594 UNSPEC_FRNDINT_FLOOR))
14595 (use (match_operand:HI 2 "memory_operand" "m"))
14596 (use (match_operand:HI 3 "memory_operand" "m"))]
14597 "TARGET_USE_FANCY_MATH_387
14598 && flag_unsafe_math_optimizations"
14599 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14600 [(set_attr "type" "frndint")
14601 (set_attr "i387_cw" "floor")
14602 (set_attr "mode" "XF")])
14603
14604 (define_expand "floorxf2"
14605 [(use (match_operand:XF 0 "register_operand" ""))
14606 (use (match_operand:XF 1 "register_operand" ""))]
14607 "TARGET_USE_FANCY_MATH_387
14608 && flag_unsafe_math_optimizations"
14609 {
14610 if (optimize_insn_for_size_p ())
14611 FAIL;
14612 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14613 DONE;
14614 })
14615
14616 (define_expand "floor<mode>2"
14617 [(use (match_operand:MODEF 0 "register_operand" ""))
14618 (use (match_operand:MODEF 1 "register_operand" ""))]
14619 "(TARGET_USE_FANCY_MATH_387
14620 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14621 || TARGET_MIX_SSE_I387)
14622 && flag_unsafe_math_optimizations)
14623 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14624 && !flag_trapping_math)"
14625 {
14626 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14627 && !flag_trapping_math
14628 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14629 {
14630 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14631 FAIL;
14632 if (TARGET_ROUND)
14633 emit_insn (gen_sse4_1_round<mode>2
14634 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14635 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14636 ix86_expand_floorceil (operand0, operand1, true);
14637 else
14638 ix86_expand_floorceildf_32 (operand0, operand1, true);
14639 }
14640 else
14641 {
14642 rtx op0, op1;
14643
14644 if (optimize_insn_for_size_p ())
14645 FAIL;
14646
14647 op0 = gen_reg_rtx (XFmode);
14648 op1 = gen_reg_rtx (XFmode);
14649 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14650 emit_insn (gen_frndintxf2_floor (op0, op1));
14651
14652 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14653 }
14654 DONE;
14655 })
14656
14657 (define_insn_and_split "*fist<mode>2_floor_1"
14658 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14659 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14660 UNSPEC_FIST_FLOOR))
14661 (clobber (reg:CC FLAGS_REG))]
14662 "TARGET_USE_FANCY_MATH_387
14663 && flag_unsafe_math_optimizations
14664 && can_create_pseudo_p ()"
14665 "#"
14666 "&& 1"
14667 [(const_int 0)]
14668 {
14669 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14670
14671 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14672 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14673 if (memory_operand (operands[0], VOIDmode))
14674 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14675 operands[2], operands[3]));
14676 else
14677 {
14678 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14679 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14680 operands[2], operands[3],
14681 operands[4]));
14682 }
14683 DONE;
14684 }
14685 [(set_attr "type" "fistp")
14686 (set_attr "i387_cw" "floor")
14687 (set_attr "mode" "<MODE>")])
14688
14689 (define_insn "fistdi2_floor"
14690 [(set (match_operand:DI 0 "memory_operand" "=m")
14691 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14692 UNSPEC_FIST_FLOOR))
14693 (use (match_operand:HI 2 "memory_operand" "m"))
14694 (use (match_operand:HI 3 "memory_operand" "m"))
14695 (clobber (match_scratch:XF 4 "=&1f"))]
14696 "TARGET_USE_FANCY_MATH_387
14697 && flag_unsafe_math_optimizations"
14698 "* return output_fix_trunc (insn, operands, false);"
14699 [(set_attr "type" "fistp")
14700 (set_attr "i387_cw" "floor")
14701 (set_attr "mode" "DI")])
14702
14703 (define_insn "fistdi2_floor_with_temp"
14704 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14705 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14706 UNSPEC_FIST_FLOOR))
14707 (use (match_operand:HI 2 "memory_operand" "m,m"))
14708 (use (match_operand:HI 3 "memory_operand" "m,m"))
14709 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14710 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14711 "TARGET_USE_FANCY_MATH_387
14712 && flag_unsafe_math_optimizations"
14713 "#"
14714 [(set_attr "type" "fistp")
14715 (set_attr "i387_cw" "floor")
14716 (set_attr "mode" "DI")])
14717
14718 (define_split
14719 [(set (match_operand:DI 0 "register_operand" "")
14720 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14721 UNSPEC_FIST_FLOOR))
14722 (use (match_operand:HI 2 "memory_operand" ""))
14723 (use (match_operand:HI 3 "memory_operand" ""))
14724 (clobber (match_operand:DI 4 "memory_operand" ""))
14725 (clobber (match_scratch 5 ""))]
14726 "reload_completed"
14727 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14728 (use (match_dup 2))
14729 (use (match_dup 3))
14730 (clobber (match_dup 5))])
14731 (set (match_dup 0) (match_dup 4))])
14732
14733 (define_split
14734 [(set (match_operand:DI 0 "memory_operand" "")
14735 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14736 UNSPEC_FIST_FLOOR))
14737 (use (match_operand:HI 2 "memory_operand" ""))
14738 (use (match_operand:HI 3 "memory_operand" ""))
14739 (clobber (match_operand:DI 4 "memory_operand" ""))
14740 (clobber (match_scratch 5 ""))]
14741 "reload_completed"
14742 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14743 (use (match_dup 2))
14744 (use (match_dup 3))
14745 (clobber (match_dup 5))])])
14746
14747 (define_insn "fist<mode>2_floor"
14748 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14749 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14750 UNSPEC_FIST_FLOOR))
14751 (use (match_operand:HI 2 "memory_operand" "m"))
14752 (use (match_operand:HI 3 "memory_operand" "m"))]
14753 "TARGET_USE_FANCY_MATH_387
14754 && flag_unsafe_math_optimizations"
14755 "* return output_fix_trunc (insn, operands, false);"
14756 [(set_attr "type" "fistp")
14757 (set_attr "i387_cw" "floor")
14758 (set_attr "mode" "<MODE>")])
14759
14760 (define_insn "fist<mode>2_floor_with_temp"
14761 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14762 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14763 UNSPEC_FIST_FLOOR))
14764 (use (match_operand:HI 2 "memory_operand" "m,m"))
14765 (use (match_operand:HI 3 "memory_operand" "m,m"))
14766 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14767 "TARGET_USE_FANCY_MATH_387
14768 && flag_unsafe_math_optimizations"
14769 "#"
14770 [(set_attr "type" "fistp")
14771 (set_attr "i387_cw" "floor")
14772 (set_attr "mode" "<MODE>")])
14773
14774 (define_split
14775 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14776 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14777 UNSPEC_FIST_FLOOR))
14778 (use (match_operand:HI 2 "memory_operand" ""))
14779 (use (match_operand:HI 3 "memory_operand" ""))
14780 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14781 "reload_completed"
14782 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14783 UNSPEC_FIST_FLOOR))
14784 (use (match_dup 2))
14785 (use (match_dup 3))])
14786 (set (match_dup 0) (match_dup 4))])
14787
14788 (define_split
14789 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14790 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14791 UNSPEC_FIST_FLOOR))
14792 (use (match_operand:HI 2 "memory_operand" ""))
14793 (use (match_operand:HI 3 "memory_operand" ""))
14794 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14795 "reload_completed"
14796 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14797 UNSPEC_FIST_FLOOR))
14798 (use (match_dup 2))
14799 (use (match_dup 3))])])
14800
14801 (define_expand "lfloorxf<mode>2"
14802 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14803 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14804 UNSPEC_FIST_FLOOR))
14805 (clobber (reg:CC FLAGS_REG))])]
14806 "TARGET_USE_FANCY_MATH_387
14807 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14808 && flag_unsafe_math_optimizations")
14809
14810 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14811 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14812 (match_operand:MODEF 1 "register_operand" "")]
14813 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14814 && !flag_trapping_math"
14815 {
14816 if (TARGET_64BIT && optimize_insn_for_size_p ())
14817 FAIL;
14818 ix86_expand_lfloorceil (operand0, operand1, true);
14819 DONE;
14820 })
14821
14822 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14823 (define_insn_and_split "frndintxf2_ceil"
14824 [(set (match_operand:XF 0 "register_operand" "")
14825 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14826 UNSPEC_FRNDINT_CEIL))
14827 (clobber (reg:CC FLAGS_REG))]
14828 "TARGET_USE_FANCY_MATH_387
14829 && flag_unsafe_math_optimizations
14830 && can_create_pseudo_p ()"
14831 "#"
14832 "&& 1"
14833 [(const_int 0)]
14834 {
14835 ix86_optimize_mode_switching[I387_CEIL] = 1;
14836
14837 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14838 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14839
14840 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14841 operands[2], operands[3]));
14842 DONE;
14843 }
14844 [(set_attr "type" "frndint")
14845 (set_attr "i387_cw" "ceil")
14846 (set_attr "mode" "XF")])
14847
14848 (define_insn "frndintxf2_ceil_i387"
14849 [(set (match_operand:XF 0 "register_operand" "=f")
14850 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14851 UNSPEC_FRNDINT_CEIL))
14852 (use (match_operand:HI 2 "memory_operand" "m"))
14853 (use (match_operand:HI 3 "memory_operand" "m"))]
14854 "TARGET_USE_FANCY_MATH_387
14855 && flag_unsafe_math_optimizations"
14856 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14857 [(set_attr "type" "frndint")
14858 (set_attr "i387_cw" "ceil")
14859 (set_attr "mode" "XF")])
14860
14861 (define_expand "ceilxf2"
14862 [(use (match_operand:XF 0 "register_operand" ""))
14863 (use (match_operand:XF 1 "register_operand" ""))]
14864 "TARGET_USE_FANCY_MATH_387
14865 && flag_unsafe_math_optimizations"
14866 {
14867 if (optimize_insn_for_size_p ())
14868 FAIL;
14869 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14870 DONE;
14871 })
14872
14873 (define_expand "ceil<mode>2"
14874 [(use (match_operand:MODEF 0 "register_operand" ""))
14875 (use (match_operand:MODEF 1 "register_operand" ""))]
14876 "(TARGET_USE_FANCY_MATH_387
14877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14878 || TARGET_MIX_SSE_I387)
14879 && flag_unsafe_math_optimizations)
14880 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14881 && !flag_trapping_math)"
14882 {
14883 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14884 && !flag_trapping_math
14885 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14886 {
14887 if (TARGET_ROUND)
14888 emit_insn (gen_sse4_1_round<mode>2
14889 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14890 else if (optimize_insn_for_size_p ())
14891 FAIL;
14892 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14893 ix86_expand_floorceil (operand0, operand1, false);
14894 else
14895 ix86_expand_floorceildf_32 (operand0, operand1, false);
14896 }
14897 else
14898 {
14899 rtx op0, op1;
14900
14901 if (optimize_insn_for_size_p ())
14902 FAIL;
14903
14904 op0 = gen_reg_rtx (XFmode);
14905 op1 = gen_reg_rtx (XFmode);
14906 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14907 emit_insn (gen_frndintxf2_ceil (op0, op1));
14908
14909 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14910 }
14911 DONE;
14912 })
14913
14914 (define_insn_and_split "*fist<mode>2_ceil_1"
14915 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14916 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14917 UNSPEC_FIST_CEIL))
14918 (clobber (reg:CC FLAGS_REG))]
14919 "TARGET_USE_FANCY_MATH_387
14920 && flag_unsafe_math_optimizations
14921 && can_create_pseudo_p ()"
14922 "#"
14923 "&& 1"
14924 [(const_int 0)]
14925 {
14926 ix86_optimize_mode_switching[I387_CEIL] = 1;
14927
14928 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14929 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14930 if (memory_operand (operands[0], VOIDmode))
14931 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14932 operands[2], operands[3]));
14933 else
14934 {
14935 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14936 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14937 operands[2], operands[3],
14938 operands[4]));
14939 }
14940 DONE;
14941 }
14942 [(set_attr "type" "fistp")
14943 (set_attr "i387_cw" "ceil")
14944 (set_attr "mode" "<MODE>")])
14945
14946 (define_insn "fistdi2_ceil"
14947 [(set (match_operand:DI 0 "memory_operand" "=m")
14948 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14949 UNSPEC_FIST_CEIL))
14950 (use (match_operand:HI 2 "memory_operand" "m"))
14951 (use (match_operand:HI 3 "memory_operand" "m"))
14952 (clobber (match_scratch:XF 4 "=&1f"))]
14953 "TARGET_USE_FANCY_MATH_387
14954 && flag_unsafe_math_optimizations"
14955 "* return output_fix_trunc (insn, operands, false);"
14956 [(set_attr "type" "fistp")
14957 (set_attr "i387_cw" "ceil")
14958 (set_attr "mode" "DI")])
14959
14960 (define_insn "fistdi2_ceil_with_temp"
14961 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14962 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14963 UNSPEC_FIST_CEIL))
14964 (use (match_operand:HI 2 "memory_operand" "m,m"))
14965 (use (match_operand:HI 3 "memory_operand" "m,m"))
14966 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14967 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14968 "TARGET_USE_FANCY_MATH_387
14969 && flag_unsafe_math_optimizations"
14970 "#"
14971 [(set_attr "type" "fistp")
14972 (set_attr "i387_cw" "ceil")
14973 (set_attr "mode" "DI")])
14974
14975 (define_split
14976 [(set (match_operand:DI 0 "register_operand" "")
14977 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14978 UNSPEC_FIST_CEIL))
14979 (use (match_operand:HI 2 "memory_operand" ""))
14980 (use (match_operand:HI 3 "memory_operand" ""))
14981 (clobber (match_operand:DI 4 "memory_operand" ""))
14982 (clobber (match_scratch 5 ""))]
14983 "reload_completed"
14984 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14985 (use (match_dup 2))
14986 (use (match_dup 3))
14987 (clobber (match_dup 5))])
14988 (set (match_dup 0) (match_dup 4))])
14989
14990 (define_split
14991 [(set (match_operand:DI 0 "memory_operand" "")
14992 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14993 UNSPEC_FIST_CEIL))
14994 (use (match_operand:HI 2 "memory_operand" ""))
14995 (use (match_operand:HI 3 "memory_operand" ""))
14996 (clobber (match_operand:DI 4 "memory_operand" ""))
14997 (clobber (match_scratch 5 ""))]
14998 "reload_completed"
14999 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15000 (use (match_dup 2))
15001 (use (match_dup 3))
15002 (clobber (match_dup 5))])])
15003
15004 (define_insn "fist<mode>2_ceil"
15005 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15006 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15007 UNSPEC_FIST_CEIL))
15008 (use (match_operand:HI 2 "memory_operand" "m"))
15009 (use (match_operand:HI 3 "memory_operand" "m"))]
15010 "TARGET_USE_FANCY_MATH_387
15011 && flag_unsafe_math_optimizations"
15012 "* return output_fix_trunc (insn, operands, false);"
15013 [(set_attr "type" "fistp")
15014 (set_attr "i387_cw" "ceil")
15015 (set_attr "mode" "<MODE>")])
15016
15017 (define_insn "fist<mode>2_ceil_with_temp"
15018 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15019 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15020 UNSPEC_FIST_CEIL))
15021 (use (match_operand:HI 2 "memory_operand" "m,m"))
15022 (use (match_operand:HI 3 "memory_operand" "m,m"))
15023 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15024 "TARGET_USE_FANCY_MATH_387
15025 && flag_unsafe_math_optimizations"
15026 "#"
15027 [(set_attr "type" "fistp")
15028 (set_attr "i387_cw" "ceil")
15029 (set_attr "mode" "<MODE>")])
15030
15031 (define_split
15032 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15033 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15034 UNSPEC_FIST_CEIL))
15035 (use (match_operand:HI 2 "memory_operand" ""))
15036 (use (match_operand:HI 3 "memory_operand" ""))
15037 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15038 "reload_completed"
15039 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15040 UNSPEC_FIST_CEIL))
15041 (use (match_dup 2))
15042 (use (match_dup 3))])
15043 (set (match_dup 0) (match_dup 4))])
15044
15045 (define_split
15046 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15047 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15048 UNSPEC_FIST_CEIL))
15049 (use (match_operand:HI 2 "memory_operand" ""))
15050 (use (match_operand:HI 3 "memory_operand" ""))
15051 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15052 "reload_completed"
15053 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15054 UNSPEC_FIST_CEIL))
15055 (use (match_dup 2))
15056 (use (match_dup 3))])])
15057
15058 (define_expand "lceilxf<mode>2"
15059 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15060 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15061 UNSPEC_FIST_CEIL))
15062 (clobber (reg:CC FLAGS_REG))])]
15063 "TARGET_USE_FANCY_MATH_387
15064 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15065 && flag_unsafe_math_optimizations")
15066
15067 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15068 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15069 (match_operand:MODEF 1 "register_operand" "")]
15070 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15071 && !flag_trapping_math"
15072 {
15073 ix86_expand_lfloorceil (operand0, operand1, false);
15074 DONE;
15075 })
15076
15077 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15078 (define_insn_and_split "frndintxf2_trunc"
15079 [(set (match_operand:XF 0 "register_operand" "")
15080 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15081 UNSPEC_FRNDINT_TRUNC))
15082 (clobber (reg:CC FLAGS_REG))]
15083 "TARGET_USE_FANCY_MATH_387
15084 && flag_unsafe_math_optimizations
15085 && can_create_pseudo_p ()"
15086 "#"
15087 "&& 1"
15088 [(const_int 0)]
15089 {
15090 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15091
15092 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15093 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15094
15095 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15096 operands[2], operands[3]));
15097 DONE;
15098 }
15099 [(set_attr "type" "frndint")
15100 (set_attr "i387_cw" "trunc")
15101 (set_attr "mode" "XF")])
15102
15103 (define_insn "frndintxf2_trunc_i387"
15104 [(set (match_operand:XF 0 "register_operand" "=f")
15105 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15106 UNSPEC_FRNDINT_TRUNC))
15107 (use (match_operand:HI 2 "memory_operand" "m"))
15108 (use (match_operand:HI 3 "memory_operand" "m"))]
15109 "TARGET_USE_FANCY_MATH_387
15110 && flag_unsafe_math_optimizations"
15111 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15112 [(set_attr "type" "frndint")
15113 (set_attr "i387_cw" "trunc")
15114 (set_attr "mode" "XF")])
15115
15116 (define_expand "btruncxf2"
15117 [(use (match_operand:XF 0 "register_operand" ""))
15118 (use (match_operand:XF 1 "register_operand" ""))]
15119 "TARGET_USE_FANCY_MATH_387
15120 && flag_unsafe_math_optimizations"
15121 {
15122 if (optimize_insn_for_size_p ())
15123 FAIL;
15124 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15125 DONE;
15126 })
15127
15128 (define_expand "btrunc<mode>2"
15129 [(use (match_operand:MODEF 0 "register_operand" ""))
15130 (use (match_operand:MODEF 1 "register_operand" ""))]
15131 "(TARGET_USE_FANCY_MATH_387
15132 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15133 || TARGET_MIX_SSE_I387)
15134 && flag_unsafe_math_optimizations)
15135 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15136 && !flag_trapping_math)"
15137 {
15138 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15139 && !flag_trapping_math
15140 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15141 {
15142 if (TARGET_ROUND)
15143 emit_insn (gen_sse4_1_round<mode>2
15144 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15145 else if (optimize_insn_for_size_p ())
15146 FAIL;
15147 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15148 ix86_expand_trunc (operand0, operand1);
15149 else
15150 ix86_expand_truncdf_32 (operand0, operand1);
15151 }
15152 else
15153 {
15154 rtx op0, op1;
15155
15156 if (optimize_insn_for_size_p ())
15157 FAIL;
15158
15159 op0 = gen_reg_rtx (XFmode);
15160 op1 = gen_reg_rtx (XFmode);
15161 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15162 emit_insn (gen_frndintxf2_trunc (op0, op1));
15163
15164 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15165 }
15166 DONE;
15167 })
15168
15169 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15170 (define_insn_and_split "frndintxf2_mask_pm"
15171 [(set (match_operand:XF 0 "register_operand" "")
15172 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15173 UNSPEC_FRNDINT_MASK_PM))
15174 (clobber (reg:CC FLAGS_REG))]
15175 "TARGET_USE_FANCY_MATH_387
15176 && flag_unsafe_math_optimizations
15177 && can_create_pseudo_p ()"
15178 "#"
15179 "&& 1"
15180 [(const_int 0)]
15181 {
15182 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15183
15184 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15185 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15186
15187 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15188 operands[2], operands[3]));
15189 DONE;
15190 }
15191 [(set_attr "type" "frndint")
15192 (set_attr "i387_cw" "mask_pm")
15193 (set_attr "mode" "XF")])
15194
15195 (define_insn "frndintxf2_mask_pm_i387"
15196 [(set (match_operand:XF 0 "register_operand" "=f")
15197 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15198 UNSPEC_FRNDINT_MASK_PM))
15199 (use (match_operand:HI 2 "memory_operand" "m"))
15200 (use (match_operand:HI 3 "memory_operand" "m"))]
15201 "TARGET_USE_FANCY_MATH_387
15202 && flag_unsafe_math_optimizations"
15203 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15204 [(set_attr "type" "frndint")
15205 (set_attr "i387_cw" "mask_pm")
15206 (set_attr "mode" "XF")])
15207
15208 (define_expand "nearbyintxf2"
15209 [(use (match_operand:XF 0 "register_operand" ""))
15210 (use (match_operand:XF 1 "register_operand" ""))]
15211 "TARGET_USE_FANCY_MATH_387
15212 && flag_unsafe_math_optimizations"
15213 {
15214 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15215 DONE;
15216 })
15217
15218 (define_expand "nearbyint<mode>2"
15219 [(use (match_operand:MODEF 0 "register_operand" ""))
15220 (use (match_operand:MODEF 1 "register_operand" ""))]
15221 "TARGET_USE_FANCY_MATH_387
15222 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15223 || TARGET_MIX_SSE_I387)
15224 && flag_unsafe_math_optimizations"
15225 {
15226 rtx op0 = gen_reg_rtx (XFmode);
15227 rtx op1 = gen_reg_rtx (XFmode);
15228
15229 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15230 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15231
15232 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15233 DONE;
15234 })
15235
15236 (define_insn "fxam<mode>2_i387"
15237 [(set (match_operand:HI 0 "register_operand" "=a")
15238 (unspec:HI
15239 [(match_operand:X87MODEF 1 "register_operand" "f")]
15240 UNSPEC_FXAM))]
15241 "TARGET_USE_FANCY_MATH_387"
15242 "fxam\n\tfnstsw\t%0"
15243 [(set_attr "type" "multi")
15244 (set_attr "length" "4")
15245 (set_attr "unit" "i387")
15246 (set_attr "mode" "<MODE>")])
15247
15248 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15249 [(set (match_operand:HI 0 "register_operand" "")
15250 (unspec:HI
15251 [(match_operand:MODEF 1 "memory_operand" "")]
15252 UNSPEC_FXAM_MEM))]
15253 "TARGET_USE_FANCY_MATH_387
15254 && can_create_pseudo_p ()"
15255 "#"
15256 "&& 1"
15257 [(set (match_dup 2)(match_dup 1))
15258 (set (match_dup 0)
15259 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15260 {
15261 operands[2] = gen_reg_rtx (<MODE>mode);
15262
15263 MEM_VOLATILE_P (operands[1]) = 1;
15264 }
15265 [(set_attr "type" "multi")
15266 (set_attr "unit" "i387")
15267 (set_attr "mode" "<MODE>")])
15268
15269 (define_expand "isinfxf2"
15270 [(use (match_operand:SI 0 "register_operand" ""))
15271 (use (match_operand:XF 1 "register_operand" ""))]
15272 "TARGET_USE_FANCY_MATH_387
15273 && TARGET_C99_FUNCTIONS"
15274 {
15275 rtx mask = GEN_INT (0x45);
15276 rtx val = GEN_INT (0x05);
15277
15278 rtx cond;
15279
15280 rtx scratch = gen_reg_rtx (HImode);
15281 rtx res = gen_reg_rtx (QImode);
15282
15283 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15284
15285 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15286 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15287 cond = gen_rtx_fmt_ee (EQ, QImode,
15288 gen_rtx_REG (CCmode, FLAGS_REG),
15289 const0_rtx);
15290 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15291 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15292 DONE;
15293 })
15294
15295 (define_expand "isinf<mode>2"
15296 [(use (match_operand:SI 0 "register_operand" ""))
15297 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15298 "TARGET_USE_FANCY_MATH_387
15299 && TARGET_C99_FUNCTIONS
15300 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15301 {
15302 rtx mask = GEN_INT (0x45);
15303 rtx val = GEN_INT (0x05);
15304
15305 rtx cond;
15306
15307 rtx scratch = gen_reg_rtx (HImode);
15308 rtx res = gen_reg_rtx (QImode);
15309
15310 /* Remove excess precision by forcing value through memory. */
15311 if (memory_operand (operands[1], VOIDmode))
15312 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15313 else
15314 {
15315 enum ix86_stack_slot slot = (virtuals_instantiated
15316 ? SLOT_TEMP
15317 : SLOT_VIRTUAL);
15318 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15319
15320 emit_move_insn (temp, operands[1]);
15321 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15322 }
15323
15324 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15325 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15326 cond = gen_rtx_fmt_ee (EQ, QImode,
15327 gen_rtx_REG (CCmode, FLAGS_REG),
15328 const0_rtx);
15329 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15330 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15331 DONE;
15332 })
15333
15334 (define_expand "signbitxf2"
15335 [(use (match_operand:SI 0 "register_operand" ""))
15336 (use (match_operand:XF 1 "register_operand" ""))]
15337 "TARGET_USE_FANCY_MATH_387"
15338 {
15339 rtx scratch = gen_reg_rtx (HImode);
15340
15341 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15342 emit_insn (gen_andsi3 (operands[0],
15343 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15344 DONE;
15345 })
15346
15347 (define_insn "movmsk_df"
15348 [(set (match_operand:SI 0 "register_operand" "=r")
15349 (unspec:SI
15350 [(match_operand:DF 1 "register_operand" "x")]
15351 UNSPEC_MOVMSK))]
15352 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15353 "%vmovmskpd\t{%1, %0|%0, %1}"
15354 [(set_attr "type" "ssemov")
15355 (set_attr "prefix" "maybe_vex")
15356 (set_attr "mode" "DF")])
15357
15358 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15359 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15360 (define_expand "signbitdf2"
15361 [(use (match_operand:SI 0 "register_operand" ""))
15362 (use (match_operand:DF 1 "register_operand" ""))]
15363 "TARGET_USE_FANCY_MATH_387
15364 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15365 {
15366 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15367 {
15368 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15369 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15370 }
15371 else
15372 {
15373 rtx scratch = gen_reg_rtx (HImode);
15374
15375 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15376 emit_insn (gen_andsi3 (operands[0],
15377 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15378 }
15379 DONE;
15380 })
15381
15382 (define_expand "signbitsf2"
15383 [(use (match_operand:SI 0 "register_operand" ""))
15384 (use (match_operand:SF 1 "register_operand" ""))]
15385 "TARGET_USE_FANCY_MATH_387
15386 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15387 {
15388 rtx scratch = gen_reg_rtx (HImode);
15389
15390 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15391 emit_insn (gen_andsi3 (operands[0],
15392 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15393 DONE;
15394 })
15395 \f
15396 ;; Block operation instructions
15397
15398 (define_insn "cld"
15399 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15400 ""
15401 "cld"
15402 [(set_attr "length" "1")
15403 (set_attr "length_immediate" "0")
15404 (set_attr "modrm" "0")])
15405
15406 (define_expand "movmem<mode>"
15407 [(use (match_operand:BLK 0 "memory_operand" ""))
15408 (use (match_operand:BLK 1 "memory_operand" ""))
15409 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15410 (use (match_operand:SWI48 3 "const_int_operand" ""))
15411 (use (match_operand:SI 4 "const_int_operand" ""))
15412 (use (match_operand:SI 5 "const_int_operand" ""))]
15413 ""
15414 {
15415 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15416 operands[4], operands[5]))
15417 DONE;
15418 else
15419 FAIL;
15420 })
15421
15422 ;; Most CPUs don't like single string operations
15423 ;; Handle this case here to simplify previous expander.
15424
15425 (define_expand "strmov"
15426 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15427 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15428 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15429 (clobber (reg:CC FLAGS_REG))])
15430 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15431 (clobber (reg:CC FLAGS_REG))])]
15432 ""
15433 {
15434 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15435
15436 /* If .md ever supports :P for Pmode, these can be directly
15437 in the pattern above. */
15438 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15439 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15440
15441 /* Can't use this if the user has appropriated esi or edi. */
15442 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15443 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15444 {
15445 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15446 operands[2], operands[3],
15447 operands[5], operands[6]));
15448 DONE;
15449 }
15450
15451 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15452 })
15453
15454 (define_expand "strmov_singleop"
15455 [(parallel [(set (match_operand 1 "memory_operand" "")
15456 (match_operand 3 "memory_operand" ""))
15457 (set (match_operand 0 "register_operand" "")
15458 (match_operand 4 "" ""))
15459 (set (match_operand 2 "register_operand" "")
15460 (match_operand 5 "" ""))])]
15461 ""
15462 "ix86_current_function_needs_cld = 1;")
15463
15464 (define_insn "*strmovdi_rex_1"
15465 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15466 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15467 (set (match_operand:DI 0 "register_operand" "=D")
15468 (plus:DI (match_dup 2)
15469 (const_int 8)))
15470 (set (match_operand:DI 1 "register_operand" "=S")
15471 (plus:DI (match_dup 3)
15472 (const_int 8)))]
15473 "TARGET_64BIT"
15474 "movsq"
15475 [(set_attr "type" "str")
15476 (set_attr "memory" "both")
15477 (set_attr "mode" "DI")])
15478
15479 (define_insn "*strmovsi_1"
15480 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15481 (mem:SI (match_operand:P 3 "register_operand" "1")))
15482 (set (match_operand:P 0 "register_operand" "=D")
15483 (plus:P (match_dup 2)
15484 (const_int 4)))
15485 (set (match_operand:P 1 "register_operand" "=S")
15486 (plus:P (match_dup 3)
15487 (const_int 4)))]
15488 ""
15489 "movs{l|d}"
15490 [(set_attr "type" "str")
15491 (set_attr "memory" "both")
15492 (set_attr "mode" "SI")])
15493
15494 (define_insn "*strmovhi_1"
15495 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15496 (mem:HI (match_operand:P 3 "register_operand" "1")))
15497 (set (match_operand:P 0 "register_operand" "=D")
15498 (plus:P (match_dup 2)
15499 (const_int 2)))
15500 (set (match_operand:P 1 "register_operand" "=S")
15501 (plus:P (match_dup 3)
15502 (const_int 2)))]
15503 ""
15504 "movsw"
15505 [(set_attr "type" "str")
15506 (set_attr "memory" "both")
15507 (set_attr "mode" "HI")])
15508
15509 (define_insn "*strmovqi_1"
15510 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15511 (mem:QI (match_operand:P 3 "register_operand" "1")))
15512 (set (match_operand:P 0 "register_operand" "=D")
15513 (plus:P (match_dup 2)
15514 (const_int 1)))
15515 (set (match_operand:P 1 "register_operand" "=S")
15516 (plus:P (match_dup 3)
15517 (const_int 1)))]
15518 ""
15519 "movsb"
15520 [(set_attr "type" "str")
15521 (set_attr "memory" "both")
15522 (set (attr "prefix_rex")
15523 (if_then_else
15524 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15525 (const_string "0")
15526 (const_string "*")))
15527 (set_attr "mode" "QI")])
15528
15529 (define_expand "rep_mov"
15530 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15531 (set (match_operand 0 "register_operand" "")
15532 (match_operand 5 "" ""))
15533 (set (match_operand 2 "register_operand" "")
15534 (match_operand 6 "" ""))
15535 (set (match_operand 1 "memory_operand" "")
15536 (match_operand 3 "memory_operand" ""))
15537 (use (match_dup 4))])]
15538 ""
15539 "ix86_current_function_needs_cld = 1;")
15540
15541 (define_insn "*rep_movdi_rex64"
15542 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15543 (set (match_operand:DI 0 "register_operand" "=D")
15544 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15545 (const_int 3))
15546 (match_operand:DI 3 "register_operand" "0")))
15547 (set (match_operand:DI 1 "register_operand" "=S")
15548 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15549 (match_operand:DI 4 "register_operand" "1")))
15550 (set (mem:BLK (match_dup 3))
15551 (mem:BLK (match_dup 4)))
15552 (use (match_dup 5))]
15553 "TARGET_64BIT"
15554 "rep{%;} movsq"
15555 [(set_attr "type" "str")
15556 (set_attr "prefix_rep" "1")
15557 (set_attr "memory" "both")
15558 (set_attr "mode" "DI")])
15559
15560 (define_insn "*rep_movsi"
15561 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15562 (set (match_operand:P 0 "register_operand" "=D")
15563 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15564 (const_int 2))
15565 (match_operand:P 3 "register_operand" "0")))
15566 (set (match_operand:P 1 "register_operand" "=S")
15567 (plus:P (ashift:P (match_dup 5) (const_int 2))
15568 (match_operand:P 4 "register_operand" "1")))
15569 (set (mem:BLK (match_dup 3))
15570 (mem:BLK (match_dup 4)))
15571 (use (match_dup 5))]
15572 ""
15573 "rep{%;} movs{l|d}"
15574 [(set_attr "type" "str")
15575 (set_attr "prefix_rep" "1")
15576 (set_attr "memory" "both")
15577 (set_attr "mode" "SI")])
15578
15579 (define_insn "*rep_movqi"
15580 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15581 (set (match_operand:P 0 "register_operand" "=D")
15582 (plus:P (match_operand:P 3 "register_operand" "0")
15583 (match_operand:P 5 "register_operand" "2")))
15584 (set (match_operand:P 1 "register_operand" "=S")
15585 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15586 (set (mem:BLK (match_dup 3))
15587 (mem:BLK (match_dup 4)))
15588 (use (match_dup 5))]
15589 ""
15590 "rep{%;} movsb"
15591 [(set_attr "type" "str")
15592 (set_attr "prefix_rep" "1")
15593 (set_attr "memory" "both")
15594 (set_attr "mode" "QI")])
15595
15596 (define_expand "setmem<mode>"
15597 [(use (match_operand:BLK 0 "memory_operand" ""))
15598 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15599 (use (match_operand:QI 2 "nonmemory_operand" ""))
15600 (use (match_operand 3 "const_int_operand" ""))
15601 (use (match_operand:SI 4 "const_int_operand" ""))
15602 (use (match_operand:SI 5 "const_int_operand" ""))]
15603 ""
15604 {
15605 if (ix86_expand_setmem (operands[0], operands[1],
15606 operands[2], operands[3],
15607 operands[4], operands[5]))
15608 DONE;
15609 else
15610 FAIL;
15611 })
15612
15613 ;; Most CPUs don't like single string operations
15614 ;; Handle this case here to simplify previous expander.
15615
15616 (define_expand "strset"
15617 [(set (match_operand 1 "memory_operand" "")
15618 (match_operand 2 "register_operand" ""))
15619 (parallel [(set (match_operand 0 "register_operand" "")
15620 (match_dup 3))
15621 (clobber (reg:CC FLAGS_REG))])]
15622 ""
15623 {
15624 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15625 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15626
15627 /* If .md ever supports :P for Pmode, this can be directly
15628 in the pattern above. */
15629 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15630 GEN_INT (GET_MODE_SIZE (GET_MODE
15631 (operands[2]))));
15632 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15633 {
15634 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15635 operands[3]));
15636 DONE;
15637 }
15638 })
15639
15640 (define_expand "strset_singleop"
15641 [(parallel [(set (match_operand 1 "memory_operand" "")
15642 (match_operand 2 "register_operand" ""))
15643 (set (match_operand 0 "register_operand" "")
15644 (match_operand 3 "" ""))])]
15645 ""
15646 "ix86_current_function_needs_cld = 1;")
15647
15648 (define_insn "*strsetdi_rex_1"
15649 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15650 (match_operand:DI 2 "register_operand" "a"))
15651 (set (match_operand:DI 0 "register_operand" "=D")
15652 (plus:DI (match_dup 1)
15653 (const_int 8)))]
15654 "TARGET_64BIT"
15655 "stosq"
15656 [(set_attr "type" "str")
15657 (set_attr "memory" "store")
15658 (set_attr "mode" "DI")])
15659
15660 (define_insn "*strsetsi_1"
15661 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15662 (match_operand:SI 2 "register_operand" "a"))
15663 (set (match_operand:P 0 "register_operand" "=D")
15664 (plus:P (match_dup 1)
15665 (const_int 4)))]
15666 ""
15667 "stos{l|d}"
15668 [(set_attr "type" "str")
15669 (set_attr "memory" "store")
15670 (set_attr "mode" "SI")])
15671
15672 (define_insn "*strsethi_1"
15673 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15674 (match_operand:HI 2 "register_operand" "a"))
15675 (set (match_operand:P 0 "register_operand" "=D")
15676 (plus:P (match_dup 1)
15677 (const_int 2)))]
15678 ""
15679 "stosw"
15680 [(set_attr "type" "str")
15681 (set_attr "memory" "store")
15682 (set_attr "mode" "HI")])
15683
15684 (define_insn "*strsetqi_1"
15685 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15686 (match_operand:QI 2 "register_operand" "a"))
15687 (set (match_operand:P 0 "register_operand" "=D")
15688 (plus:P (match_dup 1)
15689 (const_int 1)))]
15690 ""
15691 "stosb"
15692 [(set_attr "type" "str")
15693 (set_attr "memory" "store")
15694 (set (attr "prefix_rex")
15695 (if_then_else
15696 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15697 (const_string "0")
15698 (const_string "*")))
15699 (set_attr "mode" "QI")])
15700
15701 (define_expand "rep_stos"
15702 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15703 (set (match_operand 0 "register_operand" "")
15704 (match_operand 4 "" ""))
15705 (set (match_operand 2 "memory_operand" "") (const_int 0))
15706 (use (match_operand 3 "register_operand" ""))
15707 (use (match_dup 1))])]
15708 ""
15709 "ix86_current_function_needs_cld = 1;")
15710
15711 (define_insn "*rep_stosdi_rex64"
15712 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15713 (set (match_operand:DI 0 "register_operand" "=D")
15714 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15715 (const_int 3))
15716 (match_operand:DI 3 "register_operand" "0")))
15717 (set (mem:BLK (match_dup 3))
15718 (const_int 0))
15719 (use (match_operand:DI 2 "register_operand" "a"))
15720 (use (match_dup 4))]
15721 "TARGET_64BIT"
15722 "rep{%;} stosq"
15723 [(set_attr "type" "str")
15724 (set_attr "prefix_rep" "1")
15725 (set_attr "memory" "store")
15726 (set_attr "mode" "DI")])
15727
15728 (define_insn "*rep_stossi"
15729 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15730 (set (match_operand:P 0 "register_operand" "=D")
15731 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15732 (const_int 2))
15733 (match_operand:P 3 "register_operand" "0")))
15734 (set (mem:BLK (match_dup 3))
15735 (const_int 0))
15736 (use (match_operand:SI 2 "register_operand" "a"))
15737 (use (match_dup 4))]
15738 ""
15739 "rep{%;} stos{l|d}"
15740 [(set_attr "type" "str")
15741 (set_attr "prefix_rep" "1")
15742 (set_attr "memory" "store")
15743 (set_attr "mode" "SI")])
15744
15745 (define_insn "*rep_stosqi"
15746 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15747 (set (match_operand:P 0 "register_operand" "=D")
15748 (plus:P (match_operand:P 3 "register_operand" "0")
15749 (match_operand:P 4 "register_operand" "1")))
15750 (set (mem:BLK (match_dup 3))
15751 (const_int 0))
15752 (use (match_operand:QI 2 "register_operand" "a"))
15753 (use (match_dup 4))]
15754 ""
15755 "rep{%;} stosb"
15756 [(set_attr "type" "str")
15757 (set_attr "prefix_rep" "1")
15758 (set_attr "memory" "store")
15759 (set (attr "prefix_rex")
15760 (if_then_else
15761 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15762 (const_string "0")
15763 (const_string "*")))
15764 (set_attr "mode" "QI")])
15765
15766 (define_expand "cmpstrnsi"
15767 [(set (match_operand:SI 0 "register_operand" "")
15768 (compare:SI (match_operand:BLK 1 "general_operand" "")
15769 (match_operand:BLK 2 "general_operand" "")))
15770 (use (match_operand 3 "general_operand" ""))
15771 (use (match_operand 4 "immediate_operand" ""))]
15772 ""
15773 {
15774 rtx addr1, addr2, out, outlow, count, countreg, align;
15775
15776 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15777 FAIL;
15778
15779 /* Can't use this if the user has appropriated esi or edi. */
15780 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15781 FAIL;
15782
15783 out = operands[0];
15784 if (!REG_P (out))
15785 out = gen_reg_rtx (SImode);
15786
15787 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15788 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15789 if (addr1 != XEXP (operands[1], 0))
15790 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15791 if (addr2 != XEXP (operands[2], 0))
15792 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15793
15794 count = operands[3];
15795 countreg = ix86_zero_extend_to_Pmode (count);
15796
15797 /* %%% Iff we are testing strict equality, we can use known alignment
15798 to good advantage. This may be possible with combine, particularly
15799 once cc0 is dead. */
15800 align = operands[4];
15801
15802 if (CONST_INT_P (count))
15803 {
15804 if (INTVAL (count) == 0)
15805 {
15806 emit_move_insn (operands[0], const0_rtx);
15807 DONE;
15808 }
15809 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15810 operands[1], operands[2]));
15811 }
15812 else
15813 {
15814 rtx (*gen_cmp) (rtx, rtx);
15815
15816 gen_cmp = (TARGET_64BIT
15817 ? gen_cmpdi_1 : gen_cmpsi_1);
15818
15819 emit_insn (gen_cmp (countreg, countreg));
15820 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15821 operands[1], operands[2]));
15822 }
15823
15824 outlow = gen_lowpart (QImode, out);
15825 emit_insn (gen_cmpintqi (outlow));
15826 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15827
15828 if (operands[0] != out)
15829 emit_move_insn (operands[0], out);
15830
15831 DONE;
15832 })
15833
15834 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15835
15836 (define_expand "cmpintqi"
15837 [(set (match_dup 1)
15838 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15839 (set (match_dup 2)
15840 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15841 (parallel [(set (match_operand:QI 0 "register_operand" "")
15842 (minus:QI (match_dup 1)
15843 (match_dup 2)))
15844 (clobber (reg:CC FLAGS_REG))])]
15845 ""
15846 {
15847 operands[1] = gen_reg_rtx (QImode);
15848 operands[2] = gen_reg_rtx (QImode);
15849 })
15850
15851 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15852 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15853
15854 (define_expand "cmpstrnqi_nz_1"
15855 [(parallel [(set (reg:CC FLAGS_REG)
15856 (compare:CC (match_operand 4 "memory_operand" "")
15857 (match_operand 5 "memory_operand" "")))
15858 (use (match_operand 2 "register_operand" ""))
15859 (use (match_operand:SI 3 "immediate_operand" ""))
15860 (clobber (match_operand 0 "register_operand" ""))
15861 (clobber (match_operand 1 "register_operand" ""))
15862 (clobber (match_dup 2))])]
15863 ""
15864 "ix86_current_function_needs_cld = 1;")
15865
15866 (define_insn "*cmpstrnqi_nz_1"
15867 [(set (reg:CC FLAGS_REG)
15868 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15869 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15870 (use (match_operand:P 6 "register_operand" "2"))
15871 (use (match_operand:SI 3 "immediate_operand" "i"))
15872 (clobber (match_operand:P 0 "register_operand" "=S"))
15873 (clobber (match_operand:P 1 "register_operand" "=D"))
15874 (clobber (match_operand:P 2 "register_operand" "=c"))]
15875 ""
15876 "repz{%;} cmpsb"
15877 [(set_attr "type" "str")
15878 (set_attr "mode" "QI")
15879 (set (attr "prefix_rex")
15880 (if_then_else
15881 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15882 (const_string "0")
15883 (const_string "*")))
15884 (set_attr "prefix_rep" "1")])
15885
15886 ;; The same, but the count is not known to not be zero.
15887
15888 (define_expand "cmpstrnqi_1"
15889 [(parallel [(set (reg:CC FLAGS_REG)
15890 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15891 (const_int 0))
15892 (compare:CC (match_operand 4 "memory_operand" "")
15893 (match_operand 5 "memory_operand" ""))
15894 (const_int 0)))
15895 (use (match_operand:SI 3 "immediate_operand" ""))
15896 (use (reg:CC FLAGS_REG))
15897 (clobber (match_operand 0 "register_operand" ""))
15898 (clobber (match_operand 1 "register_operand" ""))
15899 (clobber (match_dup 2))])]
15900 ""
15901 "ix86_current_function_needs_cld = 1;")
15902
15903 (define_insn "*cmpstrnqi_1"
15904 [(set (reg:CC FLAGS_REG)
15905 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15906 (const_int 0))
15907 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15908 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15909 (const_int 0)))
15910 (use (match_operand:SI 3 "immediate_operand" "i"))
15911 (use (reg:CC FLAGS_REG))
15912 (clobber (match_operand:P 0 "register_operand" "=S"))
15913 (clobber (match_operand:P 1 "register_operand" "=D"))
15914 (clobber (match_operand:P 2 "register_operand" "=c"))]
15915 ""
15916 "repz{%;} cmpsb"
15917 [(set_attr "type" "str")
15918 (set_attr "mode" "QI")
15919 (set (attr "prefix_rex")
15920 (if_then_else
15921 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15922 (const_string "0")
15923 (const_string "*")))
15924 (set_attr "prefix_rep" "1")])
15925
15926 (define_expand "strlen<mode>"
15927 [(set (match_operand:SWI48x 0 "register_operand" "")
15928 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15929 (match_operand:QI 2 "immediate_operand" "")
15930 (match_operand 3 "immediate_operand" "")]
15931 UNSPEC_SCAS))]
15932 ""
15933 {
15934 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15935 DONE;
15936 else
15937 FAIL;
15938 })
15939
15940 (define_expand "strlenqi_1"
15941 [(parallel [(set (match_operand 0 "register_operand" "")
15942 (match_operand 2 "" ""))
15943 (clobber (match_operand 1 "register_operand" ""))
15944 (clobber (reg:CC FLAGS_REG))])]
15945 ""
15946 "ix86_current_function_needs_cld = 1;")
15947
15948 (define_insn "*strlenqi_1"
15949 [(set (match_operand:P 0 "register_operand" "=&c")
15950 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15951 (match_operand:QI 2 "register_operand" "a")
15952 (match_operand:P 3 "immediate_operand" "i")
15953 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15954 (clobber (match_operand:P 1 "register_operand" "=D"))
15955 (clobber (reg:CC FLAGS_REG))]
15956 ""
15957 "repnz{%;} scasb"
15958 [(set_attr "type" "str")
15959 (set_attr "mode" "QI")
15960 (set (attr "prefix_rex")
15961 (if_then_else
15962 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15963 (const_string "0")
15964 (const_string "*")))
15965 (set_attr "prefix_rep" "1")])
15966
15967 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15968 ;; handled in combine, but it is not currently up to the task.
15969 ;; When used for their truth value, the cmpstrn* expanders generate
15970 ;; code like this:
15971 ;;
15972 ;; repz cmpsb
15973 ;; seta %al
15974 ;; setb %dl
15975 ;; cmpb %al, %dl
15976 ;; jcc label
15977 ;;
15978 ;; The intermediate three instructions are unnecessary.
15979
15980 ;; This one handles cmpstrn*_nz_1...
15981 (define_peephole2
15982 [(parallel[
15983 (set (reg:CC FLAGS_REG)
15984 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15985 (mem:BLK (match_operand 5 "register_operand" ""))))
15986 (use (match_operand 6 "register_operand" ""))
15987 (use (match_operand:SI 3 "immediate_operand" ""))
15988 (clobber (match_operand 0 "register_operand" ""))
15989 (clobber (match_operand 1 "register_operand" ""))
15990 (clobber (match_operand 2 "register_operand" ""))])
15991 (set (match_operand:QI 7 "register_operand" "")
15992 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15993 (set (match_operand:QI 8 "register_operand" "")
15994 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15995 (set (reg FLAGS_REG)
15996 (compare (match_dup 7) (match_dup 8)))
15997 ]
15998 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15999 [(parallel[
16000 (set (reg:CC FLAGS_REG)
16001 (compare:CC (mem:BLK (match_dup 4))
16002 (mem:BLK (match_dup 5))))
16003 (use (match_dup 6))
16004 (use (match_dup 3))
16005 (clobber (match_dup 0))
16006 (clobber (match_dup 1))
16007 (clobber (match_dup 2))])])
16008
16009 ;; ...and this one handles cmpstrn*_1.
16010 (define_peephole2
16011 [(parallel[
16012 (set (reg:CC FLAGS_REG)
16013 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16014 (const_int 0))
16015 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16016 (mem:BLK (match_operand 5 "register_operand" "")))
16017 (const_int 0)))
16018 (use (match_operand:SI 3 "immediate_operand" ""))
16019 (use (reg:CC FLAGS_REG))
16020 (clobber (match_operand 0 "register_operand" ""))
16021 (clobber (match_operand 1 "register_operand" ""))
16022 (clobber (match_operand 2 "register_operand" ""))])
16023 (set (match_operand:QI 7 "register_operand" "")
16024 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16025 (set (match_operand:QI 8 "register_operand" "")
16026 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16027 (set (reg FLAGS_REG)
16028 (compare (match_dup 7) (match_dup 8)))
16029 ]
16030 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16031 [(parallel[
16032 (set (reg:CC FLAGS_REG)
16033 (if_then_else:CC (ne (match_dup 6)
16034 (const_int 0))
16035 (compare:CC (mem:BLK (match_dup 4))
16036 (mem:BLK (match_dup 5)))
16037 (const_int 0)))
16038 (use (match_dup 3))
16039 (use (reg:CC FLAGS_REG))
16040 (clobber (match_dup 0))
16041 (clobber (match_dup 1))
16042 (clobber (match_dup 2))])])
16043 \f
16044 ;; Conditional move instructions.
16045
16046 (define_expand "mov<mode>cc"
16047 [(set (match_operand:SWIM 0 "register_operand" "")
16048 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16049 (match_operand:SWIM 2 "general_operand" "")
16050 (match_operand:SWIM 3 "general_operand" "")))]
16051 ""
16052 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16053
16054 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16055 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16056 ;; So just document what we're doing explicitly.
16057
16058 (define_expand "x86_mov<mode>cc_0_m1"
16059 [(parallel
16060 [(set (match_operand:SWI48 0 "register_operand" "")
16061 (if_then_else:SWI48
16062 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16063 [(match_operand 1 "flags_reg_operand" "")
16064 (const_int 0)])
16065 (const_int -1)
16066 (const_int 0)))
16067 (clobber (reg:CC FLAGS_REG))])])
16068
16069 (define_insn "*x86_mov<mode>cc_0_m1"
16070 [(set (match_operand:SWI48 0 "register_operand" "=r")
16071 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16072 [(reg FLAGS_REG) (const_int 0)])
16073 (const_int -1)
16074 (const_int 0)))
16075 (clobber (reg:CC FLAGS_REG))]
16076 ""
16077 "sbb{<imodesuffix>}\t%0, %0"
16078 ; Since we don't have the proper number of operands for an alu insn,
16079 ; fill in all the blanks.
16080 [(set_attr "type" "alu")
16081 (set_attr "use_carry" "1")
16082 (set_attr "pent_pair" "pu")
16083 (set_attr "memory" "none")
16084 (set_attr "imm_disp" "false")
16085 (set_attr "mode" "<MODE>")
16086 (set_attr "length_immediate" "0")])
16087
16088 (define_insn "*x86_mov<mode>cc_0_m1_se"
16089 [(set (match_operand:SWI48 0 "register_operand" "=r")
16090 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16091 [(reg FLAGS_REG) (const_int 0)])
16092 (const_int 1)
16093 (const_int 0)))
16094 (clobber (reg:CC FLAGS_REG))]
16095 ""
16096 "sbb{<imodesuffix>}\t%0, %0"
16097 [(set_attr "type" "alu")
16098 (set_attr "use_carry" "1")
16099 (set_attr "pent_pair" "pu")
16100 (set_attr "memory" "none")
16101 (set_attr "imm_disp" "false")
16102 (set_attr "mode" "<MODE>")
16103 (set_attr "length_immediate" "0")])
16104
16105 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16106 [(set (match_operand:SWI48 0 "register_operand" "=r")
16107 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16108 [(reg FLAGS_REG) (const_int 0)])))]
16109 ""
16110 "sbb{<imodesuffix>}\t%0, %0"
16111 [(set_attr "type" "alu")
16112 (set_attr "use_carry" "1")
16113 (set_attr "pent_pair" "pu")
16114 (set_attr "memory" "none")
16115 (set_attr "imm_disp" "false")
16116 (set_attr "mode" "<MODE>")
16117 (set_attr "length_immediate" "0")])
16118
16119 (define_insn "*mov<mode>cc_noc"
16120 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16121 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16122 [(reg FLAGS_REG) (const_int 0)])
16123 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16124 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16125 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16126 "@
16127 cmov%O2%C1\t{%2, %0|%0, %2}
16128 cmov%O2%c1\t{%3, %0|%0, %3}"
16129 [(set_attr "type" "icmov")
16130 (set_attr "mode" "<MODE>")])
16131
16132 (define_insn_and_split "*movqicc_noc"
16133 [(set (match_operand:QI 0 "register_operand" "=r,r")
16134 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16135 [(match_operand 4 "flags_reg_operand" "")
16136 (const_int 0)])
16137 (match_operand:QI 2 "register_operand" "r,0")
16138 (match_operand:QI 3 "register_operand" "0,r")))]
16139 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16140 "#"
16141 "&& reload_completed"
16142 [(set (match_dup 0)
16143 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16144 (match_dup 2)
16145 (match_dup 3)))]
16146 "operands[0] = gen_lowpart (SImode, operands[0]);
16147 operands[2] = gen_lowpart (SImode, operands[2]);
16148 operands[3] = gen_lowpart (SImode, operands[3]);"
16149 [(set_attr "type" "icmov")
16150 (set_attr "mode" "SI")])
16151
16152 (define_expand "mov<mode>cc"
16153 [(set (match_operand:X87MODEF 0 "register_operand" "")
16154 (if_then_else:X87MODEF
16155 (match_operand 1 "ix86_fp_comparison_operator" "")
16156 (match_operand:X87MODEF 2 "register_operand" "")
16157 (match_operand:X87MODEF 3 "register_operand" "")))]
16158 "(TARGET_80387 && TARGET_CMOVE)
16159 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16160 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16161
16162 (define_insn "*movxfcc_1"
16163 [(set (match_operand:XF 0 "register_operand" "=f,f")
16164 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16165 [(reg FLAGS_REG) (const_int 0)])
16166 (match_operand:XF 2 "register_operand" "f,0")
16167 (match_operand:XF 3 "register_operand" "0,f")))]
16168 "TARGET_80387 && TARGET_CMOVE"
16169 "@
16170 fcmov%F1\t{%2, %0|%0, %2}
16171 fcmov%f1\t{%3, %0|%0, %3}"
16172 [(set_attr "type" "fcmov")
16173 (set_attr "mode" "XF")])
16174
16175 (define_insn "*movdfcc_1_rex64"
16176 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16177 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16178 [(reg FLAGS_REG) (const_int 0)])
16179 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16180 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16181 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16182 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16183 "@
16184 fcmov%F1\t{%2, %0|%0, %2}
16185 fcmov%f1\t{%3, %0|%0, %3}
16186 cmov%O2%C1\t{%2, %0|%0, %2}
16187 cmov%O2%c1\t{%3, %0|%0, %3}"
16188 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16189 (set_attr "mode" "DF,DF,DI,DI")])
16190
16191 (define_insn "*movdfcc_1"
16192 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16193 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16194 [(reg FLAGS_REG) (const_int 0)])
16195 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16196 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16197 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16198 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16199 "@
16200 fcmov%F1\t{%2, %0|%0, %2}
16201 fcmov%f1\t{%3, %0|%0, %3}
16202 #
16203 #"
16204 [(set_attr "type" "fcmov,fcmov,multi,multi")
16205 (set_attr "mode" "DF,DF,DI,DI")])
16206
16207 (define_split
16208 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16209 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16210 [(match_operand 4 "flags_reg_operand" "")
16211 (const_int 0)])
16212 (match_operand:DF 2 "nonimmediate_operand" "")
16213 (match_operand:DF 3 "nonimmediate_operand" "")))]
16214 "!TARGET_64BIT && reload_completed"
16215 [(set (match_dup 2)
16216 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16217 (match_dup 5)
16218 (match_dup 6)))
16219 (set (match_dup 3)
16220 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16221 (match_dup 7)
16222 (match_dup 8)))]
16223 {
16224 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16225 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16226 })
16227
16228 (define_insn "*movsfcc_1_387"
16229 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16230 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16231 [(reg FLAGS_REG) (const_int 0)])
16232 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16233 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16234 "TARGET_80387 && TARGET_CMOVE
16235 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16236 "@
16237 fcmov%F1\t{%2, %0|%0, %2}
16238 fcmov%f1\t{%3, %0|%0, %3}
16239 cmov%O2%C1\t{%2, %0|%0, %2}
16240 cmov%O2%c1\t{%3, %0|%0, %3}"
16241 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16242 (set_attr "mode" "SF,SF,SI,SI")])
16243
16244 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16245 ;; the scalar versions to have only XMM registers as operands.
16246
16247 ;; XOP conditional move
16248 (define_insn "*xop_pcmov_<mode>"
16249 [(set (match_operand:MODEF 0 "register_operand" "=x")
16250 (if_then_else:MODEF
16251 (match_operand:MODEF 1 "register_operand" "x")
16252 (match_operand:MODEF 2 "register_operand" "x")
16253 (match_operand:MODEF 3 "register_operand" "x")))]
16254 "TARGET_XOP"
16255 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16256 [(set_attr "type" "sse4arg")])
16257
16258 ;; These versions of the min/max patterns are intentionally ignorant of
16259 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16260 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16261 ;; are undefined in this condition, we're certain this is correct.
16262
16263 (define_insn "<code><mode>3"
16264 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16265 (smaxmin:MODEF
16266 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16267 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16268 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16269 "@
16270 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16271 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16272 [(set_attr "isa" "noavx,avx")
16273 (set_attr "prefix" "orig,vex")
16274 (set_attr "type" "sseadd")
16275 (set_attr "mode" "<MODE>")])
16276
16277 ;; These versions of the min/max patterns implement exactly the operations
16278 ;; min = (op1 < op2 ? op1 : op2)
16279 ;; max = (!(op1 < op2) ? op1 : op2)
16280 ;; Their operands are not commutative, and thus they may be used in the
16281 ;; presence of -0.0 and NaN.
16282
16283 (define_insn "*ieee_smin<mode>3"
16284 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16285 (unspec:MODEF
16286 [(match_operand:MODEF 1 "register_operand" "0,x")
16287 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16288 UNSPEC_IEEE_MIN))]
16289 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16290 "@
16291 min<ssemodesuffix>\t{%2, %0|%0, %2}
16292 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16293 [(set_attr "isa" "noavx,avx")
16294 (set_attr "prefix" "orig,vex")
16295 (set_attr "type" "sseadd")
16296 (set_attr "mode" "<MODE>")])
16297
16298 (define_insn "*ieee_smax<mode>3"
16299 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16300 (unspec:MODEF
16301 [(match_operand:MODEF 1 "register_operand" "0,x")
16302 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16303 UNSPEC_IEEE_MAX))]
16304 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16305 "@
16306 max<ssemodesuffix>\t{%2, %0|%0, %2}
16307 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16308 [(set_attr "isa" "noavx,avx")
16309 (set_attr "prefix" "orig,vex")
16310 (set_attr "type" "sseadd")
16311 (set_attr "mode" "<MODE>")])
16312
16313 ;; Make two stack loads independent:
16314 ;; fld aa fld aa
16315 ;; fld %st(0) -> fld bb
16316 ;; fmul bb fmul %st(1), %st
16317 ;;
16318 ;; Actually we only match the last two instructions for simplicity.
16319 (define_peephole2
16320 [(set (match_operand 0 "fp_register_operand" "")
16321 (match_operand 1 "fp_register_operand" ""))
16322 (set (match_dup 0)
16323 (match_operator 2 "binary_fp_operator"
16324 [(match_dup 0)
16325 (match_operand 3 "memory_operand" "")]))]
16326 "REGNO (operands[0]) != REGNO (operands[1])"
16327 [(set (match_dup 0) (match_dup 3))
16328 (set (match_dup 0) (match_dup 4))]
16329
16330 ;; The % modifier is not operational anymore in peephole2's, so we have to
16331 ;; swap the operands manually in the case of addition and multiplication.
16332 "if (COMMUTATIVE_ARITH_P (operands[2]))
16333 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16334 GET_MODE (operands[2]),
16335 operands[0], operands[1]);
16336 else
16337 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16338 GET_MODE (operands[2]),
16339 operands[1], operands[0]);")
16340
16341 ;; Conditional addition patterns
16342 (define_expand "add<mode>cc"
16343 [(match_operand:SWI 0 "register_operand" "")
16344 (match_operand 1 "ordered_comparison_operator" "")
16345 (match_operand:SWI 2 "register_operand" "")
16346 (match_operand:SWI 3 "const_int_operand" "")]
16347 ""
16348 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16349 \f
16350 ;; Misc patterns (?)
16351
16352 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16353 ;; Otherwise there will be nothing to keep
16354 ;;
16355 ;; [(set (reg ebp) (reg esp))]
16356 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16357 ;; (clobber (eflags)]
16358 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16359 ;;
16360 ;; in proper program order.
16361
16362 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16363 [(set (match_operand:P 0 "register_operand" "=r,r")
16364 (plus:P (match_operand:P 1 "register_operand" "0,r")
16365 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16366 (clobber (reg:CC FLAGS_REG))
16367 (clobber (mem:BLK (scratch)))]
16368 ""
16369 {
16370 switch (get_attr_type (insn))
16371 {
16372 case TYPE_IMOV:
16373 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16374
16375 case TYPE_ALU:
16376 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16377 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16378 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16379
16380 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16381
16382 default:
16383 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16384 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16385 }
16386 }
16387 [(set (attr "type")
16388 (cond [(and (eq_attr "alternative" "0")
16389 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16390 (const_string "alu")
16391 (match_operand:<MODE> 2 "const0_operand" "")
16392 (const_string "imov")
16393 ]
16394 (const_string "lea")))
16395 (set (attr "length_immediate")
16396 (cond [(eq_attr "type" "imov")
16397 (const_string "0")
16398 (and (eq_attr "type" "alu")
16399 (match_operand 2 "const128_operand" ""))
16400 (const_string "1")
16401 ]
16402 (const_string "*")))
16403 (set_attr "mode" "<MODE>")])
16404
16405 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16406 [(set (match_operand:P 0 "register_operand" "=r")
16407 (minus:P (match_operand:P 1 "register_operand" "0")
16408 (match_operand:P 2 "register_operand" "r")))
16409 (clobber (reg:CC FLAGS_REG))
16410 (clobber (mem:BLK (scratch)))]
16411 ""
16412 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16413 [(set_attr "type" "alu")
16414 (set_attr "mode" "<MODE>")])
16415
16416 (define_insn "allocate_stack_worker_probe_<mode>"
16417 [(set (match_operand:P 0 "register_operand" "=a")
16418 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16419 UNSPECV_STACK_PROBE))
16420 (clobber (reg:CC FLAGS_REG))]
16421 "ix86_target_stack_probe ()"
16422 "call\t___chkstk_ms"
16423 [(set_attr "type" "multi")
16424 (set_attr "length" "5")])
16425
16426 (define_expand "allocate_stack"
16427 [(match_operand 0 "register_operand" "")
16428 (match_operand 1 "general_operand" "")]
16429 "ix86_target_stack_probe ()"
16430 {
16431 rtx x;
16432
16433 #ifndef CHECK_STACK_LIMIT
16434 #define CHECK_STACK_LIMIT 0
16435 #endif
16436
16437 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16438 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16439 {
16440 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16441 stack_pointer_rtx, 0, OPTAB_DIRECT);
16442 if (x != stack_pointer_rtx)
16443 emit_move_insn (stack_pointer_rtx, x);
16444 }
16445 else
16446 {
16447 x = copy_to_mode_reg (Pmode, operands[1]);
16448 if (TARGET_64BIT)
16449 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16450 else
16451 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16452 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16453 stack_pointer_rtx, 0, OPTAB_DIRECT);
16454 if (x != stack_pointer_rtx)
16455 emit_move_insn (stack_pointer_rtx, x);
16456 }
16457
16458 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16459 DONE;
16460 })
16461
16462 ;; Use IOR for stack probes, this is shorter.
16463 (define_expand "probe_stack"
16464 [(match_operand 0 "memory_operand" "")]
16465 ""
16466 {
16467 rtx (*gen_ior3) (rtx, rtx, rtx);
16468
16469 gen_ior3 = (GET_MODE (operands[0]) == DImode
16470 ? gen_iordi3 : gen_iorsi3);
16471
16472 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16473 DONE;
16474 })
16475
16476 (define_insn "adjust_stack_and_probe<mode>"
16477 [(set (match_operand:P 0 "register_operand" "=r")
16478 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16479 UNSPECV_PROBE_STACK_RANGE))
16480 (set (reg:P SP_REG)
16481 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16482 (clobber (reg:CC FLAGS_REG))
16483 (clobber (mem:BLK (scratch)))]
16484 ""
16485 "* return output_adjust_stack_and_probe (operands[0]);"
16486 [(set_attr "type" "multi")])
16487
16488 (define_insn "probe_stack_range<mode>"
16489 [(set (match_operand:P 0 "register_operand" "=r")
16490 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16491 (match_operand:P 2 "const_int_operand" "n")]
16492 UNSPECV_PROBE_STACK_RANGE))
16493 (clobber (reg:CC FLAGS_REG))]
16494 ""
16495 "* return output_probe_stack_range (operands[0], operands[2]);"
16496 [(set_attr "type" "multi")])
16497
16498 (define_expand "builtin_setjmp_receiver"
16499 [(label_ref (match_operand 0 "" ""))]
16500 "!TARGET_64BIT && flag_pic"
16501 {
16502 #if TARGET_MACHO
16503 if (TARGET_MACHO)
16504 {
16505 rtx xops[3];
16506 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16507 rtx label_rtx = gen_label_rtx ();
16508 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16509 xops[0] = xops[1] = picreg;
16510 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16511 ix86_expand_binary_operator (MINUS, SImode, xops);
16512 }
16513 else
16514 #endif
16515 emit_insn (gen_set_got (pic_offset_table_rtx));
16516 DONE;
16517 })
16518 \f
16519 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16520
16521 (define_split
16522 [(set (match_operand 0 "register_operand" "")
16523 (match_operator 3 "promotable_binary_operator"
16524 [(match_operand 1 "register_operand" "")
16525 (match_operand 2 "aligned_operand" "")]))
16526 (clobber (reg:CC FLAGS_REG))]
16527 "! TARGET_PARTIAL_REG_STALL && reload_completed
16528 && ((GET_MODE (operands[0]) == HImode
16529 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16530 /* ??? next two lines just !satisfies_constraint_K (...) */
16531 || !CONST_INT_P (operands[2])
16532 || satisfies_constraint_K (operands[2])))
16533 || (GET_MODE (operands[0]) == QImode
16534 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16535 [(parallel [(set (match_dup 0)
16536 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16537 (clobber (reg:CC FLAGS_REG))])]
16538 "operands[0] = gen_lowpart (SImode, operands[0]);
16539 operands[1] = gen_lowpart (SImode, operands[1]);
16540 if (GET_CODE (operands[3]) != ASHIFT)
16541 operands[2] = gen_lowpart (SImode, operands[2]);
16542 PUT_MODE (operands[3], SImode);")
16543
16544 ; Promote the QImode tests, as i386 has encoding of the AND
16545 ; instruction with 32-bit sign-extended immediate and thus the
16546 ; instruction size is unchanged, except in the %eax case for
16547 ; which it is increased by one byte, hence the ! optimize_size.
16548 (define_split
16549 [(set (match_operand 0 "flags_reg_operand" "")
16550 (match_operator 2 "compare_operator"
16551 [(and (match_operand 3 "aligned_operand" "")
16552 (match_operand 4 "const_int_operand" ""))
16553 (const_int 0)]))
16554 (set (match_operand 1 "register_operand" "")
16555 (and (match_dup 3) (match_dup 4)))]
16556 "! TARGET_PARTIAL_REG_STALL && reload_completed
16557 && optimize_insn_for_speed_p ()
16558 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16559 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16560 /* Ensure that the operand will remain sign-extended immediate. */
16561 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16562 [(parallel [(set (match_dup 0)
16563 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16564 (const_int 0)]))
16565 (set (match_dup 1)
16566 (and:SI (match_dup 3) (match_dup 4)))])]
16567 {
16568 operands[4]
16569 = gen_int_mode (INTVAL (operands[4])
16570 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16571 operands[1] = gen_lowpart (SImode, operands[1]);
16572 operands[3] = gen_lowpart (SImode, operands[3]);
16573 })
16574
16575 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16576 ; the TEST instruction with 32-bit sign-extended immediate and thus
16577 ; the instruction size would at least double, which is not what we
16578 ; want even with ! optimize_size.
16579 (define_split
16580 [(set (match_operand 0 "flags_reg_operand" "")
16581 (match_operator 1 "compare_operator"
16582 [(and (match_operand:HI 2 "aligned_operand" "")
16583 (match_operand:HI 3 "const_int_operand" ""))
16584 (const_int 0)]))]
16585 "! TARGET_PARTIAL_REG_STALL && reload_completed
16586 && ! TARGET_FAST_PREFIX
16587 && optimize_insn_for_speed_p ()
16588 /* Ensure that the operand will remain sign-extended immediate. */
16589 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16590 [(set (match_dup 0)
16591 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16592 (const_int 0)]))]
16593 {
16594 operands[3]
16595 = gen_int_mode (INTVAL (operands[3])
16596 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16597 operands[2] = gen_lowpart (SImode, operands[2]);
16598 })
16599
16600 (define_split
16601 [(set (match_operand 0 "register_operand" "")
16602 (neg (match_operand 1 "register_operand" "")))
16603 (clobber (reg:CC FLAGS_REG))]
16604 "! TARGET_PARTIAL_REG_STALL && reload_completed
16605 && (GET_MODE (operands[0]) == HImode
16606 || (GET_MODE (operands[0]) == QImode
16607 && (TARGET_PROMOTE_QImode
16608 || optimize_insn_for_size_p ())))"
16609 [(parallel [(set (match_dup 0)
16610 (neg:SI (match_dup 1)))
16611 (clobber (reg:CC FLAGS_REG))])]
16612 "operands[0] = gen_lowpart (SImode, operands[0]);
16613 operands[1] = gen_lowpart (SImode, operands[1]);")
16614
16615 (define_split
16616 [(set (match_operand 0 "register_operand" "")
16617 (not (match_operand 1 "register_operand" "")))]
16618 "! TARGET_PARTIAL_REG_STALL && reload_completed
16619 && (GET_MODE (operands[0]) == HImode
16620 || (GET_MODE (operands[0]) == QImode
16621 && (TARGET_PROMOTE_QImode
16622 || optimize_insn_for_size_p ())))"
16623 [(set (match_dup 0)
16624 (not:SI (match_dup 1)))]
16625 "operands[0] = gen_lowpart (SImode, operands[0]);
16626 operands[1] = gen_lowpart (SImode, operands[1]);")
16627
16628 (define_split
16629 [(set (match_operand 0 "register_operand" "")
16630 (if_then_else (match_operator 1 "ordered_comparison_operator"
16631 [(reg FLAGS_REG) (const_int 0)])
16632 (match_operand 2 "register_operand" "")
16633 (match_operand 3 "register_operand" "")))]
16634 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16635 && (GET_MODE (operands[0]) == HImode
16636 || (GET_MODE (operands[0]) == QImode
16637 && (TARGET_PROMOTE_QImode
16638 || optimize_insn_for_size_p ())))"
16639 [(set (match_dup 0)
16640 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16641 "operands[0] = gen_lowpart (SImode, operands[0]);
16642 operands[2] = gen_lowpart (SImode, operands[2]);
16643 operands[3] = gen_lowpart (SImode, operands[3]);")
16644 \f
16645 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16646 ;; transform a complex memory operation into two memory to register operations.
16647
16648 ;; Don't push memory operands
16649 (define_peephole2
16650 [(set (match_operand:SWI 0 "push_operand" "")
16651 (match_operand:SWI 1 "memory_operand" ""))
16652 (match_scratch:SWI 2 "<r>")]
16653 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16654 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16655 [(set (match_dup 2) (match_dup 1))
16656 (set (match_dup 0) (match_dup 2))])
16657
16658 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16659 ;; SImode pushes.
16660 (define_peephole2
16661 [(set (match_operand:SF 0 "push_operand" "")
16662 (match_operand:SF 1 "memory_operand" ""))
16663 (match_scratch:SF 2 "r")]
16664 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16665 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16666 [(set (match_dup 2) (match_dup 1))
16667 (set (match_dup 0) (match_dup 2))])
16668
16669 ;; Don't move an immediate directly to memory when the instruction
16670 ;; gets too big.
16671 (define_peephole2
16672 [(match_scratch:SWI124 1 "<r>")
16673 (set (match_operand:SWI124 0 "memory_operand" "")
16674 (const_int 0))]
16675 "optimize_insn_for_speed_p ()
16676 && !TARGET_USE_MOV0
16677 && TARGET_SPLIT_LONG_MOVES
16678 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16679 && peep2_regno_dead_p (0, FLAGS_REG)"
16680 [(parallel [(set (match_dup 2) (const_int 0))
16681 (clobber (reg:CC FLAGS_REG))])
16682 (set (match_dup 0) (match_dup 1))]
16683 "operands[2] = gen_lowpart (SImode, operands[1]);")
16684
16685 (define_peephole2
16686 [(match_scratch:SWI124 2 "<r>")
16687 (set (match_operand:SWI124 0 "memory_operand" "")
16688 (match_operand:SWI124 1 "immediate_operand" ""))]
16689 "optimize_insn_for_speed_p ()
16690 && TARGET_SPLIT_LONG_MOVES
16691 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16692 [(set (match_dup 2) (match_dup 1))
16693 (set (match_dup 0) (match_dup 2))])
16694
16695 ;; Don't compare memory with zero, load and use a test instead.
16696 (define_peephole2
16697 [(set (match_operand 0 "flags_reg_operand" "")
16698 (match_operator 1 "compare_operator"
16699 [(match_operand:SI 2 "memory_operand" "")
16700 (const_int 0)]))
16701 (match_scratch:SI 3 "r")]
16702 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16703 [(set (match_dup 3) (match_dup 2))
16704 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16705
16706 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16707 ;; Don't split NOTs with a displacement operand, because resulting XOR
16708 ;; will not be pairable anyway.
16709 ;;
16710 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16711 ;; represented using a modRM byte. The XOR replacement is long decoded,
16712 ;; so this split helps here as well.
16713 ;;
16714 ;; Note: Can't do this as a regular split because we can't get proper
16715 ;; lifetime information then.
16716
16717 (define_peephole2
16718 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16719 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16720 "optimize_insn_for_speed_p ()
16721 && ((TARGET_NOT_UNPAIRABLE
16722 && (!MEM_P (operands[0])
16723 || !memory_displacement_operand (operands[0], <MODE>mode)))
16724 || (TARGET_NOT_VECTORMODE
16725 && long_memory_operand (operands[0], <MODE>mode)))
16726 && peep2_regno_dead_p (0, FLAGS_REG)"
16727 [(parallel [(set (match_dup 0)
16728 (xor:SWI124 (match_dup 1) (const_int -1)))
16729 (clobber (reg:CC FLAGS_REG))])])
16730
16731 ;; Non pairable "test imm, reg" instructions can be translated to
16732 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16733 ;; byte opcode instead of two, have a short form for byte operands),
16734 ;; so do it for other CPUs as well. Given that the value was dead,
16735 ;; this should not create any new dependencies. Pass on the sub-word
16736 ;; versions if we're concerned about partial register stalls.
16737
16738 (define_peephole2
16739 [(set (match_operand 0 "flags_reg_operand" "")
16740 (match_operator 1 "compare_operator"
16741 [(and:SI (match_operand:SI 2 "register_operand" "")
16742 (match_operand:SI 3 "immediate_operand" ""))
16743 (const_int 0)]))]
16744 "ix86_match_ccmode (insn, CCNOmode)
16745 && (true_regnum (operands[2]) != AX_REG
16746 || satisfies_constraint_K (operands[3]))
16747 && peep2_reg_dead_p (1, operands[2])"
16748 [(parallel
16749 [(set (match_dup 0)
16750 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16751 (const_int 0)]))
16752 (set (match_dup 2)
16753 (and:SI (match_dup 2) (match_dup 3)))])])
16754
16755 ;; We don't need to handle HImode case, because it will be promoted to SImode
16756 ;; on ! TARGET_PARTIAL_REG_STALL
16757
16758 (define_peephole2
16759 [(set (match_operand 0 "flags_reg_operand" "")
16760 (match_operator 1 "compare_operator"
16761 [(and:QI (match_operand:QI 2 "register_operand" "")
16762 (match_operand:QI 3 "immediate_operand" ""))
16763 (const_int 0)]))]
16764 "! TARGET_PARTIAL_REG_STALL
16765 && ix86_match_ccmode (insn, CCNOmode)
16766 && true_regnum (operands[2]) != AX_REG
16767 && peep2_reg_dead_p (1, operands[2])"
16768 [(parallel
16769 [(set (match_dup 0)
16770 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16771 (const_int 0)]))
16772 (set (match_dup 2)
16773 (and:QI (match_dup 2) (match_dup 3)))])])
16774
16775 (define_peephole2
16776 [(set (match_operand 0 "flags_reg_operand" "")
16777 (match_operator 1 "compare_operator"
16778 [(and:SI
16779 (zero_extract:SI
16780 (match_operand 2 "ext_register_operand" "")
16781 (const_int 8)
16782 (const_int 8))
16783 (match_operand 3 "const_int_operand" ""))
16784 (const_int 0)]))]
16785 "! TARGET_PARTIAL_REG_STALL
16786 && ix86_match_ccmode (insn, CCNOmode)
16787 && true_regnum (operands[2]) != AX_REG
16788 && peep2_reg_dead_p (1, operands[2])"
16789 [(parallel [(set (match_dup 0)
16790 (match_op_dup 1
16791 [(and:SI
16792 (zero_extract:SI
16793 (match_dup 2)
16794 (const_int 8)
16795 (const_int 8))
16796 (match_dup 3))
16797 (const_int 0)]))
16798 (set (zero_extract:SI (match_dup 2)
16799 (const_int 8)
16800 (const_int 8))
16801 (and:SI
16802 (zero_extract:SI
16803 (match_dup 2)
16804 (const_int 8)
16805 (const_int 8))
16806 (match_dup 3)))])])
16807
16808 ;; Don't do logical operations with memory inputs.
16809 (define_peephole2
16810 [(match_scratch:SI 2 "r")
16811 (parallel [(set (match_operand:SI 0 "register_operand" "")
16812 (match_operator:SI 3 "arith_or_logical_operator"
16813 [(match_dup 0)
16814 (match_operand:SI 1 "memory_operand" "")]))
16815 (clobber (reg:CC FLAGS_REG))])]
16816 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16817 [(set (match_dup 2) (match_dup 1))
16818 (parallel [(set (match_dup 0)
16819 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16820 (clobber (reg:CC FLAGS_REG))])])
16821
16822 (define_peephole2
16823 [(match_scratch:SI 2 "r")
16824 (parallel [(set (match_operand:SI 0 "register_operand" "")
16825 (match_operator:SI 3 "arith_or_logical_operator"
16826 [(match_operand:SI 1 "memory_operand" "")
16827 (match_dup 0)]))
16828 (clobber (reg:CC FLAGS_REG))])]
16829 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16830 [(set (match_dup 2) (match_dup 1))
16831 (parallel [(set (match_dup 0)
16832 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16833 (clobber (reg:CC FLAGS_REG))])])
16834
16835 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16836 ;; refers to the destination of the load!
16837
16838 (define_peephole2
16839 [(set (match_operand:SI 0 "register_operand" "")
16840 (match_operand:SI 1 "register_operand" ""))
16841 (parallel [(set (match_dup 0)
16842 (match_operator:SI 3 "commutative_operator"
16843 [(match_dup 0)
16844 (match_operand:SI 2 "memory_operand" "")]))
16845 (clobber (reg:CC FLAGS_REG))])]
16846 "REGNO (operands[0]) != REGNO (operands[1])
16847 && GENERAL_REGNO_P (REGNO (operands[0]))
16848 && GENERAL_REGNO_P (REGNO (operands[1]))"
16849 [(set (match_dup 0) (match_dup 4))
16850 (parallel [(set (match_dup 0)
16851 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16852 (clobber (reg:CC FLAGS_REG))])]
16853 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16854
16855 (define_peephole2
16856 [(set (match_operand 0 "register_operand" "")
16857 (match_operand 1 "register_operand" ""))
16858 (set (match_dup 0)
16859 (match_operator 3 "commutative_operator"
16860 [(match_dup 0)
16861 (match_operand 2 "memory_operand" "")]))]
16862 "REGNO (operands[0]) != REGNO (operands[1])
16863 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16864 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16865 [(set (match_dup 0) (match_dup 2))
16866 (set (match_dup 0)
16867 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16868
16869 ; Don't do logical operations with memory outputs
16870 ;
16871 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16872 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16873 ; the same decoder scheduling characteristics as the original.
16874
16875 (define_peephole2
16876 [(match_scratch:SI 2 "r")
16877 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16878 (match_operator:SI 3 "arith_or_logical_operator"
16879 [(match_dup 0)
16880 (match_operand:SI 1 "nonmemory_operand" "")]))
16881 (clobber (reg:CC FLAGS_REG))])]
16882 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16883 /* Do not split stack checking probes. */
16884 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16885 [(set (match_dup 2) (match_dup 0))
16886 (parallel [(set (match_dup 2)
16887 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16888 (clobber (reg:CC FLAGS_REG))])
16889 (set (match_dup 0) (match_dup 2))])
16890
16891 (define_peephole2
16892 [(match_scratch:SI 2 "r")
16893 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16894 (match_operator:SI 3 "arith_or_logical_operator"
16895 [(match_operand:SI 1 "nonmemory_operand" "")
16896 (match_dup 0)]))
16897 (clobber (reg:CC FLAGS_REG))])]
16898 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16899 /* Do not split stack checking probes. */
16900 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16901 [(set (match_dup 2) (match_dup 0))
16902 (parallel [(set (match_dup 2)
16903 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16904 (clobber (reg:CC FLAGS_REG))])
16905 (set (match_dup 0) (match_dup 2))])
16906
16907 ;; Attempt to use arith or logical operations with memory outputs with
16908 ;; setting of flags.
16909 (define_peephole2
16910 [(set (match_operand:SWI 0 "register_operand" "")
16911 (match_operand:SWI 1 "memory_operand" ""))
16912 (parallel [(set (match_dup 0)
16913 (match_operator:SWI 3 "plusminuslogic_operator"
16914 [(match_dup 0)
16915 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16916 (clobber (reg:CC FLAGS_REG))])
16917 (set (match_dup 1) (match_dup 0))
16918 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16919 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16920 && peep2_reg_dead_p (4, operands[0])
16921 && !reg_overlap_mentioned_p (operands[0], operands[1])
16922 && ix86_match_ccmode (peep2_next_insn (3),
16923 (GET_CODE (operands[3]) == PLUS
16924 || GET_CODE (operands[3]) == MINUS)
16925 ? CCGOCmode : CCNOmode)"
16926 [(parallel [(set (match_dup 4) (match_dup 5))
16927 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16928 (match_dup 2)]))])]
16929 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16930 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16931 copy_rtx (operands[1]),
16932 copy_rtx (operands[2]));
16933 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16934 operands[5], const0_rtx);")
16935
16936 (define_peephole2
16937 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16938 (match_operator:SWI 2 "plusminuslogic_operator"
16939 [(match_dup 0)
16940 (match_operand:SWI 1 "memory_operand" "")]))
16941 (clobber (reg:CC FLAGS_REG))])
16942 (set (match_dup 1) (match_dup 0))
16943 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16944 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16945 && GET_CODE (operands[2]) != MINUS
16946 && peep2_reg_dead_p (3, operands[0])
16947 && !reg_overlap_mentioned_p (operands[0], operands[1])
16948 && ix86_match_ccmode (peep2_next_insn (2),
16949 GET_CODE (operands[2]) == PLUS
16950 ? CCGOCmode : CCNOmode)"
16951 [(parallel [(set (match_dup 3) (match_dup 4))
16952 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16953 (match_dup 0)]))])]
16954 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16955 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16956 copy_rtx (operands[1]),
16957 copy_rtx (operands[0]));
16958 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16959 operands[4], const0_rtx);")
16960
16961 (define_peephole2
16962 [(set (match_operand:SWI12 0 "register_operand" "")
16963 (match_operand:SWI12 1 "memory_operand" ""))
16964 (parallel [(set (match_operand:SI 4 "register_operand" "")
16965 (match_operator:SI 3 "plusminuslogic_operator"
16966 [(match_dup 4)
16967 (match_operand:SI 2 "nonmemory_operand" "")]))
16968 (clobber (reg:CC FLAGS_REG))])
16969 (set (match_dup 1) (match_dup 0))
16970 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16971 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16972 && REG_P (operands[0]) && REG_P (operands[4])
16973 && REGNO (operands[0]) == REGNO (operands[4])
16974 && peep2_reg_dead_p (4, operands[0])
16975 && !reg_overlap_mentioned_p (operands[0], operands[1])
16976 && ix86_match_ccmode (peep2_next_insn (3),
16977 (GET_CODE (operands[3]) == PLUS
16978 || GET_CODE (operands[3]) == MINUS)
16979 ? CCGOCmode : CCNOmode)"
16980 [(parallel [(set (match_dup 4) (match_dup 5))
16981 (set (match_dup 1) (match_dup 6))])]
16982 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16983 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16984 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16985 copy_rtx (operands[1]), operands[2]);
16986 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16987 operands[5], const0_rtx);
16988 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16989 copy_rtx (operands[1]),
16990 copy_rtx (operands[2]));")
16991
16992 ;; Attempt to always use XOR for zeroing registers.
16993 (define_peephole2
16994 [(set (match_operand 0 "register_operand" "")
16995 (match_operand 1 "const0_operand" ""))]
16996 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16997 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16998 && GENERAL_REG_P (operands[0])
16999 && peep2_regno_dead_p (0, FLAGS_REG)"
17000 [(parallel [(set (match_dup 0) (const_int 0))
17001 (clobber (reg:CC FLAGS_REG))])]
17002 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17003
17004 (define_peephole2
17005 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17006 (const_int 0))]
17007 "(GET_MODE (operands[0]) == QImode
17008 || GET_MODE (operands[0]) == HImode)
17009 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17010 && peep2_regno_dead_p (0, FLAGS_REG)"
17011 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17012 (clobber (reg:CC FLAGS_REG))])])
17013
17014 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17015 (define_peephole2
17016 [(set (match_operand:SWI248 0 "register_operand" "")
17017 (const_int -1))]
17018 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17019 && peep2_regno_dead_p (0, FLAGS_REG)"
17020 [(parallel [(set (match_dup 0) (const_int -1))
17021 (clobber (reg:CC FLAGS_REG))])]
17022 {
17023 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17024 operands[0] = gen_lowpart (SImode, operands[0]);
17025 })
17026
17027 ;; Attempt to convert simple lea to add/shift.
17028 ;; These can be created by move expanders.
17029
17030 (define_peephole2
17031 [(set (match_operand:SWI48 0 "register_operand" "")
17032 (plus:SWI48 (match_dup 0)
17033 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17034 "peep2_regno_dead_p (0, FLAGS_REG)"
17035 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17036 (clobber (reg:CC FLAGS_REG))])])
17037
17038 (define_peephole2
17039 [(set (match_operand:SI 0 "register_operand" "")
17040 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17041 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17042 "TARGET_64BIT
17043 && peep2_regno_dead_p (0, FLAGS_REG)
17044 && REGNO (operands[0]) == REGNO (operands[1])"
17045 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17046 (clobber (reg:CC FLAGS_REG))])]
17047 "operands[2] = gen_lowpart (SImode, operands[2]);")
17048
17049 (define_peephole2
17050 [(set (match_operand:SWI48 0 "register_operand" "")
17051 (mult:SWI48 (match_dup 0)
17052 (match_operand:SWI48 1 "const_int_operand" "")))]
17053 "exact_log2 (INTVAL (operands[1])) >= 0
17054 && peep2_regno_dead_p (0, FLAGS_REG)"
17055 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17056 (clobber (reg:CC FLAGS_REG))])]
17057 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17058
17059 (define_peephole2
17060 [(set (match_operand:SI 0 "register_operand" "")
17061 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17062 (match_operand:DI 2 "const_int_operand" "")) 0))]
17063 "TARGET_64BIT
17064 && exact_log2 (INTVAL (operands[2])) >= 0
17065 && REGNO (operands[0]) == REGNO (operands[1])
17066 && peep2_regno_dead_p (0, FLAGS_REG)"
17067 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17068 (clobber (reg:CC FLAGS_REG))])]
17069 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17070
17071 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17072 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17073 ;; On many CPUs it is also faster, since special hardware to avoid esp
17074 ;; dependencies is present.
17075
17076 ;; While some of these conversions may be done using splitters, we use
17077 ;; peepholes in order to allow combine_stack_adjustments pass to see
17078 ;; nonobfuscated RTL.
17079
17080 ;; Convert prologue esp subtractions to push.
17081 ;; We need register to push. In order to keep verify_flow_info happy we have
17082 ;; two choices
17083 ;; - use scratch and clobber it in order to avoid dependencies
17084 ;; - use already live register
17085 ;; We can't use the second way right now, since there is no reliable way how to
17086 ;; verify that given register is live. First choice will also most likely in
17087 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17088 ;; call clobbered registers are dead. We may want to use base pointer as an
17089 ;; alternative when no register is available later.
17090
17091 (define_peephole2
17092 [(match_scratch:P 1 "r")
17093 (parallel [(set (reg:P SP_REG)
17094 (plus:P (reg:P SP_REG)
17095 (match_operand:P 0 "const_int_operand" "")))
17096 (clobber (reg:CC FLAGS_REG))
17097 (clobber (mem:BLK (scratch)))])]
17098 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17099 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17100 [(clobber (match_dup 1))
17101 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17102 (clobber (mem:BLK (scratch)))])])
17103
17104 (define_peephole2
17105 [(match_scratch:P 1 "r")
17106 (parallel [(set (reg:P SP_REG)
17107 (plus:P (reg:P SP_REG)
17108 (match_operand:P 0 "const_int_operand" "")))
17109 (clobber (reg:CC FLAGS_REG))
17110 (clobber (mem:BLK (scratch)))])]
17111 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17112 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17113 [(clobber (match_dup 1))
17114 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17115 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17116 (clobber (mem:BLK (scratch)))])])
17117
17118 ;; Convert esp subtractions to push.
17119 (define_peephole2
17120 [(match_scratch:P 1 "r")
17121 (parallel [(set (reg:P SP_REG)
17122 (plus:P (reg:P SP_REG)
17123 (match_operand:P 0 "const_int_operand" "")))
17124 (clobber (reg:CC FLAGS_REG))])]
17125 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17126 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17127 [(clobber (match_dup 1))
17128 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17129
17130 (define_peephole2
17131 [(match_scratch:P 1 "r")
17132 (parallel [(set (reg:P SP_REG)
17133 (plus:P (reg:P SP_REG)
17134 (match_operand:P 0 "const_int_operand" "")))
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17137 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17138 [(clobber (match_dup 1))
17139 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17140 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17141
17142 ;; Convert epilogue deallocator to pop.
17143 (define_peephole2
17144 [(match_scratch:P 1 "r")
17145 (parallel [(set (reg:P SP_REG)
17146 (plus:P (reg:P SP_REG)
17147 (match_operand:P 0 "const_int_operand" "")))
17148 (clobber (reg:CC FLAGS_REG))
17149 (clobber (mem:BLK (scratch)))])]
17150 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17151 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17152 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17153 (clobber (mem:BLK (scratch)))])])
17154
17155 ;; Two pops case is tricky, since pop causes dependency
17156 ;; on destination register. We use two registers if available.
17157 (define_peephole2
17158 [(match_scratch:P 1 "r")
17159 (match_scratch:P 2 "r")
17160 (parallel [(set (reg:P SP_REG)
17161 (plus:P (reg:P SP_REG)
17162 (match_operand:P 0 "const_int_operand" "")))
17163 (clobber (reg:CC FLAGS_REG))
17164 (clobber (mem:BLK (scratch)))])]
17165 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17166 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17167 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17168 (clobber (mem:BLK (scratch)))])
17169 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17170
17171 (define_peephole2
17172 [(match_scratch:P 1 "r")
17173 (parallel [(set (reg:P SP_REG)
17174 (plus:P (reg:P SP_REG)
17175 (match_operand:P 0 "const_int_operand" "")))
17176 (clobber (reg:CC FLAGS_REG))
17177 (clobber (mem:BLK (scratch)))])]
17178 "optimize_insn_for_size_p ()
17179 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17180 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17181 (clobber (mem:BLK (scratch)))])
17182 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17183
17184 ;; Convert esp additions to pop.
17185 (define_peephole2
17186 [(match_scratch:P 1 "r")
17187 (parallel [(set (reg:P SP_REG)
17188 (plus:P (reg:P SP_REG)
17189 (match_operand:P 0 "const_int_operand" "")))
17190 (clobber (reg:CC FLAGS_REG))])]
17191 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17192 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17193
17194 ;; Two pops case is tricky, since pop causes dependency
17195 ;; on destination register. We use two registers if available.
17196 (define_peephole2
17197 [(match_scratch:P 1 "r")
17198 (match_scratch:P 2 "r")
17199 (parallel [(set (reg:P SP_REG)
17200 (plus:P (reg:P SP_REG)
17201 (match_operand:P 0 "const_int_operand" "")))
17202 (clobber (reg:CC FLAGS_REG))])]
17203 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17204 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17205 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17206
17207 (define_peephole2
17208 [(match_scratch:P 1 "r")
17209 (parallel [(set (reg:P SP_REG)
17210 (plus:P (reg:P SP_REG)
17211 (match_operand:P 0 "const_int_operand" "")))
17212 (clobber (reg:CC FLAGS_REG))])]
17213 "optimize_insn_for_size_p ()
17214 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17215 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17216 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17217 \f
17218 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17219 ;; required and register dies. Similarly for 128 to -128.
17220 (define_peephole2
17221 [(set (match_operand 0 "flags_reg_operand" "")
17222 (match_operator 1 "compare_operator"
17223 [(match_operand 2 "register_operand" "")
17224 (match_operand 3 "const_int_operand" "")]))]
17225 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17226 && incdec_operand (operands[3], GET_MODE (operands[3])))
17227 || (!TARGET_FUSE_CMP_AND_BRANCH
17228 && INTVAL (operands[3]) == 128))
17229 && ix86_match_ccmode (insn, CCGCmode)
17230 && peep2_reg_dead_p (1, operands[2])"
17231 [(parallel [(set (match_dup 0)
17232 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17233 (clobber (match_dup 2))])])
17234 \f
17235 ;; Convert imul by three, five and nine into lea
17236 (define_peephole2
17237 [(parallel
17238 [(set (match_operand:SWI48 0 "register_operand" "")
17239 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17240 (match_operand:SWI48 2 "const_int_operand" "")))
17241 (clobber (reg:CC FLAGS_REG))])]
17242 "INTVAL (operands[2]) == 3
17243 || INTVAL (operands[2]) == 5
17244 || INTVAL (operands[2]) == 9"
17245 [(set (match_dup 0)
17246 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17247 (match_dup 1)))]
17248 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17249
17250 (define_peephole2
17251 [(parallel
17252 [(set (match_operand:SWI48 0 "register_operand" "")
17253 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17254 (match_operand:SWI48 2 "const_int_operand" "")))
17255 (clobber (reg:CC FLAGS_REG))])]
17256 "optimize_insn_for_speed_p ()
17257 && (INTVAL (operands[2]) == 3
17258 || INTVAL (operands[2]) == 5
17259 || INTVAL (operands[2]) == 9)"
17260 [(set (match_dup 0) (match_dup 1))
17261 (set (match_dup 0)
17262 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17263 (match_dup 0)))]
17264 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17265
17266 ;; imul $32bit_imm, mem, reg is vector decoded, while
17267 ;; imul $32bit_imm, reg, reg is direct decoded.
17268 (define_peephole2
17269 [(match_scratch:SWI48 3 "r")
17270 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17271 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17272 (match_operand:SWI48 2 "immediate_operand" "")))
17273 (clobber (reg:CC FLAGS_REG))])]
17274 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17275 && !satisfies_constraint_K (operands[2])"
17276 [(set (match_dup 3) (match_dup 1))
17277 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17278 (clobber (reg:CC FLAGS_REG))])])
17279
17280 (define_peephole2
17281 [(match_scratch:SI 3 "r")
17282 (parallel [(set (match_operand:DI 0 "register_operand" "")
17283 (zero_extend:DI
17284 (mult:SI (match_operand:SI 1 "memory_operand" "")
17285 (match_operand:SI 2 "immediate_operand" ""))))
17286 (clobber (reg:CC FLAGS_REG))])]
17287 "TARGET_64BIT
17288 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17289 && !satisfies_constraint_K (operands[2])"
17290 [(set (match_dup 3) (match_dup 1))
17291 (parallel [(set (match_dup 0)
17292 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17293 (clobber (reg:CC FLAGS_REG))])])
17294
17295 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17296 ;; Convert it into imul reg, reg
17297 ;; It would be better to force assembler to encode instruction using long
17298 ;; immediate, but there is apparently no way to do so.
17299 (define_peephole2
17300 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17301 (mult:SWI248
17302 (match_operand:SWI248 1 "nonimmediate_operand" "")
17303 (match_operand:SWI248 2 "const_int_operand" "")))
17304 (clobber (reg:CC FLAGS_REG))])
17305 (match_scratch:SWI248 3 "r")]
17306 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17307 && satisfies_constraint_K (operands[2])"
17308 [(set (match_dup 3) (match_dup 2))
17309 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17310 (clobber (reg:CC FLAGS_REG))])]
17311 {
17312 if (!rtx_equal_p (operands[0], operands[1]))
17313 emit_move_insn (operands[0], operands[1]);
17314 })
17315
17316 ;; After splitting up read-modify operations, array accesses with memory
17317 ;; operands might end up in form:
17318 ;; sall $2, %eax
17319 ;; movl 4(%esp), %edx
17320 ;; addl %edx, %eax
17321 ;; instead of pre-splitting:
17322 ;; sall $2, %eax
17323 ;; addl 4(%esp), %eax
17324 ;; Turn it into:
17325 ;; movl 4(%esp), %edx
17326 ;; leal (%edx,%eax,4), %eax
17327
17328 (define_peephole2
17329 [(match_scratch:P 5 "r")
17330 (parallel [(set (match_operand 0 "register_operand" "")
17331 (ashift (match_operand 1 "register_operand" "")
17332 (match_operand 2 "const_int_operand" "")))
17333 (clobber (reg:CC FLAGS_REG))])
17334 (parallel [(set (match_operand 3 "register_operand" "")
17335 (plus (match_dup 0)
17336 (match_operand 4 "x86_64_general_operand" "")))
17337 (clobber (reg:CC FLAGS_REG))])]
17338 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17339 /* Validate MODE for lea. */
17340 && ((!TARGET_PARTIAL_REG_STALL
17341 && (GET_MODE (operands[0]) == QImode
17342 || GET_MODE (operands[0]) == HImode))
17343 || GET_MODE (operands[0]) == SImode
17344 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17345 && (rtx_equal_p (operands[0], operands[3])
17346 || peep2_reg_dead_p (2, operands[0]))
17347 /* We reorder load and the shift. */
17348 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17349 [(set (match_dup 5) (match_dup 4))
17350 (set (match_dup 0) (match_dup 1))]
17351 {
17352 enum machine_mode op1mode = GET_MODE (operands[1]);
17353 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17354 int scale = 1 << INTVAL (operands[2]);
17355 rtx index = gen_lowpart (Pmode, operands[1]);
17356 rtx base = gen_lowpart (Pmode, operands[5]);
17357 rtx dest = gen_lowpart (mode, operands[3]);
17358
17359 operands[1] = gen_rtx_PLUS (Pmode, base,
17360 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17361 operands[5] = base;
17362 if (mode != Pmode)
17363 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17364 if (op1mode != Pmode)
17365 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17366 operands[0] = dest;
17367 })
17368 \f
17369 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17370 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17371 ;; caught for use by garbage collectors and the like. Using an insn that
17372 ;; maps to SIGILL makes it more likely the program will rightfully die.
17373 ;; Keeping with tradition, "6" is in honor of #UD.
17374 (define_insn "trap"
17375 [(trap_if (const_int 1) (const_int 6))]
17376 ""
17377 { return ASM_SHORT "0x0b0f"; }
17378 [(set_attr "length" "2")])
17379
17380 (define_expand "prefetch"
17381 [(prefetch (match_operand 0 "address_operand" "")
17382 (match_operand:SI 1 "const_int_operand" "")
17383 (match_operand:SI 2 "const_int_operand" ""))]
17384 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17385 {
17386 int rw = INTVAL (operands[1]);
17387 int locality = INTVAL (operands[2]);
17388
17389 gcc_assert (rw == 0 || rw == 1);
17390 gcc_assert (locality >= 0 && locality <= 3);
17391 gcc_assert (GET_MODE (operands[0]) == Pmode
17392 || GET_MODE (operands[0]) == VOIDmode);
17393
17394 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17395 supported by SSE counterpart or the SSE prefetch is not available
17396 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17397 of locality. */
17398 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17399 operands[2] = GEN_INT (3);
17400 else
17401 operands[1] = const0_rtx;
17402 })
17403
17404 (define_insn "*prefetch_sse_<mode>"
17405 [(prefetch (match_operand:P 0 "address_operand" "p")
17406 (const_int 0)
17407 (match_operand:SI 1 "const_int_operand" ""))]
17408 "TARGET_PREFETCH_SSE"
17409 {
17410 static const char * const patterns[4] = {
17411 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17412 };
17413
17414 int locality = INTVAL (operands[1]);
17415 gcc_assert (locality >= 0 && locality <= 3);
17416
17417 return patterns[locality];
17418 }
17419 [(set_attr "type" "sse")
17420 (set_attr "atom_sse_attr" "prefetch")
17421 (set (attr "length_address")
17422 (symbol_ref "memory_address_length (operands[0])"))
17423 (set_attr "memory" "none")])
17424
17425 (define_insn "*prefetch_3dnow_<mode>"
17426 [(prefetch (match_operand:P 0 "address_operand" "p")
17427 (match_operand:SI 1 "const_int_operand" "n")
17428 (const_int 3))]
17429 "TARGET_3DNOW"
17430 {
17431 if (INTVAL (operands[1]) == 0)
17432 return "prefetch\t%a0";
17433 else
17434 return "prefetchw\t%a0";
17435 }
17436 [(set_attr "type" "mmx")
17437 (set (attr "length_address")
17438 (symbol_ref "memory_address_length (operands[0])"))
17439 (set_attr "memory" "none")])
17440
17441 (define_expand "stack_protect_set"
17442 [(match_operand 0 "memory_operand" "")
17443 (match_operand 1 "memory_operand" "")]
17444 ""
17445 {
17446 rtx (*insn)(rtx, rtx);
17447
17448 #ifdef TARGET_THREAD_SSP_OFFSET
17449 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17450 insn = (TARGET_64BIT
17451 ? gen_stack_tls_protect_set_di
17452 : gen_stack_tls_protect_set_si);
17453 #else
17454 insn = (TARGET_64BIT
17455 ? gen_stack_protect_set_di
17456 : gen_stack_protect_set_si);
17457 #endif
17458
17459 emit_insn (insn (operands[0], operands[1]));
17460 DONE;
17461 })
17462
17463 (define_insn "stack_protect_set_<mode>"
17464 [(set (match_operand:P 0 "memory_operand" "=m")
17465 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17466 (set (match_scratch:P 2 "=&r") (const_int 0))
17467 (clobber (reg:CC FLAGS_REG))]
17468 ""
17469 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17470 [(set_attr "type" "multi")])
17471
17472 (define_insn "stack_tls_protect_set_<mode>"
17473 [(set (match_operand:P 0 "memory_operand" "=m")
17474 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17475 UNSPEC_SP_TLS_SET))
17476 (set (match_scratch:P 2 "=&r") (const_int 0))
17477 (clobber (reg:CC FLAGS_REG))]
17478 ""
17479 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17480 [(set_attr "type" "multi")])
17481
17482 (define_expand "stack_protect_test"
17483 [(match_operand 0 "memory_operand" "")
17484 (match_operand 1 "memory_operand" "")
17485 (match_operand 2 "" "")]
17486 ""
17487 {
17488 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17489
17490 rtx (*insn)(rtx, rtx, rtx);
17491
17492 #ifdef TARGET_THREAD_SSP_OFFSET
17493 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17494 insn = (TARGET_64BIT
17495 ? gen_stack_tls_protect_test_di
17496 : gen_stack_tls_protect_test_si);
17497 #else
17498 insn = (TARGET_64BIT
17499 ? gen_stack_protect_test_di
17500 : gen_stack_protect_test_si);
17501 #endif
17502
17503 emit_insn (insn (flags, operands[0], operands[1]));
17504
17505 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17506 flags, const0_rtx, operands[2]));
17507 DONE;
17508 })
17509
17510 (define_insn "stack_protect_test_<mode>"
17511 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17512 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17513 (match_operand:P 2 "memory_operand" "m")]
17514 UNSPEC_SP_TEST))
17515 (clobber (match_scratch:P 3 "=&r"))]
17516 ""
17517 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17518 [(set_attr "type" "multi")])
17519
17520 (define_insn "stack_tls_protect_test_<mode>"
17521 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17522 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17523 (match_operand:P 2 "const_int_operand" "i")]
17524 UNSPEC_SP_TLS_TEST))
17525 (clobber (match_scratch:P 3 "=r"))]
17526 ""
17527 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17528 [(set_attr "type" "multi")])
17529
17530 (define_insn "sse4_2_crc32<mode>"
17531 [(set (match_operand:SI 0 "register_operand" "=r")
17532 (unspec:SI
17533 [(match_operand:SI 1 "register_operand" "0")
17534 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17535 UNSPEC_CRC32))]
17536 "TARGET_SSE4_2 || TARGET_CRC32"
17537 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17538 [(set_attr "type" "sselog1")
17539 (set_attr "prefix_rep" "1")
17540 (set_attr "prefix_extra" "1")
17541 (set (attr "prefix_data16")
17542 (if_then_else (match_operand:HI 2 "" "")
17543 (const_string "1")
17544 (const_string "*")))
17545 (set (attr "prefix_rex")
17546 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17547 (const_string "1")
17548 (const_string "*")))
17549 (set_attr "mode" "SI")])
17550
17551 (define_insn "sse4_2_crc32di"
17552 [(set (match_operand:DI 0 "register_operand" "=r")
17553 (unspec:DI
17554 [(match_operand:DI 1 "register_operand" "0")
17555 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17556 UNSPEC_CRC32))]
17557 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17558 "crc32{q}\t{%2, %0|%0, %2}"
17559 [(set_attr "type" "sselog1")
17560 (set_attr "prefix_rep" "1")
17561 (set_attr "prefix_extra" "1")
17562 (set_attr "mode" "DI")])
17563
17564 (define_expand "rdpmc"
17565 [(match_operand:DI 0 "register_operand" "")
17566 (match_operand:SI 1 "register_operand" "")]
17567 ""
17568 {
17569 rtx reg = gen_reg_rtx (DImode);
17570 rtx si;
17571
17572 /* Force operand 1 into ECX. */
17573 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17574 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17575 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17576 UNSPECV_RDPMC);
17577
17578 if (TARGET_64BIT)
17579 {
17580 rtvec vec = rtvec_alloc (2);
17581 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17582 rtx upper = gen_reg_rtx (DImode);
17583 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17584 gen_rtvec (1, const0_rtx),
17585 UNSPECV_RDPMC);
17586 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17587 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17588 emit_insn (load);
17589 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17590 NULL, 1, OPTAB_DIRECT);
17591 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17592 OPTAB_DIRECT);
17593 }
17594 else
17595 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17596 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17597 DONE;
17598 })
17599
17600 (define_insn "*rdpmc"
17601 [(set (match_operand:DI 0 "register_operand" "=A")
17602 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17603 UNSPECV_RDPMC))]
17604 "!TARGET_64BIT"
17605 "rdpmc"
17606 [(set_attr "type" "other")
17607 (set_attr "length" "2")])
17608
17609 (define_insn "*rdpmc_rex64"
17610 [(set (match_operand:DI 0 "register_operand" "=a")
17611 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17612 UNSPECV_RDPMC))
17613 (set (match_operand:DI 1 "register_operand" "=d")
17614 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17615 "TARGET_64BIT"
17616 "rdpmc"
17617 [(set_attr "type" "other")
17618 (set_attr "length" "2")])
17619
17620 (define_expand "rdtsc"
17621 [(set (match_operand:DI 0 "register_operand" "")
17622 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17623 ""
17624 {
17625 if (TARGET_64BIT)
17626 {
17627 rtvec vec = rtvec_alloc (2);
17628 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17629 rtx upper = gen_reg_rtx (DImode);
17630 rtx lower = gen_reg_rtx (DImode);
17631 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17632 gen_rtvec (1, const0_rtx),
17633 UNSPECV_RDTSC);
17634 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17635 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17636 emit_insn (load);
17637 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17638 NULL, 1, OPTAB_DIRECT);
17639 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17640 OPTAB_DIRECT);
17641 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17642 DONE;
17643 }
17644 })
17645
17646 (define_insn "*rdtsc"
17647 [(set (match_operand:DI 0 "register_operand" "=A")
17648 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17649 "!TARGET_64BIT"
17650 "rdtsc"
17651 [(set_attr "type" "other")
17652 (set_attr "length" "2")])
17653
17654 (define_insn "*rdtsc_rex64"
17655 [(set (match_operand:DI 0 "register_operand" "=a")
17656 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17657 (set (match_operand:DI 1 "register_operand" "=d")
17658 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17659 "TARGET_64BIT"
17660 "rdtsc"
17661 [(set_attr "type" "other")
17662 (set_attr "length" "2")])
17663
17664 (define_expand "rdtscp"
17665 [(match_operand:DI 0 "register_operand" "")
17666 (match_operand:SI 1 "memory_operand" "")]
17667 ""
17668 {
17669 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17670 gen_rtvec (1, const0_rtx),
17671 UNSPECV_RDTSCP);
17672 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17673 gen_rtvec (1, const0_rtx),
17674 UNSPECV_RDTSCP);
17675 rtx reg = gen_reg_rtx (DImode);
17676 rtx tmp = gen_reg_rtx (SImode);
17677
17678 if (TARGET_64BIT)
17679 {
17680 rtvec vec = rtvec_alloc (3);
17681 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17682 rtx upper = gen_reg_rtx (DImode);
17683 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17684 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17685 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17686 emit_insn (load);
17687 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17688 NULL, 1, OPTAB_DIRECT);
17689 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17690 OPTAB_DIRECT);
17691 }
17692 else
17693 {
17694 rtvec vec = rtvec_alloc (2);
17695 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17696 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17697 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17698 emit_insn (load);
17699 }
17700 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17701 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17702 DONE;
17703 })
17704
17705 (define_insn "*rdtscp"
17706 [(set (match_operand:DI 0 "register_operand" "=A")
17707 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17708 (set (match_operand:SI 1 "register_operand" "=c")
17709 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17710 "!TARGET_64BIT"
17711 "rdtscp"
17712 [(set_attr "type" "other")
17713 (set_attr "length" "3")])
17714
17715 (define_insn "*rdtscp_rex64"
17716 [(set (match_operand:DI 0 "register_operand" "=a")
17717 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17718 (set (match_operand:DI 1 "register_operand" "=d")
17719 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17720 (set (match_operand:SI 2 "register_operand" "=c")
17721 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17722 "TARGET_64BIT"
17723 "rdtscp"
17724 [(set_attr "type" "other")
17725 (set_attr "length" "3")])
17726
17727 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17728 ;;
17729 ;; LWP instructions
17730 ;;
17731 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17732
17733 (define_expand "lwp_llwpcb"
17734 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17735 UNSPECV_LLWP_INTRINSIC)]
17736 "TARGET_LWP")
17737
17738 (define_insn "*lwp_llwpcb<mode>1"
17739 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17740 UNSPECV_LLWP_INTRINSIC)]
17741 "TARGET_LWP"
17742 "llwpcb\t%0"
17743 [(set_attr "type" "lwp")
17744 (set_attr "mode" "<MODE>")
17745 (set_attr "length" "5")])
17746
17747 (define_expand "lwp_slwpcb"
17748 [(set (match_operand 0 "register_operand" "=r")
17749 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17750 "TARGET_LWP"
17751 {
17752 rtx (*insn)(rtx);
17753
17754 insn = (TARGET_64BIT
17755 ? gen_lwp_slwpcbdi
17756 : gen_lwp_slwpcbsi);
17757
17758 emit_insn (insn (operands[0]));
17759 DONE;
17760 })
17761
17762 (define_insn "lwp_slwpcb<mode>"
17763 [(set (match_operand:P 0 "register_operand" "=r")
17764 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17765 "TARGET_LWP"
17766 "slwpcb\t%0"
17767 [(set_attr "type" "lwp")
17768 (set_attr "mode" "<MODE>")
17769 (set_attr "length" "5")])
17770
17771 (define_expand "lwp_lwpval<mode>3"
17772 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17773 (match_operand:SI 2 "nonimmediate_operand" "rm")
17774 (match_operand:SI 3 "const_int_operand" "i")]
17775 UNSPECV_LWPVAL_INTRINSIC)]
17776 "TARGET_LWP"
17777 "/* Avoid unused variable warning. */
17778 (void) operand0;")
17779
17780 (define_insn "*lwp_lwpval<mode>3_1"
17781 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17782 (match_operand:SI 1 "nonimmediate_operand" "rm")
17783 (match_operand:SI 2 "const_int_operand" "i")]
17784 UNSPECV_LWPVAL_INTRINSIC)]
17785 "TARGET_LWP"
17786 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17787 [(set_attr "type" "lwp")
17788 (set_attr "mode" "<MODE>")
17789 (set (attr "length")
17790 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17791
17792 (define_expand "lwp_lwpins<mode>3"
17793 [(set (reg:CCC FLAGS_REG)
17794 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17795 (match_operand:SI 2 "nonimmediate_operand" "rm")
17796 (match_operand:SI 3 "const_int_operand" "i")]
17797 UNSPECV_LWPINS_INTRINSIC))
17798 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17799 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17800 "TARGET_LWP")
17801
17802 (define_insn "*lwp_lwpins<mode>3_1"
17803 [(set (reg:CCC FLAGS_REG)
17804 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17805 (match_operand:SI 1 "nonimmediate_operand" "rm")
17806 (match_operand:SI 2 "const_int_operand" "i")]
17807 UNSPECV_LWPINS_INTRINSIC))]
17808 "TARGET_LWP"
17809 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17810 [(set_attr "type" "lwp")
17811 (set_attr "mode" "<MODE>")
17812 (set (attr "length")
17813 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17814
17815 (define_insn "rdfsbase<mode>"
17816 [(set (match_operand:SWI48 0 "register_operand" "=r")
17817 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17818 "TARGET_64BIT && TARGET_FSGSBASE"
17819 "rdfsbase %0"
17820 [(set_attr "type" "other")
17821 (set_attr "prefix_extra" "2")])
17822
17823 (define_insn "rdgsbase<mode>"
17824 [(set (match_operand:SWI48 0 "register_operand" "=r")
17825 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17826 "TARGET_64BIT && TARGET_FSGSBASE"
17827 "rdgsbase %0"
17828 [(set_attr "type" "other")
17829 (set_attr "prefix_extra" "2")])
17830
17831 (define_insn "wrfsbase<mode>"
17832 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17833 UNSPECV_WRFSBASE)]
17834 "TARGET_64BIT && TARGET_FSGSBASE"
17835 "wrfsbase %0"
17836 [(set_attr "type" "other")
17837 (set_attr "prefix_extra" "2")])
17838
17839 (define_insn "wrgsbase<mode>"
17840 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17841 UNSPECV_WRGSBASE)]
17842 "TARGET_64BIT && TARGET_FSGSBASE"
17843 "wrgsbase %0"
17844 [(set_attr "type" "other")
17845 (set_attr "prefix_extra" "2")])
17846
17847 (define_insn "rdrand<mode>_1"
17848 [(set (match_operand:SWI248 0 "register_operand" "=r")
17849 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17850 (set (reg:CCC FLAGS_REG)
17851 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17852 "TARGET_RDRND"
17853 "rdrand\t%0"
17854 [(set_attr "type" "other")
17855 (set_attr "prefix_extra" "1")])
17856
17857 (define_expand "pause"
17858 [(set (match_dup 0)
17859 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17860 ""
17861 {
17862 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17863 MEM_VOLATILE_P (operands[0]) = 1;
17864 })
17865
17866 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17867 ;; They have the same encoding.
17868 (define_insn "*pause"
17869 [(set (match_operand:BLK 0 "" "")
17870 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17871 ""
17872 "rep; nop"
17873 [(set_attr "length" "2")
17874 (set_attr "memory" "unknown")])
17875
17876 (include "mmx.md")
17877 (include "sse.md")
17878 (include "sync.md")