018678dc850292d761d7039dff6728b12cfa356d
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2013 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12 ;;
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
21 ;;
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
24 ;;
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;; otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;; delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
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 "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
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_SET_RIP
86 UNSPEC_SET_GOT_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
88 UNSPEC_STACK_CHECK
89
90 ;; TLS support
91 UNSPEC_TP
92 UNSPEC_TLS_GD
93 UNSPEC_TLS_LD_BASE
94 UNSPEC_TLSDESC
95 UNSPEC_TLS_IE_SUN
96
97 ;; Other random patterns
98 UNSPEC_SCAS
99 UNSPEC_FNSTSW
100 UNSPEC_SAHF
101 UNSPEC_PARITY
102 UNSPEC_FSTCW
103 UNSPEC_ADD_CARRY
104 UNSPEC_FLDCW
105 UNSPEC_REP
106 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_TRUNC_NOOP
108 UNSPEC_DIV_ALREADY_SPLIT
109 UNSPEC_MS_TO_SYSV_CALL
110 UNSPEC_PAUSE
111 UNSPEC_LEA_ADDR
112 UNSPEC_XBEGIN_ABORT
113 UNSPEC_STOS
114
115 ;; For SSE/MMX support:
116 UNSPEC_FIX_NOTRUNC
117 UNSPEC_MASKMOV
118 UNSPEC_MOVMSK
119 UNSPEC_RCP
120 UNSPEC_RSQRT
121 UNSPEC_PSADBW
122
123 ;; Generic math support
124 UNSPEC_COPYSIGN
125 UNSPEC_IEEE_MIN ; not commutative
126 UNSPEC_IEEE_MAX ; not commutative
127
128 ;; x87 Floating point
129 UNSPEC_SIN
130 UNSPEC_COS
131 UNSPEC_FPATAN
132 UNSPEC_FYL2X
133 UNSPEC_FYL2XP1
134 UNSPEC_FRNDINT
135 UNSPEC_FIST
136 UNSPEC_F2XM1
137 UNSPEC_TAN
138 UNSPEC_FXAM
139
140 ;; x87 Rounding
141 UNSPEC_FRNDINT_FLOOR
142 UNSPEC_FRNDINT_CEIL
143 UNSPEC_FRNDINT_TRUNC
144 UNSPEC_FRNDINT_MASK_PM
145 UNSPEC_FIST_FLOOR
146 UNSPEC_FIST_CEIL
147
148 ;; x87 Double output FP
149 UNSPEC_SINCOS_COS
150 UNSPEC_SINCOS_SIN
151 UNSPEC_XTRACT_FRACT
152 UNSPEC_XTRACT_EXP
153 UNSPEC_FSCALE_FRACT
154 UNSPEC_FSCALE_EXP
155 UNSPEC_FPREM_F
156 UNSPEC_FPREM_U
157 UNSPEC_FPREM1_F
158 UNSPEC_FPREM1_U
159
160 UNSPEC_C2_FLAG
161 UNSPEC_FXAM_MEM
162
163 ;; SSP patterns
164 UNSPEC_SP_SET
165 UNSPEC_SP_TEST
166 UNSPEC_SP_TLS_SET
167 UNSPEC_SP_TLS_TEST
168
169 ;; For ROUND support
170 UNSPEC_ROUND
171
172 ;; For CRC32 support
173 UNSPEC_CRC32
174
175 ;; For BMI support
176 UNSPEC_BEXTR
177
178 ;; For BMI2 support
179 UNSPEC_PDEP
180 UNSPEC_PEXT
181 ])
182
183 (define_c_enum "unspecv" [
184 UNSPECV_BLOCKAGE
185 UNSPECV_STACK_PROBE
186 UNSPECV_PROBE_STACK_RANGE
187 UNSPECV_ALIGN
188 UNSPECV_PROLOGUE_USE
189 UNSPECV_SPLIT_STACK_RETURN
190 UNSPECV_CLD
191 UNSPECV_NOPS
192 UNSPECV_RDTSC
193 UNSPECV_RDTSCP
194 UNSPECV_RDPMC
195 UNSPECV_LLWP_INTRINSIC
196 UNSPECV_SLWP_INTRINSIC
197 UNSPECV_LWPVAL_INTRINSIC
198 UNSPECV_LWPINS_INTRINSIC
199 UNSPECV_RDFSBASE
200 UNSPECV_RDGSBASE
201 UNSPECV_WRFSBASE
202 UNSPECV_WRGSBASE
203 UNSPECV_FXSAVE
204 UNSPECV_FXRSTOR
205 UNSPECV_FXSAVE64
206 UNSPECV_FXRSTOR64
207 UNSPECV_XSAVE
208 UNSPECV_XRSTOR
209 UNSPECV_XSAVE64
210 UNSPECV_XRSTOR64
211 UNSPECV_XSAVEOPT
212 UNSPECV_XSAVEOPT64
213
214 ;; For RDRAND support
215 UNSPECV_RDRAND
216
217 ;; For RDSEED support
218 UNSPECV_RDSEED
219
220 ;; For RTM support
221 UNSPECV_XBEGIN
222 UNSPECV_XEND
223 UNSPECV_XABORT
224 UNSPECV_XTEST
225 ])
226
227 ;; Constants to represent rounding modes in the ROUND instruction
228 (define_constants
229 [(ROUND_FLOOR 0x1)
230 (ROUND_CEIL 0x2)
231 (ROUND_TRUNC 0x3)
232 (ROUND_MXCSR 0x4)
233 (ROUND_NO_EXC 0x8)
234 ])
235
236 ;; Constants to represent pcomtrue/pcomfalse variants
237 (define_constants
238 [(PCOM_FALSE 0)
239 (PCOM_TRUE 1)
240 (COM_FALSE_S 2)
241 (COM_FALSE_P 3)
242 (COM_TRUE_S 4)
243 (COM_TRUE_P 5)
244 ])
245
246 ;; Constants used in the XOP pperm instruction
247 (define_constants
248 [(PPERM_SRC 0x00) /* copy source */
249 (PPERM_INVERT 0x20) /* invert source */
250 (PPERM_REVERSE 0x40) /* bit reverse source */
251 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
252 (PPERM_ZERO 0x80) /* all 0's */
253 (PPERM_ONES 0xa0) /* all 1's */
254 (PPERM_SIGN 0xc0) /* propagate sign bit */
255 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
256 (PPERM_SRC1 0x00) /* use first source byte */
257 (PPERM_SRC2 0x10) /* use second source byte */
258 ])
259
260 ;; Registers by name.
261 (define_constants
262 [(AX_REG 0)
263 (DX_REG 1)
264 (CX_REG 2)
265 (BX_REG 3)
266 (SI_REG 4)
267 (DI_REG 5)
268 (BP_REG 6)
269 (SP_REG 7)
270 (ST0_REG 8)
271 (ST1_REG 9)
272 (ST2_REG 10)
273 (ST3_REG 11)
274 (ST4_REG 12)
275 (ST5_REG 13)
276 (ST6_REG 14)
277 (ST7_REG 15)
278 (FLAGS_REG 17)
279 (FPSR_REG 18)
280 (FPCR_REG 19)
281 (XMM0_REG 21)
282 (XMM1_REG 22)
283 (XMM2_REG 23)
284 (XMM3_REG 24)
285 (XMM4_REG 25)
286 (XMM5_REG 26)
287 (XMM6_REG 27)
288 (XMM7_REG 28)
289 (MM0_REG 29)
290 (MM1_REG 30)
291 (MM2_REG 31)
292 (MM3_REG 32)
293 (MM4_REG 33)
294 (MM5_REG 34)
295 (MM6_REG 35)
296 (MM7_REG 36)
297 (R8_REG 37)
298 (R9_REG 38)
299 (R10_REG 39)
300 (R11_REG 40)
301 (R12_REG 41)
302 (R13_REG 42)
303 (R14_REG 43)
304 (R15_REG 44)
305 (XMM8_REG 45)
306 (XMM9_REG 46)
307 (XMM10_REG 47)
308 (XMM11_REG 48)
309 (XMM12_REG 49)
310 (XMM13_REG 50)
311 (XMM14_REG 51)
312 (XMM15_REG 52)
313 ])
314
315 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
316 ;; from i386.c.
317
318 ;; In C guard expressions, put expressions which may be compile-time
319 ;; constants first. This allows for better optimization. For
320 ;; example, write "TARGET_64BIT && reload_completed", not
321 ;; "reload_completed && TARGET_64BIT".
322
323 \f
324 ;; Processor type.
325 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
326 atom,slm,generic64,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
327 (const (symbol_ref "ix86_schedule")))
328
329 ;; A basic instruction type. Refinements due to arguments to be
330 ;; provided in other attributes.
331 (define_attr "type"
332 "other,multi,
333 alu,alu1,negnot,imov,imovx,lea,
334 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
335 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
336 push,pop,call,callv,leave,
337 str,bitmanip,
338 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
339 fxch,fistp,fisttp,frndint,
340 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
341 ssemul,sseimul,ssediv,sselog,sselog1,
342 sseishft,sseishft1,ssecmp,ssecomi,
343 ssecvt,ssecvt1,sseicvt,sseins,
344 sseshuf,sseshuf1,ssemuladd,sse4arg,
345 lwp,
346 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
347 (const_string "other"))
348
349 ;; Main data type used by the insn
350 (define_attr "mode"
351 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
352 (const_string "unknown"))
353
354 ;; The CPU unit operations uses.
355 (define_attr "unit" "integer,i387,sse,mmx,unknown"
356 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
357 fxch,fistp,fisttp,frndint")
358 (const_string "i387")
359 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
360 ssemul,sseimul,ssediv,sselog,sselog1,
361 sseishft,sseishft1,ssecmp,ssecomi,
362 ssecvt,ssecvt1,sseicvt,sseins,
363 sseshuf,sseshuf1,ssemuladd,sse4arg")
364 (const_string "sse")
365 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
366 (const_string "mmx")
367 (eq_attr "type" "other")
368 (const_string "unknown")]
369 (const_string "integer")))
370
371 ;; The (bounding maximum) length of an instruction immediate.
372 (define_attr "length_immediate" ""
373 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
374 bitmanip,imulx")
375 (const_int 0)
376 (eq_attr "unit" "i387,sse,mmx")
377 (const_int 0)
378 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
379 rotate,rotatex,rotate1,imul,icmp,push,pop")
380 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
381 (eq_attr "type" "imov,test")
382 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
383 (eq_attr "type" "call")
384 (if_then_else (match_operand 0 "constant_call_address_operand")
385 (const_int 4)
386 (const_int 0))
387 (eq_attr "type" "callv")
388 (if_then_else (match_operand 1 "constant_call_address_operand")
389 (const_int 4)
390 (const_int 0))
391 ;; We don't know the size before shorten_branches. Expect
392 ;; the instruction to fit for better scheduling.
393 (eq_attr "type" "ibr")
394 (const_int 1)
395 ]
396 (symbol_ref "/* Update immediate_length and other attributes! */
397 gcc_unreachable (),1")))
398
399 ;; The (bounding maximum) length of an instruction address.
400 (define_attr "length_address" ""
401 (cond [(eq_attr "type" "str,other,multi,fxch")
402 (const_int 0)
403 (and (eq_attr "type" "call")
404 (match_operand 0 "constant_call_address_operand"))
405 (const_int 0)
406 (and (eq_attr "type" "callv")
407 (match_operand 1 "constant_call_address_operand"))
408 (const_int 0)
409 ]
410 (symbol_ref "ix86_attr_length_address_default (insn)")))
411
412 ;; Set when length prefix is used.
413 (define_attr "prefix_data16" ""
414 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
415 (const_int 0)
416 (eq_attr "mode" "HI")
417 (const_int 1)
418 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
419 (const_int 1)
420 ]
421 (const_int 0)))
422
423 ;; Set when string REP prefix is used.
424 (define_attr "prefix_rep" ""
425 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
426 (const_int 0)
427 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
428 (const_int 1)
429 ]
430 (const_int 0)))
431
432 ;; Set when 0f opcode prefix is used.
433 (define_attr "prefix_0f" ""
434 (if_then_else
435 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
436 (eq_attr "unit" "sse,mmx"))
437 (const_int 1)
438 (const_int 0)))
439
440 ;; Set when REX opcode prefix is used.
441 (define_attr "prefix_rex" ""
442 (cond [(not (match_test "TARGET_64BIT"))
443 (const_int 0)
444 (and (eq_attr "mode" "DI")
445 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
446 (eq_attr "unit" "!mmx")))
447 (const_int 1)
448 (and (eq_attr "mode" "QI")
449 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
450 (const_int 1)
451 (match_test "x86_extended_reg_mentioned_p (insn)")
452 (const_int 1)
453 (and (eq_attr "type" "imovx")
454 (match_operand:QI 1 "ext_QIreg_operand"))
455 (const_int 1)
456 ]
457 (const_int 0)))
458
459 ;; There are also additional prefixes in 3DNOW, SSSE3.
460 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
461 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
462 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
463 (define_attr "prefix_extra" ""
464 (cond [(eq_attr "type" "ssemuladd,sse4arg")
465 (const_int 2)
466 (eq_attr "type" "sseiadd1,ssecvt1")
467 (const_int 1)
468 ]
469 (const_int 0)))
470
471 ;; Prefix used: original, VEX or maybe VEX.
472 (define_attr "prefix" "orig,vex,maybe_vex"
473 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
474 (const_string "vex")
475 (const_string "orig")))
476
477 ;; VEX W bit is used.
478 (define_attr "prefix_vex_w" "" (const_int 0))
479
480 ;; The length of VEX prefix
481 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
482 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
483 ;; still prefix_0f 1, with prefix_extra 1.
484 (define_attr "length_vex" ""
485 (if_then_else (and (eq_attr "prefix_0f" "1")
486 (eq_attr "prefix_extra" "0"))
487 (if_then_else (eq_attr "prefix_vex_w" "1")
488 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
489 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
490 (if_then_else (eq_attr "prefix_vex_w" "1")
491 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
492 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
493
494 ;; Set when modrm byte is used.
495 (define_attr "modrm" ""
496 (cond [(eq_attr "type" "str,leave")
497 (const_int 0)
498 (eq_attr "unit" "i387")
499 (const_int 0)
500 (and (eq_attr "type" "incdec")
501 (and (not (match_test "TARGET_64BIT"))
502 (ior (match_operand:SI 1 "register_operand")
503 (match_operand:HI 1 "register_operand"))))
504 (const_int 0)
505 (and (eq_attr "type" "push")
506 (not (match_operand 1 "memory_operand")))
507 (const_int 0)
508 (and (eq_attr "type" "pop")
509 (not (match_operand 0 "memory_operand")))
510 (const_int 0)
511 (and (eq_attr "type" "imov")
512 (and (not (eq_attr "mode" "DI"))
513 (ior (and (match_operand 0 "register_operand")
514 (match_operand 1 "immediate_operand"))
515 (ior (and (match_operand 0 "ax_reg_operand")
516 (match_operand 1 "memory_displacement_only_operand"))
517 (and (match_operand 0 "memory_displacement_only_operand")
518 (match_operand 1 "ax_reg_operand"))))))
519 (const_int 0)
520 (and (eq_attr "type" "call")
521 (match_operand 0 "constant_call_address_operand"))
522 (const_int 0)
523 (and (eq_attr "type" "callv")
524 (match_operand 1 "constant_call_address_operand"))
525 (const_int 0)
526 (and (eq_attr "type" "alu,alu1,icmp,test")
527 (match_operand 0 "ax_reg_operand"))
528 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
529 ]
530 (const_int 1)))
531
532 ;; The (bounding maximum) length of an instruction in bytes.
533 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
534 ;; Later we may want to split them and compute proper length as for
535 ;; other insns.
536 (define_attr "length" ""
537 (cond [(eq_attr "type" "other,multi,fistp,frndint")
538 (const_int 16)
539 (eq_attr "type" "fcmp")
540 (const_int 4)
541 (eq_attr "unit" "i387")
542 (plus (const_int 2)
543 (plus (attr "prefix_data16")
544 (attr "length_address")))
545 (ior (eq_attr "prefix" "vex")
546 (and (eq_attr "prefix" "maybe_vex")
547 (match_test "TARGET_AVX")))
548 (plus (attr "length_vex")
549 (plus (attr "length_immediate")
550 (plus (attr "modrm")
551 (attr "length_address"))))]
552 (plus (plus (attr "modrm")
553 (plus (attr "prefix_0f")
554 (plus (attr "prefix_rex")
555 (plus (attr "prefix_extra")
556 (const_int 1)))))
557 (plus (attr "prefix_rep")
558 (plus (attr "prefix_data16")
559 (plus (attr "length_immediate")
560 (attr "length_address")))))))
561
562 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
563 ;; `store' if there is a simple memory reference therein, or `unknown'
564 ;; if the instruction is complex.
565
566 (define_attr "memory" "none,load,store,both,unknown"
567 (cond [(eq_attr "type" "other,multi,str,lwp")
568 (const_string "unknown")
569 (eq_attr "type" "lea,fcmov,fpspc")
570 (const_string "none")
571 (eq_attr "type" "fistp,leave")
572 (const_string "both")
573 (eq_attr "type" "frndint")
574 (const_string "load")
575 (eq_attr "type" "push")
576 (if_then_else (match_operand 1 "memory_operand")
577 (const_string "both")
578 (const_string "store"))
579 (eq_attr "type" "pop")
580 (if_then_else (match_operand 0 "memory_operand")
581 (const_string "both")
582 (const_string "load"))
583 (eq_attr "type" "setcc")
584 (if_then_else (match_operand 0 "memory_operand")
585 (const_string "store")
586 (const_string "none"))
587 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
588 (if_then_else (ior (match_operand 0 "memory_operand")
589 (match_operand 1 "memory_operand"))
590 (const_string "load")
591 (const_string "none"))
592 (eq_attr "type" "ibr")
593 (if_then_else (match_operand 0 "memory_operand")
594 (const_string "load")
595 (const_string "none"))
596 (eq_attr "type" "call")
597 (if_then_else (match_operand 0 "constant_call_address_operand")
598 (const_string "none")
599 (const_string "load"))
600 (eq_attr "type" "callv")
601 (if_then_else (match_operand 1 "constant_call_address_operand")
602 (const_string "none")
603 (const_string "load"))
604 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
605 (match_operand 1 "memory_operand"))
606 (const_string "both")
607 (and (match_operand 0 "memory_operand")
608 (match_operand 1 "memory_operand"))
609 (const_string "both")
610 (match_operand 0 "memory_operand")
611 (const_string "store")
612 (match_operand 1 "memory_operand")
613 (const_string "load")
614 (and (eq_attr "type"
615 "!alu1,negnot,ishift1,
616 imov,imovx,icmp,test,bitmanip,
617 fmov,fcmp,fsgn,
618 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
619 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
620 mmx,mmxmov,mmxcmp,mmxcvt")
621 (match_operand 2 "memory_operand"))
622 (const_string "load")
623 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
624 (match_operand 3 "memory_operand"))
625 (const_string "load")
626 ]
627 (const_string "none")))
628
629 ;; Indicates if an instruction has both an immediate and a displacement.
630
631 (define_attr "imm_disp" "false,true,unknown"
632 (cond [(eq_attr "type" "other,multi")
633 (const_string "unknown")
634 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
635 (and (match_operand 0 "memory_displacement_operand")
636 (match_operand 1 "immediate_operand")))
637 (const_string "true")
638 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
639 (and (match_operand 0 "memory_displacement_operand")
640 (match_operand 2 "immediate_operand")))
641 (const_string "true")
642 ]
643 (const_string "false")))
644
645 ;; Indicates if an FP operation has an integer source.
646
647 (define_attr "fp_int_src" "false,true"
648 (const_string "false"))
649
650 ;; Defines rounding mode of an FP operation.
651
652 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
653 (const_string "any"))
654
655 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
656 (define_attr "use_carry" "0,1" (const_string "0"))
657
658 ;; Define attribute to indicate unaligned ssemov insns
659 (define_attr "movu" "0,1" (const_string "0"))
660
661 ;; Used to control the "enabled" attribute on a per-instruction basis.
662 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
663 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
664 avx2,noavx2,bmi2,fma4,fma"
665 (const_string "base"))
666
667 (define_attr "enabled" ""
668 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
669 (eq_attr "isa" "x64_sse4")
670 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
671 (eq_attr "isa" "x64_sse4_noavx")
672 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
673 (eq_attr "isa" "x64_avx")
674 (symbol_ref "TARGET_64BIT && TARGET_AVX")
675 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
676 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
677 (eq_attr "isa" "sse2_noavx")
678 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
679 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
680 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
681 (eq_attr "isa" "sse4_noavx")
682 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
683 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
684 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
685 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
686 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
687 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
688 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
689 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
690 ]
691 (const_int 1)))
692
693 ;; Describe a user's asm statement.
694 (define_asm_attributes
695 [(set_attr "length" "128")
696 (set_attr "type" "multi")])
697
698 (define_code_iterator plusminus [plus minus])
699
700 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
701
702 ;; Base name for define_insn
703 (define_code_attr plusminus_insn
704 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
705 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
706
707 ;; Base name for insn mnemonic.
708 (define_code_attr plusminus_mnemonic
709 [(plus "add") (ss_plus "adds") (us_plus "addus")
710 (minus "sub") (ss_minus "subs") (us_minus "subus")])
711 (define_code_attr plusminus_carry_mnemonic
712 [(plus "adc") (minus "sbb")])
713
714 ;; Mark commutative operators as such in constraints.
715 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
716 (minus "") (ss_minus "") (us_minus "")])
717
718 ;; Mapping of max and min
719 (define_code_iterator maxmin [smax smin umax umin])
720
721 ;; Mapping of signed max and min
722 (define_code_iterator smaxmin [smax smin])
723
724 ;; Mapping of unsigned max and min
725 (define_code_iterator umaxmin [umax umin])
726
727 ;; Base name for integer and FP insn mnemonic
728 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
729 (umax "maxu") (umin "minu")])
730 (define_code_attr maxmin_float [(smax "max") (smin "min")])
731
732 ;; Mapping of logic operators
733 (define_code_iterator any_logic [and ior xor])
734 (define_code_iterator any_or [ior xor])
735
736 ;; Base name for insn mnemonic.
737 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
738
739 ;; Mapping of logic-shift operators
740 (define_code_iterator any_lshift [ashift lshiftrt])
741
742 ;; Mapping of shift-right operators
743 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
744
745 ;; Mapping of all shift operators
746 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
747
748 ;; Base name for define_insn
749 (define_code_attr shift_insn
750 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
751
752 ;; Base name for insn mnemonic.
753 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
754 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
755
756 ;; Mapping of rotate operators
757 (define_code_iterator any_rotate [rotate rotatert])
758
759 ;; Base name for define_insn
760 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
761
762 ;; Base name for insn mnemonic.
763 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
764
765 ;; Mapping of abs neg operators
766 (define_code_iterator absneg [abs neg])
767
768 ;; Base name for x87 insn mnemonic.
769 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
770
771 ;; Used in signed and unsigned widening multiplications.
772 (define_code_iterator any_extend [sign_extend zero_extend])
773
774 ;; Prefix for insn menmonic.
775 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
776
777 ;; Prefix for define_insn
778 (define_code_attr u [(sign_extend "") (zero_extend "u")])
779 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
780 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
781
782 ;; All integer modes.
783 (define_mode_iterator SWI1248x [QI HI SI DI])
784
785 ;; All integer modes without QImode.
786 (define_mode_iterator SWI248x [HI SI DI])
787
788 ;; All integer modes without QImode and HImode.
789 (define_mode_iterator SWI48x [SI DI])
790
791 ;; All integer modes without SImode and DImode.
792 (define_mode_iterator SWI12 [QI HI])
793
794 ;; All integer modes without DImode.
795 (define_mode_iterator SWI124 [QI HI SI])
796
797 ;; All integer modes without QImode and DImode.
798 (define_mode_iterator SWI24 [HI SI])
799
800 ;; Single word integer modes.
801 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
802
803 ;; Single word integer modes without QImode.
804 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
805
806 ;; Single word integer modes without QImode and HImode.
807 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
808
809 ;; All math-dependant single and double word integer modes.
810 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
811 (HI "TARGET_HIMODE_MATH")
812 SI DI (TI "TARGET_64BIT")])
813
814 ;; Math-dependant single word integer modes.
815 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
816 (HI "TARGET_HIMODE_MATH")
817 SI (DI "TARGET_64BIT")])
818
819 ;; Math-dependant integer modes without DImode.
820 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
821 (HI "TARGET_HIMODE_MATH")
822 SI])
823
824 ;; Math-dependant single word integer modes without QImode.
825 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
826 SI (DI "TARGET_64BIT")])
827
828 ;; Double word integer modes.
829 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
830 (TI "TARGET_64BIT")])
831
832 ;; Double word integer modes as mode attribute.
833 (define_mode_attr DWI [(SI "DI") (DI "TI")])
834 (define_mode_attr dwi [(SI "di") (DI "ti")])
835
836 ;; Half mode for double word integer modes.
837 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
838 (DI "TARGET_64BIT")])
839
840 ;; Instruction suffix for integer modes.
841 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
842
843 ;; Pointer size prefix for integer modes (Intel asm dialect)
844 (define_mode_attr iptrsize [(QI "BYTE")
845 (HI "WORD")
846 (SI "DWORD")
847 (DI "QWORD")])
848
849 ;; Register class for integer modes.
850 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
851
852 ;; Immediate operand constraint for integer modes.
853 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
854
855 ;; General operand constraint for word modes.
856 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
857
858 ;; Immediate operand constraint for double integer modes.
859 (define_mode_attr di [(SI "nF") (DI "e")])
860
861 ;; Immediate operand constraint for shifts.
862 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
863
864 ;; General operand predicate for integer modes.
865 (define_mode_attr general_operand
866 [(QI "general_operand")
867 (HI "general_operand")
868 (SI "x86_64_general_operand")
869 (DI "x86_64_general_operand")
870 (TI "x86_64_general_operand")])
871
872 ;; General sign/zero extend operand predicate for integer modes.
873 (define_mode_attr general_szext_operand
874 [(QI "general_operand")
875 (HI "general_operand")
876 (SI "x86_64_szext_general_operand")
877 (DI "x86_64_szext_general_operand")])
878
879 ;; Immediate operand predicate for integer modes.
880 (define_mode_attr immediate_operand
881 [(QI "immediate_operand")
882 (HI "immediate_operand")
883 (SI "x86_64_immediate_operand")
884 (DI "x86_64_immediate_operand")])
885
886 ;; Nonmemory operand predicate for integer modes.
887 (define_mode_attr nonmemory_operand
888 [(QI "nonmemory_operand")
889 (HI "nonmemory_operand")
890 (SI "x86_64_nonmemory_operand")
891 (DI "x86_64_nonmemory_operand")])
892
893 ;; Operand predicate for shifts.
894 (define_mode_attr shift_operand
895 [(QI "nonimmediate_operand")
896 (HI "nonimmediate_operand")
897 (SI "nonimmediate_operand")
898 (DI "shiftdi_operand")
899 (TI "register_operand")])
900
901 ;; Operand predicate for shift argument.
902 (define_mode_attr shift_immediate_operand
903 [(QI "const_1_to_31_operand")
904 (HI "const_1_to_31_operand")
905 (SI "const_1_to_31_operand")
906 (DI "const_1_to_63_operand")])
907
908 ;; Input operand predicate for arithmetic left shifts.
909 (define_mode_attr ashl_input_operand
910 [(QI "nonimmediate_operand")
911 (HI "nonimmediate_operand")
912 (SI "nonimmediate_operand")
913 (DI "ashldi_input_operand")
914 (TI "reg_or_pm1_operand")])
915
916 ;; SSE and x87 SFmode and DFmode floating point modes
917 (define_mode_iterator MODEF [SF DF])
918
919 ;; All x87 floating point modes
920 (define_mode_iterator X87MODEF [SF DF XF])
921
922 ;; SSE instruction suffix for various modes
923 (define_mode_attr ssemodesuffix
924 [(SF "ss") (DF "sd")
925 (V8SF "ps") (V4DF "pd")
926 (V4SF "ps") (V2DF "pd")
927 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
928 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
929
930 ;; SSE vector suffix for floating point modes
931 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
932
933 ;; SSE vector mode corresponding to a scalar mode
934 (define_mode_attr ssevecmode
935 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
936 (define_mode_attr ssevecmodelower
937 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
938
939 ;; Instruction suffix for REX 64bit operators.
940 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
941
942 ;; This mode iterator allows :P to be used for patterns that operate on
943 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
944 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
945
946 ;; This mode iterator allows :W to be used for patterns that operate on
947 ;; word_mode sized quantities.
948 (define_mode_iterator W
949 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
950
951 ;; This mode iterator allows :PTR to be used for patterns that operate on
952 ;; ptr_mode sized quantities.
953 (define_mode_iterator PTR
954 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
955 \f
956 ;; Scheduling descriptions
957
958 (include "pentium.md")
959 (include "ppro.md")
960 (include "k6.md")
961 (include "athlon.md")
962 (include "bdver1.md")
963 (include "bdver3.md")
964 (include "btver2.md")
965 (include "geode.md")
966 (include "atom.md")
967 (include "slm.md")
968 (include "core2.md")
969
970 \f
971 ;; Operand and operator predicates and constraints
972
973 (include "predicates.md")
974 (include "constraints.md")
975
976 \f
977 ;; Compare and branch/compare and store instructions.
978
979 (define_expand "cbranch<mode>4"
980 [(set (reg:CC FLAGS_REG)
981 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
982 (match_operand:SDWIM 2 "<general_operand>")))
983 (set (pc) (if_then_else
984 (match_operator 0 "ordered_comparison_operator"
985 [(reg:CC FLAGS_REG) (const_int 0)])
986 (label_ref (match_operand 3))
987 (pc)))]
988 ""
989 {
990 if (MEM_P (operands[1]) && MEM_P (operands[2]))
991 operands[1] = force_reg (<MODE>mode, operands[1]);
992 ix86_expand_branch (GET_CODE (operands[0]),
993 operands[1], operands[2], operands[3]);
994 DONE;
995 })
996
997 (define_expand "cstore<mode>4"
998 [(set (reg:CC FLAGS_REG)
999 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1000 (match_operand:SWIM 3 "<general_operand>")))
1001 (set (match_operand:QI 0 "register_operand")
1002 (match_operator 1 "ordered_comparison_operator"
1003 [(reg:CC FLAGS_REG) (const_int 0)]))]
1004 ""
1005 {
1006 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1007 operands[2] = force_reg (<MODE>mode, operands[2]);
1008 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1009 operands[2], operands[3]);
1010 DONE;
1011 })
1012
1013 (define_expand "cmp<mode>_1"
1014 [(set (reg:CC FLAGS_REG)
1015 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1016 (match_operand:SWI48 1 "<general_operand>")))])
1017
1018 (define_insn "*cmp<mode>_ccno_1"
1019 [(set (reg FLAGS_REG)
1020 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1021 (match_operand:SWI 1 "const0_operand")))]
1022 "ix86_match_ccmode (insn, CCNOmode)"
1023 "@
1024 test{<imodesuffix>}\t%0, %0
1025 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1026 [(set_attr "type" "test,icmp")
1027 (set_attr "length_immediate" "0,1")
1028 (set_attr "mode" "<MODE>")])
1029
1030 (define_insn "*cmp<mode>_1"
1031 [(set (reg FLAGS_REG)
1032 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1033 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1034 "ix86_match_ccmode (insn, CCmode)"
1035 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "<MODE>")])
1038
1039 (define_insn "*cmp<mode>_minus_1"
1040 [(set (reg FLAGS_REG)
1041 (compare
1042 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1043 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1044 (const_int 0)))]
1045 "ix86_match_ccmode (insn, CCGOCmode)"
1046 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1047 [(set_attr "type" "icmp")
1048 (set_attr "mode" "<MODE>")])
1049
1050 (define_insn "*cmpqi_ext_1"
1051 [(set (reg FLAGS_REG)
1052 (compare
1053 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1054 (subreg:QI
1055 (zero_extract:SI
1056 (match_operand 1 "ext_register_operand" "Q,Q")
1057 (const_int 8)
1058 (const_int 8)) 0)))]
1059 "ix86_match_ccmode (insn, CCmode)"
1060 "cmp{b}\t{%h1, %0|%0, %h1}"
1061 [(set_attr "isa" "*,nox64")
1062 (set_attr "type" "icmp")
1063 (set_attr "mode" "QI")])
1064
1065 (define_insn "*cmpqi_ext_2"
1066 [(set (reg FLAGS_REG)
1067 (compare
1068 (subreg:QI
1069 (zero_extract:SI
1070 (match_operand 0 "ext_register_operand" "Q")
1071 (const_int 8)
1072 (const_int 8)) 0)
1073 (match_operand:QI 1 "const0_operand")))]
1074 "ix86_match_ccmode (insn, CCNOmode)"
1075 "test{b}\t%h0, %h0"
1076 [(set_attr "type" "test")
1077 (set_attr "length_immediate" "0")
1078 (set_attr "mode" "QI")])
1079
1080 (define_expand "cmpqi_ext_3"
1081 [(set (reg:CC FLAGS_REG)
1082 (compare:CC
1083 (subreg:QI
1084 (zero_extract:SI
1085 (match_operand 0 "ext_register_operand")
1086 (const_int 8)
1087 (const_int 8)) 0)
1088 (match_operand:QI 1 "const_int_operand")))])
1089
1090 (define_insn "*cmpqi_ext_3"
1091 [(set (reg FLAGS_REG)
1092 (compare
1093 (subreg:QI
1094 (zero_extract:SI
1095 (match_operand 0 "ext_register_operand" "Q,Q")
1096 (const_int 8)
1097 (const_int 8)) 0)
1098 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1099 "ix86_match_ccmode (insn, CCmode)"
1100 "cmp{b}\t{%1, %h0|%h0, %1}"
1101 [(set_attr "isa" "*,nox64")
1102 (set_attr "type" "icmp")
1103 (set_attr "modrm" "1")
1104 (set_attr "mode" "QI")])
1105
1106 (define_insn "*cmpqi_ext_4"
1107 [(set (reg FLAGS_REG)
1108 (compare
1109 (subreg:QI
1110 (zero_extract:SI
1111 (match_operand 0 "ext_register_operand" "Q")
1112 (const_int 8)
1113 (const_int 8)) 0)
1114 (subreg:QI
1115 (zero_extract:SI
1116 (match_operand 1 "ext_register_operand" "Q")
1117 (const_int 8)
1118 (const_int 8)) 0)))]
1119 "ix86_match_ccmode (insn, CCmode)"
1120 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1121 [(set_attr "type" "icmp")
1122 (set_attr "mode" "QI")])
1123
1124 ;; These implement float point compares.
1125 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1126 ;; which would allow mix and match FP modes on the compares. Which is what
1127 ;; the old patterns did, but with many more of them.
1128
1129 (define_expand "cbranchxf4"
1130 [(set (reg:CC FLAGS_REG)
1131 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1132 (match_operand:XF 2 "nonmemory_operand")))
1133 (set (pc) (if_then_else
1134 (match_operator 0 "ix86_fp_comparison_operator"
1135 [(reg:CC FLAGS_REG)
1136 (const_int 0)])
1137 (label_ref (match_operand 3))
1138 (pc)))]
1139 "TARGET_80387"
1140 {
1141 ix86_expand_branch (GET_CODE (operands[0]),
1142 operands[1], operands[2], operands[3]);
1143 DONE;
1144 })
1145
1146 (define_expand "cstorexf4"
1147 [(set (reg:CC FLAGS_REG)
1148 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1149 (match_operand:XF 3 "nonmemory_operand")))
1150 (set (match_operand:QI 0 "register_operand")
1151 (match_operator 1 "ix86_fp_comparison_operator"
1152 [(reg:CC FLAGS_REG)
1153 (const_int 0)]))]
1154 "TARGET_80387"
1155 {
1156 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1157 operands[2], operands[3]);
1158 DONE;
1159 })
1160
1161 (define_expand "cbranch<mode>4"
1162 [(set (reg:CC FLAGS_REG)
1163 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1164 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1165 (set (pc) (if_then_else
1166 (match_operator 0 "ix86_fp_comparison_operator"
1167 [(reg:CC FLAGS_REG)
1168 (const_int 0)])
1169 (label_ref (match_operand 3))
1170 (pc)))]
1171 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1172 {
1173 ix86_expand_branch (GET_CODE (operands[0]),
1174 operands[1], operands[2], operands[3]);
1175 DONE;
1176 })
1177
1178 (define_expand "cstore<mode>4"
1179 [(set (reg:CC FLAGS_REG)
1180 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1181 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1182 (set (match_operand:QI 0 "register_operand")
1183 (match_operator 1 "ix86_fp_comparison_operator"
1184 [(reg:CC FLAGS_REG)
1185 (const_int 0)]))]
1186 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1187 {
1188 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1189 operands[2], operands[3]);
1190 DONE;
1191 })
1192
1193 (define_expand "cbranchcc4"
1194 [(set (pc) (if_then_else
1195 (match_operator 0 "comparison_operator"
1196 [(match_operand 1 "flags_reg_operand")
1197 (match_operand 2 "const0_operand")])
1198 (label_ref (match_operand 3))
1199 (pc)))]
1200 ""
1201 {
1202 ix86_expand_branch (GET_CODE (operands[0]),
1203 operands[1], operands[2], operands[3]);
1204 DONE;
1205 })
1206
1207 (define_expand "cstorecc4"
1208 [(set (match_operand:QI 0 "register_operand")
1209 (match_operator 1 "comparison_operator"
1210 [(match_operand 2 "flags_reg_operand")
1211 (match_operand 3 "const0_operand")]))]
1212 ""
1213 {
1214 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1215 operands[2], operands[3]);
1216 DONE;
1217 })
1218
1219
1220 ;; FP compares, step 1:
1221 ;; Set the FP condition codes.
1222 ;;
1223 ;; CCFPmode compare with exceptions
1224 ;; CCFPUmode compare with no exceptions
1225
1226 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1227 ;; used to manage the reg stack popping would not be preserved.
1228
1229 (define_insn "*cmp<mode>_0_i387"
1230 [(set (match_operand:HI 0 "register_operand" "=a")
1231 (unspec:HI
1232 [(compare:CCFP
1233 (match_operand:X87MODEF 1 "register_operand" "f")
1234 (match_operand:X87MODEF 2 "const0_operand"))]
1235 UNSPEC_FNSTSW))]
1236 "TARGET_80387"
1237 "* return output_fp_compare (insn, operands, false, false);"
1238 [(set_attr "type" "multi")
1239 (set_attr "unit" "i387")
1240 (set_attr "mode" "<MODE>")])
1241
1242 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1243 [(set (reg:CCFP FLAGS_REG)
1244 (compare:CCFP
1245 (match_operand:X87MODEF 1 "register_operand" "f")
1246 (match_operand:X87MODEF 2 "const0_operand")))
1247 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1248 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1249 "#"
1250 "&& reload_completed"
1251 [(set (match_dup 0)
1252 (unspec:HI
1253 [(compare:CCFP (match_dup 1)(match_dup 2))]
1254 UNSPEC_FNSTSW))
1255 (set (reg:CC FLAGS_REG)
1256 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1257 ""
1258 [(set_attr "type" "multi")
1259 (set_attr "unit" "i387")
1260 (set_attr "mode" "<MODE>")])
1261
1262 (define_insn "*cmpxf_i387"
1263 [(set (match_operand:HI 0 "register_operand" "=a")
1264 (unspec:HI
1265 [(compare:CCFP
1266 (match_operand:XF 1 "register_operand" "f")
1267 (match_operand:XF 2 "register_operand" "f"))]
1268 UNSPEC_FNSTSW))]
1269 "TARGET_80387"
1270 "* return output_fp_compare (insn, operands, false, false);"
1271 [(set_attr "type" "multi")
1272 (set_attr "unit" "i387")
1273 (set_attr "mode" "XF")])
1274
1275 (define_insn_and_split "*cmpxf_cc_i387"
1276 [(set (reg:CCFP FLAGS_REG)
1277 (compare:CCFP
1278 (match_operand:XF 1 "register_operand" "f")
1279 (match_operand:XF 2 "register_operand" "f")))
1280 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1281 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1282 "#"
1283 "&& reload_completed"
1284 [(set (match_dup 0)
1285 (unspec:HI
1286 [(compare:CCFP (match_dup 1)(match_dup 2))]
1287 UNSPEC_FNSTSW))
1288 (set (reg:CC FLAGS_REG)
1289 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1290 ""
1291 [(set_attr "type" "multi")
1292 (set_attr "unit" "i387")
1293 (set_attr "mode" "XF")])
1294
1295 (define_insn "*cmp<mode>_i387"
1296 [(set (match_operand:HI 0 "register_operand" "=a")
1297 (unspec:HI
1298 [(compare:CCFP
1299 (match_operand:MODEF 1 "register_operand" "f")
1300 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1301 UNSPEC_FNSTSW))]
1302 "TARGET_80387"
1303 "* return output_fp_compare (insn, operands, false, false);"
1304 [(set_attr "type" "multi")
1305 (set_attr "unit" "i387")
1306 (set_attr "mode" "<MODE>")])
1307
1308 (define_insn_and_split "*cmp<mode>_cc_i387"
1309 [(set (reg:CCFP FLAGS_REG)
1310 (compare:CCFP
1311 (match_operand:MODEF 1 "register_operand" "f")
1312 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1313 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1314 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1315 "#"
1316 "&& reload_completed"
1317 [(set (match_dup 0)
1318 (unspec:HI
1319 [(compare:CCFP (match_dup 1)(match_dup 2))]
1320 UNSPEC_FNSTSW))
1321 (set (reg:CC FLAGS_REG)
1322 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1323 ""
1324 [(set_attr "type" "multi")
1325 (set_attr "unit" "i387")
1326 (set_attr "mode" "<MODE>")])
1327
1328 (define_insn "*cmpu<mode>_i387"
1329 [(set (match_operand:HI 0 "register_operand" "=a")
1330 (unspec:HI
1331 [(compare:CCFPU
1332 (match_operand:X87MODEF 1 "register_operand" "f")
1333 (match_operand:X87MODEF 2 "register_operand" "f"))]
1334 UNSPEC_FNSTSW))]
1335 "TARGET_80387"
1336 "* return output_fp_compare (insn, operands, false, true);"
1337 [(set_attr "type" "multi")
1338 (set_attr "unit" "i387")
1339 (set_attr "mode" "<MODE>")])
1340
1341 (define_insn_and_split "*cmpu<mode>_cc_i387"
1342 [(set (reg:CCFPU FLAGS_REG)
1343 (compare:CCFPU
1344 (match_operand:X87MODEF 1 "register_operand" "f")
1345 (match_operand:X87MODEF 2 "register_operand" "f")))
1346 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1347 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1348 "#"
1349 "&& reload_completed"
1350 [(set (match_dup 0)
1351 (unspec:HI
1352 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1353 UNSPEC_FNSTSW))
1354 (set (reg:CC FLAGS_REG)
1355 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1356 ""
1357 [(set_attr "type" "multi")
1358 (set_attr "unit" "i387")
1359 (set_attr "mode" "<MODE>")])
1360
1361 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1362 [(set (match_operand:HI 0 "register_operand" "=a")
1363 (unspec:HI
1364 [(compare:CCFP
1365 (match_operand:X87MODEF 1 "register_operand" "f")
1366 (match_operator:X87MODEF 3 "float_operator"
1367 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1368 UNSPEC_FNSTSW))]
1369 "TARGET_80387
1370 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1371 || optimize_function_for_size_p (cfun))"
1372 "* return output_fp_compare (insn, operands, false, false);"
1373 [(set_attr "type" "multi")
1374 (set_attr "unit" "i387")
1375 (set_attr "fp_int_src" "true")
1376 (set_attr "mode" "<SWI24:MODE>")])
1377
1378 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1379 [(set (reg:CCFP FLAGS_REG)
1380 (compare:CCFP
1381 (match_operand:X87MODEF 1 "register_operand" "f")
1382 (match_operator:X87MODEF 3 "float_operator"
1383 [(match_operand:SWI24 2 "memory_operand" "m")])))
1384 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1385 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1386 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1387 || optimize_function_for_size_p (cfun))"
1388 "#"
1389 "&& reload_completed"
1390 [(set (match_dup 0)
1391 (unspec:HI
1392 [(compare:CCFP
1393 (match_dup 1)
1394 (match_op_dup 3 [(match_dup 2)]))]
1395 UNSPEC_FNSTSW))
1396 (set (reg:CC FLAGS_REG)
1397 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1398 ""
1399 [(set_attr "type" "multi")
1400 (set_attr "unit" "i387")
1401 (set_attr "fp_int_src" "true")
1402 (set_attr "mode" "<SWI24:MODE>")])
1403
1404 ;; FP compares, step 2
1405 ;; Move the fpsw to ax.
1406
1407 (define_insn "x86_fnstsw_1"
1408 [(set (match_operand:HI 0 "register_operand" "=a")
1409 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1410 "TARGET_80387"
1411 "fnstsw\t%0"
1412 [(set (attr "length")
1413 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1414 (set_attr "mode" "SI")
1415 (set_attr "unit" "i387")])
1416
1417 ;; FP compares, step 3
1418 ;; Get ax into flags, general case.
1419
1420 (define_insn "x86_sahf_1"
1421 [(set (reg:CC FLAGS_REG)
1422 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1423 UNSPEC_SAHF))]
1424 "TARGET_SAHF"
1425 {
1426 #ifndef HAVE_AS_IX86_SAHF
1427 if (TARGET_64BIT)
1428 return ASM_BYTE "0x9e";
1429 else
1430 #endif
1431 return "sahf";
1432 }
1433 [(set_attr "length" "1")
1434 (set_attr "athlon_decode" "vector")
1435 (set_attr "amdfam10_decode" "direct")
1436 (set_attr "bdver1_decode" "direct")
1437 (set_attr "mode" "SI")])
1438
1439 ;; Pentium Pro can do steps 1 through 3 in one go.
1440 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1441 ;; (these i387 instructions set flags directly)
1442
1443 (define_mode_iterator FPCMP [CCFP CCFPU])
1444 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1445
1446 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1447 [(set (reg:FPCMP FLAGS_REG)
1448 (compare:FPCMP
1449 (match_operand:MODEF 0 "register_operand" "f,x")
1450 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1451 "TARGET_MIX_SSE_I387
1452 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1453 "* return output_fp_compare (insn, operands, true,
1454 <FPCMP:MODE>mode == CCFPUmode);"
1455 [(set_attr "type" "fcmp,ssecomi")
1456 (set_attr "prefix" "orig,maybe_vex")
1457 (set_attr "mode" "<MODEF:MODE>")
1458 (set (attr "prefix_rep")
1459 (if_then_else (eq_attr "type" "ssecomi")
1460 (const_string "0")
1461 (const_string "*")))
1462 (set (attr "prefix_data16")
1463 (cond [(eq_attr "type" "fcmp")
1464 (const_string "*")
1465 (eq_attr "mode" "DF")
1466 (const_string "1")
1467 ]
1468 (const_string "0")))
1469 (set_attr "athlon_decode" "vector")
1470 (set_attr "amdfam10_decode" "direct")
1471 (set_attr "bdver1_decode" "double")])
1472
1473 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1474 [(set (reg:FPCMP FLAGS_REG)
1475 (compare:FPCMP
1476 (match_operand:MODEF 0 "register_operand" "x")
1477 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1478 "TARGET_SSE_MATH
1479 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1480 "* return output_fp_compare (insn, operands, true,
1481 <FPCMP:MODE>mode == CCFPUmode);"
1482 [(set_attr "type" "ssecomi")
1483 (set_attr "prefix" "maybe_vex")
1484 (set_attr "mode" "<MODEF:MODE>")
1485 (set_attr "prefix_rep" "0")
1486 (set (attr "prefix_data16")
1487 (if_then_else (eq_attr "mode" "DF")
1488 (const_string "1")
1489 (const_string "0")))
1490 (set_attr "athlon_decode" "vector")
1491 (set_attr "amdfam10_decode" "direct")
1492 (set_attr "bdver1_decode" "double")])
1493
1494 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1495 [(set (reg:FPCMP FLAGS_REG)
1496 (compare:FPCMP
1497 (match_operand:X87MODEF 0 "register_operand" "f")
1498 (match_operand:X87MODEF 1 "register_operand" "f")))]
1499 "TARGET_80387 && TARGET_CMOVE
1500 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1501 "* return output_fp_compare (insn, operands, true,
1502 <FPCMP:MODE>mode == CCFPUmode);"
1503 [(set_attr "type" "fcmp")
1504 (set_attr "mode" "<X87MODEF:MODE>")
1505 (set_attr "athlon_decode" "vector")
1506 (set_attr "amdfam10_decode" "direct")
1507 (set_attr "bdver1_decode" "double")])
1508 \f
1509 ;; Push/pop instructions.
1510
1511 (define_insn "*push<mode>2"
1512 [(set (match_operand:DWI 0 "push_operand" "=<")
1513 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1514 ""
1515 "#"
1516 [(set_attr "type" "multi")
1517 (set_attr "mode" "<MODE>")])
1518
1519 (define_split
1520 [(set (match_operand:TI 0 "push_operand")
1521 (match_operand:TI 1 "general_operand"))]
1522 "TARGET_64BIT && reload_completed
1523 && !SSE_REG_P (operands[1])"
1524 [(const_int 0)]
1525 "ix86_split_long_move (operands); DONE;")
1526
1527 (define_insn "*pushdi2_rex64"
1528 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1529 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1530 "TARGET_64BIT"
1531 "@
1532 push{q}\t%1
1533 #"
1534 [(set_attr "type" "push,multi")
1535 (set_attr "mode" "DI")])
1536
1537 ;; Convert impossible pushes of immediate to existing instructions.
1538 ;; First try to get scratch register and go through it. In case this
1539 ;; fails, push sign extended lower part first and then overwrite
1540 ;; upper part by 32bit move.
1541 (define_peephole2
1542 [(match_scratch:DI 2 "r")
1543 (set (match_operand:DI 0 "push_operand")
1544 (match_operand:DI 1 "immediate_operand"))]
1545 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1546 && !x86_64_immediate_operand (operands[1], DImode)"
1547 [(set (match_dup 2) (match_dup 1))
1548 (set (match_dup 0) (match_dup 2))])
1549
1550 ;; We need to define this as both peepholer and splitter for case
1551 ;; peephole2 pass is not run.
1552 ;; "&& 1" is needed to keep it from matching the previous pattern.
1553 (define_peephole2
1554 [(set (match_operand:DI 0 "push_operand")
1555 (match_operand:DI 1 "immediate_operand"))]
1556 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1557 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1558 [(set (match_dup 0) (match_dup 1))
1559 (set (match_dup 2) (match_dup 3))]
1560 {
1561 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1562
1563 operands[1] = gen_lowpart (DImode, operands[2]);
1564 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1565 GEN_INT (4)));
1566 })
1567
1568 (define_split
1569 [(set (match_operand:DI 0 "push_operand")
1570 (match_operand:DI 1 "immediate_operand"))]
1571 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1572 ? epilogue_completed : reload_completed)
1573 && !symbolic_operand (operands[1], DImode)
1574 && !x86_64_immediate_operand (operands[1], DImode)"
1575 [(set (match_dup 0) (match_dup 1))
1576 (set (match_dup 2) (match_dup 3))]
1577 {
1578 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1579
1580 operands[1] = gen_lowpart (DImode, operands[2]);
1581 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1582 GEN_INT (4)));
1583 })
1584
1585 (define_split
1586 [(set (match_operand:DI 0 "push_operand")
1587 (match_operand:DI 1 "general_operand"))]
1588 "!TARGET_64BIT && reload_completed
1589 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1590 [(const_int 0)]
1591 "ix86_split_long_move (operands); DONE;")
1592
1593 (define_insn "*pushsi2"
1594 [(set (match_operand:SI 0 "push_operand" "=<")
1595 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1596 "!TARGET_64BIT"
1597 "push{l}\t%1"
1598 [(set_attr "type" "push")
1599 (set_attr "mode" "SI")])
1600
1601 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1602 ;; "push a byte/word". But actually we use pushl, which has the effect
1603 ;; of rounding the amount pushed up to a word.
1604
1605 ;; For TARGET_64BIT we always round up to 8 bytes.
1606 (define_insn "*push<mode>2_rex64"
1607 [(set (match_operand:SWI124 0 "push_operand" "=X")
1608 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1609 "TARGET_64BIT"
1610 "push{q}\t%q1"
1611 [(set_attr "type" "push")
1612 (set_attr "mode" "DI")])
1613
1614 (define_insn "*push<mode>2"
1615 [(set (match_operand:SWI12 0 "push_operand" "=X")
1616 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1617 "!TARGET_64BIT"
1618 "push{l}\t%k1"
1619 [(set_attr "type" "push")
1620 (set_attr "mode" "SI")])
1621
1622 (define_insn "*push<mode>2_prologue"
1623 [(set (match_operand:W 0 "push_operand" "=<")
1624 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1625 (clobber (mem:BLK (scratch)))]
1626 ""
1627 "push{<imodesuffix>}\t%1"
1628 [(set_attr "type" "push")
1629 (set_attr "mode" "<MODE>")])
1630
1631 (define_insn "*pop<mode>1"
1632 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1633 (match_operand:W 1 "pop_operand" ">"))]
1634 ""
1635 "pop{<imodesuffix>}\t%0"
1636 [(set_attr "type" "pop")
1637 (set_attr "mode" "<MODE>")])
1638
1639 (define_insn "*pop<mode>1_epilogue"
1640 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1641 (match_operand:W 1 "pop_operand" ">"))
1642 (clobber (mem:BLK (scratch)))]
1643 ""
1644 "pop{<imodesuffix>}\t%0"
1645 [(set_attr "type" "pop")
1646 (set_attr "mode" "<MODE>")])
1647 \f
1648 ;; Move instructions.
1649
1650 ;; Reload patterns to support multi-word load/store
1651 ;; with non-offsetable address.
1652 (define_expand "reload_noff_store"
1653 [(parallel [(match_operand 0 "memory_operand" "=m")
1654 (match_operand 1 "register_operand" "r")
1655 (match_operand:DI 2 "register_operand" "=&r")])]
1656 "TARGET_64BIT"
1657 {
1658 rtx mem = operands[0];
1659 rtx addr = XEXP (mem, 0);
1660
1661 emit_move_insn (operands[2], addr);
1662 mem = replace_equiv_address_nv (mem, operands[2]);
1663
1664 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1665 DONE;
1666 })
1667
1668 (define_expand "reload_noff_load"
1669 [(parallel [(match_operand 0 "register_operand" "=r")
1670 (match_operand 1 "memory_operand" "m")
1671 (match_operand:DI 2 "register_operand" "=r")])]
1672 "TARGET_64BIT"
1673 {
1674 rtx mem = operands[1];
1675 rtx addr = XEXP (mem, 0);
1676
1677 emit_move_insn (operands[2], addr);
1678 mem = replace_equiv_address_nv (mem, operands[2]);
1679
1680 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1681 DONE;
1682 })
1683
1684 (define_expand "movoi"
1685 [(set (match_operand:OI 0 "nonimmediate_operand")
1686 (match_operand:OI 1 "general_operand"))]
1687 "TARGET_AVX"
1688 "ix86_expand_move (OImode, operands); DONE;")
1689
1690 (define_expand "movti"
1691 [(set (match_operand:TI 0 "nonimmediate_operand")
1692 (match_operand:TI 1 "nonimmediate_operand"))]
1693 "TARGET_64BIT || TARGET_SSE"
1694 {
1695 if (TARGET_64BIT)
1696 ix86_expand_move (TImode, operands);
1697 else if (push_operand (operands[0], TImode))
1698 ix86_expand_push (TImode, operands[1]);
1699 else
1700 ix86_expand_vector_move (TImode, operands);
1701 DONE;
1702 })
1703
1704 ;; This expands to what emit_move_complex would generate if we didn't
1705 ;; have a movti pattern. Having this avoids problems with reload on
1706 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1707 ;; to have around all the time.
1708 (define_expand "movcdi"
1709 [(set (match_operand:CDI 0 "nonimmediate_operand")
1710 (match_operand:CDI 1 "general_operand"))]
1711 ""
1712 {
1713 if (push_operand (operands[0], CDImode))
1714 emit_move_complex_push (CDImode, operands[0], operands[1]);
1715 else
1716 emit_move_complex_parts (operands[0], operands[1]);
1717 DONE;
1718 })
1719
1720 (define_expand "mov<mode>"
1721 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1722 (match_operand:SWI1248x 1 "general_operand"))]
1723 ""
1724 "ix86_expand_move (<MODE>mode, operands); DONE;")
1725
1726 (define_insn "*mov<mode>_xor"
1727 [(set (match_operand:SWI48 0 "register_operand" "=r")
1728 (match_operand:SWI48 1 "const0_operand"))
1729 (clobber (reg:CC FLAGS_REG))]
1730 "reload_completed"
1731 "xor{l}\t%k0, %k0"
1732 [(set_attr "type" "alu1")
1733 (set_attr "mode" "SI")
1734 (set_attr "length_immediate" "0")])
1735
1736 (define_insn "*mov<mode>_or"
1737 [(set (match_operand:SWI48 0 "register_operand" "=r")
1738 (match_operand:SWI48 1 "const_int_operand"))
1739 (clobber (reg:CC FLAGS_REG))]
1740 "reload_completed
1741 && operands[1] == constm1_rtx"
1742 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1743 [(set_attr "type" "alu1")
1744 (set_attr "mode" "<MODE>")
1745 (set_attr "length_immediate" "1")])
1746
1747 (define_insn "*movoi_internal_avx"
1748 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1749 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1750 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1751 {
1752 switch (get_attr_type (insn))
1753 {
1754 case TYPE_SSELOG1:
1755 return standard_sse_constant_opcode (insn, operands[1]);
1756
1757 case TYPE_SSEMOV:
1758 if (misaligned_operand (operands[0], OImode)
1759 || misaligned_operand (operands[1], OImode))
1760 {
1761 if (get_attr_mode (insn) == MODE_V8SF)
1762 return "vmovups\t{%1, %0|%0, %1}";
1763 else
1764 return "vmovdqu\t{%1, %0|%0, %1}";
1765 }
1766 else
1767 {
1768 if (get_attr_mode (insn) == MODE_V8SF)
1769 return "vmovaps\t{%1, %0|%0, %1}";
1770 else
1771 return "vmovdqa\t{%1, %0|%0, %1}";
1772 }
1773
1774 default:
1775 gcc_unreachable ();
1776 }
1777 }
1778 [(set_attr "type" "sselog1,ssemov,ssemov")
1779 (set_attr "prefix" "vex")
1780 (set (attr "mode")
1781 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1782 (const_string "V8SF")
1783 (and (eq_attr "alternative" "2")
1784 (match_test "TARGET_SSE_TYPELESS_STORES"))
1785 (const_string "V8SF")
1786 ]
1787 (const_string "OI")))])
1788
1789 (define_insn "*movti_internal"
1790 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1791 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1792 "(TARGET_64BIT || TARGET_SSE)
1793 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1794 {
1795 switch (get_attr_type (insn))
1796 {
1797 case TYPE_MULTI:
1798 return "#";
1799
1800 case TYPE_SSELOG1:
1801 return standard_sse_constant_opcode (insn, operands[1]);
1802
1803 case TYPE_SSEMOV:
1804 /* TDmode values are passed as TImode on the stack. Moving them
1805 to stack may result in unaligned memory access. */
1806 if (misaligned_operand (operands[0], TImode)
1807 || misaligned_operand (operands[1], TImode))
1808 {
1809 if (get_attr_mode (insn) == MODE_V4SF)
1810 return "%vmovups\t{%1, %0|%0, %1}";
1811 else
1812 return "%vmovdqu\t{%1, %0|%0, %1}";
1813 }
1814 else
1815 {
1816 if (get_attr_mode (insn) == MODE_V4SF)
1817 return "%vmovaps\t{%1, %0|%0, %1}";
1818 else
1819 return "%vmovdqa\t{%1, %0|%0, %1}";
1820 }
1821
1822 default:
1823 gcc_unreachable ();
1824 }
1825 }
1826 [(set_attr "isa" "x64,x64,*,*,*")
1827 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1828 (set (attr "prefix")
1829 (if_then_else (eq_attr "type" "sselog1,ssemov")
1830 (const_string "maybe_vex")
1831 (const_string "orig")))
1832 (set (attr "mode")
1833 (cond [(eq_attr "alternative" "0,1")
1834 (const_string "DI")
1835 (ior (not (match_test "TARGET_SSE2"))
1836 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1837 (const_string "V4SF")
1838 (and (eq_attr "alternative" "4")
1839 (match_test "TARGET_SSE_TYPELESS_STORES"))
1840 (const_string "V4SF")
1841 (match_test "TARGET_AVX")
1842 (const_string "TI")
1843 (match_test "optimize_function_for_size_p (cfun)")
1844 (const_string "V4SF")
1845 ]
1846 (const_string "TI")))])
1847
1848 (define_split
1849 [(set (match_operand:TI 0 "nonimmediate_operand")
1850 (match_operand:TI 1 "general_operand"))]
1851 "reload_completed
1852 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1853 [(const_int 0)]
1854 "ix86_split_long_move (operands); DONE;")
1855
1856 (define_insn "*movdi_internal"
1857 [(set (match_operand:DI 0 "nonimmediate_operand"
1858 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*x,*x,*x,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1859 (match_operand:DI 1 "general_operand"
1860 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*x,m ,*x,*Yj,*x,r ,*Yj ,*Yn"))]
1861 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1862 {
1863 switch (get_attr_type (insn))
1864 {
1865 case TYPE_MULTI:
1866 return "#";
1867
1868 case TYPE_MMX:
1869 return "pxor\t%0, %0";
1870
1871 case TYPE_MMXMOV:
1872 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
1873 /* Handle broken assemblers that require movd instead of movq. */
1874 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1875 return "movd\t{%1, %0|%0, %1}";
1876 #endif
1877 return "movq\t{%1, %0|%0, %1}";
1878
1879 case TYPE_SSELOG1:
1880 if (GENERAL_REG_P (operands[0]))
1881 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
1882
1883 return standard_sse_constant_opcode (insn, operands[1]);
1884
1885 case TYPE_SSEMOV:
1886 switch (get_attr_mode (insn))
1887 {
1888 case MODE_DI:
1889 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
1890 /* Handle broken assemblers that require movd instead of movq. */
1891 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1892 return "%vmovd\t{%1, %0|%0, %1}";
1893 #endif
1894 return "%vmovq\t{%1, %0|%0, %1}";
1895 case MODE_TI:
1896 return "%vmovdqa\t{%1, %0|%0, %1}";
1897
1898 case MODE_V2SF:
1899 gcc_assert (!TARGET_AVX);
1900 return "movlps\t{%1, %0|%0, %1}";
1901 case MODE_V4SF:
1902 return "%vmovaps\t{%1, %0|%0, %1}";
1903
1904 default:
1905 gcc_unreachable ();
1906 }
1907
1908 case TYPE_SSECVT:
1909 if (SSE_REG_P (operands[0]))
1910 return "movq2dq\t{%1, %0|%0, %1}";
1911 else
1912 return "movdq2q\t{%1, %0|%0, %1}";
1913
1914 case TYPE_LEA:
1915 return "lea{q}\t{%E1, %0|%0, %E1}";
1916
1917 case TYPE_IMOV:
1918 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1919 if (get_attr_mode (insn) == MODE_SI)
1920 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1921 else if (which_alternative == 4)
1922 return "movabs{q}\t{%1, %0|%0, %1}";
1923 else if (ix86_use_lea_for_mov (insn, operands))
1924 return "lea{q}\t{%E1, %0|%0, %E1}";
1925 else
1926 return "mov{q}\t{%1, %0|%0, %1}";
1927
1928 default:
1929 gcc_unreachable ();
1930 }
1931 }
1932 [(set (attr "isa")
1933 (cond [(eq_attr "alternative" "0,1")
1934 (const_string "nox64")
1935 (eq_attr "alternative" "2,3,4,5,10,11,16,18")
1936 (const_string "x64")
1937 (eq_attr "alternative" "17")
1938 (const_string "x64_sse4")
1939 ]
1940 (const_string "*")))
1941 (set (attr "type")
1942 (cond [(eq_attr "alternative" "0,1")
1943 (const_string "multi")
1944 (eq_attr "alternative" "6")
1945 (const_string "mmx")
1946 (eq_attr "alternative" "7,8,9,10,11")
1947 (const_string "mmxmov")
1948 (eq_attr "alternative" "12,17")
1949 (const_string "sselog1")
1950 (eq_attr "alternative" "13,14,15,16,18")
1951 (const_string "ssemov")
1952 (eq_attr "alternative" "19,20")
1953 (const_string "ssecvt")
1954 (match_operand 1 "pic_32bit_operand")
1955 (const_string "lea")
1956 ]
1957 (const_string "imov")))
1958 (set (attr "modrm")
1959 (if_then_else
1960 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1961 (const_string "0")
1962 (const_string "*")))
1963 (set (attr "length_immediate")
1964 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1965 (const_string "8")
1966 (eq_attr "alternative" "17")
1967 (const_string "1")
1968 ]
1969 (const_string "*")))
1970 (set (attr "prefix_rex")
1971 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
1972 (const_string "1")
1973 (const_string "*")))
1974 (set (attr "prefix_extra")
1975 (if_then_else (eq_attr "alternative" "17")
1976 (const_string "1")
1977 (const_string "*")))
1978 (set (attr "prefix")
1979 (if_then_else (eq_attr "type" "sselog1,ssemov")
1980 (const_string "maybe_vex")
1981 (const_string "orig")))
1982 (set (attr "prefix_data16")
1983 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
1984 (const_string "1")
1985 (const_string "*")))
1986 (set (attr "mode")
1987 (cond [(eq_attr "alternative" "2")
1988 (const_string "SI")
1989 (eq_attr "alternative" "12,13")
1990 (cond [(ior (not (match_test "TARGET_SSE2"))
1991 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1992 (const_string "V4SF")
1993 (match_test "TARGET_AVX")
1994 (const_string "TI")
1995 (match_test "optimize_function_for_size_p (cfun)")
1996 (const_string "V4SF")
1997 ]
1998 (const_string "TI"))
1999
2000 (and (eq_attr "alternative" "14,15")
2001 (not (match_test "TARGET_SSE2")))
2002 (const_string "V2SF")
2003 (eq_attr "alternative" "17")
2004 (const_string "TI")
2005 ]
2006 (const_string "DI")))])
2007
2008 (define_split
2009 [(set (match_operand:DI 0 "nonimmediate_operand")
2010 (match_operand:DI 1 "general_operand"))]
2011 "!TARGET_64BIT && reload_completed
2012 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2013 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2014 [(const_int 0)]
2015 "ix86_split_long_move (operands); DONE;")
2016
2017 (define_insn "*movsi_internal"
2018 [(set (match_operand:SI 0 "nonimmediate_operand"
2019 "=r,m ,*y,*y,?rm,?*y,*x,*x,*x,m ,?r ,?r,?*Yi")
2020 (match_operand:SI 1 "general_operand"
2021 "g ,re,C ,*y,*y ,rm ,C ,*x,m ,*x,*Yj,*x,r"))]
2022 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2023 {
2024 switch (get_attr_type (insn))
2025 {
2026 case TYPE_SSELOG1:
2027 if (GENERAL_REG_P (operands[0]))
2028 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2029
2030 return standard_sse_constant_opcode (insn, operands[1]);
2031
2032 case TYPE_SSEMOV:
2033 switch (get_attr_mode (insn))
2034 {
2035 case MODE_SI:
2036 return "%vmovd\t{%1, %0|%0, %1}";
2037 case MODE_TI:
2038 return "%vmovdqa\t{%1, %0|%0, %1}";
2039
2040 case MODE_V4SF:
2041 return "%vmovaps\t{%1, %0|%0, %1}";
2042
2043 case MODE_SF:
2044 gcc_assert (!TARGET_AVX);
2045 return "movss\t{%1, %0|%0, %1}";
2046
2047 default:
2048 gcc_unreachable ();
2049 }
2050
2051 case TYPE_MMX:
2052 return "pxor\t%0, %0";
2053
2054 case TYPE_MMXMOV:
2055 switch (get_attr_mode (insn))
2056 {
2057 case MODE_DI:
2058 return "movq\t{%1, %0|%0, %1}";
2059 case MODE_SI:
2060 return "movd\t{%1, %0|%0, %1}";
2061
2062 default:
2063 gcc_unreachable ();
2064 }
2065
2066 case TYPE_LEA:
2067 return "lea{l}\t{%E1, %0|%0, %E1}";
2068
2069 case TYPE_IMOV:
2070 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2071 if (ix86_use_lea_for_mov (insn, operands))
2072 return "lea{l}\t{%E1, %0|%0, %E1}";
2073 else
2074 return "mov{l}\t{%1, %0|%0, %1}";
2075
2076 default:
2077 gcc_unreachable ();
2078 }
2079 }
2080 [(set (attr "isa")
2081 (if_then_else (eq_attr "alternative" "11")
2082 (const_string "sse4")
2083 (const_string "*")))
2084 (set (attr "type")
2085 (cond [(eq_attr "alternative" "2")
2086 (const_string "mmx")
2087 (eq_attr "alternative" "3,4,5")
2088 (const_string "mmxmov")
2089 (eq_attr "alternative" "6,11")
2090 (const_string "sselog1")
2091 (eq_attr "alternative" "7,8,9,10,12")
2092 (const_string "ssemov")
2093 (match_operand 1 "pic_32bit_operand")
2094 (const_string "lea")
2095 ]
2096 (const_string "imov")))
2097 (set (attr "length_immediate")
2098 (if_then_else (eq_attr "alternative" "11")
2099 (const_string "1")
2100 (const_string "*")))
2101 (set (attr "prefix_extra")
2102 (if_then_else (eq_attr "alternative" "11")
2103 (const_string "1")
2104 (const_string "*")))
2105 (set (attr "prefix")
2106 (if_then_else (eq_attr "type" "sselog1,ssemov")
2107 (const_string "maybe_vex")
2108 (const_string "orig")))
2109 (set (attr "prefix_data16")
2110 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2111 (const_string "1")
2112 (const_string "*")))
2113 (set (attr "mode")
2114 (cond [(eq_attr "alternative" "2,3")
2115 (const_string "DI")
2116 (eq_attr "alternative" "6,7")
2117 (cond [(ior (not (match_test "TARGET_SSE2"))
2118 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2119 (const_string "V4SF")
2120 (match_test "TARGET_AVX")
2121 (const_string "TI")
2122 (match_test "optimize_function_for_size_p (cfun)")
2123 (const_string "V4SF")
2124 ]
2125 (const_string "TI"))
2126
2127 (and (eq_attr "alternative" "8,9")
2128 (not (match_test "TARGET_SSE2")))
2129 (const_string "SF")
2130 (eq_attr "alternative" "11")
2131 (const_string "TI")
2132 ]
2133 (const_string "SI")))])
2134
2135 (define_insn "*movhi_internal"
2136 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m")
2137 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn"))]
2138 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2139 {
2140 switch (get_attr_type (insn))
2141 {
2142 case TYPE_IMOVX:
2143 /* movzwl is faster than movw on p2 due to partial word stalls,
2144 though not as fast as an aligned movl. */
2145 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2146 default:
2147 if (get_attr_mode (insn) == MODE_SI)
2148 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2149 else
2150 return "mov{w}\t{%1, %0|%0, %1}";
2151 }
2152 }
2153 [(set (attr "type")
2154 (cond [(match_test "optimize_function_for_size_p (cfun)")
2155 (const_string "imov")
2156 (and (eq_attr "alternative" "0")
2157 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2158 (not (match_test "TARGET_HIMODE_MATH"))))
2159 (const_string "imov")
2160 (and (eq_attr "alternative" "1,2")
2161 (match_operand:HI 1 "aligned_operand"))
2162 (const_string "imov")
2163 (and (match_test "TARGET_MOVX")
2164 (eq_attr "alternative" "0,2"))
2165 (const_string "imovx")
2166 ]
2167 (const_string "imov")))
2168 (set (attr "mode")
2169 (cond [(eq_attr "type" "imovx")
2170 (const_string "SI")
2171 (and (eq_attr "alternative" "1,2")
2172 (match_operand:HI 1 "aligned_operand"))
2173 (const_string "SI")
2174 (and (eq_attr "alternative" "0")
2175 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2176 (not (match_test "TARGET_HIMODE_MATH"))))
2177 (const_string "SI")
2178 ]
2179 (const_string "HI")))])
2180
2181 ;; Situation is quite tricky about when to choose full sized (SImode) move
2182 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2183 ;; partial register dependency machines (such as AMD Athlon), where QImode
2184 ;; moves issue extra dependency and for partial register stalls machines
2185 ;; that don't use QImode patterns (and QImode move cause stall on the next
2186 ;; instruction).
2187 ;;
2188 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2189 ;; register stall machines with, where we use QImode instructions, since
2190 ;; partial register stall can be caused there. Then we use movzx.
2191 (define_insn "*movqi_internal"
2192 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2193 (match_operand:QI 1 "general_operand" "q ,qn,qm,q,rn,qm,qn"))]
2194 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2195 {
2196 switch (get_attr_type (insn))
2197 {
2198 case TYPE_IMOVX:
2199 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2200 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2201 default:
2202 if (get_attr_mode (insn) == MODE_SI)
2203 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2204 else
2205 return "mov{b}\t{%1, %0|%0, %1}";
2206 }
2207 }
2208 [(set (attr "type")
2209 (cond [(and (eq_attr "alternative" "5")
2210 (not (match_operand:QI 1 "aligned_operand")))
2211 (const_string "imovx")
2212 (match_test "optimize_function_for_size_p (cfun)")
2213 (const_string "imov")
2214 (and (eq_attr "alternative" "3")
2215 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2216 (not (match_test "TARGET_QIMODE_MATH"))))
2217 (const_string "imov")
2218 (eq_attr "alternative" "3,5")
2219 (const_string "imovx")
2220 (and (match_test "TARGET_MOVX")
2221 (eq_attr "alternative" "2"))
2222 (const_string "imovx")
2223 ]
2224 (const_string "imov")))
2225 (set (attr "mode")
2226 (cond [(eq_attr "alternative" "3,4,5")
2227 (const_string "SI")
2228 (eq_attr "alternative" "6")
2229 (const_string "QI")
2230 (eq_attr "type" "imovx")
2231 (const_string "SI")
2232 (and (eq_attr "type" "imov")
2233 (and (eq_attr "alternative" "0,1")
2234 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2235 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2236 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2237 (const_string "SI")
2238 ;; Avoid partial register stalls when not using QImode arithmetic
2239 (and (eq_attr "type" "imov")
2240 (and (eq_attr "alternative" "0,1")
2241 (and (match_test "TARGET_PARTIAL_REG_STALL")
2242 (not (match_test "TARGET_QIMODE_MATH")))))
2243 (const_string "SI")
2244 ]
2245 (const_string "QI")))])
2246
2247 ;; Stores and loads of ax to arbitrary constant address.
2248 ;; We fake an second form of instruction to force reload to load address
2249 ;; into register when rax is not available
2250 (define_insn "*movabs<mode>_1"
2251 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2252 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2253 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2254 "@
2255 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2256 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2257 [(set_attr "type" "imov")
2258 (set_attr "modrm" "0,*")
2259 (set_attr "length_address" "8,0")
2260 (set_attr "length_immediate" "0,*")
2261 (set_attr "memory" "store")
2262 (set_attr "mode" "<MODE>")])
2263
2264 (define_insn "*movabs<mode>_2"
2265 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2266 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2267 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2268 "@
2269 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2270 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2271 [(set_attr "type" "imov")
2272 (set_attr "modrm" "0,*")
2273 (set_attr "length_address" "8,0")
2274 (set_attr "length_immediate" "0")
2275 (set_attr "memory" "load")
2276 (set_attr "mode" "<MODE>")])
2277
2278 (define_insn "swap<mode>"
2279 [(set (match_operand:SWI48 0 "register_operand" "+r")
2280 (match_operand:SWI48 1 "register_operand" "+r"))
2281 (set (match_dup 1)
2282 (match_dup 0))]
2283 ""
2284 "xchg{<imodesuffix>}\t%1, %0"
2285 [(set_attr "type" "imov")
2286 (set_attr "mode" "<MODE>")
2287 (set_attr "pent_pair" "np")
2288 (set_attr "athlon_decode" "vector")
2289 (set_attr "amdfam10_decode" "double")
2290 (set_attr "bdver1_decode" "double")])
2291
2292 (define_insn "*swap<mode>_1"
2293 [(set (match_operand:SWI12 0 "register_operand" "+r")
2294 (match_operand:SWI12 1 "register_operand" "+r"))
2295 (set (match_dup 1)
2296 (match_dup 0))]
2297 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2298 "xchg{l}\t%k1, %k0"
2299 [(set_attr "type" "imov")
2300 (set_attr "mode" "SI")
2301 (set_attr "pent_pair" "np")
2302 (set_attr "athlon_decode" "vector")
2303 (set_attr "amdfam10_decode" "double")
2304 (set_attr "bdver1_decode" "double")])
2305
2306 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2307 ;; is disabled for AMDFAM10
2308 (define_insn "*swap<mode>_2"
2309 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2310 (match_operand:SWI12 1 "register_operand" "+<r>"))
2311 (set (match_dup 1)
2312 (match_dup 0))]
2313 "TARGET_PARTIAL_REG_STALL"
2314 "xchg{<imodesuffix>}\t%1, %0"
2315 [(set_attr "type" "imov")
2316 (set_attr "mode" "<MODE>")
2317 (set_attr "pent_pair" "np")
2318 (set_attr "athlon_decode" "vector")])
2319
2320 (define_expand "movstrict<mode>"
2321 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2322 (match_operand:SWI12 1 "general_operand"))]
2323 ""
2324 {
2325 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2326 FAIL;
2327 if (GET_CODE (operands[0]) == SUBREG
2328 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2329 FAIL;
2330 /* Don't generate memory->memory moves, go through a register */
2331 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2332 operands[1] = force_reg (<MODE>mode, operands[1]);
2333 })
2334
2335 (define_insn "*movstrict<mode>_1"
2336 [(set (strict_low_part
2337 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2338 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2339 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2340 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2341 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2342 [(set_attr "type" "imov")
2343 (set_attr "mode" "<MODE>")])
2344
2345 (define_insn "*movstrict<mode>_xor"
2346 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2347 (match_operand:SWI12 1 "const0_operand"))
2348 (clobber (reg:CC FLAGS_REG))]
2349 "reload_completed"
2350 "xor{<imodesuffix>}\t%0, %0"
2351 [(set_attr "type" "alu1")
2352 (set_attr "mode" "<MODE>")
2353 (set_attr "length_immediate" "0")])
2354
2355 (define_insn "*mov<mode>_extv_1"
2356 [(set (match_operand:SWI24 0 "register_operand" "=R")
2357 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2358 (const_int 8)
2359 (const_int 8)))]
2360 ""
2361 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2362 [(set_attr "type" "imovx")
2363 (set_attr "mode" "SI")])
2364
2365 (define_insn "*movqi_extv_1"
2366 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2367 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2368 (const_int 8)
2369 (const_int 8)))]
2370 ""
2371 {
2372 switch (get_attr_type (insn))
2373 {
2374 case TYPE_IMOVX:
2375 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2376 default:
2377 return "mov{b}\t{%h1, %0|%0, %h1}";
2378 }
2379 }
2380 [(set_attr "isa" "*,*,nox64")
2381 (set (attr "type")
2382 (if_then_else (and (match_operand:QI 0 "register_operand")
2383 (ior (not (match_operand:QI 0 "QIreg_operand"))
2384 (match_test "TARGET_MOVX")))
2385 (const_string "imovx")
2386 (const_string "imov")))
2387 (set (attr "mode")
2388 (if_then_else (eq_attr "type" "imovx")
2389 (const_string "SI")
2390 (const_string "QI")))])
2391
2392 (define_insn "*mov<mode>_extzv_1"
2393 [(set (match_operand:SWI48 0 "register_operand" "=R")
2394 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2395 (const_int 8)
2396 (const_int 8)))]
2397 ""
2398 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2399 [(set_attr "type" "imovx")
2400 (set_attr "mode" "SI")])
2401
2402 (define_insn "*movqi_extzv_2"
2403 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2404 (subreg:QI
2405 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2406 (const_int 8)
2407 (const_int 8)) 0))]
2408 ""
2409 {
2410 switch (get_attr_type (insn))
2411 {
2412 case TYPE_IMOVX:
2413 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2414 default:
2415 return "mov{b}\t{%h1, %0|%0, %h1}";
2416 }
2417 }
2418 [(set_attr "isa" "*,*,nox64")
2419 (set (attr "type")
2420 (if_then_else (and (match_operand:QI 0 "register_operand")
2421 (ior (not (match_operand:QI 0 "QIreg_operand"))
2422 (match_test "TARGET_MOVX")))
2423 (const_string "imovx")
2424 (const_string "imov")))
2425 (set (attr "mode")
2426 (if_then_else (eq_attr "type" "imovx")
2427 (const_string "SI")
2428 (const_string "QI")))])
2429
2430 (define_insn "mov<mode>_insv_1"
2431 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2432 (const_int 8)
2433 (const_int 8))
2434 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2435 ""
2436 {
2437 if (CONST_INT_P (operands[1]))
2438 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2439 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2440 }
2441 [(set_attr "isa" "*,nox64")
2442 (set_attr "type" "imov")
2443 (set_attr "mode" "QI")])
2444
2445 (define_insn "*movqi_insv_2"
2446 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2447 (const_int 8)
2448 (const_int 8))
2449 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2450 (const_int 8)))]
2451 ""
2452 "mov{b}\t{%h1, %h0|%h0, %h1}"
2453 [(set_attr "type" "imov")
2454 (set_attr "mode" "QI")])
2455 \f
2456 ;; Floating point push instructions.
2457
2458 (define_insn "*pushtf"
2459 [(set (match_operand:TF 0 "push_operand" "=<,<")
2460 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2461 "TARGET_64BIT || TARGET_SSE"
2462 {
2463 /* This insn should be already split before reg-stack. */
2464 gcc_unreachable ();
2465 }
2466 [(set_attr "isa" "*,x64")
2467 (set_attr "type" "multi")
2468 (set_attr "unit" "sse,*")
2469 (set_attr "mode" "TF,DI")])
2470
2471 ;; %%% Kill this when call knows how to work this out.
2472 (define_split
2473 [(set (match_operand:TF 0 "push_operand")
2474 (match_operand:TF 1 "sse_reg_operand"))]
2475 "TARGET_SSE && reload_completed"
2476 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2477 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2478
2479 (define_insn "*pushxf"
2480 [(set (match_operand:XF 0 "push_operand" "=<,<")
2481 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2482 ""
2483 {
2484 /* This insn should be already split before reg-stack. */
2485 gcc_unreachable ();
2486 }
2487 [(set_attr "type" "multi")
2488 (set_attr "unit" "i387,*")
2489 (set (attr "mode")
2490 (cond [(eq_attr "alternative" "1")
2491 (if_then_else (match_test "TARGET_64BIT")
2492 (const_string "DI")
2493 (const_string "SI"))
2494 ]
2495 (const_string "XF")))])
2496
2497 ;; %%% Kill this when call knows how to work this out.
2498 (define_split
2499 [(set (match_operand:XF 0 "push_operand")
2500 (match_operand:XF 1 "fp_register_operand"))]
2501 "reload_completed"
2502 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2503 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2504 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2505
2506 (define_insn "*pushdf"
2507 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2508 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2509 ""
2510 {
2511 /* This insn should be already split before reg-stack. */
2512 gcc_unreachable ();
2513 }
2514 [(set_attr "isa" "*,nox64,x64,sse2")
2515 (set_attr "type" "multi")
2516 (set_attr "unit" "i387,*,*,sse")
2517 (set_attr "mode" "DF,SI,DI,DF")])
2518
2519 ;; %%% Kill this when call knows how to work this out.
2520 (define_split
2521 [(set (match_operand:DF 0 "push_operand")
2522 (match_operand:DF 1 "any_fp_register_operand"))]
2523 "reload_completed"
2524 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2525 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2526
2527 (define_insn "*pushsf_rex64"
2528 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2529 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2530 "TARGET_64BIT"
2531 {
2532 /* Anything else should be already split before reg-stack. */
2533 gcc_assert (which_alternative == 1);
2534 return "push{q}\t%q1";
2535 }
2536 [(set_attr "type" "multi,push,multi")
2537 (set_attr "unit" "i387,*,*")
2538 (set_attr "mode" "SF,DI,SF")])
2539
2540 (define_insn "*pushsf"
2541 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2542 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2543 "!TARGET_64BIT"
2544 {
2545 /* Anything else should be already split before reg-stack. */
2546 gcc_assert (which_alternative == 1);
2547 return "push{l}\t%1";
2548 }
2549 [(set_attr "type" "multi,push,multi")
2550 (set_attr "unit" "i387,*,*")
2551 (set_attr "mode" "SF,SI,SF")])
2552
2553 ;; %%% Kill this when call knows how to work this out.
2554 (define_split
2555 [(set (match_operand:SF 0 "push_operand")
2556 (match_operand:SF 1 "any_fp_register_operand"))]
2557 "reload_completed"
2558 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2559 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2560 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2561
2562 (define_split
2563 [(set (match_operand:SF 0 "push_operand")
2564 (match_operand:SF 1 "memory_operand"))]
2565 "reload_completed
2566 && (operands[2] = find_constant_src (insn))"
2567 [(set (match_dup 0) (match_dup 2))])
2568
2569 (define_split
2570 [(set (match_operand 0 "push_operand")
2571 (match_operand 1 "general_operand"))]
2572 "reload_completed
2573 && (GET_MODE (operands[0]) == TFmode
2574 || GET_MODE (operands[0]) == XFmode
2575 || GET_MODE (operands[0]) == DFmode)
2576 && !ANY_FP_REG_P (operands[1])"
2577 [(const_int 0)]
2578 "ix86_split_long_move (operands); DONE;")
2579 \f
2580 ;; Floating point move instructions.
2581
2582 (define_expand "movtf"
2583 [(set (match_operand:TF 0 "nonimmediate_operand")
2584 (match_operand:TF 1 "nonimmediate_operand"))]
2585 "TARGET_64BIT || TARGET_SSE"
2586 "ix86_expand_move (TFmode, operands); DONE;")
2587
2588 (define_expand "mov<mode>"
2589 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2590 (match_operand:X87MODEF 1 "general_operand"))]
2591 ""
2592 "ix86_expand_move (<MODE>mode, operands); DONE;")
2593
2594 (define_insn "*movtf_internal"
2595 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2596 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2597 "(TARGET_64BIT || TARGET_SSE)
2598 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2599 && (!can_create_pseudo_p ()
2600 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2601 || GET_CODE (operands[1]) != CONST_DOUBLE
2602 || (optimize_function_for_size_p (cfun)
2603 && standard_sse_constant_p (operands[1])
2604 && !memory_operand (operands[0], TFmode))
2605 || (!TARGET_MEMORY_MISMATCH_STALL
2606 && memory_operand (operands[0], TFmode)))"
2607 {
2608 switch (get_attr_type (insn))
2609 {
2610 case TYPE_SSELOG1:
2611 return standard_sse_constant_opcode (insn, operands[1]);
2612
2613 case TYPE_SSEMOV:
2614 /* Handle misaligned load/store since we
2615 don't have movmisaligntf pattern. */
2616 if (misaligned_operand (operands[0], TFmode)
2617 || misaligned_operand (operands[1], TFmode))
2618 {
2619 if (get_attr_mode (insn) == MODE_V4SF)
2620 return "%vmovups\t{%1, %0|%0, %1}";
2621 else
2622 return "%vmovdqu\t{%1, %0|%0, %1}";
2623 }
2624 else
2625 {
2626 if (get_attr_mode (insn) == MODE_V4SF)
2627 return "%vmovaps\t{%1, %0|%0, %1}";
2628 else
2629 return "%vmovdqa\t{%1, %0|%0, %1}";
2630 }
2631
2632 case TYPE_MULTI:
2633 return "#";
2634
2635 default:
2636 gcc_unreachable ();
2637 }
2638 }
2639 [(set_attr "isa" "*,*,*,x64,x64")
2640 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2641 (set (attr "prefix")
2642 (if_then_else (eq_attr "type" "sselog1,ssemov")
2643 (const_string "maybe_vex")
2644 (const_string "orig")))
2645 (set (attr "mode")
2646 (cond [(eq_attr "alternative" "3,4")
2647 (const_string "DI")
2648 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2649 (const_string "V4SF")
2650 (and (eq_attr "alternative" "2")
2651 (match_test "TARGET_SSE_TYPELESS_STORES"))
2652 (const_string "V4SF")
2653 (match_test "TARGET_AVX")
2654 (const_string "TI")
2655 (ior (not (match_test "TARGET_SSE2"))
2656 (match_test "optimize_function_for_size_p (cfun)"))
2657 (const_string "V4SF")
2658 ]
2659 (const_string "TI")))])
2660
2661 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2662 (define_insn "*movxf_internal"
2663 [(set (match_operand:XF 0 "nonimmediate_operand"
2664 "=f,m,f,?Yx*r ,!o ,!o")
2665 (match_operand:XF 1 "general_operand"
2666 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2667 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2668 && (!can_create_pseudo_p ()
2669 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2670 || GET_CODE (operands[1]) != CONST_DOUBLE
2671 || (optimize_function_for_size_p (cfun)
2672 && standard_80387_constant_p (operands[1]) > 0
2673 && !memory_operand (operands[0], XFmode))
2674 || (!TARGET_MEMORY_MISMATCH_STALL
2675 && memory_operand (operands[0], XFmode)))"
2676 {
2677 switch (get_attr_type (insn))
2678 {
2679 case TYPE_FMOV:
2680 if (which_alternative == 2)
2681 return standard_80387_constant_opcode (operands[1]);
2682 return output_387_reg_move (insn, operands);
2683
2684 case TYPE_MULTI:
2685 return "#";
2686
2687 default:
2688 gcc_unreachable ();
2689 }
2690 }
2691 [(set_attr "isa" "*,*,*,*,nox64,x64")
2692 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2693 (set (attr "mode")
2694 (cond [(eq_attr "alternative" "3,4,5")
2695 (if_then_else (match_test "TARGET_64BIT")
2696 (const_string "DI")
2697 (const_string "SI"))
2698 ]
2699 (const_string "XF")))])
2700
2701 ;; Possible store forwarding (partial memory) stall in alternative 4.
2702 (define_insn "*movdf_internal"
2703 [(set (match_operand:DF 0 "nonimmediate_operand"
2704 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,x,x,x,m,*x,*x,*x,m ,r ,Yi")
2705 (match_operand:DF 1 "general_operand"
2706 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,x,m,x,C ,*x,m ,*x,Yj,r"))]
2707 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2708 && (!can_create_pseudo_p ()
2709 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2710 || GET_CODE (operands[1]) != CONST_DOUBLE
2711 || (optimize_function_for_size_p (cfun)
2712 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2713 && standard_80387_constant_p (operands[1]) > 0)
2714 || (TARGET_SSE2 && TARGET_SSE_MATH
2715 && standard_sse_constant_p (operands[1])))
2716 && !memory_operand (operands[0], DFmode))
2717 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2718 && memory_operand (operands[0], DFmode)))"
2719 {
2720 switch (get_attr_type (insn))
2721 {
2722 case TYPE_FMOV:
2723 if (which_alternative == 2)
2724 return standard_80387_constant_opcode (operands[1]);
2725 return output_387_reg_move (insn, operands);
2726
2727 case TYPE_MULTI:
2728 return "#";
2729
2730 case TYPE_IMOV:
2731 if (get_attr_mode (insn) == MODE_SI)
2732 return "mov{l}\t{%1, %k0|%k0, %1}";
2733 else if (which_alternative == 8)
2734 return "movabs{q}\t{%1, %0|%0, %1}";
2735 else
2736 return "mov{q}\t{%1, %0|%0, %1}";
2737
2738 case TYPE_SSELOG1:
2739 return standard_sse_constant_opcode (insn, operands[1]);
2740
2741 case TYPE_SSEMOV:
2742 switch (get_attr_mode (insn))
2743 {
2744 case MODE_DF:
2745 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2746 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2747 return "%vmovsd\t{%1, %0|%0, %1}";
2748
2749 case MODE_V4SF:
2750 return "%vmovaps\t{%1, %0|%0, %1}";
2751 case MODE_V2DF:
2752 return "%vmovapd\t{%1, %0|%0, %1}";
2753
2754 case MODE_V2SF:
2755 gcc_assert (!TARGET_AVX);
2756 return "movlps\t{%1, %0|%0, %1}";
2757 case MODE_V1DF:
2758 gcc_assert (!TARGET_AVX);
2759 return "movlpd\t{%1, %0|%0, %1}";
2760
2761 case MODE_DI:
2762 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2763 /* Handle broken assemblers that require movd instead of movq. */
2764 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2765 return "%vmovd\t{%1, %0|%0, %1}";
2766 #endif
2767 return "%vmovq\t{%1, %0|%0, %1}";
2768
2769 default:
2770 gcc_unreachable ();
2771 }
2772
2773 default:
2774 gcc_unreachable ();
2775 }
2776 }
2777 [(set (attr "isa")
2778 (cond [(eq_attr "alternative" "3,4")
2779 (const_string "nox64")
2780 (eq_attr "alternative" "5,6,7,8,17,18")
2781 (const_string "x64")
2782 (eq_attr "alternative" "9,10,11,12")
2783 (const_string "sse2")
2784 ]
2785 (const_string "*")))
2786 (set (attr "type")
2787 (cond [(eq_attr "alternative" "0,1,2")
2788 (const_string "fmov")
2789 (eq_attr "alternative" "3,4")
2790 (const_string "multi")
2791 (eq_attr "alternative" "5,6,7,8")
2792 (const_string "imov")
2793 (eq_attr "alternative" "9,13")
2794 (const_string "sselog1")
2795 ]
2796 (const_string "ssemov")))
2797 (set (attr "modrm")
2798 (if_then_else (eq_attr "alternative" "8")
2799 (const_string "0")
2800 (const_string "*")))
2801 (set (attr "length_immediate")
2802 (if_then_else (eq_attr "alternative" "8")
2803 (const_string "8")
2804 (const_string "*")))
2805 (set (attr "prefix")
2806 (if_then_else (eq_attr "type" "sselog1,ssemov")
2807 (const_string "maybe_vex")
2808 (const_string "orig")))
2809 (set (attr "prefix_data16")
2810 (if_then_else
2811 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2812 (eq_attr "mode" "V1DF"))
2813 (const_string "1")
2814 (const_string "*")))
2815 (set (attr "mode")
2816 (cond [(eq_attr "alternative" "3,4,7")
2817 (const_string "SI")
2818 (eq_attr "alternative" "5,6,8,17,18")
2819 (const_string "DI")
2820
2821 /* xorps is one byte shorter for non-AVX targets. */
2822 (eq_attr "alternative" "9,13")
2823 (cond [(not (match_test "TARGET_SSE2"))
2824 (const_string "V4SF")
2825 (match_test "TARGET_AVX")
2826 (const_string "V2DF")
2827 (match_test "optimize_function_for_size_p (cfun)")
2828 (const_string "V4SF")
2829 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2830 (const_string "TI")
2831 ]
2832 (const_string "V2DF"))
2833
2834 /* For architectures resolving dependencies on
2835 whole SSE registers use movapd to break dependency
2836 chains, otherwise use short move to avoid extra work. */
2837
2838 /* movaps is one byte shorter for non-AVX targets. */
2839 (eq_attr "alternative" "10,14")
2840 (cond [(ior (not (match_test "TARGET_SSE2"))
2841 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2842 (const_string "V4SF")
2843 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2844 (const_string "V2DF")
2845 (match_test "TARGET_AVX")
2846 (const_string "DF")
2847 (match_test "optimize_function_for_size_p (cfun)")
2848 (const_string "V4SF")
2849 ]
2850 (const_string "DF"))
2851
2852 /* For architectures resolving dependencies on register
2853 parts we may avoid extra work to zero out upper part
2854 of register. */
2855 (eq_attr "alternative" "11,15")
2856 (cond [(not (match_test "TARGET_SSE2"))
2857 (const_string "V2SF")
2858 (match_test "TARGET_AVX")
2859 (const_string "DF")
2860 (match_test "TARGET_SSE_SPLIT_REGS")
2861 (const_string "V1DF")
2862 ]
2863 (const_string "DF"))
2864
2865 (and (eq_attr "alternative" "12,16")
2866 (not (match_test "TARGET_SSE2")))
2867 (const_string "V2SF")
2868 ]
2869 (const_string "DF")))])
2870
2871 (define_insn "*movsf_internal"
2872 [(set (match_operand:SF 0 "nonimmediate_operand"
2873 "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
2874 (match_operand:SF 1 "general_operand"
2875 "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,Yj,r ,*y ,m ,*y,*Yn,r"))]
2876 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2877 && (!can_create_pseudo_p ()
2878 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2879 || GET_CODE (operands[1]) != CONST_DOUBLE
2880 || (optimize_function_for_size_p (cfun)
2881 && ((!TARGET_SSE_MATH
2882 && standard_80387_constant_p (operands[1]) > 0)
2883 || (TARGET_SSE_MATH
2884 && standard_sse_constant_p (operands[1]))))
2885 || memory_operand (operands[0], SFmode))"
2886 {
2887 switch (get_attr_type (insn))
2888 {
2889 case TYPE_FMOV:
2890 if (which_alternative == 2)
2891 return standard_80387_constant_opcode (operands[1]);
2892 return output_387_reg_move (insn, operands);
2893
2894 case TYPE_IMOV:
2895 return "mov{l}\t{%1, %0|%0, %1}";
2896
2897 case TYPE_SSELOG1:
2898 return standard_sse_constant_opcode (insn, operands[1]);
2899
2900 case TYPE_SSEMOV:
2901 switch (get_attr_mode (insn))
2902 {
2903 case MODE_SF:
2904 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2905 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
2906 return "%vmovss\t{%1, %0|%0, %1}";
2907
2908 case MODE_V4SF:
2909 return "%vmovaps\t{%1, %0|%0, %1}";
2910
2911 case MODE_SI:
2912 return "%vmovd\t{%1, %0|%0, %1}";
2913
2914 default:
2915 gcc_unreachable ();
2916 }
2917
2918 case TYPE_MMXMOV:
2919 switch (get_attr_mode (insn))
2920 {
2921 case MODE_DI:
2922 return "movq\t{%1, %0|%0, %1}";
2923 case MODE_SI:
2924 return "movd\t{%1, %0|%0, %1}";
2925
2926 default:
2927 gcc_unreachable ();
2928 }
2929
2930 default:
2931 gcc_unreachable ();
2932 }
2933 }
2934 [(set (attr "type")
2935 (cond [(eq_attr "alternative" "0,1,2")
2936 (const_string "fmov")
2937 (eq_attr "alternative" "3,4")
2938 (const_string "imov")
2939 (eq_attr "alternative" "5")
2940 (const_string "sselog1")
2941 (eq_attr "alternative" "11,12,13,14,15")
2942 (const_string "mmxmov")
2943 ]
2944 (const_string "ssemov")))
2945 (set (attr "prefix")
2946 (if_then_else (eq_attr "type" "sselog1,ssemov")
2947 (const_string "maybe_vex")
2948 (const_string "orig")))
2949 (set (attr "prefix_data16")
2950 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2951 (const_string "1")
2952 (const_string "*")))
2953 (set (attr "mode")
2954 (cond [(eq_attr "alternative" "3,4,9,10,14,15")
2955 (const_string "SI")
2956 (eq_attr "alternative" "11")
2957 (const_string "DI")
2958 (eq_attr "alternative" "5")
2959 (cond [(not (match_test "TARGET_SSE2"))
2960 (const_string "V4SF")
2961 (match_test "TARGET_AVX")
2962 (const_string "V4SF")
2963 (match_test "optimize_function_for_size_p (cfun)")
2964 (const_string "V4SF")
2965 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2966 (const_string "TI")
2967 ]
2968 (const_string "V4SF"))
2969
2970 /* For architectures resolving dependencies on
2971 whole SSE registers use APS move to break dependency
2972 chains, otherwise use short move to avoid extra work.
2973
2974 Do the same for architectures resolving dependencies on
2975 the parts. While in DF mode it is better to always handle
2976 just register parts, the SF mode is different due to lack
2977 of instructions to load just part of the register. It is
2978 better to maintain the whole registers in single format
2979 to avoid problems on using packed logical operations. */
2980 (and (eq_attr "alternative" "6")
2981 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2982 (match_test "TARGET_SSE_SPLIT_REGS")))
2983 (const_string "V4SF")
2984 ]
2985 (const_string "SF")))])
2986
2987 (define_split
2988 [(set (match_operand 0 "any_fp_register_operand")
2989 (match_operand 1 "memory_operand"))]
2990 "reload_completed
2991 && (GET_MODE (operands[0]) == TFmode
2992 || GET_MODE (operands[0]) == XFmode
2993 || GET_MODE (operands[0]) == DFmode
2994 || GET_MODE (operands[0]) == SFmode)
2995 && (operands[2] = find_constant_src (insn))"
2996 [(set (match_dup 0) (match_dup 2))]
2997 {
2998 rtx c = operands[2];
2999 int r = REGNO (operands[0]);
3000
3001 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3002 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3003 FAIL;
3004 })
3005
3006 (define_split
3007 [(set (match_operand 0 "any_fp_register_operand")
3008 (float_extend (match_operand 1 "memory_operand")))]
3009 "reload_completed
3010 && (GET_MODE (operands[0]) == TFmode
3011 || GET_MODE (operands[0]) == XFmode
3012 || GET_MODE (operands[0]) == DFmode)
3013 && (operands[2] = find_constant_src (insn))"
3014 [(set (match_dup 0) (match_dup 2))]
3015 {
3016 rtx c = operands[2];
3017 int r = REGNO (operands[0]);
3018
3019 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3020 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3021 FAIL;
3022 })
3023
3024 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3025 (define_split
3026 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3027 (match_operand:X87MODEF 1 "immediate_operand"))]
3028 "reload_completed
3029 && (standard_80387_constant_p (operands[1]) == 8
3030 || standard_80387_constant_p (operands[1]) == 9)"
3031 [(set (match_dup 0)(match_dup 1))
3032 (set (match_dup 0)
3033 (neg:X87MODEF (match_dup 0)))]
3034 {
3035 REAL_VALUE_TYPE r;
3036
3037 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3038 if (real_isnegzero (&r))
3039 operands[1] = CONST0_RTX (<MODE>mode);
3040 else
3041 operands[1] = CONST1_RTX (<MODE>mode);
3042 })
3043
3044 (define_split
3045 [(set (match_operand 0 "nonimmediate_operand")
3046 (match_operand 1 "general_operand"))]
3047 "reload_completed
3048 && (GET_MODE (operands[0]) == TFmode
3049 || GET_MODE (operands[0]) == XFmode
3050 || GET_MODE (operands[0]) == DFmode)
3051 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3052 [(const_int 0)]
3053 "ix86_split_long_move (operands); DONE;")
3054
3055 (define_insn "swapxf"
3056 [(set (match_operand:XF 0 "register_operand" "+f")
3057 (match_operand:XF 1 "register_operand" "+f"))
3058 (set (match_dup 1)
3059 (match_dup 0))]
3060 "TARGET_80387"
3061 {
3062 if (STACK_TOP_P (operands[0]))
3063 return "fxch\t%1";
3064 else
3065 return "fxch\t%0";
3066 }
3067 [(set_attr "type" "fxch")
3068 (set_attr "mode" "XF")])
3069
3070 (define_insn "*swap<mode>"
3071 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3072 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3073 (set (match_dup 1)
3074 (match_dup 0))]
3075 "TARGET_80387 || reload_completed"
3076 {
3077 if (STACK_TOP_P (operands[0]))
3078 return "fxch\t%1";
3079 else
3080 return "fxch\t%0";
3081 }
3082 [(set_attr "type" "fxch")
3083 (set_attr "mode" "<MODE>")])
3084 \f
3085 ;; Zero extension instructions
3086
3087 (define_expand "zero_extendsidi2"
3088 [(set (match_operand:DI 0 "nonimmediate_operand")
3089 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3090
3091 (define_insn "*zero_extendsidi2"
3092 [(set (match_operand:DI 0 "nonimmediate_operand"
3093 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3094 (zero_extend:DI
3095 (match_operand:SI 1 "x86_64_zext_operand"
3096 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3097 ""
3098 {
3099 switch (get_attr_type (insn))
3100 {
3101 case TYPE_IMOVX:
3102 if (ix86_use_lea_for_mov (insn, operands))
3103 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3104 else
3105 return "mov{l}\t{%1, %k0|%k0, %1}";
3106
3107 case TYPE_MULTI:
3108 return "#";
3109
3110 case TYPE_MMXMOV:
3111 return "movd\t{%1, %0|%0, %1}";
3112
3113 case TYPE_SSELOG1:
3114 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3115
3116 case TYPE_SSEMOV:
3117 if (GENERAL_REG_P (operands[0]))
3118 return "%vmovd\t{%1, %k0|%k0, %1}";
3119
3120 return "%vmovd\t{%1, %0|%0, %1}";
3121
3122 default:
3123 gcc_unreachable ();
3124 }
3125 }
3126 [(set (attr "isa")
3127 (cond [(eq_attr "alternative" "0,1,2")
3128 (const_string "nox64")
3129 (eq_attr "alternative" "3,7")
3130 (const_string "x64")
3131 (eq_attr "alternative" "8")
3132 (const_string "x64_sse4")
3133 (eq_attr "alternative" "10")
3134 (const_string "sse2")
3135 ]
3136 (const_string "*")))
3137 (set (attr "type")
3138 (cond [(eq_attr "alternative" "0,1,2,4")
3139 (const_string "multi")
3140 (eq_attr "alternative" "5,6")
3141 (const_string "mmxmov")
3142 (eq_attr "alternative" "7,9,10")
3143 (const_string "ssemov")
3144 (eq_attr "alternative" "8")
3145 (const_string "sselog1")
3146 ]
3147 (const_string "imovx")))
3148 (set (attr "prefix_extra")
3149 (if_then_else (eq_attr "alternative" "8")
3150 (const_string "1")
3151 (const_string "*")))
3152 (set (attr "length_immediate")
3153 (if_then_else (eq_attr "alternative" "8")
3154 (const_string "1")
3155 (const_string "*")))
3156 (set (attr "prefix")
3157 (if_then_else (eq_attr "type" "ssemov,sselog1")
3158 (const_string "maybe_vex")
3159 (const_string "orig")))
3160 (set (attr "prefix_0f")
3161 (if_then_else (eq_attr "type" "imovx")
3162 (const_string "0")
3163 (const_string "*")))
3164 (set (attr "mode")
3165 (cond [(eq_attr "alternative" "5,6")
3166 (const_string "DI")
3167 (eq_attr "alternative" "7,8,9")
3168 (const_string "TI")
3169 ]
3170 (const_string "SI")))])
3171
3172 (define_split
3173 [(set (match_operand:DI 0 "memory_operand")
3174 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3175 "reload_completed"
3176 [(set (match_dup 4) (const_int 0))]
3177 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3178
3179 (define_split
3180 [(set (match_operand:DI 0 "register_operand")
3181 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3182 "!TARGET_64BIT && reload_completed
3183 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3184 && true_regnum (operands[0]) == true_regnum (operands[1])"
3185 [(set (match_dup 4) (const_int 0))]
3186 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3187
3188 (define_split
3189 [(set (match_operand:DI 0 "nonimmediate_operand")
3190 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3191 "!TARGET_64BIT && reload_completed
3192 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3193 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3194 [(set (match_dup 3) (match_dup 1))
3195 (set (match_dup 4) (const_int 0))]
3196 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3197
3198 (define_insn "zero_extend<mode>di2"
3199 [(set (match_operand:DI 0 "register_operand" "=r")
3200 (zero_extend:DI
3201 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3202 "TARGET_64BIT"
3203 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3204 [(set_attr "type" "imovx")
3205 (set_attr "mode" "SI")])
3206
3207 (define_expand "zero_extend<mode>si2"
3208 [(set (match_operand:SI 0 "register_operand")
3209 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3210 ""
3211 {
3212 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3213 {
3214 operands[1] = force_reg (<MODE>mode, operands[1]);
3215 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3216 DONE;
3217 }
3218 })
3219
3220 (define_insn_and_split "zero_extend<mode>si2_and"
3221 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3222 (zero_extend:SI
3223 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3224 (clobber (reg:CC FLAGS_REG))]
3225 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3226 "#"
3227 "&& reload_completed"
3228 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3229 (clobber (reg:CC FLAGS_REG))])]
3230 {
3231 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3232 {
3233 ix86_expand_clear (operands[0]);
3234
3235 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3236 emit_insn (gen_movstrict<mode>
3237 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3238 DONE;
3239 }
3240
3241 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3242 }
3243 [(set_attr "type" "alu1")
3244 (set_attr "mode" "SI")])
3245
3246 (define_insn "*zero_extend<mode>si2"
3247 [(set (match_operand:SI 0 "register_operand" "=r")
3248 (zero_extend:SI
3249 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3250 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3251 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3252 [(set_attr "type" "imovx")
3253 (set_attr "mode" "SI")])
3254
3255 (define_expand "zero_extendqihi2"
3256 [(set (match_operand:HI 0 "register_operand")
3257 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3258 ""
3259 {
3260 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3261 {
3262 operands[1] = force_reg (QImode, operands[1]);
3263 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3264 DONE;
3265 }
3266 })
3267
3268 (define_insn_and_split "zero_extendqihi2_and"
3269 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3270 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3271 (clobber (reg:CC FLAGS_REG))]
3272 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3273 "#"
3274 "&& reload_completed"
3275 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3276 (clobber (reg:CC FLAGS_REG))])]
3277 {
3278 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3279 {
3280 ix86_expand_clear (operands[0]);
3281
3282 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3283 emit_insn (gen_movstrictqi
3284 (gen_lowpart (QImode, operands[0]), operands[1]));
3285 DONE;
3286 }
3287
3288 operands[0] = gen_lowpart (SImode, operands[0]);
3289 }
3290 [(set_attr "type" "alu1")
3291 (set_attr "mode" "SI")])
3292
3293 ; zero extend to SImode to avoid partial register stalls
3294 (define_insn "*zero_extendqihi2"
3295 [(set (match_operand:HI 0 "register_operand" "=r")
3296 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3297 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3298 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3299 [(set_attr "type" "imovx")
3300 (set_attr "mode" "SI")])
3301 \f
3302 ;; Sign extension instructions
3303
3304 (define_expand "extendsidi2"
3305 [(set (match_operand:DI 0 "register_operand")
3306 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3307 ""
3308 {
3309 if (!TARGET_64BIT)
3310 {
3311 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3312 DONE;
3313 }
3314 })
3315
3316 (define_insn "*extendsidi2_rex64"
3317 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3318 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3319 "TARGET_64BIT"
3320 "@
3321 {cltq|cdqe}
3322 movs{lq|x}\t{%1, %0|%0, %1}"
3323 [(set_attr "type" "imovx")
3324 (set_attr "mode" "DI")
3325 (set_attr "prefix_0f" "0")
3326 (set_attr "modrm" "0,1")])
3327
3328 (define_insn "extendsidi2_1"
3329 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3330 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3331 (clobber (reg:CC FLAGS_REG))
3332 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3333 "!TARGET_64BIT"
3334 "#")
3335
3336 ;; Split the memory case. If the source register doesn't die, it will stay
3337 ;; this way, if it does die, following peephole2s take care of it.
3338 (define_split
3339 [(set (match_operand:DI 0 "memory_operand")
3340 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3341 (clobber (reg:CC FLAGS_REG))
3342 (clobber (match_operand:SI 2 "register_operand"))]
3343 "reload_completed"
3344 [(const_int 0)]
3345 {
3346 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3347
3348 emit_move_insn (operands[3], operands[1]);
3349
3350 /* Generate a cltd if possible and doing so it profitable. */
3351 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3352 && true_regnum (operands[1]) == AX_REG
3353 && true_regnum (operands[2]) == DX_REG)
3354 {
3355 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3356 }
3357 else
3358 {
3359 emit_move_insn (operands[2], operands[1]);
3360 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3361 }
3362 emit_move_insn (operands[4], operands[2]);
3363 DONE;
3364 })
3365
3366 ;; Peepholes for the case where the source register does die, after
3367 ;; being split with the above splitter.
3368 (define_peephole2
3369 [(set (match_operand:SI 0 "memory_operand")
3370 (match_operand:SI 1 "register_operand"))
3371 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3372 (parallel [(set (match_dup 2)
3373 (ashiftrt:SI (match_dup 2) (const_int 31)))
3374 (clobber (reg:CC FLAGS_REG))])
3375 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3376 "REGNO (operands[1]) != REGNO (operands[2])
3377 && peep2_reg_dead_p (2, operands[1])
3378 && peep2_reg_dead_p (4, operands[2])
3379 && !reg_mentioned_p (operands[2], operands[3])"
3380 [(set (match_dup 0) (match_dup 1))
3381 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3382 (clobber (reg:CC FLAGS_REG))])
3383 (set (match_dup 3) (match_dup 1))])
3384
3385 (define_peephole2
3386 [(set (match_operand:SI 0 "memory_operand")
3387 (match_operand:SI 1 "register_operand"))
3388 (parallel [(set (match_operand:SI 2 "register_operand")
3389 (ashiftrt:SI (match_dup 1) (const_int 31)))
3390 (clobber (reg:CC FLAGS_REG))])
3391 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3392 "/* cltd is shorter than sarl $31, %eax */
3393 !optimize_function_for_size_p (cfun)
3394 && true_regnum (operands[1]) == AX_REG
3395 && true_regnum (operands[2]) == DX_REG
3396 && peep2_reg_dead_p (2, operands[1])
3397 && peep2_reg_dead_p (3, operands[2])
3398 && !reg_mentioned_p (operands[2], operands[3])"
3399 [(set (match_dup 0) (match_dup 1))
3400 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3401 (clobber (reg:CC FLAGS_REG))])
3402 (set (match_dup 3) (match_dup 1))])
3403
3404 ;; Extend to register case. Optimize case where source and destination
3405 ;; registers match and cases where we can use cltd.
3406 (define_split
3407 [(set (match_operand:DI 0 "register_operand")
3408 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3409 (clobber (reg:CC FLAGS_REG))
3410 (clobber (match_scratch:SI 2))]
3411 "reload_completed"
3412 [(const_int 0)]
3413 {
3414 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3415
3416 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3417 emit_move_insn (operands[3], operands[1]);
3418
3419 /* Generate a cltd if possible and doing so it profitable. */
3420 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3421 && true_regnum (operands[3]) == AX_REG
3422 && true_regnum (operands[4]) == DX_REG)
3423 {
3424 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3425 DONE;
3426 }
3427
3428 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3429 emit_move_insn (operands[4], operands[1]);
3430
3431 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3432 DONE;
3433 })
3434
3435 (define_insn "extend<mode>di2"
3436 [(set (match_operand:DI 0 "register_operand" "=r")
3437 (sign_extend:DI
3438 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3439 "TARGET_64BIT"
3440 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3441 [(set_attr "type" "imovx")
3442 (set_attr "mode" "DI")])
3443
3444 (define_insn "extendhisi2"
3445 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3446 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3447 ""
3448 {
3449 switch (get_attr_prefix_0f (insn))
3450 {
3451 case 0:
3452 return "{cwtl|cwde}";
3453 default:
3454 return "movs{wl|x}\t{%1, %0|%0, %1}";
3455 }
3456 }
3457 [(set_attr "type" "imovx")
3458 (set_attr "mode" "SI")
3459 (set (attr "prefix_0f")
3460 ;; movsx is short decodable while cwtl is vector decoded.
3461 (if_then_else (and (eq_attr "cpu" "!k6")
3462 (eq_attr "alternative" "0"))
3463 (const_string "0")
3464 (const_string "1")))
3465 (set (attr "modrm")
3466 (if_then_else (eq_attr "prefix_0f" "0")
3467 (const_string "0")
3468 (const_string "1")))])
3469
3470 (define_insn "*extendhisi2_zext"
3471 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3472 (zero_extend:DI
3473 (sign_extend:SI
3474 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3475 "TARGET_64BIT"
3476 {
3477 switch (get_attr_prefix_0f (insn))
3478 {
3479 case 0:
3480 return "{cwtl|cwde}";
3481 default:
3482 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3483 }
3484 }
3485 [(set_attr "type" "imovx")
3486 (set_attr "mode" "SI")
3487 (set (attr "prefix_0f")
3488 ;; movsx is short decodable while cwtl is vector decoded.
3489 (if_then_else (and (eq_attr "cpu" "!k6")
3490 (eq_attr "alternative" "0"))
3491 (const_string "0")
3492 (const_string "1")))
3493 (set (attr "modrm")
3494 (if_then_else (eq_attr "prefix_0f" "0")
3495 (const_string "0")
3496 (const_string "1")))])
3497
3498 (define_insn "extendqisi2"
3499 [(set (match_operand:SI 0 "register_operand" "=r")
3500 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3501 ""
3502 "movs{bl|x}\t{%1, %0|%0, %1}"
3503 [(set_attr "type" "imovx")
3504 (set_attr "mode" "SI")])
3505
3506 (define_insn "*extendqisi2_zext"
3507 [(set (match_operand:DI 0 "register_operand" "=r")
3508 (zero_extend:DI
3509 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3510 "TARGET_64BIT"
3511 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3512 [(set_attr "type" "imovx")
3513 (set_attr "mode" "SI")])
3514
3515 (define_insn "extendqihi2"
3516 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3517 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3518 ""
3519 {
3520 switch (get_attr_prefix_0f (insn))
3521 {
3522 case 0:
3523 return "{cbtw|cbw}";
3524 default:
3525 return "movs{bw|x}\t{%1, %0|%0, %1}";
3526 }
3527 }
3528 [(set_attr "type" "imovx")
3529 (set_attr "mode" "HI")
3530 (set (attr "prefix_0f")
3531 ;; movsx is short decodable while cwtl is vector decoded.
3532 (if_then_else (and (eq_attr "cpu" "!k6")
3533 (eq_attr "alternative" "0"))
3534 (const_string "0")
3535 (const_string "1")))
3536 (set (attr "modrm")
3537 (if_then_else (eq_attr "prefix_0f" "0")
3538 (const_string "0")
3539 (const_string "1")))])
3540 \f
3541 ;; Conversions between float and double.
3542
3543 ;; These are all no-ops in the model used for the 80387.
3544 ;; So just emit moves.
3545
3546 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3547 (define_split
3548 [(set (match_operand:DF 0 "push_operand")
3549 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3550 "reload_completed"
3551 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3552 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3553
3554 (define_split
3555 [(set (match_operand:XF 0 "push_operand")
3556 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3557 "reload_completed"
3558 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3559 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3560 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3561
3562 (define_expand "extendsfdf2"
3563 [(set (match_operand:DF 0 "nonimmediate_operand")
3564 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3565 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3566 {
3567 /* ??? Needed for compress_float_constant since all fp constants
3568 are TARGET_LEGITIMATE_CONSTANT_P. */
3569 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3570 {
3571 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3572 && standard_80387_constant_p (operands[1]) > 0)
3573 {
3574 operands[1] = simplify_const_unary_operation
3575 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3576 emit_move_insn_1 (operands[0], operands[1]);
3577 DONE;
3578 }
3579 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3580 }
3581 })
3582
3583 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3584 cvtss2sd:
3585 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3586 cvtps2pd xmm2,xmm1
3587 We do the conversion post reload to avoid producing of 128bit spills
3588 that might lead to ICE on 32bit target. The sequence unlikely combine
3589 anyway. */
3590 (define_split
3591 [(set (match_operand:DF 0 "register_operand")
3592 (float_extend:DF
3593 (match_operand:SF 1 "nonimmediate_operand")))]
3594 "TARGET_USE_VECTOR_FP_CONVERTS
3595 && optimize_insn_for_speed_p ()
3596 && reload_completed && SSE_REG_P (operands[0])"
3597 [(set (match_dup 2)
3598 (float_extend:V2DF
3599 (vec_select:V2SF
3600 (match_dup 3)
3601 (parallel [(const_int 0) (const_int 1)]))))]
3602 {
3603 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3604 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3605 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3606 Try to avoid move when unpacking can be done in source. */
3607 if (REG_P (operands[1]))
3608 {
3609 /* If it is unsafe to overwrite upper half of source, we need
3610 to move to destination and unpack there. */
3611 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3612 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3613 && true_regnum (operands[0]) != true_regnum (operands[1]))
3614 {
3615 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3616 emit_move_insn (tmp, operands[1]);
3617 }
3618 else
3619 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3620 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3621 operands[3]));
3622 }
3623 else
3624 emit_insn (gen_vec_setv4sf_0 (operands[3],
3625 CONST0_RTX (V4SFmode), operands[1]));
3626 })
3627
3628 ;; It's more profitable to split and then extend in the same register.
3629 (define_peephole2
3630 [(set (match_operand:DF 0 "register_operand")
3631 (float_extend:DF
3632 (match_operand:SF 1 "memory_operand")))]
3633 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3634 && optimize_insn_for_speed_p ()
3635 && SSE_REG_P (operands[0])"
3636 [(set (match_dup 2) (match_dup 1))
3637 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3638 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3639
3640 (define_insn "*extendsfdf2_mixed"
3641 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3642 (float_extend:DF
3643 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3644 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3645 {
3646 switch (which_alternative)
3647 {
3648 case 0:
3649 case 1:
3650 return output_387_reg_move (insn, operands);
3651
3652 case 2:
3653 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3654
3655 default:
3656 gcc_unreachable ();
3657 }
3658 }
3659 [(set_attr "type" "fmov,fmov,ssecvt")
3660 (set_attr "prefix" "orig,orig,maybe_vex")
3661 (set_attr "mode" "SF,XF,DF")])
3662
3663 (define_insn "*extendsfdf2_sse"
3664 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3665 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3666 "TARGET_SSE2 && TARGET_SSE_MATH"
3667 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3668 [(set_attr "type" "ssecvt")
3669 (set_attr "prefix" "maybe_vex")
3670 (set_attr "mode" "DF")])
3671
3672 (define_insn "*extendsfdf2_i387"
3673 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3674 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3675 "TARGET_80387"
3676 "* return output_387_reg_move (insn, operands);"
3677 [(set_attr "type" "fmov")
3678 (set_attr "mode" "SF,XF")])
3679
3680 (define_expand "extend<mode>xf2"
3681 [(set (match_operand:XF 0 "nonimmediate_operand")
3682 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3683 "TARGET_80387"
3684 {
3685 /* ??? Needed for compress_float_constant since all fp constants
3686 are TARGET_LEGITIMATE_CONSTANT_P. */
3687 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3688 {
3689 if (standard_80387_constant_p (operands[1]) > 0)
3690 {
3691 operands[1] = simplify_const_unary_operation
3692 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3693 emit_move_insn_1 (operands[0], operands[1]);
3694 DONE;
3695 }
3696 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3697 }
3698 })
3699
3700 (define_insn "*extend<mode>xf2_i387"
3701 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3702 (float_extend:XF
3703 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3704 "TARGET_80387"
3705 "* return output_387_reg_move (insn, operands);"
3706 [(set_attr "type" "fmov")
3707 (set_attr "mode" "<MODE>,XF")])
3708
3709 ;; %%% This seems bad bad news.
3710 ;; This cannot output into an f-reg because there is no way to be sure
3711 ;; of truncating in that case. Otherwise this is just like a simple move
3712 ;; insn. So we pretend we can output to a reg in order to get better
3713 ;; register preferencing, but we really use a stack slot.
3714
3715 ;; Conversion from DFmode to SFmode.
3716
3717 (define_expand "truncdfsf2"
3718 [(set (match_operand:SF 0 "nonimmediate_operand")
3719 (float_truncate:SF
3720 (match_operand:DF 1 "nonimmediate_operand")))]
3721 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3722 {
3723 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3724 ;
3725 else if (flag_unsafe_math_optimizations)
3726 ;
3727 else
3728 {
3729 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3730 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3731 DONE;
3732 }
3733 })
3734
3735 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3736 cvtsd2ss:
3737 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3738 cvtpd2ps xmm2,xmm1
3739 We do the conversion post reload to avoid producing of 128bit spills
3740 that might lead to ICE on 32bit target. The sequence unlikely combine
3741 anyway. */
3742 (define_split
3743 [(set (match_operand:SF 0 "register_operand")
3744 (float_truncate:SF
3745 (match_operand:DF 1 "nonimmediate_operand")))]
3746 "TARGET_USE_VECTOR_FP_CONVERTS
3747 && optimize_insn_for_speed_p ()
3748 && reload_completed && SSE_REG_P (operands[0])"
3749 [(set (match_dup 2)
3750 (vec_concat:V4SF
3751 (float_truncate:V2SF
3752 (match_dup 4))
3753 (match_dup 3)))]
3754 {
3755 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3756 operands[3] = CONST0_RTX (V2SFmode);
3757 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3758 /* Use movsd for loading from memory, unpcklpd for registers.
3759 Try to avoid move when unpacking can be done in source, or SSE3
3760 movddup is available. */
3761 if (REG_P (operands[1]))
3762 {
3763 if (!TARGET_SSE3
3764 && true_regnum (operands[0]) != true_regnum (operands[1])
3765 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3766 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3767 {
3768 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3769 emit_move_insn (tmp, operands[1]);
3770 operands[1] = tmp;
3771 }
3772 else if (!TARGET_SSE3)
3773 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3774 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3775 }
3776 else
3777 emit_insn (gen_sse2_loadlpd (operands[4],
3778 CONST0_RTX (V2DFmode), operands[1]));
3779 })
3780
3781 ;; It's more profitable to split and then extend in the same register.
3782 (define_peephole2
3783 [(set (match_operand:SF 0 "register_operand")
3784 (float_truncate:SF
3785 (match_operand:DF 1 "memory_operand")))]
3786 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3787 && optimize_insn_for_speed_p ()
3788 && SSE_REG_P (operands[0])"
3789 [(set (match_dup 2) (match_dup 1))
3790 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
3791 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
3792
3793 (define_expand "truncdfsf2_with_temp"
3794 [(parallel [(set (match_operand:SF 0)
3795 (float_truncate:SF (match_operand:DF 1)))
3796 (clobber (match_operand:SF 2))])])
3797
3798 (define_insn "*truncdfsf_fast_mixed"
3799 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
3800 (float_truncate:SF
3801 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
3802 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3803 {
3804 switch (which_alternative)
3805 {
3806 case 0:
3807 return output_387_reg_move (insn, operands);
3808 case 1:
3809 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3810 default:
3811 gcc_unreachable ();
3812 }
3813 }
3814 [(set_attr "type" "fmov,ssecvt")
3815 (set_attr "prefix" "orig,maybe_vex")
3816 (set_attr "mode" "SF")])
3817
3818 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3819 ;; because nothing we do here is unsafe.
3820 (define_insn "*truncdfsf_fast_sse"
3821 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3822 (float_truncate:SF
3823 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3824 "TARGET_SSE2 && TARGET_SSE_MATH"
3825 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
3826 [(set_attr "type" "ssecvt")
3827 (set_attr "prefix" "maybe_vex")
3828 (set_attr "mode" "SF")])
3829
3830 (define_insn "*truncdfsf_fast_i387"
3831 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3832 (float_truncate:SF
3833 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3834 "TARGET_80387 && flag_unsafe_math_optimizations"
3835 "* return output_387_reg_move (insn, operands);"
3836 [(set_attr "type" "fmov")
3837 (set_attr "mode" "SF")])
3838
3839 (define_insn "*truncdfsf_mixed"
3840 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
3841 (float_truncate:SF
3842 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
3843 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
3844 "TARGET_MIX_SSE_I387"
3845 {
3846 switch (which_alternative)
3847 {
3848 case 0:
3849 return output_387_reg_move (insn, operands);
3850 case 1:
3851 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3852
3853 default:
3854 return "#";
3855 }
3856 }
3857 [(set_attr "isa" "*,sse2,*,*,*")
3858 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
3859 (set_attr "unit" "*,*,i387,i387,i387")
3860 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
3861 (set_attr "mode" "SF")])
3862
3863 (define_insn "*truncdfsf_i387"
3864 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3865 (float_truncate:SF
3866 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
3867 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
3868 "TARGET_80387"
3869 {
3870 switch (which_alternative)
3871 {
3872 case 0:
3873 return output_387_reg_move (insn, operands);
3874
3875 default:
3876 return "#";
3877 }
3878 }
3879 [(set_attr "type" "fmov,multi,multi,multi")
3880 (set_attr "unit" "*,i387,i387,i387")
3881 (set_attr "mode" "SF")])
3882
3883 (define_insn "*truncdfsf2_i387_1"
3884 [(set (match_operand:SF 0 "memory_operand" "=m")
3885 (float_truncate:SF
3886 (match_operand:DF 1 "register_operand" "f")))]
3887 "TARGET_80387
3888 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3889 && !TARGET_MIX_SSE_I387"
3890 "* return output_387_reg_move (insn, operands);"
3891 [(set_attr "type" "fmov")
3892 (set_attr "mode" "SF")])
3893
3894 (define_split
3895 [(set (match_operand:SF 0 "register_operand")
3896 (float_truncate:SF
3897 (match_operand:DF 1 "fp_register_operand")))
3898 (clobber (match_operand 2))]
3899 "reload_completed"
3900 [(set (match_dup 2) (match_dup 1))
3901 (set (match_dup 0) (match_dup 2))]
3902 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
3903
3904 ;; Conversion from XFmode to {SF,DF}mode
3905
3906 (define_expand "truncxf<mode>2"
3907 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
3908 (float_truncate:MODEF
3909 (match_operand:XF 1 "register_operand")))
3910 (clobber (match_dup 2))])]
3911 "TARGET_80387"
3912 {
3913 if (flag_unsafe_math_optimizations)
3914 {
3915 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3916 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3917 if (reg != operands[0])
3918 emit_move_insn (operands[0], reg);
3919 DONE;
3920 }
3921 else
3922 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
3923 })
3924
3925 (define_insn "*truncxfsf2_mixed"
3926 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3927 (float_truncate:SF
3928 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
3929 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
3930 "TARGET_80387"
3931 {
3932 gcc_assert (!which_alternative);
3933 return output_387_reg_move (insn, operands);
3934 }
3935 [(set_attr "type" "fmov,multi,multi,multi")
3936 (set_attr "unit" "*,i387,i387,i387")
3937 (set_attr "mode" "SF")])
3938
3939 (define_insn "*truncxfdf2_mixed"
3940 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3941 (float_truncate:DF
3942 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
3943 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
3944 "TARGET_80387"
3945 {
3946 gcc_assert (!which_alternative);
3947 return output_387_reg_move (insn, operands);
3948 }
3949 [(set_attr "isa" "*,*,sse2,*")
3950 (set_attr "type" "fmov,multi,multi,multi")
3951 (set_attr "unit" "*,i387,i387,i387")
3952 (set_attr "mode" "DF")])
3953
3954 (define_insn "truncxf<mode>2_i387_noop"
3955 [(set (match_operand:MODEF 0 "register_operand" "=f")
3956 (float_truncate:MODEF
3957 (match_operand:XF 1 "register_operand" "f")))]
3958 "TARGET_80387 && flag_unsafe_math_optimizations"
3959 "* return output_387_reg_move (insn, operands);"
3960 [(set_attr "type" "fmov")
3961 (set_attr "mode" "<MODE>")])
3962
3963 (define_insn "*truncxf<mode>2_i387"
3964 [(set (match_operand:MODEF 0 "memory_operand" "=m")
3965 (float_truncate:MODEF
3966 (match_operand:XF 1 "register_operand" "f")))]
3967 "TARGET_80387"
3968 "* return output_387_reg_move (insn, operands);"
3969 [(set_attr "type" "fmov")
3970 (set_attr "mode" "<MODE>")])
3971
3972 (define_split
3973 [(set (match_operand:MODEF 0 "register_operand")
3974 (float_truncate:MODEF
3975 (match_operand:XF 1 "register_operand")))
3976 (clobber (match_operand:MODEF 2 "memory_operand"))]
3977 "TARGET_80387 && reload_completed"
3978 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
3979 (set (match_dup 0) (match_dup 2))])
3980
3981 (define_split
3982 [(set (match_operand:MODEF 0 "memory_operand")
3983 (float_truncate:MODEF
3984 (match_operand:XF 1 "register_operand")))
3985 (clobber (match_operand:MODEF 2 "memory_operand"))]
3986 "TARGET_80387"
3987 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
3988 \f
3989 ;; Signed conversion to DImode.
3990
3991 (define_expand "fix_truncxfdi2"
3992 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
3993 (fix:DI (match_operand:XF 1 "register_operand")))
3994 (clobber (reg:CC FLAGS_REG))])]
3995 "TARGET_80387"
3996 {
3997 if (TARGET_FISTTP)
3998 {
3999 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4000 DONE;
4001 }
4002 })
4003
4004 (define_expand "fix_trunc<mode>di2"
4005 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4006 (fix:DI (match_operand:MODEF 1 "register_operand")))
4007 (clobber (reg:CC FLAGS_REG))])]
4008 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4009 {
4010 if (TARGET_FISTTP
4011 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4012 {
4013 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4014 DONE;
4015 }
4016 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4017 {
4018 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4019 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4020 if (out != operands[0])
4021 emit_move_insn (operands[0], out);
4022 DONE;
4023 }
4024 })
4025
4026 ;; Signed conversion to SImode.
4027
4028 (define_expand "fix_truncxfsi2"
4029 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4030 (fix:SI (match_operand:XF 1 "register_operand")))
4031 (clobber (reg:CC FLAGS_REG))])]
4032 "TARGET_80387"
4033 {
4034 if (TARGET_FISTTP)
4035 {
4036 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4037 DONE;
4038 }
4039 })
4040
4041 (define_expand "fix_trunc<mode>si2"
4042 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4043 (fix:SI (match_operand:MODEF 1 "register_operand")))
4044 (clobber (reg:CC FLAGS_REG))])]
4045 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4046 {
4047 if (TARGET_FISTTP
4048 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4049 {
4050 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4051 DONE;
4052 }
4053 if (SSE_FLOAT_MODE_P (<MODE>mode))
4054 {
4055 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4056 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4057 if (out != operands[0])
4058 emit_move_insn (operands[0], out);
4059 DONE;
4060 }
4061 })
4062
4063 ;; Signed conversion to HImode.
4064
4065 (define_expand "fix_trunc<mode>hi2"
4066 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4067 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4068 (clobber (reg:CC FLAGS_REG))])]
4069 "TARGET_80387
4070 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4071 {
4072 if (TARGET_FISTTP)
4073 {
4074 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4075 DONE;
4076 }
4077 })
4078
4079 ;; Unsigned conversion to SImode.
4080
4081 (define_expand "fixuns_trunc<mode>si2"
4082 [(parallel
4083 [(set (match_operand:SI 0 "register_operand")
4084 (unsigned_fix:SI
4085 (match_operand:MODEF 1 "nonimmediate_operand")))
4086 (use (match_dup 2))
4087 (clobber (match_scratch:<ssevecmode> 3))
4088 (clobber (match_scratch:<ssevecmode> 4))])]
4089 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4090 {
4091 enum machine_mode mode = <MODE>mode;
4092 enum machine_mode vecmode = <ssevecmode>mode;
4093 REAL_VALUE_TYPE TWO31r;
4094 rtx two31;
4095
4096 if (optimize_insn_for_size_p ())
4097 FAIL;
4098
4099 real_ldexp (&TWO31r, &dconst1, 31);
4100 two31 = const_double_from_real_value (TWO31r, mode);
4101 two31 = ix86_build_const_vector (vecmode, true, two31);
4102 operands[2] = force_reg (vecmode, two31);
4103 })
4104
4105 (define_insn_and_split "*fixuns_trunc<mode>_1"
4106 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4107 (unsigned_fix:SI
4108 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4109 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4110 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4111 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4112 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4113 && optimize_function_for_speed_p (cfun)"
4114 "#"
4115 "&& reload_completed"
4116 [(const_int 0)]
4117 {
4118 ix86_split_convert_uns_si_sse (operands);
4119 DONE;
4120 })
4121
4122 ;; Unsigned conversion to HImode.
4123 ;; Without these patterns, we'll try the unsigned SI conversion which
4124 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4125
4126 (define_expand "fixuns_trunc<mode>hi2"
4127 [(set (match_dup 2)
4128 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4129 (set (match_operand:HI 0 "nonimmediate_operand")
4130 (subreg:HI (match_dup 2) 0))]
4131 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4132 "operands[2] = gen_reg_rtx (SImode);")
4133
4134 ;; When SSE is available, it is always faster to use it!
4135 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4136 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4137 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4138 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4139 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4140 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4141 [(set_attr "type" "sseicvt")
4142 (set_attr "prefix" "maybe_vex")
4143 (set (attr "prefix_rex")
4144 (if_then_else
4145 (match_test "<SWI48:MODE>mode == DImode")
4146 (const_string "1")
4147 (const_string "*")))
4148 (set_attr "mode" "<MODEF:MODE>")
4149 (set_attr "athlon_decode" "double,vector")
4150 (set_attr "amdfam10_decode" "double,double")
4151 (set_attr "bdver1_decode" "double,double")])
4152
4153 ;; Avoid vector decoded forms of the instruction.
4154 (define_peephole2
4155 [(match_scratch:MODEF 2 "x")
4156 (set (match_operand:SWI48 0 "register_operand")
4157 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4158 "TARGET_AVOID_VECTOR_DECODE
4159 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4160 && optimize_insn_for_speed_p ()"
4161 [(set (match_dup 2) (match_dup 1))
4162 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4163
4164 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4165 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4166 (fix:SWI248x (match_operand 1 "register_operand")))]
4167 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4168 && TARGET_FISTTP
4169 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4170 && (TARGET_64BIT || <MODE>mode != DImode))
4171 && TARGET_SSE_MATH)
4172 && can_create_pseudo_p ()"
4173 "#"
4174 "&& 1"
4175 [(const_int 0)]
4176 {
4177 if (memory_operand (operands[0], VOIDmode))
4178 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4179 else
4180 {
4181 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4182 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4183 operands[1],
4184 operands[2]));
4185 }
4186 DONE;
4187 }
4188 [(set_attr "type" "fisttp")
4189 (set_attr "mode" "<MODE>")])
4190
4191 (define_insn "fix_trunc<mode>_i387_fisttp"
4192 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4193 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4194 (clobber (match_scratch:XF 2 "=&1f"))]
4195 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4196 && TARGET_FISTTP
4197 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4198 && (TARGET_64BIT || <MODE>mode != DImode))
4199 && TARGET_SSE_MATH)"
4200 "* return output_fix_trunc (insn, operands, true);"
4201 [(set_attr "type" "fisttp")
4202 (set_attr "mode" "<MODE>")])
4203
4204 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4205 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4206 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4207 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4208 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4209 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4210 && TARGET_FISTTP
4211 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4212 && (TARGET_64BIT || <MODE>mode != DImode))
4213 && TARGET_SSE_MATH)"
4214 "#"
4215 [(set_attr "type" "fisttp")
4216 (set_attr "mode" "<MODE>")])
4217
4218 (define_split
4219 [(set (match_operand:SWI248x 0 "register_operand")
4220 (fix:SWI248x (match_operand 1 "register_operand")))
4221 (clobber (match_operand:SWI248x 2 "memory_operand"))
4222 (clobber (match_scratch 3))]
4223 "reload_completed"
4224 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4225 (clobber (match_dup 3))])
4226 (set (match_dup 0) (match_dup 2))])
4227
4228 (define_split
4229 [(set (match_operand:SWI248x 0 "memory_operand")
4230 (fix:SWI248x (match_operand 1 "register_operand")))
4231 (clobber (match_operand:SWI248x 2 "memory_operand"))
4232 (clobber (match_scratch 3))]
4233 "reload_completed"
4234 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4235 (clobber (match_dup 3))])])
4236
4237 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4238 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4239 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4240 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4241 ;; function in i386.c.
4242 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4243 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4244 (fix:SWI248x (match_operand 1 "register_operand")))
4245 (clobber (reg:CC FLAGS_REG))]
4246 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4247 && !TARGET_FISTTP
4248 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4249 && (TARGET_64BIT || <MODE>mode != DImode))
4250 && can_create_pseudo_p ()"
4251 "#"
4252 "&& 1"
4253 [(const_int 0)]
4254 {
4255 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4256
4257 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4258 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4259 if (memory_operand (operands[0], VOIDmode))
4260 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4261 operands[2], operands[3]));
4262 else
4263 {
4264 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4265 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4266 operands[2], operands[3],
4267 operands[4]));
4268 }
4269 DONE;
4270 }
4271 [(set_attr "type" "fistp")
4272 (set_attr "i387_cw" "trunc")
4273 (set_attr "mode" "<MODE>")])
4274
4275 (define_insn "fix_truncdi_i387"
4276 [(set (match_operand:DI 0 "memory_operand" "=m")
4277 (fix:DI (match_operand 1 "register_operand" "f")))
4278 (use (match_operand:HI 2 "memory_operand" "m"))
4279 (use (match_operand:HI 3 "memory_operand" "m"))
4280 (clobber (match_scratch:XF 4 "=&1f"))]
4281 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4282 && !TARGET_FISTTP
4283 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4284 "* return output_fix_trunc (insn, operands, false);"
4285 [(set_attr "type" "fistp")
4286 (set_attr "i387_cw" "trunc")
4287 (set_attr "mode" "DI")])
4288
4289 (define_insn "fix_truncdi_i387_with_temp"
4290 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4291 (fix:DI (match_operand 1 "register_operand" "f,f")))
4292 (use (match_operand:HI 2 "memory_operand" "m,m"))
4293 (use (match_operand:HI 3 "memory_operand" "m,m"))
4294 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4295 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4296 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4297 && !TARGET_FISTTP
4298 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4299 "#"
4300 [(set_attr "type" "fistp")
4301 (set_attr "i387_cw" "trunc")
4302 (set_attr "mode" "DI")])
4303
4304 (define_split
4305 [(set (match_operand:DI 0 "register_operand")
4306 (fix:DI (match_operand 1 "register_operand")))
4307 (use (match_operand:HI 2 "memory_operand"))
4308 (use (match_operand:HI 3 "memory_operand"))
4309 (clobber (match_operand:DI 4 "memory_operand"))
4310 (clobber (match_scratch 5))]
4311 "reload_completed"
4312 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4313 (use (match_dup 2))
4314 (use (match_dup 3))
4315 (clobber (match_dup 5))])
4316 (set (match_dup 0) (match_dup 4))])
4317
4318 (define_split
4319 [(set (match_operand:DI 0 "memory_operand")
4320 (fix:DI (match_operand 1 "register_operand")))
4321 (use (match_operand:HI 2 "memory_operand"))
4322 (use (match_operand:HI 3 "memory_operand"))
4323 (clobber (match_operand:DI 4 "memory_operand"))
4324 (clobber (match_scratch 5))]
4325 "reload_completed"
4326 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4327 (use (match_dup 2))
4328 (use (match_dup 3))
4329 (clobber (match_dup 5))])])
4330
4331 (define_insn "fix_trunc<mode>_i387"
4332 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4333 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4334 (use (match_operand:HI 2 "memory_operand" "m"))
4335 (use (match_operand:HI 3 "memory_operand" "m"))]
4336 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4337 && !TARGET_FISTTP
4338 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4339 "* return output_fix_trunc (insn, operands, false);"
4340 [(set_attr "type" "fistp")
4341 (set_attr "i387_cw" "trunc")
4342 (set_attr "mode" "<MODE>")])
4343
4344 (define_insn "fix_trunc<mode>_i387_with_temp"
4345 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4346 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4347 (use (match_operand:HI 2 "memory_operand" "m,m"))
4348 (use (match_operand:HI 3 "memory_operand" "m,m"))
4349 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4350 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4351 && !TARGET_FISTTP
4352 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4353 "#"
4354 [(set_attr "type" "fistp")
4355 (set_attr "i387_cw" "trunc")
4356 (set_attr "mode" "<MODE>")])
4357
4358 (define_split
4359 [(set (match_operand:SWI24 0 "register_operand")
4360 (fix:SWI24 (match_operand 1 "register_operand")))
4361 (use (match_operand:HI 2 "memory_operand"))
4362 (use (match_operand:HI 3 "memory_operand"))
4363 (clobber (match_operand:SWI24 4 "memory_operand"))]
4364 "reload_completed"
4365 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4366 (use (match_dup 2))
4367 (use (match_dup 3))])
4368 (set (match_dup 0) (match_dup 4))])
4369
4370 (define_split
4371 [(set (match_operand:SWI24 0 "memory_operand")
4372 (fix:SWI24 (match_operand 1 "register_operand")))
4373 (use (match_operand:HI 2 "memory_operand"))
4374 (use (match_operand:HI 3 "memory_operand"))
4375 (clobber (match_operand:SWI24 4 "memory_operand"))]
4376 "reload_completed"
4377 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4378 (use (match_dup 2))
4379 (use (match_dup 3))])])
4380
4381 (define_insn "x86_fnstcw_1"
4382 [(set (match_operand:HI 0 "memory_operand" "=m")
4383 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4384 "TARGET_80387"
4385 "fnstcw\t%0"
4386 [(set (attr "length")
4387 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4388 (set_attr "mode" "HI")
4389 (set_attr "unit" "i387")
4390 (set_attr "bdver1_decode" "vector")])
4391
4392 (define_insn "x86_fldcw_1"
4393 [(set (reg:HI FPCR_REG)
4394 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4395 "TARGET_80387"
4396 "fldcw\t%0"
4397 [(set (attr "length")
4398 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4399 (set_attr "mode" "HI")
4400 (set_attr "unit" "i387")
4401 (set_attr "athlon_decode" "vector")
4402 (set_attr "amdfam10_decode" "vector")
4403 (set_attr "bdver1_decode" "vector")])
4404 \f
4405 ;; Conversion between fixed point and floating point.
4406
4407 ;; Even though we only accept memory inputs, the backend _really_
4408 ;; wants to be able to do this between registers.
4409
4410 (define_expand "floathi<mode>2"
4411 [(set (match_operand:X87MODEF 0 "register_operand")
4412 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4413 "TARGET_80387
4414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4415 || TARGET_MIX_SSE_I387)")
4416
4417 ;; Pre-reload splitter to add memory clobber to the pattern.
4418 (define_insn_and_split "*floathi<mode>2_1"
4419 [(set (match_operand:X87MODEF 0 "register_operand")
4420 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4421 "TARGET_80387
4422 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4423 || TARGET_MIX_SSE_I387)
4424 && can_create_pseudo_p ()"
4425 "#"
4426 "&& 1"
4427 [(parallel [(set (match_dup 0)
4428 (float:X87MODEF (match_dup 1)))
4429 (clobber (match_dup 2))])]
4430 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4431
4432 (define_insn "*floathi<mode>2_i387_with_temp"
4433 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4434 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4435 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4436 "TARGET_80387
4437 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4438 || TARGET_MIX_SSE_I387)"
4439 "#"
4440 [(set_attr "type" "fmov,multi")
4441 (set_attr "mode" "<MODE>")
4442 (set_attr "unit" "*,i387")
4443 (set_attr "fp_int_src" "true")])
4444
4445 (define_insn "*floathi<mode>2_i387"
4446 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4447 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4448 "TARGET_80387
4449 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4450 || TARGET_MIX_SSE_I387)"
4451 "fild%Z1\t%1"
4452 [(set_attr "type" "fmov")
4453 (set_attr "mode" "<MODE>")
4454 (set_attr "fp_int_src" "true")])
4455
4456 (define_split
4457 [(set (match_operand:X87MODEF 0 "register_operand")
4458 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4459 (clobber (match_operand:HI 2 "memory_operand"))]
4460 "TARGET_80387
4461 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4462 || TARGET_MIX_SSE_I387)
4463 && reload_completed"
4464 [(set (match_dup 2) (match_dup 1))
4465 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4466
4467 (define_split
4468 [(set (match_operand:X87MODEF 0 "register_operand")
4469 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4470 (clobber (match_operand:HI 2 "memory_operand"))]
4471 "TARGET_80387
4472 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4473 || TARGET_MIX_SSE_I387)
4474 && reload_completed"
4475 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4476
4477 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4478 [(set (match_operand:X87MODEF 0 "register_operand")
4479 (float:X87MODEF
4480 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4481 "TARGET_80387
4482 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4483 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4484 {
4485 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4486 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4487 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4488 {
4489 rtx reg = gen_reg_rtx (XFmode);
4490 rtx (*insn)(rtx, rtx);
4491
4492 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4493
4494 if (<X87MODEF:MODE>mode == SFmode)
4495 insn = gen_truncxfsf2;
4496 else if (<X87MODEF:MODE>mode == DFmode)
4497 insn = gen_truncxfdf2;
4498 else
4499 gcc_unreachable ();
4500
4501 emit_insn (insn (operands[0], reg));
4502 DONE;
4503 }
4504 })
4505
4506 ;; Pre-reload splitter to add memory clobber to the pattern.
4507 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4508 [(set (match_operand:X87MODEF 0 "register_operand")
4509 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4510 "((TARGET_80387
4511 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4512 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4513 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4514 || TARGET_MIX_SSE_I387))
4515 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4516 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4517 && ((<SWI48x:MODE>mode == SImode
4518 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4519 && optimize_function_for_speed_p (cfun)
4520 && flag_trapping_math)
4521 || !(TARGET_INTER_UNIT_CONVERSIONS
4522 || optimize_function_for_size_p (cfun)))))
4523 && can_create_pseudo_p ()"
4524 "#"
4525 "&& 1"
4526 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4527 (clobber (match_dup 2))])]
4528 {
4529 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4530
4531 /* Avoid store forwarding (partial memory) stall penalty
4532 by passing DImode value through XMM registers. */
4533 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4534 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4535 && optimize_function_for_speed_p (cfun))
4536 {
4537 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4538 operands[1],
4539 operands[2]));
4540 DONE;
4541 }
4542 })
4543
4544 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4545 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4546 (float:MODEF
4547 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4548 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4549 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4550 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4551 "#"
4552 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4553 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4554 (set_attr "unit" "*,i387,*,*,*")
4555 (set_attr "athlon_decode" "*,*,double,direct,double")
4556 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4557 (set_attr "bdver1_decode" "*,*,double,direct,double")
4558 (set_attr "fp_int_src" "true")])
4559
4560 (define_insn "*floatsi<mode>2_vector_mixed"
4561 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4562 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4563 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4564 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4565 "@
4566 fild%Z1\t%1
4567 #"
4568 [(set_attr "type" "fmov,sseicvt")
4569 (set_attr "mode" "<MODE>,<ssevecmode>")
4570 (set_attr "unit" "i387,*")
4571 (set_attr "athlon_decode" "*,direct")
4572 (set_attr "amdfam10_decode" "*,double")
4573 (set_attr "bdver1_decode" "*,direct")
4574 (set_attr "fp_int_src" "true")])
4575
4576 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4577 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4578 (float:MODEF
4579 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4580 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4581 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4582 "#"
4583 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4584 (set_attr "mode" "<MODEF:MODE>")
4585 (set_attr "unit" "*,i387,*,*")
4586 (set_attr "athlon_decode" "*,*,double,direct")
4587 (set_attr "amdfam10_decode" "*,*,vector,double")
4588 (set_attr "bdver1_decode" "*,*,double,direct")
4589 (set_attr "fp_int_src" "true")])
4590
4591 (define_split
4592 [(set (match_operand:MODEF 0 "register_operand")
4593 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4594 (clobber (match_operand:SWI48 2 "memory_operand"))]
4595 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4596 && TARGET_INTER_UNIT_CONVERSIONS
4597 && reload_completed
4598 && (SSE_REG_P (operands[0])
4599 || (GET_CODE (operands[0]) == SUBREG
4600 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4601 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4602
4603 (define_split
4604 [(set (match_operand:MODEF 0 "register_operand")
4605 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4606 (clobber (match_operand:SWI48 2 "memory_operand"))]
4607 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4608 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4609 && reload_completed
4610 && (SSE_REG_P (operands[0])
4611 || (GET_CODE (operands[0]) == SUBREG
4612 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4613 [(set (match_dup 2) (match_dup 1))
4614 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4615
4616 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4617 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4618 (float:MODEF
4619 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4620 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4621 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4622 "@
4623 fild%Z1\t%1
4624 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4625 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4626 [(set_attr "type" "fmov,sseicvt,sseicvt")
4627 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4628 (set_attr "mode" "<MODEF:MODE>")
4629 (set (attr "prefix_rex")
4630 (if_then_else
4631 (and (eq_attr "prefix" "maybe_vex")
4632 (match_test "<SWI48:MODE>mode == DImode"))
4633 (const_string "1")
4634 (const_string "*")))
4635 (set_attr "unit" "i387,*,*")
4636 (set_attr "athlon_decode" "*,double,direct")
4637 (set_attr "amdfam10_decode" "*,vector,double")
4638 (set_attr "bdver1_decode" "*,double,direct")
4639 (set_attr "fp_int_src" "true")])
4640
4641 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4642 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4643 (float:MODEF
4644 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4645 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4646 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4647 "@
4648 fild%Z1\t%1
4649 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4650 [(set_attr "type" "fmov,sseicvt")
4651 (set_attr "prefix" "orig,maybe_vex")
4652 (set_attr "mode" "<MODEF:MODE>")
4653 (set (attr "prefix_rex")
4654 (if_then_else
4655 (and (eq_attr "prefix" "maybe_vex")
4656 (match_test "<SWI48:MODE>mode == DImode"))
4657 (const_string "1")
4658 (const_string "*")))
4659 (set_attr "athlon_decode" "*,direct")
4660 (set_attr "amdfam10_decode" "*,double")
4661 (set_attr "bdver1_decode" "*,direct")
4662 (set_attr "fp_int_src" "true")])
4663
4664 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4665 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4666 (float:MODEF
4667 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4668 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4669 "TARGET_SSE2 && TARGET_SSE_MATH
4670 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4671 "#"
4672 [(set_attr "type" "sseicvt")
4673 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4674 (set_attr "athlon_decode" "double,direct,double")
4675 (set_attr "amdfam10_decode" "vector,double,double")
4676 (set_attr "bdver1_decode" "double,direct,double")
4677 (set_attr "fp_int_src" "true")])
4678
4679 (define_insn "*floatsi<mode>2_vector_sse"
4680 [(set (match_operand:MODEF 0 "register_operand" "=x")
4681 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4682 "TARGET_SSE2 && TARGET_SSE_MATH
4683 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4684 "#"
4685 [(set_attr "type" "sseicvt")
4686 (set_attr "mode" "<MODE>")
4687 (set_attr "athlon_decode" "direct")
4688 (set_attr "amdfam10_decode" "double")
4689 (set_attr "bdver1_decode" "direct")
4690 (set_attr "fp_int_src" "true")])
4691
4692 (define_split
4693 [(set (match_operand:MODEF 0 "register_operand")
4694 (float:MODEF (match_operand:SI 1 "register_operand")))
4695 (clobber (match_operand:SI 2 "memory_operand"))]
4696 "TARGET_SSE2 && TARGET_SSE_MATH
4697 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4698 && reload_completed
4699 && (SSE_REG_P (operands[0])
4700 || (GET_CODE (operands[0]) == SUBREG
4701 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4702 [(const_int 0)]
4703 {
4704 rtx op1 = operands[1];
4705
4706 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4707 <MODE>mode, 0);
4708 if (GET_CODE (op1) == SUBREG)
4709 op1 = SUBREG_REG (op1);
4710
4711 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4712 {
4713 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4714 emit_insn (gen_sse2_loadld (operands[4],
4715 CONST0_RTX (V4SImode), operands[1]));
4716 }
4717 /* We can ignore possible trapping value in the
4718 high part of SSE register for non-trapping math. */
4719 else if (SSE_REG_P (op1) && !flag_trapping_math)
4720 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4721 else
4722 {
4723 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4724 emit_move_insn (operands[2], operands[1]);
4725 emit_insn (gen_sse2_loadld (operands[4],
4726 CONST0_RTX (V4SImode), operands[2]));
4727 }
4728 if (<ssevecmode>mode == V4SFmode)
4729 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4730 else
4731 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4732 DONE;
4733 })
4734
4735 (define_split
4736 [(set (match_operand:MODEF 0 "register_operand")
4737 (float:MODEF (match_operand:SI 1 "memory_operand")))
4738 (clobber (match_operand:SI 2 "memory_operand"))]
4739 "TARGET_SSE2 && TARGET_SSE_MATH
4740 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4741 && reload_completed
4742 && (SSE_REG_P (operands[0])
4743 || (GET_CODE (operands[0]) == SUBREG
4744 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4745 [(const_int 0)]
4746 {
4747 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4748 <MODE>mode, 0);
4749 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4750
4751 emit_insn (gen_sse2_loadld (operands[4],
4752 CONST0_RTX (V4SImode), operands[1]));
4753 if (<ssevecmode>mode == V4SFmode)
4754 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4755 else
4756 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4757 DONE;
4758 })
4759
4760 (define_split
4761 [(set (match_operand:MODEF 0 "register_operand")
4762 (float:MODEF (match_operand:SI 1 "register_operand")))]
4763 "TARGET_SSE2 && TARGET_SSE_MATH
4764 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4765 && reload_completed
4766 && (SSE_REG_P (operands[0])
4767 || (GET_CODE (operands[0]) == SUBREG
4768 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4769 [(const_int 0)]
4770 {
4771 rtx op1 = operands[1];
4772
4773 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4774 <MODE>mode, 0);
4775 if (GET_CODE (op1) == SUBREG)
4776 op1 = SUBREG_REG (op1);
4777
4778 if (GENERAL_REG_P (op1))
4779 {
4780 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4781 if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4782 emit_insn (gen_sse2_loadld (operands[4],
4783 CONST0_RTX (V4SImode), operands[1]));
4784 else
4785 {
4786 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4787 operands[1]);
4788 emit_insn (gen_sse2_loadld (operands[4],
4789 CONST0_RTX (V4SImode), operands[5]));
4790 ix86_free_from_memory (GET_MODE (operands[1]));
4791 }
4792 }
4793 /* We can ignore possible trapping value in the
4794 high part of SSE register for non-trapping math. */
4795 else if (SSE_REG_P (op1) && !flag_trapping_math)
4796 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4797 else
4798 gcc_unreachable ();
4799 if (<ssevecmode>mode == V4SFmode)
4800 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4801 else
4802 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4803 DONE;
4804 })
4805
4806 (define_split
4807 [(set (match_operand:MODEF 0 "register_operand")
4808 (float:MODEF (match_operand:SI 1 "memory_operand")))]
4809 "TARGET_SSE2 && TARGET_SSE_MATH
4810 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4811 && reload_completed
4812 && (SSE_REG_P (operands[0])
4813 || (GET_CODE (operands[0]) == SUBREG
4814 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4815 [(const_int 0)]
4816 {
4817 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4818 <MODE>mode, 0);
4819 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4820
4821 emit_insn (gen_sse2_loadld (operands[4],
4822 CONST0_RTX (V4SImode), operands[1]));
4823 if (<ssevecmode>mode == V4SFmode)
4824 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4825 else
4826 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4827 DONE;
4828 })
4829
4830 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
4831 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4832 (float:MODEF
4833 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
4834 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
4835 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4836 "#"
4837 [(set_attr "type" "sseicvt")
4838 (set_attr "mode" "<MODEF:MODE>")
4839 (set_attr "athlon_decode" "double,direct")
4840 (set_attr "amdfam10_decode" "vector,double")
4841 (set_attr "bdver1_decode" "double,direct")
4842 (set_attr "btver2_decode" "double,double")
4843 (set_attr "fp_int_src" "true")])
4844
4845 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
4846 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4847 (float:MODEF
4848 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
4849 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4850 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4851 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4852 [(set_attr "type" "sseicvt")
4853 (set_attr "prefix" "maybe_vex")
4854 (set_attr "mode" "<MODEF:MODE>")
4855 (set (attr "prefix_rex")
4856 (if_then_else
4857 (and (eq_attr "prefix" "maybe_vex")
4858 (match_test "<SWI48:MODE>mode == DImode"))
4859 (const_string "1")
4860 (const_string "*")))
4861 (set_attr "athlon_decode" "double,direct")
4862 (set_attr "amdfam10_decode" "vector,double")
4863 (set_attr "bdver1_decode" "double,direct")
4864 (set_attr "btver2_decode" "double,double")
4865 (set_attr "fp_int_src" "true")])
4866
4867 (define_split
4868 [(set (match_operand:MODEF 0 "register_operand")
4869 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
4870 (clobber (match_operand:SWI48 2 "memory_operand"))]
4871 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4872 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4873 && reload_completed
4874 && (SSE_REG_P (operands[0])
4875 || (GET_CODE (operands[0]) == SUBREG
4876 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4877 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4878
4879 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
4880 [(set (match_operand:MODEF 0 "register_operand" "=x")
4881 (float:MODEF
4882 (match_operand:SWI48 1 "memory_operand" "m")))]
4883 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4884 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4885 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4886 [(set_attr "type" "sseicvt")
4887 (set_attr "prefix" "maybe_vex")
4888 (set_attr "mode" "<MODEF:MODE>")
4889 (set (attr "prefix_rex")
4890 (if_then_else
4891 (and (eq_attr "prefix" "maybe_vex")
4892 (match_test "<SWI48:MODE>mode == DImode"))
4893 (const_string "1")
4894 (const_string "*")))
4895 (set_attr "athlon_decode" "direct")
4896 (set_attr "amdfam10_decode" "double")
4897 (set_attr "bdver1_decode" "direct")
4898 (set_attr "fp_int_src" "true")])
4899
4900 (define_split
4901 [(set (match_operand:MODEF 0 "register_operand")
4902 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4903 (clobber (match_operand:SWI48 2 "memory_operand"))]
4904 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4905 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4906 && reload_completed
4907 && (SSE_REG_P (operands[0])
4908 || (GET_CODE (operands[0]) == SUBREG
4909 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4910 [(set (match_dup 2) (match_dup 1))
4911 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4912
4913 (define_split
4914 [(set (match_operand:MODEF 0 "register_operand")
4915 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
4916 (clobber (match_operand:SWI48 2 "memory_operand"))]
4917 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4918 && reload_completed
4919 && (SSE_REG_P (operands[0])
4920 || (GET_CODE (operands[0]) == SUBREG
4921 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4922 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4923
4924 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
4925 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4926 (float:X87MODEF
4927 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
4928 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
4929 "TARGET_80387
4930 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4931 "@
4932 fild%Z1\t%1
4933 #"
4934 [(set_attr "type" "fmov,multi")
4935 (set_attr "mode" "<X87MODEF:MODE>")
4936 (set_attr "unit" "*,i387")
4937 (set_attr "fp_int_src" "true")])
4938
4939 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
4940 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4941 (float:X87MODEF
4942 (match_operand:SWI48x 1 "memory_operand" "m")))]
4943 "TARGET_80387
4944 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4945 "fild%Z1\t%1"
4946 [(set_attr "type" "fmov")
4947 (set_attr "mode" "<X87MODEF:MODE>")
4948 (set_attr "fp_int_src" "true")])
4949
4950 (define_split
4951 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4952 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
4953 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4954 "TARGET_80387
4955 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4956 && reload_completed"
4957 [(set (match_dup 2) (match_dup 1))
4958 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4959
4960 (define_split
4961 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4962 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
4963 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4964 "TARGET_80387
4965 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4966 && reload_completed"
4967 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4968
4969 ;; Avoid store forwarding (partial memory) stall penalty
4970 ;; by passing DImode value through XMM registers. */
4971
4972 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4973 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4974 (float:X87MODEF
4975 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4976 (clobber (match_scratch:V4SI 3 "=X,x"))
4977 (clobber (match_scratch:V4SI 4 "=X,x"))
4978 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4979 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4980 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4981 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4982 "#"
4983 [(set_attr "type" "multi")
4984 (set_attr "mode" "<X87MODEF:MODE>")
4985 (set_attr "unit" "i387")
4986 (set_attr "fp_int_src" "true")])
4987
4988 (define_split
4989 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4990 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4991 (clobber (match_scratch:V4SI 3))
4992 (clobber (match_scratch:V4SI 4))
4993 (clobber (match_operand:DI 2 "memory_operand"))]
4994 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4995 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4996 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4997 && reload_completed"
4998 [(set (match_dup 2) (match_dup 3))
4999 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5000 {
5001 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5002 Assemble the 64-bit DImode value in an xmm register. */
5003 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5004 gen_rtx_SUBREG (SImode, operands[1], 0)));
5005 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5006 gen_rtx_SUBREG (SImode, operands[1], 4)));
5007 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5008 operands[4]));
5009
5010 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5011 })
5012
5013 (define_split
5014 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5015 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5016 (clobber (match_scratch:V4SI 3))
5017 (clobber (match_scratch:V4SI 4))
5018 (clobber (match_operand:DI 2 "memory_operand"))]
5019 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5020 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5021 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5022 && reload_completed"
5023 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5024
5025 ;; Avoid store forwarding (partial memory) stall penalty by extending
5026 ;; SImode value to DImode through XMM register instead of pushing two
5027 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5028 ;; targets benefit from this optimization. Also note that fild
5029 ;; loads from memory only.
5030
5031 (define_insn "*floatunssi<mode>2_1"
5032 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5033 (unsigned_float:X87MODEF
5034 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5035 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5036 (clobber (match_scratch:SI 3 "=X,x"))]
5037 "!TARGET_64BIT
5038 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5039 && TARGET_SSE"
5040 "#"
5041 [(set_attr "type" "multi")
5042 (set_attr "mode" "<MODE>")])
5043
5044 (define_split
5045 [(set (match_operand:X87MODEF 0 "register_operand")
5046 (unsigned_float:X87MODEF
5047 (match_operand:SI 1 "register_operand")))
5048 (clobber (match_operand:DI 2 "memory_operand"))
5049 (clobber (match_scratch:SI 3))]
5050 "!TARGET_64BIT
5051 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5052 && TARGET_SSE
5053 && reload_completed"
5054 [(set (match_dup 2) (match_dup 1))
5055 (set (match_dup 0)
5056 (float:X87MODEF (match_dup 2)))]
5057 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5058
5059 (define_split
5060 [(set (match_operand:X87MODEF 0 "register_operand")
5061 (unsigned_float:X87MODEF
5062 (match_operand:SI 1 "memory_operand")))
5063 (clobber (match_operand:DI 2 "memory_operand"))
5064 (clobber (match_scratch:SI 3))]
5065 "!TARGET_64BIT
5066 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5067 && TARGET_SSE
5068 && reload_completed"
5069 [(set (match_dup 2) (match_dup 3))
5070 (set (match_dup 0)
5071 (float:X87MODEF (match_dup 2)))]
5072 {
5073 emit_move_insn (operands[3], operands[1]);
5074 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5075 })
5076
5077 (define_expand "floatunssi<mode>2"
5078 [(parallel
5079 [(set (match_operand:X87MODEF 0 "register_operand")
5080 (unsigned_float:X87MODEF
5081 (match_operand:SI 1 "nonimmediate_operand")))
5082 (clobber (match_dup 2))
5083 (clobber (match_scratch:SI 3))])]
5084 "!TARGET_64BIT
5085 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5086 && TARGET_SSE)
5087 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5088 {
5089 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5090 {
5091 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5092 DONE;
5093 }
5094 else
5095 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5096 })
5097
5098 (define_expand "floatunsdisf2"
5099 [(use (match_operand:SF 0 "register_operand"))
5100 (use (match_operand:DI 1 "nonimmediate_operand"))]
5101 "TARGET_64BIT && TARGET_SSE_MATH"
5102 "x86_emit_floatuns (operands); DONE;")
5103
5104 (define_expand "floatunsdidf2"
5105 [(use (match_operand:DF 0 "register_operand"))
5106 (use (match_operand:DI 1 "nonimmediate_operand"))]
5107 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5108 && TARGET_SSE2 && TARGET_SSE_MATH"
5109 {
5110 if (TARGET_64BIT)
5111 x86_emit_floatuns (operands);
5112 else
5113 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5114 DONE;
5115 })
5116 \f
5117 ;; Load effective address instructions
5118
5119 (define_insn_and_split "*lea<mode>"
5120 [(set (match_operand:SWI48 0 "register_operand" "=r")
5121 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5122 ""
5123 {
5124 if (SImode_address_operand (operands[1], VOIDmode))
5125 {
5126 gcc_assert (TARGET_64BIT);
5127 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5128 }
5129 else
5130 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5131 }
5132 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5133 [(const_int 0)]
5134 {
5135 enum machine_mode mode = <MODE>mode;
5136 rtx pat;
5137
5138 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5139 change operands[] array behind our back. */
5140 pat = PATTERN (curr_insn);
5141
5142 operands[0] = SET_DEST (pat);
5143 operands[1] = SET_SRC (pat);
5144
5145 /* Emit all operations in SImode for zero-extended addresses. Recall
5146 that x86_64 inheretly zero-extends SImode operations to DImode. */
5147 if (SImode_address_operand (operands[1], VOIDmode))
5148 mode = SImode;
5149
5150 ix86_split_lea_for_addr (curr_insn, operands, mode);
5151 DONE;
5152 }
5153 [(set_attr "type" "lea")
5154 (set (attr "mode")
5155 (if_then_else
5156 (match_operand 1 "SImode_address_operand")
5157 (const_string "SI")
5158 (const_string "<MODE>")))])
5159 \f
5160 ;; Add instructions
5161
5162 (define_expand "add<mode>3"
5163 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5164 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5165 (match_operand:SDWIM 2 "<general_operand>")))]
5166 ""
5167 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5168
5169 (define_insn_and_split "*add<dwi>3_doubleword"
5170 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5171 (plus:<DWI>
5172 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5173 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5174 (clobber (reg:CC FLAGS_REG))]
5175 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5176 "#"
5177 "reload_completed"
5178 [(parallel [(set (reg:CC FLAGS_REG)
5179 (unspec:CC [(match_dup 1) (match_dup 2)]
5180 UNSPEC_ADD_CARRY))
5181 (set (match_dup 0)
5182 (plus:DWIH (match_dup 1) (match_dup 2)))])
5183 (parallel [(set (match_dup 3)
5184 (plus:DWIH
5185 (match_dup 4)
5186 (plus:DWIH
5187 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5188 (match_dup 5))))
5189 (clobber (reg:CC FLAGS_REG))])]
5190 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5191
5192 (define_insn "*add<mode>3_cc"
5193 [(set (reg:CC FLAGS_REG)
5194 (unspec:CC
5195 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5196 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5197 UNSPEC_ADD_CARRY))
5198 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5199 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5200 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5201 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5202 [(set_attr "type" "alu")
5203 (set_attr "mode" "<MODE>")])
5204
5205 (define_insn "addqi3_cc"
5206 [(set (reg:CC FLAGS_REG)
5207 (unspec:CC
5208 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5209 (match_operand:QI 2 "general_operand" "qn,qm")]
5210 UNSPEC_ADD_CARRY))
5211 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5212 (plus:QI (match_dup 1) (match_dup 2)))]
5213 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5214 "add{b}\t{%2, %0|%0, %2}"
5215 [(set_attr "type" "alu")
5216 (set_attr "mode" "QI")])
5217
5218 (define_insn "*add<mode>_1"
5219 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5220 (plus:SWI48
5221 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5222 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5223 (clobber (reg:CC FLAGS_REG))]
5224 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5225 {
5226 switch (get_attr_type (insn))
5227 {
5228 case TYPE_LEA:
5229 return "#";
5230
5231 case TYPE_INCDEC:
5232 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5233 if (operands[2] == const1_rtx)
5234 return "inc{<imodesuffix>}\t%0";
5235 else
5236 {
5237 gcc_assert (operands[2] == constm1_rtx);
5238 return "dec{<imodesuffix>}\t%0";
5239 }
5240
5241 default:
5242 /* For most processors, ADD is faster than LEA. This alternative
5243 was added to use ADD as much as possible. */
5244 if (which_alternative == 2)
5245 {
5246 rtx tmp;
5247 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5248 }
5249
5250 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5251 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5252 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5253
5254 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5255 }
5256 }
5257 [(set (attr "type")
5258 (cond [(eq_attr "alternative" "3")
5259 (const_string "lea")
5260 (match_operand:SWI48 2 "incdec_operand")
5261 (const_string "incdec")
5262 ]
5263 (const_string "alu")))
5264 (set (attr "length_immediate")
5265 (if_then_else
5266 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5267 (const_string "1")
5268 (const_string "*")))
5269 (set_attr "mode" "<MODE>")])
5270
5271 ;; It may seem that nonimmediate operand is proper one for operand 1.
5272 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5273 ;; we take care in ix86_binary_operator_ok to not allow two memory
5274 ;; operands so proper swapping will be done in reload. This allow
5275 ;; patterns constructed from addsi_1 to match.
5276
5277 (define_insn "addsi_1_zext"
5278 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5279 (zero_extend:DI
5280 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5281 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5282 (clobber (reg:CC FLAGS_REG))]
5283 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5284 {
5285 switch (get_attr_type (insn))
5286 {
5287 case TYPE_LEA:
5288 return "#";
5289
5290 case TYPE_INCDEC:
5291 if (operands[2] == const1_rtx)
5292 return "inc{l}\t%k0";
5293 else
5294 {
5295 gcc_assert (operands[2] == constm1_rtx);
5296 return "dec{l}\t%k0";
5297 }
5298
5299 default:
5300 /* For most processors, ADD is faster than LEA. This alternative
5301 was added to use ADD as much as possible. */
5302 if (which_alternative == 1)
5303 {
5304 rtx tmp;
5305 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5306 }
5307
5308 if (x86_maybe_negate_const_int (&operands[2], SImode))
5309 return "sub{l}\t{%2, %k0|%k0, %2}";
5310
5311 return "add{l}\t{%2, %k0|%k0, %2}";
5312 }
5313 }
5314 [(set (attr "type")
5315 (cond [(eq_attr "alternative" "2")
5316 (const_string "lea")
5317 (match_operand:SI 2 "incdec_operand")
5318 (const_string "incdec")
5319 ]
5320 (const_string "alu")))
5321 (set (attr "length_immediate")
5322 (if_then_else
5323 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5324 (const_string "1")
5325 (const_string "*")))
5326 (set_attr "mode" "SI")])
5327
5328 (define_insn "*addhi_1"
5329 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5330 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5331 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5332 (clobber (reg:CC FLAGS_REG))]
5333 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5334 {
5335 switch (get_attr_type (insn))
5336 {
5337 case TYPE_LEA:
5338 return "#";
5339
5340 case TYPE_INCDEC:
5341 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5342 if (operands[2] == const1_rtx)
5343 return "inc{w}\t%0";
5344 else
5345 {
5346 gcc_assert (operands[2] == constm1_rtx);
5347 return "dec{w}\t%0";
5348 }
5349
5350 default:
5351 /* For most processors, ADD is faster than LEA. This alternative
5352 was added to use ADD as much as possible. */
5353 if (which_alternative == 2)
5354 {
5355 rtx tmp;
5356 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5357 }
5358
5359 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5360 if (x86_maybe_negate_const_int (&operands[2], HImode))
5361 return "sub{w}\t{%2, %0|%0, %2}";
5362
5363 return "add{w}\t{%2, %0|%0, %2}";
5364 }
5365 }
5366 [(set (attr "type")
5367 (cond [(eq_attr "alternative" "3")
5368 (const_string "lea")
5369 (match_operand:HI 2 "incdec_operand")
5370 (const_string "incdec")
5371 ]
5372 (const_string "alu")))
5373 (set (attr "length_immediate")
5374 (if_then_else
5375 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5376 (const_string "1")
5377 (const_string "*")))
5378 (set_attr "mode" "HI,HI,HI,SI")])
5379
5380 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5381 (define_insn "*addqi_1"
5382 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5383 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5384 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5385 (clobber (reg:CC FLAGS_REG))]
5386 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5387 {
5388 bool widen = (which_alternative == 3 || which_alternative == 4);
5389
5390 switch (get_attr_type (insn))
5391 {
5392 case TYPE_LEA:
5393 return "#";
5394
5395 case TYPE_INCDEC:
5396 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5397 if (operands[2] == const1_rtx)
5398 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5399 else
5400 {
5401 gcc_assert (operands[2] == constm1_rtx);
5402 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5403 }
5404
5405 default:
5406 /* For most processors, ADD is faster than LEA. These alternatives
5407 were added to use ADD as much as possible. */
5408 if (which_alternative == 2 || which_alternative == 4)
5409 {
5410 rtx tmp;
5411 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5412 }
5413
5414 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5415 if (x86_maybe_negate_const_int (&operands[2], QImode))
5416 {
5417 if (widen)
5418 return "sub{l}\t{%2, %k0|%k0, %2}";
5419 else
5420 return "sub{b}\t{%2, %0|%0, %2}";
5421 }
5422 if (widen)
5423 return "add{l}\t{%k2, %k0|%k0, %k2}";
5424 else
5425 return "add{b}\t{%2, %0|%0, %2}";
5426 }
5427 }
5428 [(set (attr "type")
5429 (cond [(eq_attr "alternative" "5")
5430 (const_string "lea")
5431 (match_operand:QI 2 "incdec_operand")
5432 (const_string "incdec")
5433 ]
5434 (const_string "alu")))
5435 (set (attr "length_immediate")
5436 (if_then_else
5437 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5438 (const_string "1")
5439 (const_string "*")))
5440 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5441
5442 (define_insn "*addqi_1_slp"
5443 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5444 (plus:QI (match_dup 0)
5445 (match_operand:QI 1 "general_operand" "qn,qm")))
5446 (clobber (reg:CC FLAGS_REG))]
5447 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5448 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5449 {
5450 switch (get_attr_type (insn))
5451 {
5452 case TYPE_INCDEC:
5453 if (operands[1] == const1_rtx)
5454 return "inc{b}\t%0";
5455 else
5456 {
5457 gcc_assert (operands[1] == constm1_rtx);
5458 return "dec{b}\t%0";
5459 }
5460
5461 default:
5462 if (x86_maybe_negate_const_int (&operands[1], QImode))
5463 return "sub{b}\t{%1, %0|%0, %1}";
5464
5465 return "add{b}\t{%1, %0|%0, %1}";
5466 }
5467 }
5468 [(set (attr "type")
5469 (if_then_else (match_operand:QI 1 "incdec_operand")
5470 (const_string "incdec")
5471 (const_string "alu1")))
5472 (set (attr "memory")
5473 (if_then_else (match_operand 1 "memory_operand")
5474 (const_string "load")
5475 (const_string "none")))
5476 (set_attr "mode" "QI")])
5477
5478 ;; Split non destructive adds if we cannot use lea.
5479 (define_split
5480 [(set (match_operand:SWI48 0 "register_operand")
5481 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5482 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5483 (clobber (reg:CC FLAGS_REG))]
5484 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5485 [(set (match_dup 0) (match_dup 1))
5486 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5487 (clobber (reg:CC FLAGS_REG))])])
5488
5489 ;; Convert add to the lea pattern to avoid flags dependency.
5490 (define_split
5491 [(set (match_operand:SWI 0 "register_operand")
5492 (plus:SWI (match_operand:SWI 1 "register_operand")
5493 (match_operand:SWI 2 "<nonmemory_operand>")))
5494 (clobber (reg:CC FLAGS_REG))]
5495 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5496 [(const_int 0)]
5497 {
5498 enum machine_mode mode = <MODE>mode;
5499 rtx pat;
5500
5501 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5502 {
5503 mode = SImode;
5504 operands[0] = gen_lowpart (mode, operands[0]);
5505 operands[1] = gen_lowpart (mode, operands[1]);
5506 operands[2] = gen_lowpart (mode, operands[2]);
5507 }
5508
5509 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5510
5511 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5512 DONE;
5513 })
5514
5515 ;; Split non destructive adds if we cannot use lea.
5516 (define_split
5517 [(set (match_operand:DI 0 "register_operand")
5518 (zero_extend:DI
5519 (plus:SI (match_operand:SI 1 "register_operand")
5520 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5521 (clobber (reg:CC FLAGS_REG))]
5522 "TARGET_64BIT
5523 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5524 [(set (match_dup 3) (match_dup 1))
5525 (parallel [(set (match_dup 0)
5526 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5527 (clobber (reg:CC FLAGS_REG))])]
5528 "operands[3] = gen_lowpart (SImode, operands[0]);")
5529
5530 ;; Convert add to the lea pattern to avoid flags dependency.
5531 (define_split
5532 [(set (match_operand:DI 0 "register_operand")
5533 (zero_extend:DI
5534 (plus:SI (match_operand:SI 1 "register_operand")
5535 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5536 (clobber (reg:CC FLAGS_REG))]
5537 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5538 [(set (match_dup 0)
5539 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5540
5541 (define_insn "*add<mode>_2"
5542 [(set (reg FLAGS_REG)
5543 (compare
5544 (plus:SWI
5545 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5546 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5547 (const_int 0)))
5548 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5549 (plus:SWI (match_dup 1) (match_dup 2)))]
5550 "ix86_match_ccmode (insn, CCGOCmode)
5551 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5552 {
5553 switch (get_attr_type (insn))
5554 {
5555 case TYPE_INCDEC:
5556 if (operands[2] == const1_rtx)
5557 return "inc{<imodesuffix>}\t%0";
5558 else
5559 {
5560 gcc_assert (operands[2] == constm1_rtx);
5561 return "dec{<imodesuffix>}\t%0";
5562 }
5563
5564 default:
5565 if (which_alternative == 2)
5566 {
5567 rtx tmp;
5568 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5569 }
5570
5571 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5572 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5573 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5574
5575 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5576 }
5577 }
5578 [(set (attr "type")
5579 (if_then_else (match_operand:SWI 2 "incdec_operand")
5580 (const_string "incdec")
5581 (const_string "alu")))
5582 (set (attr "length_immediate")
5583 (if_then_else
5584 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5585 (const_string "1")
5586 (const_string "*")))
5587 (set_attr "mode" "<MODE>")])
5588
5589 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5590 (define_insn "*addsi_2_zext"
5591 [(set (reg FLAGS_REG)
5592 (compare
5593 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5594 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5595 (const_int 0)))
5596 (set (match_operand:DI 0 "register_operand" "=r,r")
5597 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5598 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5599 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5600 {
5601 switch (get_attr_type (insn))
5602 {
5603 case TYPE_INCDEC:
5604 if (operands[2] == const1_rtx)
5605 return "inc{l}\t%k0";
5606 else
5607 {
5608 gcc_assert (operands[2] == constm1_rtx);
5609 return "dec{l}\t%k0";
5610 }
5611
5612 default:
5613 if (which_alternative == 1)
5614 {
5615 rtx tmp;
5616 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5617 }
5618
5619 if (x86_maybe_negate_const_int (&operands[2], SImode))
5620 return "sub{l}\t{%2, %k0|%k0, %2}";
5621
5622 return "add{l}\t{%2, %k0|%k0, %2}";
5623 }
5624 }
5625 [(set (attr "type")
5626 (if_then_else (match_operand:SI 2 "incdec_operand")
5627 (const_string "incdec")
5628 (const_string "alu")))
5629 (set (attr "length_immediate")
5630 (if_then_else
5631 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5632 (const_string "1")
5633 (const_string "*")))
5634 (set_attr "mode" "SI")])
5635
5636 (define_insn "*add<mode>_3"
5637 [(set (reg FLAGS_REG)
5638 (compare
5639 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5640 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5641 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5642 "ix86_match_ccmode (insn, CCZmode)
5643 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5644 {
5645 switch (get_attr_type (insn))
5646 {
5647 case TYPE_INCDEC:
5648 if (operands[2] == const1_rtx)
5649 return "inc{<imodesuffix>}\t%0";
5650 else
5651 {
5652 gcc_assert (operands[2] == constm1_rtx);
5653 return "dec{<imodesuffix>}\t%0";
5654 }
5655
5656 default:
5657 if (which_alternative == 1)
5658 {
5659 rtx tmp;
5660 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5661 }
5662
5663 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5664 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5665 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5666
5667 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5668 }
5669 }
5670 [(set (attr "type")
5671 (if_then_else (match_operand:SWI 2 "incdec_operand")
5672 (const_string "incdec")
5673 (const_string "alu")))
5674 (set (attr "length_immediate")
5675 (if_then_else
5676 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5677 (const_string "1")
5678 (const_string "*")))
5679 (set_attr "mode" "<MODE>")])
5680
5681 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5682 (define_insn "*addsi_3_zext"
5683 [(set (reg FLAGS_REG)
5684 (compare
5685 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5686 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5687 (set (match_operand:DI 0 "register_operand" "=r,r")
5688 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5689 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5690 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5691 {
5692 switch (get_attr_type (insn))
5693 {
5694 case TYPE_INCDEC:
5695 if (operands[2] == const1_rtx)
5696 return "inc{l}\t%k0";
5697 else
5698 {
5699 gcc_assert (operands[2] == constm1_rtx);
5700 return "dec{l}\t%k0";
5701 }
5702
5703 default:
5704 if (which_alternative == 1)
5705 {
5706 rtx tmp;
5707 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5708 }
5709
5710 if (x86_maybe_negate_const_int (&operands[2], SImode))
5711 return "sub{l}\t{%2, %k0|%k0, %2}";
5712
5713 return "add{l}\t{%2, %k0|%k0, %2}";
5714 }
5715 }
5716 [(set (attr "type")
5717 (if_then_else (match_operand:SI 2 "incdec_operand")
5718 (const_string "incdec")
5719 (const_string "alu")))
5720 (set (attr "length_immediate")
5721 (if_then_else
5722 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5723 (const_string "1")
5724 (const_string "*")))
5725 (set_attr "mode" "SI")])
5726
5727 ; For comparisons against 1, -1 and 128, we may generate better code
5728 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5729 ; is matched then. We can't accept general immediate, because for
5730 ; case of overflows, the result is messed up.
5731 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5732 ; only for comparisons not depending on it.
5733
5734 (define_insn "*adddi_4"
5735 [(set (reg FLAGS_REG)
5736 (compare
5737 (match_operand:DI 1 "nonimmediate_operand" "0")
5738 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5739 (clobber (match_scratch:DI 0 "=rm"))]
5740 "TARGET_64BIT
5741 && ix86_match_ccmode (insn, CCGCmode)"
5742 {
5743 switch (get_attr_type (insn))
5744 {
5745 case TYPE_INCDEC:
5746 if (operands[2] == constm1_rtx)
5747 return "inc{q}\t%0";
5748 else
5749 {
5750 gcc_assert (operands[2] == const1_rtx);
5751 return "dec{q}\t%0";
5752 }
5753
5754 default:
5755 if (x86_maybe_negate_const_int (&operands[2], DImode))
5756 return "add{q}\t{%2, %0|%0, %2}";
5757
5758 return "sub{q}\t{%2, %0|%0, %2}";
5759 }
5760 }
5761 [(set (attr "type")
5762 (if_then_else (match_operand:DI 2 "incdec_operand")
5763 (const_string "incdec")
5764 (const_string "alu")))
5765 (set (attr "length_immediate")
5766 (if_then_else
5767 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5768 (const_string "1")
5769 (const_string "*")))
5770 (set_attr "mode" "DI")])
5771
5772 ; For comparisons against 1, -1 and 128, we may generate better code
5773 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5774 ; is matched then. We can't accept general immediate, because for
5775 ; case of overflows, the result is messed up.
5776 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5777 ; only for comparisons not depending on it.
5778
5779 (define_insn "*add<mode>_4"
5780 [(set (reg FLAGS_REG)
5781 (compare
5782 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5783 (match_operand:SWI124 2 "const_int_operand" "n")))
5784 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5785 "ix86_match_ccmode (insn, CCGCmode)"
5786 {
5787 switch (get_attr_type (insn))
5788 {
5789 case TYPE_INCDEC:
5790 if (operands[2] == constm1_rtx)
5791 return "inc{<imodesuffix>}\t%0";
5792 else
5793 {
5794 gcc_assert (operands[2] == const1_rtx);
5795 return "dec{<imodesuffix>}\t%0";
5796 }
5797
5798 default:
5799 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5800 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5801
5802 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5803 }
5804 }
5805 [(set (attr "type")
5806 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5807 (const_string "incdec")
5808 (const_string "alu")))
5809 (set (attr "length_immediate")
5810 (if_then_else
5811 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5812 (const_string "1")
5813 (const_string "*")))
5814 (set_attr "mode" "<MODE>")])
5815
5816 (define_insn "*add<mode>_5"
5817 [(set (reg FLAGS_REG)
5818 (compare
5819 (plus:SWI
5820 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5821 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5822 (const_int 0)))
5823 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5824 "ix86_match_ccmode (insn, CCGOCmode)
5825 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5826 {
5827 switch (get_attr_type (insn))
5828 {
5829 case TYPE_INCDEC:
5830 if (operands[2] == const1_rtx)
5831 return "inc{<imodesuffix>}\t%0";
5832 else
5833 {
5834 gcc_assert (operands[2] == constm1_rtx);
5835 return "dec{<imodesuffix>}\t%0";
5836 }
5837
5838 default:
5839 if (which_alternative == 1)
5840 {
5841 rtx tmp;
5842 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5843 }
5844
5845 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5846 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5847 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5848
5849 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5850 }
5851 }
5852 [(set (attr "type")
5853 (if_then_else (match_operand:SWI 2 "incdec_operand")
5854 (const_string "incdec")
5855 (const_string "alu")))
5856 (set (attr "length_immediate")
5857 (if_then_else
5858 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5859 (const_string "1")
5860 (const_string "*")))
5861 (set_attr "mode" "<MODE>")])
5862
5863 (define_insn "addqi_ext_1"
5864 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5865 (const_int 8)
5866 (const_int 8))
5867 (plus:SI
5868 (zero_extract:SI
5869 (match_operand 1 "ext_register_operand" "0,0")
5870 (const_int 8)
5871 (const_int 8))
5872 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5873 (clobber (reg:CC FLAGS_REG))]
5874 ""
5875 {
5876 switch (get_attr_type (insn))
5877 {
5878 case TYPE_INCDEC:
5879 if (operands[2] == const1_rtx)
5880 return "inc{b}\t%h0";
5881 else
5882 {
5883 gcc_assert (operands[2] == constm1_rtx);
5884 return "dec{b}\t%h0";
5885 }
5886
5887 default:
5888 return "add{b}\t{%2, %h0|%h0, %2}";
5889 }
5890 }
5891 [(set_attr "isa" "*,nox64")
5892 (set (attr "type")
5893 (if_then_else (match_operand:QI 2 "incdec_operand")
5894 (const_string "incdec")
5895 (const_string "alu")))
5896 (set_attr "modrm" "1")
5897 (set_attr "mode" "QI")])
5898
5899 (define_insn "*addqi_ext_2"
5900 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5901 (const_int 8)
5902 (const_int 8))
5903 (plus:SI
5904 (zero_extract:SI
5905 (match_operand 1 "ext_register_operand" "%0")
5906 (const_int 8)
5907 (const_int 8))
5908 (zero_extract:SI
5909 (match_operand 2 "ext_register_operand" "Q")
5910 (const_int 8)
5911 (const_int 8))))
5912 (clobber (reg:CC FLAGS_REG))]
5913 ""
5914 "add{b}\t{%h2, %h0|%h0, %h2}"
5915 [(set_attr "type" "alu")
5916 (set_attr "mode" "QI")])
5917
5918 ;; The lea patterns for modes less than 32 bits need to be matched by
5919 ;; several insns converted to real lea by splitters.
5920
5921 (define_insn_and_split "*lea_general_1"
5922 [(set (match_operand 0 "register_operand" "=r")
5923 (plus (plus (match_operand 1 "index_register_operand" "l")
5924 (match_operand 2 "register_operand" "r"))
5925 (match_operand 3 "immediate_operand" "i")))]
5926 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5927 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5928 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5929 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5930 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5931 || GET_MODE (operands[3]) == VOIDmode)"
5932 "#"
5933 "&& reload_completed"
5934 [(const_int 0)]
5935 {
5936 enum machine_mode mode = SImode;
5937 rtx pat;
5938
5939 operands[0] = gen_lowpart (mode, operands[0]);
5940 operands[1] = gen_lowpart (mode, operands[1]);
5941 operands[2] = gen_lowpart (mode, operands[2]);
5942 operands[3] = gen_lowpart (mode, operands[3]);
5943
5944 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5945 operands[3]);
5946
5947 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5948 DONE;
5949 }
5950 [(set_attr "type" "lea")
5951 (set_attr "mode" "SI")])
5952
5953 (define_insn_and_split "*lea_general_2"
5954 [(set (match_operand 0 "register_operand" "=r")
5955 (plus (mult (match_operand 1 "index_register_operand" "l")
5956 (match_operand 2 "const248_operand" "n"))
5957 (match_operand 3 "nonmemory_operand" "ri")))]
5958 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5959 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5960 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5961 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5962 || GET_MODE (operands[3]) == VOIDmode)"
5963 "#"
5964 "&& reload_completed"
5965 [(const_int 0)]
5966 {
5967 enum machine_mode mode = SImode;
5968 rtx pat;
5969
5970 operands[0] = gen_lowpart (mode, operands[0]);
5971 operands[1] = gen_lowpart (mode, operands[1]);
5972 operands[3] = gen_lowpart (mode, operands[3]);
5973
5974 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5975 operands[3]);
5976
5977 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5978 DONE;
5979 }
5980 [(set_attr "type" "lea")
5981 (set_attr "mode" "SI")])
5982
5983 (define_insn_and_split "*lea_general_3"
5984 [(set (match_operand 0 "register_operand" "=r")
5985 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5986 (match_operand 2 "const248_operand" "n"))
5987 (match_operand 3 "register_operand" "r"))
5988 (match_operand 4 "immediate_operand" "i")))]
5989 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5990 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5991 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5992 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5993 "#"
5994 "&& reload_completed"
5995 [(const_int 0)]
5996 {
5997 enum machine_mode mode = SImode;
5998 rtx pat;
5999
6000 operands[0] = gen_lowpart (mode, operands[0]);
6001 operands[1] = gen_lowpart (mode, operands[1]);
6002 operands[3] = gen_lowpart (mode, operands[3]);
6003 operands[4] = gen_lowpart (mode, operands[4]);
6004
6005 pat = gen_rtx_PLUS (mode,
6006 gen_rtx_PLUS (mode,
6007 gen_rtx_MULT (mode, operands[1],
6008 operands[2]),
6009 operands[3]),
6010 operands[4]);
6011
6012 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6013 DONE;
6014 }
6015 [(set_attr "type" "lea")
6016 (set_attr "mode" "SI")])
6017
6018 (define_insn_and_split "*lea_general_4"
6019 [(set (match_operand 0 "register_operand" "=r")
6020 (any_or (ashift
6021 (match_operand 1 "index_register_operand" "l")
6022 (match_operand 2 "const_int_operand" "n"))
6023 (match_operand 3 "const_int_operand" "n")))]
6024 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6025 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6026 || GET_MODE (operands[0]) == SImode
6027 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6028 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6029 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6030 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6031 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6032 "#"
6033 "&& reload_completed"
6034 [(const_int 0)]
6035 {
6036 enum machine_mode mode = GET_MODE (operands[0]);
6037 rtx pat;
6038
6039 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6040 {
6041 mode = SImode;
6042 operands[0] = gen_lowpart (mode, operands[0]);
6043 operands[1] = gen_lowpart (mode, operands[1]);
6044 }
6045
6046 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6047
6048 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6049 INTVAL (operands[3]));
6050
6051 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6052 DONE;
6053 }
6054 [(set_attr "type" "lea")
6055 (set (attr "mode")
6056 (if_then_else (match_operand:DI 0)
6057 (const_string "DI")
6058 (const_string "SI")))])
6059 \f
6060 ;; Subtract instructions
6061
6062 (define_expand "sub<mode>3"
6063 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6064 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6065 (match_operand:SDWIM 2 "<general_operand>")))]
6066 ""
6067 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6068
6069 (define_insn_and_split "*sub<dwi>3_doubleword"
6070 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6071 (minus:<DWI>
6072 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6073 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6074 (clobber (reg:CC FLAGS_REG))]
6075 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6076 "#"
6077 "reload_completed"
6078 [(parallel [(set (reg:CC FLAGS_REG)
6079 (compare:CC (match_dup 1) (match_dup 2)))
6080 (set (match_dup 0)
6081 (minus:DWIH (match_dup 1) (match_dup 2)))])
6082 (parallel [(set (match_dup 3)
6083 (minus:DWIH
6084 (match_dup 4)
6085 (plus:DWIH
6086 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6087 (match_dup 5))))
6088 (clobber (reg:CC FLAGS_REG))])]
6089 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6090
6091 (define_insn "*sub<mode>_1"
6092 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6093 (minus:SWI
6094 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6095 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6096 (clobber (reg:CC FLAGS_REG))]
6097 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6098 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6099 [(set_attr "type" "alu")
6100 (set_attr "mode" "<MODE>")])
6101
6102 (define_insn "*subsi_1_zext"
6103 [(set (match_operand:DI 0 "register_operand" "=r")
6104 (zero_extend:DI
6105 (minus:SI (match_operand:SI 1 "register_operand" "0")
6106 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6107 (clobber (reg:CC FLAGS_REG))]
6108 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6109 "sub{l}\t{%2, %k0|%k0, %2}"
6110 [(set_attr "type" "alu")
6111 (set_attr "mode" "SI")])
6112
6113 (define_insn "*subqi_1_slp"
6114 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6115 (minus:QI (match_dup 0)
6116 (match_operand:QI 1 "general_operand" "qn,qm")))
6117 (clobber (reg:CC FLAGS_REG))]
6118 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6119 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6120 "sub{b}\t{%1, %0|%0, %1}"
6121 [(set_attr "type" "alu1")
6122 (set_attr "mode" "QI")])
6123
6124 (define_insn "*sub<mode>_2"
6125 [(set (reg FLAGS_REG)
6126 (compare
6127 (minus:SWI
6128 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6129 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6130 (const_int 0)))
6131 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6132 (minus:SWI (match_dup 1) (match_dup 2)))]
6133 "ix86_match_ccmode (insn, CCGOCmode)
6134 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6135 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6136 [(set_attr "type" "alu")
6137 (set_attr "mode" "<MODE>")])
6138
6139 (define_insn "*subsi_2_zext"
6140 [(set (reg FLAGS_REG)
6141 (compare
6142 (minus:SI (match_operand:SI 1 "register_operand" "0")
6143 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6144 (const_int 0)))
6145 (set (match_operand:DI 0 "register_operand" "=r")
6146 (zero_extend:DI
6147 (minus:SI (match_dup 1)
6148 (match_dup 2))))]
6149 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6150 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6151 "sub{l}\t{%2, %k0|%k0, %2}"
6152 [(set_attr "type" "alu")
6153 (set_attr "mode" "SI")])
6154
6155 (define_insn "*sub<mode>_3"
6156 [(set (reg FLAGS_REG)
6157 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6158 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6159 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6160 (minus:SWI (match_dup 1) (match_dup 2)))]
6161 "ix86_match_ccmode (insn, CCmode)
6162 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6163 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6164 [(set_attr "type" "alu")
6165 (set_attr "mode" "<MODE>")])
6166
6167 (define_insn "*subsi_3_zext"
6168 [(set (reg FLAGS_REG)
6169 (compare (match_operand:SI 1 "register_operand" "0")
6170 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6171 (set (match_operand:DI 0 "register_operand" "=r")
6172 (zero_extend:DI
6173 (minus:SI (match_dup 1)
6174 (match_dup 2))))]
6175 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6176 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6177 "sub{l}\t{%2, %1|%1, %2}"
6178 [(set_attr "type" "alu")
6179 (set_attr "mode" "SI")])
6180 \f
6181 ;; Add with carry and subtract with borrow
6182
6183 (define_expand "<plusminus_insn><mode>3_carry"
6184 [(parallel
6185 [(set (match_operand:SWI 0 "nonimmediate_operand")
6186 (plusminus:SWI
6187 (match_operand:SWI 1 "nonimmediate_operand")
6188 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6189 [(match_operand 3 "flags_reg_operand")
6190 (const_int 0)])
6191 (match_operand:SWI 2 "<general_operand>"))))
6192 (clobber (reg:CC FLAGS_REG))])]
6193 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6194
6195 (define_insn "*<plusminus_insn><mode>3_carry"
6196 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6197 (plusminus:SWI
6198 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6199 (plus:SWI
6200 (match_operator 3 "ix86_carry_flag_operator"
6201 [(reg FLAGS_REG) (const_int 0)])
6202 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6203 (clobber (reg:CC FLAGS_REG))]
6204 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6205 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6206 [(set_attr "type" "alu")
6207 (set_attr "use_carry" "1")
6208 (set_attr "pent_pair" "pu")
6209 (set_attr "mode" "<MODE>")])
6210
6211 (define_insn "*addsi3_carry_zext"
6212 [(set (match_operand:DI 0 "register_operand" "=r")
6213 (zero_extend:DI
6214 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6215 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6216 [(reg FLAGS_REG) (const_int 0)])
6217 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6218 (clobber (reg:CC FLAGS_REG))]
6219 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6220 "adc{l}\t{%2, %k0|%k0, %2}"
6221 [(set_attr "type" "alu")
6222 (set_attr "use_carry" "1")
6223 (set_attr "pent_pair" "pu")
6224 (set_attr "mode" "SI")])
6225
6226 (define_insn "*subsi3_carry_zext"
6227 [(set (match_operand:DI 0 "register_operand" "=r")
6228 (zero_extend:DI
6229 (minus:SI (match_operand:SI 1 "register_operand" "0")
6230 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6231 [(reg FLAGS_REG) (const_int 0)])
6232 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6233 (clobber (reg:CC FLAGS_REG))]
6234 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6235 "sbb{l}\t{%2, %k0|%k0, %2}"
6236 [(set_attr "type" "alu")
6237 (set_attr "pent_pair" "pu")
6238 (set_attr "mode" "SI")])
6239 \f
6240 ;; ADCX instruction
6241
6242 (define_insn "adcx<mode>3"
6243 [(set (reg:CCC FLAGS_REG)
6244 (compare:CCC
6245 (plus:SWI48
6246 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6247 (plus:SWI48
6248 (match_operator 4 "ix86_carry_flag_operator"
6249 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6250 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6251 (const_int 0)))
6252 (set (match_operand:SWI48 0 "register_operand" "=r")
6253 (plus:SWI48 (match_dup 1)
6254 (plus:SWI48 (match_op_dup 4
6255 [(match_dup 3) (const_int 0)])
6256 (match_dup 2))))]
6257 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6258 "adcx\t{%2, %0|%0, %2}"
6259 [(set_attr "type" "alu")
6260 (set_attr "use_carry" "1")
6261 (set_attr "mode" "<MODE>")])
6262 \f
6263 ;; Overflow setting add and subtract instructions
6264
6265 (define_insn "*add<mode>3_cconly_overflow"
6266 [(set (reg:CCC FLAGS_REG)
6267 (compare:CCC
6268 (plus:SWI
6269 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6270 (match_operand:SWI 2 "<general_operand>" "<g>"))
6271 (match_dup 1)))
6272 (clobber (match_scratch:SWI 0 "=<r>"))]
6273 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6274 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6275 [(set_attr "type" "alu")
6276 (set_attr "mode" "<MODE>")])
6277
6278 (define_insn "*sub<mode>3_cconly_overflow"
6279 [(set (reg:CCC FLAGS_REG)
6280 (compare:CCC
6281 (minus:SWI
6282 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6283 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6284 (match_dup 0)))]
6285 ""
6286 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6287 [(set_attr "type" "icmp")
6288 (set_attr "mode" "<MODE>")])
6289
6290 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6291 [(set (reg:CCC FLAGS_REG)
6292 (compare:CCC
6293 (plusminus:SWI
6294 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6295 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6296 (match_dup 1)))
6297 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6298 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6299 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6300 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6301 [(set_attr "type" "alu")
6302 (set_attr "mode" "<MODE>")])
6303
6304 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6305 [(set (reg:CCC FLAGS_REG)
6306 (compare:CCC
6307 (plusminus:SI
6308 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6309 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6310 (match_dup 1)))
6311 (set (match_operand:DI 0 "register_operand" "=r")
6312 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6313 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6314 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6315 [(set_attr "type" "alu")
6316 (set_attr "mode" "SI")])
6317
6318 ;; The patterns that match these are at the end of this file.
6319
6320 (define_expand "<plusminus_insn>xf3"
6321 [(set (match_operand:XF 0 "register_operand")
6322 (plusminus:XF
6323 (match_operand:XF 1 "register_operand")
6324 (match_operand:XF 2 "register_operand")))]
6325 "TARGET_80387")
6326
6327 (define_expand "<plusminus_insn><mode>3"
6328 [(set (match_operand:MODEF 0 "register_operand")
6329 (plusminus:MODEF
6330 (match_operand:MODEF 1 "register_operand")
6331 (match_operand:MODEF 2 "nonimmediate_operand")))]
6332 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6333 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6334 \f
6335 ;; Multiply instructions
6336
6337 (define_expand "mul<mode>3"
6338 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6339 (mult:SWIM248
6340 (match_operand:SWIM248 1 "register_operand")
6341 (match_operand:SWIM248 2 "<general_operand>")))
6342 (clobber (reg:CC FLAGS_REG))])])
6343
6344 (define_expand "mulqi3"
6345 [(parallel [(set (match_operand:QI 0 "register_operand")
6346 (mult:QI
6347 (match_operand:QI 1 "register_operand")
6348 (match_operand:QI 2 "nonimmediate_operand")))
6349 (clobber (reg:CC FLAGS_REG))])]
6350 "TARGET_QIMODE_MATH")
6351
6352 ;; On AMDFAM10
6353 ;; IMUL reg32/64, reg32/64, imm8 Direct
6354 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6355 ;; IMUL reg32/64, reg32/64, imm32 Direct
6356 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6357 ;; IMUL reg32/64, reg32/64 Direct
6358 ;; IMUL reg32/64, mem32/64 Direct
6359 ;;
6360 ;; On BDVER1, all above IMULs use DirectPath
6361
6362 (define_insn "*mul<mode>3_1"
6363 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6364 (mult:SWI48
6365 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6366 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6367 (clobber (reg:CC FLAGS_REG))]
6368 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6369 "@
6370 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6371 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6372 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6373 [(set_attr "type" "imul")
6374 (set_attr "prefix_0f" "0,0,1")
6375 (set (attr "athlon_decode")
6376 (cond [(eq_attr "cpu" "athlon")
6377 (const_string "vector")
6378 (eq_attr "alternative" "1")
6379 (const_string "vector")
6380 (and (eq_attr "alternative" "2")
6381 (match_operand 1 "memory_operand"))
6382 (const_string "vector")]
6383 (const_string "direct")))
6384 (set (attr "amdfam10_decode")
6385 (cond [(and (eq_attr "alternative" "0,1")
6386 (match_operand 1 "memory_operand"))
6387 (const_string "vector")]
6388 (const_string "direct")))
6389 (set_attr "bdver1_decode" "direct")
6390 (set_attr "mode" "<MODE>")])
6391
6392 (define_insn "*mulsi3_1_zext"
6393 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6394 (zero_extend:DI
6395 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6396 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6397 (clobber (reg:CC FLAGS_REG))]
6398 "TARGET_64BIT
6399 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6400 "@
6401 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6402 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6403 imul{l}\t{%2, %k0|%k0, %2}"
6404 [(set_attr "type" "imul")
6405 (set_attr "prefix_0f" "0,0,1")
6406 (set (attr "athlon_decode")
6407 (cond [(eq_attr "cpu" "athlon")
6408 (const_string "vector")
6409 (eq_attr "alternative" "1")
6410 (const_string "vector")
6411 (and (eq_attr "alternative" "2")
6412 (match_operand 1 "memory_operand"))
6413 (const_string "vector")]
6414 (const_string "direct")))
6415 (set (attr "amdfam10_decode")
6416 (cond [(and (eq_attr "alternative" "0,1")
6417 (match_operand 1 "memory_operand"))
6418 (const_string "vector")]
6419 (const_string "direct")))
6420 (set_attr "bdver1_decode" "direct")
6421 (set_attr "mode" "SI")])
6422
6423 ;; On AMDFAM10
6424 ;; IMUL reg16, reg16, imm8 VectorPath
6425 ;; IMUL reg16, mem16, imm8 VectorPath
6426 ;; IMUL reg16, reg16, imm16 VectorPath
6427 ;; IMUL reg16, mem16, imm16 VectorPath
6428 ;; IMUL reg16, reg16 Direct
6429 ;; IMUL reg16, mem16 Direct
6430 ;;
6431 ;; On BDVER1, all HI MULs use DoublePath
6432
6433 (define_insn "*mulhi3_1"
6434 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6435 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6436 (match_operand:HI 2 "general_operand" "K,n,mr")))
6437 (clobber (reg:CC FLAGS_REG))]
6438 "TARGET_HIMODE_MATH
6439 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6440 "@
6441 imul{w}\t{%2, %1, %0|%0, %1, %2}
6442 imul{w}\t{%2, %1, %0|%0, %1, %2}
6443 imul{w}\t{%2, %0|%0, %2}"
6444 [(set_attr "type" "imul")
6445 (set_attr "prefix_0f" "0,0,1")
6446 (set (attr "athlon_decode")
6447 (cond [(eq_attr "cpu" "athlon")
6448 (const_string "vector")
6449 (eq_attr "alternative" "1,2")
6450 (const_string "vector")]
6451 (const_string "direct")))
6452 (set (attr "amdfam10_decode")
6453 (cond [(eq_attr "alternative" "0,1")
6454 (const_string "vector")]
6455 (const_string "direct")))
6456 (set_attr "bdver1_decode" "double")
6457 (set_attr "mode" "HI")])
6458
6459 ;;On AMDFAM10 and BDVER1
6460 ;; MUL reg8 Direct
6461 ;; MUL mem8 Direct
6462
6463 (define_insn "*mulqi3_1"
6464 [(set (match_operand:QI 0 "register_operand" "=a")
6465 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6466 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6467 (clobber (reg:CC FLAGS_REG))]
6468 "TARGET_QIMODE_MATH
6469 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6470 "mul{b}\t%2"
6471 [(set_attr "type" "imul")
6472 (set_attr "length_immediate" "0")
6473 (set (attr "athlon_decode")
6474 (if_then_else (eq_attr "cpu" "athlon")
6475 (const_string "vector")
6476 (const_string "direct")))
6477 (set_attr "amdfam10_decode" "direct")
6478 (set_attr "bdver1_decode" "direct")
6479 (set_attr "mode" "QI")])
6480
6481 (define_expand "<u>mul<mode><dwi>3"
6482 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6483 (mult:<DWI>
6484 (any_extend:<DWI>
6485 (match_operand:DWIH 1 "nonimmediate_operand"))
6486 (any_extend:<DWI>
6487 (match_operand:DWIH 2 "register_operand"))))
6488 (clobber (reg:CC FLAGS_REG))])])
6489
6490 (define_expand "<u>mulqihi3"
6491 [(parallel [(set (match_operand:HI 0 "register_operand")
6492 (mult:HI
6493 (any_extend:HI
6494 (match_operand:QI 1 "nonimmediate_operand"))
6495 (any_extend:HI
6496 (match_operand:QI 2 "register_operand"))))
6497 (clobber (reg:CC FLAGS_REG))])]
6498 "TARGET_QIMODE_MATH")
6499
6500 (define_insn "*bmi2_umulditi3_1"
6501 [(set (match_operand:DI 0 "register_operand" "=r")
6502 (mult:DI
6503 (match_operand:DI 2 "nonimmediate_operand" "%d")
6504 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6505 (set (match_operand:DI 1 "register_operand" "=r")
6506 (truncate:DI
6507 (lshiftrt:TI
6508 (mult:TI (zero_extend:TI (match_dup 2))
6509 (zero_extend:TI (match_dup 3)))
6510 (const_int 64))))]
6511 "TARGET_64BIT && TARGET_BMI2
6512 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6513 "mulx\t{%3, %0, %1|%1, %0, %3}"
6514 [(set_attr "type" "imulx")
6515 (set_attr "prefix" "vex")
6516 (set_attr "mode" "DI")])
6517
6518 (define_insn "*bmi2_umulsidi3_1"
6519 [(set (match_operand:SI 0 "register_operand" "=r")
6520 (mult:SI
6521 (match_operand:SI 2 "nonimmediate_operand" "%d")
6522 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6523 (set (match_operand:SI 1 "register_operand" "=r")
6524 (truncate:SI
6525 (lshiftrt:DI
6526 (mult:DI (zero_extend:DI (match_dup 2))
6527 (zero_extend:DI (match_dup 3)))
6528 (const_int 32))))]
6529 "!TARGET_64BIT && TARGET_BMI2
6530 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6531 "mulx\t{%3, %0, %1|%1, %0, %3}"
6532 [(set_attr "type" "imulx")
6533 (set_attr "prefix" "vex")
6534 (set_attr "mode" "SI")])
6535
6536 (define_insn "*umul<mode><dwi>3_1"
6537 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6538 (mult:<DWI>
6539 (zero_extend:<DWI>
6540 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6541 (zero_extend:<DWI>
6542 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6543 (clobber (reg:CC FLAGS_REG))]
6544 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6545 "@
6546 #
6547 mul{<imodesuffix>}\t%2"
6548 [(set_attr "isa" "bmi2,*")
6549 (set_attr "type" "imulx,imul")
6550 (set_attr "length_immediate" "*,0")
6551 (set (attr "athlon_decode")
6552 (cond [(eq_attr "alternative" "1")
6553 (if_then_else (eq_attr "cpu" "athlon")
6554 (const_string "vector")
6555 (const_string "double"))]
6556 (const_string "*")))
6557 (set_attr "amdfam10_decode" "*,double")
6558 (set_attr "bdver1_decode" "*,direct")
6559 (set_attr "prefix" "vex,orig")
6560 (set_attr "mode" "<MODE>")])
6561
6562 ;; Convert mul to the mulx pattern to avoid flags dependency.
6563 (define_split
6564 [(set (match_operand:<DWI> 0 "register_operand")
6565 (mult:<DWI>
6566 (zero_extend:<DWI>
6567 (match_operand:DWIH 1 "register_operand"))
6568 (zero_extend:<DWI>
6569 (match_operand:DWIH 2 "nonimmediate_operand"))))
6570 (clobber (reg:CC FLAGS_REG))]
6571 "TARGET_BMI2 && reload_completed
6572 && true_regnum (operands[1]) == DX_REG"
6573 [(parallel [(set (match_dup 3)
6574 (mult:DWIH (match_dup 1) (match_dup 2)))
6575 (set (match_dup 4)
6576 (truncate:DWIH
6577 (lshiftrt:<DWI>
6578 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6579 (zero_extend:<DWI> (match_dup 2)))
6580 (match_dup 5))))])]
6581 {
6582 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6583
6584 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6585 })
6586
6587 (define_insn "*mul<mode><dwi>3_1"
6588 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6589 (mult:<DWI>
6590 (sign_extend:<DWI>
6591 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6592 (sign_extend:<DWI>
6593 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6594 (clobber (reg:CC FLAGS_REG))]
6595 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6596 "imul{<imodesuffix>}\t%2"
6597 [(set_attr "type" "imul")
6598 (set_attr "length_immediate" "0")
6599 (set (attr "athlon_decode")
6600 (if_then_else (eq_attr "cpu" "athlon")
6601 (const_string "vector")
6602 (const_string "double")))
6603 (set_attr "amdfam10_decode" "double")
6604 (set_attr "bdver1_decode" "direct")
6605 (set_attr "mode" "<MODE>")])
6606
6607 (define_insn "*<u>mulqihi3_1"
6608 [(set (match_operand:HI 0 "register_operand" "=a")
6609 (mult:HI
6610 (any_extend:HI
6611 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6612 (any_extend:HI
6613 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6614 (clobber (reg:CC FLAGS_REG))]
6615 "TARGET_QIMODE_MATH
6616 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6617 "<sgnprefix>mul{b}\t%2"
6618 [(set_attr "type" "imul")
6619 (set_attr "length_immediate" "0")
6620 (set (attr "athlon_decode")
6621 (if_then_else (eq_attr "cpu" "athlon")
6622 (const_string "vector")
6623 (const_string "direct")))
6624 (set_attr "amdfam10_decode" "direct")
6625 (set_attr "bdver1_decode" "direct")
6626 (set_attr "mode" "QI")])
6627
6628 (define_expand "<s>mul<mode>3_highpart"
6629 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6630 (truncate:SWI48
6631 (lshiftrt:<DWI>
6632 (mult:<DWI>
6633 (any_extend:<DWI>
6634 (match_operand:SWI48 1 "nonimmediate_operand"))
6635 (any_extend:<DWI>
6636 (match_operand:SWI48 2 "register_operand")))
6637 (match_dup 4))))
6638 (clobber (match_scratch:SWI48 3))
6639 (clobber (reg:CC FLAGS_REG))])]
6640 ""
6641 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6642
6643 (define_insn "*<s>muldi3_highpart_1"
6644 [(set (match_operand:DI 0 "register_operand" "=d")
6645 (truncate:DI
6646 (lshiftrt:TI
6647 (mult:TI
6648 (any_extend:TI
6649 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6650 (any_extend:TI
6651 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6652 (const_int 64))))
6653 (clobber (match_scratch:DI 3 "=1"))
6654 (clobber (reg:CC FLAGS_REG))]
6655 "TARGET_64BIT
6656 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6657 "<sgnprefix>mul{q}\t%2"
6658 [(set_attr "type" "imul")
6659 (set_attr "length_immediate" "0")
6660 (set (attr "athlon_decode")
6661 (if_then_else (eq_attr "cpu" "athlon")
6662 (const_string "vector")
6663 (const_string "double")))
6664 (set_attr "amdfam10_decode" "double")
6665 (set_attr "bdver1_decode" "direct")
6666 (set_attr "mode" "DI")])
6667
6668 (define_insn "*<s>mulsi3_highpart_1"
6669 [(set (match_operand:SI 0 "register_operand" "=d")
6670 (truncate:SI
6671 (lshiftrt:DI
6672 (mult:DI
6673 (any_extend:DI
6674 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6675 (any_extend:DI
6676 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6677 (const_int 32))))
6678 (clobber (match_scratch:SI 3 "=1"))
6679 (clobber (reg:CC FLAGS_REG))]
6680 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6681 "<sgnprefix>mul{l}\t%2"
6682 [(set_attr "type" "imul")
6683 (set_attr "length_immediate" "0")
6684 (set (attr "athlon_decode")
6685 (if_then_else (eq_attr "cpu" "athlon")
6686 (const_string "vector")
6687 (const_string "double")))
6688 (set_attr "amdfam10_decode" "double")
6689 (set_attr "bdver1_decode" "direct")
6690 (set_attr "mode" "SI")])
6691
6692 (define_insn "*<s>mulsi3_highpart_zext"
6693 [(set (match_operand:DI 0 "register_operand" "=d")
6694 (zero_extend:DI (truncate:SI
6695 (lshiftrt:DI
6696 (mult:DI (any_extend:DI
6697 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6698 (any_extend:DI
6699 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6700 (const_int 32)))))
6701 (clobber (match_scratch:SI 3 "=1"))
6702 (clobber (reg:CC FLAGS_REG))]
6703 "TARGET_64BIT
6704 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6705 "<sgnprefix>mul{l}\t%2"
6706 [(set_attr "type" "imul")
6707 (set_attr "length_immediate" "0")
6708 (set (attr "athlon_decode")
6709 (if_then_else (eq_attr "cpu" "athlon")
6710 (const_string "vector")
6711 (const_string "double")))
6712 (set_attr "amdfam10_decode" "double")
6713 (set_attr "bdver1_decode" "direct")
6714 (set_attr "mode" "SI")])
6715
6716 ;; The patterns that match these are at the end of this file.
6717
6718 (define_expand "mulxf3"
6719 [(set (match_operand:XF 0 "register_operand")
6720 (mult:XF (match_operand:XF 1 "register_operand")
6721 (match_operand:XF 2 "register_operand")))]
6722 "TARGET_80387")
6723
6724 (define_expand "mul<mode>3"
6725 [(set (match_operand:MODEF 0 "register_operand")
6726 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6727 (match_operand:MODEF 2 "nonimmediate_operand")))]
6728 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6729 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6730 \f
6731 ;; Divide instructions
6732
6733 ;; The patterns that match these are at the end of this file.
6734
6735 (define_expand "divxf3"
6736 [(set (match_operand:XF 0 "register_operand")
6737 (div:XF (match_operand:XF 1 "register_operand")
6738 (match_operand:XF 2 "register_operand")))]
6739 "TARGET_80387")
6740
6741 (define_expand "divdf3"
6742 [(set (match_operand:DF 0 "register_operand")
6743 (div:DF (match_operand:DF 1 "register_operand")
6744 (match_operand:DF 2 "nonimmediate_operand")))]
6745 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6746 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6747
6748 (define_expand "divsf3"
6749 [(set (match_operand:SF 0 "register_operand")
6750 (div:SF (match_operand:SF 1 "register_operand")
6751 (match_operand:SF 2 "nonimmediate_operand")))]
6752 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6753 || TARGET_SSE_MATH"
6754 {
6755 if (TARGET_SSE_MATH
6756 && TARGET_RECIP_DIV
6757 && optimize_insn_for_speed_p ()
6758 && flag_finite_math_only && !flag_trapping_math
6759 && flag_unsafe_math_optimizations)
6760 {
6761 ix86_emit_swdivsf (operands[0], operands[1],
6762 operands[2], SFmode);
6763 DONE;
6764 }
6765 })
6766 \f
6767 ;; Divmod instructions.
6768
6769 (define_expand "divmod<mode>4"
6770 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6771 (div:SWIM248
6772 (match_operand:SWIM248 1 "register_operand")
6773 (match_operand:SWIM248 2 "nonimmediate_operand")))
6774 (set (match_operand:SWIM248 3 "register_operand")
6775 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6776 (clobber (reg:CC FLAGS_REG))])])
6777
6778 ;; Split with 8bit unsigned divide:
6779 ;; if (dividend an divisor are in [0-255])
6780 ;; use 8bit unsigned integer divide
6781 ;; else
6782 ;; use original integer divide
6783 (define_split
6784 [(set (match_operand:SWI48 0 "register_operand")
6785 (div:SWI48 (match_operand:SWI48 2 "register_operand")
6786 (match_operand:SWI48 3 "nonimmediate_operand")))
6787 (set (match_operand:SWI48 1 "register_operand")
6788 (mod:SWI48 (match_dup 2) (match_dup 3)))
6789 (clobber (reg:CC FLAGS_REG))]
6790 "TARGET_USE_8BIT_IDIV
6791 && TARGET_QIMODE_MATH
6792 && can_create_pseudo_p ()
6793 && !optimize_insn_for_size_p ()"
6794 [(const_int 0)]
6795 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6796
6797 (define_insn_and_split "divmod<mode>4_1"
6798 [(set (match_operand:SWI48 0 "register_operand" "=a")
6799 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6800 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6801 (set (match_operand:SWI48 1 "register_operand" "=&d")
6802 (mod:SWI48 (match_dup 2) (match_dup 3)))
6803 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6804 (clobber (reg:CC FLAGS_REG))]
6805 ""
6806 "#"
6807 "reload_completed"
6808 [(parallel [(set (match_dup 1)
6809 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6810 (clobber (reg:CC FLAGS_REG))])
6811 (parallel [(set (match_dup 0)
6812 (div:SWI48 (match_dup 2) (match_dup 3)))
6813 (set (match_dup 1)
6814 (mod:SWI48 (match_dup 2) (match_dup 3)))
6815 (use (match_dup 1))
6816 (clobber (reg:CC FLAGS_REG))])]
6817 {
6818 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6819
6820 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6821 operands[4] = operands[2];
6822 else
6823 {
6824 /* Avoid use of cltd in favor of a mov+shift. */
6825 emit_move_insn (operands[1], operands[2]);
6826 operands[4] = operands[1];
6827 }
6828 }
6829 [(set_attr "type" "multi")
6830 (set_attr "mode" "<MODE>")])
6831
6832 (define_insn_and_split "*divmod<mode>4"
6833 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6834 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6835 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6836 (set (match_operand:SWIM248 1 "register_operand" "=&d")
6837 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6838 (clobber (reg:CC FLAGS_REG))]
6839 ""
6840 "#"
6841 "reload_completed"
6842 [(parallel [(set (match_dup 1)
6843 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
6844 (clobber (reg:CC FLAGS_REG))])
6845 (parallel [(set (match_dup 0)
6846 (div:SWIM248 (match_dup 2) (match_dup 3)))
6847 (set (match_dup 1)
6848 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6849 (use (match_dup 1))
6850 (clobber (reg:CC FLAGS_REG))])]
6851 {
6852 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6853
6854 if (<MODE>mode != HImode
6855 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
6856 operands[4] = operands[2];
6857 else
6858 {
6859 /* Avoid use of cltd in favor of a mov+shift. */
6860 emit_move_insn (operands[1], operands[2]);
6861 operands[4] = operands[1];
6862 }
6863 }
6864 [(set_attr "type" "multi")
6865 (set_attr "mode" "<MODE>")])
6866
6867 (define_insn "*divmod<mode>4_noext"
6868 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6869 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6870 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6871 (set (match_operand:SWIM248 1 "register_operand" "=d")
6872 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6873 (use (match_operand:SWIM248 4 "register_operand" "1"))
6874 (clobber (reg:CC FLAGS_REG))]
6875 ""
6876 "idiv{<imodesuffix>}\t%3"
6877 [(set_attr "type" "idiv")
6878 (set_attr "mode" "<MODE>")])
6879
6880 (define_expand "divmodqi4"
6881 [(parallel [(set (match_operand:QI 0 "register_operand")
6882 (div:QI
6883 (match_operand:QI 1 "register_operand")
6884 (match_operand:QI 2 "nonimmediate_operand")))
6885 (set (match_operand:QI 3 "register_operand")
6886 (mod:QI (match_dup 1) (match_dup 2)))
6887 (clobber (reg:CC FLAGS_REG))])]
6888 "TARGET_QIMODE_MATH"
6889 {
6890 rtx div, mod, insn;
6891 rtx tmp0, tmp1;
6892
6893 tmp0 = gen_reg_rtx (HImode);
6894 tmp1 = gen_reg_rtx (HImode);
6895
6896 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
6897 in AX. */
6898 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
6899 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
6900
6901 /* Extract remainder from AH. */
6902 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
6903 insn = emit_move_insn (operands[3], tmp1);
6904
6905 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
6906 set_unique_reg_note (insn, REG_EQUAL, mod);
6907
6908 /* Extract quotient from AL. */
6909 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
6910
6911 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
6912 set_unique_reg_note (insn, REG_EQUAL, div);
6913
6914 DONE;
6915 })
6916
6917 ;; Divide AX by r/m8, with result stored in
6918 ;; AL <- Quotient
6919 ;; AH <- Remainder
6920 ;; Change div/mod to HImode and extend the second argument to HImode
6921 ;; so that mode of div/mod matches with mode of arguments. Otherwise
6922 ;; combine may fail.
6923 (define_insn "divmodhiqi3"
6924 [(set (match_operand:HI 0 "register_operand" "=a")
6925 (ior:HI
6926 (ashift:HI
6927 (zero_extend:HI
6928 (truncate:QI
6929 (mod:HI (match_operand:HI 1 "register_operand" "0")
6930 (sign_extend:HI
6931 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
6932 (const_int 8))
6933 (zero_extend:HI
6934 (truncate:QI
6935 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
6936 (clobber (reg:CC FLAGS_REG))]
6937 "TARGET_QIMODE_MATH"
6938 "idiv{b}\t%2"
6939 [(set_attr "type" "idiv")
6940 (set_attr "mode" "QI")])
6941
6942 (define_expand "udivmod<mode>4"
6943 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6944 (udiv:SWIM248
6945 (match_operand:SWIM248 1 "register_operand")
6946 (match_operand:SWIM248 2 "nonimmediate_operand")))
6947 (set (match_operand:SWIM248 3 "register_operand")
6948 (umod:SWIM248 (match_dup 1) (match_dup 2)))
6949 (clobber (reg:CC FLAGS_REG))])])
6950
6951 ;; Split with 8bit unsigned divide:
6952 ;; if (dividend an divisor are in [0-255])
6953 ;; use 8bit unsigned integer divide
6954 ;; else
6955 ;; use original integer divide
6956 (define_split
6957 [(set (match_operand:SWI48 0 "register_operand")
6958 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
6959 (match_operand:SWI48 3 "nonimmediate_operand")))
6960 (set (match_operand:SWI48 1 "register_operand")
6961 (umod:SWI48 (match_dup 2) (match_dup 3)))
6962 (clobber (reg:CC FLAGS_REG))]
6963 "TARGET_USE_8BIT_IDIV
6964 && TARGET_QIMODE_MATH
6965 && can_create_pseudo_p ()
6966 && !optimize_insn_for_size_p ()"
6967 [(const_int 0)]
6968 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
6969
6970 (define_insn_and_split "udivmod<mode>4_1"
6971 [(set (match_operand:SWI48 0 "register_operand" "=a")
6972 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6973 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6974 (set (match_operand:SWI48 1 "register_operand" "=&d")
6975 (umod:SWI48 (match_dup 2) (match_dup 3)))
6976 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6977 (clobber (reg:CC FLAGS_REG))]
6978 ""
6979 "#"
6980 "reload_completed"
6981 [(set (match_dup 1) (const_int 0))
6982 (parallel [(set (match_dup 0)
6983 (udiv:SWI48 (match_dup 2) (match_dup 3)))
6984 (set (match_dup 1)
6985 (umod:SWI48 (match_dup 2) (match_dup 3)))
6986 (use (match_dup 1))
6987 (clobber (reg:CC FLAGS_REG))])]
6988 ""
6989 [(set_attr "type" "multi")
6990 (set_attr "mode" "<MODE>")])
6991
6992 (define_insn_and_split "*udivmod<mode>4"
6993 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6994 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6995 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6996 (set (match_operand:SWIM248 1 "register_operand" "=&d")
6997 (umod:SWIM248 (match_dup 2) (match_dup 3)))
6998 (clobber (reg:CC FLAGS_REG))]
6999 ""
7000 "#"
7001 "reload_completed"
7002 [(set (match_dup 1) (const_int 0))
7003 (parallel [(set (match_dup 0)
7004 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7005 (set (match_dup 1)
7006 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7007 (use (match_dup 1))
7008 (clobber (reg:CC FLAGS_REG))])]
7009 ""
7010 [(set_attr "type" "multi")
7011 (set_attr "mode" "<MODE>")])
7012
7013 (define_insn "*udivmod<mode>4_noext"
7014 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7015 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7016 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7017 (set (match_operand:SWIM248 1 "register_operand" "=d")
7018 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7019 (use (match_operand:SWIM248 4 "register_operand" "1"))
7020 (clobber (reg:CC FLAGS_REG))]
7021 ""
7022 "div{<imodesuffix>}\t%3"
7023 [(set_attr "type" "idiv")
7024 (set_attr "mode" "<MODE>")])
7025
7026 (define_expand "udivmodqi4"
7027 [(parallel [(set (match_operand:QI 0 "register_operand")
7028 (udiv:QI
7029 (match_operand:QI 1 "register_operand")
7030 (match_operand:QI 2 "nonimmediate_operand")))
7031 (set (match_operand:QI 3 "register_operand")
7032 (umod:QI (match_dup 1) (match_dup 2)))
7033 (clobber (reg:CC FLAGS_REG))])]
7034 "TARGET_QIMODE_MATH"
7035 {
7036 rtx div, mod, insn;
7037 rtx tmp0, tmp1;
7038
7039 tmp0 = gen_reg_rtx (HImode);
7040 tmp1 = gen_reg_rtx (HImode);
7041
7042 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7043 in AX. */
7044 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7045 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7046
7047 /* Extract remainder from AH. */
7048 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7049 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7050 insn = emit_move_insn (operands[3], tmp1);
7051
7052 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7053 set_unique_reg_note (insn, REG_EQUAL, mod);
7054
7055 /* Extract quotient from AL. */
7056 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7057
7058 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7059 set_unique_reg_note (insn, REG_EQUAL, div);
7060
7061 DONE;
7062 })
7063
7064 (define_insn "udivmodhiqi3"
7065 [(set (match_operand:HI 0 "register_operand" "=a")
7066 (ior:HI
7067 (ashift:HI
7068 (zero_extend:HI
7069 (truncate:QI
7070 (mod:HI (match_operand:HI 1 "register_operand" "0")
7071 (zero_extend:HI
7072 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7073 (const_int 8))
7074 (zero_extend:HI
7075 (truncate:QI
7076 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7077 (clobber (reg:CC FLAGS_REG))]
7078 "TARGET_QIMODE_MATH"
7079 "div{b}\t%2"
7080 [(set_attr "type" "idiv")
7081 (set_attr "mode" "QI")])
7082
7083 ;; We cannot use div/idiv for double division, because it causes
7084 ;; "division by zero" on the overflow and that's not what we expect
7085 ;; from truncate. Because true (non truncating) double division is
7086 ;; never generated, we can't create this insn anyway.
7087 ;
7088 ;(define_insn ""
7089 ; [(set (match_operand:SI 0 "register_operand" "=a")
7090 ; (truncate:SI
7091 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7092 ; (zero_extend:DI
7093 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7094 ; (set (match_operand:SI 3 "register_operand" "=d")
7095 ; (truncate:SI
7096 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7097 ; (clobber (reg:CC FLAGS_REG))]
7098 ; ""
7099 ; "div{l}\t{%2, %0|%0, %2}"
7100 ; [(set_attr "type" "idiv")])
7101 \f
7102 ;;- Logical AND instructions
7103
7104 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7105 ;; Note that this excludes ah.
7106
7107 (define_expand "testsi_ccno_1"
7108 [(set (reg:CCNO FLAGS_REG)
7109 (compare:CCNO
7110 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7111 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7112 (const_int 0)))])
7113
7114 (define_expand "testqi_ccz_1"
7115 [(set (reg:CCZ FLAGS_REG)
7116 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7117 (match_operand:QI 1 "nonmemory_operand"))
7118 (const_int 0)))])
7119
7120 (define_expand "testdi_ccno_1"
7121 [(set (reg:CCNO FLAGS_REG)
7122 (compare:CCNO
7123 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7124 (match_operand:DI 1 "x86_64_szext_general_operand"))
7125 (const_int 0)))]
7126 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7127
7128 (define_insn "*testdi_1"
7129 [(set (reg FLAGS_REG)
7130 (compare
7131 (and:DI
7132 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7133 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7134 (const_int 0)))]
7135 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7136 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7137 "@
7138 test{l}\t{%k1, %k0|%k0, %k1}
7139 test{l}\t{%k1, %k0|%k0, %k1}
7140 test{q}\t{%1, %0|%0, %1}
7141 test{q}\t{%1, %0|%0, %1}
7142 test{q}\t{%1, %0|%0, %1}"
7143 [(set_attr "type" "test")
7144 (set_attr "modrm" "0,1,0,1,1")
7145 (set_attr "mode" "SI,SI,DI,DI,DI")])
7146
7147 (define_insn "*testqi_1_maybe_si"
7148 [(set (reg FLAGS_REG)
7149 (compare
7150 (and:QI
7151 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7152 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7153 (const_int 0)))]
7154 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7155 && ix86_match_ccmode (insn,
7156 CONST_INT_P (operands[1])
7157 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7158 {
7159 if (which_alternative == 3)
7160 {
7161 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7162 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7163 return "test{l}\t{%1, %k0|%k0, %1}";
7164 }
7165 return "test{b}\t{%1, %0|%0, %1}";
7166 }
7167 [(set_attr "type" "test")
7168 (set_attr "modrm" "0,1,1,1")
7169 (set_attr "mode" "QI,QI,QI,SI")
7170 (set_attr "pent_pair" "uv,np,uv,np")])
7171
7172 (define_insn "*test<mode>_1"
7173 [(set (reg FLAGS_REG)
7174 (compare
7175 (and:SWI124
7176 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7177 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7178 (const_int 0)))]
7179 "ix86_match_ccmode (insn, CCNOmode)
7180 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7181 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7182 [(set_attr "type" "test")
7183 (set_attr "modrm" "0,1,1")
7184 (set_attr "mode" "<MODE>")
7185 (set_attr "pent_pair" "uv,np,uv")])
7186
7187 (define_expand "testqi_ext_ccno_0"
7188 [(set (reg:CCNO FLAGS_REG)
7189 (compare:CCNO
7190 (and:SI
7191 (zero_extract:SI
7192 (match_operand 0 "ext_register_operand")
7193 (const_int 8)
7194 (const_int 8))
7195 (match_operand 1 "const_int_operand"))
7196 (const_int 0)))])
7197
7198 (define_insn "*testqi_ext_0"
7199 [(set (reg FLAGS_REG)
7200 (compare
7201 (and:SI
7202 (zero_extract:SI
7203 (match_operand 0 "ext_register_operand" "Q")
7204 (const_int 8)
7205 (const_int 8))
7206 (match_operand 1 "const_int_operand" "n"))
7207 (const_int 0)))]
7208 "ix86_match_ccmode (insn, CCNOmode)"
7209 "test{b}\t{%1, %h0|%h0, %1}"
7210 [(set_attr "type" "test")
7211 (set_attr "mode" "QI")
7212 (set_attr "length_immediate" "1")
7213 (set_attr "modrm" "1")
7214 (set_attr "pent_pair" "np")])
7215
7216 (define_insn "*testqi_ext_1"
7217 [(set (reg FLAGS_REG)
7218 (compare
7219 (and:SI
7220 (zero_extract:SI
7221 (match_operand 0 "ext_register_operand" "Q,Q")
7222 (const_int 8)
7223 (const_int 8))
7224 (zero_extend:SI
7225 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7226 (const_int 0)))]
7227 "ix86_match_ccmode (insn, CCNOmode)"
7228 "test{b}\t{%1, %h0|%h0, %1}"
7229 [(set_attr "isa" "*,nox64")
7230 (set_attr "type" "test")
7231 (set_attr "mode" "QI")])
7232
7233 (define_insn "*testqi_ext_2"
7234 [(set (reg FLAGS_REG)
7235 (compare
7236 (and:SI
7237 (zero_extract:SI
7238 (match_operand 0 "ext_register_operand" "Q")
7239 (const_int 8)
7240 (const_int 8))
7241 (zero_extract:SI
7242 (match_operand 1 "ext_register_operand" "Q")
7243 (const_int 8)
7244 (const_int 8)))
7245 (const_int 0)))]
7246 "ix86_match_ccmode (insn, CCNOmode)"
7247 "test{b}\t{%h1, %h0|%h0, %h1}"
7248 [(set_attr "type" "test")
7249 (set_attr "mode" "QI")])
7250
7251 ;; Combine likes to form bit extractions for some tests. Humor it.
7252 (define_insn "*testqi_ext_3"
7253 [(set (reg FLAGS_REG)
7254 (compare (zero_extract:SWI48
7255 (match_operand 0 "nonimmediate_operand" "rm")
7256 (match_operand:SWI48 1 "const_int_operand")
7257 (match_operand:SWI48 2 "const_int_operand"))
7258 (const_int 0)))]
7259 "ix86_match_ccmode (insn, CCNOmode)
7260 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7261 || GET_MODE (operands[0]) == SImode
7262 || GET_MODE (operands[0]) == HImode
7263 || GET_MODE (operands[0]) == QImode)
7264 /* Ensure that resulting mask is zero or sign extended operand. */
7265 && INTVAL (operands[2]) >= 0
7266 && ((INTVAL (operands[1]) > 0
7267 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7268 || (<MODE>mode == DImode
7269 && INTVAL (operands[1]) > 32
7270 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7271 "#")
7272
7273 (define_split
7274 [(set (match_operand 0 "flags_reg_operand")
7275 (match_operator 1 "compare_operator"
7276 [(zero_extract
7277 (match_operand 2 "nonimmediate_operand")
7278 (match_operand 3 "const_int_operand")
7279 (match_operand 4 "const_int_operand"))
7280 (const_int 0)]))]
7281 "ix86_match_ccmode (insn, CCNOmode)"
7282 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7283 {
7284 rtx val = operands[2];
7285 HOST_WIDE_INT len = INTVAL (operands[3]);
7286 HOST_WIDE_INT pos = INTVAL (operands[4]);
7287 HOST_WIDE_INT mask;
7288 enum machine_mode mode, submode;
7289
7290 mode = GET_MODE (val);
7291 if (MEM_P (val))
7292 {
7293 /* ??? Combine likes to put non-volatile mem extractions in QImode
7294 no matter the size of the test. So find a mode that works. */
7295 if (! MEM_VOLATILE_P (val))
7296 {
7297 mode = smallest_mode_for_size (pos + len, MODE_INT);
7298 val = adjust_address (val, mode, 0);
7299 }
7300 }
7301 else if (GET_CODE (val) == SUBREG
7302 && (submode = GET_MODE (SUBREG_REG (val)),
7303 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7304 && pos + len <= GET_MODE_BITSIZE (submode)
7305 && GET_MODE_CLASS (submode) == MODE_INT)
7306 {
7307 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7308 mode = submode;
7309 val = SUBREG_REG (val);
7310 }
7311 else if (mode == HImode && pos + len <= 8)
7312 {
7313 /* Small HImode tests can be converted to QImode. */
7314 mode = QImode;
7315 val = gen_lowpart (QImode, val);
7316 }
7317
7318 if (len == HOST_BITS_PER_WIDE_INT)
7319 mask = -1;
7320 else
7321 mask = ((HOST_WIDE_INT)1 << len) - 1;
7322 mask <<= pos;
7323
7324 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7325 })
7326
7327 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7328 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7329 ;; this is relatively important trick.
7330 ;; Do the conversion only post-reload to avoid limiting of the register class
7331 ;; to QI regs.
7332 (define_split
7333 [(set (match_operand 0 "flags_reg_operand")
7334 (match_operator 1 "compare_operator"
7335 [(and (match_operand 2 "register_operand")
7336 (match_operand 3 "const_int_operand"))
7337 (const_int 0)]))]
7338 "reload_completed
7339 && QI_REG_P (operands[2])
7340 && GET_MODE (operands[2]) != QImode
7341 && ((ix86_match_ccmode (insn, CCZmode)
7342 && !(INTVAL (operands[3]) & ~(255 << 8)))
7343 || (ix86_match_ccmode (insn, CCNOmode)
7344 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7345 [(set (match_dup 0)
7346 (match_op_dup 1
7347 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7348 (match_dup 3))
7349 (const_int 0)]))]
7350 {
7351 operands[2] = gen_lowpart (SImode, operands[2]);
7352 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7353 })
7354
7355 (define_split
7356 [(set (match_operand 0 "flags_reg_operand")
7357 (match_operator 1 "compare_operator"
7358 [(and (match_operand 2 "nonimmediate_operand")
7359 (match_operand 3 "const_int_operand"))
7360 (const_int 0)]))]
7361 "reload_completed
7362 && GET_MODE (operands[2]) != QImode
7363 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7364 && ((ix86_match_ccmode (insn, CCZmode)
7365 && !(INTVAL (operands[3]) & ~255))
7366 || (ix86_match_ccmode (insn, CCNOmode)
7367 && !(INTVAL (operands[3]) & ~127)))"
7368 [(set (match_dup 0)
7369 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7370 (const_int 0)]))]
7371 {
7372 operands[2] = gen_lowpart (QImode, operands[2]);
7373 operands[3] = gen_lowpart (QImode, operands[3]);
7374 })
7375
7376 ;; %%% This used to optimize known byte-wide and operations to memory,
7377 ;; and sometimes to QImode registers. If this is considered useful,
7378 ;; it should be done with splitters.
7379
7380 (define_expand "and<mode>3"
7381 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7382 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7383 (match_operand:SWIM 2 "<general_szext_operand>")))]
7384 ""
7385 {
7386 enum machine_mode mode = <MODE>mode;
7387 rtx (*insn) (rtx, rtx);
7388
7389 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7390 {
7391 HOST_WIDE_INT ival = INTVAL (operands[2]);
7392
7393 if (ival == (HOST_WIDE_INT) 0xffffffff)
7394 mode = SImode;
7395 else if (ival == 0xffff)
7396 mode = HImode;
7397 else if (ival == 0xff)
7398 mode = QImode;
7399 }
7400
7401 if (mode == <MODE>mode)
7402 {
7403 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7404 DONE;
7405 }
7406
7407 if (<MODE>mode == DImode)
7408 insn = (mode == SImode)
7409 ? gen_zero_extendsidi2
7410 : (mode == HImode)
7411 ? gen_zero_extendhidi2
7412 : gen_zero_extendqidi2;
7413 else if (<MODE>mode == SImode)
7414 insn = (mode == HImode)
7415 ? gen_zero_extendhisi2
7416 : gen_zero_extendqisi2;
7417 else if (<MODE>mode == HImode)
7418 insn = gen_zero_extendqihi2;
7419 else
7420 gcc_unreachable ();
7421
7422 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7423 DONE;
7424 })
7425
7426 (define_insn "*anddi_1"
7427 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7428 (and:DI
7429 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7430 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7431 (clobber (reg:CC FLAGS_REG))]
7432 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7433 {
7434 switch (get_attr_type (insn))
7435 {
7436 case TYPE_IMOVX:
7437 return "#";
7438
7439 default:
7440 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7441 if (get_attr_mode (insn) == MODE_SI)
7442 return "and{l}\t{%k2, %k0|%k0, %k2}";
7443 else
7444 return "and{q}\t{%2, %0|%0, %2}";
7445 }
7446 }
7447 [(set_attr "type" "alu,alu,alu,imovx")
7448 (set_attr "length_immediate" "*,*,*,0")
7449 (set (attr "prefix_rex")
7450 (if_then_else
7451 (and (eq_attr "type" "imovx")
7452 (and (match_test "INTVAL (operands[2]) == 0xff")
7453 (match_operand 1 "ext_QIreg_operand")))
7454 (const_string "1")
7455 (const_string "*")))
7456 (set_attr "mode" "SI,DI,DI,SI")])
7457
7458 (define_insn "*andsi_1"
7459 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7460 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7461 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7462 (clobber (reg:CC FLAGS_REG))]
7463 "ix86_binary_operator_ok (AND, SImode, operands)"
7464 {
7465 switch (get_attr_type (insn))
7466 {
7467 case TYPE_IMOVX:
7468 return "#";
7469
7470 default:
7471 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7472 return "and{l}\t{%2, %0|%0, %2}";
7473 }
7474 }
7475 [(set_attr "type" "alu,alu,imovx")
7476 (set (attr "prefix_rex")
7477 (if_then_else
7478 (and (eq_attr "type" "imovx")
7479 (and (match_test "INTVAL (operands[2]) == 0xff")
7480 (match_operand 1 "ext_QIreg_operand")))
7481 (const_string "1")
7482 (const_string "*")))
7483 (set_attr "length_immediate" "*,*,0")
7484 (set_attr "mode" "SI")])
7485
7486 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7487 (define_insn "*andsi_1_zext"
7488 [(set (match_operand:DI 0 "register_operand" "=r")
7489 (zero_extend:DI
7490 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7491 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7492 (clobber (reg:CC FLAGS_REG))]
7493 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7494 "and{l}\t{%2, %k0|%k0, %2}"
7495 [(set_attr "type" "alu")
7496 (set_attr "mode" "SI")])
7497
7498 (define_insn "*andhi_1"
7499 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7500 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7501 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7502 (clobber (reg:CC FLAGS_REG))]
7503 "ix86_binary_operator_ok (AND, HImode, operands)"
7504 {
7505 switch (get_attr_type (insn))
7506 {
7507 case TYPE_IMOVX:
7508 return "#";
7509
7510 default:
7511 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7512 return "and{w}\t{%2, %0|%0, %2}";
7513 }
7514 }
7515 [(set_attr "type" "alu,alu,imovx")
7516 (set_attr "length_immediate" "*,*,0")
7517 (set (attr "prefix_rex")
7518 (if_then_else
7519 (and (eq_attr "type" "imovx")
7520 (match_operand 1 "ext_QIreg_operand"))
7521 (const_string "1")
7522 (const_string "*")))
7523 (set_attr "mode" "HI,HI,SI")])
7524
7525 ;; %%% Potential partial reg stall on alternative 2. What to do?
7526 (define_insn "*andqi_1"
7527 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7528 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7529 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7530 (clobber (reg:CC FLAGS_REG))]
7531 "ix86_binary_operator_ok (AND, QImode, operands)"
7532 "@
7533 and{b}\t{%2, %0|%0, %2}
7534 and{b}\t{%2, %0|%0, %2}
7535 and{l}\t{%k2, %k0|%k0, %k2}"
7536 [(set_attr "type" "alu")
7537 (set_attr "mode" "QI,QI,SI")])
7538
7539 (define_insn "*andqi_1_slp"
7540 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7541 (and:QI (match_dup 0)
7542 (match_operand:QI 1 "general_operand" "qn,qmn")))
7543 (clobber (reg:CC FLAGS_REG))]
7544 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7545 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7546 "and{b}\t{%1, %0|%0, %1}"
7547 [(set_attr "type" "alu1")
7548 (set_attr "mode" "QI")])
7549
7550 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7551 (define_split
7552 [(set (match_operand:DI 0 "register_operand")
7553 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7554 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7555 (clobber (reg:CC FLAGS_REG))]
7556 "TARGET_64BIT"
7557 [(parallel [(set (match_dup 0)
7558 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7559 (clobber (reg:CC FLAGS_REG))])]
7560 "operands[2] = gen_lowpart (SImode, operands[2]);")
7561
7562 (define_split
7563 [(set (match_operand:SWI248 0 "register_operand")
7564 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7565 (match_operand:SWI248 2 "const_int_operand")))
7566 (clobber (reg:CC FLAGS_REG))]
7567 "reload_completed
7568 && true_regnum (operands[0]) != true_regnum (operands[1])"
7569 [(const_int 0)]
7570 {
7571 HOST_WIDE_INT ival = INTVAL (operands[2]);
7572 enum machine_mode mode;
7573 rtx (*insn) (rtx, rtx);
7574
7575 if (ival == (HOST_WIDE_INT) 0xffffffff)
7576 mode = SImode;
7577 else if (ival == 0xffff)
7578 mode = HImode;
7579 else
7580 {
7581 gcc_assert (ival == 0xff);
7582 mode = QImode;
7583 }
7584
7585 if (<MODE>mode == DImode)
7586 insn = (mode == SImode)
7587 ? gen_zero_extendsidi2
7588 : (mode == HImode)
7589 ? gen_zero_extendhidi2
7590 : gen_zero_extendqidi2;
7591 else
7592 {
7593 if (<MODE>mode != SImode)
7594 /* Zero extend to SImode to avoid partial register stalls. */
7595 operands[0] = gen_lowpart (SImode, operands[0]);
7596
7597 insn = (mode == HImode)
7598 ? gen_zero_extendhisi2
7599 : gen_zero_extendqisi2;
7600 }
7601 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7602 DONE;
7603 })
7604
7605 (define_split
7606 [(set (match_operand 0 "register_operand")
7607 (and (match_dup 0)
7608 (const_int -65536)))
7609 (clobber (reg:CC FLAGS_REG))]
7610 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7611 || optimize_function_for_size_p (cfun)"
7612 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7613 "operands[1] = gen_lowpart (HImode, operands[0]);")
7614
7615 (define_split
7616 [(set (match_operand 0 "ext_register_operand")
7617 (and (match_dup 0)
7618 (const_int -256)))
7619 (clobber (reg:CC FLAGS_REG))]
7620 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7621 && reload_completed"
7622 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7623 "operands[1] = gen_lowpart (QImode, operands[0]);")
7624
7625 (define_split
7626 [(set (match_operand 0 "ext_register_operand")
7627 (and (match_dup 0)
7628 (const_int -65281)))
7629 (clobber (reg:CC FLAGS_REG))]
7630 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7631 && reload_completed"
7632 [(parallel [(set (zero_extract:SI (match_dup 0)
7633 (const_int 8)
7634 (const_int 8))
7635 (xor:SI
7636 (zero_extract:SI (match_dup 0)
7637 (const_int 8)
7638 (const_int 8))
7639 (zero_extract:SI (match_dup 0)
7640 (const_int 8)
7641 (const_int 8))))
7642 (clobber (reg:CC FLAGS_REG))])]
7643 "operands[0] = gen_lowpart (SImode, operands[0]);")
7644
7645 (define_insn "*anddi_2"
7646 [(set (reg FLAGS_REG)
7647 (compare
7648 (and:DI
7649 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7650 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7651 (const_int 0)))
7652 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7653 (and:DI (match_dup 1) (match_dup 2)))]
7654 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7655 && ix86_binary_operator_ok (AND, DImode, operands)"
7656 "@
7657 and{l}\t{%k2, %k0|%k0, %k2}
7658 and{q}\t{%2, %0|%0, %2}
7659 and{q}\t{%2, %0|%0, %2}"
7660 [(set_attr "type" "alu")
7661 (set_attr "mode" "SI,DI,DI")])
7662
7663 (define_insn "*andqi_2_maybe_si"
7664 [(set (reg FLAGS_REG)
7665 (compare (and:QI
7666 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7667 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7668 (const_int 0)))
7669 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7670 (and:QI (match_dup 1) (match_dup 2)))]
7671 "ix86_binary_operator_ok (AND, QImode, operands)
7672 && ix86_match_ccmode (insn,
7673 CONST_INT_P (operands[2])
7674 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7675 {
7676 if (which_alternative == 2)
7677 {
7678 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7679 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7680 return "and{l}\t{%2, %k0|%k0, %2}";
7681 }
7682 return "and{b}\t{%2, %0|%0, %2}";
7683 }
7684 [(set_attr "type" "alu")
7685 (set_attr "mode" "QI,QI,SI")])
7686
7687 (define_insn "*and<mode>_2"
7688 [(set (reg FLAGS_REG)
7689 (compare (and:SWI124
7690 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7691 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7692 (const_int 0)))
7693 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7694 (and:SWI124 (match_dup 1) (match_dup 2)))]
7695 "ix86_match_ccmode (insn, CCNOmode)
7696 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7697 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7698 [(set_attr "type" "alu")
7699 (set_attr "mode" "<MODE>")])
7700
7701 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7702 (define_insn "*andsi_2_zext"
7703 [(set (reg FLAGS_REG)
7704 (compare (and:SI
7705 (match_operand:SI 1 "nonimmediate_operand" "%0")
7706 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7707 (const_int 0)))
7708 (set (match_operand:DI 0 "register_operand" "=r")
7709 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7710 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7711 && ix86_binary_operator_ok (AND, SImode, operands)"
7712 "and{l}\t{%2, %k0|%k0, %2}"
7713 [(set_attr "type" "alu")
7714 (set_attr "mode" "SI")])
7715
7716 (define_insn "*andqi_2_slp"
7717 [(set (reg FLAGS_REG)
7718 (compare (and:QI
7719 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7720 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7721 (const_int 0)))
7722 (set (strict_low_part (match_dup 0))
7723 (and:QI (match_dup 0) (match_dup 1)))]
7724 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7725 && ix86_match_ccmode (insn, CCNOmode)
7726 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7727 "and{b}\t{%1, %0|%0, %1}"
7728 [(set_attr "type" "alu1")
7729 (set_attr "mode" "QI")])
7730
7731 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7732 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7733 ;; for a QImode operand, which of course failed.
7734 (define_insn "andqi_ext_0"
7735 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7736 (const_int 8)
7737 (const_int 8))
7738 (and:SI
7739 (zero_extract:SI
7740 (match_operand 1 "ext_register_operand" "0")
7741 (const_int 8)
7742 (const_int 8))
7743 (match_operand 2 "const_int_operand" "n")))
7744 (clobber (reg:CC FLAGS_REG))]
7745 ""
7746 "and{b}\t{%2, %h0|%h0, %2}"
7747 [(set_attr "type" "alu")
7748 (set_attr "length_immediate" "1")
7749 (set_attr "modrm" "1")
7750 (set_attr "mode" "QI")])
7751
7752 ;; Generated by peephole translating test to and. This shows up
7753 ;; often in fp comparisons.
7754 (define_insn "*andqi_ext_0_cc"
7755 [(set (reg FLAGS_REG)
7756 (compare
7757 (and:SI
7758 (zero_extract:SI
7759 (match_operand 1 "ext_register_operand" "0")
7760 (const_int 8)
7761 (const_int 8))
7762 (match_operand 2 "const_int_operand" "n"))
7763 (const_int 0)))
7764 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7765 (const_int 8)
7766 (const_int 8))
7767 (and:SI
7768 (zero_extract:SI
7769 (match_dup 1)
7770 (const_int 8)
7771 (const_int 8))
7772 (match_dup 2)))]
7773 "ix86_match_ccmode (insn, CCNOmode)"
7774 "and{b}\t{%2, %h0|%h0, %2}"
7775 [(set_attr "type" "alu")
7776 (set_attr "length_immediate" "1")
7777 (set_attr "modrm" "1")
7778 (set_attr "mode" "QI")])
7779
7780 (define_insn "*andqi_ext_1"
7781 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
7782 (const_int 8)
7783 (const_int 8))
7784 (and:SI
7785 (zero_extract:SI
7786 (match_operand 1 "ext_register_operand" "0,0")
7787 (const_int 8)
7788 (const_int 8))
7789 (zero_extend:SI
7790 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
7791 (clobber (reg:CC FLAGS_REG))]
7792 ""
7793 "and{b}\t{%2, %h0|%h0, %2}"
7794 [(set_attr "isa" "*,nox64")
7795 (set_attr "type" "alu")
7796 (set_attr "length_immediate" "0")
7797 (set_attr "mode" "QI")])
7798
7799 (define_insn "*andqi_ext_2"
7800 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7801 (const_int 8)
7802 (const_int 8))
7803 (and:SI
7804 (zero_extract:SI
7805 (match_operand 1 "ext_register_operand" "%0")
7806 (const_int 8)
7807 (const_int 8))
7808 (zero_extract:SI
7809 (match_operand 2 "ext_register_operand" "Q")
7810 (const_int 8)
7811 (const_int 8))))
7812 (clobber (reg:CC FLAGS_REG))]
7813 ""
7814 "and{b}\t{%h2, %h0|%h0, %h2}"
7815 [(set_attr "type" "alu")
7816 (set_attr "length_immediate" "0")
7817 (set_attr "mode" "QI")])
7818
7819 ;; Convert wide AND instructions with immediate operand to shorter QImode
7820 ;; equivalents when possible.
7821 ;; Don't do the splitting with memory operands, since it introduces risk
7822 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
7823 ;; for size, but that can (should?) be handled by generic code instead.
7824 (define_split
7825 [(set (match_operand 0 "register_operand")
7826 (and (match_operand 1 "register_operand")
7827 (match_operand 2 "const_int_operand")))
7828 (clobber (reg:CC FLAGS_REG))]
7829 "reload_completed
7830 && QI_REG_P (operands[0])
7831 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7832 && !(~INTVAL (operands[2]) & ~(255 << 8))
7833 && GET_MODE (operands[0]) != QImode"
7834 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7835 (and:SI (zero_extract:SI (match_dup 1)
7836 (const_int 8) (const_int 8))
7837 (match_dup 2)))
7838 (clobber (reg:CC FLAGS_REG))])]
7839 {
7840 operands[0] = gen_lowpart (SImode, operands[0]);
7841 operands[1] = gen_lowpart (SImode, operands[1]);
7842 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
7843 })
7844
7845 ;; Since AND can be encoded with sign extended immediate, this is only
7846 ;; profitable when 7th bit is not set.
7847 (define_split
7848 [(set (match_operand 0 "register_operand")
7849 (and (match_operand 1 "general_operand")
7850 (match_operand 2 "const_int_operand")))
7851 (clobber (reg:CC FLAGS_REG))]
7852 "reload_completed
7853 && ANY_QI_REG_P (operands[0])
7854 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7855 && !(~INTVAL (operands[2]) & ~255)
7856 && !(INTVAL (operands[2]) & 128)
7857 && GET_MODE (operands[0]) != QImode"
7858 [(parallel [(set (strict_low_part (match_dup 0))
7859 (and:QI (match_dup 1)
7860 (match_dup 2)))
7861 (clobber (reg:CC FLAGS_REG))])]
7862 {
7863 operands[0] = gen_lowpart (QImode, operands[0]);
7864 operands[1] = gen_lowpart (QImode, operands[1]);
7865 operands[2] = gen_lowpart (QImode, operands[2]);
7866 })
7867 \f
7868 ;; Logical inclusive and exclusive OR instructions
7869
7870 ;; %%% This used to optimize known byte-wide and operations to memory.
7871 ;; If this is considered useful, it should be done with splitters.
7872
7873 (define_expand "<code><mode>3"
7874 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7875 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7876 (match_operand:SWIM 2 "<general_operand>")))]
7877 ""
7878 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
7879
7880 (define_insn "*<code><mode>_1"
7881 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
7882 (any_or:SWI248
7883 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
7884 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
7885 (clobber (reg:CC FLAGS_REG))]
7886 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7887 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7888 [(set_attr "type" "alu")
7889 (set_attr "mode" "<MODE>")])
7890
7891 ;; %%% Potential partial reg stall on alternative 2. What to do?
7892 (define_insn "*<code>qi_1"
7893 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
7894 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7895 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
7896 (clobber (reg:CC FLAGS_REG))]
7897 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
7898 "@
7899 <logic>{b}\t{%2, %0|%0, %2}
7900 <logic>{b}\t{%2, %0|%0, %2}
7901 <logic>{l}\t{%k2, %k0|%k0, %k2}"
7902 [(set_attr "type" "alu")
7903 (set_attr "mode" "QI,QI,SI")])
7904
7905 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7906 (define_insn "*<code>si_1_zext"
7907 [(set (match_operand:DI 0 "register_operand" "=r")
7908 (zero_extend:DI
7909 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7910 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7911 (clobber (reg:CC FLAGS_REG))]
7912 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7913 "<logic>{l}\t{%2, %k0|%k0, %2}"
7914 [(set_attr "type" "alu")
7915 (set_attr "mode" "SI")])
7916
7917 (define_insn "*<code>si_1_zext_imm"
7918 [(set (match_operand:DI 0 "register_operand" "=r")
7919 (any_or:DI
7920 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7921 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
7922 (clobber (reg:CC FLAGS_REG))]
7923 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7924 "<logic>{l}\t{%2, %k0|%k0, %2}"
7925 [(set_attr "type" "alu")
7926 (set_attr "mode" "SI")])
7927
7928 (define_insn "*<code>qi_1_slp"
7929 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
7930 (any_or:QI (match_dup 0)
7931 (match_operand:QI 1 "general_operand" "qmn,qn")))
7932 (clobber (reg:CC FLAGS_REG))]
7933 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7934 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7935 "<logic>{b}\t{%1, %0|%0, %1}"
7936 [(set_attr "type" "alu1")
7937 (set_attr "mode" "QI")])
7938
7939 (define_insn "*<code><mode>_2"
7940 [(set (reg FLAGS_REG)
7941 (compare (any_or:SWI
7942 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7943 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
7944 (const_int 0)))
7945 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
7946 (any_or:SWI (match_dup 1) (match_dup 2)))]
7947 "ix86_match_ccmode (insn, CCNOmode)
7948 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7949 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7950 [(set_attr "type" "alu")
7951 (set_attr "mode" "<MODE>")])
7952
7953 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7954 ;; ??? Special case for immediate operand is missing - it is tricky.
7955 (define_insn "*<code>si_2_zext"
7956 [(set (reg FLAGS_REG)
7957 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7958 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7959 (const_int 0)))
7960 (set (match_operand:DI 0 "register_operand" "=r")
7961 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
7962 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7963 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7964 "<logic>{l}\t{%2, %k0|%k0, %2}"
7965 [(set_attr "type" "alu")
7966 (set_attr "mode" "SI")])
7967
7968 (define_insn "*<code>si_2_zext_imm"
7969 [(set (reg FLAGS_REG)
7970 (compare (any_or:SI
7971 (match_operand:SI 1 "nonimmediate_operand" "%0")
7972 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
7973 (const_int 0)))
7974 (set (match_operand:DI 0 "register_operand" "=r")
7975 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
7976 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7977 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7978 "<logic>{l}\t{%2, %k0|%k0, %2}"
7979 [(set_attr "type" "alu")
7980 (set_attr "mode" "SI")])
7981
7982 (define_insn "*<code>qi_2_slp"
7983 [(set (reg FLAGS_REG)
7984 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7985 (match_operand:QI 1 "general_operand" "qmn,qn"))
7986 (const_int 0)))
7987 (set (strict_low_part (match_dup 0))
7988 (any_or:QI (match_dup 0) (match_dup 1)))]
7989 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7990 && ix86_match_ccmode (insn, CCNOmode)
7991 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7992 "<logic>{b}\t{%1, %0|%0, %1}"
7993 [(set_attr "type" "alu1")
7994 (set_attr "mode" "QI")])
7995
7996 (define_insn "*<code><mode>_3"
7997 [(set (reg FLAGS_REG)
7998 (compare (any_or:SWI
7999 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8000 (match_operand:SWI 2 "<general_operand>" "<g>"))
8001 (const_int 0)))
8002 (clobber (match_scratch:SWI 0 "=<r>"))]
8003 "ix86_match_ccmode (insn, CCNOmode)
8004 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8005 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8006 [(set_attr "type" "alu")
8007 (set_attr "mode" "<MODE>")])
8008
8009 (define_insn "*<code>qi_ext_0"
8010 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8011 (const_int 8)
8012 (const_int 8))
8013 (any_or:SI
8014 (zero_extract:SI
8015 (match_operand 1 "ext_register_operand" "0")
8016 (const_int 8)
8017 (const_int 8))
8018 (match_operand 2 "const_int_operand" "n")))
8019 (clobber (reg:CC FLAGS_REG))]
8020 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8021 "<logic>{b}\t{%2, %h0|%h0, %2}"
8022 [(set_attr "type" "alu")
8023 (set_attr "length_immediate" "1")
8024 (set_attr "modrm" "1")
8025 (set_attr "mode" "QI")])
8026
8027 (define_insn "*<code>qi_ext_1"
8028 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8029 (const_int 8)
8030 (const_int 8))
8031 (any_or:SI
8032 (zero_extract:SI
8033 (match_operand 1 "ext_register_operand" "0,0")
8034 (const_int 8)
8035 (const_int 8))
8036 (zero_extend:SI
8037 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8038 (clobber (reg:CC FLAGS_REG))]
8039 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8040 "<logic>{b}\t{%2, %h0|%h0, %2}"
8041 [(set_attr "isa" "*,nox64")
8042 (set_attr "type" "alu")
8043 (set_attr "length_immediate" "0")
8044 (set_attr "mode" "QI")])
8045
8046 (define_insn "*<code>qi_ext_2"
8047 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8048 (const_int 8)
8049 (const_int 8))
8050 (any_or:SI
8051 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8052 (const_int 8)
8053 (const_int 8))
8054 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8055 (const_int 8)
8056 (const_int 8))))
8057 (clobber (reg:CC FLAGS_REG))]
8058 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8059 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8060 [(set_attr "type" "alu")
8061 (set_attr "length_immediate" "0")
8062 (set_attr "mode" "QI")])
8063
8064 (define_split
8065 [(set (match_operand 0 "register_operand")
8066 (any_or (match_operand 1 "register_operand")
8067 (match_operand 2 "const_int_operand")))
8068 (clobber (reg:CC FLAGS_REG))]
8069 "reload_completed
8070 && QI_REG_P (operands[0])
8071 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8072 && !(INTVAL (operands[2]) & ~(255 << 8))
8073 && GET_MODE (operands[0]) != QImode"
8074 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8075 (any_or:SI (zero_extract:SI (match_dup 1)
8076 (const_int 8) (const_int 8))
8077 (match_dup 2)))
8078 (clobber (reg:CC FLAGS_REG))])]
8079 {
8080 operands[0] = gen_lowpart (SImode, operands[0]);
8081 operands[1] = gen_lowpart (SImode, operands[1]);
8082 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8083 })
8084
8085 ;; Since OR can be encoded with sign extended immediate, this is only
8086 ;; profitable when 7th bit is set.
8087 (define_split
8088 [(set (match_operand 0 "register_operand")
8089 (any_or (match_operand 1 "general_operand")
8090 (match_operand 2 "const_int_operand")))
8091 (clobber (reg:CC FLAGS_REG))]
8092 "reload_completed
8093 && ANY_QI_REG_P (operands[0])
8094 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8095 && !(INTVAL (operands[2]) & ~255)
8096 && (INTVAL (operands[2]) & 128)
8097 && GET_MODE (operands[0]) != QImode"
8098 [(parallel [(set (strict_low_part (match_dup 0))
8099 (any_or:QI (match_dup 1)
8100 (match_dup 2)))
8101 (clobber (reg:CC FLAGS_REG))])]
8102 {
8103 operands[0] = gen_lowpart (QImode, operands[0]);
8104 operands[1] = gen_lowpart (QImode, operands[1]);
8105 operands[2] = gen_lowpart (QImode, operands[2]);
8106 })
8107
8108 (define_expand "xorqi_cc_ext_1"
8109 [(parallel [
8110 (set (reg:CCNO FLAGS_REG)
8111 (compare:CCNO
8112 (xor:SI
8113 (zero_extract:SI
8114 (match_operand 1 "ext_register_operand")
8115 (const_int 8)
8116 (const_int 8))
8117 (match_operand:QI 2 "const_int_operand"))
8118 (const_int 0)))
8119 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8120 (const_int 8)
8121 (const_int 8))
8122 (xor:SI
8123 (zero_extract:SI
8124 (match_dup 1)
8125 (const_int 8)
8126 (const_int 8))
8127 (match_dup 2)))])])
8128
8129 (define_insn "*xorqi_cc_ext_1"
8130 [(set (reg FLAGS_REG)
8131 (compare
8132 (xor:SI
8133 (zero_extract:SI
8134 (match_operand 1 "ext_register_operand" "0,0")
8135 (const_int 8)
8136 (const_int 8))
8137 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8138 (const_int 0)))
8139 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8140 (const_int 8)
8141 (const_int 8))
8142 (xor:SI
8143 (zero_extract:SI
8144 (match_dup 1)
8145 (const_int 8)
8146 (const_int 8))
8147 (match_dup 2)))]
8148 "ix86_match_ccmode (insn, CCNOmode)"
8149 "xor{b}\t{%2, %h0|%h0, %2}"
8150 [(set_attr "isa" "*,nox64")
8151 (set_attr "type" "alu")
8152 (set_attr "modrm" "1")
8153 (set_attr "mode" "QI")])
8154 \f
8155 ;; Negation instructions
8156
8157 (define_expand "neg<mode>2"
8158 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8159 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8160 ""
8161 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8162
8163 (define_insn_and_split "*neg<dwi>2_doubleword"
8164 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8165 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8166 (clobber (reg:CC FLAGS_REG))]
8167 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8168 "#"
8169 "reload_completed"
8170 [(parallel
8171 [(set (reg:CCZ FLAGS_REG)
8172 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8173 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8174 (parallel
8175 [(set (match_dup 2)
8176 (plus:DWIH (match_dup 3)
8177 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8178 (const_int 0))))
8179 (clobber (reg:CC FLAGS_REG))])
8180 (parallel
8181 [(set (match_dup 2)
8182 (neg:DWIH (match_dup 2)))
8183 (clobber (reg:CC FLAGS_REG))])]
8184 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8185
8186 (define_insn "*neg<mode>2_1"
8187 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8188 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8189 (clobber (reg:CC FLAGS_REG))]
8190 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8191 "neg{<imodesuffix>}\t%0"
8192 [(set_attr "type" "negnot")
8193 (set_attr "mode" "<MODE>")])
8194
8195 ;; Combine is quite creative about this pattern.
8196 (define_insn "*negsi2_1_zext"
8197 [(set (match_operand:DI 0 "register_operand" "=r")
8198 (lshiftrt:DI
8199 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8200 (const_int 32)))
8201 (const_int 32)))
8202 (clobber (reg:CC FLAGS_REG))]
8203 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8204 "neg{l}\t%k0"
8205 [(set_attr "type" "negnot")
8206 (set_attr "mode" "SI")])
8207
8208 ;; The problem with neg is that it does not perform (compare x 0),
8209 ;; it really performs (compare 0 x), which leaves us with the zero
8210 ;; flag being the only useful item.
8211
8212 (define_insn "*neg<mode>2_cmpz"
8213 [(set (reg:CCZ FLAGS_REG)
8214 (compare:CCZ
8215 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8216 (const_int 0)))
8217 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8218 (neg:SWI (match_dup 1)))]
8219 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8220 "neg{<imodesuffix>}\t%0"
8221 [(set_attr "type" "negnot")
8222 (set_attr "mode" "<MODE>")])
8223
8224 (define_insn "*negsi2_cmpz_zext"
8225 [(set (reg:CCZ FLAGS_REG)
8226 (compare:CCZ
8227 (lshiftrt:DI
8228 (neg:DI (ashift:DI
8229 (match_operand:DI 1 "register_operand" "0")
8230 (const_int 32)))
8231 (const_int 32))
8232 (const_int 0)))
8233 (set (match_operand:DI 0 "register_operand" "=r")
8234 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8235 (const_int 32)))
8236 (const_int 32)))]
8237 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8238 "neg{l}\t%k0"
8239 [(set_attr "type" "negnot")
8240 (set_attr "mode" "SI")])
8241
8242 ;; Changing of sign for FP values is doable using integer unit too.
8243
8244 (define_expand "<code><mode>2"
8245 [(set (match_operand:X87MODEF 0 "register_operand")
8246 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8247 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8248 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8249
8250 (define_insn "*absneg<mode>2_mixed"
8251 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8252 (match_operator:MODEF 3 "absneg_operator"
8253 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8254 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8255 (clobber (reg:CC FLAGS_REG))]
8256 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8257 "#")
8258
8259 (define_insn "*absneg<mode>2_sse"
8260 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8261 (match_operator:MODEF 3 "absneg_operator"
8262 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8263 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8264 (clobber (reg:CC FLAGS_REG))]
8265 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8266 "#")
8267
8268 (define_insn "*absneg<mode>2_i387"
8269 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8270 (match_operator:X87MODEF 3 "absneg_operator"
8271 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8272 (use (match_operand 2))
8273 (clobber (reg:CC FLAGS_REG))]
8274 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8275 "#")
8276
8277 (define_expand "<code>tf2"
8278 [(set (match_operand:TF 0 "register_operand")
8279 (absneg:TF (match_operand:TF 1 "register_operand")))]
8280 "TARGET_SSE"
8281 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8282
8283 (define_insn "*absnegtf2_sse"
8284 [(set (match_operand:TF 0 "register_operand" "=x,x")
8285 (match_operator:TF 3 "absneg_operator"
8286 [(match_operand:TF 1 "register_operand" "0,x")]))
8287 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8288 (clobber (reg:CC FLAGS_REG))]
8289 "TARGET_SSE"
8290 "#")
8291
8292 ;; Splitters for fp abs and neg.
8293
8294 (define_split
8295 [(set (match_operand 0 "fp_register_operand")
8296 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8297 (use (match_operand 2))
8298 (clobber (reg:CC FLAGS_REG))]
8299 "reload_completed"
8300 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8301
8302 (define_split
8303 [(set (match_operand 0 "register_operand")
8304 (match_operator 3 "absneg_operator"
8305 [(match_operand 1 "register_operand")]))
8306 (use (match_operand 2 "nonimmediate_operand"))
8307 (clobber (reg:CC FLAGS_REG))]
8308 "reload_completed && SSE_REG_P (operands[0])"
8309 [(set (match_dup 0) (match_dup 3))]
8310 {
8311 enum machine_mode mode = GET_MODE (operands[0]);
8312 enum machine_mode vmode = GET_MODE (operands[2]);
8313 rtx tmp;
8314
8315 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8316 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8317 if (operands_match_p (operands[0], operands[2]))
8318 {
8319 tmp = operands[1];
8320 operands[1] = operands[2];
8321 operands[2] = tmp;
8322 }
8323 if (GET_CODE (operands[3]) == ABS)
8324 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8325 else
8326 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8327 operands[3] = tmp;
8328 })
8329
8330 (define_split
8331 [(set (match_operand:SF 0 "register_operand")
8332 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8333 (use (match_operand:V4SF 2))
8334 (clobber (reg:CC FLAGS_REG))]
8335 "reload_completed"
8336 [(parallel [(set (match_dup 0) (match_dup 1))
8337 (clobber (reg:CC FLAGS_REG))])]
8338 {
8339 rtx tmp;
8340 operands[0] = gen_lowpart (SImode, operands[0]);
8341 if (GET_CODE (operands[1]) == ABS)
8342 {
8343 tmp = gen_int_mode (0x7fffffff, SImode);
8344 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8345 }
8346 else
8347 {
8348 tmp = gen_int_mode (0x80000000, SImode);
8349 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8350 }
8351 operands[1] = tmp;
8352 })
8353
8354 (define_split
8355 [(set (match_operand:DF 0 "register_operand")
8356 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8357 (use (match_operand 2))
8358 (clobber (reg:CC FLAGS_REG))]
8359 "reload_completed"
8360 [(parallel [(set (match_dup 0) (match_dup 1))
8361 (clobber (reg:CC FLAGS_REG))])]
8362 {
8363 rtx tmp;
8364 if (TARGET_64BIT)
8365 {
8366 tmp = gen_lowpart (DImode, operands[0]);
8367 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8368 operands[0] = tmp;
8369
8370 if (GET_CODE (operands[1]) == ABS)
8371 tmp = const0_rtx;
8372 else
8373 tmp = gen_rtx_NOT (DImode, tmp);
8374 }
8375 else
8376 {
8377 operands[0] = gen_highpart (SImode, operands[0]);
8378 if (GET_CODE (operands[1]) == ABS)
8379 {
8380 tmp = gen_int_mode (0x7fffffff, SImode);
8381 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8382 }
8383 else
8384 {
8385 tmp = gen_int_mode (0x80000000, SImode);
8386 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8387 }
8388 }
8389 operands[1] = tmp;
8390 })
8391
8392 (define_split
8393 [(set (match_operand:XF 0 "register_operand")
8394 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8395 (use (match_operand 2))
8396 (clobber (reg:CC FLAGS_REG))]
8397 "reload_completed"
8398 [(parallel [(set (match_dup 0) (match_dup 1))
8399 (clobber (reg:CC FLAGS_REG))])]
8400 {
8401 rtx tmp;
8402 operands[0] = gen_rtx_REG (SImode,
8403 true_regnum (operands[0])
8404 + (TARGET_64BIT ? 1 : 2));
8405 if (GET_CODE (operands[1]) == ABS)
8406 {
8407 tmp = GEN_INT (0x7fff);
8408 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8409 }
8410 else
8411 {
8412 tmp = GEN_INT (0x8000);
8413 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8414 }
8415 operands[1] = tmp;
8416 })
8417
8418 ;; Conditionalize these after reload. If they match before reload, we
8419 ;; lose the clobber and ability to use integer instructions.
8420
8421 (define_insn "*<code><mode>2_1"
8422 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8423 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8424 "TARGET_80387
8425 && (reload_completed
8426 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8427 "f<absneg_mnemonic>"
8428 [(set_attr "type" "fsgn")
8429 (set_attr "mode" "<MODE>")])
8430
8431 (define_insn "*<code>extendsfdf2"
8432 [(set (match_operand:DF 0 "register_operand" "=f")
8433 (absneg:DF (float_extend:DF
8434 (match_operand:SF 1 "register_operand" "0"))))]
8435 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8436 "f<absneg_mnemonic>"
8437 [(set_attr "type" "fsgn")
8438 (set_attr "mode" "DF")])
8439
8440 (define_insn "*<code>extendsfxf2"
8441 [(set (match_operand:XF 0 "register_operand" "=f")
8442 (absneg:XF (float_extend:XF
8443 (match_operand:SF 1 "register_operand" "0"))))]
8444 "TARGET_80387"
8445 "f<absneg_mnemonic>"
8446 [(set_attr "type" "fsgn")
8447 (set_attr "mode" "XF")])
8448
8449 (define_insn "*<code>extenddfxf2"
8450 [(set (match_operand:XF 0 "register_operand" "=f")
8451 (absneg:XF (float_extend:XF
8452 (match_operand:DF 1 "register_operand" "0"))))]
8453 "TARGET_80387"
8454 "f<absneg_mnemonic>"
8455 [(set_attr "type" "fsgn")
8456 (set_attr "mode" "XF")])
8457
8458 ;; Copysign instructions
8459
8460 (define_mode_iterator CSGNMODE [SF DF TF])
8461 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8462
8463 (define_expand "copysign<mode>3"
8464 [(match_operand:CSGNMODE 0 "register_operand")
8465 (match_operand:CSGNMODE 1 "nonmemory_operand")
8466 (match_operand:CSGNMODE 2 "register_operand")]
8467 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8468 || (TARGET_SSE && (<MODE>mode == TFmode))"
8469 "ix86_expand_copysign (operands); DONE;")
8470
8471 (define_insn_and_split "copysign<mode>3_const"
8472 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8473 (unspec:CSGNMODE
8474 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8475 (match_operand:CSGNMODE 2 "register_operand" "0")
8476 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8477 UNSPEC_COPYSIGN))]
8478 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8479 || (TARGET_SSE && (<MODE>mode == TFmode))"
8480 "#"
8481 "&& reload_completed"
8482 [(const_int 0)]
8483 "ix86_split_copysign_const (operands); DONE;")
8484
8485 (define_insn "copysign<mode>3_var"
8486 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8487 (unspec:CSGNMODE
8488 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8489 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8490 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8491 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8492 UNSPEC_COPYSIGN))
8493 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8494 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8495 || (TARGET_SSE && (<MODE>mode == TFmode))"
8496 "#")
8497
8498 (define_split
8499 [(set (match_operand:CSGNMODE 0 "register_operand")
8500 (unspec:CSGNMODE
8501 [(match_operand:CSGNMODE 2 "register_operand")
8502 (match_operand:CSGNMODE 3 "register_operand")
8503 (match_operand:<CSGNVMODE> 4)
8504 (match_operand:<CSGNVMODE> 5)]
8505 UNSPEC_COPYSIGN))
8506 (clobber (match_scratch:<CSGNVMODE> 1))]
8507 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8508 || (TARGET_SSE && (<MODE>mode == TFmode)))
8509 && reload_completed"
8510 [(const_int 0)]
8511 "ix86_split_copysign_var (operands); DONE;")
8512 \f
8513 ;; One complement instructions
8514
8515 (define_expand "one_cmpl<mode>2"
8516 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8517 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8518 ""
8519 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8520
8521 (define_insn "*one_cmpl<mode>2_1"
8522 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8523 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8524 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8525 "not{<imodesuffix>}\t%0"
8526 [(set_attr "type" "negnot")
8527 (set_attr "mode" "<MODE>")])
8528
8529 ;; %%% Potential partial reg stall on alternative 1. What to do?
8530 (define_insn "*one_cmplqi2_1"
8531 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8532 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8533 "ix86_unary_operator_ok (NOT, QImode, operands)"
8534 "@
8535 not{b}\t%0
8536 not{l}\t%k0"
8537 [(set_attr "type" "negnot")
8538 (set_attr "mode" "QI,SI")])
8539
8540 ;; ??? Currently never generated - xor is used instead.
8541 (define_insn "*one_cmplsi2_1_zext"
8542 [(set (match_operand:DI 0 "register_operand" "=r")
8543 (zero_extend:DI
8544 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8545 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8546 "not{l}\t%k0"
8547 [(set_attr "type" "negnot")
8548 (set_attr "mode" "SI")])
8549
8550 (define_insn "*one_cmpl<mode>2_2"
8551 [(set (reg FLAGS_REG)
8552 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8553 (const_int 0)))
8554 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8555 (not:SWI (match_dup 1)))]
8556 "ix86_match_ccmode (insn, CCNOmode)
8557 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8558 "#"
8559 [(set_attr "type" "alu1")
8560 (set_attr "mode" "<MODE>")])
8561
8562 (define_split
8563 [(set (match_operand 0 "flags_reg_operand")
8564 (match_operator 2 "compare_operator"
8565 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8566 (const_int 0)]))
8567 (set (match_operand:SWI 1 "nonimmediate_operand")
8568 (not:SWI (match_dup 3)))]
8569 "ix86_match_ccmode (insn, CCNOmode)"
8570 [(parallel [(set (match_dup 0)
8571 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8572 (const_int 0)]))
8573 (set (match_dup 1)
8574 (xor:SWI (match_dup 3) (const_int -1)))])])
8575
8576 ;; ??? Currently never generated - xor is used instead.
8577 (define_insn "*one_cmplsi2_2_zext"
8578 [(set (reg FLAGS_REG)
8579 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8580 (const_int 0)))
8581 (set (match_operand:DI 0 "register_operand" "=r")
8582 (zero_extend:DI (not:SI (match_dup 1))))]
8583 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8584 && ix86_unary_operator_ok (NOT, SImode, operands)"
8585 "#"
8586 [(set_attr "type" "alu1")
8587 (set_attr "mode" "SI")])
8588
8589 (define_split
8590 [(set (match_operand 0 "flags_reg_operand")
8591 (match_operator 2 "compare_operator"
8592 [(not:SI (match_operand:SI 3 "register_operand"))
8593 (const_int 0)]))
8594 (set (match_operand:DI 1 "register_operand")
8595 (zero_extend:DI (not:SI (match_dup 3))))]
8596 "ix86_match_ccmode (insn, CCNOmode)"
8597 [(parallel [(set (match_dup 0)
8598 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8599 (const_int 0)]))
8600 (set (match_dup 1)
8601 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8602 \f
8603 ;; Shift instructions
8604
8605 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8606 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8607 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8608 ;; from the assembler input.
8609 ;;
8610 ;; This instruction shifts the target reg/mem as usual, but instead of
8611 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8612 ;; is a left shift double, bits are taken from the high order bits of
8613 ;; reg, else if the insn is a shift right double, bits are taken from the
8614 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8615 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8616 ;;
8617 ;; Since sh[lr]d does not change the `reg' operand, that is done
8618 ;; separately, making all shifts emit pairs of shift double and normal
8619 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8620 ;; support a 63 bit shift, each shift where the count is in a reg expands
8621 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8622 ;;
8623 ;; If the shift count is a constant, we need never emit more than one
8624 ;; shift pair, instead using moves and sign extension for counts greater
8625 ;; than 31.
8626
8627 (define_expand "ashl<mode>3"
8628 [(set (match_operand:SDWIM 0 "<shift_operand>")
8629 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
8630 (match_operand:QI 2 "nonmemory_operand")))]
8631 ""
8632 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8633
8634 (define_insn "*ashl<mode>3_doubleword"
8635 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8636 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8637 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8638 (clobber (reg:CC FLAGS_REG))]
8639 ""
8640 "#"
8641 [(set_attr "type" "multi")])
8642
8643 (define_split
8644 [(set (match_operand:DWI 0 "register_operand")
8645 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
8646 (match_operand:QI 2 "nonmemory_operand")))
8647 (clobber (reg:CC FLAGS_REG))]
8648 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8649 [(const_int 0)]
8650 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8651
8652 ;; By default we don't ask for a scratch register, because when DWImode
8653 ;; values are manipulated, registers are already at a premium. But if
8654 ;; we have one handy, we won't turn it away.
8655
8656 (define_peephole2
8657 [(match_scratch:DWIH 3 "r")
8658 (parallel [(set (match_operand:<DWI> 0 "register_operand")
8659 (ashift:<DWI>
8660 (match_operand:<DWI> 1 "nonmemory_operand")
8661 (match_operand:QI 2 "nonmemory_operand")))
8662 (clobber (reg:CC FLAGS_REG))])
8663 (match_dup 3)]
8664 "TARGET_CMOVE"
8665 [(const_int 0)]
8666 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8667
8668 (define_insn "x86_64_shld"
8669 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8670 (ior:DI (ashift:DI (match_dup 0)
8671 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8672 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8673 (minus:QI (const_int 64) (match_dup 2)))))
8674 (clobber (reg:CC FLAGS_REG))]
8675 "TARGET_64BIT"
8676 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8677 [(set_attr "type" "ishift")
8678 (set_attr "prefix_0f" "1")
8679 (set_attr "mode" "DI")
8680 (set_attr "athlon_decode" "vector")
8681 (set_attr "amdfam10_decode" "vector")
8682 (set_attr "bdver1_decode" "vector")])
8683
8684 (define_insn "x86_shld"
8685 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8686 (ior:SI (ashift:SI (match_dup 0)
8687 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8688 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8689 (minus:QI (const_int 32) (match_dup 2)))))
8690 (clobber (reg:CC FLAGS_REG))]
8691 ""
8692 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8693 [(set_attr "type" "ishift")
8694 (set_attr "prefix_0f" "1")
8695 (set_attr "mode" "SI")
8696 (set_attr "pent_pair" "np")
8697 (set_attr "athlon_decode" "vector")
8698 (set_attr "amdfam10_decode" "vector")
8699 (set_attr "bdver1_decode" "vector")])
8700
8701 (define_expand "x86_shift<mode>_adj_1"
8702 [(set (reg:CCZ FLAGS_REG)
8703 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
8704 (match_dup 4))
8705 (const_int 0)))
8706 (set (match_operand:SWI48 0 "register_operand")
8707 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8708 (match_operand:SWI48 1 "register_operand")
8709 (match_dup 0)))
8710 (set (match_dup 1)
8711 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8712 (match_operand:SWI48 3 "register_operand")
8713 (match_dup 1)))]
8714 "TARGET_CMOVE"
8715 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8716
8717 (define_expand "x86_shift<mode>_adj_2"
8718 [(use (match_operand:SWI48 0 "register_operand"))
8719 (use (match_operand:SWI48 1 "register_operand"))
8720 (use (match_operand:QI 2 "register_operand"))]
8721 ""
8722 {
8723 rtx label = gen_label_rtx ();
8724 rtx tmp;
8725
8726 emit_insn (gen_testqi_ccz_1 (operands[2],
8727 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8728
8729 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8730 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8731 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8732 gen_rtx_LABEL_REF (VOIDmode, label),
8733 pc_rtx);
8734 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8735 JUMP_LABEL (tmp) = label;
8736
8737 emit_move_insn (operands[0], operands[1]);
8738 ix86_expand_clear (operands[1]);
8739
8740 emit_label (label);
8741 LABEL_NUSES (label) = 1;
8742
8743 DONE;
8744 })
8745
8746 ;; Avoid useless masking of count operand.
8747 (define_insn "*ashl<mode>3_mask"
8748 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8749 (ashift:SWI48
8750 (match_operand:SWI48 1 "nonimmediate_operand" "0")
8751 (subreg:QI
8752 (and:SI
8753 (match_operand:SI 2 "register_operand" "c")
8754 (match_operand:SI 3 "const_int_operand" "n")) 0)))
8755 (clobber (reg:CC FLAGS_REG))]
8756 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
8757 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
8758 == GET_MODE_BITSIZE (<MODE>mode)-1"
8759 {
8760 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
8761 }
8762 [(set_attr "type" "ishift")
8763 (set_attr "mode" "<MODE>")])
8764
8765 (define_insn "*bmi2_ashl<mode>3_1"
8766 [(set (match_operand:SWI48 0 "register_operand" "=r")
8767 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
8768 (match_operand:SWI48 2 "register_operand" "r")))]
8769 "TARGET_BMI2"
8770 "shlx\t{%2, %1, %0|%0, %1, %2}"
8771 [(set_attr "type" "ishiftx")
8772 (set_attr "mode" "<MODE>")])
8773
8774 (define_insn "*ashl<mode>3_1"
8775 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
8776 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
8777 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
8778 (clobber (reg:CC FLAGS_REG))]
8779 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
8780 {
8781 switch (get_attr_type (insn))
8782 {
8783 case TYPE_LEA:
8784 case TYPE_ISHIFTX:
8785 return "#";
8786
8787 case TYPE_ALU:
8788 gcc_assert (operands[2] == const1_rtx);
8789 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8790 return "add{<imodesuffix>}\t%0, %0";
8791
8792 default:
8793 if (operands[2] == const1_rtx
8794 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8795 return "sal{<imodesuffix>}\t%0";
8796 else
8797 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
8798 }
8799 }
8800 [(set_attr "isa" "*,*,bmi2")
8801 (set (attr "type")
8802 (cond [(eq_attr "alternative" "1")
8803 (const_string "lea")
8804 (eq_attr "alternative" "2")
8805 (const_string "ishiftx")
8806 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8807 (match_operand 0 "register_operand"))
8808 (match_operand 2 "const1_operand"))
8809 (const_string "alu")
8810 ]
8811 (const_string "ishift")))
8812 (set (attr "length_immediate")
8813 (if_then_else
8814 (ior (eq_attr "type" "alu")
8815 (and (eq_attr "type" "ishift")
8816 (and (match_operand 2 "const1_operand")
8817 (ior (match_test "TARGET_SHIFT1")
8818 (match_test "optimize_function_for_size_p (cfun)")))))
8819 (const_string "0")
8820 (const_string "*")))
8821 (set_attr "mode" "<MODE>")])
8822
8823 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8824 (define_split
8825 [(set (match_operand:SWI48 0 "register_operand")
8826 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
8827 (match_operand:QI 2 "register_operand")))
8828 (clobber (reg:CC FLAGS_REG))]
8829 "TARGET_BMI2 && reload_completed"
8830 [(set (match_dup 0)
8831 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
8832 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
8833
8834 (define_insn "*bmi2_ashlsi3_1_zext"
8835 [(set (match_operand:DI 0 "register_operand" "=r")
8836 (zero_extend:DI
8837 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
8838 (match_operand:SI 2 "register_operand" "r"))))]
8839 "TARGET_64BIT && TARGET_BMI2"
8840 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
8841 [(set_attr "type" "ishiftx")
8842 (set_attr "mode" "SI")])
8843
8844 (define_insn "*ashlsi3_1_zext"
8845 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8846 (zero_extend:DI
8847 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
8848 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
8849 (clobber (reg:CC FLAGS_REG))]
8850 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
8851 {
8852 switch (get_attr_type (insn))
8853 {
8854 case TYPE_LEA:
8855 case TYPE_ISHIFTX:
8856 return "#";
8857
8858 case TYPE_ALU:
8859 gcc_assert (operands[2] == const1_rtx);
8860 return "add{l}\t%k0, %k0";
8861
8862 default:
8863 if (operands[2] == const1_rtx
8864 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8865 return "sal{l}\t%k0";
8866 else
8867 return "sal{l}\t{%2, %k0|%k0, %2}";
8868 }
8869 }
8870 [(set_attr "isa" "*,*,bmi2")
8871 (set (attr "type")
8872 (cond [(eq_attr "alternative" "1")
8873 (const_string "lea")
8874 (eq_attr "alternative" "2")
8875 (const_string "ishiftx")
8876 (and (match_test "TARGET_DOUBLE_WITH_ADD")
8877 (match_operand 2 "const1_operand"))
8878 (const_string "alu")
8879 ]
8880 (const_string "ishift")))
8881 (set (attr "length_immediate")
8882 (if_then_else
8883 (ior (eq_attr "type" "alu")
8884 (and (eq_attr "type" "ishift")
8885 (and (match_operand 2 "const1_operand")
8886 (ior (match_test "TARGET_SHIFT1")
8887 (match_test "optimize_function_for_size_p (cfun)")))))
8888 (const_string "0")
8889 (const_string "*")))
8890 (set_attr "mode" "SI")])
8891
8892 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8893 (define_split
8894 [(set (match_operand:DI 0 "register_operand")
8895 (zero_extend:DI
8896 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
8897 (match_operand:QI 2 "register_operand"))))
8898 (clobber (reg:CC FLAGS_REG))]
8899 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
8900 [(set (match_dup 0)
8901 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
8902 "operands[2] = gen_lowpart (SImode, operands[2]);")
8903
8904 (define_insn "*ashlhi3_1"
8905 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
8906 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
8907 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8908 (clobber (reg:CC FLAGS_REG))]
8909 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
8910 {
8911 switch (get_attr_type (insn))
8912 {
8913 case TYPE_LEA:
8914 return "#";
8915
8916 case TYPE_ALU:
8917 gcc_assert (operands[2] == const1_rtx);
8918 return "add{w}\t%0, %0";
8919
8920 default:
8921 if (operands[2] == const1_rtx
8922 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8923 return "sal{w}\t%0";
8924 else
8925 return "sal{w}\t{%2, %0|%0, %2}";
8926 }
8927 }
8928 [(set (attr "type")
8929 (cond [(eq_attr "alternative" "1")
8930 (const_string "lea")
8931 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8932 (match_operand 0 "register_operand"))
8933 (match_operand 2 "const1_operand"))
8934 (const_string "alu")
8935 ]
8936 (const_string "ishift")))
8937 (set (attr "length_immediate")
8938 (if_then_else
8939 (ior (eq_attr "type" "alu")
8940 (and (eq_attr "type" "ishift")
8941 (and (match_operand 2 "const1_operand")
8942 (ior (match_test "TARGET_SHIFT1")
8943 (match_test "optimize_function_for_size_p (cfun)")))))
8944 (const_string "0")
8945 (const_string "*")))
8946 (set_attr "mode" "HI,SI")])
8947
8948 ;; %%% Potential partial reg stall on alternative 1. What to do?
8949 (define_insn "*ashlqi3_1"
8950 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
8951 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
8952 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
8953 (clobber (reg:CC FLAGS_REG))]
8954 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8955 {
8956 switch (get_attr_type (insn))
8957 {
8958 case TYPE_LEA:
8959 return "#";
8960
8961 case TYPE_ALU:
8962 gcc_assert (operands[2] == const1_rtx);
8963 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
8964 return "add{l}\t%k0, %k0";
8965 else
8966 return "add{b}\t%0, %0";
8967
8968 default:
8969 if (operands[2] == const1_rtx
8970 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8971 {
8972 if (get_attr_mode (insn) == MODE_SI)
8973 return "sal{l}\t%k0";
8974 else
8975 return "sal{b}\t%0";
8976 }
8977 else
8978 {
8979 if (get_attr_mode (insn) == MODE_SI)
8980 return "sal{l}\t{%2, %k0|%k0, %2}";
8981 else
8982 return "sal{b}\t{%2, %0|%0, %2}";
8983 }
8984 }
8985 }
8986 [(set (attr "type")
8987 (cond [(eq_attr "alternative" "2")
8988 (const_string "lea")
8989 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8990 (match_operand 0 "register_operand"))
8991 (match_operand 2 "const1_operand"))
8992 (const_string "alu")
8993 ]
8994 (const_string "ishift")))
8995 (set (attr "length_immediate")
8996 (if_then_else
8997 (ior (eq_attr "type" "alu")
8998 (and (eq_attr "type" "ishift")
8999 (and (match_operand 2 "const1_operand")
9000 (ior (match_test "TARGET_SHIFT1")
9001 (match_test "optimize_function_for_size_p (cfun)")))))
9002 (const_string "0")
9003 (const_string "*")))
9004 (set_attr "mode" "QI,SI,SI")])
9005
9006 (define_insn "*ashlqi3_1_slp"
9007 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9008 (ashift:QI (match_dup 0)
9009 (match_operand:QI 1 "nonmemory_operand" "cI")))
9010 (clobber (reg:CC FLAGS_REG))]
9011 "(optimize_function_for_size_p (cfun)
9012 || !TARGET_PARTIAL_FLAG_REG_STALL
9013 || (operands[1] == const1_rtx
9014 && (TARGET_SHIFT1
9015 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9016 {
9017 switch (get_attr_type (insn))
9018 {
9019 case TYPE_ALU:
9020 gcc_assert (operands[1] == const1_rtx);
9021 return "add{b}\t%0, %0";
9022
9023 default:
9024 if (operands[1] == const1_rtx
9025 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9026 return "sal{b}\t%0";
9027 else
9028 return "sal{b}\t{%1, %0|%0, %1}";
9029 }
9030 }
9031 [(set (attr "type")
9032 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9033 (match_operand 0 "register_operand"))
9034 (match_operand 1 "const1_operand"))
9035 (const_string "alu")
9036 ]
9037 (const_string "ishift1")))
9038 (set (attr "length_immediate")
9039 (if_then_else
9040 (ior (eq_attr "type" "alu")
9041 (and (eq_attr "type" "ishift1")
9042 (and (match_operand 1 "const1_operand")
9043 (ior (match_test "TARGET_SHIFT1")
9044 (match_test "optimize_function_for_size_p (cfun)")))))
9045 (const_string "0")
9046 (const_string "*")))
9047 (set_attr "mode" "QI")])
9048
9049 ;; Convert ashift to the lea pattern to avoid flags dependency.
9050 (define_split
9051 [(set (match_operand 0 "register_operand")
9052 (ashift (match_operand 1 "index_register_operand")
9053 (match_operand:QI 2 "const_int_operand")))
9054 (clobber (reg:CC FLAGS_REG))]
9055 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9056 && reload_completed
9057 && true_regnum (operands[0]) != true_regnum (operands[1])"
9058 [(const_int 0)]
9059 {
9060 enum machine_mode mode = GET_MODE (operands[0]);
9061 rtx pat;
9062
9063 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9064 {
9065 mode = SImode;
9066 operands[0] = gen_lowpart (mode, operands[0]);
9067 operands[1] = gen_lowpart (mode, operands[1]);
9068 }
9069
9070 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9071
9072 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9073
9074 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9075 DONE;
9076 })
9077
9078 ;; Convert ashift to the lea pattern to avoid flags dependency.
9079 (define_split
9080 [(set (match_operand:DI 0 "register_operand")
9081 (zero_extend:DI
9082 (ashift:SI (match_operand:SI 1 "index_register_operand")
9083 (match_operand:QI 2 "const_int_operand"))))
9084 (clobber (reg:CC FLAGS_REG))]
9085 "TARGET_64BIT && reload_completed
9086 && true_regnum (operands[0]) != true_regnum (operands[1])"
9087 [(set (match_dup 0)
9088 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9089 {
9090 operands[1] = gen_lowpart (SImode, operands[1]);
9091 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9092 })
9093
9094 ;; This pattern can't accept a variable shift count, since shifts by
9095 ;; zero don't affect the flags. We assume that shifts by constant
9096 ;; zero are optimized away.
9097 (define_insn "*ashl<mode>3_cmp"
9098 [(set (reg FLAGS_REG)
9099 (compare
9100 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9101 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9102 (const_int 0)))
9103 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9104 (ashift:SWI (match_dup 1) (match_dup 2)))]
9105 "(optimize_function_for_size_p (cfun)
9106 || !TARGET_PARTIAL_FLAG_REG_STALL
9107 || (operands[2] == const1_rtx
9108 && (TARGET_SHIFT1
9109 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9110 && ix86_match_ccmode (insn, CCGOCmode)
9111 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9112 {
9113 switch (get_attr_type (insn))
9114 {
9115 case TYPE_ALU:
9116 gcc_assert (operands[2] == const1_rtx);
9117 return "add{<imodesuffix>}\t%0, %0";
9118
9119 default:
9120 if (operands[2] == const1_rtx
9121 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9122 return "sal{<imodesuffix>}\t%0";
9123 else
9124 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9125 }
9126 }
9127 [(set (attr "type")
9128 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9129 (match_operand 0 "register_operand"))
9130 (match_operand 2 "const1_operand"))
9131 (const_string "alu")
9132 ]
9133 (const_string "ishift")))
9134 (set (attr "length_immediate")
9135 (if_then_else
9136 (ior (eq_attr "type" "alu")
9137 (and (eq_attr "type" "ishift")
9138 (and (match_operand 2 "const1_operand")
9139 (ior (match_test "TARGET_SHIFT1")
9140 (match_test "optimize_function_for_size_p (cfun)")))))
9141 (const_string "0")
9142 (const_string "*")))
9143 (set_attr "mode" "<MODE>")])
9144
9145 (define_insn "*ashlsi3_cmp_zext"
9146 [(set (reg FLAGS_REG)
9147 (compare
9148 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9149 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9150 (const_int 0)))
9151 (set (match_operand:DI 0 "register_operand" "=r")
9152 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9153 "TARGET_64BIT
9154 && (optimize_function_for_size_p (cfun)
9155 || !TARGET_PARTIAL_FLAG_REG_STALL
9156 || (operands[2] == const1_rtx
9157 && (TARGET_SHIFT1
9158 || TARGET_DOUBLE_WITH_ADD)))
9159 && ix86_match_ccmode (insn, CCGOCmode)
9160 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9161 {
9162 switch (get_attr_type (insn))
9163 {
9164 case TYPE_ALU:
9165 gcc_assert (operands[2] == const1_rtx);
9166 return "add{l}\t%k0, %k0";
9167
9168 default:
9169 if (operands[2] == const1_rtx
9170 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9171 return "sal{l}\t%k0";
9172 else
9173 return "sal{l}\t{%2, %k0|%k0, %2}";
9174 }
9175 }
9176 [(set (attr "type")
9177 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9178 (match_operand 2 "const1_operand"))
9179 (const_string "alu")
9180 ]
9181 (const_string "ishift")))
9182 (set (attr "length_immediate")
9183 (if_then_else
9184 (ior (eq_attr "type" "alu")
9185 (and (eq_attr "type" "ishift")
9186 (and (match_operand 2 "const1_operand")
9187 (ior (match_test "TARGET_SHIFT1")
9188 (match_test "optimize_function_for_size_p (cfun)")))))
9189 (const_string "0")
9190 (const_string "*")))
9191 (set_attr "mode" "SI")])
9192
9193 (define_insn "*ashl<mode>3_cconly"
9194 [(set (reg FLAGS_REG)
9195 (compare
9196 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9197 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9198 (const_int 0)))
9199 (clobber (match_scratch:SWI 0 "=<r>"))]
9200 "(optimize_function_for_size_p (cfun)
9201 || !TARGET_PARTIAL_FLAG_REG_STALL
9202 || (operands[2] == const1_rtx
9203 && (TARGET_SHIFT1
9204 || TARGET_DOUBLE_WITH_ADD)))
9205 && ix86_match_ccmode (insn, CCGOCmode)"
9206 {
9207 switch (get_attr_type (insn))
9208 {
9209 case TYPE_ALU:
9210 gcc_assert (operands[2] == const1_rtx);
9211 return "add{<imodesuffix>}\t%0, %0";
9212
9213 default:
9214 if (operands[2] == const1_rtx
9215 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9216 return "sal{<imodesuffix>}\t%0";
9217 else
9218 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9219 }
9220 }
9221 [(set (attr "type")
9222 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9223 (match_operand 0 "register_operand"))
9224 (match_operand 2 "const1_operand"))
9225 (const_string "alu")
9226 ]
9227 (const_string "ishift")))
9228 (set (attr "length_immediate")
9229 (if_then_else
9230 (ior (eq_attr "type" "alu")
9231 (and (eq_attr "type" "ishift")
9232 (and (match_operand 2 "const1_operand")
9233 (ior (match_test "TARGET_SHIFT1")
9234 (match_test "optimize_function_for_size_p (cfun)")))))
9235 (const_string "0")
9236 (const_string "*")))
9237 (set_attr "mode" "<MODE>")])
9238
9239 ;; See comment above `ashl<mode>3' about how this works.
9240
9241 (define_expand "<shift_insn><mode>3"
9242 [(set (match_operand:SDWIM 0 "<shift_operand>")
9243 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9244 (match_operand:QI 2 "nonmemory_operand")))]
9245 ""
9246 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9247
9248 ;; Avoid useless masking of count operand.
9249 (define_insn "*<shift_insn><mode>3_mask"
9250 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9251 (any_shiftrt:SWI48
9252 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9253 (subreg:QI
9254 (and:SI
9255 (match_operand:SI 2 "register_operand" "c")
9256 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9257 (clobber (reg:CC FLAGS_REG))]
9258 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9259 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9260 == GET_MODE_BITSIZE (<MODE>mode)-1"
9261 {
9262 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9263 }
9264 [(set_attr "type" "ishift")
9265 (set_attr "mode" "<MODE>")])
9266
9267 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9268 [(set (match_operand:DWI 0 "register_operand" "=r")
9269 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9270 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9271 (clobber (reg:CC FLAGS_REG))]
9272 ""
9273 "#"
9274 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9275 [(const_int 0)]
9276 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9277 [(set_attr "type" "multi")])
9278
9279 ;; By default we don't ask for a scratch register, because when DWImode
9280 ;; values are manipulated, registers are already at a premium. But if
9281 ;; we have one handy, we won't turn it away.
9282
9283 (define_peephole2
9284 [(match_scratch:DWIH 3 "r")
9285 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9286 (any_shiftrt:<DWI>
9287 (match_operand:<DWI> 1 "register_operand")
9288 (match_operand:QI 2 "nonmemory_operand")))
9289 (clobber (reg:CC FLAGS_REG))])
9290 (match_dup 3)]
9291 "TARGET_CMOVE"
9292 [(const_int 0)]
9293 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9294
9295 (define_insn "x86_64_shrd"
9296 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9297 (ior:DI (ashiftrt:DI (match_dup 0)
9298 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9299 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9300 (minus:QI (const_int 64) (match_dup 2)))))
9301 (clobber (reg:CC FLAGS_REG))]
9302 "TARGET_64BIT"
9303 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9304 [(set_attr "type" "ishift")
9305 (set_attr "prefix_0f" "1")
9306 (set_attr "mode" "DI")
9307 (set_attr "athlon_decode" "vector")
9308 (set_attr "amdfam10_decode" "vector")
9309 (set_attr "bdver1_decode" "vector")])
9310
9311 (define_insn "x86_shrd"
9312 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9313 (ior:SI (ashiftrt:SI (match_dup 0)
9314 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9315 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9316 (minus:QI (const_int 32) (match_dup 2)))))
9317 (clobber (reg:CC FLAGS_REG))]
9318 ""
9319 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9320 [(set_attr "type" "ishift")
9321 (set_attr "prefix_0f" "1")
9322 (set_attr "mode" "SI")
9323 (set_attr "pent_pair" "np")
9324 (set_attr "athlon_decode" "vector")
9325 (set_attr "amdfam10_decode" "vector")
9326 (set_attr "bdver1_decode" "vector")])
9327
9328 (define_insn "ashrdi3_cvt"
9329 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9330 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9331 (match_operand:QI 2 "const_int_operand")))
9332 (clobber (reg:CC FLAGS_REG))]
9333 "TARGET_64BIT && INTVAL (operands[2]) == 63
9334 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9335 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9336 "@
9337 {cqto|cqo}
9338 sar{q}\t{%2, %0|%0, %2}"
9339 [(set_attr "type" "imovx,ishift")
9340 (set_attr "prefix_0f" "0,*")
9341 (set_attr "length_immediate" "0,*")
9342 (set_attr "modrm" "0,1")
9343 (set_attr "mode" "DI")])
9344
9345 (define_insn "ashrsi3_cvt"
9346 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9347 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9348 (match_operand:QI 2 "const_int_operand")))
9349 (clobber (reg:CC FLAGS_REG))]
9350 "INTVAL (operands[2]) == 31
9351 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9352 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9353 "@
9354 {cltd|cdq}
9355 sar{l}\t{%2, %0|%0, %2}"
9356 [(set_attr "type" "imovx,ishift")
9357 (set_attr "prefix_0f" "0,*")
9358 (set_attr "length_immediate" "0,*")
9359 (set_attr "modrm" "0,1")
9360 (set_attr "mode" "SI")])
9361
9362 (define_insn "*ashrsi3_cvt_zext"
9363 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9364 (zero_extend:DI
9365 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9366 (match_operand:QI 2 "const_int_operand"))))
9367 (clobber (reg:CC FLAGS_REG))]
9368 "TARGET_64BIT && INTVAL (operands[2]) == 31
9369 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9370 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9371 "@
9372 {cltd|cdq}
9373 sar{l}\t{%2, %k0|%k0, %2}"
9374 [(set_attr "type" "imovx,ishift")
9375 (set_attr "prefix_0f" "0,*")
9376 (set_attr "length_immediate" "0,*")
9377 (set_attr "modrm" "0,1")
9378 (set_attr "mode" "SI")])
9379
9380 (define_expand "x86_shift<mode>_adj_3"
9381 [(use (match_operand:SWI48 0 "register_operand"))
9382 (use (match_operand:SWI48 1 "register_operand"))
9383 (use (match_operand:QI 2 "register_operand"))]
9384 ""
9385 {
9386 rtx label = gen_label_rtx ();
9387 rtx tmp;
9388
9389 emit_insn (gen_testqi_ccz_1 (operands[2],
9390 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9391
9392 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9393 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9394 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9395 gen_rtx_LABEL_REF (VOIDmode, label),
9396 pc_rtx);
9397 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9398 JUMP_LABEL (tmp) = label;
9399
9400 emit_move_insn (operands[0], operands[1]);
9401 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9402 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9403 emit_label (label);
9404 LABEL_NUSES (label) = 1;
9405
9406 DONE;
9407 })
9408
9409 (define_insn "*bmi2_<shift_insn><mode>3_1"
9410 [(set (match_operand:SWI48 0 "register_operand" "=r")
9411 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9412 (match_operand:SWI48 2 "register_operand" "r")))]
9413 "TARGET_BMI2"
9414 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9415 [(set_attr "type" "ishiftx")
9416 (set_attr "mode" "<MODE>")])
9417
9418 (define_insn "*<shift_insn><mode>3_1"
9419 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9420 (any_shiftrt:SWI48
9421 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9422 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9423 (clobber (reg:CC FLAGS_REG))]
9424 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9425 {
9426 switch (get_attr_type (insn))
9427 {
9428 case TYPE_ISHIFTX:
9429 return "#";
9430
9431 default:
9432 if (operands[2] == const1_rtx
9433 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9434 return "<shift>{<imodesuffix>}\t%0";
9435 else
9436 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9437 }
9438 }
9439 [(set_attr "isa" "*,bmi2")
9440 (set_attr "type" "ishift,ishiftx")
9441 (set (attr "length_immediate")
9442 (if_then_else
9443 (and (match_operand 2 "const1_operand")
9444 (ior (match_test "TARGET_SHIFT1")
9445 (match_test "optimize_function_for_size_p (cfun)")))
9446 (const_string "0")
9447 (const_string "*")))
9448 (set_attr "mode" "<MODE>")])
9449
9450 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9451 (define_split
9452 [(set (match_operand:SWI48 0 "register_operand")
9453 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9454 (match_operand:QI 2 "register_operand")))
9455 (clobber (reg:CC FLAGS_REG))]
9456 "TARGET_BMI2 && reload_completed"
9457 [(set (match_dup 0)
9458 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9459 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9460
9461 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9462 [(set (match_operand:DI 0 "register_operand" "=r")
9463 (zero_extend:DI
9464 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9465 (match_operand:SI 2 "register_operand" "r"))))]
9466 "TARGET_64BIT && TARGET_BMI2"
9467 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9468 [(set_attr "type" "ishiftx")
9469 (set_attr "mode" "SI")])
9470
9471 (define_insn "*<shift_insn>si3_1_zext"
9472 [(set (match_operand:DI 0 "register_operand" "=r,r")
9473 (zero_extend:DI
9474 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9475 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9476 (clobber (reg:CC FLAGS_REG))]
9477 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9478 {
9479 switch (get_attr_type (insn))
9480 {
9481 case TYPE_ISHIFTX:
9482 return "#";
9483
9484 default:
9485 if (operands[2] == const1_rtx
9486 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9487 return "<shift>{l}\t%k0";
9488 else
9489 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9490 }
9491 }
9492 [(set_attr "isa" "*,bmi2")
9493 (set_attr "type" "ishift,ishiftx")
9494 (set (attr "length_immediate")
9495 (if_then_else
9496 (and (match_operand 2 "const1_operand")
9497 (ior (match_test "TARGET_SHIFT1")
9498 (match_test "optimize_function_for_size_p (cfun)")))
9499 (const_string "0")
9500 (const_string "*")))
9501 (set_attr "mode" "SI")])
9502
9503 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9504 (define_split
9505 [(set (match_operand:DI 0 "register_operand")
9506 (zero_extend:DI
9507 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9508 (match_operand:QI 2 "register_operand"))))
9509 (clobber (reg:CC FLAGS_REG))]
9510 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9511 [(set (match_dup 0)
9512 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9513 "operands[2] = gen_lowpart (SImode, operands[2]);")
9514
9515 (define_insn "*<shift_insn><mode>3_1"
9516 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9517 (any_shiftrt:SWI12
9518 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9519 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9520 (clobber (reg:CC FLAGS_REG))]
9521 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9522 {
9523 if (operands[2] == const1_rtx
9524 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9525 return "<shift>{<imodesuffix>}\t%0";
9526 else
9527 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9528 }
9529 [(set_attr "type" "ishift")
9530 (set (attr "length_immediate")
9531 (if_then_else
9532 (and (match_operand 2 "const1_operand")
9533 (ior (match_test "TARGET_SHIFT1")
9534 (match_test "optimize_function_for_size_p (cfun)")))
9535 (const_string "0")
9536 (const_string "*")))
9537 (set_attr "mode" "<MODE>")])
9538
9539 (define_insn "*<shift_insn>qi3_1_slp"
9540 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9541 (any_shiftrt:QI (match_dup 0)
9542 (match_operand:QI 1 "nonmemory_operand" "cI")))
9543 (clobber (reg:CC FLAGS_REG))]
9544 "(optimize_function_for_size_p (cfun)
9545 || !TARGET_PARTIAL_REG_STALL
9546 || (operands[1] == const1_rtx
9547 && TARGET_SHIFT1))"
9548 {
9549 if (operands[1] == const1_rtx
9550 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9551 return "<shift>{b}\t%0";
9552 else
9553 return "<shift>{b}\t{%1, %0|%0, %1}";
9554 }
9555 [(set_attr "type" "ishift1")
9556 (set (attr "length_immediate")
9557 (if_then_else
9558 (and (match_operand 1 "const1_operand")
9559 (ior (match_test "TARGET_SHIFT1")
9560 (match_test "optimize_function_for_size_p (cfun)")))
9561 (const_string "0")
9562 (const_string "*")))
9563 (set_attr "mode" "QI")])
9564
9565 ;; This pattern can't accept a variable shift count, since shifts by
9566 ;; zero don't affect the flags. We assume that shifts by constant
9567 ;; zero are optimized away.
9568 (define_insn "*<shift_insn><mode>3_cmp"
9569 [(set (reg FLAGS_REG)
9570 (compare
9571 (any_shiftrt:SWI
9572 (match_operand:SWI 1 "nonimmediate_operand" "0")
9573 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9574 (const_int 0)))
9575 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9576 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9577 "(optimize_function_for_size_p (cfun)
9578 || !TARGET_PARTIAL_FLAG_REG_STALL
9579 || (operands[2] == const1_rtx
9580 && TARGET_SHIFT1))
9581 && ix86_match_ccmode (insn, CCGOCmode)
9582 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9583 {
9584 if (operands[2] == const1_rtx
9585 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9586 return "<shift>{<imodesuffix>}\t%0";
9587 else
9588 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9589 }
9590 [(set_attr "type" "ishift")
9591 (set (attr "length_immediate")
9592 (if_then_else
9593 (and (match_operand 2 "const1_operand")
9594 (ior (match_test "TARGET_SHIFT1")
9595 (match_test "optimize_function_for_size_p (cfun)")))
9596 (const_string "0")
9597 (const_string "*")))
9598 (set_attr "mode" "<MODE>")])
9599
9600 (define_insn "*<shift_insn>si3_cmp_zext"
9601 [(set (reg FLAGS_REG)
9602 (compare
9603 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9604 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9605 (const_int 0)))
9606 (set (match_operand:DI 0 "register_operand" "=r")
9607 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9608 "TARGET_64BIT
9609 && (optimize_function_for_size_p (cfun)
9610 || !TARGET_PARTIAL_FLAG_REG_STALL
9611 || (operands[2] == const1_rtx
9612 && TARGET_SHIFT1))
9613 && ix86_match_ccmode (insn, CCGOCmode)
9614 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9615 {
9616 if (operands[2] == const1_rtx
9617 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9618 return "<shift>{l}\t%k0";
9619 else
9620 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9621 }
9622 [(set_attr "type" "ishift")
9623 (set (attr "length_immediate")
9624 (if_then_else
9625 (and (match_operand 2 "const1_operand")
9626 (ior (match_test "TARGET_SHIFT1")
9627 (match_test "optimize_function_for_size_p (cfun)")))
9628 (const_string "0")
9629 (const_string "*")))
9630 (set_attr "mode" "SI")])
9631
9632 (define_insn "*<shift_insn><mode>3_cconly"
9633 [(set (reg FLAGS_REG)
9634 (compare
9635 (any_shiftrt:SWI
9636 (match_operand:SWI 1 "register_operand" "0")
9637 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9638 (const_int 0)))
9639 (clobber (match_scratch:SWI 0 "=<r>"))]
9640 "(optimize_function_for_size_p (cfun)
9641 || !TARGET_PARTIAL_FLAG_REG_STALL
9642 || (operands[2] == const1_rtx
9643 && TARGET_SHIFT1))
9644 && ix86_match_ccmode (insn, CCGOCmode)"
9645 {
9646 if (operands[2] == const1_rtx
9647 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9648 return "<shift>{<imodesuffix>}\t%0";
9649 else
9650 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9651 }
9652 [(set_attr "type" "ishift")
9653 (set (attr "length_immediate")
9654 (if_then_else
9655 (and (match_operand 2 "const1_operand")
9656 (ior (match_test "TARGET_SHIFT1")
9657 (match_test "optimize_function_for_size_p (cfun)")))
9658 (const_string "0")
9659 (const_string "*")))
9660 (set_attr "mode" "<MODE>")])
9661 \f
9662 ;; Rotate instructions
9663
9664 (define_expand "<rotate_insn>ti3"
9665 [(set (match_operand:TI 0 "register_operand")
9666 (any_rotate:TI (match_operand:TI 1 "register_operand")
9667 (match_operand:QI 2 "nonmemory_operand")))]
9668 "TARGET_64BIT"
9669 {
9670 if (const_1_to_63_operand (operands[2], VOIDmode))
9671 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9672 (operands[0], operands[1], operands[2]));
9673 else
9674 FAIL;
9675
9676 DONE;
9677 })
9678
9679 (define_expand "<rotate_insn>di3"
9680 [(set (match_operand:DI 0 "shiftdi_operand")
9681 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
9682 (match_operand:QI 2 "nonmemory_operand")))]
9683 ""
9684 {
9685 if (TARGET_64BIT)
9686 ix86_expand_binary_operator (<CODE>, DImode, operands);
9687 else if (const_1_to_31_operand (operands[2], VOIDmode))
9688 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9689 (operands[0], operands[1], operands[2]));
9690 else
9691 FAIL;
9692
9693 DONE;
9694 })
9695
9696 (define_expand "<rotate_insn><mode>3"
9697 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
9698 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
9699 (match_operand:QI 2 "nonmemory_operand")))]
9700 ""
9701 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9702
9703 ;; Avoid useless masking of count operand.
9704 (define_insn "*<rotate_insn><mode>3_mask"
9705 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9706 (any_rotate:SWI48
9707 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9708 (subreg:QI
9709 (and:SI
9710 (match_operand:SI 2 "register_operand" "c")
9711 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9712 (clobber (reg:CC FLAGS_REG))]
9713 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9714 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9715 == GET_MODE_BITSIZE (<MODE>mode)-1"
9716 {
9717 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9718 }
9719 [(set_attr "type" "rotate")
9720 (set_attr "mode" "<MODE>")])
9721
9722 ;; Implement rotation using two double-precision
9723 ;; shift instructions and a scratch register.
9724
9725 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9726 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9727 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9728 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9729 (clobber (reg:CC FLAGS_REG))
9730 (clobber (match_scratch:DWIH 3 "=&r"))]
9731 ""
9732 "#"
9733 "reload_completed"
9734 [(set (match_dup 3) (match_dup 4))
9735 (parallel
9736 [(set (match_dup 4)
9737 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9738 (lshiftrt:DWIH (match_dup 5)
9739 (minus:QI (match_dup 6) (match_dup 2)))))
9740 (clobber (reg:CC FLAGS_REG))])
9741 (parallel
9742 [(set (match_dup 5)
9743 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9744 (lshiftrt:DWIH (match_dup 3)
9745 (minus:QI (match_dup 6) (match_dup 2)))))
9746 (clobber (reg:CC FLAGS_REG))])]
9747 {
9748 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9749
9750 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9751 })
9752
9753 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
9754 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9755 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9756 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9757 (clobber (reg:CC FLAGS_REG))
9758 (clobber (match_scratch:DWIH 3 "=&r"))]
9759 ""
9760 "#"
9761 "reload_completed"
9762 [(set (match_dup 3) (match_dup 4))
9763 (parallel
9764 [(set (match_dup 4)
9765 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
9766 (ashift:DWIH (match_dup 5)
9767 (minus:QI (match_dup 6) (match_dup 2)))))
9768 (clobber (reg:CC FLAGS_REG))])
9769 (parallel
9770 [(set (match_dup 5)
9771 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
9772 (ashift:DWIH (match_dup 3)
9773 (minus:QI (match_dup 6) (match_dup 2)))))
9774 (clobber (reg:CC FLAGS_REG))])]
9775 {
9776 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9777
9778 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9779 })
9780
9781 (define_insn "*bmi2_rorx<mode>3_1"
9782 [(set (match_operand:SWI48 0 "register_operand" "=r")
9783 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9784 (match_operand:QI 2 "immediate_operand" "<S>")))]
9785 "TARGET_BMI2"
9786 "rorx\t{%2, %1, %0|%0, %1, %2}"
9787 [(set_attr "type" "rotatex")
9788 (set_attr "mode" "<MODE>")])
9789
9790 (define_insn "*<rotate_insn><mode>3_1"
9791 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9792 (any_rotate:SWI48
9793 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9794 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
9795 (clobber (reg:CC FLAGS_REG))]
9796 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9797 {
9798 switch (get_attr_type (insn))
9799 {
9800 case TYPE_ROTATEX:
9801 return "#";
9802
9803 default:
9804 if (operands[2] == const1_rtx
9805 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9806 return "<rotate>{<imodesuffix>}\t%0";
9807 else
9808 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9809 }
9810 }
9811 [(set_attr "isa" "*,bmi2")
9812 (set_attr "type" "rotate,rotatex")
9813 (set (attr "length_immediate")
9814 (if_then_else
9815 (and (eq_attr "type" "rotate")
9816 (and (match_operand 2 "const1_operand")
9817 (ior (match_test "TARGET_SHIFT1")
9818 (match_test "optimize_function_for_size_p (cfun)"))))
9819 (const_string "0")
9820 (const_string "*")))
9821 (set_attr "mode" "<MODE>")])
9822
9823 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9824 (define_split
9825 [(set (match_operand:SWI48 0 "register_operand")
9826 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9827 (match_operand:QI 2 "immediate_operand")))
9828 (clobber (reg:CC FLAGS_REG))]
9829 "TARGET_BMI2 && reload_completed"
9830 [(set (match_dup 0)
9831 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
9832 {
9833 operands[2]
9834 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
9835 })
9836
9837 (define_split
9838 [(set (match_operand:SWI48 0 "register_operand")
9839 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9840 (match_operand:QI 2 "immediate_operand")))
9841 (clobber (reg:CC FLAGS_REG))]
9842 "TARGET_BMI2 && reload_completed"
9843 [(set (match_dup 0)
9844 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
9845
9846 (define_insn "*bmi2_rorxsi3_1_zext"
9847 [(set (match_operand:DI 0 "register_operand" "=r")
9848 (zero_extend:DI
9849 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9850 (match_operand:QI 2 "immediate_operand" "I"))))]
9851 "TARGET_64BIT && TARGET_BMI2"
9852 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
9853 [(set_attr "type" "rotatex")
9854 (set_attr "mode" "SI")])
9855
9856 (define_insn "*<rotate_insn>si3_1_zext"
9857 [(set (match_operand:DI 0 "register_operand" "=r,r")
9858 (zero_extend:DI
9859 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9860 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
9861 (clobber (reg:CC FLAGS_REG))]
9862 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9863 {
9864 switch (get_attr_type (insn))
9865 {
9866 case TYPE_ROTATEX:
9867 return "#";
9868
9869 default:
9870 if (operands[2] == const1_rtx
9871 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9872 return "<rotate>{l}\t%k0";
9873 else
9874 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
9875 }
9876 }
9877 [(set_attr "isa" "*,bmi2")
9878 (set_attr "type" "rotate,rotatex")
9879 (set (attr "length_immediate")
9880 (if_then_else
9881 (and (eq_attr "type" "rotate")
9882 (and (match_operand 2 "const1_operand")
9883 (ior (match_test "TARGET_SHIFT1")
9884 (match_test "optimize_function_for_size_p (cfun)"))))
9885 (const_string "0")
9886 (const_string "*")))
9887 (set_attr "mode" "SI")])
9888
9889 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9890 (define_split
9891 [(set (match_operand:DI 0 "register_operand")
9892 (zero_extend:DI
9893 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
9894 (match_operand:QI 2 "immediate_operand"))))
9895 (clobber (reg:CC FLAGS_REG))]
9896 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9897 [(set (match_dup 0)
9898 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
9899 {
9900 operands[2]
9901 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
9902 })
9903
9904 (define_split
9905 [(set (match_operand:DI 0 "register_operand")
9906 (zero_extend:DI
9907 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
9908 (match_operand:QI 2 "immediate_operand"))))
9909 (clobber (reg:CC FLAGS_REG))]
9910 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9911 [(set (match_dup 0)
9912 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
9913
9914 (define_insn "*<rotate_insn><mode>3_1"
9915 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9916 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9917 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9918 (clobber (reg:CC FLAGS_REG))]
9919 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9920 {
9921 if (operands[2] == const1_rtx
9922 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9923 return "<rotate>{<imodesuffix>}\t%0";
9924 else
9925 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9926 }
9927 [(set_attr "type" "rotate")
9928 (set (attr "length_immediate")
9929 (if_then_else
9930 (and (match_operand 2 "const1_operand")
9931 (ior (match_test "TARGET_SHIFT1")
9932 (match_test "optimize_function_for_size_p (cfun)")))
9933 (const_string "0")
9934 (const_string "*")))
9935 (set_attr "mode" "<MODE>")])
9936
9937 (define_insn "*<rotate_insn>qi3_1_slp"
9938 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9939 (any_rotate:QI (match_dup 0)
9940 (match_operand:QI 1 "nonmemory_operand" "cI")))
9941 (clobber (reg:CC FLAGS_REG))]
9942 "(optimize_function_for_size_p (cfun)
9943 || !TARGET_PARTIAL_REG_STALL
9944 || (operands[1] == const1_rtx
9945 && TARGET_SHIFT1))"
9946 {
9947 if (operands[1] == const1_rtx
9948 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9949 return "<rotate>{b}\t%0";
9950 else
9951 return "<rotate>{b}\t{%1, %0|%0, %1}";
9952 }
9953 [(set_attr "type" "rotate1")
9954 (set (attr "length_immediate")
9955 (if_then_else
9956 (and (match_operand 1 "const1_operand")
9957 (ior (match_test "TARGET_SHIFT1")
9958 (match_test "optimize_function_for_size_p (cfun)")))
9959 (const_string "0")
9960 (const_string "*")))
9961 (set_attr "mode" "QI")])
9962
9963 (define_split
9964 [(set (match_operand:HI 0 "register_operand")
9965 (any_rotate:HI (match_dup 0) (const_int 8)))
9966 (clobber (reg:CC FLAGS_REG))]
9967 "reload_completed
9968 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
9969 [(parallel [(set (strict_low_part (match_dup 0))
9970 (bswap:HI (match_dup 0)))
9971 (clobber (reg:CC FLAGS_REG))])])
9972 \f
9973 ;; Bit set / bit test instructions
9974
9975 (define_expand "extv"
9976 [(set (match_operand:SI 0 "register_operand")
9977 (sign_extract:SI (match_operand:SI 1 "register_operand")
9978 (match_operand:SI 2 "const8_operand")
9979 (match_operand:SI 3 "const8_operand")))]
9980 ""
9981 {
9982 /* Handle extractions from %ah et al. */
9983 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
9984 FAIL;
9985
9986 /* From mips.md: extract_bit_field doesn't verify that our source
9987 matches the predicate, so check it again here. */
9988 if (! ext_register_operand (operands[1], VOIDmode))
9989 FAIL;
9990 })
9991
9992 (define_expand "extzv"
9993 [(set (match_operand:SI 0 "register_operand")
9994 (zero_extract:SI (match_operand 1 "ext_register_operand")
9995 (match_operand:SI 2 "const8_operand")
9996 (match_operand:SI 3 "const8_operand")))]
9997 ""
9998 {
9999 /* Handle extractions from %ah et al. */
10000 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10001 FAIL;
10002
10003 /* From mips.md: extract_bit_field doesn't verify that our source
10004 matches the predicate, so check it again here. */
10005 if (! ext_register_operand (operands[1], VOIDmode))
10006 FAIL;
10007 })
10008
10009 (define_expand "insv"
10010 [(set (zero_extract (match_operand 0 "register_operand")
10011 (match_operand 1 "const_int_operand")
10012 (match_operand 2 "const_int_operand"))
10013 (match_operand 3 "register_operand"))]
10014 ""
10015 {
10016 rtx (*gen_mov_insv_1) (rtx, rtx);
10017
10018 if (ix86_expand_pinsr (operands))
10019 DONE;
10020
10021 /* Handle insertions to %ah et al. */
10022 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10023 FAIL;
10024
10025 /* From mips.md: insert_bit_field doesn't verify that our source
10026 matches the predicate, so check it again here. */
10027 if (! ext_register_operand (operands[0], VOIDmode))
10028 FAIL;
10029
10030 gen_mov_insv_1 = (TARGET_64BIT
10031 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10032
10033 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10034 DONE;
10035 })
10036
10037 ;; %%% bts, btr, btc, bt.
10038 ;; In general these instructions are *slow* when applied to memory,
10039 ;; since they enforce atomic operation. When applied to registers,
10040 ;; it depends on the cpu implementation. They're never faster than
10041 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10042 ;; no point. But in 64-bit, we can't hold the relevant immediates
10043 ;; within the instruction itself, so operating on bits in the high
10044 ;; 32-bits of a register becomes easier.
10045 ;;
10046 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10047 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10048 ;; negdf respectively, so they can never be disabled entirely.
10049
10050 (define_insn "*btsq"
10051 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10052 (const_int 1)
10053 (match_operand:DI 1 "const_0_to_63_operand"))
10054 (const_int 1))
10055 (clobber (reg:CC FLAGS_REG))]
10056 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10057 "bts{q}\t{%1, %0|%0, %1}"
10058 [(set_attr "type" "alu1")
10059 (set_attr "prefix_0f" "1")
10060 (set_attr "mode" "DI")])
10061
10062 (define_insn "*btrq"
10063 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10064 (const_int 1)
10065 (match_operand:DI 1 "const_0_to_63_operand"))
10066 (const_int 0))
10067 (clobber (reg:CC FLAGS_REG))]
10068 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10069 "btr{q}\t{%1, %0|%0, %1}"
10070 [(set_attr "type" "alu1")
10071 (set_attr "prefix_0f" "1")
10072 (set_attr "mode" "DI")])
10073
10074 (define_insn "*btcq"
10075 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10076 (const_int 1)
10077 (match_operand:DI 1 "const_0_to_63_operand"))
10078 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10079 (clobber (reg:CC FLAGS_REG))]
10080 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10081 "btc{q}\t{%1, %0|%0, %1}"
10082 [(set_attr "type" "alu1")
10083 (set_attr "prefix_0f" "1")
10084 (set_attr "mode" "DI")])
10085
10086 ;; Allow Nocona to avoid these instructions if a register is available.
10087
10088 (define_peephole2
10089 [(match_scratch:DI 2 "r")
10090 (parallel [(set (zero_extract:DI
10091 (match_operand:DI 0 "register_operand")
10092 (const_int 1)
10093 (match_operand:DI 1 "const_0_to_63_operand"))
10094 (const_int 1))
10095 (clobber (reg:CC FLAGS_REG))])]
10096 "TARGET_64BIT && !TARGET_USE_BT"
10097 [(const_int 0)]
10098 {
10099 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10100 rtx op1;
10101
10102 if (HOST_BITS_PER_WIDE_INT >= 64)
10103 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10104 else if (i < HOST_BITS_PER_WIDE_INT)
10105 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10106 else
10107 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10108
10109 op1 = immed_double_const (lo, hi, DImode);
10110 if (i >= 31)
10111 {
10112 emit_move_insn (operands[2], op1);
10113 op1 = operands[2];
10114 }
10115
10116 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10117 DONE;
10118 })
10119
10120 (define_peephole2
10121 [(match_scratch:DI 2 "r")
10122 (parallel [(set (zero_extract:DI
10123 (match_operand:DI 0 "register_operand")
10124 (const_int 1)
10125 (match_operand:DI 1 "const_0_to_63_operand"))
10126 (const_int 0))
10127 (clobber (reg:CC FLAGS_REG))])]
10128 "TARGET_64BIT && !TARGET_USE_BT"
10129 [(const_int 0)]
10130 {
10131 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10132 rtx op1;
10133
10134 if (HOST_BITS_PER_WIDE_INT >= 64)
10135 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10136 else if (i < HOST_BITS_PER_WIDE_INT)
10137 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10138 else
10139 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10140
10141 op1 = immed_double_const (~lo, ~hi, DImode);
10142 if (i >= 32)
10143 {
10144 emit_move_insn (operands[2], op1);
10145 op1 = operands[2];
10146 }
10147
10148 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10149 DONE;
10150 })
10151
10152 (define_peephole2
10153 [(match_scratch:DI 2 "r")
10154 (parallel [(set (zero_extract:DI
10155 (match_operand:DI 0 "register_operand")
10156 (const_int 1)
10157 (match_operand:DI 1 "const_0_to_63_operand"))
10158 (not:DI (zero_extract:DI
10159 (match_dup 0) (const_int 1) (match_dup 1))))
10160 (clobber (reg:CC FLAGS_REG))])]
10161 "TARGET_64BIT && !TARGET_USE_BT"
10162 [(const_int 0)]
10163 {
10164 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10165 rtx op1;
10166
10167 if (HOST_BITS_PER_WIDE_INT >= 64)
10168 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10169 else if (i < HOST_BITS_PER_WIDE_INT)
10170 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10171 else
10172 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10173
10174 op1 = immed_double_const (lo, hi, DImode);
10175 if (i >= 31)
10176 {
10177 emit_move_insn (operands[2], op1);
10178 op1 = operands[2];
10179 }
10180
10181 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10182 DONE;
10183 })
10184
10185 (define_insn "*bt<mode>"
10186 [(set (reg:CCC FLAGS_REG)
10187 (compare:CCC
10188 (zero_extract:SWI48
10189 (match_operand:SWI48 0 "register_operand" "r")
10190 (const_int 1)
10191 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10192 (const_int 0)))]
10193 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10194 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10195 [(set_attr "type" "alu1")
10196 (set_attr "prefix_0f" "1")
10197 (set_attr "mode" "<MODE>")])
10198 \f
10199 ;; Store-flag instructions.
10200
10201 ;; For all sCOND expanders, also expand the compare or test insn that
10202 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10203
10204 (define_insn_and_split "*setcc_di_1"
10205 [(set (match_operand:DI 0 "register_operand" "=q")
10206 (match_operator:DI 1 "ix86_comparison_operator"
10207 [(reg FLAGS_REG) (const_int 0)]))]
10208 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10209 "#"
10210 "&& reload_completed"
10211 [(set (match_dup 2) (match_dup 1))
10212 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10213 {
10214 PUT_MODE (operands[1], QImode);
10215 operands[2] = gen_lowpart (QImode, operands[0]);
10216 })
10217
10218 (define_insn_and_split "*setcc_si_1_and"
10219 [(set (match_operand:SI 0 "register_operand" "=q")
10220 (match_operator:SI 1 "ix86_comparison_operator"
10221 [(reg FLAGS_REG) (const_int 0)]))
10222 (clobber (reg:CC FLAGS_REG))]
10223 "!TARGET_PARTIAL_REG_STALL
10224 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10225 "#"
10226 "&& reload_completed"
10227 [(set (match_dup 2) (match_dup 1))
10228 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10229 (clobber (reg:CC FLAGS_REG))])]
10230 {
10231 PUT_MODE (operands[1], QImode);
10232 operands[2] = gen_lowpart (QImode, operands[0]);
10233 })
10234
10235 (define_insn_and_split "*setcc_si_1_movzbl"
10236 [(set (match_operand:SI 0 "register_operand" "=q")
10237 (match_operator:SI 1 "ix86_comparison_operator"
10238 [(reg FLAGS_REG) (const_int 0)]))]
10239 "!TARGET_PARTIAL_REG_STALL
10240 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10241 "#"
10242 "&& reload_completed"
10243 [(set (match_dup 2) (match_dup 1))
10244 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10245 {
10246 PUT_MODE (operands[1], QImode);
10247 operands[2] = gen_lowpart (QImode, operands[0]);
10248 })
10249
10250 (define_insn "*setcc_qi"
10251 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10252 (match_operator:QI 1 "ix86_comparison_operator"
10253 [(reg FLAGS_REG) (const_int 0)]))]
10254 ""
10255 "set%C1\t%0"
10256 [(set_attr "type" "setcc")
10257 (set_attr "mode" "QI")])
10258
10259 (define_insn "*setcc_qi_slp"
10260 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10261 (match_operator:QI 1 "ix86_comparison_operator"
10262 [(reg FLAGS_REG) (const_int 0)]))]
10263 ""
10264 "set%C1\t%0"
10265 [(set_attr "type" "setcc")
10266 (set_attr "mode" "QI")])
10267
10268 ;; In general it is not safe to assume too much about CCmode registers,
10269 ;; so simplify-rtx stops when it sees a second one. Under certain
10270 ;; conditions this is safe on x86, so help combine not create
10271 ;;
10272 ;; seta %al
10273 ;; testb %al, %al
10274 ;; sete %al
10275
10276 (define_split
10277 [(set (match_operand:QI 0 "nonimmediate_operand")
10278 (ne:QI (match_operator 1 "ix86_comparison_operator"
10279 [(reg FLAGS_REG) (const_int 0)])
10280 (const_int 0)))]
10281 ""
10282 [(set (match_dup 0) (match_dup 1))]
10283 "PUT_MODE (operands[1], QImode);")
10284
10285 (define_split
10286 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10287 (ne:QI (match_operator 1 "ix86_comparison_operator"
10288 [(reg FLAGS_REG) (const_int 0)])
10289 (const_int 0)))]
10290 ""
10291 [(set (match_dup 0) (match_dup 1))]
10292 "PUT_MODE (operands[1], QImode);")
10293
10294 (define_split
10295 [(set (match_operand:QI 0 "nonimmediate_operand")
10296 (eq:QI (match_operator 1 "ix86_comparison_operator"
10297 [(reg FLAGS_REG) (const_int 0)])
10298 (const_int 0)))]
10299 ""
10300 [(set (match_dup 0) (match_dup 1))]
10301 {
10302 rtx new_op1 = copy_rtx (operands[1]);
10303 operands[1] = new_op1;
10304 PUT_MODE (new_op1, QImode);
10305 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10306 GET_MODE (XEXP (new_op1, 0))));
10307
10308 /* Make sure that (a) the CCmode we have for the flags is strong
10309 enough for the reversed compare or (b) we have a valid FP compare. */
10310 if (! ix86_comparison_operator (new_op1, VOIDmode))
10311 FAIL;
10312 })
10313
10314 (define_split
10315 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10316 (eq:QI (match_operator 1 "ix86_comparison_operator"
10317 [(reg FLAGS_REG) (const_int 0)])
10318 (const_int 0)))]
10319 ""
10320 [(set (match_dup 0) (match_dup 1))]
10321 {
10322 rtx new_op1 = copy_rtx (operands[1]);
10323 operands[1] = new_op1;
10324 PUT_MODE (new_op1, QImode);
10325 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10326 GET_MODE (XEXP (new_op1, 0))));
10327
10328 /* Make sure that (a) the CCmode we have for the flags is strong
10329 enough for the reversed compare or (b) we have a valid FP compare. */
10330 if (! ix86_comparison_operator (new_op1, VOIDmode))
10331 FAIL;
10332 })
10333
10334 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10335 ;; subsequent logical operations are used to imitate conditional moves.
10336 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10337 ;; it directly.
10338
10339 (define_insn "setcc_<mode>_sse"
10340 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10341 (match_operator:MODEF 3 "sse_comparison_operator"
10342 [(match_operand:MODEF 1 "register_operand" "0,x")
10343 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10344 "SSE_FLOAT_MODE_P (<MODE>mode)"
10345 "@
10346 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10347 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10348 [(set_attr "isa" "noavx,avx")
10349 (set_attr "type" "ssecmp")
10350 (set_attr "length_immediate" "1")
10351 (set_attr "prefix" "orig,vex")
10352 (set_attr "mode" "<MODE>")])
10353 \f
10354 ;; Basic conditional jump instructions.
10355 ;; We ignore the overflow flag for signed branch instructions.
10356
10357 (define_insn "*jcc_1"
10358 [(set (pc)
10359 (if_then_else (match_operator 1 "ix86_comparison_operator"
10360 [(reg FLAGS_REG) (const_int 0)])
10361 (label_ref (match_operand 0))
10362 (pc)))]
10363 ""
10364 "%+j%C1\t%l0"
10365 [(set_attr "type" "ibr")
10366 (set_attr "modrm" "0")
10367 (set (attr "length")
10368 (if_then_else (and (ge (minus (match_dup 0) (pc))
10369 (const_int -126))
10370 (lt (minus (match_dup 0) (pc))
10371 (const_int 128)))
10372 (const_int 2)
10373 (const_int 6)))])
10374
10375 (define_insn "*jcc_2"
10376 [(set (pc)
10377 (if_then_else (match_operator 1 "ix86_comparison_operator"
10378 [(reg FLAGS_REG) (const_int 0)])
10379 (pc)
10380 (label_ref (match_operand 0))))]
10381 ""
10382 "%+j%c1\t%l0"
10383 [(set_attr "type" "ibr")
10384 (set_attr "modrm" "0")
10385 (set (attr "length")
10386 (if_then_else (and (ge (minus (match_dup 0) (pc))
10387 (const_int -126))
10388 (lt (minus (match_dup 0) (pc))
10389 (const_int 128)))
10390 (const_int 2)
10391 (const_int 6)))])
10392
10393 ;; In general it is not safe to assume too much about CCmode registers,
10394 ;; so simplify-rtx stops when it sees a second one. Under certain
10395 ;; conditions this is safe on x86, so help combine not create
10396 ;;
10397 ;; seta %al
10398 ;; testb %al, %al
10399 ;; je Lfoo
10400
10401 (define_split
10402 [(set (pc)
10403 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10404 [(reg FLAGS_REG) (const_int 0)])
10405 (const_int 0))
10406 (label_ref (match_operand 1))
10407 (pc)))]
10408 ""
10409 [(set (pc)
10410 (if_then_else (match_dup 0)
10411 (label_ref (match_dup 1))
10412 (pc)))]
10413 "PUT_MODE (operands[0], VOIDmode);")
10414
10415 (define_split
10416 [(set (pc)
10417 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10418 [(reg FLAGS_REG) (const_int 0)])
10419 (const_int 0))
10420 (label_ref (match_operand 1))
10421 (pc)))]
10422 ""
10423 [(set (pc)
10424 (if_then_else (match_dup 0)
10425 (label_ref (match_dup 1))
10426 (pc)))]
10427 {
10428 rtx new_op0 = copy_rtx (operands[0]);
10429 operands[0] = new_op0;
10430 PUT_MODE (new_op0, VOIDmode);
10431 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10432 GET_MODE (XEXP (new_op0, 0))));
10433
10434 /* Make sure that (a) the CCmode we have for the flags is strong
10435 enough for the reversed compare or (b) we have a valid FP compare. */
10436 if (! ix86_comparison_operator (new_op0, VOIDmode))
10437 FAIL;
10438 })
10439
10440 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10441 ;; pass generates from shift insn with QImode operand. Actually, the mode
10442 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10443 ;; appropriate modulo of the bit offset value.
10444
10445 (define_insn_and_split "*jcc_bt<mode>"
10446 [(set (pc)
10447 (if_then_else (match_operator 0 "bt_comparison_operator"
10448 [(zero_extract:SWI48
10449 (match_operand:SWI48 1 "register_operand" "r")
10450 (const_int 1)
10451 (zero_extend:SI
10452 (match_operand:QI 2 "register_operand" "r")))
10453 (const_int 0)])
10454 (label_ref (match_operand 3))
10455 (pc)))
10456 (clobber (reg:CC FLAGS_REG))]
10457 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10458 "#"
10459 "&& 1"
10460 [(set (reg:CCC FLAGS_REG)
10461 (compare:CCC
10462 (zero_extract:SWI48
10463 (match_dup 1)
10464 (const_int 1)
10465 (match_dup 2))
10466 (const_int 0)))
10467 (set (pc)
10468 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10469 (label_ref (match_dup 3))
10470 (pc)))]
10471 {
10472 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10473
10474 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10475 })
10476
10477 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10478 ;; also for DImode, this is what combine produces.
10479 (define_insn_and_split "*jcc_bt<mode>_mask"
10480 [(set (pc)
10481 (if_then_else (match_operator 0 "bt_comparison_operator"
10482 [(zero_extract:SWI48
10483 (match_operand:SWI48 1 "register_operand" "r")
10484 (const_int 1)
10485 (and:SI
10486 (match_operand:SI 2 "register_operand" "r")
10487 (match_operand:SI 3 "const_int_operand" "n")))])
10488 (label_ref (match_operand 4))
10489 (pc)))
10490 (clobber (reg:CC FLAGS_REG))]
10491 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10492 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10493 == GET_MODE_BITSIZE (<MODE>mode)-1"
10494 "#"
10495 "&& 1"
10496 [(set (reg:CCC FLAGS_REG)
10497 (compare:CCC
10498 (zero_extract:SWI48
10499 (match_dup 1)
10500 (const_int 1)
10501 (match_dup 2))
10502 (const_int 0)))
10503 (set (pc)
10504 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10505 (label_ref (match_dup 4))
10506 (pc)))]
10507 {
10508 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10509
10510 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10511 })
10512
10513 (define_insn_and_split "*jcc_btsi_1"
10514 [(set (pc)
10515 (if_then_else (match_operator 0 "bt_comparison_operator"
10516 [(and:SI
10517 (lshiftrt:SI
10518 (match_operand:SI 1 "register_operand" "r")
10519 (match_operand:QI 2 "register_operand" "r"))
10520 (const_int 1))
10521 (const_int 0)])
10522 (label_ref (match_operand 3))
10523 (pc)))
10524 (clobber (reg:CC FLAGS_REG))]
10525 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10526 "#"
10527 "&& 1"
10528 [(set (reg:CCC FLAGS_REG)
10529 (compare:CCC
10530 (zero_extract:SI
10531 (match_dup 1)
10532 (const_int 1)
10533 (match_dup 2))
10534 (const_int 0)))
10535 (set (pc)
10536 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10537 (label_ref (match_dup 3))
10538 (pc)))]
10539 {
10540 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10541
10542 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10543 })
10544
10545 ;; avoid useless masking of bit offset operand
10546 (define_insn_and_split "*jcc_btsi_mask_1"
10547 [(set (pc)
10548 (if_then_else
10549 (match_operator 0 "bt_comparison_operator"
10550 [(and:SI
10551 (lshiftrt:SI
10552 (match_operand:SI 1 "register_operand" "r")
10553 (subreg:QI
10554 (and:SI
10555 (match_operand:SI 2 "register_operand" "r")
10556 (match_operand:SI 3 "const_int_operand" "n")) 0))
10557 (const_int 1))
10558 (const_int 0)])
10559 (label_ref (match_operand 4))
10560 (pc)))
10561 (clobber (reg:CC FLAGS_REG))]
10562 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10563 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10564 "#"
10565 "&& 1"
10566 [(set (reg:CCC FLAGS_REG)
10567 (compare:CCC
10568 (zero_extract:SI
10569 (match_dup 1)
10570 (const_int 1)
10571 (match_dup 2))
10572 (const_int 0)))
10573 (set (pc)
10574 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10575 (label_ref (match_dup 4))
10576 (pc)))]
10577 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10578
10579 ;; Define combination compare-and-branch fp compare instructions to help
10580 ;; combine.
10581
10582 (define_insn "*jcc<mode>_0_i387"
10583 [(set (pc)
10584 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10585 [(match_operand:X87MODEF 1 "register_operand" "f")
10586 (match_operand:X87MODEF 2 "const0_operand")])
10587 (label_ref (match_operand 3))
10588 (pc)))
10589 (clobber (reg:CCFP FPSR_REG))
10590 (clobber (reg:CCFP FLAGS_REG))
10591 (clobber (match_scratch:HI 4 "=a"))]
10592 "TARGET_80387 && !TARGET_CMOVE"
10593 "#")
10594
10595 (define_insn "*jcc<mode>_0_r_i387"
10596 [(set (pc)
10597 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10598 [(match_operand:X87MODEF 1 "register_operand" "f")
10599 (match_operand:X87MODEF 2 "const0_operand")])
10600 (pc)
10601 (label_ref (match_operand 3))))
10602 (clobber (reg:CCFP FPSR_REG))
10603 (clobber (reg:CCFP FLAGS_REG))
10604 (clobber (match_scratch:HI 4 "=a"))]
10605 "TARGET_80387 && !TARGET_CMOVE"
10606 "#")
10607
10608 (define_insn "*jccxf_i387"
10609 [(set (pc)
10610 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10611 [(match_operand:XF 1 "register_operand" "f")
10612 (match_operand:XF 2 "register_operand" "f")])
10613 (label_ref (match_operand 3))
10614 (pc)))
10615 (clobber (reg:CCFP FPSR_REG))
10616 (clobber (reg:CCFP FLAGS_REG))
10617 (clobber (match_scratch:HI 4 "=a"))]
10618 "TARGET_80387 && !TARGET_CMOVE"
10619 "#")
10620
10621 (define_insn "*jccxf_r_i387"
10622 [(set (pc)
10623 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10624 [(match_operand:XF 1 "register_operand" "f")
10625 (match_operand:XF 2 "register_operand" "f")])
10626 (pc)
10627 (label_ref (match_operand 3))))
10628 (clobber (reg:CCFP FPSR_REG))
10629 (clobber (reg:CCFP FLAGS_REG))
10630 (clobber (match_scratch:HI 4 "=a"))]
10631 "TARGET_80387 && !TARGET_CMOVE"
10632 "#")
10633
10634 (define_insn "*jcc<mode>_i387"
10635 [(set (pc)
10636 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10637 [(match_operand:MODEF 1 "register_operand" "f")
10638 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10639 (label_ref (match_operand 3))
10640 (pc)))
10641 (clobber (reg:CCFP FPSR_REG))
10642 (clobber (reg:CCFP FLAGS_REG))
10643 (clobber (match_scratch:HI 4 "=a"))]
10644 "TARGET_80387 && !TARGET_CMOVE"
10645 "#")
10646
10647 (define_insn "*jcc<mode>_r_i387"
10648 [(set (pc)
10649 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10650 [(match_operand:MODEF 1 "register_operand" "f")
10651 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10652 (pc)
10653 (label_ref (match_operand 3))))
10654 (clobber (reg:CCFP FPSR_REG))
10655 (clobber (reg:CCFP FLAGS_REG))
10656 (clobber (match_scratch:HI 4 "=a"))]
10657 "TARGET_80387 && !TARGET_CMOVE"
10658 "#")
10659
10660 (define_insn "*jccu<mode>_i387"
10661 [(set (pc)
10662 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10663 [(match_operand:X87MODEF 1 "register_operand" "f")
10664 (match_operand:X87MODEF 2 "register_operand" "f")])
10665 (label_ref (match_operand 3))
10666 (pc)))
10667 (clobber (reg:CCFP FPSR_REG))
10668 (clobber (reg:CCFP FLAGS_REG))
10669 (clobber (match_scratch:HI 4 "=a"))]
10670 "TARGET_80387 && !TARGET_CMOVE"
10671 "#")
10672
10673 (define_insn "*jccu<mode>_r_i387"
10674 [(set (pc)
10675 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10676 [(match_operand:X87MODEF 1 "register_operand" "f")
10677 (match_operand:X87MODEF 2 "register_operand" "f")])
10678 (pc)
10679 (label_ref (match_operand 3))))
10680 (clobber (reg:CCFP FPSR_REG))
10681 (clobber (reg:CCFP FLAGS_REG))
10682 (clobber (match_scratch:HI 4 "=a"))]
10683 "TARGET_80387 && !TARGET_CMOVE"
10684 "#")
10685
10686 (define_split
10687 [(set (pc)
10688 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10689 [(match_operand:X87MODEF 1 "register_operand")
10690 (match_operand:X87MODEF 2 "nonimmediate_operand")])
10691 (match_operand 3)
10692 (match_operand 4)))
10693 (clobber (reg:CCFP FPSR_REG))
10694 (clobber (reg:CCFP FLAGS_REG))]
10695 "TARGET_80387 && !TARGET_CMOVE
10696 && reload_completed"
10697 [(const_int 0)]
10698 {
10699 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10700 operands[3], operands[4], NULL_RTX, NULL_RTX);
10701 DONE;
10702 })
10703
10704 (define_split
10705 [(set (pc)
10706 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10707 [(match_operand:X87MODEF 1 "register_operand")
10708 (match_operand:X87MODEF 2 "general_operand")])
10709 (match_operand 3)
10710 (match_operand 4)))
10711 (clobber (reg:CCFP FPSR_REG))
10712 (clobber (reg:CCFP FLAGS_REG))
10713 (clobber (match_scratch:HI 5))]
10714 "TARGET_80387 && !TARGET_CMOVE
10715 && reload_completed"
10716 [(const_int 0)]
10717 {
10718 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10719 operands[3], operands[4], operands[5], NULL_RTX);
10720 DONE;
10721 })
10722
10723 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
10724 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10725 ;; with a precedence over other operators and is always put in the first
10726 ;; place. Swap condition and operands to match ficom instruction.
10727
10728 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
10729 [(set (pc)
10730 (if_then_else
10731 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10732 [(match_operator:X87MODEF 1 "float_operator"
10733 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10734 (match_operand:X87MODEF 3 "register_operand" "f,f")])
10735 (label_ref (match_operand 4))
10736 (pc)))
10737 (clobber (reg:CCFP FPSR_REG))
10738 (clobber (reg:CCFP FLAGS_REG))
10739 (clobber (match_scratch:HI 5 "=a,a"))]
10740 "TARGET_80387 && !TARGET_CMOVE
10741 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10742 || optimize_function_for_size_p (cfun))"
10743 "#")
10744
10745 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
10746 [(set (pc)
10747 (if_then_else
10748 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10749 [(match_operator:X87MODEF 1 "float_operator"
10750 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10751 (match_operand:X87MODEF 3 "register_operand" "f,f")])
10752 (pc)
10753 (label_ref (match_operand 4))))
10754 (clobber (reg:CCFP FPSR_REG))
10755 (clobber (reg:CCFP FLAGS_REG))
10756 (clobber (match_scratch:HI 5 "=a,a"))]
10757 "TARGET_80387 && !TARGET_CMOVE
10758 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10759 || optimize_function_for_size_p (cfun))"
10760 "#")
10761
10762 (define_split
10763 [(set (pc)
10764 (if_then_else
10765 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10766 [(match_operator:X87MODEF 1 "float_operator"
10767 [(match_operand:SWI24 2 "memory_operand")])
10768 (match_operand:X87MODEF 3 "register_operand")])
10769 (match_operand 4)
10770 (match_operand 5)))
10771 (clobber (reg:CCFP FPSR_REG))
10772 (clobber (reg:CCFP FLAGS_REG))
10773 (clobber (match_scratch:HI 6))]
10774 "TARGET_80387 && !TARGET_CMOVE
10775 && reload_completed"
10776 [(const_int 0)]
10777 {
10778 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10779 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
10780 operands[4], operands[5], operands[6], NULL_RTX);
10781 DONE;
10782 })
10783
10784 ;; %%% Kill this when reload knows how to do it.
10785 (define_split
10786 [(set (pc)
10787 (if_then_else
10788 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10789 [(match_operator:X87MODEF 1 "float_operator"
10790 [(match_operand:SWI24 2 "register_operand")])
10791 (match_operand:X87MODEF 3 "register_operand")])
10792 (match_operand 4)
10793 (match_operand 5)))
10794 (clobber (reg:CCFP FPSR_REG))
10795 (clobber (reg:CCFP FLAGS_REG))
10796 (clobber (match_scratch:HI 6))]
10797 "TARGET_80387 && !TARGET_CMOVE
10798 && reload_completed"
10799 [(const_int 0)]
10800 {
10801 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10802
10803 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10804 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
10805 operands[4], operands[5], operands[6], operands[2]);
10806 DONE;
10807 })
10808 \f
10809 ;; Unconditional and other jump instructions
10810
10811 (define_insn "jump"
10812 [(set (pc)
10813 (label_ref (match_operand 0)))]
10814 ""
10815 "jmp\t%l0"
10816 [(set_attr "type" "ibr")
10817 (set (attr "length")
10818 (if_then_else (and (ge (minus (match_dup 0) (pc))
10819 (const_int -126))
10820 (lt (minus (match_dup 0) (pc))
10821 (const_int 128)))
10822 (const_int 2)
10823 (const_int 5)))
10824 (set_attr "modrm" "0")])
10825
10826 (define_expand "indirect_jump"
10827 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
10828 ""
10829 {
10830 if (TARGET_X32)
10831 operands[0] = convert_memory_address (word_mode, operands[0]);
10832 })
10833
10834 (define_insn "*indirect_jump"
10835 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
10836 ""
10837 "jmp\t%A0"
10838 [(set_attr "type" "ibr")
10839 (set_attr "length_immediate" "0")])
10840
10841 (define_expand "tablejump"
10842 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
10843 (use (label_ref (match_operand 1)))])]
10844 ""
10845 {
10846 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10847 relative. Convert the relative address to an absolute address. */
10848 if (flag_pic)
10849 {
10850 rtx op0, op1;
10851 enum rtx_code code;
10852
10853 /* We can't use @GOTOFF for text labels on VxWorks;
10854 see gotoff_operand. */
10855 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10856 {
10857 code = PLUS;
10858 op0 = operands[0];
10859 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10860 }
10861 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10862 {
10863 code = PLUS;
10864 op0 = operands[0];
10865 op1 = pic_offset_table_rtx;
10866 }
10867 else
10868 {
10869 code = MINUS;
10870 op0 = pic_offset_table_rtx;
10871 op1 = operands[0];
10872 }
10873
10874 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10875 OPTAB_DIRECT);
10876 }
10877
10878 if (TARGET_X32)
10879 operands[0] = convert_memory_address (word_mode, operands[0]);
10880 })
10881
10882 (define_insn "*tablejump_1"
10883 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
10884 (use (label_ref (match_operand 1)))]
10885 ""
10886 "jmp\t%A0"
10887 [(set_attr "type" "ibr")
10888 (set_attr "length_immediate" "0")])
10889 \f
10890 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10891
10892 (define_peephole2
10893 [(set (reg FLAGS_REG) (match_operand 0))
10894 (set (match_operand:QI 1 "register_operand")
10895 (match_operator:QI 2 "ix86_comparison_operator"
10896 [(reg FLAGS_REG) (const_int 0)]))
10897 (set (match_operand 3 "q_regs_operand")
10898 (zero_extend (match_dup 1)))]
10899 "(peep2_reg_dead_p (3, operands[1])
10900 || operands_match_p (operands[1], operands[3]))
10901 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10902 [(set (match_dup 4) (match_dup 0))
10903 (set (strict_low_part (match_dup 5))
10904 (match_dup 2))]
10905 {
10906 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10907 operands[5] = gen_lowpart (QImode, operands[3]);
10908 ix86_expand_clear (operands[3]);
10909 })
10910
10911 (define_peephole2
10912 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
10913 (match_operand 4)])
10914 (set (match_operand:QI 1 "register_operand")
10915 (match_operator:QI 2 "ix86_comparison_operator"
10916 [(reg FLAGS_REG) (const_int 0)]))
10917 (set (match_operand 3 "q_regs_operand")
10918 (zero_extend (match_dup 1)))]
10919 "(peep2_reg_dead_p (3, operands[1])
10920 || operands_match_p (operands[1], operands[3]))
10921 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10922 [(parallel [(set (match_dup 5) (match_dup 0))
10923 (match_dup 4)])
10924 (set (strict_low_part (match_dup 6))
10925 (match_dup 2))]
10926 {
10927 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10928 operands[6] = gen_lowpart (QImode, operands[3]);
10929 ix86_expand_clear (operands[3]);
10930 })
10931
10932 ;; Similar, but match zero extend with andsi3.
10933
10934 (define_peephole2
10935 [(set (reg FLAGS_REG) (match_operand 0))
10936 (set (match_operand:QI 1 "register_operand")
10937 (match_operator:QI 2 "ix86_comparison_operator"
10938 [(reg FLAGS_REG) (const_int 0)]))
10939 (parallel [(set (match_operand:SI 3 "q_regs_operand")
10940 (and:SI (match_dup 3) (const_int 255)))
10941 (clobber (reg:CC FLAGS_REG))])]
10942 "REGNO (operands[1]) == REGNO (operands[3])
10943 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10944 [(set (match_dup 4) (match_dup 0))
10945 (set (strict_low_part (match_dup 5))
10946 (match_dup 2))]
10947 {
10948 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10949 operands[5] = gen_lowpart (QImode, operands[3]);
10950 ix86_expand_clear (operands[3]);
10951 })
10952
10953 (define_peephole2
10954 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
10955 (match_operand 4)])
10956 (set (match_operand:QI 1 "register_operand")
10957 (match_operator:QI 2 "ix86_comparison_operator"
10958 [(reg FLAGS_REG) (const_int 0)]))
10959 (parallel [(set (match_operand 3 "q_regs_operand")
10960 (zero_extend (match_dup 1)))
10961 (clobber (reg:CC FLAGS_REG))])]
10962 "(peep2_reg_dead_p (3, operands[1])
10963 || operands_match_p (operands[1], operands[3]))
10964 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10965 [(parallel [(set (match_dup 5) (match_dup 0))
10966 (match_dup 4)])
10967 (set (strict_low_part (match_dup 6))
10968 (match_dup 2))]
10969 {
10970 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10971 operands[6] = gen_lowpart (QImode, operands[3]);
10972 ix86_expand_clear (operands[3]);
10973 })
10974 \f
10975 ;; Call instructions.
10976
10977 ;; The predicates normally associated with named expanders are not properly
10978 ;; checked for calls. This is a bug in the generic code, but it isn't that
10979 ;; easy to fix. Ignore it for now and be prepared to fix things up.
10980
10981 ;; P6 processors will jump to the address after the decrement when %esp
10982 ;; is used as a call operand, so they will execute return address as a code.
10983 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
10984
10985 ;; Register constraint for call instruction.
10986 (define_mode_attr c [(SI "l") (DI "r")])
10987
10988 ;; Call subroutine returning no value.
10989
10990 (define_expand "call"
10991 [(call (match_operand:QI 0)
10992 (match_operand 1))
10993 (use (match_operand 2))]
10994 ""
10995 {
10996 ix86_expand_call (NULL, operands[0], operands[1],
10997 operands[2], NULL, false);
10998 DONE;
10999 })
11000
11001 (define_expand "sibcall"
11002 [(call (match_operand:QI 0)
11003 (match_operand 1))
11004 (use (match_operand 2))]
11005 ""
11006 {
11007 ix86_expand_call (NULL, operands[0], operands[1],
11008 operands[2], NULL, true);
11009 DONE;
11010 })
11011
11012 (define_insn "*call"
11013 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11014 (match_operand 1))]
11015 "!SIBLING_CALL_P (insn)"
11016 "* return ix86_output_call_insn (insn, operands[0]);"
11017 [(set_attr "type" "call")])
11018
11019 (define_insn "*call_rex64_ms_sysv"
11020 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11021 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11022 (match_operand 1))
11023 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11024 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11025 "* return ix86_output_call_insn (insn, operands[0]);"
11026 [(set_attr "type" "call")])
11027
11028 (define_insn "*sibcall"
11029 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11030 (match_operand 1))]
11031 "SIBLING_CALL_P (insn)"
11032 "* return ix86_output_call_insn (insn, operands[0]);"
11033 [(set_attr "type" "call")])
11034
11035 (define_expand "call_pop"
11036 [(parallel [(call (match_operand:QI 0)
11037 (match_operand:SI 1))
11038 (set (reg:SI SP_REG)
11039 (plus:SI (reg:SI SP_REG)
11040 (match_operand:SI 3)))])]
11041 "!TARGET_64BIT"
11042 {
11043 ix86_expand_call (NULL, operands[0], operands[1],
11044 operands[2], operands[3], false);
11045 DONE;
11046 })
11047
11048 (define_insn "*call_pop"
11049 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11050 (match_operand 1))
11051 (set (reg:SI SP_REG)
11052 (plus:SI (reg:SI SP_REG)
11053 (match_operand:SI 2 "immediate_operand" "i")))]
11054 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11055 "* return ix86_output_call_insn (insn, operands[0]);"
11056 [(set_attr "type" "call")])
11057
11058 (define_insn "*sibcall_pop"
11059 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11060 (match_operand 1))
11061 (set (reg:SI SP_REG)
11062 (plus:SI (reg:SI SP_REG)
11063 (match_operand:SI 2 "immediate_operand" "i")))]
11064 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11065 "* return ix86_output_call_insn (insn, operands[0]);"
11066 [(set_attr "type" "call")])
11067
11068 ;; Call subroutine, returning value in operand 0
11069
11070 (define_expand "call_value"
11071 [(set (match_operand 0)
11072 (call (match_operand:QI 1)
11073 (match_operand 2)))
11074 (use (match_operand 3))]
11075 ""
11076 {
11077 ix86_expand_call (operands[0], operands[1], operands[2],
11078 operands[3], NULL, false);
11079 DONE;
11080 })
11081
11082 (define_expand "sibcall_value"
11083 [(set (match_operand 0)
11084 (call (match_operand:QI 1)
11085 (match_operand 2)))
11086 (use (match_operand 3))]
11087 ""
11088 {
11089 ix86_expand_call (operands[0], operands[1], operands[2],
11090 operands[3], NULL, true);
11091 DONE;
11092 })
11093
11094 (define_insn "*call_value"
11095 [(set (match_operand 0)
11096 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11097 (match_operand 2)))]
11098 "!SIBLING_CALL_P (insn)"
11099 "* return ix86_output_call_insn (insn, operands[1]);"
11100 [(set_attr "type" "callv")])
11101
11102 (define_insn "*sibcall_value"
11103 [(set (match_operand 0)
11104 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11105 (match_operand 2)))]
11106 "SIBLING_CALL_P (insn)"
11107 "* return ix86_output_call_insn (insn, operands[1]);"
11108 [(set_attr "type" "callv")])
11109
11110 (define_insn "*call_value_rex64_ms_sysv"
11111 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11112 [(set (match_operand 0)
11113 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11114 (match_operand 2)))
11115 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11116 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11117 "* return ix86_output_call_insn (insn, operands[1]);"
11118 [(set_attr "type" "callv")])
11119
11120 (define_expand "call_value_pop"
11121 [(parallel [(set (match_operand 0)
11122 (call (match_operand:QI 1)
11123 (match_operand:SI 2)))
11124 (set (reg:SI SP_REG)
11125 (plus:SI (reg:SI SP_REG)
11126 (match_operand:SI 4)))])]
11127 "!TARGET_64BIT"
11128 {
11129 ix86_expand_call (operands[0], operands[1], operands[2],
11130 operands[3], operands[4], false);
11131 DONE;
11132 })
11133
11134 (define_insn "*call_value_pop"
11135 [(set (match_operand 0)
11136 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11137 (match_operand 2)))
11138 (set (reg:SI SP_REG)
11139 (plus:SI (reg:SI SP_REG)
11140 (match_operand:SI 3 "immediate_operand" "i")))]
11141 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11142 "* return ix86_output_call_insn (insn, operands[1]);"
11143 [(set_attr "type" "callv")])
11144
11145 (define_insn "*sibcall_value_pop"
11146 [(set (match_operand 0)
11147 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11148 (match_operand 2)))
11149 (set (reg:SI SP_REG)
11150 (plus:SI (reg:SI SP_REG)
11151 (match_operand:SI 3 "immediate_operand" "i")))]
11152 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11153 "* return ix86_output_call_insn (insn, operands[1]);"
11154 [(set_attr "type" "callv")])
11155
11156 ;; Call subroutine returning any type.
11157
11158 (define_expand "untyped_call"
11159 [(parallel [(call (match_operand 0)
11160 (const_int 0))
11161 (match_operand 1)
11162 (match_operand 2)])]
11163 ""
11164 {
11165 int i;
11166
11167 /* In order to give reg-stack an easier job in validating two
11168 coprocessor registers as containing a possible return value,
11169 simply pretend the untyped call returns a complex long double
11170 value.
11171
11172 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11173 and should have the default ABI. */
11174
11175 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11176 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11177 operands[0], const0_rtx,
11178 GEN_INT ((TARGET_64BIT
11179 ? (ix86_abi == SYSV_ABI
11180 ? X86_64_SSE_REGPARM_MAX
11181 : X86_64_MS_SSE_REGPARM_MAX)
11182 : X86_32_SSE_REGPARM_MAX)
11183 - 1),
11184 NULL, false);
11185
11186 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11187 {
11188 rtx set = XVECEXP (operands[2], 0, i);
11189 emit_move_insn (SET_DEST (set), SET_SRC (set));
11190 }
11191
11192 /* The optimizer does not know that the call sets the function value
11193 registers we stored in the result block. We avoid problems by
11194 claiming that all hard registers are used and clobbered at this
11195 point. */
11196 emit_insn (gen_blockage ());
11197
11198 DONE;
11199 })
11200 \f
11201 ;; Prologue and epilogue instructions
11202
11203 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11204 ;; all of memory. This blocks insns from being moved across this point.
11205
11206 (define_insn "blockage"
11207 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11208 ""
11209 ""
11210 [(set_attr "length" "0")])
11211
11212 ;; Do not schedule instructions accessing memory across this point.
11213
11214 (define_expand "memory_blockage"
11215 [(set (match_dup 0)
11216 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11217 ""
11218 {
11219 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11220 MEM_VOLATILE_P (operands[0]) = 1;
11221 })
11222
11223 (define_insn "*memory_blockage"
11224 [(set (match_operand:BLK 0)
11225 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11226 ""
11227 ""
11228 [(set_attr "length" "0")])
11229
11230 ;; As USE insns aren't meaningful after reload, this is used instead
11231 ;; to prevent deleting instructions setting registers for PIC code
11232 (define_insn "prologue_use"
11233 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11234 ""
11235 ""
11236 [(set_attr "length" "0")])
11237
11238 ;; Insn emitted into the body of a function to return from a function.
11239 ;; This is only done if the function's epilogue is known to be simple.
11240 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11241
11242 (define_expand "return"
11243 [(simple_return)]
11244 "ix86_can_use_return_insn_p ()"
11245 {
11246 if (crtl->args.pops_args)
11247 {
11248 rtx popc = GEN_INT (crtl->args.pops_args);
11249 emit_jump_insn (gen_simple_return_pop_internal (popc));
11250 DONE;
11251 }
11252 })
11253
11254 ;; We need to disable this for TARGET_SEH, as otherwise
11255 ;; shrink-wrapped prologue gets enabled too. This might exceed
11256 ;; the maximum size of prologue in unwind information.
11257
11258 (define_expand "simple_return"
11259 [(simple_return)]
11260 "!TARGET_SEH"
11261 {
11262 if (crtl->args.pops_args)
11263 {
11264 rtx popc = GEN_INT (crtl->args.pops_args);
11265 emit_jump_insn (gen_simple_return_pop_internal (popc));
11266 DONE;
11267 }
11268 })
11269
11270 (define_insn "simple_return_internal"
11271 [(simple_return)]
11272 "reload_completed"
11273 "ret"
11274 [(set_attr "length" "1")
11275 (set_attr "atom_unit" "jeu")
11276 (set_attr "length_immediate" "0")
11277 (set_attr "modrm" "0")])
11278
11279 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11280 ;; instruction Athlon and K8 have.
11281
11282 (define_insn "simple_return_internal_long"
11283 [(simple_return)
11284 (unspec [(const_int 0)] UNSPEC_REP)]
11285 "reload_completed"
11286 "rep%; ret"
11287 [(set_attr "length" "2")
11288 (set_attr "atom_unit" "jeu")
11289 (set_attr "length_immediate" "0")
11290 (set_attr "prefix_rep" "1")
11291 (set_attr "modrm" "0")])
11292
11293 (define_insn "simple_return_pop_internal"
11294 [(simple_return)
11295 (use (match_operand:SI 0 "const_int_operand"))]
11296 "reload_completed"
11297 "ret\t%0"
11298 [(set_attr "length" "3")
11299 (set_attr "atom_unit" "jeu")
11300 (set_attr "length_immediate" "2")
11301 (set_attr "modrm" "0")])
11302
11303 (define_insn "simple_return_indirect_internal"
11304 [(simple_return)
11305 (use (match_operand:SI 0 "register_operand" "r"))]
11306 "reload_completed"
11307 "jmp\t%A0"
11308 [(set_attr "type" "ibr")
11309 (set_attr "length_immediate" "0")])
11310
11311 (define_insn "nop"
11312 [(const_int 0)]
11313 ""
11314 "nop"
11315 [(set_attr "length" "1")
11316 (set_attr "length_immediate" "0")
11317 (set_attr "modrm" "0")])
11318
11319 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11320 (define_insn "nops"
11321 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11322 UNSPECV_NOPS)]
11323 "reload_completed"
11324 {
11325 int num = INTVAL (operands[0]);
11326
11327 gcc_assert (IN_RANGE (num, 1, 8));
11328
11329 while (num--)
11330 fputs ("\tnop\n", asm_out_file);
11331
11332 return "";
11333 }
11334 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11335 (set_attr "length_immediate" "0")
11336 (set_attr "modrm" "0")])
11337
11338 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11339 ;; branch prediction penalty for the third jump in a 16-byte
11340 ;; block on K8.
11341
11342 (define_insn "pad"
11343 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11344 ""
11345 {
11346 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11347 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11348 #else
11349 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11350 The align insn is used to avoid 3 jump instructions in the row to improve
11351 branch prediction and the benefits hardly outweigh the cost of extra 8
11352 nops on the average inserted by full alignment pseudo operation. */
11353 #endif
11354 return "";
11355 }
11356 [(set_attr "length" "16")])
11357
11358 (define_expand "prologue"
11359 [(const_int 0)]
11360 ""
11361 "ix86_expand_prologue (); DONE;")
11362
11363 (define_insn "set_got"
11364 [(set (match_operand:SI 0 "register_operand" "=r")
11365 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11366 (clobber (reg:CC FLAGS_REG))]
11367 "!TARGET_64BIT"
11368 "* return output_set_got (operands[0], NULL_RTX);"
11369 [(set_attr "type" "multi")
11370 (set_attr "length" "12")])
11371
11372 (define_insn "set_got_labelled"
11373 [(set (match_operand:SI 0 "register_operand" "=r")
11374 (unspec:SI [(label_ref (match_operand 1))]
11375 UNSPEC_SET_GOT))
11376 (clobber (reg:CC FLAGS_REG))]
11377 "!TARGET_64BIT"
11378 "* return output_set_got (operands[0], operands[1]);"
11379 [(set_attr "type" "multi")
11380 (set_attr "length" "12")])
11381
11382 (define_insn "set_got_rex64"
11383 [(set (match_operand:DI 0 "register_operand" "=r")
11384 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11385 "TARGET_64BIT"
11386 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11387 [(set_attr "type" "lea")
11388 (set_attr "length_address" "4")
11389 (set_attr "mode" "DI")])
11390
11391 (define_insn "set_rip_rex64"
11392 [(set (match_operand:DI 0 "register_operand" "=r")
11393 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11394 "TARGET_64BIT"
11395 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11396 [(set_attr "type" "lea")
11397 (set_attr "length_address" "4")
11398 (set_attr "mode" "DI")])
11399
11400 (define_insn "set_got_offset_rex64"
11401 [(set (match_operand:DI 0 "register_operand" "=r")
11402 (unspec:DI
11403 [(label_ref (match_operand 1))]
11404 UNSPEC_SET_GOT_OFFSET))]
11405 "TARGET_LP64"
11406 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11407 [(set_attr "type" "imov")
11408 (set_attr "length_immediate" "0")
11409 (set_attr "length_address" "8")
11410 (set_attr "mode" "DI")])
11411
11412 (define_expand "epilogue"
11413 [(const_int 0)]
11414 ""
11415 "ix86_expand_epilogue (1); DONE;")
11416
11417 (define_expand "sibcall_epilogue"
11418 [(const_int 0)]
11419 ""
11420 "ix86_expand_epilogue (0); DONE;")
11421
11422 (define_expand "eh_return"
11423 [(use (match_operand 0 "register_operand"))]
11424 ""
11425 {
11426 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11427
11428 /* Tricky bit: we write the address of the handler to which we will
11429 be returning into someone else's stack frame, one word below the
11430 stack address we wish to restore. */
11431 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11432 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11433 tmp = gen_rtx_MEM (Pmode, tmp);
11434 emit_move_insn (tmp, ra);
11435
11436 emit_jump_insn (gen_eh_return_internal ());
11437 emit_barrier ();
11438 DONE;
11439 })
11440
11441 (define_insn_and_split "eh_return_internal"
11442 [(eh_return)]
11443 ""
11444 "#"
11445 "epilogue_completed"
11446 [(const_int 0)]
11447 "ix86_expand_epilogue (2); DONE;")
11448
11449 (define_insn "leave"
11450 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11451 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11452 (clobber (mem:BLK (scratch)))]
11453 "!TARGET_64BIT"
11454 "leave"
11455 [(set_attr "type" "leave")])
11456
11457 (define_insn "leave_rex64"
11458 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11459 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11460 (clobber (mem:BLK (scratch)))]
11461 "TARGET_64BIT"
11462 "leave"
11463 [(set_attr "type" "leave")])
11464 \f
11465 ;; Handle -fsplit-stack.
11466
11467 (define_expand "split_stack_prologue"
11468 [(const_int 0)]
11469 ""
11470 {
11471 ix86_expand_split_stack_prologue ();
11472 DONE;
11473 })
11474
11475 ;; In order to support the call/return predictor, we use a return
11476 ;; instruction which the middle-end doesn't see.
11477 (define_insn "split_stack_return"
11478 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11479 UNSPECV_SPLIT_STACK_RETURN)]
11480 ""
11481 {
11482 if (operands[0] == const0_rtx)
11483 return "ret";
11484 else
11485 return "ret\t%0";
11486 }
11487 [(set_attr "atom_unit" "jeu")
11488 (set_attr "modrm" "0")
11489 (set (attr "length")
11490 (if_then_else (match_operand:SI 0 "const0_operand")
11491 (const_int 1)
11492 (const_int 3)))
11493 (set (attr "length_immediate")
11494 (if_then_else (match_operand:SI 0 "const0_operand")
11495 (const_int 0)
11496 (const_int 2)))])
11497
11498 ;; If there are operand 0 bytes available on the stack, jump to
11499 ;; operand 1.
11500
11501 (define_expand "split_stack_space_check"
11502 [(set (pc) (if_then_else
11503 (ltu (minus (reg SP_REG)
11504 (match_operand 0 "register_operand"))
11505 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11506 (label_ref (match_operand 1))
11507 (pc)))]
11508 ""
11509 {
11510 rtx reg, size, limit;
11511
11512 reg = gen_reg_rtx (Pmode);
11513 size = force_reg (Pmode, operands[0]);
11514 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11515 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11516 UNSPEC_STACK_CHECK);
11517 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11518 ix86_expand_branch (GEU, reg, limit, operands[1]);
11519
11520 DONE;
11521 })
11522 \f
11523 ;; Bit manipulation instructions.
11524
11525 (define_expand "ffs<mode>2"
11526 [(set (match_dup 2) (const_int -1))
11527 (parallel [(set (match_dup 3) (match_dup 4))
11528 (set (match_operand:SWI48 0 "register_operand")
11529 (ctz:SWI48
11530 (match_operand:SWI48 1 "nonimmediate_operand")))])
11531 (set (match_dup 0) (if_then_else:SWI48
11532 (eq (match_dup 3) (const_int 0))
11533 (match_dup 2)
11534 (match_dup 0)))
11535 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11536 (clobber (reg:CC FLAGS_REG))])]
11537 ""
11538 {
11539 enum machine_mode flags_mode;
11540
11541 if (<MODE>mode == SImode && !TARGET_CMOVE)
11542 {
11543 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11544 DONE;
11545 }
11546
11547 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11548
11549 operands[2] = gen_reg_rtx (<MODE>mode);
11550 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
11551 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11552 })
11553
11554 (define_insn_and_split "ffssi2_no_cmove"
11555 [(set (match_operand:SI 0 "register_operand" "=r")
11556 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11557 (clobber (match_scratch:SI 2 "=&q"))
11558 (clobber (reg:CC FLAGS_REG))]
11559 "!TARGET_CMOVE"
11560 "#"
11561 "&& reload_completed"
11562 [(parallel [(set (match_dup 4) (match_dup 5))
11563 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11564 (set (strict_low_part (match_dup 3))
11565 (eq:QI (match_dup 4) (const_int 0)))
11566 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11567 (clobber (reg:CC FLAGS_REG))])
11568 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11569 (clobber (reg:CC FLAGS_REG))])
11570 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11571 (clobber (reg:CC FLAGS_REG))])]
11572 {
11573 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11574
11575 operands[3] = gen_lowpart (QImode, operands[2]);
11576 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
11577 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11578
11579 ix86_expand_clear (operands[2]);
11580 })
11581
11582 (define_insn "*tzcnt<mode>_1"
11583 [(set (reg:CCC FLAGS_REG)
11584 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11585 (const_int 0)))
11586 (set (match_operand:SWI48 0 "register_operand" "=r")
11587 (ctz:SWI48 (match_dup 1)))]
11588 "TARGET_BMI"
11589 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11590 [(set_attr "type" "alu1")
11591 (set_attr "prefix_0f" "1")
11592 (set_attr "prefix_rep" "1")
11593 (set_attr "btver2_decode" "double")
11594 (set_attr "mode" "<MODE>")])
11595
11596 (define_insn "*bsf<mode>_1"
11597 [(set (reg:CCZ FLAGS_REG)
11598 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11599 (const_int 0)))
11600 (set (match_operand:SWI48 0 "register_operand" "=r")
11601 (ctz:SWI48 (match_dup 1)))]
11602 ""
11603 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11604 [(set_attr "type" "alu1")
11605 (set_attr "prefix_0f" "1")
11606 (set_attr "btver2_decode" "double")
11607 (set_attr "mode" "<MODE>")])
11608
11609 (define_insn "ctz<mode>2"
11610 [(set (match_operand:SWI248 0 "register_operand" "=r")
11611 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11612 (clobber (reg:CC FLAGS_REG))]
11613 ""
11614 {
11615 if (TARGET_BMI)
11616 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11617 else if (optimize_function_for_size_p (cfun))
11618 ;
11619 else if (TARGET_GENERIC)
11620 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
11621 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11622
11623 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11624 }
11625 [(set_attr "type" "alu1")
11626 (set_attr "prefix_0f" "1")
11627 (set (attr "prefix_rep")
11628 (if_then_else
11629 (ior (match_test "TARGET_BMI")
11630 (and (not (match_test "optimize_function_for_size_p (cfun)"))
11631 (match_test "TARGET_GENERIC")))
11632 (const_string "1")
11633 (const_string "0")))
11634 (set_attr "mode" "<MODE>")])
11635
11636 (define_expand "clz<mode>2"
11637 [(parallel
11638 [(set (match_operand:SWI248 0 "register_operand")
11639 (minus:SWI248
11640 (match_dup 2)
11641 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
11642 (clobber (reg:CC FLAGS_REG))])
11643 (parallel
11644 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11645 (clobber (reg:CC FLAGS_REG))])]
11646 ""
11647 {
11648 if (TARGET_LZCNT)
11649 {
11650 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
11651 DONE;
11652 }
11653 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11654 })
11655
11656 (define_insn "clz<mode>2_lzcnt"
11657 [(set (match_operand:SWI248 0 "register_operand" "=r")
11658 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11659 (clobber (reg:CC FLAGS_REG))]
11660 "TARGET_LZCNT"
11661 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11662 [(set_attr "prefix_rep" "1")
11663 (set_attr "type" "bitmanip")
11664 (set_attr "mode" "<MODE>")])
11665
11666 ;; BMI instructions.
11667 (define_insn "*bmi_andn_<mode>"
11668 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11669 (and:SWI48
11670 (not:SWI48
11671 (match_operand:SWI48 1 "register_operand" "r,r"))
11672 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
11673 (clobber (reg:CC FLAGS_REG))]
11674 "TARGET_BMI"
11675 "andn\t{%2, %1, %0|%0, %1, %2}"
11676 [(set_attr "type" "bitmanip")
11677 (set_attr "btver2_decode" "direct, double")
11678 (set_attr "mode" "<MODE>")])
11679
11680 (define_insn "bmi_bextr_<mode>"
11681 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11682 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r,r")
11683 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")]
11684 UNSPEC_BEXTR))
11685 (clobber (reg:CC FLAGS_REG))]
11686 "TARGET_BMI"
11687 "bextr\t{%2, %1, %0|%0, %1, %2}"
11688 [(set_attr "type" "bitmanip")
11689 (set_attr "btver2_decode" "direct, double")
11690 (set_attr "mode" "<MODE>")])
11691
11692 (define_insn "*bmi_blsi_<mode>"
11693 [(set (match_operand:SWI48 0 "register_operand" "=r")
11694 (and:SWI48
11695 (neg:SWI48
11696 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11697 (match_dup 1)))
11698 (clobber (reg:CC FLAGS_REG))]
11699 "TARGET_BMI"
11700 "blsi\t{%1, %0|%0, %1}"
11701 [(set_attr "type" "bitmanip")
11702 (set_attr "btver2_decode" "double")
11703 (set_attr "mode" "<MODE>")])
11704
11705 (define_insn "*bmi_blsmsk_<mode>"
11706 [(set (match_operand:SWI48 0 "register_operand" "=r")
11707 (xor:SWI48
11708 (plus:SWI48
11709 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11710 (const_int -1))
11711 (match_dup 1)))
11712 (clobber (reg:CC FLAGS_REG))]
11713 "TARGET_BMI"
11714 "blsmsk\t{%1, %0|%0, %1}"
11715 [(set_attr "type" "bitmanip")
11716 (set_attr "btver2_decode" "double")
11717 (set_attr "mode" "<MODE>")])
11718
11719 (define_insn "*bmi_blsr_<mode>"
11720 [(set (match_operand:SWI48 0 "register_operand" "=r")
11721 (and:SWI48
11722 (plus:SWI48
11723 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11724 (const_int -1))
11725 (match_dup 1)))
11726 (clobber (reg:CC FLAGS_REG))]
11727 "TARGET_BMI"
11728 "blsr\t{%1, %0|%0, %1}"
11729 [(set_attr "type" "bitmanip")
11730 (set_attr "btver2_decode" "double")
11731 (set_attr "mode" "<MODE>")])
11732
11733 ;; BMI2 instructions.
11734 (define_insn "bmi2_bzhi_<mode>3"
11735 [(set (match_operand:SWI48 0 "register_operand" "=r")
11736 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
11737 (lshiftrt:SWI48 (const_int -1)
11738 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
11739 (clobber (reg:CC FLAGS_REG))]
11740 "TARGET_BMI2"
11741 "bzhi\t{%2, %1, %0|%0, %1, %2}"
11742 [(set_attr "type" "bitmanip")
11743 (set_attr "prefix" "vex")
11744 (set_attr "mode" "<MODE>")])
11745
11746 (define_insn "bmi2_pdep_<mode>3"
11747 [(set (match_operand:SWI48 0 "register_operand" "=r")
11748 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11749 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11750 UNSPEC_PDEP))]
11751 "TARGET_BMI2"
11752 "pdep\t{%2, %1, %0|%0, %1, %2}"
11753 [(set_attr "type" "bitmanip")
11754 (set_attr "prefix" "vex")
11755 (set_attr "mode" "<MODE>")])
11756
11757 (define_insn "bmi2_pext_<mode>3"
11758 [(set (match_operand:SWI48 0 "register_operand" "=r")
11759 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11760 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11761 UNSPEC_PEXT))]
11762 "TARGET_BMI2"
11763 "pext\t{%2, %1, %0|%0, %1, %2}"
11764 [(set_attr "type" "bitmanip")
11765 (set_attr "prefix" "vex")
11766 (set_attr "mode" "<MODE>")])
11767
11768 ;; TBM instructions.
11769 (define_insn "tbm_bextri_<mode>"
11770 [(set (match_operand:SWI48 0 "register_operand" "=r")
11771 (zero_extract:SWI48
11772 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11773 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11774 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11775 (clobber (reg:CC FLAGS_REG))]
11776 "TARGET_TBM"
11777 {
11778 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11779 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11780 }
11781 [(set_attr "type" "bitmanip")
11782 (set_attr "mode" "<MODE>")])
11783
11784 (define_insn "*tbm_blcfill_<mode>"
11785 [(set (match_operand:SWI48 0 "register_operand" "=r")
11786 (and:SWI48
11787 (plus:SWI48
11788 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11789 (const_int 1))
11790 (match_dup 1)))
11791 (clobber (reg:CC FLAGS_REG))]
11792 "TARGET_TBM"
11793 "blcfill\t{%1, %0|%0, %1}"
11794 [(set_attr "type" "bitmanip")
11795 (set_attr "mode" "<MODE>")])
11796
11797 (define_insn "*tbm_blci_<mode>"
11798 [(set (match_operand:SWI48 0 "register_operand" "=r")
11799 (ior:SWI48
11800 (not:SWI48
11801 (plus:SWI48
11802 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11803 (const_int 1)))
11804 (match_dup 1)))
11805 (clobber (reg:CC FLAGS_REG))]
11806 "TARGET_TBM"
11807 "blci\t{%1, %0|%0, %1}"
11808 [(set_attr "type" "bitmanip")
11809 (set_attr "mode" "<MODE>")])
11810
11811 (define_insn "*tbm_blcic_<mode>"
11812 [(set (match_operand:SWI48 0 "register_operand" "=r")
11813 (and:SWI48
11814 (plus:SWI48
11815 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11816 (const_int 1))
11817 (not:SWI48
11818 (match_dup 1))))
11819 (clobber (reg:CC FLAGS_REG))]
11820 "TARGET_TBM"
11821 "blcic\t{%1, %0|%0, %1}"
11822 [(set_attr "type" "bitmanip")
11823 (set_attr "mode" "<MODE>")])
11824
11825 (define_insn "*tbm_blcmsk_<mode>"
11826 [(set (match_operand:SWI48 0 "register_operand" "=r")
11827 (xor:SWI48
11828 (plus:SWI48
11829 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11830 (const_int 1))
11831 (match_dup 1)))
11832 (clobber (reg:CC FLAGS_REG))]
11833 "TARGET_TBM"
11834 "blcmsk\t{%1, %0|%0, %1}"
11835 [(set_attr "type" "bitmanip")
11836 (set_attr "mode" "<MODE>")])
11837
11838 (define_insn "*tbm_blcs_<mode>"
11839 [(set (match_operand:SWI48 0 "register_operand" "=r")
11840 (ior:SWI48
11841 (plus:SWI48
11842 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11843 (const_int 1))
11844 (match_dup 1)))
11845 (clobber (reg:CC FLAGS_REG))]
11846 "TARGET_TBM"
11847 "blcs\t{%1, %0|%0, %1}"
11848 [(set_attr "type" "bitmanip")
11849 (set_attr "mode" "<MODE>")])
11850
11851 (define_insn "*tbm_blsfill_<mode>"
11852 [(set (match_operand:SWI48 0 "register_operand" "=r")
11853 (ior:SWI48
11854 (plus:SWI48
11855 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11856 (const_int -1))
11857 (match_dup 1)))
11858 (clobber (reg:CC FLAGS_REG))]
11859 "TARGET_TBM"
11860 "blsfill\t{%1, %0|%0, %1}"
11861 [(set_attr "type" "bitmanip")
11862 (set_attr "mode" "<MODE>")])
11863
11864 (define_insn "*tbm_blsic_<mode>"
11865 [(set (match_operand:SWI48 0 "register_operand" "=r")
11866 (ior:SWI48
11867 (plus:SWI48
11868 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11869 (const_int -1))
11870 (not:SWI48
11871 (match_dup 1))))
11872 (clobber (reg:CC FLAGS_REG))]
11873 "TARGET_TBM"
11874 "blsic\t{%1, %0|%0, %1}"
11875 [(set_attr "type" "bitmanip")
11876 (set_attr "mode" "<MODE>")])
11877
11878 (define_insn "*tbm_t1mskc_<mode>"
11879 [(set (match_operand:SWI48 0 "register_operand" "=r")
11880 (ior:SWI48
11881 (plus:SWI48
11882 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11883 (const_int 1))
11884 (not:SWI48
11885 (match_dup 1))))
11886 (clobber (reg:CC FLAGS_REG))]
11887 "TARGET_TBM"
11888 "t1mskc\t{%1, %0|%0, %1}"
11889 [(set_attr "type" "bitmanip")
11890 (set_attr "mode" "<MODE>")])
11891
11892 (define_insn "*tbm_tzmsk_<mode>"
11893 [(set (match_operand:SWI48 0 "register_operand" "=r")
11894 (and:SWI48
11895 (plus:SWI48
11896 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11897 (const_int -1))
11898 (not:SWI48
11899 (match_dup 1))))
11900 (clobber (reg:CC FLAGS_REG))]
11901 "TARGET_TBM"
11902 "tzmsk\t{%1, %0|%0, %1}"
11903 [(set_attr "type" "bitmanip")
11904 (set_attr "mode" "<MODE>")])
11905
11906 (define_insn "bsr_rex64"
11907 [(set (match_operand:DI 0 "register_operand" "=r")
11908 (minus:DI (const_int 63)
11909 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11910 (clobber (reg:CC FLAGS_REG))]
11911 "TARGET_64BIT"
11912 "bsr{q}\t{%1, %0|%0, %1}"
11913 [(set_attr "type" "alu1")
11914 (set_attr "prefix_0f" "1")
11915 (set_attr "mode" "DI")])
11916
11917 (define_insn "bsr"
11918 [(set (match_operand:SI 0 "register_operand" "=r")
11919 (minus:SI (const_int 31)
11920 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11921 (clobber (reg:CC FLAGS_REG))]
11922 ""
11923 "bsr{l}\t{%1, %0|%0, %1}"
11924 [(set_attr "type" "alu1")
11925 (set_attr "prefix_0f" "1")
11926 (set_attr "mode" "SI")])
11927
11928 (define_insn "*bsrhi"
11929 [(set (match_operand:HI 0 "register_operand" "=r")
11930 (minus:HI (const_int 15)
11931 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11932 (clobber (reg:CC FLAGS_REG))]
11933 ""
11934 "bsr{w}\t{%1, %0|%0, %1}"
11935 [(set_attr "type" "alu1")
11936 (set_attr "prefix_0f" "1")
11937 (set_attr "mode" "HI")])
11938
11939 (define_insn "popcount<mode>2"
11940 [(set (match_operand:SWI248 0 "register_operand" "=r")
11941 (popcount:SWI248
11942 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11943 (clobber (reg:CC FLAGS_REG))]
11944 "TARGET_POPCNT"
11945 {
11946 #if TARGET_MACHO
11947 return "popcnt\t{%1, %0|%0, %1}";
11948 #else
11949 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11950 #endif
11951 }
11952 [(set_attr "prefix_rep" "1")
11953 (set_attr "type" "bitmanip")
11954 (set_attr "mode" "<MODE>")])
11955
11956 (define_insn "*popcount<mode>2_cmp"
11957 [(set (reg FLAGS_REG)
11958 (compare
11959 (popcount:SWI248
11960 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11961 (const_int 0)))
11962 (set (match_operand:SWI248 0 "register_operand" "=r")
11963 (popcount:SWI248 (match_dup 1)))]
11964 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11965 {
11966 #if TARGET_MACHO
11967 return "popcnt\t{%1, %0|%0, %1}";
11968 #else
11969 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11970 #endif
11971 }
11972 [(set_attr "prefix_rep" "1")
11973 (set_attr "type" "bitmanip")
11974 (set_attr "mode" "<MODE>")])
11975
11976 (define_insn "*popcountsi2_cmp_zext"
11977 [(set (reg FLAGS_REG)
11978 (compare
11979 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11980 (const_int 0)))
11981 (set (match_operand:DI 0 "register_operand" "=r")
11982 (zero_extend:DI(popcount:SI (match_dup 1))))]
11983 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11984 {
11985 #if TARGET_MACHO
11986 return "popcnt\t{%1, %0|%0, %1}";
11987 #else
11988 return "popcnt{l}\t{%1, %0|%0, %1}";
11989 #endif
11990 }
11991 [(set_attr "prefix_rep" "1")
11992 (set_attr "type" "bitmanip")
11993 (set_attr "mode" "SI")])
11994
11995 (define_expand "bswapdi2"
11996 [(set (match_operand:DI 0 "register_operand")
11997 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
11998 "TARGET_64BIT"
11999 {
12000 if (!TARGET_MOVBE)
12001 operands[1] = force_reg (DImode, operands[1]);
12002 })
12003
12004 (define_expand "bswapsi2"
12005 [(set (match_operand:SI 0 "register_operand")
12006 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12007 ""
12008 {
12009 if (TARGET_MOVBE)
12010 ;
12011 else if (TARGET_BSWAP)
12012 operands[1] = force_reg (SImode, operands[1]);
12013 else
12014 {
12015 rtx x = operands[0];
12016
12017 emit_move_insn (x, operands[1]);
12018 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12019 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12020 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12021 DONE;
12022 }
12023 })
12024
12025 (define_insn "*bswap<mode>2_movbe"
12026 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12027 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12028 "TARGET_MOVBE
12029 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12030 "@
12031 bswap\t%0
12032 movbe\t{%1, %0|%0, %1}
12033 movbe\t{%1, %0|%0, %1}"
12034 [(set_attr "type" "bitmanip,imov,imov")
12035 (set_attr "modrm" "0,1,1")
12036 (set_attr "prefix_0f" "*,1,1")
12037 (set_attr "prefix_extra" "*,1,1")
12038 (set_attr "mode" "<MODE>")])
12039
12040 (define_insn "*bswap<mode>2"
12041 [(set (match_operand:SWI48 0 "register_operand" "=r")
12042 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12043 "TARGET_BSWAP"
12044 "bswap\t%0"
12045 [(set_attr "type" "bitmanip")
12046 (set_attr "modrm" "0")
12047 (set_attr "mode" "<MODE>")])
12048
12049 (define_insn "*bswaphi_lowpart_1"
12050 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12051 (bswap:HI (match_dup 0)))
12052 (clobber (reg:CC FLAGS_REG))]
12053 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12054 "@
12055 xchg{b}\t{%h0, %b0|%b0, %h0}
12056 rol{w}\t{$8, %0|%0, 8}"
12057 [(set_attr "length" "2,4")
12058 (set_attr "mode" "QI,HI")])
12059
12060 (define_insn "bswaphi_lowpart"
12061 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12062 (bswap:HI (match_dup 0)))
12063 (clobber (reg:CC FLAGS_REG))]
12064 ""
12065 "rol{w}\t{$8, %0|%0, 8}"
12066 [(set_attr "length" "4")
12067 (set_attr "mode" "HI")])
12068
12069 (define_expand "paritydi2"
12070 [(set (match_operand:DI 0 "register_operand")
12071 (parity:DI (match_operand:DI 1 "register_operand")))]
12072 "! TARGET_POPCNT"
12073 {
12074 rtx scratch = gen_reg_rtx (QImode);
12075 rtx cond;
12076
12077 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12078 NULL_RTX, operands[1]));
12079
12080 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12081 gen_rtx_REG (CCmode, FLAGS_REG),
12082 const0_rtx);
12083 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12084
12085 if (TARGET_64BIT)
12086 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12087 else
12088 {
12089 rtx tmp = gen_reg_rtx (SImode);
12090
12091 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12092 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12093 }
12094 DONE;
12095 })
12096
12097 (define_expand "paritysi2"
12098 [(set (match_operand:SI 0 "register_operand")
12099 (parity:SI (match_operand:SI 1 "register_operand")))]
12100 "! TARGET_POPCNT"
12101 {
12102 rtx scratch = gen_reg_rtx (QImode);
12103 rtx cond;
12104
12105 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12106
12107 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12108 gen_rtx_REG (CCmode, FLAGS_REG),
12109 const0_rtx);
12110 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12111
12112 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12113 DONE;
12114 })
12115
12116 (define_insn_and_split "paritydi2_cmp"
12117 [(set (reg:CC FLAGS_REG)
12118 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12119 UNSPEC_PARITY))
12120 (clobber (match_scratch:DI 0 "=r"))
12121 (clobber (match_scratch:SI 1 "=&r"))
12122 (clobber (match_scratch:HI 2 "=Q"))]
12123 "! TARGET_POPCNT"
12124 "#"
12125 "&& reload_completed"
12126 [(parallel
12127 [(set (match_dup 1)
12128 (xor:SI (match_dup 1) (match_dup 4)))
12129 (clobber (reg:CC FLAGS_REG))])
12130 (parallel
12131 [(set (reg:CC FLAGS_REG)
12132 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12133 (clobber (match_dup 1))
12134 (clobber (match_dup 2))])]
12135 {
12136 operands[4] = gen_lowpart (SImode, operands[3]);
12137
12138 if (TARGET_64BIT)
12139 {
12140 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12141 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12142 }
12143 else
12144 operands[1] = gen_highpart (SImode, operands[3]);
12145 })
12146
12147 (define_insn_and_split "paritysi2_cmp"
12148 [(set (reg:CC FLAGS_REG)
12149 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12150 UNSPEC_PARITY))
12151 (clobber (match_scratch:SI 0 "=r"))
12152 (clobber (match_scratch:HI 1 "=&Q"))]
12153 "! TARGET_POPCNT"
12154 "#"
12155 "&& reload_completed"
12156 [(parallel
12157 [(set (match_dup 1)
12158 (xor:HI (match_dup 1) (match_dup 3)))
12159 (clobber (reg:CC FLAGS_REG))])
12160 (parallel
12161 [(set (reg:CC FLAGS_REG)
12162 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12163 (clobber (match_dup 1))])]
12164 {
12165 operands[3] = gen_lowpart (HImode, operands[2]);
12166
12167 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12168 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12169 })
12170
12171 (define_insn "*parityhi2_cmp"
12172 [(set (reg:CC FLAGS_REG)
12173 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12174 UNSPEC_PARITY))
12175 (clobber (match_scratch:HI 0 "=Q"))]
12176 "! TARGET_POPCNT"
12177 "xor{b}\t{%h0, %b0|%b0, %h0}"
12178 [(set_attr "length" "2")
12179 (set_attr "mode" "HI")])
12180
12181 \f
12182 ;; Thread-local storage patterns for ELF.
12183 ;;
12184 ;; Note that these code sequences must appear exactly as shown
12185 ;; in order to allow linker relaxation.
12186
12187 (define_insn "*tls_global_dynamic_32_gnu"
12188 [(set (match_operand:SI 0 "register_operand" "=a")
12189 (unspec:SI
12190 [(match_operand:SI 1 "register_operand" "b")
12191 (match_operand 2 "tls_symbolic_operand")
12192 (match_operand 3 "constant_call_address_operand" "z")]
12193 UNSPEC_TLS_GD))
12194 (clobber (match_scratch:SI 4 "=d"))
12195 (clobber (match_scratch:SI 5 "=c"))
12196 (clobber (reg:CC FLAGS_REG))]
12197 "!TARGET_64BIT && TARGET_GNU_TLS"
12198 {
12199 output_asm_insn
12200 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12201 if (TARGET_SUN_TLS)
12202 #ifdef HAVE_AS_IX86_TLSGDPLT
12203 return "call\t%a2@tlsgdplt";
12204 #else
12205 return "call\t%p3@plt";
12206 #endif
12207 return "call\t%P3";
12208 }
12209 [(set_attr "type" "multi")
12210 (set_attr "length" "12")])
12211
12212 (define_expand "tls_global_dynamic_32"
12213 [(parallel
12214 [(set (match_operand:SI 0 "register_operand")
12215 (unspec:SI [(match_operand:SI 2 "register_operand")
12216 (match_operand 1 "tls_symbolic_operand")
12217 (match_operand 3 "constant_call_address_operand")]
12218 UNSPEC_TLS_GD))
12219 (clobber (match_scratch:SI 4))
12220 (clobber (match_scratch:SI 5))
12221 (clobber (reg:CC FLAGS_REG))])])
12222
12223 (define_insn "*tls_global_dynamic_64_<mode>"
12224 [(set (match_operand:P 0 "register_operand" "=a")
12225 (call:P
12226 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12227 (match_operand 3)))
12228 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12229 UNSPEC_TLS_GD)]
12230 "TARGET_64BIT"
12231 {
12232 if (!TARGET_X32)
12233 fputs (ASM_BYTE "0x66\n", asm_out_file);
12234 output_asm_insn
12235 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12236 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12237 fputs ("\trex64\n", asm_out_file);
12238 if (TARGET_SUN_TLS)
12239 return "call\t%p2@plt";
12240 return "call\t%P2";
12241 }
12242 [(set_attr "type" "multi")
12243 (set (attr "length")
12244 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12245
12246 (define_expand "tls_global_dynamic_64_<mode>"
12247 [(parallel
12248 [(set (match_operand:P 0 "register_operand")
12249 (call:P
12250 (mem:QI (match_operand 2 "constant_call_address_operand"))
12251 (const_int 0)))
12252 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12253 UNSPEC_TLS_GD)])]
12254 "TARGET_64BIT")
12255
12256 (define_insn "*tls_local_dynamic_base_32_gnu"
12257 [(set (match_operand:SI 0 "register_operand" "=a")
12258 (unspec:SI
12259 [(match_operand:SI 1 "register_operand" "b")
12260 (match_operand 2 "constant_call_address_operand" "z")]
12261 UNSPEC_TLS_LD_BASE))
12262 (clobber (match_scratch:SI 3 "=d"))
12263 (clobber (match_scratch:SI 4 "=c"))
12264 (clobber (reg:CC FLAGS_REG))]
12265 "!TARGET_64BIT && TARGET_GNU_TLS"
12266 {
12267 output_asm_insn
12268 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12269 if (TARGET_SUN_TLS)
12270 #ifdef HAVE_AS_IX86_TLSLDMPLT
12271 return "call\t%&@tlsldmplt";
12272 #else
12273 return "call\t%p2@plt";
12274 #endif
12275 return "call\t%P2";
12276 }
12277 [(set_attr "type" "multi")
12278 (set_attr "length" "11")])
12279
12280 (define_expand "tls_local_dynamic_base_32"
12281 [(parallel
12282 [(set (match_operand:SI 0 "register_operand")
12283 (unspec:SI
12284 [(match_operand:SI 1 "register_operand")
12285 (match_operand 2 "constant_call_address_operand")]
12286 UNSPEC_TLS_LD_BASE))
12287 (clobber (match_scratch:SI 3))
12288 (clobber (match_scratch:SI 4))
12289 (clobber (reg:CC FLAGS_REG))])])
12290
12291 (define_insn "*tls_local_dynamic_base_64_<mode>"
12292 [(set (match_operand:P 0 "register_operand" "=a")
12293 (call:P
12294 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12295 (match_operand 2)))
12296 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12297 "TARGET_64BIT"
12298 {
12299 output_asm_insn
12300 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12301 if (TARGET_SUN_TLS)
12302 return "call\t%p1@plt";
12303 return "call\t%P1";
12304 }
12305 [(set_attr "type" "multi")
12306 (set_attr "length" "12")])
12307
12308 (define_expand "tls_local_dynamic_base_64_<mode>"
12309 [(parallel
12310 [(set (match_operand:P 0 "register_operand")
12311 (call:P
12312 (mem:QI (match_operand 1 "constant_call_address_operand"))
12313 (const_int 0)))
12314 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12315 "TARGET_64BIT")
12316
12317 ;; Local dynamic of a single variable is a lose. Show combine how
12318 ;; to convert that back to global dynamic.
12319
12320 (define_insn_and_split "*tls_local_dynamic_32_once"
12321 [(set (match_operand:SI 0 "register_operand" "=a")
12322 (plus:SI
12323 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12324 (match_operand 2 "constant_call_address_operand" "z")]
12325 UNSPEC_TLS_LD_BASE)
12326 (const:SI (unspec:SI
12327 [(match_operand 3 "tls_symbolic_operand")]
12328 UNSPEC_DTPOFF))))
12329 (clobber (match_scratch:SI 4 "=d"))
12330 (clobber (match_scratch:SI 5 "=c"))
12331 (clobber (reg:CC FLAGS_REG))]
12332 ""
12333 "#"
12334 ""
12335 [(parallel
12336 [(set (match_dup 0)
12337 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12338 UNSPEC_TLS_GD))
12339 (clobber (match_dup 4))
12340 (clobber (match_dup 5))
12341 (clobber (reg:CC FLAGS_REG))])])
12342
12343 ;; Segment register for the thread base ptr load
12344 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12345
12346 ;; Load and add the thread base pointer from %<tp_seg>:0.
12347 (define_insn "*load_tp_x32"
12348 [(set (match_operand:SI 0 "register_operand" "=r")
12349 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12350 "TARGET_X32"
12351 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12352 [(set_attr "type" "imov")
12353 (set_attr "modrm" "0")
12354 (set_attr "length" "7")
12355 (set_attr "memory" "load")
12356 (set_attr "imm_disp" "false")])
12357
12358 (define_insn "*load_tp_x32_zext"
12359 [(set (match_operand:DI 0 "register_operand" "=r")
12360 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12361 "TARGET_X32"
12362 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12363 [(set_attr "type" "imov")
12364 (set_attr "modrm" "0")
12365 (set_attr "length" "7")
12366 (set_attr "memory" "load")
12367 (set_attr "imm_disp" "false")])
12368
12369 (define_insn "*load_tp_<mode>"
12370 [(set (match_operand:P 0 "register_operand" "=r")
12371 (unspec:P [(const_int 0)] UNSPEC_TP))]
12372 "!TARGET_X32"
12373 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12374 [(set_attr "type" "imov")
12375 (set_attr "modrm" "0")
12376 (set_attr "length" "7")
12377 (set_attr "memory" "load")
12378 (set_attr "imm_disp" "false")])
12379
12380 (define_insn "*add_tp_x32"
12381 [(set (match_operand:SI 0 "register_operand" "=r")
12382 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12383 (match_operand:SI 1 "register_operand" "0")))
12384 (clobber (reg:CC FLAGS_REG))]
12385 "TARGET_X32"
12386 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12387 [(set_attr "type" "alu")
12388 (set_attr "modrm" "0")
12389 (set_attr "length" "7")
12390 (set_attr "memory" "load")
12391 (set_attr "imm_disp" "false")])
12392
12393 (define_insn "*add_tp_x32_zext"
12394 [(set (match_operand:DI 0 "register_operand" "=r")
12395 (zero_extend:DI
12396 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12397 (match_operand:SI 1 "register_operand" "0"))))
12398 (clobber (reg:CC FLAGS_REG))]
12399 "TARGET_X32"
12400 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12401 [(set_attr "type" "alu")
12402 (set_attr "modrm" "0")
12403 (set_attr "length" "7")
12404 (set_attr "memory" "load")
12405 (set_attr "imm_disp" "false")])
12406
12407 (define_insn "*add_tp_<mode>"
12408 [(set (match_operand:P 0 "register_operand" "=r")
12409 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12410 (match_operand:P 1 "register_operand" "0")))
12411 (clobber (reg:CC FLAGS_REG))]
12412 "!TARGET_X32"
12413 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12414 [(set_attr "type" "alu")
12415 (set_attr "modrm" "0")
12416 (set_attr "length" "7")
12417 (set_attr "memory" "load")
12418 (set_attr "imm_disp" "false")])
12419
12420 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12421 ;; %rax as destination of the initial executable code sequence.
12422 (define_insn "tls_initial_exec_64_sun"
12423 [(set (match_operand:DI 0 "register_operand" "=a")
12424 (unspec:DI
12425 [(match_operand 1 "tls_symbolic_operand")]
12426 UNSPEC_TLS_IE_SUN))
12427 (clobber (reg:CC FLAGS_REG))]
12428 "TARGET_64BIT && TARGET_SUN_TLS"
12429 {
12430 output_asm_insn
12431 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12432 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12433 }
12434 [(set_attr "type" "multi")])
12435
12436 ;; GNU2 TLS patterns can be split.
12437
12438 (define_expand "tls_dynamic_gnu2_32"
12439 [(set (match_dup 3)
12440 (plus:SI (match_operand:SI 2 "register_operand")
12441 (const:SI
12442 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12443 UNSPEC_TLSDESC))))
12444 (parallel
12445 [(set (match_operand:SI 0 "register_operand")
12446 (unspec:SI [(match_dup 1) (match_dup 3)
12447 (match_dup 2) (reg:SI SP_REG)]
12448 UNSPEC_TLSDESC))
12449 (clobber (reg:CC FLAGS_REG))])]
12450 "!TARGET_64BIT && TARGET_GNU2_TLS"
12451 {
12452 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12453 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12454 })
12455
12456 (define_insn "*tls_dynamic_gnu2_lea_32"
12457 [(set (match_operand:SI 0 "register_operand" "=r")
12458 (plus:SI (match_operand:SI 1 "register_operand" "b")
12459 (const:SI
12460 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12461 UNSPEC_TLSDESC))))]
12462 "!TARGET_64BIT && TARGET_GNU2_TLS"
12463 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12464 [(set_attr "type" "lea")
12465 (set_attr "mode" "SI")
12466 (set_attr "length" "6")
12467 (set_attr "length_address" "4")])
12468
12469 (define_insn "*tls_dynamic_gnu2_call_32"
12470 [(set (match_operand:SI 0 "register_operand" "=a")
12471 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12472 (match_operand:SI 2 "register_operand" "0")
12473 ;; we have to make sure %ebx still points to the GOT
12474 (match_operand:SI 3 "register_operand" "b")
12475 (reg:SI SP_REG)]
12476 UNSPEC_TLSDESC))
12477 (clobber (reg:CC FLAGS_REG))]
12478 "!TARGET_64BIT && TARGET_GNU2_TLS"
12479 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12480 [(set_attr "type" "call")
12481 (set_attr "length" "2")
12482 (set_attr "length_address" "0")])
12483
12484 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12485 [(set (match_operand:SI 0 "register_operand" "=&a")
12486 (plus:SI
12487 (unspec:SI [(match_operand 3 "tls_modbase_operand")
12488 (match_operand:SI 4)
12489 (match_operand:SI 2 "register_operand" "b")
12490 (reg:SI SP_REG)]
12491 UNSPEC_TLSDESC)
12492 (const:SI (unspec:SI
12493 [(match_operand 1 "tls_symbolic_operand")]
12494 UNSPEC_DTPOFF))))
12495 (clobber (reg:CC FLAGS_REG))]
12496 "!TARGET_64BIT && TARGET_GNU2_TLS"
12497 "#"
12498 ""
12499 [(set (match_dup 0) (match_dup 5))]
12500 {
12501 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12502 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12503 })
12504
12505 (define_expand "tls_dynamic_gnu2_64"
12506 [(set (match_dup 2)
12507 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12508 UNSPEC_TLSDESC))
12509 (parallel
12510 [(set (match_operand:DI 0 "register_operand")
12511 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12512 UNSPEC_TLSDESC))
12513 (clobber (reg:CC FLAGS_REG))])]
12514 "TARGET_64BIT && TARGET_GNU2_TLS"
12515 {
12516 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12517 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12518 })
12519
12520 (define_insn "*tls_dynamic_gnu2_lea_64"
12521 [(set (match_operand:DI 0 "register_operand" "=r")
12522 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12523 UNSPEC_TLSDESC))]
12524 "TARGET_64BIT && TARGET_GNU2_TLS"
12525 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12526 [(set_attr "type" "lea")
12527 (set_attr "mode" "DI")
12528 (set_attr "length" "7")
12529 (set_attr "length_address" "4")])
12530
12531 (define_insn "*tls_dynamic_gnu2_call_64"
12532 [(set (match_operand:DI 0 "register_operand" "=a")
12533 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
12534 (match_operand:DI 2 "register_operand" "0")
12535 (reg:DI SP_REG)]
12536 UNSPEC_TLSDESC))
12537 (clobber (reg:CC FLAGS_REG))]
12538 "TARGET_64BIT && TARGET_GNU2_TLS"
12539 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12540 [(set_attr "type" "call")
12541 (set_attr "length" "2")
12542 (set_attr "length_address" "0")])
12543
12544 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12545 [(set (match_operand:DI 0 "register_operand" "=&a")
12546 (plus:DI
12547 (unspec:DI [(match_operand 2 "tls_modbase_operand")
12548 (match_operand:DI 3)
12549 (reg:DI SP_REG)]
12550 UNSPEC_TLSDESC)
12551 (const:DI (unspec:DI
12552 [(match_operand 1 "tls_symbolic_operand")]
12553 UNSPEC_DTPOFF))))
12554 (clobber (reg:CC FLAGS_REG))]
12555 "TARGET_64BIT && TARGET_GNU2_TLS"
12556 "#"
12557 ""
12558 [(set (match_dup 0) (match_dup 4))]
12559 {
12560 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12561 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12562 })
12563 \f
12564 ;; These patterns match the binary 387 instructions for addM3, subM3,
12565 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12566 ;; SFmode. The first is the normal insn, the second the same insn but
12567 ;; with one operand a conversion, and the third the same insn but with
12568 ;; the other operand a conversion. The conversion may be SFmode or
12569 ;; SImode if the target mode DFmode, but only SImode if the target mode
12570 ;; is SFmode.
12571
12572 ;; Gcc is slightly more smart about handling normal two address instructions
12573 ;; so use special patterns for add and mull.
12574
12575 (define_insn "*fop_<mode>_comm_mixed"
12576 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12577 (match_operator:MODEF 3 "binary_fp_operator"
12578 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12579 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12580 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12581 && COMMUTATIVE_ARITH_P (operands[3])
12582 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12583 "* return output_387_binary_op (insn, operands);"
12584 [(set (attr "type")
12585 (if_then_else (eq_attr "alternative" "1,2")
12586 (if_then_else (match_operand:MODEF 3 "mult_operator")
12587 (const_string "ssemul")
12588 (const_string "sseadd"))
12589 (if_then_else (match_operand:MODEF 3 "mult_operator")
12590 (const_string "fmul")
12591 (const_string "fop"))))
12592 (set_attr "isa" "*,noavx,avx")
12593 (set_attr "prefix" "orig,orig,vex")
12594 (set_attr "mode" "<MODE>")])
12595
12596 (define_insn "*fop_<mode>_comm_sse"
12597 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12598 (match_operator:MODEF 3 "binary_fp_operator"
12599 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12600 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12601 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12602 && COMMUTATIVE_ARITH_P (operands[3])
12603 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12604 "* return output_387_binary_op (insn, operands);"
12605 [(set (attr "type")
12606 (if_then_else (match_operand:MODEF 3 "mult_operator")
12607 (const_string "ssemul")
12608 (const_string "sseadd")))
12609 (set_attr "isa" "noavx,avx")
12610 (set_attr "prefix" "orig,vex")
12611 (set_attr "mode" "<MODE>")])
12612
12613 (define_insn "*fop_<mode>_comm_i387"
12614 [(set (match_operand:MODEF 0 "register_operand" "=f")
12615 (match_operator:MODEF 3 "binary_fp_operator"
12616 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12617 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12618 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12619 && COMMUTATIVE_ARITH_P (operands[3])
12620 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12621 "* return output_387_binary_op (insn, operands);"
12622 [(set (attr "type")
12623 (if_then_else (match_operand:MODEF 3 "mult_operator")
12624 (const_string "fmul")
12625 (const_string "fop")))
12626 (set_attr "mode" "<MODE>")])
12627
12628 (define_insn "*fop_<mode>_1_mixed"
12629 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12630 (match_operator:MODEF 3 "binary_fp_operator"
12631 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12632 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12633 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12634 && !COMMUTATIVE_ARITH_P (operands[3])
12635 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12636 "* return output_387_binary_op (insn, operands);"
12637 [(set (attr "type")
12638 (cond [(and (eq_attr "alternative" "2,3")
12639 (match_operand:MODEF 3 "mult_operator"))
12640 (const_string "ssemul")
12641 (and (eq_attr "alternative" "2,3")
12642 (match_operand:MODEF 3 "div_operator"))
12643 (const_string "ssediv")
12644 (eq_attr "alternative" "2,3")
12645 (const_string "sseadd")
12646 (match_operand:MODEF 3 "mult_operator")
12647 (const_string "fmul")
12648 (match_operand:MODEF 3 "div_operator")
12649 (const_string "fdiv")
12650 ]
12651 (const_string "fop")))
12652 (set_attr "isa" "*,*,noavx,avx")
12653 (set_attr "prefix" "orig,orig,orig,vex")
12654 (set_attr "mode" "<MODE>")])
12655
12656 (define_insn "*rcpsf2_sse"
12657 [(set (match_operand:SF 0 "register_operand" "=x")
12658 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12659 UNSPEC_RCP))]
12660 "TARGET_SSE_MATH"
12661 "%vrcpss\t{%1, %d0|%d0, %1}"
12662 [(set_attr "type" "sse")
12663 (set_attr "atom_sse_attr" "rcp")
12664 (set_attr "btver2_sse_attr" "rcp")
12665 (set_attr "prefix" "maybe_vex")
12666 (set_attr "mode" "SF")])
12667
12668 (define_insn "*fop_<mode>_1_sse"
12669 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12670 (match_operator:MODEF 3 "binary_fp_operator"
12671 [(match_operand:MODEF 1 "register_operand" "0,x")
12672 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12673 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12674 && !COMMUTATIVE_ARITH_P (operands[3])"
12675 "* return output_387_binary_op (insn, operands);"
12676 [(set (attr "type")
12677 (cond [(match_operand:MODEF 3 "mult_operator")
12678 (const_string "ssemul")
12679 (match_operand:MODEF 3 "div_operator")
12680 (const_string "ssediv")
12681 ]
12682 (const_string "sseadd")))
12683 (set_attr "isa" "noavx,avx")
12684 (set_attr "prefix" "orig,vex")
12685 (set_attr "mode" "<MODE>")])
12686
12687 ;; This pattern is not fully shadowed by the pattern above.
12688 (define_insn "*fop_<mode>_1_i387"
12689 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12690 (match_operator:MODEF 3 "binary_fp_operator"
12691 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12692 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12693 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12694 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12695 && !COMMUTATIVE_ARITH_P (operands[3])
12696 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12697 "* return output_387_binary_op (insn, operands);"
12698 [(set (attr "type")
12699 (cond [(match_operand:MODEF 3 "mult_operator")
12700 (const_string "fmul")
12701 (match_operand:MODEF 3 "div_operator")
12702 (const_string "fdiv")
12703 ]
12704 (const_string "fop")))
12705 (set_attr "mode" "<MODE>")])
12706
12707 ;; ??? Add SSE splitters for these!
12708 (define_insn "*fop_<MODEF:mode>_2_i387"
12709 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12710 (match_operator:MODEF 3 "binary_fp_operator"
12711 [(float:MODEF
12712 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12713 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12714 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12715 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12716 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12717 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12718 [(set (attr "type")
12719 (cond [(match_operand:MODEF 3 "mult_operator")
12720 (const_string "fmul")
12721 (match_operand:MODEF 3 "div_operator")
12722 (const_string "fdiv")
12723 ]
12724 (const_string "fop")))
12725 (set_attr "fp_int_src" "true")
12726 (set_attr "mode" "<SWI24:MODE>")])
12727
12728 (define_insn "*fop_<MODEF:mode>_3_i387"
12729 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12730 (match_operator:MODEF 3 "binary_fp_operator"
12731 [(match_operand:MODEF 1 "register_operand" "0,0")
12732 (float:MODEF
12733 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12734 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12735 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12736 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12737 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12738 [(set (attr "type")
12739 (cond [(match_operand:MODEF 3 "mult_operator")
12740 (const_string "fmul")
12741 (match_operand:MODEF 3 "div_operator")
12742 (const_string "fdiv")
12743 ]
12744 (const_string "fop")))
12745 (set_attr "fp_int_src" "true")
12746 (set_attr "mode" "<MODE>")])
12747
12748 (define_insn "*fop_df_4_i387"
12749 [(set (match_operand:DF 0 "register_operand" "=f,f")
12750 (match_operator:DF 3 "binary_fp_operator"
12751 [(float_extend:DF
12752 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12753 (match_operand:DF 2 "register_operand" "0,f")]))]
12754 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12755 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12756 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12757 "* return output_387_binary_op (insn, operands);"
12758 [(set (attr "type")
12759 (cond [(match_operand:DF 3 "mult_operator")
12760 (const_string "fmul")
12761 (match_operand:DF 3 "div_operator")
12762 (const_string "fdiv")
12763 ]
12764 (const_string "fop")))
12765 (set_attr "mode" "SF")])
12766
12767 (define_insn "*fop_df_5_i387"
12768 [(set (match_operand:DF 0 "register_operand" "=f,f")
12769 (match_operator:DF 3 "binary_fp_operator"
12770 [(match_operand:DF 1 "register_operand" "0,f")
12771 (float_extend:DF
12772 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12773 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12774 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12775 "* return output_387_binary_op (insn, operands);"
12776 [(set (attr "type")
12777 (cond [(match_operand:DF 3 "mult_operator")
12778 (const_string "fmul")
12779 (match_operand:DF 3 "div_operator")
12780 (const_string "fdiv")
12781 ]
12782 (const_string "fop")))
12783 (set_attr "mode" "SF")])
12784
12785 (define_insn "*fop_df_6_i387"
12786 [(set (match_operand:DF 0 "register_operand" "=f,f")
12787 (match_operator:DF 3 "binary_fp_operator"
12788 [(float_extend:DF
12789 (match_operand:SF 1 "register_operand" "0,f"))
12790 (float_extend:DF
12791 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12792 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12793 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12794 "* return output_387_binary_op (insn, operands);"
12795 [(set (attr "type")
12796 (cond [(match_operand:DF 3 "mult_operator")
12797 (const_string "fmul")
12798 (match_operand:DF 3 "div_operator")
12799 (const_string "fdiv")
12800 ]
12801 (const_string "fop")))
12802 (set_attr "mode" "SF")])
12803
12804 (define_insn "*fop_xf_comm_i387"
12805 [(set (match_operand:XF 0 "register_operand" "=f")
12806 (match_operator:XF 3 "binary_fp_operator"
12807 [(match_operand:XF 1 "register_operand" "%0")
12808 (match_operand:XF 2 "register_operand" "f")]))]
12809 "TARGET_80387
12810 && COMMUTATIVE_ARITH_P (operands[3])"
12811 "* return output_387_binary_op (insn, operands);"
12812 [(set (attr "type")
12813 (if_then_else (match_operand:XF 3 "mult_operator")
12814 (const_string "fmul")
12815 (const_string "fop")))
12816 (set_attr "mode" "XF")])
12817
12818 (define_insn "*fop_xf_1_i387"
12819 [(set (match_operand:XF 0 "register_operand" "=f,f")
12820 (match_operator:XF 3 "binary_fp_operator"
12821 [(match_operand:XF 1 "register_operand" "0,f")
12822 (match_operand:XF 2 "register_operand" "f,0")]))]
12823 "TARGET_80387
12824 && !COMMUTATIVE_ARITH_P (operands[3])"
12825 "* return output_387_binary_op (insn, operands);"
12826 [(set (attr "type")
12827 (cond [(match_operand:XF 3 "mult_operator")
12828 (const_string "fmul")
12829 (match_operand:XF 3 "div_operator")
12830 (const_string "fdiv")
12831 ]
12832 (const_string "fop")))
12833 (set_attr "mode" "XF")])
12834
12835 (define_insn "*fop_xf_2_i387"
12836 [(set (match_operand:XF 0 "register_operand" "=f,f")
12837 (match_operator:XF 3 "binary_fp_operator"
12838 [(float:XF
12839 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12840 (match_operand:XF 2 "register_operand" "0,0")]))]
12841 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12842 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12843 [(set (attr "type")
12844 (cond [(match_operand:XF 3 "mult_operator")
12845 (const_string "fmul")
12846 (match_operand:XF 3 "div_operator")
12847 (const_string "fdiv")
12848 ]
12849 (const_string "fop")))
12850 (set_attr "fp_int_src" "true")
12851 (set_attr "mode" "<MODE>")])
12852
12853 (define_insn "*fop_xf_3_i387"
12854 [(set (match_operand:XF 0 "register_operand" "=f,f")
12855 (match_operator:XF 3 "binary_fp_operator"
12856 [(match_operand:XF 1 "register_operand" "0,0")
12857 (float:XF
12858 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12859 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12860 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12861 [(set (attr "type")
12862 (cond [(match_operand:XF 3 "mult_operator")
12863 (const_string "fmul")
12864 (match_operand:XF 3 "div_operator")
12865 (const_string "fdiv")
12866 ]
12867 (const_string "fop")))
12868 (set_attr "fp_int_src" "true")
12869 (set_attr "mode" "<MODE>")])
12870
12871 (define_insn "*fop_xf_4_i387"
12872 [(set (match_operand:XF 0 "register_operand" "=f,f")
12873 (match_operator:XF 3 "binary_fp_operator"
12874 [(float_extend:XF
12875 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12876 (match_operand:XF 2 "register_operand" "0,f")]))]
12877 "TARGET_80387"
12878 "* return output_387_binary_op (insn, operands);"
12879 [(set (attr "type")
12880 (cond [(match_operand:XF 3 "mult_operator")
12881 (const_string "fmul")
12882 (match_operand:XF 3 "div_operator")
12883 (const_string "fdiv")
12884 ]
12885 (const_string "fop")))
12886 (set_attr "mode" "<MODE>")])
12887
12888 (define_insn "*fop_xf_5_i387"
12889 [(set (match_operand:XF 0 "register_operand" "=f,f")
12890 (match_operator:XF 3 "binary_fp_operator"
12891 [(match_operand:XF 1 "register_operand" "0,f")
12892 (float_extend:XF
12893 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12894 "TARGET_80387"
12895 "* return output_387_binary_op (insn, operands);"
12896 [(set (attr "type")
12897 (cond [(match_operand:XF 3 "mult_operator")
12898 (const_string "fmul")
12899 (match_operand:XF 3 "div_operator")
12900 (const_string "fdiv")
12901 ]
12902 (const_string "fop")))
12903 (set_attr "mode" "<MODE>")])
12904
12905 (define_insn "*fop_xf_6_i387"
12906 [(set (match_operand:XF 0 "register_operand" "=f,f")
12907 (match_operator:XF 3 "binary_fp_operator"
12908 [(float_extend:XF
12909 (match_operand:MODEF 1 "register_operand" "0,f"))
12910 (float_extend:XF
12911 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12912 "TARGET_80387"
12913 "* return output_387_binary_op (insn, operands);"
12914 [(set (attr "type")
12915 (cond [(match_operand:XF 3 "mult_operator")
12916 (const_string "fmul")
12917 (match_operand:XF 3 "div_operator")
12918 (const_string "fdiv")
12919 ]
12920 (const_string "fop")))
12921 (set_attr "mode" "<MODE>")])
12922
12923 (define_split
12924 [(set (match_operand 0 "register_operand")
12925 (match_operator 3 "binary_fp_operator"
12926 [(float (match_operand:SWI24 1 "register_operand"))
12927 (match_operand 2 "register_operand")]))]
12928 "reload_completed
12929 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12930 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12931 [(const_int 0)]
12932 {
12933 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12934 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12935 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12936 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12937 GET_MODE (operands[3]),
12938 operands[4],
12939 operands[2])));
12940 ix86_free_from_memory (GET_MODE (operands[1]));
12941 DONE;
12942 })
12943
12944 (define_split
12945 [(set (match_operand 0 "register_operand")
12946 (match_operator 3 "binary_fp_operator"
12947 [(match_operand 1 "register_operand")
12948 (float (match_operand:SWI24 2 "register_operand"))]))]
12949 "reload_completed
12950 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12951 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12952 [(const_int 0)]
12953 {
12954 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12955 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12956 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12957 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12958 GET_MODE (operands[3]),
12959 operands[1],
12960 operands[4])));
12961 ix86_free_from_memory (GET_MODE (operands[2]));
12962 DONE;
12963 })
12964 \f
12965 ;; FPU special functions.
12966
12967 ;; This pattern implements a no-op XFmode truncation for
12968 ;; all fancy i386 XFmode math functions.
12969
12970 (define_insn "truncxf<mode>2_i387_noop_unspec"
12971 [(set (match_operand:MODEF 0 "register_operand" "=f")
12972 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12973 UNSPEC_TRUNC_NOOP))]
12974 "TARGET_USE_FANCY_MATH_387"
12975 "* return output_387_reg_move (insn, operands);"
12976 [(set_attr "type" "fmov")
12977 (set_attr "mode" "<MODE>")])
12978
12979 (define_insn "sqrtxf2"
12980 [(set (match_operand:XF 0 "register_operand" "=f")
12981 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12982 "TARGET_USE_FANCY_MATH_387"
12983 "fsqrt"
12984 [(set_attr "type" "fpspc")
12985 (set_attr "mode" "XF")
12986 (set_attr "athlon_decode" "direct")
12987 (set_attr "amdfam10_decode" "direct")
12988 (set_attr "bdver1_decode" "direct")])
12989
12990 (define_insn "sqrt_extend<mode>xf2_i387"
12991 [(set (match_operand:XF 0 "register_operand" "=f")
12992 (sqrt:XF
12993 (float_extend:XF
12994 (match_operand:MODEF 1 "register_operand" "0"))))]
12995 "TARGET_USE_FANCY_MATH_387"
12996 "fsqrt"
12997 [(set_attr "type" "fpspc")
12998 (set_attr "mode" "XF")
12999 (set_attr "athlon_decode" "direct")
13000 (set_attr "amdfam10_decode" "direct")
13001 (set_attr "bdver1_decode" "direct")])
13002
13003 (define_insn "*rsqrtsf2_sse"
13004 [(set (match_operand:SF 0 "register_operand" "=x")
13005 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13006 UNSPEC_RSQRT))]
13007 "TARGET_SSE_MATH"
13008 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13009 [(set_attr "type" "sse")
13010 (set_attr "atom_sse_attr" "rcp")
13011 (set_attr "btver2_sse_attr" "rcp")
13012 (set_attr "prefix" "maybe_vex")
13013 (set_attr "mode" "SF")])
13014
13015 (define_expand "rsqrtsf2"
13016 [(set (match_operand:SF 0 "register_operand")
13017 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13018 UNSPEC_RSQRT))]
13019 "TARGET_SSE_MATH"
13020 {
13021 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13022 DONE;
13023 })
13024
13025 (define_insn "*sqrt<mode>2_sse"
13026 [(set (match_operand:MODEF 0 "register_operand" "=x")
13027 (sqrt:MODEF
13028 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13029 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13030 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13031 [(set_attr "type" "sse")
13032 (set_attr "atom_sse_attr" "sqrt")
13033 (set_attr "btver2_sse_attr" "sqrt")
13034 (set_attr "prefix" "maybe_vex")
13035 (set_attr "mode" "<MODE>")
13036 (set_attr "athlon_decode" "*")
13037 (set_attr "amdfam10_decode" "*")
13038 (set_attr "bdver1_decode" "*")])
13039
13040 (define_expand "sqrt<mode>2"
13041 [(set (match_operand:MODEF 0 "register_operand")
13042 (sqrt:MODEF
13043 (match_operand:MODEF 1 "nonimmediate_operand")))]
13044 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13045 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13046 {
13047 if (<MODE>mode == SFmode
13048 && TARGET_SSE_MATH
13049 && TARGET_RECIP_SQRT
13050 && !optimize_function_for_size_p (cfun)
13051 && flag_finite_math_only && !flag_trapping_math
13052 && flag_unsafe_math_optimizations)
13053 {
13054 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13055 DONE;
13056 }
13057
13058 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13059 {
13060 rtx op0 = gen_reg_rtx (XFmode);
13061 rtx op1 = force_reg (<MODE>mode, operands[1]);
13062
13063 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13064 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13065 DONE;
13066 }
13067 })
13068
13069 (define_insn "fpremxf4_i387"
13070 [(set (match_operand:XF 0 "register_operand" "=f")
13071 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13072 (match_operand:XF 3 "register_operand" "1")]
13073 UNSPEC_FPREM_F))
13074 (set (match_operand:XF 1 "register_operand" "=u")
13075 (unspec:XF [(match_dup 2) (match_dup 3)]
13076 UNSPEC_FPREM_U))
13077 (set (reg:CCFP FPSR_REG)
13078 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13079 UNSPEC_C2_FLAG))]
13080 "TARGET_USE_FANCY_MATH_387"
13081 "fprem"
13082 [(set_attr "type" "fpspc")
13083 (set_attr "mode" "XF")])
13084
13085 (define_expand "fmodxf3"
13086 [(use (match_operand:XF 0 "register_operand"))
13087 (use (match_operand:XF 1 "general_operand"))
13088 (use (match_operand:XF 2 "general_operand"))]
13089 "TARGET_USE_FANCY_MATH_387"
13090 {
13091 rtx label = gen_label_rtx ();
13092
13093 rtx op1 = gen_reg_rtx (XFmode);
13094 rtx op2 = gen_reg_rtx (XFmode);
13095
13096 emit_move_insn (op2, operands[2]);
13097 emit_move_insn (op1, operands[1]);
13098
13099 emit_label (label);
13100 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13101 ix86_emit_fp_unordered_jump (label);
13102 LABEL_NUSES (label) = 1;
13103
13104 emit_move_insn (operands[0], op1);
13105 DONE;
13106 })
13107
13108 (define_expand "fmod<mode>3"
13109 [(use (match_operand:MODEF 0 "register_operand"))
13110 (use (match_operand:MODEF 1 "general_operand"))
13111 (use (match_operand:MODEF 2 "general_operand"))]
13112 "TARGET_USE_FANCY_MATH_387"
13113 {
13114 rtx (*gen_truncxf) (rtx, rtx);
13115
13116 rtx label = gen_label_rtx ();
13117
13118 rtx op1 = gen_reg_rtx (XFmode);
13119 rtx op2 = gen_reg_rtx (XFmode);
13120
13121 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13122 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13123
13124 emit_label (label);
13125 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13126 ix86_emit_fp_unordered_jump (label);
13127 LABEL_NUSES (label) = 1;
13128
13129 /* Truncate the result properly for strict SSE math. */
13130 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13131 && !TARGET_MIX_SSE_I387)
13132 gen_truncxf = gen_truncxf<mode>2;
13133 else
13134 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13135
13136 emit_insn (gen_truncxf (operands[0], op1));
13137 DONE;
13138 })
13139
13140 (define_insn "fprem1xf4_i387"
13141 [(set (match_operand:XF 0 "register_operand" "=f")
13142 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13143 (match_operand:XF 3 "register_operand" "1")]
13144 UNSPEC_FPREM1_F))
13145 (set (match_operand:XF 1 "register_operand" "=u")
13146 (unspec:XF [(match_dup 2) (match_dup 3)]
13147 UNSPEC_FPREM1_U))
13148 (set (reg:CCFP FPSR_REG)
13149 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13150 UNSPEC_C2_FLAG))]
13151 "TARGET_USE_FANCY_MATH_387"
13152 "fprem1"
13153 [(set_attr "type" "fpspc")
13154 (set_attr "mode" "XF")])
13155
13156 (define_expand "remainderxf3"
13157 [(use (match_operand:XF 0 "register_operand"))
13158 (use (match_operand:XF 1 "general_operand"))
13159 (use (match_operand:XF 2 "general_operand"))]
13160 "TARGET_USE_FANCY_MATH_387"
13161 {
13162 rtx label = gen_label_rtx ();
13163
13164 rtx op1 = gen_reg_rtx (XFmode);
13165 rtx op2 = gen_reg_rtx (XFmode);
13166
13167 emit_move_insn (op2, operands[2]);
13168 emit_move_insn (op1, operands[1]);
13169
13170 emit_label (label);
13171 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13172 ix86_emit_fp_unordered_jump (label);
13173 LABEL_NUSES (label) = 1;
13174
13175 emit_move_insn (operands[0], op1);
13176 DONE;
13177 })
13178
13179 (define_expand "remainder<mode>3"
13180 [(use (match_operand:MODEF 0 "register_operand"))
13181 (use (match_operand:MODEF 1 "general_operand"))
13182 (use (match_operand:MODEF 2 "general_operand"))]
13183 "TARGET_USE_FANCY_MATH_387"
13184 {
13185 rtx (*gen_truncxf) (rtx, rtx);
13186
13187 rtx label = gen_label_rtx ();
13188
13189 rtx op1 = gen_reg_rtx (XFmode);
13190 rtx op2 = gen_reg_rtx (XFmode);
13191
13192 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13193 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13194
13195 emit_label (label);
13196
13197 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13198 ix86_emit_fp_unordered_jump (label);
13199 LABEL_NUSES (label) = 1;
13200
13201 /* Truncate the result properly for strict SSE math. */
13202 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13203 && !TARGET_MIX_SSE_I387)
13204 gen_truncxf = gen_truncxf<mode>2;
13205 else
13206 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13207
13208 emit_insn (gen_truncxf (operands[0], op1));
13209 DONE;
13210 })
13211
13212 (define_int_iterator SINCOS
13213 [UNSPEC_SIN
13214 UNSPEC_COS])
13215
13216 (define_int_attr sincos
13217 [(UNSPEC_SIN "sin")
13218 (UNSPEC_COS "cos")])
13219
13220 (define_insn "*<sincos>xf2_i387"
13221 [(set (match_operand:XF 0 "register_operand" "=f")
13222 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13223 SINCOS))]
13224 "TARGET_USE_FANCY_MATH_387
13225 && flag_unsafe_math_optimizations"
13226 "f<sincos>"
13227 [(set_attr "type" "fpspc")
13228 (set_attr "mode" "XF")])
13229
13230 (define_insn "*<sincos>_extend<mode>xf2_i387"
13231 [(set (match_operand:XF 0 "register_operand" "=f")
13232 (unspec:XF [(float_extend:XF
13233 (match_operand:MODEF 1 "register_operand" "0"))]
13234 SINCOS))]
13235 "TARGET_USE_FANCY_MATH_387
13236 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13237 || TARGET_MIX_SSE_I387)
13238 && flag_unsafe_math_optimizations"
13239 "f<sincos>"
13240 [(set_attr "type" "fpspc")
13241 (set_attr "mode" "XF")])
13242
13243 ;; When sincos pattern is defined, sin and cos builtin functions will be
13244 ;; expanded to sincos pattern with one of its outputs left unused.
13245 ;; CSE pass will figure out if two sincos patterns can be combined,
13246 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13247 ;; depending on the unused output.
13248
13249 (define_insn "sincosxf3"
13250 [(set (match_operand:XF 0 "register_operand" "=f")
13251 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13252 UNSPEC_SINCOS_COS))
13253 (set (match_operand:XF 1 "register_operand" "=u")
13254 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13255 "TARGET_USE_FANCY_MATH_387
13256 && flag_unsafe_math_optimizations"
13257 "fsincos"
13258 [(set_attr "type" "fpspc")
13259 (set_attr "mode" "XF")])
13260
13261 (define_split
13262 [(set (match_operand:XF 0 "register_operand")
13263 (unspec:XF [(match_operand:XF 2 "register_operand")]
13264 UNSPEC_SINCOS_COS))
13265 (set (match_operand:XF 1 "register_operand")
13266 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13267 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13268 && can_create_pseudo_p ()"
13269 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13270
13271 (define_split
13272 [(set (match_operand:XF 0 "register_operand")
13273 (unspec:XF [(match_operand:XF 2 "register_operand")]
13274 UNSPEC_SINCOS_COS))
13275 (set (match_operand:XF 1 "register_operand")
13276 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13277 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13278 && can_create_pseudo_p ()"
13279 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13280
13281 (define_insn "sincos_extend<mode>xf3_i387"
13282 [(set (match_operand:XF 0 "register_operand" "=f")
13283 (unspec:XF [(float_extend:XF
13284 (match_operand:MODEF 2 "register_operand" "0"))]
13285 UNSPEC_SINCOS_COS))
13286 (set (match_operand:XF 1 "register_operand" "=u")
13287 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13288 "TARGET_USE_FANCY_MATH_387
13289 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13290 || TARGET_MIX_SSE_I387)
13291 && flag_unsafe_math_optimizations"
13292 "fsincos"
13293 [(set_attr "type" "fpspc")
13294 (set_attr "mode" "XF")])
13295
13296 (define_split
13297 [(set (match_operand:XF 0 "register_operand")
13298 (unspec:XF [(float_extend:XF
13299 (match_operand:MODEF 2 "register_operand"))]
13300 UNSPEC_SINCOS_COS))
13301 (set (match_operand:XF 1 "register_operand")
13302 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13303 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13304 && can_create_pseudo_p ()"
13305 [(set (match_dup 1)
13306 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13307
13308 (define_split
13309 [(set (match_operand:XF 0 "register_operand")
13310 (unspec:XF [(float_extend:XF
13311 (match_operand:MODEF 2 "register_operand"))]
13312 UNSPEC_SINCOS_COS))
13313 (set (match_operand:XF 1 "register_operand")
13314 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13315 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13316 && can_create_pseudo_p ()"
13317 [(set (match_dup 0)
13318 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13319
13320 (define_expand "sincos<mode>3"
13321 [(use (match_operand:MODEF 0 "register_operand"))
13322 (use (match_operand:MODEF 1 "register_operand"))
13323 (use (match_operand:MODEF 2 "register_operand"))]
13324 "TARGET_USE_FANCY_MATH_387
13325 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13326 || TARGET_MIX_SSE_I387)
13327 && flag_unsafe_math_optimizations"
13328 {
13329 rtx op0 = gen_reg_rtx (XFmode);
13330 rtx op1 = gen_reg_rtx (XFmode);
13331
13332 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13333 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13334 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13335 DONE;
13336 })
13337
13338 (define_insn "fptanxf4_i387"
13339 [(set (match_operand:XF 0 "register_operand" "=f")
13340 (match_operand:XF 3 "const_double_operand" "F"))
13341 (set (match_operand:XF 1 "register_operand" "=u")
13342 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13343 UNSPEC_TAN))]
13344 "TARGET_USE_FANCY_MATH_387
13345 && flag_unsafe_math_optimizations
13346 && standard_80387_constant_p (operands[3]) == 2"
13347 "fptan"
13348 [(set_attr "type" "fpspc")
13349 (set_attr "mode" "XF")])
13350
13351 (define_insn "fptan_extend<mode>xf4_i387"
13352 [(set (match_operand:MODEF 0 "register_operand" "=f")
13353 (match_operand:MODEF 3 "const_double_operand" "F"))
13354 (set (match_operand:XF 1 "register_operand" "=u")
13355 (unspec:XF [(float_extend:XF
13356 (match_operand:MODEF 2 "register_operand" "0"))]
13357 UNSPEC_TAN))]
13358 "TARGET_USE_FANCY_MATH_387
13359 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13360 || TARGET_MIX_SSE_I387)
13361 && flag_unsafe_math_optimizations
13362 && standard_80387_constant_p (operands[3]) == 2"
13363 "fptan"
13364 [(set_attr "type" "fpspc")
13365 (set_attr "mode" "XF")])
13366
13367 (define_expand "tanxf2"
13368 [(use (match_operand:XF 0 "register_operand"))
13369 (use (match_operand:XF 1 "register_operand"))]
13370 "TARGET_USE_FANCY_MATH_387
13371 && flag_unsafe_math_optimizations"
13372 {
13373 rtx one = gen_reg_rtx (XFmode);
13374 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13375
13376 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13377 DONE;
13378 })
13379
13380 (define_expand "tan<mode>2"
13381 [(use (match_operand:MODEF 0 "register_operand"))
13382 (use (match_operand:MODEF 1 "register_operand"))]
13383 "TARGET_USE_FANCY_MATH_387
13384 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13385 || TARGET_MIX_SSE_I387)
13386 && flag_unsafe_math_optimizations"
13387 {
13388 rtx op0 = gen_reg_rtx (XFmode);
13389
13390 rtx one = gen_reg_rtx (<MODE>mode);
13391 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13392
13393 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13394 operands[1], op2));
13395 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13396 DONE;
13397 })
13398
13399 (define_insn "*fpatanxf3_i387"
13400 [(set (match_operand:XF 0 "register_operand" "=f")
13401 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13402 (match_operand:XF 2 "register_operand" "u")]
13403 UNSPEC_FPATAN))
13404 (clobber (match_scratch:XF 3 "=2"))]
13405 "TARGET_USE_FANCY_MATH_387
13406 && flag_unsafe_math_optimizations"
13407 "fpatan"
13408 [(set_attr "type" "fpspc")
13409 (set_attr "mode" "XF")])
13410
13411 (define_insn "fpatan_extend<mode>xf3_i387"
13412 [(set (match_operand:XF 0 "register_operand" "=f")
13413 (unspec:XF [(float_extend:XF
13414 (match_operand:MODEF 1 "register_operand" "0"))
13415 (float_extend:XF
13416 (match_operand:MODEF 2 "register_operand" "u"))]
13417 UNSPEC_FPATAN))
13418 (clobber (match_scratch:XF 3 "=2"))]
13419 "TARGET_USE_FANCY_MATH_387
13420 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13421 || TARGET_MIX_SSE_I387)
13422 && flag_unsafe_math_optimizations"
13423 "fpatan"
13424 [(set_attr "type" "fpspc")
13425 (set_attr "mode" "XF")])
13426
13427 (define_expand "atan2xf3"
13428 [(parallel [(set (match_operand:XF 0 "register_operand")
13429 (unspec:XF [(match_operand:XF 2 "register_operand")
13430 (match_operand:XF 1 "register_operand")]
13431 UNSPEC_FPATAN))
13432 (clobber (match_scratch:XF 3))])]
13433 "TARGET_USE_FANCY_MATH_387
13434 && flag_unsafe_math_optimizations")
13435
13436 (define_expand "atan2<mode>3"
13437 [(use (match_operand:MODEF 0 "register_operand"))
13438 (use (match_operand:MODEF 1 "register_operand"))
13439 (use (match_operand:MODEF 2 "register_operand"))]
13440 "TARGET_USE_FANCY_MATH_387
13441 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13442 || TARGET_MIX_SSE_I387)
13443 && flag_unsafe_math_optimizations"
13444 {
13445 rtx op0 = gen_reg_rtx (XFmode);
13446
13447 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13448 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13449 DONE;
13450 })
13451
13452 (define_expand "atanxf2"
13453 [(parallel [(set (match_operand:XF 0 "register_operand")
13454 (unspec:XF [(match_dup 2)
13455 (match_operand:XF 1 "register_operand")]
13456 UNSPEC_FPATAN))
13457 (clobber (match_scratch:XF 3))])]
13458 "TARGET_USE_FANCY_MATH_387
13459 && flag_unsafe_math_optimizations"
13460 {
13461 operands[2] = gen_reg_rtx (XFmode);
13462 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13463 })
13464
13465 (define_expand "atan<mode>2"
13466 [(use (match_operand:MODEF 0 "register_operand"))
13467 (use (match_operand:MODEF 1 "register_operand"))]
13468 "TARGET_USE_FANCY_MATH_387
13469 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13470 || TARGET_MIX_SSE_I387)
13471 && flag_unsafe_math_optimizations"
13472 {
13473 rtx op0 = gen_reg_rtx (XFmode);
13474
13475 rtx op2 = gen_reg_rtx (<MODE>mode);
13476 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13477
13478 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13479 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13480 DONE;
13481 })
13482
13483 (define_expand "asinxf2"
13484 [(set (match_dup 2)
13485 (mult:XF (match_operand:XF 1 "register_operand")
13486 (match_dup 1)))
13487 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13488 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13489 (parallel [(set (match_operand:XF 0 "register_operand")
13490 (unspec:XF [(match_dup 5) (match_dup 1)]
13491 UNSPEC_FPATAN))
13492 (clobber (match_scratch:XF 6))])]
13493 "TARGET_USE_FANCY_MATH_387
13494 && flag_unsafe_math_optimizations"
13495 {
13496 int i;
13497
13498 if (optimize_insn_for_size_p ())
13499 FAIL;
13500
13501 for (i = 2; i < 6; i++)
13502 operands[i] = gen_reg_rtx (XFmode);
13503
13504 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13505 })
13506
13507 (define_expand "asin<mode>2"
13508 [(use (match_operand:MODEF 0 "register_operand"))
13509 (use (match_operand:MODEF 1 "general_operand"))]
13510 "TARGET_USE_FANCY_MATH_387
13511 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13512 || TARGET_MIX_SSE_I387)
13513 && flag_unsafe_math_optimizations"
13514 {
13515 rtx op0 = gen_reg_rtx (XFmode);
13516 rtx op1 = gen_reg_rtx (XFmode);
13517
13518 if (optimize_insn_for_size_p ())
13519 FAIL;
13520
13521 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13522 emit_insn (gen_asinxf2 (op0, op1));
13523 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13524 DONE;
13525 })
13526
13527 (define_expand "acosxf2"
13528 [(set (match_dup 2)
13529 (mult:XF (match_operand:XF 1 "register_operand")
13530 (match_dup 1)))
13531 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13532 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13533 (parallel [(set (match_operand:XF 0 "register_operand")
13534 (unspec:XF [(match_dup 1) (match_dup 5)]
13535 UNSPEC_FPATAN))
13536 (clobber (match_scratch:XF 6))])]
13537 "TARGET_USE_FANCY_MATH_387
13538 && flag_unsafe_math_optimizations"
13539 {
13540 int i;
13541
13542 if (optimize_insn_for_size_p ())
13543 FAIL;
13544
13545 for (i = 2; i < 6; i++)
13546 operands[i] = gen_reg_rtx (XFmode);
13547
13548 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13549 })
13550
13551 (define_expand "acos<mode>2"
13552 [(use (match_operand:MODEF 0 "register_operand"))
13553 (use (match_operand:MODEF 1 "general_operand"))]
13554 "TARGET_USE_FANCY_MATH_387
13555 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13556 || TARGET_MIX_SSE_I387)
13557 && flag_unsafe_math_optimizations"
13558 {
13559 rtx op0 = gen_reg_rtx (XFmode);
13560 rtx op1 = gen_reg_rtx (XFmode);
13561
13562 if (optimize_insn_for_size_p ())
13563 FAIL;
13564
13565 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13566 emit_insn (gen_acosxf2 (op0, op1));
13567 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13568 DONE;
13569 })
13570
13571 (define_insn "fyl2xxf3_i387"
13572 [(set (match_operand:XF 0 "register_operand" "=f")
13573 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13574 (match_operand:XF 2 "register_operand" "u")]
13575 UNSPEC_FYL2X))
13576 (clobber (match_scratch:XF 3 "=2"))]
13577 "TARGET_USE_FANCY_MATH_387
13578 && flag_unsafe_math_optimizations"
13579 "fyl2x"
13580 [(set_attr "type" "fpspc")
13581 (set_attr "mode" "XF")])
13582
13583 (define_insn "fyl2x_extend<mode>xf3_i387"
13584 [(set (match_operand:XF 0 "register_operand" "=f")
13585 (unspec:XF [(float_extend:XF
13586 (match_operand:MODEF 1 "register_operand" "0"))
13587 (match_operand:XF 2 "register_operand" "u")]
13588 UNSPEC_FYL2X))
13589 (clobber (match_scratch:XF 3 "=2"))]
13590 "TARGET_USE_FANCY_MATH_387
13591 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13592 || TARGET_MIX_SSE_I387)
13593 && flag_unsafe_math_optimizations"
13594 "fyl2x"
13595 [(set_attr "type" "fpspc")
13596 (set_attr "mode" "XF")])
13597
13598 (define_expand "logxf2"
13599 [(parallel [(set (match_operand:XF 0 "register_operand")
13600 (unspec:XF [(match_operand:XF 1 "register_operand")
13601 (match_dup 2)] UNSPEC_FYL2X))
13602 (clobber (match_scratch:XF 3))])]
13603 "TARGET_USE_FANCY_MATH_387
13604 && flag_unsafe_math_optimizations"
13605 {
13606 operands[2] = gen_reg_rtx (XFmode);
13607 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13608 })
13609
13610 (define_expand "log<mode>2"
13611 [(use (match_operand:MODEF 0 "register_operand"))
13612 (use (match_operand:MODEF 1 "register_operand"))]
13613 "TARGET_USE_FANCY_MATH_387
13614 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13615 || TARGET_MIX_SSE_I387)
13616 && flag_unsafe_math_optimizations"
13617 {
13618 rtx op0 = gen_reg_rtx (XFmode);
13619
13620 rtx op2 = gen_reg_rtx (XFmode);
13621 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13622
13623 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13624 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13625 DONE;
13626 })
13627
13628 (define_expand "log10xf2"
13629 [(parallel [(set (match_operand:XF 0 "register_operand")
13630 (unspec:XF [(match_operand:XF 1 "register_operand")
13631 (match_dup 2)] UNSPEC_FYL2X))
13632 (clobber (match_scratch:XF 3))])]
13633 "TARGET_USE_FANCY_MATH_387
13634 && flag_unsafe_math_optimizations"
13635 {
13636 operands[2] = gen_reg_rtx (XFmode);
13637 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13638 })
13639
13640 (define_expand "log10<mode>2"
13641 [(use (match_operand:MODEF 0 "register_operand"))
13642 (use (match_operand:MODEF 1 "register_operand"))]
13643 "TARGET_USE_FANCY_MATH_387
13644 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13645 || TARGET_MIX_SSE_I387)
13646 && flag_unsafe_math_optimizations"
13647 {
13648 rtx op0 = gen_reg_rtx (XFmode);
13649
13650 rtx op2 = gen_reg_rtx (XFmode);
13651 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13652
13653 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13654 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13655 DONE;
13656 })
13657
13658 (define_expand "log2xf2"
13659 [(parallel [(set (match_operand:XF 0 "register_operand")
13660 (unspec:XF [(match_operand:XF 1 "register_operand")
13661 (match_dup 2)] UNSPEC_FYL2X))
13662 (clobber (match_scratch:XF 3))])]
13663 "TARGET_USE_FANCY_MATH_387
13664 && flag_unsafe_math_optimizations"
13665 {
13666 operands[2] = gen_reg_rtx (XFmode);
13667 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13668 })
13669
13670 (define_expand "log2<mode>2"
13671 [(use (match_operand:MODEF 0 "register_operand"))
13672 (use (match_operand:MODEF 1 "register_operand"))]
13673 "TARGET_USE_FANCY_MATH_387
13674 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13675 || TARGET_MIX_SSE_I387)
13676 && flag_unsafe_math_optimizations"
13677 {
13678 rtx op0 = gen_reg_rtx (XFmode);
13679
13680 rtx op2 = gen_reg_rtx (XFmode);
13681 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13682
13683 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13684 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13685 DONE;
13686 })
13687
13688 (define_insn "fyl2xp1xf3_i387"
13689 [(set (match_operand:XF 0 "register_operand" "=f")
13690 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13691 (match_operand:XF 2 "register_operand" "u")]
13692 UNSPEC_FYL2XP1))
13693 (clobber (match_scratch:XF 3 "=2"))]
13694 "TARGET_USE_FANCY_MATH_387
13695 && flag_unsafe_math_optimizations"
13696 "fyl2xp1"
13697 [(set_attr "type" "fpspc")
13698 (set_attr "mode" "XF")])
13699
13700 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13701 [(set (match_operand:XF 0 "register_operand" "=f")
13702 (unspec:XF [(float_extend:XF
13703 (match_operand:MODEF 1 "register_operand" "0"))
13704 (match_operand:XF 2 "register_operand" "u")]
13705 UNSPEC_FYL2XP1))
13706 (clobber (match_scratch:XF 3 "=2"))]
13707 "TARGET_USE_FANCY_MATH_387
13708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13709 || TARGET_MIX_SSE_I387)
13710 && flag_unsafe_math_optimizations"
13711 "fyl2xp1"
13712 [(set_attr "type" "fpspc")
13713 (set_attr "mode" "XF")])
13714
13715 (define_expand "log1pxf2"
13716 [(use (match_operand:XF 0 "register_operand"))
13717 (use (match_operand:XF 1 "register_operand"))]
13718 "TARGET_USE_FANCY_MATH_387
13719 && flag_unsafe_math_optimizations"
13720 {
13721 if (optimize_insn_for_size_p ())
13722 FAIL;
13723
13724 ix86_emit_i387_log1p (operands[0], operands[1]);
13725 DONE;
13726 })
13727
13728 (define_expand "log1p<mode>2"
13729 [(use (match_operand:MODEF 0 "register_operand"))
13730 (use (match_operand:MODEF 1 "register_operand"))]
13731 "TARGET_USE_FANCY_MATH_387
13732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13733 || TARGET_MIX_SSE_I387)
13734 && flag_unsafe_math_optimizations"
13735 {
13736 rtx op0;
13737
13738 if (optimize_insn_for_size_p ())
13739 FAIL;
13740
13741 op0 = gen_reg_rtx (XFmode);
13742
13743 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13744
13745 ix86_emit_i387_log1p (op0, operands[1]);
13746 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13747 DONE;
13748 })
13749
13750 (define_insn "fxtractxf3_i387"
13751 [(set (match_operand:XF 0 "register_operand" "=f")
13752 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13753 UNSPEC_XTRACT_FRACT))
13754 (set (match_operand:XF 1 "register_operand" "=u")
13755 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13756 "TARGET_USE_FANCY_MATH_387
13757 && flag_unsafe_math_optimizations"
13758 "fxtract"
13759 [(set_attr "type" "fpspc")
13760 (set_attr "mode" "XF")])
13761
13762 (define_insn "fxtract_extend<mode>xf3_i387"
13763 [(set (match_operand:XF 0 "register_operand" "=f")
13764 (unspec:XF [(float_extend:XF
13765 (match_operand:MODEF 2 "register_operand" "0"))]
13766 UNSPEC_XTRACT_FRACT))
13767 (set (match_operand:XF 1 "register_operand" "=u")
13768 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13769 "TARGET_USE_FANCY_MATH_387
13770 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13771 || TARGET_MIX_SSE_I387)
13772 && flag_unsafe_math_optimizations"
13773 "fxtract"
13774 [(set_attr "type" "fpspc")
13775 (set_attr "mode" "XF")])
13776
13777 (define_expand "logbxf2"
13778 [(parallel [(set (match_dup 2)
13779 (unspec:XF [(match_operand:XF 1 "register_operand")]
13780 UNSPEC_XTRACT_FRACT))
13781 (set (match_operand:XF 0 "register_operand")
13782 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13783 "TARGET_USE_FANCY_MATH_387
13784 && flag_unsafe_math_optimizations"
13785 "operands[2] = gen_reg_rtx (XFmode);")
13786
13787 (define_expand "logb<mode>2"
13788 [(use (match_operand:MODEF 0 "register_operand"))
13789 (use (match_operand:MODEF 1 "register_operand"))]
13790 "TARGET_USE_FANCY_MATH_387
13791 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13792 || TARGET_MIX_SSE_I387)
13793 && flag_unsafe_math_optimizations"
13794 {
13795 rtx op0 = gen_reg_rtx (XFmode);
13796 rtx op1 = gen_reg_rtx (XFmode);
13797
13798 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13799 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13800 DONE;
13801 })
13802
13803 (define_expand "ilogbxf2"
13804 [(use (match_operand:SI 0 "register_operand"))
13805 (use (match_operand:XF 1 "register_operand"))]
13806 "TARGET_USE_FANCY_MATH_387
13807 && flag_unsafe_math_optimizations"
13808 {
13809 rtx op0, op1;
13810
13811 if (optimize_insn_for_size_p ())
13812 FAIL;
13813
13814 op0 = gen_reg_rtx (XFmode);
13815 op1 = gen_reg_rtx (XFmode);
13816
13817 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13818 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13819 DONE;
13820 })
13821
13822 (define_expand "ilogb<mode>2"
13823 [(use (match_operand:SI 0 "register_operand"))
13824 (use (match_operand:MODEF 1 "register_operand"))]
13825 "TARGET_USE_FANCY_MATH_387
13826 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13827 || TARGET_MIX_SSE_I387)
13828 && flag_unsafe_math_optimizations"
13829 {
13830 rtx op0, op1;
13831
13832 if (optimize_insn_for_size_p ())
13833 FAIL;
13834
13835 op0 = gen_reg_rtx (XFmode);
13836 op1 = gen_reg_rtx (XFmode);
13837
13838 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13839 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13840 DONE;
13841 })
13842
13843 (define_insn "*f2xm1xf2_i387"
13844 [(set (match_operand:XF 0 "register_operand" "=f")
13845 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13846 UNSPEC_F2XM1))]
13847 "TARGET_USE_FANCY_MATH_387
13848 && flag_unsafe_math_optimizations"
13849 "f2xm1"
13850 [(set_attr "type" "fpspc")
13851 (set_attr "mode" "XF")])
13852
13853 (define_insn "*fscalexf4_i387"
13854 [(set (match_operand:XF 0 "register_operand" "=f")
13855 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13856 (match_operand:XF 3 "register_operand" "1")]
13857 UNSPEC_FSCALE_FRACT))
13858 (set (match_operand:XF 1 "register_operand" "=u")
13859 (unspec:XF [(match_dup 2) (match_dup 3)]
13860 UNSPEC_FSCALE_EXP))]
13861 "TARGET_USE_FANCY_MATH_387
13862 && flag_unsafe_math_optimizations"
13863 "fscale"
13864 [(set_attr "type" "fpspc")
13865 (set_attr "mode" "XF")])
13866
13867 (define_expand "expNcorexf3"
13868 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
13869 (match_operand:XF 2 "register_operand")))
13870 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13871 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13872 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13873 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13874 (parallel [(set (match_operand:XF 0 "register_operand")
13875 (unspec:XF [(match_dup 8) (match_dup 4)]
13876 UNSPEC_FSCALE_FRACT))
13877 (set (match_dup 9)
13878 (unspec:XF [(match_dup 8) (match_dup 4)]
13879 UNSPEC_FSCALE_EXP))])]
13880 "TARGET_USE_FANCY_MATH_387
13881 && flag_unsafe_math_optimizations"
13882 {
13883 int i;
13884
13885 if (optimize_insn_for_size_p ())
13886 FAIL;
13887
13888 for (i = 3; i < 10; i++)
13889 operands[i] = gen_reg_rtx (XFmode);
13890
13891 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13892 })
13893
13894 (define_expand "expxf2"
13895 [(use (match_operand:XF 0 "register_operand"))
13896 (use (match_operand:XF 1 "register_operand"))]
13897 "TARGET_USE_FANCY_MATH_387
13898 && flag_unsafe_math_optimizations"
13899 {
13900 rtx op2;
13901
13902 if (optimize_insn_for_size_p ())
13903 FAIL;
13904
13905 op2 = gen_reg_rtx (XFmode);
13906 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13907
13908 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13909 DONE;
13910 })
13911
13912 (define_expand "exp<mode>2"
13913 [(use (match_operand:MODEF 0 "register_operand"))
13914 (use (match_operand:MODEF 1 "general_operand"))]
13915 "TARGET_USE_FANCY_MATH_387
13916 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13917 || TARGET_MIX_SSE_I387)
13918 && flag_unsafe_math_optimizations"
13919 {
13920 rtx op0, op1;
13921
13922 if (optimize_insn_for_size_p ())
13923 FAIL;
13924
13925 op0 = gen_reg_rtx (XFmode);
13926 op1 = gen_reg_rtx (XFmode);
13927
13928 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13929 emit_insn (gen_expxf2 (op0, op1));
13930 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13931 DONE;
13932 })
13933
13934 (define_expand "exp10xf2"
13935 [(use (match_operand:XF 0 "register_operand"))
13936 (use (match_operand:XF 1 "register_operand"))]
13937 "TARGET_USE_FANCY_MATH_387
13938 && flag_unsafe_math_optimizations"
13939 {
13940 rtx op2;
13941
13942 if (optimize_insn_for_size_p ())
13943 FAIL;
13944
13945 op2 = gen_reg_rtx (XFmode);
13946 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13947
13948 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13949 DONE;
13950 })
13951
13952 (define_expand "exp10<mode>2"
13953 [(use (match_operand:MODEF 0 "register_operand"))
13954 (use (match_operand:MODEF 1 "general_operand"))]
13955 "TARGET_USE_FANCY_MATH_387
13956 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13957 || TARGET_MIX_SSE_I387)
13958 && flag_unsafe_math_optimizations"
13959 {
13960 rtx op0, op1;
13961
13962 if (optimize_insn_for_size_p ())
13963 FAIL;
13964
13965 op0 = gen_reg_rtx (XFmode);
13966 op1 = gen_reg_rtx (XFmode);
13967
13968 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13969 emit_insn (gen_exp10xf2 (op0, op1));
13970 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13971 DONE;
13972 })
13973
13974 (define_expand "exp2xf2"
13975 [(use (match_operand:XF 0 "register_operand"))
13976 (use (match_operand:XF 1 "register_operand"))]
13977 "TARGET_USE_FANCY_MATH_387
13978 && flag_unsafe_math_optimizations"
13979 {
13980 rtx op2;
13981
13982 if (optimize_insn_for_size_p ())
13983 FAIL;
13984
13985 op2 = gen_reg_rtx (XFmode);
13986 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13987
13988 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13989 DONE;
13990 })
13991
13992 (define_expand "exp2<mode>2"
13993 [(use (match_operand:MODEF 0 "register_operand"))
13994 (use (match_operand:MODEF 1 "general_operand"))]
13995 "TARGET_USE_FANCY_MATH_387
13996 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13997 || TARGET_MIX_SSE_I387)
13998 && flag_unsafe_math_optimizations"
13999 {
14000 rtx op0, op1;
14001
14002 if (optimize_insn_for_size_p ())
14003 FAIL;
14004
14005 op0 = gen_reg_rtx (XFmode);
14006 op1 = gen_reg_rtx (XFmode);
14007
14008 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14009 emit_insn (gen_exp2xf2 (op0, op1));
14010 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14011 DONE;
14012 })
14013
14014 (define_expand "expm1xf2"
14015 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14016 (match_dup 2)))
14017 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14018 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14019 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14020 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14021 (parallel [(set (match_dup 7)
14022 (unspec:XF [(match_dup 6) (match_dup 4)]
14023 UNSPEC_FSCALE_FRACT))
14024 (set (match_dup 8)
14025 (unspec:XF [(match_dup 6) (match_dup 4)]
14026 UNSPEC_FSCALE_EXP))])
14027 (parallel [(set (match_dup 10)
14028 (unspec:XF [(match_dup 9) (match_dup 8)]
14029 UNSPEC_FSCALE_FRACT))
14030 (set (match_dup 11)
14031 (unspec:XF [(match_dup 9) (match_dup 8)]
14032 UNSPEC_FSCALE_EXP))])
14033 (set (match_dup 12) (minus:XF (match_dup 10)
14034 (float_extend:XF (match_dup 13))))
14035 (set (match_operand:XF 0 "register_operand")
14036 (plus:XF (match_dup 12) (match_dup 7)))]
14037 "TARGET_USE_FANCY_MATH_387
14038 && flag_unsafe_math_optimizations"
14039 {
14040 int i;
14041
14042 if (optimize_insn_for_size_p ())
14043 FAIL;
14044
14045 for (i = 2; i < 13; i++)
14046 operands[i] = gen_reg_rtx (XFmode);
14047
14048 operands[13]
14049 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14050
14051 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14052 })
14053
14054 (define_expand "expm1<mode>2"
14055 [(use (match_operand:MODEF 0 "register_operand"))
14056 (use (match_operand:MODEF 1 "general_operand"))]
14057 "TARGET_USE_FANCY_MATH_387
14058 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14059 || TARGET_MIX_SSE_I387)
14060 && flag_unsafe_math_optimizations"
14061 {
14062 rtx op0, op1;
14063
14064 if (optimize_insn_for_size_p ())
14065 FAIL;
14066
14067 op0 = gen_reg_rtx (XFmode);
14068 op1 = gen_reg_rtx (XFmode);
14069
14070 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14071 emit_insn (gen_expm1xf2 (op0, op1));
14072 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14073 DONE;
14074 })
14075
14076 (define_expand "ldexpxf3"
14077 [(set (match_dup 3)
14078 (float:XF (match_operand:SI 2 "register_operand")))
14079 (parallel [(set (match_operand:XF 0 " register_operand")
14080 (unspec:XF [(match_operand:XF 1 "register_operand")
14081 (match_dup 3)]
14082 UNSPEC_FSCALE_FRACT))
14083 (set (match_dup 4)
14084 (unspec:XF [(match_dup 1) (match_dup 3)]
14085 UNSPEC_FSCALE_EXP))])]
14086 "TARGET_USE_FANCY_MATH_387
14087 && flag_unsafe_math_optimizations"
14088 {
14089 if (optimize_insn_for_size_p ())
14090 FAIL;
14091
14092 operands[3] = gen_reg_rtx (XFmode);
14093 operands[4] = gen_reg_rtx (XFmode);
14094 })
14095
14096 (define_expand "ldexp<mode>3"
14097 [(use (match_operand:MODEF 0 "register_operand"))
14098 (use (match_operand:MODEF 1 "general_operand"))
14099 (use (match_operand:SI 2 "register_operand"))]
14100 "TARGET_USE_FANCY_MATH_387
14101 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14102 || TARGET_MIX_SSE_I387)
14103 && flag_unsafe_math_optimizations"
14104 {
14105 rtx op0, op1;
14106
14107 if (optimize_insn_for_size_p ())
14108 FAIL;
14109
14110 op0 = gen_reg_rtx (XFmode);
14111 op1 = gen_reg_rtx (XFmode);
14112
14113 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14114 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14115 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14116 DONE;
14117 })
14118
14119 (define_expand "scalbxf3"
14120 [(parallel [(set (match_operand:XF 0 " register_operand")
14121 (unspec:XF [(match_operand:XF 1 "register_operand")
14122 (match_operand:XF 2 "register_operand")]
14123 UNSPEC_FSCALE_FRACT))
14124 (set (match_dup 3)
14125 (unspec:XF [(match_dup 1) (match_dup 2)]
14126 UNSPEC_FSCALE_EXP))])]
14127 "TARGET_USE_FANCY_MATH_387
14128 && flag_unsafe_math_optimizations"
14129 {
14130 if (optimize_insn_for_size_p ())
14131 FAIL;
14132
14133 operands[3] = gen_reg_rtx (XFmode);
14134 })
14135
14136 (define_expand "scalb<mode>3"
14137 [(use (match_operand:MODEF 0 "register_operand"))
14138 (use (match_operand:MODEF 1 "general_operand"))
14139 (use (match_operand:MODEF 2 "general_operand"))]
14140 "TARGET_USE_FANCY_MATH_387
14141 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14142 || TARGET_MIX_SSE_I387)
14143 && flag_unsafe_math_optimizations"
14144 {
14145 rtx op0, op1, op2;
14146
14147 if (optimize_insn_for_size_p ())
14148 FAIL;
14149
14150 op0 = gen_reg_rtx (XFmode);
14151 op1 = gen_reg_rtx (XFmode);
14152 op2 = gen_reg_rtx (XFmode);
14153
14154 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14155 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14156 emit_insn (gen_scalbxf3 (op0, op1, op2));
14157 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14158 DONE;
14159 })
14160
14161 (define_expand "significandxf2"
14162 [(parallel [(set (match_operand:XF 0 "register_operand")
14163 (unspec:XF [(match_operand:XF 1 "register_operand")]
14164 UNSPEC_XTRACT_FRACT))
14165 (set (match_dup 2)
14166 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14167 "TARGET_USE_FANCY_MATH_387
14168 && flag_unsafe_math_optimizations"
14169 "operands[2] = gen_reg_rtx (XFmode);")
14170
14171 (define_expand "significand<mode>2"
14172 [(use (match_operand:MODEF 0 "register_operand"))
14173 (use (match_operand:MODEF 1 "register_operand"))]
14174 "TARGET_USE_FANCY_MATH_387
14175 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14176 || TARGET_MIX_SSE_I387)
14177 && flag_unsafe_math_optimizations"
14178 {
14179 rtx op0 = gen_reg_rtx (XFmode);
14180 rtx op1 = gen_reg_rtx (XFmode);
14181
14182 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14183 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14184 DONE;
14185 })
14186 \f
14187
14188 (define_insn "sse4_1_round<mode>2"
14189 [(set (match_operand:MODEF 0 "register_operand" "=x")
14190 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14191 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14192 UNSPEC_ROUND))]
14193 "TARGET_ROUND"
14194 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14195 [(set_attr "type" "ssecvt")
14196 (set_attr "prefix_extra" "1")
14197 (set_attr "prefix" "maybe_vex")
14198 (set_attr "mode" "<MODE>")])
14199
14200 (define_insn "rintxf2"
14201 [(set (match_operand:XF 0 "register_operand" "=f")
14202 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14203 UNSPEC_FRNDINT))]
14204 "TARGET_USE_FANCY_MATH_387
14205 && flag_unsafe_math_optimizations"
14206 "frndint"
14207 [(set_attr "type" "fpspc")
14208 (set_attr "mode" "XF")])
14209
14210 (define_expand "rint<mode>2"
14211 [(use (match_operand:MODEF 0 "register_operand"))
14212 (use (match_operand:MODEF 1 "register_operand"))]
14213 "(TARGET_USE_FANCY_MATH_387
14214 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14215 || TARGET_MIX_SSE_I387)
14216 && flag_unsafe_math_optimizations)
14217 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14218 && !flag_trapping_math)"
14219 {
14220 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14221 && !flag_trapping_math)
14222 {
14223 if (TARGET_ROUND)
14224 emit_insn (gen_sse4_1_round<mode>2
14225 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14226 else if (optimize_insn_for_size_p ())
14227 FAIL;
14228 else
14229 ix86_expand_rint (operands[0], operands[1]);
14230 }
14231 else
14232 {
14233 rtx op0 = gen_reg_rtx (XFmode);
14234 rtx op1 = gen_reg_rtx (XFmode);
14235
14236 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14237 emit_insn (gen_rintxf2 (op0, op1));
14238
14239 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14240 }
14241 DONE;
14242 })
14243
14244 (define_expand "round<mode>2"
14245 [(match_operand:X87MODEF 0 "register_operand")
14246 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14247 "(TARGET_USE_FANCY_MATH_387
14248 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14249 || TARGET_MIX_SSE_I387)
14250 && flag_unsafe_math_optimizations)
14251 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14252 && !flag_trapping_math && !flag_rounding_math)"
14253 {
14254 if (optimize_insn_for_size_p ())
14255 FAIL;
14256
14257 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14258 && !flag_trapping_math && !flag_rounding_math)
14259 {
14260 if (TARGET_ROUND)
14261 {
14262 operands[1] = force_reg (<MODE>mode, operands[1]);
14263 ix86_expand_round_sse4 (operands[0], operands[1]);
14264 }
14265 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14266 ix86_expand_round (operands[0], operands[1]);
14267 else
14268 ix86_expand_rounddf_32 (operands[0], operands[1]);
14269 }
14270 else
14271 {
14272 operands[1] = force_reg (<MODE>mode, operands[1]);
14273 ix86_emit_i387_round (operands[0], operands[1]);
14274 }
14275 DONE;
14276 })
14277
14278 (define_insn_and_split "*fistdi2_1"
14279 [(set (match_operand:DI 0 "nonimmediate_operand")
14280 (unspec:DI [(match_operand:XF 1 "register_operand")]
14281 UNSPEC_FIST))]
14282 "TARGET_USE_FANCY_MATH_387
14283 && can_create_pseudo_p ()"
14284 "#"
14285 "&& 1"
14286 [(const_int 0)]
14287 {
14288 if (memory_operand (operands[0], VOIDmode))
14289 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14290 else
14291 {
14292 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14293 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14294 operands[2]));
14295 }
14296 DONE;
14297 }
14298 [(set_attr "type" "fpspc")
14299 (set_attr "mode" "DI")])
14300
14301 (define_insn "fistdi2"
14302 [(set (match_operand:DI 0 "memory_operand" "=m")
14303 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14304 UNSPEC_FIST))
14305 (clobber (match_scratch:XF 2 "=&1f"))]
14306 "TARGET_USE_FANCY_MATH_387"
14307 "* return output_fix_trunc (insn, operands, false);"
14308 [(set_attr "type" "fpspc")
14309 (set_attr "mode" "DI")])
14310
14311 (define_insn "fistdi2_with_temp"
14312 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14313 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14314 UNSPEC_FIST))
14315 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14316 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14317 "TARGET_USE_FANCY_MATH_387"
14318 "#"
14319 [(set_attr "type" "fpspc")
14320 (set_attr "mode" "DI")])
14321
14322 (define_split
14323 [(set (match_operand:DI 0 "register_operand")
14324 (unspec:DI [(match_operand:XF 1 "register_operand")]
14325 UNSPEC_FIST))
14326 (clobber (match_operand:DI 2 "memory_operand"))
14327 (clobber (match_scratch 3))]
14328 "reload_completed"
14329 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14330 (clobber (match_dup 3))])
14331 (set (match_dup 0) (match_dup 2))])
14332
14333 (define_split
14334 [(set (match_operand:DI 0 "memory_operand")
14335 (unspec:DI [(match_operand:XF 1 "register_operand")]
14336 UNSPEC_FIST))
14337 (clobber (match_operand:DI 2 "memory_operand"))
14338 (clobber (match_scratch 3))]
14339 "reload_completed"
14340 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14341 (clobber (match_dup 3))])])
14342
14343 (define_insn_and_split "*fist<mode>2_1"
14344 [(set (match_operand:SWI24 0 "register_operand")
14345 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14346 UNSPEC_FIST))]
14347 "TARGET_USE_FANCY_MATH_387
14348 && can_create_pseudo_p ()"
14349 "#"
14350 "&& 1"
14351 [(const_int 0)]
14352 {
14353 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14354 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14355 operands[2]));
14356 DONE;
14357 }
14358 [(set_attr "type" "fpspc")
14359 (set_attr "mode" "<MODE>")])
14360
14361 (define_insn "fist<mode>2"
14362 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14363 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14364 UNSPEC_FIST))]
14365 "TARGET_USE_FANCY_MATH_387"
14366 "* return output_fix_trunc (insn, operands, false);"
14367 [(set_attr "type" "fpspc")
14368 (set_attr "mode" "<MODE>")])
14369
14370 (define_insn "fist<mode>2_with_temp"
14371 [(set (match_operand:SWI24 0 "register_operand" "=r")
14372 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14373 UNSPEC_FIST))
14374 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14375 "TARGET_USE_FANCY_MATH_387"
14376 "#"
14377 [(set_attr "type" "fpspc")
14378 (set_attr "mode" "<MODE>")])
14379
14380 (define_split
14381 [(set (match_operand:SWI24 0 "register_operand")
14382 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14383 UNSPEC_FIST))
14384 (clobber (match_operand:SWI24 2 "memory_operand"))]
14385 "reload_completed"
14386 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14387 (set (match_dup 0) (match_dup 2))])
14388
14389 (define_split
14390 [(set (match_operand:SWI24 0 "memory_operand")
14391 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14392 UNSPEC_FIST))
14393 (clobber (match_operand:SWI24 2 "memory_operand"))]
14394 "reload_completed"
14395 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14396
14397 (define_expand "lrintxf<mode>2"
14398 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14399 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14400 UNSPEC_FIST))]
14401 "TARGET_USE_FANCY_MATH_387")
14402
14403 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14404 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14405 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14406 UNSPEC_FIX_NOTRUNC))]
14407 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14408
14409 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14410 [(match_operand:SWI248x 0 "nonimmediate_operand")
14411 (match_operand:X87MODEF 1 "register_operand")]
14412 "(TARGET_USE_FANCY_MATH_387
14413 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14414 || TARGET_MIX_SSE_I387)
14415 && flag_unsafe_math_optimizations)
14416 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14417 && <SWI248x:MODE>mode != HImode
14418 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14419 && !flag_trapping_math && !flag_rounding_math)"
14420 {
14421 if (optimize_insn_for_size_p ())
14422 FAIL;
14423
14424 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14425 && <SWI248x:MODE>mode != HImode
14426 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14427 && !flag_trapping_math && !flag_rounding_math)
14428 ix86_expand_lround (operands[0], operands[1]);
14429 else
14430 ix86_emit_i387_round (operands[0], operands[1]);
14431 DONE;
14432 })
14433
14434 (define_int_iterator FRNDINT_ROUNDING
14435 [UNSPEC_FRNDINT_FLOOR
14436 UNSPEC_FRNDINT_CEIL
14437 UNSPEC_FRNDINT_TRUNC])
14438
14439 (define_int_iterator FIST_ROUNDING
14440 [UNSPEC_FIST_FLOOR
14441 UNSPEC_FIST_CEIL])
14442
14443 ;; Base name for define_insn
14444 (define_int_attr rounding_insn
14445 [(UNSPEC_FRNDINT_FLOOR "floor")
14446 (UNSPEC_FRNDINT_CEIL "ceil")
14447 (UNSPEC_FRNDINT_TRUNC "btrunc")
14448 (UNSPEC_FIST_FLOOR "floor")
14449 (UNSPEC_FIST_CEIL "ceil")])
14450
14451 (define_int_attr rounding
14452 [(UNSPEC_FRNDINT_FLOOR "floor")
14453 (UNSPEC_FRNDINT_CEIL "ceil")
14454 (UNSPEC_FRNDINT_TRUNC "trunc")
14455 (UNSPEC_FIST_FLOOR "floor")
14456 (UNSPEC_FIST_CEIL "ceil")])
14457
14458 (define_int_attr ROUNDING
14459 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14460 (UNSPEC_FRNDINT_CEIL "CEIL")
14461 (UNSPEC_FRNDINT_TRUNC "TRUNC")
14462 (UNSPEC_FIST_FLOOR "FLOOR")
14463 (UNSPEC_FIST_CEIL "CEIL")])
14464
14465 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14466 (define_insn_and_split "frndintxf2_<rounding>"
14467 [(set (match_operand:XF 0 "register_operand")
14468 (unspec:XF [(match_operand:XF 1 "register_operand")]
14469 FRNDINT_ROUNDING))
14470 (clobber (reg:CC FLAGS_REG))]
14471 "TARGET_USE_FANCY_MATH_387
14472 && flag_unsafe_math_optimizations
14473 && can_create_pseudo_p ()"
14474 "#"
14475 "&& 1"
14476 [(const_int 0)]
14477 {
14478 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14479
14480 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14481 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14482
14483 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14484 operands[2], operands[3]));
14485 DONE;
14486 }
14487 [(set_attr "type" "frndint")
14488 (set_attr "i387_cw" "<rounding>")
14489 (set_attr "mode" "XF")])
14490
14491 (define_insn "frndintxf2_<rounding>_i387"
14492 [(set (match_operand:XF 0 "register_operand" "=f")
14493 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14494 FRNDINT_ROUNDING))
14495 (use (match_operand:HI 2 "memory_operand" "m"))
14496 (use (match_operand:HI 3 "memory_operand" "m"))]
14497 "TARGET_USE_FANCY_MATH_387
14498 && flag_unsafe_math_optimizations"
14499 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14500 [(set_attr "type" "frndint")
14501 (set_attr "i387_cw" "<rounding>")
14502 (set_attr "mode" "XF")])
14503
14504 (define_expand "<rounding_insn>xf2"
14505 [(parallel [(set (match_operand:XF 0 "register_operand")
14506 (unspec:XF [(match_operand:XF 1 "register_operand")]
14507 FRNDINT_ROUNDING))
14508 (clobber (reg:CC FLAGS_REG))])]
14509 "TARGET_USE_FANCY_MATH_387
14510 && flag_unsafe_math_optimizations
14511 && !optimize_insn_for_size_p ()")
14512
14513 (define_expand "<rounding_insn><mode>2"
14514 [(parallel [(set (match_operand:MODEF 0 "register_operand")
14515 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
14516 FRNDINT_ROUNDING))
14517 (clobber (reg:CC FLAGS_REG))])]
14518 "(TARGET_USE_FANCY_MATH_387
14519 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14520 || TARGET_MIX_SSE_I387)
14521 && flag_unsafe_math_optimizations)
14522 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14523 && !flag_trapping_math)"
14524 {
14525 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14526 && !flag_trapping_math)
14527 {
14528 if (TARGET_ROUND)
14529 emit_insn (gen_sse4_1_round<mode>2
14530 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
14531 else if (optimize_insn_for_size_p ())
14532 FAIL;
14533 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14534 {
14535 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14536 ix86_expand_floorceil (operands[0], operands[1], true);
14537 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14538 ix86_expand_floorceil (operands[0], operands[1], false);
14539 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14540 ix86_expand_trunc (operands[0], operands[1]);
14541 else
14542 gcc_unreachable ();
14543 }
14544 else
14545 {
14546 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14547 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14548 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14549 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
14550 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14551 ix86_expand_truncdf_32 (operands[0], operands[1]);
14552 else
14553 gcc_unreachable ();
14554 }
14555 }
14556 else
14557 {
14558 rtx op0, op1;
14559
14560 if (optimize_insn_for_size_p ())
14561 FAIL;
14562
14563 op0 = gen_reg_rtx (XFmode);
14564 op1 = gen_reg_rtx (XFmode);
14565 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14566 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
14567
14568 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14569 }
14570 DONE;
14571 })
14572
14573 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14574 (define_insn_and_split "frndintxf2_mask_pm"
14575 [(set (match_operand:XF 0 "register_operand")
14576 (unspec:XF [(match_operand:XF 1 "register_operand")]
14577 UNSPEC_FRNDINT_MASK_PM))
14578 (clobber (reg:CC FLAGS_REG))]
14579 "TARGET_USE_FANCY_MATH_387
14580 && flag_unsafe_math_optimizations
14581 && can_create_pseudo_p ()"
14582 "#"
14583 "&& 1"
14584 [(const_int 0)]
14585 {
14586 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14587
14588 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14589 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14590
14591 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14592 operands[2], operands[3]));
14593 DONE;
14594 }
14595 [(set_attr "type" "frndint")
14596 (set_attr "i387_cw" "mask_pm")
14597 (set_attr "mode" "XF")])
14598
14599 (define_insn "frndintxf2_mask_pm_i387"
14600 [(set (match_operand:XF 0 "register_operand" "=f")
14601 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14602 UNSPEC_FRNDINT_MASK_PM))
14603 (use (match_operand:HI 2 "memory_operand" "m"))
14604 (use (match_operand:HI 3 "memory_operand" "m"))]
14605 "TARGET_USE_FANCY_MATH_387
14606 && flag_unsafe_math_optimizations"
14607 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14608 [(set_attr "type" "frndint")
14609 (set_attr "i387_cw" "mask_pm")
14610 (set_attr "mode" "XF")])
14611
14612 (define_expand "nearbyintxf2"
14613 [(parallel [(set (match_operand:XF 0 "register_operand")
14614 (unspec:XF [(match_operand:XF 1 "register_operand")]
14615 UNSPEC_FRNDINT_MASK_PM))
14616 (clobber (reg:CC FLAGS_REG))])]
14617 "TARGET_USE_FANCY_MATH_387
14618 && flag_unsafe_math_optimizations")
14619
14620 (define_expand "nearbyint<mode>2"
14621 [(use (match_operand:MODEF 0 "register_operand"))
14622 (use (match_operand:MODEF 1 "register_operand"))]
14623 "TARGET_USE_FANCY_MATH_387
14624 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14625 || TARGET_MIX_SSE_I387)
14626 && flag_unsafe_math_optimizations"
14627 {
14628 rtx op0 = gen_reg_rtx (XFmode);
14629 rtx op1 = gen_reg_rtx (XFmode);
14630
14631 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14632 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14633
14634 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14635 DONE;
14636 })
14637
14638 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14639 (define_insn_and_split "*fist<mode>2_<rounding>_1"
14640 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14641 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14642 FIST_ROUNDING))
14643 (clobber (reg:CC FLAGS_REG))]
14644 "TARGET_USE_FANCY_MATH_387
14645 && flag_unsafe_math_optimizations
14646 && can_create_pseudo_p ()"
14647 "#"
14648 "&& 1"
14649 [(const_int 0)]
14650 {
14651 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14652
14653 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14654 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14655 if (memory_operand (operands[0], VOIDmode))
14656 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
14657 operands[2], operands[3]));
14658 else
14659 {
14660 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14661 emit_insn (gen_fist<mode>2_<rounding>_with_temp
14662 (operands[0], operands[1], operands[2],
14663 operands[3], operands[4]));
14664 }
14665 DONE;
14666 }
14667 [(set_attr "type" "fistp")
14668 (set_attr "i387_cw" "<rounding>")
14669 (set_attr "mode" "<MODE>")])
14670
14671 (define_insn "fistdi2_<rounding>"
14672 [(set (match_operand:DI 0 "memory_operand" "=m")
14673 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14674 FIST_ROUNDING))
14675 (use (match_operand:HI 2 "memory_operand" "m"))
14676 (use (match_operand:HI 3 "memory_operand" "m"))
14677 (clobber (match_scratch:XF 4 "=&1f"))]
14678 "TARGET_USE_FANCY_MATH_387
14679 && flag_unsafe_math_optimizations"
14680 "* return output_fix_trunc (insn, operands, false);"
14681 [(set_attr "type" "fistp")
14682 (set_attr "i387_cw" "<rounding>")
14683 (set_attr "mode" "DI")])
14684
14685 (define_insn "fistdi2_<rounding>_with_temp"
14686 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14687 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14688 FIST_ROUNDING))
14689 (use (match_operand:HI 2 "memory_operand" "m,m"))
14690 (use (match_operand:HI 3 "memory_operand" "m,m"))
14691 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14692 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14693 "TARGET_USE_FANCY_MATH_387
14694 && flag_unsafe_math_optimizations"
14695 "#"
14696 [(set_attr "type" "fistp")
14697 (set_attr "i387_cw" "<rounding>")
14698 (set_attr "mode" "DI")])
14699
14700 (define_split
14701 [(set (match_operand:DI 0 "register_operand")
14702 (unspec:DI [(match_operand:XF 1 "register_operand")]
14703 FIST_ROUNDING))
14704 (use (match_operand:HI 2 "memory_operand"))
14705 (use (match_operand:HI 3 "memory_operand"))
14706 (clobber (match_operand:DI 4 "memory_operand"))
14707 (clobber (match_scratch 5))]
14708 "reload_completed"
14709 [(parallel [(set (match_dup 4)
14710 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14711 (use (match_dup 2))
14712 (use (match_dup 3))
14713 (clobber (match_dup 5))])
14714 (set (match_dup 0) (match_dup 4))])
14715
14716 (define_split
14717 [(set (match_operand:DI 0 "memory_operand")
14718 (unspec:DI [(match_operand:XF 1 "register_operand")]
14719 FIST_ROUNDING))
14720 (use (match_operand:HI 2 "memory_operand"))
14721 (use (match_operand:HI 3 "memory_operand"))
14722 (clobber (match_operand:DI 4 "memory_operand"))
14723 (clobber (match_scratch 5))]
14724 "reload_completed"
14725 [(parallel [(set (match_dup 0)
14726 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14727 (use (match_dup 2))
14728 (use (match_dup 3))
14729 (clobber (match_dup 5))])])
14730
14731 (define_insn "fist<mode>2_<rounding>"
14732 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14733 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14734 FIST_ROUNDING))
14735 (use (match_operand:HI 2 "memory_operand" "m"))
14736 (use (match_operand:HI 3 "memory_operand" "m"))]
14737 "TARGET_USE_FANCY_MATH_387
14738 && flag_unsafe_math_optimizations"
14739 "* return output_fix_trunc (insn, operands, false);"
14740 [(set_attr "type" "fistp")
14741 (set_attr "i387_cw" "<rounding>")
14742 (set_attr "mode" "<MODE>")])
14743
14744 (define_insn "fist<mode>2_<rounding>_with_temp"
14745 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14746 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14747 FIST_ROUNDING))
14748 (use (match_operand:HI 2 "memory_operand" "m,m"))
14749 (use (match_operand:HI 3 "memory_operand" "m,m"))
14750 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14751 "TARGET_USE_FANCY_MATH_387
14752 && flag_unsafe_math_optimizations"
14753 "#"
14754 [(set_attr "type" "fistp")
14755 (set_attr "i387_cw" "<rounding>")
14756 (set_attr "mode" "<MODE>")])
14757
14758 (define_split
14759 [(set (match_operand:SWI24 0 "register_operand")
14760 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14761 FIST_ROUNDING))
14762 (use (match_operand:HI 2 "memory_operand"))
14763 (use (match_operand:HI 3 "memory_operand"))
14764 (clobber (match_operand:SWI24 4 "memory_operand"))]
14765 "reload_completed"
14766 [(parallel [(set (match_dup 4)
14767 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14768 (use (match_dup 2))
14769 (use (match_dup 3))])
14770 (set (match_dup 0) (match_dup 4))])
14771
14772 (define_split
14773 [(set (match_operand:SWI24 0 "memory_operand")
14774 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14775 FIST_ROUNDING))
14776 (use (match_operand:HI 2 "memory_operand"))
14777 (use (match_operand:HI 3 "memory_operand"))
14778 (clobber (match_operand:SWI24 4 "memory_operand"))]
14779 "reload_completed"
14780 [(parallel [(set (match_dup 0)
14781 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14782 (use (match_dup 2))
14783 (use (match_dup 3))])])
14784
14785 (define_expand "l<rounding_insn>xf<mode>2"
14786 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14787 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14788 FIST_ROUNDING))
14789 (clobber (reg:CC FLAGS_REG))])]
14790 "TARGET_USE_FANCY_MATH_387
14791 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14792 && flag_unsafe_math_optimizations")
14793
14794 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
14795 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
14796 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14797 FIST_ROUNDING))
14798 (clobber (reg:CC FLAGS_REG))])]
14799 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14800 && !flag_trapping_math"
14801 {
14802 if (TARGET_64BIT && optimize_insn_for_size_p ())
14803 FAIL;
14804
14805 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14806 ix86_expand_lfloorceil (operands[0], operands[1], true);
14807 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14808 ix86_expand_lfloorceil (operands[0], operands[1], false);
14809 else
14810 gcc_unreachable ();
14811
14812 DONE;
14813 })
14814
14815 (define_insn "fxam<mode>2_i387"
14816 [(set (match_operand:HI 0 "register_operand" "=a")
14817 (unspec:HI
14818 [(match_operand:X87MODEF 1 "register_operand" "f")]
14819 UNSPEC_FXAM))]
14820 "TARGET_USE_FANCY_MATH_387"
14821 "fxam\n\tfnstsw\t%0"
14822 [(set_attr "type" "multi")
14823 (set_attr "length" "4")
14824 (set_attr "unit" "i387")
14825 (set_attr "mode" "<MODE>")])
14826
14827 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14828 [(set (match_operand:HI 0 "register_operand")
14829 (unspec:HI
14830 [(match_operand:MODEF 1 "memory_operand")]
14831 UNSPEC_FXAM_MEM))]
14832 "TARGET_USE_FANCY_MATH_387
14833 && can_create_pseudo_p ()"
14834 "#"
14835 "&& 1"
14836 [(set (match_dup 2)(match_dup 1))
14837 (set (match_dup 0)
14838 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14839 {
14840 operands[2] = gen_reg_rtx (<MODE>mode);
14841
14842 MEM_VOLATILE_P (operands[1]) = 1;
14843 }
14844 [(set_attr "type" "multi")
14845 (set_attr "unit" "i387")
14846 (set_attr "mode" "<MODE>")])
14847
14848 (define_expand "isinfxf2"
14849 [(use (match_operand:SI 0 "register_operand"))
14850 (use (match_operand:XF 1 "register_operand"))]
14851 "TARGET_USE_FANCY_MATH_387
14852 && TARGET_C99_FUNCTIONS"
14853 {
14854 rtx mask = GEN_INT (0x45);
14855 rtx val = GEN_INT (0x05);
14856
14857 rtx cond;
14858
14859 rtx scratch = gen_reg_rtx (HImode);
14860 rtx res = gen_reg_rtx (QImode);
14861
14862 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14863
14864 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14865 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14866 cond = gen_rtx_fmt_ee (EQ, QImode,
14867 gen_rtx_REG (CCmode, FLAGS_REG),
14868 const0_rtx);
14869 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14870 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14871 DONE;
14872 })
14873
14874 (define_expand "isinf<mode>2"
14875 [(use (match_operand:SI 0 "register_operand"))
14876 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
14877 "TARGET_USE_FANCY_MATH_387
14878 && TARGET_C99_FUNCTIONS
14879 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14880 {
14881 rtx mask = GEN_INT (0x45);
14882 rtx val = GEN_INT (0x05);
14883
14884 rtx cond;
14885
14886 rtx scratch = gen_reg_rtx (HImode);
14887 rtx res = gen_reg_rtx (QImode);
14888
14889 /* Remove excess precision by forcing value through memory. */
14890 if (memory_operand (operands[1], VOIDmode))
14891 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14892 else
14893 {
14894 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14895
14896 emit_move_insn (temp, operands[1]);
14897 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
14898 }
14899
14900 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14901 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14902 cond = gen_rtx_fmt_ee (EQ, QImode,
14903 gen_rtx_REG (CCmode, FLAGS_REG),
14904 const0_rtx);
14905 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14906 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14907 DONE;
14908 })
14909
14910 (define_expand "signbitxf2"
14911 [(use (match_operand:SI 0 "register_operand"))
14912 (use (match_operand:XF 1 "register_operand"))]
14913 "TARGET_USE_FANCY_MATH_387"
14914 {
14915 rtx scratch = gen_reg_rtx (HImode);
14916
14917 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14918 emit_insn (gen_andsi3 (operands[0],
14919 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14920 DONE;
14921 })
14922
14923 (define_insn "movmsk_df"
14924 [(set (match_operand:SI 0 "register_operand" "=r")
14925 (unspec:SI
14926 [(match_operand:DF 1 "register_operand" "x")]
14927 UNSPEC_MOVMSK))]
14928 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
14929 "%vmovmskpd\t{%1, %0|%0, %1}"
14930 [(set_attr "type" "ssemov")
14931 (set_attr "prefix" "maybe_vex")
14932 (set_attr "mode" "DF")])
14933
14934 ;; Use movmskpd in SSE mode to avoid store forwarding stall
14935 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
14936 (define_expand "signbitdf2"
14937 [(use (match_operand:SI 0 "register_operand"))
14938 (use (match_operand:DF 1 "register_operand"))]
14939 "TARGET_USE_FANCY_MATH_387
14940 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14941 {
14942 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
14943 {
14944 emit_insn (gen_movmsk_df (operands[0], operands[1]));
14945 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
14946 }
14947 else
14948 {
14949 rtx scratch = gen_reg_rtx (HImode);
14950
14951 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
14952 emit_insn (gen_andsi3 (operands[0],
14953 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14954 }
14955 DONE;
14956 })
14957
14958 (define_expand "signbitsf2"
14959 [(use (match_operand:SI 0 "register_operand"))
14960 (use (match_operand:SF 1 "register_operand"))]
14961 "TARGET_USE_FANCY_MATH_387
14962 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
14963 {
14964 rtx scratch = gen_reg_rtx (HImode);
14965
14966 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
14967 emit_insn (gen_andsi3 (operands[0],
14968 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14969 DONE;
14970 })
14971 \f
14972 ;; Block operation instructions
14973
14974 (define_insn "cld"
14975 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
14976 ""
14977 "cld"
14978 [(set_attr "length" "1")
14979 (set_attr "length_immediate" "0")
14980 (set_attr "modrm" "0")])
14981
14982 (define_expand "movmem<mode>"
14983 [(use (match_operand:BLK 0 "memory_operand"))
14984 (use (match_operand:BLK 1 "memory_operand"))
14985 (use (match_operand:SWI48 2 "nonmemory_operand"))
14986 (use (match_operand:SWI48 3 "const_int_operand"))
14987 (use (match_operand:SI 4 "const_int_operand"))
14988 (use (match_operand:SI 5 "const_int_operand"))]
14989 ""
14990 {
14991 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14992 operands[4], operands[5]))
14993 DONE;
14994 else
14995 FAIL;
14996 })
14997
14998 ;; Most CPUs don't like single string operations
14999 ;; Handle this case here to simplify previous expander.
15000
15001 (define_expand "strmov"
15002 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15003 (set (match_operand 1 "memory_operand") (match_dup 4))
15004 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15005 (clobber (reg:CC FLAGS_REG))])
15006 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15007 (clobber (reg:CC FLAGS_REG))])]
15008 ""
15009 {
15010 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15011
15012 /* If .md ever supports :P for Pmode, these can be directly
15013 in the pattern above. */
15014 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15015 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15016
15017 /* Can't use this if the user has appropriated esi or edi. */
15018 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15019 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15020 {
15021 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15022 operands[2], operands[3],
15023 operands[5], operands[6]));
15024 DONE;
15025 }
15026
15027 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15028 })
15029
15030 (define_expand "strmov_singleop"
15031 [(parallel [(set (match_operand 1 "memory_operand")
15032 (match_operand 3 "memory_operand"))
15033 (set (match_operand 0 "register_operand")
15034 (match_operand 4))
15035 (set (match_operand 2 "register_operand")
15036 (match_operand 5))])]
15037 ""
15038 "ix86_current_function_needs_cld = 1;")
15039
15040 (define_insn "*strmovdi_rex_1"
15041 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15042 (mem:DI (match_operand:P 3 "register_operand" "1")))
15043 (set (match_operand:P 0 "register_operand" "=D")
15044 (plus:P (match_dup 2)
15045 (const_int 8)))
15046 (set (match_operand:P 1 "register_operand" "=S")
15047 (plus:P (match_dup 3)
15048 (const_int 8)))]
15049 "TARGET_64BIT
15050 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15051 "%^movsq"
15052 [(set_attr "type" "str")
15053 (set_attr "memory" "both")
15054 (set_attr "mode" "DI")])
15055
15056 (define_insn "*strmovsi_1"
15057 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15058 (mem:SI (match_operand:P 3 "register_operand" "1")))
15059 (set (match_operand:P 0 "register_operand" "=D")
15060 (plus:P (match_dup 2)
15061 (const_int 4)))
15062 (set (match_operand:P 1 "register_operand" "=S")
15063 (plus:P (match_dup 3)
15064 (const_int 4)))]
15065 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15066 "%^movs{l|d}"
15067 [(set_attr "type" "str")
15068 (set_attr "memory" "both")
15069 (set_attr "mode" "SI")])
15070
15071 (define_insn "*strmovhi_1"
15072 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15073 (mem:HI (match_operand:P 3 "register_operand" "1")))
15074 (set (match_operand:P 0 "register_operand" "=D")
15075 (plus:P (match_dup 2)
15076 (const_int 2)))
15077 (set (match_operand:P 1 "register_operand" "=S")
15078 (plus:P (match_dup 3)
15079 (const_int 2)))]
15080 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15081 "%^movsw"
15082 [(set_attr "type" "str")
15083 (set_attr "memory" "both")
15084 (set_attr "mode" "HI")])
15085
15086 (define_insn "*strmovqi_1"
15087 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15088 (mem:QI (match_operand:P 3 "register_operand" "1")))
15089 (set (match_operand:P 0 "register_operand" "=D")
15090 (plus:P (match_dup 2)
15091 (const_int 1)))
15092 (set (match_operand:P 1 "register_operand" "=S")
15093 (plus:P (match_dup 3)
15094 (const_int 1)))]
15095 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15096 "%^movsb"
15097 [(set_attr "type" "str")
15098 (set_attr "memory" "both")
15099 (set (attr "prefix_rex")
15100 (if_then_else
15101 (match_test "<P:MODE>mode == DImode")
15102 (const_string "0")
15103 (const_string "*")))
15104 (set_attr "mode" "QI")])
15105
15106 (define_expand "rep_mov"
15107 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15108 (set (match_operand 0 "register_operand")
15109 (match_operand 5))
15110 (set (match_operand 2 "register_operand")
15111 (match_operand 6))
15112 (set (match_operand 1 "memory_operand")
15113 (match_operand 3 "memory_operand"))
15114 (use (match_dup 4))])]
15115 ""
15116 "ix86_current_function_needs_cld = 1;")
15117
15118 (define_insn "*rep_movdi_rex64"
15119 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15120 (set (match_operand:P 0 "register_operand" "=D")
15121 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15122 (const_int 3))
15123 (match_operand:P 3 "register_operand" "0")))
15124 (set (match_operand:P 1 "register_operand" "=S")
15125 (plus:P (ashift:P (match_dup 5) (const_int 3))
15126 (match_operand:P 4 "register_operand" "1")))
15127 (set (mem:BLK (match_dup 3))
15128 (mem:BLK (match_dup 4)))
15129 (use (match_dup 5))]
15130 "TARGET_64BIT
15131 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15132 "%^rep{%;} movsq"
15133 [(set_attr "type" "str")
15134 (set_attr "prefix_rep" "1")
15135 (set_attr "memory" "both")
15136 (set_attr "mode" "DI")])
15137
15138 (define_insn "*rep_movsi"
15139 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15140 (set (match_operand:P 0 "register_operand" "=D")
15141 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15142 (const_int 2))
15143 (match_operand:P 3 "register_operand" "0")))
15144 (set (match_operand:P 1 "register_operand" "=S")
15145 (plus:P (ashift:P (match_dup 5) (const_int 2))
15146 (match_operand:P 4 "register_operand" "1")))
15147 (set (mem:BLK (match_dup 3))
15148 (mem:BLK (match_dup 4)))
15149 (use (match_dup 5))]
15150 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15151 "%^rep{%;} movs{l|d}"
15152 [(set_attr "type" "str")
15153 (set_attr "prefix_rep" "1")
15154 (set_attr "memory" "both")
15155 (set_attr "mode" "SI")])
15156
15157 (define_insn "*rep_movqi"
15158 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15159 (set (match_operand:P 0 "register_operand" "=D")
15160 (plus:P (match_operand:P 3 "register_operand" "0")
15161 (match_operand:P 5 "register_operand" "2")))
15162 (set (match_operand:P 1 "register_operand" "=S")
15163 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15164 (set (mem:BLK (match_dup 3))
15165 (mem:BLK (match_dup 4)))
15166 (use (match_dup 5))]
15167 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15168 "%^rep{%;} movsb"
15169 [(set_attr "type" "str")
15170 (set_attr "prefix_rep" "1")
15171 (set_attr "memory" "both")
15172 (set_attr "mode" "QI")])
15173
15174 (define_expand "setmem<mode>"
15175 [(use (match_operand:BLK 0 "memory_operand"))
15176 (use (match_operand:SWI48 1 "nonmemory_operand"))
15177 (use (match_operand:QI 2 "nonmemory_operand"))
15178 (use (match_operand 3 "const_int_operand"))
15179 (use (match_operand:SI 4 "const_int_operand"))
15180 (use (match_operand:SI 5 "const_int_operand"))]
15181 ""
15182 {
15183 if (ix86_expand_setmem (operands[0], operands[1],
15184 operands[2], operands[3],
15185 operands[4], operands[5]))
15186 DONE;
15187 else
15188 FAIL;
15189 })
15190
15191 ;; Most CPUs don't like single string operations
15192 ;; Handle this case here to simplify previous expander.
15193
15194 (define_expand "strset"
15195 [(set (match_operand 1 "memory_operand")
15196 (match_operand 2 "register_operand"))
15197 (parallel [(set (match_operand 0 "register_operand")
15198 (match_dup 3))
15199 (clobber (reg:CC FLAGS_REG))])]
15200 ""
15201 {
15202 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15203 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15204
15205 /* If .md ever supports :P for Pmode, this can be directly
15206 in the pattern above. */
15207 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15208 GEN_INT (GET_MODE_SIZE (GET_MODE
15209 (operands[2]))));
15210 /* Can't use this if the user has appropriated eax or edi. */
15211 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15212 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15213 {
15214 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15215 operands[3]));
15216 DONE;
15217 }
15218 })
15219
15220 (define_expand "strset_singleop"
15221 [(parallel [(set (match_operand 1 "memory_operand")
15222 (match_operand 2 "register_operand"))
15223 (set (match_operand 0 "register_operand")
15224 (match_operand 3))
15225 (unspec [(const_int 0)] UNSPEC_STOS)])]
15226 ""
15227 "ix86_current_function_needs_cld = 1;")
15228
15229 (define_insn "*strsetdi_rex_1"
15230 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15231 (match_operand:DI 2 "register_operand" "a"))
15232 (set (match_operand:P 0 "register_operand" "=D")
15233 (plus:P (match_dup 1)
15234 (const_int 8)))
15235 (unspec [(const_int 0)] UNSPEC_STOS)]
15236 "TARGET_64BIT
15237 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15238 "%^stosq"
15239 [(set_attr "type" "str")
15240 (set_attr "memory" "store")
15241 (set_attr "mode" "DI")])
15242
15243 (define_insn "*strsetsi_1"
15244 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15245 (match_operand:SI 2 "register_operand" "a"))
15246 (set (match_operand:P 0 "register_operand" "=D")
15247 (plus:P (match_dup 1)
15248 (const_int 4)))
15249 (unspec [(const_int 0)] UNSPEC_STOS)]
15250 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15251 "%^stos{l|d}"
15252 [(set_attr "type" "str")
15253 (set_attr "memory" "store")
15254 (set_attr "mode" "SI")])
15255
15256 (define_insn "*strsethi_1"
15257 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15258 (match_operand:HI 2 "register_operand" "a"))
15259 (set (match_operand:P 0 "register_operand" "=D")
15260 (plus:P (match_dup 1)
15261 (const_int 2)))
15262 (unspec [(const_int 0)] UNSPEC_STOS)]
15263 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15264 "%^stosw"
15265 [(set_attr "type" "str")
15266 (set_attr "memory" "store")
15267 (set_attr "mode" "HI")])
15268
15269 (define_insn "*strsetqi_1"
15270 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15271 (match_operand:QI 2 "register_operand" "a"))
15272 (set (match_operand:P 0 "register_operand" "=D")
15273 (plus:P (match_dup 1)
15274 (const_int 1)))
15275 (unspec [(const_int 0)] UNSPEC_STOS)]
15276 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15277 "%^stosb"
15278 [(set_attr "type" "str")
15279 (set_attr "memory" "store")
15280 (set (attr "prefix_rex")
15281 (if_then_else
15282 (match_test "<P:MODE>mode == DImode")
15283 (const_string "0")
15284 (const_string "*")))
15285 (set_attr "mode" "QI")])
15286
15287 (define_expand "rep_stos"
15288 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15289 (set (match_operand 0 "register_operand")
15290 (match_operand 4))
15291 (set (match_operand 2 "memory_operand") (const_int 0))
15292 (use (match_operand 3 "register_operand"))
15293 (use (match_dup 1))])]
15294 ""
15295 "ix86_current_function_needs_cld = 1;")
15296
15297 (define_insn "*rep_stosdi_rex64"
15298 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15299 (set (match_operand:P 0 "register_operand" "=D")
15300 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15301 (const_int 3))
15302 (match_operand:P 3 "register_operand" "0")))
15303 (set (mem:BLK (match_dup 3))
15304 (const_int 0))
15305 (use (match_operand:DI 2 "register_operand" "a"))
15306 (use (match_dup 4))]
15307 "TARGET_64BIT
15308 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15309 "%^rep{%;} stosq"
15310 [(set_attr "type" "str")
15311 (set_attr "prefix_rep" "1")
15312 (set_attr "memory" "store")
15313 (set_attr "mode" "DI")])
15314
15315 (define_insn "*rep_stossi"
15316 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15317 (set (match_operand:P 0 "register_operand" "=D")
15318 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15319 (const_int 2))
15320 (match_operand:P 3 "register_operand" "0")))
15321 (set (mem:BLK (match_dup 3))
15322 (const_int 0))
15323 (use (match_operand:SI 2 "register_operand" "a"))
15324 (use (match_dup 4))]
15325 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15326 "%^rep{%;} stos{l|d}"
15327 [(set_attr "type" "str")
15328 (set_attr "prefix_rep" "1")
15329 (set_attr "memory" "store")
15330 (set_attr "mode" "SI")])
15331
15332 (define_insn "*rep_stosqi"
15333 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15334 (set (match_operand:P 0 "register_operand" "=D")
15335 (plus:P (match_operand:P 3 "register_operand" "0")
15336 (match_operand:P 4 "register_operand" "1")))
15337 (set (mem:BLK (match_dup 3))
15338 (const_int 0))
15339 (use (match_operand:QI 2 "register_operand" "a"))
15340 (use (match_dup 4))]
15341 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15342 "%^rep{%;} stosb"
15343 [(set_attr "type" "str")
15344 (set_attr "prefix_rep" "1")
15345 (set_attr "memory" "store")
15346 (set (attr "prefix_rex")
15347 (if_then_else
15348 (match_test "<P:MODE>mode == DImode")
15349 (const_string "0")
15350 (const_string "*")))
15351 (set_attr "mode" "QI")])
15352
15353 (define_expand "cmpstrnsi"
15354 [(set (match_operand:SI 0 "register_operand")
15355 (compare:SI (match_operand:BLK 1 "general_operand")
15356 (match_operand:BLK 2 "general_operand")))
15357 (use (match_operand 3 "general_operand"))
15358 (use (match_operand 4 "immediate_operand"))]
15359 ""
15360 {
15361 rtx addr1, addr2, out, outlow, count, countreg, align;
15362
15363 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15364 FAIL;
15365
15366 /* Can't use this if the user has appropriated ecx, esi or edi. */
15367 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15368 FAIL;
15369
15370 out = operands[0];
15371 if (!REG_P (out))
15372 out = gen_reg_rtx (SImode);
15373
15374 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15375 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15376 if (addr1 != XEXP (operands[1], 0))
15377 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15378 if (addr2 != XEXP (operands[2], 0))
15379 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15380
15381 count = operands[3];
15382 countreg = ix86_zero_extend_to_Pmode (count);
15383
15384 /* %%% Iff we are testing strict equality, we can use known alignment
15385 to good advantage. This may be possible with combine, particularly
15386 once cc0 is dead. */
15387 align = operands[4];
15388
15389 if (CONST_INT_P (count))
15390 {
15391 if (INTVAL (count) == 0)
15392 {
15393 emit_move_insn (operands[0], const0_rtx);
15394 DONE;
15395 }
15396 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15397 operands[1], operands[2]));
15398 }
15399 else
15400 {
15401 rtx (*gen_cmp) (rtx, rtx);
15402
15403 gen_cmp = (TARGET_64BIT
15404 ? gen_cmpdi_1 : gen_cmpsi_1);
15405
15406 emit_insn (gen_cmp (countreg, countreg));
15407 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15408 operands[1], operands[2]));
15409 }
15410
15411 outlow = gen_lowpart (QImode, out);
15412 emit_insn (gen_cmpintqi (outlow));
15413 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15414
15415 if (operands[0] != out)
15416 emit_move_insn (operands[0], out);
15417
15418 DONE;
15419 })
15420
15421 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15422
15423 (define_expand "cmpintqi"
15424 [(set (match_dup 1)
15425 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15426 (set (match_dup 2)
15427 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15428 (parallel [(set (match_operand:QI 0 "register_operand")
15429 (minus:QI (match_dup 1)
15430 (match_dup 2)))
15431 (clobber (reg:CC FLAGS_REG))])]
15432 ""
15433 {
15434 operands[1] = gen_reg_rtx (QImode);
15435 operands[2] = gen_reg_rtx (QImode);
15436 })
15437
15438 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15439 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15440
15441 (define_expand "cmpstrnqi_nz_1"
15442 [(parallel [(set (reg:CC FLAGS_REG)
15443 (compare:CC (match_operand 4 "memory_operand")
15444 (match_operand 5 "memory_operand")))
15445 (use (match_operand 2 "register_operand"))
15446 (use (match_operand:SI 3 "immediate_operand"))
15447 (clobber (match_operand 0 "register_operand"))
15448 (clobber (match_operand 1 "register_operand"))
15449 (clobber (match_dup 2))])]
15450 ""
15451 "ix86_current_function_needs_cld = 1;")
15452
15453 (define_insn "*cmpstrnqi_nz_1"
15454 [(set (reg:CC FLAGS_REG)
15455 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15456 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15457 (use (match_operand:P 6 "register_operand" "2"))
15458 (use (match_operand:SI 3 "immediate_operand" "i"))
15459 (clobber (match_operand:P 0 "register_operand" "=S"))
15460 (clobber (match_operand:P 1 "register_operand" "=D"))
15461 (clobber (match_operand:P 2 "register_operand" "=c"))]
15462 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15463 "%^repz{%;} cmpsb"
15464 [(set_attr "type" "str")
15465 (set_attr "mode" "QI")
15466 (set (attr "prefix_rex")
15467 (if_then_else
15468 (match_test "<P:MODE>mode == DImode")
15469 (const_string "0")
15470 (const_string "*")))
15471 (set_attr "prefix_rep" "1")])
15472
15473 ;; The same, but the count is not known to not be zero.
15474
15475 (define_expand "cmpstrnqi_1"
15476 [(parallel [(set (reg:CC FLAGS_REG)
15477 (if_then_else:CC (ne (match_operand 2 "register_operand")
15478 (const_int 0))
15479 (compare:CC (match_operand 4 "memory_operand")
15480 (match_operand 5 "memory_operand"))
15481 (const_int 0)))
15482 (use (match_operand:SI 3 "immediate_operand"))
15483 (use (reg:CC FLAGS_REG))
15484 (clobber (match_operand 0 "register_operand"))
15485 (clobber (match_operand 1 "register_operand"))
15486 (clobber (match_dup 2))])]
15487 ""
15488 "ix86_current_function_needs_cld = 1;")
15489
15490 (define_insn "*cmpstrnqi_1"
15491 [(set (reg:CC FLAGS_REG)
15492 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15493 (const_int 0))
15494 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15495 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15496 (const_int 0)))
15497 (use (match_operand:SI 3 "immediate_operand" "i"))
15498 (use (reg:CC FLAGS_REG))
15499 (clobber (match_operand:P 0 "register_operand" "=S"))
15500 (clobber (match_operand:P 1 "register_operand" "=D"))
15501 (clobber (match_operand:P 2 "register_operand" "=c"))]
15502 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15503 "%^repz{%;} cmpsb"
15504 [(set_attr "type" "str")
15505 (set_attr "mode" "QI")
15506 (set (attr "prefix_rex")
15507 (if_then_else
15508 (match_test "<P:MODE>mode == DImode")
15509 (const_string "0")
15510 (const_string "*")))
15511 (set_attr "prefix_rep" "1")])
15512
15513 (define_expand "strlen<mode>"
15514 [(set (match_operand:P 0 "register_operand")
15515 (unspec:P [(match_operand:BLK 1 "general_operand")
15516 (match_operand:QI 2 "immediate_operand")
15517 (match_operand 3 "immediate_operand")]
15518 UNSPEC_SCAS))]
15519 ""
15520 {
15521 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15522 DONE;
15523 else
15524 FAIL;
15525 })
15526
15527 (define_expand "strlenqi_1"
15528 [(parallel [(set (match_operand 0 "register_operand")
15529 (match_operand 2))
15530 (clobber (match_operand 1 "register_operand"))
15531 (clobber (reg:CC FLAGS_REG))])]
15532 ""
15533 "ix86_current_function_needs_cld = 1;")
15534
15535 (define_insn "*strlenqi_1"
15536 [(set (match_operand:P 0 "register_operand" "=&c")
15537 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15538 (match_operand:QI 2 "register_operand" "a")
15539 (match_operand:P 3 "immediate_operand" "i")
15540 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15541 (clobber (match_operand:P 1 "register_operand" "=D"))
15542 (clobber (reg:CC FLAGS_REG))]
15543 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15544 "%^repnz{%;} scasb"
15545 [(set_attr "type" "str")
15546 (set_attr "mode" "QI")
15547 (set (attr "prefix_rex")
15548 (if_then_else
15549 (match_test "<P:MODE>mode == DImode")
15550 (const_string "0")
15551 (const_string "*")))
15552 (set_attr "prefix_rep" "1")])
15553
15554 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15555 ;; handled in combine, but it is not currently up to the task.
15556 ;; When used for their truth value, the cmpstrn* expanders generate
15557 ;; code like this:
15558 ;;
15559 ;; repz cmpsb
15560 ;; seta %al
15561 ;; setb %dl
15562 ;; cmpb %al, %dl
15563 ;; jcc label
15564 ;;
15565 ;; The intermediate three instructions are unnecessary.
15566
15567 ;; This one handles cmpstrn*_nz_1...
15568 (define_peephole2
15569 [(parallel[
15570 (set (reg:CC FLAGS_REG)
15571 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15572 (mem:BLK (match_operand 5 "register_operand"))))
15573 (use (match_operand 6 "register_operand"))
15574 (use (match_operand:SI 3 "immediate_operand"))
15575 (clobber (match_operand 0 "register_operand"))
15576 (clobber (match_operand 1 "register_operand"))
15577 (clobber (match_operand 2 "register_operand"))])
15578 (set (match_operand:QI 7 "register_operand")
15579 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15580 (set (match_operand:QI 8 "register_operand")
15581 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15582 (set (reg FLAGS_REG)
15583 (compare (match_dup 7) (match_dup 8)))
15584 ]
15585 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15586 [(parallel[
15587 (set (reg:CC FLAGS_REG)
15588 (compare:CC (mem:BLK (match_dup 4))
15589 (mem:BLK (match_dup 5))))
15590 (use (match_dup 6))
15591 (use (match_dup 3))
15592 (clobber (match_dup 0))
15593 (clobber (match_dup 1))
15594 (clobber (match_dup 2))])])
15595
15596 ;; ...and this one handles cmpstrn*_1.
15597 (define_peephole2
15598 [(parallel[
15599 (set (reg:CC FLAGS_REG)
15600 (if_then_else:CC (ne (match_operand 6 "register_operand")
15601 (const_int 0))
15602 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15603 (mem:BLK (match_operand 5 "register_operand")))
15604 (const_int 0)))
15605 (use (match_operand:SI 3 "immediate_operand"))
15606 (use (reg:CC FLAGS_REG))
15607 (clobber (match_operand 0 "register_operand"))
15608 (clobber (match_operand 1 "register_operand"))
15609 (clobber (match_operand 2 "register_operand"))])
15610 (set (match_operand:QI 7 "register_operand")
15611 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15612 (set (match_operand:QI 8 "register_operand")
15613 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15614 (set (reg FLAGS_REG)
15615 (compare (match_dup 7) (match_dup 8)))
15616 ]
15617 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15618 [(parallel[
15619 (set (reg:CC FLAGS_REG)
15620 (if_then_else:CC (ne (match_dup 6)
15621 (const_int 0))
15622 (compare:CC (mem:BLK (match_dup 4))
15623 (mem:BLK (match_dup 5)))
15624 (const_int 0)))
15625 (use (match_dup 3))
15626 (use (reg:CC FLAGS_REG))
15627 (clobber (match_dup 0))
15628 (clobber (match_dup 1))
15629 (clobber (match_dup 2))])])
15630 \f
15631 ;; Conditional move instructions.
15632
15633 (define_expand "mov<mode>cc"
15634 [(set (match_operand:SWIM 0 "register_operand")
15635 (if_then_else:SWIM (match_operand 1 "comparison_operator")
15636 (match_operand:SWIM 2 "<general_operand>")
15637 (match_operand:SWIM 3 "<general_operand>")))]
15638 ""
15639 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15640
15641 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15642 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15643 ;; So just document what we're doing explicitly.
15644
15645 (define_expand "x86_mov<mode>cc_0_m1"
15646 [(parallel
15647 [(set (match_operand:SWI48 0 "register_operand")
15648 (if_then_else:SWI48
15649 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15650 [(match_operand 1 "flags_reg_operand")
15651 (const_int 0)])
15652 (const_int -1)
15653 (const_int 0)))
15654 (clobber (reg:CC FLAGS_REG))])])
15655
15656 (define_insn "*x86_mov<mode>cc_0_m1"
15657 [(set (match_operand:SWI48 0 "register_operand" "=r")
15658 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15659 [(reg FLAGS_REG) (const_int 0)])
15660 (const_int -1)
15661 (const_int 0)))
15662 (clobber (reg:CC FLAGS_REG))]
15663 ""
15664 "sbb{<imodesuffix>}\t%0, %0"
15665 ; Since we don't have the proper number of operands for an alu insn,
15666 ; fill in all the blanks.
15667 [(set_attr "type" "alu")
15668 (set_attr "use_carry" "1")
15669 (set_attr "pent_pair" "pu")
15670 (set_attr "memory" "none")
15671 (set_attr "imm_disp" "false")
15672 (set_attr "mode" "<MODE>")
15673 (set_attr "length_immediate" "0")])
15674
15675 (define_insn "*x86_mov<mode>cc_0_m1_se"
15676 [(set (match_operand:SWI48 0 "register_operand" "=r")
15677 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15678 [(reg FLAGS_REG) (const_int 0)])
15679 (const_int 1)
15680 (const_int 0)))
15681 (clobber (reg:CC FLAGS_REG))]
15682 ""
15683 "sbb{<imodesuffix>}\t%0, %0"
15684 [(set_attr "type" "alu")
15685 (set_attr "use_carry" "1")
15686 (set_attr "pent_pair" "pu")
15687 (set_attr "memory" "none")
15688 (set_attr "imm_disp" "false")
15689 (set_attr "mode" "<MODE>")
15690 (set_attr "length_immediate" "0")])
15691
15692 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15693 [(set (match_operand:SWI48 0 "register_operand" "=r")
15694 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15695 [(reg FLAGS_REG) (const_int 0)])))
15696 (clobber (reg:CC FLAGS_REG))]
15697 ""
15698 "sbb{<imodesuffix>}\t%0, %0"
15699 [(set_attr "type" "alu")
15700 (set_attr "use_carry" "1")
15701 (set_attr "pent_pair" "pu")
15702 (set_attr "memory" "none")
15703 (set_attr "imm_disp" "false")
15704 (set_attr "mode" "<MODE>")
15705 (set_attr "length_immediate" "0")])
15706
15707 (define_insn "*mov<mode>cc_noc"
15708 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15709 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15710 [(reg FLAGS_REG) (const_int 0)])
15711 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15712 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15713 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15714 "@
15715 cmov%O2%C1\t{%2, %0|%0, %2}
15716 cmov%O2%c1\t{%3, %0|%0, %3}"
15717 [(set_attr "type" "icmov")
15718 (set_attr "mode" "<MODE>")])
15719
15720 ;; Don't do conditional moves with memory inputs. This splitter helps
15721 ;; register starved x86_32 by forcing inputs into registers before reload.
15722 (define_split
15723 [(set (match_operand:SWI248 0 "register_operand")
15724 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15725 [(reg FLAGS_REG) (const_int 0)])
15726 (match_operand:SWI248 2 "nonimmediate_operand")
15727 (match_operand:SWI248 3 "nonimmediate_operand")))]
15728 "!TARGET_64BIT && TARGET_CMOVE
15729 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15730 && (MEM_P (operands[2]) || MEM_P (operands[3]))
15731 && can_create_pseudo_p ()
15732 && optimize_insn_for_speed_p ()"
15733 [(set (match_dup 0)
15734 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
15735 {
15736 if (MEM_P (operands[2]))
15737 operands[2] = force_reg (<MODE>mode, operands[2]);
15738 if (MEM_P (operands[3]))
15739 operands[3] = force_reg (<MODE>mode, operands[3]);
15740 })
15741
15742 (define_insn "*movqicc_noc"
15743 [(set (match_operand:QI 0 "register_operand" "=r,r")
15744 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15745 [(reg FLAGS_REG) (const_int 0)])
15746 (match_operand:QI 2 "register_operand" "r,0")
15747 (match_operand:QI 3 "register_operand" "0,r")))]
15748 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15749 "#"
15750 [(set_attr "type" "icmov")
15751 (set_attr "mode" "QI")])
15752
15753 (define_split
15754 [(set (match_operand:SWI12 0 "register_operand")
15755 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
15756 [(reg FLAGS_REG) (const_int 0)])
15757 (match_operand:SWI12 2 "register_operand")
15758 (match_operand:SWI12 3 "register_operand")))]
15759 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
15760 && reload_completed"
15761 [(set (match_dup 0)
15762 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
15763 {
15764 operands[0] = gen_lowpart (SImode, operands[0]);
15765 operands[2] = gen_lowpart (SImode, operands[2]);
15766 operands[3] = gen_lowpart (SImode, operands[3]);
15767 })
15768
15769 ;; Don't do conditional moves with memory inputs
15770 (define_peephole2
15771 [(match_scratch:SWI248 2 "r")
15772 (set (match_operand:SWI248 0 "register_operand")
15773 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15774 [(reg FLAGS_REG) (const_int 0)])
15775 (match_dup 0)
15776 (match_operand:SWI248 3 "memory_operand")))]
15777 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15778 && optimize_insn_for_speed_p ()"
15779 [(set (match_dup 2) (match_dup 3))
15780 (set (match_dup 0)
15781 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
15782
15783 (define_peephole2
15784 [(match_scratch:SWI248 2 "r")
15785 (set (match_operand:SWI248 0 "register_operand")
15786 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15787 [(reg FLAGS_REG) (const_int 0)])
15788 (match_operand:SWI248 3 "memory_operand")
15789 (match_dup 0)))]
15790 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15791 && optimize_insn_for_speed_p ()"
15792 [(set (match_dup 2) (match_dup 3))
15793 (set (match_dup 0)
15794 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
15795
15796 (define_expand "mov<mode>cc"
15797 [(set (match_operand:X87MODEF 0 "register_operand")
15798 (if_then_else:X87MODEF
15799 (match_operand 1 "comparison_operator")
15800 (match_operand:X87MODEF 2 "register_operand")
15801 (match_operand:X87MODEF 3 "register_operand")))]
15802 "(TARGET_80387 && TARGET_CMOVE)
15803 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15804 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15805
15806 (define_insn "*movxfcc_1"
15807 [(set (match_operand:XF 0 "register_operand" "=f,f")
15808 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15809 [(reg FLAGS_REG) (const_int 0)])
15810 (match_operand:XF 2 "register_operand" "f,0")
15811 (match_operand:XF 3 "register_operand" "0,f")))]
15812 "TARGET_80387 && TARGET_CMOVE"
15813 "@
15814 fcmov%F1\t{%2, %0|%0, %2}
15815 fcmov%f1\t{%3, %0|%0, %3}"
15816 [(set_attr "type" "fcmov")
15817 (set_attr "mode" "XF")])
15818
15819 (define_insn "*movdfcc_1"
15820 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
15821 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15822 [(reg FLAGS_REG) (const_int 0)])
15823 (match_operand:DF 2 "nonimmediate_operand"
15824 "f ,0,rm,0 ,rm,0")
15825 (match_operand:DF 3 "nonimmediate_operand"
15826 "0 ,f,0 ,rm,0, rm")))]
15827 "TARGET_80387 && TARGET_CMOVE
15828 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15829 "@
15830 fcmov%F1\t{%2, %0|%0, %2}
15831 fcmov%f1\t{%3, %0|%0, %3}
15832 #
15833 #
15834 cmov%O2%C1\t{%2, %0|%0, %2}
15835 cmov%O2%c1\t{%3, %0|%0, %3}"
15836 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
15837 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
15838 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
15839
15840 (define_split
15841 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
15842 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15843 [(reg FLAGS_REG) (const_int 0)])
15844 (match_operand:DF 2 "nonimmediate_operand")
15845 (match_operand:DF 3 "nonimmediate_operand")))]
15846 "!TARGET_64BIT && reload_completed"
15847 [(set (match_dup 2)
15848 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
15849 (set (match_dup 3)
15850 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
15851 {
15852 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
15853 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
15854 })
15855
15856 (define_insn "*movsfcc_1_387"
15857 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15858 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15859 [(reg FLAGS_REG) (const_int 0)])
15860 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15861 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15862 "TARGET_80387 && TARGET_CMOVE
15863 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15864 "@
15865 fcmov%F1\t{%2, %0|%0, %2}
15866 fcmov%f1\t{%3, %0|%0, %3}
15867 cmov%O2%C1\t{%2, %0|%0, %2}
15868 cmov%O2%c1\t{%3, %0|%0, %3}"
15869 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15870 (set_attr "mode" "SF,SF,SI,SI")])
15871
15872 ;; Don't do conditional moves with memory inputs. This splitter helps
15873 ;; register starved x86_32 by forcing inputs into registers before reload.
15874 (define_split
15875 [(set (match_operand:MODEF 0 "register_operand")
15876 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
15877 [(reg FLAGS_REG) (const_int 0)])
15878 (match_operand:MODEF 2 "nonimmediate_operand")
15879 (match_operand:MODEF 3 "nonimmediate_operand")))]
15880 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15881 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15882 && (MEM_P (operands[2]) || MEM_P (operands[3]))
15883 && can_create_pseudo_p ()
15884 && optimize_insn_for_speed_p ()"
15885 [(set (match_dup 0)
15886 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
15887 {
15888 if (MEM_P (operands[2]))
15889 operands[2] = force_reg (<MODE>mode, operands[2]);
15890 if (MEM_P (operands[3]))
15891 operands[3] = force_reg (<MODE>mode, operands[3]);
15892 })
15893
15894 ;; Don't do conditional moves with memory inputs
15895 (define_peephole2
15896 [(match_scratch:MODEF 2 "r")
15897 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
15898 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
15899 [(reg FLAGS_REG) (const_int 0)])
15900 (match_dup 0)
15901 (match_operand:MODEF 3 "memory_operand")))]
15902 "(<MODE>mode != DFmode || TARGET_64BIT)
15903 && TARGET_80387 && TARGET_CMOVE
15904 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15905 && optimize_insn_for_speed_p ()"
15906 [(set (match_dup 2) (match_dup 3))
15907 (set (match_dup 0)
15908 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
15909
15910 (define_peephole2
15911 [(match_scratch:MODEF 2 "r")
15912 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
15913 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
15914 [(reg FLAGS_REG) (const_int 0)])
15915 (match_operand:MODEF 3 "memory_operand")
15916 (match_dup 0)))]
15917 "(<MODE>mode != DFmode || TARGET_64BIT)
15918 && TARGET_80387 && TARGET_CMOVE
15919 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15920 && optimize_insn_for_speed_p ()"
15921 [(set (match_dup 2) (match_dup 3))
15922 (set (match_dup 0)
15923 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
15924
15925 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
15926 ;; the scalar versions to have only XMM registers as operands.
15927
15928 ;; XOP conditional move
15929 (define_insn "*xop_pcmov_<mode>"
15930 [(set (match_operand:MODEF 0 "register_operand" "=x")
15931 (if_then_else:MODEF
15932 (match_operand:MODEF 1 "register_operand" "x")
15933 (match_operand:MODEF 2 "register_operand" "x")
15934 (match_operand:MODEF 3 "register_operand" "x")))]
15935 "TARGET_XOP"
15936 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
15937 [(set_attr "type" "sse4arg")])
15938
15939 ;; These versions of the min/max patterns are intentionally ignorant of
15940 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
15941 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
15942 ;; are undefined in this condition, we're certain this is correct.
15943
15944 (define_insn "<code><mode>3"
15945 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
15946 (smaxmin:MODEF
15947 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15948 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
15949 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15950 "@
15951 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
15952 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
15953 [(set_attr "isa" "noavx,avx")
15954 (set_attr "prefix" "orig,vex")
15955 (set_attr "type" "sseadd")
15956 (set_attr "mode" "<MODE>")])
15957
15958 ;; These versions of the min/max patterns implement exactly the operations
15959 ;; min = (op1 < op2 ? op1 : op2)
15960 ;; max = (!(op1 < op2) ? op1 : op2)
15961 ;; Their operands are not commutative, and thus they may be used in the
15962 ;; presence of -0.0 and NaN.
15963
15964 (define_int_iterator IEEE_MAXMIN
15965 [UNSPEC_IEEE_MAX
15966 UNSPEC_IEEE_MIN])
15967
15968 (define_int_attr ieee_maxmin
15969 [(UNSPEC_IEEE_MAX "max")
15970 (UNSPEC_IEEE_MIN "min")])
15971
15972 (define_insn "*ieee_s<ieee_maxmin><mode>3"
15973 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
15974 (unspec:MODEF
15975 [(match_operand:MODEF 1 "register_operand" "0,x")
15976 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
15977 IEEE_MAXMIN))]
15978 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15979 "@
15980 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
15981 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
15982 [(set_attr "isa" "noavx,avx")
15983 (set_attr "prefix" "orig,vex")
15984 (set_attr "type" "sseadd")
15985 (set_attr "mode" "<MODE>")])
15986
15987 ;; Make two stack loads independent:
15988 ;; fld aa fld aa
15989 ;; fld %st(0) -> fld bb
15990 ;; fmul bb fmul %st(1), %st
15991 ;;
15992 ;; Actually we only match the last two instructions for simplicity.
15993 (define_peephole2
15994 [(set (match_operand 0 "fp_register_operand")
15995 (match_operand 1 "fp_register_operand"))
15996 (set (match_dup 0)
15997 (match_operator 2 "binary_fp_operator"
15998 [(match_dup 0)
15999 (match_operand 3 "memory_operand")]))]
16000 "REGNO (operands[0]) != REGNO (operands[1])"
16001 [(set (match_dup 0) (match_dup 3))
16002 (set (match_dup 0) (match_dup 4))]
16003
16004 ;; The % modifier is not operational anymore in peephole2's, so we have to
16005 ;; swap the operands manually in the case of addition and multiplication.
16006 {
16007 rtx op0, op1;
16008
16009 if (COMMUTATIVE_ARITH_P (operands[2]))
16010 op0 = operands[0], op1 = operands[1];
16011 else
16012 op0 = operands[1], op1 = operands[0];
16013
16014 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16015 GET_MODE (operands[2]),
16016 op0, op1);
16017 })
16018
16019 ;; Conditional addition patterns
16020 (define_expand "add<mode>cc"
16021 [(match_operand:SWI 0 "register_operand")
16022 (match_operand 1 "ordered_comparison_operator")
16023 (match_operand:SWI 2 "register_operand")
16024 (match_operand:SWI 3 "const_int_operand")]
16025 ""
16026 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16027 \f
16028 ;; Misc patterns (?)
16029
16030 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16031 ;; Otherwise there will be nothing to keep
16032 ;;
16033 ;; [(set (reg ebp) (reg esp))]
16034 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16035 ;; (clobber (eflags)]
16036 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16037 ;;
16038 ;; in proper program order.
16039
16040 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16041 [(set (match_operand:P 0 "register_operand" "=r,r")
16042 (plus:P (match_operand:P 1 "register_operand" "0,r")
16043 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16044 (clobber (reg:CC FLAGS_REG))
16045 (clobber (mem:BLK (scratch)))]
16046 ""
16047 {
16048 switch (get_attr_type (insn))
16049 {
16050 case TYPE_IMOV:
16051 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16052
16053 case TYPE_ALU:
16054 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16055 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16056 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16057
16058 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16059
16060 default:
16061 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16062 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16063 }
16064 }
16065 [(set (attr "type")
16066 (cond [(and (eq_attr "alternative" "0")
16067 (not (match_test "TARGET_OPT_AGU")))
16068 (const_string "alu")
16069 (match_operand:<MODE> 2 "const0_operand")
16070 (const_string "imov")
16071 ]
16072 (const_string "lea")))
16073 (set (attr "length_immediate")
16074 (cond [(eq_attr "type" "imov")
16075 (const_string "0")
16076 (and (eq_attr "type" "alu")
16077 (match_operand 2 "const128_operand"))
16078 (const_string "1")
16079 ]
16080 (const_string "*")))
16081 (set_attr "mode" "<MODE>")])
16082
16083 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16084 [(set (match_operand:P 0 "register_operand" "=r")
16085 (minus:P (match_operand:P 1 "register_operand" "0")
16086 (match_operand:P 2 "register_operand" "r")))
16087 (clobber (reg:CC FLAGS_REG))
16088 (clobber (mem:BLK (scratch)))]
16089 ""
16090 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16091 [(set_attr "type" "alu")
16092 (set_attr "mode" "<MODE>")])
16093
16094 (define_insn "allocate_stack_worker_probe_<mode>"
16095 [(set (match_operand:P 0 "register_operand" "=a")
16096 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16097 UNSPECV_STACK_PROBE))
16098 (clobber (reg:CC FLAGS_REG))]
16099 "ix86_target_stack_probe ()"
16100 "call\t___chkstk_ms"
16101 [(set_attr "type" "multi")
16102 (set_attr "length" "5")])
16103
16104 (define_expand "allocate_stack"
16105 [(match_operand 0 "register_operand")
16106 (match_operand 1 "general_operand")]
16107 "ix86_target_stack_probe ()"
16108 {
16109 rtx x;
16110
16111 #ifndef CHECK_STACK_LIMIT
16112 #define CHECK_STACK_LIMIT 0
16113 #endif
16114
16115 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16116 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16117 x = operands[1];
16118 else
16119 {
16120 rtx (*insn) (rtx, rtx);
16121
16122 x = copy_to_mode_reg (Pmode, operands[1]);
16123
16124 insn = (TARGET_64BIT
16125 ? gen_allocate_stack_worker_probe_di
16126 : gen_allocate_stack_worker_probe_si);
16127
16128 emit_insn (insn (x, x));
16129 }
16130
16131 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16132 stack_pointer_rtx, 0, OPTAB_DIRECT);
16133
16134 if (x != stack_pointer_rtx)
16135 emit_move_insn (stack_pointer_rtx, x);
16136
16137 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16138 DONE;
16139 })
16140
16141 ;; Use IOR for stack probes, this is shorter.
16142 (define_expand "probe_stack"
16143 [(match_operand 0 "memory_operand")]
16144 ""
16145 {
16146 rtx (*gen_ior3) (rtx, rtx, rtx);
16147
16148 gen_ior3 = (GET_MODE (operands[0]) == DImode
16149 ? gen_iordi3 : gen_iorsi3);
16150
16151 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16152 DONE;
16153 })
16154
16155 (define_insn "adjust_stack_and_probe<mode>"
16156 [(set (match_operand:P 0 "register_operand" "=r")
16157 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16158 UNSPECV_PROBE_STACK_RANGE))
16159 (set (reg:P SP_REG)
16160 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16161 (clobber (reg:CC FLAGS_REG))
16162 (clobber (mem:BLK (scratch)))]
16163 ""
16164 "* return output_adjust_stack_and_probe (operands[0]);"
16165 [(set_attr "type" "multi")])
16166
16167 (define_insn "probe_stack_range<mode>"
16168 [(set (match_operand:P 0 "register_operand" "=r")
16169 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16170 (match_operand:P 2 "const_int_operand" "n")]
16171 UNSPECV_PROBE_STACK_RANGE))
16172 (clobber (reg:CC FLAGS_REG))]
16173 ""
16174 "* return output_probe_stack_range (operands[0], operands[2]);"
16175 [(set_attr "type" "multi")])
16176
16177 (define_expand "builtin_setjmp_receiver"
16178 [(label_ref (match_operand 0))]
16179 "!TARGET_64BIT && flag_pic"
16180 {
16181 #if TARGET_MACHO
16182 if (TARGET_MACHO)
16183 {
16184 rtx xops[3];
16185 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16186 rtx label_rtx = gen_label_rtx ();
16187 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16188 xops[0] = xops[1] = picreg;
16189 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16190 ix86_expand_binary_operator (MINUS, SImode, xops);
16191 }
16192 else
16193 #endif
16194 emit_insn (gen_set_got (pic_offset_table_rtx));
16195 DONE;
16196 })
16197 \f
16198 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16199
16200 (define_split
16201 [(set (match_operand 0 "register_operand")
16202 (match_operator 3 "promotable_binary_operator"
16203 [(match_operand 1 "register_operand")
16204 (match_operand 2 "aligned_operand")]))
16205 (clobber (reg:CC FLAGS_REG))]
16206 "! TARGET_PARTIAL_REG_STALL && reload_completed
16207 && ((GET_MODE (operands[0]) == HImode
16208 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16209 /* ??? next two lines just !satisfies_constraint_K (...) */
16210 || !CONST_INT_P (operands[2])
16211 || satisfies_constraint_K (operands[2])))
16212 || (GET_MODE (operands[0]) == QImode
16213 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16214 [(parallel [(set (match_dup 0)
16215 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16216 (clobber (reg:CC FLAGS_REG))])]
16217 {
16218 operands[0] = gen_lowpart (SImode, operands[0]);
16219 operands[1] = gen_lowpart (SImode, operands[1]);
16220 if (GET_CODE (operands[3]) != ASHIFT)
16221 operands[2] = gen_lowpart (SImode, operands[2]);
16222 PUT_MODE (operands[3], SImode);
16223 })
16224
16225 ; Promote the QImode tests, as i386 has encoding of the AND
16226 ; instruction with 32-bit sign-extended immediate and thus the
16227 ; instruction size is unchanged, except in the %eax case for
16228 ; which it is increased by one byte, hence the ! optimize_size.
16229 (define_split
16230 [(set (match_operand 0 "flags_reg_operand")
16231 (match_operator 2 "compare_operator"
16232 [(and (match_operand 3 "aligned_operand")
16233 (match_operand 4 "const_int_operand"))
16234 (const_int 0)]))
16235 (set (match_operand 1 "register_operand")
16236 (and (match_dup 3) (match_dup 4)))]
16237 "! TARGET_PARTIAL_REG_STALL && reload_completed
16238 && optimize_insn_for_speed_p ()
16239 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16240 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16241 /* Ensure that the operand will remain sign-extended immediate. */
16242 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16243 [(parallel [(set (match_dup 0)
16244 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16245 (const_int 0)]))
16246 (set (match_dup 1)
16247 (and:SI (match_dup 3) (match_dup 4)))])]
16248 {
16249 operands[4]
16250 = gen_int_mode (INTVAL (operands[4])
16251 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16252 operands[1] = gen_lowpart (SImode, operands[1]);
16253 operands[3] = gen_lowpart (SImode, operands[3]);
16254 })
16255
16256 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16257 ; the TEST instruction with 32-bit sign-extended immediate and thus
16258 ; the instruction size would at least double, which is not what we
16259 ; want even with ! optimize_size.
16260 (define_split
16261 [(set (match_operand 0 "flags_reg_operand")
16262 (match_operator 1 "compare_operator"
16263 [(and (match_operand:HI 2 "aligned_operand")
16264 (match_operand:HI 3 "const_int_operand"))
16265 (const_int 0)]))]
16266 "! TARGET_PARTIAL_REG_STALL && reload_completed
16267 && ! TARGET_FAST_PREFIX
16268 && optimize_insn_for_speed_p ()
16269 /* Ensure that the operand will remain sign-extended immediate. */
16270 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16271 [(set (match_dup 0)
16272 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16273 (const_int 0)]))]
16274 {
16275 operands[3]
16276 = gen_int_mode (INTVAL (operands[3])
16277 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16278 operands[2] = gen_lowpart (SImode, operands[2]);
16279 })
16280
16281 (define_split
16282 [(set (match_operand 0 "register_operand")
16283 (neg (match_operand 1 "register_operand")))
16284 (clobber (reg:CC FLAGS_REG))]
16285 "! TARGET_PARTIAL_REG_STALL && reload_completed
16286 && (GET_MODE (operands[0]) == HImode
16287 || (GET_MODE (operands[0]) == QImode
16288 && (TARGET_PROMOTE_QImode
16289 || optimize_insn_for_size_p ())))"
16290 [(parallel [(set (match_dup 0)
16291 (neg:SI (match_dup 1)))
16292 (clobber (reg:CC FLAGS_REG))])]
16293 {
16294 operands[0] = gen_lowpart (SImode, operands[0]);
16295 operands[1] = gen_lowpart (SImode, operands[1]);
16296 })
16297
16298 (define_split
16299 [(set (match_operand 0 "register_operand")
16300 (not (match_operand 1 "register_operand")))]
16301 "! TARGET_PARTIAL_REG_STALL && reload_completed
16302 && (GET_MODE (operands[0]) == HImode
16303 || (GET_MODE (operands[0]) == QImode
16304 && (TARGET_PROMOTE_QImode
16305 || optimize_insn_for_size_p ())))"
16306 [(set (match_dup 0)
16307 (not:SI (match_dup 1)))]
16308 {
16309 operands[0] = gen_lowpart (SImode, operands[0]);
16310 operands[1] = gen_lowpart (SImode, operands[1]);
16311 })
16312 \f
16313 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16314 ;; transform a complex memory operation into two memory to register operations.
16315
16316 ;; Don't push memory operands
16317 (define_peephole2
16318 [(set (match_operand:SWI 0 "push_operand")
16319 (match_operand:SWI 1 "memory_operand"))
16320 (match_scratch:SWI 2 "<r>")]
16321 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16322 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16323 [(set (match_dup 2) (match_dup 1))
16324 (set (match_dup 0) (match_dup 2))])
16325
16326 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16327 ;; SImode pushes.
16328 (define_peephole2
16329 [(set (match_operand:SF 0 "push_operand")
16330 (match_operand:SF 1 "memory_operand"))
16331 (match_scratch:SF 2 "r")]
16332 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16333 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16334 [(set (match_dup 2) (match_dup 1))
16335 (set (match_dup 0) (match_dup 2))])
16336
16337 ;; Don't move an immediate directly to memory when the instruction
16338 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16339 (define_peephole2
16340 [(match_scratch:SWI124 1 "<r>")
16341 (set (match_operand:SWI124 0 "memory_operand")
16342 (const_int 0))]
16343 "optimize_insn_for_speed_p ()
16344 && ((<MODE>mode == HImode
16345 && TARGET_LCP_STALL)
16346 || (!TARGET_USE_MOV0
16347 && TARGET_SPLIT_LONG_MOVES
16348 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16349 && peep2_regno_dead_p (0, FLAGS_REG)"
16350 [(parallel [(set (match_dup 2) (const_int 0))
16351 (clobber (reg:CC FLAGS_REG))])
16352 (set (match_dup 0) (match_dup 1))]
16353 "operands[2] = gen_lowpart (SImode, operands[1]);")
16354
16355 (define_peephole2
16356 [(match_scratch:SWI124 2 "<r>")
16357 (set (match_operand:SWI124 0 "memory_operand")
16358 (match_operand:SWI124 1 "immediate_operand"))]
16359 "optimize_insn_for_speed_p ()
16360 && ((<MODE>mode == HImode
16361 && TARGET_LCP_STALL)
16362 || (TARGET_SPLIT_LONG_MOVES
16363 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16364 [(set (match_dup 2) (match_dup 1))
16365 (set (match_dup 0) (match_dup 2))])
16366
16367 ;; Don't compare memory with zero, load and use a test instead.
16368 (define_peephole2
16369 [(set (match_operand 0 "flags_reg_operand")
16370 (match_operator 1 "compare_operator"
16371 [(match_operand:SI 2 "memory_operand")
16372 (const_int 0)]))
16373 (match_scratch:SI 3 "r")]
16374 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16375 [(set (match_dup 3) (match_dup 2))
16376 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16377
16378 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16379 ;; Don't split NOTs with a displacement operand, because resulting XOR
16380 ;; will not be pairable anyway.
16381 ;;
16382 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16383 ;; represented using a modRM byte. The XOR replacement is long decoded,
16384 ;; so this split helps here as well.
16385 ;;
16386 ;; Note: Can't do this as a regular split because we can't get proper
16387 ;; lifetime information then.
16388
16389 (define_peephole2
16390 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16391 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16392 "optimize_insn_for_speed_p ()
16393 && ((TARGET_NOT_UNPAIRABLE
16394 && (!MEM_P (operands[0])
16395 || !memory_displacement_operand (operands[0], <MODE>mode)))
16396 || (TARGET_NOT_VECTORMODE
16397 && long_memory_operand (operands[0], <MODE>mode)))
16398 && peep2_regno_dead_p (0, FLAGS_REG)"
16399 [(parallel [(set (match_dup 0)
16400 (xor:SWI124 (match_dup 1) (const_int -1)))
16401 (clobber (reg:CC FLAGS_REG))])])
16402
16403 ;; Non pairable "test imm, reg" instructions can be translated to
16404 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16405 ;; byte opcode instead of two, have a short form for byte operands),
16406 ;; so do it for other CPUs as well. Given that the value was dead,
16407 ;; this should not create any new dependencies. Pass on the sub-word
16408 ;; versions if we're concerned about partial register stalls.
16409
16410 (define_peephole2
16411 [(set (match_operand 0 "flags_reg_operand")
16412 (match_operator 1 "compare_operator"
16413 [(and:SI (match_operand:SI 2 "register_operand")
16414 (match_operand:SI 3 "immediate_operand"))
16415 (const_int 0)]))]
16416 "ix86_match_ccmode (insn, CCNOmode)
16417 && (true_regnum (operands[2]) != AX_REG
16418 || satisfies_constraint_K (operands[3]))
16419 && peep2_reg_dead_p (1, operands[2])"
16420 [(parallel
16421 [(set (match_dup 0)
16422 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16423 (const_int 0)]))
16424 (set (match_dup 2)
16425 (and:SI (match_dup 2) (match_dup 3)))])])
16426
16427 ;; We don't need to handle HImode case, because it will be promoted to SImode
16428 ;; on ! TARGET_PARTIAL_REG_STALL
16429
16430 (define_peephole2
16431 [(set (match_operand 0 "flags_reg_operand")
16432 (match_operator 1 "compare_operator"
16433 [(and:QI (match_operand:QI 2 "register_operand")
16434 (match_operand:QI 3 "immediate_operand"))
16435 (const_int 0)]))]
16436 "! TARGET_PARTIAL_REG_STALL
16437 && ix86_match_ccmode (insn, CCNOmode)
16438 && true_regnum (operands[2]) != AX_REG
16439 && peep2_reg_dead_p (1, operands[2])"
16440 [(parallel
16441 [(set (match_dup 0)
16442 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16443 (const_int 0)]))
16444 (set (match_dup 2)
16445 (and:QI (match_dup 2) (match_dup 3)))])])
16446
16447 (define_peephole2
16448 [(set (match_operand 0 "flags_reg_operand")
16449 (match_operator 1 "compare_operator"
16450 [(and:SI
16451 (zero_extract:SI
16452 (match_operand 2 "ext_register_operand")
16453 (const_int 8)
16454 (const_int 8))
16455 (match_operand 3 "const_int_operand"))
16456 (const_int 0)]))]
16457 "! TARGET_PARTIAL_REG_STALL
16458 && ix86_match_ccmode (insn, CCNOmode)
16459 && true_regnum (operands[2]) != AX_REG
16460 && peep2_reg_dead_p (1, operands[2])"
16461 [(parallel [(set (match_dup 0)
16462 (match_op_dup 1
16463 [(and:SI
16464 (zero_extract:SI
16465 (match_dup 2)
16466 (const_int 8)
16467 (const_int 8))
16468 (match_dup 3))
16469 (const_int 0)]))
16470 (set (zero_extract:SI (match_dup 2)
16471 (const_int 8)
16472 (const_int 8))
16473 (and:SI
16474 (zero_extract:SI
16475 (match_dup 2)
16476 (const_int 8)
16477 (const_int 8))
16478 (match_dup 3)))])])
16479
16480 ;; Don't do logical operations with memory inputs.
16481 (define_peephole2
16482 [(match_scratch:SI 2 "r")
16483 (parallel [(set (match_operand:SI 0 "register_operand")
16484 (match_operator:SI 3 "arith_or_logical_operator"
16485 [(match_dup 0)
16486 (match_operand:SI 1 "memory_operand")]))
16487 (clobber (reg:CC FLAGS_REG))])]
16488 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16489 [(set (match_dup 2) (match_dup 1))
16490 (parallel [(set (match_dup 0)
16491 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16492 (clobber (reg:CC FLAGS_REG))])])
16493
16494 (define_peephole2
16495 [(match_scratch:SI 2 "r")
16496 (parallel [(set (match_operand:SI 0 "register_operand")
16497 (match_operator:SI 3 "arith_or_logical_operator"
16498 [(match_operand:SI 1 "memory_operand")
16499 (match_dup 0)]))
16500 (clobber (reg:CC FLAGS_REG))])]
16501 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16502 [(set (match_dup 2) (match_dup 1))
16503 (parallel [(set (match_dup 0)
16504 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16505 (clobber (reg:CC FLAGS_REG))])])
16506
16507 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16508 ;; refers to the destination of the load!
16509
16510 (define_peephole2
16511 [(set (match_operand:SI 0 "register_operand")
16512 (match_operand:SI 1 "register_operand"))
16513 (parallel [(set (match_dup 0)
16514 (match_operator:SI 3 "commutative_operator"
16515 [(match_dup 0)
16516 (match_operand:SI 2 "memory_operand")]))
16517 (clobber (reg:CC FLAGS_REG))])]
16518 "REGNO (operands[0]) != REGNO (operands[1])
16519 && GENERAL_REGNO_P (REGNO (operands[0]))
16520 && GENERAL_REGNO_P (REGNO (operands[1]))"
16521 [(set (match_dup 0) (match_dup 4))
16522 (parallel [(set (match_dup 0)
16523 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16524 (clobber (reg:CC FLAGS_REG))])]
16525 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16526
16527 (define_peephole2
16528 [(set (match_operand 0 "register_operand")
16529 (match_operand 1 "register_operand"))
16530 (set (match_dup 0)
16531 (match_operator 3 "commutative_operator"
16532 [(match_dup 0)
16533 (match_operand 2 "memory_operand")]))]
16534 "REGNO (operands[0]) != REGNO (operands[1])
16535 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16536 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16537 [(set (match_dup 0) (match_dup 2))
16538 (set (match_dup 0)
16539 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16540
16541 ; Don't do logical operations with memory outputs
16542 ;
16543 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16544 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16545 ; the same decoder scheduling characteristics as the original.
16546
16547 (define_peephole2
16548 [(match_scratch:SI 2 "r")
16549 (parallel [(set (match_operand:SI 0 "memory_operand")
16550 (match_operator:SI 3 "arith_or_logical_operator"
16551 [(match_dup 0)
16552 (match_operand:SI 1 "nonmemory_operand")]))
16553 (clobber (reg:CC FLAGS_REG))])]
16554 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16555 /* Do not split stack checking probes. */
16556 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16557 [(set (match_dup 2) (match_dup 0))
16558 (parallel [(set (match_dup 2)
16559 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16560 (clobber (reg:CC FLAGS_REG))])
16561 (set (match_dup 0) (match_dup 2))])
16562
16563 (define_peephole2
16564 [(match_scratch:SI 2 "r")
16565 (parallel [(set (match_operand:SI 0 "memory_operand")
16566 (match_operator:SI 3 "arith_or_logical_operator"
16567 [(match_operand:SI 1 "nonmemory_operand")
16568 (match_dup 0)]))
16569 (clobber (reg:CC FLAGS_REG))])]
16570 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16571 /* Do not split stack checking probes. */
16572 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16573 [(set (match_dup 2) (match_dup 0))
16574 (parallel [(set (match_dup 2)
16575 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16576 (clobber (reg:CC FLAGS_REG))])
16577 (set (match_dup 0) (match_dup 2))])
16578
16579 ;; Attempt to use arith or logical operations with memory outputs with
16580 ;; setting of flags.
16581 (define_peephole2
16582 [(set (match_operand:SWI 0 "register_operand")
16583 (match_operand:SWI 1 "memory_operand"))
16584 (parallel [(set (match_dup 0)
16585 (match_operator:SWI 3 "plusminuslogic_operator"
16586 [(match_dup 0)
16587 (match_operand:SWI 2 "<nonmemory_operand>")]))
16588 (clobber (reg:CC FLAGS_REG))])
16589 (set (match_dup 1) (match_dup 0))
16590 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16591 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16592 && peep2_reg_dead_p (4, operands[0])
16593 && !reg_overlap_mentioned_p (operands[0], operands[1])
16594 && (<MODE>mode != QImode
16595 || immediate_operand (operands[2], QImode)
16596 || q_regs_operand (operands[2], QImode))
16597 && ix86_match_ccmode (peep2_next_insn (3),
16598 (GET_CODE (operands[3]) == PLUS
16599 || GET_CODE (operands[3]) == MINUS)
16600 ? CCGOCmode : CCNOmode)"
16601 [(parallel [(set (match_dup 4) (match_dup 5))
16602 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16603 (match_dup 2)]))])]
16604 {
16605 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16606 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16607 copy_rtx (operands[1]),
16608 copy_rtx (operands[2]));
16609 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16610 operands[5], const0_rtx);
16611 })
16612
16613 (define_peephole2
16614 [(parallel [(set (match_operand:SWI 0 "register_operand")
16615 (match_operator:SWI 2 "plusminuslogic_operator"
16616 [(match_dup 0)
16617 (match_operand:SWI 1 "memory_operand")]))
16618 (clobber (reg:CC FLAGS_REG))])
16619 (set (match_dup 1) (match_dup 0))
16620 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16621 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16622 && GET_CODE (operands[2]) != MINUS
16623 && peep2_reg_dead_p (3, operands[0])
16624 && !reg_overlap_mentioned_p (operands[0], operands[1])
16625 && ix86_match_ccmode (peep2_next_insn (2),
16626 GET_CODE (operands[2]) == PLUS
16627 ? CCGOCmode : CCNOmode)"
16628 [(parallel [(set (match_dup 3) (match_dup 4))
16629 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16630 (match_dup 0)]))])]
16631 {
16632 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16633 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16634 copy_rtx (operands[1]),
16635 copy_rtx (operands[0]));
16636 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16637 operands[4], const0_rtx);
16638 })
16639
16640 (define_peephole2
16641 [(set (match_operand:SWI12 0 "register_operand")
16642 (match_operand:SWI12 1 "memory_operand"))
16643 (parallel [(set (match_operand:SI 4 "register_operand")
16644 (match_operator:SI 3 "plusminuslogic_operator"
16645 [(match_dup 4)
16646 (match_operand:SI 2 "nonmemory_operand")]))
16647 (clobber (reg:CC FLAGS_REG))])
16648 (set (match_dup 1) (match_dup 0))
16649 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16650 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16651 && REG_P (operands[0]) && REG_P (operands[4])
16652 && REGNO (operands[0]) == REGNO (operands[4])
16653 && peep2_reg_dead_p (4, operands[0])
16654 && (<MODE>mode != QImode
16655 || immediate_operand (operands[2], SImode)
16656 || q_regs_operand (operands[2], SImode))
16657 && !reg_overlap_mentioned_p (operands[0], operands[1])
16658 && ix86_match_ccmode (peep2_next_insn (3),
16659 (GET_CODE (operands[3]) == PLUS
16660 || GET_CODE (operands[3]) == MINUS)
16661 ? CCGOCmode : CCNOmode)"
16662 [(parallel [(set (match_dup 4) (match_dup 5))
16663 (set (match_dup 1) (match_dup 6))])]
16664 {
16665 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16666 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16667 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16668 copy_rtx (operands[1]), operands[2]);
16669 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16670 operands[5], const0_rtx);
16671 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16672 copy_rtx (operands[1]),
16673 copy_rtx (operands[2]));
16674 })
16675
16676 ;; Attempt to always use XOR for zeroing registers.
16677 (define_peephole2
16678 [(set (match_operand 0 "register_operand")
16679 (match_operand 1 "const0_operand"))]
16680 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16681 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16682 && GENERAL_REG_P (operands[0])
16683 && peep2_regno_dead_p (0, FLAGS_REG)"
16684 [(parallel [(set (match_dup 0) (const_int 0))
16685 (clobber (reg:CC FLAGS_REG))])]
16686 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16687
16688 (define_peephole2
16689 [(set (strict_low_part (match_operand 0 "register_operand"))
16690 (const_int 0))]
16691 "(GET_MODE (operands[0]) == QImode
16692 || GET_MODE (operands[0]) == HImode)
16693 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16694 && peep2_regno_dead_p (0, FLAGS_REG)"
16695 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16696 (clobber (reg:CC FLAGS_REG))])])
16697
16698 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16699 (define_peephole2
16700 [(set (match_operand:SWI248 0 "register_operand")
16701 (const_int -1))]
16702 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16703 && peep2_regno_dead_p (0, FLAGS_REG)"
16704 [(parallel [(set (match_dup 0) (const_int -1))
16705 (clobber (reg:CC FLAGS_REG))])]
16706 {
16707 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16708 operands[0] = gen_lowpart (SImode, operands[0]);
16709 })
16710
16711 ;; Attempt to convert simple lea to add/shift.
16712 ;; These can be created by move expanders.
16713 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
16714 ;; relevant lea instructions were already split.
16715
16716 (define_peephole2
16717 [(set (match_operand:SWI48 0 "register_operand")
16718 (plus:SWI48 (match_dup 0)
16719 (match_operand:SWI48 1 "<nonmemory_operand>")))]
16720 "!TARGET_OPT_AGU
16721 && peep2_regno_dead_p (0, FLAGS_REG)"
16722 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16723 (clobber (reg:CC FLAGS_REG))])])
16724
16725 (define_peephole2
16726 [(set (match_operand:SWI48 0 "register_operand")
16727 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
16728 (match_dup 0)))]
16729 "!TARGET_OPT_AGU
16730 && peep2_regno_dead_p (0, FLAGS_REG)"
16731 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16732 (clobber (reg:CC FLAGS_REG))])])
16733
16734 (define_peephole2
16735 [(set (match_operand:DI 0 "register_operand")
16736 (zero_extend:DI
16737 (plus:SI (match_operand:SI 1 "register_operand")
16738 (match_operand:SI 2 "nonmemory_operand"))))]
16739 "TARGET_64BIT && !TARGET_OPT_AGU
16740 && REGNO (operands[0]) == REGNO (operands[1])
16741 && peep2_regno_dead_p (0, FLAGS_REG)"
16742 [(parallel [(set (match_dup 0)
16743 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
16744 (clobber (reg:CC FLAGS_REG))])])
16745
16746 (define_peephole2
16747 [(set (match_operand:DI 0 "register_operand")
16748 (zero_extend:DI
16749 (plus:SI (match_operand:SI 1 "nonmemory_operand")
16750 (match_operand:SI 2 "register_operand"))))]
16751 "TARGET_64BIT && !TARGET_OPT_AGU
16752 && REGNO (operands[0]) == REGNO (operands[2])
16753 && peep2_regno_dead_p (0, FLAGS_REG)"
16754 [(parallel [(set (match_dup 0)
16755 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
16756 (clobber (reg:CC FLAGS_REG))])])
16757
16758 (define_peephole2
16759 [(set (match_operand:SWI48 0 "register_operand")
16760 (mult:SWI48 (match_dup 0)
16761 (match_operand:SWI48 1 "const_int_operand")))]
16762 "exact_log2 (INTVAL (operands[1])) >= 0
16763 && peep2_regno_dead_p (0, FLAGS_REG)"
16764 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
16765 (clobber (reg:CC FLAGS_REG))])]
16766 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16767
16768 (define_peephole2
16769 [(set (match_operand:DI 0 "register_operand")
16770 (zero_extend:DI
16771 (mult:SI (match_operand:SI 1 "register_operand")
16772 (match_operand:SI 2 "const_int_operand"))))]
16773 "TARGET_64BIT
16774 && exact_log2 (INTVAL (operands[2])) >= 0
16775 && REGNO (operands[0]) == REGNO (operands[1])
16776 && peep2_regno_dead_p (0, FLAGS_REG)"
16777 [(parallel [(set (match_dup 0)
16778 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
16779 (clobber (reg:CC FLAGS_REG))])]
16780 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16781
16782 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16783 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16784 ;; On many CPUs it is also faster, since special hardware to avoid esp
16785 ;; dependencies is present.
16786
16787 ;; While some of these conversions may be done using splitters, we use
16788 ;; peepholes in order to allow combine_stack_adjustments pass to see
16789 ;; nonobfuscated RTL.
16790
16791 ;; Convert prologue esp subtractions to push.
16792 ;; We need register to push. In order to keep verify_flow_info happy we have
16793 ;; two choices
16794 ;; - use scratch and clobber it in order to avoid dependencies
16795 ;; - use already live register
16796 ;; We can't use the second way right now, since there is no reliable way how to
16797 ;; verify that given register is live. First choice will also most likely in
16798 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16799 ;; call clobbered registers are dead. We may want to use base pointer as an
16800 ;; alternative when no register is available later.
16801
16802 (define_peephole2
16803 [(match_scratch:W 1 "r")
16804 (parallel [(set (reg:P SP_REG)
16805 (plus:P (reg:P SP_REG)
16806 (match_operand:P 0 "const_int_operand")))
16807 (clobber (reg:CC FLAGS_REG))
16808 (clobber (mem:BLK (scratch)))])]
16809 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16810 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16811 [(clobber (match_dup 1))
16812 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16813 (clobber (mem:BLK (scratch)))])])
16814
16815 (define_peephole2
16816 [(match_scratch:W 1 "r")
16817 (parallel [(set (reg:P SP_REG)
16818 (plus:P (reg:P SP_REG)
16819 (match_operand:P 0 "const_int_operand")))
16820 (clobber (reg:CC FLAGS_REG))
16821 (clobber (mem:BLK (scratch)))])]
16822 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16823 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16824 [(clobber (match_dup 1))
16825 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16826 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16827 (clobber (mem:BLK (scratch)))])])
16828
16829 ;; Convert esp subtractions to push.
16830 (define_peephole2
16831 [(match_scratch:W 1 "r")
16832 (parallel [(set (reg:P SP_REG)
16833 (plus:P (reg:P SP_REG)
16834 (match_operand:P 0 "const_int_operand")))
16835 (clobber (reg:CC FLAGS_REG))])]
16836 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16837 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16838 [(clobber (match_dup 1))
16839 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16840
16841 (define_peephole2
16842 [(match_scratch:W 1 "r")
16843 (parallel [(set (reg:P SP_REG)
16844 (plus:P (reg:P SP_REG)
16845 (match_operand:P 0 "const_int_operand")))
16846 (clobber (reg:CC FLAGS_REG))])]
16847 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16848 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16849 [(clobber (match_dup 1))
16850 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16851 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16852
16853 ;; Convert epilogue deallocator to pop.
16854 (define_peephole2
16855 [(match_scratch:W 1 "r")
16856 (parallel [(set (reg:P SP_REG)
16857 (plus:P (reg:P SP_REG)
16858 (match_operand:P 0 "const_int_operand")))
16859 (clobber (reg:CC FLAGS_REG))
16860 (clobber (mem:BLK (scratch)))])]
16861 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16862 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
16863 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16864 (clobber (mem:BLK (scratch)))])])
16865
16866 ;; Two pops case is tricky, since pop causes dependency
16867 ;; on destination register. We use two registers if available.
16868 (define_peephole2
16869 [(match_scratch:W 1 "r")
16870 (match_scratch:W 2 "r")
16871 (parallel [(set (reg:P SP_REG)
16872 (plus:P (reg:P SP_REG)
16873 (match_operand:P 0 "const_int_operand")))
16874 (clobber (reg:CC FLAGS_REG))
16875 (clobber (mem:BLK (scratch)))])]
16876 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16877 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16878 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16879 (clobber (mem:BLK (scratch)))])
16880 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
16881
16882 (define_peephole2
16883 [(match_scratch:W 1 "r")
16884 (parallel [(set (reg:P SP_REG)
16885 (plus:P (reg:P SP_REG)
16886 (match_operand:P 0 "const_int_operand")))
16887 (clobber (reg:CC FLAGS_REG))
16888 (clobber (mem:BLK (scratch)))])]
16889 "optimize_insn_for_size_p ()
16890 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16891 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16892 (clobber (mem:BLK (scratch)))])
16893 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16894
16895 ;; Convert esp additions to pop.
16896 (define_peephole2
16897 [(match_scratch:W 1 "r")
16898 (parallel [(set (reg:P SP_REG)
16899 (plus:P (reg:P SP_REG)
16900 (match_operand:P 0 "const_int_operand")))
16901 (clobber (reg:CC FLAGS_REG))])]
16902 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
16903 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16904
16905 ;; Two pops case is tricky, since pop causes dependency
16906 ;; on destination register. We use two registers if available.
16907 (define_peephole2
16908 [(match_scratch:W 1 "r")
16909 (match_scratch:W 2 "r")
16910 (parallel [(set (reg:P SP_REG)
16911 (plus:P (reg:P SP_REG)
16912 (match_operand:P 0 "const_int_operand")))
16913 (clobber (reg:CC FLAGS_REG))])]
16914 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16915 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16916 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
16917
16918 (define_peephole2
16919 [(match_scratch:W 1 "r")
16920 (parallel [(set (reg:P SP_REG)
16921 (plus:P (reg:P SP_REG)
16922 (match_operand:P 0 "const_int_operand")))
16923 (clobber (reg:CC FLAGS_REG))])]
16924 "optimize_insn_for_size_p ()
16925 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16926 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16927 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16928 \f
16929 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16930 ;; required and register dies. Similarly for 128 to -128.
16931 (define_peephole2
16932 [(set (match_operand 0 "flags_reg_operand")
16933 (match_operator 1 "compare_operator"
16934 [(match_operand 2 "register_operand")
16935 (match_operand 3 "const_int_operand")]))]
16936 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
16937 && incdec_operand (operands[3], GET_MODE (operands[3])))
16938 || (!TARGET_FUSE_CMP_AND_BRANCH
16939 && INTVAL (operands[3]) == 128))
16940 && ix86_match_ccmode (insn, CCGCmode)
16941 && peep2_reg_dead_p (1, operands[2])"
16942 [(parallel [(set (match_dup 0)
16943 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
16944 (clobber (match_dup 2))])])
16945 \f
16946 ;; Convert imul by three, five and nine into lea
16947 (define_peephole2
16948 [(parallel
16949 [(set (match_operand:SWI48 0 "register_operand")
16950 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
16951 (match_operand:SWI48 2 "const359_operand")))
16952 (clobber (reg:CC FLAGS_REG))])]
16953 "!TARGET_PARTIAL_REG_STALL
16954 || <MODE>mode == SImode
16955 || optimize_function_for_size_p (cfun)"
16956 [(set (match_dup 0)
16957 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
16958 (match_dup 1)))]
16959 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16960
16961 (define_peephole2
16962 [(parallel
16963 [(set (match_operand:SWI48 0 "register_operand")
16964 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
16965 (match_operand:SWI48 2 "const359_operand")))
16966 (clobber (reg:CC FLAGS_REG))])]
16967 "optimize_insn_for_speed_p ()
16968 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
16969 [(set (match_dup 0) (match_dup 1))
16970 (set (match_dup 0)
16971 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
16972 (match_dup 0)))]
16973 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16974
16975 ;; imul $32bit_imm, mem, reg is vector decoded, while
16976 ;; imul $32bit_imm, reg, reg is direct decoded.
16977 (define_peephole2
16978 [(match_scratch:SWI48 3 "r")
16979 (parallel [(set (match_operand:SWI48 0 "register_operand")
16980 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
16981 (match_operand:SWI48 2 "immediate_operand")))
16982 (clobber (reg:CC FLAGS_REG))])]
16983 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16984 && !satisfies_constraint_K (operands[2])"
16985 [(set (match_dup 3) (match_dup 1))
16986 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
16987 (clobber (reg:CC FLAGS_REG))])])
16988
16989 (define_peephole2
16990 [(match_scratch:SI 3 "r")
16991 (parallel [(set (match_operand:DI 0 "register_operand")
16992 (zero_extend:DI
16993 (mult:SI (match_operand:SI 1 "memory_operand")
16994 (match_operand:SI 2 "immediate_operand"))))
16995 (clobber (reg:CC FLAGS_REG))])]
16996 "TARGET_64BIT
16997 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16998 && !satisfies_constraint_K (operands[2])"
16999 [(set (match_dup 3) (match_dup 1))
17000 (parallel [(set (match_dup 0)
17001 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17002 (clobber (reg:CC FLAGS_REG))])])
17003
17004 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17005 ;; Convert it into imul reg, reg
17006 ;; It would be better to force assembler to encode instruction using long
17007 ;; immediate, but there is apparently no way to do so.
17008 (define_peephole2
17009 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17010 (mult:SWI248
17011 (match_operand:SWI248 1 "nonimmediate_operand")
17012 (match_operand:SWI248 2 "const_int_operand")))
17013 (clobber (reg:CC FLAGS_REG))])
17014 (match_scratch:SWI248 3 "r")]
17015 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17016 && satisfies_constraint_K (operands[2])"
17017 [(set (match_dup 3) (match_dup 2))
17018 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17019 (clobber (reg:CC FLAGS_REG))])]
17020 {
17021 if (!rtx_equal_p (operands[0], operands[1]))
17022 emit_move_insn (operands[0], operands[1]);
17023 })
17024
17025 ;; After splitting up read-modify operations, array accesses with memory
17026 ;; operands might end up in form:
17027 ;; sall $2, %eax
17028 ;; movl 4(%esp), %edx
17029 ;; addl %edx, %eax
17030 ;; instead of pre-splitting:
17031 ;; sall $2, %eax
17032 ;; addl 4(%esp), %eax
17033 ;; Turn it into:
17034 ;; movl 4(%esp), %edx
17035 ;; leal (%edx,%eax,4), %eax
17036
17037 (define_peephole2
17038 [(match_scratch:W 5 "r")
17039 (parallel [(set (match_operand 0 "register_operand")
17040 (ashift (match_operand 1 "register_operand")
17041 (match_operand 2 "const_int_operand")))
17042 (clobber (reg:CC FLAGS_REG))])
17043 (parallel [(set (match_operand 3 "register_operand")
17044 (plus (match_dup 0)
17045 (match_operand 4 "x86_64_general_operand")))
17046 (clobber (reg:CC FLAGS_REG))])]
17047 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17048 /* Validate MODE for lea. */
17049 && ((!TARGET_PARTIAL_REG_STALL
17050 && (GET_MODE (operands[0]) == QImode
17051 || GET_MODE (operands[0]) == HImode))
17052 || GET_MODE (operands[0]) == SImode
17053 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17054 && (rtx_equal_p (operands[0], operands[3])
17055 || peep2_reg_dead_p (2, operands[0]))
17056 /* We reorder load and the shift. */
17057 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17058 [(set (match_dup 5) (match_dup 4))
17059 (set (match_dup 0) (match_dup 1))]
17060 {
17061 enum machine_mode op1mode = GET_MODE (operands[1]);
17062 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17063 int scale = 1 << INTVAL (operands[2]);
17064 rtx index = gen_lowpart (word_mode, operands[1]);
17065 rtx base = gen_lowpart (word_mode, operands[5]);
17066 rtx dest = gen_lowpart (mode, operands[3]);
17067
17068 operands[1] = gen_rtx_PLUS (word_mode, base,
17069 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17070 operands[5] = base;
17071 if (mode != word_mode)
17072 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17073 if (op1mode != word_mode)
17074 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17075 operands[0] = dest;
17076 })
17077 \f
17078 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17079 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17080 ;; caught for use by garbage collectors and the like. Using an insn that
17081 ;; maps to SIGILL makes it more likely the program will rightfully die.
17082 ;; Keeping with tradition, "6" is in honor of #UD.
17083 (define_insn "trap"
17084 [(trap_if (const_int 1) (const_int 6))]
17085 ""
17086 { return ASM_SHORT "0x0b0f"; }
17087 [(set_attr "length" "2")])
17088
17089 (define_expand "prefetch"
17090 [(prefetch (match_operand 0 "address_operand")
17091 (match_operand:SI 1 "const_int_operand")
17092 (match_operand:SI 2 "const_int_operand"))]
17093 "TARGET_PREFETCH_SSE || TARGET_PRFCHW"
17094 {
17095 bool write = INTVAL (operands[1]) != 0;
17096 int locality = INTVAL (operands[2]);
17097
17098 gcc_assert (IN_RANGE (locality, 0, 3));
17099
17100 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17101 supported by SSE counterpart or the SSE prefetch is not available
17102 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17103 of locality. */
17104 if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17105 operands[2] = GEN_INT (3);
17106 else
17107 operands[1] = const0_rtx;
17108 })
17109
17110 (define_insn "*prefetch_sse"
17111 [(prefetch (match_operand 0 "address_operand" "p")
17112 (const_int 0)
17113 (match_operand:SI 1 "const_int_operand"))]
17114 "TARGET_PREFETCH_SSE"
17115 {
17116 static const char * const patterns[4] = {
17117 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17118 };
17119
17120 int locality = INTVAL (operands[1]);
17121 gcc_assert (IN_RANGE (locality, 0, 3));
17122
17123 return patterns[locality];
17124 }
17125 [(set_attr "type" "sse")
17126 (set_attr "atom_sse_attr" "prefetch")
17127 (set (attr "length_address")
17128 (symbol_ref "memory_address_length (operands[0], false)"))
17129 (set_attr "memory" "none")])
17130
17131 (define_insn "*prefetch_3dnow"
17132 [(prefetch (match_operand 0 "address_operand" "p")
17133 (match_operand:SI 1 "const_int_operand" "n")
17134 (const_int 3))]
17135 "TARGET_PRFCHW"
17136 {
17137 if (INTVAL (operands[1]) == 0)
17138 return "prefetch\t%a0";
17139 else
17140 return "prefetchw\t%a0";
17141 }
17142 [(set_attr "type" "mmx")
17143 (set (attr "length_address")
17144 (symbol_ref "memory_address_length (operands[0], false)"))
17145 (set_attr "memory" "none")])
17146
17147 (define_expand "stack_protect_set"
17148 [(match_operand 0 "memory_operand")
17149 (match_operand 1 "memory_operand")]
17150 "TARGET_SSP_TLS_GUARD"
17151 {
17152 rtx (*insn)(rtx, rtx);
17153
17154 #ifdef TARGET_THREAD_SSP_OFFSET
17155 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17156 insn = (TARGET_LP64
17157 ? gen_stack_tls_protect_set_di
17158 : gen_stack_tls_protect_set_si);
17159 #else
17160 insn = (TARGET_LP64
17161 ? gen_stack_protect_set_di
17162 : gen_stack_protect_set_si);
17163 #endif
17164
17165 emit_insn (insn (operands[0], operands[1]));
17166 DONE;
17167 })
17168
17169 (define_insn "stack_protect_set_<mode>"
17170 [(set (match_operand:PTR 0 "memory_operand" "=m")
17171 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17172 UNSPEC_SP_SET))
17173 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17174 (clobber (reg:CC FLAGS_REG))]
17175 "TARGET_SSP_TLS_GUARD"
17176 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17177 [(set_attr "type" "multi")])
17178
17179 (define_insn "stack_tls_protect_set_<mode>"
17180 [(set (match_operand:PTR 0 "memory_operand" "=m")
17181 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17182 UNSPEC_SP_TLS_SET))
17183 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17184 (clobber (reg:CC FLAGS_REG))]
17185 ""
17186 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17187 [(set_attr "type" "multi")])
17188
17189 (define_expand "stack_protect_test"
17190 [(match_operand 0 "memory_operand")
17191 (match_operand 1 "memory_operand")
17192 (match_operand 2)]
17193 "TARGET_SSP_TLS_GUARD"
17194 {
17195 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17196
17197 rtx (*insn)(rtx, rtx, rtx);
17198
17199 #ifdef TARGET_THREAD_SSP_OFFSET
17200 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17201 insn = (TARGET_LP64
17202 ? gen_stack_tls_protect_test_di
17203 : gen_stack_tls_protect_test_si);
17204 #else
17205 insn = (TARGET_LP64
17206 ? gen_stack_protect_test_di
17207 : gen_stack_protect_test_si);
17208 #endif
17209
17210 emit_insn (insn (flags, operands[0], operands[1]));
17211
17212 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17213 flags, const0_rtx, operands[2]));
17214 DONE;
17215 })
17216
17217 (define_insn "stack_protect_test_<mode>"
17218 [(set (match_operand:CCZ 0 "flags_reg_operand")
17219 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17220 (match_operand:PTR 2 "memory_operand" "m")]
17221 UNSPEC_SP_TEST))
17222 (clobber (match_scratch:PTR 3 "=&r"))]
17223 "TARGET_SSP_TLS_GUARD"
17224 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17225 [(set_attr "type" "multi")])
17226
17227 (define_insn "stack_tls_protect_test_<mode>"
17228 [(set (match_operand:CCZ 0 "flags_reg_operand")
17229 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17230 (match_operand:PTR 2 "const_int_operand" "i")]
17231 UNSPEC_SP_TLS_TEST))
17232 (clobber (match_scratch:PTR 3 "=r"))]
17233 ""
17234 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17235 [(set_attr "type" "multi")])
17236
17237 (define_insn "sse4_2_crc32<mode>"
17238 [(set (match_operand:SI 0 "register_operand" "=r")
17239 (unspec:SI
17240 [(match_operand:SI 1 "register_operand" "0")
17241 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17242 UNSPEC_CRC32))]
17243 "TARGET_SSE4_2 || TARGET_CRC32"
17244 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17245 [(set_attr "type" "sselog1")
17246 (set_attr "prefix_rep" "1")
17247 (set_attr "prefix_extra" "1")
17248 (set (attr "prefix_data16")
17249 (if_then_else (match_operand:HI 2)
17250 (const_string "1")
17251 (const_string "*")))
17252 (set (attr "prefix_rex")
17253 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17254 (const_string "1")
17255 (const_string "*")))
17256 (set_attr "mode" "SI")])
17257
17258 (define_insn "sse4_2_crc32di"
17259 [(set (match_operand:DI 0 "register_operand" "=r")
17260 (unspec:DI
17261 [(match_operand:DI 1 "register_operand" "0")
17262 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17263 UNSPEC_CRC32))]
17264 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17265 "crc32{q}\t{%2, %0|%0, %2}"
17266 [(set_attr "type" "sselog1")
17267 (set_attr "prefix_rep" "1")
17268 (set_attr "prefix_extra" "1")
17269 (set_attr "mode" "DI")])
17270
17271 (define_insn "rdpmc"
17272 [(set (match_operand:DI 0 "register_operand" "=A")
17273 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17274 UNSPECV_RDPMC))]
17275 "!TARGET_64BIT"
17276 "rdpmc"
17277 [(set_attr "type" "other")
17278 (set_attr "length" "2")])
17279
17280 (define_insn "rdpmc_rex64"
17281 [(set (match_operand:DI 0 "register_operand" "=a")
17282 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17283 UNSPECV_RDPMC))
17284 (set (match_operand:DI 1 "register_operand" "=d")
17285 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17286 "TARGET_64BIT"
17287 "rdpmc"
17288 [(set_attr "type" "other")
17289 (set_attr "length" "2")])
17290
17291 (define_insn "rdtsc"
17292 [(set (match_operand:DI 0 "register_operand" "=A")
17293 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17294 "!TARGET_64BIT"
17295 "rdtsc"
17296 [(set_attr "type" "other")
17297 (set_attr "length" "2")])
17298
17299 (define_insn "rdtsc_rex64"
17300 [(set (match_operand:DI 0 "register_operand" "=a")
17301 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17302 (set (match_operand:DI 1 "register_operand" "=d")
17303 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17304 "TARGET_64BIT"
17305 "rdtsc"
17306 [(set_attr "type" "other")
17307 (set_attr "length" "2")])
17308
17309 (define_insn "rdtscp"
17310 [(set (match_operand:DI 0 "register_operand" "=A")
17311 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17312 (set (match_operand:SI 1 "register_operand" "=c")
17313 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17314 "!TARGET_64BIT"
17315 "rdtscp"
17316 [(set_attr "type" "other")
17317 (set_attr "length" "3")])
17318
17319 (define_insn "rdtscp_rex64"
17320 [(set (match_operand:DI 0 "register_operand" "=a")
17321 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17322 (set (match_operand:DI 1 "register_operand" "=d")
17323 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17324 (set (match_operand:SI 2 "register_operand" "=c")
17325 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17326 "TARGET_64BIT"
17327 "rdtscp"
17328 [(set_attr "type" "other")
17329 (set_attr "length" "3")])
17330
17331 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17332 ;;
17333 ;; FXSR, XSAVE and XSAVEOPT instructions
17334 ;;
17335 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17336
17337 (define_insn "fxsave"
17338 [(set (match_operand:BLK 0 "memory_operand" "=m")
17339 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17340 "TARGET_FXSR"
17341 "fxsave\t%0"
17342 [(set_attr "type" "other")
17343 (set_attr "memory" "store")
17344 (set (attr "length")
17345 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17346
17347 (define_insn "fxsave64"
17348 [(set (match_operand:BLK 0 "memory_operand" "=m")
17349 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17350 "TARGET_64BIT && TARGET_FXSR"
17351 "fxsave64\t%0"
17352 [(set_attr "type" "other")
17353 (set_attr "memory" "store")
17354 (set (attr "length")
17355 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17356
17357 (define_insn "fxrstor"
17358 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17359 UNSPECV_FXRSTOR)]
17360 "TARGET_FXSR"
17361 "fxrstor\t%0"
17362 [(set_attr "type" "other")
17363 (set_attr "memory" "load")
17364 (set (attr "length")
17365 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17366
17367 (define_insn "fxrstor64"
17368 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17369 UNSPECV_FXRSTOR64)]
17370 "TARGET_64BIT && TARGET_FXSR"
17371 "fxrstor64\t%0"
17372 [(set_attr "type" "other")
17373 (set_attr "memory" "load")
17374 (set (attr "length")
17375 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17376
17377 (define_int_iterator ANY_XSAVE
17378 [UNSPECV_XSAVE
17379 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17380
17381 (define_int_iterator ANY_XSAVE64
17382 [UNSPECV_XSAVE64
17383 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17384
17385 (define_int_attr xsave
17386 [(UNSPECV_XSAVE "xsave")
17387 (UNSPECV_XSAVE64 "xsave64")
17388 (UNSPECV_XSAVEOPT "xsaveopt")
17389 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17390
17391 (define_insn "<xsave>"
17392 [(set (match_operand:BLK 0 "memory_operand" "=m")
17393 (unspec_volatile:BLK
17394 [(match_operand:DI 1 "register_operand" "A")]
17395 ANY_XSAVE))]
17396 "!TARGET_64BIT && TARGET_XSAVE"
17397 "<xsave>\t%0"
17398 [(set_attr "type" "other")
17399 (set_attr "memory" "store")
17400 (set (attr "length")
17401 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17402
17403 (define_insn "<xsave>_rex64"
17404 [(set (match_operand:BLK 0 "memory_operand" "=m")
17405 (unspec_volatile:BLK
17406 [(match_operand:SI 1 "register_operand" "a")
17407 (match_operand:SI 2 "register_operand" "d")]
17408 ANY_XSAVE))]
17409 "TARGET_64BIT && TARGET_XSAVE"
17410 "<xsave>\t%0"
17411 [(set_attr "type" "other")
17412 (set_attr "memory" "store")
17413 (set (attr "length")
17414 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17415
17416 (define_insn "<xsave>"
17417 [(set (match_operand:BLK 0 "memory_operand" "=m")
17418 (unspec_volatile:BLK
17419 [(match_operand:SI 1 "register_operand" "a")
17420 (match_operand:SI 2 "register_operand" "d")]
17421 ANY_XSAVE64))]
17422 "TARGET_64BIT && TARGET_XSAVE"
17423 "<xsave>\t%0"
17424 [(set_attr "type" "other")
17425 (set_attr "memory" "store")
17426 (set (attr "length")
17427 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17428
17429 (define_insn "xrstor"
17430 [(unspec_volatile:BLK
17431 [(match_operand:BLK 0 "memory_operand" "m")
17432 (match_operand:DI 1 "register_operand" "A")]
17433 UNSPECV_XRSTOR)]
17434 "!TARGET_64BIT && TARGET_XSAVE"
17435 "xrstor\t%0"
17436 [(set_attr "type" "other")
17437 (set_attr "memory" "load")
17438 (set (attr "length")
17439 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17440
17441 (define_insn "xrstor_rex64"
17442 [(unspec_volatile:BLK
17443 [(match_operand:BLK 0 "memory_operand" "m")
17444 (match_operand:SI 1 "register_operand" "a")
17445 (match_operand:SI 2 "register_operand" "d")]
17446 UNSPECV_XRSTOR)]
17447 "TARGET_64BIT && TARGET_XSAVE"
17448 "xrstor\t%0"
17449 [(set_attr "type" "other")
17450 (set_attr "memory" "load")
17451 (set (attr "length")
17452 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17453
17454 (define_insn "xrstor64"
17455 [(unspec_volatile:BLK
17456 [(match_operand:BLK 0 "memory_operand" "m")
17457 (match_operand:SI 1 "register_operand" "a")
17458 (match_operand:SI 2 "register_operand" "d")]
17459 UNSPECV_XRSTOR64)]
17460 "TARGET_64BIT && TARGET_XSAVE"
17461 "xrstor64\t%0"
17462 [(set_attr "type" "other")
17463 (set_attr "memory" "load")
17464 (set (attr "length")
17465 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17466
17467 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17468 ;;
17469 ;; LWP instructions
17470 ;;
17471 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17472
17473 (define_expand "lwp_llwpcb"
17474 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17475 UNSPECV_LLWP_INTRINSIC)]
17476 "TARGET_LWP")
17477
17478 (define_insn "*lwp_llwpcb<mode>1"
17479 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17480 UNSPECV_LLWP_INTRINSIC)]
17481 "TARGET_LWP"
17482 "llwpcb\t%0"
17483 [(set_attr "type" "lwp")
17484 (set_attr "mode" "<MODE>")
17485 (set_attr "length" "5")])
17486
17487 (define_expand "lwp_slwpcb"
17488 [(set (match_operand 0 "register_operand" "=r")
17489 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17490 "TARGET_LWP"
17491 {
17492 rtx (*insn)(rtx);
17493
17494 insn = (Pmode == DImode
17495 ? gen_lwp_slwpcbdi
17496 : gen_lwp_slwpcbsi);
17497
17498 emit_insn (insn (operands[0]));
17499 DONE;
17500 })
17501
17502 (define_insn "lwp_slwpcb<mode>"
17503 [(set (match_operand:P 0 "register_operand" "=r")
17504 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17505 "TARGET_LWP"
17506 "slwpcb\t%0"
17507 [(set_attr "type" "lwp")
17508 (set_attr "mode" "<MODE>")
17509 (set_attr "length" "5")])
17510
17511 (define_expand "lwp_lwpval<mode>3"
17512 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17513 (match_operand:SI 2 "nonimmediate_operand" "rm")
17514 (match_operand:SI 3 "const_int_operand" "i")]
17515 UNSPECV_LWPVAL_INTRINSIC)]
17516 "TARGET_LWP"
17517 ;; Avoid unused variable warning.
17518 "(void) operands[0];")
17519
17520 (define_insn "*lwp_lwpval<mode>3_1"
17521 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17522 (match_operand:SI 1 "nonimmediate_operand" "rm")
17523 (match_operand:SI 2 "const_int_operand" "i")]
17524 UNSPECV_LWPVAL_INTRINSIC)]
17525 "TARGET_LWP"
17526 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17527 [(set_attr "type" "lwp")
17528 (set_attr "mode" "<MODE>")
17529 (set (attr "length")
17530 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17531
17532 (define_expand "lwp_lwpins<mode>3"
17533 [(set (reg:CCC FLAGS_REG)
17534 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17535 (match_operand:SI 2 "nonimmediate_operand" "rm")
17536 (match_operand:SI 3 "const_int_operand" "i")]
17537 UNSPECV_LWPINS_INTRINSIC))
17538 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17539 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17540 "TARGET_LWP")
17541
17542 (define_insn "*lwp_lwpins<mode>3_1"
17543 [(set (reg:CCC FLAGS_REG)
17544 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17545 (match_operand:SI 1 "nonimmediate_operand" "rm")
17546 (match_operand:SI 2 "const_int_operand" "i")]
17547 UNSPECV_LWPINS_INTRINSIC))]
17548 "TARGET_LWP"
17549 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17550 [(set_attr "type" "lwp")
17551 (set_attr "mode" "<MODE>")
17552 (set (attr "length")
17553 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17554
17555 (define_int_iterator RDFSGSBASE
17556 [UNSPECV_RDFSBASE
17557 UNSPECV_RDGSBASE])
17558
17559 (define_int_iterator WRFSGSBASE
17560 [UNSPECV_WRFSBASE
17561 UNSPECV_WRGSBASE])
17562
17563 (define_int_attr fsgs
17564 [(UNSPECV_RDFSBASE "fs")
17565 (UNSPECV_RDGSBASE "gs")
17566 (UNSPECV_WRFSBASE "fs")
17567 (UNSPECV_WRGSBASE "gs")])
17568
17569 (define_insn "rd<fsgs>base<mode>"
17570 [(set (match_operand:SWI48 0 "register_operand" "=r")
17571 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
17572 "TARGET_64BIT && TARGET_FSGSBASE"
17573 "rd<fsgs>base\t%0"
17574 [(set_attr "type" "other")
17575 (set_attr "prefix_extra" "2")])
17576
17577 (define_insn "wr<fsgs>base<mode>"
17578 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17579 WRFSGSBASE)]
17580 "TARGET_64BIT && TARGET_FSGSBASE"
17581 "wr<fsgs>base\t%0"
17582 [(set_attr "type" "other")
17583 (set_attr "prefix_extra" "2")])
17584
17585 (define_insn "rdrand<mode>_1"
17586 [(set (match_operand:SWI248 0 "register_operand" "=r")
17587 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
17588 (set (reg:CCC FLAGS_REG)
17589 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
17590 "TARGET_RDRND"
17591 "rdrand\t%0"
17592 [(set_attr "type" "other")
17593 (set_attr "prefix_extra" "1")])
17594
17595 (define_insn "rdseed<mode>_1"
17596 [(set (match_operand:SWI248 0 "register_operand" "=r")
17597 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
17598 (set (reg:CCC FLAGS_REG)
17599 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
17600 "TARGET_RDSEED"
17601 "rdseed\t%0"
17602 [(set_attr "type" "other")
17603 (set_attr "prefix_extra" "1")])
17604
17605 (define_expand "pause"
17606 [(set (match_dup 0)
17607 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17608 ""
17609 {
17610 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17611 MEM_VOLATILE_P (operands[0]) = 1;
17612 })
17613
17614 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17615 ;; They have the same encoding.
17616 (define_insn "*pause"
17617 [(set (match_operand:BLK 0)
17618 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17619 ""
17620 "rep%; nop"
17621 [(set_attr "length" "2")
17622 (set_attr "memory" "unknown")])
17623
17624 (define_expand "xbegin"
17625 [(set (match_operand:SI 0 "register_operand")
17626 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
17627 "TARGET_RTM"
17628 {
17629 rtx label = gen_label_rtx ();
17630
17631 /* xbegin is emitted as jump_insn, so reload won't be able
17632 to reload its operand. Force the value into AX hard register. */
17633 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
17634 emit_move_insn (ax_reg, constm1_rtx);
17635
17636 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
17637
17638 emit_label (label);
17639 LABEL_NUSES (label) = 1;
17640
17641 emit_move_insn (operands[0], ax_reg);
17642
17643 DONE;
17644 })
17645
17646 (define_insn "xbegin_1"
17647 [(set (pc)
17648 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
17649 (const_int 0))
17650 (label_ref (match_operand 1))
17651 (pc)))
17652 (set (match_operand:SI 0 "register_operand" "+a")
17653 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
17654 "TARGET_RTM"
17655 "xbegin\t%l1"
17656 [(set_attr "type" "other")
17657 (set_attr "length" "6")])
17658
17659 (define_insn "xend"
17660 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
17661 "TARGET_RTM"
17662 "xend"
17663 [(set_attr "type" "other")
17664 (set_attr "length" "3")])
17665
17666 (define_insn "xabort"
17667 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
17668 UNSPECV_XABORT)]
17669 "TARGET_RTM"
17670 "xabort\t%0"
17671 [(set_attr "type" "other")
17672 (set_attr "length" "3")])
17673
17674 (define_expand "xtest"
17675 [(set (match_operand:QI 0 "register_operand")
17676 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
17677 "TARGET_RTM"
17678 {
17679 emit_insn (gen_xtest_1 ());
17680
17681 ix86_expand_setcc (operands[0], NE,
17682 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17683 DONE;
17684 })
17685
17686 (define_insn "xtest_1"
17687 [(set (reg:CCZ FLAGS_REG)
17688 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
17689 "TARGET_RTM"
17690 "xtest"
17691 [(set_attr "type" "other")
17692 (set_attr "length" "3")])
17693
17694 (include "mmx.md")
17695 (include "sse.md")
17696 (include "sync.md")