re PR target/34673 (ICE in extract_insn, at recog.c:1990)
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
31 ;; operands[1].
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
39 ;;
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
46
47 ;; UNSPEC usage:
48
49 (define_constants
50 [; Relocation specifiers
51 (UNSPEC_GOT 0)
52 (UNSPEC_GOTOFF 1)
53 (UNSPEC_GOTPCREL 2)
54 (UNSPEC_GOTTPOFF 3)
55 (UNSPEC_TPOFF 4)
56 (UNSPEC_NTPOFF 5)
57 (UNSPEC_DTPOFF 6)
58 (UNSPEC_GOTNTPOFF 7)
59 (UNSPEC_INDNTPOFF 8)
60 (UNSPEC_PLTOFF 9)
61
62 ; Prologue support
63 (UNSPEC_STACK_ALLOC 11)
64 (UNSPEC_SET_GOT 12)
65 (UNSPEC_SSE_PROLOGUE_SAVE 13)
66 (UNSPEC_REG_SAVE 14)
67 (UNSPEC_DEF_CFA 15)
68 (UNSPEC_SET_RIP 16)
69 (UNSPEC_SET_GOT_OFFSET 17)
70
71 ; TLS support
72 (UNSPEC_TP 18)
73 (UNSPEC_TLS_GD 19)
74 (UNSPEC_TLS_LD_BASE 20)
75 (UNSPEC_TLSDESC 21)
76
77 ; Other random patterns
78 (UNSPEC_SCAS 30)
79 (UNSPEC_FNSTSW 31)
80 (UNSPEC_SAHF 32)
81 (UNSPEC_FSTCW 33)
82 (UNSPEC_ADD_CARRY 34)
83 (UNSPEC_FLDCW 35)
84 (UNSPEC_REP 36)
85 (UNSPEC_EH_RETURN 37)
86 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
87 (UNSPEC_TRUNC_NOOP 39)
88
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 40)
91 (UNSPEC_MASKMOV 41)
92 (UNSPEC_MOVMSK 42)
93 (UNSPEC_MOVNT 43)
94 (UNSPEC_MOVU 44)
95 (UNSPEC_RCP 45)
96 (UNSPEC_RSQRT 46)
97 (UNSPEC_SFENCE 47)
98 (UNSPEC_NOP 48) ; prevents combiner cleverness
99 (UNSPEC_PFRCP 49)
100 (UNSPEC_PFRCPIT1 40)
101 (UNSPEC_PFRCPIT2 41)
102 (UNSPEC_PFRSQRT 42)
103 (UNSPEC_PFRSQIT1 43)
104 (UNSPEC_MFENCE 44)
105 (UNSPEC_LFENCE 45)
106 (UNSPEC_PSADBW 46)
107 (UNSPEC_LDDQU 47)
108
109 ; Generic math support
110 (UNSPEC_COPYSIGN 50)
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
113
114 ; x87 Floating point
115 (UNSPEC_SIN 60)
116 (UNSPEC_COS 61)
117 (UNSPEC_FPATAN 62)
118 (UNSPEC_FYL2X 63)
119 (UNSPEC_FYL2XP1 64)
120 (UNSPEC_FRNDINT 65)
121 (UNSPEC_FIST 66)
122 (UNSPEC_F2XM1 67)
123 (UNSPEC_TAN 68)
124 (UNSPEC_FXAM 69)
125
126 ; x87 Rounding
127 (UNSPEC_FRNDINT_FLOOR 70)
128 (UNSPEC_FRNDINT_CEIL 71)
129 (UNSPEC_FRNDINT_TRUNC 72)
130 (UNSPEC_FRNDINT_MASK_PM 73)
131 (UNSPEC_FIST_FLOOR 74)
132 (UNSPEC_FIST_CEIL 75)
133
134 ; x87 Double output FP
135 (UNSPEC_SINCOS_COS 80)
136 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
141 (UNSPEC_FPREM_F 88)
142 (UNSPEC_FPREM_U 89)
143 (UNSPEC_FPREM1_F 90)
144 (UNSPEC_FPREM1_U 91)
145
146 (UNSPEC_C2_FLAG 95)
147
148 ; SSP patterns
149 (UNSPEC_SP_SET 100)
150 (UNSPEC_SP_TEST 101)
151 (UNSPEC_SP_TLS_SET 102)
152 (UNSPEC_SP_TLS_TEST 103)
153
154 ; SSSE3
155 (UNSPEC_PSHUFB 120)
156 (UNSPEC_PSIGN 121)
157 (UNSPEC_PALIGNR 122)
158
159 ; For SSE4A support
160 (UNSPEC_EXTRQI 130)
161 (UNSPEC_EXTRQ 131)
162 (UNSPEC_INSERTQI 132)
163 (UNSPEC_INSERTQ 133)
164
165 ; For SSE4.1 support
166 (UNSPEC_BLENDV 134)
167 (UNSPEC_INSERTPS 135)
168 (UNSPEC_DP 136)
169 (UNSPEC_MOVNTDQA 137)
170 (UNSPEC_MPSADBW 138)
171 (UNSPEC_PHMINPOSUW 139)
172 (UNSPEC_PTEST 140)
173 (UNSPEC_ROUND 141)
174
175 ; For SSE4.2 support
176 (UNSPEC_CRC32 143)
177 (UNSPEC_PCMPESTR 144)
178 (UNSPEC_PCMPISTR 145)
179
180 ;; For SSE5
181 (UNSPEC_SSE5_INTRINSIC 150)
182 (UNSPEC_SSE5_UNSIGNED_CMP 151)
183 (UNSPEC_SSE5_TRUEFALSE 152)
184 (UNSPEC_SSE5_PERMUTE 153)
185 (UNSPEC_SSE5_ASHIFT 154)
186 (UNSPEC_SSE5_LSHIFT 155)
187 (UNSPEC_FRCZ 156)
188 (UNSPEC_CVTPH2PS 157)
189 (UNSPEC_CVTPS2PH 158)
190 ])
191
192 (define_constants
193 [(UNSPECV_BLOCKAGE 0)
194 (UNSPECV_STACK_PROBE 1)
195 (UNSPECV_EMMS 2)
196 (UNSPECV_LDMXCSR 3)
197 (UNSPECV_STMXCSR 4)
198 (UNSPECV_FEMMS 5)
199 (UNSPECV_CLFLUSH 6)
200 (UNSPECV_ALIGN 7)
201 (UNSPECV_MONITOR 8)
202 (UNSPECV_MWAIT 9)
203 (UNSPECV_CMPXCHG_1 10)
204 (UNSPECV_CMPXCHG_2 11)
205 (UNSPECV_XCHG 12)
206 (UNSPECV_LOCK 13)
207 (UNSPECV_PROLOGUE_USE 14)
208 ])
209
210 ;; Constants to represent pcomtrue/pcomfalse variants
211 (define_constants
212 [(PCOM_FALSE 0)
213 (PCOM_TRUE 1)
214 (COM_FALSE_S 2)
215 (COM_FALSE_P 3)
216 (COM_TRUE_S 4)
217 (COM_TRUE_P 5)
218 ])
219
220 ;; Registers by name.
221 (define_constants
222 [(AX_REG 0)
223 (DX_REG 1)
224 (CX_REG 2)
225 (SI_REG 4)
226 (DI_REG 5)
227 (BP_REG 6)
228 (SP_REG 7)
229 (FLAGS_REG 17)
230 (FPSR_REG 18)
231 (FPCR_REG 19)
232 (R10_REG 39)
233 (R11_REG 40)
234 ])
235
236 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
237 ;; from i386.c.
238
239 ;; In C guard expressions, put expressions which may be compile-time
240 ;; constants first. This allows for better optimization. For
241 ;; example, write "TARGET_64BIT && reload_completed", not
242 ;; "reload_completed && TARGET_64BIT".
243
244 \f
245 ;; Processor type. This attribute must exactly match the processor_type
246 ;; enumeration in i386.h.
247 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
248 nocona,core2,generic32,generic64,amdfam10"
249 (const (symbol_ref "ix86_tune")))
250
251 ;; A basic instruction type. Refinements due to arguments to be
252 ;; provided in other attributes.
253 (define_attr "type"
254 "other,multi,
255 alu,alu1,negnot,imov,imovx,lea,
256 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
257 icmp,test,ibr,setcc,icmov,
258 push,pop,call,callv,leave,
259 str,bitmanip,
260 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
261 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
262 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
263 ssemuladd,sse4arg,
264 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
265 (const_string "other"))
266
267 ;; Main data type used by the insn
268 (define_attr "mode"
269 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
270 (const_string "unknown"))
271
272 ;; The CPU unit operations uses.
273 (define_attr "unit" "integer,i387,sse,mmx,unknown"
274 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
275 (const_string "i387")
276 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
277 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
278 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
279 (const_string "sse")
280 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
281 (const_string "mmx")
282 (eq_attr "type" "other")
283 (const_string "unknown")]
284 (const_string "integer")))
285
286 ;; The (bounding maximum) length of an instruction immediate.
287 (define_attr "length_immediate" ""
288 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
289 bitmanip")
290 (const_int 0)
291 (eq_attr "unit" "i387,sse,mmx")
292 (const_int 0)
293 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
294 imul,icmp,push,pop")
295 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
296 (eq_attr "type" "imov,test")
297 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
298 (eq_attr "type" "call")
299 (if_then_else (match_operand 0 "constant_call_address_operand" "")
300 (const_int 4)
301 (const_int 0))
302 (eq_attr "type" "callv")
303 (if_then_else (match_operand 1 "constant_call_address_operand" "")
304 (const_int 4)
305 (const_int 0))
306 ;; We don't know the size before shorten_branches. Expect
307 ;; the instruction to fit for better scheduling.
308 (eq_attr "type" "ibr")
309 (const_int 1)
310 ]
311 (symbol_ref "/* Update immediate_length and other attributes! */
312 gcc_unreachable (),1")))
313
314 ;; The (bounding maximum) length of an instruction address.
315 (define_attr "length_address" ""
316 (cond [(eq_attr "type" "str,other,multi,fxch")
317 (const_int 0)
318 (and (eq_attr "type" "call")
319 (match_operand 0 "constant_call_address_operand" ""))
320 (const_int 0)
321 (and (eq_attr "type" "callv")
322 (match_operand 1 "constant_call_address_operand" ""))
323 (const_int 0)
324 ]
325 (symbol_ref "ix86_attr_length_address_default (insn)")))
326
327 ;; Set when length prefix is used.
328 (define_attr "prefix_data16" ""
329 (if_then_else (ior (eq_attr "mode" "HI")
330 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
331 (const_int 1)
332 (const_int 0)))
333
334 ;; Set when string REP prefix is used.
335 (define_attr "prefix_rep" ""
336 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
337 (const_int 1)
338 (const_int 0)))
339
340 ;; Set when 0f opcode prefix is used.
341 (define_attr "prefix_0f" ""
342 (if_then_else
343 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
344 (eq_attr "unit" "sse,mmx"))
345 (const_int 1)
346 (const_int 0)))
347
348 ;; Set when REX opcode prefix is used.
349 (define_attr "prefix_rex" ""
350 (cond [(and (eq_attr "mode" "DI")
351 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
352 (const_int 1)
353 (and (eq_attr "mode" "QI")
354 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
355 (const_int 0)))
356 (const_int 1)
357 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
358 (const_int 0))
359 (const_int 1)
360 ]
361 (const_int 0)))
362
363 ;; There are also additional prefixes in SSSE3.
364 (define_attr "prefix_extra" "" (const_int 0))
365
366 ;; Set when modrm byte is used.
367 (define_attr "modrm" ""
368 (cond [(eq_attr "type" "str,leave")
369 (const_int 0)
370 (eq_attr "unit" "i387")
371 (const_int 0)
372 (and (eq_attr "type" "incdec")
373 (ior (match_operand:SI 1 "register_operand" "")
374 (match_operand:HI 1 "register_operand" "")))
375 (const_int 0)
376 (and (eq_attr "type" "push")
377 (not (match_operand 1 "memory_operand" "")))
378 (const_int 0)
379 (and (eq_attr "type" "pop")
380 (not (match_operand 0 "memory_operand" "")))
381 (const_int 0)
382 (and (eq_attr "type" "imov")
383 (ior (and (match_operand 0 "register_operand" "")
384 (match_operand 1 "immediate_operand" ""))
385 (ior (and (match_operand 0 "ax_reg_operand" "")
386 (match_operand 1 "memory_displacement_only_operand" ""))
387 (and (match_operand 0 "memory_displacement_only_operand" "")
388 (match_operand 1 "ax_reg_operand" "")))))
389 (const_int 0)
390 (and (eq_attr "type" "call")
391 (match_operand 0 "constant_call_address_operand" ""))
392 (const_int 0)
393 (and (eq_attr "type" "callv")
394 (match_operand 1 "constant_call_address_operand" ""))
395 (const_int 0)
396 ]
397 (const_int 1)))
398
399 ;; The (bounding maximum) length of an instruction in bytes.
400 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
401 ;; Later we may want to split them and compute proper length as for
402 ;; other insns.
403 (define_attr "length" ""
404 (cond [(eq_attr "type" "other,multi,fistp,frndint")
405 (const_int 16)
406 (eq_attr "type" "fcmp")
407 (const_int 4)
408 (eq_attr "unit" "i387")
409 (plus (const_int 2)
410 (plus (attr "prefix_data16")
411 (attr "length_address")))]
412 (plus (plus (attr "modrm")
413 (plus (attr "prefix_0f")
414 (plus (attr "prefix_rex")
415 (plus (attr "prefix_extra")
416 (const_int 1)))))
417 (plus (attr "prefix_rep")
418 (plus (attr "prefix_data16")
419 (plus (attr "length_immediate")
420 (attr "length_address")))))))
421
422 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
423 ;; `store' if there is a simple memory reference therein, or `unknown'
424 ;; if the instruction is complex.
425
426 (define_attr "memory" "none,load,store,both,unknown"
427 (cond [(eq_attr "type" "other,multi,str")
428 (const_string "unknown")
429 (eq_attr "type" "lea,fcmov,fpspc")
430 (const_string "none")
431 (eq_attr "type" "fistp,leave")
432 (const_string "both")
433 (eq_attr "type" "frndint")
434 (const_string "load")
435 (eq_attr "type" "push")
436 (if_then_else (match_operand 1 "memory_operand" "")
437 (const_string "both")
438 (const_string "store"))
439 (eq_attr "type" "pop")
440 (if_then_else (match_operand 0 "memory_operand" "")
441 (const_string "both")
442 (const_string "load"))
443 (eq_attr "type" "setcc")
444 (if_then_else (match_operand 0 "memory_operand" "")
445 (const_string "store")
446 (const_string "none"))
447 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
448 (if_then_else (ior (match_operand 0 "memory_operand" "")
449 (match_operand 1 "memory_operand" ""))
450 (const_string "load")
451 (const_string "none"))
452 (eq_attr "type" "ibr")
453 (if_then_else (match_operand 0 "memory_operand" "")
454 (const_string "load")
455 (const_string "none"))
456 (eq_attr "type" "call")
457 (if_then_else (match_operand 0 "constant_call_address_operand" "")
458 (const_string "none")
459 (const_string "load"))
460 (eq_attr "type" "callv")
461 (if_then_else (match_operand 1 "constant_call_address_operand" "")
462 (const_string "none")
463 (const_string "load"))
464 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
465 (match_operand 1 "memory_operand" ""))
466 (const_string "both")
467 (and (match_operand 0 "memory_operand" "")
468 (match_operand 1 "memory_operand" ""))
469 (const_string "both")
470 (match_operand 0 "memory_operand" "")
471 (const_string "store")
472 (match_operand 1 "memory_operand" "")
473 (const_string "load")
474 (and (eq_attr "type"
475 "!alu1,negnot,ishift1,
476 imov,imovx,icmp,test,bitmanip,
477 fmov,fcmp,fsgn,
478 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
479 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
480 (match_operand 2 "memory_operand" ""))
481 (const_string "load")
482 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
483 (match_operand 3 "memory_operand" ""))
484 (const_string "load")
485 ]
486 (const_string "none")))
487
488 ;; Indicates if an instruction has both an immediate and a displacement.
489
490 (define_attr "imm_disp" "false,true,unknown"
491 (cond [(eq_attr "type" "other,multi")
492 (const_string "unknown")
493 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
494 (and (match_operand 0 "memory_displacement_operand" "")
495 (match_operand 1 "immediate_operand" "")))
496 (const_string "true")
497 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
498 (and (match_operand 0 "memory_displacement_operand" "")
499 (match_operand 2 "immediate_operand" "")))
500 (const_string "true")
501 ]
502 (const_string "false")))
503
504 ;; Indicates if an FP operation has an integer source.
505
506 (define_attr "fp_int_src" "false,true"
507 (const_string "false"))
508
509 ;; Defines rounding mode of an FP operation.
510
511 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
512 (const_string "any"))
513
514 ;; Describe a user's asm statement.
515 (define_asm_attributes
516 [(set_attr "length" "128")
517 (set_attr "type" "multi")])
518
519 (define_code_iterator plusminus [plus minus])
520
521 ;; Base name for define_insn and insn mnemonic.
522 (define_code_attr addsub [(plus "add") (minus "sub")])
523
524 ;; Mark commutative operators as such in constraints.
525 (define_code_attr comm [(plus "%") (minus "")])
526
527 ;; All single word integer modes.
528 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
529
530 ;; Instruction suffix for integer modes.
531 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
532
533 ;; Register class for integer modes.
534 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
535
536 ;; Immediate operand constraint for integer modes.
537 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
538
539 ;; General operand predicate for integer modes.
540 (define_mode_attr general_operand
541 [(QI "general_operand")
542 (HI "general_operand")
543 (SI "general_operand")
544 (DI "x86_64_general_operand")])
545
546 ;; SSE and x87 SFmode and DFmode floating point modes
547 (define_mode_iterator MODEF [SF DF])
548
549 ;; All x87 floating point modes
550 (define_mode_iterator X87MODEF [SF DF XF])
551
552 ;; All integer modes handled by x87 fisttp operator.
553 (define_mode_iterator X87MODEI [HI SI DI])
554
555 ;; All integer modes handled by integer x87 operators.
556 (define_mode_iterator X87MODEI12 [HI SI])
557
558 ;; All integer modes handled by SSE cvtts?2si* operators.
559 (define_mode_iterator SSEMODEI24 [SI DI])
560
561 ;; SSE asm suffix for floating point modes
562 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
563
564 ;; SSE vector mode corresponding to a scalar mode
565 (define_mode_attr ssevecmode
566 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
567 \f
568 ;; Scheduling descriptions
569
570 (include "pentium.md")
571 (include "ppro.md")
572 (include "k6.md")
573 (include "athlon.md")
574 (include "geode.md")
575
576 \f
577 ;; Operand and operator predicates and constraints
578
579 (include "predicates.md")
580 (include "constraints.md")
581
582 \f
583 ;; Compare instructions.
584
585 ;; All compare insns have expanders that save the operands away without
586 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
587 ;; after the cmp) will actually emit the cmpM.
588
589 (define_expand "cmpti"
590 [(set (reg:CC FLAGS_REG)
591 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
592 (match_operand:TI 1 "x86_64_general_operand" "")))]
593 "TARGET_64BIT"
594 {
595 if (MEM_P (operands[0]) && MEM_P (operands[1]))
596 operands[0] = force_reg (TImode, operands[0]);
597 ix86_compare_op0 = operands[0];
598 ix86_compare_op1 = operands[1];
599 DONE;
600 })
601
602 (define_expand "cmpdi"
603 [(set (reg:CC FLAGS_REG)
604 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
605 (match_operand:DI 1 "x86_64_general_operand" "")))]
606 ""
607 {
608 if (MEM_P (operands[0]) && MEM_P (operands[1]))
609 operands[0] = force_reg (DImode, operands[0]);
610 ix86_compare_op0 = operands[0];
611 ix86_compare_op1 = operands[1];
612 DONE;
613 })
614
615 (define_expand "cmpsi"
616 [(set (reg:CC FLAGS_REG)
617 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
618 (match_operand:SI 1 "general_operand" "")))]
619 ""
620 {
621 if (MEM_P (operands[0]) && MEM_P (operands[1]))
622 operands[0] = force_reg (SImode, operands[0]);
623 ix86_compare_op0 = operands[0];
624 ix86_compare_op1 = operands[1];
625 DONE;
626 })
627
628 (define_expand "cmphi"
629 [(set (reg:CC FLAGS_REG)
630 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
631 (match_operand:HI 1 "general_operand" "")))]
632 ""
633 {
634 if (MEM_P (operands[0]) && MEM_P (operands[1]))
635 operands[0] = force_reg (HImode, operands[0]);
636 ix86_compare_op0 = operands[0];
637 ix86_compare_op1 = operands[1];
638 DONE;
639 })
640
641 (define_expand "cmpqi"
642 [(set (reg:CC FLAGS_REG)
643 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
644 (match_operand:QI 1 "general_operand" "")))]
645 "TARGET_QIMODE_MATH"
646 {
647 if (MEM_P (operands[0]) && MEM_P (operands[1]))
648 operands[0] = force_reg (QImode, operands[0]);
649 ix86_compare_op0 = operands[0];
650 ix86_compare_op1 = operands[1];
651 DONE;
652 })
653
654 (define_insn "cmpdi_ccno_1_rex64"
655 [(set (reg FLAGS_REG)
656 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
657 (match_operand:DI 1 "const0_operand" "n,n")))]
658 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
659 "@
660 test{q}\t%0, %0
661 cmp{q}\t{%1, %0|%0, %1}"
662 [(set_attr "type" "test,icmp")
663 (set_attr "length_immediate" "0,1")
664 (set_attr "mode" "DI")])
665
666 (define_insn "*cmpdi_minus_1_rex64"
667 [(set (reg FLAGS_REG)
668 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
669 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
670 (const_int 0)))]
671 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
672 "cmp{q}\t{%1, %0|%0, %1}"
673 [(set_attr "type" "icmp")
674 (set_attr "mode" "DI")])
675
676 (define_expand "cmpdi_1_rex64"
677 [(set (reg:CC FLAGS_REG)
678 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
679 (match_operand:DI 1 "general_operand" "")))]
680 "TARGET_64BIT"
681 "")
682
683 (define_insn "cmpdi_1_insn_rex64"
684 [(set (reg FLAGS_REG)
685 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
686 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
687 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688 "cmp{q}\t{%1, %0|%0, %1}"
689 [(set_attr "type" "icmp")
690 (set_attr "mode" "DI")])
691
692
693 (define_insn "*cmpsi_ccno_1"
694 [(set (reg FLAGS_REG)
695 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
696 (match_operand:SI 1 "const0_operand" "n,n")))]
697 "ix86_match_ccmode (insn, CCNOmode)"
698 "@
699 test{l}\t%0, %0
700 cmp{l}\t{%1, %0|%0, %1}"
701 [(set_attr "type" "test,icmp")
702 (set_attr "length_immediate" "0,1")
703 (set_attr "mode" "SI")])
704
705 (define_insn "*cmpsi_minus_1"
706 [(set (reg FLAGS_REG)
707 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
708 (match_operand:SI 1 "general_operand" "ri,mr"))
709 (const_int 0)))]
710 "ix86_match_ccmode (insn, CCGOCmode)"
711 "cmp{l}\t{%1, %0|%0, %1}"
712 [(set_attr "type" "icmp")
713 (set_attr "mode" "SI")])
714
715 (define_expand "cmpsi_1"
716 [(set (reg:CC FLAGS_REG)
717 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
718 (match_operand:SI 1 "general_operand" "")))]
719 ""
720 "")
721
722 (define_insn "*cmpsi_1_insn"
723 [(set (reg FLAGS_REG)
724 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
725 (match_operand:SI 1 "general_operand" "ri,mr")))]
726 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
727 && ix86_match_ccmode (insn, CCmode)"
728 "cmp{l}\t{%1, %0|%0, %1}"
729 [(set_attr "type" "icmp")
730 (set_attr "mode" "SI")])
731
732 (define_insn "*cmphi_ccno_1"
733 [(set (reg FLAGS_REG)
734 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
735 (match_operand:HI 1 "const0_operand" "n,n")))]
736 "ix86_match_ccmode (insn, CCNOmode)"
737 "@
738 test{w}\t%0, %0
739 cmp{w}\t{%1, %0|%0, %1}"
740 [(set_attr "type" "test,icmp")
741 (set_attr "length_immediate" "0,1")
742 (set_attr "mode" "HI")])
743
744 (define_insn "*cmphi_minus_1"
745 [(set (reg FLAGS_REG)
746 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
747 (match_operand:HI 1 "general_operand" "ri,mr"))
748 (const_int 0)))]
749 "ix86_match_ccmode (insn, CCGOCmode)"
750 "cmp{w}\t{%1, %0|%0, %1}"
751 [(set_attr "type" "icmp")
752 (set_attr "mode" "HI")])
753
754 (define_insn "*cmphi_1"
755 [(set (reg FLAGS_REG)
756 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
757 (match_operand:HI 1 "general_operand" "ri,mr")))]
758 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
759 && ix86_match_ccmode (insn, CCmode)"
760 "cmp{w}\t{%1, %0|%0, %1}"
761 [(set_attr "type" "icmp")
762 (set_attr "mode" "HI")])
763
764 (define_insn "*cmpqi_ccno_1"
765 [(set (reg FLAGS_REG)
766 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
767 (match_operand:QI 1 "const0_operand" "n,n")))]
768 "ix86_match_ccmode (insn, CCNOmode)"
769 "@
770 test{b}\t%0, %0
771 cmp{b}\t{$0, %0|%0, 0}"
772 [(set_attr "type" "test,icmp")
773 (set_attr "length_immediate" "0,1")
774 (set_attr "mode" "QI")])
775
776 (define_insn "*cmpqi_1"
777 [(set (reg FLAGS_REG)
778 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
779 (match_operand:QI 1 "general_operand" "qi,mq")))]
780 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
781 && ix86_match_ccmode (insn, CCmode)"
782 "cmp{b}\t{%1, %0|%0, %1}"
783 [(set_attr "type" "icmp")
784 (set_attr "mode" "QI")])
785
786 (define_insn "*cmpqi_minus_1"
787 [(set (reg FLAGS_REG)
788 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
789 (match_operand:QI 1 "general_operand" "qi,mq"))
790 (const_int 0)))]
791 "ix86_match_ccmode (insn, CCGOCmode)"
792 "cmp{b}\t{%1, %0|%0, %1}"
793 [(set_attr "type" "icmp")
794 (set_attr "mode" "QI")])
795
796 (define_insn "*cmpqi_ext_1"
797 [(set (reg FLAGS_REG)
798 (compare
799 (match_operand:QI 0 "general_operand" "Qm")
800 (subreg:QI
801 (zero_extract:SI
802 (match_operand 1 "ext_register_operand" "Q")
803 (const_int 8)
804 (const_int 8)) 0)))]
805 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
806 "cmp{b}\t{%h1, %0|%0, %h1}"
807 [(set_attr "type" "icmp")
808 (set_attr "mode" "QI")])
809
810 (define_insn "*cmpqi_ext_1_rex64"
811 [(set (reg FLAGS_REG)
812 (compare
813 (match_operand:QI 0 "register_operand" "Q")
814 (subreg:QI
815 (zero_extract:SI
816 (match_operand 1 "ext_register_operand" "Q")
817 (const_int 8)
818 (const_int 8)) 0)))]
819 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
820 "cmp{b}\t{%h1, %0|%0, %h1}"
821 [(set_attr "type" "icmp")
822 (set_attr "mode" "QI")])
823
824 (define_insn "*cmpqi_ext_2"
825 [(set (reg FLAGS_REG)
826 (compare
827 (subreg:QI
828 (zero_extract:SI
829 (match_operand 0 "ext_register_operand" "Q")
830 (const_int 8)
831 (const_int 8)) 0)
832 (match_operand:QI 1 "const0_operand" "n")))]
833 "ix86_match_ccmode (insn, CCNOmode)"
834 "test{b}\t%h0, %h0"
835 [(set_attr "type" "test")
836 (set_attr "length_immediate" "0")
837 (set_attr "mode" "QI")])
838
839 (define_expand "cmpqi_ext_3"
840 [(set (reg:CC FLAGS_REG)
841 (compare:CC
842 (subreg:QI
843 (zero_extract:SI
844 (match_operand 0 "ext_register_operand" "")
845 (const_int 8)
846 (const_int 8)) 0)
847 (match_operand:QI 1 "general_operand" "")))]
848 ""
849 "")
850
851 (define_insn "cmpqi_ext_3_insn"
852 [(set (reg FLAGS_REG)
853 (compare
854 (subreg:QI
855 (zero_extract:SI
856 (match_operand 0 "ext_register_operand" "Q")
857 (const_int 8)
858 (const_int 8)) 0)
859 (match_operand:QI 1 "general_operand" "Qmn")))]
860 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
861 "cmp{b}\t{%1, %h0|%h0, %1}"
862 [(set_attr "type" "icmp")
863 (set_attr "mode" "QI")])
864
865 (define_insn "cmpqi_ext_3_insn_rex64"
866 [(set (reg FLAGS_REG)
867 (compare
868 (subreg:QI
869 (zero_extract:SI
870 (match_operand 0 "ext_register_operand" "Q")
871 (const_int 8)
872 (const_int 8)) 0)
873 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
874 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
875 "cmp{b}\t{%1, %h0|%h0, %1}"
876 [(set_attr "type" "icmp")
877 (set_attr "mode" "QI")])
878
879 (define_insn "*cmpqi_ext_4"
880 [(set (reg FLAGS_REG)
881 (compare
882 (subreg:QI
883 (zero_extract:SI
884 (match_operand 0 "ext_register_operand" "Q")
885 (const_int 8)
886 (const_int 8)) 0)
887 (subreg:QI
888 (zero_extract:SI
889 (match_operand 1 "ext_register_operand" "Q")
890 (const_int 8)
891 (const_int 8)) 0)))]
892 "ix86_match_ccmode (insn, CCmode)"
893 "cmp{b}\t{%h1, %h0|%h0, %h1}"
894 [(set_attr "type" "icmp")
895 (set_attr "mode" "QI")])
896
897 ;; These implement float point compares.
898 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
899 ;; which would allow mix and match FP modes on the compares. Which is what
900 ;; the old patterns did, but with many more of them.
901
902 (define_expand "cmpxf"
903 [(set (reg:CC FLAGS_REG)
904 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
905 (match_operand:XF 1 "nonmemory_operand" "")))]
906 "TARGET_80387"
907 {
908 ix86_compare_op0 = operands[0];
909 ix86_compare_op1 = operands[1];
910 DONE;
911 })
912
913 (define_expand "cmp<mode>"
914 [(set (reg:CC FLAGS_REG)
915 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
916 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
917 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
918 {
919 ix86_compare_op0 = operands[0];
920 ix86_compare_op1 = operands[1];
921 DONE;
922 })
923
924 ;; FP compares, step 1:
925 ;; Set the FP condition codes.
926 ;;
927 ;; CCFPmode compare with exceptions
928 ;; CCFPUmode compare with no exceptions
929
930 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
931 ;; used to manage the reg stack popping would not be preserved.
932
933 (define_insn "*cmpfp_0"
934 [(set (match_operand:HI 0 "register_operand" "=a")
935 (unspec:HI
936 [(compare:CCFP
937 (match_operand 1 "register_operand" "f")
938 (match_operand 2 "const0_operand" "X"))]
939 UNSPEC_FNSTSW))]
940 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
941 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
942 "* return output_fp_compare (insn, operands, 0, 0);"
943 [(set_attr "type" "multi")
944 (set_attr "unit" "i387")
945 (set (attr "mode")
946 (cond [(match_operand:SF 1 "" "")
947 (const_string "SF")
948 (match_operand:DF 1 "" "")
949 (const_string "DF")
950 ]
951 (const_string "XF")))])
952
953 (define_insn_and_split "*cmpfp_0_cc"
954 [(set (reg:CCFP FLAGS_REG)
955 (compare:CCFP
956 (match_operand 1 "register_operand" "f")
957 (match_operand 2 "const0_operand" "X")))
958 (clobber (match_operand:HI 0 "register_operand" "=a"))]
959 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
960 && TARGET_SAHF && !TARGET_CMOVE
961 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
962 "#"
963 "&& reload_completed"
964 [(set (match_dup 0)
965 (unspec:HI
966 [(compare:CCFP (match_dup 1)(match_dup 2))]
967 UNSPEC_FNSTSW))
968 (set (reg:CC FLAGS_REG)
969 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
970 ""
971 [(set_attr "type" "multi")
972 (set_attr "unit" "i387")
973 (set (attr "mode")
974 (cond [(match_operand:SF 1 "" "")
975 (const_string "SF")
976 (match_operand:DF 1 "" "")
977 (const_string "DF")
978 ]
979 (const_string "XF")))])
980
981 (define_insn "*cmpfp_xf"
982 [(set (match_operand:HI 0 "register_operand" "=a")
983 (unspec:HI
984 [(compare:CCFP
985 (match_operand:XF 1 "register_operand" "f")
986 (match_operand:XF 2 "register_operand" "f"))]
987 UNSPEC_FNSTSW))]
988 "TARGET_80387"
989 "* return output_fp_compare (insn, operands, 0, 0);"
990 [(set_attr "type" "multi")
991 (set_attr "unit" "i387")
992 (set_attr "mode" "XF")])
993
994 (define_insn_and_split "*cmpfp_xf_cc"
995 [(set (reg:CCFP FLAGS_REG)
996 (compare:CCFP
997 (match_operand:XF 1 "register_operand" "f")
998 (match_operand:XF 2 "register_operand" "f")))
999 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1000 "TARGET_80387
1001 && TARGET_SAHF && !TARGET_CMOVE"
1002 "#"
1003 "&& reload_completed"
1004 [(set (match_dup 0)
1005 (unspec:HI
1006 [(compare:CCFP (match_dup 1)(match_dup 2))]
1007 UNSPEC_FNSTSW))
1008 (set (reg:CC FLAGS_REG)
1009 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1010 ""
1011 [(set_attr "type" "multi")
1012 (set_attr "unit" "i387")
1013 (set_attr "mode" "XF")])
1014
1015 (define_insn "*cmpfp_<mode>"
1016 [(set (match_operand:HI 0 "register_operand" "=a")
1017 (unspec:HI
1018 [(compare:CCFP
1019 (match_operand:MODEF 1 "register_operand" "f")
1020 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1021 UNSPEC_FNSTSW))]
1022 "TARGET_80387"
1023 "* return output_fp_compare (insn, operands, 0, 0);"
1024 [(set_attr "type" "multi")
1025 (set_attr "unit" "i387")
1026 (set_attr "mode" "<MODE>")])
1027
1028 (define_insn_and_split "*cmpfp_<mode>_cc"
1029 [(set (reg:CCFP FLAGS_REG)
1030 (compare:CCFP
1031 (match_operand:MODEF 1 "register_operand" "f")
1032 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1033 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1034 "TARGET_80387
1035 && TARGET_SAHF && !TARGET_CMOVE"
1036 "#"
1037 "&& reload_completed"
1038 [(set (match_dup 0)
1039 (unspec:HI
1040 [(compare:CCFP (match_dup 1)(match_dup 2))]
1041 UNSPEC_FNSTSW))
1042 (set (reg:CC FLAGS_REG)
1043 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1044 ""
1045 [(set_attr "type" "multi")
1046 (set_attr "unit" "i387")
1047 (set_attr "mode" "<MODE>")])
1048
1049 (define_insn "*cmpfp_u"
1050 [(set (match_operand:HI 0 "register_operand" "=a")
1051 (unspec:HI
1052 [(compare:CCFPU
1053 (match_operand 1 "register_operand" "f")
1054 (match_operand 2 "register_operand" "f"))]
1055 UNSPEC_FNSTSW))]
1056 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1057 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1058 "* return output_fp_compare (insn, operands, 0, 1);"
1059 [(set_attr "type" "multi")
1060 (set_attr "unit" "i387")
1061 (set (attr "mode")
1062 (cond [(match_operand:SF 1 "" "")
1063 (const_string "SF")
1064 (match_operand:DF 1 "" "")
1065 (const_string "DF")
1066 ]
1067 (const_string "XF")))])
1068
1069 (define_insn_and_split "*cmpfp_u_cc"
1070 [(set (reg:CCFPU FLAGS_REG)
1071 (compare:CCFPU
1072 (match_operand 1 "register_operand" "f")
1073 (match_operand 2 "register_operand" "f")))
1074 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1075 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1076 && TARGET_SAHF && !TARGET_CMOVE
1077 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1078 "#"
1079 "&& reload_completed"
1080 [(set (match_dup 0)
1081 (unspec:HI
1082 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1083 UNSPEC_FNSTSW))
1084 (set (reg:CC FLAGS_REG)
1085 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1086 ""
1087 [(set_attr "type" "multi")
1088 (set_attr "unit" "i387")
1089 (set (attr "mode")
1090 (cond [(match_operand:SF 1 "" "")
1091 (const_string "SF")
1092 (match_operand:DF 1 "" "")
1093 (const_string "DF")
1094 ]
1095 (const_string "XF")))])
1096
1097 (define_insn "*cmpfp_<mode>"
1098 [(set (match_operand:HI 0 "register_operand" "=a")
1099 (unspec:HI
1100 [(compare:CCFP
1101 (match_operand 1 "register_operand" "f")
1102 (match_operator 3 "float_operator"
1103 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1104 UNSPEC_FNSTSW))]
1105 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1106 && TARGET_USE_<MODE>MODE_FIOP
1107 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1108 "* return output_fp_compare (insn, operands, 0, 0);"
1109 [(set_attr "type" "multi")
1110 (set_attr "unit" "i387")
1111 (set_attr "fp_int_src" "true")
1112 (set_attr "mode" "<MODE>")])
1113
1114 (define_insn_and_split "*cmpfp_<mode>_cc"
1115 [(set (reg:CCFP FLAGS_REG)
1116 (compare:CCFP
1117 (match_operand 1 "register_operand" "f")
1118 (match_operator 3 "float_operator"
1119 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1120 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1121 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1122 && TARGET_SAHF && !TARGET_CMOVE
1123 && TARGET_USE_<MODE>MODE_FIOP
1124 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1125 "#"
1126 "&& reload_completed"
1127 [(set (match_dup 0)
1128 (unspec:HI
1129 [(compare:CCFP
1130 (match_dup 1)
1131 (match_op_dup 3 [(match_dup 2)]))]
1132 UNSPEC_FNSTSW))
1133 (set (reg:CC FLAGS_REG)
1134 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1135 ""
1136 [(set_attr "type" "multi")
1137 (set_attr "unit" "i387")
1138 (set_attr "fp_int_src" "true")
1139 (set_attr "mode" "<MODE>")])
1140
1141 ;; FP compares, step 2
1142 ;; Move the fpsw to ax.
1143
1144 (define_insn "x86_fnstsw_1"
1145 [(set (match_operand:HI 0 "register_operand" "=a")
1146 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1147 "TARGET_80387"
1148 "fnstsw\t%0"
1149 [(set_attr "length" "2")
1150 (set_attr "mode" "SI")
1151 (set_attr "unit" "i387")])
1152
1153 ;; FP compares, step 3
1154 ;; Get ax into flags, general case.
1155
1156 (define_insn "x86_sahf_1"
1157 [(set (reg:CC FLAGS_REG)
1158 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1159 UNSPEC_SAHF))]
1160 "TARGET_SAHF"
1161 {
1162 #ifdef HAVE_AS_IX86_SAHF
1163 return "sahf";
1164 #else
1165 return ".byte\t0x9e";
1166 #endif
1167 }
1168 [(set_attr "length" "1")
1169 (set_attr "athlon_decode" "vector")
1170 (set_attr "amdfam10_decode" "direct")
1171 (set_attr "mode" "SI")])
1172
1173 ;; Pentium Pro can do steps 1 through 3 in one go.
1174 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1175 (define_insn "*cmpfp_i_mixed"
1176 [(set (reg:CCFP FLAGS_REG)
1177 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1178 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1179 "TARGET_MIX_SSE_I387
1180 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1181 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1182 "* return output_fp_compare (insn, operands, 1, 0);"
1183 [(set_attr "type" "fcmp,ssecomi")
1184 (set (attr "mode")
1185 (if_then_else (match_operand:SF 1 "" "")
1186 (const_string "SF")
1187 (const_string "DF")))
1188 (set_attr "athlon_decode" "vector")
1189 (set_attr "amdfam10_decode" "direct")])
1190
1191 (define_insn "*cmpfp_i_sse"
1192 [(set (reg:CCFP FLAGS_REG)
1193 (compare:CCFP (match_operand 0 "register_operand" "x")
1194 (match_operand 1 "nonimmediate_operand" "xm")))]
1195 "TARGET_SSE_MATH
1196 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1197 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1198 "* return output_fp_compare (insn, operands, 1, 0);"
1199 [(set_attr "type" "ssecomi")
1200 (set (attr "mode")
1201 (if_then_else (match_operand:SF 1 "" "")
1202 (const_string "SF")
1203 (const_string "DF")))
1204 (set_attr "athlon_decode" "vector")
1205 (set_attr "amdfam10_decode" "direct")])
1206
1207 (define_insn "*cmpfp_i_i387"
1208 [(set (reg:CCFP FLAGS_REG)
1209 (compare:CCFP (match_operand 0 "register_operand" "f")
1210 (match_operand 1 "register_operand" "f")))]
1211 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1212 && TARGET_CMOVE
1213 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1214 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1215 "* return output_fp_compare (insn, operands, 1, 0);"
1216 [(set_attr "type" "fcmp")
1217 (set (attr "mode")
1218 (cond [(match_operand:SF 1 "" "")
1219 (const_string "SF")
1220 (match_operand:DF 1 "" "")
1221 (const_string "DF")
1222 ]
1223 (const_string "XF")))
1224 (set_attr "athlon_decode" "vector")
1225 (set_attr "amdfam10_decode" "direct")])
1226
1227 (define_insn "*cmpfp_iu_mixed"
1228 [(set (reg:CCFPU FLAGS_REG)
1229 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1230 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1231 "TARGET_MIX_SSE_I387
1232 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1233 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1234 "* return output_fp_compare (insn, operands, 1, 1);"
1235 [(set_attr "type" "fcmp,ssecomi")
1236 (set (attr "mode")
1237 (if_then_else (match_operand:SF 1 "" "")
1238 (const_string "SF")
1239 (const_string "DF")))
1240 (set_attr "athlon_decode" "vector")
1241 (set_attr "amdfam10_decode" "direct")])
1242
1243 (define_insn "*cmpfp_iu_sse"
1244 [(set (reg:CCFPU FLAGS_REG)
1245 (compare:CCFPU (match_operand 0 "register_operand" "x")
1246 (match_operand 1 "nonimmediate_operand" "xm")))]
1247 "TARGET_SSE_MATH
1248 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1249 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1250 "* return output_fp_compare (insn, operands, 1, 1);"
1251 [(set_attr "type" "ssecomi")
1252 (set (attr "mode")
1253 (if_then_else (match_operand:SF 1 "" "")
1254 (const_string "SF")
1255 (const_string "DF")))
1256 (set_attr "athlon_decode" "vector")
1257 (set_attr "amdfam10_decode" "direct")])
1258
1259 (define_insn "*cmpfp_iu_387"
1260 [(set (reg:CCFPU FLAGS_REG)
1261 (compare:CCFPU (match_operand 0 "register_operand" "f")
1262 (match_operand 1 "register_operand" "f")))]
1263 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1264 && TARGET_CMOVE
1265 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1266 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1267 "* return output_fp_compare (insn, operands, 1, 1);"
1268 [(set_attr "type" "fcmp")
1269 (set (attr "mode")
1270 (cond [(match_operand:SF 1 "" "")
1271 (const_string "SF")
1272 (match_operand:DF 1 "" "")
1273 (const_string "DF")
1274 ]
1275 (const_string "XF")))
1276 (set_attr "athlon_decode" "vector")
1277 (set_attr "amdfam10_decode" "direct")])
1278 \f
1279 ;; Move instructions.
1280
1281 ;; General case of fullword move.
1282
1283 (define_expand "movsi"
1284 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1285 (match_operand:SI 1 "general_operand" ""))]
1286 ""
1287 "ix86_expand_move (SImode, operands); DONE;")
1288
1289 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1290 ;; general_operand.
1291 ;;
1292 ;; %%% We don't use a post-inc memory reference because x86 is not a
1293 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1294 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1295 ;; targets without our curiosities, and it is just as easy to represent
1296 ;; this differently.
1297
1298 (define_insn "*pushsi2"
1299 [(set (match_operand:SI 0 "push_operand" "=<")
1300 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1301 "!TARGET_64BIT"
1302 "push{l}\t%1"
1303 [(set_attr "type" "push")
1304 (set_attr "mode" "SI")])
1305
1306 ;; For 64BIT abi we always round up to 8 bytes.
1307 (define_insn "*pushsi2_rex64"
1308 [(set (match_operand:SI 0 "push_operand" "=X")
1309 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1310 "TARGET_64BIT"
1311 "push{q}\t%q1"
1312 [(set_attr "type" "push")
1313 (set_attr "mode" "SI")])
1314
1315 (define_insn "*pushsi2_prologue"
1316 [(set (match_operand:SI 0 "push_operand" "=<")
1317 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1318 (clobber (mem:BLK (scratch)))]
1319 "!TARGET_64BIT"
1320 "push{l}\t%1"
1321 [(set_attr "type" "push")
1322 (set_attr "mode" "SI")])
1323
1324 (define_insn "*popsi1_epilogue"
1325 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1326 (mem:SI (reg:SI SP_REG)))
1327 (set (reg:SI SP_REG)
1328 (plus:SI (reg:SI SP_REG) (const_int 4)))
1329 (clobber (mem:BLK (scratch)))]
1330 "!TARGET_64BIT"
1331 "pop{l}\t%0"
1332 [(set_attr "type" "pop")
1333 (set_attr "mode" "SI")])
1334
1335 (define_insn "popsi1"
1336 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1337 (mem:SI (reg:SI SP_REG)))
1338 (set (reg:SI SP_REG)
1339 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1340 "!TARGET_64BIT"
1341 "pop{l}\t%0"
1342 [(set_attr "type" "pop")
1343 (set_attr "mode" "SI")])
1344
1345 (define_insn "*movsi_xor"
1346 [(set (match_operand:SI 0 "register_operand" "=r")
1347 (match_operand:SI 1 "const0_operand" "i"))
1348 (clobber (reg:CC FLAGS_REG))]
1349 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1350 "xor{l}\t%0, %0"
1351 [(set_attr "type" "alu1")
1352 (set_attr "mode" "SI")
1353 (set_attr "length_immediate" "0")])
1354
1355 (define_insn "*movsi_or"
1356 [(set (match_operand:SI 0 "register_operand" "=r")
1357 (match_operand:SI 1 "immediate_operand" "i"))
1358 (clobber (reg:CC FLAGS_REG))]
1359 "reload_completed
1360 && operands[1] == constm1_rtx
1361 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1362 {
1363 operands[1] = constm1_rtx;
1364 return "or{l}\t{%1, %0|%0, %1}";
1365 }
1366 [(set_attr "type" "alu1")
1367 (set_attr "mode" "SI")
1368 (set_attr "length_immediate" "1")])
1369
1370 (define_insn "*movsi_1"
1371 [(set (match_operand:SI 0 "nonimmediate_operand"
1372 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1373 (match_operand:SI 1 "general_operand"
1374 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1375 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1376 {
1377 switch (get_attr_type (insn))
1378 {
1379 case TYPE_SSELOG1:
1380 if (get_attr_mode (insn) == MODE_TI)
1381 return "pxor\t%0, %0";
1382 return "xorps\t%0, %0";
1383
1384 case TYPE_SSEMOV:
1385 switch (get_attr_mode (insn))
1386 {
1387 case MODE_TI:
1388 return "movdqa\t{%1, %0|%0, %1}";
1389 case MODE_V4SF:
1390 return "movaps\t{%1, %0|%0, %1}";
1391 case MODE_SI:
1392 return "movd\t{%1, %0|%0, %1}";
1393 case MODE_SF:
1394 return "movss\t{%1, %0|%0, %1}";
1395 default:
1396 gcc_unreachable ();
1397 }
1398
1399 case TYPE_MMXADD:
1400 return "pxor\t%0, %0";
1401
1402 case TYPE_MMXMOV:
1403 if (get_attr_mode (insn) == MODE_DI)
1404 return "movq\t{%1, %0|%0, %1}";
1405 return "movd\t{%1, %0|%0, %1}";
1406
1407 case TYPE_LEA:
1408 return "lea{l}\t{%1, %0|%0, %1}";
1409
1410 default:
1411 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1412 return "mov{l}\t{%1, %0|%0, %1}";
1413 }
1414 }
1415 [(set (attr "type")
1416 (cond [(eq_attr "alternative" "2")
1417 (const_string "mmxadd")
1418 (eq_attr "alternative" "3,4,5")
1419 (const_string "mmxmov")
1420 (eq_attr "alternative" "6")
1421 (const_string "sselog1")
1422 (eq_attr "alternative" "7,8,9,10,11")
1423 (const_string "ssemov")
1424 (match_operand:DI 1 "pic_32bit_operand" "")
1425 (const_string "lea")
1426 ]
1427 (const_string "imov")))
1428 (set (attr "mode")
1429 (cond [(eq_attr "alternative" "2,3")
1430 (const_string "DI")
1431 (eq_attr "alternative" "6,7")
1432 (if_then_else
1433 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1434 (const_string "V4SF")
1435 (const_string "TI"))
1436 (and (eq_attr "alternative" "8,9,10,11")
1437 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1438 (const_string "SF")
1439 ]
1440 (const_string "SI")))])
1441
1442 ;; Stores and loads of ax to arbitrary constant address.
1443 ;; We fake an second form of instruction to force reload to load address
1444 ;; into register when rax is not available
1445 (define_insn "*movabssi_1_rex64"
1446 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1447 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1448 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1449 "@
1450 movabs{l}\t{%1, %P0|%P0, %1}
1451 mov{l}\t{%1, %a0|%a0, %1}"
1452 [(set_attr "type" "imov")
1453 (set_attr "modrm" "0,*")
1454 (set_attr "length_address" "8,0")
1455 (set_attr "length_immediate" "0,*")
1456 (set_attr "memory" "store")
1457 (set_attr "mode" "SI")])
1458
1459 (define_insn "*movabssi_2_rex64"
1460 [(set (match_operand:SI 0 "register_operand" "=a,r")
1461 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1462 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1463 "@
1464 movabs{l}\t{%P1, %0|%0, %P1}
1465 mov{l}\t{%a1, %0|%0, %a1}"
1466 [(set_attr "type" "imov")
1467 (set_attr "modrm" "0,*")
1468 (set_attr "length_address" "8,0")
1469 (set_attr "length_immediate" "0")
1470 (set_attr "memory" "load")
1471 (set_attr "mode" "SI")])
1472
1473 (define_insn "*swapsi"
1474 [(set (match_operand:SI 0 "register_operand" "+r")
1475 (match_operand:SI 1 "register_operand" "+r"))
1476 (set (match_dup 1)
1477 (match_dup 0))]
1478 ""
1479 "xchg{l}\t%1, %0"
1480 [(set_attr "type" "imov")
1481 (set_attr "mode" "SI")
1482 (set_attr "pent_pair" "np")
1483 (set_attr "athlon_decode" "vector")
1484 (set_attr "amdfam10_decode" "double")])
1485
1486 (define_expand "movhi"
1487 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1488 (match_operand:HI 1 "general_operand" ""))]
1489 ""
1490 "ix86_expand_move (HImode, operands); DONE;")
1491
1492 (define_insn "*pushhi2"
1493 [(set (match_operand:HI 0 "push_operand" "=X")
1494 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1495 "!TARGET_64BIT"
1496 "push{l}\t%k1"
1497 [(set_attr "type" "push")
1498 (set_attr "mode" "SI")])
1499
1500 ;; For 64BIT abi we always round up to 8 bytes.
1501 (define_insn "*pushhi2_rex64"
1502 [(set (match_operand:HI 0 "push_operand" "=X")
1503 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1504 "TARGET_64BIT"
1505 "push{q}\t%q1"
1506 [(set_attr "type" "push")
1507 (set_attr "mode" "DI")])
1508
1509 (define_insn "*movhi_1"
1510 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1511 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1512 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1513 {
1514 switch (get_attr_type (insn))
1515 {
1516 case TYPE_IMOVX:
1517 /* movzwl is faster than movw on p2 due to partial word stalls,
1518 though not as fast as an aligned movl. */
1519 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1520 default:
1521 if (get_attr_mode (insn) == MODE_SI)
1522 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1523 else
1524 return "mov{w}\t{%1, %0|%0, %1}";
1525 }
1526 }
1527 [(set (attr "type")
1528 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1529 (const_string "imov")
1530 (and (eq_attr "alternative" "0")
1531 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1532 (const_int 0))
1533 (eq (symbol_ref "TARGET_HIMODE_MATH")
1534 (const_int 0))))
1535 (const_string "imov")
1536 (and (eq_attr "alternative" "1,2")
1537 (match_operand:HI 1 "aligned_operand" ""))
1538 (const_string "imov")
1539 (and (ne (symbol_ref "TARGET_MOVX")
1540 (const_int 0))
1541 (eq_attr "alternative" "0,2"))
1542 (const_string "imovx")
1543 ]
1544 (const_string "imov")))
1545 (set (attr "mode")
1546 (cond [(eq_attr "type" "imovx")
1547 (const_string "SI")
1548 (and (eq_attr "alternative" "1,2")
1549 (match_operand:HI 1 "aligned_operand" ""))
1550 (const_string "SI")
1551 (and (eq_attr "alternative" "0")
1552 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1553 (const_int 0))
1554 (eq (symbol_ref "TARGET_HIMODE_MATH")
1555 (const_int 0))))
1556 (const_string "SI")
1557 ]
1558 (const_string "HI")))])
1559
1560 ;; Stores and loads of ax to arbitrary constant address.
1561 ;; We fake an second form of instruction to force reload to load address
1562 ;; into register when rax is not available
1563 (define_insn "*movabshi_1_rex64"
1564 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1565 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1566 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1567 "@
1568 movabs{w}\t{%1, %P0|%P0, %1}
1569 mov{w}\t{%1, %a0|%a0, %1}"
1570 [(set_attr "type" "imov")
1571 (set_attr "modrm" "0,*")
1572 (set_attr "length_address" "8,0")
1573 (set_attr "length_immediate" "0,*")
1574 (set_attr "memory" "store")
1575 (set_attr "mode" "HI")])
1576
1577 (define_insn "*movabshi_2_rex64"
1578 [(set (match_operand:HI 0 "register_operand" "=a,r")
1579 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1580 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1581 "@
1582 movabs{w}\t{%P1, %0|%0, %P1}
1583 mov{w}\t{%a1, %0|%0, %a1}"
1584 [(set_attr "type" "imov")
1585 (set_attr "modrm" "0,*")
1586 (set_attr "length_address" "8,0")
1587 (set_attr "length_immediate" "0")
1588 (set_attr "memory" "load")
1589 (set_attr "mode" "HI")])
1590
1591 (define_insn "*swaphi_1"
1592 [(set (match_operand:HI 0 "register_operand" "+r")
1593 (match_operand:HI 1 "register_operand" "+r"))
1594 (set (match_dup 1)
1595 (match_dup 0))]
1596 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1597 "xchg{l}\t%k1, %k0"
1598 [(set_attr "type" "imov")
1599 (set_attr "mode" "SI")
1600 (set_attr "pent_pair" "np")
1601 (set_attr "athlon_decode" "vector")
1602 (set_attr "amdfam10_decode" "double")])
1603
1604 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1605 (define_insn "*swaphi_2"
1606 [(set (match_operand:HI 0 "register_operand" "+r")
1607 (match_operand:HI 1 "register_operand" "+r"))
1608 (set (match_dup 1)
1609 (match_dup 0))]
1610 "TARGET_PARTIAL_REG_STALL"
1611 "xchg{w}\t%1, %0"
1612 [(set_attr "type" "imov")
1613 (set_attr "mode" "HI")
1614 (set_attr "pent_pair" "np")
1615 (set_attr "athlon_decode" "vector")])
1616
1617 (define_expand "movstricthi"
1618 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1619 (match_operand:HI 1 "general_operand" ""))]
1620 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1621 {
1622 /* Don't generate memory->memory moves, go through a register */
1623 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1624 operands[1] = force_reg (HImode, operands[1]);
1625 })
1626
1627 (define_insn "*movstricthi_1"
1628 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1629 (match_operand:HI 1 "general_operand" "rn,m"))]
1630 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1631 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1632 "mov{w}\t{%1, %0|%0, %1}"
1633 [(set_attr "type" "imov")
1634 (set_attr "mode" "HI")])
1635
1636 (define_insn "*movstricthi_xor"
1637 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1638 (match_operand:HI 1 "const0_operand" "i"))
1639 (clobber (reg:CC FLAGS_REG))]
1640 "reload_completed
1641 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1642 "xor{w}\t%0, %0"
1643 [(set_attr "type" "alu1")
1644 (set_attr "mode" "HI")
1645 (set_attr "length_immediate" "0")])
1646
1647 (define_expand "movqi"
1648 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1649 (match_operand:QI 1 "general_operand" ""))]
1650 ""
1651 "ix86_expand_move (QImode, operands); DONE;")
1652
1653 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1654 ;; "push a byte". But actually we use pushl, which has the effect
1655 ;; of rounding the amount pushed up to a word.
1656
1657 (define_insn "*pushqi2"
1658 [(set (match_operand:QI 0 "push_operand" "=X")
1659 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1660 "!TARGET_64BIT"
1661 "push{l}\t%k1"
1662 [(set_attr "type" "push")
1663 (set_attr "mode" "SI")])
1664
1665 ;; For 64BIT abi we always round up to 8 bytes.
1666 (define_insn "*pushqi2_rex64"
1667 [(set (match_operand:QI 0 "push_operand" "=X")
1668 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1669 "TARGET_64BIT"
1670 "push{q}\t%q1"
1671 [(set_attr "type" "push")
1672 (set_attr "mode" "DI")])
1673
1674 ;; Situation is quite tricky about when to choose full sized (SImode) move
1675 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1676 ;; partial register dependency machines (such as AMD Athlon), where QImode
1677 ;; moves issue extra dependency and for partial register stalls machines
1678 ;; that don't use QImode patterns (and QImode move cause stall on the next
1679 ;; instruction).
1680 ;;
1681 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1682 ;; register stall machines with, where we use QImode instructions, since
1683 ;; partial register stall can be caused there. Then we use movzx.
1684 (define_insn "*movqi_1"
1685 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1686 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1687 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1688 {
1689 switch (get_attr_type (insn))
1690 {
1691 case TYPE_IMOVX:
1692 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1693 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1694 default:
1695 if (get_attr_mode (insn) == MODE_SI)
1696 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1697 else
1698 return "mov{b}\t{%1, %0|%0, %1}";
1699 }
1700 }
1701 [(set (attr "type")
1702 (cond [(and (eq_attr "alternative" "5")
1703 (not (match_operand:QI 1 "aligned_operand" "")))
1704 (const_string "imovx")
1705 (ne (symbol_ref "optimize_size") (const_int 0))
1706 (const_string "imov")
1707 (and (eq_attr "alternative" "3")
1708 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1709 (const_int 0))
1710 (eq (symbol_ref "TARGET_QIMODE_MATH")
1711 (const_int 0))))
1712 (const_string "imov")
1713 (eq_attr "alternative" "3,5")
1714 (const_string "imovx")
1715 (and (ne (symbol_ref "TARGET_MOVX")
1716 (const_int 0))
1717 (eq_attr "alternative" "2"))
1718 (const_string "imovx")
1719 ]
1720 (const_string "imov")))
1721 (set (attr "mode")
1722 (cond [(eq_attr "alternative" "3,4,5")
1723 (const_string "SI")
1724 (eq_attr "alternative" "6")
1725 (const_string "QI")
1726 (eq_attr "type" "imovx")
1727 (const_string "SI")
1728 (and (eq_attr "type" "imov")
1729 (and (eq_attr "alternative" "0,1")
1730 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1731 (const_int 0))
1732 (and (eq (symbol_ref "optimize_size")
1733 (const_int 0))
1734 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1735 (const_int 0))))))
1736 (const_string "SI")
1737 ;; Avoid partial register stalls when not using QImode arithmetic
1738 (and (eq_attr "type" "imov")
1739 (and (eq_attr "alternative" "0,1")
1740 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1741 (const_int 0))
1742 (eq (symbol_ref "TARGET_QIMODE_MATH")
1743 (const_int 0)))))
1744 (const_string "SI")
1745 ]
1746 (const_string "QI")))])
1747
1748 (define_expand "reload_outqi"
1749 [(parallel [(match_operand:QI 0 "" "=m")
1750 (match_operand:QI 1 "register_operand" "r")
1751 (match_operand:QI 2 "register_operand" "=&q")])]
1752 ""
1753 {
1754 rtx op0, op1, op2;
1755 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1756
1757 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1758 if (! q_regs_operand (op1, QImode))
1759 {
1760 emit_insn (gen_movqi (op2, op1));
1761 op1 = op2;
1762 }
1763 emit_insn (gen_movqi (op0, op1));
1764 DONE;
1765 })
1766
1767 (define_insn "*swapqi_1"
1768 [(set (match_operand:QI 0 "register_operand" "+r")
1769 (match_operand:QI 1 "register_operand" "+r"))
1770 (set (match_dup 1)
1771 (match_dup 0))]
1772 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1773 "xchg{l}\t%k1, %k0"
1774 [(set_attr "type" "imov")
1775 (set_attr "mode" "SI")
1776 (set_attr "pent_pair" "np")
1777 (set_attr "athlon_decode" "vector")
1778 (set_attr "amdfam10_decode" "vector")])
1779
1780 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1781 (define_insn "*swapqi_2"
1782 [(set (match_operand:QI 0 "register_operand" "+q")
1783 (match_operand:QI 1 "register_operand" "+q"))
1784 (set (match_dup 1)
1785 (match_dup 0))]
1786 "TARGET_PARTIAL_REG_STALL"
1787 "xchg{b}\t%1, %0"
1788 [(set_attr "type" "imov")
1789 (set_attr "mode" "QI")
1790 (set_attr "pent_pair" "np")
1791 (set_attr "athlon_decode" "vector")])
1792
1793 (define_expand "movstrictqi"
1794 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1795 (match_operand:QI 1 "general_operand" ""))]
1796 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1797 {
1798 /* Don't generate memory->memory moves, go through a register. */
1799 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1800 operands[1] = force_reg (QImode, operands[1]);
1801 })
1802
1803 (define_insn "*movstrictqi_1"
1804 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1805 (match_operand:QI 1 "general_operand" "*qn,m"))]
1806 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1808 "mov{b}\t{%1, %0|%0, %1}"
1809 [(set_attr "type" "imov")
1810 (set_attr "mode" "QI")])
1811
1812 (define_insn "*movstrictqi_xor"
1813 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1814 (match_operand:QI 1 "const0_operand" "i"))
1815 (clobber (reg:CC FLAGS_REG))]
1816 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1817 "xor{b}\t%0, %0"
1818 [(set_attr "type" "alu1")
1819 (set_attr "mode" "QI")
1820 (set_attr "length_immediate" "0")])
1821
1822 (define_insn "*movsi_extv_1"
1823 [(set (match_operand:SI 0 "register_operand" "=R")
1824 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1825 (const_int 8)
1826 (const_int 8)))]
1827 ""
1828 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1829 [(set_attr "type" "imovx")
1830 (set_attr "mode" "SI")])
1831
1832 (define_insn "*movhi_extv_1"
1833 [(set (match_operand:HI 0 "register_operand" "=R")
1834 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1835 (const_int 8)
1836 (const_int 8)))]
1837 ""
1838 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1839 [(set_attr "type" "imovx")
1840 (set_attr "mode" "SI")])
1841
1842 (define_insn "*movqi_extv_1"
1843 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1844 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1845 (const_int 8)
1846 (const_int 8)))]
1847 "!TARGET_64BIT"
1848 {
1849 switch (get_attr_type (insn))
1850 {
1851 case TYPE_IMOVX:
1852 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1853 default:
1854 return "mov{b}\t{%h1, %0|%0, %h1}";
1855 }
1856 }
1857 [(set (attr "type")
1858 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1859 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1860 (ne (symbol_ref "TARGET_MOVX")
1861 (const_int 0))))
1862 (const_string "imovx")
1863 (const_string "imov")))
1864 (set (attr "mode")
1865 (if_then_else (eq_attr "type" "imovx")
1866 (const_string "SI")
1867 (const_string "QI")))])
1868
1869 (define_insn "*movqi_extv_1_rex64"
1870 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1871 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1872 (const_int 8)
1873 (const_int 8)))]
1874 "TARGET_64BIT"
1875 {
1876 switch (get_attr_type (insn))
1877 {
1878 case TYPE_IMOVX:
1879 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1880 default:
1881 return "mov{b}\t{%h1, %0|%0, %h1}";
1882 }
1883 }
1884 [(set (attr "type")
1885 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1886 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1887 (ne (symbol_ref "TARGET_MOVX")
1888 (const_int 0))))
1889 (const_string "imovx")
1890 (const_string "imov")))
1891 (set (attr "mode")
1892 (if_then_else (eq_attr "type" "imovx")
1893 (const_string "SI")
1894 (const_string "QI")))])
1895
1896 ;; Stores and loads of ax to arbitrary constant address.
1897 ;; We fake an second form of instruction to force reload to load address
1898 ;; into register when rax is not available
1899 (define_insn "*movabsqi_1_rex64"
1900 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1901 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1902 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1903 "@
1904 movabs{b}\t{%1, %P0|%P0, %1}
1905 mov{b}\t{%1, %a0|%a0, %1}"
1906 [(set_attr "type" "imov")
1907 (set_attr "modrm" "0,*")
1908 (set_attr "length_address" "8,0")
1909 (set_attr "length_immediate" "0,*")
1910 (set_attr "memory" "store")
1911 (set_attr "mode" "QI")])
1912
1913 (define_insn "*movabsqi_2_rex64"
1914 [(set (match_operand:QI 0 "register_operand" "=a,r")
1915 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1916 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1917 "@
1918 movabs{b}\t{%P1, %0|%0, %P1}
1919 mov{b}\t{%a1, %0|%0, %a1}"
1920 [(set_attr "type" "imov")
1921 (set_attr "modrm" "0,*")
1922 (set_attr "length_address" "8,0")
1923 (set_attr "length_immediate" "0")
1924 (set_attr "memory" "load")
1925 (set_attr "mode" "QI")])
1926
1927 (define_insn "*movdi_extzv_1"
1928 [(set (match_operand:DI 0 "register_operand" "=R")
1929 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1930 (const_int 8)
1931 (const_int 8)))]
1932 "TARGET_64BIT"
1933 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1934 [(set_attr "type" "imovx")
1935 (set_attr "mode" "DI")])
1936
1937 (define_insn "*movsi_extzv_1"
1938 [(set (match_operand:SI 0 "register_operand" "=R")
1939 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1940 (const_int 8)
1941 (const_int 8)))]
1942 ""
1943 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1944 [(set_attr "type" "imovx")
1945 (set_attr "mode" "SI")])
1946
1947 (define_insn "*movqi_extzv_2"
1948 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1949 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1950 (const_int 8)
1951 (const_int 8)) 0))]
1952 "!TARGET_64BIT"
1953 {
1954 switch (get_attr_type (insn))
1955 {
1956 case TYPE_IMOVX:
1957 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1958 default:
1959 return "mov{b}\t{%h1, %0|%0, %h1}";
1960 }
1961 }
1962 [(set (attr "type")
1963 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1964 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1965 (ne (symbol_ref "TARGET_MOVX")
1966 (const_int 0))))
1967 (const_string "imovx")
1968 (const_string "imov")))
1969 (set (attr "mode")
1970 (if_then_else (eq_attr "type" "imovx")
1971 (const_string "SI")
1972 (const_string "QI")))])
1973
1974 (define_insn "*movqi_extzv_2_rex64"
1975 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1976 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1977 (const_int 8)
1978 (const_int 8)) 0))]
1979 "TARGET_64BIT"
1980 {
1981 switch (get_attr_type (insn))
1982 {
1983 case TYPE_IMOVX:
1984 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1985 default:
1986 return "mov{b}\t{%h1, %0|%0, %h1}";
1987 }
1988 }
1989 [(set (attr "type")
1990 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1991 (ne (symbol_ref "TARGET_MOVX")
1992 (const_int 0)))
1993 (const_string "imovx")
1994 (const_string "imov")))
1995 (set (attr "mode")
1996 (if_then_else (eq_attr "type" "imovx")
1997 (const_string "SI")
1998 (const_string "QI")))])
1999
2000 (define_insn "movsi_insv_1"
2001 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2002 (const_int 8)
2003 (const_int 8))
2004 (match_operand:SI 1 "general_operand" "Qmn"))]
2005 "!TARGET_64BIT"
2006 "mov{b}\t{%b1, %h0|%h0, %b1}"
2007 [(set_attr "type" "imov")
2008 (set_attr "mode" "QI")])
2009
2010 (define_insn "*movsi_insv_1_rex64"
2011 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2012 (const_int 8)
2013 (const_int 8))
2014 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2015 "TARGET_64BIT"
2016 "mov{b}\t{%b1, %h0|%h0, %b1}"
2017 [(set_attr "type" "imov")
2018 (set_attr "mode" "QI")])
2019
2020 (define_insn "movdi_insv_1_rex64"
2021 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2022 (const_int 8)
2023 (const_int 8))
2024 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2025 "TARGET_64BIT"
2026 "mov{b}\t{%b1, %h0|%h0, %b1}"
2027 [(set_attr "type" "imov")
2028 (set_attr "mode" "QI")])
2029
2030 (define_insn "*movqi_insv_2"
2031 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2032 (const_int 8)
2033 (const_int 8))
2034 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2035 (const_int 8)))]
2036 ""
2037 "mov{b}\t{%h1, %h0|%h0, %h1}"
2038 [(set_attr "type" "imov")
2039 (set_attr "mode" "QI")])
2040
2041 (define_expand "movdi"
2042 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2043 (match_operand:DI 1 "general_operand" ""))]
2044 ""
2045 "ix86_expand_move (DImode, operands); DONE;")
2046
2047 (define_insn "*pushdi"
2048 [(set (match_operand:DI 0 "push_operand" "=<")
2049 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2050 "!TARGET_64BIT"
2051 "#")
2052
2053 (define_insn "*pushdi2_rex64"
2054 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2055 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2056 "TARGET_64BIT"
2057 "@
2058 push{q}\t%1
2059 #"
2060 [(set_attr "type" "push,multi")
2061 (set_attr "mode" "DI")])
2062
2063 ;; Convert impossible pushes of immediate to existing instructions.
2064 ;; First try to get scratch register and go through it. In case this
2065 ;; fails, push sign extended lower part first and then overwrite
2066 ;; upper part by 32bit move.
2067 (define_peephole2
2068 [(match_scratch:DI 2 "r")
2069 (set (match_operand:DI 0 "push_operand" "")
2070 (match_operand:DI 1 "immediate_operand" ""))]
2071 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2072 && !x86_64_immediate_operand (operands[1], DImode)"
2073 [(set (match_dup 2) (match_dup 1))
2074 (set (match_dup 0) (match_dup 2))]
2075 "")
2076
2077 ;; We need to define this as both peepholer and splitter for case
2078 ;; peephole2 pass is not run.
2079 ;; "&& 1" is needed to keep it from matching the previous pattern.
2080 (define_peephole2
2081 [(set (match_operand:DI 0 "push_operand" "")
2082 (match_operand:DI 1 "immediate_operand" ""))]
2083 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2085 [(set (match_dup 0) (match_dup 1))
2086 (set (match_dup 2) (match_dup 3))]
2087 "split_di (operands + 1, 1, operands + 2, operands + 3);
2088 operands[1] = gen_lowpart (DImode, operands[2]);
2089 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2090 GEN_INT (4)));
2091 ")
2092
2093 (define_split
2094 [(set (match_operand:DI 0 "push_operand" "")
2095 (match_operand:DI 1 "immediate_operand" ""))]
2096 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2097 ? epilogue_completed : reload_completed)
2098 && !symbolic_operand (operands[1], DImode)
2099 && !x86_64_immediate_operand (operands[1], DImode)"
2100 [(set (match_dup 0) (match_dup 1))
2101 (set (match_dup 2) (match_dup 3))]
2102 "split_di (operands + 1, 1, operands + 2, operands + 3);
2103 operands[1] = gen_lowpart (DImode, operands[2]);
2104 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2105 GEN_INT (4)));
2106 ")
2107
2108 (define_insn "*pushdi2_prologue_rex64"
2109 [(set (match_operand:DI 0 "push_operand" "=<")
2110 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2111 (clobber (mem:BLK (scratch)))]
2112 "TARGET_64BIT"
2113 "push{q}\t%1"
2114 [(set_attr "type" "push")
2115 (set_attr "mode" "DI")])
2116
2117 (define_insn "*popdi1_epilogue_rex64"
2118 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2119 (mem:DI (reg:DI SP_REG)))
2120 (set (reg:DI SP_REG)
2121 (plus:DI (reg:DI SP_REG) (const_int 8)))
2122 (clobber (mem:BLK (scratch)))]
2123 "TARGET_64BIT"
2124 "pop{q}\t%0"
2125 [(set_attr "type" "pop")
2126 (set_attr "mode" "DI")])
2127
2128 (define_insn "popdi1"
2129 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2130 (mem:DI (reg:DI SP_REG)))
2131 (set (reg:DI SP_REG)
2132 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2133 "TARGET_64BIT"
2134 "pop{q}\t%0"
2135 [(set_attr "type" "pop")
2136 (set_attr "mode" "DI")])
2137
2138 (define_insn "*movdi_xor_rex64"
2139 [(set (match_operand:DI 0 "register_operand" "=r")
2140 (match_operand:DI 1 "const0_operand" "i"))
2141 (clobber (reg:CC FLAGS_REG))]
2142 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2143 && reload_completed"
2144 "xor{l}\t%k0, %k0";
2145 [(set_attr "type" "alu1")
2146 (set_attr "mode" "SI")
2147 (set_attr "length_immediate" "0")])
2148
2149 (define_insn "*movdi_or_rex64"
2150 [(set (match_operand:DI 0 "register_operand" "=r")
2151 (match_operand:DI 1 "const_int_operand" "i"))
2152 (clobber (reg:CC FLAGS_REG))]
2153 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2154 && reload_completed
2155 && operands[1] == constm1_rtx"
2156 {
2157 operands[1] = constm1_rtx;
2158 return "or{q}\t{%1, %0|%0, %1}";
2159 }
2160 [(set_attr "type" "alu1")
2161 (set_attr "mode" "DI")
2162 (set_attr "length_immediate" "1")])
2163
2164 (define_insn "*movdi_2"
2165 [(set (match_operand:DI 0 "nonimmediate_operand"
2166 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2167 (match_operand:DI 1 "general_operand"
2168 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2169 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2170 "@
2171 #
2172 #
2173 pxor\t%0, %0
2174 movq\t{%1, %0|%0, %1}
2175 movq\t{%1, %0|%0, %1}
2176 pxor\t%0, %0
2177 movq\t{%1, %0|%0, %1}
2178 movdqa\t{%1, %0|%0, %1}
2179 movq\t{%1, %0|%0, %1}
2180 xorps\t%0, %0
2181 movlps\t{%1, %0|%0, %1}
2182 movaps\t{%1, %0|%0, %1}
2183 movlps\t{%1, %0|%0, %1}"
2184 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2185 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2186
2187 (define_split
2188 [(set (match_operand:DI 0 "push_operand" "")
2189 (match_operand:DI 1 "general_operand" ""))]
2190 "!TARGET_64BIT && reload_completed
2191 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2192 [(const_int 0)]
2193 "ix86_split_long_move (operands); DONE;")
2194
2195 ;; %%% This multiword shite has got to go.
2196 (define_split
2197 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2198 (match_operand:DI 1 "general_operand" ""))]
2199 "!TARGET_64BIT && reload_completed
2200 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2201 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2202 [(const_int 0)]
2203 "ix86_split_long_move (operands); DONE;")
2204
2205 (define_insn "*movdi_1_rex64"
2206 [(set (match_operand:DI 0 "nonimmediate_operand"
2207 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2208 (match_operand:DI 1 "general_operand"
2209 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2210 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2211 {
2212 switch (get_attr_type (insn))
2213 {
2214 case TYPE_SSECVT:
2215 if (SSE_REG_P (operands[0]))
2216 return "movq2dq\t{%1, %0|%0, %1}";
2217 else
2218 return "movdq2q\t{%1, %0|%0, %1}";
2219
2220 case TYPE_SSEMOV:
2221 if (get_attr_mode (insn) == MODE_TI)
2222 return "movdqa\t{%1, %0|%0, %1}";
2223 /* FALLTHRU */
2224
2225 case TYPE_MMXMOV:
2226 /* Moves from and into integer register is done using movd
2227 opcode with REX prefix. */
2228 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2229 return "movd\t{%1, %0|%0, %1}";
2230 return "movq\t{%1, %0|%0, %1}";
2231
2232 case TYPE_SSELOG1:
2233 case TYPE_MMXADD:
2234 return "pxor\t%0, %0";
2235
2236 case TYPE_MULTI:
2237 return "#";
2238
2239 case TYPE_LEA:
2240 return "lea{q}\t{%a1, %0|%0, %a1}";
2241
2242 default:
2243 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2244 if (get_attr_mode (insn) == MODE_SI)
2245 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2246 else if (which_alternative == 2)
2247 return "movabs{q}\t{%1, %0|%0, %1}";
2248 else
2249 return "mov{q}\t{%1, %0|%0, %1}";
2250 }
2251 }
2252 [(set (attr "type")
2253 (cond [(eq_attr "alternative" "5")
2254 (const_string "mmxadd")
2255 (eq_attr "alternative" "6,7,8,9,10")
2256 (const_string "mmxmov")
2257 (eq_attr "alternative" "11")
2258 (const_string "sselog1")
2259 (eq_attr "alternative" "12,13,14,15,16")
2260 (const_string "ssemov")
2261 (eq_attr "alternative" "17,18")
2262 (const_string "ssecvt")
2263 (eq_attr "alternative" "4")
2264 (const_string "multi")
2265 (match_operand:DI 1 "pic_32bit_operand" "")
2266 (const_string "lea")
2267 ]
2268 (const_string "imov")))
2269 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2270 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2271 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2272
2273 ;; Stores and loads of ax to arbitrary constant address.
2274 ;; We fake an second form of instruction to force reload to load address
2275 ;; into register when rax is not available
2276 (define_insn "*movabsdi_1_rex64"
2277 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2278 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2279 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2280 "@
2281 movabs{q}\t{%1, %P0|%P0, %1}
2282 mov{q}\t{%1, %a0|%a0, %1}"
2283 [(set_attr "type" "imov")
2284 (set_attr "modrm" "0,*")
2285 (set_attr "length_address" "8,0")
2286 (set_attr "length_immediate" "0,*")
2287 (set_attr "memory" "store")
2288 (set_attr "mode" "DI")])
2289
2290 (define_insn "*movabsdi_2_rex64"
2291 [(set (match_operand:DI 0 "register_operand" "=a,r")
2292 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2293 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2294 "@
2295 movabs{q}\t{%P1, %0|%0, %P1}
2296 mov{q}\t{%a1, %0|%0, %a1}"
2297 [(set_attr "type" "imov")
2298 (set_attr "modrm" "0,*")
2299 (set_attr "length_address" "8,0")
2300 (set_attr "length_immediate" "0")
2301 (set_attr "memory" "load")
2302 (set_attr "mode" "DI")])
2303
2304 ;; Convert impossible stores of immediate to existing instructions.
2305 ;; First try to get scratch register and go through it. In case this
2306 ;; fails, move by 32bit parts.
2307 (define_peephole2
2308 [(match_scratch:DI 2 "r")
2309 (set (match_operand:DI 0 "memory_operand" "")
2310 (match_operand:DI 1 "immediate_operand" ""))]
2311 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2312 && !x86_64_immediate_operand (operands[1], DImode)"
2313 [(set (match_dup 2) (match_dup 1))
2314 (set (match_dup 0) (match_dup 2))]
2315 "")
2316
2317 ;; We need to define this as both peepholer and splitter for case
2318 ;; peephole2 pass is not run.
2319 ;; "&& 1" is needed to keep it from matching the previous pattern.
2320 (define_peephole2
2321 [(set (match_operand:DI 0 "memory_operand" "")
2322 (match_operand:DI 1 "immediate_operand" ""))]
2323 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2324 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2325 [(set (match_dup 2) (match_dup 3))
2326 (set (match_dup 4) (match_dup 5))]
2327 "split_di (operands, 2, operands + 2, operands + 4);")
2328
2329 (define_split
2330 [(set (match_operand:DI 0 "memory_operand" "")
2331 (match_operand:DI 1 "immediate_operand" ""))]
2332 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2333 ? epilogue_completed : reload_completed)
2334 && !symbolic_operand (operands[1], DImode)
2335 && !x86_64_immediate_operand (operands[1], DImode)"
2336 [(set (match_dup 2) (match_dup 3))
2337 (set (match_dup 4) (match_dup 5))]
2338 "split_di (operands, 2, operands + 2, operands + 4);")
2339
2340 (define_insn "*swapdi_rex64"
2341 [(set (match_operand:DI 0 "register_operand" "+r")
2342 (match_operand:DI 1 "register_operand" "+r"))
2343 (set (match_dup 1)
2344 (match_dup 0))]
2345 "TARGET_64BIT"
2346 "xchg{q}\t%1, %0"
2347 [(set_attr "type" "imov")
2348 (set_attr "mode" "DI")
2349 (set_attr "pent_pair" "np")
2350 (set_attr "athlon_decode" "vector")
2351 (set_attr "amdfam10_decode" "double")])
2352
2353 (define_expand "movti"
2354 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2355 (match_operand:TI 1 "nonimmediate_operand" ""))]
2356 "TARGET_SSE || TARGET_64BIT"
2357 {
2358 if (TARGET_64BIT)
2359 ix86_expand_move (TImode, operands);
2360 else if (push_operand (operands[0], TImode))
2361 ix86_expand_push (TImode, operands[1]);
2362 else
2363 ix86_expand_vector_move (TImode, operands);
2364 DONE;
2365 })
2366
2367 (define_insn "*movti_internal"
2368 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2369 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2370 "TARGET_SSE && !TARGET_64BIT
2371 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2372 {
2373 switch (which_alternative)
2374 {
2375 case 0:
2376 if (get_attr_mode (insn) == MODE_V4SF)
2377 return "xorps\t%0, %0";
2378 else
2379 return "pxor\t%0, %0";
2380 case 1:
2381 case 2:
2382 if (get_attr_mode (insn) == MODE_V4SF)
2383 return "movaps\t{%1, %0|%0, %1}";
2384 else
2385 return "movdqa\t{%1, %0|%0, %1}";
2386 default:
2387 gcc_unreachable ();
2388 }
2389 }
2390 [(set_attr "type" "sselog1,ssemov,ssemov")
2391 (set (attr "mode")
2392 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2393 (ne (symbol_ref "optimize_size") (const_int 0)))
2394 (const_string "V4SF")
2395 (and (eq_attr "alternative" "2")
2396 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2397 (const_int 0)))
2398 (const_string "V4SF")]
2399 (const_string "TI")))])
2400
2401 (define_insn "*movti_rex64"
2402 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2403 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2404 "TARGET_64BIT
2405 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2406 {
2407 switch (which_alternative)
2408 {
2409 case 0:
2410 case 1:
2411 return "#";
2412 case 2:
2413 if (get_attr_mode (insn) == MODE_V4SF)
2414 return "xorps\t%0, %0";
2415 else
2416 return "pxor\t%0, %0";
2417 case 3:
2418 case 4:
2419 if (get_attr_mode (insn) == MODE_V4SF)
2420 return "movaps\t{%1, %0|%0, %1}";
2421 else
2422 return "movdqa\t{%1, %0|%0, %1}";
2423 default:
2424 gcc_unreachable ();
2425 }
2426 }
2427 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2428 (set (attr "mode")
2429 (cond [(eq_attr "alternative" "2,3")
2430 (if_then_else
2431 (ne (symbol_ref "optimize_size")
2432 (const_int 0))
2433 (const_string "V4SF")
2434 (const_string "TI"))
2435 (eq_attr "alternative" "4")
2436 (if_then_else
2437 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2438 (const_int 0))
2439 (ne (symbol_ref "optimize_size")
2440 (const_int 0)))
2441 (const_string "V4SF")
2442 (const_string "TI"))]
2443 (const_string "DI")))])
2444
2445 (define_split
2446 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2447 (match_operand:TI 1 "general_operand" ""))]
2448 "reload_completed && !SSE_REG_P (operands[0])
2449 && !SSE_REG_P (operands[1])"
2450 [(const_int 0)]
2451 "ix86_split_long_move (operands); DONE;")
2452
2453 ;; This expands to what emit_move_complex would generate if we didn't
2454 ;; have a movti pattern. Having this avoids problems with reload on
2455 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2456 ;; to have around all the time.
2457 (define_expand "movcdi"
2458 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2459 (match_operand:CDI 1 "general_operand" ""))]
2460 ""
2461 {
2462 if (push_operand (operands[0], CDImode))
2463 emit_move_complex_push (CDImode, operands[0], operands[1]);
2464 else
2465 emit_move_complex_parts (operands[0], operands[1]);
2466 DONE;
2467 })
2468
2469 (define_expand "movsf"
2470 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2471 (match_operand:SF 1 "general_operand" ""))]
2472 ""
2473 "ix86_expand_move (SFmode, operands); DONE;")
2474
2475 (define_insn "*pushsf"
2476 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2477 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2478 "!TARGET_64BIT"
2479 {
2480 /* Anything else should be already split before reg-stack. */
2481 gcc_assert (which_alternative == 1);
2482 return "push{l}\t%1";
2483 }
2484 [(set_attr "type" "multi,push,multi")
2485 (set_attr "unit" "i387,*,*")
2486 (set_attr "mode" "SF,SI,SF")])
2487
2488 (define_insn "*pushsf_rex64"
2489 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2490 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2491 "TARGET_64BIT"
2492 {
2493 /* Anything else should be already split before reg-stack. */
2494 gcc_assert (which_alternative == 1);
2495 return "push{q}\t%q1";
2496 }
2497 [(set_attr "type" "multi,push,multi")
2498 (set_attr "unit" "i387,*,*")
2499 (set_attr "mode" "SF,DI,SF")])
2500
2501 (define_split
2502 [(set (match_operand:SF 0 "push_operand" "")
2503 (match_operand:SF 1 "memory_operand" ""))]
2504 "reload_completed
2505 && MEM_P (operands[1])
2506 && (operands[2] = find_constant_src (insn))"
2507 [(set (match_dup 0)
2508 (match_dup 2))])
2509
2510
2511 ;; %%% Kill this when call knows how to work this out.
2512 (define_split
2513 [(set (match_operand:SF 0 "push_operand" "")
2514 (match_operand:SF 1 "any_fp_register_operand" ""))]
2515 "!TARGET_64BIT"
2516 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2517 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2518
2519 (define_split
2520 [(set (match_operand:SF 0 "push_operand" "")
2521 (match_operand:SF 1 "any_fp_register_operand" ""))]
2522 "TARGET_64BIT"
2523 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2524 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2525
2526 (define_insn "*movsf_1"
2527 [(set (match_operand:SF 0 "nonimmediate_operand"
2528 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2529 (match_operand:SF 1 "general_operand"
2530 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2531 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2532 && (reload_in_progress || reload_completed
2533 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2534 || (!TARGET_SSE_MATH && optimize_size
2535 && standard_80387_constant_p (operands[1]))
2536 || GET_CODE (operands[1]) != CONST_DOUBLE
2537 || memory_operand (operands[0], SFmode))"
2538 {
2539 switch (which_alternative)
2540 {
2541 case 0:
2542 case 1:
2543 return output_387_reg_move (insn, operands);
2544
2545 case 2:
2546 return standard_80387_constant_opcode (operands[1]);
2547
2548 case 3:
2549 case 4:
2550 return "mov{l}\t{%1, %0|%0, %1}";
2551 case 5:
2552 if (get_attr_mode (insn) == MODE_TI)
2553 return "pxor\t%0, %0";
2554 else
2555 return "xorps\t%0, %0";
2556 case 6:
2557 if (get_attr_mode (insn) == MODE_V4SF)
2558 return "movaps\t{%1, %0|%0, %1}";
2559 else
2560 return "movss\t{%1, %0|%0, %1}";
2561 case 7: case 8:
2562 return "movss\t{%1, %0|%0, %1}";
2563
2564 case 9: case 10:
2565 case 12: case 13: case 14: case 15:
2566 return "movd\t{%1, %0|%0, %1}";
2567
2568 case 11:
2569 return "movq\t{%1, %0|%0, %1}";
2570
2571 default:
2572 gcc_unreachable ();
2573 }
2574 }
2575 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2576 (set (attr "mode")
2577 (cond [(eq_attr "alternative" "3,4,9,10")
2578 (const_string "SI")
2579 (eq_attr "alternative" "5")
2580 (if_then_else
2581 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2582 (const_int 0))
2583 (ne (symbol_ref "TARGET_SSE2")
2584 (const_int 0)))
2585 (eq (symbol_ref "optimize_size")
2586 (const_int 0)))
2587 (const_string "TI")
2588 (const_string "V4SF"))
2589 /* For architectures resolving dependencies on
2590 whole SSE registers use APS move to break dependency
2591 chains, otherwise use short move to avoid extra work.
2592
2593 Do the same for architectures resolving dependencies on
2594 the parts. While in DF mode it is better to always handle
2595 just register parts, the SF mode is different due to lack
2596 of instructions to load just part of the register. It is
2597 better to maintain the whole registers in single format
2598 to avoid problems on using packed logical operations. */
2599 (eq_attr "alternative" "6")
2600 (if_then_else
2601 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2602 (const_int 0))
2603 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2604 (const_int 0)))
2605 (const_string "V4SF")
2606 (const_string "SF"))
2607 (eq_attr "alternative" "11")
2608 (const_string "DI")]
2609 (const_string "SF")))])
2610
2611 (define_insn "*swapsf"
2612 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2613 (match_operand:SF 1 "fp_register_operand" "+f"))
2614 (set (match_dup 1)
2615 (match_dup 0))]
2616 "reload_completed || TARGET_80387"
2617 {
2618 if (STACK_TOP_P (operands[0]))
2619 return "fxch\t%1";
2620 else
2621 return "fxch\t%0";
2622 }
2623 [(set_attr "type" "fxch")
2624 (set_attr "mode" "SF")])
2625
2626 (define_expand "movdf"
2627 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2628 (match_operand:DF 1 "general_operand" ""))]
2629 ""
2630 "ix86_expand_move (DFmode, operands); DONE;")
2631
2632 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2633 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2634 ;; On the average, pushdf using integers can be still shorter. Allow this
2635 ;; pattern for optimize_size too.
2636
2637 (define_insn "*pushdf_nointeger"
2638 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2639 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2640 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2641 {
2642 /* This insn should be already split before reg-stack. */
2643 gcc_unreachable ();
2644 }
2645 [(set_attr "type" "multi")
2646 (set_attr "unit" "i387,*,*,*")
2647 (set_attr "mode" "DF,SI,SI,DF")])
2648
2649 (define_insn "*pushdf_integer"
2650 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2651 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2652 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2653 {
2654 /* This insn should be already split before reg-stack. */
2655 gcc_unreachable ();
2656 }
2657 [(set_attr "type" "multi")
2658 (set_attr "unit" "i387,*,*")
2659 (set_attr "mode" "DF,SI,DF")])
2660
2661 ;; %%% Kill this when call knows how to work this out.
2662 (define_split
2663 [(set (match_operand:DF 0 "push_operand" "")
2664 (match_operand:DF 1 "any_fp_register_operand" ""))]
2665 "!TARGET_64BIT && reload_completed"
2666 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2667 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2668 "")
2669
2670 (define_split
2671 [(set (match_operand:DF 0 "push_operand" "")
2672 (match_operand:DF 1 "any_fp_register_operand" ""))]
2673 "TARGET_64BIT && reload_completed"
2674 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2675 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2676 "")
2677
2678 (define_split
2679 [(set (match_operand:DF 0 "push_operand" "")
2680 (match_operand:DF 1 "general_operand" ""))]
2681 "reload_completed"
2682 [(const_int 0)]
2683 "ix86_split_long_move (operands); DONE;")
2684
2685 ;; Moving is usually shorter when only FP registers are used. This separate
2686 ;; movdf pattern avoids the use of integer registers for FP operations
2687 ;; when optimizing for size.
2688
2689 (define_insn "*movdf_nointeger"
2690 [(set (match_operand:DF 0 "nonimmediate_operand"
2691 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2692 (match_operand:DF 1 "general_operand"
2693 "fm,f,G,*roF,F*r,C ,Y2*x,mY2*x,Y2*x"))]
2694 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2695 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2696 && (reload_in_progress || reload_completed
2697 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2698 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2699 && standard_80387_constant_p (operands[1]))
2700 || GET_CODE (operands[1]) != CONST_DOUBLE
2701 || memory_operand (operands[0], DFmode))"
2702 {
2703 switch (which_alternative)
2704 {
2705 case 0:
2706 case 1:
2707 return output_387_reg_move (insn, operands);
2708
2709 case 2:
2710 return standard_80387_constant_opcode (operands[1]);
2711
2712 case 3:
2713 case 4:
2714 return "#";
2715 case 5:
2716 switch (get_attr_mode (insn))
2717 {
2718 case MODE_V4SF:
2719 return "xorps\t%0, %0";
2720 case MODE_V2DF:
2721 return "xorpd\t%0, %0";
2722 case MODE_TI:
2723 return "pxor\t%0, %0";
2724 default:
2725 gcc_unreachable ();
2726 }
2727 case 6:
2728 case 7:
2729 case 8:
2730 switch (get_attr_mode (insn))
2731 {
2732 case MODE_V4SF:
2733 return "movaps\t{%1, %0|%0, %1}";
2734 case MODE_V2DF:
2735 return "movapd\t{%1, %0|%0, %1}";
2736 case MODE_TI:
2737 return "movdqa\t{%1, %0|%0, %1}";
2738 case MODE_DI:
2739 return "movq\t{%1, %0|%0, %1}";
2740 case MODE_DF:
2741 return "movsd\t{%1, %0|%0, %1}";
2742 case MODE_V1DF:
2743 return "movlpd\t{%1, %0|%0, %1}";
2744 case MODE_V2SF:
2745 return "movlps\t{%1, %0|%0, %1}";
2746 default:
2747 gcc_unreachable ();
2748 }
2749
2750 default:
2751 gcc_unreachable ();
2752 }
2753 }
2754 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2755 (set (attr "mode")
2756 (cond [(eq_attr "alternative" "0,1,2")
2757 (const_string "DF")
2758 (eq_attr "alternative" "3,4")
2759 (const_string "SI")
2760
2761 /* For SSE1, we have many fewer alternatives. */
2762 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2763 (cond [(eq_attr "alternative" "5,6")
2764 (const_string "V4SF")
2765 ]
2766 (const_string "V2SF"))
2767
2768 /* xorps is one byte shorter. */
2769 (eq_attr "alternative" "5")
2770 (cond [(ne (symbol_ref "optimize_size")
2771 (const_int 0))
2772 (const_string "V4SF")
2773 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2774 (const_int 0))
2775 (const_string "TI")
2776 ]
2777 (const_string "V2DF"))
2778
2779 /* For architectures resolving dependencies on
2780 whole SSE registers use APD move to break dependency
2781 chains, otherwise use short move to avoid extra work.
2782
2783 movaps encodes one byte shorter. */
2784 (eq_attr "alternative" "6")
2785 (cond
2786 [(ne (symbol_ref "optimize_size")
2787 (const_int 0))
2788 (const_string "V4SF")
2789 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2790 (const_int 0))
2791 (const_string "V2DF")
2792 ]
2793 (const_string "DF"))
2794 /* For architectures resolving dependencies on register
2795 parts we may avoid extra work to zero out upper part
2796 of register. */
2797 (eq_attr "alternative" "7")
2798 (if_then_else
2799 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2800 (const_int 0))
2801 (const_string "V1DF")
2802 (const_string "DF"))
2803 ]
2804 (const_string "DF")))])
2805
2806 (define_insn "*movdf_integer_rex64"
2807 [(set (match_operand:DF 0 "nonimmediate_operand"
2808 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2809 (match_operand:DF 1 "general_operand"
2810 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2811 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2812 && (reload_in_progress || reload_completed
2813 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2814 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2815 && standard_80387_constant_p (operands[1]))
2816 || GET_CODE (operands[1]) != CONST_DOUBLE
2817 || memory_operand (operands[0], DFmode))"
2818 {
2819 switch (which_alternative)
2820 {
2821 case 0:
2822 case 1:
2823 return output_387_reg_move (insn, operands);
2824
2825 case 2:
2826 return standard_80387_constant_opcode (operands[1]);
2827
2828 case 3:
2829 case 4:
2830 return "#";
2831
2832 case 5:
2833 switch (get_attr_mode (insn))
2834 {
2835 case MODE_V4SF:
2836 return "xorps\t%0, %0";
2837 case MODE_V2DF:
2838 return "xorpd\t%0, %0";
2839 case MODE_TI:
2840 return "pxor\t%0, %0";
2841 default:
2842 gcc_unreachable ();
2843 }
2844 case 6:
2845 case 7:
2846 case 8:
2847 switch (get_attr_mode (insn))
2848 {
2849 case MODE_V4SF:
2850 return "movaps\t{%1, %0|%0, %1}";
2851 case MODE_V2DF:
2852 return "movapd\t{%1, %0|%0, %1}";
2853 case MODE_TI:
2854 return "movdqa\t{%1, %0|%0, %1}";
2855 case MODE_DI:
2856 return "movq\t{%1, %0|%0, %1}";
2857 case MODE_DF:
2858 return "movsd\t{%1, %0|%0, %1}";
2859 case MODE_V1DF:
2860 return "movlpd\t{%1, %0|%0, %1}";
2861 case MODE_V2SF:
2862 return "movlps\t{%1, %0|%0, %1}";
2863 default:
2864 gcc_unreachable ();
2865 }
2866
2867 case 9:
2868 case 10:
2869 return "movd\t{%1, %0|%0, %1}";
2870
2871 default:
2872 gcc_unreachable();
2873 }
2874 }
2875 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2876 (set (attr "mode")
2877 (cond [(eq_attr "alternative" "0,1,2")
2878 (const_string "DF")
2879 (eq_attr "alternative" "3,4,9,10")
2880 (const_string "DI")
2881
2882 /* For SSE1, we have many fewer alternatives. */
2883 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2884 (cond [(eq_attr "alternative" "5,6")
2885 (const_string "V4SF")
2886 ]
2887 (const_string "V2SF"))
2888
2889 /* xorps is one byte shorter. */
2890 (eq_attr "alternative" "5")
2891 (cond [(ne (symbol_ref "optimize_size")
2892 (const_int 0))
2893 (const_string "V4SF")
2894 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2895 (const_int 0))
2896 (const_string "TI")
2897 ]
2898 (const_string "V2DF"))
2899
2900 /* For architectures resolving dependencies on
2901 whole SSE registers use APD move to break dependency
2902 chains, otherwise use short move to avoid extra work.
2903
2904 movaps encodes one byte shorter. */
2905 (eq_attr "alternative" "6")
2906 (cond
2907 [(ne (symbol_ref "optimize_size")
2908 (const_int 0))
2909 (const_string "V4SF")
2910 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2911 (const_int 0))
2912 (const_string "V2DF")
2913 ]
2914 (const_string "DF"))
2915 /* For architectures resolving dependencies on register
2916 parts we may avoid extra work to zero out upper part
2917 of register. */
2918 (eq_attr "alternative" "7")
2919 (if_then_else
2920 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2921 (const_int 0))
2922 (const_string "V1DF")
2923 (const_string "DF"))
2924 ]
2925 (const_string "DF")))])
2926
2927 (define_insn "*movdf_integer"
2928 [(set (match_operand:DF 0 "nonimmediate_operand"
2929 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2930 (match_operand:DF 1 "general_operand"
2931 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2932 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2933 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2934 && (reload_in_progress || reload_completed
2935 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2936 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2937 && standard_80387_constant_p (operands[1]))
2938 || GET_CODE (operands[1]) != CONST_DOUBLE
2939 || memory_operand (operands[0], DFmode))"
2940 {
2941 switch (which_alternative)
2942 {
2943 case 0:
2944 case 1:
2945 return output_387_reg_move (insn, operands);
2946
2947 case 2:
2948 return standard_80387_constant_opcode (operands[1]);
2949
2950 case 3:
2951 case 4:
2952 return "#";
2953
2954 case 5:
2955 switch (get_attr_mode (insn))
2956 {
2957 case MODE_V4SF:
2958 return "xorps\t%0, %0";
2959 case MODE_V2DF:
2960 return "xorpd\t%0, %0";
2961 case MODE_TI:
2962 return "pxor\t%0, %0";
2963 default:
2964 gcc_unreachable ();
2965 }
2966 case 6:
2967 case 7:
2968 case 8:
2969 switch (get_attr_mode (insn))
2970 {
2971 case MODE_V4SF:
2972 return "movaps\t{%1, %0|%0, %1}";
2973 case MODE_V2DF:
2974 return "movapd\t{%1, %0|%0, %1}";
2975 case MODE_TI:
2976 return "movdqa\t{%1, %0|%0, %1}";
2977 case MODE_DI:
2978 return "movq\t{%1, %0|%0, %1}";
2979 case MODE_DF:
2980 return "movsd\t{%1, %0|%0, %1}";
2981 case MODE_V1DF:
2982 return "movlpd\t{%1, %0|%0, %1}";
2983 case MODE_V2SF:
2984 return "movlps\t{%1, %0|%0, %1}";
2985 default:
2986 gcc_unreachable ();
2987 }
2988
2989 default:
2990 gcc_unreachable();
2991 }
2992 }
2993 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2994 (set (attr "mode")
2995 (cond [(eq_attr "alternative" "0,1,2")
2996 (const_string "DF")
2997 (eq_attr "alternative" "3,4")
2998 (const_string "SI")
2999
3000 /* For SSE1, we have many fewer alternatives. */
3001 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3002 (cond [(eq_attr "alternative" "5,6")
3003 (const_string "V4SF")
3004 ]
3005 (const_string "V2SF"))
3006
3007 /* xorps is one byte shorter. */
3008 (eq_attr "alternative" "5")
3009 (cond [(ne (symbol_ref "optimize_size")
3010 (const_int 0))
3011 (const_string "V4SF")
3012 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3013 (const_int 0))
3014 (const_string "TI")
3015 ]
3016 (const_string "V2DF"))
3017
3018 /* For architectures resolving dependencies on
3019 whole SSE registers use APD move to break dependency
3020 chains, otherwise use short move to avoid extra work.
3021
3022 movaps encodes one byte shorter. */
3023 (eq_attr "alternative" "6")
3024 (cond
3025 [(ne (symbol_ref "optimize_size")
3026 (const_int 0))
3027 (const_string "V4SF")
3028 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3029 (const_int 0))
3030 (const_string "V2DF")
3031 ]
3032 (const_string "DF"))
3033 /* For architectures resolving dependencies on register
3034 parts we may avoid extra work to zero out upper part
3035 of register. */
3036 (eq_attr "alternative" "7")
3037 (if_then_else
3038 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3039 (const_int 0))
3040 (const_string "V1DF")
3041 (const_string "DF"))
3042 ]
3043 (const_string "DF")))])
3044
3045 (define_split
3046 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3047 (match_operand:DF 1 "general_operand" ""))]
3048 "reload_completed
3049 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3050 && ! (ANY_FP_REG_P (operands[0]) ||
3051 (GET_CODE (operands[0]) == SUBREG
3052 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3053 && ! (ANY_FP_REG_P (operands[1]) ||
3054 (GET_CODE (operands[1]) == SUBREG
3055 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3056 [(const_int 0)]
3057 "ix86_split_long_move (operands); DONE;")
3058
3059 (define_insn "*swapdf"
3060 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3061 (match_operand:DF 1 "fp_register_operand" "+f"))
3062 (set (match_dup 1)
3063 (match_dup 0))]
3064 "reload_completed || TARGET_80387"
3065 {
3066 if (STACK_TOP_P (operands[0]))
3067 return "fxch\t%1";
3068 else
3069 return "fxch\t%0";
3070 }
3071 [(set_attr "type" "fxch")
3072 (set_attr "mode" "DF")])
3073
3074 (define_expand "movxf"
3075 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3076 (match_operand:XF 1 "general_operand" ""))]
3077 ""
3078 "ix86_expand_move (XFmode, operands); DONE;")
3079
3080 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3081 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3082 ;; Pushing using integer instructions is longer except for constants
3083 ;; and direct memory references.
3084 ;; (assuming that any given constant is pushed only once, but this ought to be
3085 ;; handled elsewhere).
3086
3087 (define_insn "*pushxf_nointeger"
3088 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3089 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3090 "optimize_size"
3091 {
3092 /* This insn should be already split before reg-stack. */
3093 gcc_unreachable ();
3094 }
3095 [(set_attr "type" "multi")
3096 (set_attr "unit" "i387,*,*")
3097 (set_attr "mode" "XF,SI,SI")])
3098
3099 (define_insn "*pushxf_integer"
3100 [(set (match_operand:XF 0 "push_operand" "=<,<")
3101 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3102 "!optimize_size"
3103 {
3104 /* This insn should be already split before reg-stack. */
3105 gcc_unreachable ();
3106 }
3107 [(set_attr "type" "multi")
3108 (set_attr "unit" "i387,*")
3109 (set_attr "mode" "XF,SI")])
3110
3111 (define_split
3112 [(set (match_operand 0 "push_operand" "")
3113 (match_operand 1 "general_operand" ""))]
3114 "reload_completed
3115 && (GET_MODE (operands[0]) == XFmode
3116 || GET_MODE (operands[0]) == DFmode)
3117 && !ANY_FP_REG_P (operands[1])"
3118 [(const_int 0)]
3119 "ix86_split_long_move (operands); DONE;")
3120
3121 (define_split
3122 [(set (match_operand:XF 0 "push_operand" "")
3123 (match_operand:XF 1 "any_fp_register_operand" ""))]
3124 "!TARGET_64BIT"
3125 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3126 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3127 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3128
3129 (define_split
3130 [(set (match_operand:XF 0 "push_operand" "")
3131 (match_operand:XF 1 "any_fp_register_operand" ""))]
3132 "TARGET_64BIT"
3133 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3134 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3135 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3136
3137 ;; Do not use integer registers when optimizing for size
3138 (define_insn "*movxf_nointeger"
3139 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3140 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3141 "optimize_size
3142 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3143 && (reload_in_progress || reload_completed
3144 || (optimize_size && standard_80387_constant_p (operands[1]))
3145 || GET_CODE (operands[1]) != CONST_DOUBLE
3146 || memory_operand (operands[0], XFmode))"
3147 {
3148 switch (which_alternative)
3149 {
3150 case 0:
3151 case 1:
3152 return output_387_reg_move (insn, operands);
3153
3154 case 2:
3155 return standard_80387_constant_opcode (operands[1]);
3156
3157 case 3: case 4:
3158 return "#";
3159 default:
3160 gcc_unreachable ();
3161 }
3162 }
3163 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3164 (set_attr "mode" "XF,XF,XF,SI,SI")])
3165
3166 (define_insn "*movxf_integer"
3167 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3168 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3169 "!optimize_size
3170 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3171 && (reload_in_progress || reload_completed
3172 || (optimize_size && standard_80387_constant_p (operands[1]))
3173 || GET_CODE (operands[1]) != CONST_DOUBLE
3174 || memory_operand (operands[0], XFmode))"
3175 {
3176 switch (which_alternative)
3177 {
3178 case 0:
3179 case 1:
3180 return output_387_reg_move (insn, operands);
3181
3182 case 2:
3183 return standard_80387_constant_opcode (operands[1]);
3184
3185 case 3: case 4:
3186 return "#";
3187
3188 default:
3189 gcc_unreachable ();
3190 }
3191 }
3192 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3193 (set_attr "mode" "XF,XF,XF,SI,SI")])
3194
3195 (define_expand "movtf"
3196 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3197 (match_operand:TF 1 "nonimmediate_operand" ""))]
3198 "TARGET_64BIT"
3199 {
3200 ix86_expand_move (TFmode, operands);
3201 DONE;
3202 })
3203
3204 (define_insn "*movtf_internal"
3205 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3206 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3207 "TARGET_64BIT
3208 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3209 {
3210 switch (which_alternative)
3211 {
3212 case 0:
3213 case 1:
3214 if (get_attr_mode (insn) == MODE_V4SF)
3215 return "movaps\t{%1, %0|%0, %1}";
3216 else
3217 return "movdqa\t{%1, %0|%0, %1}";
3218 case 2:
3219 if (get_attr_mode (insn) == MODE_V4SF)
3220 return "xorps\t%0, %0";
3221 else
3222 return "pxor\t%0, %0";
3223 case 3:
3224 case 4:
3225 return "#";
3226 default:
3227 gcc_unreachable ();
3228 }
3229 }
3230 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3231 (set (attr "mode")
3232 (cond [(eq_attr "alternative" "0,2")
3233 (if_then_else
3234 (ne (symbol_ref "optimize_size")
3235 (const_int 0))
3236 (const_string "V4SF")
3237 (const_string "TI"))
3238 (eq_attr "alternative" "1")
3239 (if_then_else
3240 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3241 (const_int 0))
3242 (ne (symbol_ref "optimize_size")
3243 (const_int 0)))
3244 (const_string "V4SF")
3245 (const_string "TI"))]
3246 (const_string "DI")))])
3247
3248 (define_split
3249 [(set (match_operand 0 "nonimmediate_operand" "")
3250 (match_operand 1 "general_operand" ""))]
3251 "reload_completed
3252 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3253 && GET_MODE (operands[0]) == XFmode
3254 && ! (ANY_FP_REG_P (operands[0]) ||
3255 (GET_CODE (operands[0]) == SUBREG
3256 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3257 && ! (ANY_FP_REG_P (operands[1]) ||
3258 (GET_CODE (operands[1]) == SUBREG
3259 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3260 [(const_int 0)]
3261 "ix86_split_long_move (operands); DONE;")
3262
3263 (define_split
3264 [(set (match_operand 0 "register_operand" "")
3265 (match_operand 1 "memory_operand" ""))]
3266 "reload_completed
3267 && MEM_P (operands[1])
3268 && (GET_MODE (operands[0]) == TFmode
3269 || GET_MODE (operands[0]) == XFmode
3270 || GET_MODE (operands[0]) == SFmode
3271 || GET_MODE (operands[0]) == DFmode)
3272 && (operands[2] = find_constant_src (insn))"
3273 [(set (match_dup 0) (match_dup 2))]
3274 {
3275 rtx c = operands[2];
3276 rtx r = operands[0];
3277
3278 if (GET_CODE (r) == SUBREG)
3279 r = SUBREG_REG (r);
3280
3281 if (SSE_REG_P (r))
3282 {
3283 if (!standard_sse_constant_p (c))
3284 FAIL;
3285 }
3286 else if (FP_REG_P (r))
3287 {
3288 if (!standard_80387_constant_p (c))
3289 FAIL;
3290 }
3291 else if (MMX_REG_P (r))
3292 FAIL;
3293 })
3294
3295 (define_split
3296 [(set (match_operand 0 "register_operand" "")
3297 (float_extend (match_operand 1 "memory_operand" "")))]
3298 "reload_completed
3299 && MEM_P (operands[1])
3300 && (GET_MODE (operands[0]) == TFmode
3301 || GET_MODE (operands[0]) == XFmode
3302 || GET_MODE (operands[0]) == SFmode
3303 || GET_MODE (operands[0]) == DFmode)
3304 && (operands[2] = find_constant_src (insn))"
3305 [(set (match_dup 0) (match_dup 2))]
3306 {
3307 rtx c = operands[2];
3308 rtx r = operands[0];
3309
3310 if (GET_CODE (r) == SUBREG)
3311 r = SUBREG_REG (r);
3312
3313 if (SSE_REG_P (r))
3314 {
3315 if (!standard_sse_constant_p (c))
3316 FAIL;
3317 }
3318 else if (FP_REG_P (r))
3319 {
3320 if (!standard_80387_constant_p (c))
3321 FAIL;
3322 }
3323 else if (MMX_REG_P (r))
3324 FAIL;
3325 })
3326
3327 (define_insn "swapxf"
3328 [(set (match_operand:XF 0 "register_operand" "+f")
3329 (match_operand:XF 1 "register_operand" "+f"))
3330 (set (match_dup 1)
3331 (match_dup 0))]
3332 "TARGET_80387"
3333 {
3334 if (STACK_TOP_P (operands[0]))
3335 return "fxch\t%1";
3336 else
3337 return "fxch\t%0";
3338 }
3339 [(set_attr "type" "fxch")
3340 (set_attr "mode" "XF")])
3341
3342 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3343 (define_split
3344 [(set (match_operand:X87MODEF 0 "register_operand" "")
3345 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3346 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3347 && (standard_80387_constant_p (operands[1]) == 8
3348 || standard_80387_constant_p (operands[1]) == 9)"
3349 [(set (match_dup 0)(match_dup 1))
3350 (set (match_dup 0)
3351 (neg:X87MODEF (match_dup 0)))]
3352 {
3353 REAL_VALUE_TYPE r;
3354
3355 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3356 if (real_isnegzero (&r))
3357 operands[1] = CONST0_RTX (<MODE>mode);
3358 else
3359 operands[1] = CONST1_RTX (<MODE>mode);
3360 })
3361
3362 (define_split
3363 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3364 (match_operand:TF 1 "general_operand" ""))]
3365 "reload_completed
3366 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3367 [(const_int 0)]
3368 "ix86_split_long_move (operands); DONE;")
3369 \f
3370 ;; Zero extension instructions
3371
3372 (define_expand "zero_extendhisi2"
3373 [(set (match_operand:SI 0 "register_operand" "")
3374 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3375 ""
3376 {
3377 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3378 {
3379 operands[1] = force_reg (HImode, operands[1]);
3380 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3381 DONE;
3382 }
3383 })
3384
3385 (define_insn "zero_extendhisi2_and"
3386 [(set (match_operand:SI 0 "register_operand" "=r")
3387 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3388 (clobber (reg:CC FLAGS_REG))]
3389 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3390 "#"
3391 [(set_attr "type" "alu1")
3392 (set_attr "mode" "SI")])
3393
3394 (define_split
3395 [(set (match_operand:SI 0 "register_operand" "")
3396 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3397 (clobber (reg:CC FLAGS_REG))]
3398 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3399 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3400 (clobber (reg:CC FLAGS_REG))])]
3401 "")
3402
3403 (define_insn "*zero_extendhisi2_movzwl"
3404 [(set (match_operand:SI 0 "register_operand" "=r")
3405 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3406 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3407 "movz{wl|x}\t{%1, %0|%0, %1}"
3408 [(set_attr "type" "imovx")
3409 (set_attr "mode" "SI")])
3410
3411 (define_expand "zero_extendqihi2"
3412 [(parallel
3413 [(set (match_operand:HI 0 "register_operand" "")
3414 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3415 (clobber (reg:CC FLAGS_REG))])]
3416 ""
3417 "")
3418
3419 (define_insn "*zero_extendqihi2_and"
3420 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3421 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3422 (clobber (reg:CC FLAGS_REG))]
3423 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3424 "#"
3425 [(set_attr "type" "alu1")
3426 (set_attr "mode" "HI")])
3427
3428 (define_insn "*zero_extendqihi2_movzbw_and"
3429 [(set (match_operand:HI 0 "register_operand" "=r,r")
3430 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3431 (clobber (reg:CC FLAGS_REG))]
3432 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3433 "#"
3434 [(set_attr "type" "imovx,alu1")
3435 (set_attr "mode" "HI")])
3436
3437 ; zero extend to SImode here to avoid partial register stalls
3438 (define_insn "*zero_extendqihi2_movzbl"
3439 [(set (match_operand:HI 0 "register_operand" "=r")
3440 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3441 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3442 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3443 [(set_attr "type" "imovx")
3444 (set_attr "mode" "SI")])
3445
3446 ;; For the movzbw case strip only the clobber
3447 (define_split
3448 [(set (match_operand:HI 0 "register_operand" "")
3449 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3450 (clobber (reg:CC FLAGS_REG))]
3451 "reload_completed
3452 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3453 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3454 [(set (match_operand:HI 0 "register_operand" "")
3455 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3456
3457 ;; When source and destination does not overlap, clear destination
3458 ;; first and then do the movb
3459 (define_split
3460 [(set (match_operand:HI 0 "register_operand" "")
3461 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3462 (clobber (reg:CC FLAGS_REG))]
3463 "reload_completed
3464 && ANY_QI_REG_P (operands[0])
3465 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3466 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3467 [(set (match_dup 0) (const_int 0))
3468 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3469 "operands[2] = gen_lowpart (QImode, operands[0]);")
3470
3471 ;; Rest is handled by single and.
3472 (define_split
3473 [(set (match_operand:HI 0 "register_operand" "")
3474 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3475 (clobber (reg:CC FLAGS_REG))]
3476 "reload_completed
3477 && true_regnum (operands[0]) == true_regnum (operands[1])"
3478 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3479 (clobber (reg:CC FLAGS_REG))])]
3480 "")
3481
3482 (define_expand "zero_extendqisi2"
3483 [(parallel
3484 [(set (match_operand:SI 0 "register_operand" "")
3485 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3486 (clobber (reg:CC FLAGS_REG))])]
3487 ""
3488 "")
3489
3490 (define_insn "*zero_extendqisi2_and"
3491 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3492 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3493 (clobber (reg:CC FLAGS_REG))]
3494 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3495 "#"
3496 [(set_attr "type" "alu1")
3497 (set_attr "mode" "SI")])
3498
3499 (define_insn "*zero_extendqisi2_movzbw_and"
3500 [(set (match_operand:SI 0 "register_operand" "=r,r")
3501 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3502 (clobber (reg:CC FLAGS_REG))]
3503 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3504 "#"
3505 [(set_attr "type" "imovx,alu1")
3506 (set_attr "mode" "SI")])
3507
3508 (define_insn "*zero_extendqisi2_movzbw"
3509 [(set (match_operand:SI 0 "register_operand" "=r")
3510 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3511 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3512 "movz{bl|x}\t{%1, %0|%0, %1}"
3513 [(set_attr "type" "imovx")
3514 (set_attr "mode" "SI")])
3515
3516 ;; For the movzbl case strip only the clobber
3517 (define_split
3518 [(set (match_operand:SI 0 "register_operand" "")
3519 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3520 (clobber (reg:CC FLAGS_REG))]
3521 "reload_completed
3522 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3523 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3524 [(set (match_dup 0)
3525 (zero_extend:SI (match_dup 1)))])
3526
3527 ;; When source and destination does not overlap, clear destination
3528 ;; first and then do the movb
3529 (define_split
3530 [(set (match_operand:SI 0 "register_operand" "")
3531 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3532 (clobber (reg:CC FLAGS_REG))]
3533 "reload_completed
3534 && ANY_QI_REG_P (operands[0])
3535 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3536 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3537 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3538 [(set (match_dup 0) (const_int 0))
3539 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3540 "operands[2] = gen_lowpart (QImode, operands[0]);")
3541
3542 ;; Rest is handled by single and.
3543 (define_split
3544 [(set (match_operand:SI 0 "register_operand" "")
3545 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3546 (clobber (reg:CC FLAGS_REG))]
3547 "reload_completed
3548 && true_regnum (operands[0]) == true_regnum (operands[1])"
3549 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3550 (clobber (reg:CC FLAGS_REG))])]
3551 "")
3552
3553 ;; %%% Kill me once multi-word ops are sane.
3554 (define_expand "zero_extendsidi2"
3555 [(set (match_operand:DI 0 "register_operand" "")
3556 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3557 ""
3558 {
3559 if (!TARGET_64BIT)
3560 {
3561 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3562 DONE;
3563 }
3564 })
3565
3566 (define_insn "zero_extendsidi2_32"
3567 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3568 (zero_extend:DI
3569 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3570 (clobber (reg:CC FLAGS_REG))]
3571 "!TARGET_64BIT"
3572 "@
3573 #
3574 #
3575 #
3576 movd\t{%1, %0|%0, %1}
3577 movd\t{%1, %0|%0, %1}
3578 movd\t{%1, %0|%0, %1}
3579 movd\t{%1, %0|%0, %1}"
3580 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3581 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3582
3583 (define_insn "zero_extendsidi2_rex64"
3584 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3585 (zero_extend:DI
3586 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3587 "TARGET_64BIT"
3588 "@
3589 mov\t{%k1, %k0|%k0, %k1}
3590 #
3591 movd\t{%1, %0|%0, %1}
3592 movd\t{%1, %0|%0, %1}
3593 movd\t{%1, %0|%0, %1}
3594 movd\t{%1, %0|%0, %1}"
3595 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3596 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3597
3598 (define_split
3599 [(set (match_operand:DI 0 "memory_operand" "")
3600 (zero_extend:DI (match_dup 0)))]
3601 "TARGET_64BIT"
3602 [(set (match_dup 4) (const_int 0))]
3603 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3604
3605 (define_split
3606 [(set (match_operand:DI 0 "register_operand" "")
3607 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3608 (clobber (reg:CC FLAGS_REG))]
3609 "!TARGET_64BIT && reload_completed
3610 && true_regnum (operands[0]) == true_regnum (operands[1])"
3611 [(set (match_dup 4) (const_int 0))]
3612 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3613
3614 (define_split
3615 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3616 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3617 (clobber (reg:CC FLAGS_REG))]
3618 "!TARGET_64BIT && reload_completed
3619 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3620 [(set (match_dup 3) (match_dup 1))
3621 (set (match_dup 4) (const_int 0))]
3622 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3623
3624 (define_insn "zero_extendhidi2"
3625 [(set (match_operand:DI 0 "register_operand" "=r")
3626 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3627 "TARGET_64BIT"
3628 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3629 [(set_attr "type" "imovx")
3630 (set_attr "mode" "DI")])
3631
3632 (define_insn "zero_extendqidi2"
3633 [(set (match_operand:DI 0 "register_operand" "=r")
3634 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3635 "TARGET_64BIT"
3636 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3637 [(set_attr "type" "imovx")
3638 (set_attr "mode" "DI")])
3639 \f
3640 ;; Sign extension instructions
3641
3642 (define_expand "extendsidi2"
3643 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3644 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3645 (clobber (reg:CC FLAGS_REG))
3646 (clobber (match_scratch:SI 2 ""))])]
3647 ""
3648 {
3649 if (TARGET_64BIT)
3650 {
3651 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3652 DONE;
3653 }
3654 })
3655
3656 (define_insn "*extendsidi2_1"
3657 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3658 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3659 (clobber (reg:CC FLAGS_REG))
3660 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3661 "!TARGET_64BIT"
3662 "#")
3663
3664 (define_insn "extendsidi2_rex64"
3665 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3666 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3667 "TARGET_64BIT"
3668 "@
3669 {cltq|cdqe}
3670 movs{lq|x}\t{%1,%0|%0, %1}"
3671 [(set_attr "type" "imovx")
3672 (set_attr "mode" "DI")
3673 (set_attr "prefix_0f" "0")
3674 (set_attr "modrm" "0,1")])
3675
3676 (define_insn "extendhidi2"
3677 [(set (match_operand:DI 0 "register_operand" "=r")
3678 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3679 "TARGET_64BIT"
3680 "movs{wq|x}\t{%1,%0|%0, %1}"
3681 [(set_attr "type" "imovx")
3682 (set_attr "mode" "DI")])
3683
3684 (define_insn "extendqidi2"
3685 [(set (match_operand:DI 0 "register_operand" "=r")
3686 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3687 "TARGET_64BIT"
3688 "movs{bq|x}\t{%1,%0|%0, %1}"
3689 [(set_attr "type" "imovx")
3690 (set_attr "mode" "DI")])
3691
3692 ;; Extend to memory case when source register does die.
3693 (define_split
3694 [(set (match_operand:DI 0 "memory_operand" "")
3695 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3696 (clobber (reg:CC FLAGS_REG))
3697 (clobber (match_operand:SI 2 "register_operand" ""))]
3698 "(reload_completed
3699 && dead_or_set_p (insn, operands[1])
3700 && !reg_mentioned_p (operands[1], operands[0]))"
3701 [(set (match_dup 3) (match_dup 1))
3702 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3703 (clobber (reg:CC FLAGS_REG))])
3704 (set (match_dup 4) (match_dup 1))]
3705 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3706
3707 ;; Extend to memory case when source register does not die.
3708 (define_split
3709 [(set (match_operand:DI 0 "memory_operand" "")
3710 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3711 (clobber (reg:CC FLAGS_REG))
3712 (clobber (match_operand:SI 2 "register_operand" ""))]
3713 "reload_completed"
3714 [(const_int 0)]
3715 {
3716 split_di (&operands[0], 1, &operands[3], &operands[4]);
3717
3718 emit_move_insn (operands[3], operands[1]);
3719
3720 /* Generate a cltd if possible and doing so it profitable. */
3721 if ((optimize_size || TARGET_USE_CLTD)
3722 && true_regnum (operands[1]) == AX_REG
3723 && true_regnum (operands[2]) == DX_REG)
3724 {
3725 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3726 }
3727 else
3728 {
3729 emit_move_insn (operands[2], operands[1]);
3730 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3731 }
3732 emit_move_insn (operands[4], operands[2]);
3733 DONE;
3734 })
3735
3736 ;; Extend to register case. Optimize case where source and destination
3737 ;; registers match and cases where we can use cltd.
3738 (define_split
3739 [(set (match_operand:DI 0 "register_operand" "")
3740 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3741 (clobber (reg:CC FLAGS_REG))
3742 (clobber (match_scratch:SI 2 ""))]
3743 "reload_completed"
3744 [(const_int 0)]
3745 {
3746 split_di (&operands[0], 1, &operands[3], &operands[4]);
3747
3748 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3749 emit_move_insn (operands[3], operands[1]);
3750
3751 /* Generate a cltd if possible and doing so it profitable. */
3752 if ((optimize_size || TARGET_USE_CLTD)
3753 && true_regnum (operands[3]) == AX_REG)
3754 {
3755 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3756 DONE;
3757 }
3758
3759 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3760 emit_move_insn (operands[4], operands[1]);
3761
3762 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3763 DONE;
3764 })
3765
3766 (define_insn "extendhisi2"
3767 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3768 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3769 ""
3770 {
3771 switch (get_attr_prefix_0f (insn))
3772 {
3773 case 0:
3774 return "{cwtl|cwde}";
3775 default:
3776 return "movs{wl|x}\t{%1,%0|%0, %1}";
3777 }
3778 }
3779 [(set_attr "type" "imovx")
3780 (set_attr "mode" "SI")
3781 (set (attr "prefix_0f")
3782 ;; movsx is short decodable while cwtl is vector decoded.
3783 (if_then_else (and (eq_attr "cpu" "!k6")
3784 (eq_attr "alternative" "0"))
3785 (const_string "0")
3786 (const_string "1")))
3787 (set (attr "modrm")
3788 (if_then_else (eq_attr "prefix_0f" "0")
3789 (const_string "0")
3790 (const_string "1")))])
3791
3792 (define_insn "*extendhisi2_zext"
3793 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3794 (zero_extend:DI
3795 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3796 "TARGET_64BIT"
3797 {
3798 switch (get_attr_prefix_0f (insn))
3799 {
3800 case 0:
3801 return "{cwtl|cwde}";
3802 default:
3803 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3804 }
3805 }
3806 [(set_attr "type" "imovx")
3807 (set_attr "mode" "SI")
3808 (set (attr "prefix_0f")
3809 ;; movsx is short decodable while cwtl is vector decoded.
3810 (if_then_else (and (eq_attr "cpu" "!k6")
3811 (eq_attr "alternative" "0"))
3812 (const_string "0")
3813 (const_string "1")))
3814 (set (attr "modrm")
3815 (if_then_else (eq_attr "prefix_0f" "0")
3816 (const_string "0")
3817 (const_string "1")))])
3818
3819 (define_insn "extendqihi2"
3820 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3821 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3822 ""
3823 {
3824 switch (get_attr_prefix_0f (insn))
3825 {
3826 case 0:
3827 return "{cbtw|cbw}";
3828 default:
3829 return "movs{bw|x}\t{%1,%0|%0, %1}";
3830 }
3831 }
3832 [(set_attr "type" "imovx")
3833 (set_attr "mode" "HI")
3834 (set (attr "prefix_0f")
3835 ;; movsx is short decodable while cwtl is vector decoded.
3836 (if_then_else (and (eq_attr "cpu" "!k6")
3837 (eq_attr "alternative" "0"))
3838 (const_string "0")
3839 (const_string "1")))
3840 (set (attr "modrm")
3841 (if_then_else (eq_attr "prefix_0f" "0")
3842 (const_string "0")
3843 (const_string "1")))])
3844
3845 (define_insn "extendqisi2"
3846 [(set (match_operand:SI 0 "register_operand" "=r")
3847 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3848 ""
3849 "movs{bl|x}\t{%1,%0|%0, %1}"
3850 [(set_attr "type" "imovx")
3851 (set_attr "mode" "SI")])
3852
3853 (define_insn "*extendqisi2_zext"
3854 [(set (match_operand:DI 0 "register_operand" "=r")
3855 (zero_extend:DI
3856 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3857 "TARGET_64BIT"
3858 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3859 [(set_attr "type" "imovx")
3860 (set_attr "mode" "SI")])
3861 \f
3862 ;; Conversions between float and double.
3863
3864 ;; These are all no-ops in the model used for the 80387. So just
3865 ;; emit moves.
3866
3867 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3868 (define_insn "*dummy_extendsfdf2"
3869 [(set (match_operand:DF 0 "push_operand" "=<")
3870 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3871 "0"
3872 "#")
3873
3874 (define_split
3875 [(set (match_operand:DF 0 "push_operand" "")
3876 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3877 "!TARGET_64BIT"
3878 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3879 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3880
3881 (define_split
3882 [(set (match_operand:DF 0 "push_operand" "")
3883 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3884 "TARGET_64BIT"
3885 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3886 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3887
3888 (define_insn "*dummy_extendsfxf2"
3889 [(set (match_operand:XF 0 "push_operand" "=<")
3890 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3891 "0"
3892 "#")
3893
3894 (define_split
3895 [(set (match_operand:XF 0 "push_operand" "")
3896 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3897 ""
3898 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3899 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3900 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3901
3902 (define_split
3903 [(set (match_operand:XF 0 "push_operand" "")
3904 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3905 "TARGET_64BIT"
3906 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3907 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3908 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3909
3910 (define_split
3911 [(set (match_operand:XF 0 "push_operand" "")
3912 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3913 ""
3914 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3915 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3916 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3917
3918 (define_split
3919 [(set (match_operand:XF 0 "push_operand" "")
3920 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3921 "TARGET_64BIT"
3922 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3923 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3924 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3925
3926 (define_expand "extendsfdf2"
3927 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3928 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3929 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3930 {
3931 /* ??? Needed for compress_float_constant since all fp constants
3932 are LEGITIMATE_CONSTANT_P. */
3933 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3934 {
3935 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3936 && standard_80387_constant_p (operands[1]) > 0)
3937 {
3938 operands[1] = simplify_const_unary_operation
3939 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3940 emit_move_insn_1 (operands[0], operands[1]);
3941 DONE;
3942 }
3943 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3944 }
3945 })
3946
3947 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3948 cvtss2sd:
3949 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3950 cvtps2pd xmm2,xmm1
3951 We do the conversion post reload to avoid producing of 128bit spills
3952 that might lead to ICE on 32bit target. The sequence unlikely combine
3953 anyway. */
3954 (define_split
3955 [(set (match_operand:DF 0 "register_operand" "")
3956 (float_extend:DF
3957 (match_operand:SF 1 "nonimmediate_operand" "")))]
3958 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
3959 && reload_completed && SSE_REG_P (operands[0])"
3960 [(set (match_dup 2)
3961 (float_extend:V2DF
3962 (vec_select:V2SF
3963 (match_dup 3)
3964 (parallel [(const_int 0) (const_int 1)]))))]
3965 {
3966 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3967 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3968 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3969 Try to avoid move when unpacking can be done in source. */
3970 if (REG_P (operands[1]))
3971 {
3972 /* If it is unsafe to overwrite upper half of source, we need
3973 to move to destination and unpack there. */
3974 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3975 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3976 && true_regnum (operands[0]) != true_regnum (operands[1]))
3977 {
3978 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3979 emit_move_insn (tmp, operands[1]);
3980 }
3981 else
3982 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3983 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3984 }
3985 else
3986 emit_insn (gen_vec_setv4sf_0 (operands[3],
3987 CONST0_RTX (V4SFmode), operands[1]));
3988 })
3989
3990 (define_insn "*extendsfdf2_mixed"
3991 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3992 (float_extend:DF
3993 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3994 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3995 {
3996 switch (which_alternative)
3997 {
3998 case 0:
3999 case 1:
4000 return output_387_reg_move (insn, operands);
4001
4002 case 2:
4003 return "cvtss2sd\t{%1, %0|%0, %1}";
4004
4005 default:
4006 gcc_unreachable ();
4007 }
4008 }
4009 [(set_attr "type" "fmov,fmov,ssecvt")
4010 (set_attr "mode" "SF,XF,DF")])
4011
4012 (define_insn "*extendsfdf2_sse"
4013 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4014 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4015 "TARGET_SSE2 && TARGET_SSE_MATH"
4016 "cvtss2sd\t{%1, %0|%0, %1}"
4017 [(set_attr "type" "ssecvt")
4018 (set_attr "mode" "DF")])
4019
4020 (define_insn "*extendsfdf2_i387"
4021 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4022 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4023 "TARGET_80387"
4024 "* return output_387_reg_move (insn, operands);"
4025 [(set_attr "type" "fmov")
4026 (set_attr "mode" "SF,XF")])
4027
4028 (define_expand "extend<mode>xf2"
4029 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4030 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4031 "TARGET_80387"
4032 {
4033 /* ??? Needed for compress_float_constant since all fp constants
4034 are LEGITIMATE_CONSTANT_P. */
4035 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4036 {
4037 if (standard_80387_constant_p (operands[1]) > 0)
4038 {
4039 operands[1] = simplify_const_unary_operation
4040 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4041 emit_move_insn_1 (operands[0], operands[1]);
4042 DONE;
4043 }
4044 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4045 }
4046 })
4047
4048 (define_insn "*extend<mode>xf2_i387"
4049 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4050 (float_extend:XF
4051 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4052 "TARGET_80387"
4053 "* return output_387_reg_move (insn, operands);"
4054 [(set_attr "type" "fmov")
4055 (set_attr "mode" "<MODE>,XF")])
4056
4057 ;; %%% This seems bad bad news.
4058 ;; This cannot output into an f-reg because there is no way to be sure
4059 ;; of truncating in that case. Otherwise this is just like a simple move
4060 ;; insn. So we pretend we can output to a reg in order to get better
4061 ;; register preferencing, but we really use a stack slot.
4062
4063 ;; Conversion from DFmode to SFmode.
4064
4065 (define_expand "truncdfsf2"
4066 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4067 (float_truncate:SF
4068 (match_operand:DF 1 "nonimmediate_operand" "")))]
4069 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4070 {
4071 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4072 ;
4073 else if (flag_unsafe_math_optimizations)
4074 ;
4075 else
4076 {
4077 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4078 rtx temp = assign_386_stack_local (SFmode, slot);
4079 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4080 DONE;
4081 }
4082 })
4083
4084 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4085 cvtsd2ss:
4086 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4087 cvtpd2ps xmm2,xmm1
4088 We do the conversion post reload to avoid producing of 128bit spills
4089 that might lead to ICE on 32bit target. The sequence unlikely combine
4090 anyway. */
4091 (define_split
4092 [(set (match_operand:SF 0 "register_operand" "")
4093 (float_truncate:SF
4094 (match_operand:DF 1 "nonimmediate_operand" "")))]
4095 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4096 && reload_completed && SSE_REG_P (operands[0])"
4097 [(set (match_dup 2)
4098 (vec_concat:V4SF
4099 (float_truncate:V2SF
4100 (match_dup 4))
4101 (match_dup 3)))]
4102 {
4103 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4104 operands[3] = CONST0_RTX (V2SFmode);
4105 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4106 /* Use movsd for loading from memory, unpcklpd for registers.
4107 Try to avoid move when unpacking can be done in source, or SSE3
4108 movddup is available. */
4109 if (REG_P (operands[1]))
4110 {
4111 if (!TARGET_SSE3
4112 && true_regnum (operands[0]) != true_regnum (operands[1])
4113 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4114 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4115 {
4116 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4117 emit_move_insn (tmp, operands[1]);
4118 operands[1] = tmp;
4119 }
4120 else if (!TARGET_SSE3)
4121 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4122 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4123 }
4124 else
4125 emit_insn (gen_sse2_loadlpd (operands[4],
4126 CONST0_RTX (V2DFmode), operands[1]));
4127 })
4128
4129 (define_expand "truncdfsf2_with_temp"
4130 [(parallel [(set (match_operand:SF 0 "" "")
4131 (float_truncate:SF (match_operand:DF 1 "" "")))
4132 (clobber (match_operand:SF 2 "" ""))])]
4133 "")
4134
4135 (define_insn "*truncdfsf_fast_mixed"
4136 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
4137 (float_truncate:SF
4138 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4139 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4140 {
4141 switch (which_alternative)
4142 {
4143 case 0:
4144 case 1:
4145 return output_387_reg_move (insn, operands);
4146 case 2:
4147 return "cvtsd2ss\t{%1, %0|%0, %1}";
4148 default:
4149 gcc_unreachable ();
4150 }
4151 }
4152 [(set_attr "type" "fmov,fmov,ssecvt")
4153 (set_attr "mode" "SF")])
4154
4155 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4156 ;; because nothing we do here is unsafe.
4157 (define_insn "*truncdfsf_fast_sse"
4158 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4159 (float_truncate:SF
4160 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4161 "TARGET_SSE2 && TARGET_SSE_MATH"
4162 "cvtsd2ss\t{%1, %0|%0, %1}"
4163 [(set_attr "type" "ssecvt")
4164 (set_attr "mode" "SF")])
4165
4166 (define_insn "*truncdfsf_fast_i387"
4167 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4168 (float_truncate:SF
4169 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4170 "TARGET_80387 && flag_unsafe_math_optimizations"
4171 "* return output_387_reg_move (insn, operands);"
4172 [(set_attr "type" "fmov")
4173 (set_attr "mode" "SF")])
4174
4175 (define_insn "*truncdfsf_mixed"
4176 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4177 (float_truncate:SF
4178 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4179 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4180 "TARGET_MIX_SSE_I387"
4181 {
4182 switch (which_alternative)
4183 {
4184 case 0:
4185 return output_387_reg_move (insn, operands);
4186
4187 case 1:
4188 return "#";
4189 case 2:
4190 return "cvtsd2ss\t{%1, %0|%0, %1}";
4191 default:
4192 gcc_unreachable ();
4193 }
4194 }
4195 [(set_attr "type" "fmov,multi,ssecvt")
4196 (set_attr "unit" "*,i387,*")
4197 (set_attr "mode" "SF")])
4198
4199 (define_insn "*truncdfsf_i387"
4200 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4201 (float_truncate:SF
4202 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4203 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4204 "TARGET_80387"
4205 {
4206 switch (which_alternative)
4207 {
4208 case 0:
4209 return output_387_reg_move (insn, operands);
4210
4211 case 1:
4212 return "#";
4213 default:
4214 gcc_unreachable ();
4215 }
4216 }
4217 [(set_attr "type" "fmov,multi")
4218 (set_attr "unit" "*,i387")
4219 (set_attr "mode" "SF")])
4220
4221 (define_insn "*truncdfsf2_i387_1"
4222 [(set (match_operand:SF 0 "memory_operand" "=m")
4223 (float_truncate:SF
4224 (match_operand:DF 1 "register_operand" "f")))]
4225 "TARGET_80387
4226 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4227 && !TARGET_MIX_SSE_I387"
4228 "* return output_387_reg_move (insn, operands);"
4229 [(set_attr "type" "fmov")
4230 (set_attr "mode" "SF")])
4231
4232 (define_split
4233 [(set (match_operand:SF 0 "register_operand" "")
4234 (float_truncate:SF
4235 (match_operand:DF 1 "fp_register_operand" "")))
4236 (clobber (match_operand 2 "" ""))]
4237 "reload_completed"
4238 [(set (match_dup 2) (match_dup 1))
4239 (set (match_dup 0) (match_dup 2))]
4240 {
4241 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4242 })
4243
4244 ;; Conversion from XFmode to {SF,DF}mode
4245
4246 (define_expand "truncxf<mode>2"
4247 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4248 (float_truncate:MODEF
4249 (match_operand:XF 1 "register_operand" "")))
4250 (clobber (match_dup 2))])]
4251 "TARGET_80387"
4252 {
4253 if (flag_unsafe_math_optimizations)
4254 {
4255 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4256 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4257 if (reg != operands[0])
4258 emit_move_insn (operands[0], reg);
4259 DONE;
4260 }
4261 else
4262 {
4263 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4264 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4265 }
4266 })
4267
4268 (define_insn "*truncxfsf2_mixed"
4269 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4270 (float_truncate:SF
4271 (match_operand:XF 1 "register_operand" "f,f")))
4272 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4273 "TARGET_80387"
4274 {
4275 gcc_assert (!which_alternative);
4276 return output_387_reg_move (insn, operands);
4277 }
4278 [(set_attr "type" "fmov,multi")
4279 (set_attr "unit" "*,i387")
4280 (set_attr "mode" "SF")])
4281
4282 (define_insn "*truncxfdf2_mixed"
4283 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4284 (float_truncate:DF
4285 (match_operand:XF 1 "register_operand" "f,f")))
4286 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4287 "TARGET_80387"
4288 {
4289 gcc_assert (!which_alternative);
4290 return output_387_reg_move (insn, operands);
4291 }
4292 [(set_attr "type" "fmov,multi")
4293 (set_attr "unit" "*,i387")
4294 (set_attr "mode" "DF")])
4295
4296 (define_insn "truncxf<mode>2_i387_noop"
4297 [(set (match_operand:MODEF 0 "register_operand" "=f")
4298 (float_truncate:MODEF
4299 (match_operand:XF 1 "register_operand" "f")))]
4300 "TARGET_80387 && flag_unsafe_math_optimizations"
4301 "* return output_387_reg_move (insn, operands);"
4302 [(set_attr "type" "fmov")
4303 (set_attr "mode" "<MODE>")])
4304
4305 (define_insn "*truncxf<mode>2_i387"
4306 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4307 (float_truncate:MODEF
4308 (match_operand:XF 1 "register_operand" "f")))]
4309 "TARGET_80387"
4310 "* return output_387_reg_move (insn, operands);"
4311 [(set_attr "type" "fmov")
4312 (set_attr "mode" "<MODE>")])
4313
4314 (define_split
4315 [(set (match_operand:MODEF 0 "register_operand" "")
4316 (float_truncate:MODEF
4317 (match_operand:XF 1 "register_operand" "")))
4318 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4319 "TARGET_80387 && reload_completed"
4320 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4321 (set (match_dup 0) (match_dup 2))]
4322 "")
4323
4324 (define_split
4325 [(set (match_operand:MODEF 0 "memory_operand" "")
4326 (float_truncate:MODEF
4327 (match_operand:XF 1 "register_operand" "")))
4328 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4329 "TARGET_80387"
4330 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4331 "")
4332 \f
4333 ;; Signed conversion to DImode.
4334
4335 (define_expand "fix_truncxfdi2"
4336 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4337 (fix:DI (match_operand:XF 1 "register_operand" "")))
4338 (clobber (reg:CC FLAGS_REG))])]
4339 "TARGET_80387"
4340 {
4341 if (TARGET_FISTTP)
4342 {
4343 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4344 DONE;
4345 }
4346 })
4347
4348 (define_expand "fix_trunc<mode>di2"
4349 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4350 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4351 (clobber (reg:CC FLAGS_REG))])]
4352 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4353 {
4354 if (TARGET_FISTTP
4355 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4356 {
4357 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4358 DONE;
4359 }
4360 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4361 {
4362 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4363 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4364 if (out != operands[0])
4365 emit_move_insn (operands[0], out);
4366 DONE;
4367 }
4368 })
4369
4370 ;; Signed conversion to SImode.
4371
4372 (define_expand "fix_truncxfsi2"
4373 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4374 (fix:SI (match_operand:XF 1 "register_operand" "")))
4375 (clobber (reg:CC FLAGS_REG))])]
4376 "TARGET_80387"
4377 {
4378 if (TARGET_FISTTP)
4379 {
4380 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4381 DONE;
4382 }
4383 })
4384
4385 (define_expand "fix_trunc<mode>si2"
4386 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4387 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4388 (clobber (reg:CC FLAGS_REG))])]
4389 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4390 {
4391 if (TARGET_FISTTP
4392 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4393 {
4394 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4395 DONE;
4396 }
4397 if (SSE_FLOAT_MODE_P (<MODE>mode))
4398 {
4399 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4400 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4401 if (out != operands[0])
4402 emit_move_insn (operands[0], out);
4403 DONE;
4404 }
4405 })
4406
4407 ;; Signed conversion to HImode.
4408
4409 (define_expand "fix_trunc<mode>hi2"
4410 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4411 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4412 (clobber (reg:CC FLAGS_REG))])]
4413 "TARGET_80387
4414 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4415 {
4416 if (TARGET_FISTTP)
4417 {
4418 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4419 DONE;
4420 }
4421 })
4422
4423 ;; Unsigned conversion to SImode.
4424
4425 (define_expand "fixuns_trunc<mode>si2"
4426 [(parallel
4427 [(set (match_operand:SI 0 "register_operand" "")
4428 (unsigned_fix:SI
4429 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4430 (use (match_dup 2))
4431 (clobber (match_scratch:<ssevecmode> 3 ""))
4432 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4433 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4434 {
4435 enum machine_mode mode = <MODE>mode;
4436 enum machine_mode vecmode = <ssevecmode>mode;
4437 REAL_VALUE_TYPE TWO31r;
4438 rtx two31;
4439
4440 real_ldexp (&TWO31r, &dconst1, 31);
4441 two31 = const_double_from_real_value (TWO31r, mode);
4442 two31 = ix86_build_const_vector (mode, true, two31);
4443 operands[2] = force_reg (vecmode, two31);
4444 })
4445
4446 (define_insn_and_split "*fixuns_trunc<mode>_1"
4447 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4448 (unsigned_fix:SI
4449 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4450 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4451 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4452 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4453 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4454 "#"
4455 "&& reload_completed"
4456 [(const_int 0)]
4457 {
4458 ix86_split_convert_uns_si_sse (operands);
4459 DONE;
4460 })
4461
4462 ;; Unsigned conversion to HImode.
4463 ;; Without these patterns, we'll try the unsigned SI conversion which
4464 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4465
4466 (define_expand "fixuns_trunc<mode>hi2"
4467 [(set (match_dup 2)
4468 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4469 (set (match_operand:HI 0 "nonimmediate_operand" "")
4470 (subreg:HI (match_dup 2) 0))]
4471 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4472 "operands[2] = gen_reg_rtx (SImode);")
4473
4474 ;; When SSE is available, it is always faster to use it!
4475 (define_insn "fix_trunc<mode>di_sse"
4476 [(set (match_operand:DI 0 "register_operand" "=r,r")
4477 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4478 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4479 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4480 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4481 [(set_attr "type" "sseicvt")
4482 (set_attr "mode" "<MODE>")
4483 (set_attr "athlon_decode" "double,vector")
4484 (set_attr "amdfam10_decode" "double,double")])
4485
4486 (define_insn "fix_trunc<mode>si_sse"
4487 [(set (match_operand:SI 0 "register_operand" "=r,r")
4488 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4489 "SSE_FLOAT_MODE_P (<MODE>mode)
4490 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4491 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4492 [(set_attr "type" "sseicvt")
4493 (set_attr "mode" "<MODE>")
4494 (set_attr "athlon_decode" "double,vector")
4495 (set_attr "amdfam10_decode" "double,double")])
4496
4497 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4498 (define_peephole2
4499 [(set (match_operand:MODEF 0 "register_operand" "")
4500 (match_operand:MODEF 1 "memory_operand" ""))
4501 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4502 (fix:SSEMODEI24 (match_dup 0)))]
4503 "TARGET_SHORTEN_X87_SSE
4504 && peep2_reg_dead_p (2, operands[0])"
4505 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4506 "")
4507
4508 ;; Avoid vector decoded forms of the instruction.
4509 (define_peephole2
4510 [(match_scratch:DF 2 "Y2")
4511 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4512 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4513 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4514 [(set (match_dup 2) (match_dup 1))
4515 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4516 "")
4517
4518 (define_peephole2
4519 [(match_scratch:SF 2 "x")
4520 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4521 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4522 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4523 [(set (match_dup 2) (match_dup 1))
4524 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4525 "")
4526
4527 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4528 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4529 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4530 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4531 && TARGET_FISTTP
4532 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && (TARGET_64BIT || <MODE>mode != DImode))
4534 && TARGET_SSE_MATH)
4535 && !(reload_completed || reload_in_progress)"
4536 "#"
4537 "&& 1"
4538 [(const_int 0)]
4539 {
4540 if (memory_operand (operands[0], VOIDmode))
4541 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4542 else
4543 {
4544 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4545 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4546 operands[1],
4547 operands[2]));
4548 }
4549 DONE;
4550 }
4551 [(set_attr "type" "fisttp")
4552 (set_attr "mode" "<MODE>")])
4553
4554 (define_insn "fix_trunc<mode>_i387_fisttp"
4555 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4556 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4557 (clobber (match_scratch:XF 2 "=&1f"))]
4558 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4559 && TARGET_FISTTP
4560 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4561 && (TARGET_64BIT || <MODE>mode != DImode))
4562 && TARGET_SSE_MATH)"
4563 "* return output_fix_trunc (insn, operands, 1);"
4564 [(set_attr "type" "fisttp")
4565 (set_attr "mode" "<MODE>")])
4566
4567 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4568 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4569 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4570 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4571 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4572 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4573 && TARGET_FISTTP
4574 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4575 && (TARGET_64BIT || <MODE>mode != DImode))
4576 && TARGET_SSE_MATH)"
4577 "#"
4578 [(set_attr "type" "fisttp")
4579 (set_attr "mode" "<MODE>")])
4580
4581 (define_split
4582 [(set (match_operand:X87MODEI 0 "register_operand" "")
4583 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4584 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4585 (clobber (match_scratch 3 ""))]
4586 "reload_completed"
4587 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4588 (clobber (match_dup 3))])
4589 (set (match_dup 0) (match_dup 2))]
4590 "")
4591
4592 (define_split
4593 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4594 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4595 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4596 (clobber (match_scratch 3 ""))]
4597 "reload_completed"
4598 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4599 (clobber (match_dup 3))])]
4600 "")
4601
4602 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4603 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4604 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4605 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4606 ;; function in i386.c.
4607 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4608 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4609 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4610 (clobber (reg:CC FLAGS_REG))]
4611 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4612 && !TARGET_FISTTP
4613 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4614 && (TARGET_64BIT || <MODE>mode != DImode))
4615 && !(reload_completed || reload_in_progress)"
4616 "#"
4617 "&& 1"
4618 [(const_int 0)]
4619 {
4620 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4621
4622 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4623 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4624 if (memory_operand (operands[0], VOIDmode))
4625 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4626 operands[2], operands[3]));
4627 else
4628 {
4629 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4630 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4631 operands[2], operands[3],
4632 operands[4]));
4633 }
4634 DONE;
4635 }
4636 [(set_attr "type" "fistp")
4637 (set_attr "i387_cw" "trunc")
4638 (set_attr "mode" "<MODE>")])
4639
4640 (define_insn "fix_truncdi_i387"
4641 [(set (match_operand:DI 0 "memory_operand" "=m")
4642 (fix:DI (match_operand 1 "register_operand" "f")))
4643 (use (match_operand:HI 2 "memory_operand" "m"))
4644 (use (match_operand:HI 3 "memory_operand" "m"))
4645 (clobber (match_scratch:XF 4 "=&1f"))]
4646 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4647 && !TARGET_FISTTP
4648 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4649 "* return output_fix_trunc (insn, operands, 0);"
4650 [(set_attr "type" "fistp")
4651 (set_attr "i387_cw" "trunc")
4652 (set_attr "mode" "DI")])
4653
4654 (define_insn "fix_truncdi_i387_with_temp"
4655 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4656 (fix:DI (match_operand 1 "register_operand" "f,f")))
4657 (use (match_operand:HI 2 "memory_operand" "m,m"))
4658 (use (match_operand:HI 3 "memory_operand" "m,m"))
4659 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4660 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4661 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4662 && !TARGET_FISTTP
4663 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4664 "#"
4665 [(set_attr "type" "fistp")
4666 (set_attr "i387_cw" "trunc")
4667 (set_attr "mode" "DI")])
4668
4669 (define_split
4670 [(set (match_operand:DI 0 "register_operand" "")
4671 (fix:DI (match_operand 1 "register_operand" "")))
4672 (use (match_operand:HI 2 "memory_operand" ""))
4673 (use (match_operand:HI 3 "memory_operand" ""))
4674 (clobber (match_operand:DI 4 "memory_operand" ""))
4675 (clobber (match_scratch 5 ""))]
4676 "reload_completed"
4677 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4678 (use (match_dup 2))
4679 (use (match_dup 3))
4680 (clobber (match_dup 5))])
4681 (set (match_dup 0) (match_dup 4))]
4682 "")
4683
4684 (define_split
4685 [(set (match_operand:DI 0 "memory_operand" "")
4686 (fix:DI (match_operand 1 "register_operand" "")))
4687 (use (match_operand:HI 2 "memory_operand" ""))
4688 (use (match_operand:HI 3 "memory_operand" ""))
4689 (clobber (match_operand:DI 4 "memory_operand" ""))
4690 (clobber (match_scratch 5 ""))]
4691 "reload_completed"
4692 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4693 (use (match_dup 2))
4694 (use (match_dup 3))
4695 (clobber (match_dup 5))])]
4696 "")
4697
4698 (define_insn "fix_trunc<mode>_i387"
4699 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4700 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4701 (use (match_operand:HI 2 "memory_operand" "m"))
4702 (use (match_operand:HI 3 "memory_operand" "m"))]
4703 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4704 && !TARGET_FISTTP
4705 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4706 "* return output_fix_trunc (insn, operands, 0);"
4707 [(set_attr "type" "fistp")
4708 (set_attr "i387_cw" "trunc")
4709 (set_attr "mode" "<MODE>")])
4710
4711 (define_insn "fix_trunc<mode>_i387_with_temp"
4712 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4713 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4714 (use (match_operand:HI 2 "memory_operand" "m,m"))
4715 (use (match_operand:HI 3 "memory_operand" "m,m"))
4716 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4717 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4718 && !TARGET_FISTTP
4719 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4720 "#"
4721 [(set_attr "type" "fistp")
4722 (set_attr "i387_cw" "trunc")
4723 (set_attr "mode" "<MODE>")])
4724
4725 (define_split
4726 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4727 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4728 (use (match_operand:HI 2 "memory_operand" ""))
4729 (use (match_operand:HI 3 "memory_operand" ""))
4730 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4731 "reload_completed"
4732 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4733 (use (match_dup 2))
4734 (use (match_dup 3))])
4735 (set (match_dup 0) (match_dup 4))]
4736 "")
4737
4738 (define_split
4739 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4740 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4741 (use (match_operand:HI 2 "memory_operand" ""))
4742 (use (match_operand:HI 3 "memory_operand" ""))
4743 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4744 "reload_completed"
4745 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4746 (use (match_dup 2))
4747 (use (match_dup 3))])]
4748 "")
4749
4750 (define_insn "x86_fnstcw_1"
4751 [(set (match_operand:HI 0 "memory_operand" "=m")
4752 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4753 "TARGET_80387"
4754 "fnstcw\t%0"
4755 [(set_attr "length" "2")
4756 (set_attr "mode" "HI")
4757 (set_attr "unit" "i387")])
4758
4759 (define_insn "x86_fldcw_1"
4760 [(set (reg:HI FPCR_REG)
4761 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4762 "TARGET_80387"
4763 "fldcw\t%0"
4764 [(set_attr "length" "2")
4765 (set_attr "mode" "HI")
4766 (set_attr "unit" "i387")
4767 (set_attr "athlon_decode" "vector")
4768 (set_attr "amdfam10_decode" "vector")])
4769 \f
4770 ;; Conversion between fixed point and floating point.
4771
4772 ;; Even though we only accept memory inputs, the backend _really_
4773 ;; wants to be able to do this between registers.
4774
4775 (define_expand "floathi<mode>2"
4776 [(set (match_operand:MODEF 0 "register_operand" "")
4777 (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4778 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4779 {
4780 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4781 {
4782 emit_insn
4783 (gen_floatsi<mode>2 (operands[0],
4784 convert_to_mode (SImode, operands[1], 0)));
4785 DONE;
4786 }
4787 })
4788
4789 (define_insn "*floathi<mode>2_i387"
4790 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4791 (float:MODEF
4792 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4793 "TARGET_80387
4794 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4795 || TARGET_MIX_SSE_I387)"
4796 "@
4797 fild%z1\t%1
4798 #"
4799 [(set_attr "type" "fmov,multi")
4800 (set_attr "mode" "<MODE>")
4801 (set_attr "unit" "*,i387")
4802 (set_attr "fp_int_src" "true")])
4803
4804 (define_expand "floatsi<mode>2"
4805 [(set (match_operand:MODEF 0 "register_operand" "")
4806 (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4807 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4808 "
4809 /* When we use vector converts, we can't have input in memory. */
4810 if (GET_MODE (operands[0]) == DFmode
4811 && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4812 && SSE_FLOAT_MODE_P (DFmode))
4813 operands[1] = force_reg (SImode, operands[1]);
4814 else if (GET_MODE (operands[0]) == SFmode
4815 && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4816 && SSE_FLOAT_MODE_P (SFmode))
4817 {
4818 /* When !flag_trapping_math, we handle SImode->SFmode vector
4819 conversions same way as SImode->DFmode.
4820
4821 For flat_trapping_math we can't safely use vector conversion without
4822 clearing upper half, otherwise precision exception might occur.
4823 However we can still generate the common sequence converting value
4824 from general register to XMM register as:
4825
4826 mov reg32, mem32
4827 movd mem32, xmm
4828 cvtdq2pd xmm,xmm
4829
4830 because we know that movd clears the upper half.
4831
4832 Sadly in this case we can't rely on reload moving the value to XMM
4833 register, since we need to know if upper half is OK, so we need
4834 to do reloading by hand. We force operand to memory unless target
4835 supports inter unit moves. */
4836 if (!flag_trapping_math)
4837 operands[1] = force_reg (SImode, operands[1]);
4838 else if (!MEM_P (operands[1]))
4839 {
4840 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4841 rtx tmp = assign_386_stack_local (SImode, slot);
4842 emit_move_insn (tmp, operands[1]);
4843 operands[1] = tmp;
4844 }
4845 }
4846 /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4847 !TARGET_INTER_UNIT_CONVERSIONS
4848 It is necessary for the patterns to not accept nonmemory operands
4849 as we would optimize out later. */
4850 else if (!TARGET_INTER_UNIT_CONVERSIONS
4851 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4852 && !optimize_size
4853 && !MEM_P (operands[1]))
4854 {
4855 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4856 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
4857 emit_move_insn (tmp, operands[1]);
4858 operands[1] = tmp;
4859 }
4860 ")
4861
4862 (define_insn "*floatsisf2_mixed_vector"
4863 [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4864 (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4865 "TARGET_MIX_SSE_I387 && !flag_trapping_math
4866 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4867 "@
4868 cvtdq2ps\t{%1, %0|%0, %1}
4869 fild%z1\t%1
4870 #"
4871 [(set_attr "type" "sseicvt,fmov,multi")
4872 (set_attr "mode" "SF")
4873 (set_attr "unit" "*,i387,*")
4874 (set_attr "athlon_decode" "double,*,*")
4875 (set_attr "amdfam10_decode" "double,*,*")
4876 (set_attr "fp_int_src" "false,true,true")])
4877
4878 (define_insn "*floatsisf2_mixed"
4879 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4880 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4881 "TARGET_MIX_SSE_I387
4882 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4883 || optimize_size)"
4884 "@
4885 fild%z1\t%1
4886 #
4887 cvtsi2ss\t{%1, %0|%0, %1}
4888 cvtsi2ss\t{%1, %0|%0, %1}"
4889 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4890 (set_attr "mode" "SF")
4891 (set_attr "unit" "*,i387,*,*")
4892 (set_attr "athlon_decode" "*,*,vector,double")
4893 (set_attr "amdfam10_decode" "*,*,vector,double")
4894 (set_attr "fp_int_src" "true")])
4895
4896 (define_insn "*floatsisf2_mixed_memory"
4897 [(set (match_operand:SF 0 "register_operand" "=f,x")
4898 (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4899 "TARGET_MIX_SSE_I387
4900 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4901 "@
4902 fild%z1\t%1
4903 cvtsi2ss\t{%1, %0|%0, %1}"
4904 [(set_attr "type" "fmov,sseicvt")
4905 (set_attr "mode" "SF")
4906 (set_attr "athlon_decode" "*,double")
4907 (set_attr "amdfam10_decode" "*,double")
4908 (set_attr "fp_int_src" "true")])
4909
4910 (define_insn "*floatsisf2_sse_vector_nointernunit"
4911 [(set (match_operand:SF 0 "register_operand" "=x")
4912 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4913 "TARGET_SSE_MATH && flag_trapping_math
4914 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4915 && !TARGET_INTER_UNIT_MOVES"
4916 "#"
4917 [(set_attr "type" "multi")])
4918
4919 (define_insn "*floatsisf2_sse_vector_internunit"
4920 [(set (match_operand:SF 0 "register_operand" "=x,x")
4921 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4922 "TARGET_SSE_MATH && flag_trapping_math
4923 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4924 && TARGET_INTER_UNIT_MOVES"
4925 "#"
4926 [(set_attr "type" "multi")])
4927
4928 (define_split
4929 [(set (match_operand:SF 0 "register_operand" "")
4930 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4931 "flag_trapping_math
4932 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4933 && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4934 && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4935 [(set (match_dup 0)
4936 (float:V4SF (match_dup 2)))]
4937 {
4938 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4939 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4940 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4941 })
4942
4943 (define_split
4944 [(set (match_operand:SF 0 "register_operand" "")
4945 (float:SF (match_operand:SI 1 "register_operand" "")))]
4946 "flag_trapping_math
4947 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4948 && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4949 [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4950 (set (match_dup 0)
4951 (float:V4SF (match_dup 2)))]
4952 {
4953 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4954 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4955 })
4956
4957 (define_insn "*floatsisf2_sse_vector"
4958 [(set (match_operand:SF 0 "register_operand" "=x")
4959 (float:SF (match_operand:SI 1 "register_operand" "x")))]
4960 "TARGET_SSE_MATH && !flag_trapping_math
4961 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4962 && !TARGET_INTER_UNIT_MOVES"
4963 "cvtdq2ps\t{%1, %0|%0, %1}"
4964 [(set_attr "type" "sseicvt")
4965 (set_attr "mode" "SF")
4966 (set_attr "athlon_decode" "double")
4967 (set_attr "amdfam10_decode" "double")
4968 (set_attr "fp_int_src" "true")])
4969
4970 (define_insn "*floatsisf2_sse"
4971 [(set (match_operand:SF 0 "register_operand" "=x,x")
4972 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4973 "TARGET_SSE_MATH
4974 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4975 || optimize_size)"
4976 "cvtsi2ss\t{%1, %0|%0, %1}"
4977 [(set_attr "type" "sseicvt")
4978 (set_attr "mode" "SF")
4979 (set_attr "athlon_decode" "vector,double")
4980 (set_attr "amdfam10_decode" "vector,double")
4981 (set_attr "fp_int_src" "true")])
4982
4983 (define_insn "*floatsisf2_sse_memory"
4984 [(set (match_operand:SF 0 "register_operand" "=x")
4985 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4986 "TARGET_SSE_MATH
4987 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4988 "cvtsi2ss\t{%1, %0|%0, %1}"
4989 [(set_attr "type" "sseicvt")
4990 (set_attr "mode" "SF")
4991 (set_attr "athlon_decode" "double")
4992 (set_attr "amdfam10_decode" "double")
4993 (set_attr "fp_int_src" "true")])
4994
4995 (define_insn "*floatsidf2_mixed_vector"
4996 [(set (match_operand:DF 0 "register_operand" "=x,f,f")
4997 (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4998 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4999 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5000 "@
5001 cvtdq2pd\t{%1, %0|%0, %1}
5002 fild%z1\t%1
5003 #"
5004 [(set_attr "type" "sseicvt,fmov,multi")
5005 (set_attr "mode" "V2DF,DF,DF")
5006 (set_attr "unit" "*,*,i387")
5007 (set_attr "athlon_decode" "double,*,*")
5008 (set_attr "amdfam10_decode" "double,*,*")
5009 (set_attr "fp_int_src" "false,true,true")])
5010
5011 (define_insn "*floatsidf2_mixed"
5012 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
5013 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
5014 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5015 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5016 || optimize_size)"
5017 "@
5018 fild%z1\t%1
5019 #
5020 cvtsi2sd\t{%1, %0|%0, %1}
5021 cvtsi2sd\t{%1, %0|%0, %1}
5022 cvtdq2pd\t{%1, %0|%0, %1}"
5023 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5024 (set_attr "mode" "DF,DF,DF,DF,V2DF")
5025 (set_attr "unit" "*,i387,*,*,*")
5026 (set_attr "athlon_decode" "*,*,double,direct,double")
5027 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5028 (set_attr "fp_int_src" "true,true,true,true,false")])
5029
5030 (define_insn "*floatsidf2_mixed_memory"
5031 [(set (match_operand:DF 0 "register_operand" "=f,x")
5032 (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
5033 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5034 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5035 "@
5036 fild%z1\t%1
5037 cvtsi2sd\t{%1, %0|%0, %1}"
5038 [(set_attr "type" "fmov,sseicvt")
5039 (set_attr "mode" "DF")
5040 (set_attr "athlon_decode" "*,direct")
5041 (set_attr "amdfam10_decode" "*,double")
5042 (set_attr "fp_int_src" "true")])
5043
5044 (define_insn "*floatsidf2_sse_vector"
5045 [(set (match_operand:DF 0 "register_operand" "=x")
5046 (float:DF (match_operand:SI 1 "register_operand" "x")))]
5047 "TARGET_SSE2 && TARGET_SSE_MATH
5048 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5049 "cvtdq2pd\t{%1, %0|%0, %1}"
5050 [(set_attr "type" "sseicvt")
5051 (set_attr "mode" "V2DF")
5052 (set_attr "athlon_decode" "double")
5053 (set_attr "amdfam10_decode" "double")
5054 (set_attr "fp_int_src" "true")])
5055
5056 (define_split
5057 [(set (match_operand:DF 0 "register_operand" "")
5058 (float:DF (match_operand:SI 1 "memory_operand" "")))]
5059 "TARGET_USE_VECTOR_CONVERTS && reload_completed
5060 && SSE_REG_P (operands[0])"
5061 [(set (match_dup 0)
5062 (float:V2DF
5063 (vec_select:V2SI
5064 (match_dup 2)
5065 (parallel [(const_int 0) (const_int 1)]))))]
5066 {
5067 operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5068 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5069 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5070 })
5071
5072 (define_insn "*floatsidf2_sse"
5073 [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5074 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5075 "TARGET_SSE2 && TARGET_SSE_MATH
5076 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5077 || optimize_size)"
5078 "@
5079 cvtsi2sd\t{%1, %0|%0, %1}
5080 cvtsi2sd\t{%1, %0|%0, %1}
5081 cvtdq2pd\t{%1, %0|%0, %1}"
5082 [(set_attr "type" "sseicvt")
5083 (set_attr "mode" "DF,DF,V2DF")
5084 (set_attr "athlon_decode" "double,direct,double")
5085 (set_attr "amdfam10_decode" "vector,double,double")
5086 (set_attr "fp_int_src" "true")])
5087
5088 (define_insn "*floatsidf2_memory"
5089 [(set (match_operand:DF 0 "register_operand" "=x")
5090 (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5091 "TARGET_SSE2 && TARGET_SSE_MATH
5092 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5093 || optimize_size)"
5094 "cvtsi2sd\t{%1, %0|%0, %1}"
5095 [(set_attr "type" "sseicvt")
5096 (set_attr "mode" "DF")
5097 (set_attr "athlon_decode" "direct")
5098 (set_attr "amdfam10_decode" "double")
5099 (set_attr "fp_int_src" "true")])
5100
5101 (define_insn "*floatsi<mode>2_i387"
5102 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5103 (float:MODEF
5104 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5105 "TARGET_80387
5106 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5107 "@
5108 fild%z1\t%1
5109 #"
5110 [(set_attr "type" "fmov,multi")
5111 (set_attr "mode" "<MODE>")
5112 (set_attr "unit" "*,i387")
5113 (set_attr "fp_int_src" "true")])
5114
5115 (define_expand "floatdisf2"
5116 [(set (match_operand:SF 0 "register_operand" "")
5117 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5118 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5119 {
5120 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5121 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5122 && !optimize_size
5123 && !MEM_P (operands[1]))
5124 {
5125 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5126 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5127 emit_move_insn (tmp, operands[1]);
5128 operands[1] = tmp;
5129 }
5130 })
5131
5132 (define_insn "*floatdisf2_mixed"
5133 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5134 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5135 "TARGET_64BIT && TARGET_MIX_SSE_I387
5136 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5137 "@
5138 fild%z1\t%1
5139 #
5140 cvtsi2ss{q}\t{%1, %0|%0, %1}
5141 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5142 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5143 (set_attr "mode" "SF")
5144 (set_attr "unit" "*,i387,*,*")
5145 (set_attr "athlon_decode" "*,*,vector,double")
5146 (set_attr "amdfam10_decode" "*,*,vector,double")
5147 (set_attr "fp_int_src" "true")])
5148
5149 (define_insn "*floatdisf2_mixed"
5150 [(set (match_operand:SF 0 "register_operand" "=f,x")
5151 (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5152 "TARGET_64BIT && TARGET_MIX_SSE_I387
5153 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5154 "@
5155 fild%z1\t%1
5156 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5157 [(set_attr "type" "fmov,sseicvt")
5158 (set_attr "mode" "SF")
5159 (set_attr "athlon_decode" "*,double")
5160 (set_attr "amdfam10_decode" "*,double")
5161 (set_attr "fp_int_src" "true")])
5162
5163 (define_insn "*floatdisf2_sse"
5164 [(set (match_operand:SF 0 "register_operand" "=x,x")
5165 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5166 "TARGET_64BIT && TARGET_SSE_MATH
5167 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5168 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5169 [(set_attr "type" "sseicvt")
5170 (set_attr "mode" "SF")
5171 (set_attr "athlon_decode" "vector,double")
5172 (set_attr "amdfam10_decode" "vector,double")
5173 (set_attr "fp_int_src" "true")])
5174
5175 (define_insn "*floatdisf2_memory"
5176 [(set (match_operand:SF 0 "register_operand" "=x")
5177 (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5178 "TARGET_64BIT && TARGET_SSE_MATH
5179 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5180 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5181 [(set_attr "type" "sseicvt")
5182 (set_attr "mode" "SF")
5183 (set_attr "athlon_decode" "double")
5184 (set_attr "amdfam10_decode" "double")
5185 (set_attr "fp_int_src" "true")])
5186
5187 (define_expand "floatdidf2"
5188 [(set (match_operand:DF 0 "register_operand" "")
5189 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5190 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5191 {
5192 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5193 {
5194 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5195 DONE;
5196 }
5197 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5198 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5199 && !optimize_size
5200 && !MEM_P (operands[1]))
5201 {
5202 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5203 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5204 emit_move_insn (tmp, operands[1]);
5205 operands[1] = tmp;
5206 }
5207 })
5208
5209 (define_insn "*floatdidf2_mixed"
5210 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5211 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5212 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5213 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5214 "@
5215 fild%z1\t%1
5216 #
5217 cvtsi2sd{q}\t{%1, %0|%0, %1}
5218 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5219 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5220 (set_attr "mode" "DF")
5221 (set_attr "unit" "*,i387,*,*")
5222 (set_attr "athlon_decode" "*,*,double,direct")
5223 (set_attr "amdfam10_decode" "*,*,vector,double")
5224 (set_attr "fp_int_src" "true")])
5225
5226 (define_insn "*floatdidf2_mixed_memory"
5227 [(set (match_operand:DF 0 "register_operand" "=f,x")
5228 (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5229 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5230 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5231 "@
5232 fild%z1\t%1
5233 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5234 [(set_attr "type" "fmov,sseicvt")
5235 (set_attr "mode" "DF")
5236 (set_attr "athlon_decode" "*,direct")
5237 (set_attr "amdfam10_decode" "*,double")
5238 (set_attr "fp_int_src" "true")])
5239
5240 (define_insn "*floatdidf2_sse"
5241 [(set (match_operand:DF 0 "register_operand" "=x,x")
5242 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5243 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5244 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5245 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5246 [(set_attr "type" "sseicvt")
5247 (set_attr "mode" "DF")
5248 (set_attr "athlon_decode" "double,direct")
5249 (set_attr "amdfam10_decode" "vector,double")
5250 (set_attr "fp_int_src" "true")])
5251
5252 (define_insn "*floatdidf2_sse_memory"
5253 [(set (match_operand:DF 0 "register_operand" "=x")
5254 (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5255 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5256 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5257 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5258 [(set_attr "type" "sseicvt")
5259 (set_attr "mode" "DF")
5260 (set_attr "athlon_decode" "direct")
5261 (set_attr "amdfam10_decode" "double")
5262 (set_attr "fp_int_src" "true")])
5263
5264 (define_insn "*floatdi<mode>2_i387"
5265 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5266 (float:MODEF
5267 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5268 "TARGET_80387
5269 && (!TARGET_SSE_MATH || !TARGET_64BIT
5270 || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5271 "@
5272 fild%z1\t%1
5273 #"
5274 [(set_attr "type" "fmov,multi")
5275 (set_attr "mode" "<MODE>")
5276 (set_attr "unit" "*,i387")
5277 (set_attr "fp_int_src" "true")])
5278
5279 (define_insn "float<mode>xf2"
5280 [(set (match_operand:XF 0 "register_operand" "=f,f")
5281 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5282 "TARGET_80387"
5283 "@
5284 fild%z1\t%1
5285 #"
5286 [(set_attr "type" "fmov,multi")
5287 (set_attr "mode" "XF")
5288 (set_attr "unit" "*,i387")
5289 (set_attr "fp_int_src" "true")])
5290
5291 ;; %%% Kill these when reload knows how to do it.
5292 (define_split
5293 [(set (match_operand 0 "fp_register_operand" "")
5294 (float (match_operand 1 "register_operand" "")))]
5295 "reload_completed
5296 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5297 [(const_int 0)]
5298 {
5299 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5300 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5301 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5302 ix86_free_from_memory (GET_MODE (operands[1]));
5303 DONE;
5304 })
5305
5306 (define_expand "floatunssisf2"
5307 [(use (match_operand:SF 0 "register_operand" ""))
5308 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5309 "!TARGET_64BIT"
5310 {
5311 if (TARGET_SSE_MATH && TARGET_SSE2)
5312 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5313 else
5314 x86_emit_floatuns (operands);
5315 DONE;
5316 })
5317
5318 (define_expand "floatunssidf2"
5319 [(use (match_operand:DF 0 "register_operand" ""))
5320 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5321 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5322 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5323
5324 (define_expand "floatunsdisf2"
5325 [(use (match_operand:SF 0 "register_operand" ""))
5326 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5327 "TARGET_64BIT && TARGET_SSE_MATH"
5328 "x86_emit_floatuns (operands); DONE;")
5329
5330 (define_expand "floatunsdidf2"
5331 [(use (match_operand:DF 0 "register_operand" ""))
5332 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5333 "TARGET_SSE_MATH && TARGET_SSE2
5334 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5335 {
5336 if (TARGET_64BIT)
5337 x86_emit_floatuns (operands);
5338 else
5339 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5340 DONE;
5341 })
5342 \f
5343 ;; Add instructions
5344
5345 ;; %%% splits for addditi3
5346
5347 (define_expand "addti3"
5348 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5349 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5350 (match_operand:TI 2 "x86_64_general_operand" "")))
5351 (clobber (reg:CC FLAGS_REG))]
5352 "TARGET_64BIT"
5353 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5354
5355 (define_insn "*addti3_1"
5356 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5357 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5358 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5359 (clobber (reg:CC FLAGS_REG))]
5360 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5361 "#")
5362
5363 (define_split
5364 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5365 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5366 (match_operand:TI 2 "x86_64_general_operand" "")))
5367 (clobber (reg:CC FLAGS_REG))]
5368 "TARGET_64BIT && reload_completed"
5369 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5370 UNSPEC_ADD_CARRY))
5371 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5372 (parallel [(set (match_dup 3)
5373 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5374 (match_dup 4))
5375 (match_dup 5)))
5376 (clobber (reg:CC FLAGS_REG))])]
5377 "split_ti (operands+0, 1, operands+0, operands+3);
5378 split_ti (operands+1, 1, operands+1, operands+4);
5379 split_ti (operands+2, 1, operands+2, operands+5);")
5380
5381 ;; %%% splits for addsidi3
5382 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5383 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5384 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5385
5386 (define_expand "adddi3"
5387 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5388 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5389 (match_operand:DI 2 "x86_64_general_operand" "")))
5390 (clobber (reg:CC FLAGS_REG))]
5391 ""
5392 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5393
5394 (define_insn "*adddi3_1"
5395 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5396 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5397 (match_operand:DI 2 "general_operand" "roiF,riF")))
5398 (clobber (reg:CC FLAGS_REG))]
5399 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5400 "#")
5401
5402 (define_split
5403 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5404 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5405 (match_operand:DI 2 "general_operand" "")))
5406 (clobber (reg:CC FLAGS_REG))]
5407 "!TARGET_64BIT && reload_completed"
5408 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5409 UNSPEC_ADD_CARRY))
5410 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5411 (parallel [(set (match_dup 3)
5412 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5413 (match_dup 4))
5414 (match_dup 5)))
5415 (clobber (reg:CC FLAGS_REG))])]
5416 "split_di (operands+0, 1, operands+0, operands+3);
5417 split_di (operands+1, 1, operands+1, operands+4);
5418 split_di (operands+2, 1, operands+2, operands+5);")
5419
5420 (define_insn "adddi3_carry_rex64"
5421 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5422 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5423 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5424 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5425 (clobber (reg:CC FLAGS_REG))]
5426 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5427 "adc{q}\t{%2, %0|%0, %2}"
5428 [(set_attr "type" "alu")
5429 (set_attr "pent_pair" "pu")
5430 (set_attr "mode" "DI")])
5431
5432 (define_insn "*adddi3_cc_rex64"
5433 [(set (reg:CC FLAGS_REG)
5434 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5435 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5436 UNSPEC_ADD_CARRY))
5437 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5438 (plus:DI (match_dup 1) (match_dup 2)))]
5439 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5440 "add{q}\t{%2, %0|%0, %2}"
5441 [(set_attr "type" "alu")
5442 (set_attr "mode" "DI")])
5443
5444 (define_insn "*<addsub><mode>3_cc_overflow"
5445 [(set (reg:CCC FLAGS_REG)
5446 (compare:CCC
5447 (plusminus:SWI
5448 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5449 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5450 (match_dup 1)))
5451 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5452 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5453 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5454 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5455 [(set_attr "type" "alu")
5456 (set_attr "mode" "<MODE>")])
5457
5458 (define_insn "*add<mode>3_cconly_overflow"
5459 [(set (reg:CCC FLAGS_REG)
5460 (compare:CCC
5461 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5462 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5463 (match_dup 1)))
5464 (clobber (match_scratch:SWI 0 "=<r>"))]
5465 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5466 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5467 [(set_attr "type" "alu")
5468 (set_attr "mode" "<MODE>")])
5469
5470 (define_insn "*sub<mode>3_cconly_overflow"
5471 [(set (reg:CCC FLAGS_REG)
5472 (compare:CCC
5473 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5474 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5475 (match_dup 0)))]
5476 ""
5477 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5478 [(set_attr "type" "icmp")
5479 (set_attr "mode" "<MODE>")])
5480
5481 (define_insn "*<addsub>si3_zext_cc_overflow"
5482 [(set (reg:CCC FLAGS_REG)
5483 (compare:CCC
5484 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5485 (match_operand:SI 2 "general_operand" "g"))
5486 (match_dup 1)))
5487 (set (match_operand:DI 0 "register_operand" "=r")
5488 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5489 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5490 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5491 [(set_attr "type" "alu")
5492 (set_attr "mode" "SI")])
5493
5494 (define_insn "addqi3_carry"
5495 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5496 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5497 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5498 (match_operand:QI 2 "general_operand" "qi,qm")))
5499 (clobber (reg:CC FLAGS_REG))]
5500 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5501 "adc{b}\t{%2, %0|%0, %2}"
5502 [(set_attr "type" "alu")
5503 (set_attr "pent_pair" "pu")
5504 (set_attr "mode" "QI")])
5505
5506 (define_insn "addhi3_carry"
5507 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5508 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5509 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5510 (match_operand:HI 2 "general_operand" "ri,rm")))
5511 (clobber (reg:CC FLAGS_REG))]
5512 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5513 "adc{w}\t{%2, %0|%0, %2}"
5514 [(set_attr "type" "alu")
5515 (set_attr "pent_pair" "pu")
5516 (set_attr "mode" "HI")])
5517
5518 (define_insn "addsi3_carry"
5519 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5520 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5521 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5522 (match_operand:SI 2 "general_operand" "ri,rm")))
5523 (clobber (reg:CC FLAGS_REG))]
5524 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5525 "adc{l}\t{%2, %0|%0, %2}"
5526 [(set_attr "type" "alu")
5527 (set_attr "pent_pair" "pu")
5528 (set_attr "mode" "SI")])
5529
5530 (define_insn "*addsi3_carry_zext"
5531 [(set (match_operand:DI 0 "register_operand" "=r")
5532 (zero_extend:DI
5533 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5534 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5535 (match_operand:SI 2 "general_operand" "g"))))
5536 (clobber (reg:CC FLAGS_REG))]
5537 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5538 "adc{l}\t{%2, %k0|%k0, %2}"
5539 [(set_attr "type" "alu")
5540 (set_attr "pent_pair" "pu")
5541 (set_attr "mode" "SI")])
5542
5543 (define_insn "*addsi3_cc"
5544 [(set (reg:CC FLAGS_REG)
5545 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5546 (match_operand:SI 2 "general_operand" "ri,rm")]
5547 UNSPEC_ADD_CARRY))
5548 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5549 (plus:SI (match_dup 1) (match_dup 2)))]
5550 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5551 "add{l}\t{%2, %0|%0, %2}"
5552 [(set_attr "type" "alu")
5553 (set_attr "mode" "SI")])
5554
5555 (define_insn "addqi3_cc"
5556 [(set (reg:CC FLAGS_REG)
5557 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5558 (match_operand:QI 2 "general_operand" "qi,qm")]
5559 UNSPEC_ADD_CARRY))
5560 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5561 (plus:QI (match_dup 1) (match_dup 2)))]
5562 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5563 "add{b}\t{%2, %0|%0, %2}"
5564 [(set_attr "type" "alu")
5565 (set_attr "mode" "QI")])
5566
5567 (define_expand "addsi3"
5568 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5569 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5570 (match_operand:SI 2 "general_operand" "")))
5571 (clobber (reg:CC FLAGS_REG))])]
5572 ""
5573 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5574
5575 (define_insn "*lea_1"
5576 [(set (match_operand:SI 0 "register_operand" "=r")
5577 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5578 "!TARGET_64BIT"
5579 "lea{l}\t{%a1, %0|%0, %a1}"
5580 [(set_attr "type" "lea")
5581 (set_attr "mode" "SI")])
5582
5583 (define_insn "*lea_1_rex64"
5584 [(set (match_operand:SI 0 "register_operand" "=r")
5585 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5586 "TARGET_64BIT"
5587 "lea{l}\t{%a1, %0|%0, %a1}"
5588 [(set_attr "type" "lea")
5589 (set_attr "mode" "SI")])
5590
5591 (define_insn "*lea_1_zext"
5592 [(set (match_operand:DI 0 "register_operand" "=r")
5593 (zero_extend:DI
5594 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5595 "TARGET_64BIT"
5596 "lea{l}\t{%a1, %k0|%k0, %a1}"
5597 [(set_attr "type" "lea")
5598 (set_attr "mode" "SI")])
5599
5600 (define_insn "*lea_2_rex64"
5601 [(set (match_operand:DI 0 "register_operand" "=r")
5602 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5603 "TARGET_64BIT"
5604 "lea{q}\t{%a1, %0|%0, %a1}"
5605 [(set_attr "type" "lea")
5606 (set_attr "mode" "DI")])
5607
5608 ;; The lea patterns for non-Pmodes needs to be matched by several
5609 ;; insns converted to real lea by splitters.
5610
5611 (define_insn_and_split "*lea_general_1"
5612 [(set (match_operand 0 "register_operand" "=r")
5613 (plus (plus (match_operand 1 "index_register_operand" "l")
5614 (match_operand 2 "register_operand" "r"))
5615 (match_operand 3 "immediate_operand" "i")))]
5616 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5617 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5618 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5619 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5620 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5621 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5622 || GET_MODE (operands[3]) == VOIDmode)"
5623 "#"
5624 "&& reload_completed"
5625 [(const_int 0)]
5626 {
5627 rtx pat;
5628 operands[0] = gen_lowpart (SImode, operands[0]);
5629 operands[1] = gen_lowpart (Pmode, operands[1]);
5630 operands[2] = gen_lowpart (Pmode, operands[2]);
5631 operands[3] = gen_lowpart (Pmode, operands[3]);
5632 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5633 operands[3]);
5634 if (Pmode != SImode)
5635 pat = gen_rtx_SUBREG (SImode, pat, 0);
5636 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5637 DONE;
5638 }
5639 [(set_attr "type" "lea")
5640 (set_attr "mode" "SI")])
5641
5642 (define_insn_and_split "*lea_general_1_zext"
5643 [(set (match_operand:DI 0 "register_operand" "=r")
5644 (zero_extend:DI
5645 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5646 (match_operand:SI 2 "register_operand" "r"))
5647 (match_operand:SI 3 "immediate_operand" "i"))))]
5648 "TARGET_64BIT"
5649 "#"
5650 "&& reload_completed"
5651 [(set (match_dup 0)
5652 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5653 (match_dup 2))
5654 (match_dup 3)) 0)))]
5655 {
5656 operands[1] = gen_lowpart (Pmode, operands[1]);
5657 operands[2] = gen_lowpart (Pmode, operands[2]);
5658 operands[3] = gen_lowpart (Pmode, operands[3]);
5659 }
5660 [(set_attr "type" "lea")
5661 (set_attr "mode" "SI")])
5662
5663 (define_insn_and_split "*lea_general_2"
5664 [(set (match_operand 0 "register_operand" "=r")
5665 (plus (mult (match_operand 1 "index_register_operand" "l")
5666 (match_operand 2 "const248_operand" "i"))
5667 (match_operand 3 "nonmemory_operand" "ri")))]
5668 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5669 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5670 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5671 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5672 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5673 || GET_MODE (operands[3]) == VOIDmode)"
5674 "#"
5675 "&& reload_completed"
5676 [(const_int 0)]
5677 {
5678 rtx pat;
5679 operands[0] = gen_lowpart (SImode, operands[0]);
5680 operands[1] = gen_lowpart (Pmode, operands[1]);
5681 operands[3] = gen_lowpart (Pmode, operands[3]);
5682 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5683 operands[3]);
5684 if (Pmode != SImode)
5685 pat = gen_rtx_SUBREG (SImode, pat, 0);
5686 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5687 DONE;
5688 }
5689 [(set_attr "type" "lea")
5690 (set_attr "mode" "SI")])
5691
5692 (define_insn_and_split "*lea_general_2_zext"
5693 [(set (match_operand:DI 0 "register_operand" "=r")
5694 (zero_extend:DI
5695 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5696 (match_operand:SI 2 "const248_operand" "n"))
5697 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5698 "TARGET_64BIT"
5699 "#"
5700 "&& reload_completed"
5701 [(set (match_dup 0)
5702 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5703 (match_dup 2))
5704 (match_dup 3)) 0)))]
5705 {
5706 operands[1] = gen_lowpart (Pmode, operands[1]);
5707 operands[3] = gen_lowpart (Pmode, operands[3]);
5708 }
5709 [(set_attr "type" "lea")
5710 (set_attr "mode" "SI")])
5711
5712 (define_insn_and_split "*lea_general_3"
5713 [(set (match_operand 0 "register_operand" "=r")
5714 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5715 (match_operand 2 "const248_operand" "i"))
5716 (match_operand 3 "register_operand" "r"))
5717 (match_operand 4 "immediate_operand" "i")))]
5718 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5719 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5720 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5721 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5722 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5723 "#"
5724 "&& reload_completed"
5725 [(const_int 0)]
5726 {
5727 rtx pat;
5728 operands[0] = gen_lowpart (SImode, operands[0]);
5729 operands[1] = gen_lowpart (Pmode, operands[1]);
5730 operands[3] = gen_lowpart (Pmode, operands[3]);
5731 operands[4] = gen_lowpart (Pmode, operands[4]);
5732 pat = gen_rtx_PLUS (Pmode,
5733 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5734 operands[2]),
5735 operands[3]),
5736 operands[4]);
5737 if (Pmode != SImode)
5738 pat = gen_rtx_SUBREG (SImode, pat, 0);
5739 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5740 DONE;
5741 }
5742 [(set_attr "type" "lea")
5743 (set_attr "mode" "SI")])
5744
5745 (define_insn_and_split "*lea_general_3_zext"
5746 [(set (match_operand:DI 0 "register_operand" "=r")
5747 (zero_extend:DI
5748 (plus:SI (plus:SI (mult:SI
5749 (match_operand:SI 1 "index_register_operand" "l")
5750 (match_operand:SI 2 "const248_operand" "n"))
5751 (match_operand:SI 3 "register_operand" "r"))
5752 (match_operand:SI 4 "immediate_operand" "i"))))]
5753 "TARGET_64BIT"
5754 "#"
5755 "&& reload_completed"
5756 [(set (match_dup 0)
5757 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5758 (match_dup 2))
5759 (match_dup 3))
5760 (match_dup 4)) 0)))]
5761 {
5762 operands[1] = gen_lowpart (Pmode, operands[1]);
5763 operands[3] = gen_lowpart (Pmode, operands[3]);
5764 operands[4] = gen_lowpart (Pmode, operands[4]);
5765 }
5766 [(set_attr "type" "lea")
5767 (set_attr "mode" "SI")])
5768
5769 (define_insn "*adddi_1_rex64"
5770 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5771 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5772 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5773 (clobber (reg:CC FLAGS_REG))]
5774 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5775 {
5776 switch (get_attr_type (insn))
5777 {
5778 case TYPE_LEA:
5779 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5780 return "lea{q}\t{%a2, %0|%0, %a2}";
5781
5782 case TYPE_INCDEC:
5783 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5784 if (operands[2] == const1_rtx)
5785 return "inc{q}\t%0";
5786 else
5787 {
5788 gcc_assert (operands[2] == constm1_rtx);
5789 return "dec{q}\t%0";
5790 }
5791
5792 default:
5793 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5794
5795 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5796 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5797 if (CONST_INT_P (operands[2])
5798 /* Avoid overflows. */
5799 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5800 && (INTVAL (operands[2]) == 128
5801 || (INTVAL (operands[2]) < 0
5802 && INTVAL (operands[2]) != -128)))
5803 {
5804 operands[2] = GEN_INT (-INTVAL (operands[2]));
5805 return "sub{q}\t{%2, %0|%0, %2}";
5806 }
5807 return "add{q}\t{%2, %0|%0, %2}";
5808 }
5809 }
5810 [(set (attr "type")
5811 (cond [(eq_attr "alternative" "2")
5812 (const_string "lea")
5813 ; Current assemblers are broken and do not allow @GOTOFF in
5814 ; ought but a memory context.
5815 (match_operand:DI 2 "pic_symbolic_operand" "")
5816 (const_string "lea")
5817 (match_operand:DI 2 "incdec_operand" "")
5818 (const_string "incdec")
5819 ]
5820 (const_string "alu")))
5821 (set_attr "mode" "DI")])
5822
5823 ;; Convert lea to the lea pattern to avoid flags dependency.
5824 (define_split
5825 [(set (match_operand:DI 0 "register_operand" "")
5826 (plus:DI (match_operand:DI 1 "register_operand" "")
5827 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5828 (clobber (reg:CC FLAGS_REG))]
5829 "TARGET_64BIT && reload_completed
5830 && true_regnum (operands[0]) != true_regnum (operands[1])"
5831 [(set (match_dup 0)
5832 (plus:DI (match_dup 1)
5833 (match_dup 2)))]
5834 "")
5835
5836 (define_insn "*adddi_2_rex64"
5837 [(set (reg FLAGS_REG)
5838 (compare
5839 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5840 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5841 (const_int 0)))
5842 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5843 (plus:DI (match_dup 1) (match_dup 2)))]
5844 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5845 && ix86_binary_operator_ok (PLUS, DImode, operands)
5846 /* Current assemblers are broken and do not allow @GOTOFF in
5847 ought but a memory context. */
5848 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5849 {
5850 switch (get_attr_type (insn))
5851 {
5852 case TYPE_INCDEC:
5853 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5854 if (operands[2] == const1_rtx)
5855 return "inc{q}\t%0";
5856 else
5857 {
5858 gcc_assert (operands[2] == constm1_rtx);
5859 return "dec{q}\t%0";
5860 }
5861
5862 default:
5863 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5864 /* ???? We ought to handle there the 32bit case too
5865 - do we need new constraint? */
5866 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5867 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5868 if (CONST_INT_P (operands[2])
5869 /* Avoid overflows. */
5870 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5871 && (INTVAL (operands[2]) == 128
5872 || (INTVAL (operands[2]) < 0
5873 && INTVAL (operands[2]) != -128)))
5874 {
5875 operands[2] = GEN_INT (-INTVAL (operands[2]));
5876 return "sub{q}\t{%2, %0|%0, %2}";
5877 }
5878 return "add{q}\t{%2, %0|%0, %2}";
5879 }
5880 }
5881 [(set (attr "type")
5882 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5883 (const_string "incdec")
5884 (const_string "alu")))
5885 (set_attr "mode" "DI")])
5886
5887 (define_insn "*adddi_3_rex64"
5888 [(set (reg FLAGS_REG)
5889 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5890 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5891 (clobber (match_scratch:DI 0 "=r"))]
5892 "TARGET_64BIT
5893 && ix86_match_ccmode (insn, CCZmode)
5894 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5895 /* Current assemblers are broken and do not allow @GOTOFF in
5896 ought but a memory context. */
5897 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5898 {
5899 switch (get_attr_type (insn))
5900 {
5901 case TYPE_INCDEC:
5902 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5903 if (operands[2] == const1_rtx)
5904 return "inc{q}\t%0";
5905 else
5906 {
5907 gcc_assert (operands[2] == constm1_rtx);
5908 return "dec{q}\t%0";
5909 }
5910
5911 default:
5912 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5913 /* ???? We ought to handle there the 32bit case too
5914 - do we need new constraint? */
5915 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5917 if (CONST_INT_P (operands[2])
5918 /* Avoid overflows. */
5919 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5920 && (INTVAL (operands[2]) == 128
5921 || (INTVAL (operands[2]) < 0
5922 && INTVAL (operands[2]) != -128)))
5923 {
5924 operands[2] = GEN_INT (-INTVAL (operands[2]));
5925 return "sub{q}\t{%2, %0|%0, %2}";
5926 }
5927 return "add{q}\t{%2, %0|%0, %2}";
5928 }
5929 }
5930 [(set (attr "type")
5931 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5932 (const_string "incdec")
5933 (const_string "alu")))
5934 (set_attr "mode" "DI")])
5935
5936 ; For comparisons against 1, -1 and 128, we may generate better code
5937 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5938 ; is matched then. We can't accept general immediate, because for
5939 ; case of overflows, the result is messed up.
5940 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5941 ; when negated.
5942 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5943 ; only for comparisons not depending on it.
5944 (define_insn "*adddi_4_rex64"
5945 [(set (reg FLAGS_REG)
5946 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5947 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5948 (clobber (match_scratch:DI 0 "=rm"))]
5949 "TARGET_64BIT
5950 && ix86_match_ccmode (insn, CCGCmode)"
5951 {
5952 switch (get_attr_type (insn))
5953 {
5954 case TYPE_INCDEC:
5955 if (operands[2] == constm1_rtx)
5956 return "inc{q}\t%0";
5957 else
5958 {
5959 gcc_assert (operands[2] == const1_rtx);
5960 return "dec{q}\t%0";
5961 }
5962
5963 default:
5964 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5965 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5966 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5967 if ((INTVAL (operands[2]) == -128
5968 || (INTVAL (operands[2]) > 0
5969 && INTVAL (operands[2]) != 128))
5970 /* Avoid overflows. */
5971 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5972 return "sub{q}\t{%2, %0|%0, %2}";
5973 operands[2] = GEN_INT (-INTVAL (operands[2]));
5974 return "add{q}\t{%2, %0|%0, %2}";
5975 }
5976 }
5977 [(set (attr "type")
5978 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5979 (const_string "incdec")
5980 (const_string "alu")))
5981 (set_attr "mode" "DI")])
5982
5983 (define_insn "*adddi_5_rex64"
5984 [(set (reg FLAGS_REG)
5985 (compare
5986 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5987 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5988 (const_int 0)))
5989 (clobber (match_scratch:DI 0 "=r"))]
5990 "TARGET_64BIT
5991 && ix86_match_ccmode (insn, CCGOCmode)
5992 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5993 /* Current assemblers are broken and do not allow @GOTOFF in
5994 ought but a memory context. */
5995 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5996 {
5997 switch (get_attr_type (insn))
5998 {
5999 case TYPE_INCDEC:
6000 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6001 if (operands[2] == const1_rtx)
6002 return "inc{q}\t%0";
6003 else
6004 {
6005 gcc_assert (operands[2] == constm1_rtx);
6006 return "dec{q}\t%0";
6007 }
6008
6009 default:
6010 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6011 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6012 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6013 if (CONST_INT_P (operands[2])
6014 /* Avoid overflows. */
6015 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6016 && (INTVAL (operands[2]) == 128
6017 || (INTVAL (operands[2]) < 0
6018 && INTVAL (operands[2]) != -128)))
6019 {
6020 operands[2] = GEN_INT (-INTVAL (operands[2]));
6021 return "sub{q}\t{%2, %0|%0, %2}";
6022 }
6023 return "add{q}\t{%2, %0|%0, %2}";
6024 }
6025 }
6026 [(set (attr "type")
6027 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6028 (const_string "incdec")
6029 (const_string "alu")))
6030 (set_attr "mode" "DI")])
6031
6032
6033 (define_insn "*addsi_1"
6034 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6035 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6036 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6037 (clobber (reg:CC FLAGS_REG))]
6038 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6039 {
6040 switch (get_attr_type (insn))
6041 {
6042 case TYPE_LEA:
6043 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6044 return "lea{l}\t{%a2, %0|%0, %a2}";
6045
6046 case TYPE_INCDEC:
6047 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6048 if (operands[2] == const1_rtx)
6049 return "inc{l}\t%0";
6050 else
6051 {
6052 gcc_assert (operands[2] == constm1_rtx);
6053 return "dec{l}\t%0";
6054 }
6055
6056 default:
6057 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6058
6059 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6060 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6061 if (CONST_INT_P (operands[2])
6062 && (INTVAL (operands[2]) == 128
6063 || (INTVAL (operands[2]) < 0
6064 && INTVAL (operands[2]) != -128)))
6065 {
6066 operands[2] = GEN_INT (-INTVAL (operands[2]));
6067 return "sub{l}\t{%2, %0|%0, %2}";
6068 }
6069 return "add{l}\t{%2, %0|%0, %2}";
6070 }
6071 }
6072 [(set (attr "type")
6073 (cond [(eq_attr "alternative" "2")
6074 (const_string "lea")
6075 ; Current assemblers are broken and do not allow @GOTOFF in
6076 ; ought but a memory context.
6077 (match_operand:SI 2 "pic_symbolic_operand" "")
6078 (const_string "lea")
6079 (match_operand:SI 2 "incdec_operand" "")
6080 (const_string "incdec")
6081 ]
6082 (const_string "alu")))
6083 (set_attr "mode" "SI")])
6084
6085 ;; Convert lea to the lea pattern to avoid flags dependency.
6086 (define_split
6087 [(set (match_operand 0 "register_operand" "")
6088 (plus (match_operand 1 "register_operand" "")
6089 (match_operand 2 "nonmemory_operand" "")))
6090 (clobber (reg:CC FLAGS_REG))]
6091 "reload_completed
6092 && true_regnum (operands[0]) != true_regnum (operands[1])"
6093 [(const_int 0)]
6094 {
6095 rtx pat;
6096 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6097 may confuse gen_lowpart. */
6098 if (GET_MODE (operands[0]) != Pmode)
6099 {
6100 operands[1] = gen_lowpart (Pmode, operands[1]);
6101 operands[2] = gen_lowpart (Pmode, operands[2]);
6102 }
6103 operands[0] = gen_lowpart (SImode, operands[0]);
6104 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6105 if (Pmode != SImode)
6106 pat = gen_rtx_SUBREG (SImode, pat, 0);
6107 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6108 DONE;
6109 })
6110
6111 ;; It may seem that nonimmediate operand is proper one for operand 1.
6112 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6113 ;; we take care in ix86_binary_operator_ok to not allow two memory
6114 ;; operands so proper swapping will be done in reload. This allow
6115 ;; patterns constructed from addsi_1 to match.
6116 (define_insn "addsi_1_zext"
6117 [(set (match_operand:DI 0 "register_operand" "=r,r")
6118 (zero_extend:DI
6119 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6120 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6121 (clobber (reg:CC FLAGS_REG))]
6122 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6123 {
6124 switch (get_attr_type (insn))
6125 {
6126 case TYPE_LEA:
6127 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6128 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6129
6130 case TYPE_INCDEC:
6131 if (operands[2] == const1_rtx)
6132 return "inc{l}\t%k0";
6133 else
6134 {
6135 gcc_assert (operands[2] == constm1_rtx);
6136 return "dec{l}\t%k0";
6137 }
6138
6139 default:
6140 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6141 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6142 if (CONST_INT_P (operands[2])
6143 && (INTVAL (operands[2]) == 128
6144 || (INTVAL (operands[2]) < 0
6145 && INTVAL (operands[2]) != -128)))
6146 {
6147 operands[2] = GEN_INT (-INTVAL (operands[2]));
6148 return "sub{l}\t{%2, %k0|%k0, %2}";
6149 }
6150 return "add{l}\t{%2, %k0|%k0, %2}";
6151 }
6152 }
6153 [(set (attr "type")
6154 (cond [(eq_attr "alternative" "1")
6155 (const_string "lea")
6156 ; Current assemblers are broken and do not allow @GOTOFF in
6157 ; ought but a memory context.
6158 (match_operand:SI 2 "pic_symbolic_operand" "")
6159 (const_string "lea")
6160 (match_operand:SI 2 "incdec_operand" "")
6161 (const_string "incdec")
6162 ]
6163 (const_string "alu")))
6164 (set_attr "mode" "SI")])
6165
6166 ;; Convert lea to the lea pattern to avoid flags dependency.
6167 (define_split
6168 [(set (match_operand:DI 0 "register_operand" "")
6169 (zero_extend:DI
6170 (plus:SI (match_operand:SI 1 "register_operand" "")
6171 (match_operand:SI 2 "nonmemory_operand" ""))))
6172 (clobber (reg:CC FLAGS_REG))]
6173 "TARGET_64BIT && reload_completed
6174 && true_regnum (operands[0]) != true_regnum (operands[1])"
6175 [(set (match_dup 0)
6176 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6177 {
6178 operands[1] = gen_lowpart (Pmode, operands[1]);
6179 operands[2] = gen_lowpart (Pmode, operands[2]);
6180 })
6181
6182 (define_insn "*addsi_2"
6183 [(set (reg FLAGS_REG)
6184 (compare
6185 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6186 (match_operand:SI 2 "general_operand" "rmni,rni"))
6187 (const_int 0)))
6188 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6189 (plus:SI (match_dup 1) (match_dup 2)))]
6190 "ix86_match_ccmode (insn, CCGOCmode)
6191 && ix86_binary_operator_ok (PLUS, SImode, operands)
6192 /* Current assemblers are broken and do not allow @GOTOFF in
6193 ought but a memory context. */
6194 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6195 {
6196 switch (get_attr_type (insn))
6197 {
6198 case TYPE_INCDEC:
6199 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6200 if (operands[2] == const1_rtx)
6201 return "inc{l}\t%0";
6202 else
6203 {
6204 gcc_assert (operands[2] == constm1_rtx);
6205 return "dec{l}\t%0";
6206 }
6207
6208 default:
6209 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6210 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6211 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6212 if (CONST_INT_P (operands[2])
6213 && (INTVAL (operands[2]) == 128
6214 || (INTVAL (operands[2]) < 0
6215 && INTVAL (operands[2]) != -128)))
6216 {
6217 operands[2] = GEN_INT (-INTVAL (operands[2]));
6218 return "sub{l}\t{%2, %0|%0, %2}";
6219 }
6220 return "add{l}\t{%2, %0|%0, %2}";
6221 }
6222 }
6223 [(set (attr "type")
6224 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6225 (const_string "incdec")
6226 (const_string "alu")))
6227 (set_attr "mode" "SI")])
6228
6229 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6230 (define_insn "*addsi_2_zext"
6231 [(set (reg FLAGS_REG)
6232 (compare
6233 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6234 (match_operand:SI 2 "general_operand" "rmni"))
6235 (const_int 0)))
6236 (set (match_operand:DI 0 "register_operand" "=r")
6237 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6238 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6239 && ix86_binary_operator_ok (PLUS, SImode, operands)
6240 /* Current assemblers are broken and do not allow @GOTOFF in
6241 ought but a memory context. */
6242 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6243 {
6244 switch (get_attr_type (insn))
6245 {
6246 case TYPE_INCDEC:
6247 if (operands[2] == const1_rtx)
6248 return "inc{l}\t%k0";
6249 else
6250 {
6251 gcc_assert (operands[2] == constm1_rtx);
6252 return "dec{l}\t%k0";
6253 }
6254
6255 default:
6256 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6257 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6258 if (CONST_INT_P (operands[2])
6259 && (INTVAL (operands[2]) == 128
6260 || (INTVAL (operands[2]) < 0
6261 && INTVAL (operands[2]) != -128)))
6262 {
6263 operands[2] = GEN_INT (-INTVAL (operands[2]));
6264 return "sub{l}\t{%2, %k0|%k0, %2}";
6265 }
6266 return "add{l}\t{%2, %k0|%k0, %2}";
6267 }
6268 }
6269 [(set (attr "type")
6270 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6271 (const_string "incdec")
6272 (const_string "alu")))
6273 (set_attr "mode" "SI")])
6274
6275 (define_insn "*addsi_3"
6276 [(set (reg FLAGS_REG)
6277 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6278 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6279 (clobber (match_scratch:SI 0 "=r"))]
6280 "ix86_match_ccmode (insn, CCZmode)
6281 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6282 /* Current assemblers are broken and do not allow @GOTOFF in
6283 ought but a memory context. */
6284 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6285 {
6286 switch (get_attr_type (insn))
6287 {
6288 case TYPE_INCDEC:
6289 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6290 if (operands[2] == const1_rtx)
6291 return "inc{l}\t%0";
6292 else
6293 {
6294 gcc_assert (operands[2] == constm1_rtx);
6295 return "dec{l}\t%0";
6296 }
6297
6298 default:
6299 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6300 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6301 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6302 if (CONST_INT_P (operands[2])
6303 && (INTVAL (operands[2]) == 128
6304 || (INTVAL (operands[2]) < 0
6305 && INTVAL (operands[2]) != -128)))
6306 {
6307 operands[2] = GEN_INT (-INTVAL (operands[2]));
6308 return "sub{l}\t{%2, %0|%0, %2}";
6309 }
6310 return "add{l}\t{%2, %0|%0, %2}";
6311 }
6312 }
6313 [(set (attr "type")
6314 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6315 (const_string "incdec")
6316 (const_string "alu")))
6317 (set_attr "mode" "SI")])
6318
6319 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6320 (define_insn "*addsi_3_zext"
6321 [(set (reg FLAGS_REG)
6322 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6323 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6324 (set (match_operand:DI 0 "register_operand" "=r")
6325 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6326 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6327 && ix86_binary_operator_ok (PLUS, SImode, operands)
6328 /* Current assemblers are broken and do not allow @GOTOFF in
6329 ought but a memory context. */
6330 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6331 {
6332 switch (get_attr_type (insn))
6333 {
6334 case TYPE_INCDEC:
6335 if (operands[2] == const1_rtx)
6336 return "inc{l}\t%k0";
6337 else
6338 {
6339 gcc_assert (operands[2] == constm1_rtx);
6340 return "dec{l}\t%k0";
6341 }
6342
6343 default:
6344 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6345 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6346 if (CONST_INT_P (operands[2])
6347 && (INTVAL (operands[2]) == 128
6348 || (INTVAL (operands[2]) < 0
6349 && INTVAL (operands[2]) != -128)))
6350 {
6351 operands[2] = GEN_INT (-INTVAL (operands[2]));
6352 return "sub{l}\t{%2, %k0|%k0, %2}";
6353 }
6354 return "add{l}\t{%2, %k0|%k0, %2}";
6355 }
6356 }
6357 [(set (attr "type")
6358 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6359 (const_string "incdec")
6360 (const_string "alu")))
6361 (set_attr "mode" "SI")])
6362
6363 ; For comparisons against 1, -1 and 128, we may generate better code
6364 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6365 ; is matched then. We can't accept general immediate, because for
6366 ; case of overflows, the result is messed up.
6367 ; This pattern also don't hold of 0x80000000, since the value overflows
6368 ; when negated.
6369 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6370 ; only for comparisons not depending on it.
6371 (define_insn "*addsi_4"
6372 [(set (reg FLAGS_REG)
6373 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6374 (match_operand:SI 2 "const_int_operand" "n")))
6375 (clobber (match_scratch:SI 0 "=rm"))]
6376 "ix86_match_ccmode (insn, CCGCmode)
6377 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6378 {
6379 switch (get_attr_type (insn))
6380 {
6381 case TYPE_INCDEC:
6382 if (operands[2] == constm1_rtx)
6383 return "inc{l}\t%0";
6384 else
6385 {
6386 gcc_assert (operands[2] == const1_rtx);
6387 return "dec{l}\t%0";
6388 }
6389
6390 default:
6391 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6392 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6393 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6394 if ((INTVAL (operands[2]) == -128
6395 || (INTVAL (operands[2]) > 0
6396 && INTVAL (operands[2]) != 128)))
6397 return "sub{l}\t{%2, %0|%0, %2}";
6398 operands[2] = GEN_INT (-INTVAL (operands[2]));
6399 return "add{l}\t{%2, %0|%0, %2}";
6400 }
6401 }
6402 [(set (attr "type")
6403 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6404 (const_string "incdec")
6405 (const_string "alu")))
6406 (set_attr "mode" "SI")])
6407
6408 (define_insn "*addsi_5"
6409 [(set (reg FLAGS_REG)
6410 (compare
6411 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6412 (match_operand:SI 2 "general_operand" "rmni"))
6413 (const_int 0)))
6414 (clobber (match_scratch:SI 0 "=r"))]
6415 "ix86_match_ccmode (insn, CCGOCmode)
6416 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6417 /* Current assemblers are broken and do not allow @GOTOFF in
6418 ought but a memory context. */
6419 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6420 {
6421 switch (get_attr_type (insn))
6422 {
6423 case TYPE_INCDEC:
6424 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6425 if (operands[2] == const1_rtx)
6426 return "inc{l}\t%0";
6427 else
6428 {
6429 gcc_assert (operands[2] == constm1_rtx);
6430 return "dec{l}\t%0";
6431 }
6432
6433 default:
6434 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6435 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6436 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6437 if (CONST_INT_P (operands[2])
6438 && (INTVAL (operands[2]) == 128
6439 || (INTVAL (operands[2]) < 0
6440 && INTVAL (operands[2]) != -128)))
6441 {
6442 operands[2] = GEN_INT (-INTVAL (operands[2]));
6443 return "sub{l}\t{%2, %0|%0, %2}";
6444 }
6445 return "add{l}\t{%2, %0|%0, %2}";
6446 }
6447 }
6448 [(set (attr "type")
6449 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6450 (const_string "incdec")
6451 (const_string "alu")))
6452 (set_attr "mode" "SI")])
6453
6454 (define_expand "addhi3"
6455 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6456 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6457 (match_operand:HI 2 "general_operand" "")))
6458 (clobber (reg:CC FLAGS_REG))])]
6459 "TARGET_HIMODE_MATH"
6460 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6461
6462 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6463 ;; type optimizations enabled by define-splits. This is not important
6464 ;; for PII, and in fact harmful because of partial register stalls.
6465
6466 (define_insn "*addhi_1_lea"
6467 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6468 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6469 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6470 (clobber (reg:CC FLAGS_REG))]
6471 "!TARGET_PARTIAL_REG_STALL
6472 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6473 {
6474 switch (get_attr_type (insn))
6475 {
6476 case TYPE_LEA:
6477 return "#";
6478 case TYPE_INCDEC:
6479 if (operands[2] == const1_rtx)
6480 return "inc{w}\t%0";
6481 else
6482 {
6483 gcc_assert (operands[2] == constm1_rtx);
6484 return "dec{w}\t%0";
6485 }
6486
6487 default:
6488 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6489 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6490 if (CONST_INT_P (operands[2])
6491 && (INTVAL (operands[2]) == 128
6492 || (INTVAL (operands[2]) < 0
6493 && INTVAL (operands[2]) != -128)))
6494 {
6495 operands[2] = GEN_INT (-INTVAL (operands[2]));
6496 return "sub{w}\t{%2, %0|%0, %2}";
6497 }
6498 return "add{w}\t{%2, %0|%0, %2}";
6499 }
6500 }
6501 [(set (attr "type")
6502 (if_then_else (eq_attr "alternative" "2")
6503 (const_string "lea")
6504 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6505 (const_string "incdec")
6506 (const_string "alu"))))
6507 (set_attr "mode" "HI,HI,SI")])
6508
6509 (define_insn "*addhi_1"
6510 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6511 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6512 (match_operand:HI 2 "general_operand" "ri,rm")))
6513 (clobber (reg:CC FLAGS_REG))]
6514 "TARGET_PARTIAL_REG_STALL
6515 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6516 {
6517 switch (get_attr_type (insn))
6518 {
6519 case TYPE_INCDEC:
6520 if (operands[2] == const1_rtx)
6521 return "inc{w}\t%0";
6522 else
6523 {
6524 gcc_assert (operands[2] == constm1_rtx);
6525 return "dec{w}\t%0";
6526 }
6527
6528 default:
6529 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6530 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6531 if (CONST_INT_P (operands[2])
6532 && (INTVAL (operands[2]) == 128
6533 || (INTVAL (operands[2]) < 0
6534 && INTVAL (operands[2]) != -128)))
6535 {
6536 operands[2] = GEN_INT (-INTVAL (operands[2]));
6537 return "sub{w}\t{%2, %0|%0, %2}";
6538 }
6539 return "add{w}\t{%2, %0|%0, %2}";
6540 }
6541 }
6542 [(set (attr "type")
6543 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6544 (const_string "incdec")
6545 (const_string "alu")))
6546 (set_attr "mode" "HI")])
6547
6548 (define_insn "*addhi_2"
6549 [(set (reg FLAGS_REG)
6550 (compare
6551 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6552 (match_operand:HI 2 "general_operand" "rmni,rni"))
6553 (const_int 0)))
6554 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6555 (plus:HI (match_dup 1) (match_dup 2)))]
6556 "ix86_match_ccmode (insn, CCGOCmode)
6557 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6558 {
6559 switch (get_attr_type (insn))
6560 {
6561 case TYPE_INCDEC:
6562 if (operands[2] == const1_rtx)
6563 return "inc{w}\t%0";
6564 else
6565 {
6566 gcc_assert (operands[2] == constm1_rtx);
6567 return "dec{w}\t%0";
6568 }
6569
6570 default:
6571 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6572 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6573 if (CONST_INT_P (operands[2])
6574 && (INTVAL (operands[2]) == 128
6575 || (INTVAL (operands[2]) < 0
6576 && INTVAL (operands[2]) != -128)))
6577 {
6578 operands[2] = GEN_INT (-INTVAL (operands[2]));
6579 return "sub{w}\t{%2, %0|%0, %2}";
6580 }
6581 return "add{w}\t{%2, %0|%0, %2}";
6582 }
6583 }
6584 [(set (attr "type")
6585 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6586 (const_string "incdec")
6587 (const_string "alu")))
6588 (set_attr "mode" "HI")])
6589
6590 (define_insn "*addhi_3"
6591 [(set (reg FLAGS_REG)
6592 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6593 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6594 (clobber (match_scratch:HI 0 "=r"))]
6595 "ix86_match_ccmode (insn, CCZmode)
6596 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6597 {
6598 switch (get_attr_type (insn))
6599 {
6600 case TYPE_INCDEC:
6601 if (operands[2] == const1_rtx)
6602 return "inc{w}\t%0";
6603 else
6604 {
6605 gcc_assert (operands[2] == constm1_rtx);
6606 return "dec{w}\t%0";
6607 }
6608
6609 default:
6610 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6611 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6612 if (CONST_INT_P (operands[2])
6613 && (INTVAL (operands[2]) == 128
6614 || (INTVAL (operands[2]) < 0
6615 && INTVAL (operands[2]) != -128)))
6616 {
6617 operands[2] = GEN_INT (-INTVAL (operands[2]));
6618 return "sub{w}\t{%2, %0|%0, %2}";
6619 }
6620 return "add{w}\t{%2, %0|%0, %2}";
6621 }
6622 }
6623 [(set (attr "type")
6624 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6625 (const_string "incdec")
6626 (const_string "alu")))
6627 (set_attr "mode" "HI")])
6628
6629 ; See comments above addsi_4 for details.
6630 (define_insn "*addhi_4"
6631 [(set (reg FLAGS_REG)
6632 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6633 (match_operand:HI 2 "const_int_operand" "n")))
6634 (clobber (match_scratch:HI 0 "=rm"))]
6635 "ix86_match_ccmode (insn, CCGCmode)
6636 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6637 {
6638 switch (get_attr_type (insn))
6639 {
6640 case TYPE_INCDEC:
6641 if (operands[2] == constm1_rtx)
6642 return "inc{w}\t%0";
6643 else
6644 {
6645 gcc_assert (operands[2] == const1_rtx);
6646 return "dec{w}\t%0";
6647 }
6648
6649 default:
6650 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6651 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6652 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6653 if ((INTVAL (operands[2]) == -128
6654 || (INTVAL (operands[2]) > 0
6655 && INTVAL (operands[2]) != 128)))
6656 return "sub{w}\t{%2, %0|%0, %2}";
6657 operands[2] = GEN_INT (-INTVAL (operands[2]));
6658 return "add{w}\t{%2, %0|%0, %2}";
6659 }
6660 }
6661 [(set (attr "type")
6662 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6663 (const_string "incdec")
6664 (const_string "alu")))
6665 (set_attr "mode" "SI")])
6666
6667
6668 (define_insn "*addhi_5"
6669 [(set (reg FLAGS_REG)
6670 (compare
6671 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6672 (match_operand:HI 2 "general_operand" "rmni"))
6673 (const_int 0)))
6674 (clobber (match_scratch:HI 0 "=r"))]
6675 "ix86_match_ccmode (insn, CCGOCmode)
6676 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6677 {
6678 switch (get_attr_type (insn))
6679 {
6680 case TYPE_INCDEC:
6681 if (operands[2] == const1_rtx)
6682 return "inc{w}\t%0";
6683 else
6684 {
6685 gcc_assert (operands[2] == constm1_rtx);
6686 return "dec{w}\t%0";
6687 }
6688
6689 default:
6690 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6691 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6692 if (CONST_INT_P (operands[2])
6693 && (INTVAL (operands[2]) == 128
6694 || (INTVAL (operands[2]) < 0
6695 && INTVAL (operands[2]) != -128)))
6696 {
6697 operands[2] = GEN_INT (-INTVAL (operands[2]));
6698 return "sub{w}\t{%2, %0|%0, %2}";
6699 }
6700 return "add{w}\t{%2, %0|%0, %2}";
6701 }
6702 }
6703 [(set (attr "type")
6704 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6705 (const_string "incdec")
6706 (const_string "alu")))
6707 (set_attr "mode" "HI")])
6708
6709 (define_expand "addqi3"
6710 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6711 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6712 (match_operand:QI 2 "general_operand" "")))
6713 (clobber (reg:CC FLAGS_REG))])]
6714 "TARGET_QIMODE_MATH"
6715 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6716
6717 ;; %%% Potential partial reg stall on alternative 2. What to do?
6718 (define_insn "*addqi_1_lea"
6719 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6720 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6721 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6722 (clobber (reg:CC FLAGS_REG))]
6723 "!TARGET_PARTIAL_REG_STALL
6724 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6725 {
6726 int widen = (which_alternative == 2);
6727 switch (get_attr_type (insn))
6728 {
6729 case TYPE_LEA:
6730 return "#";
6731 case TYPE_INCDEC:
6732 if (operands[2] == const1_rtx)
6733 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6734 else
6735 {
6736 gcc_assert (operands[2] == constm1_rtx);
6737 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6738 }
6739
6740 default:
6741 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6742 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6743 if (CONST_INT_P (operands[2])
6744 && (INTVAL (operands[2]) == 128
6745 || (INTVAL (operands[2]) < 0
6746 && INTVAL (operands[2]) != -128)))
6747 {
6748 operands[2] = GEN_INT (-INTVAL (operands[2]));
6749 if (widen)
6750 return "sub{l}\t{%2, %k0|%k0, %2}";
6751 else
6752 return "sub{b}\t{%2, %0|%0, %2}";
6753 }
6754 if (widen)
6755 return "add{l}\t{%k2, %k0|%k0, %k2}";
6756 else
6757 return "add{b}\t{%2, %0|%0, %2}";
6758 }
6759 }
6760 [(set (attr "type")
6761 (if_then_else (eq_attr "alternative" "3")
6762 (const_string "lea")
6763 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6764 (const_string "incdec")
6765 (const_string "alu"))))
6766 (set_attr "mode" "QI,QI,SI,SI")])
6767
6768 (define_insn "*addqi_1"
6769 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6770 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6771 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6772 (clobber (reg:CC FLAGS_REG))]
6773 "TARGET_PARTIAL_REG_STALL
6774 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6775 {
6776 int widen = (which_alternative == 2);
6777 switch (get_attr_type (insn))
6778 {
6779 case TYPE_INCDEC:
6780 if (operands[2] == const1_rtx)
6781 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6782 else
6783 {
6784 gcc_assert (operands[2] == constm1_rtx);
6785 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6786 }
6787
6788 default:
6789 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6790 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6791 if (CONST_INT_P (operands[2])
6792 && (INTVAL (operands[2]) == 128
6793 || (INTVAL (operands[2]) < 0
6794 && INTVAL (operands[2]) != -128)))
6795 {
6796 operands[2] = GEN_INT (-INTVAL (operands[2]));
6797 if (widen)
6798 return "sub{l}\t{%2, %k0|%k0, %2}";
6799 else
6800 return "sub{b}\t{%2, %0|%0, %2}";
6801 }
6802 if (widen)
6803 return "add{l}\t{%k2, %k0|%k0, %k2}";
6804 else
6805 return "add{b}\t{%2, %0|%0, %2}";
6806 }
6807 }
6808 [(set (attr "type")
6809 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6810 (const_string "incdec")
6811 (const_string "alu")))
6812 (set_attr "mode" "QI,QI,SI")])
6813
6814 (define_insn "*addqi_1_slp"
6815 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6816 (plus:QI (match_dup 0)
6817 (match_operand:QI 1 "general_operand" "qn,qnm")))
6818 (clobber (reg:CC FLAGS_REG))]
6819 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6820 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6821 {
6822 switch (get_attr_type (insn))
6823 {
6824 case TYPE_INCDEC:
6825 if (operands[1] == const1_rtx)
6826 return "inc{b}\t%0";
6827 else
6828 {
6829 gcc_assert (operands[1] == constm1_rtx);
6830 return "dec{b}\t%0";
6831 }
6832
6833 default:
6834 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6835 if (CONST_INT_P (operands[1])
6836 && INTVAL (operands[1]) < 0)
6837 {
6838 operands[1] = GEN_INT (-INTVAL (operands[1]));
6839 return "sub{b}\t{%1, %0|%0, %1}";
6840 }
6841 return "add{b}\t{%1, %0|%0, %1}";
6842 }
6843 }
6844 [(set (attr "type")
6845 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6846 (const_string "incdec")
6847 (const_string "alu1")))
6848 (set (attr "memory")
6849 (if_then_else (match_operand 1 "memory_operand" "")
6850 (const_string "load")
6851 (const_string "none")))
6852 (set_attr "mode" "QI")])
6853
6854 (define_insn "*addqi_2"
6855 [(set (reg FLAGS_REG)
6856 (compare
6857 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6858 (match_operand:QI 2 "general_operand" "qmni,qni"))
6859 (const_int 0)))
6860 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6861 (plus:QI (match_dup 1) (match_dup 2)))]
6862 "ix86_match_ccmode (insn, CCGOCmode)
6863 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6864 {
6865 switch (get_attr_type (insn))
6866 {
6867 case TYPE_INCDEC:
6868 if (operands[2] == const1_rtx)
6869 return "inc{b}\t%0";
6870 else
6871 {
6872 gcc_assert (operands[2] == constm1_rtx
6873 || (CONST_INT_P (operands[2])
6874 && INTVAL (operands[2]) == 255));
6875 return "dec{b}\t%0";
6876 }
6877
6878 default:
6879 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6880 if (CONST_INT_P (operands[2])
6881 && INTVAL (operands[2]) < 0)
6882 {
6883 operands[2] = GEN_INT (-INTVAL (operands[2]));
6884 return "sub{b}\t{%2, %0|%0, %2}";
6885 }
6886 return "add{b}\t{%2, %0|%0, %2}";
6887 }
6888 }
6889 [(set (attr "type")
6890 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6891 (const_string "incdec")
6892 (const_string "alu")))
6893 (set_attr "mode" "QI")])
6894
6895 (define_insn "*addqi_3"
6896 [(set (reg FLAGS_REG)
6897 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6898 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6899 (clobber (match_scratch:QI 0 "=q"))]
6900 "ix86_match_ccmode (insn, CCZmode)
6901 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6902 {
6903 switch (get_attr_type (insn))
6904 {
6905 case TYPE_INCDEC:
6906 if (operands[2] == const1_rtx)
6907 return "inc{b}\t%0";
6908 else
6909 {
6910 gcc_assert (operands[2] == constm1_rtx
6911 || (CONST_INT_P (operands[2])
6912 && INTVAL (operands[2]) == 255));
6913 return "dec{b}\t%0";
6914 }
6915
6916 default:
6917 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6918 if (CONST_INT_P (operands[2])
6919 && INTVAL (operands[2]) < 0)
6920 {
6921 operands[2] = GEN_INT (-INTVAL (operands[2]));
6922 return "sub{b}\t{%2, %0|%0, %2}";
6923 }
6924 return "add{b}\t{%2, %0|%0, %2}";
6925 }
6926 }
6927 [(set (attr "type")
6928 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6929 (const_string "incdec")
6930 (const_string "alu")))
6931 (set_attr "mode" "QI")])
6932
6933 ; See comments above addsi_4 for details.
6934 (define_insn "*addqi_4"
6935 [(set (reg FLAGS_REG)
6936 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6937 (match_operand:QI 2 "const_int_operand" "n")))
6938 (clobber (match_scratch:QI 0 "=qm"))]
6939 "ix86_match_ccmode (insn, CCGCmode)
6940 && (INTVAL (operands[2]) & 0xff) != 0x80"
6941 {
6942 switch (get_attr_type (insn))
6943 {
6944 case TYPE_INCDEC:
6945 if (operands[2] == constm1_rtx
6946 || (CONST_INT_P (operands[2])
6947 && INTVAL (operands[2]) == 255))
6948 return "inc{b}\t%0";
6949 else
6950 {
6951 gcc_assert (operands[2] == const1_rtx);
6952 return "dec{b}\t%0";
6953 }
6954
6955 default:
6956 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6957 if (INTVAL (operands[2]) < 0)
6958 {
6959 operands[2] = GEN_INT (-INTVAL (operands[2]));
6960 return "add{b}\t{%2, %0|%0, %2}";
6961 }
6962 return "sub{b}\t{%2, %0|%0, %2}";
6963 }
6964 }
6965 [(set (attr "type")
6966 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6967 (const_string "incdec")
6968 (const_string "alu")))
6969 (set_attr "mode" "QI")])
6970
6971
6972 (define_insn "*addqi_5"
6973 [(set (reg FLAGS_REG)
6974 (compare
6975 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6976 (match_operand:QI 2 "general_operand" "qmni"))
6977 (const_int 0)))
6978 (clobber (match_scratch:QI 0 "=q"))]
6979 "ix86_match_ccmode (insn, CCGOCmode)
6980 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6981 {
6982 switch (get_attr_type (insn))
6983 {
6984 case TYPE_INCDEC:
6985 if (operands[2] == const1_rtx)
6986 return "inc{b}\t%0";
6987 else
6988 {
6989 gcc_assert (operands[2] == constm1_rtx
6990 || (CONST_INT_P (operands[2])
6991 && INTVAL (operands[2]) == 255));
6992 return "dec{b}\t%0";
6993 }
6994
6995 default:
6996 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6997 if (CONST_INT_P (operands[2])
6998 && INTVAL (operands[2]) < 0)
6999 {
7000 operands[2] = GEN_INT (-INTVAL (operands[2]));
7001 return "sub{b}\t{%2, %0|%0, %2}";
7002 }
7003 return "add{b}\t{%2, %0|%0, %2}";
7004 }
7005 }
7006 [(set (attr "type")
7007 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7008 (const_string "incdec")
7009 (const_string "alu")))
7010 (set_attr "mode" "QI")])
7011
7012
7013 (define_insn "addqi_ext_1"
7014 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7015 (const_int 8)
7016 (const_int 8))
7017 (plus:SI
7018 (zero_extract:SI
7019 (match_operand 1 "ext_register_operand" "0")
7020 (const_int 8)
7021 (const_int 8))
7022 (match_operand:QI 2 "general_operand" "Qmn")))
7023 (clobber (reg:CC FLAGS_REG))]
7024 "!TARGET_64BIT"
7025 {
7026 switch (get_attr_type (insn))
7027 {
7028 case TYPE_INCDEC:
7029 if (operands[2] == const1_rtx)
7030 return "inc{b}\t%h0";
7031 else
7032 {
7033 gcc_assert (operands[2] == constm1_rtx
7034 || (CONST_INT_P (operands[2])
7035 && INTVAL (operands[2]) == 255));
7036 return "dec{b}\t%h0";
7037 }
7038
7039 default:
7040 return "add{b}\t{%2, %h0|%h0, %2}";
7041 }
7042 }
7043 [(set (attr "type")
7044 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7045 (const_string "incdec")
7046 (const_string "alu")))
7047 (set_attr "mode" "QI")])
7048
7049 (define_insn "*addqi_ext_1_rex64"
7050 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7051 (const_int 8)
7052 (const_int 8))
7053 (plus:SI
7054 (zero_extract:SI
7055 (match_operand 1 "ext_register_operand" "0")
7056 (const_int 8)
7057 (const_int 8))
7058 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7059 (clobber (reg:CC FLAGS_REG))]
7060 "TARGET_64BIT"
7061 {
7062 switch (get_attr_type (insn))
7063 {
7064 case TYPE_INCDEC:
7065 if (operands[2] == const1_rtx)
7066 return "inc{b}\t%h0";
7067 else
7068 {
7069 gcc_assert (operands[2] == constm1_rtx
7070 || (CONST_INT_P (operands[2])
7071 && INTVAL (operands[2]) == 255));
7072 return "dec{b}\t%h0";
7073 }
7074
7075 default:
7076 return "add{b}\t{%2, %h0|%h0, %2}";
7077 }
7078 }
7079 [(set (attr "type")
7080 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7081 (const_string "incdec")
7082 (const_string "alu")))
7083 (set_attr "mode" "QI")])
7084
7085 (define_insn "*addqi_ext_2"
7086 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7087 (const_int 8)
7088 (const_int 8))
7089 (plus:SI
7090 (zero_extract:SI
7091 (match_operand 1 "ext_register_operand" "%0")
7092 (const_int 8)
7093 (const_int 8))
7094 (zero_extract:SI
7095 (match_operand 2 "ext_register_operand" "Q")
7096 (const_int 8)
7097 (const_int 8))))
7098 (clobber (reg:CC FLAGS_REG))]
7099 ""
7100 "add{b}\t{%h2, %h0|%h0, %h2}"
7101 [(set_attr "type" "alu")
7102 (set_attr "mode" "QI")])
7103
7104 ;; The patterns that match these are at the end of this file.
7105
7106 (define_expand "addxf3"
7107 [(set (match_operand:XF 0 "register_operand" "")
7108 (plus:XF (match_operand:XF 1 "register_operand" "")
7109 (match_operand:XF 2 "register_operand" "")))]
7110 "TARGET_80387"
7111 "")
7112
7113 (define_expand "add<mode>3"
7114 [(set (match_operand:MODEF 0 "register_operand" "")
7115 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7116 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7117 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7118 "")
7119 \f
7120 ;; Subtract instructions
7121
7122 ;; %%% splits for subditi3
7123
7124 (define_expand "subti3"
7125 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7126 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7127 (match_operand:TI 2 "x86_64_general_operand" "")))
7128 (clobber (reg:CC FLAGS_REG))])]
7129 "TARGET_64BIT"
7130 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7131
7132 (define_insn "*subti3_1"
7133 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7134 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7135 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7136 (clobber (reg:CC FLAGS_REG))]
7137 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7138 "#")
7139
7140 (define_split
7141 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7142 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7143 (match_operand:TI 2 "x86_64_general_operand" "")))
7144 (clobber (reg:CC FLAGS_REG))]
7145 "TARGET_64BIT && reload_completed"
7146 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7147 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7148 (parallel [(set (match_dup 3)
7149 (minus:DI (match_dup 4)
7150 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7151 (match_dup 5))))
7152 (clobber (reg:CC FLAGS_REG))])]
7153 "split_ti (operands+0, 1, operands+0, operands+3);
7154 split_ti (operands+1, 1, operands+1, operands+4);
7155 split_ti (operands+2, 1, operands+2, operands+5);")
7156
7157 ;; %%% splits for subsidi3
7158
7159 (define_expand "subdi3"
7160 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7161 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7162 (match_operand:DI 2 "x86_64_general_operand" "")))
7163 (clobber (reg:CC FLAGS_REG))])]
7164 ""
7165 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7166
7167 (define_insn "*subdi3_1"
7168 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7169 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7170 (match_operand:DI 2 "general_operand" "roiF,riF")))
7171 (clobber (reg:CC FLAGS_REG))]
7172 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7173 "#")
7174
7175 (define_split
7176 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7177 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7178 (match_operand:DI 2 "general_operand" "")))
7179 (clobber (reg:CC FLAGS_REG))]
7180 "!TARGET_64BIT && reload_completed"
7181 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7182 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7183 (parallel [(set (match_dup 3)
7184 (minus:SI (match_dup 4)
7185 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7186 (match_dup 5))))
7187 (clobber (reg:CC FLAGS_REG))])]
7188 "split_di (operands+0, 1, operands+0, operands+3);
7189 split_di (operands+1, 1, operands+1, operands+4);
7190 split_di (operands+2, 1, operands+2, operands+5);")
7191
7192 (define_insn "subdi3_carry_rex64"
7193 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7194 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7195 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7196 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7197 (clobber (reg:CC FLAGS_REG))]
7198 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7199 "sbb{q}\t{%2, %0|%0, %2}"
7200 [(set_attr "type" "alu")
7201 (set_attr "pent_pair" "pu")
7202 (set_attr "mode" "DI")])
7203
7204 (define_insn "*subdi_1_rex64"
7205 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7206 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7207 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7208 (clobber (reg:CC FLAGS_REG))]
7209 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7210 "sub{q}\t{%2, %0|%0, %2}"
7211 [(set_attr "type" "alu")
7212 (set_attr "mode" "DI")])
7213
7214 (define_insn "*subdi_2_rex64"
7215 [(set (reg FLAGS_REG)
7216 (compare
7217 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7218 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7219 (const_int 0)))
7220 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7221 (minus:DI (match_dup 1) (match_dup 2)))]
7222 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7223 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7224 "sub{q}\t{%2, %0|%0, %2}"
7225 [(set_attr "type" "alu")
7226 (set_attr "mode" "DI")])
7227
7228 (define_insn "*subdi_3_rex63"
7229 [(set (reg FLAGS_REG)
7230 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7231 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7232 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7233 (minus:DI (match_dup 1) (match_dup 2)))]
7234 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7235 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7236 "sub{q}\t{%2, %0|%0, %2}"
7237 [(set_attr "type" "alu")
7238 (set_attr "mode" "DI")])
7239
7240 (define_insn "subqi3_carry"
7241 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7242 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7243 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7244 (match_operand:QI 2 "general_operand" "qi,qm"))))
7245 (clobber (reg:CC FLAGS_REG))]
7246 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7247 "sbb{b}\t{%2, %0|%0, %2}"
7248 [(set_attr "type" "alu")
7249 (set_attr "pent_pair" "pu")
7250 (set_attr "mode" "QI")])
7251
7252 (define_insn "subhi3_carry"
7253 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7254 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7255 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7256 (match_operand:HI 2 "general_operand" "ri,rm"))))
7257 (clobber (reg:CC FLAGS_REG))]
7258 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7259 "sbb{w}\t{%2, %0|%0, %2}"
7260 [(set_attr "type" "alu")
7261 (set_attr "pent_pair" "pu")
7262 (set_attr "mode" "HI")])
7263
7264 (define_insn "subsi3_carry"
7265 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7266 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7267 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7268 (match_operand:SI 2 "general_operand" "ri,rm"))))
7269 (clobber (reg:CC FLAGS_REG))]
7270 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7271 "sbb{l}\t{%2, %0|%0, %2}"
7272 [(set_attr "type" "alu")
7273 (set_attr "pent_pair" "pu")
7274 (set_attr "mode" "SI")])
7275
7276 (define_insn "subsi3_carry_zext"
7277 [(set (match_operand:DI 0 "register_operand" "=r")
7278 (zero_extend:DI
7279 (minus:SI (match_operand:SI 1 "register_operand" "0")
7280 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7281 (match_operand:SI 2 "general_operand" "g")))))
7282 (clobber (reg:CC FLAGS_REG))]
7283 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7284 "sbb{l}\t{%2, %k0|%k0, %2}"
7285 [(set_attr "type" "alu")
7286 (set_attr "pent_pair" "pu")
7287 (set_attr "mode" "SI")])
7288
7289 (define_expand "subsi3"
7290 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7291 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7292 (match_operand:SI 2 "general_operand" "")))
7293 (clobber (reg:CC FLAGS_REG))])]
7294 ""
7295 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7296
7297 (define_insn "*subsi_1"
7298 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7299 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7300 (match_operand:SI 2 "general_operand" "ri,rm")))
7301 (clobber (reg:CC FLAGS_REG))]
7302 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7303 "sub{l}\t{%2, %0|%0, %2}"
7304 [(set_attr "type" "alu")
7305 (set_attr "mode" "SI")])
7306
7307 (define_insn "*subsi_1_zext"
7308 [(set (match_operand:DI 0 "register_operand" "=r")
7309 (zero_extend:DI
7310 (minus:SI (match_operand:SI 1 "register_operand" "0")
7311 (match_operand:SI 2 "general_operand" "g"))))
7312 (clobber (reg:CC FLAGS_REG))]
7313 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7314 "sub{l}\t{%2, %k0|%k0, %2}"
7315 [(set_attr "type" "alu")
7316 (set_attr "mode" "SI")])
7317
7318 (define_insn "*subsi_2"
7319 [(set (reg FLAGS_REG)
7320 (compare
7321 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7322 (match_operand:SI 2 "general_operand" "ri,rm"))
7323 (const_int 0)))
7324 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7325 (minus:SI (match_dup 1) (match_dup 2)))]
7326 "ix86_match_ccmode (insn, CCGOCmode)
7327 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7328 "sub{l}\t{%2, %0|%0, %2}"
7329 [(set_attr "type" "alu")
7330 (set_attr "mode" "SI")])
7331
7332 (define_insn "*subsi_2_zext"
7333 [(set (reg FLAGS_REG)
7334 (compare
7335 (minus:SI (match_operand:SI 1 "register_operand" "0")
7336 (match_operand:SI 2 "general_operand" "g"))
7337 (const_int 0)))
7338 (set (match_operand:DI 0 "register_operand" "=r")
7339 (zero_extend:DI
7340 (minus:SI (match_dup 1)
7341 (match_dup 2))))]
7342 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7343 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7344 "sub{l}\t{%2, %k0|%k0, %2}"
7345 [(set_attr "type" "alu")
7346 (set_attr "mode" "SI")])
7347
7348 (define_insn "*subsi_3"
7349 [(set (reg FLAGS_REG)
7350 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7351 (match_operand:SI 2 "general_operand" "ri,rm")))
7352 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7353 (minus:SI (match_dup 1) (match_dup 2)))]
7354 "ix86_match_ccmode (insn, CCmode)
7355 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7356 "sub{l}\t{%2, %0|%0, %2}"
7357 [(set_attr "type" "alu")
7358 (set_attr "mode" "SI")])
7359
7360 (define_insn "*subsi_3_zext"
7361 [(set (reg FLAGS_REG)
7362 (compare (match_operand:SI 1 "register_operand" "0")
7363 (match_operand:SI 2 "general_operand" "g")))
7364 (set (match_operand:DI 0 "register_operand" "=r")
7365 (zero_extend:DI
7366 (minus:SI (match_dup 1)
7367 (match_dup 2))))]
7368 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7369 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7370 "sub{l}\t{%2, %1|%1, %2}"
7371 [(set_attr "type" "alu")
7372 (set_attr "mode" "DI")])
7373
7374 (define_expand "subhi3"
7375 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7376 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7377 (match_operand:HI 2 "general_operand" "")))
7378 (clobber (reg:CC FLAGS_REG))])]
7379 "TARGET_HIMODE_MATH"
7380 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7381
7382 (define_insn "*subhi_1"
7383 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7384 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7385 (match_operand:HI 2 "general_operand" "ri,rm")))
7386 (clobber (reg:CC FLAGS_REG))]
7387 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7388 "sub{w}\t{%2, %0|%0, %2}"
7389 [(set_attr "type" "alu")
7390 (set_attr "mode" "HI")])
7391
7392 (define_insn "*subhi_2"
7393 [(set (reg FLAGS_REG)
7394 (compare
7395 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7396 (match_operand:HI 2 "general_operand" "ri,rm"))
7397 (const_int 0)))
7398 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7399 (minus:HI (match_dup 1) (match_dup 2)))]
7400 "ix86_match_ccmode (insn, CCGOCmode)
7401 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7402 "sub{w}\t{%2, %0|%0, %2}"
7403 [(set_attr "type" "alu")
7404 (set_attr "mode" "HI")])
7405
7406 (define_insn "*subhi_3"
7407 [(set (reg FLAGS_REG)
7408 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7409 (match_operand:HI 2 "general_operand" "ri,rm")))
7410 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7411 (minus:HI (match_dup 1) (match_dup 2)))]
7412 "ix86_match_ccmode (insn, CCmode)
7413 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7414 "sub{w}\t{%2, %0|%0, %2}"
7415 [(set_attr "type" "alu")
7416 (set_attr "mode" "HI")])
7417
7418 (define_expand "subqi3"
7419 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7420 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7421 (match_operand:QI 2 "general_operand" "")))
7422 (clobber (reg:CC FLAGS_REG))])]
7423 "TARGET_QIMODE_MATH"
7424 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7425
7426 (define_insn "*subqi_1"
7427 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7428 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7429 (match_operand:QI 2 "general_operand" "qn,qmn")))
7430 (clobber (reg:CC FLAGS_REG))]
7431 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7432 "sub{b}\t{%2, %0|%0, %2}"
7433 [(set_attr "type" "alu")
7434 (set_attr "mode" "QI")])
7435
7436 (define_insn "*subqi_1_slp"
7437 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7438 (minus:QI (match_dup 0)
7439 (match_operand:QI 1 "general_operand" "qn,qmn")))
7440 (clobber (reg:CC FLAGS_REG))]
7441 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7442 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7443 "sub{b}\t{%1, %0|%0, %1}"
7444 [(set_attr "type" "alu1")
7445 (set_attr "mode" "QI")])
7446
7447 (define_insn "*subqi_2"
7448 [(set (reg FLAGS_REG)
7449 (compare
7450 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7451 (match_operand:QI 2 "general_operand" "qi,qm"))
7452 (const_int 0)))
7453 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7454 (minus:HI (match_dup 1) (match_dup 2)))]
7455 "ix86_match_ccmode (insn, CCGOCmode)
7456 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7457 "sub{b}\t{%2, %0|%0, %2}"
7458 [(set_attr "type" "alu")
7459 (set_attr "mode" "QI")])
7460
7461 (define_insn "*subqi_3"
7462 [(set (reg FLAGS_REG)
7463 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7464 (match_operand:QI 2 "general_operand" "qi,qm")))
7465 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7466 (minus:HI (match_dup 1) (match_dup 2)))]
7467 "ix86_match_ccmode (insn, CCmode)
7468 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7469 "sub{b}\t{%2, %0|%0, %2}"
7470 [(set_attr "type" "alu")
7471 (set_attr "mode" "QI")])
7472
7473 ;; The patterns that match these are at the end of this file.
7474
7475 (define_expand "subxf3"
7476 [(set (match_operand:XF 0 "register_operand" "")
7477 (minus:XF (match_operand:XF 1 "register_operand" "")
7478 (match_operand:XF 2 "register_operand" "")))]
7479 "TARGET_80387"
7480 "")
7481
7482 (define_expand "sub<mode>3"
7483 [(set (match_operand:MODEF 0 "register_operand" "")
7484 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7485 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7486 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7487 "")
7488 \f
7489 ;; Multiply instructions
7490
7491 (define_expand "muldi3"
7492 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7493 (mult:DI (match_operand:DI 1 "register_operand" "")
7494 (match_operand:DI 2 "x86_64_general_operand" "")))
7495 (clobber (reg:CC FLAGS_REG))])]
7496 "TARGET_64BIT"
7497 "")
7498
7499 ;; On AMDFAM10
7500 ;; IMUL reg64, reg64, imm8 Direct
7501 ;; IMUL reg64, mem64, imm8 VectorPath
7502 ;; IMUL reg64, reg64, imm32 Direct
7503 ;; IMUL reg64, mem64, imm32 VectorPath
7504 ;; IMUL reg64, reg64 Direct
7505 ;; IMUL reg64, mem64 Direct
7506
7507 (define_insn "*muldi3_1_rex64"
7508 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7509 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7510 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7511 (clobber (reg:CC FLAGS_REG))]
7512 "TARGET_64BIT
7513 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7514 "@
7515 imul{q}\t{%2, %1, %0|%0, %1, %2}
7516 imul{q}\t{%2, %1, %0|%0, %1, %2}
7517 imul{q}\t{%2, %0|%0, %2}"
7518 [(set_attr "type" "imul")
7519 (set_attr "prefix_0f" "0,0,1")
7520 (set (attr "athlon_decode")
7521 (cond [(eq_attr "cpu" "athlon")
7522 (const_string "vector")
7523 (eq_attr "alternative" "1")
7524 (const_string "vector")
7525 (and (eq_attr "alternative" "2")
7526 (match_operand 1 "memory_operand" ""))
7527 (const_string "vector")]
7528 (const_string "direct")))
7529 (set (attr "amdfam10_decode")
7530 (cond [(and (eq_attr "alternative" "0,1")
7531 (match_operand 1 "memory_operand" ""))
7532 (const_string "vector")]
7533 (const_string "direct")))
7534 (set_attr "mode" "DI")])
7535
7536 (define_expand "mulsi3"
7537 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7538 (mult:SI (match_operand:SI 1 "register_operand" "")
7539 (match_operand:SI 2 "general_operand" "")))
7540 (clobber (reg:CC FLAGS_REG))])]
7541 ""
7542 "")
7543
7544 ;; On AMDFAM10
7545 ;; IMUL reg32, reg32, imm8 Direct
7546 ;; IMUL reg32, mem32, imm8 VectorPath
7547 ;; IMUL reg32, reg32, imm32 Direct
7548 ;; IMUL reg32, mem32, imm32 VectorPath
7549 ;; IMUL reg32, reg32 Direct
7550 ;; IMUL reg32, mem32 Direct
7551
7552 (define_insn "*mulsi3_1"
7553 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7554 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7555 (match_operand:SI 2 "general_operand" "K,i,mr")))
7556 (clobber (reg:CC FLAGS_REG))]
7557 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7558 "@
7559 imul{l}\t{%2, %1, %0|%0, %1, %2}
7560 imul{l}\t{%2, %1, %0|%0, %1, %2}
7561 imul{l}\t{%2, %0|%0, %2}"
7562 [(set_attr "type" "imul")
7563 (set_attr "prefix_0f" "0,0,1")
7564 (set (attr "athlon_decode")
7565 (cond [(eq_attr "cpu" "athlon")
7566 (const_string "vector")
7567 (eq_attr "alternative" "1")
7568 (const_string "vector")
7569 (and (eq_attr "alternative" "2")
7570 (match_operand 1 "memory_operand" ""))
7571 (const_string "vector")]
7572 (const_string "direct")))
7573 (set (attr "amdfam10_decode")
7574 (cond [(and (eq_attr "alternative" "0,1")
7575 (match_operand 1 "memory_operand" ""))
7576 (const_string "vector")]
7577 (const_string "direct")))
7578 (set_attr "mode" "SI")])
7579
7580 (define_insn "*mulsi3_1_zext"
7581 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7582 (zero_extend:DI
7583 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7584 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7585 (clobber (reg:CC FLAGS_REG))]
7586 "TARGET_64BIT
7587 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7588 "@
7589 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7590 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7591 imul{l}\t{%2, %k0|%k0, %2}"
7592 [(set_attr "type" "imul")
7593 (set_attr "prefix_0f" "0,0,1")
7594 (set (attr "athlon_decode")
7595 (cond [(eq_attr "cpu" "athlon")
7596 (const_string "vector")
7597 (eq_attr "alternative" "1")
7598 (const_string "vector")
7599 (and (eq_attr "alternative" "2")
7600 (match_operand 1 "memory_operand" ""))
7601 (const_string "vector")]
7602 (const_string "direct")))
7603 (set (attr "amdfam10_decode")
7604 (cond [(and (eq_attr "alternative" "0,1")
7605 (match_operand 1 "memory_operand" ""))
7606 (const_string "vector")]
7607 (const_string "direct")))
7608 (set_attr "mode" "SI")])
7609
7610 (define_expand "mulhi3"
7611 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7612 (mult:HI (match_operand:HI 1 "register_operand" "")
7613 (match_operand:HI 2 "general_operand" "")))
7614 (clobber (reg:CC FLAGS_REG))])]
7615 "TARGET_HIMODE_MATH"
7616 "")
7617
7618 ;; On AMDFAM10
7619 ;; IMUL reg16, reg16, imm8 VectorPath
7620 ;; IMUL reg16, mem16, imm8 VectorPath
7621 ;; IMUL reg16, reg16, imm16 VectorPath
7622 ;; IMUL reg16, mem16, imm16 VectorPath
7623 ;; IMUL reg16, reg16 Direct
7624 ;; IMUL reg16, mem16 Direct
7625 (define_insn "*mulhi3_1"
7626 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7627 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7628 (match_operand:HI 2 "general_operand" "K,i,mr")))
7629 (clobber (reg:CC FLAGS_REG))]
7630 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7631 "@
7632 imul{w}\t{%2, %1, %0|%0, %1, %2}
7633 imul{w}\t{%2, %1, %0|%0, %1, %2}
7634 imul{w}\t{%2, %0|%0, %2}"
7635 [(set_attr "type" "imul")
7636 (set_attr "prefix_0f" "0,0,1")
7637 (set (attr "athlon_decode")
7638 (cond [(eq_attr "cpu" "athlon")
7639 (const_string "vector")
7640 (eq_attr "alternative" "1,2")
7641 (const_string "vector")]
7642 (const_string "direct")))
7643 (set (attr "amdfam10_decode")
7644 (cond [(eq_attr "alternative" "0,1")
7645 (const_string "vector")]
7646 (const_string "direct")))
7647 (set_attr "mode" "HI")])
7648
7649 (define_expand "mulqi3"
7650 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7651 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7652 (match_operand:QI 2 "register_operand" "")))
7653 (clobber (reg:CC FLAGS_REG))])]
7654 "TARGET_QIMODE_MATH"
7655 "")
7656
7657 ;;On AMDFAM10
7658 ;; MUL reg8 Direct
7659 ;; MUL mem8 Direct
7660
7661 (define_insn "*mulqi3_1"
7662 [(set (match_operand:QI 0 "register_operand" "=a")
7663 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7664 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7665 (clobber (reg:CC FLAGS_REG))]
7666 "TARGET_QIMODE_MATH
7667 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7668 "mul{b}\t%2"
7669 [(set_attr "type" "imul")
7670 (set_attr "length_immediate" "0")
7671 (set (attr "athlon_decode")
7672 (if_then_else (eq_attr "cpu" "athlon")
7673 (const_string "vector")
7674 (const_string "direct")))
7675 (set_attr "amdfam10_decode" "direct")
7676 (set_attr "mode" "QI")])
7677
7678 (define_expand "umulqihi3"
7679 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7680 (mult:HI (zero_extend:HI
7681 (match_operand:QI 1 "nonimmediate_operand" ""))
7682 (zero_extend:HI
7683 (match_operand:QI 2 "register_operand" ""))))
7684 (clobber (reg:CC FLAGS_REG))])]
7685 "TARGET_QIMODE_MATH"
7686 "")
7687
7688 (define_insn "*umulqihi3_1"
7689 [(set (match_operand:HI 0 "register_operand" "=a")
7690 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7691 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7692 (clobber (reg:CC FLAGS_REG))]
7693 "TARGET_QIMODE_MATH
7694 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7695 "mul{b}\t%2"
7696 [(set_attr "type" "imul")
7697 (set_attr "length_immediate" "0")
7698 (set (attr "athlon_decode")
7699 (if_then_else (eq_attr "cpu" "athlon")
7700 (const_string "vector")
7701 (const_string "direct")))
7702 (set_attr "amdfam10_decode" "direct")
7703 (set_attr "mode" "QI")])
7704
7705 (define_expand "mulqihi3"
7706 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7707 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7708 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7709 (clobber (reg:CC FLAGS_REG))])]
7710 "TARGET_QIMODE_MATH"
7711 "")
7712
7713 (define_insn "*mulqihi3_insn"
7714 [(set (match_operand:HI 0 "register_operand" "=a")
7715 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7716 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7717 (clobber (reg:CC FLAGS_REG))]
7718 "TARGET_QIMODE_MATH
7719 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7720 "imul{b}\t%2"
7721 [(set_attr "type" "imul")
7722 (set_attr "length_immediate" "0")
7723 (set (attr "athlon_decode")
7724 (if_then_else (eq_attr "cpu" "athlon")
7725 (const_string "vector")
7726 (const_string "direct")))
7727 (set_attr "amdfam10_decode" "direct")
7728 (set_attr "mode" "QI")])
7729
7730 (define_expand "umulditi3"
7731 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7732 (mult:TI (zero_extend:TI
7733 (match_operand:DI 1 "nonimmediate_operand" ""))
7734 (zero_extend:TI
7735 (match_operand:DI 2 "register_operand" ""))))
7736 (clobber (reg:CC FLAGS_REG))])]
7737 "TARGET_64BIT"
7738 "")
7739
7740 (define_insn "*umulditi3_insn"
7741 [(set (match_operand:TI 0 "register_operand" "=A")
7742 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7743 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7744 (clobber (reg:CC FLAGS_REG))]
7745 "TARGET_64BIT
7746 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7747 "mul{q}\t%2"
7748 [(set_attr "type" "imul")
7749 (set_attr "length_immediate" "0")
7750 (set (attr "athlon_decode")
7751 (if_then_else (eq_attr "cpu" "athlon")
7752 (const_string "vector")
7753 (const_string "double")))
7754 (set_attr "amdfam10_decode" "double")
7755 (set_attr "mode" "DI")])
7756
7757 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7758 (define_expand "umulsidi3"
7759 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7760 (mult:DI (zero_extend:DI
7761 (match_operand:SI 1 "nonimmediate_operand" ""))
7762 (zero_extend:DI
7763 (match_operand:SI 2 "register_operand" ""))))
7764 (clobber (reg:CC FLAGS_REG))])]
7765 "!TARGET_64BIT"
7766 "")
7767
7768 (define_insn "*umulsidi3_insn"
7769 [(set (match_operand:DI 0 "register_operand" "=A")
7770 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7771 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7772 (clobber (reg:CC FLAGS_REG))]
7773 "!TARGET_64BIT
7774 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7775 "mul{l}\t%2"
7776 [(set_attr "type" "imul")
7777 (set_attr "length_immediate" "0")
7778 (set (attr "athlon_decode")
7779 (if_then_else (eq_attr "cpu" "athlon")
7780 (const_string "vector")
7781 (const_string "double")))
7782 (set_attr "amdfam10_decode" "double")
7783 (set_attr "mode" "SI")])
7784
7785 (define_expand "mulditi3"
7786 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7787 (mult:TI (sign_extend:TI
7788 (match_operand:DI 1 "nonimmediate_operand" ""))
7789 (sign_extend:TI
7790 (match_operand:DI 2 "register_operand" ""))))
7791 (clobber (reg:CC FLAGS_REG))])]
7792 "TARGET_64BIT"
7793 "")
7794
7795 (define_insn "*mulditi3_insn"
7796 [(set (match_operand:TI 0 "register_operand" "=A")
7797 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7798 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7799 (clobber (reg:CC FLAGS_REG))]
7800 "TARGET_64BIT
7801 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7802 "imul{q}\t%2"
7803 [(set_attr "type" "imul")
7804 (set_attr "length_immediate" "0")
7805 (set (attr "athlon_decode")
7806 (if_then_else (eq_attr "cpu" "athlon")
7807 (const_string "vector")
7808 (const_string "double")))
7809 (set_attr "amdfam10_decode" "double")
7810 (set_attr "mode" "DI")])
7811
7812 (define_expand "mulsidi3"
7813 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7814 (mult:DI (sign_extend:DI
7815 (match_operand:SI 1 "nonimmediate_operand" ""))
7816 (sign_extend:DI
7817 (match_operand:SI 2 "register_operand" ""))))
7818 (clobber (reg:CC FLAGS_REG))])]
7819 "!TARGET_64BIT"
7820 "")
7821
7822 (define_insn "*mulsidi3_insn"
7823 [(set (match_operand:DI 0 "register_operand" "=A")
7824 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7825 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7826 (clobber (reg:CC FLAGS_REG))]
7827 "!TARGET_64BIT
7828 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7829 "imul{l}\t%2"
7830 [(set_attr "type" "imul")
7831 (set_attr "length_immediate" "0")
7832 (set (attr "athlon_decode")
7833 (if_then_else (eq_attr "cpu" "athlon")
7834 (const_string "vector")
7835 (const_string "double")))
7836 (set_attr "amdfam10_decode" "double")
7837 (set_attr "mode" "SI")])
7838
7839 (define_expand "umuldi3_highpart"
7840 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7841 (truncate:DI
7842 (lshiftrt:TI
7843 (mult:TI (zero_extend:TI
7844 (match_operand:DI 1 "nonimmediate_operand" ""))
7845 (zero_extend:TI
7846 (match_operand:DI 2 "register_operand" "")))
7847 (const_int 64))))
7848 (clobber (match_scratch:DI 3 ""))
7849 (clobber (reg:CC FLAGS_REG))])]
7850 "TARGET_64BIT"
7851 "")
7852
7853 (define_insn "*umuldi3_highpart_rex64"
7854 [(set (match_operand:DI 0 "register_operand" "=d")
7855 (truncate:DI
7856 (lshiftrt:TI
7857 (mult:TI (zero_extend:TI
7858 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7859 (zero_extend:TI
7860 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7861 (const_int 64))))
7862 (clobber (match_scratch:DI 3 "=1"))
7863 (clobber (reg:CC FLAGS_REG))]
7864 "TARGET_64BIT
7865 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7866 "mul{q}\t%2"
7867 [(set_attr "type" "imul")
7868 (set_attr "length_immediate" "0")
7869 (set (attr "athlon_decode")
7870 (if_then_else (eq_attr "cpu" "athlon")
7871 (const_string "vector")
7872 (const_string "double")))
7873 (set_attr "amdfam10_decode" "double")
7874 (set_attr "mode" "DI")])
7875
7876 (define_expand "umulsi3_highpart"
7877 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7878 (truncate:SI
7879 (lshiftrt:DI
7880 (mult:DI (zero_extend:DI
7881 (match_operand:SI 1 "nonimmediate_operand" ""))
7882 (zero_extend:DI
7883 (match_operand:SI 2 "register_operand" "")))
7884 (const_int 32))))
7885 (clobber (match_scratch:SI 3 ""))
7886 (clobber (reg:CC FLAGS_REG))])]
7887 ""
7888 "")
7889
7890 (define_insn "*umulsi3_highpart_insn"
7891 [(set (match_operand:SI 0 "register_operand" "=d")
7892 (truncate:SI
7893 (lshiftrt:DI
7894 (mult:DI (zero_extend:DI
7895 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7896 (zero_extend:DI
7897 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7898 (const_int 32))))
7899 (clobber (match_scratch:SI 3 "=1"))
7900 (clobber (reg:CC FLAGS_REG))]
7901 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7902 "mul{l}\t%2"
7903 [(set_attr "type" "imul")
7904 (set_attr "length_immediate" "0")
7905 (set (attr "athlon_decode")
7906 (if_then_else (eq_attr "cpu" "athlon")
7907 (const_string "vector")
7908 (const_string "double")))
7909 (set_attr "amdfam10_decode" "double")
7910 (set_attr "mode" "SI")])
7911
7912 (define_insn "*umulsi3_highpart_zext"
7913 [(set (match_operand:DI 0 "register_operand" "=d")
7914 (zero_extend:DI (truncate:SI
7915 (lshiftrt:DI
7916 (mult:DI (zero_extend:DI
7917 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7918 (zero_extend:DI
7919 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7920 (const_int 32)))))
7921 (clobber (match_scratch:SI 3 "=1"))
7922 (clobber (reg:CC FLAGS_REG))]
7923 "TARGET_64BIT
7924 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7925 "mul{l}\t%2"
7926 [(set_attr "type" "imul")
7927 (set_attr "length_immediate" "0")
7928 (set (attr "athlon_decode")
7929 (if_then_else (eq_attr "cpu" "athlon")
7930 (const_string "vector")
7931 (const_string "double")))
7932 (set_attr "amdfam10_decode" "double")
7933 (set_attr "mode" "SI")])
7934
7935 (define_expand "smuldi3_highpart"
7936 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7937 (truncate:DI
7938 (lshiftrt:TI
7939 (mult:TI (sign_extend:TI
7940 (match_operand:DI 1 "nonimmediate_operand" ""))
7941 (sign_extend:TI
7942 (match_operand:DI 2 "register_operand" "")))
7943 (const_int 64))))
7944 (clobber (match_scratch:DI 3 ""))
7945 (clobber (reg:CC FLAGS_REG))])]
7946 "TARGET_64BIT"
7947 "")
7948
7949 (define_insn "*smuldi3_highpart_rex64"
7950 [(set (match_operand:DI 0 "register_operand" "=d")
7951 (truncate:DI
7952 (lshiftrt:TI
7953 (mult:TI (sign_extend:TI
7954 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7955 (sign_extend:TI
7956 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7957 (const_int 64))))
7958 (clobber (match_scratch:DI 3 "=1"))
7959 (clobber (reg:CC FLAGS_REG))]
7960 "TARGET_64BIT
7961 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7962 "imul{q}\t%2"
7963 [(set_attr "type" "imul")
7964 (set (attr "athlon_decode")
7965 (if_then_else (eq_attr "cpu" "athlon")
7966 (const_string "vector")
7967 (const_string "double")))
7968 (set_attr "amdfam10_decode" "double")
7969 (set_attr "mode" "DI")])
7970
7971 (define_expand "smulsi3_highpart"
7972 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7973 (truncate:SI
7974 (lshiftrt:DI
7975 (mult:DI (sign_extend:DI
7976 (match_operand:SI 1 "nonimmediate_operand" ""))
7977 (sign_extend:DI
7978 (match_operand:SI 2 "register_operand" "")))
7979 (const_int 32))))
7980 (clobber (match_scratch:SI 3 ""))
7981 (clobber (reg:CC FLAGS_REG))])]
7982 ""
7983 "")
7984
7985 (define_insn "*smulsi3_highpart_insn"
7986 [(set (match_operand:SI 0 "register_operand" "=d")
7987 (truncate:SI
7988 (lshiftrt:DI
7989 (mult:DI (sign_extend:DI
7990 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7991 (sign_extend:DI
7992 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7993 (const_int 32))))
7994 (clobber (match_scratch:SI 3 "=1"))
7995 (clobber (reg:CC FLAGS_REG))]
7996 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7997 "imul{l}\t%2"
7998 [(set_attr "type" "imul")
7999 (set (attr "athlon_decode")
8000 (if_then_else (eq_attr "cpu" "athlon")
8001 (const_string "vector")
8002 (const_string "double")))
8003 (set_attr "amdfam10_decode" "double")
8004 (set_attr "mode" "SI")])
8005
8006 (define_insn "*smulsi3_highpart_zext"
8007 [(set (match_operand:DI 0 "register_operand" "=d")
8008 (zero_extend:DI (truncate:SI
8009 (lshiftrt:DI
8010 (mult:DI (sign_extend:DI
8011 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8012 (sign_extend:DI
8013 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8014 (const_int 32)))))
8015 (clobber (match_scratch:SI 3 "=1"))
8016 (clobber (reg:CC FLAGS_REG))]
8017 "TARGET_64BIT
8018 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8019 "imul{l}\t%2"
8020 [(set_attr "type" "imul")
8021 (set (attr "athlon_decode")
8022 (if_then_else (eq_attr "cpu" "athlon")
8023 (const_string "vector")
8024 (const_string "double")))
8025 (set_attr "amdfam10_decode" "double")
8026 (set_attr "mode" "SI")])
8027
8028 ;; The patterns that match these are at the end of this file.
8029
8030 (define_expand "mulxf3"
8031 [(set (match_operand:XF 0 "register_operand" "")
8032 (mult:XF (match_operand:XF 1 "register_operand" "")
8033 (match_operand:XF 2 "register_operand" "")))]
8034 "TARGET_80387"
8035 "")
8036
8037 (define_expand "mul<mode>3"
8038 [(set (match_operand:MODEF 0 "register_operand" "")
8039 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8040 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8041 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8042 "")
8043
8044 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8045
8046 \f
8047 ;; Divide instructions
8048
8049 (define_insn "divqi3"
8050 [(set (match_operand:QI 0 "register_operand" "=a")
8051 (div:QI (match_operand:HI 1 "register_operand" "0")
8052 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8053 (clobber (reg:CC FLAGS_REG))]
8054 "TARGET_QIMODE_MATH"
8055 "idiv{b}\t%2"
8056 [(set_attr "type" "idiv")
8057 (set_attr "mode" "QI")])
8058
8059 (define_insn "udivqi3"
8060 [(set (match_operand:QI 0 "register_operand" "=a")
8061 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8062 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8063 (clobber (reg:CC FLAGS_REG))]
8064 "TARGET_QIMODE_MATH"
8065 "div{b}\t%2"
8066 [(set_attr "type" "idiv")
8067 (set_attr "mode" "QI")])
8068
8069 ;; The patterns that match these are at the end of this file.
8070
8071 (define_expand "divxf3"
8072 [(set (match_operand:XF 0 "register_operand" "")
8073 (div:XF (match_operand:XF 1 "register_operand" "")
8074 (match_operand:XF 2 "register_operand" "")))]
8075 "TARGET_80387"
8076 "")
8077
8078 (define_expand "divdf3"
8079 [(set (match_operand:DF 0 "register_operand" "")
8080 (div:DF (match_operand:DF 1 "register_operand" "")
8081 (match_operand:DF 2 "nonimmediate_operand" "")))]
8082 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8083 "")
8084
8085 (define_expand "divsf3"
8086 [(set (match_operand:SF 0 "register_operand" "")
8087 (div:SF (match_operand:SF 1 "register_operand" "")
8088 (match_operand:SF 2 "nonimmediate_operand" "")))]
8089 "TARGET_80387 || TARGET_SSE_MATH"
8090 {
8091 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8092 && flag_finite_math_only && !flag_trapping_math
8093 && flag_unsafe_math_optimizations)
8094 {
8095 ix86_emit_swdivsf (operands[0], operands[1],
8096 operands[2], SFmode);
8097 DONE;
8098 }
8099 })
8100 \f
8101 ;; Remainder instructions.
8102
8103 (define_expand "divmoddi4"
8104 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8105 (div:DI (match_operand:DI 1 "register_operand" "")
8106 (match_operand:DI 2 "nonimmediate_operand" "")))
8107 (set (match_operand:DI 3 "register_operand" "")
8108 (mod:DI (match_dup 1) (match_dup 2)))
8109 (clobber (reg:CC FLAGS_REG))])]
8110 "TARGET_64BIT"
8111 "")
8112
8113 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8114 ;; Penalize eax case slightly because it results in worse scheduling
8115 ;; of code.
8116 (define_insn "*divmoddi4_nocltd_rex64"
8117 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8118 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8119 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8120 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8121 (mod:DI (match_dup 2) (match_dup 3)))
8122 (clobber (reg:CC FLAGS_REG))]
8123 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8124 "#"
8125 [(set_attr "type" "multi")])
8126
8127 (define_insn "*divmoddi4_cltd_rex64"
8128 [(set (match_operand:DI 0 "register_operand" "=a")
8129 (div:DI (match_operand:DI 2 "register_operand" "a")
8130 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8131 (set (match_operand:DI 1 "register_operand" "=&d")
8132 (mod:DI (match_dup 2) (match_dup 3)))
8133 (clobber (reg:CC FLAGS_REG))]
8134 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8135 "#"
8136 [(set_attr "type" "multi")])
8137
8138 (define_insn "*divmoddi_noext_rex64"
8139 [(set (match_operand:DI 0 "register_operand" "=a")
8140 (div:DI (match_operand:DI 1 "register_operand" "0")
8141 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8142 (set (match_operand:DI 3 "register_operand" "=d")
8143 (mod:DI (match_dup 1) (match_dup 2)))
8144 (use (match_operand:DI 4 "register_operand" "3"))
8145 (clobber (reg:CC FLAGS_REG))]
8146 "TARGET_64BIT"
8147 "idiv{q}\t%2"
8148 [(set_attr "type" "idiv")
8149 (set_attr "mode" "DI")])
8150
8151 (define_split
8152 [(set (match_operand:DI 0 "register_operand" "")
8153 (div:DI (match_operand:DI 1 "register_operand" "")
8154 (match_operand:DI 2 "nonimmediate_operand" "")))
8155 (set (match_operand:DI 3 "register_operand" "")
8156 (mod:DI (match_dup 1) (match_dup 2)))
8157 (clobber (reg:CC FLAGS_REG))]
8158 "TARGET_64BIT && reload_completed"
8159 [(parallel [(set (match_dup 3)
8160 (ashiftrt:DI (match_dup 4) (const_int 63)))
8161 (clobber (reg:CC FLAGS_REG))])
8162 (parallel [(set (match_dup 0)
8163 (div:DI (reg:DI 0) (match_dup 2)))
8164 (set (match_dup 3)
8165 (mod:DI (reg:DI 0) (match_dup 2)))
8166 (use (match_dup 3))
8167 (clobber (reg:CC FLAGS_REG))])]
8168 {
8169 /* Avoid use of cltd in favor of a mov+shift. */
8170 if (!TARGET_USE_CLTD && !optimize_size)
8171 {
8172 if (true_regnum (operands[1]))
8173 emit_move_insn (operands[0], operands[1]);
8174 else
8175 emit_move_insn (operands[3], operands[1]);
8176 operands[4] = operands[3];
8177 }
8178 else
8179 {
8180 gcc_assert (!true_regnum (operands[1]));
8181 operands[4] = operands[1];
8182 }
8183 })
8184
8185
8186 (define_expand "divmodsi4"
8187 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8188 (div:SI (match_operand:SI 1 "register_operand" "")
8189 (match_operand:SI 2 "nonimmediate_operand" "")))
8190 (set (match_operand:SI 3 "register_operand" "")
8191 (mod:SI (match_dup 1) (match_dup 2)))
8192 (clobber (reg:CC FLAGS_REG))])]
8193 ""
8194 "")
8195
8196 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8197 ;; Penalize eax case slightly because it results in worse scheduling
8198 ;; of code.
8199 (define_insn "*divmodsi4_nocltd"
8200 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8201 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8202 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8203 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8204 (mod:SI (match_dup 2) (match_dup 3)))
8205 (clobber (reg:CC FLAGS_REG))]
8206 "!optimize_size && !TARGET_USE_CLTD"
8207 "#"
8208 [(set_attr "type" "multi")])
8209
8210 (define_insn "*divmodsi4_cltd"
8211 [(set (match_operand:SI 0 "register_operand" "=a")
8212 (div:SI (match_operand:SI 2 "register_operand" "a")
8213 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8214 (set (match_operand:SI 1 "register_operand" "=&d")
8215 (mod:SI (match_dup 2) (match_dup 3)))
8216 (clobber (reg:CC FLAGS_REG))]
8217 "optimize_size || TARGET_USE_CLTD"
8218 "#"
8219 [(set_attr "type" "multi")])
8220
8221 (define_insn "*divmodsi_noext"
8222 [(set (match_operand:SI 0 "register_operand" "=a")
8223 (div:SI (match_operand:SI 1 "register_operand" "0")
8224 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8225 (set (match_operand:SI 3 "register_operand" "=d")
8226 (mod:SI (match_dup 1) (match_dup 2)))
8227 (use (match_operand:SI 4 "register_operand" "3"))
8228 (clobber (reg:CC FLAGS_REG))]
8229 ""
8230 "idiv{l}\t%2"
8231 [(set_attr "type" "idiv")
8232 (set_attr "mode" "SI")])
8233
8234 (define_split
8235 [(set (match_operand:SI 0 "register_operand" "")
8236 (div:SI (match_operand:SI 1 "register_operand" "")
8237 (match_operand:SI 2 "nonimmediate_operand" "")))
8238 (set (match_operand:SI 3 "register_operand" "")
8239 (mod:SI (match_dup 1) (match_dup 2)))
8240 (clobber (reg:CC FLAGS_REG))]
8241 "reload_completed"
8242 [(parallel [(set (match_dup 3)
8243 (ashiftrt:SI (match_dup 4) (const_int 31)))
8244 (clobber (reg:CC FLAGS_REG))])
8245 (parallel [(set (match_dup 0)
8246 (div:SI (reg:SI 0) (match_dup 2)))
8247 (set (match_dup 3)
8248 (mod:SI (reg:SI 0) (match_dup 2)))
8249 (use (match_dup 3))
8250 (clobber (reg:CC FLAGS_REG))])]
8251 {
8252 /* Avoid use of cltd in favor of a mov+shift. */
8253 if (!TARGET_USE_CLTD && !optimize_size)
8254 {
8255 if (true_regnum (operands[1]))
8256 emit_move_insn (operands[0], operands[1]);
8257 else
8258 emit_move_insn (operands[3], operands[1]);
8259 operands[4] = operands[3];
8260 }
8261 else
8262 {
8263 gcc_assert (!true_regnum (operands[1]));
8264 operands[4] = operands[1];
8265 }
8266 })
8267 ;; %%% Split me.
8268 (define_insn "divmodhi4"
8269 [(set (match_operand:HI 0 "register_operand" "=a")
8270 (div:HI (match_operand:HI 1 "register_operand" "0")
8271 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8272 (set (match_operand:HI 3 "register_operand" "=&d")
8273 (mod:HI (match_dup 1) (match_dup 2)))
8274 (clobber (reg:CC FLAGS_REG))]
8275 "TARGET_HIMODE_MATH"
8276 "cwtd\;idiv{w}\t%2"
8277 [(set_attr "type" "multi")
8278 (set_attr "length_immediate" "0")
8279 (set_attr "mode" "SI")])
8280
8281 (define_insn "udivmoddi4"
8282 [(set (match_operand:DI 0 "register_operand" "=a")
8283 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8284 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8285 (set (match_operand:DI 3 "register_operand" "=&d")
8286 (umod:DI (match_dup 1) (match_dup 2)))
8287 (clobber (reg:CC FLAGS_REG))]
8288 "TARGET_64BIT"
8289 "xor{q}\t%3, %3\;div{q}\t%2"
8290 [(set_attr "type" "multi")
8291 (set_attr "length_immediate" "0")
8292 (set_attr "mode" "DI")])
8293
8294 (define_insn "*udivmoddi4_noext"
8295 [(set (match_operand:DI 0 "register_operand" "=a")
8296 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8297 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8298 (set (match_operand:DI 3 "register_operand" "=d")
8299 (umod:DI (match_dup 1) (match_dup 2)))
8300 (use (match_dup 3))
8301 (clobber (reg:CC FLAGS_REG))]
8302 "TARGET_64BIT"
8303 "div{q}\t%2"
8304 [(set_attr "type" "idiv")
8305 (set_attr "mode" "DI")])
8306
8307 (define_split
8308 [(set (match_operand:DI 0 "register_operand" "")
8309 (udiv:DI (match_operand:DI 1 "register_operand" "")
8310 (match_operand:DI 2 "nonimmediate_operand" "")))
8311 (set (match_operand:DI 3 "register_operand" "")
8312 (umod:DI (match_dup 1) (match_dup 2)))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "TARGET_64BIT && reload_completed"
8315 [(set (match_dup 3) (const_int 0))
8316 (parallel [(set (match_dup 0)
8317 (udiv:DI (match_dup 1) (match_dup 2)))
8318 (set (match_dup 3)
8319 (umod:DI (match_dup 1) (match_dup 2)))
8320 (use (match_dup 3))
8321 (clobber (reg:CC FLAGS_REG))])]
8322 "")
8323
8324 (define_insn "udivmodsi4"
8325 [(set (match_operand:SI 0 "register_operand" "=a")
8326 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8327 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8328 (set (match_operand:SI 3 "register_operand" "=&d")
8329 (umod:SI (match_dup 1) (match_dup 2)))
8330 (clobber (reg:CC FLAGS_REG))]
8331 ""
8332 "xor{l}\t%3, %3\;div{l}\t%2"
8333 [(set_attr "type" "multi")
8334 (set_attr "length_immediate" "0")
8335 (set_attr "mode" "SI")])
8336
8337 (define_insn "*udivmodsi4_noext"
8338 [(set (match_operand:SI 0 "register_operand" "=a")
8339 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8340 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8341 (set (match_operand:SI 3 "register_operand" "=d")
8342 (umod:SI (match_dup 1) (match_dup 2)))
8343 (use (match_dup 3))
8344 (clobber (reg:CC FLAGS_REG))]
8345 ""
8346 "div{l}\t%2"
8347 [(set_attr "type" "idiv")
8348 (set_attr "mode" "SI")])
8349
8350 (define_split
8351 [(set (match_operand:SI 0 "register_operand" "")
8352 (udiv:SI (match_operand:SI 1 "register_operand" "")
8353 (match_operand:SI 2 "nonimmediate_operand" "")))
8354 (set (match_operand:SI 3 "register_operand" "")
8355 (umod:SI (match_dup 1) (match_dup 2)))
8356 (clobber (reg:CC FLAGS_REG))]
8357 "reload_completed"
8358 [(set (match_dup 3) (const_int 0))
8359 (parallel [(set (match_dup 0)
8360 (udiv:SI (match_dup 1) (match_dup 2)))
8361 (set (match_dup 3)
8362 (umod:SI (match_dup 1) (match_dup 2)))
8363 (use (match_dup 3))
8364 (clobber (reg:CC FLAGS_REG))])]
8365 "")
8366
8367 (define_expand "udivmodhi4"
8368 [(set (match_dup 4) (const_int 0))
8369 (parallel [(set (match_operand:HI 0 "register_operand" "")
8370 (udiv:HI (match_operand:HI 1 "register_operand" "")
8371 (match_operand:HI 2 "nonimmediate_operand" "")))
8372 (set (match_operand:HI 3 "register_operand" "")
8373 (umod:HI (match_dup 1) (match_dup 2)))
8374 (use (match_dup 4))
8375 (clobber (reg:CC FLAGS_REG))])]
8376 "TARGET_HIMODE_MATH"
8377 "operands[4] = gen_reg_rtx (HImode);")
8378
8379 (define_insn "*udivmodhi_noext"
8380 [(set (match_operand:HI 0 "register_operand" "=a")
8381 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8382 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8383 (set (match_operand:HI 3 "register_operand" "=d")
8384 (umod:HI (match_dup 1) (match_dup 2)))
8385 (use (match_operand:HI 4 "register_operand" "3"))
8386 (clobber (reg:CC FLAGS_REG))]
8387 ""
8388 "div{w}\t%2"
8389 [(set_attr "type" "idiv")
8390 (set_attr "mode" "HI")])
8391
8392 ;; We cannot use div/idiv for double division, because it causes
8393 ;; "division by zero" on the overflow and that's not what we expect
8394 ;; from truncate. Because true (non truncating) double division is
8395 ;; never generated, we can't create this insn anyway.
8396 ;
8397 ;(define_insn ""
8398 ; [(set (match_operand:SI 0 "register_operand" "=a")
8399 ; (truncate:SI
8400 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8401 ; (zero_extend:DI
8402 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8403 ; (set (match_operand:SI 3 "register_operand" "=d")
8404 ; (truncate:SI
8405 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8406 ; (clobber (reg:CC FLAGS_REG))]
8407 ; ""
8408 ; "div{l}\t{%2, %0|%0, %2}"
8409 ; [(set_attr "type" "idiv")])
8410 \f
8411 ;;- Logical AND instructions
8412
8413 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8414 ;; Note that this excludes ah.
8415
8416 (define_insn "*testdi_1_rex64"
8417 [(set (reg FLAGS_REG)
8418 (compare
8419 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8420 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8421 (const_int 0)))]
8422 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8423 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8424 "@
8425 test{l}\t{%k1, %k0|%k0, %k1}
8426 test{l}\t{%k1, %k0|%k0, %k1}
8427 test{q}\t{%1, %0|%0, %1}
8428 test{q}\t{%1, %0|%0, %1}
8429 test{q}\t{%1, %0|%0, %1}"
8430 [(set_attr "type" "test")
8431 (set_attr "modrm" "0,1,0,1,1")
8432 (set_attr "mode" "SI,SI,DI,DI,DI")
8433 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8434
8435 (define_insn "testsi_1"
8436 [(set (reg FLAGS_REG)
8437 (compare
8438 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8439 (match_operand:SI 1 "general_operand" "in,in,rin"))
8440 (const_int 0)))]
8441 "ix86_match_ccmode (insn, CCNOmode)
8442 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8443 "test{l}\t{%1, %0|%0, %1}"
8444 [(set_attr "type" "test")
8445 (set_attr "modrm" "0,1,1")
8446 (set_attr "mode" "SI")
8447 (set_attr "pent_pair" "uv,np,uv")])
8448
8449 (define_expand "testsi_ccno_1"
8450 [(set (reg:CCNO FLAGS_REG)
8451 (compare:CCNO
8452 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8453 (match_operand:SI 1 "nonmemory_operand" ""))
8454 (const_int 0)))]
8455 ""
8456 "")
8457
8458 (define_insn "*testhi_1"
8459 [(set (reg FLAGS_REG)
8460 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8461 (match_operand:HI 1 "general_operand" "n,n,rn"))
8462 (const_int 0)))]
8463 "ix86_match_ccmode (insn, CCNOmode)
8464 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8465 "test{w}\t{%1, %0|%0, %1}"
8466 [(set_attr "type" "test")
8467 (set_attr "modrm" "0,1,1")
8468 (set_attr "mode" "HI")
8469 (set_attr "pent_pair" "uv,np,uv")])
8470
8471 (define_expand "testqi_ccz_1"
8472 [(set (reg:CCZ FLAGS_REG)
8473 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8474 (match_operand:QI 1 "nonmemory_operand" ""))
8475 (const_int 0)))]
8476 ""
8477 "")
8478
8479 (define_insn "*testqi_1_maybe_si"
8480 [(set (reg FLAGS_REG)
8481 (compare
8482 (and:QI
8483 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8484 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8485 (const_int 0)))]
8486 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8487 && ix86_match_ccmode (insn,
8488 CONST_INT_P (operands[1])
8489 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8490 {
8491 if (which_alternative == 3)
8492 {
8493 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8494 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8495 return "test{l}\t{%1, %k0|%k0, %1}";
8496 }
8497 return "test{b}\t{%1, %0|%0, %1}";
8498 }
8499 [(set_attr "type" "test")
8500 (set_attr "modrm" "0,1,1,1")
8501 (set_attr "mode" "QI,QI,QI,SI")
8502 (set_attr "pent_pair" "uv,np,uv,np")])
8503
8504 (define_insn "*testqi_1"
8505 [(set (reg FLAGS_REG)
8506 (compare
8507 (and:QI
8508 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8509 (match_operand:QI 1 "general_operand" "n,n,qn"))
8510 (const_int 0)))]
8511 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8512 && ix86_match_ccmode (insn, CCNOmode)"
8513 "test{b}\t{%1, %0|%0, %1}"
8514 [(set_attr "type" "test")
8515 (set_attr "modrm" "0,1,1")
8516 (set_attr "mode" "QI")
8517 (set_attr "pent_pair" "uv,np,uv")])
8518
8519 (define_expand "testqi_ext_ccno_0"
8520 [(set (reg:CCNO FLAGS_REG)
8521 (compare:CCNO
8522 (and:SI
8523 (zero_extract:SI
8524 (match_operand 0 "ext_register_operand" "")
8525 (const_int 8)
8526 (const_int 8))
8527 (match_operand 1 "const_int_operand" ""))
8528 (const_int 0)))]
8529 ""
8530 "")
8531
8532 (define_insn "*testqi_ext_0"
8533 [(set (reg FLAGS_REG)
8534 (compare
8535 (and:SI
8536 (zero_extract:SI
8537 (match_operand 0 "ext_register_operand" "Q")
8538 (const_int 8)
8539 (const_int 8))
8540 (match_operand 1 "const_int_operand" "n"))
8541 (const_int 0)))]
8542 "ix86_match_ccmode (insn, CCNOmode)"
8543 "test{b}\t{%1, %h0|%h0, %1}"
8544 [(set_attr "type" "test")
8545 (set_attr "mode" "QI")
8546 (set_attr "length_immediate" "1")
8547 (set_attr "pent_pair" "np")])
8548
8549 (define_insn "*testqi_ext_1"
8550 [(set (reg FLAGS_REG)
8551 (compare
8552 (and:SI
8553 (zero_extract:SI
8554 (match_operand 0 "ext_register_operand" "Q")
8555 (const_int 8)
8556 (const_int 8))
8557 (zero_extend:SI
8558 (match_operand:QI 1 "general_operand" "Qm")))
8559 (const_int 0)))]
8560 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8561 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8562 "test{b}\t{%1, %h0|%h0, %1}"
8563 [(set_attr "type" "test")
8564 (set_attr "mode" "QI")])
8565
8566 (define_insn "*testqi_ext_1_rex64"
8567 [(set (reg FLAGS_REG)
8568 (compare
8569 (and:SI
8570 (zero_extract:SI
8571 (match_operand 0 "ext_register_operand" "Q")
8572 (const_int 8)
8573 (const_int 8))
8574 (zero_extend:SI
8575 (match_operand:QI 1 "register_operand" "Q")))
8576 (const_int 0)))]
8577 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8578 "test{b}\t{%1, %h0|%h0, %1}"
8579 [(set_attr "type" "test")
8580 (set_attr "mode" "QI")])
8581
8582 (define_insn "*testqi_ext_2"
8583 [(set (reg FLAGS_REG)
8584 (compare
8585 (and:SI
8586 (zero_extract:SI
8587 (match_operand 0 "ext_register_operand" "Q")
8588 (const_int 8)
8589 (const_int 8))
8590 (zero_extract:SI
8591 (match_operand 1 "ext_register_operand" "Q")
8592 (const_int 8)
8593 (const_int 8)))
8594 (const_int 0)))]
8595 "ix86_match_ccmode (insn, CCNOmode)"
8596 "test{b}\t{%h1, %h0|%h0, %h1}"
8597 [(set_attr "type" "test")
8598 (set_attr "mode" "QI")])
8599
8600 ;; Combine likes to form bit extractions for some tests. Humor it.
8601 (define_insn "*testqi_ext_3"
8602 [(set (reg FLAGS_REG)
8603 (compare (zero_extract:SI
8604 (match_operand 0 "nonimmediate_operand" "rm")
8605 (match_operand:SI 1 "const_int_operand" "")
8606 (match_operand:SI 2 "const_int_operand" ""))
8607 (const_int 0)))]
8608 "ix86_match_ccmode (insn, CCNOmode)
8609 && INTVAL (operands[1]) > 0
8610 && INTVAL (operands[2]) >= 0
8611 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8612 && (GET_MODE (operands[0]) == SImode
8613 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8614 || GET_MODE (operands[0]) == HImode
8615 || GET_MODE (operands[0]) == QImode)"
8616 "#")
8617
8618 (define_insn "*testqi_ext_3_rex64"
8619 [(set (reg FLAGS_REG)
8620 (compare (zero_extract:DI
8621 (match_operand 0 "nonimmediate_operand" "rm")
8622 (match_operand:DI 1 "const_int_operand" "")
8623 (match_operand:DI 2 "const_int_operand" ""))
8624 (const_int 0)))]
8625 "TARGET_64BIT
8626 && ix86_match_ccmode (insn, CCNOmode)
8627 && INTVAL (operands[1]) > 0
8628 && INTVAL (operands[2]) >= 0
8629 /* Ensure that resulting mask is zero or sign extended operand. */
8630 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8631 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8632 && INTVAL (operands[1]) > 32))
8633 && (GET_MODE (operands[0]) == SImode
8634 || GET_MODE (operands[0]) == DImode
8635 || GET_MODE (operands[0]) == HImode
8636 || GET_MODE (operands[0]) == QImode)"
8637 "#")
8638
8639 (define_split
8640 [(set (match_operand 0 "flags_reg_operand" "")
8641 (match_operator 1 "compare_operator"
8642 [(zero_extract
8643 (match_operand 2 "nonimmediate_operand" "")
8644 (match_operand 3 "const_int_operand" "")
8645 (match_operand 4 "const_int_operand" ""))
8646 (const_int 0)]))]
8647 "ix86_match_ccmode (insn, CCNOmode)"
8648 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8649 {
8650 rtx val = operands[2];
8651 HOST_WIDE_INT len = INTVAL (operands[3]);
8652 HOST_WIDE_INT pos = INTVAL (operands[4]);
8653 HOST_WIDE_INT mask;
8654 enum machine_mode mode, submode;
8655
8656 mode = GET_MODE (val);
8657 if (MEM_P (val))
8658 {
8659 /* ??? Combine likes to put non-volatile mem extractions in QImode
8660 no matter the size of the test. So find a mode that works. */
8661 if (! MEM_VOLATILE_P (val))
8662 {
8663 mode = smallest_mode_for_size (pos + len, MODE_INT);
8664 val = adjust_address (val, mode, 0);
8665 }
8666 }
8667 else if (GET_CODE (val) == SUBREG
8668 && (submode = GET_MODE (SUBREG_REG (val)),
8669 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8670 && pos + len <= GET_MODE_BITSIZE (submode))
8671 {
8672 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8673 mode = submode;
8674 val = SUBREG_REG (val);
8675 }
8676 else if (mode == HImode && pos + len <= 8)
8677 {
8678 /* Small HImode tests can be converted to QImode. */
8679 mode = QImode;
8680 val = gen_lowpart (QImode, val);
8681 }
8682
8683 if (len == HOST_BITS_PER_WIDE_INT)
8684 mask = -1;
8685 else
8686 mask = ((HOST_WIDE_INT)1 << len) - 1;
8687 mask <<= pos;
8688
8689 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8690 })
8691
8692 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8693 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8694 ;; this is relatively important trick.
8695 ;; Do the conversion only post-reload to avoid limiting of the register class
8696 ;; to QI regs.
8697 (define_split
8698 [(set (match_operand 0 "flags_reg_operand" "")
8699 (match_operator 1 "compare_operator"
8700 [(and (match_operand 2 "register_operand" "")
8701 (match_operand 3 "const_int_operand" ""))
8702 (const_int 0)]))]
8703 "reload_completed
8704 && QI_REG_P (operands[2])
8705 && GET_MODE (operands[2]) != QImode
8706 && ((ix86_match_ccmode (insn, CCZmode)
8707 && !(INTVAL (operands[3]) & ~(255 << 8)))
8708 || (ix86_match_ccmode (insn, CCNOmode)
8709 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8710 [(set (match_dup 0)
8711 (match_op_dup 1
8712 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8713 (match_dup 3))
8714 (const_int 0)]))]
8715 "operands[2] = gen_lowpart (SImode, operands[2]);
8716 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8717
8718 (define_split
8719 [(set (match_operand 0 "flags_reg_operand" "")
8720 (match_operator 1 "compare_operator"
8721 [(and (match_operand 2 "nonimmediate_operand" "")
8722 (match_operand 3 "const_int_operand" ""))
8723 (const_int 0)]))]
8724 "reload_completed
8725 && GET_MODE (operands[2]) != QImode
8726 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8727 && ((ix86_match_ccmode (insn, CCZmode)
8728 && !(INTVAL (operands[3]) & ~255))
8729 || (ix86_match_ccmode (insn, CCNOmode)
8730 && !(INTVAL (operands[3]) & ~127)))"
8731 [(set (match_dup 0)
8732 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8733 (const_int 0)]))]
8734 "operands[2] = gen_lowpart (QImode, operands[2]);
8735 operands[3] = gen_lowpart (QImode, operands[3]);")
8736
8737
8738 ;; %%% This used to optimize known byte-wide and operations to memory,
8739 ;; and sometimes to QImode registers. If this is considered useful,
8740 ;; it should be done with splitters.
8741
8742 (define_expand "anddi3"
8743 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8744 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8745 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8746 (clobber (reg:CC FLAGS_REG))]
8747 "TARGET_64BIT"
8748 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8749
8750 (define_insn "*anddi_1_rex64"
8751 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8752 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8753 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8754 (clobber (reg:CC FLAGS_REG))]
8755 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8756 {
8757 switch (get_attr_type (insn))
8758 {
8759 case TYPE_IMOVX:
8760 {
8761 enum machine_mode mode;
8762
8763 gcc_assert (CONST_INT_P (operands[2]));
8764 if (INTVAL (operands[2]) == 0xff)
8765 mode = QImode;
8766 else
8767 {
8768 gcc_assert (INTVAL (operands[2]) == 0xffff);
8769 mode = HImode;
8770 }
8771
8772 operands[1] = gen_lowpart (mode, operands[1]);
8773 if (mode == QImode)
8774 return "movz{bq|x}\t{%1,%0|%0, %1}";
8775 else
8776 return "movz{wq|x}\t{%1,%0|%0, %1}";
8777 }
8778
8779 default:
8780 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8781 if (get_attr_mode (insn) == MODE_SI)
8782 return "and{l}\t{%k2, %k0|%k0, %k2}";
8783 else
8784 return "and{q}\t{%2, %0|%0, %2}";
8785 }
8786 }
8787 [(set_attr "type" "alu,alu,alu,imovx")
8788 (set_attr "length_immediate" "*,*,*,0")
8789 (set_attr "mode" "SI,DI,DI,DI")])
8790
8791 (define_insn "*anddi_2"
8792 [(set (reg FLAGS_REG)
8793 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8794 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8795 (const_int 0)))
8796 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8797 (and:DI (match_dup 1) (match_dup 2)))]
8798 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8799 && ix86_binary_operator_ok (AND, DImode, operands)"
8800 "@
8801 and{l}\t{%k2, %k0|%k0, %k2}
8802 and{q}\t{%2, %0|%0, %2}
8803 and{q}\t{%2, %0|%0, %2}"
8804 [(set_attr "type" "alu")
8805 (set_attr "mode" "SI,DI,DI")])
8806
8807 (define_expand "andsi3"
8808 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8809 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8810 (match_operand:SI 2 "general_operand" "")))
8811 (clobber (reg:CC FLAGS_REG))]
8812 ""
8813 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8814
8815 (define_insn "*andsi_1"
8816 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8817 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8818 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8819 (clobber (reg:CC FLAGS_REG))]
8820 "ix86_binary_operator_ok (AND, SImode, operands)"
8821 {
8822 switch (get_attr_type (insn))
8823 {
8824 case TYPE_IMOVX:
8825 {
8826 enum machine_mode mode;
8827
8828 gcc_assert (CONST_INT_P (operands[2]));
8829 if (INTVAL (operands[2]) == 0xff)
8830 mode = QImode;
8831 else
8832 {
8833 gcc_assert (INTVAL (operands[2]) == 0xffff);
8834 mode = HImode;
8835 }
8836
8837 operands[1] = gen_lowpart (mode, operands[1]);
8838 if (mode == QImode)
8839 return "movz{bl|x}\t{%1,%0|%0, %1}";
8840 else
8841 return "movz{wl|x}\t{%1,%0|%0, %1}";
8842 }
8843
8844 default:
8845 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8846 return "and{l}\t{%2, %0|%0, %2}";
8847 }
8848 }
8849 [(set_attr "type" "alu,alu,imovx")
8850 (set_attr "length_immediate" "*,*,0")
8851 (set_attr "mode" "SI")])
8852
8853 (define_split
8854 [(set (match_operand 0 "register_operand" "")
8855 (and (match_dup 0)
8856 (const_int -65536)))
8857 (clobber (reg:CC FLAGS_REG))]
8858 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8859 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8860 "operands[1] = gen_lowpart (HImode, operands[0]);")
8861
8862 (define_split
8863 [(set (match_operand 0 "ext_register_operand" "")
8864 (and (match_dup 0)
8865 (const_int -256)))
8866 (clobber (reg:CC FLAGS_REG))]
8867 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8868 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8869 "operands[1] = gen_lowpart (QImode, operands[0]);")
8870
8871 (define_split
8872 [(set (match_operand 0 "ext_register_operand" "")
8873 (and (match_dup 0)
8874 (const_int -65281)))
8875 (clobber (reg:CC FLAGS_REG))]
8876 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8877 [(parallel [(set (zero_extract:SI (match_dup 0)
8878 (const_int 8)
8879 (const_int 8))
8880 (xor:SI
8881 (zero_extract:SI (match_dup 0)
8882 (const_int 8)
8883 (const_int 8))
8884 (zero_extract:SI (match_dup 0)
8885 (const_int 8)
8886 (const_int 8))))
8887 (clobber (reg:CC FLAGS_REG))])]
8888 "operands[0] = gen_lowpart (SImode, operands[0]);")
8889
8890 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8891 (define_insn "*andsi_1_zext"
8892 [(set (match_operand:DI 0 "register_operand" "=r")
8893 (zero_extend:DI
8894 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8895 (match_operand:SI 2 "general_operand" "g"))))
8896 (clobber (reg:CC FLAGS_REG))]
8897 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8898 "and{l}\t{%2, %k0|%k0, %2}"
8899 [(set_attr "type" "alu")
8900 (set_attr "mode" "SI")])
8901
8902 (define_insn "*andsi_2"
8903 [(set (reg FLAGS_REG)
8904 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8905 (match_operand:SI 2 "general_operand" "g,ri"))
8906 (const_int 0)))
8907 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8908 (and:SI (match_dup 1) (match_dup 2)))]
8909 "ix86_match_ccmode (insn, CCNOmode)
8910 && ix86_binary_operator_ok (AND, SImode, operands)"
8911 "and{l}\t{%2, %0|%0, %2}"
8912 [(set_attr "type" "alu")
8913 (set_attr "mode" "SI")])
8914
8915 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8916 (define_insn "*andsi_2_zext"
8917 [(set (reg FLAGS_REG)
8918 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8919 (match_operand:SI 2 "general_operand" "g"))
8920 (const_int 0)))
8921 (set (match_operand:DI 0 "register_operand" "=r")
8922 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8923 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8924 && ix86_binary_operator_ok (AND, SImode, operands)"
8925 "and{l}\t{%2, %k0|%k0, %2}"
8926 [(set_attr "type" "alu")
8927 (set_attr "mode" "SI")])
8928
8929 (define_expand "andhi3"
8930 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8931 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8932 (match_operand:HI 2 "general_operand" "")))
8933 (clobber (reg:CC FLAGS_REG))]
8934 "TARGET_HIMODE_MATH"
8935 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8936
8937 (define_insn "*andhi_1"
8938 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8939 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8940 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8941 (clobber (reg:CC FLAGS_REG))]
8942 "ix86_binary_operator_ok (AND, HImode, operands)"
8943 {
8944 switch (get_attr_type (insn))
8945 {
8946 case TYPE_IMOVX:
8947 gcc_assert (CONST_INT_P (operands[2]));
8948 gcc_assert (INTVAL (operands[2]) == 0xff);
8949 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8950
8951 default:
8952 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8953
8954 return "and{w}\t{%2, %0|%0, %2}";
8955 }
8956 }
8957 [(set_attr "type" "alu,alu,imovx")
8958 (set_attr "length_immediate" "*,*,0")
8959 (set_attr "mode" "HI,HI,SI")])
8960
8961 (define_insn "*andhi_2"
8962 [(set (reg FLAGS_REG)
8963 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8964 (match_operand:HI 2 "general_operand" "g,ri"))
8965 (const_int 0)))
8966 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8967 (and:HI (match_dup 1) (match_dup 2)))]
8968 "ix86_match_ccmode (insn, CCNOmode)
8969 && ix86_binary_operator_ok (AND, HImode, operands)"
8970 "and{w}\t{%2, %0|%0, %2}"
8971 [(set_attr "type" "alu")
8972 (set_attr "mode" "HI")])
8973
8974 (define_expand "andqi3"
8975 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8976 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8977 (match_operand:QI 2 "general_operand" "")))
8978 (clobber (reg:CC FLAGS_REG))]
8979 "TARGET_QIMODE_MATH"
8980 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8981
8982 ;; %%% Potential partial reg stall on alternative 2. What to do?
8983 (define_insn "*andqi_1"
8984 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8985 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8986 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8987 (clobber (reg:CC FLAGS_REG))]
8988 "ix86_binary_operator_ok (AND, QImode, operands)"
8989 "@
8990 and{b}\t{%2, %0|%0, %2}
8991 and{b}\t{%2, %0|%0, %2}
8992 and{l}\t{%k2, %k0|%k0, %k2}"
8993 [(set_attr "type" "alu")
8994 (set_attr "mode" "QI,QI,SI")])
8995
8996 (define_insn "*andqi_1_slp"
8997 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8998 (and:QI (match_dup 0)
8999 (match_operand:QI 1 "general_operand" "qi,qmi")))
9000 (clobber (reg:CC FLAGS_REG))]
9001 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9002 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9003 "and{b}\t{%1, %0|%0, %1}"
9004 [(set_attr "type" "alu1")
9005 (set_attr "mode" "QI")])
9006
9007 (define_insn "*andqi_2_maybe_si"
9008 [(set (reg FLAGS_REG)
9009 (compare (and:QI
9010 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9011 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9012 (const_int 0)))
9013 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9014 (and:QI (match_dup 1) (match_dup 2)))]
9015 "ix86_binary_operator_ok (AND, QImode, operands)
9016 && ix86_match_ccmode (insn,
9017 CONST_INT_P (operands[2])
9018 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9019 {
9020 if (which_alternative == 2)
9021 {
9022 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9023 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9024 return "and{l}\t{%2, %k0|%k0, %2}";
9025 }
9026 return "and{b}\t{%2, %0|%0, %2}";
9027 }
9028 [(set_attr "type" "alu")
9029 (set_attr "mode" "QI,QI,SI")])
9030
9031 (define_insn "*andqi_2"
9032 [(set (reg FLAGS_REG)
9033 (compare (and:QI
9034 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9035 (match_operand:QI 2 "general_operand" "qim,qi"))
9036 (const_int 0)))
9037 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9038 (and:QI (match_dup 1) (match_dup 2)))]
9039 "ix86_match_ccmode (insn, CCNOmode)
9040 && ix86_binary_operator_ok (AND, QImode, operands)"
9041 "and{b}\t{%2, %0|%0, %2}"
9042 [(set_attr "type" "alu")
9043 (set_attr "mode" "QI")])
9044
9045 (define_insn "*andqi_2_slp"
9046 [(set (reg FLAGS_REG)
9047 (compare (and:QI
9048 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9049 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9050 (const_int 0)))
9051 (set (strict_low_part (match_dup 0))
9052 (and:QI (match_dup 0) (match_dup 1)))]
9053 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9054 && ix86_match_ccmode (insn, CCNOmode)
9055 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9056 "and{b}\t{%1, %0|%0, %1}"
9057 [(set_attr "type" "alu1")
9058 (set_attr "mode" "QI")])
9059
9060 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9061 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9062 ;; for a QImode operand, which of course failed.
9063
9064 (define_insn "andqi_ext_0"
9065 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9066 (const_int 8)
9067 (const_int 8))
9068 (and:SI
9069 (zero_extract:SI
9070 (match_operand 1 "ext_register_operand" "0")
9071 (const_int 8)
9072 (const_int 8))
9073 (match_operand 2 "const_int_operand" "n")))
9074 (clobber (reg:CC FLAGS_REG))]
9075 ""
9076 "and{b}\t{%2, %h0|%h0, %2}"
9077 [(set_attr "type" "alu")
9078 (set_attr "length_immediate" "1")
9079 (set_attr "mode" "QI")])
9080
9081 ;; Generated by peephole translating test to and. This shows up
9082 ;; often in fp comparisons.
9083
9084 (define_insn "*andqi_ext_0_cc"
9085 [(set (reg FLAGS_REG)
9086 (compare
9087 (and:SI
9088 (zero_extract:SI
9089 (match_operand 1 "ext_register_operand" "0")
9090 (const_int 8)
9091 (const_int 8))
9092 (match_operand 2 "const_int_operand" "n"))
9093 (const_int 0)))
9094 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9095 (const_int 8)
9096 (const_int 8))
9097 (and:SI
9098 (zero_extract:SI
9099 (match_dup 1)
9100 (const_int 8)
9101 (const_int 8))
9102 (match_dup 2)))]
9103 "ix86_match_ccmode (insn, CCNOmode)"
9104 "and{b}\t{%2, %h0|%h0, %2}"
9105 [(set_attr "type" "alu")
9106 (set_attr "length_immediate" "1")
9107 (set_attr "mode" "QI")])
9108
9109 (define_insn "*andqi_ext_1"
9110 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9111 (const_int 8)
9112 (const_int 8))
9113 (and:SI
9114 (zero_extract:SI
9115 (match_operand 1 "ext_register_operand" "0")
9116 (const_int 8)
9117 (const_int 8))
9118 (zero_extend:SI
9119 (match_operand:QI 2 "general_operand" "Qm"))))
9120 (clobber (reg:CC FLAGS_REG))]
9121 "!TARGET_64BIT"
9122 "and{b}\t{%2, %h0|%h0, %2}"
9123 [(set_attr "type" "alu")
9124 (set_attr "length_immediate" "0")
9125 (set_attr "mode" "QI")])
9126
9127 (define_insn "*andqi_ext_1_rex64"
9128 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9129 (const_int 8)
9130 (const_int 8))
9131 (and:SI
9132 (zero_extract:SI
9133 (match_operand 1 "ext_register_operand" "0")
9134 (const_int 8)
9135 (const_int 8))
9136 (zero_extend:SI
9137 (match_operand 2 "ext_register_operand" "Q"))))
9138 (clobber (reg:CC FLAGS_REG))]
9139 "TARGET_64BIT"
9140 "and{b}\t{%2, %h0|%h0, %2}"
9141 [(set_attr "type" "alu")
9142 (set_attr "length_immediate" "0")
9143 (set_attr "mode" "QI")])
9144
9145 (define_insn "*andqi_ext_2"
9146 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9147 (const_int 8)
9148 (const_int 8))
9149 (and:SI
9150 (zero_extract:SI
9151 (match_operand 1 "ext_register_operand" "%0")
9152 (const_int 8)
9153 (const_int 8))
9154 (zero_extract:SI
9155 (match_operand 2 "ext_register_operand" "Q")
9156 (const_int 8)
9157 (const_int 8))))
9158 (clobber (reg:CC FLAGS_REG))]
9159 ""
9160 "and{b}\t{%h2, %h0|%h0, %h2}"
9161 [(set_attr "type" "alu")
9162 (set_attr "length_immediate" "0")
9163 (set_attr "mode" "QI")])
9164
9165 ;; Convert wide AND instructions with immediate operand to shorter QImode
9166 ;; equivalents when possible.
9167 ;; Don't do the splitting with memory operands, since it introduces risk
9168 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9169 ;; for size, but that can (should?) be handled by generic code instead.
9170 (define_split
9171 [(set (match_operand 0 "register_operand" "")
9172 (and (match_operand 1 "register_operand" "")
9173 (match_operand 2 "const_int_operand" "")))
9174 (clobber (reg:CC FLAGS_REG))]
9175 "reload_completed
9176 && QI_REG_P (operands[0])
9177 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9178 && !(~INTVAL (operands[2]) & ~(255 << 8))
9179 && GET_MODE (operands[0]) != QImode"
9180 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9181 (and:SI (zero_extract:SI (match_dup 1)
9182 (const_int 8) (const_int 8))
9183 (match_dup 2)))
9184 (clobber (reg:CC FLAGS_REG))])]
9185 "operands[0] = gen_lowpart (SImode, operands[0]);
9186 operands[1] = gen_lowpart (SImode, operands[1]);
9187 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9188
9189 ;; Since AND can be encoded with sign extended immediate, this is only
9190 ;; profitable when 7th bit is not set.
9191 (define_split
9192 [(set (match_operand 0 "register_operand" "")
9193 (and (match_operand 1 "general_operand" "")
9194 (match_operand 2 "const_int_operand" "")))
9195 (clobber (reg:CC FLAGS_REG))]
9196 "reload_completed
9197 && ANY_QI_REG_P (operands[0])
9198 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9199 && !(~INTVAL (operands[2]) & ~255)
9200 && !(INTVAL (operands[2]) & 128)
9201 && GET_MODE (operands[0]) != QImode"
9202 [(parallel [(set (strict_low_part (match_dup 0))
9203 (and:QI (match_dup 1)
9204 (match_dup 2)))
9205 (clobber (reg:CC FLAGS_REG))])]
9206 "operands[0] = gen_lowpart (QImode, operands[0]);
9207 operands[1] = gen_lowpart (QImode, operands[1]);
9208 operands[2] = gen_lowpart (QImode, operands[2]);")
9209 \f
9210 ;; Logical inclusive OR instructions
9211
9212 ;; %%% This used to optimize known byte-wide and operations to memory.
9213 ;; If this is considered useful, it should be done with splitters.
9214
9215 (define_expand "iordi3"
9216 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9217 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9218 (match_operand:DI 2 "x86_64_general_operand" "")))
9219 (clobber (reg:CC FLAGS_REG))]
9220 "TARGET_64BIT"
9221 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9222
9223 (define_insn "*iordi_1_rex64"
9224 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9225 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9226 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9227 (clobber (reg:CC FLAGS_REG))]
9228 "TARGET_64BIT
9229 && ix86_binary_operator_ok (IOR, DImode, operands)"
9230 "or{q}\t{%2, %0|%0, %2}"
9231 [(set_attr "type" "alu")
9232 (set_attr "mode" "DI")])
9233
9234 (define_insn "*iordi_2_rex64"
9235 [(set (reg FLAGS_REG)
9236 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9237 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9238 (const_int 0)))
9239 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9240 (ior:DI (match_dup 1) (match_dup 2)))]
9241 "TARGET_64BIT
9242 && ix86_match_ccmode (insn, CCNOmode)
9243 && ix86_binary_operator_ok (IOR, DImode, operands)"
9244 "or{q}\t{%2, %0|%0, %2}"
9245 [(set_attr "type" "alu")
9246 (set_attr "mode" "DI")])
9247
9248 (define_insn "*iordi_3_rex64"
9249 [(set (reg FLAGS_REG)
9250 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9251 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9252 (const_int 0)))
9253 (clobber (match_scratch:DI 0 "=r"))]
9254 "TARGET_64BIT
9255 && ix86_match_ccmode (insn, CCNOmode)
9256 && ix86_binary_operator_ok (IOR, DImode, operands)"
9257 "or{q}\t{%2, %0|%0, %2}"
9258 [(set_attr "type" "alu")
9259 (set_attr "mode" "DI")])
9260
9261
9262 (define_expand "iorsi3"
9263 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9264 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9265 (match_operand:SI 2 "general_operand" "")))
9266 (clobber (reg:CC FLAGS_REG))]
9267 ""
9268 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9269
9270 (define_insn "*iorsi_1"
9271 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9272 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9273 (match_operand:SI 2 "general_operand" "ri,g")))
9274 (clobber (reg:CC FLAGS_REG))]
9275 "ix86_binary_operator_ok (IOR, SImode, operands)"
9276 "or{l}\t{%2, %0|%0, %2}"
9277 [(set_attr "type" "alu")
9278 (set_attr "mode" "SI")])
9279
9280 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9281 (define_insn "*iorsi_1_zext"
9282 [(set (match_operand:DI 0 "register_operand" "=r")
9283 (zero_extend:DI
9284 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9285 (match_operand:SI 2 "general_operand" "g"))))
9286 (clobber (reg:CC FLAGS_REG))]
9287 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9288 "or{l}\t{%2, %k0|%k0, %2}"
9289 [(set_attr "type" "alu")
9290 (set_attr "mode" "SI")])
9291
9292 (define_insn "*iorsi_1_zext_imm"
9293 [(set (match_operand:DI 0 "register_operand" "=r")
9294 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9295 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9296 (clobber (reg:CC FLAGS_REG))]
9297 "TARGET_64BIT"
9298 "or{l}\t{%2, %k0|%k0, %2}"
9299 [(set_attr "type" "alu")
9300 (set_attr "mode" "SI")])
9301
9302 (define_insn "*iorsi_2"
9303 [(set (reg FLAGS_REG)
9304 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9305 (match_operand:SI 2 "general_operand" "g,ri"))
9306 (const_int 0)))
9307 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9308 (ior:SI (match_dup 1) (match_dup 2)))]
9309 "ix86_match_ccmode (insn, CCNOmode)
9310 && ix86_binary_operator_ok (IOR, SImode, operands)"
9311 "or{l}\t{%2, %0|%0, %2}"
9312 [(set_attr "type" "alu")
9313 (set_attr "mode" "SI")])
9314
9315 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9316 ;; ??? Special case for immediate operand is missing - it is tricky.
9317 (define_insn "*iorsi_2_zext"
9318 [(set (reg FLAGS_REG)
9319 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9320 (match_operand:SI 2 "general_operand" "g"))
9321 (const_int 0)))
9322 (set (match_operand:DI 0 "register_operand" "=r")
9323 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9324 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9325 && ix86_binary_operator_ok (IOR, SImode, operands)"
9326 "or{l}\t{%2, %k0|%k0, %2}"
9327 [(set_attr "type" "alu")
9328 (set_attr "mode" "SI")])
9329
9330 (define_insn "*iorsi_2_zext_imm"
9331 [(set (reg FLAGS_REG)
9332 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9333 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9334 (const_int 0)))
9335 (set (match_operand:DI 0 "register_operand" "=r")
9336 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9337 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9338 && ix86_binary_operator_ok (IOR, SImode, operands)"
9339 "or{l}\t{%2, %k0|%k0, %2}"
9340 [(set_attr "type" "alu")
9341 (set_attr "mode" "SI")])
9342
9343 (define_insn "*iorsi_3"
9344 [(set (reg FLAGS_REG)
9345 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9346 (match_operand:SI 2 "general_operand" "g"))
9347 (const_int 0)))
9348 (clobber (match_scratch:SI 0 "=r"))]
9349 "ix86_match_ccmode (insn, CCNOmode)
9350 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9351 "or{l}\t{%2, %0|%0, %2}"
9352 [(set_attr "type" "alu")
9353 (set_attr "mode" "SI")])
9354
9355 (define_expand "iorhi3"
9356 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9357 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9358 (match_operand:HI 2 "general_operand" "")))
9359 (clobber (reg:CC FLAGS_REG))]
9360 "TARGET_HIMODE_MATH"
9361 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9362
9363 (define_insn "*iorhi_1"
9364 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9365 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9366 (match_operand:HI 2 "general_operand" "g,ri")))
9367 (clobber (reg:CC FLAGS_REG))]
9368 "ix86_binary_operator_ok (IOR, HImode, operands)"
9369 "or{w}\t{%2, %0|%0, %2}"
9370 [(set_attr "type" "alu")
9371 (set_attr "mode" "HI")])
9372
9373 (define_insn "*iorhi_2"
9374 [(set (reg FLAGS_REG)
9375 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9376 (match_operand:HI 2 "general_operand" "g,ri"))
9377 (const_int 0)))
9378 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9379 (ior:HI (match_dup 1) (match_dup 2)))]
9380 "ix86_match_ccmode (insn, CCNOmode)
9381 && ix86_binary_operator_ok (IOR, HImode, operands)"
9382 "or{w}\t{%2, %0|%0, %2}"
9383 [(set_attr "type" "alu")
9384 (set_attr "mode" "HI")])
9385
9386 (define_insn "*iorhi_3"
9387 [(set (reg FLAGS_REG)
9388 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9389 (match_operand:HI 2 "general_operand" "g"))
9390 (const_int 0)))
9391 (clobber (match_scratch:HI 0 "=r"))]
9392 "ix86_match_ccmode (insn, CCNOmode)
9393 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9394 "or{w}\t{%2, %0|%0, %2}"
9395 [(set_attr "type" "alu")
9396 (set_attr "mode" "HI")])
9397
9398 (define_expand "iorqi3"
9399 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9400 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9401 (match_operand:QI 2 "general_operand" "")))
9402 (clobber (reg:CC FLAGS_REG))]
9403 "TARGET_QIMODE_MATH"
9404 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9405
9406 ;; %%% Potential partial reg stall on alternative 2. What to do?
9407 (define_insn "*iorqi_1"
9408 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9409 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9410 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9411 (clobber (reg:CC FLAGS_REG))]
9412 "ix86_binary_operator_ok (IOR, QImode, operands)"
9413 "@
9414 or{b}\t{%2, %0|%0, %2}
9415 or{b}\t{%2, %0|%0, %2}
9416 or{l}\t{%k2, %k0|%k0, %k2}"
9417 [(set_attr "type" "alu")
9418 (set_attr "mode" "QI,QI,SI")])
9419
9420 (define_insn "*iorqi_1_slp"
9421 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9422 (ior:QI (match_dup 0)
9423 (match_operand:QI 1 "general_operand" "qmi,qi")))
9424 (clobber (reg:CC FLAGS_REG))]
9425 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9426 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9427 "or{b}\t{%1, %0|%0, %1}"
9428 [(set_attr "type" "alu1")
9429 (set_attr "mode" "QI")])
9430
9431 (define_insn "*iorqi_2"
9432 [(set (reg FLAGS_REG)
9433 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9434 (match_operand:QI 2 "general_operand" "qim,qi"))
9435 (const_int 0)))
9436 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9437 (ior:QI (match_dup 1) (match_dup 2)))]
9438 "ix86_match_ccmode (insn, CCNOmode)
9439 && ix86_binary_operator_ok (IOR, QImode, operands)"
9440 "or{b}\t{%2, %0|%0, %2}"
9441 [(set_attr "type" "alu")
9442 (set_attr "mode" "QI")])
9443
9444 (define_insn "*iorqi_2_slp"
9445 [(set (reg FLAGS_REG)
9446 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9447 (match_operand:QI 1 "general_operand" "qim,qi"))
9448 (const_int 0)))
9449 (set (strict_low_part (match_dup 0))
9450 (ior:QI (match_dup 0) (match_dup 1)))]
9451 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9452 && ix86_match_ccmode (insn, CCNOmode)
9453 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9454 "or{b}\t{%1, %0|%0, %1}"
9455 [(set_attr "type" "alu1")
9456 (set_attr "mode" "QI")])
9457
9458 (define_insn "*iorqi_3"
9459 [(set (reg FLAGS_REG)
9460 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9461 (match_operand:QI 2 "general_operand" "qim"))
9462 (const_int 0)))
9463 (clobber (match_scratch:QI 0 "=q"))]
9464 "ix86_match_ccmode (insn, CCNOmode)
9465 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9466 "or{b}\t{%2, %0|%0, %2}"
9467 [(set_attr "type" "alu")
9468 (set_attr "mode" "QI")])
9469
9470 (define_insn "iorqi_ext_0"
9471 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9472 (const_int 8)
9473 (const_int 8))
9474 (ior:SI
9475 (zero_extract:SI
9476 (match_operand 1 "ext_register_operand" "0")
9477 (const_int 8)
9478 (const_int 8))
9479 (match_operand 2 "const_int_operand" "n")))
9480 (clobber (reg:CC FLAGS_REG))]
9481 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9482 "or{b}\t{%2, %h0|%h0, %2}"
9483 [(set_attr "type" "alu")
9484 (set_attr "length_immediate" "1")
9485 (set_attr "mode" "QI")])
9486
9487 (define_insn "*iorqi_ext_1"
9488 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9489 (const_int 8)
9490 (const_int 8))
9491 (ior:SI
9492 (zero_extract:SI
9493 (match_operand 1 "ext_register_operand" "0")
9494 (const_int 8)
9495 (const_int 8))
9496 (zero_extend:SI
9497 (match_operand:QI 2 "general_operand" "Qm"))))
9498 (clobber (reg:CC FLAGS_REG))]
9499 "!TARGET_64BIT
9500 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9501 "or{b}\t{%2, %h0|%h0, %2}"
9502 [(set_attr "type" "alu")
9503 (set_attr "length_immediate" "0")
9504 (set_attr "mode" "QI")])
9505
9506 (define_insn "*iorqi_ext_1_rex64"
9507 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9508 (const_int 8)
9509 (const_int 8))
9510 (ior:SI
9511 (zero_extract:SI
9512 (match_operand 1 "ext_register_operand" "0")
9513 (const_int 8)
9514 (const_int 8))
9515 (zero_extend:SI
9516 (match_operand 2 "ext_register_operand" "Q"))))
9517 (clobber (reg:CC FLAGS_REG))]
9518 "TARGET_64BIT
9519 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9520 "or{b}\t{%2, %h0|%h0, %2}"
9521 [(set_attr "type" "alu")
9522 (set_attr "length_immediate" "0")
9523 (set_attr "mode" "QI")])
9524
9525 (define_insn "*iorqi_ext_2"
9526 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9527 (const_int 8)
9528 (const_int 8))
9529 (ior:SI
9530 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9531 (const_int 8)
9532 (const_int 8))
9533 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9534 (const_int 8)
9535 (const_int 8))))
9536 (clobber (reg:CC FLAGS_REG))]
9537 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9538 "ior{b}\t{%h2, %h0|%h0, %h2}"
9539 [(set_attr "type" "alu")
9540 (set_attr "length_immediate" "0")
9541 (set_attr "mode" "QI")])
9542
9543 (define_split
9544 [(set (match_operand 0 "register_operand" "")
9545 (ior (match_operand 1 "register_operand" "")
9546 (match_operand 2 "const_int_operand" "")))
9547 (clobber (reg:CC FLAGS_REG))]
9548 "reload_completed
9549 && QI_REG_P (operands[0])
9550 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9551 && !(INTVAL (operands[2]) & ~(255 << 8))
9552 && GET_MODE (operands[0]) != QImode"
9553 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9554 (ior:SI (zero_extract:SI (match_dup 1)
9555 (const_int 8) (const_int 8))
9556 (match_dup 2)))
9557 (clobber (reg:CC FLAGS_REG))])]
9558 "operands[0] = gen_lowpart (SImode, operands[0]);
9559 operands[1] = gen_lowpart (SImode, operands[1]);
9560 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9561
9562 ;; Since OR can be encoded with sign extended immediate, this is only
9563 ;; profitable when 7th bit is set.
9564 (define_split
9565 [(set (match_operand 0 "register_operand" "")
9566 (ior (match_operand 1 "general_operand" "")
9567 (match_operand 2 "const_int_operand" "")))
9568 (clobber (reg:CC FLAGS_REG))]
9569 "reload_completed
9570 && ANY_QI_REG_P (operands[0])
9571 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9572 && !(INTVAL (operands[2]) & ~255)
9573 && (INTVAL (operands[2]) & 128)
9574 && GET_MODE (operands[0]) != QImode"
9575 [(parallel [(set (strict_low_part (match_dup 0))
9576 (ior:QI (match_dup 1)
9577 (match_dup 2)))
9578 (clobber (reg:CC FLAGS_REG))])]
9579 "operands[0] = gen_lowpart (QImode, operands[0]);
9580 operands[1] = gen_lowpart (QImode, operands[1]);
9581 operands[2] = gen_lowpart (QImode, operands[2]);")
9582 \f
9583 ;; Logical XOR instructions
9584
9585 ;; %%% This used to optimize known byte-wide and operations to memory.
9586 ;; If this is considered useful, it should be done with splitters.
9587
9588 (define_expand "xordi3"
9589 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9590 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9591 (match_operand:DI 2 "x86_64_general_operand" "")))
9592 (clobber (reg:CC FLAGS_REG))]
9593 "TARGET_64BIT"
9594 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9595
9596 (define_insn "*xordi_1_rex64"
9597 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9598 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9599 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9600 (clobber (reg:CC FLAGS_REG))]
9601 "TARGET_64BIT
9602 && ix86_binary_operator_ok (XOR, DImode, operands)"
9603 "@
9604 xor{q}\t{%2, %0|%0, %2}
9605 xor{q}\t{%2, %0|%0, %2}"
9606 [(set_attr "type" "alu")
9607 (set_attr "mode" "DI,DI")])
9608
9609 (define_insn "*xordi_2_rex64"
9610 [(set (reg FLAGS_REG)
9611 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9612 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9613 (const_int 0)))
9614 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9615 (xor:DI (match_dup 1) (match_dup 2)))]
9616 "TARGET_64BIT
9617 && ix86_match_ccmode (insn, CCNOmode)
9618 && ix86_binary_operator_ok (XOR, DImode, operands)"
9619 "@
9620 xor{q}\t{%2, %0|%0, %2}
9621 xor{q}\t{%2, %0|%0, %2}"
9622 [(set_attr "type" "alu")
9623 (set_attr "mode" "DI,DI")])
9624
9625 (define_insn "*xordi_3_rex64"
9626 [(set (reg FLAGS_REG)
9627 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9628 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9629 (const_int 0)))
9630 (clobber (match_scratch:DI 0 "=r"))]
9631 "TARGET_64BIT
9632 && ix86_match_ccmode (insn, CCNOmode)
9633 && ix86_binary_operator_ok (XOR, DImode, operands)"
9634 "xor{q}\t{%2, %0|%0, %2}"
9635 [(set_attr "type" "alu")
9636 (set_attr "mode" "DI")])
9637
9638 (define_expand "xorsi3"
9639 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9640 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9641 (match_operand:SI 2 "general_operand" "")))
9642 (clobber (reg:CC FLAGS_REG))]
9643 ""
9644 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9645
9646 (define_insn "*xorsi_1"
9647 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9648 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9649 (match_operand:SI 2 "general_operand" "ri,rm")))
9650 (clobber (reg:CC FLAGS_REG))]
9651 "ix86_binary_operator_ok (XOR, SImode, operands)"
9652 "xor{l}\t{%2, %0|%0, %2}"
9653 [(set_attr "type" "alu")
9654 (set_attr "mode" "SI")])
9655
9656 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9657 ;; Add speccase for immediates
9658 (define_insn "*xorsi_1_zext"
9659 [(set (match_operand:DI 0 "register_operand" "=r")
9660 (zero_extend:DI
9661 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9662 (match_operand:SI 2 "general_operand" "g"))))
9663 (clobber (reg:CC FLAGS_REG))]
9664 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9665 "xor{l}\t{%2, %k0|%k0, %2}"
9666 [(set_attr "type" "alu")
9667 (set_attr "mode" "SI")])
9668
9669 (define_insn "*xorsi_1_zext_imm"
9670 [(set (match_operand:DI 0 "register_operand" "=r")
9671 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9672 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9673 (clobber (reg:CC FLAGS_REG))]
9674 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9675 "xor{l}\t{%2, %k0|%k0, %2}"
9676 [(set_attr "type" "alu")
9677 (set_attr "mode" "SI")])
9678
9679 (define_insn "*xorsi_2"
9680 [(set (reg FLAGS_REG)
9681 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9682 (match_operand:SI 2 "general_operand" "g,ri"))
9683 (const_int 0)))
9684 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9685 (xor:SI (match_dup 1) (match_dup 2)))]
9686 "ix86_match_ccmode (insn, CCNOmode)
9687 && ix86_binary_operator_ok (XOR, SImode, operands)"
9688 "xor{l}\t{%2, %0|%0, %2}"
9689 [(set_attr "type" "alu")
9690 (set_attr "mode" "SI")])
9691
9692 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9693 ;; ??? Special case for immediate operand is missing - it is tricky.
9694 (define_insn "*xorsi_2_zext"
9695 [(set (reg FLAGS_REG)
9696 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9697 (match_operand:SI 2 "general_operand" "g"))
9698 (const_int 0)))
9699 (set (match_operand:DI 0 "register_operand" "=r")
9700 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9701 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9702 && ix86_binary_operator_ok (XOR, SImode, operands)"
9703 "xor{l}\t{%2, %k0|%k0, %2}"
9704 [(set_attr "type" "alu")
9705 (set_attr "mode" "SI")])
9706
9707 (define_insn "*xorsi_2_zext_imm"
9708 [(set (reg FLAGS_REG)
9709 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9710 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9711 (const_int 0)))
9712 (set (match_operand:DI 0 "register_operand" "=r")
9713 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9714 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9715 && ix86_binary_operator_ok (XOR, SImode, operands)"
9716 "xor{l}\t{%2, %k0|%k0, %2}"
9717 [(set_attr "type" "alu")
9718 (set_attr "mode" "SI")])
9719
9720 (define_insn "*xorsi_3"
9721 [(set (reg FLAGS_REG)
9722 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9723 (match_operand:SI 2 "general_operand" "g"))
9724 (const_int 0)))
9725 (clobber (match_scratch:SI 0 "=r"))]
9726 "ix86_match_ccmode (insn, CCNOmode)
9727 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9728 "xor{l}\t{%2, %0|%0, %2}"
9729 [(set_attr "type" "alu")
9730 (set_attr "mode" "SI")])
9731
9732 (define_expand "xorhi3"
9733 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9734 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9735 (match_operand:HI 2 "general_operand" "")))
9736 (clobber (reg:CC FLAGS_REG))]
9737 "TARGET_HIMODE_MATH"
9738 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9739
9740 (define_insn "*xorhi_1"
9741 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9742 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9743 (match_operand:HI 2 "general_operand" "g,ri")))
9744 (clobber (reg:CC FLAGS_REG))]
9745 "ix86_binary_operator_ok (XOR, HImode, operands)"
9746 "xor{w}\t{%2, %0|%0, %2}"
9747 [(set_attr "type" "alu")
9748 (set_attr "mode" "HI")])
9749
9750 (define_insn "*xorhi_2"
9751 [(set (reg FLAGS_REG)
9752 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9753 (match_operand:HI 2 "general_operand" "g,ri"))
9754 (const_int 0)))
9755 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9756 (xor:HI (match_dup 1) (match_dup 2)))]
9757 "ix86_match_ccmode (insn, CCNOmode)
9758 && ix86_binary_operator_ok (XOR, HImode, operands)"
9759 "xor{w}\t{%2, %0|%0, %2}"
9760 [(set_attr "type" "alu")
9761 (set_attr "mode" "HI")])
9762
9763 (define_insn "*xorhi_3"
9764 [(set (reg FLAGS_REG)
9765 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9766 (match_operand:HI 2 "general_operand" "g"))
9767 (const_int 0)))
9768 (clobber (match_scratch:HI 0 "=r"))]
9769 "ix86_match_ccmode (insn, CCNOmode)
9770 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9771 "xor{w}\t{%2, %0|%0, %2}"
9772 [(set_attr "type" "alu")
9773 (set_attr "mode" "HI")])
9774
9775 (define_expand "xorqi3"
9776 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9777 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9778 (match_operand:QI 2 "general_operand" "")))
9779 (clobber (reg:CC FLAGS_REG))]
9780 "TARGET_QIMODE_MATH"
9781 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9782
9783 ;; %%% Potential partial reg stall on alternative 2. What to do?
9784 (define_insn "*xorqi_1"
9785 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9786 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9787 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9788 (clobber (reg:CC FLAGS_REG))]
9789 "ix86_binary_operator_ok (XOR, QImode, operands)"
9790 "@
9791 xor{b}\t{%2, %0|%0, %2}
9792 xor{b}\t{%2, %0|%0, %2}
9793 xor{l}\t{%k2, %k0|%k0, %k2}"
9794 [(set_attr "type" "alu")
9795 (set_attr "mode" "QI,QI,SI")])
9796
9797 (define_insn "*xorqi_1_slp"
9798 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9799 (xor:QI (match_dup 0)
9800 (match_operand:QI 1 "general_operand" "qi,qmi")))
9801 (clobber (reg:CC FLAGS_REG))]
9802 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9803 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9804 "xor{b}\t{%1, %0|%0, %1}"
9805 [(set_attr "type" "alu1")
9806 (set_attr "mode" "QI")])
9807
9808 (define_insn "xorqi_ext_0"
9809 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9810 (const_int 8)
9811 (const_int 8))
9812 (xor:SI
9813 (zero_extract:SI
9814 (match_operand 1 "ext_register_operand" "0")
9815 (const_int 8)
9816 (const_int 8))
9817 (match_operand 2 "const_int_operand" "n")))
9818 (clobber (reg:CC FLAGS_REG))]
9819 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9820 "xor{b}\t{%2, %h0|%h0, %2}"
9821 [(set_attr "type" "alu")
9822 (set_attr "length_immediate" "1")
9823 (set_attr "mode" "QI")])
9824
9825 (define_insn "*xorqi_ext_1"
9826 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9827 (const_int 8)
9828 (const_int 8))
9829 (xor:SI
9830 (zero_extract:SI
9831 (match_operand 1 "ext_register_operand" "0")
9832 (const_int 8)
9833 (const_int 8))
9834 (zero_extend:SI
9835 (match_operand:QI 2 "general_operand" "Qm"))))
9836 (clobber (reg:CC FLAGS_REG))]
9837 "!TARGET_64BIT
9838 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9839 "xor{b}\t{%2, %h0|%h0, %2}"
9840 [(set_attr "type" "alu")
9841 (set_attr "length_immediate" "0")
9842 (set_attr "mode" "QI")])
9843
9844 (define_insn "*xorqi_ext_1_rex64"
9845 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9846 (const_int 8)
9847 (const_int 8))
9848 (xor:SI
9849 (zero_extract:SI
9850 (match_operand 1 "ext_register_operand" "0")
9851 (const_int 8)
9852 (const_int 8))
9853 (zero_extend:SI
9854 (match_operand 2 "ext_register_operand" "Q"))))
9855 (clobber (reg:CC FLAGS_REG))]
9856 "TARGET_64BIT
9857 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9858 "xor{b}\t{%2, %h0|%h0, %2}"
9859 [(set_attr "type" "alu")
9860 (set_attr "length_immediate" "0")
9861 (set_attr "mode" "QI")])
9862
9863 (define_insn "*xorqi_ext_2"
9864 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9865 (const_int 8)
9866 (const_int 8))
9867 (xor:SI
9868 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9869 (const_int 8)
9870 (const_int 8))
9871 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9872 (const_int 8)
9873 (const_int 8))))
9874 (clobber (reg:CC FLAGS_REG))]
9875 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9876 "xor{b}\t{%h2, %h0|%h0, %h2}"
9877 [(set_attr "type" "alu")
9878 (set_attr "length_immediate" "0")
9879 (set_attr "mode" "QI")])
9880
9881 (define_insn "*xorqi_cc_1"
9882 [(set (reg FLAGS_REG)
9883 (compare
9884 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9885 (match_operand:QI 2 "general_operand" "qim,qi"))
9886 (const_int 0)))
9887 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9888 (xor:QI (match_dup 1) (match_dup 2)))]
9889 "ix86_match_ccmode (insn, CCNOmode)
9890 && ix86_binary_operator_ok (XOR, QImode, operands)"
9891 "xor{b}\t{%2, %0|%0, %2}"
9892 [(set_attr "type" "alu")
9893 (set_attr "mode" "QI")])
9894
9895 (define_insn "*xorqi_2_slp"
9896 [(set (reg FLAGS_REG)
9897 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9898 (match_operand:QI 1 "general_operand" "qim,qi"))
9899 (const_int 0)))
9900 (set (strict_low_part (match_dup 0))
9901 (xor:QI (match_dup 0) (match_dup 1)))]
9902 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9903 && ix86_match_ccmode (insn, CCNOmode)
9904 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9905 "xor{b}\t{%1, %0|%0, %1}"
9906 [(set_attr "type" "alu1")
9907 (set_attr "mode" "QI")])
9908
9909 (define_insn "*xorqi_cc_2"
9910 [(set (reg FLAGS_REG)
9911 (compare
9912 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9913 (match_operand:QI 2 "general_operand" "qim"))
9914 (const_int 0)))
9915 (clobber (match_scratch:QI 0 "=q"))]
9916 "ix86_match_ccmode (insn, CCNOmode)
9917 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9918 "xor{b}\t{%2, %0|%0, %2}"
9919 [(set_attr "type" "alu")
9920 (set_attr "mode" "QI")])
9921
9922 (define_insn "*xorqi_cc_ext_1"
9923 [(set (reg FLAGS_REG)
9924 (compare
9925 (xor:SI
9926 (zero_extract:SI
9927 (match_operand 1 "ext_register_operand" "0")
9928 (const_int 8)
9929 (const_int 8))
9930 (match_operand:QI 2 "general_operand" "qmn"))
9931 (const_int 0)))
9932 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9933 (const_int 8)
9934 (const_int 8))
9935 (xor:SI
9936 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9937 (match_dup 2)))]
9938 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9939 "xor{b}\t{%2, %h0|%h0, %2}"
9940 [(set_attr "type" "alu")
9941 (set_attr "mode" "QI")])
9942
9943 (define_insn "*xorqi_cc_ext_1_rex64"
9944 [(set (reg FLAGS_REG)
9945 (compare
9946 (xor:SI
9947 (zero_extract:SI
9948 (match_operand 1 "ext_register_operand" "0")
9949 (const_int 8)
9950 (const_int 8))
9951 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9952 (const_int 0)))
9953 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9954 (const_int 8)
9955 (const_int 8))
9956 (xor:SI
9957 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9958 (match_dup 2)))]
9959 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9960 "xor{b}\t{%2, %h0|%h0, %2}"
9961 [(set_attr "type" "alu")
9962 (set_attr "mode" "QI")])
9963
9964 (define_expand "xorqi_cc_ext_1"
9965 [(parallel [
9966 (set (reg:CCNO FLAGS_REG)
9967 (compare:CCNO
9968 (xor:SI
9969 (zero_extract:SI
9970 (match_operand 1 "ext_register_operand" "")
9971 (const_int 8)
9972 (const_int 8))
9973 (match_operand:QI 2 "general_operand" ""))
9974 (const_int 0)))
9975 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9976 (const_int 8)
9977 (const_int 8))
9978 (xor:SI
9979 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9980 (match_dup 2)))])]
9981 ""
9982 "")
9983
9984 (define_split
9985 [(set (match_operand 0 "register_operand" "")
9986 (xor (match_operand 1 "register_operand" "")
9987 (match_operand 2 "const_int_operand" "")))
9988 (clobber (reg:CC FLAGS_REG))]
9989 "reload_completed
9990 && QI_REG_P (operands[0])
9991 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9992 && !(INTVAL (operands[2]) & ~(255 << 8))
9993 && GET_MODE (operands[0]) != QImode"
9994 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9995 (xor:SI (zero_extract:SI (match_dup 1)
9996 (const_int 8) (const_int 8))
9997 (match_dup 2)))
9998 (clobber (reg:CC FLAGS_REG))])]
9999 "operands[0] = gen_lowpart (SImode, operands[0]);
10000 operands[1] = gen_lowpart (SImode, operands[1]);
10001 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10002
10003 ;; Since XOR can be encoded with sign extended immediate, this is only
10004 ;; profitable when 7th bit is set.
10005 (define_split
10006 [(set (match_operand 0 "register_operand" "")
10007 (xor (match_operand 1 "general_operand" "")
10008 (match_operand 2 "const_int_operand" "")))
10009 (clobber (reg:CC FLAGS_REG))]
10010 "reload_completed
10011 && ANY_QI_REG_P (operands[0])
10012 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10013 && !(INTVAL (operands[2]) & ~255)
10014 && (INTVAL (operands[2]) & 128)
10015 && GET_MODE (operands[0]) != QImode"
10016 [(parallel [(set (strict_low_part (match_dup 0))
10017 (xor:QI (match_dup 1)
10018 (match_dup 2)))
10019 (clobber (reg:CC FLAGS_REG))])]
10020 "operands[0] = gen_lowpart (QImode, operands[0]);
10021 operands[1] = gen_lowpart (QImode, operands[1]);
10022 operands[2] = gen_lowpart (QImode, operands[2]);")
10023 \f
10024 ;; Negation instructions
10025
10026 (define_expand "negti2"
10027 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10028 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10029 (clobber (reg:CC FLAGS_REG))])]
10030 "TARGET_64BIT"
10031 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10032
10033 (define_insn "*negti2_1"
10034 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10035 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10036 (clobber (reg:CC FLAGS_REG))]
10037 "TARGET_64BIT
10038 && ix86_unary_operator_ok (NEG, TImode, operands)"
10039 "#")
10040
10041 (define_split
10042 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10043 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10044 (clobber (reg:CC FLAGS_REG))]
10045 "TARGET_64BIT && reload_completed"
10046 [(parallel
10047 [(set (reg:CCZ FLAGS_REG)
10048 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10049 (set (match_dup 0) (neg:DI (match_dup 2)))])
10050 (parallel
10051 [(set (match_dup 1)
10052 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10053 (match_dup 3))
10054 (const_int 0)))
10055 (clobber (reg:CC FLAGS_REG))])
10056 (parallel
10057 [(set (match_dup 1)
10058 (neg:DI (match_dup 1)))
10059 (clobber (reg:CC FLAGS_REG))])]
10060 "split_ti (operands+1, 1, operands+2, operands+3);
10061 split_ti (operands+0, 1, operands+0, operands+1);")
10062
10063 (define_expand "negdi2"
10064 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10065 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10066 (clobber (reg:CC FLAGS_REG))])]
10067 ""
10068 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10069
10070 (define_insn "*negdi2_1"
10071 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10072 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10073 (clobber (reg:CC FLAGS_REG))]
10074 "!TARGET_64BIT
10075 && ix86_unary_operator_ok (NEG, DImode, operands)"
10076 "#")
10077
10078 (define_split
10079 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10080 (neg:DI (match_operand:DI 1 "general_operand" "")))
10081 (clobber (reg:CC FLAGS_REG))]
10082 "!TARGET_64BIT && reload_completed"
10083 [(parallel
10084 [(set (reg:CCZ FLAGS_REG)
10085 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10086 (set (match_dup 0) (neg:SI (match_dup 2)))])
10087 (parallel
10088 [(set (match_dup 1)
10089 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10090 (match_dup 3))
10091 (const_int 0)))
10092 (clobber (reg:CC FLAGS_REG))])
10093 (parallel
10094 [(set (match_dup 1)
10095 (neg:SI (match_dup 1)))
10096 (clobber (reg:CC FLAGS_REG))])]
10097 "split_di (operands+1, 1, operands+2, operands+3);
10098 split_di (operands+0, 1, operands+0, operands+1);")
10099
10100 (define_insn "*negdi2_1_rex64"
10101 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10102 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10103 (clobber (reg:CC FLAGS_REG))]
10104 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10105 "neg{q}\t%0"
10106 [(set_attr "type" "negnot")
10107 (set_attr "mode" "DI")])
10108
10109 ;; The problem with neg is that it does not perform (compare x 0),
10110 ;; it really performs (compare 0 x), which leaves us with the zero
10111 ;; flag being the only useful item.
10112
10113 (define_insn "*negdi2_cmpz_rex64"
10114 [(set (reg:CCZ FLAGS_REG)
10115 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10116 (const_int 0)))
10117 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10118 (neg:DI (match_dup 1)))]
10119 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10120 "neg{q}\t%0"
10121 [(set_attr "type" "negnot")
10122 (set_attr "mode" "DI")])
10123
10124
10125 (define_expand "negsi2"
10126 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10127 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10128 (clobber (reg:CC FLAGS_REG))])]
10129 ""
10130 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10131
10132 (define_insn "*negsi2_1"
10133 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10134 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10135 (clobber (reg:CC FLAGS_REG))]
10136 "ix86_unary_operator_ok (NEG, SImode, operands)"
10137 "neg{l}\t%0"
10138 [(set_attr "type" "negnot")
10139 (set_attr "mode" "SI")])
10140
10141 ;; Combine is quite creative about this pattern.
10142 (define_insn "*negsi2_1_zext"
10143 [(set (match_operand:DI 0 "register_operand" "=r")
10144 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10145 (const_int 32)))
10146 (const_int 32)))
10147 (clobber (reg:CC FLAGS_REG))]
10148 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10149 "neg{l}\t%k0"
10150 [(set_attr "type" "negnot")
10151 (set_attr "mode" "SI")])
10152
10153 ;; The problem with neg is that it does not perform (compare x 0),
10154 ;; it really performs (compare 0 x), which leaves us with the zero
10155 ;; flag being the only useful item.
10156
10157 (define_insn "*negsi2_cmpz"
10158 [(set (reg:CCZ FLAGS_REG)
10159 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10160 (const_int 0)))
10161 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10162 (neg:SI (match_dup 1)))]
10163 "ix86_unary_operator_ok (NEG, SImode, operands)"
10164 "neg{l}\t%0"
10165 [(set_attr "type" "negnot")
10166 (set_attr "mode" "SI")])
10167
10168 (define_insn "*negsi2_cmpz_zext"
10169 [(set (reg:CCZ FLAGS_REG)
10170 (compare:CCZ (lshiftrt:DI
10171 (neg:DI (ashift:DI
10172 (match_operand:DI 1 "register_operand" "0")
10173 (const_int 32)))
10174 (const_int 32))
10175 (const_int 0)))
10176 (set (match_operand:DI 0 "register_operand" "=r")
10177 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10178 (const_int 32)))
10179 (const_int 32)))]
10180 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10181 "neg{l}\t%k0"
10182 [(set_attr "type" "negnot")
10183 (set_attr "mode" "SI")])
10184
10185 (define_expand "neghi2"
10186 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10187 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10188 (clobber (reg:CC FLAGS_REG))])]
10189 "TARGET_HIMODE_MATH"
10190 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10191
10192 (define_insn "*neghi2_1"
10193 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10194 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10195 (clobber (reg:CC FLAGS_REG))]
10196 "ix86_unary_operator_ok (NEG, HImode, operands)"
10197 "neg{w}\t%0"
10198 [(set_attr "type" "negnot")
10199 (set_attr "mode" "HI")])
10200
10201 (define_insn "*neghi2_cmpz"
10202 [(set (reg:CCZ FLAGS_REG)
10203 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10204 (const_int 0)))
10205 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10206 (neg:HI (match_dup 1)))]
10207 "ix86_unary_operator_ok (NEG, HImode, operands)"
10208 "neg{w}\t%0"
10209 [(set_attr "type" "negnot")
10210 (set_attr "mode" "HI")])
10211
10212 (define_expand "negqi2"
10213 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10214 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10215 (clobber (reg:CC FLAGS_REG))])]
10216 "TARGET_QIMODE_MATH"
10217 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10218
10219 (define_insn "*negqi2_1"
10220 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10221 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10222 (clobber (reg:CC FLAGS_REG))]
10223 "ix86_unary_operator_ok (NEG, QImode, operands)"
10224 "neg{b}\t%0"
10225 [(set_attr "type" "negnot")
10226 (set_attr "mode" "QI")])
10227
10228 (define_insn "*negqi2_cmpz"
10229 [(set (reg:CCZ FLAGS_REG)
10230 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10231 (const_int 0)))
10232 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10233 (neg:QI (match_dup 1)))]
10234 "ix86_unary_operator_ok (NEG, QImode, operands)"
10235 "neg{b}\t%0"
10236 [(set_attr "type" "negnot")
10237 (set_attr "mode" "QI")])
10238
10239 ;; Changing of sign for FP values is doable using integer unit too.
10240
10241 (define_expand "negsf2"
10242 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10243 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10244 "TARGET_80387 || TARGET_SSE_MATH"
10245 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
10246
10247 (define_expand "abssf2"
10248 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10249 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10250 "TARGET_80387 || TARGET_SSE_MATH"
10251 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
10252
10253 (define_insn "*absnegsf2_mixed"
10254 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
10255 (match_operator:SF 3 "absneg_operator"
10256 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
10257 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
10258 (clobber (reg:CC FLAGS_REG))]
10259 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10260 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10261 "#")
10262
10263 (define_insn "*absnegsf2_sse"
10264 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
10265 (match_operator:SF 3 "absneg_operator"
10266 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
10267 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
10268 (clobber (reg:CC FLAGS_REG))]
10269 "TARGET_SSE_MATH
10270 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10271 "#")
10272
10273 (define_insn "*absnegsf2_i387"
10274 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
10275 (match_operator:SF 3 "absneg_operator"
10276 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
10277 (use (match_operand 2 "" ""))
10278 (clobber (reg:CC FLAGS_REG))]
10279 "TARGET_80387 && !TARGET_SSE_MATH
10280 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10281 "#")
10282
10283 (define_expand "negdf2"
10284 [(set (match_operand:DF 0 "nonimmediate_operand" "")
10285 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10286 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10287 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
10288
10289 (define_expand "absdf2"
10290 [(set (match_operand:DF 0 "nonimmediate_operand" "")
10291 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10292 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10293 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10294
10295 (define_insn "*absnegdf2_mixed"
10296 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
10297 (match_operator:DF 3 "absneg_operator"
10298 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10299 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
10300 (clobber (reg:CC FLAGS_REG))]
10301 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10302 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10303 "#")
10304
10305 (define_insn "*absnegdf2_sse"
10306 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
10307 (match_operator:DF 3 "absneg_operator"
10308 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10309 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
10310 (clobber (reg:CC FLAGS_REG))]
10311 "TARGET_SSE2 && TARGET_SSE_MATH
10312 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10313 "#")
10314
10315 (define_insn "*absnegdf2_i387"
10316 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10317 (match_operator:DF 3 "absneg_operator"
10318 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10319 (use (match_operand 2 "" ""))
10320 (clobber (reg:CC FLAGS_REG))]
10321 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10322 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10323 "#")
10324
10325 (define_expand "negxf2"
10326 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10327 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10328 "TARGET_80387"
10329 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10330
10331 (define_expand "absxf2"
10332 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10333 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10334 "TARGET_80387"
10335 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10336
10337 (define_insn "*absnegxf2_i387"
10338 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10339 (match_operator:XF 3 "absneg_operator"
10340 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10341 (use (match_operand 2 "" ""))
10342 (clobber (reg:CC FLAGS_REG))]
10343 "TARGET_80387
10344 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10345 "#")
10346
10347 (define_expand "negtf2"
10348 [(set (match_operand:TF 0 "nonimmediate_operand" "")
10349 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10350 "TARGET_64BIT"
10351 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10352
10353 (define_expand "abstf2"
10354 [(set (match_operand:TF 0 "nonimmediate_operand" "")
10355 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10356 "TARGET_64BIT"
10357 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10358
10359 (define_insn "*absnegtf2_sse"
10360 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x,m")
10361 (match_operator:TF 3 "absneg_operator"
10362 [(match_operand:TF 1 "nonimmediate_operand" "0, x,0")]))
10363 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0,X"))
10364 (clobber (reg:CC FLAGS_REG))]
10365 "TARGET_64BIT
10366 && ix86_unary_operator_ok (GET_CODE (operands[3]), TFmode, operands)"
10367 "#")
10368
10369 ;; Splitters for fp abs and neg.
10370
10371 (define_split
10372 [(set (match_operand 0 "fp_register_operand" "")
10373 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10374 (use (match_operand 2 "" ""))
10375 (clobber (reg:CC FLAGS_REG))]
10376 "reload_completed"
10377 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10378
10379 (define_split
10380 [(set (match_operand 0 "register_operand" "")
10381 (match_operator 3 "absneg_operator"
10382 [(match_operand 1 "register_operand" "")]))
10383 (use (match_operand 2 "nonimmediate_operand" ""))
10384 (clobber (reg:CC FLAGS_REG))]
10385 "reload_completed && SSE_REG_P (operands[0])"
10386 [(set (match_dup 0) (match_dup 3))]
10387 {
10388 enum machine_mode mode = GET_MODE (operands[0]);
10389 enum machine_mode vmode = GET_MODE (operands[2]);
10390 rtx tmp;
10391
10392 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10393 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10394 if (operands_match_p (operands[0], operands[2]))
10395 {
10396 tmp = operands[1];
10397 operands[1] = operands[2];
10398 operands[2] = tmp;
10399 }
10400 if (GET_CODE (operands[3]) == ABS)
10401 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10402 else
10403 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10404 operands[3] = tmp;
10405 })
10406
10407 (define_split
10408 [(set (match_operand:SF 0 "register_operand" "")
10409 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10410 (use (match_operand:V4SF 2 "" ""))
10411 (clobber (reg:CC FLAGS_REG))]
10412 "reload_completed"
10413 [(parallel [(set (match_dup 0) (match_dup 1))
10414 (clobber (reg:CC FLAGS_REG))])]
10415 {
10416 rtx tmp;
10417 operands[0] = gen_lowpart (SImode, operands[0]);
10418 if (GET_CODE (operands[1]) == ABS)
10419 {
10420 tmp = gen_int_mode (0x7fffffff, SImode);
10421 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10422 }
10423 else
10424 {
10425 tmp = gen_int_mode (0x80000000, SImode);
10426 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10427 }
10428 operands[1] = tmp;
10429 })
10430
10431 (define_split
10432 [(set (match_operand:DF 0 "register_operand" "")
10433 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10434 (use (match_operand 2 "" ""))
10435 (clobber (reg:CC FLAGS_REG))]
10436 "reload_completed"
10437 [(parallel [(set (match_dup 0) (match_dup 1))
10438 (clobber (reg:CC FLAGS_REG))])]
10439 {
10440 rtx tmp;
10441 if (TARGET_64BIT)
10442 {
10443 tmp = gen_lowpart (DImode, operands[0]);
10444 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10445 operands[0] = tmp;
10446
10447 if (GET_CODE (operands[1]) == ABS)
10448 tmp = const0_rtx;
10449 else
10450 tmp = gen_rtx_NOT (DImode, tmp);
10451 }
10452 else
10453 {
10454 operands[0] = gen_highpart (SImode, operands[0]);
10455 if (GET_CODE (operands[1]) == ABS)
10456 {
10457 tmp = gen_int_mode (0x7fffffff, SImode);
10458 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10459 }
10460 else
10461 {
10462 tmp = gen_int_mode (0x80000000, SImode);
10463 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10464 }
10465 }
10466 operands[1] = tmp;
10467 })
10468
10469 (define_split
10470 [(set (match_operand:XF 0 "register_operand" "")
10471 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10472 (use (match_operand 2 "" ""))
10473 (clobber (reg:CC FLAGS_REG))]
10474 "reload_completed"
10475 [(parallel [(set (match_dup 0) (match_dup 1))
10476 (clobber (reg:CC FLAGS_REG))])]
10477 {
10478 rtx tmp;
10479 operands[0] = gen_rtx_REG (SImode,
10480 true_regnum (operands[0])
10481 + (TARGET_64BIT ? 1 : 2));
10482 if (GET_CODE (operands[1]) == ABS)
10483 {
10484 tmp = GEN_INT (0x7fff);
10485 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10486 }
10487 else
10488 {
10489 tmp = GEN_INT (0x8000);
10490 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10491 }
10492 operands[1] = tmp;
10493 })
10494
10495 (define_split
10496 [(set (match_operand 0 "memory_operand" "")
10497 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10498 (use (match_operand 2 "" ""))
10499 (clobber (reg:CC FLAGS_REG))]
10500 "reload_completed"
10501 [(parallel [(set (match_dup 0) (match_dup 1))
10502 (clobber (reg:CC FLAGS_REG))])]
10503 {
10504 enum machine_mode mode = GET_MODE (operands[0]);
10505 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10506 rtx tmp;
10507
10508 operands[0] = adjust_address (operands[0], QImode, size - 1);
10509 if (GET_CODE (operands[1]) == ABS)
10510 {
10511 tmp = gen_int_mode (0x7f, QImode);
10512 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10513 }
10514 else
10515 {
10516 tmp = gen_int_mode (0x80, QImode);
10517 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10518 }
10519 operands[1] = tmp;
10520 })
10521
10522 ;; Conditionalize these after reload. If they match before reload, we
10523 ;; lose the clobber and ability to use integer instructions.
10524
10525 (define_insn "*negsf2_1"
10526 [(set (match_operand:SF 0 "register_operand" "=f")
10527 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10528 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10529 "fchs"
10530 [(set_attr "type" "fsgn")
10531 (set_attr "mode" "SF")])
10532
10533 (define_insn "*negdf2_1"
10534 [(set (match_operand:DF 0 "register_operand" "=f")
10535 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10536 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10537 "fchs"
10538 [(set_attr "type" "fsgn")
10539 (set_attr "mode" "DF")])
10540
10541 (define_insn "*negxf2_1"
10542 [(set (match_operand:XF 0 "register_operand" "=f")
10543 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10544 "TARGET_80387"
10545 "fchs"
10546 [(set_attr "type" "fsgn")
10547 (set_attr "mode" "XF")])
10548
10549 (define_insn "*abssf2_1"
10550 [(set (match_operand:SF 0 "register_operand" "=f")
10551 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10552 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10553 "fabs"
10554 [(set_attr "type" "fsgn")
10555 (set_attr "mode" "SF")])
10556
10557 (define_insn "*absdf2_1"
10558 [(set (match_operand:DF 0 "register_operand" "=f")
10559 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10560 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10561 "fabs"
10562 [(set_attr "type" "fsgn")
10563 (set_attr "mode" "DF")])
10564
10565 (define_insn "*absxf2_1"
10566 [(set (match_operand:XF 0 "register_operand" "=f")
10567 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10568 "TARGET_80387"
10569 "fabs"
10570 [(set_attr "type" "fsgn")
10571 (set_attr "mode" "DF")])
10572
10573 (define_insn "*negextendsfdf2"
10574 [(set (match_operand:DF 0 "register_operand" "=f")
10575 (neg:DF (float_extend:DF
10576 (match_operand:SF 1 "register_operand" "0"))))]
10577 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10578 "fchs"
10579 [(set_attr "type" "fsgn")
10580 (set_attr "mode" "DF")])
10581
10582 (define_insn "*negextenddfxf2"
10583 [(set (match_operand:XF 0 "register_operand" "=f")
10584 (neg:XF (float_extend:XF
10585 (match_operand:DF 1 "register_operand" "0"))))]
10586 "TARGET_80387"
10587 "fchs"
10588 [(set_attr "type" "fsgn")
10589 (set_attr "mode" "XF")])
10590
10591 (define_insn "*negextendsfxf2"
10592 [(set (match_operand:XF 0 "register_operand" "=f")
10593 (neg:XF (float_extend:XF
10594 (match_operand:SF 1 "register_operand" "0"))))]
10595 "TARGET_80387"
10596 "fchs"
10597 [(set_attr "type" "fsgn")
10598 (set_attr "mode" "XF")])
10599
10600 (define_insn "*absextendsfdf2"
10601 [(set (match_operand:DF 0 "register_operand" "=f")
10602 (abs:DF (float_extend:DF
10603 (match_operand:SF 1 "register_operand" "0"))))]
10604 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10605 "fabs"
10606 [(set_attr "type" "fsgn")
10607 (set_attr "mode" "DF")])
10608
10609 (define_insn "*absextenddfxf2"
10610 [(set (match_operand:XF 0 "register_operand" "=f")
10611 (abs:XF (float_extend:XF
10612 (match_operand:DF 1 "register_operand" "0"))))]
10613 "TARGET_80387"
10614 "fabs"
10615 [(set_attr "type" "fsgn")
10616 (set_attr "mode" "XF")])
10617
10618 (define_insn "*absextendsfxf2"
10619 [(set (match_operand:XF 0 "register_operand" "=f")
10620 (abs:XF (float_extend:XF
10621 (match_operand:SF 1 "register_operand" "0"))))]
10622 "TARGET_80387"
10623 "fabs"
10624 [(set_attr "type" "fsgn")
10625 (set_attr "mode" "XF")])
10626
10627 ;; Copysign instructions
10628
10629 (define_mode_iterator CSGNMODE [SF DF TF])
10630 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10631
10632 (define_expand "copysign<mode>3"
10633 [(match_operand:CSGNMODE 0 "register_operand" "")
10634 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10635 (match_operand:CSGNMODE 2 "register_operand" "")]
10636 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10637 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10638 {
10639 ix86_expand_copysign (operands);
10640 DONE;
10641 })
10642
10643 (define_insn_and_split "copysign<mode>3_const"
10644 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10645 (unspec:CSGNMODE
10646 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10647 (match_operand:CSGNMODE 2 "register_operand" "0")
10648 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10649 UNSPEC_COPYSIGN))]
10650 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10651 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10652 "#"
10653 "&& reload_completed"
10654 [(const_int 0)]
10655 {
10656 ix86_split_copysign_const (operands);
10657 DONE;
10658 })
10659
10660 (define_insn "copysign<mode>3_var"
10661 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10662 (unspec:CSGNMODE
10663 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10664 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10665 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10666 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10667 UNSPEC_COPYSIGN))
10668 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10669 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10670 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10671 "#")
10672
10673 (define_split
10674 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10675 (unspec:CSGNMODE
10676 [(match_operand:CSGNMODE 2 "register_operand" "")
10677 (match_operand:CSGNMODE 3 "register_operand" "")
10678 (match_operand:<CSGNVMODE> 4 "" "")
10679 (match_operand:<CSGNVMODE> 5 "" "")]
10680 UNSPEC_COPYSIGN))
10681 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10682 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10683 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10684 && reload_completed"
10685 [(const_int 0)]
10686 {
10687 ix86_split_copysign_var (operands);
10688 DONE;
10689 })
10690 \f
10691 ;; One complement instructions
10692
10693 (define_expand "one_cmpldi2"
10694 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10695 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10696 "TARGET_64BIT"
10697 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10698
10699 (define_insn "*one_cmpldi2_1_rex64"
10700 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10701 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10702 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10703 "not{q}\t%0"
10704 [(set_attr "type" "negnot")
10705 (set_attr "mode" "DI")])
10706
10707 (define_insn "*one_cmpldi2_2_rex64"
10708 [(set (reg FLAGS_REG)
10709 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10710 (const_int 0)))
10711 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10712 (not:DI (match_dup 1)))]
10713 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10714 && ix86_unary_operator_ok (NOT, DImode, operands)"
10715 "#"
10716 [(set_attr "type" "alu1")
10717 (set_attr "mode" "DI")])
10718
10719 (define_split
10720 [(set (match_operand 0 "flags_reg_operand" "")
10721 (match_operator 2 "compare_operator"
10722 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10723 (const_int 0)]))
10724 (set (match_operand:DI 1 "nonimmediate_operand" "")
10725 (not:DI (match_dup 3)))]
10726 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10727 [(parallel [(set (match_dup 0)
10728 (match_op_dup 2
10729 [(xor:DI (match_dup 3) (const_int -1))
10730 (const_int 0)]))
10731 (set (match_dup 1)
10732 (xor:DI (match_dup 3) (const_int -1)))])]
10733 "")
10734
10735 (define_expand "one_cmplsi2"
10736 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10737 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10738 ""
10739 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10740
10741 (define_insn "*one_cmplsi2_1"
10742 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10743 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10744 "ix86_unary_operator_ok (NOT, SImode, operands)"
10745 "not{l}\t%0"
10746 [(set_attr "type" "negnot")
10747 (set_attr "mode" "SI")])
10748
10749 ;; ??? Currently never generated - xor is used instead.
10750 (define_insn "*one_cmplsi2_1_zext"
10751 [(set (match_operand:DI 0 "register_operand" "=r")
10752 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10753 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10754 "not{l}\t%k0"
10755 [(set_attr "type" "negnot")
10756 (set_attr "mode" "SI")])
10757
10758 (define_insn "*one_cmplsi2_2"
10759 [(set (reg FLAGS_REG)
10760 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10761 (const_int 0)))
10762 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10763 (not:SI (match_dup 1)))]
10764 "ix86_match_ccmode (insn, CCNOmode)
10765 && ix86_unary_operator_ok (NOT, SImode, operands)"
10766 "#"
10767 [(set_attr "type" "alu1")
10768 (set_attr "mode" "SI")])
10769
10770 (define_split
10771 [(set (match_operand 0 "flags_reg_operand" "")
10772 (match_operator 2 "compare_operator"
10773 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10774 (const_int 0)]))
10775 (set (match_operand:SI 1 "nonimmediate_operand" "")
10776 (not:SI (match_dup 3)))]
10777 "ix86_match_ccmode (insn, CCNOmode)"
10778 [(parallel [(set (match_dup 0)
10779 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10780 (const_int 0)]))
10781 (set (match_dup 1)
10782 (xor:SI (match_dup 3) (const_int -1)))])]
10783 "")
10784
10785 ;; ??? Currently never generated - xor is used instead.
10786 (define_insn "*one_cmplsi2_2_zext"
10787 [(set (reg FLAGS_REG)
10788 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10789 (const_int 0)))
10790 (set (match_operand:DI 0 "register_operand" "=r")
10791 (zero_extend:DI (not:SI (match_dup 1))))]
10792 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10793 && ix86_unary_operator_ok (NOT, SImode, operands)"
10794 "#"
10795 [(set_attr "type" "alu1")
10796 (set_attr "mode" "SI")])
10797
10798 (define_split
10799 [(set (match_operand 0 "flags_reg_operand" "")
10800 (match_operator 2 "compare_operator"
10801 [(not:SI (match_operand:SI 3 "register_operand" ""))
10802 (const_int 0)]))
10803 (set (match_operand:DI 1 "register_operand" "")
10804 (zero_extend:DI (not:SI (match_dup 3))))]
10805 "ix86_match_ccmode (insn, CCNOmode)"
10806 [(parallel [(set (match_dup 0)
10807 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10808 (const_int 0)]))
10809 (set (match_dup 1)
10810 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10811 "")
10812
10813 (define_expand "one_cmplhi2"
10814 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10815 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10816 "TARGET_HIMODE_MATH"
10817 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10818
10819 (define_insn "*one_cmplhi2_1"
10820 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10821 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10822 "ix86_unary_operator_ok (NOT, HImode, operands)"
10823 "not{w}\t%0"
10824 [(set_attr "type" "negnot")
10825 (set_attr "mode" "HI")])
10826
10827 (define_insn "*one_cmplhi2_2"
10828 [(set (reg FLAGS_REG)
10829 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10830 (const_int 0)))
10831 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10832 (not:HI (match_dup 1)))]
10833 "ix86_match_ccmode (insn, CCNOmode)
10834 && ix86_unary_operator_ok (NEG, HImode, operands)"
10835 "#"
10836 [(set_attr "type" "alu1")
10837 (set_attr "mode" "HI")])
10838
10839 (define_split
10840 [(set (match_operand 0 "flags_reg_operand" "")
10841 (match_operator 2 "compare_operator"
10842 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10843 (const_int 0)]))
10844 (set (match_operand:HI 1 "nonimmediate_operand" "")
10845 (not:HI (match_dup 3)))]
10846 "ix86_match_ccmode (insn, CCNOmode)"
10847 [(parallel [(set (match_dup 0)
10848 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10849 (const_int 0)]))
10850 (set (match_dup 1)
10851 (xor:HI (match_dup 3) (const_int -1)))])]
10852 "")
10853
10854 ;; %%% Potential partial reg stall on alternative 1. What to do?
10855 (define_expand "one_cmplqi2"
10856 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10857 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10858 "TARGET_QIMODE_MATH"
10859 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10860
10861 (define_insn "*one_cmplqi2_1"
10862 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10863 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10864 "ix86_unary_operator_ok (NOT, QImode, operands)"
10865 "@
10866 not{b}\t%0
10867 not{l}\t%k0"
10868 [(set_attr "type" "negnot")
10869 (set_attr "mode" "QI,SI")])
10870
10871 (define_insn "*one_cmplqi2_2"
10872 [(set (reg FLAGS_REG)
10873 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10874 (const_int 0)))
10875 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10876 (not:QI (match_dup 1)))]
10877 "ix86_match_ccmode (insn, CCNOmode)
10878 && ix86_unary_operator_ok (NOT, QImode, operands)"
10879 "#"
10880 [(set_attr "type" "alu1")
10881 (set_attr "mode" "QI")])
10882
10883 (define_split
10884 [(set (match_operand 0 "flags_reg_operand" "")
10885 (match_operator 2 "compare_operator"
10886 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10887 (const_int 0)]))
10888 (set (match_operand:QI 1 "nonimmediate_operand" "")
10889 (not:QI (match_dup 3)))]
10890 "ix86_match_ccmode (insn, CCNOmode)"
10891 [(parallel [(set (match_dup 0)
10892 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10893 (const_int 0)]))
10894 (set (match_dup 1)
10895 (xor:QI (match_dup 3) (const_int -1)))])]
10896 "")
10897 \f
10898 ;; Arithmetic shift instructions
10899
10900 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10901 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10902 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10903 ;; from the assembler input.
10904 ;;
10905 ;; This instruction shifts the target reg/mem as usual, but instead of
10906 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10907 ;; is a left shift double, bits are taken from the high order bits of
10908 ;; reg, else if the insn is a shift right double, bits are taken from the
10909 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10910 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10911 ;;
10912 ;; Since sh[lr]d does not change the `reg' operand, that is done
10913 ;; separately, making all shifts emit pairs of shift double and normal
10914 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10915 ;; support a 63 bit shift, each shift where the count is in a reg expands
10916 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10917 ;;
10918 ;; If the shift count is a constant, we need never emit more than one
10919 ;; shift pair, instead using moves and sign extension for counts greater
10920 ;; than 31.
10921
10922 (define_expand "ashlti3"
10923 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10924 (ashift:TI (match_operand:TI 1 "register_operand" "")
10925 (match_operand:QI 2 "nonmemory_operand" "")))
10926 (clobber (reg:CC FLAGS_REG))])]
10927 "TARGET_64BIT"
10928 {
10929 if (! immediate_operand (operands[2], QImode))
10930 {
10931 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10932 DONE;
10933 }
10934 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10935 DONE;
10936 })
10937
10938 (define_insn "ashlti3_1"
10939 [(set (match_operand:TI 0 "register_operand" "=r")
10940 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10941 (match_operand:QI 2 "register_operand" "c")))
10942 (clobber (match_scratch:DI 3 "=&r"))
10943 (clobber (reg:CC FLAGS_REG))]
10944 "TARGET_64BIT"
10945 "#"
10946 [(set_attr "type" "multi")])
10947
10948 ;; This pattern must be defined before *ashlti3_2 to prevent
10949 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10950
10951 (define_insn "sse2_ashlti3"
10952 [(set (match_operand:TI 0 "register_operand" "=x")
10953 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10954 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10955 "TARGET_SSE2"
10956 {
10957 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10958 return "pslldq\t{%2, %0|%0, %2}";
10959 }
10960 [(set_attr "type" "sseishft")
10961 (set_attr "prefix_data16" "1")
10962 (set_attr "mode" "TI")])
10963
10964 (define_insn "*ashlti3_2"
10965 [(set (match_operand:TI 0 "register_operand" "=r")
10966 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10967 (match_operand:QI 2 "immediate_operand" "O")))
10968 (clobber (reg:CC FLAGS_REG))]
10969 "TARGET_64BIT"
10970 "#"
10971 [(set_attr "type" "multi")])
10972
10973 (define_split
10974 [(set (match_operand:TI 0 "register_operand" "")
10975 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10976 (match_operand:QI 2 "register_operand" "")))
10977 (clobber (match_scratch:DI 3 ""))
10978 (clobber (reg:CC FLAGS_REG))]
10979 "TARGET_64BIT && reload_completed"
10980 [(const_int 0)]
10981 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10982
10983 (define_split
10984 [(set (match_operand:TI 0 "register_operand" "")
10985 (ashift:TI (match_operand:TI 1 "register_operand" "")
10986 (match_operand:QI 2 "immediate_operand" "")))
10987 (clobber (reg:CC FLAGS_REG))]
10988 "TARGET_64BIT && reload_completed"
10989 [(const_int 0)]
10990 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10991
10992 (define_insn "x86_64_shld"
10993 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10994 (ior:DI (ashift:DI (match_dup 0)
10995 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10996 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10997 (minus:QI (const_int 64) (match_dup 2)))))
10998 (clobber (reg:CC FLAGS_REG))]
10999 "TARGET_64BIT"
11000 "@
11001 shld{q}\t{%2, %1, %0|%0, %1, %2}
11002 shld{q}\t{%s2%1, %0|%0, %1, %2}"
11003 [(set_attr "type" "ishift")
11004 (set_attr "prefix_0f" "1")
11005 (set_attr "mode" "DI")
11006 (set_attr "athlon_decode" "vector")
11007 (set_attr "amdfam10_decode" "vector")])
11008
11009 (define_expand "x86_64_shift_adj"
11010 [(set (reg:CCZ FLAGS_REG)
11011 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11012 (const_int 64))
11013 (const_int 0)))
11014 (set (match_operand:DI 0 "register_operand" "")
11015 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11016 (match_operand:DI 1 "register_operand" "")
11017 (match_dup 0)))
11018 (set (match_dup 1)
11019 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11020 (match_operand:DI 3 "register_operand" "r")
11021 (match_dup 1)))]
11022 "TARGET_64BIT"
11023 "")
11024
11025 (define_expand "ashldi3"
11026 [(set (match_operand:DI 0 "shiftdi_operand" "")
11027 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11028 (match_operand:QI 2 "nonmemory_operand" "")))]
11029 ""
11030 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11031
11032 (define_insn "*ashldi3_1_rex64"
11033 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11034 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11035 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11036 (clobber (reg:CC FLAGS_REG))]
11037 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11038 {
11039 switch (get_attr_type (insn))
11040 {
11041 case TYPE_ALU:
11042 gcc_assert (operands[2] == const1_rtx);
11043 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11044 return "add{q}\t%0, %0";
11045
11046 case TYPE_LEA:
11047 gcc_assert (CONST_INT_P (operands[2]));
11048 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11049 operands[1] = gen_rtx_MULT (DImode, operands[1],
11050 GEN_INT (1 << INTVAL (operands[2])));
11051 return "lea{q}\t{%a1, %0|%0, %a1}";
11052
11053 default:
11054 if (REG_P (operands[2]))
11055 return "sal{q}\t{%b2, %0|%0, %b2}";
11056 else if (operands[2] == const1_rtx
11057 && (TARGET_SHIFT1 || optimize_size))
11058 return "sal{q}\t%0";
11059 else
11060 return "sal{q}\t{%2, %0|%0, %2}";
11061 }
11062 }
11063 [(set (attr "type")
11064 (cond [(eq_attr "alternative" "1")
11065 (const_string "lea")
11066 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11067 (const_int 0))
11068 (match_operand 0 "register_operand" ""))
11069 (match_operand 2 "const1_operand" ""))
11070 (const_string "alu")
11071 ]
11072 (const_string "ishift")))
11073 (set_attr "mode" "DI")])
11074
11075 ;; Convert lea to the lea pattern to avoid flags dependency.
11076 (define_split
11077 [(set (match_operand:DI 0 "register_operand" "")
11078 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11079 (match_operand:QI 2 "immediate_operand" "")))
11080 (clobber (reg:CC FLAGS_REG))]
11081 "TARGET_64BIT && reload_completed
11082 && true_regnum (operands[0]) != true_regnum (operands[1])"
11083 [(set (match_dup 0)
11084 (mult:DI (match_dup 1)
11085 (match_dup 2)))]
11086 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11087
11088 ;; This pattern can't accept a variable shift count, since shifts by
11089 ;; zero don't affect the flags. We assume that shifts by constant
11090 ;; zero are optimized away.
11091 (define_insn "*ashldi3_cmp_rex64"
11092 [(set (reg FLAGS_REG)
11093 (compare
11094 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11095 (match_operand:QI 2 "immediate_operand" "e"))
11096 (const_int 0)))
11097 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11098 (ashift:DI (match_dup 1) (match_dup 2)))]
11099 "TARGET_64BIT
11100 && (optimize_size
11101 || !TARGET_PARTIAL_FLAG_REG_STALL
11102 || (operands[2] == const1_rtx
11103 && (TARGET_SHIFT1
11104 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11105 && ix86_match_ccmode (insn, CCGOCmode)
11106 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11107 {
11108 switch (get_attr_type (insn))
11109 {
11110 case TYPE_ALU:
11111 gcc_assert (operands[2] == const1_rtx);
11112 return "add{q}\t%0, %0";
11113
11114 default:
11115 if (REG_P (operands[2]))
11116 return "sal{q}\t{%b2, %0|%0, %b2}";
11117 else if (operands[2] == const1_rtx
11118 && (TARGET_SHIFT1 || optimize_size))
11119 return "sal{q}\t%0";
11120 else
11121 return "sal{q}\t{%2, %0|%0, %2}";
11122 }
11123 }
11124 [(set (attr "type")
11125 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11126 (const_int 0))
11127 (match_operand 0 "register_operand" ""))
11128 (match_operand 2 "const1_operand" ""))
11129 (const_string "alu")
11130 ]
11131 (const_string "ishift")))
11132 (set_attr "mode" "DI")])
11133
11134 (define_insn "*ashldi3_cconly_rex64"
11135 [(set (reg FLAGS_REG)
11136 (compare
11137 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11138 (match_operand:QI 2 "immediate_operand" "e"))
11139 (const_int 0)))
11140 (clobber (match_scratch:DI 0 "=r"))]
11141 "TARGET_64BIT
11142 && (optimize_size
11143 || !TARGET_PARTIAL_FLAG_REG_STALL
11144 || (operands[2] == const1_rtx
11145 && (TARGET_SHIFT1
11146 || TARGET_DOUBLE_WITH_ADD)))
11147 && ix86_match_ccmode (insn, CCGOCmode)
11148 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11149 {
11150 switch (get_attr_type (insn))
11151 {
11152 case TYPE_ALU:
11153 gcc_assert (operands[2] == const1_rtx);
11154 return "add{q}\t%0, %0";
11155
11156 default:
11157 if (REG_P (operands[2]))
11158 return "sal{q}\t{%b2, %0|%0, %b2}";
11159 else if (operands[2] == const1_rtx
11160 && (TARGET_SHIFT1 || optimize_size))
11161 return "sal{q}\t%0";
11162 else
11163 return "sal{q}\t{%2, %0|%0, %2}";
11164 }
11165 }
11166 [(set (attr "type")
11167 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11168 (const_int 0))
11169 (match_operand 0 "register_operand" ""))
11170 (match_operand 2 "const1_operand" ""))
11171 (const_string "alu")
11172 ]
11173 (const_string "ishift")))
11174 (set_attr "mode" "DI")])
11175
11176 (define_insn "*ashldi3_1"
11177 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11178 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11179 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11180 (clobber (reg:CC FLAGS_REG))]
11181 "!TARGET_64BIT"
11182 "#"
11183 [(set_attr "type" "multi")])
11184
11185 ;; By default we don't ask for a scratch register, because when DImode
11186 ;; values are manipulated, registers are already at a premium. But if
11187 ;; we have one handy, we won't turn it away.
11188 (define_peephole2
11189 [(match_scratch:SI 3 "r")
11190 (parallel [(set (match_operand:DI 0 "register_operand" "")
11191 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11192 (match_operand:QI 2 "nonmemory_operand" "")))
11193 (clobber (reg:CC FLAGS_REG))])
11194 (match_dup 3)]
11195 "!TARGET_64BIT && TARGET_CMOVE"
11196 [(const_int 0)]
11197 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11198
11199 (define_split
11200 [(set (match_operand:DI 0 "register_operand" "")
11201 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11202 (match_operand:QI 2 "nonmemory_operand" "")))
11203 (clobber (reg:CC FLAGS_REG))]
11204 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11205 ? epilogue_completed : reload_completed)"
11206 [(const_int 0)]
11207 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11208
11209 (define_insn "x86_shld_1"
11210 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11211 (ior:SI (ashift:SI (match_dup 0)
11212 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11213 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11214 (minus:QI (const_int 32) (match_dup 2)))))
11215 (clobber (reg:CC FLAGS_REG))]
11216 ""
11217 "@
11218 shld{l}\t{%2, %1, %0|%0, %1, %2}
11219 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11220 [(set_attr "type" "ishift")
11221 (set_attr "prefix_0f" "1")
11222 (set_attr "mode" "SI")
11223 (set_attr "pent_pair" "np")
11224 (set_attr "athlon_decode" "vector")
11225 (set_attr "amdfam10_decode" "vector")])
11226
11227 (define_expand "x86_shift_adj_1"
11228 [(set (reg:CCZ FLAGS_REG)
11229 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11230 (const_int 32))
11231 (const_int 0)))
11232 (set (match_operand:SI 0 "register_operand" "")
11233 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11234 (match_operand:SI 1 "register_operand" "")
11235 (match_dup 0)))
11236 (set (match_dup 1)
11237 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11238 (match_operand:SI 3 "register_operand" "r")
11239 (match_dup 1)))]
11240 "TARGET_CMOVE"
11241 "")
11242
11243 (define_expand "x86_shift_adj_2"
11244 [(use (match_operand:SI 0 "register_operand" ""))
11245 (use (match_operand:SI 1 "register_operand" ""))
11246 (use (match_operand:QI 2 "register_operand" ""))]
11247 ""
11248 {
11249 rtx label = gen_label_rtx ();
11250 rtx tmp;
11251
11252 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11253
11254 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11255 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11256 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11257 gen_rtx_LABEL_REF (VOIDmode, label),
11258 pc_rtx);
11259 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11260 JUMP_LABEL (tmp) = label;
11261
11262 emit_move_insn (operands[0], operands[1]);
11263 ix86_expand_clear (operands[1]);
11264
11265 emit_label (label);
11266 LABEL_NUSES (label) = 1;
11267
11268 DONE;
11269 })
11270
11271 (define_expand "ashlsi3"
11272 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11273 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11274 (match_operand:QI 2 "nonmemory_operand" "")))
11275 (clobber (reg:CC FLAGS_REG))]
11276 ""
11277 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11278
11279 (define_insn "*ashlsi3_1"
11280 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11281 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11282 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11283 (clobber (reg:CC FLAGS_REG))]
11284 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11285 {
11286 switch (get_attr_type (insn))
11287 {
11288 case TYPE_ALU:
11289 gcc_assert (operands[2] == const1_rtx);
11290 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11291 return "add{l}\t%0, %0";
11292
11293 case TYPE_LEA:
11294 return "#";
11295
11296 default:
11297 if (REG_P (operands[2]))
11298 return "sal{l}\t{%b2, %0|%0, %b2}";
11299 else if (operands[2] == const1_rtx
11300 && (TARGET_SHIFT1 || optimize_size))
11301 return "sal{l}\t%0";
11302 else
11303 return "sal{l}\t{%2, %0|%0, %2}";
11304 }
11305 }
11306 [(set (attr "type")
11307 (cond [(eq_attr "alternative" "1")
11308 (const_string "lea")
11309 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11310 (const_int 0))
11311 (match_operand 0 "register_operand" ""))
11312 (match_operand 2 "const1_operand" ""))
11313 (const_string "alu")
11314 ]
11315 (const_string "ishift")))
11316 (set_attr "mode" "SI")])
11317
11318 ;; Convert lea to the lea pattern to avoid flags dependency.
11319 (define_split
11320 [(set (match_operand 0 "register_operand" "")
11321 (ashift (match_operand 1 "index_register_operand" "")
11322 (match_operand:QI 2 "const_int_operand" "")))
11323 (clobber (reg:CC FLAGS_REG))]
11324 "reload_completed
11325 && true_regnum (operands[0]) != true_regnum (operands[1])
11326 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11327 [(const_int 0)]
11328 {
11329 rtx pat;
11330 enum machine_mode mode = GET_MODE (operands[0]);
11331
11332 if (GET_MODE_SIZE (mode) < 4)
11333 operands[0] = gen_lowpart (SImode, operands[0]);
11334 if (mode != Pmode)
11335 operands[1] = gen_lowpart (Pmode, operands[1]);
11336 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11337
11338 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11339 if (Pmode != SImode)
11340 pat = gen_rtx_SUBREG (SImode, pat, 0);
11341 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11342 DONE;
11343 })
11344
11345 ;; Rare case of shifting RSP is handled by generating move and shift
11346 (define_split
11347 [(set (match_operand 0 "register_operand" "")
11348 (ashift (match_operand 1 "register_operand" "")
11349 (match_operand:QI 2 "const_int_operand" "")))
11350 (clobber (reg:CC FLAGS_REG))]
11351 "reload_completed
11352 && true_regnum (operands[0]) != true_regnum (operands[1])"
11353 [(const_int 0)]
11354 {
11355 rtx pat, clob;
11356 emit_move_insn (operands[0], operands[1]);
11357 pat = gen_rtx_SET (VOIDmode, operands[0],
11358 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11359 operands[0], operands[2]));
11360 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11361 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11362 DONE;
11363 })
11364
11365 (define_insn "*ashlsi3_1_zext"
11366 [(set (match_operand:DI 0 "register_operand" "=r,r")
11367 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11368 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11369 (clobber (reg:CC FLAGS_REG))]
11370 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11371 {
11372 switch (get_attr_type (insn))
11373 {
11374 case TYPE_ALU:
11375 gcc_assert (operands[2] == const1_rtx);
11376 return "add{l}\t%k0, %k0";
11377
11378 case TYPE_LEA:
11379 return "#";
11380
11381 default:
11382 if (REG_P (operands[2]))
11383 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11384 else if (operands[2] == const1_rtx
11385 && (TARGET_SHIFT1 || optimize_size))
11386 return "sal{l}\t%k0";
11387 else
11388 return "sal{l}\t{%2, %k0|%k0, %2}";
11389 }
11390 }
11391 [(set (attr "type")
11392 (cond [(eq_attr "alternative" "1")
11393 (const_string "lea")
11394 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11395 (const_int 0))
11396 (match_operand 2 "const1_operand" ""))
11397 (const_string "alu")
11398 ]
11399 (const_string "ishift")))
11400 (set_attr "mode" "SI")])
11401
11402 ;; Convert lea to the lea pattern to avoid flags dependency.
11403 (define_split
11404 [(set (match_operand:DI 0 "register_operand" "")
11405 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11406 (match_operand:QI 2 "const_int_operand" ""))))
11407 (clobber (reg:CC FLAGS_REG))]
11408 "TARGET_64BIT && reload_completed
11409 && true_regnum (operands[0]) != true_regnum (operands[1])"
11410 [(set (match_dup 0) (zero_extend:DI
11411 (subreg:SI (mult:SI (match_dup 1)
11412 (match_dup 2)) 0)))]
11413 {
11414 operands[1] = gen_lowpart (Pmode, operands[1]);
11415 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11416 })
11417
11418 ;; This pattern can't accept a variable shift count, since shifts by
11419 ;; zero don't affect the flags. We assume that shifts by constant
11420 ;; zero are optimized away.
11421 (define_insn "*ashlsi3_cmp"
11422 [(set (reg FLAGS_REG)
11423 (compare
11424 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11425 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11426 (const_int 0)))
11427 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11428 (ashift:SI (match_dup 1) (match_dup 2)))]
11429 "(optimize_size
11430 || !TARGET_PARTIAL_FLAG_REG_STALL
11431 || (operands[2] == const1_rtx
11432 && (TARGET_SHIFT1
11433 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11434 && ix86_match_ccmode (insn, CCGOCmode)
11435 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11436 {
11437 switch (get_attr_type (insn))
11438 {
11439 case TYPE_ALU:
11440 gcc_assert (operands[2] == const1_rtx);
11441 return "add{l}\t%0, %0";
11442
11443 default:
11444 if (REG_P (operands[2]))
11445 return "sal{l}\t{%b2, %0|%0, %b2}";
11446 else if (operands[2] == const1_rtx
11447 && (TARGET_SHIFT1 || optimize_size))
11448 return "sal{l}\t%0";
11449 else
11450 return "sal{l}\t{%2, %0|%0, %2}";
11451 }
11452 }
11453 [(set (attr "type")
11454 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11455 (const_int 0))
11456 (match_operand 0 "register_operand" ""))
11457 (match_operand 2 "const1_operand" ""))
11458 (const_string "alu")
11459 ]
11460 (const_string "ishift")))
11461 (set_attr "mode" "SI")])
11462
11463 (define_insn "*ashlsi3_cconly"
11464 [(set (reg FLAGS_REG)
11465 (compare
11466 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11467 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11468 (const_int 0)))
11469 (clobber (match_scratch:SI 0 "=r"))]
11470 "(optimize_size
11471 || !TARGET_PARTIAL_FLAG_REG_STALL
11472 || (operands[2] == const1_rtx
11473 && (TARGET_SHIFT1
11474 || TARGET_DOUBLE_WITH_ADD)))
11475 && ix86_match_ccmode (insn, CCGOCmode)
11476 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11477 {
11478 switch (get_attr_type (insn))
11479 {
11480 case TYPE_ALU:
11481 gcc_assert (operands[2] == const1_rtx);
11482 return "add{l}\t%0, %0";
11483
11484 default:
11485 if (REG_P (operands[2]))
11486 return "sal{l}\t{%b2, %0|%0, %b2}";
11487 else if (operands[2] == const1_rtx
11488 && (TARGET_SHIFT1 || optimize_size))
11489 return "sal{l}\t%0";
11490 else
11491 return "sal{l}\t{%2, %0|%0, %2}";
11492 }
11493 }
11494 [(set (attr "type")
11495 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11496 (const_int 0))
11497 (match_operand 0 "register_operand" ""))
11498 (match_operand 2 "const1_operand" ""))
11499 (const_string "alu")
11500 ]
11501 (const_string "ishift")))
11502 (set_attr "mode" "SI")])
11503
11504 (define_insn "*ashlsi3_cmp_zext"
11505 [(set (reg FLAGS_REG)
11506 (compare
11507 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11508 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11509 (const_int 0)))
11510 (set (match_operand:DI 0 "register_operand" "=r")
11511 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11512 "TARGET_64BIT
11513 && (optimize_size
11514 || !TARGET_PARTIAL_FLAG_REG_STALL
11515 || (operands[2] == const1_rtx
11516 && (TARGET_SHIFT1
11517 || TARGET_DOUBLE_WITH_ADD)))
11518 && ix86_match_ccmode (insn, CCGOCmode)
11519 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11520 {
11521 switch (get_attr_type (insn))
11522 {
11523 case TYPE_ALU:
11524 gcc_assert (operands[2] == const1_rtx);
11525 return "add{l}\t%k0, %k0";
11526
11527 default:
11528 if (REG_P (operands[2]))
11529 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11530 else if (operands[2] == const1_rtx
11531 && (TARGET_SHIFT1 || optimize_size))
11532 return "sal{l}\t%k0";
11533 else
11534 return "sal{l}\t{%2, %k0|%k0, %2}";
11535 }
11536 }
11537 [(set (attr "type")
11538 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11539 (const_int 0))
11540 (match_operand 2 "const1_operand" ""))
11541 (const_string "alu")
11542 ]
11543 (const_string "ishift")))
11544 (set_attr "mode" "SI")])
11545
11546 (define_expand "ashlhi3"
11547 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11548 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11549 (match_operand:QI 2 "nonmemory_operand" "")))
11550 (clobber (reg:CC FLAGS_REG))]
11551 "TARGET_HIMODE_MATH"
11552 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11553
11554 (define_insn "*ashlhi3_1_lea"
11555 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11556 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11557 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11558 (clobber (reg:CC FLAGS_REG))]
11559 "!TARGET_PARTIAL_REG_STALL
11560 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11561 {
11562 switch (get_attr_type (insn))
11563 {
11564 case TYPE_LEA:
11565 return "#";
11566 case TYPE_ALU:
11567 gcc_assert (operands[2] == const1_rtx);
11568 return "add{w}\t%0, %0";
11569
11570 default:
11571 if (REG_P (operands[2]))
11572 return "sal{w}\t{%b2, %0|%0, %b2}";
11573 else if (operands[2] == const1_rtx
11574 && (TARGET_SHIFT1 || optimize_size))
11575 return "sal{w}\t%0";
11576 else
11577 return "sal{w}\t{%2, %0|%0, %2}";
11578 }
11579 }
11580 [(set (attr "type")
11581 (cond [(eq_attr "alternative" "1")
11582 (const_string "lea")
11583 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11584 (const_int 0))
11585 (match_operand 0 "register_operand" ""))
11586 (match_operand 2 "const1_operand" ""))
11587 (const_string "alu")
11588 ]
11589 (const_string "ishift")))
11590 (set_attr "mode" "HI,SI")])
11591
11592 (define_insn "*ashlhi3_1"
11593 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11594 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11595 (match_operand:QI 2 "nonmemory_operand" "cI")))
11596 (clobber (reg:CC FLAGS_REG))]
11597 "TARGET_PARTIAL_REG_STALL
11598 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11599 {
11600 switch (get_attr_type (insn))
11601 {
11602 case TYPE_ALU:
11603 gcc_assert (operands[2] == const1_rtx);
11604 return "add{w}\t%0, %0";
11605
11606 default:
11607 if (REG_P (operands[2]))
11608 return "sal{w}\t{%b2, %0|%0, %b2}";
11609 else if (operands[2] == const1_rtx
11610 && (TARGET_SHIFT1 || optimize_size))
11611 return "sal{w}\t%0";
11612 else
11613 return "sal{w}\t{%2, %0|%0, %2}";
11614 }
11615 }
11616 [(set (attr "type")
11617 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11618 (const_int 0))
11619 (match_operand 0 "register_operand" ""))
11620 (match_operand 2 "const1_operand" ""))
11621 (const_string "alu")
11622 ]
11623 (const_string "ishift")))
11624 (set_attr "mode" "HI")])
11625
11626 ;; This pattern can't accept a variable shift count, since shifts by
11627 ;; zero don't affect the flags. We assume that shifts by constant
11628 ;; zero are optimized away.
11629 (define_insn "*ashlhi3_cmp"
11630 [(set (reg FLAGS_REG)
11631 (compare
11632 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11633 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11634 (const_int 0)))
11635 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11636 (ashift:HI (match_dup 1) (match_dup 2)))]
11637 "(optimize_size
11638 || !TARGET_PARTIAL_FLAG_REG_STALL
11639 || (operands[2] == const1_rtx
11640 && (TARGET_SHIFT1
11641 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11642 && ix86_match_ccmode (insn, CCGOCmode)
11643 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11644 {
11645 switch (get_attr_type (insn))
11646 {
11647 case TYPE_ALU:
11648 gcc_assert (operands[2] == const1_rtx);
11649 return "add{w}\t%0, %0";
11650
11651 default:
11652 if (REG_P (operands[2]))
11653 return "sal{w}\t{%b2, %0|%0, %b2}";
11654 else if (operands[2] == const1_rtx
11655 && (TARGET_SHIFT1 || optimize_size))
11656 return "sal{w}\t%0";
11657 else
11658 return "sal{w}\t{%2, %0|%0, %2}";
11659 }
11660 }
11661 [(set (attr "type")
11662 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11663 (const_int 0))
11664 (match_operand 0 "register_operand" ""))
11665 (match_operand 2 "const1_operand" ""))
11666 (const_string "alu")
11667 ]
11668 (const_string "ishift")))
11669 (set_attr "mode" "HI")])
11670
11671 (define_insn "*ashlhi3_cconly"
11672 [(set (reg FLAGS_REG)
11673 (compare
11674 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11675 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11676 (const_int 0)))
11677 (clobber (match_scratch:HI 0 "=r"))]
11678 "(optimize_size
11679 || !TARGET_PARTIAL_FLAG_REG_STALL
11680 || (operands[2] == const1_rtx
11681 && (TARGET_SHIFT1
11682 || TARGET_DOUBLE_WITH_ADD)))
11683 && ix86_match_ccmode (insn, CCGOCmode)
11684 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11685 {
11686 switch (get_attr_type (insn))
11687 {
11688 case TYPE_ALU:
11689 gcc_assert (operands[2] == const1_rtx);
11690 return "add{w}\t%0, %0";
11691
11692 default:
11693 if (REG_P (operands[2]))
11694 return "sal{w}\t{%b2, %0|%0, %b2}";
11695 else if (operands[2] == const1_rtx
11696 && (TARGET_SHIFT1 || optimize_size))
11697 return "sal{w}\t%0";
11698 else
11699 return "sal{w}\t{%2, %0|%0, %2}";
11700 }
11701 }
11702 [(set (attr "type")
11703 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11704 (const_int 0))
11705 (match_operand 0 "register_operand" ""))
11706 (match_operand 2 "const1_operand" ""))
11707 (const_string "alu")
11708 ]
11709 (const_string "ishift")))
11710 (set_attr "mode" "HI")])
11711
11712 (define_expand "ashlqi3"
11713 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11714 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11715 (match_operand:QI 2 "nonmemory_operand" "")))
11716 (clobber (reg:CC FLAGS_REG))]
11717 "TARGET_QIMODE_MATH"
11718 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11719
11720 ;; %%% Potential partial reg stall on alternative 2. What to do?
11721
11722 (define_insn "*ashlqi3_1_lea"
11723 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11724 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11725 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11726 (clobber (reg:CC FLAGS_REG))]
11727 "!TARGET_PARTIAL_REG_STALL
11728 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11729 {
11730 switch (get_attr_type (insn))
11731 {
11732 case TYPE_LEA:
11733 return "#";
11734 case TYPE_ALU:
11735 gcc_assert (operands[2] == const1_rtx);
11736 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11737 return "add{l}\t%k0, %k0";
11738 else
11739 return "add{b}\t%0, %0";
11740
11741 default:
11742 if (REG_P (operands[2]))
11743 {
11744 if (get_attr_mode (insn) == MODE_SI)
11745 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11746 else
11747 return "sal{b}\t{%b2, %0|%0, %b2}";
11748 }
11749 else if (operands[2] == const1_rtx
11750 && (TARGET_SHIFT1 || optimize_size))
11751 {
11752 if (get_attr_mode (insn) == MODE_SI)
11753 return "sal{l}\t%0";
11754 else
11755 return "sal{b}\t%0";
11756 }
11757 else
11758 {
11759 if (get_attr_mode (insn) == MODE_SI)
11760 return "sal{l}\t{%2, %k0|%k0, %2}";
11761 else
11762 return "sal{b}\t{%2, %0|%0, %2}";
11763 }
11764 }
11765 }
11766 [(set (attr "type")
11767 (cond [(eq_attr "alternative" "2")
11768 (const_string "lea")
11769 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11770 (const_int 0))
11771 (match_operand 0 "register_operand" ""))
11772 (match_operand 2 "const1_operand" ""))
11773 (const_string "alu")
11774 ]
11775 (const_string "ishift")))
11776 (set_attr "mode" "QI,SI,SI")])
11777
11778 (define_insn "*ashlqi3_1"
11779 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11780 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11781 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11782 (clobber (reg:CC FLAGS_REG))]
11783 "TARGET_PARTIAL_REG_STALL
11784 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11785 {
11786 switch (get_attr_type (insn))
11787 {
11788 case TYPE_ALU:
11789 gcc_assert (operands[2] == const1_rtx);
11790 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11791 return "add{l}\t%k0, %k0";
11792 else
11793 return "add{b}\t%0, %0";
11794
11795 default:
11796 if (REG_P (operands[2]))
11797 {
11798 if (get_attr_mode (insn) == MODE_SI)
11799 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11800 else
11801 return "sal{b}\t{%b2, %0|%0, %b2}";
11802 }
11803 else if (operands[2] == const1_rtx
11804 && (TARGET_SHIFT1 || optimize_size))
11805 {
11806 if (get_attr_mode (insn) == MODE_SI)
11807 return "sal{l}\t%0";
11808 else
11809 return "sal{b}\t%0";
11810 }
11811 else
11812 {
11813 if (get_attr_mode (insn) == MODE_SI)
11814 return "sal{l}\t{%2, %k0|%k0, %2}";
11815 else
11816 return "sal{b}\t{%2, %0|%0, %2}";
11817 }
11818 }
11819 }
11820 [(set (attr "type")
11821 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11822 (const_int 0))
11823 (match_operand 0 "register_operand" ""))
11824 (match_operand 2 "const1_operand" ""))
11825 (const_string "alu")
11826 ]
11827 (const_string "ishift")))
11828 (set_attr "mode" "QI,SI")])
11829
11830 ;; This pattern can't accept a variable shift count, since shifts by
11831 ;; zero don't affect the flags. We assume that shifts by constant
11832 ;; zero are optimized away.
11833 (define_insn "*ashlqi3_cmp"
11834 [(set (reg FLAGS_REG)
11835 (compare
11836 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11837 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11838 (const_int 0)))
11839 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11840 (ashift:QI (match_dup 1) (match_dup 2)))]
11841 "(optimize_size
11842 || !TARGET_PARTIAL_FLAG_REG_STALL
11843 || (operands[2] == const1_rtx
11844 && (TARGET_SHIFT1
11845 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11846 && ix86_match_ccmode (insn, CCGOCmode)
11847 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11848 {
11849 switch (get_attr_type (insn))
11850 {
11851 case TYPE_ALU:
11852 gcc_assert (operands[2] == const1_rtx);
11853 return "add{b}\t%0, %0";
11854
11855 default:
11856 if (REG_P (operands[2]))
11857 return "sal{b}\t{%b2, %0|%0, %b2}";
11858 else if (operands[2] == const1_rtx
11859 && (TARGET_SHIFT1 || optimize_size))
11860 return "sal{b}\t%0";
11861 else
11862 return "sal{b}\t{%2, %0|%0, %2}";
11863 }
11864 }
11865 [(set (attr "type")
11866 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11867 (const_int 0))
11868 (match_operand 0 "register_operand" ""))
11869 (match_operand 2 "const1_operand" ""))
11870 (const_string "alu")
11871 ]
11872 (const_string "ishift")))
11873 (set_attr "mode" "QI")])
11874
11875 (define_insn "*ashlqi3_cconly"
11876 [(set (reg FLAGS_REG)
11877 (compare
11878 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11879 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11880 (const_int 0)))
11881 (clobber (match_scratch:QI 0 "=q"))]
11882 "(optimize_size
11883 || !TARGET_PARTIAL_FLAG_REG_STALL
11884 || (operands[2] == const1_rtx
11885 && (TARGET_SHIFT1
11886 || TARGET_DOUBLE_WITH_ADD)))
11887 && ix86_match_ccmode (insn, CCGOCmode)
11888 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11889 {
11890 switch (get_attr_type (insn))
11891 {
11892 case TYPE_ALU:
11893 gcc_assert (operands[2] == const1_rtx);
11894 return "add{b}\t%0, %0";
11895
11896 default:
11897 if (REG_P (operands[2]))
11898 return "sal{b}\t{%b2, %0|%0, %b2}";
11899 else if (operands[2] == const1_rtx
11900 && (TARGET_SHIFT1 || optimize_size))
11901 return "sal{b}\t%0";
11902 else
11903 return "sal{b}\t{%2, %0|%0, %2}";
11904 }
11905 }
11906 [(set (attr "type")
11907 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11908 (const_int 0))
11909 (match_operand 0 "register_operand" ""))
11910 (match_operand 2 "const1_operand" ""))
11911 (const_string "alu")
11912 ]
11913 (const_string "ishift")))
11914 (set_attr "mode" "QI")])
11915
11916 ;; See comment above `ashldi3' about how this works.
11917
11918 (define_expand "ashrti3"
11919 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11920 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11921 (match_operand:QI 2 "nonmemory_operand" "")))
11922 (clobber (reg:CC FLAGS_REG))])]
11923 "TARGET_64BIT"
11924 {
11925 if (! immediate_operand (operands[2], QImode))
11926 {
11927 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11928 DONE;
11929 }
11930 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11931 DONE;
11932 })
11933
11934 (define_insn "ashrti3_1"
11935 [(set (match_operand:TI 0 "register_operand" "=r")
11936 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11937 (match_operand:QI 2 "register_operand" "c")))
11938 (clobber (match_scratch:DI 3 "=&r"))
11939 (clobber (reg:CC FLAGS_REG))]
11940 "TARGET_64BIT"
11941 "#"
11942 [(set_attr "type" "multi")])
11943
11944 (define_insn "*ashrti3_2"
11945 [(set (match_operand:TI 0 "register_operand" "=r")
11946 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11947 (match_operand:QI 2 "immediate_operand" "O")))
11948 (clobber (reg:CC FLAGS_REG))]
11949 "TARGET_64BIT"
11950 "#"
11951 [(set_attr "type" "multi")])
11952
11953 (define_split
11954 [(set (match_operand:TI 0 "register_operand" "")
11955 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11956 (match_operand:QI 2 "register_operand" "")))
11957 (clobber (match_scratch:DI 3 ""))
11958 (clobber (reg:CC FLAGS_REG))]
11959 "TARGET_64BIT && reload_completed"
11960 [(const_int 0)]
11961 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11962
11963 (define_split
11964 [(set (match_operand:TI 0 "register_operand" "")
11965 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11966 (match_operand:QI 2 "immediate_operand" "")))
11967 (clobber (reg:CC FLAGS_REG))]
11968 "TARGET_64BIT && reload_completed"
11969 [(const_int 0)]
11970 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11971
11972 (define_insn "x86_64_shrd"
11973 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11974 (ior:DI (ashiftrt:DI (match_dup 0)
11975 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11976 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11977 (minus:QI (const_int 64) (match_dup 2)))))
11978 (clobber (reg:CC FLAGS_REG))]
11979 "TARGET_64BIT"
11980 "@
11981 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11982 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11983 [(set_attr "type" "ishift")
11984 (set_attr "prefix_0f" "1")
11985 (set_attr "mode" "DI")
11986 (set_attr "athlon_decode" "vector")
11987 (set_attr "amdfam10_decode" "vector")])
11988
11989 (define_expand "ashrdi3"
11990 [(set (match_operand:DI 0 "shiftdi_operand" "")
11991 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11992 (match_operand:QI 2 "nonmemory_operand" "")))]
11993 ""
11994 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11995
11996 (define_insn "*ashrdi3_63_rex64"
11997 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11998 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11999 (match_operand:DI 2 "const_int_operand" "i,i")))
12000 (clobber (reg:CC FLAGS_REG))]
12001 "TARGET_64BIT && INTVAL (operands[2]) == 63
12002 && (TARGET_USE_CLTD || optimize_size)
12003 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12004 "@
12005 {cqto|cqo}
12006 sar{q}\t{%2, %0|%0, %2}"
12007 [(set_attr "type" "imovx,ishift")
12008 (set_attr "prefix_0f" "0,*")
12009 (set_attr "length_immediate" "0,*")
12010 (set_attr "modrm" "0,1")
12011 (set_attr "mode" "DI")])
12012
12013 (define_insn "*ashrdi3_1_one_bit_rex64"
12014 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12015 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12016 (match_operand:QI 2 "const1_operand" "")))
12017 (clobber (reg:CC FLAGS_REG))]
12018 "TARGET_64BIT
12019 && (TARGET_SHIFT1 || optimize_size)
12020 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12021 "sar{q}\t%0"
12022 [(set_attr "type" "ishift")
12023 (set (attr "length")
12024 (if_then_else (match_operand:DI 0 "register_operand" "")
12025 (const_string "2")
12026 (const_string "*")))])
12027
12028 (define_insn "*ashrdi3_1_rex64"
12029 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12030 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12031 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12032 (clobber (reg:CC FLAGS_REG))]
12033 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12034 "@
12035 sar{q}\t{%2, %0|%0, %2}
12036 sar{q}\t{%b2, %0|%0, %b2}"
12037 [(set_attr "type" "ishift")
12038 (set_attr "mode" "DI")])
12039
12040 ;; This pattern can't accept a variable shift count, since shifts by
12041 ;; zero don't affect the flags. We assume that shifts by constant
12042 ;; zero are optimized away.
12043 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12044 [(set (reg FLAGS_REG)
12045 (compare
12046 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12047 (match_operand:QI 2 "const1_operand" ""))
12048 (const_int 0)))
12049 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12050 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12051 "TARGET_64BIT
12052 && (TARGET_SHIFT1 || optimize_size)
12053 && ix86_match_ccmode (insn, CCGOCmode)
12054 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12055 "sar{q}\t%0"
12056 [(set_attr "type" "ishift")
12057 (set (attr "length")
12058 (if_then_else (match_operand:DI 0 "register_operand" "")
12059 (const_string "2")
12060 (const_string "*")))])
12061
12062 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12063 [(set (reg FLAGS_REG)
12064 (compare
12065 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12066 (match_operand:QI 2 "const1_operand" ""))
12067 (const_int 0)))
12068 (clobber (match_scratch:DI 0 "=r"))]
12069 "TARGET_64BIT
12070 && (TARGET_SHIFT1 || optimize_size)
12071 && ix86_match_ccmode (insn, CCGOCmode)
12072 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12073 "sar{q}\t%0"
12074 [(set_attr "type" "ishift")
12075 (set_attr "length" "2")])
12076
12077 ;; This pattern can't accept a variable shift count, since shifts by
12078 ;; zero don't affect the flags. We assume that shifts by constant
12079 ;; zero are optimized away.
12080 (define_insn "*ashrdi3_cmp_rex64"
12081 [(set (reg FLAGS_REG)
12082 (compare
12083 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12084 (match_operand:QI 2 "const_int_operand" "n"))
12085 (const_int 0)))
12086 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12087 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12088 "TARGET_64BIT
12089 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12090 && ix86_match_ccmode (insn, CCGOCmode)
12091 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12092 "sar{q}\t{%2, %0|%0, %2}"
12093 [(set_attr "type" "ishift")
12094 (set_attr "mode" "DI")])
12095
12096 (define_insn "*ashrdi3_cconly_rex64"
12097 [(set (reg FLAGS_REG)
12098 (compare
12099 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12100 (match_operand:QI 2 "const_int_operand" "n"))
12101 (const_int 0)))
12102 (clobber (match_scratch:DI 0 "=r"))]
12103 "TARGET_64BIT
12104 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12105 && ix86_match_ccmode (insn, CCGOCmode)
12106 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12107 "sar{q}\t{%2, %0|%0, %2}"
12108 [(set_attr "type" "ishift")
12109 (set_attr "mode" "DI")])
12110
12111 (define_insn "*ashrdi3_1"
12112 [(set (match_operand:DI 0 "register_operand" "=r")
12113 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12114 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12115 (clobber (reg:CC FLAGS_REG))]
12116 "!TARGET_64BIT"
12117 "#"
12118 [(set_attr "type" "multi")])
12119
12120 ;; By default we don't ask for a scratch register, because when DImode
12121 ;; values are manipulated, registers are already at a premium. But if
12122 ;; we have one handy, we won't turn it away.
12123 (define_peephole2
12124 [(match_scratch:SI 3 "r")
12125 (parallel [(set (match_operand:DI 0 "register_operand" "")
12126 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12127 (match_operand:QI 2 "nonmemory_operand" "")))
12128 (clobber (reg:CC FLAGS_REG))])
12129 (match_dup 3)]
12130 "!TARGET_64BIT && TARGET_CMOVE"
12131 [(const_int 0)]
12132 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12133
12134 (define_split
12135 [(set (match_operand:DI 0 "register_operand" "")
12136 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12137 (match_operand:QI 2 "nonmemory_operand" "")))
12138 (clobber (reg:CC FLAGS_REG))]
12139 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12140 ? epilogue_completed : reload_completed)"
12141 [(const_int 0)]
12142 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12143
12144 (define_insn "x86_shrd_1"
12145 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12146 (ior:SI (ashiftrt:SI (match_dup 0)
12147 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12148 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12149 (minus:QI (const_int 32) (match_dup 2)))))
12150 (clobber (reg:CC FLAGS_REG))]
12151 ""
12152 "@
12153 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12154 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12155 [(set_attr "type" "ishift")
12156 (set_attr "prefix_0f" "1")
12157 (set_attr "pent_pair" "np")
12158 (set_attr "mode" "SI")])
12159
12160 (define_expand "x86_shift_adj_3"
12161 [(use (match_operand:SI 0 "register_operand" ""))
12162 (use (match_operand:SI 1 "register_operand" ""))
12163 (use (match_operand:QI 2 "register_operand" ""))]
12164 ""
12165 {
12166 rtx label = gen_label_rtx ();
12167 rtx tmp;
12168
12169 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12170
12171 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12172 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12173 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12174 gen_rtx_LABEL_REF (VOIDmode, label),
12175 pc_rtx);
12176 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12177 JUMP_LABEL (tmp) = label;
12178
12179 emit_move_insn (operands[0], operands[1]);
12180 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12181
12182 emit_label (label);
12183 LABEL_NUSES (label) = 1;
12184
12185 DONE;
12186 })
12187
12188 (define_insn "ashrsi3_31"
12189 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12190 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12191 (match_operand:SI 2 "const_int_operand" "i,i")))
12192 (clobber (reg:CC FLAGS_REG))]
12193 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12194 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12195 "@
12196 {cltd|cdq}
12197 sar{l}\t{%2, %0|%0, %2}"
12198 [(set_attr "type" "imovx,ishift")
12199 (set_attr "prefix_0f" "0,*")
12200 (set_attr "length_immediate" "0,*")
12201 (set_attr "modrm" "0,1")
12202 (set_attr "mode" "SI")])
12203
12204 (define_insn "*ashrsi3_31_zext"
12205 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12206 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12207 (match_operand:SI 2 "const_int_operand" "i,i"))))
12208 (clobber (reg:CC FLAGS_REG))]
12209 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12210 && INTVAL (operands[2]) == 31
12211 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12212 "@
12213 {cltd|cdq}
12214 sar{l}\t{%2, %k0|%k0, %2}"
12215 [(set_attr "type" "imovx,ishift")
12216 (set_attr "prefix_0f" "0,*")
12217 (set_attr "length_immediate" "0,*")
12218 (set_attr "modrm" "0,1")
12219 (set_attr "mode" "SI")])
12220
12221 (define_expand "ashrsi3"
12222 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12223 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12224 (match_operand:QI 2 "nonmemory_operand" "")))
12225 (clobber (reg:CC FLAGS_REG))]
12226 ""
12227 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12228
12229 (define_insn "*ashrsi3_1_one_bit"
12230 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12231 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12232 (match_operand:QI 2 "const1_operand" "")))
12233 (clobber (reg:CC FLAGS_REG))]
12234 "(TARGET_SHIFT1 || optimize_size)
12235 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12236 "sar{l}\t%0"
12237 [(set_attr "type" "ishift")
12238 (set (attr "length")
12239 (if_then_else (match_operand:SI 0 "register_operand" "")
12240 (const_string "2")
12241 (const_string "*")))])
12242
12243 (define_insn "*ashrsi3_1_one_bit_zext"
12244 [(set (match_operand:DI 0 "register_operand" "=r")
12245 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12246 (match_operand:QI 2 "const1_operand" ""))))
12247 (clobber (reg:CC FLAGS_REG))]
12248 "TARGET_64BIT
12249 && (TARGET_SHIFT1 || optimize_size)
12250 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12251 "sar{l}\t%k0"
12252 [(set_attr "type" "ishift")
12253 (set_attr "length" "2")])
12254
12255 (define_insn "*ashrsi3_1"
12256 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12257 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12258 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12259 (clobber (reg:CC FLAGS_REG))]
12260 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12261 "@
12262 sar{l}\t{%2, %0|%0, %2}
12263 sar{l}\t{%b2, %0|%0, %b2}"
12264 [(set_attr "type" "ishift")
12265 (set_attr "mode" "SI")])
12266
12267 (define_insn "*ashrsi3_1_zext"
12268 [(set (match_operand:DI 0 "register_operand" "=r,r")
12269 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12270 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12271 (clobber (reg:CC FLAGS_REG))]
12272 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12273 "@
12274 sar{l}\t{%2, %k0|%k0, %2}
12275 sar{l}\t{%b2, %k0|%k0, %b2}"
12276 [(set_attr "type" "ishift")
12277 (set_attr "mode" "SI")])
12278
12279 ;; This pattern can't accept a variable shift count, since shifts by
12280 ;; zero don't affect the flags. We assume that shifts by constant
12281 ;; zero are optimized away.
12282 (define_insn "*ashrsi3_one_bit_cmp"
12283 [(set (reg FLAGS_REG)
12284 (compare
12285 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12286 (match_operand:QI 2 "const1_operand" ""))
12287 (const_int 0)))
12288 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12289 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12290 "(TARGET_SHIFT1 || optimize_size)
12291 && ix86_match_ccmode (insn, CCGOCmode)
12292 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12293 "sar{l}\t%0"
12294 [(set_attr "type" "ishift")
12295 (set (attr "length")
12296 (if_then_else (match_operand:SI 0 "register_operand" "")
12297 (const_string "2")
12298 (const_string "*")))])
12299
12300 (define_insn "*ashrsi3_one_bit_cconly"
12301 [(set (reg FLAGS_REG)
12302 (compare
12303 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12304 (match_operand:QI 2 "const1_operand" ""))
12305 (const_int 0)))
12306 (clobber (match_scratch:SI 0 "=r"))]
12307 "(TARGET_SHIFT1 || optimize_size)
12308 && ix86_match_ccmode (insn, CCGOCmode)
12309 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12310 "sar{l}\t%0"
12311 [(set_attr "type" "ishift")
12312 (set_attr "length" "2")])
12313
12314 (define_insn "*ashrsi3_one_bit_cmp_zext"
12315 [(set (reg FLAGS_REG)
12316 (compare
12317 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12318 (match_operand:QI 2 "const1_operand" ""))
12319 (const_int 0)))
12320 (set (match_operand:DI 0 "register_operand" "=r")
12321 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12322 "TARGET_64BIT
12323 && (TARGET_SHIFT1 || optimize_size)
12324 && ix86_match_ccmode (insn, CCmode)
12325 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12326 "sar{l}\t%k0"
12327 [(set_attr "type" "ishift")
12328 (set_attr "length" "2")])
12329
12330 ;; This pattern can't accept a variable shift count, since shifts by
12331 ;; zero don't affect the flags. We assume that shifts by constant
12332 ;; zero are optimized away.
12333 (define_insn "*ashrsi3_cmp"
12334 [(set (reg FLAGS_REG)
12335 (compare
12336 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12337 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12338 (const_int 0)))
12339 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12340 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12341 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12342 && ix86_match_ccmode (insn, CCGOCmode)
12343 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12344 "sar{l}\t{%2, %0|%0, %2}"
12345 [(set_attr "type" "ishift")
12346 (set_attr "mode" "SI")])
12347
12348 (define_insn "*ashrsi3_cconly"
12349 [(set (reg FLAGS_REG)
12350 (compare
12351 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12352 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12353 (const_int 0)))
12354 (clobber (match_scratch:SI 0 "=r"))]
12355 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12356 && ix86_match_ccmode (insn, CCGOCmode)
12357 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12358 "sar{l}\t{%2, %0|%0, %2}"
12359 [(set_attr "type" "ishift")
12360 (set_attr "mode" "SI")])
12361
12362 (define_insn "*ashrsi3_cmp_zext"
12363 [(set (reg FLAGS_REG)
12364 (compare
12365 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12366 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12367 (const_int 0)))
12368 (set (match_operand:DI 0 "register_operand" "=r")
12369 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12370 "TARGET_64BIT
12371 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12372 && ix86_match_ccmode (insn, CCGOCmode)
12373 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12374 "sar{l}\t{%2, %k0|%k0, %2}"
12375 [(set_attr "type" "ishift")
12376 (set_attr "mode" "SI")])
12377
12378 (define_expand "ashrhi3"
12379 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12380 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12381 (match_operand:QI 2 "nonmemory_operand" "")))
12382 (clobber (reg:CC FLAGS_REG))]
12383 "TARGET_HIMODE_MATH"
12384 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12385
12386 (define_insn "*ashrhi3_1_one_bit"
12387 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12388 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12389 (match_operand:QI 2 "const1_operand" "")))
12390 (clobber (reg:CC FLAGS_REG))]
12391 "(TARGET_SHIFT1 || optimize_size)
12392 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12393 "sar{w}\t%0"
12394 [(set_attr "type" "ishift")
12395 (set (attr "length")
12396 (if_then_else (match_operand 0 "register_operand" "")
12397 (const_string "2")
12398 (const_string "*")))])
12399
12400 (define_insn "*ashrhi3_1"
12401 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12402 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12403 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12404 (clobber (reg:CC FLAGS_REG))]
12405 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12406 "@
12407 sar{w}\t{%2, %0|%0, %2}
12408 sar{w}\t{%b2, %0|%0, %b2}"
12409 [(set_attr "type" "ishift")
12410 (set_attr "mode" "HI")])
12411
12412 ;; This pattern can't accept a variable shift count, since shifts by
12413 ;; zero don't affect the flags. We assume that shifts by constant
12414 ;; zero are optimized away.
12415 (define_insn "*ashrhi3_one_bit_cmp"
12416 [(set (reg FLAGS_REG)
12417 (compare
12418 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12419 (match_operand:QI 2 "const1_operand" ""))
12420 (const_int 0)))
12421 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12422 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12423 "(TARGET_SHIFT1 || optimize_size)
12424 && ix86_match_ccmode (insn, CCGOCmode)
12425 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12426 "sar{w}\t%0"
12427 [(set_attr "type" "ishift")
12428 (set (attr "length")
12429 (if_then_else (match_operand 0 "register_operand" "")
12430 (const_string "2")
12431 (const_string "*")))])
12432
12433 (define_insn "*ashrhi3_one_bit_cconly"
12434 [(set (reg FLAGS_REG)
12435 (compare
12436 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12437 (match_operand:QI 2 "const1_operand" ""))
12438 (const_int 0)))
12439 (clobber (match_scratch:HI 0 "=r"))]
12440 "(TARGET_SHIFT1 || optimize_size)
12441 && ix86_match_ccmode (insn, CCGOCmode)
12442 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12443 "sar{w}\t%0"
12444 [(set_attr "type" "ishift")
12445 (set_attr "length" "2")])
12446
12447 ;; This pattern can't accept a variable shift count, since shifts by
12448 ;; zero don't affect the flags. We assume that shifts by constant
12449 ;; zero are optimized away.
12450 (define_insn "*ashrhi3_cmp"
12451 [(set (reg FLAGS_REG)
12452 (compare
12453 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12454 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12455 (const_int 0)))
12456 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12457 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12458 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12459 && ix86_match_ccmode (insn, CCGOCmode)
12460 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12461 "sar{w}\t{%2, %0|%0, %2}"
12462 [(set_attr "type" "ishift")
12463 (set_attr "mode" "HI")])
12464
12465 (define_insn "*ashrhi3_cconly"
12466 [(set (reg FLAGS_REG)
12467 (compare
12468 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12469 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12470 (const_int 0)))
12471 (clobber (match_scratch:HI 0 "=r"))]
12472 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12473 && ix86_match_ccmode (insn, CCGOCmode)
12474 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12475 "sar{w}\t{%2, %0|%0, %2}"
12476 [(set_attr "type" "ishift")
12477 (set_attr "mode" "HI")])
12478
12479 (define_expand "ashrqi3"
12480 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12481 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12482 (match_operand:QI 2 "nonmemory_operand" "")))
12483 (clobber (reg:CC FLAGS_REG))]
12484 "TARGET_QIMODE_MATH"
12485 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12486
12487 (define_insn "*ashrqi3_1_one_bit"
12488 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12489 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12490 (match_operand:QI 2 "const1_operand" "")))
12491 (clobber (reg:CC FLAGS_REG))]
12492 "(TARGET_SHIFT1 || optimize_size)
12493 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12494 "sar{b}\t%0"
12495 [(set_attr "type" "ishift")
12496 (set (attr "length")
12497 (if_then_else (match_operand 0 "register_operand" "")
12498 (const_string "2")
12499 (const_string "*")))])
12500
12501 (define_insn "*ashrqi3_1_one_bit_slp"
12502 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12503 (ashiftrt:QI (match_dup 0)
12504 (match_operand:QI 1 "const1_operand" "")))
12505 (clobber (reg:CC FLAGS_REG))]
12506 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12507 && (TARGET_SHIFT1 || optimize_size)
12508 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12509 "sar{b}\t%0"
12510 [(set_attr "type" "ishift1")
12511 (set (attr "length")
12512 (if_then_else (match_operand 0 "register_operand" "")
12513 (const_string "2")
12514 (const_string "*")))])
12515
12516 (define_insn "*ashrqi3_1"
12517 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12518 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12519 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12520 (clobber (reg:CC FLAGS_REG))]
12521 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12522 "@
12523 sar{b}\t{%2, %0|%0, %2}
12524 sar{b}\t{%b2, %0|%0, %b2}"
12525 [(set_attr "type" "ishift")
12526 (set_attr "mode" "QI")])
12527
12528 (define_insn "*ashrqi3_1_slp"
12529 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12530 (ashiftrt:QI (match_dup 0)
12531 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12532 (clobber (reg:CC FLAGS_REG))]
12533 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12534 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12535 "@
12536 sar{b}\t{%1, %0|%0, %1}
12537 sar{b}\t{%b1, %0|%0, %b1}"
12538 [(set_attr "type" "ishift1")
12539 (set_attr "mode" "QI")])
12540
12541 ;; This pattern can't accept a variable shift count, since shifts by
12542 ;; zero don't affect the flags. We assume that shifts by constant
12543 ;; zero are optimized away.
12544 (define_insn "*ashrqi3_one_bit_cmp"
12545 [(set (reg FLAGS_REG)
12546 (compare
12547 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12548 (match_operand:QI 2 "const1_operand" "I"))
12549 (const_int 0)))
12550 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12551 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12552 "(TARGET_SHIFT1 || optimize_size)
12553 && ix86_match_ccmode (insn, CCGOCmode)
12554 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12555 "sar{b}\t%0"
12556 [(set_attr "type" "ishift")
12557 (set (attr "length")
12558 (if_then_else (match_operand 0 "register_operand" "")
12559 (const_string "2")
12560 (const_string "*")))])
12561
12562 (define_insn "*ashrqi3_one_bit_cconly"
12563 [(set (reg FLAGS_REG)
12564 (compare
12565 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12566 (match_operand:QI 2 "const1_operand" "I"))
12567 (const_int 0)))
12568 (clobber (match_scratch:QI 0 "=q"))]
12569 "(TARGET_SHIFT1 || optimize_size)
12570 && ix86_match_ccmode (insn, CCGOCmode)
12571 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12572 "sar{b}\t%0"
12573 [(set_attr "type" "ishift")
12574 (set_attr "length" "2")])
12575
12576 ;; This pattern can't accept a variable shift count, since shifts by
12577 ;; zero don't affect the flags. We assume that shifts by constant
12578 ;; zero are optimized away.
12579 (define_insn "*ashrqi3_cmp"
12580 [(set (reg FLAGS_REG)
12581 (compare
12582 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12583 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12584 (const_int 0)))
12585 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12586 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12587 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12588 && ix86_match_ccmode (insn, CCGOCmode)
12589 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12590 "sar{b}\t{%2, %0|%0, %2}"
12591 [(set_attr "type" "ishift")
12592 (set_attr "mode" "QI")])
12593
12594 (define_insn "*ashrqi3_cconly"
12595 [(set (reg FLAGS_REG)
12596 (compare
12597 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12598 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12599 (const_int 0)))
12600 (clobber (match_scratch:QI 0 "=q"))]
12601 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12602 && ix86_match_ccmode (insn, CCGOCmode)
12603 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12604 "sar{b}\t{%2, %0|%0, %2}"
12605 [(set_attr "type" "ishift")
12606 (set_attr "mode" "QI")])
12607
12608 \f
12609 ;; Logical shift instructions
12610
12611 ;; See comment above `ashldi3' about how this works.
12612
12613 (define_expand "lshrti3"
12614 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12615 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12616 (match_operand:QI 2 "nonmemory_operand" "")))
12617 (clobber (reg:CC FLAGS_REG))])]
12618 "TARGET_64BIT"
12619 {
12620 if (! immediate_operand (operands[2], QImode))
12621 {
12622 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12623 DONE;
12624 }
12625 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12626 DONE;
12627 })
12628
12629 (define_insn "lshrti3_1"
12630 [(set (match_operand:TI 0 "register_operand" "=r")
12631 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12632 (match_operand:QI 2 "register_operand" "c")))
12633 (clobber (match_scratch:DI 3 "=&r"))
12634 (clobber (reg:CC FLAGS_REG))]
12635 "TARGET_64BIT"
12636 "#"
12637 [(set_attr "type" "multi")])
12638
12639 ;; This pattern must be defined before *lshrti3_2 to prevent
12640 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12641
12642 (define_insn "sse2_lshrti3"
12643 [(set (match_operand:TI 0 "register_operand" "=x")
12644 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12645 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12646 "TARGET_SSE2"
12647 {
12648 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12649 return "psrldq\t{%2, %0|%0, %2}";
12650 }
12651 [(set_attr "type" "sseishft")
12652 (set_attr "prefix_data16" "1")
12653 (set_attr "mode" "TI")])
12654
12655 (define_insn "*lshrti3_2"
12656 [(set (match_operand:TI 0 "register_operand" "=r")
12657 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12658 (match_operand:QI 2 "immediate_operand" "O")))
12659 (clobber (reg:CC FLAGS_REG))]
12660 "TARGET_64BIT"
12661 "#"
12662 [(set_attr "type" "multi")])
12663
12664 (define_split
12665 [(set (match_operand:TI 0 "register_operand" "")
12666 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12667 (match_operand:QI 2 "register_operand" "")))
12668 (clobber (match_scratch:DI 3 ""))
12669 (clobber (reg:CC FLAGS_REG))]
12670 "TARGET_64BIT && reload_completed"
12671 [(const_int 0)]
12672 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12673
12674 (define_split
12675 [(set (match_operand:TI 0 "register_operand" "")
12676 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12677 (match_operand:QI 2 "immediate_operand" "")))
12678 (clobber (reg:CC FLAGS_REG))]
12679 "TARGET_64BIT && reload_completed"
12680 [(const_int 0)]
12681 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12682
12683 (define_expand "lshrdi3"
12684 [(set (match_operand:DI 0 "shiftdi_operand" "")
12685 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12686 (match_operand:QI 2 "nonmemory_operand" "")))]
12687 ""
12688 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12689
12690 (define_insn "*lshrdi3_1_one_bit_rex64"
12691 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12692 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12693 (match_operand:QI 2 "const1_operand" "")))
12694 (clobber (reg:CC FLAGS_REG))]
12695 "TARGET_64BIT
12696 && (TARGET_SHIFT1 || optimize_size)
12697 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12698 "shr{q}\t%0"
12699 [(set_attr "type" "ishift")
12700 (set (attr "length")
12701 (if_then_else (match_operand:DI 0 "register_operand" "")
12702 (const_string "2")
12703 (const_string "*")))])
12704
12705 (define_insn "*lshrdi3_1_rex64"
12706 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12707 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12708 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12709 (clobber (reg:CC FLAGS_REG))]
12710 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12711 "@
12712 shr{q}\t{%2, %0|%0, %2}
12713 shr{q}\t{%b2, %0|%0, %b2}"
12714 [(set_attr "type" "ishift")
12715 (set_attr "mode" "DI")])
12716
12717 ;; This pattern can't accept a variable shift count, since shifts by
12718 ;; zero don't affect the flags. We assume that shifts by constant
12719 ;; zero are optimized away.
12720 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12721 [(set (reg FLAGS_REG)
12722 (compare
12723 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12724 (match_operand:QI 2 "const1_operand" ""))
12725 (const_int 0)))
12726 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12727 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12728 "TARGET_64BIT
12729 && (TARGET_SHIFT1 || optimize_size)
12730 && ix86_match_ccmode (insn, CCGOCmode)
12731 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12732 "shr{q}\t%0"
12733 [(set_attr "type" "ishift")
12734 (set (attr "length")
12735 (if_then_else (match_operand:DI 0 "register_operand" "")
12736 (const_string "2")
12737 (const_string "*")))])
12738
12739 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12740 [(set (reg FLAGS_REG)
12741 (compare
12742 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12743 (match_operand:QI 2 "const1_operand" ""))
12744 (const_int 0)))
12745 (clobber (match_scratch:DI 0 "=r"))]
12746 "TARGET_64BIT
12747 && (TARGET_SHIFT1 || optimize_size)
12748 && ix86_match_ccmode (insn, CCGOCmode)
12749 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12750 "shr{q}\t%0"
12751 [(set_attr "type" "ishift")
12752 (set_attr "length" "2")])
12753
12754 ;; This pattern can't accept a variable shift count, since shifts by
12755 ;; zero don't affect the flags. We assume that shifts by constant
12756 ;; zero are optimized away.
12757 (define_insn "*lshrdi3_cmp_rex64"
12758 [(set (reg FLAGS_REG)
12759 (compare
12760 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12761 (match_operand:QI 2 "const_int_operand" "e"))
12762 (const_int 0)))
12763 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12764 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12765 "TARGET_64BIT
12766 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12767 && ix86_match_ccmode (insn, CCGOCmode)
12768 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12769 "shr{q}\t{%2, %0|%0, %2}"
12770 [(set_attr "type" "ishift")
12771 (set_attr "mode" "DI")])
12772
12773 (define_insn "*lshrdi3_cconly_rex64"
12774 [(set (reg FLAGS_REG)
12775 (compare
12776 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12777 (match_operand:QI 2 "const_int_operand" "e"))
12778 (const_int 0)))
12779 (clobber (match_scratch:DI 0 "=r"))]
12780 "TARGET_64BIT
12781 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12782 && ix86_match_ccmode (insn, CCGOCmode)
12783 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12784 "shr{q}\t{%2, %0|%0, %2}"
12785 [(set_attr "type" "ishift")
12786 (set_attr "mode" "DI")])
12787
12788 (define_insn "*lshrdi3_1"
12789 [(set (match_operand:DI 0 "register_operand" "=r")
12790 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12791 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12792 (clobber (reg:CC FLAGS_REG))]
12793 "!TARGET_64BIT"
12794 "#"
12795 [(set_attr "type" "multi")])
12796
12797 ;; By default we don't ask for a scratch register, because when DImode
12798 ;; values are manipulated, registers are already at a premium. But if
12799 ;; we have one handy, we won't turn it away.
12800 (define_peephole2
12801 [(match_scratch:SI 3 "r")
12802 (parallel [(set (match_operand:DI 0 "register_operand" "")
12803 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12804 (match_operand:QI 2 "nonmemory_operand" "")))
12805 (clobber (reg:CC FLAGS_REG))])
12806 (match_dup 3)]
12807 "!TARGET_64BIT && TARGET_CMOVE"
12808 [(const_int 0)]
12809 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12810
12811 (define_split
12812 [(set (match_operand:DI 0 "register_operand" "")
12813 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12814 (match_operand:QI 2 "nonmemory_operand" "")))
12815 (clobber (reg:CC FLAGS_REG))]
12816 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12817 ? epilogue_completed : reload_completed)"
12818 [(const_int 0)]
12819 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12820
12821 (define_expand "lshrsi3"
12822 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12823 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12824 (match_operand:QI 2 "nonmemory_operand" "")))
12825 (clobber (reg:CC FLAGS_REG))]
12826 ""
12827 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12828
12829 (define_insn "*lshrsi3_1_one_bit"
12830 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12831 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12832 (match_operand:QI 2 "const1_operand" "")))
12833 (clobber (reg:CC FLAGS_REG))]
12834 "(TARGET_SHIFT1 || optimize_size)
12835 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12836 "shr{l}\t%0"
12837 [(set_attr "type" "ishift")
12838 (set (attr "length")
12839 (if_then_else (match_operand:SI 0 "register_operand" "")
12840 (const_string "2")
12841 (const_string "*")))])
12842
12843 (define_insn "*lshrsi3_1_one_bit_zext"
12844 [(set (match_operand:DI 0 "register_operand" "=r")
12845 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12846 (match_operand:QI 2 "const1_operand" "")))
12847 (clobber (reg:CC FLAGS_REG))]
12848 "TARGET_64BIT
12849 && (TARGET_SHIFT1 || optimize_size)
12850 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12851 "shr{l}\t%k0"
12852 [(set_attr "type" "ishift")
12853 (set_attr "length" "2")])
12854
12855 (define_insn "*lshrsi3_1"
12856 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12857 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12858 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12859 (clobber (reg:CC FLAGS_REG))]
12860 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12861 "@
12862 shr{l}\t{%2, %0|%0, %2}
12863 shr{l}\t{%b2, %0|%0, %b2}"
12864 [(set_attr "type" "ishift")
12865 (set_attr "mode" "SI")])
12866
12867 (define_insn "*lshrsi3_1_zext"
12868 [(set (match_operand:DI 0 "register_operand" "=r,r")
12869 (zero_extend:DI
12870 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12871 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12872 (clobber (reg:CC FLAGS_REG))]
12873 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12874 "@
12875 shr{l}\t{%2, %k0|%k0, %2}
12876 shr{l}\t{%b2, %k0|%k0, %b2}"
12877 [(set_attr "type" "ishift")
12878 (set_attr "mode" "SI")])
12879
12880 ;; This pattern can't accept a variable shift count, since shifts by
12881 ;; zero don't affect the flags. We assume that shifts by constant
12882 ;; zero are optimized away.
12883 (define_insn "*lshrsi3_one_bit_cmp"
12884 [(set (reg FLAGS_REG)
12885 (compare
12886 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12887 (match_operand:QI 2 "const1_operand" ""))
12888 (const_int 0)))
12889 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12890 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12891 "(TARGET_SHIFT1 || optimize_size)
12892 && ix86_match_ccmode (insn, CCGOCmode)
12893 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12894 "shr{l}\t%0"
12895 [(set_attr "type" "ishift")
12896 (set (attr "length")
12897 (if_then_else (match_operand:SI 0 "register_operand" "")
12898 (const_string "2")
12899 (const_string "*")))])
12900
12901 (define_insn "*lshrsi3_one_bit_cconly"
12902 [(set (reg FLAGS_REG)
12903 (compare
12904 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12905 (match_operand:QI 2 "const1_operand" ""))
12906 (const_int 0)))
12907 (clobber (match_scratch:SI 0 "=r"))]
12908 "(TARGET_SHIFT1 || optimize_size)
12909 && ix86_match_ccmode (insn, CCGOCmode)
12910 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12911 "shr{l}\t%0"
12912 [(set_attr "type" "ishift")
12913 (set_attr "length" "2")])
12914
12915 (define_insn "*lshrsi3_cmp_one_bit_zext"
12916 [(set (reg FLAGS_REG)
12917 (compare
12918 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12919 (match_operand:QI 2 "const1_operand" ""))
12920 (const_int 0)))
12921 (set (match_operand:DI 0 "register_operand" "=r")
12922 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12923 "TARGET_64BIT
12924 && (TARGET_SHIFT1 || optimize_size)
12925 && ix86_match_ccmode (insn, CCGOCmode)
12926 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12927 "shr{l}\t%k0"
12928 [(set_attr "type" "ishift")
12929 (set_attr "length" "2")])
12930
12931 ;; This pattern can't accept a variable shift count, since shifts by
12932 ;; zero don't affect the flags. We assume that shifts by constant
12933 ;; zero are optimized away.
12934 (define_insn "*lshrsi3_cmp"
12935 [(set (reg FLAGS_REG)
12936 (compare
12937 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12938 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12939 (const_int 0)))
12940 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12941 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12942 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12943 && ix86_match_ccmode (insn, CCGOCmode)
12944 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12945 "shr{l}\t{%2, %0|%0, %2}"
12946 [(set_attr "type" "ishift")
12947 (set_attr "mode" "SI")])
12948
12949 (define_insn "*lshrsi3_cconly"
12950 [(set (reg FLAGS_REG)
12951 (compare
12952 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12953 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12954 (const_int 0)))
12955 (clobber (match_scratch:SI 0 "=r"))]
12956 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12957 && ix86_match_ccmode (insn, CCGOCmode)
12958 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12959 "shr{l}\t{%2, %0|%0, %2}"
12960 [(set_attr "type" "ishift")
12961 (set_attr "mode" "SI")])
12962
12963 (define_insn "*lshrsi3_cmp_zext"
12964 [(set (reg FLAGS_REG)
12965 (compare
12966 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12967 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12968 (const_int 0)))
12969 (set (match_operand:DI 0 "register_operand" "=r")
12970 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12971 "TARGET_64BIT
12972 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12973 && ix86_match_ccmode (insn, CCGOCmode)
12974 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12975 "shr{l}\t{%2, %k0|%k0, %2}"
12976 [(set_attr "type" "ishift")
12977 (set_attr "mode" "SI")])
12978
12979 (define_expand "lshrhi3"
12980 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12981 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12982 (match_operand:QI 2 "nonmemory_operand" "")))
12983 (clobber (reg:CC FLAGS_REG))]
12984 "TARGET_HIMODE_MATH"
12985 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12986
12987 (define_insn "*lshrhi3_1_one_bit"
12988 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12989 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12990 (match_operand:QI 2 "const1_operand" "")))
12991 (clobber (reg:CC FLAGS_REG))]
12992 "(TARGET_SHIFT1 || optimize_size)
12993 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12994 "shr{w}\t%0"
12995 [(set_attr "type" "ishift")
12996 (set (attr "length")
12997 (if_then_else (match_operand 0 "register_operand" "")
12998 (const_string "2")
12999 (const_string "*")))])
13000
13001 (define_insn "*lshrhi3_1"
13002 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13003 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13004 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13005 (clobber (reg:CC FLAGS_REG))]
13006 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13007 "@
13008 shr{w}\t{%2, %0|%0, %2}
13009 shr{w}\t{%b2, %0|%0, %b2}"
13010 [(set_attr "type" "ishift")
13011 (set_attr "mode" "HI")])
13012
13013 ;; This pattern can't accept a variable shift count, since shifts by
13014 ;; zero don't affect the flags. We assume that shifts by constant
13015 ;; zero are optimized away.
13016 (define_insn "*lshrhi3_one_bit_cmp"
13017 [(set (reg FLAGS_REG)
13018 (compare
13019 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13020 (match_operand:QI 2 "const1_operand" ""))
13021 (const_int 0)))
13022 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13023 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13024 "(TARGET_SHIFT1 || optimize_size)
13025 && ix86_match_ccmode (insn, CCGOCmode)
13026 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13027 "shr{w}\t%0"
13028 [(set_attr "type" "ishift")
13029 (set (attr "length")
13030 (if_then_else (match_operand:SI 0 "register_operand" "")
13031 (const_string "2")
13032 (const_string "*")))])
13033
13034 (define_insn "*lshrhi3_one_bit_cconly"
13035 [(set (reg FLAGS_REG)
13036 (compare
13037 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13038 (match_operand:QI 2 "const1_operand" ""))
13039 (const_int 0)))
13040 (clobber (match_scratch:HI 0 "=r"))]
13041 "(TARGET_SHIFT1 || optimize_size)
13042 && ix86_match_ccmode (insn, CCGOCmode)
13043 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13044 "shr{w}\t%0"
13045 [(set_attr "type" "ishift")
13046 (set_attr "length" "2")])
13047
13048 ;; This pattern can't accept a variable shift count, since shifts by
13049 ;; zero don't affect the flags. We assume that shifts by constant
13050 ;; zero are optimized away.
13051 (define_insn "*lshrhi3_cmp"
13052 [(set (reg FLAGS_REG)
13053 (compare
13054 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13055 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13056 (const_int 0)))
13057 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13058 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13059 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13060 && ix86_match_ccmode (insn, CCGOCmode)
13061 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13062 "shr{w}\t{%2, %0|%0, %2}"
13063 [(set_attr "type" "ishift")
13064 (set_attr "mode" "HI")])
13065
13066 (define_insn "*lshrhi3_cconly"
13067 [(set (reg FLAGS_REG)
13068 (compare
13069 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13070 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13071 (const_int 0)))
13072 (clobber (match_scratch:HI 0 "=r"))]
13073 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13074 && ix86_match_ccmode (insn, CCGOCmode)
13075 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13076 "shr{w}\t{%2, %0|%0, %2}"
13077 [(set_attr "type" "ishift")
13078 (set_attr "mode" "HI")])
13079
13080 (define_expand "lshrqi3"
13081 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13082 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13083 (match_operand:QI 2 "nonmemory_operand" "")))
13084 (clobber (reg:CC FLAGS_REG))]
13085 "TARGET_QIMODE_MATH"
13086 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13087
13088 (define_insn "*lshrqi3_1_one_bit"
13089 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13090 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13091 (match_operand:QI 2 "const1_operand" "")))
13092 (clobber (reg:CC FLAGS_REG))]
13093 "(TARGET_SHIFT1 || optimize_size)
13094 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13095 "shr{b}\t%0"
13096 [(set_attr "type" "ishift")
13097 (set (attr "length")
13098 (if_then_else (match_operand 0 "register_operand" "")
13099 (const_string "2")
13100 (const_string "*")))])
13101
13102 (define_insn "*lshrqi3_1_one_bit_slp"
13103 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13104 (lshiftrt:QI (match_dup 0)
13105 (match_operand:QI 1 "const1_operand" "")))
13106 (clobber (reg:CC FLAGS_REG))]
13107 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13108 && (TARGET_SHIFT1 || optimize_size)"
13109 "shr{b}\t%0"
13110 [(set_attr "type" "ishift1")
13111 (set (attr "length")
13112 (if_then_else (match_operand 0 "register_operand" "")
13113 (const_string "2")
13114 (const_string "*")))])
13115
13116 (define_insn "*lshrqi3_1"
13117 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13118 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13119 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13120 (clobber (reg:CC FLAGS_REG))]
13121 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13122 "@
13123 shr{b}\t{%2, %0|%0, %2}
13124 shr{b}\t{%b2, %0|%0, %b2}"
13125 [(set_attr "type" "ishift")
13126 (set_attr "mode" "QI")])
13127
13128 (define_insn "*lshrqi3_1_slp"
13129 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13130 (lshiftrt:QI (match_dup 0)
13131 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13132 (clobber (reg:CC FLAGS_REG))]
13133 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13134 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13135 "@
13136 shr{b}\t{%1, %0|%0, %1}
13137 shr{b}\t{%b1, %0|%0, %b1}"
13138 [(set_attr "type" "ishift1")
13139 (set_attr "mode" "QI")])
13140
13141 ;; This pattern can't accept a variable shift count, since shifts by
13142 ;; zero don't affect the flags. We assume that shifts by constant
13143 ;; zero are optimized away.
13144 (define_insn "*lshrqi2_one_bit_cmp"
13145 [(set (reg FLAGS_REG)
13146 (compare
13147 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13148 (match_operand:QI 2 "const1_operand" ""))
13149 (const_int 0)))
13150 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13151 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13152 "(TARGET_SHIFT1 || optimize_size)
13153 && ix86_match_ccmode (insn, CCGOCmode)
13154 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13155 "shr{b}\t%0"
13156 [(set_attr "type" "ishift")
13157 (set (attr "length")
13158 (if_then_else (match_operand:SI 0 "register_operand" "")
13159 (const_string "2")
13160 (const_string "*")))])
13161
13162 (define_insn "*lshrqi2_one_bit_cconly"
13163 [(set (reg FLAGS_REG)
13164 (compare
13165 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13166 (match_operand:QI 2 "const1_operand" ""))
13167 (const_int 0)))
13168 (clobber (match_scratch:QI 0 "=q"))]
13169 "(TARGET_SHIFT1 || optimize_size)
13170 && ix86_match_ccmode (insn, CCGOCmode)
13171 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13172 "shr{b}\t%0"
13173 [(set_attr "type" "ishift")
13174 (set_attr "length" "2")])
13175
13176 ;; This pattern can't accept a variable shift count, since shifts by
13177 ;; zero don't affect the flags. We assume that shifts by constant
13178 ;; zero are optimized away.
13179 (define_insn "*lshrqi2_cmp"
13180 [(set (reg FLAGS_REG)
13181 (compare
13182 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13183 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13184 (const_int 0)))
13185 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13186 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13187 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13188 && ix86_match_ccmode (insn, CCGOCmode)
13189 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13190 "shr{b}\t{%2, %0|%0, %2}"
13191 [(set_attr "type" "ishift")
13192 (set_attr "mode" "QI")])
13193
13194 (define_insn "*lshrqi2_cconly"
13195 [(set (reg FLAGS_REG)
13196 (compare
13197 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13198 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13199 (const_int 0)))
13200 (clobber (match_scratch:QI 0 "=q"))]
13201 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13202 && ix86_match_ccmode (insn, CCGOCmode)
13203 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13204 "shr{b}\t{%2, %0|%0, %2}"
13205 [(set_attr "type" "ishift")
13206 (set_attr "mode" "QI")])
13207 \f
13208 ;; Rotate instructions
13209
13210 (define_expand "rotldi3"
13211 [(set (match_operand:DI 0 "shiftdi_operand" "")
13212 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13213 (match_operand:QI 2 "nonmemory_operand" "")))
13214 (clobber (reg:CC FLAGS_REG))]
13215 ""
13216 {
13217 if (TARGET_64BIT)
13218 {
13219 ix86_expand_binary_operator (ROTATE, DImode, operands);
13220 DONE;
13221 }
13222 if (!const_1_to_31_operand (operands[2], VOIDmode))
13223 FAIL;
13224 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13225 DONE;
13226 })
13227
13228 ;; Implement rotation using two double-precision shift instructions
13229 ;; and a scratch register.
13230 (define_insn_and_split "ix86_rotldi3"
13231 [(set (match_operand:DI 0 "register_operand" "=r")
13232 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13233 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13234 (clobber (reg:CC FLAGS_REG))
13235 (clobber (match_scratch:SI 3 "=&r"))]
13236 "!TARGET_64BIT"
13237 ""
13238 "&& reload_completed"
13239 [(set (match_dup 3) (match_dup 4))
13240 (parallel
13241 [(set (match_dup 4)
13242 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13243 (lshiftrt:SI (match_dup 5)
13244 (minus:QI (const_int 32) (match_dup 2)))))
13245 (clobber (reg:CC FLAGS_REG))])
13246 (parallel
13247 [(set (match_dup 5)
13248 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13249 (lshiftrt:SI (match_dup 3)
13250 (minus:QI (const_int 32) (match_dup 2)))))
13251 (clobber (reg:CC FLAGS_REG))])]
13252 "split_di (operands, 1, operands + 4, operands + 5);")
13253
13254 (define_insn "*rotlsi3_1_one_bit_rex64"
13255 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13256 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13257 (match_operand:QI 2 "const1_operand" "")))
13258 (clobber (reg:CC FLAGS_REG))]
13259 "TARGET_64BIT
13260 && (TARGET_SHIFT1 || optimize_size)
13261 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13262 "rol{q}\t%0"
13263 [(set_attr "type" "rotate")
13264 (set (attr "length")
13265 (if_then_else (match_operand:DI 0 "register_operand" "")
13266 (const_string "2")
13267 (const_string "*")))])
13268
13269 (define_insn "*rotldi3_1_rex64"
13270 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13271 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13272 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13273 (clobber (reg:CC FLAGS_REG))]
13274 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13275 "@
13276 rol{q}\t{%2, %0|%0, %2}
13277 rol{q}\t{%b2, %0|%0, %b2}"
13278 [(set_attr "type" "rotate")
13279 (set_attr "mode" "DI")])
13280
13281 (define_expand "rotlsi3"
13282 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13283 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13284 (match_operand:QI 2 "nonmemory_operand" "")))
13285 (clobber (reg:CC FLAGS_REG))]
13286 ""
13287 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13288
13289 (define_insn "*rotlsi3_1_one_bit"
13290 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13291 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13292 (match_operand:QI 2 "const1_operand" "")))
13293 (clobber (reg:CC FLAGS_REG))]
13294 "(TARGET_SHIFT1 || optimize_size)
13295 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13296 "rol{l}\t%0"
13297 [(set_attr "type" "rotate")
13298 (set (attr "length")
13299 (if_then_else (match_operand:SI 0 "register_operand" "")
13300 (const_string "2")
13301 (const_string "*")))])
13302
13303 (define_insn "*rotlsi3_1_one_bit_zext"
13304 [(set (match_operand:DI 0 "register_operand" "=r")
13305 (zero_extend:DI
13306 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13307 (match_operand:QI 2 "const1_operand" ""))))
13308 (clobber (reg:CC FLAGS_REG))]
13309 "TARGET_64BIT
13310 && (TARGET_SHIFT1 || optimize_size)
13311 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13312 "rol{l}\t%k0"
13313 [(set_attr "type" "rotate")
13314 (set_attr "length" "2")])
13315
13316 (define_insn "*rotlsi3_1"
13317 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13318 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13319 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13320 (clobber (reg:CC FLAGS_REG))]
13321 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13322 "@
13323 rol{l}\t{%2, %0|%0, %2}
13324 rol{l}\t{%b2, %0|%0, %b2}"
13325 [(set_attr "type" "rotate")
13326 (set_attr "mode" "SI")])
13327
13328 (define_insn "*rotlsi3_1_zext"
13329 [(set (match_operand:DI 0 "register_operand" "=r,r")
13330 (zero_extend:DI
13331 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13332 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13333 (clobber (reg:CC FLAGS_REG))]
13334 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13335 "@
13336 rol{l}\t{%2, %k0|%k0, %2}
13337 rol{l}\t{%b2, %k0|%k0, %b2}"
13338 [(set_attr "type" "rotate")
13339 (set_attr "mode" "SI")])
13340
13341 (define_expand "rotlhi3"
13342 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13343 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13344 (match_operand:QI 2 "nonmemory_operand" "")))
13345 (clobber (reg:CC FLAGS_REG))]
13346 "TARGET_HIMODE_MATH"
13347 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13348
13349 (define_insn "*rotlhi3_1_one_bit"
13350 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13351 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13352 (match_operand:QI 2 "const1_operand" "")))
13353 (clobber (reg:CC FLAGS_REG))]
13354 "(TARGET_SHIFT1 || optimize_size)
13355 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13356 "rol{w}\t%0"
13357 [(set_attr "type" "rotate")
13358 (set (attr "length")
13359 (if_then_else (match_operand 0 "register_operand" "")
13360 (const_string "2")
13361 (const_string "*")))])
13362
13363 (define_insn "*rotlhi3_1"
13364 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13365 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13366 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13367 (clobber (reg:CC FLAGS_REG))]
13368 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13369 "@
13370 rol{w}\t{%2, %0|%0, %2}
13371 rol{w}\t{%b2, %0|%0, %b2}"
13372 [(set_attr "type" "rotate")
13373 (set_attr "mode" "HI")])
13374
13375 (define_split
13376 [(set (match_operand:HI 0 "register_operand" "")
13377 (rotate:HI (match_dup 0) (const_int 8)))
13378 (clobber (reg:CC FLAGS_REG))]
13379 "reload_completed"
13380 [(parallel [(set (strict_low_part (match_dup 0))
13381 (bswap:HI (match_dup 0)))
13382 (clobber (reg:CC FLAGS_REG))])]
13383 "")
13384
13385 (define_expand "rotlqi3"
13386 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13387 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13388 (match_operand:QI 2 "nonmemory_operand" "")))
13389 (clobber (reg:CC FLAGS_REG))]
13390 "TARGET_QIMODE_MATH"
13391 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13392
13393 (define_insn "*rotlqi3_1_one_bit_slp"
13394 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13395 (rotate:QI (match_dup 0)
13396 (match_operand:QI 1 "const1_operand" "")))
13397 (clobber (reg:CC FLAGS_REG))]
13398 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13399 && (TARGET_SHIFT1 || optimize_size)"
13400 "rol{b}\t%0"
13401 [(set_attr "type" "rotate1")
13402 (set (attr "length")
13403 (if_then_else (match_operand 0 "register_operand" "")
13404 (const_string "2")
13405 (const_string "*")))])
13406
13407 (define_insn "*rotlqi3_1_one_bit"
13408 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13409 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13410 (match_operand:QI 2 "const1_operand" "")))
13411 (clobber (reg:CC FLAGS_REG))]
13412 "(TARGET_SHIFT1 || optimize_size)
13413 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13414 "rol{b}\t%0"
13415 [(set_attr "type" "rotate")
13416 (set (attr "length")
13417 (if_then_else (match_operand 0 "register_operand" "")
13418 (const_string "2")
13419 (const_string "*")))])
13420
13421 (define_insn "*rotlqi3_1_slp"
13422 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13423 (rotate:QI (match_dup 0)
13424 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13425 (clobber (reg:CC FLAGS_REG))]
13426 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13427 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13428 "@
13429 rol{b}\t{%1, %0|%0, %1}
13430 rol{b}\t{%b1, %0|%0, %b1}"
13431 [(set_attr "type" "rotate1")
13432 (set_attr "mode" "QI")])
13433
13434 (define_insn "*rotlqi3_1"
13435 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13436 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13437 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13438 (clobber (reg:CC FLAGS_REG))]
13439 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13440 "@
13441 rol{b}\t{%2, %0|%0, %2}
13442 rol{b}\t{%b2, %0|%0, %b2}"
13443 [(set_attr "type" "rotate")
13444 (set_attr "mode" "QI")])
13445
13446 (define_expand "rotrdi3"
13447 [(set (match_operand:DI 0 "shiftdi_operand" "")
13448 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13449 (match_operand:QI 2 "nonmemory_operand" "")))
13450 (clobber (reg:CC FLAGS_REG))]
13451 ""
13452 {
13453 if (TARGET_64BIT)
13454 {
13455 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13456 DONE;
13457 }
13458 if (!const_1_to_31_operand (operands[2], VOIDmode))
13459 FAIL;
13460 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13461 DONE;
13462 })
13463
13464 ;; Implement rotation using two double-precision shift instructions
13465 ;; and a scratch register.
13466 (define_insn_and_split "ix86_rotrdi3"
13467 [(set (match_operand:DI 0 "register_operand" "=r")
13468 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13469 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13470 (clobber (reg:CC FLAGS_REG))
13471 (clobber (match_scratch:SI 3 "=&r"))]
13472 "!TARGET_64BIT"
13473 ""
13474 "&& reload_completed"
13475 [(set (match_dup 3) (match_dup 4))
13476 (parallel
13477 [(set (match_dup 4)
13478 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13479 (ashift:SI (match_dup 5)
13480 (minus:QI (const_int 32) (match_dup 2)))))
13481 (clobber (reg:CC FLAGS_REG))])
13482 (parallel
13483 [(set (match_dup 5)
13484 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13485 (ashift:SI (match_dup 3)
13486 (minus:QI (const_int 32) (match_dup 2)))))
13487 (clobber (reg:CC FLAGS_REG))])]
13488 "split_di (operands, 1, operands + 4, operands + 5);")
13489
13490 (define_insn "*rotrdi3_1_one_bit_rex64"
13491 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13492 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13493 (match_operand:QI 2 "const1_operand" "")))
13494 (clobber (reg:CC FLAGS_REG))]
13495 "TARGET_64BIT
13496 && (TARGET_SHIFT1 || optimize_size)
13497 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13498 "ror{q}\t%0"
13499 [(set_attr "type" "rotate")
13500 (set (attr "length")
13501 (if_then_else (match_operand:DI 0 "register_operand" "")
13502 (const_string "2")
13503 (const_string "*")))])
13504
13505 (define_insn "*rotrdi3_1_rex64"
13506 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13507 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13508 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13509 (clobber (reg:CC FLAGS_REG))]
13510 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13511 "@
13512 ror{q}\t{%2, %0|%0, %2}
13513 ror{q}\t{%b2, %0|%0, %b2}"
13514 [(set_attr "type" "rotate")
13515 (set_attr "mode" "DI")])
13516
13517 (define_expand "rotrsi3"
13518 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13519 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13520 (match_operand:QI 2 "nonmemory_operand" "")))
13521 (clobber (reg:CC FLAGS_REG))]
13522 ""
13523 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13524
13525 (define_insn "*rotrsi3_1_one_bit"
13526 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13527 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13528 (match_operand:QI 2 "const1_operand" "")))
13529 (clobber (reg:CC FLAGS_REG))]
13530 "(TARGET_SHIFT1 || optimize_size)
13531 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13532 "ror{l}\t%0"
13533 [(set_attr "type" "rotate")
13534 (set (attr "length")
13535 (if_then_else (match_operand:SI 0 "register_operand" "")
13536 (const_string "2")
13537 (const_string "*")))])
13538
13539 (define_insn "*rotrsi3_1_one_bit_zext"
13540 [(set (match_operand:DI 0 "register_operand" "=r")
13541 (zero_extend:DI
13542 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13543 (match_operand:QI 2 "const1_operand" ""))))
13544 (clobber (reg:CC FLAGS_REG))]
13545 "TARGET_64BIT
13546 && (TARGET_SHIFT1 || optimize_size)
13547 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13548 "ror{l}\t%k0"
13549 [(set_attr "type" "rotate")
13550 (set (attr "length")
13551 (if_then_else (match_operand:SI 0 "register_operand" "")
13552 (const_string "2")
13553 (const_string "*")))])
13554
13555 (define_insn "*rotrsi3_1"
13556 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13557 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13558 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13559 (clobber (reg:CC FLAGS_REG))]
13560 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13561 "@
13562 ror{l}\t{%2, %0|%0, %2}
13563 ror{l}\t{%b2, %0|%0, %b2}"
13564 [(set_attr "type" "rotate")
13565 (set_attr "mode" "SI")])
13566
13567 (define_insn "*rotrsi3_1_zext"
13568 [(set (match_operand:DI 0 "register_operand" "=r,r")
13569 (zero_extend:DI
13570 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13571 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13572 (clobber (reg:CC FLAGS_REG))]
13573 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13574 "@
13575 ror{l}\t{%2, %k0|%k0, %2}
13576 ror{l}\t{%b2, %k0|%k0, %b2}"
13577 [(set_attr "type" "rotate")
13578 (set_attr "mode" "SI")])
13579
13580 (define_expand "rotrhi3"
13581 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13582 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13583 (match_operand:QI 2 "nonmemory_operand" "")))
13584 (clobber (reg:CC FLAGS_REG))]
13585 "TARGET_HIMODE_MATH"
13586 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13587
13588 (define_insn "*rotrhi3_one_bit"
13589 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13590 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13591 (match_operand:QI 2 "const1_operand" "")))
13592 (clobber (reg:CC FLAGS_REG))]
13593 "(TARGET_SHIFT1 || optimize_size)
13594 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13595 "ror{w}\t%0"
13596 [(set_attr "type" "rotate")
13597 (set (attr "length")
13598 (if_then_else (match_operand 0 "register_operand" "")
13599 (const_string "2")
13600 (const_string "*")))])
13601
13602 (define_insn "*rotrhi3_1"
13603 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13604 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13605 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13606 (clobber (reg:CC FLAGS_REG))]
13607 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13608 "@
13609 ror{w}\t{%2, %0|%0, %2}
13610 ror{w}\t{%b2, %0|%0, %b2}"
13611 [(set_attr "type" "rotate")
13612 (set_attr "mode" "HI")])
13613
13614 (define_split
13615 [(set (match_operand:HI 0 "register_operand" "")
13616 (rotatert:HI (match_dup 0) (const_int 8)))
13617 (clobber (reg:CC FLAGS_REG))]
13618 "reload_completed"
13619 [(parallel [(set (strict_low_part (match_dup 0))
13620 (bswap:HI (match_dup 0)))
13621 (clobber (reg:CC FLAGS_REG))])]
13622 "")
13623
13624 (define_expand "rotrqi3"
13625 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13626 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13627 (match_operand:QI 2 "nonmemory_operand" "")))
13628 (clobber (reg:CC FLAGS_REG))]
13629 "TARGET_QIMODE_MATH"
13630 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13631
13632 (define_insn "*rotrqi3_1_one_bit"
13633 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13634 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13635 (match_operand:QI 2 "const1_operand" "")))
13636 (clobber (reg:CC FLAGS_REG))]
13637 "(TARGET_SHIFT1 || optimize_size)
13638 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13639 "ror{b}\t%0"
13640 [(set_attr "type" "rotate")
13641 (set (attr "length")
13642 (if_then_else (match_operand 0 "register_operand" "")
13643 (const_string "2")
13644 (const_string "*")))])
13645
13646 (define_insn "*rotrqi3_1_one_bit_slp"
13647 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13648 (rotatert:QI (match_dup 0)
13649 (match_operand:QI 1 "const1_operand" "")))
13650 (clobber (reg:CC FLAGS_REG))]
13651 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13652 && (TARGET_SHIFT1 || optimize_size)"
13653 "ror{b}\t%0"
13654 [(set_attr "type" "rotate1")
13655 (set (attr "length")
13656 (if_then_else (match_operand 0 "register_operand" "")
13657 (const_string "2")
13658 (const_string "*")))])
13659
13660 (define_insn "*rotrqi3_1"
13661 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13662 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13663 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13664 (clobber (reg:CC FLAGS_REG))]
13665 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13666 "@
13667 ror{b}\t{%2, %0|%0, %2}
13668 ror{b}\t{%b2, %0|%0, %b2}"
13669 [(set_attr "type" "rotate")
13670 (set_attr "mode" "QI")])
13671
13672 (define_insn "*rotrqi3_1_slp"
13673 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13674 (rotatert:QI (match_dup 0)
13675 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13676 (clobber (reg:CC FLAGS_REG))]
13677 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13678 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13679 "@
13680 ror{b}\t{%1, %0|%0, %1}
13681 ror{b}\t{%b1, %0|%0, %b1}"
13682 [(set_attr "type" "rotate1")
13683 (set_attr "mode" "QI")])
13684 \f
13685 ;; Bit set / bit test instructions
13686
13687 (define_expand "extv"
13688 [(set (match_operand:SI 0 "register_operand" "")
13689 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13690 (match_operand:SI 2 "const8_operand" "")
13691 (match_operand:SI 3 "const8_operand" "")))]
13692 ""
13693 {
13694 /* Handle extractions from %ah et al. */
13695 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13696 FAIL;
13697
13698 /* From mips.md: extract_bit_field doesn't verify that our source
13699 matches the predicate, so check it again here. */
13700 if (! ext_register_operand (operands[1], VOIDmode))
13701 FAIL;
13702 })
13703
13704 (define_expand "extzv"
13705 [(set (match_operand:SI 0 "register_operand" "")
13706 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13707 (match_operand:SI 2 "const8_operand" "")
13708 (match_operand:SI 3 "const8_operand" "")))]
13709 ""
13710 {
13711 /* Handle extractions from %ah et al. */
13712 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13713 FAIL;
13714
13715 /* From mips.md: extract_bit_field doesn't verify that our source
13716 matches the predicate, so check it again here. */
13717 if (! ext_register_operand (operands[1], VOIDmode))
13718 FAIL;
13719 })
13720
13721 (define_expand "insv"
13722 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13723 (match_operand 1 "const8_operand" "")
13724 (match_operand 2 "const8_operand" ""))
13725 (match_operand 3 "register_operand" ""))]
13726 ""
13727 {
13728 /* Handle insertions to %ah et al. */
13729 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13730 FAIL;
13731
13732 /* From mips.md: insert_bit_field doesn't verify that our source
13733 matches the predicate, so check it again here. */
13734 if (! ext_register_operand (operands[0], VOIDmode))
13735 FAIL;
13736
13737 if (TARGET_64BIT)
13738 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13739 else
13740 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13741
13742 DONE;
13743 })
13744
13745 ;; %%% bts, btr, btc, bt.
13746 ;; In general these instructions are *slow* when applied to memory,
13747 ;; since they enforce atomic operation. When applied to registers,
13748 ;; it depends on the cpu implementation. They're never faster than
13749 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13750 ;; no point. But in 64-bit, we can't hold the relevant immediates
13751 ;; within the instruction itself, so operating on bits in the high
13752 ;; 32-bits of a register becomes easier.
13753 ;;
13754 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13755 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13756 ;; negdf respectively, so they can never be disabled entirely.
13757
13758 (define_insn "*btsq"
13759 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13760 (const_int 1)
13761 (match_operand:DI 1 "const_0_to_63_operand" ""))
13762 (const_int 1))
13763 (clobber (reg:CC FLAGS_REG))]
13764 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13765 "bts{q} %1,%0"
13766 [(set_attr "type" "alu1")])
13767
13768 (define_insn "*btrq"
13769 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13770 (const_int 1)
13771 (match_operand:DI 1 "const_0_to_63_operand" ""))
13772 (const_int 0))
13773 (clobber (reg:CC FLAGS_REG))]
13774 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13775 "btr{q} %1,%0"
13776 [(set_attr "type" "alu1")])
13777
13778 (define_insn "*btcq"
13779 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13780 (const_int 1)
13781 (match_operand:DI 1 "const_0_to_63_operand" ""))
13782 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13783 (clobber (reg:CC FLAGS_REG))]
13784 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13785 "btc{q} %1,%0"
13786 [(set_attr "type" "alu1")])
13787
13788 ;; Allow Nocona to avoid these instructions if a register is available.
13789
13790 (define_peephole2
13791 [(match_scratch:DI 2 "r")
13792 (parallel [(set (zero_extract:DI
13793 (match_operand:DI 0 "register_operand" "")
13794 (const_int 1)
13795 (match_operand:DI 1 "const_0_to_63_operand" ""))
13796 (const_int 1))
13797 (clobber (reg:CC FLAGS_REG))])]
13798 "TARGET_64BIT && !TARGET_USE_BT"
13799 [(const_int 0)]
13800 {
13801 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13802 rtx op1;
13803
13804 if (HOST_BITS_PER_WIDE_INT >= 64)
13805 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13806 else if (i < HOST_BITS_PER_WIDE_INT)
13807 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13808 else
13809 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13810
13811 op1 = immed_double_const (lo, hi, DImode);
13812 if (i >= 31)
13813 {
13814 emit_move_insn (operands[2], op1);
13815 op1 = operands[2];
13816 }
13817
13818 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13819 DONE;
13820 })
13821
13822 (define_peephole2
13823 [(match_scratch:DI 2 "r")
13824 (parallel [(set (zero_extract:DI
13825 (match_operand:DI 0 "register_operand" "")
13826 (const_int 1)
13827 (match_operand:DI 1 "const_0_to_63_operand" ""))
13828 (const_int 0))
13829 (clobber (reg:CC FLAGS_REG))])]
13830 "TARGET_64BIT && !TARGET_USE_BT"
13831 [(const_int 0)]
13832 {
13833 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13834 rtx op1;
13835
13836 if (HOST_BITS_PER_WIDE_INT >= 64)
13837 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13838 else if (i < HOST_BITS_PER_WIDE_INT)
13839 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13840 else
13841 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13842
13843 op1 = immed_double_const (~lo, ~hi, DImode);
13844 if (i >= 32)
13845 {
13846 emit_move_insn (operands[2], op1);
13847 op1 = operands[2];
13848 }
13849
13850 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13851 DONE;
13852 })
13853
13854 (define_peephole2
13855 [(match_scratch:DI 2 "r")
13856 (parallel [(set (zero_extract:DI
13857 (match_operand:DI 0 "register_operand" "")
13858 (const_int 1)
13859 (match_operand:DI 1 "const_0_to_63_operand" ""))
13860 (not:DI (zero_extract:DI
13861 (match_dup 0) (const_int 1) (match_dup 1))))
13862 (clobber (reg:CC FLAGS_REG))])]
13863 "TARGET_64BIT && !TARGET_USE_BT"
13864 [(const_int 0)]
13865 {
13866 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13867 rtx op1;
13868
13869 if (HOST_BITS_PER_WIDE_INT >= 64)
13870 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13871 else if (i < HOST_BITS_PER_WIDE_INT)
13872 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13873 else
13874 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13875
13876 op1 = immed_double_const (lo, hi, DImode);
13877 if (i >= 31)
13878 {
13879 emit_move_insn (operands[2], op1);
13880 op1 = operands[2];
13881 }
13882
13883 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13884 DONE;
13885 })
13886 \f
13887 ;; Store-flag instructions.
13888
13889 ;; For all sCOND expanders, also expand the compare or test insn that
13890 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13891
13892 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13893 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13894 ;; way, which can later delete the movzx if only QImode is needed.
13895
13896 (define_expand "seq"
13897 [(set (match_operand:QI 0 "register_operand" "")
13898 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13899 ""
13900 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13901
13902 (define_expand "sne"
13903 [(set (match_operand:QI 0 "register_operand" "")
13904 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13905 ""
13906 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13907
13908 (define_expand "sgt"
13909 [(set (match_operand:QI 0 "register_operand" "")
13910 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13911 ""
13912 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13913
13914 (define_expand "sgtu"
13915 [(set (match_operand:QI 0 "register_operand" "")
13916 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13917 ""
13918 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13919
13920 (define_expand "slt"
13921 [(set (match_operand:QI 0 "register_operand" "")
13922 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13923 ""
13924 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13925
13926 (define_expand "sltu"
13927 [(set (match_operand:QI 0 "register_operand" "")
13928 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13929 ""
13930 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13931
13932 (define_expand "sge"
13933 [(set (match_operand:QI 0 "register_operand" "")
13934 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13935 ""
13936 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13937
13938 (define_expand "sgeu"
13939 [(set (match_operand:QI 0 "register_operand" "")
13940 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13941 ""
13942 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13943
13944 (define_expand "sle"
13945 [(set (match_operand:QI 0 "register_operand" "")
13946 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13947 ""
13948 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13949
13950 (define_expand "sleu"
13951 [(set (match_operand:QI 0 "register_operand" "")
13952 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13953 ""
13954 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13955
13956 (define_expand "sunordered"
13957 [(set (match_operand:QI 0 "register_operand" "")
13958 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13959 "TARGET_80387 || TARGET_SSE"
13960 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13961
13962 (define_expand "sordered"
13963 [(set (match_operand:QI 0 "register_operand" "")
13964 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13965 "TARGET_80387"
13966 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13967
13968 (define_expand "suneq"
13969 [(set (match_operand:QI 0 "register_operand" "")
13970 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13971 "TARGET_80387 || TARGET_SSE"
13972 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13973
13974 (define_expand "sunge"
13975 [(set (match_operand:QI 0 "register_operand" "")
13976 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13977 "TARGET_80387 || TARGET_SSE"
13978 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13979
13980 (define_expand "sungt"
13981 [(set (match_operand:QI 0 "register_operand" "")
13982 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13983 "TARGET_80387 || TARGET_SSE"
13984 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13985
13986 (define_expand "sunle"
13987 [(set (match_operand:QI 0 "register_operand" "")
13988 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13989 "TARGET_80387 || TARGET_SSE"
13990 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13991
13992 (define_expand "sunlt"
13993 [(set (match_operand:QI 0 "register_operand" "")
13994 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13995 "TARGET_80387 || TARGET_SSE"
13996 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13997
13998 (define_expand "sltgt"
13999 [(set (match_operand:QI 0 "register_operand" "")
14000 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
14001 "TARGET_80387 || TARGET_SSE"
14002 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
14003
14004 (define_insn "*setcc_1"
14005 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14006 (match_operator:QI 1 "ix86_comparison_operator"
14007 [(reg FLAGS_REG) (const_int 0)]))]
14008 ""
14009 "set%C1\t%0"
14010 [(set_attr "type" "setcc")
14011 (set_attr "mode" "QI")])
14012
14013 (define_insn "*setcc_2"
14014 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14015 (match_operator:QI 1 "ix86_comparison_operator"
14016 [(reg FLAGS_REG) (const_int 0)]))]
14017 ""
14018 "set%C1\t%0"
14019 [(set_attr "type" "setcc")
14020 (set_attr "mode" "QI")])
14021
14022 ;; In general it is not safe to assume too much about CCmode registers,
14023 ;; so simplify-rtx stops when it sees a second one. Under certain
14024 ;; conditions this is safe on x86, so help combine not create
14025 ;;
14026 ;; seta %al
14027 ;; testb %al, %al
14028 ;; sete %al
14029
14030 (define_split
14031 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14032 (ne:QI (match_operator 1 "ix86_comparison_operator"
14033 [(reg FLAGS_REG) (const_int 0)])
14034 (const_int 0)))]
14035 ""
14036 [(set (match_dup 0) (match_dup 1))]
14037 {
14038 PUT_MODE (operands[1], QImode);
14039 })
14040
14041 (define_split
14042 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14043 (ne:QI (match_operator 1 "ix86_comparison_operator"
14044 [(reg FLAGS_REG) (const_int 0)])
14045 (const_int 0)))]
14046 ""
14047 [(set (match_dup 0) (match_dup 1))]
14048 {
14049 PUT_MODE (operands[1], QImode);
14050 })
14051
14052 (define_split
14053 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14054 (eq:QI (match_operator 1 "ix86_comparison_operator"
14055 [(reg FLAGS_REG) (const_int 0)])
14056 (const_int 0)))]
14057 ""
14058 [(set (match_dup 0) (match_dup 1))]
14059 {
14060 rtx new_op1 = copy_rtx (operands[1]);
14061 operands[1] = new_op1;
14062 PUT_MODE (new_op1, QImode);
14063 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14064 GET_MODE (XEXP (new_op1, 0))));
14065
14066 /* Make sure that (a) the CCmode we have for the flags is strong
14067 enough for the reversed compare or (b) we have a valid FP compare. */
14068 if (! ix86_comparison_operator (new_op1, VOIDmode))
14069 FAIL;
14070 })
14071
14072 (define_split
14073 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14074 (eq:QI (match_operator 1 "ix86_comparison_operator"
14075 [(reg FLAGS_REG) (const_int 0)])
14076 (const_int 0)))]
14077 ""
14078 [(set (match_dup 0) (match_dup 1))]
14079 {
14080 rtx new_op1 = copy_rtx (operands[1]);
14081 operands[1] = new_op1;
14082 PUT_MODE (new_op1, QImode);
14083 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14084 GET_MODE (XEXP (new_op1, 0))));
14085
14086 /* Make sure that (a) the CCmode we have for the flags is strong
14087 enough for the reversed compare or (b) we have a valid FP compare. */
14088 if (! ix86_comparison_operator (new_op1, VOIDmode))
14089 FAIL;
14090 })
14091
14092 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14093 ;; subsequent logical operations are used to imitate conditional moves.
14094 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14095 ;; it directly.
14096
14097 (define_insn "*sse_setccsf"
14098 [(set (match_operand:SF 0 "register_operand" "=x")
14099 (match_operator:SF 1 "sse_comparison_operator"
14100 [(match_operand:SF 2 "register_operand" "0")
14101 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
14102 "TARGET_SSE && !TARGET_SSE5"
14103 "cmp%D1ss\t{%3, %0|%0, %3}"
14104 [(set_attr "type" "ssecmp")
14105 (set_attr "mode" "SF")])
14106
14107 (define_insn "*sse_setccdf"
14108 [(set (match_operand:DF 0 "register_operand" "=x")
14109 (match_operator:DF 1 "sse_comparison_operator"
14110 [(match_operand:DF 2 "register_operand" "0")
14111 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
14112 "TARGET_SSE2 && !TARGET_SSE5"
14113 "cmp%D1sd\t{%3, %0|%0, %3}"
14114 [(set_attr "type" "ssecmp")
14115 (set_attr "mode" "DF")])
14116
14117 (define_insn "*sse5_setcc<mode>"
14118 [(set (match_operand:MODEF 0 "register_operand" "=x")
14119 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14120 [(match_operand:MODEF 2 "register_operand" "x")
14121 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14122 "TARGET_SSE5"
14123 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14124 [(set_attr "type" "sse4arg")
14125 (set_attr "mode" "<MODE>")])
14126
14127 \f
14128 ;; Basic conditional jump instructions.
14129 ;; We ignore the overflow flag for signed branch instructions.
14130
14131 ;; For all bCOND expanders, also expand the compare or test insn that
14132 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14133
14134 (define_expand "beq"
14135 [(set (pc)
14136 (if_then_else (match_dup 1)
14137 (label_ref (match_operand 0 "" ""))
14138 (pc)))]
14139 ""
14140 "ix86_expand_branch (EQ, operands[0]); DONE;")
14141
14142 (define_expand "bne"
14143 [(set (pc)
14144 (if_then_else (match_dup 1)
14145 (label_ref (match_operand 0 "" ""))
14146 (pc)))]
14147 ""
14148 "ix86_expand_branch (NE, operands[0]); DONE;")
14149
14150 (define_expand "bgt"
14151 [(set (pc)
14152 (if_then_else (match_dup 1)
14153 (label_ref (match_operand 0 "" ""))
14154 (pc)))]
14155 ""
14156 "ix86_expand_branch (GT, operands[0]); DONE;")
14157
14158 (define_expand "bgtu"
14159 [(set (pc)
14160 (if_then_else (match_dup 1)
14161 (label_ref (match_operand 0 "" ""))
14162 (pc)))]
14163 ""
14164 "ix86_expand_branch (GTU, operands[0]); DONE;")
14165
14166 (define_expand "blt"
14167 [(set (pc)
14168 (if_then_else (match_dup 1)
14169 (label_ref (match_operand 0 "" ""))
14170 (pc)))]
14171 ""
14172 "ix86_expand_branch (LT, operands[0]); DONE;")
14173
14174 (define_expand "bltu"
14175 [(set (pc)
14176 (if_then_else (match_dup 1)
14177 (label_ref (match_operand 0 "" ""))
14178 (pc)))]
14179 ""
14180 "ix86_expand_branch (LTU, operands[0]); DONE;")
14181
14182 (define_expand "bge"
14183 [(set (pc)
14184 (if_then_else (match_dup 1)
14185 (label_ref (match_operand 0 "" ""))
14186 (pc)))]
14187 ""
14188 "ix86_expand_branch (GE, operands[0]); DONE;")
14189
14190 (define_expand "bgeu"
14191 [(set (pc)
14192 (if_then_else (match_dup 1)
14193 (label_ref (match_operand 0 "" ""))
14194 (pc)))]
14195 ""
14196 "ix86_expand_branch (GEU, operands[0]); DONE;")
14197
14198 (define_expand "ble"
14199 [(set (pc)
14200 (if_then_else (match_dup 1)
14201 (label_ref (match_operand 0 "" ""))
14202 (pc)))]
14203 ""
14204 "ix86_expand_branch (LE, operands[0]); DONE;")
14205
14206 (define_expand "bleu"
14207 [(set (pc)
14208 (if_then_else (match_dup 1)
14209 (label_ref (match_operand 0 "" ""))
14210 (pc)))]
14211 ""
14212 "ix86_expand_branch (LEU, operands[0]); DONE;")
14213
14214 (define_expand "bunordered"
14215 [(set (pc)
14216 (if_then_else (match_dup 1)
14217 (label_ref (match_operand 0 "" ""))
14218 (pc)))]
14219 "TARGET_80387 || TARGET_SSE_MATH"
14220 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14221
14222 (define_expand "bordered"
14223 [(set (pc)
14224 (if_then_else (match_dup 1)
14225 (label_ref (match_operand 0 "" ""))
14226 (pc)))]
14227 "TARGET_80387 || TARGET_SSE_MATH"
14228 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14229
14230 (define_expand "buneq"
14231 [(set (pc)
14232 (if_then_else (match_dup 1)
14233 (label_ref (match_operand 0 "" ""))
14234 (pc)))]
14235 "TARGET_80387 || TARGET_SSE_MATH"
14236 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14237
14238 (define_expand "bunge"
14239 [(set (pc)
14240 (if_then_else (match_dup 1)
14241 (label_ref (match_operand 0 "" ""))
14242 (pc)))]
14243 "TARGET_80387 || TARGET_SSE_MATH"
14244 "ix86_expand_branch (UNGE, operands[0]); DONE;")
14245
14246 (define_expand "bungt"
14247 [(set (pc)
14248 (if_then_else (match_dup 1)
14249 (label_ref (match_operand 0 "" ""))
14250 (pc)))]
14251 "TARGET_80387 || TARGET_SSE_MATH"
14252 "ix86_expand_branch (UNGT, operands[0]); DONE;")
14253
14254 (define_expand "bunle"
14255 [(set (pc)
14256 (if_then_else (match_dup 1)
14257 (label_ref (match_operand 0 "" ""))
14258 (pc)))]
14259 "TARGET_80387 || TARGET_SSE_MATH"
14260 "ix86_expand_branch (UNLE, operands[0]); DONE;")
14261
14262 (define_expand "bunlt"
14263 [(set (pc)
14264 (if_then_else (match_dup 1)
14265 (label_ref (match_operand 0 "" ""))
14266 (pc)))]
14267 "TARGET_80387 || TARGET_SSE_MATH"
14268 "ix86_expand_branch (UNLT, operands[0]); DONE;")
14269
14270 (define_expand "bltgt"
14271 [(set (pc)
14272 (if_then_else (match_dup 1)
14273 (label_ref (match_operand 0 "" ""))
14274 (pc)))]
14275 "TARGET_80387 || TARGET_SSE_MATH"
14276 "ix86_expand_branch (LTGT, operands[0]); DONE;")
14277
14278 (define_insn "*jcc_1"
14279 [(set (pc)
14280 (if_then_else (match_operator 1 "ix86_comparison_operator"
14281 [(reg FLAGS_REG) (const_int 0)])
14282 (label_ref (match_operand 0 "" ""))
14283 (pc)))]
14284 ""
14285 "%+j%C1\t%l0"
14286 [(set_attr "type" "ibr")
14287 (set_attr "modrm" "0")
14288 (set (attr "length")
14289 (if_then_else (and (ge (minus (match_dup 0) (pc))
14290 (const_int -126))
14291 (lt (minus (match_dup 0) (pc))
14292 (const_int 128)))
14293 (const_int 2)
14294 (const_int 6)))])
14295
14296 (define_insn "*jcc_2"
14297 [(set (pc)
14298 (if_then_else (match_operator 1 "ix86_comparison_operator"
14299 [(reg FLAGS_REG) (const_int 0)])
14300 (pc)
14301 (label_ref (match_operand 0 "" ""))))]
14302 ""
14303 "%+j%c1\t%l0"
14304 [(set_attr "type" "ibr")
14305 (set_attr "modrm" "0")
14306 (set (attr "length")
14307 (if_then_else (and (ge (minus (match_dup 0) (pc))
14308 (const_int -126))
14309 (lt (minus (match_dup 0) (pc))
14310 (const_int 128)))
14311 (const_int 2)
14312 (const_int 6)))])
14313
14314 ;; In general it is not safe to assume too much about CCmode registers,
14315 ;; so simplify-rtx stops when it sees a second one. Under certain
14316 ;; conditions this is safe on x86, so help combine not create
14317 ;;
14318 ;; seta %al
14319 ;; testb %al, %al
14320 ;; je Lfoo
14321
14322 (define_split
14323 [(set (pc)
14324 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14325 [(reg FLAGS_REG) (const_int 0)])
14326 (const_int 0))
14327 (label_ref (match_operand 1 "" ""))
14328 (pc)))]
14329 ""
14330 [(set (pc)
14331 (if_then_else (match_dup 0)
14332 (label_ref (match_dup 1))
14333 (pc)))]
14334 {
14335 PUT_MODE (operands[0], VOIDmode);
14336 })
14337
14338 (define_split
14339 [(set (pc)
14340 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14341 [(reg FLAGS_REG) (const_int 0)])
14342 (const_int 0))
14343 (label_ref (match_operand 1 "" ""))
14344 (pc)))]
14345 ""
14346 [(set (pc)
14347 (if_then_else (match_dup 0)
14348 (label_ref (match_dup 1))
14349 (pc)))]
14350 {
14351 rtx new_op0 = copy_rtx (operands[0]);
14352 operands[0] = new_op0;
14353 PUT_MODE (new_op0, VOIDmode);
14354 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14355 GET_MODE (XEXP (new_op0, 0))));
14356
14357 /* Make sure that (a) the CCmode we have for the flags is strong
14358 enough for the reversed compare or (b) we have a valid FP compare. */
14359 if (! ix86_comparison_operator (new_op0, VOIDmode))
14360 FAIL;
14361 })
14362
14363 ;; Define combination compare-and-branch fp compare instructions to use
14364 ;; during early optimization. Splitting the operation apart early makes
14365 ;; for bad code when we want to reverse the operation.
14366
14367 (define_insn "*fp_jcc_1_mixed"
14368 [(set (pc)
14369 (if_then_else (match_operator 0 "comparison_operator"
14370 [(match_operand 1 "register_operand" "f,x")
14371 (match_operand 2 "nonimmediate_operand" "f,xm")])
14372 (label_ref (match_operand 3 "" ""))
14373 (pc)))
14374 (clobber (reg:CCFP FPSR_REG))
14375 (clobber (reg:CCFP FLAGS_REG))]
14376 "TARGET_MIX_SSE_I387
14377 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14378 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14379 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14380 "#")
14381
14382 (define_insn "*fp_jcc_1_sse"
14383 [(set (pc)
14384 (if_then_else (match_operator 0 "comparison_operator"
14385 [(match_operand 1 "register_operand" "x")
14386 (match_operand 2 "nonimmediate_operand" "xm")])
14387 (label_ref (match_operand 3 "" ""))
14388 (pc)))
14389 (clobber (reg:CCFP FPSR_REG))
14390 (clobber (reg:CCFP FLAGS_REG))]
14391 "TARGET_SSE_MATH
14392 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14393 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14394 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14395 "#")
14396
14397 (define_insn "*fp_jcc_1_387"
14398 [(set (pc)
14399 (if_then_else (match_operator 0 "comparison_operator"
14400 [(match_operand 1 "register_operand" "f")
14401 (match_operand 2 "register_operand" "f")])
14402 (label_ref (match_operand 3 "" ""))
14403 (pc)))
14404 (clobber (reg:CCFP FPSR_REG))
14405 (clobber (reg:CCFP FLAGS_REG))]
14406 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14407 && TARGET_CMOVE
14408 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14409 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14410 "#")
14411
14412 (define_insn "*fp_jcc_2_mixed"
14413 [(set (pc)
14414 (if_then_else (match_operator 0 "comparison_operator"
14415 [(match_operand 1 "register_operand" "f,x")
14416 (match_operand 2 "nonimmediate_operand" "f,xm")])
14417 (pc)
14418 (label_ref (match_operand 3 "" ""))))
14419 (clobber (reg:CCFP FPSR_REG))
14420 (clobber (reg:CCFP FLAGS_REG))]
14421 "TARGET_MIX_SSE_I387
14422 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14423 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14424 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14425 "#")
14426
14427 (define_insn "*fp_jcc_2_sse"
14428 [(set (pc)
14429 (if_then_else (match_operator 0 "comparison_operator"
14430 [(match_operand 1 "register_operand" "x")
14431 (match_operand 2 "nonimmediate_operand" "xm")])
14432 (pc)
14433 (label_ref (match_operand 3 "" ""))))
14434 (clobber (reg:CCFP FPSR_REG))
14435 (clobber (reg:CCFP FLAGS_REG))]
14436 "TARGET_SSE_MATH
14437 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14438 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14439 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14440 "#")
14441
14442 (define_insn "*fp_jcc_2_387"
14443 [(set (pc)
14444 (if_then_else (match_operator 0 "comparison_operator"
14445 [(match_operand 1 "register_operand" "f")
14446 (match_operand 2 "register_operand" "f")])
14447 (pc)
14448 (label_ref (match_operand 3 "" ""))))
14449 (clobber (reg:CCFP FPSR_REG))
14450 (clobber (reg:CCFP FLAGS_REG))]
14451 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14452 && TARGET_CMOVE
14453 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14454 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14455 "#")
14456
14457 (define_insn "*fp_jcc_3_387"
14458 [(set (pc)
14459 (if_then_else (match_operator 0 "comparison_operator"
14460 [(match_operand 1 "register_operand" "f")
14461 (match_operand 2 "nonimmediate_operand" "fm")])
14462 (label_ref (match_operand 3 "" ""))
14463 (pc)))
14464 (clobber (reg:CCFP FPSR_REG))
14465 (clobber (reg:CCFP FLAGS_REG))
14466 (clobber (match_scratch:HI 4 "=a"))]
14467 "TARGET_80387
14468 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14469 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14470 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14471 && SELECT_CC_MODE (GET_CODE (operands[0]),
14472 operands[1], operands[2]) == CCFPmode
14473 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14474 "#")
14475
14476 (define_insn "*fp_jcc_4_387"
14477 [(set (pc)
14478 (if_then_else (match_operator 0 "comparison_operator"
14479 [(match_operand 1 "register_operand" "f")
14480 (match_operand 2 "nonimmediate_operand" "fm")])
14481 (pc)
14482 (label_ref (match_operand 3 "" ""))))
14483 (clobber (reg:CCFP FPSR_REG))
14484 (clobber (reg:CCFP FLAGS_REG))
14485 (clobber (match_scratch:HI 4 "=a"))]
14486 "TARGET_80387
14487 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14488 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14489 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14490 && SELECT_CC_MODE (GET_CODE (operands[0]),
14491 operands[1], operands[2]) == CCFPmode
14492 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14493 "#")
14494
14495 (define_insn "*fp_jcc_5_387"
14496 [(set (pc)
14497 (if_then_else (match_operator 0 "comparison_operator"
14498 [(match_operand 1 "register_operand" "f")
14499 (match_operand 2 "register_operand" "f")])
14500 (label_ref (match_operand 3 "" ""))
14501 (pc)))
14502 (clobber (reg:CCFP FPSR_REG))
14503 (clobber (reg:CCFP FLAGS_REG))
14504 (clobber (match_scratch:HI 4 "=a"))]
14505 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14506 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14507 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14508 "#")
14509
14510 (define_insn "*fp_jcc_6_387"
14511 [(set (pc)
14512 (if_then_else (match_operator 0 "comparison_operator"
14513 [(match_operand 1 "register_operand" "f")
14514 (match_operand 2 "register_operand" "f")])
14515 (pc)
14516 (label_ref (match_operand 3 "" ""))))
14517 (clobber (reg:CCFP FPSR_REG))
14518 (clobber (reg:CCFP FLAGS_REG))
14519 (clobber (match_scratch:HI 4 "=a"))]
14520 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14521 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14522 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14523 "#")
14524
14525 (define_insn "*fp_jcc_7_387"
14526 [(set (pc)
14527 (if_then_else (match_operator 0 "comparison_operator"
14528 [(match_operand 1 "register_operand" "f")
14529 (match_operand 2 "const0_operand" "X")])
14530 (label_ref (match_operand 3 "" ""))
14531 (pc)))
14532 (clobber (reg:CCFP FPSR_REG))
14533 (clobber (reg:CCFP FLAGS_REG))
14534 (clobber (match_scratch:HI 4 "=a"))]
14535 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14536 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14537 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14538 && SELECT_CC_MODE (GET_CODE (operands[0]),
14539 operands[1], operands[2]) == CCFPmode
14540 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14541 "#")
14542
14543 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14544 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14545 ;; with a precedence over other operators and is always put in the first
14546 ;; place. Swap condition and operands to match ficom instruction.
14547
14548 (define_insn "*fp_jcc_8<mode>_387"
14549 [(set (pc)
14550 (if_then_else (match_operator 0 "comparison_operator"
14551 [(match_operator 1 "float_operator"
14552 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14553 (match_operand 3 "register_operand" "f,f")])
14554 (label_ref (match_operand 4 "" ""))
14555 (pc)))
14556 (clobber (reg:CCFP FPSR_REG))
14557 (clobber (reg:CCFP FLAGS_REG))
14558 (clobber (match_scratch:HI 5 "=a,a"))]
14559 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14560 && TARGET_USE_<MODE>MODE_FIOP
14561 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14562 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14563 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14564 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14565 "#")
14566
14567 (define_split
14568 [(set (pc)
14569 (if_then_else (match_operator 0 "comparison_operator"
14570 [(match_operand 1 "register_operand" "")
14571 (match_operand 2 "nonimmediate_operand" "")])
14572 (match_operand 3 "" "")
14573 (match_operand 4 "" "")))
14574 (clobber (reg:CCFP FPSR_REG))
14575 (clobber (reg:CCFP FLAGS_REG))]
14576 "reload_completed"
14577 [(const_int 0)]
14578 {
14579 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14580 operands[3], operands[4], NULL_RTX, NULL_RTX);
14581 DONE;
14582 })
14583
14584 (define_split
14585 [(set (pc)
14586 (if_then_else (match_operator 0 "comparison_operator"
14587 [(match_operand 1 "register_operand" "")
14588 (match_operand 2 "general_operand" "")])
14589 (match_operand 3 "" "")
14590 (match_operand 4 "" "")))
14591 (clobber (reg:CCFP FPSR_REG))
14592 (clobber (reg:CCFP FLAGS_REG))
14593 (clobber (match_scratch:HI 5 "=a"))]
14594 "reload_completed"
14595 [(const_int 0)]
14596 {
14597 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14598 operands[3], operands[4], operands[5], NULL_RTX);
14599 DONE;
14600 })
14601
14602 (define_split
14603 [(set (pc)
14604 (if_then_else (match_operator 0 "comparison_operator"
14605 [(match_operator 1 "float_operator"
14606 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14607 (match_operand 3 "register_operand" "")])
14608 (match_operand 4 "" "")
14609 (match_operand 5 "" "")))
14610 (clobber (reg:CCFP FPSR_REG))
14611 (clobber (reg:CCFP FLAGS_REG))
14612 (clobber (match_scratch:HI 6 "=a"))]
14613 "reload_completed"
14614 [(const_int 0)]
14615 {
14616 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14617 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14618 operands[3], operands[7],
14619 operands[4], operands[5], operands[6], NULL_RTX);
14620 DONE;
14621 })
14622
14623 ;; %%% Kill this when reload knows how to do it.
14624 (define_split
14625 [(set (pc)
14626 (if_then_else (match_operator 0 "comparison_operator"
14627 [(match_operator 1 "float_operator"
14628 [(match_operand:X87MODEI12 2 "register_operand" "")])
14629 (match_operand 3 "register_operand" "")])
14630 (match_operand 4 "" "")
14631 (match_operand 5 "" "")))
14632 (clobber (reg:CCFP FPSR_REG))
14633 (clobber (reg:CCFP FLAGS_REG))
14634 (clobber (match_scratch:HI 6 "=a"))]
14635 "reload_completed"
14636 [(const_int 0)]
14637 {
14638 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14639 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14640 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14641 operands[3], operands[7],
14642 operands[4], operands[5], operands[6], operands[2]);
14643 DONE;
14644 })
14645 \f
14646 ;; Unconditional and other jump instructions
14647
14648 (define_insn "jump"
14649 [(set (pc)
14650 (label_ref (match_operand 0 "" "")))]
14651 ""
14652 "jmp\t%l0"
14653 [(set_attr "type" "ibr")
14654 (set (attr "length")
14655 (if_then_else (and (ge (minus (match_dup 0) (pc))
14656 (const_int -126))
14657 (lt (minus (match_dup 0) (pc))
14658 (const_int 128)))
14659 (const_int 2)
14660 (const_int 5)))
14661 (set_attr "modrm" "0")])
14662
14663 (define_expand "indirect_jump"
14664 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14665 ""
14666 "")
14667
14668 (define_insn "*indirect_jump"
14669 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14670 "!TARGET_64BIT"
14671 "jmp\t%A0"
14672 [(set_attr "type" "ibr")
14673 (set_attr "length_immediate" "0")])
14674
14675 (define_insn "*indirect_jump_rtx64"
14676 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14677 "TARGET_64BIT"
14678 "jmp\t%A0"
14679 [(set_attr "type" "ibr")
14680 (set_attr "length_immediate" "0")])
14681
14682 (define_expand "tablejump"
14683 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14684 (use (label_ref (match_operand 1 "" "")))])]
14685 ""
14686 {
14687 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14688 relative. Convert the relative address to an absolute address. */
14689 if (flag_pic)
14690 {
14691 rtx op0, op1;
14692 enum rtx_code code;
14693
14694 /* We can't use @GOTOFF for text labels on VxWorks;
14695 see gotoff_operand. */
14696 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14697 {
14698 code = PLUS;
14699 op0 = operands[0];
14700 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14701 }
14702 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14703 {
14704 code = PLUS;
14705 op0 = operands[0];
14706 op1 = pic_offset_table_rtx;
14707 }
14708 else
14709 {
14710 code = MINUS;
14711 op0 = pic_offset_table_rtx;
14712 op1 = operands[0];
14713 }
14714
14715 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14716 OPTAB_DIRECT);
14717 }
14718 })
14719
14720 (define_insn "*tablejump_1"
14721 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14722 (use (label_ref (match_operand 1 "" "")))]
14723 "!TARGET_64BIT"
14724 "jmp\t%A0"
14725 [(set_attr "type" "ibr")
14726 (set_attr "length_immediate" "0")])
14727
14728 (define_insn "*tablejump_1_rtx64"
14729 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14730 (use (label_ref (match_operand 1 "" "")))]
14731 "TARGET_64BIT"
14732 "jmp\t%A0"
14733 [(set_attr "type" "ibr")
14734 (set_attr "length_immediate" "0")])
14735 \f
14736 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14737
14738 (define_peephole2
14739 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14740 (set (match_operand:QI 1 "register_operand" "")
14741 (match_operator:QI 2 "ix86_comparison_operator"
14742 [(reg FLAGS_REG) (const_int 0)]))
14743 (set (match_operand 3 "q_regs_operand" "")
14744 (zero_extend (match_dup 1)))]
14745 "(peep2_reg_dead_p (3, operands[1])
14746 || operands_match_p (operands[1], operands[3]))
14747 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14748 [(set (match_dup 4) (match_dup 0))
14749 (set (strict_low_part (match_dup 5))
14750 (match_dup 2))]
14751 {
14752 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14753 operands[5] = gen_lowpart (QImode, operands[3]);
14754 ix86_expand_clear (operands[3]);
14755 })
14756
14757 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14758
14759 (define_peephole2
14760 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14761 (set (match_operand:QI 1 "register_operand" "")
14762 (match_operator:QI 2 "ix86_comparison_operator"
14763 [(reg FLAGS_REG) (const_int 0)]))
14764 (parallel [(set (match_operand 3 "q_regs_operand" "")
14765 (zero_extend (match_dup 1)))
14766 (clobber (reg:CC FLAGS_REG))])]
14767 "(peep2_reg_dead_p (3, operands[1])
14768 || operands_match_p (operands[1], operands[3]))
14769 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14770 [(set (match_dup 4) (match_dup 0))
14771 (set (strict_low_part (match_dup 5))
14772 (match_dup 2))]
14773 {
14774 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14775 operands[5] = gen_lowpart (QImode, operands[3]);
14776 ix86_expand_clear (operands[3]);
14777 })
14778 \f
14779 ;; Call instructions.
14780
14781 ;; The predicates normally associated with named expanders are not properly
14782 ;; checked for calls. This is a bug in the generic code, but it isn't that
14783 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14784
14785 ;; Call subroutine returning no value.
14786
14787 (define_expand "call_pop"
14788 [(parallel [(call (match_operand:QI 0 "" "")
14789 (match_operand:SI 1 "" ""))
14790 (set (reg:SI SP_REG)
14791 (plus:SI (reg:SI SP_REG)
14792 (match_operand:SI 3 "" "")))])]
14793 "!TARGET_64BIT"
14794 {
14795 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14796 DONE;
14797 })
14798
14799 (define_insn "*call_pop_0"
14800 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14801 (match_operand:SI 1 "" ""))
14802 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14803 (match_operand:SI 2 "immediate_operand" "")))]
14804 "!TARGET_64BIT"
14805 {
14806 if (SIBLING_CALL_P (insn))
14807 return "jmp\t%P0";
14808 else
14809 return "call\t%P0";
14810 }
14811 [(set_attr "type" "call")])
14812
14813 (define_insn "*call_pop_1"
14814 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14815 (match_operand:SI 1 "" ""))
14816 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14817 (match_operand:SI 2 "immediate_operand" "i")))]
14818 "!TARGET_64BIT"
14819 {
14820 if (constant_call_address_operand (operands[0], Pmode))
14821 {
14822 if (SIBLING_CALL_P (insn))
14823 return "jmp\t%P0";
14824 else
14825 return "call\t%P0";
14826 }
14827 if (SIBLING_CALL_P (insn))
14828 return "jmp\t%A0";
14829 else
14830 return "call\t%A0";
14831 }
14832 [(set_attr "type" "call")])
14833
14834 (define_expand "call"
14835 [(call (match_operand:QI 0 "" "")
14836 (match_operand 1 "" ""))
14837 (use (match_operand 2 "" ""))]
14838 ""
14839 {
14840 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14841 DONE;
14842 })
14843
14844 (define_expand "sibcall"
14845 [(call (match_operand:QI 0 "" "")
14846 (match_operand 1 "" ""))
14847 (use (match_operand 2 "" ""))]
14848 ""
14849 {
14850 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14851 DONE;
14852 })
14853
14854 (define_insn "*call_0"
14855 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14856 (match_operand 1 "" ""))]
14857 ""
14858 {
14859 if (SIBLING_CALL_P (insn))
14860 return "jmp\t%P0";
14861 else
14862 return "call\t%P0";
14863 }
14864 [(set_attr "type" "call")])
14865
14866 (define_insn "*call_1"
14867 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14868 (match_operand 1 "" ""))]
14869 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14870 {
14871 if (constant_call_address_operand (operands[0], Pmode))
14872 return "call\t%P0";
14873 return "call\t%A0";
14874 }
14875 [(set_attr "type" "call")])
14876
14877 (define_insn "*sibcall_1"
14878 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14879 (match_operand 1 "" ""))]
14880 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14881 {
14882 if (constant_call_address_operand (operands[0], Pmode))
14883 return "jmp\t%P0";
14884 return "jmp\t%A0";
14885 }
14886 [(set_attr "type" "call")])
14887
14888 (define_insn "*call_1_rex64"
14889 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14890 (match_operand 1 "" ""))]
14891 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14892 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14893 {
14894 if (constant_call_address_operand (operands[0], Pmode))
14895 return "call\t%P0";
14896 return "call\t%A0";
14897 }
14898 [(set_attr "type" "call")])
14899
14900 (define_insn "*call_1_rex64_large"
14901 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14902 (match_operand 1 "" ""))]
14903 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14904 "call\t%A0"
14905 [(set_attr "type" "call")])
14906
14907 (define_insn "*sibcall_1_rex64"
14908 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14909 (match_operand 1 "" ""))]
14910 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14911 "jmp\t%P0"
14912 [(set_attr "type" "call")])
14913
14914 (define_insn "*sibcall_1_rex64_v"
14915 [(call (mem:QI (reg:DI R11_REG))
14916 (match_operand 0 "" ""))]
14917 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14918 "jmp\t{*%%}r11"
14919 [(set_attr "type" "call")])
14920
14921
14922 ;; Call subroutine, returning value in operand 0
14923
14924 (define_expand "call_value_pop"
14925 [(parallel [(set (match_operand 0 "" "")
14926 (call (match_operand:QI 1 "" "")
14927 (match_operand:SI 2 "" "")))
14928 (set (reg:SI SP_REG)
14929 (plus:SI (reg:SI SP_REG)
14930 (match_operand:SI 4 "" "")))])]
14931 "!TARGET_64BIT"
14932 {
14933 ix86_expand_call (operands[0], operands[1], operands[2],
14934 operands[3], operands[4], 0);
14935 DONE;
14936 })
14937
14938 (define_expand "call_value"
14939 [(set (match_operand 0 "" "")
14940 (call (match_operand:QI 1 "" "")
14941 (match_operand:SI 2 "" "")))
14942 (use (match_operand:SI 3 "" ""))]
14943 ;; Operand 2 not used on the i386.
14944 ""
14945 {
14946 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14947 DONE;
14948 })
14949
14950 (define_expand "sibcall_value"
14951 [(set (match_operand 0 "" "")
14952 (call (match_operand:QI 1 "" "")
14953 (match_operand:SI 2 "" "")))
14954 (use (match_operand:SI 3 "" ""))]
14955 ;; Operand 2 not used on the i386.
14956 ""
14957 {
14958 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14959 DONE;
14960 })
14961
14962 ;; Call subroutine returning any type.
14963
14964 (define_expand "untyped_call"
14965 [(parallel [(call (match_operand 0 "" "")
14966 (const_int 0))
14967 (match_operand 1 "" "")
14968 (match_operand 2 "" "")])]
14969 ""
14970 {
14971 int i;
14972
14973 /* In order to give reg-stack an easier job in validating two
14974 coprocessor registers as containing a possible return value,
14975 simply pretend the untyped call returns a complex long double
14976 value. */
14977
14978 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14979 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14980 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14981 NULL, 0);
14982
14983 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14984 {
14985 rtx set = XVECEXP (operands[2], 0, i);
14986 emit_move_insn (SET_DEST (set), SET_SRC (set));
14987 }
14988
14989 /* The optimizer does not know that the call sets the function value
14990 registers we stored in the result block. We avoid problems by
14991 claiming that all hard registers are used and clobbered at this
14992 point. */
14993 emit_insn (gen_blockage ());
14994
14995 DONE;
14996 })
14997 \f
14998 ;; Prologue and epilogue instructions
14999
15000 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15001 ;; all of memory. This blocks insns from being moved across this point.
15002
15003 (define_insn "blockage"
15004 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15005 ""
15006 ""
15007 [(set_attr "length" "0")])
15008
15009 ;; As USE insns aren't meaningful after reload, this is used instead
15010 ;; to prevent deleting instructions setting registers for PIC code
15011 (define_insn "prologue_use"
15012 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15013 ""
15014 ""
15015 [(set_attr "length" "0")])
15016
15017 ;; Insn emitted into the body of a function to return from a function.
15018 ;; This is only done if the function's epilogue is known to be simple.
15019 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15020
15021 (define_expand "return"
15022 [(return)]
15023 "ix86_can_use_return_insn_p ()"
15024 {
15025 if (current_function_pops_args)
15026 {
15027 rtx popc = GEN_INT (current_function_pops_args);
15028 emit_jump_insn (gen_return_pop_internal (popc));
15029 DONE;
15030 }
15031 })
15032
15033 (define_insn "return_internal"
15034 [(return)]
15035 "reload_completed"
15036 "ret"
15037 [(set_attr "length" "1")
15038 (set_attr "length_immediate" "0")
15039 (set_attr "modrm" "0")])
15040
15041 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15042 ;; instruction Athlon and K8 have.
15043
15044 (define_insn "return_internal_long"
15045 [(return)
15046 (unspec [(const_int 0)] UNSPEC_REP)]
15047 "reload_completed"
15048 "rep\;ret"
15049 [(set_attr "length" "1")
15050 (set_attr "length_immediate" "0")
15051 (set_attr "prefix_rep" "1")
15052 (set_attr "modrm" "0")])
15053
15054 (define_insn "return_pop_internal"
15055 [(return)
15056 (use (match_operand:SI 0 "const_int_operand" ""))]
15057 "reload_completed"
15058 "ret\t%0"
15059 [(set_attr "length" "3")
15060 (set_attr "length_immediate" "2")
15061 (set_attr "modrm" "0")])
15062
15063 (define_insn "return_indirect_internal"
15064 [(return)
15065 (use (match_operand:SI 0 "register_operand" "r"))]
15066 "reload_completed"
15067 "jmp\t%A0"
15068 [(set_attr "type" "ibr")
15069 (set_attr "length_immediate" "0")])
15070
15071 (define_insn "nop"
15072 [(const_int 0)]
15073 ""
15074 "nop"
15075 [(set_attr "length" "1")
15076 (set_attr "length_immediate" "0")
15077 (set_attr "modrm" "0")])
15078
15079 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15080 ;; branch prediction penalty for the third jump in a 16-byte
15081 ;; block on K8.
15082
15083 (define_insn "align"
15084 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15085 ""
15086 {
15087 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15088 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15089 #else
15090 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15091 The align insn is used to avoid 3 jump instructions in the row to improve
15092 branch prediction and the benefits hardly outweigh the cost of extra 8
15093 nops on the average inserted by full alignment pseudo operation. */
15094 #endif
15095 return "";
15096 }
15097 [(set_attr "length" "16")])
15098
15099 (define_expand "prologue"
15100 [(const_int 0)]
15101 ""
15102 "ix86_expand_prologue (); DONE;")
15103
15104 (define_insn "set_got"
15105 [(set (match_operand:SI 0 "register_operand" "=r")
15106 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15107 (clobber (reg:CC FLAGS_REG))]
15108 "!TARGET_64BIT"
15109 { return output_set_got (operands[0], NULL_RTX); }
15110 [(set_attr "type" "multi")
15111 (set_attr "length" "12")])
15112
15113 (define_insn "set_got_labelled"
15114 [(set (match_operand:SI 0 "register_operand" "=r")
15115 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15116 UNSPEC_SET_GOT))
15117 (clobber (reg:CC FLAGS_REG))]
15118 "!TARGET_64BIT"
15119 { return output_set_got (operands[0], operands[1]); }
15120 [(set_attr "type" "multi")
15121 (set_attr "length" "12")])
15122
15123 (define_insn "set_got_rex64"
15124 [(set (match_operand:DI 0 "register_operand" "=r")
15125 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15126 "TARGET_64BIT"
15127 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15128 [(set_attr "type" "lea")
15129 (set_attr "length" "6")])
15130
15131 (define_insn "set_rip_rex64"
15132 [(set (match_operand:DI 0 "register_operand" "=r")
15133 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15134 "TARGET_64BIT"
15135 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15136 [(set_attr "type" "lea")
15137 (set_attr "length" "6")])
15138
15139 (define_insn "set_got_offset_rex64"
15140 [(set (match_operand:DI 0 "register_operand" "=r")
15141 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15142 "TARGET_64BIT"
15143 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15144 [(set_attr "type" "imov")
15145 (set_attr "length" "11")])
15146
15147 (define_expand "epilogue"
15148 [(const_int 0)]
15149 ""
15150 "ix86_expand_epilogue (1); DONE;")
15151
15152 (define_expand "sibcall_epilogue"
15153 [(const_int 0)]
15154 ""
15155 "ix86_expand_epilogue (0); DONE;")
15156
15157 (define_expand "eh_return"
15158 [(use (match_operand 0 "register_operand" ""))]
15159 ""
15160 {
15161 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15162
15163 /* Tricky bit: we write the address of the handler to which we will
15164 be returning into someone else's stack frame, one word below the
15165 stack address we wish to restore. */
15166 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15167 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15168 tmp = gen_rtx_MEM (Pmode, tmp);
15169 emit_move_insn (tmp, ra);
15170
15171 if (Pmode == SImode)
15172 emit_jump_insn (gen_eh_return_si (sa));
15173 else
15174 emit_jump_insn (gen_eh_return_di (sa));
15175 emit_barrier ();
15176 DONE;
15177 })
15178
15179 (define_insn_and_split "eh_return_si"
15180 [(set (pc)
15181 (unspec [(match_operand:SI 0 "register_operand" "c")]
15182 UNSPEC_EH_RETURN))]
15183 "!TARGET_64BIT"
15184 "#"
15185 "reload_completed"
15186 [(const_int 0)]
15187 "ix86_expand_epilogue (2); DONE;")
15188
15189 (define_insn_and_split "eh_return_di"
15190 [(set (pc)
15191 (unspec [(match_operand:DI 0 "register_operand" "c")]
15192 UNSPEC_EH_RETURN))]
15193 "TARGET_64BIT"
15194 "#"
15195 "reload_completed"
15196 [(const_int 0)]
15197 "ix86_expand_epilogue (2); DONE;")
15198
15199 (define_insn "leave"
15200 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15201 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15202 (clobber (mem:BLK (scratch)))]
15203 "!TARGET_64BIT"
15204 "leave"
15205 [(set_attr "type" "leave")])
15206
15207 (define_insn "leave_rex64"
15208 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15209 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15210 (clobber (mem:BLK (scratch)))]
15211 "TARGET_64BIT"
15212 "leave"
15213 [(set_attr "type" "leave")])
15214 \f
15215 (define_expand "ffssi2"
15216 [(parallel
15217 [(set (match_operand:SI 0 "register_operand" "")
15218 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15219 (clobber (match_scratch:SI 2 ""))
15220 (clobber (reg:CC FLAGS_REG))])]
15221 ""
15222 {
15223 if (TARGET_CMOVE)
15224 {
15225 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15226 DONE;
15227 }
15228 })
15229
15230 (define_expand "ffs_cmove"
15231 [(set (match_dup 2) (const_int -1))
15232 (parallel [(set (reg:CCZ FLAGS_REG)
15233 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15234 (const_int 0)))
15235 (set (match_operand:SI 0 "nonimmediate_operand" "")
15236 (ctz:SI (match_dup 1)))])
15237 (set (match_dup 0) (if_then_else:SI
15238 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15239 (match_dup 2)
15240 (match_dup 0)))
15241 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15242 (clobber (reg:CC FLAGS_REG))])]
15243 "TARGET_CMOVE"
15244 "operands[2] = gen_reg_rtx (SImode);")
15245
15246 (define_insn_and_split "*ffs_no_cmove"
15247 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15248 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15249 (clobber (match_scratch:SI 2 "=&q"))
15250 (clobber (reg:CC FLAGS_REG))]
15251 "!TARGET_CMOVE"
15252 "#"
15253 "&& reload_completed"
15254 [(parallel [(set (reg:CCZ FLAGS_REG)
15255 (compare:CCZ (match_dup 1) (const_int 0)))
15256 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15257 (set (strict_low_part (match_dup 3))
15258 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15259 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15260 (clobber (reg:CC FLAGS_REG))])
15261 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15262 (clobber (reg:CC FLAGS_REG))])
15263 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15264 (clobber (reg:CC FLAGS_REG))])]
15265 {
15266 operands[3] = gen_lowpart (QImode, operands[2]);
15267 ix86_expand_clear (operands[2]);
15268 })
15269
15270 (define_insn "*ffssi_1"
15271 [(set (reg:CCZ FLAGS_REG)
15272 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15273 (const_int 0)))
15274 (set (match_operand:SI 0 "register_operand" "=r")
15275 (ctz:SI (match_dup 1)))]
15276 ""
15277 "bsf{l}\t{%1, %0|%0, %1}"
15278 [(set_attr "prefix_0f" "1")])
15279
15280 (define_expand "ffsdi2"
15281 [(set (match_dup 2) (const_int -1))
15282 (parallel [(set (reg:CCZ FLAGS_REG)
15283 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15284 (const_int 0)))
15285 (set (match_operand:DI 0 "nonimmediate_operand" "")
15286 (ctz:DI (match_dup 1)))])
15287 (set (match_dup 0) (if_then_else:DI
15288 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15289 (match_dup 2)
15290 (match_dup 0)))
15291 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15292 (clobber (reg:CC FLAGS_REG))])]
15293 "TARGET_64BIT"
15294 "operands[2] = gen_reg_rtx (DImode);")
15295
15296 (define_insn "*ffsdi_1"
15297 [(set (reg:CCZ FLAGS_REG)
15298 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15299 (const_int 0)))
15300 (set (match_operand:DI 0 "register_operand" "=r")
15301 (ctz:DI (match_dup 1)))]
15302 "TARGET_64BIT"
15303 "bsf{q}\t{%1, %0|%0, %1}"
15304 [(set_attr "prefix_0f" "1")])
15305
15306 (define_insn "ctzsi2"
15307 [(set (match_operand:SI 0 "register_operand" "=r")
15308 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15309 (clobber (reg:CC FLAGS_REG))]
15310 ""
15311 "bsf{l}\t{%1, %0|%0, %1}"
15312 [(set_attr "prefix_0f" "1")])
15313
15314 (define_insn "ctzdi2"
15315 [(set (match_operand:DI 0 "register_operand" "=r")
15316 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15317 (clobber (reg:CC FLAGS_REG))]
15318 "TARGET_64BIT"
15319 "bsf{q}\t{%1, %0|%0, %1}"
15320 [(set_attr "prefix_0f" "1")])
15321
15322 (define_expand "clzsi2"
15323 [(parallel
15324 [(set (match_operand:SI 0 "register_operand" "")
15325 (minus:SI (const_int 31)
15326 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15327 (clobber (reg:CC FLAGS_REG))])
15328 (parallel
15329 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15330 (clobber (reg:CC FLAGS_REG))])]
15331 ""
15332 {
15333 if (TARGET_ABM)
15334 {
15335 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15336 DONE;
15337 }
15338 })
15339
15340 (define_insn "clzsi2_abm"
15341 [(set (match_operand:SI 0 "register_operand" "=r")
15342 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15343 (clobber (reg:CC FLAGS_REG))]
15344 "TARGET_ABM"
15345 "lzcnt{l}\t{%1, %0|%0, %1}"
15346 [(set_attr "prefix_rep" "1")
15347 (set_attr "type" "bitmanip")
15348 (set_attr "mode" "SI")])
15349
15350 (define_insn "*bsr"
15351 [(set (match_operand:SI 0 "register_operand" "=r")
15352 (minus:SI (const_int 31)
15353 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15354 (clobber (reg:CC FLAGS_REG))]
15355 ""
15356 "bsr{l}\t{%1, %0|%0, %1}"
15357 [(set_attr "prefix_0f" "1")
15358 (set_attr "mode" "SI")])
15359
15360 (define_insn "popcountsi2"
15361 [(set (match_operand:SI 0 "register_operand" "=r")
15362 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15363 (clobber (reg:CC FLAGS_REG))]
15364 "TARGET_POPCNT"
15365 "popcnt{l}\t{%1, %0|%0, %1}"
15366 [(set_attr "prefix_rep" "1")
15367 (set_attr "type" "bitmanip")
15368 (set_attr "mode" "SI")])
15369
15370 (define_insn "*popcountsi2_cmp"
15371 [(set (reg FLAGS_REG)
15372 (compare
15373 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15374 (const_int 0)))
15375 (set (match_operand:SI 0 "register_operand" "=r")
15376 (popcount:SI (match_dup 1)))]
15377 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15378 "popcnt{l}\t{%1, %0|%0, %1}"
15379 [(set_attr "prefix_rep" "1")
15380 (set_attr "type" "bitmanip")
15381 (set_attr "mode" "SI")])
15382
15383 (define_insn "*popcountsi2_cmp_zext"
15384 [(set (reg FLAGS_REG)
15385 (compare
15386 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15387 (const_int 0)))
15388 (set (match_operand:DI 0 "register_operand" "=r")
15389 (zero_extend:DI(popcount:SI (match_dup 1))))]
15390 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15391 "popcnt{l}\t{%1, %0|%0, %1}"
15392 [(set_attr "prefix_rep" "1")
15393 (set_attr "type" "bitmanip")
15394 (set_attr "mode" "SI")])
15395
15396 (define_expand "bswapsi2"
15397 [(set (match_operand:SI 0 "register_operand" "")
15398 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15399 ""
15400 {
15401 if (!TARGET_BSWAP)
15402 {
15403 rtx x = operands[0];
15404
15405 emit_move_insn (x, operands[1]);
15406 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15407 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15408 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15409 DONE;
15410 }
15411 })
15412
15413 (define_insn "*bswapsi_1"
15414 [(set (match_operand:SI 0 "register_operand" "=r")
15415 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15416 "TARGET_BSWAP"
15417 "bswap\t%0"
15418 [(set_attr "prefix_0f" "1")
15419 (set_attr "length" "2")])
15420
15421 (define_insn "*bswaphi_lowpart_1"
15422 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15423 (bswap:HI (match_dup 0)))
15424 (clobber (reg:CC FLAGS_REG))]
15425 "TARGET_USE_XCHGB || optimize_size"
15426 "@
15427 xchg{b}\t{%h0, %b0|%b0, %h0}
15428 rol{w}\t{$8, %0|%0, 8}"
15429 [(set_attr "length" "2,4")
15430 (set_attr "mode" "QI,HI")])
15431
15432 (define_insn "bswaphi_lowpart"
15433 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15434 (bswap:HI (match_dup 0)))
15435 (clobber (reg:CC FLAGS_REG))]
15436 ""
15437 "rol{w}\t{$8, %0|%0, 8}"
15438 [(set_attr "length" "4")
15439 (set_attr "mode" "HI")])
15440
15441 (define_insn "bswapdi2"
15442 [(set (match_operand:DI 0 "register_operand" "=r")
15443 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15444 "TARGET_64BIT"
15445 "bswap\t%0"
15446 [(set_attr "prefix_0f" "1")
15447 (set_attr "length" "3")])
15448
15449 (define_expand "clzdi2"
15450 [(parallel
15451 [(set (match_operand:DI 0 "register_operand" "")
15452 (minus:DI (const_int 63)
15453 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15454 (clobber (reg:CC FLAGS_REG))])
15455 (parallel
15456 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15457 (clobber (reg:CC FLAGS_REG))])]
15458 "TARGET_64BIT"
15459 {
15460 if (TARGET_ABM)
15461 {
15462 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15463 DONE;
15464 }
15465 })
15466
15467 (define_insn "clzdi2_abm"
15468 [(set (match_operand:DI 0 "register_operand" "=r")
15469 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15470 (clobber (reg:CC FLAGS_REG))]
15471 "TARGET_64BIT && TARGET_ABM"
15472 "lzcnt{q}\t{%1, %0|%0, %1}"
15473 [(set_attr "prefix_rep" "1")
15474 (set_attr "type" "bitmanip")
15475 (set_attr "mode" "DI")])
15476
15477 (define_insn "*bsr_rex64"
15478 [(set (match_operand:DI 0 "register_operand" "=r")
15479 (minus:DI (const_int 63)
15480 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15481 (clobber (reg:CC FLAGS_REG))]
15482 "TARGET_64BIT"
15483 "bsr{q}\t{%1, %0|%0, %1}"
15484 [(set_attr "prefix_0f" "1")
15485 (set_attr "mode" "DI")])
15486
15487 (define_insn "popcountdi2"
15488 [(set (match_operand:DI 0 "register_operand" "=r")
15489 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15490 (clobber (reg:CC FLAGS_REG))]
15491 "TARGET_64BIT && TARGET_POPCNT"
15492 "popcnt{q}\t{%1, %0|%0, %1}"
15493 [(set_attr "prefix_rep" "1")
15494 (set_attr "type" "bitmanip")
15495 (set_attr "mode" "DI")])
15496
15497 (define_insn "*popcountdi2_cmp"
15498 [(set (reg FLAGS_REG)
15499 (compare
15500 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15501 (const_int 0)))
15502 (set (match_operand:DI 0 "register_operand" "=r")
15503 (popcount:DI (match_dup 1)))]
15504 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15505 "popcnt{q}\t{%1, %0|%0, %1}"
15506 [(set_attr "prefix_rep" "1")
15507 (set_attr "type" "bitmanip")
15508 (set_attr "mode" "DI")])
15509
15510 (define_expand "clzhi2"
15511 [(parallel
15512 [(set (match_operand:HI 0 "register_operand" "")
15513 (minus:HI (const_int 15)
15514 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15515 (clobber (reg:CC FLAGS_REG))])
15516 (parallel
15517 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15518 (clobber (reg:CC FLAGS_REG))])]
15519 ""
15520 {
15521 if (TARGET_ABM)
15522 {
15523 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15524 DONE;
15525 }
15526 })
15527
15528 (define_insn "clzhi2_abm"
15529 [(set (match_operand:HI 0 "register_operand" "=r")
15530 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15531 (clobber (reg:CC FLAGS_REG))]
15532 "TARGET_ABM"
15533 "lzcnt{w}\t{%1, %0|%0, %1}"
15534 [(set_attr "prefix_rep" "1")
15535 (set_attr "type" "bitmanip")
15536 (set_attr "mode" "HI")])
15537
15538 (define_insn "*bsrhi"
15539 [(set (match_operand:HI 0 "register_operand" "=r")
15540 (minus:HI (const_int 15)
15541 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15542 (clobber (reg:CC FLAGS_REG))]
15543 ""
15544 "bsr{w}\t{%1, %0|%0, %1}"
15545 [(set_attr "prefix_0f" "1")
15546 (set_attr "mode" "HI")])
15547
15548 (define_insn "popcounthi2"
15549 [(set (match_operand:HI 0 "register_operand" "=r")
15550 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15551 (clobber (reg:CC FLAGS_REG))]
15552 "TARGET_POPCNT"
15553 "popcnt{w}\t{%1, %0|%0, %1}"
15554 [(set_attr "prefix_rep" "1")
15555 (set_attr "type" "bitmanip")
15556 (set_attr "mode" "HI")])
15557
15558 (define_insn "*popcounthi2_cmp"
15559 [(set (reg FLAGS_REG)
15560 (compare
15561 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15562 (const_int 0)))
15563 (set (match_operand:HI 0 "register_operand" "=r")
15564 (popcount:HI (match_dup 1)))]
15565 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15566 "popcnt{w}\t{%1, %0|%0, %1}"
15567 [(set_attr "prefix_rep" "1")
15568 (set_attr "type" "bitmanip")
15569 (set_attr "mode" "HI")])
15570
15571 (define_expand "paritydi2"
15572 [(set (match_operand:DI 0 "register_operand" "")
15573 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15574 "! TARGET_POPCNT"
15575 {
15576 rtx scratch = gen_reg_rtx (QImode);
15577 rtx cond;
15578
15579 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15580 NULL_RTX, operands[1]));
15581
15582 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15583 gen_rtx_REG (CCmode, FLAGS_REG),
15584 const0_rtx);
15585 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15586
15587 if (TARGET_64BIT)
15588 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15589 else
15590 {
15591 rtx tmp = gen_reg_rtx (SImode);
15592
15593 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15594 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15595 }
15596 DONE;
15597 })
15598
15599 (define_insn_and_split "paritydi2_cmp"
15600 [(set (reg:CC FLAGS_REG)
15601 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15602 (clobber (match_scratch:DI 0 "=r,X"))
15603 (clobber (match_scratch:SI 1 "=r,r"))
15604 (clobber (match_scratch:HI 2 "=Q,Q"))]
15605 "! TARGET_POPCNT"
15606 "#"
15607 "&& reload_completed"
15608 [(parallel
15609 [(set (match_dup 1)
15610 (xor:SI (match_dup 1) (match_dup 4)))
15611 (clobber (reg:CC FLAGS_REG))])
15612 (parallel
15613 [(set (reg:CC FLAGS_REG)
15614 (parity:CC (match_dup 1)))
15615 (clobber (match_dup 1))
15616 (clobber (match_dup 2))])]
15617 {
15618 operands[4] = gen_lowpart (SImode, operands[3]);
15619
15620 if (MEM_P (operands[3]))
15621 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15622 else if (! TARGET_64BIT)
15623 operands[1] = gen_highpart (SImode, operands[3]);
15624 else
15625 {
15626 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15627 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15628 }
15629 })
15630
15631 (define_expand "paritysi2"
15632 [(set (match_operand:SI 0 "register_operand" "")
15633 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15634 "! TARGET_POPCNT"
15635 {
15636 rtx scratch = gen_reg_rtx (QImode);
15637 rtx cond;
15638
15639 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15640
15641 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15642 gen_rtx_REG (CCmode, FLAGS_REG),
15643 const0_rtx);
15644 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15645
15646 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15647 DONE;
15648 })
15649
15650 (define_insn_and_split "paritysi2_cmp"
15651 [(set (reg:CC FLAGS_REG)
15652 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15653 (clobber (match_scratch:SI 0 "=r,X"))
15654 (clobber (match_scratch:HI 1 "=Q,Q"))]
15655 "! TARGET_POPCNT"
15656 "#"
15657 "&& reload_completed"
15658 [(parallel
15659 [(set (match_dup 1)
15660 (xor:HI (match_dup 1) (match_dup 3)))
15661 (clobber (reg:CC FLAGS_REG))])
15662 (parallel
15663 [(set (reg:CC FLAGS_REG)
15664 (parity:CC (match_dup 1)))
15665 (clobber (match_dup 1))])]
15666 {
15667 operands[3] = gen_lowpart (HImode, operands[2]);
15668
15669 if (MEM_P (operands[2]))
15670 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15671 else
15672 {
15673 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15674 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15675 }
15676 })
15677
15678 (define_insn "*parityhi2_cmp"
15679 [(set (reg:CC FLAGS_REG)
15680 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15681 (clobber (match_scratch:HI 0 "=Q"))]
15682 "! TARGET_POPCNT"
15683 "xor{b}\t{%h0, %b0|%b0, %h0}"
15684 [(set_attr "length" "2")
15685 (set_attr "mode" "HI")])
15686
15687 (define_insn "*parityqi2_cmp"
15688 [(set (reg:CC FLAGS_REG)
15689 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15690 "! TARGET_POPCNT"
15691 "test{b}\t%0, %0"
15692 [(set_attr "length" "2")
15693 (set_attr "mode" "QI")])
15694 \f
15695 ;; Thread-local storage patterns for ELF.
15696 ;;
15697 ;; Note that these code sequences must appear exactly as shown
15698 ;; in order to allow linker relaxation.
15699
15700 (define_insn "*tls_global_dynamic_32_gnu"
15701 [(set (match_operand:SI 0 "register_operand" "=a")
15702 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15703 (match_operand:SI 2 "tls_symbolic_operand" "")
15704 (match_operand:SI 3 "call_insn_operand" "")]
15705 UNSPEC_TLS_GD))
15706 (clobber (match_scratch:SI 4 "=d"))
15707 (clobber (match_scratch:SI 5 "=c"))
15708 (clobber (reg:CC FLAGS_REG))]
15709 "!TARGET_64BIT && TARGET_GNU_TLS"
15710 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15711 [(set_attr "type" "multi")
15712 (set_attr "length" "12")])
15713
15714 (define_insn "*tls_global_dynamic_32_sun"
15715 [(set (match_operand:SI 0 "register_operand" "=a")
15716 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15717 (match_operand:SI 2 "tls_symbolic_operand" "")
15718 (match_operand:SI 3 "call_insn_operand" "")]
15719 UNSPEC_TLS_GD))
15720 (clobber (match_scratch:SI 4 "=d"))
15721 (clobber (match_scratch:SI 5 "=c"))
15722 (clobber (reg:CC FLAGS_REG))]
15723 "!TARGET_64BIT && TARGET_SUN_TLS"
15724 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15725 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15726 [(set_attr "type" "multi")
15727 (set_attr "length" "14")])
15728
15729 (define_expand "tls_global_dynamic_32"
15730 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15731 (unspec:SI
15732 [(match_dup 2)
15733 (match_operand:SI 1 "tls_symbolic_operand" "")
15734 (match_dup 3)]
15735 UNSPEC_TLS_GD))
15736 (clobber (match_scratch:SI 4 ""))
15737 (clobber (match_scratch:SI 5 ""))
15738 (clobber (reg:CC FLAGS_REG))])]
15739 ""
15740 {
15741 if (flag_pic)
15742 operands[2] = pic_offset_table_rtx;
15743 else
15744 {
15745 operands[2] = gen_reg_rtx (Pmode);
15746 emit_insn (gen_set_got (operands[2]));
15747 }
15748 if (TARGET_GNU2_TLS)
15749 {
15750 emit_insn (gen_tls_dynamic_gnu2_32
15751 (operands[0], operands[1], operands[2]));
15752 DONE;
15753 }
15754 operands[3] = ix86_tls_get_addr ();
15755 })
15756
15757 (define_insn "*tls_global_dynamic_64"
15758 [(set (match_operand:DI 0 "register_operand" "=a")
15759 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15760 (match_operand:DI 3 "" "")))
15761 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15762 UNSPEC_TLS_GD)]
15763 "TARGET_64BIT"
15764 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15765 [(set_attr "type" "multi")
15766 (set_attr "length" "16")])
15767
15768 (define_expand "tls_global_dynamic_64"
15769 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15770 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15771 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15772 UNSPEC_TLS_GD)])]
15773 ""
15774 {
15775 if (TARGET_GNU2_TLS)
15776 {
15777 emit_insn (gen_tls_dynamic_gnu2_64
15778 (operands[0], operands[1]));
15779 DONE;
15780 }
15781 operands[2] = ix86_tls_get_addr ();
15782 })
15783
15784 (define_insn "*tls_local_dynamic_base_32_gnu"
15785 [(set (match_operand:SI 0 "register_operand" "=a")
15786 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15787 (match_operand:SI 2 "call_insn_operand" "")]
15788 UNSPEC_TLS_LD_BASE))
15789 (clobber (match_scratch:SI 3 "=d"))
15790 (clobber (match_scratch:SI 4 "=c"))
15791 (clobber (reg:CC FLAGS_REG))]
15792 "!TARGET_64BIT && TARGET_GNU_TLS"
15793 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15794 [(set_attr "type" "multi")
15795 (set_attr "length" "11")])
15796
15797 (define_insn "*tls_local_dynamic_base_32_sun"
15798 [(set (match_operand:SI 0 "register_operand" "=a")
15799 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15800 (match_operand:SI 2 "call_insn_operand" "")]
15801 UNSPEC_TLS_LD_BASE))
15802 (clobber (match_scratch:SI 3 "=d"))
15803 (clobber (match_scratch:SI 4 "=c"))
15804 (clobber (reg:CC FLAGS_REG))]
15805 "!TARGET_64BIT && TARGET_SUN_TLS"
15806 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15807 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15808 [(set_attr "type" "multi")
15809 (set_attr "length" "13")])
15810
15811 (define_expand "tls_local_dynamic_base_32"
15812 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15813 (unspec:SI [(match_dup 1) (match_dup 2)]
15814 UNSPEC_TLS_LD_BASE))
15815 (clobber (match_scratch:SI 3 ""))
15816 (clobber (match_scratch:SI 4 ""))
15817 (clobber (reg:CC FLAGS_REG))])]
15818 ""
15819 {
15820 if (flag_pic)
15821 operands[1] = pic_offset_table_rtx;
15822 else
15823 {
15824 operands[1] = gen_reg_rtx (Pmode);
15825 emit_insn (gen_set_got (operands[1]));
15826 }
15827 if (TARGET_GNU2_TLS)
15828 {
15829 emit_insn (gen_tls_dynamic_gnu2_32
15830 (operands[0], ix86_tls_module_base (), operands[1]));
15831 DONE;
15832 }
15833 operands[2] = ix86_tls_get_addr ();
15834 })
15835
15836 (define_insn "*tls_local_dynamic_base_64"
15837 [(set (match_operand:DI 0 "register_operand" "=a")
15838 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15839 (match_operand:DI 2 "" "")))
15840 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15841 "TARGET_64BIT"
15842 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15843 [(set_attr "type" "multi")
15844 (set_attr "length" "12")])
15845
15846 (define_expand "tls_local_dynamic_base_64"
15847 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15848 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15849 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15850 ""
15851 {
15852 if (TARGET_GNU2_TLS)
15853 {
15854 emit_insn (gen_tls_dynamic_gnu2_64
15855 (operands[0], ix86_tls_module_base ()));
15856 DONE;
15857 }
15858 operands[1] = ix86_tls_get_addr ();
15859 })
15860
15861 ;; Local dynamic of a single variable is a lose. Show combine how
15862 ;; to convert that back to global dynamic.
15863
15864 (define_insn_and_split "*tls_local_dynamic_32_once"
15865 [(set (match_operand:SI 0 "register_operand" "=a")
15866 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15867 (match_operand:SI 2 "call_insn_operand" "")]
15868 UNSPEC_TLS_LD_BASE)
15869 (const:SI (unspec:SI
15870 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15871 UNSPEC_DTPOFF))))
15872 (clobber (match_scratch:SI 4 "=d"))
15873 (clobber (match_scratch:SI 5 "=c"))
15874 (clobber (reg:CC FLAGS_REG))]
15875 ""
15876 "#"
15877 ""
15878 [(parallel [(set (match_dup 0)
15879 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15880 UNSPEC_TLS_GD))
15881 (clobber (match_dup 4))
15882 (clobber (match_dup 5))
15883 (clobber (reg:CC FLAGS_REG))])]
15884 "")
15885
15886 ;; Load and add the thread base pointer from %gs:0.
15887
15888 (define_insn "*load_tp_si"
15889 [(set (match_operand:SI 0 "register_operand" "=r")
15890 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15891 "!TARGET_64BIT"
15892 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15893 [(set_attr "type" "imov")
15894 (set_attr "modrm" "0")
15895 (set_attr "length" "7")
15896 (set_attr "memory" "load")
15897 (set_attr "imm_disp" "false")])
15898
15899 (define_insn "*add_tp_si"
15900 [(set (match_operand:SI 0 "register_operand" "=r")
15901 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15902 (match_operand:SI 1 "register_operand" "0")))
15903 (clobber (reg:CC FLAGS_REG))]
15904 "!TARGET_64BIT"
15905 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15906 [(set_attr "type" "alu")
15907 (set_attr "modrm" "0")
15908 (set_attr "length" "7")
15909 (set_attr "memory" "load")
15910 (set_attr "imm_disp" "false")])
15911
15912 (define_insn "*load_tp_di"
15913 [(set (match_operand:DI 0 "register_operand" "=r")
15914 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15915 "TARGET_64BIT"
15916 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15917 [(set_attr "type" "imov")
15918 (set_attr "modrm" "0")
15919 (set_attr "length" "7")
15920 (set_attr "memory" "load")
15921 (set_attr "imm_disp" "false")])
15922
15923 (define_insn "*add_tp_di"
15924 [(set (match_operand:DI 0 "register_operand" "=r")
15925 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15926 (match_operand:DI 1 "register_operand" "0")))
15927 (clobber (reg:CC FLAGS_REG))]
15928 "TARGET_64BIT"
15929 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15930 [(set_attr "type" "alu")
15931 (set_attr "modrm" "0")
15932 (set_attr "length" "7")
15933 (set_attr "memory" "load")
15934 (set_attr "imm_disp" "false")])
15935
15936 ;; GNU2 TLS patterns can be split.
15937
15938 (define_expand "tls_dynamic_gnu2_32"
15939 [(set (match_dup 3)
15940 (plus:SI (match_operand:SI 2 "register_operand" "")
15941 (const:SI
15942 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15943 UNSPEC_TLSDESC))))
15944 (parallel
15945 [(set (match_operand:SI 0 "register_operand" "")
15946 (unspec:SI [(match_dup 1) (match_dup 3)
15947 (match_dup 2) (reg:SI SP_REG)]
15948 UNSPEC_TLSDESC))
15949 (clobber (reg:CC FLAGS_REG))])]
15950 "!TARGET_64BIT && TARGET_GNU2_TLS"
15951 {
15952 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15953 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15954 })
15955
15956 (define_insn "*tls_dynamic_lea_32"
15957 [(set (match_operand:SI 0 "register_operand" "=r")
15958 (plus:SI (match_operand:SI 1 "register_operand" "b")
15959 (const:SI
15960 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15961 UNSPEC_TLSDESC))))]
15962 "!TARGET_64BIT && TARGET_GNU2_TLS"
15963 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15964 [(set_attr "type" "lea")
15965 (set_attr "mode" "SI")
15966 (set_attr "length" "6")
15967 (set_attr "length_address" "4")])
15968
15969 (define_insn "*tls_dynamic_call_32"
15970 [(set (match_operand:SI 0 "register_operand" "=a")
15971 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15972 (match_operand:SI 2 "register_operand" "0")
15973 ;; we have to make sure %ebx still points to the GOT
15974 (match_operand:SI 3 "register_operand" "b")
15975 (reg:SI SP_REG)]
15976 UNSPEC_TLSDESC))
15977 (clobber (reg:CC FLAGS_REG))]
15978 "!TARGET_64BIT && TARGET_GNU2_TLS"
15979 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15980 [(set_attr "type" "call")
15981 (set_attr "length" "2")
15982 (set_attr "length_address" "0")])
15983
15984 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15985 [(set (match_operand:SI 0 "register_operand" "=&a")
15986 (plus:SI
15987 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15988 (match_operand:SI 4 "" "")
15989 (match_operand:SI 2 "register_operand" "b")
15990 (reg:SI SP_REG)]
15991 UNSPEC_TLSDESC)
15992 (const:SI (unspec:SI
15993 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15994 UNSPEC_DTPOFF))))
15995 (clobber (reg:CC FLAGS_REG))]
15996 "!TARGET_64BIT && TARGET_GNU2_TLS"
15997 "#"
15998 ""
15999 [(set (match_dup 0) (match_dup 5))]
16000 {
16001 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16002 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16003 })
16004
16005 (define_expand "tls_dynamic_gnu2_64"
16006 [(set (match_dup 2)
16007 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16008 UNSPEC_TLSDESC))
16009 (parallel
16010 [(set (match_operand:DI 0 "register_operand" "")
16011 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16012 UNSPEC_TLSDESC))
16013 (clobber (reg:CC FLAGS_REG))])]
16014 "TARGET_64BIT && TARGET_GNU2_TLS"
16015 {
16016 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16017 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16018 })
16019
16020 (define_insn "*tls_dynamic_lea_64"
16021 [(set (match_operand:DI 0 "register_operand" "=r")
16022 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16023 UNSPEC_TLSDESC))]
16024 "TARGET_64BIT && TARGET_GNU2_TLS"
16025 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16026 [(set_attr "type" "lea")
16027 (set_attr "mode" "DI")
16028 (set_attr "length" "7")
16029 (set_attr "length_address" "4")])
16030
16031 (define_insn "*tls_dynamic_call_64"
16032 [(set (match_operand:DI 0 "register_operand" "=a")
16033 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16034 (match_operand:DI 2 "register_operand" "0")
16035 (reg:DI SP_REG)]
16036 UNSPEC_TLSDESC))
16037 (clobber (reg:CC FLAGS_REG))]
16038 "TARGET_64BIT && TARGET_GNU2_TLS"
16039 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16040 [(set_attr "type" "call")
16041 (set_attr "length" "2")
16042 (set_attr "length_address" "0")])
16043
16044 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16045 [(set (match_operand:DI 0 "register_operand" "=&a")
16046 (plus:DI
16047 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16048 (match_operand:DI 3 "" "")
16049 (reg:DI SP_REG)]
16050 UNSPEC_TLSDESC)
16051 (const:DI (unspec:DI
16052 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16053 UNSPEC_DTPOFF))))
16054 (clobber (reg:CC FLAGS_REG))]
16055 "TARGET_64BIT && TARGET_GNU2_TLS"
16056 "#"
16057 ""
16058 [(set (match_dup 0) (match_dup 4))]
16059 {
16060 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16061 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16062 })
16063
16064 ;;
16065 \f
16066 ;; These patterns match the binary 387 instructions for addM3, subM3,
16067 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16068 ;; SFmode. The first is the normal insn, the second the same insn but
16069 ;; with one operand a conversion, and the third the same insn but with
16070 ;; the other operand a conversion. The conversion may be SFmode or
16071 ;; SImode if the target mode DFmode, but only SImode if the target mode
16072 ;; is SFmode.
16073
16074 ;; Gcc is slightly more smart about handling normal two address instructions
16075 ;; so use special patterns for add and mull.
16076
16077 (define_insn "*fop_sf_comm_mixed"
16078 [(set (match_operand:SF 0 "register_operand" "=f,x")
16079 (match_operator:SF 3 "binary_fp_operator"
16080 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
16081 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
16082 "TARGET_MIX_SSE_I387
16083 && COMMUTATIVE_ARITH_P (operands[3])
16084 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16085 "* return output_387_binary_op (insn, operands);"
16086 [(set (attr "type")
16087 (if_then_else (eq_attr "alternative" "1")
16088 (if_then_else (match_operand:SF 3 "mult_operator" "")
16089 (const_string "ssemul")
16090 (const_string "sseadd"))
16091 (if_then_else (match_operand:SF 3 "mult_operator" "")
16092 (const_string "fmul")
16093 (const_string "fop"))))
16094 (set_attr "mode" "SF")])
16095
16096 (define_insn "*fop_sf_comm_sse"
16097 [(set (match_operand:SF 0 "register_operand" "=x")
16098 (match_operator:SF 3 "binary_fp_operator"
16099 [(match_operand:SF 1 "nonimmediate_operand" "%0")
16100 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16101 "TARGET_SSE_MATH
16102 && COMMUTATIVE_ARITH_P (operands[3])
16103 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16104 "* return output_387_binary_op (insn, operands);"
16105 [(set (attr "type")
16106 (if_then_else (match_operand:SF 3 "mult_operator" "")
16107 (const_string "ssemul")
16108 (const_string "sseadd")))
16109 (set_attr "mode" "SF")])
16110
16111 (define_insn "*fop_sf_comm_i387"
16112 [(set (match_operand:SF 0 "register_operand" "=f")
16113 (match_operator:SF 3 "binary_fp_operator"
16114 [(match_operand:SF 1 "nonimmediate_operand" "%0")
16115 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
16116 "TARGET_80387
16117 && COMMUTATIVE_ARITH_P (operands[3])
16118 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16119 "* return output_387_binary_op (insn, operands);"
16120 [(set (attr "type")
16121 (if_then_else (match_operand:SF 3 "mult_operator" "")
16122 (const_string "fmul")
16123 (const_string "fop")))
16124 (set_attr "mode" "SF")])
16125
16126 (define_insn "*fop_sf_1_mixed"
16127 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
16128 (match_operator:SF 3 "binary_fp_operator"
16129 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
16130 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
16131 "TARGET_MIX_SSE_I387
16132 && !COMMUTATIVE_ARITH_P (operands[3])
16133 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16134 "* return output_387_binary_op (insn, operands);"
16135 [(set (attr "type")
16136 (cond [(and (eq_attr "alternative" "2")
16137 (match_operand:SF 3 "mult_operator" ""))
16138 (const_string "ssemul")
16139 (and (eq_attr "alternative" "2")
16140 (match_operand:SF 3 "div_operator" ""))
16141 (const_string "ssediv")
16142 (eq_attr "alternative" "2")
16143 (const_string "sseadd")
16144 (match_operand:SF 3 "mult_operator" "")
16145 (const_string "fmul")
16146 (match_operand:SF 3 "div_operator" "")
16147 (const_string "fdiv")
16148 ]
16149 (const_string "fop")))
16150 (set_attr "mode" "SF")])
16151
16152 (define_insn "*rcpsf2_sse"
16153 [(set (match_operand:SF 0 "register_operand" "=x")
16154 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16155 UNSPEC_RCP))]
16156 "TARGET_SSE_MATH"
16157 "rcpss\t{%1, %0|%0, %1}"
16158 [(set_attr "type" "sse")
16159 (set_attr "mode" "SF")])
16160
16161 (define_insn "*fop_sf_1_sse"
16162 [(set (match_operand:SF 0 "register_operand" "=x")
16163 (match_operator:SF 3 "binary_fp_operator"
16164 [(match_operand:SF 1 "register_operand" "0")
16165 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16166 "TARGET_SSE_MATH
16167 && !COMMUTATIVE_ARITH_P (operands[3])"
16168 "* return output_387_binary_op (insn, operands);"
16169 [(set (attr "type")
16170 (cond [(match_operand:SF 3 "mult_operator" "")
16171 (const_string "ssemul")
16172 (match_operand:SF 3 "div_operator" "")
16173 (const_string "ssediv")
16174 ]
16175 (const_string "sseadd")))
16176 (set_attr "mode" "SF")])
16177
16178 ;; This pattern is not fully shadowed by the pattern above.
16179 (define_insn "*fop_sf_1_i387"
16180 [(set (match_operand:SF 0 "register_operand" "=f,f")
16181 (match_operator:SF 3 "binary_fp_operator"
16182 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16183 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16184 "TARGET_80387 && !TARGET_SSE_MATH
16185 && !COMMUTATIVE_ARITH_P (operands[3])
16186 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16187 "* return output_387_binary_op (insn, operands);"
16188 [(set (attr "type")
16189 (cond [(match_operand:SF 3 "mult_operator" "")
16190 (const_string "fmul")
16191 (match_operand:SF 3 "div_operator" "")
16192 (const_string "fdiv")
16193 ]
16194 (const_string "fop")))
16195 (set_attr "mode" "SF")])
16196
16197 ;; ??? Add SSE splitters for these!
16198 (define_insn "*fop_sf_2<mode>_i387"
16199 [(set (match_operand:SF 0 "register_operand" "=f,f")
16200 (match_operator:SF 3 "binary_fp_operator"
16201 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16202 (match_operand:SF 2 "register_operand" "0,0")]))]
16203 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16204 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16205 [(set (attr "type")
16206 (cond [(match_operand:SF 3 "mult_operator" "")
16207 (const_string "fmul")
16208 (match_operand:SF 3 "div_operator" "")
16209 (const_string "fdiv")
16210 ]
16211 (const_string "fop")))
16212 (set_attr "fp_int_src" "true")
16213 (set_attr "mode" "<MODE>")])
16214
16215 (define_insn "*fop_sf_3<mode>_i387"
16216 [(set (match_operand:SF 0 "register_operand" "=f,f")
16217 (match_operator:SF 3 "binary_fp_operator"
16218 [(match_operand:SF 1 "register_operand" "0,0")
16219 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16220 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16221 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16222 [(set (attr "type")
16223 (cond [(match_operand:SF 3 "mult_operator" "")
16224 (const_string "fmul")
16225 (match_operand:SF 3 "div_operator" "")
16226 (const_string "fdiv")
16227 ]
16228 (const_string "fop")))
16229 (set_attr "fp_int_src" "true")
16230 (set_attr "mode" "<MODE>")])
16231
16232 (define_insn "*fop_df_comm_mixed"
16233 [(set (match_operand:DF 0 "register_operand" "=f,x")
16234 (match_operator:DF 3 "binary_fp_operator"
16235 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16236 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16237 "TARGET_SSE2 && TARGET_MIX_SSE_I387
16238 && COMMUTATIVE_ARITH_P (operands[3])
16239 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16240 "* return output_387_binary_op (insn, operands);"
16241 [(set (attr "type")
16242 (if_then_else (eq_attr "alternative" "1")
16243 (if_then_else (match_operand:DF 3 "mult_operator" "")
16244 (const_string "ssemul")
16245 (const_string "sseadd"))
16246 (if_then_else (match_operand:DF 3 "mult_operator" "")
16247 (const_string "fmul")
16248 (const_string "fop"))))
16249 (set_attr "mode" "DF")])
16250
16251 (define_insn "*fop_df_comm_sse"
16252 [(set (match_operand:DF 0 "register_operand" "=x")
16253 (match_operator:DF 3 "binary_fp_operator"
16254 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16255 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16256 "TARGET_SSE2 && TARGET_SSE_MATH
16257 && COMMUTATIVE_ARITH_P (operands[3])
16258 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16259 "* return output_387_binary_op (insn, operands);"
16260 [(set (attr "type")
16261 (if_then_else (match_operand:DF 3 "mult_operator" "")
16262 (const_string "ssemul")
16263 (const_string "sseadd")))
16264 (set_attr "mode" "DF")])
16265
16266 (define_insn "*fop_df_comm_i387"
16267 [(set (match_operand:DF 0 "register_operand" "=f")
16268 (match_operator:DF 3 "binary_fp_operator"
16269 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16270 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16271 "TARGET_80387
16272 && COMMUTATIVE_ARITH_P (operands[3])
16273 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16274 "* return output_387_binary_op (insn, operands);"
16275 [(set (attr "type")
16276 (if_then_else (match_operand:DF 3 "mult_operator" "")
16277 (const_string "fmul")
16278 (const_string "fop")))
16279 (set_attr "mode" "DF")])
16280
16281 (define_insn "*fop_df_1_mixed"
16282 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16283 (match_operator:DF 3 "binary_fp_operator"
16284 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16285 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16286 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16287 && !COMMUTATIVE_ARITH_P (operands[3])
16288 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16289 "* return output_387_binary_op (insn, operands);"
16290 [(set (attr "type")
16291 (cond [(and (eq_attr "alternative" "2")
16292 (match_operand:DF 3 "mult_operator" ""))
16293 (const_string "ssemul")
16294 (and (eq_attr "alternative" "2")
16295 (match_operand:DF 3 "div_operator" ""))
16296 (const_string "ssediv")
16297 (eq_attr "alternative" "2")
16298 (const_string "sseadd")
16299 (match_operand:DF 3 "mult_operator" "")
16300 (const_string "fmul")
16301 (match_operand:DF 3 "div_operator" "")
16302 (const_string "fdiv")
16303 ]
16304 (const_string "fop")))
16305 (set_attr "mode" "DF")])
16306
16307 (define_insn "*fop_df_1_sse"
16308 [(set (match_operand:DF 0 "register_operand" "=x")
16309 (match_operator:DF 3 "binary_fp_operator"
16310 [(match_operand:DF 1 "register_operand" "0")
16311 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16312 "TARGET_SSE2 && TARGET_SSE_MATH
16313 && !COMMUTATIVE_ARITH_P (operands[3])"
16314 "* return output_387_binary_op (insn, operands);"
16315 [(set_attr "mode" "DF")
16316 (set (attr "type")
16317 (cond [(match_operand:DF 3 "mult_operator" "")
16318 (const_string "ssemul")
16319 (match_operand:DF 3 "div_operator" "")
16320 (const_string "ssediv")
16321 ]
16322 (const_string "sseadd")))])
16323
16324 ;; This pattern is not fully shadowed by the pattern above.
16325 (define_insn "*fop_df_1_i387"
16326 [(set (match_operand:DF 0 "register_operand" "=f,f")
16327 (match_operator:DF 3 "binary_fp_operator"
16328 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16329 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16330 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16331 && !COMMUTATIVE_ARITH_P (operands[3])
16332 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16333 "* return output_387_binary_op (insn, operands);"
16334 [(set (attr "type")
16335 (cond [(match_operand:DF 3 "mult_operator" "")
16336 (const_string "fmul")
16337 (match_operand:DF 3 "div_operator" "")
16338 (const_string "fdiv")
16339 ]
16340 (const_string "fop")))
16341 (set_attr "mode" "DF")])
16342
16343 ;; ??? Add SSE splitters for these!
16344 (define_insn "*fop_df_2<mode>_i387"
16345 [(set (match_operand:DF 0 "register_operand" "=f,f")
16346 (match_operator:DF 3 "binary_fp_operator"
16347 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16348 (match_operand:DF 2 "register_operand" "0,0")]))]
16349 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16350 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16351 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16352 [(set (attr "type")
16353 (cond [(match_operand:DF 3 "mult_operator" "")
16354 (const_string "fmul")
16355 (match_operand:DF 3 "div_operator" "")
16356 (const_string "fdiv")
16357 ]
16358 (const_string "fop")))
16359 (set_attr "fp_int_src" "true")
16360 (set_attr "mode" "<MODE>")])
16361
16362 (define_insn "*fop_df_3<mode>_i387"
16363 [(set (match_operand:DF 0 "register_operand" "=f,f")
16364 (match_operator:DF 3 "binary_fp_operator"
16365 [(match_operand:DF 1 "register_operand" "0,0")
16366 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16367 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16368 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16369 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16370 [(set (attr "type")
16371 (cond [(match_operand:DF 3 "mult_operator" "")
16372 (const_string "fmul")
16373 (match_operand:DF 3 "div_operator" "")
16374 (const_string "fdiv")
16375 ]
16376 (const_string "fop")))
16377 (set_attr "fp_int_src" "true")
16378 (set_attr "mode" "<MODE>")])
16379
16380 (define_insn "*fop_df_4_i387"
16381 [(set (match_operand:DF 0 "register_operand" "=f,f")
16382 (match_operator:DF 3 "binary_fp_operator"
16383 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16384 (match_operand:DF 2 "register_operand" "0,f")]))]
16385 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16386 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16387 "* return output_387_binary_op (insn, operands);"
16388 [(set (attr "type")
16389 (cond [(match_operand:DF 3 "mult_operator" "")
16390 (const_string "fmul")
16391 (match_operand:DF 3 "div_operator" "")
16392 (const_string "fdiv")
16393 ]
16394 (const_string "fop")))
16395 (set_attr "mode" "SF")])
16396
16397 (define_insn "*fop_df_5_i387"
16398 [(set (match_operand:DF 0 "register_operand" "=f,f")
16399 (match_operator:DF 3 "binary_fp_operator"
16400 [(match_operand:DF 1 "register_operand" "0,f")
16401 (float_extend:DF
16402 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16403 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16404 "* return output_387_binary_op (insn, operands);"
16405 [(set (attr "type")
16406 (cond [(match_operand:DF 3 "mult_operator" "")
16407 (const_string "fmul")
16408 (match_operand:DF 3 "div_operator" "")
16409 (const_string "fdiv")
16410 ]
16411 (const_string "fop")))
16412 (set_attr "mode" "SF")])
16413
16414 (define_insn "*fop_df_6_i387"
16415 [(set (match_operand:DF 0 "register_operand" "=f,f")
16416 (match_operator:DF 3 "binary_fp_operator"
16417 [(float_extend:DF
16418 (match_operand:SF 1 "register_operand" "0,f"))
16419 (float_extend:DF
16420 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16421 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16422 "* return output_387_binary_op (insn, operands);"
16423 [(set (attr "type")
16424 (cond [(match_operand:DF 3 "mult_operator" "")
16425 (const_string "fmul")
16426 (match_operand:DF 3 "div_operator" "")
16427 (const_string "fdiv")
16428 ]
16429 (const_string "fop")))
16430 (set_attr "mode" "SF")])
16431
16432 (define_insn "*fop_xf_comm_i387"
16433 [(set (match_operand:XF 0 "register_operand" "=f")
16434 (match_operator:XF 3 "binary_fp_operator"
16435 [(match_operand:XF 1 "register_operand" "%0")
16436 (match_operand:XF 2 "register_operand" "f")]))]
16437 "TARGET_80387
16438 && COMMUTATIVE_ARITH_P (operands[3])"
16439 "* return output_387_binary_op (insn, operands);"
16440 [(set (attr "type")
16441 (if_then_else (match_operand:XF 3 "mult_operator" "")
16442 (const_string "fmul")
16443 (const_string "fop")))
16444 (set_attr "mode" "XF")])
16445
16446 (define_insn "*fop_xf_1_i387"
16447 [(set (match_operand:XF 0 "register_operand" "=f,f")
16448 (match_operator:XF 3 "binary_fp_operator"
16449 [(match_operand:XF 1 "register_operand" "0,f")
16450 (match_operand:XF 2 "register_operand" "f,0")]))]
16451 "TARGET_80387
16452 && !COMMUTATIVE_ARITH_P (operands[3])"
16453 "* return output_387_binary_op (insn, operands);"
16454 [(set (attr "type")
16455 (cond [(match_operand:XF 3 "mult_operator" "")
16456 (const_string "fmul")
16457 (match_operand:XF 3 "div_operator" "")
16458 (const_string "fdiv")
16459 ]
16460 (const_string "fop")))
16461 (set_attr "mode" "XF")])
16462
16463 (define_insn "*fop_xf_2<mode>_i387"
16464 [(set (match_operand:XF 0 "register_operand" "=f,f")
16465 (match_operator:XF 3 "binary_fp_operator"
16466 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16467 (match_operand:XF 2 "register_operand" "0,0")]))]
16468 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16469 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16470 [(set (attr "type")
16471 (cond [(match_operand:XF 3 "mult_operator" "")
16472 (const_string "fmul")
16473 (match_operand:XF 3 "div_operator" "")
16474 (const_string "fdiv")
16475 ]
16476 (const_string "fop")))
16477 (set_attr "fp_int_src" "true")
16478 (set_attr "mode" "<MODE>")])
16479
16480 (define_insn "*fop_xf_3<mode>_i387"
16481 [(set (match_operand:XF 0 "register_operand" "=f,f")
16482 (match_operator:XF 3 "binary_fp_operator"
16483 [(match_operand:XF 1 "register_operand" "0,0")
16484 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16485 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16486 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16487 [(set (attr "type")
16488 (cond [(match_operand:XF 3 "mult_operator" "")
16489 (const_string "fmul")
16490 (match_operand:XF 3 "div_operator" "")
16491 (const_string "fdiv")
16492 ]
16493 (const_string "fop")))
16494 (set_attr "fp_int_src" "true")
16495 (set_attr "mode" "<MODE>")])
16496
16497 (define_insn "*fop_xf_4_i387"
16498 [(set (match_operand:XF 0 "register_operand" "=f,f")
16499 (match_operator:XF 3 "binary_fp_operator"
16500 [(float_extend:XF
16501 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16502 (match_operand:XF 2 "register_operand" "0,f")]))]
16503 "TARGET_80387"
16504 "* return output_387_binary_op (insn, operands);"
16505 [(set (attr "type")
16506 (cond [(match_operand:XF 3 "mult_operator" "")
16507 (const_string "fmul")
16508 (match_operand:XF 3 "div_operator" "")
16509 (const_string "fdiv")
16510 ]
16511 (const_string "fop")))
16512 (set_attr "mode" "SF")])
16513
16514 (define_insn "*fop_xf_5_i387"
16515 [(set (match_operand:XF 0 "register_operand" "=f,f")
16516 (match_operator:XF 3 "binary_fp_operator"
16517 [(match_operand:XF 1 "register_operand" "0,f")
16518 (float_extend:XF
16519 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16520 "TARGET_80387"
16521 "* return output_387_binary_op (insn, operands);"
16522 [(set (attr "type")
16523 (cond [(match_operand:XF 3 "mult_operator" "")
16524 (const_string "fmul")
16525 (match_operand:XF 3 "div_operator" "")
16526 (const_string "fdiv")
16527 ]
16528 (const_string "fop")))
16529 (set_attr "mode" "SF")])
16530
16531 (define_insn "*fop_xf_6_i387"
16532 [(set (match_operand:XF 0 "register_operand" "=f,f")
16533 (match_operator:XF 3 "binary_fp_operator"
16534 [(float_extend:XF
16535 (match_operand:MODEF 1 "register_operand" "0,f"))
16536 (float_extend:XF
16537 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16538 "TARGET_80387"
16539 "* return output_387_binary_op (insn, operands);"
16540 [(set (attr "type")
16541 (cond [(match_operand:XF 3 "mult_operator" "")
16542 (const_string "fmul")
16543 (match_operand:XF 3 "div_operator" "")
16544 (const_string "fdiv")
16545 ]
16546 (const_string "fop")))
16547 (set_attr "mode" "SF")])
16548
16549 (define_split
16550 [(set (match_operand 0 "register_operand" "")
16551 (match_operator 3 "binary_fp_operator"
16552 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16553 (match_operand 2 "register_operand" "")]))]
16554 "reload_completed
16555 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16556 [(const_int 0)]
16557 {
16558 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16559 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16560 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16561 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16562 GET_MODE (operands[3]),
16563 operands[4],
16564 operands[2])));
16565 ix86_free_from_memory (GET_MODE (operands[1]));
16566 DONE;
16567 })
16568
16569 (define_split
16570 [(set (match_operand 0 "register_operand" "")
16571 (match_operator 3 "binary_fp_operator"
16572 [(match_operand 1 "register_operand" "")
16573 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16574 "reload_completed
16575 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16576 [(const_int 0)]
16577 {
16578 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16579 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16580 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16581 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16582 GET_MODE (operands[3]),
16583 operands[1],
16584 operands[4])));
16585 ix86_free_from_memory (GET_MODE (operands[2]));
16586 DONE;
16587 })
16588 \f
16589 ;; FPU special functions.
16590
16591 ;; This pattern implements a no-op XFmode truncation for
16592 ;; all fancy i386 XFmode math functions.
16593
16594 (define_insn "truncxf<mode>2_i387_noop_unspec"
16595 [(set (match_operand:MODEF 0 "register_operand" "=f")
16596 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16597 UNSPEC_TRUNC_NOOP))]
16598 "TARGET_USE_FANCY_MATH_387"
16599 "* return output_387_reg_move (insn, operands);"
16600 [(set_attr "type" "fmov")
16601 (set_attr "mode" "<MODE>")])
16602
16603 (define_insn "sqrtxf2"
16604 [(set (match_operand:XF 0 "register_operand" "=f")
16605 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16606 "TARGET_USE_FANCY_MATH_387"
16607 "fsqrt"
16608 [(set_attr "type" "fpspc")
16609 (set_attr "mode" "XF")
16610 (set_attr "athlon_decode" "direct")
16611 (set_attr "amdfam10_decode" "direct")])
16612
16613 (define_insn "sqrt_extend<mode>xf2_i387"
16614 [(set (match_operand:XF 0 "register_operand" "=f")
16615 (sqrt:XF
16616 (float_extend:XF
16617 (match_operand:MODEF 1 "register_operand" "0"))))]
16618 "TARGET_USE_FANCY_MATH_387"
16619 "fsqrt"
16620 [(set_attr "type" "fpspc")
16621 (set_attr "mode" "XF")
16622 (set_attr "athlon_decode" "direct")
16623 (set_attr "amdfam10_decode" "direct")])
16624
16625 (define_insn "*rsqrtsf2_sse"
16626 [(set (match_operand:SF 0 "register_operand" "=x")
16627 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16628 UNSPEC_RSQRT))]
16629 "TARGET_SSE_MATH"
16630 "rsqrtss\t{%1, %0|%0, %1}"
16631 [(set_attr "type" "sse")
16632 (set_attr "mode" "SF")])
16633
16634 (define_expand "rsqrtsf2"
16635 [(set (match_operand:SF 0 "register_operand" "")
16636 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16637 UNSPEC_RSQRT))]
16638 "TARGET_SSE_MATH"
16639 {
16640 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16641 DONE;
16642 })
16643
16644 (define_insn "*sqrt<mode>2_sse"
16645 [(set (match_operand:MODEF 0 "register_operand" "=x")
16646 (sqrt:MODEF
16647 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16648 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16649 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16650 [(set_attr "type" "sse")
16651 (set_attr "mode" "<MODE>")
16652 (set_attr "athlon_decode" "*")
16653 (set_attr "amdfam10_decode" "*")])
16654
16655 (define_expand "sqrt<mode>2"
16656 [(set (match_operand:MODEF 0 "register_operand" "")
16657 (sqrt:MODEF
16658 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16659 "TARGET_USE_FANCY_MATH_387
16660 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16661 {
16662 if (<MODE>mode == SFmode
16663 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16664 && flag_finite_math_only && !flag_trapping_math
16665 && flag_unsafe_math_optimizations)
16666 {
16667 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16668 DONE;
16669 }
16670
16671 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16672 {
16673 rtx op0 = gen_reg_rtx (XFmode);
16674 rtx op1 = force_reg (<MODE>mode, operands[1]);
16675
16676 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16677 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16678 DONE;
16679 }
16680 })
16681
16682 (define_insn "fpremxf4_i387"
16683 [(set (match_operand:XF 0 "register_operand" "=f")
16684 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16685 (match_operand:XF 3 "register_operand" "1")]
16686 UNSPEC_FPREM_F))
16687 (set (match_operand:XF 1 "register_operand" "=u")
16688 (unspec:XF [(match_dup 2) (match_dup 3)]
16689 UNSPEC_FPREM_U))
16690 (set (reg:CCFP FPSR_REG)
16691 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16692 UNSPEC_C2_FLAG))]
16693 "TARGET_USE_FANCY_MATH_387"
16694 "fprem"
16695 [(set_attr "type" "fpspc")
16696 (set_attr "mode" "XF")])
16697
16698 (define_expand "fmodxf3"
16699 [(use (match_operand:XF 0 "register_operand" ""))
16700 (use (match_operand:XF 1 "register_operand" ""))
16701 (use (match_operand:XF 2 "register_operand" ""))]
16702 "TARGET_USE_FANCY_MATH_387"
16703 {
16704 rtx label = gen_label_rtx ();
16705
16706 rtx op2;
16707
16708 if (rtx_equal_p (operands[1], operands[2]))
16709 {
16710 op2 = gen_reg_rtx (XFmode);
16711 emit_move_insn (op2, operands[2]);
16712 }
16713 else
16714 op2 = operands[2];
16715
16716 emit_label (label);
16717 emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16718 ix86_emit_fp_unordered_jump (label);
16719 LABEL_NUSES (label) = 1;
16720
16721 emit_move_insn (operands[0], operands[1]);
16722 DONE;
16723 })
16724
16725 (define_expand "fmod<mode>3"
16726 [(use (match_operand:MODEF 0 "register_operand" ""))
16727 (use (match_operand:MODEF 1 "general_operand" ""))
16728 (use (match_operand:MODEF 2 "general_operand" ""))]
16729 "TARGET_USE_FANCY_MATH_387"
16730 {
16731 rtx label = gen_label_rtx ();
16732
16733 rtx op1 = gen_reg_rtx (XFmode);
16734 rtx op2 = gen_reg_rtx (XFmode);
16735
16736 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16737 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16738
16739 emit_label (label);
16740 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16741 ix86_emit_fp_unordered_jump (label);
16742 LABEL_NUSES (label) = 1;
16743
16744 /* Truncate the result properly for strict SSE math. */
16745 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16746 && !TARGET_MIX_SSE_I387)
16747 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16748 else
16749 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16750
16751 DONE;
16752 })
16753
16754 (define_insn "fprem1xf4_i387"
16755 [(set (match_operand:XF 0 "register_operand" "=f")
16756 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16757 (match_operand:XF 3 "register_operand" "1")]
16758 UNSPEC_FPREM1_F))
16759 (set (match_operand:XF 1 "register_operand" "=u")
16760 (unspec:XF [(match_dup 2) (match_dup 3)]
16761 UNSPEC_FPREM1_U))
16762 (set (reg:CCFP FPSR_REG)
16763 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16764 UNSPEC_C2_FLAG))]
16765 "TARGET_USE_FANCY_MATH_387"
16766 "fprem1"
16767 [(set_attr "type" "fpspc")
16768 (set_attr "mode" "XF")])
16769
16770 (define_expand "remainderxf3"
16771 [(use (match_operand:XF 0 "register_operand" ""))
16772 (use (match_operand:XF 1 "register_operand" ""))
16773 (use (match_operand:XF 2 "register_operand" ""))]
16774 "TARGET_USE_FANCY_MATH_387"
16775 {
16776 rtx label = gen_label_rtx ();
16777
16778 rtx op2;
16779
16780 if (rtx_equal_p (operands[1], operands[2]))
16781 {
16782 op2 = gen_reg_rtx (XFmode);
16783 emit_move_insn (op2, operands[2]);
16784 }
16785 else
16786 op2 = operands[2];
16787
16788 emit_label (label);
16789 emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16790 ix86_emit_fp_unordered_jump (label);
16791 LABEL_NUSES (label) = 1;
16792
16793 emit_move_insn (operands[0], operands[1]);
16794 DONE;
16795 })
16796
16797 (define_expand "remainder<mode>3"
16798 [(use (match_operand:MODEF 0 "register_operand" ""))
16799 (use (match_operand:MODEF 1 "general_operand" ""))
16800 (use (match_operand:MODEF 2 "general_operand" ""))]
16801 "TARGET_USE_FANCY_MATH_387"
16802 {
16803 rtx label = gen_label_rtx ();
16804
16805 rtx op1 = gen_reg_rtx (XFmode);
16806 rtx op2 = gen_reg_rtx (XFmode);
16807
16808 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16809 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16810
16811 emit_label (label);
16812
16813 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16814 ix86_emit_fp_unordered_jump (label);
16815 LABEL_NUSES (label) = 1;
16816
16817 /* Truncate the result properly for strict SSE math. */
16818 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16819 && !TARGET_MIX_SSE_I387)
16820 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16821 else
16822 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16823
16824 DONE;
16825 })
16826
16827 (define_insn "*sinxf2_i387"
16828 [(set (match_operand:XF 0 "register_operand" "=f")
16829 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16830 "TARGET_USE_FANCY_MATH_387
16831 && flag_unsafe_math_optimizations"
16832 "fsin"
16833 [(set_attr "type" "fpspc")
16834 (set_attr "mode" "XF")])
16835
16836 (define_insn "*sin_extend<mode>xf2_i387"
16837 [(set (match_operand:XF 0 "register_operand" "=f")
16838 (unspec:XF [(float_extend:XF
16839 (match_operand:MODEF 1 "register_operand" "0"))]
16840 UNSPEC_SIN))]
16841 "TARGET_USE_FANCY_MATH_387
16842 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16843 || TARGET_MIX_SSE_I387)
16844 && flag_unsafe_math_optimizations"
16845 "fsin"
16846 [(set_attr "type" "fpspc")
16847 (set_attr "mode" "XF")])
16848
16849 (define_insn "*cosxf2_i387"
16850 [(set (match_operand:XF 0 "register_operand" "=f")
16851 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16852 "TARGET_USE_FANCY_MATH_387
16853 && flag_unsafe_math_optimizations"
16854 "fcos"
16855 [(set_attr "type" "fpspc")
16856 (set_attr "mode" "XF")])
16857
16858 (define_insn "*cos_extend<mode>xf2_i387"
16859 [(set (match_operand:XF 0 "register_operand" "=f")
16860 (unspec:XF [(float_extend:XF
16861 (match_operand:MODEF 1 "register_operand" "0"))]
16862 UNSPEC_COS))]
16863 "TARGET_USE_FANCY_MATH_387
16864 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16865 || TARGET_MIX_SSE_I387)
16866 && flag_unsafe_math_optimizations"
16867 "fcos"
16868 [(set_attr "type" "fpspc")
16869 (set_attr "mode" "XF")])
16870
16871 ;; When sincos pattern is defined, sin and cos builtin functions will be
16872 ;; expanded to sincos pattern with one of its outputs left unused.
16873 ;; CSE pass will figure out if two sincos patterns can be combined,
16874 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16875 ;; depending on the unused output.
16876
16877 (define_insn "sincosxf3"
16878 [(set (match_operand:XF 0 "register_operand" "=f")
16879 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16880 UNSPEC_SINCOS_COS))
16881 (set (match_operand:XF 1 "register_operand" "=u")
16882 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16883 "TARGET_USE_FANCY_MATH_387
16884 && flag_unsafe_math_optimizations"
16885 "fsincos"
16886 [(set_attr "type" "fpspc")
16887 (set_attr "mode" "XF")])
16888
16889 (define_split
16890 [(set (match_operand:XF 0 "register_operand" "")
16891 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16892 UNSPEC_SINCOS_COS))
16893 (set (match_operand:XF 1 "register_operand" "")
16894 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16895 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16896 && !(reload_completed || reload_in_progress)"
16897 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16898 "")
16899
16900 (define_split
16901 [(set (match_operand:XF 0 "register_operand" "")
16902 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16903 UNSPEC_SINCOS_COS))
16904 (set (match_operand:XF 1 "register_operand" "")
16905 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16906 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16907 && !(reload_completed || reload_in_progress)"
16908 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16909 "")
16910
16911 (define_insn "sincos_extend<mode>xf3_i387"
16912 [(set (match_operand:XF 0 "register_operand" "=f")
16913 (unspec:XF [(float_extend:XF
16914 (match_operand:MODEF 2 "register_operand" "0"))]
16915 UNSPEC_SINCOS_COS))
16916 (set (match_operand:XF 1 "register_operand" "=u")
16917 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16918 "TARGET_USE_FANCY_MATH_387
16919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16920 || TARGET_MIX_SSE_I387)
16921 && flag_unsafe_math_optimizations"
16922 "fsincos"
16923 [(set_attr "type" "fpspc")
16924 (set_attr "mode" "XF")])
16925
16926 (define_split
16927 [(set (match_operand:XF 0 "register_operand" "")
16928 (unspec:XF [(float_extend:XF
16929 (match_operand:MODEF 2 "register_operand" ""))]
16930 UNSPEC_SINCOS_COS))
16931 (set (match_operand:XF 1 "register_operand" "")
16932 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16933 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16934 && !(reload_completed || reload_in_progress)"
16935 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16936 "")
16937
16938 (define_split
16939 [(set (match_operand:XF 0 "register_operand" "")
16940 (unspec:XF [(float_extend:XF
16941 (match_operand:MODEF 2 "register_operand" ""))]
16942 UNSPEC_SINCOS_COS))
16943 (set (match_operand:XF 1 "register_operand" "")
16944 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16945 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16946 && !(reload_completed || reload_in_progress)"
16947 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16948 "")
16949
16950 (define_expand "sincos<mode>3"
16951 [(use (match_operand:MODEF 0 "register_operand" ""))
16952 (use (match_operand:MODEF 1 "register_operand" ""))
16953 (use (match_operand:MODEF 2 "register_operand" ""))]
16954 "TARGET_USE_FANCY_MATH_387
16955 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16956 || TARGET_MIX_SSE_I387)
16957 && flag_unsafe_math_optimizations"
16958 {
16959 rtx op0 = gen_reg_rtx (XFmode);
16960 rtx op1 = gen_reg_rtx (XFmode);
16961
16962 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16963 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16964 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16965 DONE;
16966 })
16967
16968 (define_insn "fptanxf4_i387"
16969 [(set (match_operand:XF 0 "register_operand" "=f")
16970 (match_operand:XF 3 "const_double_operand" "F"))
16971 (set (match_operand:XF 1 "register_operand" "=u")
16972 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16973 UNSPEC_TAN))]
16974 "TARGET_USE_FANCY_MATH_387
16975 && flag_unsafe_math_optimizations
16976 && standard_80387_constant_p (operands[3]) == 2"
16977 "fptan"
16978 [(set_attr "type" "fpspc")
16979 (set_attr "mode" "XF")])
16980
16981 (define_insn "fptan_extend<mode>xf4_i387"
16982 [(set (match_operand:MODEF 0 "register_operand" "=f")
16983 (match_operand:MODEF 3 "const_double_operand" "F"))
16984 (set (match_operand:XF 1 "register_operand" "=u")
16985 (unspec:XF [(float_extend:XF
16986 (match_operand:MODEF 2 "register_operand" "0"))]
16987 UNSPEC_TAN))]
16988 "TARGET_USE_FANCY_MATH_387
16989 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16990 || TARGET_MIX_SSE_I387)
16991 && flag_unsafe_math_optimizations
16992 && standard_80387_constant_p (operands[3]) == 2"
16993 "fptan"
16994 [(set_attr "type" "fpspc")
16995 (set_attr "mode" "XF")])
16996
16997 (define_expand "tanxf2"
16998 [(use (match_operand:XF 0 "register_operand" ""))
16999 (use (match_operand:XF 1 "register_operand" ""))]
17000 "TARGET_USE_FANCY_MATH_387
17001 && flag_unsafe_math_optimizations"
17002 {
17003 rtx one = gen_reg_rtx (XFmode);
17004 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17005
17006 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17007 DONE;
17008 })
17009
17010 (define_expand "tan<mode>2"
17011 [(use (match_operand:MODEF 0 "register_operand" ""))
17012 (use (match_operand:MODEF 1 "register_operand" ""))]
17013 "TARGET_USE_FANCY_MATH_387
17014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17015 || TARGET_MIX_SSE_I387)
17016 && flag_unsafe_math_optimizations"
17017 {
17018 rtx op0 = gen_reg_rtx (XFmode);
17019
17020 rtx one = gen_reg_rtx (<MODE>mode);
17021 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17022
17023 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17024 operands[1], op2));
17025 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17026 DONE;
17027 })
17028
17029 (define_insn "*fpatanxf3_i387"
17030 [(set (match_operand:XF 0 "register_operand" "=f")
17031 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17032 (match_operand:XF 2 "register_operand" "u")]
17033 UNSPEC_FPATAN))
17034 (clobber (match_scratch:XF 3 "=2"))]
17035 "TARGET_USE_FANCY_MATH_387
17036 && flag_unsafe_math_optimizations"
17037 "fpatan"
17038 [(set_attr "type" "fpspc")
17039 (set_attr "mode" "XF")])
17040
17041 (define_insn "fpatan_extend<mode>xf3_i387"
17042 [(set (match_operand:XF 0 "register_operand" "=f")
17043 (unspec:XF [(float_extend:XF
17044 (match_operand:MODEF 1 "register_operand" "0"))
17045 (float_extend:XF
17046 (match_operand:MODEF 2 "register_operand" "u"))]
17047 UNSPEC_FPATAN))
17048 (clobber (match_scratch:XF 3 "=2"))]
17049 "TARGET_USE_FANCY_MATH_387
17050 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17051 || TARGET_MIX_SSE_I387)
17052 && flag_unsafe_math_optimizations"
17053 "fpatan"
17054 [(set_attr "type" "fpspc")
17055 (set_attr "mode" "XF")])
17056
17057 (define_expand "atan2xf3"
17058 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17059 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17060 (match_operand:XF 1 "register_operand" "")]
17061 UNSPEC_FPATAN))
17062 (clobber (match_scratch:XF 3 ""))])]
17063 "TARGET_USE_FANCY_MATH_387
17064 && flag_unsafe_math_optimizations"
17065 "")
17066
17067 (define_expand "atan2<mode>3"
17068 [(use (match_operand:MODEF 0 "register_operand" ""))
17069 (use (match_operand:MODEF 1 "register_operand" ""))
17070 (use (match_operand:MODEF 2 "register_operand" ""))]
17071 "TARGET_USE_FANCY_MATH_387
17072 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17073 || TARGET_MIX_SSE_I387)
17074 && flag_unsafe_math_optimizations"
17075 {
17076 rtx op0 = gen_reg_rtx (XFmode);
17077
17078 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17079 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17080 DONE;
17081 })
17082
17083 (define_expand "atanxf2"
17084 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17085 (unspec:XF [(match_dup 2)
17086 (match_operand:XF 1 "register_operand" "")]
17087 UNSPEC_FPATAN))
17088 (clobber (match_scratch:XF 3 ""))])]
17089 "TARGET_USE_FANCY_MATH_387
17090 && flag_unsafe_math_optimizations"
17091 {
17092 operands[2] = gen_reg_rtx (XFmode);
17093 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17094 })
17095
17096 (define_expand "atan<mode>2"
17097 [(use (match_operand:MODEF 0 "register_operand" ""))
17098 (use (match_operand:MODEF 1 "register_operand" ""))]
17099 "TARGET_USE_FANCY_MATH_387
17100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17101 || TARGET_MIX_SSE_I387)
17102 && flag_unsafe_math_optimizations"
17103 {
17104 rtx op0 = gen_reg_rtx (XFmode);
17105
17106 rtx op2 = gen_reg_rtx (<MODE>mode);
17107 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17108
17109 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17110 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17111 DONE;
17112 })
17113
17114 (define_expand "asinxf2"
17115 [(set (match_dup 2)
17116 (mult:XF (match_operand:XF 1 "register_operand" "")
17117 (match_dup 1)))
17118 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17119 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17120 (parallel [(set (match_operand:XF 0 "register_operand" "")
17121 (unspec:XF [(match_dup 5) (match_dup 1)]
17122 UNSPEC_FPATAN))
17123 (clobber (match_scratch:XF 6 ""))])]
17124 "TARGET_USE_FANCY_MATH_387
17125 && flag_unsafe_math_optimizations && !optimize_size"
17126 {
17127 int i;
17128
17129 for (i = 2; i < 6; i++)
17130 operands[i] = gen_reg_rtx (XFmode);
17131
17132 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17133 })
17134
17135 (define_expand "asin<mode>2"
17136 [(use (match_operand:MODEF 0 "register_operand" ""))
17137 (use (match_operand:MODEF 1 "general_operand" ""))]
17138 "TARGET_USE_FANCY_MATH_387
17139 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17140 || TARGET_MIX_SSE_I387)
17141 && flag_unsafe_math_optimizations && !optimize_size"
17142 {
17143 rtx op0 = gen_reg_rtx (XFmode);
17144 rtx op1 = gen_reg_rtx (XFmode);
17145
17146 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17147 emit_insn (gen_asinxf2 (op0, op1));
17148 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17149 DONE;
17150 })
17151
17152 (define_expand "acosxf2"
17153 [(set (match_dup 2)
17154 (mult:XF (match_operand:XF 1 "register_operand" "")
17155 (match_dup 1)))
17156 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17157 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17158 (parallel [(set (match_operand:XF 0 "register_operand" "")
17159 (unspec:XF [(match_dup 1) (match_dup 5)]
17160 UNSPEC_FPATAN))
17161 (clobber (match_scratch:XF 6 ""))])]
17162 "TARGET_USE_FANCY_MATH_387
17163 && flag_unsafe_math_optimizations && !optimize_size"
17164 {
17165 int i;
17166
17167 for (i = 2; i < 6; i++)
17168 operands[i] = gen_reg_rtx (XFmode);
17169
17170 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17171 })
17172
17173 (define_expand "acos<mode>2"
17174 [(use (match_operand:MODEF 0 "register_operand" ""))
17175 (use (match_operand:MODEF 1 "general_operand" ""))]
17176 "TARGET_USE_FANCY_MATH_387
17177 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17178 || TARGET_MIX_SSE_I387)
17179 && flag_unsafe_math_optimizations && !optimize_size"
17180 {
17181 rtx op0 = gen_reg_rtx (XFmode);
17182 rtx op1 = gen_reg_rtx (XFmode);
17183
17184 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17185 emit_insn (gen_acosxf2 (op0, op1));
17186 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17187 DONE;
17188 })
17189
17190 (define_insn "fyl2xxf3_i387"
17191 [(set (match_operand:XF 0 "register_operand" "=f")
17192 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17193 (match_operand:XF 2 "register_operand" "u")]
17194 UNSPEC_FYL2X))
17195 (clobber (match_scratch:XF 3 "=2"))]
17196 "TARGET_USE_FANCY_MATH_387
17197 && flag_unsafe_math_optimizations"
17198 "fyl2x"
17199 [(set_attr "type" "fpspc")
17200 (set_attr "mode" "XF")])
17201
17202 (define_insn "fyl2x_extend<mode>xf3_i387"
17203 [(set (match_operand:XF 0 "register_operand" "=f")
17204 (unspec:XF [(float_extend:XF
17205 (match_operand:MODEF 1 "register_operand" "0"))
17206 (match_operand:XF 2 "register_operand" "u")]
17207 UNSPEC_FYL2X))
17208 (clobber (match_scratch:XF 3 "=2"))]
17209 "TARGET_USE_FANCY_MATH_387
17210 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17211 || TARGET_MIX_SSE_I387)
17212 && flag_unsafe_math_optimizations"
17213 "fyl2x"
17214 [(set_attr "type" "fpspc")
17215 (set_attr "mode" "XF")])
17216
17217 (define_expand "logxf2"
17218 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17219 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17220 (match_dup 2)] UNSPEC_FYL2X))
17221 (clobber (match_scratch:XF 3 ""))])]
17222 "TARGET_USE_FANCY_MATH_387
17223 && flag_unsafe_math_optimizations"
17224 {
17225 operands[2] = gen_reg_rtx (XFmode);
17226 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17227 })
17228
17229 (define_expand "log<mode>2"
17230 [(use (match_operand:MODEF 0 "register_operand" ""))
17231 (use (match_operand:MODEF 1 "register_operand" ""))]
17232 "TARGET_USE_FANCY_MATH_387
17233 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17234 || TARGET_MIX_SSE_I387)
17235 && flag_unsafe_math_optimizations"
17236 {
17237 rtx op0 = gen_reg_rtx (XFmode);
17238
17239 rtx op2 = gen_reg_rtx (XFmode);
17240 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17241
17242 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17243 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17244 DONE;
17245 })
17246
17247 (define_expand "log10xf2"
17248 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17249 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17250 (match_dup 2)] UNSPEC_FYL2X))
17251 (clobber (match_scratch:XF 3 ""))])]
17252 "TARGET_USE_FANCY_MATH_387
17253 && flag_unsafe_math_optimizations"
17254 {
17255 operands[2] = gen_reg_rtx (XFmode);
17256 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17257 })
17258
17259 (define_expand "log10<mode>2"
17260 [(use (match_operand:MODEF 0 "register_operand" ""))
17261 (use (match_operand:MODEF 1 "register_operand" ""))]
17262 "TARGET_USE_FANCY_MATH_387
17263 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17264 || TARGET_MIX_SSE_I387)
17265 && flag_unsafe_math_optimizations"
17266 {
17267 rtx op0 = gen_reg_rtx (XFmode);
17268
17269 rtx op2 = gen_reg_rtx (XFmode);
17270 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17271
17272 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17273 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17274 DONE;
17275 })
17276
17277 (define_expand "log2xf2"
17278 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17279 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17280 (match_dup 2)] UNSPEC_FYL2X))
17281 (clobber (match_scratch:XF 3 ""))])]
17282 "TARGET_USE_FANCY_MATH_387
17283 && flag_unsafe_math_optimizations"
17284 {
17285 operands[2] = gen_reg_rtx (XFmode);
17286 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17287 })
17288
17289 (define_expand "log2<mode>2"
17290 [(use (match_operand:MODEF 0 "register_operand" ""))
17291 (use (match_operand:MODEF 1 "register_operand" ""))]
17292 "TARGET_USE_FANCY_MATH_387
17293 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17294 || TARGET_MIX_SSE_I387)
17295 && flag_unsafe_math_optimizations"
17296 {
17297 rtx op0 = gen_reg_rtx (XFmode);
17298
17299 rtx op2 = gen_reg_rtx (XFmode);
17300 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17301
17302 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17303 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17304 DONE;
17305 })
17306
17307 (define_insn "fyl2xp1xf3_i387"
17308 [(set (match_operand:XF 0 "register_operand" "=f")
17309 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17310 (match_operand:XF 2 "register_operand" "u")]
17311 UNSPEC_FYL2XP1))
17312 (clobber (match_scratch:XF 3 "=2"))]
17313 "TARGET_USE_FANCY_MATH_387
17314 && flag_unsafe_math_optimizations"
17315 "fyl2xp1"
17316 [(set_attr "type" "fpspc")
17317 (set_attr "mode" "XF")])
17318
17319 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17320 [(set (match_operand:XF 0 "register_operand" "=f")
17321 (unspec:XF [(float_extend:XF
17322 (match_operand:MODEF 1 "register_operand" "0"))
17323 (match_operand:XF 2 "register_operand" "u")]
17324 UNSPEC_FYL2XP1))
17325 (clobber (match_scratch:XF 3 "=2"))]
17326 "TARGET_USE_FANCY_MATH_387
17327 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17328 || TARGET_MIX_SSE_I387)
17329 && flag_unsafe_math_optimizations"
17330 "fyl2xp1"
17331 [(set_attr "type" "fpspc")
17332 (set_attr "mode" "XF")])
17333
17334 (define_expand "log1pxf2"
17335 [(use (match_operand:XF 0 "register_operand" ""))
17336 (use (match_operand:XF 1 "register_operand" ""))]
17337 "TARGET_USE_FANCY_MATH_387
17338 && flag_unsafe_math_optimizations && !optimize_size"
17339 {
17340 ix86_emit_i387_log1p (operands[0], operands[1]);
17341 DONE;
17342 })
17343
17344 (define_expand "log1p<mode>2"
17345 [(use (match_operand:MODEF 0 "register_operand" ""))
17346 (use (match_operand:MODEF 1 "register_operand" ""))]
17347 "TARGET_USE_FANCY_MATH_387
17348 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17349 || TARGET_MIX_SSE_I387)
17350 && flag_unsafe_math_optimizations && !optimize_size"
17351 {
17352 rtx op0 = gen_reg_rtx (XFmode);
17353
17354 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17355
17356 ix86_emit_i387_log1p (op0, operands[1]);
17357 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17358 DONE;
17359 })
17360
17361 (define_insn "fxtractxf3_i387"
17362 [(set (match_operand:XF 0 "register_operand" "=f")
17363 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17364 UNSPEC_XTRACT_FRACT))
17365 (set (match_operand:XF 1 "register_operand" "=u")
17366 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17367 "TARGET_USE_FANCY_MATH_387
17368 && flag_unsafe_math_optimizations"
17369 "fxtract"
17370 [(set_attr "type" "fpspc")
17371 (set_attr "mode" "XF")])
17372
17373 (define_insn "fxtract_extend<mode>xf3_i387"
17374 [(set (match_operand:XF 0 "register_operand" "=f")
17375 (unspec:XF [(float_extend:XF
17376 (match_operand:MODEF 2 "register_operand" "0"))]
17377 UNSPEC_XTRACT_FRACT))
17378 (set (match_operand:XF 1 "register_operand" "=u")
17379 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17380 "TARGET_USE_FANCY_MATH_387
17381 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17382 || TARGET_MIX_SSE_I387)
17383 && flag_unsafe_math_optimizations"
17384 "fxtract"
17385 [(set_attr "type" "fpspc")
17386 (set_attr "mode" "XF")])
17387
17388 (define_expand "logbxf2"
17389 [(parallel [(set (match_dup 2)
17390 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17391 UNSPEC_XTRACT_FRACT))
17392 (set (match_operand:XF 0 "register_operand" "")
17393 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17394 "TARGET_USE_FANCY_MATH_387
17395 && flag_unsafe_math_optimizations"
17396 {
17397 operands[2] = gen_reg_rtx (XFmode);
17398 })
17399
17400 (define_expand "logb<mode>2"
17401 [(use (match_operand:MODEF 0 "register_operand" ""))
17402 (use (match_operand:MODEF 1 "register_operand" ""))]
17403 "TARGET_USE_FANCY_MATH_387
17404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17405 || TARGET_MIX_SSE_I387)
17406 && flag_unsafe_math_optimizations"
17407 {
17408 rtx op0 = gen_reg_rtx (XFmode);
17409 rtx op1 = gen_reg_rtx (XFmode);
17410
17411 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17412 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17413 DONE;
17414 })
17415
17416 (define_expand "ilogbxf2"
17417 [(use (match_operand:SI 0 "register_operand" ""))
17418 (use (match_operand:XF 1 "register_operand" ""))]
17419 "TARGET_USE_FANCY_MATH_387
17420 && flag_unsafe_math_optimizations && !optimize_size"
17421 {
17422 rtx op0 = gen_reg_rtx (XFmode);
17423 rtx op1 = gen_reg_rtx (XFmode);
17424
17425 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17426 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17427 DONE;
17428 })
17429
17430 (define_expand "ilogb<mode>2"
17431 [(use (match_operand:SI 0 "register_operand" ""))
17432 (use (match_operand:MODEF 1 "register_operand" ""))]
17433 "TARGET_USE_FANCY_MATH_387
17434 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17435 || TARGET_MIX_SSE_I387)
17436 && flag_unsafe_math_optimizations && !optimize_size"
17437 {
17438 rtx op0 = gen_reg_rtx (XFmode);
17439 rtx op1 = gen_reg_rtx (XFmode);
17440
17441 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17442 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17443 DONE;
17444 })
17445
17446 (define_insn "*f2xm1xf2_i387"
17447 [(set (match_operand:XF 0 "register_operand" "=f")
17448 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17449 UNSPEC_F2XM1))]
17450 "TARGET_USE_FANCY_MATH_387
17451 && flag_unsafe_math_optimizations"
17452 "f2xm1"
17453 [(set_attr "type" "fpspc")
17454 (set_attr "mode" "XF")])
17455
17456 (define_insn "*fscalexf4_i387"
17457 [(set (match_operand:XF 0 "register_operand" "=f")
17458 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17459 (match_operand:XF 3 "register_operand" "1")]
17460 UNSPEC_FSCALE_FRACT))
17461 (set (match_operand:XF 1 "register_operand" "=u")
17462 (unspec:XF [(match_dup 2) (match_dup 3)]
17463 UNSPEC_FSCALE_EXP))]
17464 "TARGET_USE_FANCY_MATH_387
17465 && flag_unsafe_math_optimizations"
17466 "fscale"
17467 [(set_attr "type" "fpspc")
17468 (set_attr "mode" "XF")])
17469
17470 (define_expand "expNcorexf3"
17471 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17472 (match_operand:XF 2 "register_operand" "")))
17473 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17474 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17475 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17476 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17477 (parallel [(set (match_operand:XF 0 "register_operand" "")
17478 (unspec:XF [(match_dup 8) (match_dup 4)]
17479 UNSPEC_FSCALE_FRACT))
17480 (set (match_dup 9)
17481 (unspec:XF [(match_dup 8) (match_dup 4)]
17482 UNSPEC_FSCALE_EXP))])]
17483 "TARGET_USE_FANCY_MATH_387
17484 && flag_unsafe_math_optimizations && !optimize_size"
17485 {
17486 int i;
17487
17488 for (i = 3; i < 10; i++)
17489 operands[i] = gen_reg_rtx (XFmode);
17490
17491 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17492 })
17493
17494 (define_expand "expxf2"
17495 [(use (match_operand:XF 0 "register_operand" ""))
17496 (use (match_operand:XF 1 "register_operand" ""))]
17497 "TARGET_USE_FANCY_MATH_387
17498 && flag_unsafe_math_optimizations && !optimize_size"
17499 {
17500 rtx op2 = gen_reg_rtx (XFmode);
17501 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17502
17503 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17504 DONE;
17505 })
17506
17507 (define_expand "exp<mode>2"
17508 [(use (match_operand:MODEF 0 "register_operand" ""))
17509 (use (match_operand:MODEF 1 "general_operand" ""))]
17510 "TARGET_USE_FANCY_MATH_387
17511 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17512 || TARGET_MIX_SSE_I387)
17513 && flag_unsafe_math_optimizations && !optimize_size"
17514 {
17515 rtx op0 = gen_reg_rtx (XFmode);
17516 rtx op1 = gen_reg_rtx (XFmode);
17517
17518 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17519 emit_insn (gen_expxf2 (op0, op1));
17520 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17521 DONE;
17522 })
17523
17524 (define_expand "exp10xf2"
17525 [(use (match_operand:XF 0 "register_operand" ""))
17526 (use (match_operand:XF 1 "register_operand" ""))]
17527 "TARGET_USE_FANCY_MATH_387
17528 && flag_unsafe_math_optimizations && !optimize_size"
17529 {
17530 rtx op2 = gen_reg_rtx (XFmode);
17531 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17532
17533 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17534 DONE;
17535 })
17536
17537 (define_expand "exp10<mode>2"
17538 [(use (match_operand:MODEF 0 "register_operand" ""))
17539 (use (match_operand:MODEF 1 "general_operand" ""))]
17540 "TARGET_USE_FANCY_MATH_387
17541 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17542 || TARGET_MIX_SSE_I387)
17543 && flag_unsafe_math_optimizations && !optimize_size"
17544 {
17545 rtx op0 = gen_reg_rtx (XFmode);
17546 rtx op1 = gen_reg_rtx (XFmode);
17547
17548 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17549 emit_insn (gen_exp10xf2 (op0, op1));
17550 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17551 DONE;
17552 })
17553
17554 (define_expand "exp2xf2"
17555 [(use (match_operand:XF 0 "register_operand" ""))
17556 (use (match_operand:XF 1 "register_operand" ""))]
17557 "TARGET_USE_FANCY_MATH_387
17558 && flag_unsafe_math_optimizations && !optimize_size"
17559 {
17560 rtx op2 = gen_reg_rtx (XFmode);
17561 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17562
17563 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17564 DONE;
17565 })
17566
17567 (define_expand "exp2<mode>2"
17568 [(use (match_operand:MODEF 0 "register_operand" ""))
17569 (use (match_operand:MODEF 1 "general_operand" ""))]
17570 "TARGET_USE_FANCY_MATH_387
17571 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17572 || TARGET_MIX_SSE_I387)
17573 && flag_unsafe_math_optimizations && !optimize_size"
17574 {
17575 rtx op0 = gen_reg_rtx (XFmode);
17576 rtx op1 = gen_reg_rtx (XFmode);
17577
17578 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17579 emit_insn (gen_exp2xf2 (op0, op1));
17580 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17581 DONE;
17582 })
17583
17584 (define_expand "expm1xf2"
17585 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17586 (match_dup 2)))
17587 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17588 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17589 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17590 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17591 (parallel [(set (match_dup 7)
17592 (unspec:XF [(match_dup 6) (match_dup 4)]
17593 UNSPEC_FSCALE_FRACT))
17594 (set (match_dup 8)
17595 (unspec:XF [(match_dup 6) (match_dup 4)]
17596 UNSPEC_FSCALE_EXP))])
17597 (parallel [(set (match_dup 10)
17598 (unspec:XF [(match_dup 9) (match_dup 8)]
17599 UNSPEC_FSCALE_FRACT))
17600 (set (match_dup 11)
17601 (unspec:XF [(match_dup 9) (match_dup 8)]
17602 UNSPEC_FSCALE_EXP))])
17603 (set (match_dup 12) (minus:XF (match_dup 10)
17604 (float_extend:XF (match_dup 13))))
17605 (set (match_operand:XF 0 "register_operand" "")
17606 (plus:XF (match_dup 12) (match_dup 7)))]
17607 "TARGET_USE_FANCY_MATH_387
17608 && flag_unsafe_math_optimizations && !optimize_size"
17609 {
17610 int i;
17611
17612 for (i = 2; i < 13; i++)
17613 operands[i] = gen_reg_rtx (XFmode);
17614
17615 operands[13]
17616 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17617
17618 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17619 })
17620
17621 (define_expand "expm1<mode>2"
17622 [(use (match_operand:MODEF 0 "register_operand" ""))
17623 (use (match_operand:MODEF 1 "general_operand" ""))]
17624 "TARGET_USE_FANCY_MATH_387
17625 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17626 || TARGET_MIX_SSE_I387)
17627 && flag_unsafe_math_optimizations && !optimize_size"
17628 {
17629 rtx op0 = gen_reg_rtx (XFmode);
17630 rtx op1 = gen_reg_rtx (XFmode);
17631
17632 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17633 emit_insn (gen_expm1xf2 (op0, op1));
17634 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17635 DONE;
17636 })
17637
17638 (define_expand "ldexpxf3"
17639 [(set (match_dup 3)
17640 (float:XF (match_operand:SI 2 "register_operand" "")))
17641 (parallel [(set (match_operand:XF 0 " register_operand" "")
17642 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17643 (match_dup 3)]
17644 UNSPEC_FSCALE_FRACT))
17645 (set (match_dup 4)
17646 (unspec:XF [(match_dup 1) (match_dup 3)]
17647 UNSPEC_FSCALE_EXP))])]
17648 "TARGET_USE_FANCY_MATH_387
17649 && flag_unsafe_math_optimizations && !optimize_size"
17650 {
17651 operands[3] = gen_reg_rtx (XFmode);
17652 operands[4] = gen_reg_rtx (XFmode);
17653 })
17654
17655 (define_expand "ldexp<mode>3"
17656 [(use (match_operand:MODEF 0 "register_operand" ""))
17657 (use (match_operand:MODEF 1 "general_operand" ""))
17658 (use (match_operand:SI 2 "register_operand" ""))]
17659 "TARGET_USE_FANCY_MATH_387
17660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17661 || TARGET_MIX_SSE_I387)
17662 && flag_unsafe_math_optimizations && !optimize_size"
17663 {
17664 rtx op0 = gen_reg_rtx (XFmode);
17665 rtx op1 = gen_reg_rtx (XFmode);
17666
17667 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17668 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17669 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17670 DONE;
17671 })
17672
17673 (define_expand "scalbxf3"
17674 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17675 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17676 (match_operand:XF 2 "register_operand" "")]
17677 UNSPEC_FSCALE_FRACT))
17678 (set (match_dup 3)
17679 (unspec:XF [(match_dup 1) (match_dup 2)]
17680 UNSPEC_FSCALE_EXP))])]
17681 "TARGET_USE_FANCY_MATH_387
17682 && flag_unsafe_math_optimizations && !optimize_size"
17683 {
17684 operands[3] = gen_reg_rtx (XFmode);
17685 })
17686
17687 (define_expand "scalb<mode>3"
17688 [(use (match_operand:MODEF 0 "register_operand" ""))
17689 (use (match_operand:MODEF 1 "general_operand" ""))
17690 (use (match_operand:MODEF 2 "register_operand" ""))]
17691 "TARGET_USE_FANCY_MATH_387
17692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17693 || TARGET_MIX_SSE_I387)
17694 && flag_unsafe_math_optimizations && !optimize_size"
17695 {
17696 rtx op0 = gen_reg_rtx (XFmode);
17697 rtx op1 = gen_reg_rtx (XFmode);
17698 rtx op2 = gen_reg_rtx (XFmode);
17699
17700 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17701 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17702 emit_insn (gen_scalbxf3 (op0, op1, op2));
17703 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17704 DONE;
17705 })
17706 \f
17707
17708 (define_insn "sse4_1_round<mode>2"
17709 [(set (match_operand:MODEF 0 "register_operand" "=x")
17710 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17711 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17712 UNSPEC_ROUND))]
17713 "TARGET_ROUND"
17714 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17715 [(set_attr "type" "ssecvt")
17716 (set_attr "prefix_extra" "1")
17717 (set_attr "mode" "<MODE>")])
17718
17719 (define_insn "rintxf2"
17720 [(set (match_operand:XF 0 "register_operand" "=f")
17721 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17722 UNSPEC_FRNDINT))]
17723 "TARGET_USE_FANCY_MATH_387
17724 && flag_unsafe_math_optimizations"
17725 "frndint"
17726 [(set_attr "type" "fpspc")
17727 (set_attr "mode" "XF")])
17728
17729 (define_expand "rint<mode>2"
17730 [(use (match_operand:MODEF 0 "register_operand" ""))
17731 (use (match_operand:MODEF 1 "register_operand" ""))]
17732 "(TARGET_USE_FANCY_MATH_387
17733 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17734 || TARGET_MIX_SSE_I387)
17735 && flag_unsafe_math_optimizations)
17736 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17737 && !flag_trapping_math
17738 && (TARGET_ROUND || !optimize_size))"
17739 {
17740 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17741 && !flag_trapping_math
17742 && (TARGET_ROUND || !optimize_size))
17743 {
17744 if (TARGET_ROUND)
17745 emit_insn (gen_sse4_1_round<mode>2
17746 (operands[0], operands[1], GEN_INT (0x04)));
17747 else
17748 ix86_expand_rint (operand0, operand1);
17749 }
17750 else
17751 {
17752 rtx op0 = gen_reg_rtx (XFmode);
17753 rtx op1 = gen_reg_rtx (XFmode);
17754
17755 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17756 emit_insn (gen_rintxf2 (op0, op1));
17757
17758 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17759 }
17760 DONE;
17761 })
17762
17763 (define_expand "round<mode>2"
17764 [(match_operand:MODEF 0 "register_operand" "")
17765 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17766 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17767 && !flag_trapping_math && !flag_rounding_math
17768 && !optimize_size"
17769 {
17770 if (TARGET_64BIT || (<MODE>mode != DFmode))
17771 ix86_expand_round (operand0, operand1);
17772 else
17773 ix86_expand_rounddf_32 (operand0, operand1);
17774 DONE;
17775 })
17776
17777 (define_insn_and_split "*fistdi2_1"
17778 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17779 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17780 UNSPEC_FIST))]
17781 "TARGET_USE_FANCY_MATH_387
17782 && !(reload_completed || reload_in_progress)"
17783 "#"
17784 "&& 1"
17785 [(const_int 0)]
17786 {
17787 if (memory_operand (operands[0], VOIDmode))
17788 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17789 else
17790 {
17791 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17792 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17793 operands[2]));
17794 }
17795 DONE;
17796 }
17797 [(set_attr "type" "fpspc")
17798 (set_attr "mode" "DI")])
17799
17800 (define_insn "fistdi2"
17801 [(set (match_operand:DI 0 "memory_operand" "=m")
17802 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17803 UNSPEC_FIST))
17804 (clobber (match_scratch:XF 2 "=&1f"))]
17805 "TARGET_USE_FANCY_MATH_387"
17806 "* return output_fix_trunc (insn, operands, 0);"
17807 [(set_attr "type" "fpspc")
17808 (set_attr "mode" "DI")])
17809
17810 (define_insn "fistdi2_with_temp"
17811 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17812 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17813 UNSPEC_FIST))
17814 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17815 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17816 "TARGET_USE_FANCY_MATH_387"
17817 "#"
17818 [(set_attr "type" "fpspc")
17819 (set_attr "mode" "DI")])
17820
17821 (define_split
17822 [(set (match_operand:DI 0 "register_operand" "")
17823 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17824 UNSPEC_FIST))
17825 (clobber (match_operand:DI 2 "memory_operand" ""))
17826 (clobber (match_scratch 3 ""))]
17827 "reload_completed"
17828 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17829 (clobber (match_dup 3))])
17830 (set (match_dup 0) (match_dup 2))]
17831 "")
17832
17833 (define_split
17834 [(set (match_operand:DI 0 "memory_operand" "")
17835 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17836 UNSPEC_FIST))
17837 (clobber (match_operand:DI 2 "memory_operand" ""))
17838 (clobber (match_scratch 3 ""))]
17839 "reload_completed"
17840 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17841 (clobber (match_dup 3))])]
17842 "")
17843
17844 (define_insn_and_split "*fist<mode>2_1"
17845 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17846 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17847 UNSPEC_FIST))]
17848 "TARGET_USE_FANCY_MATH_387
17849 && !(reload_completed || reload_in_progress)"
17850 "#"
17851 "&& 1"
17852 [(const_int 0)]
17853 {
17854 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17855 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17856 operands[2]));
17857 DONE;
17858 }
17859 [(set_attr "type" "fpspc")
17860 (set_attr "mode" "<MODE>")])
17861
17862 (define_insn "fist<mode>2"
17863 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17864 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17865 UNSPEC_FIST))]
17866 "TARGET_USE_FANCY_MATH_387"
17867 "* return output_fix_trunc (insn, operands, 0);"
17868 [(set_attr "type" "fpspc")
17869 (set_attr "mode" "<MODE>")])
17870
17871 (define_insn "fist<mode>2_with_temp"
17872 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17873 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17874 UNSPEC_FIST))
17875 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17876 "TARGET_USE_FANCY_MATH_387"
17877 "#"
17878 [(set_attr "type" "fpspc")
17879 (set_attr "mode" "<MODE>")])
17880
17881 (define_split
17882 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17883 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17884 UNSPEC_FIST))
17885 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17886 "reload_completed"
17887 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17888 (set (match_dup 0) (match_dup 2))]
17889 "")
17890
17891 (define_split
17892 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17893 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17894 UNSPEC_FIST))
17895 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17896 "reload_completed"
17897 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17898 "")
17899
17900 (define_expand "lrintxf<mode>2"
17901 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17902 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17903 UNSPEC_FIST))]
17904 "TARGET_USE_FANCY_MATH_387"
17905 "")
17906
17907 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17908 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17909 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17910 UNSPEC_FIX_NOTRUNC))]
17911 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17912 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17913 "")
17914
17915 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17916 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17917 (match_operand:MODEF 1 "register_operand" "")]
17918 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17919 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17920 && !flag_trapping_math && !flag_rounding_math
17921 && !optimize_size"
17922 {
17923 ix86_expand_lround (operand0, operand1);
17924 DONE;
17925 })
17926
17927 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17928 (define_insn_and_split "frndintxf2_floor"
17929 [(set (match_operand:XF 0 "register_operand" "")
17930 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17931 UNSPEC_FRNDINT_FLOOR))
17932 (clobber (reg:CC FLAGS_REG))]
17933 "TARGET_USE_FANCY_MATH_387
17934 && flag_unsafe_math_optimizations
17935 && !(reload_completed || reload_in_progress)"
17936 "#"
17937 "&& 1"
17938 [(const_int 0)]
17939 {
17940 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17941
17942 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17943 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17944
17945 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17946 operands[2], operands[3]));
17947 DONE;
17948 }
17949 [(set_attr "type" "frndint")
17950 (set_attr "i387_cw" "floor")
17951 (set_attr "mode" "XF")])
17952
17953 (define_insn "frndintxf2_floor_i387"
17954 [(set (match_operand:XF 0 "register_operand" "=f")
17955 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17956 UNSPEC_FRNDINT_FLOOR))
17957 (use (match_operand:HI 2 "memory_operand" "m"))
17958 (use (match_operand:HI 3 "memory_operand" "m"))]
17959 "TARGET_USE_FANCY_MATH_387
17960 && flag_unsafe_math_optimizations"
17961 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17962 [(set_attr "type" "frndint")
17963 (set_attr "i387_cw" "floor")
17964 (set_attr "mode" "XF")])
17965
17966 (define_expand "floorxf2"
17967 [(use (match_operand:XF 0 "register_operand" ""))
17968 (use (match_operand:XF 1 "register_operand" ""))]
17969 "TARGET_USE_FANCY_MATH_387
17970 && flag_unsafe_math_optimizations && !optimize_size"
17971 {
17972 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17973 DONE;
17974 })
17975
17976 (define_expand "floor<mode>2"
17977 [(use (match_operand:MODEF 0 "register_operand" ""))
17978 (use (match_operand:MODEF 1 "register_operand" ""))]
17979 "(TARGET_USE_FANCY_MATH_387
17980 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17981 || TARGET_MIX_SSE_I387)
17982 && flag_unsafe_math_optimizations && !optimize_size)
17983 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17984 && !flag_trapping_math
17985 && (TARGET_ROUND || !optimize_size))"
17986 {
17987 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17988 && !flag_trapping_math
17989 && (TARGET_ROUND || !optimize_size))
17990 {
17991 if (TARGET_ROUND)
17992 emit_insn (gen_sse4_1_round<mode>2
17993 (operands[0], operands[1], GEN_INT (0x01)));
17994 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17995 ix86_expand_floorceil (operand0, operand1, true);
17996 else
17997 ix86_expand_floorceildf_32 (operand0, operand1, true);
17998 }
17999 else
18000 {
18001 rtx op0 = gen_reg_rtx (XFmode);
18002 rtx op1 = gen_reg_rtx (XFmode);
18003
18004 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18005 emit_insn (gen_frndintxf2_floor (op0, op1));
18006
18007 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18008 }
18009 DONE;
18010 })
18011
18012 (define_insn_and_split "*fist<mode>2_floor_1"
18013 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18014 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18015 UNSPEC_FIST_FLOOR))
18016 (clobber (reg:CC FLAGS_REG))]
18017 "TARGET_USE_FANCY_MATH_387
18018 && flag_unsafe_math_optimizations
18019 && !(reload_completed || reload_in_progress)"
18020 "#"
18021 "&& 1"
18022 [(const_int 0)]
18023 {
18024 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18025
18026 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18027 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18028 if (memory_operand (operands[0], VOIDmode))
18029 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18030 operands[2], operands[3]));
18031 else
18032 {
18033 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18034 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18035 operands[2], operands[3],
18036 operands[4]));
18037 }
18038 DONE;
18039 }
18040 [(set_attr "type" "fistp")
18041 (set_attr "i387_cw" "floor")
18042 (set_attr "mode" "<MODE>")])
18043
18044 (define_insn "fistdi2_floor"
18045 [(set (match_operand:DI 0 "memory_operand" "=m")
18046 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18047 UNSPEC_FIST_FLOOR))
18048 (use (match_operand:HI 2 "memory_operand" "m"))
18049 (use (match_operand:HI 3 "memory_operand" "m"))
18050 (clobber (match_scratch:XF 4 "=&1f"))]
18051 "TARGET_USE_FANCY_MATH_387
18052 && flag_unsafe_math_optimizations"
18053 "* return output_fix_trunc (insn, operands, 0);"
18054 [(set_attr "type" "fistp")
18055 (set_attr "i387_cw" "floor")
18056 (set_attr "mode" "DI")])
18057
18058 (define_insn "fistdi2_floor_with_temp"
18059 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18060 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18061 UNSPEC_FIST_FLOOR))
18062 (use (match_operand:HI 2 "memory_operand" "m,m"))
18063 (use (match_operand:HI 3 "memory_operand" "m,m"))
18064 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18065 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18066 "TARGET_USE_FANCY_MATH_387
18067 && flag_unsafe_math_optimizations"
18068 "#"
18069 [(set_attr "type" "fistp")
18070 (set_attr "i387_cw" "floor")
18071 (set_attr "mode" "DI")])
18072
18073 (define_split
18074 [(set (match_operand:DI 0 "register_operand" "")
18075 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18076 UNSPEC_FIST_FLOOR))
18077 (use (match_operand:HI 2 "memory_operand" ""))
18078 (use (match_operand:HI 3 "memory_operand" ""))
18079 (clobber (match_operand:DI 4 "memory_operand" ""))
18080 (clobber (match_scratch 5 ""))]
18081 "reload_completed"
18082 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18083 (use (match_dup 2))
18084 (use (match_dup 3))
18085 (clobber (match_dup 5))])
18086 (set (match_dup 0) (match_dup 4))]
18087 "")
18088
18089 (define_split
18090 [(set (match_operand:DI 0 "memory_operand" "")
18091 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18092 UNSPEC_FIST_FLOOR))
18093 (use (match_operand:HI 2 "memory_operand" ""))
18094 (use (match_operand:HI 3 "memory_operand" ""))
18095 (clobber (match_operand:DI 4 "memory_operand" ""))
18096 (clobber (match_scratch 5 ""))]
18097 "reload_completed"
18098 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18099 (use (match_dup 2))
18100 (use (match_dup 3))
18101 (clobber (match_dup 5))])]
18102 "")
18103
18104 (define_insn "fist<mode>2_floor"
18105 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18106 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18107 UNSPEC_FIST_FLOOR))
18108 (use (match_operand:HI 2 "memory_operand" "m"))
18109 (use (match_operand:HI 3 "memory_operand" "m"))]
18110 "TARGET_USE_FANCY_MATH_387
18111 && flag_unsafe_math_optimizations"
18112 "* return output_fix_trunc (insn, operands, 0);"
18113 [(set_attr "type" "fistp")
18114 (set_attr "i387_cw" "floor")
18115 (set_attr "mode" "<MODE>")])
18116
18117 (define_insn "fist<mode>2_floor_with_temp"
18118 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18119 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18120 UNSPEC_FIST_FLOOR))
18121 (use (match_operand:HI 2 "memory_operand" "m,m"))
18122 (use (match_operand:HI 3 "memory_operand" "m,m"))
18123 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18124 "TARGET_USE_FANCY_MATH_387
18125 && flag_unsafe_math_optimizations"
18126 "#"
18127 [(set_attr "type" "fistp")
18128 (set_attr "i387_cw" "floor")
18129 (set_attr "mode" "<MODE>")])
18130
18131 (define_split
18132 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18133 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18134 UNSPEC_FIST_FLOOR))
18135 (use (match_operand:HI 2 "memory_operand" ""))
18136 (use (match_operand:HI 3 "memory_operand" ""))
18137 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18138 "reload_completed"
18139 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18140 UNSPEC_FIST_FLOOR))
18141 (use (match_dup 2))
18142 (use (match_dup 3))])
18143 (set (match_dup 0) (match_dup 4))]
18144 "")
18145
18146 (define_split
18147 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18148 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18149 UNSPEC_FIST_FLOOR))
18150 (use (match_operand:HI 2 "memory_operand" ""))
18151 (use (match_operand:HI 3 "memory_operand" ""))
18152 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18153 "reload_completed"
18154 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18155 UNSPEC_FIST_FLOOR))
18156 (use (match_dup 2))
18157 (use (match_dup 3))])]
18158 "")
18159
18160 (define_expand "lfloorxf<mode>2"
18161 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18162 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18163 UNSPEC_FIST_FLOOR))
18164 (clobber (reg:CC FLAGS_REG))])]
18165 "TARGET_USE_FANCY_MATH_387
18166 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18167 && flag_unsafe_math_optimizations"
18168 "")
18169
18170 (define_expand "lfloor<mode>di2"
18171 [(match_operand:DI 0 "nonimmediate_operand" "")
18172 (match_operand:MODEF 1 "register_operand" "")]
18173 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18174 && !flag_trapping_math
18175 && !optimize_size"
18176 {
18177 ix86_expand_lfloorceil (operand0, operand1, true);
18178 DONE;
18179 })
18180
18181 (define_expand "lfloor<mode>si2"
18182 [(match_operand:SI 0 "nonimmediate_operand" "")
18183 (match_operand:MODEF 1 "register_operand" "")]
18184 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18185 && !flag_trapping_math
18186 && (!optimize_size || !TARGET_64BIT)"
18187 {
18188 ix86_expand_lfloorceil (operand0, operand1, true);
18189 DONE;
18190 })
18191
18192 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18193 (define_insn_and_split "frndintxf2_ceil"
18194 [(set (match_operand:XF 0 "register_operand" "")
18195 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18196 UNSPEC_FRNDINT_CEIL))
18197 (clobber (reg:CC FLAGS_REG))]
18198 "TARGET_USE_FANCY_MATH_387
18199 && flag_unsafe_math_optimizations
18200 && !(reload_completed || reload_in_progress)"
18201 "#"
18202 "&& 1"
18203 [(const_int 0)]
18204 {
18205 ix86_optimize_mode_switching[I387_CEIL] = 1;
18206
18207 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18208 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18209
18210 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18211 operands[2], operands[3]));
18212 DONE;
18213 }
18214 [(set_attr "type" "frndint")
18215 (set_attr "i387_cw" "ceil")
18216 (set_attr "mode" "XF")])
18217
18218 (define_insn "frndintxf2_ceil_i387"
18219 [(set (match_operand:XF 0 "register_operand" "=f")
18220 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18221 UNSPEC_FRNDINT_CEIL))
18222 (use (match_operand:HI 2 "memory_operand" "m"))
18223 (use (match_operand:HI 3 "memory_operand" "m"))]
18224 "TARGET_USE_FANCY_MATH_387
18225 && flag_unsafe_math_optimizations"
18226 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18227 [(set_attr "type" "frndint")
18228 (set_attr "i387_cw" "ceil")
18229 (set_attr "mode" "XF")])
18230
18231 (define_expand "ceilxf2"
18232 [(use (match_operand:XF 0 "register_operand" ""))
18233 (use (match_operand:XF 1 "register_operand" ""))]
18234 "TARGET_USE_FANCY_MATH_387
18235 && flag_unsafe_math_optimizations && !optimize_size"
18236 {
18237 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18238 DONE;
18239 })
18240
18241 (define_expand "ceil<mode>2"
18242 [(use (match_operand:MODEF 0 "register_operand" ""))
18243 (use (match_operand:MODEF 1 "register_operand" ""))]
18244 "(TARGET_USE_FANCY_MATH_387
18245 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18246 || TARGET_MIX_SSE_I387)
18247 && flag_unsafe_math_optimizations && !optimize_size)
18248 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18249 && !flag_trapping_math
18250 && (TARGET_ROUND || !optimize_size))"
18251 {
18252 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18253 && !flag_trapping_math
18254 && (TARGET_ROUND || !optimize_size))
18255 {
18256 if (TARGET_ROUND)
18257 emit_insn (gen_sse4_1_round<mode>2
18258 (operands[0], operands[1], GEN_INT (0x02)));
18259 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18260 ix86_expand_floorceil (operand0, operand1, false);
18261 else
18262 ix86_expand_floorceildf_32 (operand0, operand1, false);
18263 }
18264 else
18265 {
18266 rtx op0 = gen_reg_rtx (XFmode);
18267 rtx op1 = gen_reg_rtx (XFmode);
18268
18269 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18270 emit_insn (gen_frndintxf2_ceil (op0, op1));
18271
18272 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18273 }
18274 DONE;
18275 })
18276
18277 (define_insn_and_split "*fist<mode>2_ceil_1"
18278 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18279 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18280 UNSPEC_FIST_CEIL))
18281 (clobber (reg:CC FLAGS_REG))]
18282 "TARGET_USE_FANCY_MATH_387
18283 && flag_unsafe_math_optimizations
18284 && !(reload_completed || reload_in_progress)"
18285 "#"
18286 "&& 1"
18287 [(const_int 0)]
18288 {
18289 ix86_optimize_mode_switching[I387_CEIL] = 1;
18290
18291 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18292 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18293 if (memory_operand (operands[0], VOIDmode))
18294 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18295 operands[2], operands[3]));
18296 else
18297 {
18298 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18299 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18300 operands[2], operands[3],
18301 operands[4]));
18302 }
18303 DONE;
18304 }
18305 [(set_attr "type" "fistp")
18306 (set_attr "i387_cw" "ceil")
18307 (set_attr "mode" "<MODE>")])
18308
18309 (define_insn "fistdi2_ceil"
18310 [(set (match_operand:DI 0 "memory_operand" "=m")
18311 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18312 UNSPEC_FIST_CEIL))
18313 (use (match_operand:HI 2 "memory_operand" "m"))
18314 (use (match_operand:HI 3 "memory_operand" "m"))
18315 (clobber (match_scratch:XF 4 "=&1f"))]
18316 "TARGET_USE_FANCY_MATH_387
18317 && flag_unsafe_math_optimizations"
18318 "* return output_fix_trunc (insn, operands, 0);"
18319 [(set_attr "type" "fistp")
18320 (set_attr "i387_cw" "ceil")
18321 (set_attr "mode" "DI")])
18322
18323 (define_insn "fistdi2_ceil_with_temp"
18324 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18325 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18326 UNSPEC_FIST_CEIL))
18327 (use (match_operand:HI 2 "memory_operand" "m,m"))
18328 (use (match_operand:HI 3 "memory_operand" "m,m"))
18329 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18330 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18331 "TARGET_USE_FANCY_MATH_387
18332 && flag_unsafe_math_optimizations"
18333 "#"
18334 [(set_attr "type" "fistp")
18335 (set_attr "i387_cw" "ceil")
18336 (set_attr "mode" "DI")])
18337
18338 (define_split
18339 [(set (match_operand:DI 0 "register_operand" "")
18340 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18341 UNSPEC_FIST_CEIL))
18342 (use (match_operand:HI 2 "memory_operand" ""))
18343 (use (match_operand:HI 3 "memory_operand" ""))
18344 (clobber (match_operand:DI 4 "memory_operand" ""))
18345 (clobber (match_scratch 5 ""))]
18346 "reload_completed"
18347 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18348 (use (match_dup 2))
18349 (use (match_dup 3))
18350 (clobber (match_dup 5))])
18351 (set (match_dup 0) (match_dup 4))]
18352 "")
18353
18354 (define_split
18355 [(set (match_operand:DI 0 "memory_operand" "")
18356 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18357 UNSPEC_FIST_CEIL))
18358 (use (match_operand:HI 2 "memory_operand" ""))
18359 (use (match_operand:HI 3 "memory_operand" ""))
18360 (clobber (match_operand:DI 4 "memory_operand" ""))
18361 (clobber (match_scratch 5 ""))]
18362 "reload_completed"
18363 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18364 (use (match_dup 2))
18365 (use (match_dup 3))
18366 (clobber (match_dup 5))])]
18367 "")
18368
18369 (define_insn "fist<mode>2_ceil"
18370 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18371 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18372 UNSPEC_FIST_CEIL))
18373 (use (match_operand:HI 2 "memory_operand" "m"))
18374 (use (match_operand:HI 3 "memory_operand" "m"))]
18375 "TARGET_USE_FANCY_MATH_387
18376 && flag_unsafe_math_optimizations"
18377 "* return output_fix_trunc (insn, operands, 0);"
18378 [(set_attr "type" "fistp")
18379 (set_attr "i387_cw" "ceil")
18380 (set_attr "mode" "<MODE>")])
18381
18382 (define_insn "fist<mode>2_ceil_with_temp"
18383 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18384 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18385 UNSPEC_FIST_CEIL))
18386 (use (match_operand:HI 2 "memory_operand" "m,m"))
18387 (use (match_operand:HI 3 "memory_operand" "m,m"))
18388 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18389 "TARGET_USE_FANCY_MATH_387
18390 && flag_unsafe_math_optimizations"
18391 "#"
18392 [(set_attr "type" "fistp")
18393 (set_attr "i387_cw" "ceil")
18394 (set_attr "mode" "<MODE>")])
18395
18396 (define_split
18397 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18398 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18399 UNSPEC_FIST_CEIL))
18400 (use (match_operand:HI 2 "memory_operand" ""))
18401 (use (match_operand:HI 3 "memory_operand" ""))
18402 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18403 "reload_completed"
18404 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18405 UNSPEC_FIST_CEIL))
18406 (use (match_dup 2))
18407 (use (match_dup 3))])
18408 (set (match_dup 0) (match_dup 4))]
18409 "")
18410
18411 (define_split
18412 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18413 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18414 UNSPEC_FIST_CEIL))
18415 (use (match_operand:HI 2 "memory_operand" ""))
18416 (use (match_operand:HI 3 "memory_operand" ""))
18417 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18418 "reload_completed"
18419 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18420 UNSPEC_FIST_CEIL))
18421 (use (match_dup 2))
18422 (use (match_dup 3))])]
18423 "")
18424
18425 (define_expand "lceilxf<mode>2"
18426 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18427 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18428 UNSPEC_FIST_CEIL))
18429 (clobber (reg:CC FLAGS_REG))])]
18430 "TARGET_USE_FANCY_MATH_387
18431 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18432 && flag_unsafe_math_optimizations"
18433 "")
18434
18435 (define_expand "lceil<mode>di2"
18436 [(match_operand:DI 0 "nonimmediate_operand" "")
18437 (match_operand:MODEF 1 "register_operand" "")]
18438 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18439 && !flag_trapping_math"
18440 {
18441 ix86_expand_lfloorceil (operand0, operand1, false);
18442 DONE;
18443 })
18444
18445 (define_expand "lceil<mode>si2"
18446 [(match_operand:SI 0 "nonimmediate_operand" "")
18447 (match_operand:MODEF 1 "register_operand" "")]
18448 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18449 && !flag_trapping_math"
18450 {
18451 ix86_expand_lfloorceil (operand0, operand1, false);
18452 DONE;
18453 })
18454
18455 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18456 (define_insn_and_split "frndintxf2_trunc"
18457 [(set (match_operand:XF 0 "register_operand" "")
18458 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18459 UNSPEC_FRNDINT_TRUNC))
18460 (clobber (reg:CC FLAGS_REG))]
18461 "TARGET_USE_FANCY_MATH_387
18462 && flag_unsafe_math_optimizations
18463 && !(reload_completed || reload_in_progress)"
18464 "#"
18465 "&& 1"
18466 [(const_int 0)]
18467 {
18468 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18469
18470 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18471 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18472
18473 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18474 operands[2], operands[3]));
18475 DONE;
18476 }
18477 [(set_attr "type" "frndint")
18478 (set_attr "i387_cw" "trunc")
18479 (set_attr "mode" "XF")])
18480
18481 (define_insn "frndintxf2_trunc_i387"
18482 [(set (match_operand:XF 0 "register_operand" "=f")
18483 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18484 UNSPEC_FRNDINT_TRUNC))
18485 (use (match_operand:HI 2 "memory_operand" "m"))
18486 (use (match_operand:HI 3 "memory_operand" "m"))]
18487 "TARGET_USE_FANCY_MATH_387
18488 && flag_unsafe_math_optimizations"
18489 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18490 [(set_attr "type" "frndint")
18491 (set_attr "i387_cw" "trunc")
18492 (set_attr "mode" "XF")])
18493
18494 (define_expand "btruncxf2"
18495 [(use (match_operand:XF 0 "register_operand" ""))
18496 (use (match_operand:XF 1 "register_operand" ""))]
18497 "TARGET_USE_FANCY_MATH_387
18498 && flag_unsafe_math_optimizations && !optimize_size"
18499 {
18500 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18501 DONE;
18502 })
18503
18504 (define_expand "btrunc<mode>2"
18505 [(use (match_operand:MODEF 0 "register_operand" ""))
18506 (use (match_operand:MODEF 1 "register_operand" ""))]
18507 "(TARGET_USE_FANCY_MATH_387
18508 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18509 || TARGET_MIX_SSE_I387)
18510 && flag_unsafe_math_optimizations && !optimize_size)
18511 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18512 && !flag_trapping_math
18513 && (TARGET_ROUND || !optimize_size))"
18514 {
18515 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18516 && !flag_trapping_math
18517 && (TARGET_ROUND || !optimize_size))
18518 {
18519 if (TARGET_ROUND)
18520 emit_insn (gen_sse4_1_round<mode>2
18521 (operands[0], operands[1], GEN_INT (0x03)));
18522 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18523 ix86_expand_trunc (operand0, operand1);
18524 else
18525 ix86_expand_truncdf_32 (operand0, operand1);
18526 }
18527 else
18528 {
18529 rtx op0 = gen_reg_rtx (XFmode);
18530 rtx op1 = gen_reg_rtx (XFmode);
18531
18532 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18533 emit_insn (gen_frndintxf2_trunc (op0, op1));
18534
18535 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18536 }
18537 DONE;
18538 })
18539
18540 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18541 (define_insn_and_split "frndintxf2_mask_pm"
18542 [(set (match_operand:XF 0 "register_operand" "")
18543 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18544 UNSPEC_FRNDINT_MASK_PM))
18545 (clobber (reg:CC FLAGS_REG))]
18546 "TARGET_USE_FANCY_MATH_387
18547 && flag_unsafe_math_optimizations
18548 && !(reload_completed || reload_in_progress)"
18549 "#"
18550 "&& 1"
18551 [(const_int 0)]
18552 {
18553 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18554
18555 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18556 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18557
18558 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18559 operands[2], operands[3]));
18560 DONE;
18561 }
18562 [(set_attr "type" "frndint")
18563 (set_attr "i387_cw" "mask_pm")
18564 (set_attr "mode" "XF")])
18565
18566 (define_insn "frndintxf2_mask_pm_i387"
18567 [(set (match_operand:XF 0 "register_operand" "=f")
18568 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18569 UNSPEC_FRNDINT_MASK_PM))
18570 (use (match_operand:HI 2 "memory_operand" "m"))
18571 (use (match_operand:HI 3 "memory_operand" "m"))]
18572 "TARGET_USE_FANCY_MATH_387
18573 && flag_unsafe_math_optimizations"
18574 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18575 [(set_attr "type" "frndint")
18576 (set_attr "i387_cw" "mask_pm")
18577 (set_attr "mode" "XF")])
18578
18579 (define_expand "nearbyintxf2"
18580 [(use (match_operand:XF 0 "register_operand" ""))
18581 (use (match_operand:XF 1 "register_operand" ""))]
18582 "TARGET_USE_FANCY_MATH_387
18583 && flag_unsafe_math_optimizations"
18584 {
18585 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18586
18587 DONE;
18588 })
18589
18590 (define_expand "nearbyint<mode>2"
18591 [(use (match_operand:MODEF 0 "register_operand" ""))
18592 (use (match_operand:MODEF 1 "register_operand" ""))]
18593 "TARGET_USE_FANCY_MATH_387
18594 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18595 || TARGET_MIX_SSE_I387)
18596 && flag_unsafe_math_optimizations"
18597 {
18598 rtx op0 = gen_reg_rtx (XFmode);
18599 rtx op1 = gen_reg_rtx (XFmode);
18600
18601 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18602 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18603
18604 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18605 DONE;
18606 })
18607
18608 (define_insn "fxam<mode>2_i387"
18609 [(set (match_operand:HI 0 "register_operand" "=a")
18610 (unspec:HI
18611 [(match_operand:X87MODEF 1 "register_operand" "f")]
18612 UNSPEC_FXAM))]
18613 "TARGET_USE_FANCY_MATH_387"
18614 "fxam\n\tfnstsw\t%0"
18615 [(set_attr "type" "multi")
18616 (set_attr "unit" "i387")
18617 (set_attr "mode" "<MODE>")])
18618
18619 (define_expand "isinf<mode>2"
18620 [(use (match_operand:SI 0 "register_operand" ""))
18621 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18622 "TARGET_USE_FANCY_MATH_387
18623 && TARGET_C99_FUNCTIONS
18624 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18625 {
18626 rtx mask = GEN_INT (0x45);
18627 rtx val = GEN_INT (0x05);
18628
18629 rtx cond;
18630
18631 rtx scratch = gen_reg_rtx (HImode);
18632 rtx res = gen_reg_rtx (QImode);
18633
18634 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18635 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18636 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18637 cond = gen_rtx_fmt_ee (EQ, QImode,
18638 gen_rtx_REG (CCmode, FLAGS_REG),
18639 const0_rtx);
18640 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18641 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18642 DONE;
18643 })
18644
18645 (define_expand "signbit<mode>2"
18646 [(use (match_operand:SI 0 "register_operand" ""))
18647 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18648 "TARGET_USE_FANCY_MATH_387
18649 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18650 {
18651 rtx mask = GEN_INT (0x0200);
18652
18653 rtx scratch = gen_reg_rtx (HImode);
18654
18655 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18656 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18657 DONE;
18658 })
18659 \f
18660 ;; Block operation instructions
18661
18662 (define_expand "movmemsi"
18663 [(use (match_operand:BLK 0 "memory_operand" ""))
18664 (use (match_operand:BLK 1 "memory_operand" ""))
18665 (use (match_operand:SI 2 "nonmemory_operand" ""))
18666 (use (match_operand:SI 3 "const_int_operand" ""))
18667 (use (match_operand:SI 4 "const_int_operand" ""))
18668 (use (match_operand:SI 5 "const_int_operand" ""))]
18669 ""
18670 {
18671 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18672 operands[4], operands[5]))
18673 DONE;
18674 else
18675 FAIL;
18676 })
18677
18678 (define_expand "movmemdi"
18679 [(use (match_operand:BLK 0 "memory_operand" ""))
18680 (use (match_operand:BLK 1 "memory_operand" ""))
18681 (use (match_operand:DI 2 "nonmemory_operand" ""))
18682 (use (match_operand:DI 3 "const_int_operand" ""))
18683 (use (match_operand:SI 4 "const_int_operand" ""))
18684 (use (match_operand:SI 5 "const_int_operand" ""))]
18685 "TARGET_64BIT"
18686 {
18687 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18688 operands[4], operands[5]))
18689 DONE;
18690 else
18691 FAIL;
18692 })
18693
18694 ;; Most CPUs don't like single string operations
18695 ;; Handle this case here to simplify previous expander.
18696
18697 (define_expand "strmov"
18698 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18699 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18700 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18701 (clobber (reg:CC FLAGS_REG))])
18702 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18703 (clobber (reg:CC FLAGS_REG))])]
18704 ""
18705 {
18706 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18707
18708 /* If .md ever supports :P for Pmode, these can be directly
18709 in the pattern above. */
18710 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18711 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18712
18713 /* Can't use this if the user has appropriated esi or edi. */
18714 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18715 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18716 {
18717 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18718 operands[2], operands[3],
18719 operands[5], operands[6]));
18720 DONE;
18721 }
18722
18723 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18724 })
18725
18726 (define_expand "strmov_singleop"
18727 [(parallel [(set (match_operand 1 "memory_operand" "")
18728 (match_operand 3 "memory_operand" ""))
18729 (set (match_operand 0 "register_operand" "")
18730 (match_operand 4 "" ""))
18731 (set (match_operand 2 "register_operand" "")
18732 (match_operand 5 "" ""))])]
18733 "TARGET_SINGLE_STRINGOP || optimize_size"
18734 "")
18735
18736 (define_insn "*strmovdi_rex_1"
18737 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18738 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18739 (set (match_operand:DI 0 "register_operand" "=D")
18740 (plus:DI (match_dup 2)
18741 (const_int 8)))
18742 (set (match_operand:DI 1 "register_operand" "=S")
18743 (plus:DI (match_dup 3)
18744 (const_int 8)))]
18745 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18746 "movsq"
18747 [(set_attr "type" "str")
18748 (set_attr "mode" "DI")
18749 (set_attr "memory" "both")])
18750
18751 (define_insn "*strmovsi_1"
18752 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18753 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18754 (set (match_operand:SI 0 "register_operand" "=D")
18755 (plus:SI (match_dup 2)
18756 (const_int 4)))
18757 (set (match_operand:SI 1 "register_operand" "=S")
18758 (plus:SI (match_dup 3)
18759 (const_int 4)))]
18760 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18761 "{movsl|movsd}"
18762 [(set_attr "type" "str")
18763 (set_attr "mode" "SI")
18764 (set_attr "memory" "both")])
18765
18766 (define_insn "*strmovsi_rex_1"
18767 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18768 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18769 (set (match_operand:DI 0 "register_operand" "=D")
18770 (plus:DI (match_dup 2)
18771 (const_int 4)))
18772 (set (match_operand:DI 1 "register_operand" "=S")
18773 (plus:DI (match_dup 3)
18774 (const_int 4)))]
18775 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18776 "{movsl|movsd}"
18777 [(set_attr "type" "str")
18778 (set_attr "mode" "SI")
18779 (set_attr "memory" "both")])
18780
18781 (define_insn "*strmovhi_1"
18782 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18783 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18784 (set (match_operand:SI 0 "register_operand" "=D")
18785 (plus:SI (match_dup 2)
18786 (const_int 2)))
18787 (set (match_operand:SI 1 "register_operand" "=S")
18788 (plus:SI (match_dup 3)
18789 (const_int 2)))]
18790 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18791 "movsw"
18792 [(set_attr "type" "str")
18793 (set_attr "memory" "both")
18794 (set_attr "mode" "HI")])
18795
18796 (define_insn "*strmovhi_rex_1"
18797 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18798 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18799 (set (match_operand:DI 0 "register_operand" "=D")
18800 (plus:DI (match_dup 2)
18801 (const_int 2)))
18802 (set (match_operand:DI 1 "register_operand" "=S")
18803 (plus:DI (match_dup 3)
18804 (const_int 2)))]
18805 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18806 "movsw"
18807 [(set_attr "type" "str")
18808 (set_attr "memory" "both")
18809 (set_attr "mode" "HI")])
18810
18811 (define_insn "*strmovqi_1"
18812 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18813 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18814 (set (match_operand:SI 0 "register_operand" "=D")
18815 (plus:SI (match_dup 2)
18816 (const_int 1)))
18817 (set (match_operand:SI 1 "register_operand" "=S")
18818 (plus:SI (match_dup 3)
18819 (const_int 1)))]
18820 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18821 "movsb"
18822 [(set_attr "type" "str")
18823 (set_attr "memory" "both")
18824 (set_attr "mode" "QI")])
18825
18826 (define_insn "*strmovqi_rex_1"
18827 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18828 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18829 (set (match_operand:DI 0 "register_operand" "=D")
18830 (plus:DI (match_dup 2)
18831 (const_int 1)))
18832 (set (match_operand:DI 1 "register_operand" "=S")
18833 (plus:DI (match_dup 3)
18834 (const_int 1)))]
18835 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18836 "movsb"
18837 [(set_attr "type" "str")
18838 (set_attr "memory" "both")
18839 (set_attr "mode" "QI")])
18840
18841 (define_expand "rep_mov"
18842 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18843 (set (match_operand 0 "register_operand" "")
18844 (match_operand 5 "" ""))
18845 (set (match_operand 2 "register_operand" "")
18846 (match_operand 6 "" ""))
18847 (set (match_operand 1 "memory_operand" "")
18848 (match_operand 3 "memory_operand" ""))
18849 (use (match_dup 4))])]
18850 ""
18851 "")
18852
18853 (define_insn "*rep_movdi_rex64"
18854 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18855 (set (match_operand:DI 0 "register_operand" "=D")
18856 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18857 (const_int 3))
18858 (match_operand:DI 3 "register_operand" "0")))
18859 (set (match_operand:DI 1 "register_operand" "=S")
18860 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18861 (match_operand:DI 4 "register_operand" "1")))
18862 (set (mem:BLK (match_dup 3))
18863 (mem:BLK (match_dup 4)))
18864 (use (match_dup 5))]
18865 "TARGET_64BIT"
18866 "rep movsq"
18867 [(set_attr "type" "str")
18868 (set_attr "prefix_rep" "1")
18869 (set_attr "memory" "both")
18870 (set_attr "mode" "DI")])
18871
18872 (define_insn "*rep_movsi"
18873 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18874 (set (match_operand:SI 0 "register_operand" "=D")
18875 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18876 (const_int 2))
18877 (match_operand:SI 3 "register_operand" "0")))
18878 (set (match_operand:SI 1 "register_operand" "=S")
18879 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18880 (match_operand:SI 4 "register_operand" "1")))
18881 (set (mem:BLK (match_dup 3))
18882 (mem:BLK (match_dup 4)))
18883 (use (match_dup 5))]
18884 "!TARGET_64BIT"
18885 "rep movs{l|d}"
18886 [(set_attr "type" "str")
18887 (set_attr "prefix_rep" "1")
18888 (set_attr "memory" "both")
18889 (set_attr "mode" "SI")])
18890
18891 (define_insn "*rep_movsi_rex64"
18892 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18893 (set (match_operand:DI 0 "register_operand" "=D")
18894 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18895 (const_int 2))
18896 (match_operand:DI 3 "register_operand" "0")))
18897 (set (match_operand:DI 1 "register_operand" "=S")
18898 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18899 (match_operand:DI 4 "register_operand" "1")))
18900 (set (mem:BLK (match_dup 3))
18901 (mem:BLK (match_dup 4)))
18902 (use (match_dup 5))]
18903 "TARGET_64BIT"
18904 "rep movs{l|d}"
18905 [(set_attr "type" "str")
18906 (set_attr "prefix_rep" "1")
18907 (set_attr "memory" "both")
18908 (set_attr "mode" "SI")])
18909
18910 (define_insn "*rep_movqi"
18911 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18912 (set (match_operand:SI 0 "register_operand" "=D")
18913 (plus:SI (match_operand:SI 3 "register_operand" "0")
18914 (match_operand:SI 5 "register_operand" "2")))
18915 (set (match_operand:SI 1 "register_operand" "=S")
18916 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18917 (set (mem:BLK (match_dup 3))
18918 (mem:BLK (match_dup 4)))
18919 (use (match_dup 5))]
18920 "!TARGET_64BIT"
18921 "rep movsb"
18922 [(set_attr "type" "str")
18923 (set_attr "prefix_rep" "1")
18924 (set_attr "memory" "both")
18925 (set_attr "mode" "SI")])
18926
18927 (define_insn "*rep_movqi_rex64"
18928 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18929 (set (match_operand:DI 0 "register_operand" "=D")
18930 (plus:DI (match_operand:DI 3 "register_operand" "0")
18931 (match_operand:DI 5 "register_operand" "2")))
18932 (set (match_operand:DI 1 "register_operand" "=S")
18933 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18934 (set (mem:BLK (match_dup 3))
18935 (mem:BLK (match_dup 4)))
18936 (use (match_dup 5))]
18937 "TARGET_64BIT"
18938 "rep movsb"
18939 [(set_attr "type" "str")
18940 (set_attr "prefix_rep" "1")
18941 (set_attr "memory" "both")
18942 (set_attr "mode" "SI")])
18943
18944 (define_expand "setmemsi"
18945 [(use (match_operand:BLK 0 "memory_operand" ""))
18946 (use (match_operand:SI 1 "nonmemory_operand" ""))
18947 (use (match_operand 2 "const_int_operand" ""))
18948 (use (match_operand 3 "const_int_operand" ""))
18949 (use (match_operand:SI 4 "const_int_operand" ""))
18950 (use (match_operand:SI 5 "const_int_operand" ""))]
18951 ""
18952 {
18953 if (ix86_expand_setmem (operands[0], operands[1],
18954 operands[2], operands[3],
18955 operands[4], operands[5]))
18956 DONE;
18957 else
18958 FAIL;
18959 })
18960
18961 (define_expand "setmemdi"
18962 [(use (match_operand:BLK 0 "memory_operand" ""))
18963 (use (match_operand:DI 1 "nonmemory_operand" ""))
18964 (use (match_operand 2 "const_int_operand" ""))
18965 (use (match_operand 3 "const_int_operand" ""))
18966 (use (match_operand 4 "const_int_operand" ""))
18967 (use (match_operand 5 "const_int_operand" ""))]
18968 "TARGET_64BIT"
18969 {
18970 if (ix86_expand_setmem (operands[0], operands[1],
18971 operands[2], operands[3],
18972 operands[4], operands[5]))
18973 DONE;
18974 else
18975 FAIL;
18976 })
18977
18978 ;; Most CPUs don't like single string operations
18979 ;; Handle this case here to simplify previous expander.
18980
18981 (define_expand "strset"
18982 [(set (match_operand 1 "memory_operand" "")
18983 (match_operand 2 "register_operand" ""))
18984 (parallel [(set (match_operand 0 "register_operand" "")
18985 (match_dup 3))
18986 (clobber (reg:CC FLAGS_REG))])]
18987 ""
18988 {
18989 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18990 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18991
18992 /* If .md ever supports :P for Pmode, this can be directly
18993 in the pattern above. */
18994 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18995 GEN_INT (GET_MODE_SIZE (GET_MODE
18996 (operands[2]))));
18997 if (TARGET_SINGLE_STRINGOP || optimize_size)
18998 {
18999 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19000 operands[3]));
19001 DONE;
19002 }
19003 })
19004
19005 (define_expand "strset_singleop"
19006 [(parallel [(set (match_operand 1 "memory_operand" "")
19007 (match_operand 2 "register_operand" ""))
19008 (set (match_operand 0 "register_operand" "")
19009 (match_operand 3 "" ""))])]
19010 "TARGET_SINGLE_STRINGOP || optimize_size"
19011 "")
19012
19013 (define_insn "*strsetdi_rex_1"
19014 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19015 (match_operand:DI 2 "register_operand" "a"))
19016 (set (match_operand:DI 0 "register_operand" "=D")
19017 (plus:DI (match_dup 1)
19018 (const_int 8)))]
19019 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19020 "stosq"
19021 [(set_attr "type" "str")
19022 (set_attr "memory" "store")
19023 (set_attr "mode" "DI")])
19024
19025 (define_insn "*strsetsi_1"
19026 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19027 (match_operand:SI 2 "register_operand" "a"))
19028 (set (match_operand:SI 0 "register_operand" "=D")
19029 (plus:SI (match_dup 1)
19030 (const_int 4)))]
19031 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19032 "{stosl|stosd}"
19033 [(set_attr "type" "str")
19034 (set_attr "memory" "store")
19035 (set_attr "mode" "SI")])
19036
19037 (define_insn "*strsetsi_rex_1"
19038 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19039 (match_operand:SI 2 "register_operand" "a"))
19040 (set (match_operand:DI 0 "register_operand" "=D")
19041 (plus:DI (match_dup 1)
19042 (const_int 4)))]
19043 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19044 "{stosl|stosd}"
19045 [(set_attr "type" "str")
19046 (set_attr "memory" "store")
19047 (set_attr "mode" "SI")])
19048
19049 (define_insn "*strsethi_1"
19050 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19051 (match_operand:HI 2 "register_operand" "a"))
19052 (set (match_operand:SI 0 "register_operand" "=D")
19053 (plus:SI (match_dup 1)
19054 (const_int 2)))]
19055 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19056 "stosw"
19057 [(set_attr "type" "str")
19058 (set_attr "memory" "store")
19059 (set_attr "mode" "HI")])
19060
19061 (define_insn "*strsethi_rex_1"
19062 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19063 (match_operand:HI 2 "register_operand" "a"))
19064 (set (match_operand:DI 0 "register_operand" "=D")
19065 (plus:DI (match_dup 1)
19066 (const_int 2)))]
19067 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19068 "stosw"
19069 [(set_attr "type" "str")
19070 (set_attr "memory" "store")
19071 (set_attr "mode" "HI")])
19072
19073 (define_insn "*strsetqi_1"
19074 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19075 (match_operand:QI 2 "register_operand" "a"))
19076 (set (match_operand:SI 0 "register_operand" "=D")
19077 (plus:SI (match_dup 1)
19078 (const_int 1)))]
19079 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19080 "stosb"
19081 [(set_attr "type" "str")
19082 (set_attr "memory" "store")
19083 (set_attr "mode" "QI")])
19084
19085 (define_insn "*strsetqi_rex_1"
19086 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19087 (match_operand:QI 2 "register_operand" "a"))
19088 (set (match_operand:DI 0 "register_operand" "=D")
19089 (plus:DI (match_dup 1)
19090 (const_int 1)))]
19091 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19092 "stosb"
19093 [(set_attr "type" "str")
19094 (set_attr "memory" "store")
19095 (set_attr "mode" "QI")])
19096
19097 (define_expand "rep_stos"
19098 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19099 (set (match_operand 0 "register_operand" "")
19100 (match_operand 4 "" ""))
19101 (set (match_operand 2 "memory_operand" "") (const_int 0))
19102 (use (match_operand 3 "register_operand" ""))
19103 (use (match_dup 1))])]
19104 ""
19105 "")
19106
19107 (define_insn "*rep_stosdi_rex64"
19108 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19109 (set (match_operand:DI 0 "register_operand" "=D")
19110 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19111 (const_int 3))
19112 (match_operand:DI 3 "register_operand" "0")))
19113 (set (mem:BLK (match_dup 3))
19114 (const_int 0))
19115 (use (match_operand:DI 2 "register_operand" "a"))
19116 (use (match_dup 4))]
19117 "TARGET_64BIT"
19118 "rep stosq"
19119 [(set_attr "type" "str")
19120 (set_attr "prefix_rep" "1")
19121 (set_attr "memory" "store")
19122 (set_attr "mode" "DI")])
19123
19124 (define_insn "*rep_stossi"
19125 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19126 (set (match_operand:SI 0 "register_operand" "=D")
19127 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19128 (const_int 2))
19129 (match_operand:SI 3 "register_operand" "0")))
19130 (set (mem:BLK (match_dup 3))
19131 (const_int 0))
19132 (use (match_operand:SI 2 "register_operand" "a"))
19133 (use (match_dup 4))]
19134 "!TARGET_64BIT"
19135 "rep stos{l|d}"
19136 [(set_attr "type" "str")
19137 (set_attr "prefix_rep" "1")
19138 (set_attr "memory" "store")
19139 (set_attr "mode" "SI")])
19140
19141 (define_insn "*rep_stossi_rex64"
19142 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19143 (set (match_operand:DI 0 "register_operand" "=D")
19144 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19145 (const_int 2))
19146 (match_operand:DI 3 "register_operand" "0")))
19147 (set (mem:BLK (match_dup 3))
19148 (const_int 0))
19149 (use (match_operand:SI 2 "register_operand" "a"))
19150 (use (match_dup 4))]
19151 "TARGET_64BIT"
19152 "rep stos{l|d}"
19153 [(set_attr "type" "str")
19154 (set_attr "prefix_rep" "1")
19155 (set_attr "memory" "store")
19156 (set_attr "mode" "SI")])
19157
19158 (define_insn "*rep_stosqi"
19159 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19160 (set (match_operand:SI 0 "register_operand" "=D")
19161 (plus:SI (match_operand:SI 3 "register_operand" "0")
19162 (match_operand:SI 4 "register_operand" "1")))
19163 (set (mem:BLK (match_dup 3))
19164 (const_int 0))
19165 (use (match_operand:QI 2 "register_operand" "a"))
19166 (use (match_dup 4))]
19167 "!TARGET_64BIT"
19168 "rep stosb"
19169 [(set_attr "type" "str")
19170 (set_attr "prefix_rep" "1")
19171 (set_attr "memory" "store")
19172 (set_attr "mode" "QI")])
19173
19174 (define_insn "*rep_stosqi_rex64"
19175 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19176 (set (match_operand:DI 0 "register_operand" "=D")
19177 (plus:DI (match_operand:DI 3 "register_operand" "0")
19178 (match_operand:DI 4 "register_operand" "1")))
19179 (set (mem:BLK (match_dup 3))
19180 (const_int 0))
19181 (use (match_operand:QI 2 "register_operand" "a"))
19182 (use (match_dup 4))]
19183 "TARGET_64BIT"
19184 "rep stosb"
19185 [(set_attr "type" "str")
19186 (set_attr "prefix_rep" "1")
19187 (set_attr "memory" "store")
19188 (set_attr "mode" "QI")])
19189
19190 (define_expand "cmpstrnsi"
19191 [(set (match_operand:SI 0 "register_operand" "")
19192 (compare:SI (match_operand:BLK 1 "general_operand" "")
19193 (match_operand:BLK 2 "general_operand" "")))
19194 (use (match_operand 3 "general_operand" ""))
19195 (use (match_operand 4 "immediate_operand" ""))]
19196 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19197 {
19198 rtx addr1, addr2, out, outlow, count, countreg, align;
19199
19200 /* Can't use this if the user has appropriated esi or edi. */
19201 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19202 FAIL;
19203
19204 out = operands[0];
19205 if (!REG_P (out))
19206 out = gen_reg_rtx (SImode);
19207
19208 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19209 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19210 if (addr1 != XEXP (operands[1], 0))
19211 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19212 if (addr2 != XEXP (operands[2], 0))
19213 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19214
19215 count = operands[3];
19216 countreg = ix86_zero_extend_to_Pmode (count);
19217
19218 /* %%% Iff we are testing strict equality, we can use known alignment
19219 to good advantage. This may be possible with combine, particularly
19220 once cc0 is dead. */
19221 align = operands[4];
19222
19223 if (CONST_INT_P (count))
19224 {
19225 if (INTVAL (count) == 0)
19226 {
19227 emit_move_insn (operands[0], const0_rtx);
19228 DONE;
19229 }
19230 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19231 operands[1], operands[2]));
19232 }
19233 else
19234 {
19235 if (TARGET_64BIT)
19236 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19237 else
19238 emit_insn (gen_cmpsi_1 (countreg, countreg));
19239 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19240 operands[1], operands[2]));
19241 }
19242
19243 outlow = gen_lowpart (QImode, out);
19244 emit_insn (gen_cmpintqi (outlow));
19245 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19246
19247 if (operands[0] != out)
19248 emit_move_insn (operands[0], out);
19249
19250 DONE;
19251 })
19252
19253 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19254
19255 (define_expand "cmpintqi"
19256 [(set (match_dup 1)
19257 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19258 (set (match_dup 2)
19259 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19260 (parallel [(set (match_operand:QI 0 "register_operand" "")
19261 (minus:QI (match_dup 1)
19262 (match_dup 2)))
19263 (clobber (reg:CC FLAGS_REG))])]
19264 ""
19265 "operands[1] = gen_reg_rtx (QImode);
19266 operands[2] = gen_reg_rtx (QImode);")
19267
19268 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19269 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19270
19271 (define_expand "cmpstrnqi_nz_1"
19272 [(parallel [(set (reg:CC FLAGS_REG)
19273 (compare:CC (match_operand 4 "memory_operand" "")
19274 (match_operand 5 "memory_operand" "")))
19275 (use (match_operand 2 "register_operand" ""))
19276 (use (match_operand:SI 3 "immediate_operand" ""))
19277 (clobber (match_operand 0 "register_operand" ""))
19278 (clobber (match_operand 1 "register_operand" ""))
19279 (clobber (match_dup 2))])]
19280 ""
19281 "")
19282
19283 (define_insn "*cmpstrnqi_nz_1"
19284 [(set (reg:CC FLAGS_REG)
19285 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19286 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19287 (use (match_operand:SI 6 "register_operand" "2"))
19288 (use (match_operand:SI 3 "immediate_operand" "i"))
19289 (clobber (match_operand:SI 0 "register_operand" "=S"))
19290 (clobber (match_operand:SI 1 "register_operand" "=D"))
19291 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19292 "!TARGET_64BIT"
19293 "repz cmpsb"
19294 [(set_attr "type" "str")
19295 (set_attr "mode" "QI")
19296 (set_attr "prefix_rep" "1")])
19297
19298 (define_insn "*cmpstrnqi_nz_rex_1"
19299 [(set (reg:CC FLAGS_REG)
19300 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19301 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19302 (use (match_operand:DI 6 "register_operand" "2"))
19303 (use (match_operand:SI 3 "immediate_operand" "i"))
19304 (clobber (match_operand:DI 0 "register_operand" "=S"))
19305 (clobber (match_operand:DI 1 "register_operand" "=D"))
19306 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19307 "TARGET_64BIT"
19308 "repz cmpsb"
19309 [(set_attr "type" "str")
19310 (set_attr "mode" "QI")
19311 (set_attr "prefix_rep" "1")])
19312
19313 ;; The same, but the count is not known to not be zero.
19314
19315 (define_expand "cmpstrnqi_1"
19316 [(parallel [(set (reg:CC FLAGS_REG)
19317 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19318 (const_int 0))
19319 (compare:CC (match_operand 4 "memory_operand" "")
19320 (match_operand 5 "memory_operand" ""))
19321 (const_int 0)))
19322 (use (match_operand:SI 3 "immediate_operand" ""))
19323 (use (reg:CC FLAGS_REG))
19324 (clobber (match_operand 0 "register_operand" ""))
19325 (clobber (match_operand 1 "register_operand" ""))
19326 (clobber (match_dup 2))])]
19327 ""
19328 "")
19329
19330 (define_insn "*cmpstrnqi_1"
19331 [(set (reg:CC FLAGS_REG)
19332 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19333 (const_int 0))
19334 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19335 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19336 (const_int 0)))
19337 (use (match_operand:SI 3 "immediate_operand" "i"))
19338 (use (reg:CC FLAGS_REG))
19339 (clobber (match_operand:SI 0 "register_operand" "=S"))
19340 (clobber (match_operand:SI 1 "register_operand" "=D"))
19341 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19342 "!TARGET_64BIT"
19343 "repz cmpsb"
19344 [(set_attr "type" "str")
19345 (set_attr "mode" "QI")
19346 (set_attr "prefix_rep" "1")])
19347
19348 (define_insn "*cmpstrnqi_rex_1"
19349 [(set (reg:CC FLAGS_REG)
19350 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19351 (const_int 0))
19352 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19353 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19354 (const_int 0)))
19355 (use (match_operand:SI 3 "immediate_operand" "i"))
19356 (use (reg:CC FLAGS_REG))
19357 (clobber (match_operand:DI 0 "register_operand" "=S"))
19358 (clobber (match_operand:DI 1 "register_operand" "=D"))
19359 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19360 "TARGET_64BIT"
19361 "repz cmpsb"
19362 [(set_attr "type" "str")
19363 (set_attr "mode" "QI")
19364 (set_attr "prefix_rep" "1")])
19365
19366 (define_expand "strlensi"
19367 [(set (match_operand:SI 0 "register_operand" "")
19368 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19369 (match_operand:QI 2 "immediate_operand" "")
19370 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19371 ""
19372 {
19373 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19374 DONE;
19375 else
19376 FAIL;
19377 })
19378
19379 (define_expand "strlendi"
19380 [(set (match_operand:DI 0 "register_operand" "")
19381 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19382 (match_operand:QI 2 "immediate_operand" "")
19383 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19384 ""
19385 {
19386 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19387 DONE;
19388 else
19389 FAIL;
19390 })
19391
19392 (define_expand "strlenqi_1"
19393 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19394 (clobber (match_operand 1 "register_operand" ""))
19395 (clobber (reg:CC FLAGS_REG))])]
19396 ""
19397 "")
19398
19399 (define_insn "*strlenqi_1"
19400 [(set (match_operand:SI 0 "register_operand" "=&c")
19401 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19402 (match_operand:QI 2 "register_operand" "a")
19403 (match_operand:SI 3 "immediate_operand" "i")
19404 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19405 (clobber (match_operand:SI 1 "register_operand" "=D"))
19406 (clobber (reg:CC FLAGS_REG))]
19407 "!TARGET_64BIT"
19408 "repnz scasb"
19409 [(set_attr "type" "str")
19410 (set_attr "mode" "QI")
19411 (set_attr "prefix_rep" "1")])
19412
19413 (define_insn "*strlenqi_rex_1"
19414 [(set (match_operand:DI 0 "register_operand" "=&c")
19415 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19416 (match_operand:QI 2 "register_operand" "a")
19417 (match_operand:DI 3 "immediate_operand" "i")
19418 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19419 (clobber (match_operand:DI 1 "register_operand" "=D"))
19420 (clobber (reg:CC FLAGS_REG))]
19421 "TARGET_64BIT"
19422 "repnz scasb"
19423 [(set_attr "type" "str")
19424 (set_attr "mode" "QI")
19425 (set_attr "prefix_rep" "1")])
19426
19427 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19428 ;; handled in combine, but it is not currently up to the task.
19429 ;; When used for their truth value, the cmpstrn* expanders generate
19430 ;; code like this:
19431 ;;
19432 ;; repz cmpsb
19433 ;; seta %al
19434 ;; setb %dl
19435 ;; cmpb %al, %dl
19436 ;; jcc label
19437 ;;
19438 ;; The intermediate three instructions are unnecessary.
19439
19440 ;; This one handles cmpstrn*_nz_1...
19441 (define_peephole2
19442 [(parallel[
19443 (set (reg:CC FLAGS_REG)
19444 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19445 (mem:BLK (match_operand 5 "register_operand" ""))))
19446 (use (match_operand 6 "register_operand" ""))
19447 (use (match_operand:SI 3 "immediate_operand" ""))
19448 (clobber (match_operand 0 "register_operand" ""))
19449 (clobber (match_operand 1 "register_operand" ""))
19450 (clobber (match_operand 2 "register_operand" ""))])
19451 (set (match_operand:QI 7 "register_operand" "")
19452 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19453 (set (match_operand:QI 8 "register_operand" "")
19454 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19455 (set (reg FLAGS_REG)
19456 (compare (match_dup 7) (match_dup 8)))
19457 ]
19458 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19459 [(parallel[
19460 (set (reg:CC FLAGS_REG)
19461 (compare:CC (mem:BLK (match_dup 4))
19462 (mem:BLK (match_dup 5))))
19463 (use (match_dup 6))
19464 (use (match_dup 3))
19465 (clobber (match_dup 0))
19466 (clobber (match_dup 1))
19467 (clobber (match_dup 2))])]
19468 "")
19469
19470 ;; ...and this one handles cmpstrn*_1.
19471 (define_peephole2
19472 [(parallel[
19473 (set (reg:CC FLAGS_REG)
19474 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19475 (const_int 0))
19476 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19477 (mem:BLK (match_operand 5 "register_operand" "")))
19478 (const_int 0)))
19479 (use (match_operand:SI 3 "immediate_operand" ""))
19480 (use (reg:CC FLAGS_REG))
19481 (clobber (match_operand 0 "register_operand" ""))
19482 (clobber (match_operand 1 "register_operand" ""))
19483 (clobber (match_operand 2 "register_operand" ""))])
19484 (set (match_operand:QI 7 "register_operand" "")
19485 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19486 (set (match_operand:QI 8 "register_operand" "")
19487 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19488 (set (reg FLAGS_REG)
19489 (compare (match_dup 7) (match_dup 8)))
19490 ]
19491 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19492 [(parallel[
19493 (set (reg:CC FLAGS_REG)
19494 (if_then_else:CC (ne (match_dup 6)
19495 (const_int 0))
19496 (compare:CC (mem:BLK (match_dup 4))
19497 (mem:BLK (match_dup 5)))
19498 (const_int 0)))
19499 (use (match_dup 3))
19500 (use (reg:CC FLAGS_REG))
19501 (clobber (match_dup 0))
19502 (clobber (match_dup 1))
19503 (clobber (match_dup 2))])]
19504 "")
19505
19506
19507 \f
19508 ;; Conditional move instructions.
19509
19510 (define_expand "movdicc"
19511 [(set (match_operand:DI 0 "register_operand" "")
19512 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19513 (match_operand:DI 2 "general_operand" "")
19514 (match_operand:DI 3 "general_operand" "")))]
19515 "TARGET_64BIT"
19516 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19517
19518 (define_insn "x86_movdicc_0_m1_rex64"
19519 [(set (match_operand:DI 0 "register_operand" "=r")
19520 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19521 (const_int -1)
19522 (const_int 0)))
19523 (clobber (reg:CC FLAGS_REG))]
19524 "TARGET_64BIT"
19525 "sbb{q}\t%0, %0"
19526 ; Since we don't have the proper number of operands for an alu insn,
19527 ; fill in all the blanks.
19528 [(set_attr "type" "alu")
19529 (set_attr "pent_pair" "pu")
19530 (set_attr "memory" "none")
19531 (set_attr "imm_disp" "false")
19532 (set_attr "mode" "DI")
19533 (set_attr "length_immediate" "0")])
19534
19535 (define_insn "*movdicc_c_rex64"
19536 [(set (match_operand:DI 0 "register_operand" "=r,r")
19537 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19538 [(reg FLAGS_REG) (const_int 0)])
19539 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19540 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19541 "TARGET_64BIT && TARGET_CMOVE
19542 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19543 "@
19544 cmov%O2%C1\t{%2, %0|%0, %2}
19545 cmov%O2%c1\t{%3, %0|%0, %3}"
19546 [(set_attr "type" "icmov")
19547 (set_attr "mode" "DI")])
19548
19549 (define_expand "movsicc"
19550 [(set (match_operand:SI 0 "register_operand" "")
19551 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19552 (match_operand:SI 2 "general_operand" "")
19553 (match_operand:SI 3 "general_operand" "")))]
19554 ""
19555 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19556
19557 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19558 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19559 ;; So just document what we're doing explicitly.
19560
19561 (define_insn "x86_movsicc_0_m1"
19562 [(set (match_operand:SI 0 "register_operand" "=r")
19563 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19564 (const_int -1)
19565 (const_int 0)))
19566 (clobber (reg:CC FLAGS_REG))]
19567 ""
19568 "sbb{l}\t%0, %0"
19569 ; Since we don't have the proper number of operands for an alu insn,
19570 ; fill in all the blanks.
19571 [(set_attr "type" "alu")
19572 (set_attr "pent_pair" "pu")
19573 (set_attr "memory" "none")
19574 (set_attr "imm_disp" "false")
19575 (set_attr "mode" "SI")
19576 (set_attr "length_immediate" "0")])
19577
19578 (define_insn "*movsicc_noc"
19579 [(set (match_operand:SI 0 "register_operand" "=r,r")
19580 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19581 [(reg FLAGS_REG) (const_int 0)])
19582 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19583 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19584 "TARGET_CMOVE
19585 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19586 "@
19587 cmov%O2%C1\t{%2, %0|%0, %2}
19588 cmov%O2%c1\t{%3, %0|%0, %3}"
19589 [(set_attr "type" "icmov")
19590 (set_attr "mode" "SI")])
19591
19592 (define_expand "movhicc"
19593 [(set (match_operand:HI 0 "register_operand" "")
19594 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19595 (match_operand:HI 2 "general_operand" "")
19596 (match_operand:HI 3 "general_operand" "")))]
19597 "TARGET_HIMODE_MATH"
19598 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19599
19600 (define_insn "*movhicc_noc"
19601 [(set (match_operand:HI 0 "register_operand" "=r,r")
19602 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19603 [(reg FLAGS_REG) (const_int 0)])
19604 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19605 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19606 "TARGET_CMOVE
19607 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19608 "@
19609 cmov%O2%C1\t{%2, %0|%0, %2}
19610 cmov%O2%c1\t{%3, %0|%0, %3}"
19611 [(set_attr "type" "icmov")
19612 (set_attr "mode" "HI")])
19613
19614 (define_expand "movqicc"
19615 [(set (match_operand:QI 0 "register_operand" "")
19616 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19617 (match_operand:QI 2 "general_operand" "")
19618 (match_operand:QI 3 "general_operand" "")))]
19619 "TARGET_QIMODE_MATH"
19620 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19621
19622 (define_insn_and_split "*movqicc_noc"
19623 [(set (match_operand:QI 0 "register_operand" "=r,r")
19624 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19625 [(match_operand 4 "flags_reg_operand" "")
19626 (const_int 0)])
19627 (match_operand:QI 2 "register_operand" "r,0")
19628 (match_operand:QI 3 "register_operand" "0,r")))]
19629 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19630 "#"
19631 "&& reload_completed"
19632 [(set (match_dup 0)
19633 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19634 (match_dup 2)
19635 (match_dup 3)))]
19636 "operands[0] = gen_lowpart (SImode, operands[0]);
19637 operands[2] = gen_lowpart (SImode, operands[2]);
19638 operands[3] = gen_lowpart (SImode, operands[3]);"
19639 [(set_attr "type" "icmov")
19640 (set_attr "mode" "SI")])
19641
19642 (define_expand "movsfcc"
19643 [(set (match_operand:SF 0 "register_operand" "")
19644 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19645 (match_operand:SF 2 "register_operand" "")
19646 (match_operand:SF 3 "register_operand" "")))]
19647 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19648 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19649
19650 (define_insn "*movsfcc_1_387"
19651 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19652 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19653 [(reg FLAGS_REG) (const_int 0)])
19654 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19655 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19656 "TARGET_80387 && TARGET_CMOVE
19657 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19658 "@
19659 fcmov%F1\t{%2, %0|%0, %2}
19660 fcmov%f1\t{%3, %0|%0, %3}
19661 cmov%O2%C1\t{%2, %0|%0, %2}
19662 cmov%O2%c1\t{%3, %0|%0, %3}"
19663 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19664 (set_attr "mode" "SF,SF,SI,SI")])
19665
19666 (define_expand "movdfcc"
19667 [(set (match_operand:DF 0 "register_operand" "")
19668 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19669 (match_operand:DF 2 "register_operand" "")
19670 (match_operand:DF 3 "register_operand" "")))]
19671 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19672 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19673
19674 (define_insn "*movdfcc_1"
19675 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19676 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19677 [(reg FLAGS_REG) (const_int 0)])
19678 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19679 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19680 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19681 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19682 "@
19683 fcmov%F1\t{%2, %0|%0, %2}
19684 fcmov%f1\t{%3, %0|%0, %3}
19685 #
19686 #"
19687 [(set_attr "type" "fcmov,fcmov,multi,multi")
19688 (set_attr "mode" "DF")])
19689
19690 (define_insn "*movdfcc_1_rex64"
19691 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19692 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19693 [(reg FLAGS_REG) (const_int 0)])
19694 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19695 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19696 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19697 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19698 "@
19699 fcmov%F1\t{%2, %0|%0, %2}
19700 fcmov%f1\t{%3, %0|%0, %3}
19701 cmov%O2%C1\t{%2, %0|%0, %2}
19702 cmov%O2%c1\t{%3, %0|%0, %3}"
19703 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19704 (set_attr "mode" "DF")])
19705
19706 (define_split
19707 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19708 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19709 [(match_operand 4 "flags_reg_operand" "")
19710 (const_int 0)])
19711 (match_operand:DF 2 "nonimmediate_operand" "")
19712 (match_operand:DF 3 "nonimmediate_operand" "")))]
19713 "!TARGET_64BIT && reload_completed"
19714 [(set (match_dup 2)
19715 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19716 (match_dup 5)
19717 (match_dup 7)))
19718 (set (match_dup 3)
19719 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19720 (match_dup 6)
19721 (match_dup 8)))]
19722 "split_di (operands+2, 1, operands+5, operands+6);
19723 split_di (operands+3, 1, operands+7, operands+8);
19724 split_di (operands, 1, operands+2, operands+3);")
19725
19726 (define_expand "movxfcc"
19727 [(set (match_operand:XF 0 "register_operand" "")
19728 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19729 (match_operand:XF 2 "register_operand" "")
19730 (match_operand:XF 3 "register_operand" "")))]
19731 "TARGET_80387 && TARGET_CMOVE"
19732 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19733
19734 (define_insn "*movxfcc_1"
19735 [(set (match_operand:XF 0 "register_operand" "=f,f")
19736 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19737 [(reg FLAGS_REG) (const_int 0)])
19738 (match_operand:XF 2 "register_operand" "f,0")
19739 (match_operand:XF 3 "register_operand" "0,f")))]
19740 "TARGET_80387 && TARGET_CMOVE"
19741 "@
19742 fcmov%F1\t{%2, %0|%0, %2}
19743 fcmov%f1\t{%3, %0|%0, %3}"
19744 [(set_attr "type" "fcmov")
19745 (set_attr "mode" "XF")])
19746
19747 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19748 ;; the scalar versions to have only XMM registers as operands.
19749
19750 ;; SSE5 conditional move
19751 (define_insn "*sse5_pcmov_<mode>"
19752 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19753 (if_then_else:MODEF
19754 (match_operand:MODEF 1 "register_operand" "x,0")
19755 (match_operand:MODEF 2 "register_operand" "0,x")
19756 (match_operand:MODEF 3 "register_operand" "x,x")))]
19757 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19758 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19759 [(set_attr "type" "sse4arg")])
19760
19761 ;; These versions of the min/max patterns are intentionally ignorant of
19762 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19763 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19764 ;; are undefined in this condition, we're certain this is correct.
19765
19766 (define_insn "sminsf3"
19767 [(set (match_operand:SF 0 "register_operand" "=x")
19768 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19769 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19770 "TARGET_SSE_MATH"
19771 "minss\t{%2, %0|%0, %2}"
19772 [(set_attr "type" "sseadd")
19773 (set_attr "mode" "SF")])
19774
19775 (define_insn "smaxsf3"
19776 [(set (match_operand:SF 0 "register_operand" "=x")
19777 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19778 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19779 "TARGET_SSE_MATH"
19780 "maxss\t{%2, %0|%0, %2}"
19781 [(set_attr "type" "sseadd")
19782 (set_attr "mode" "SF")])
19783
19784 (define_insn "smindf3"
19785 [(set (match_operand:DF 0 "register_operand" "=x")
19786 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19787 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19788 "TARGET_SSE2 && TARGET_SSE_MATH"
19789 "minsd\t{%2, %0|%0, %2}"
19790 [(set_attr "type" "sseadd")
19791 (set_attr "mode" "DF")])
19792
19793 (define_insn "smaxdf3"
19794 [(set (match_operand:DF 0 "register_operand" "=x")
19795 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19796 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19797 "TARGET_SSE2 && TARGET_SSE_MATH"
19798 "maxsd\t{%2, %0|%0, %2}"
19799 [(set_attr "type" "sseadd")
19800 (set_attr "mode" "DF")])
19801
19802 ;; These versions of the min/max patterns implement exactly the operations
19803 ;; min = (op1 < op2 ? op1 : op2)
19804 ;; max = (!(op1 < op2) ? op1 : op2)
19805 ;; Their operands are not commutative, and thus they may be used in the
19806 ;; presence of -0.0 and NaN.
19807
19808 (define_insn "*ieee_sminsf3"
19809 [(set (match_operand:SF 0 "register_operand" "=x")
19810 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19811 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19812 UNSPEC_IEEE_MIN))]
19813 "TARGET_SSE_MATH"
19814 "minss\t{%2, %0|%0, %2}"
19815 [(set_attr "type" "sseadd")
19816 (set_attr "mode" "SF")])
19817
19818 (define_insn "*ieee_smaxsf3"
19819 [(set (match_operand:SF 0 "register_operand" "=x")
19820 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19821 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19822 UNSPEC_IEEE_MAX))]
19823 "TARGET_SSE_MATH"
19824 "maxss\t{%2, %0|%0, %2}"
19825 [(set_attr "type" "sseadd")
19826 (set_attr "mode" "SF")])
19827
19828 (define_insn "*ieee_smindf3"
19829 [(set (match_operand:DF 0 "register_operand" "=x")
19830 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19831 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19832 UNSPEC_IEEE_MIN))]
19833 "TARGET_SSE2 && TARGET_SSE_MATH"
19834 "minsd\t{%2, %0|%0, %2}"
19835 [(set_attr "type" "sseadd")
19836 (set_attr "mode" "DF")])
19837
19838 (define_insn "*ieee_smaxdf3"
19839 [(set (match_operand:DF 0 "register_operand" "=x")
19840 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19841 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19842 UNSPEC_IEEE_MAX))]
19843 "TARGET_SSE2 && TARGET_SSE_MATH"
19844 "maxsd\t{%2, %0|%0, %2}"
19845 [(set_attr "type" "sseadd")
19846 (set_attr "mode" "DF")])
19847
19848 ;; Make two stack loads independent:
19849 ;; fld aa fld aa
19850 ;; fld %st(0) -> fld bb
19851 ;; fmul bb fmul %st(1), %st
19852 ;;
19853 ;; Actually we only match the last two instructions for simplicity.
19854 (define_peephole2
19855 [(set (match_operand 0 "fp_register_operand" "")
19856 (match_operand 1 "fp_register_operand" ""))
19857 (set (match_dup 0)
19858 (match_operator 2 "binary_fp_operator"
19859 [(match_dup 0)
19860 (match_operand 3 "memory_operand" "")]))]
19861 "REGNO (operands[0]) != REGNO (operands[1])"
19862 [(set (match_dup 0) (match_dup 3))
19863 (set (match_dup 0) (match_dup 4))]
19864
19865 ;; The % modifier is not operational anymore in peephole2's, so we have to
19866 ;; swap the operands manually in the case of addition and multiplication.
19867 "if (COMMUTATIVE_ARITH_P (operands[2]))
19868 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19869 operands[0], operands[1]);
19870 else
19871 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19872 operands[1], operands[0]);")
19873
19874 ;; Conditional addition patterns
19875 (define_expand "addqicc"
19876 [(match_operand:QI 0 "register_operand" "")
19877 (match_operand 1 "comparison_operator" "")
19878 (match_operand:QI 2 "register_operand" "")
19879 (match_operand:QI 3 "const_int_operand" "")]
19880 ""
19881 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19882
19883 (define_expand "addhicc"
19884 [(match_operand:HI 0 "register_operand" "")
19885 (match_operand 1 "comparison_operator" "")
19886 (match_operand:HI 2 "register_operand" "")
19887 (match_operand:HI 3 "const_int_operand" "")]
19888 ""
19889 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19890
19891 (define_expand "addsicc"
19892 [(match_operand:SI 0 "register_operand" "")
19893 (match_operand 1 "comparison_operator" "")
19894 (match_operand:SI 2 "register_operand" "")
19895 (match_operand:SI 3 "const_int_operand" "")]
19896 ""
19897 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19898
19899 (define_expand "adddicc"
19900 [(match_operand:DI 0 "register_operand" "")
19901 (match_operand 1 "comparison_operator" "")
19902 (match_operand:DI 2 "register_operand" "")
19903 (match_operand:DI 3 "const_int_operand" "")]
19904 "TARGET_64BIT"
19905 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19906
19907 \f
19908 ;; Misc patterns (?)
19909
19910 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19911 ;; Otherwise there will be nothing to keep
19912 ;;
19913 ;; [(set (reg ebp) (reg esp))]
19914 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19915 ;; (clobber (eflags)]
19916 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19917 ;;
19918 ;; in proper program order.
19919 (define_insn "pro_epilogue_adjust_stack_1"
19920 [(set (match_operand:SI 0 "register_operand" "=r,r")
19921 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19922 (match_operand:SI 2 "immediate_operand" "i,i")))
19923 (clobber (reg:CC FLAGS_REG))
19924 (clobber (mem:BLK (scratch)))]
19925 "!TARGET_64BIT"
19926 {
19927 switch (get_attr_type (insn))
19928 {
19929 case TYPE_IMOV:
19930 return "mov{l}\t{%1, %0|%0, %1}";
19931
19932 case TYPE_ALU:
19933 if (CONST_INT_P (operands[2])
19934 && (INTVAL (operands[2]) == 128
19935 || (INTVAL (operands[2]) < 0
19936 && INTVAL (operands[2]) != -128)))
19937 {
19938 operands[2] = GEN_INT (-INTVAL (operands[2]));
19939 return "sub{l}\t{%2, %0|%0, %2}";
19940 }
19941 return "add{l}\t{%2, %0|%0, %2}";
19942
19943 case TYPE_LEA:
19944 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19945 return "lea{l}\t{%a2, %0|%0, %a2}";
19946
19947 default:
19948 gcc_unreachable ();
19949 }
19950 }
19951 [(set (attr "type")
19952 (cond [(eq_attr "alternative" "0")
19953 (const_string "alu")
19954 (match_operand:SI 2 "const0_operand" "")
19955 (const_string "imov")
19956 ]
19957 (const_string "lea")))
19958 (set_attr "mode" "SI")])
19959
19960 (define_insn "pro_epilogue_adjust_stack_rex64"
19961 [(set (match_operand:DI 0 "register_operand" "=r,r")
19962 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19963 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19964 (clobber (reg:CC FLAGS_REG))
19965 (clobber (mem:BLK (scratch)))]
19966 "TARGET_64BIT"
19967 {
19968 switch (get_attr_type (insn))
19969 {
19970 case TYPE_IMOV:
19971 return "mov{q}\t{%1, %0|%0, %1}";
19972
19973 case TYPE_ALU:
19974 if (CONST_INT_P (operands[2])
19975 /* Avoid overflows. */
19976 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19977 && (INTVAL (operands[2]) == 128
19978 || (INTVAL (operands[2]) < 0
19979 && INTVAL (operands[2]) != -128)))
19980 {
19981 operands[2] = GEN_INT (-INTVAL (operands[2]));
19982 return "sub{q}\t{%2, %0|%0, %2}";
19983 }
19984 return "add{q}\t{%2, %0|%0, %2}";
19985
19986 case TYPE_LEA:
19987 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19988 return "lea{q}\t{%a2, %0|%0, %a2}";
19989
19990 default:
19991 gcc_unreachable ();
19992 }
19993 }
19994 [(set (attr "type")
19995 (cond [(eq_attr "alternative" "0")
19996 (const_string "alu")
19997 (match_operand:DI 2 "const0_operand" "")
19998 (const_string "imov")
19999 ]
20000 (const_string "lea")))
20001 (set_attr "mode" "DI")])
20002
20003 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20004 [(set (match_operand:DI 0 "register_operand" "=r,r")
20005 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20006 (match_operand:DI 3 "immediate_operand" "i,i")))
20007 (use (match_operand:DI 2 "register_operand" "r,r"))
20008 (clobber (reg:CC FLAGS_REG))
20009 (clobber (mem:BLK (scratch)))]
20010 "TARGET_64BIT"
20011 {
20012 switch (get_attr_type (insn))
20013 {
20014 case TYPE_ALU:
20015 return "add{q}\t{%2, %0|%0, %2}";
20016
20017 case TYPE_LEA:
20018 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20019 return "lea{q}\t{%a2, %0|%0, %a2}";
20020
20021 default:
20022 gcc_unreachable ();
20023 }
20024 }
20025 [(set_attr "type" "alu,lea")
20026 (set_attr "mode" "DI")])
20027
20028 (define_insn "allocate_stack_worker_32"
20029 [(set (match_operand:SI 0 "register_operand" "+a")
20030 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
20031 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
20032 (clobber (reg:CC FLAGS_REG))]
20033 "!TARGET_64BIT && TARGET_STACK_PROBE"
20034 "call\t__alloca"
20035 [(set_attr "type" "multi")
20036 (set_attr "length" "5")])
20037
20038 (define_insn "allocate_stack_worker_64"
20039 [(set (match_operand:DI 0 "register_operand" "=a")
20040 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
20041 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
20042 (clobber (reg:DI R10_REG))
20043 (clobber (reg:DI R11_REG))
20044 (clobber (reg:CC FLAGS_REG))]
20045 "TARGET_64BIT && TARGET_STACK_PROBE"
20046 "call\t___chkstk"
20047 [(set_attr "type" "multi")
20048 (set_attr "length" "5")])
20049
20050 (define_expand "allocate_stack"
20051 [(match_operand 0 "register_operand" "")
20052 (match_operand 1 "general_operand" "")]
20053 "TARGET_STACK_PROBE"
20054 {
20055 rtx x;
20056
20057 #ifndef CHECK_STACK_LIMIT
20058 #define CHECK_STACK_LIMIT 0
20059 #endif
20060
20061 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20062 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20063 {
20064 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20065 stack_pointer_rtx, 0, OPTAB_DIRECT);
20066 if (x != stack_pointer_rtx)
20067 emit_move_insn (stack_pointer_rtx, x);
20068 }
20069 else
20070 {
20071 x = copy_to_mode_reg (Pmode, operands[1]);
20072 if (TARGET_64BIT)
20073 x = gen_allocate_stack_worker_64 (x);
20074 else
20075 x = gen_allocate_stack_worker_32 (x);
20076 emit_insn (x);
20077 }
20078
20079 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20080 DONE;
20081 })
20082
20083 (define_expand "builtin_setjmp_receiver"
20084 [(label_ref (match_operand 0 "" ""))]
20085 "!TARGET_64BIT && flag_pic"
20086 {
20087 if (TARGET_MACHO)
20088 {
20089 rtx xops[3];
20090 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20091 rtx label_rtx = gen_label_rtx ();
20092 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20093 xops[0] = xops[1] = picreg;
20094 xops[2] = gen_rtx_CONST (SImode,
20095 gen_rtx_MINUS (SImode,
20096 gen_rtx_LABEL_REF (SImode, label_rtx),
20097 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
20098 ix86_expand_binary_operator (MINUS, SImode, xops);
20099 }
20100 else
20101 emit_insn (gen_set_got (pic_offset_table_rtx));
20102 DONE;
20103 })
20104 \f
20105 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20106
20107 (define_split
20108 [(set (match_operand 0 "register_operand" "")
20109 (match_operator 3 "promotable_binary_operator"
20110 [(match_operand 1 "register_operand" "")
20111 (match_operand 2 "aligned_operand" "")]))
20112 (clobber (reg:CC FLAGS_REG))]
20113 "! TARGET_PARTIAL_REG_STALL && reload_completed
20114 && ((GET_MODE (operands[0]) == HImode
20115 && ((!optimize_size && !TARGET_FAST_PREFIX)
20116 /* ??? next two lines just !satisfies_constraint_K (...) */
20117 || !CONST_INT_P (operands[2])
20118 || satisfies_constraint_K (operands[2])))
20119 || (GET_MODE (operands[0]) == QImode
20120 && (TARGET_PROMOTE_QImode || optimize_size)))"
20121 [(parallel [(set (match_dup 0)
20122 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20123 (clobber (reg:CC FLAGS_REG))])]
20124 "operands[0] = gen_lowpart (SImode, operands[0]);
20125 operands[1] = gen_lowpart (SImode, operands[1]);
20126 if (GET_CODE (operands[3]) != ASHIFT)
20127 operands[2] = gen_lowpart (SImode, operands[2]);
20128 PUT_MODE (operands[3], SImode);")
20129
20130 ; Promote the QImode tests, as i386 has encoding of the AND
20131 ; instruction with 32-bit sign-extended immediate and thus the
20132 ; instruction size is unchanged, except in the %eax case for
20133 ; which it is increased by one byte, hence the ! optimize_size.
20134 (define_split
20135 [(set (match_operand 0 "flags_reg_operand" "")
20136 (match_operator 2 "compare_operator"
20137 [(and (match_operand 3 "aligned_operand" "")
20138 (match_operand 4 "const_int_operand" ""))
20139 (const_int 0)]))
20140 (set (match_operand 1 "register_operand" "")
20141 (and (match_dup 3) (match_dup 4)))]
20142 "! TARGET_PARTIAL_REG_STALL && reload_completed
20143 && ! optimize_size
20144 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20145 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20146 /* Ensure that the operand will remain sign-extended immediate. */
20147 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20148 [(parallel [(set (match_dup 0)
20149 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20150 (const_int 0)]))
20151 (set (match_dup 1)
20152 (and:SI (match_dup 3) (match_dup 4)))])]
20153 {
20154 operands[4]
20155 = gen_int_mode (INTVAL (operands[4])
20156 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20157 operands[1] = gen_lowpart (SImode, operands[1]);
20158 operands[3] = gen_lowpart (SImode, operands[3]);
20159 })
20160
20161 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20162 ; the TEST instruction with 32-bit sign-extended immediate and thus
20163 ; the instruction size would at least double, which is not what we
20164 ; want even with ! optimize_size.
20165 (define_split
20166 [(set (match_operand 0 "flags_reg_operand" "")
20167 (match_operator 1 "compare_operator"
20168 [(and (match_operand:HI 2 "aligned_operand" "")
20169 (match_operand:HI 3 "const_int_operand" ""))
20170 (const_int 0)]))]
20171 "! TARGET_PARTIAL_REG_STALL && reload_completed
20172 && ! TARGET_FAST_PREFIX
20173 && ! optimize_size
20174 /* Ensure that the operand will remain sign-extended immediate. */
20175 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20176 [(set (match_dup 0)
20177 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20178 (const_int 0)]))]
20179 {
20180 operands[3]
20181 = gen_int_mode (INTVAL (operands[3])
20182 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20183 operands[2] = gen_lowpart (SImode, operands[2]);
20184 })
20185
20186 (define_split
20187 [(set (match_operand 0 "register_operand" "")
20188 (neg (match_operand 1 "register_operand" "")))
20189 (clobber (reg:CC FLAGS_REG))]
20190 "! TARGET_PARTIAL_REG_STALL && reload_completed
20191 && (GET_MODE (operands[0]) == HImode
20192 || (GET_MODE (operands[0]) == QImode
20193 && (TARGET_PROMOTE_QImode || optimize_size)))"
20194 [(parallel [(set (match_dup 0)
20195 (neg:SI (match_dup 1)))
20196 (clobber (reg:CC FLAGS_REG))])]
20197 "operands[0] = gen_lowpart (SImode, operands[0]);
20198 operands[1] = gen_lowpart (SImode, operands[1]);")
20199
20200 (define_split
20201 [(set (match_operand 0 "register_operand" "")
20202 (not (match_operand 1 "register_operand" "")))]
20203 "! TARGET_PARTIAL_REG_STALL && reload_completed
20204 && (GET_MODE (operands[0]) == HImode
20205 || (GET_MODE (operands[0]) == QImode
20206 && (TARGET_PROMOTE_QImode || optimize_size)))"
20207 [(set (match_dup 0)
20208 (not:SI (match_dup 1)))]
20209 "operands[0] = gen_lowpart (SImode, operands[0]);
20210 operands[1] = gen_lowpart (SImode, operands[1]);")
20211
20212 (define_split
20213 [(set (match_operand 0 "register_operand" "")
20214 (if_then_else (match_operator 1 "comparison_operator"
20215 [(reg FLAGS_REG) (const_int 0)])
20216 (match_operand 2 "register_operand" "")
20217 (match_operand 3 "register_operand" "")))]
20218 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20219 && (GET_MODE (operands[0]) == HImode
20220 || (GET_MODE (operands[0]) == QImode
20221 && (TARGET_PROMOTE_QImode || optimize_size)))"
20222 [(set (match_dup 0)
20223 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20224 "operands[0] = gen_lowpart (SImode, operands[0]);
20225 operands[2] = gen_lowpart (SImode, operands[2]);
20226 operands[3] = gen_lowpart (SImode, operands[3]);")
20227
20228 \f
20229 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20230 ;; transform a complex memory operation into two memory to register operations.
20231
20232 ;; Don't push memory operands
20233 (define_peephole2
20234 [(set (match_operand:SI 0 "push_operand" "")
20235 (match_operand:SI 1 "memory_operand" ""))
20236 (match_scratch:SI 2 "r")]
20237 "!optimize_size && !TARGET_PUSH_MEMORY
20238 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20239 [(set (match_dup 2) (match_dup 1))
20240 (set (match_dup 0) (match_dup 2))]
20241 "")
20242
20243 (define_peephole2
20244 [(set (match_operand:DI 0 "push_operand" "")
20245 (match_operand:DI 1 "memory_operand" ""))
20246 (match_scratch:DI 2 "r")]
20247 "!optimize_size && !TARGET_PUSH_MEMORY
20248 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20249 [(set (match_dup 2) (match_dup 1))
20250 (set (match_dup 0) (match_dup 2))]
20251 "")
20252
20253 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20254 ;; SImode pushes.
20255 (define_peephole2
20256 [(set (match_operand:SF 0 "push_operand" "")
20257 (match_operand:SF 1 "memory_operand" ""))
20258 (match_scratch:SF 2 "r")]
20259 "!optimize_size && !TARGET_PUSH_MEMORY
20260 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20261 [(set (match_dup 2) (match_dup 1))
20262 (set (match_dup 0) (match_dup 2))]
20263 "")
20264
20265 (define_peephole2
20266 [(set (match_operand:HI 0 "push_operand" "")
20267 (match_operand:HI 1 "memory_operand" ""))
20268 (match_scratch:HI 2 "r")]
20269 "!optimize_size && !TARGET_PUSH_MEMORY
20270 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20271 [(set (match_dup 2) (match_dup 1))
20272 (set (match_dup 0) (match_dup 2))]
20273 "")
20274
20275 (define_peephole2
20276 [(set (match_operand:QI 0 "push_operand" "")
20277 (match_operand:QI 1 "memory_operand" ""))
20278 (match_scratch:QI 2 "q")]
20279 "!optimize_size && !TARGET_PUSH_MEMORY
20280 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20281 [(set (match_dup 2) (match_dup 1))
20282 (set (match_dup 0) (match_dup 2))]
20283 "")
20284
20285 ;; Don't move an immediate directly to memory when the instruction
20286 ;; gets too big.
20287 (define_peephole2
20288 [(match_scratch:SI 1 "r")
20289 (set (match_operand:SI 0 "memory_operand" "")
20290 (const_int 0))]
20291 "! optimize_size
20292 && ! TARGET_USE_MOV0
20293 && TARGET_SPLIT_LONG_MOVES
20294 && get_attr_length (insn) >= ix86_cost->large_insn
20295 && peep2_regno_dead_p (0, FLAGS_REG)"
20296 [(parallel [(set (match_dup 1) (const_int 0))
20297 (clobber (reg:CC FLAGS_REG))])
20298 (set (match_dup 0) (match_dup 1))]
20299 "")
20300
20301 (define_peephole2
20302 [(match_scratch:HI 1 "r")
20303 (set (match_operand:HI 0 "memory_operand" "")
20304 (const_int 0))]
20305 "! optimize_size
20306 && ! TARGET_USE_MOV0
20307 && TARGET_SPLIT_LONG_MOVES
20308 && get_attr_length (insn) >= ix86_cost->large_insn
20309 && peep2_regno_dead_p (0, FLAGS_REG)"
20310 [(parallel [(set (match_dup 2) (const_int 0))
20311 (clobber (reg:CC FLAGS_REG))])
20312 (set (match_dup 0) (match_dup 1))]
20313 "operands[2] = gen_lowpart (SImode, operands[1]);")
20314
20315 (define_peephole2
20316 [(match_scratch:QI 1 "q")
20317 (set (match_operand:QI 0 "memory_operand" "")
20318 (const_int 0))]
20319 "! optimize_size
20320 && ! TARGET_USE_MOV0
20321 && TARGET_SPLIT_LONG_MOVES
20322 && get_attr_length (insn) >= ix86_cost->large_insn
20323 && peep2_regno_dead_p (0, FLAGS_REG)"
20324 [(parallel [(set (match_dup 2) (const_int 0))
20325 (clobber (reg:CC FLAGS_REG))])
20326 (set (match_dup 0) (match_dup 1))]
20327 "operands[2] = gen_lowpart (SImode, operands[1]);")
20328
20329 (define_peephole2
20330 [(match_scratch:SI 2 "r")
20331 (set (match_operand:SI 0 "memory_operand" "")
20332 (match_operand:SI 1 "immediate_operand" ""))]
20333 "! optimize_size
20334 && TARGET_SPLIT_LONG_MOVES
20335 && get_attr_length (insn) >= ix86_cost->large_insn"
20336 [(set (match_dup 2) (match_dup 1))
20337 (set (match_dup 0) (match_dup 2))]
20338 "")
20339
20340 (define_peephole2
20341 [(match_scratch:HI 2 "r")
20342 (set (match_operand:HI 0 "memory_operand" "")
20343 (match_operand:HI 1 "immediate_operand" ""))]
20344 "! optimize_size
20345 && TARGET_SPLIT_LONG_MOVES
20346 && get_attr_length (insn) >= ix86_cost->large_insn"
20347 [(set (match_dup 2) (match_dup 1))
20348 (set (match_dup 0) (match_dup 2))]
20349 "")
20350
20351 (define_peephole2
20352 [(match_scratch:QI 2 "q")
20353 (set (match_operand:QI 0 "memory_operand" "")
20354 (match_operand:QI 1 "immediate_operand" ""))]
20355 "! optimize_size
20356 && TARGET_SPLIT_LONG_MOVES
20357 && get_attr_length (insn) >= ix86_cost->large_insn"
20358 [(set (match_dup 2) (match_dup 1))
20359 (set (match_dup 0) (match_dup 2))]
20360 "")
20361
20362 ;; Don't compare memory with zero, load and use a test instead.
20363 (define_peephole2
20364 [(set (match_operand 0 "flags_reg_operand" "")
20365 (match_operator 1 "compare_operator"
20366 [(match_operand:SI 2 "memory_operand" "")
20367 (const_int 0)]))
20368 (match_scratch:SI 3 "r")]
20369 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20370 [(set (match_dup 3) (match_dup 2))
20371 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20372 "")
20373
20374 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20375 ;; Don't split NOTs with a displacement operand, because resulting XOR
20376 ;; will not be pairable anyway.
20377 ;;
20378 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20379 ;; represented using a modRM byte. The XOR replacement is long decoded,
20380 ;; so this split helps here as well.
20381 ;;
20382 ;; Note: Can't do this as a regular split because we can't get proper
20383 ;; lifetime information then.
20384
20385 (define_peephole2
20386 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20387 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20388 "!optimize_size
20389 && ((TARGET_NOT_UNPAIRABLE
20390 && (!MEM_P (operands[0])
20391 || !memory_displacement_operand (operands[0], SImode)))
20392 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20393 && peep2_regno_dead_p (0, FLAGS_REG)"
20394 [(parallel [(set (match_dup 0)
20395 (xor:SI (match_dup 1) (const_int -1)))
20396 (clobber (reg:CC FLAGS_REG))])]
20397 "")
20398
20399 (define_peephole2
20400 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20401 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20402 "!optimize_size
20403 && ((TARGET_NOT_UNPAIRABLE
20404 && (!MEM_P (operands[0])
20405 || !memory_displacement_operand (operands[0], HImode)))
20406 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20407 && peep2_regno_dead_p (0, FLAGS_REG)"
20408 [(parallel [(set (match_dup 0)
20409 (xor:HI (match_dup 1) (const_int -1)))
20410 (clobber (reg:CC FLAGS_REG))])]
20411 "")
20412
20413 (define_peephole2
20414 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20415 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20416 "!optimize_size
20417 && ((TARGET_NOT_UNPAIRABLE
20418 && (!MEM_P (operands[0])
20419 || !memory_displacement_operand (operands[0], QImode)))
20420 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20421 && peep2_regno_dead_p (0, FLAGS_REG)"
20422 [(parallel [(set (match_dup 0)
20423 (xor:QI (match_dup 1) (const_int -1)))
20424 (clobber (reg:CC FLAGS_REG))])]
20425 "")
20426
20427 ;; Non pairable "test imm, reg" instructions can be translated to
20428 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20429 ;; byte opcode instead of two, have a short form for byte operands),
20430 ;; so do it for other CPUs as well. Given that the value was dead,
20431 ;; this should not create any new dependencies. Pass on the sub-word
20432 ;; versions if we're concerned about partial register stalls.
20433
20434 (define_peephole2
20435 [(set (match_operand 0 "flags_reg_operand" "")
20436 (match_operator 1 "compare_operator"
20437 [(and:SI (match_operand:SI 2 "register_operand" "")
20438 (match_operand:SI 3 "immediate_operand" ""))
20439 (const_int 0)]))]
20440 "ix86_match_ccmode (insn, CCNOmode)
20441 && (true_regnum (operands[2]) != AX_REG
20442 || satisfies_constraint_K (operands[3]))
20443 && peep2_reg_dead_p (1, operands[2])"
20444 [(parallel
20445 [(set (match_dup 0)
20446 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20447 (const_int 0)]))
20448 (set (match_dup 2)
20449 (and:SI (match_dup 2) (match_dup 3)))])]
20450 "")
20451
20452 ;; We don't need to handle HImode case, because it will be promoted to SImode
20453 ;; on ! TARGET_PARTIAL_REG_STALL
20454
20455 (define_peephole2
20456 [(set (match_operand 0 "flags_reg_operand" "")
20457 (match_operator 1 "compare_operator"
20458 [(and:QI (match_operand:QI 2 "register_operand" "")
20459 (match_operand:QI 3 "immediate_operand" ""))
20460 (const_int 0)]))]
20461 "! TARGET_PARTIAL_REG_STALL
20462 && ix86_match_ccmode (insn, CCNOmode)
20463 && true_regnum (operands[2]) != AX_REG
20464 && peep2_reg_dead_p (1, operands[2])"
20465 [(parallel
20466 [(set (match_dup 0)
20467 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20468 (const_int 0)]))
20469 (set (match_dup 2)
20470 (and:QI (match_dup 2) (match_dup 3)))])]
20471 "")
20472
20473 (define_peephole2
20474 [(set (match_operand 0 "flags_reg_operand" "")
20475 (match_operator 1 "compare_operator"
20476 [(and:SI
20477 (zero_extract:SI
20478 (match_operand 2 "ext_register_operand" "")
20479 (const_int 8)
20480 (const_int 8))
20481 (match_operand 3 "const_int_operand" ""))
20482 (const_int 0)]))]
20483 "! TARGET_PARTIAL_REG_STALL
20484 && ix86_match_ccmode (insn, CCNOmode)
20485 && true_regnum (operands[2]) != AX_REG
20486 && peep2_reg_dead_p (1, operands[2])"
20487 [(parallel [(set (match_dup 0)
20488 (match_op_dup 1
20489 [(and:SI
20490 (zero_extract:SI
20491 (match_dup 2)
20492 (const_int 8)
20493 (const_int 8))
20494 (match_dup 3))
20495 (const_int 0)]))
20496 (set (zero_extract:SI (match_dup 2)
20497 (const_int 8)
20498 (const_int 8))
20499 (and:SI
20500 (zero_extract:SI
20501 (match_dup 2)
20502 (const_int 8)
20503 (const_int 8))
20504 (match_dup 3)))])]
20505 "")
20506
20507 ;; Don't do logical operations with memory inputs.
20508 (define_peephole2
20509 [(match_scratch:SI 2 "r")
20510 (parallel [(set (match_operand:SI 0 "register_operand" "")
20511 (match_operator:SI 3 "arith_or_logical_operator"
20512 [(match_dup 0)
20513 (match_operand:SI 1 "memory_operand" "")]))
20514 (clobber (reg:CC FLAGS_REG))])]
20515 "! optimize_size && ! TARGET_READ_MODIFY"
20516 [(set (match_dup 2) (match_dup 1))
20517 (parallel [(set (match_dup 0)
20518 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20519 (clobber (reg:CC FLAGS_REG))])]
20520 "")
20521
20522 (define_peephole2
20523 [(match_scratch:SI 2 "r")
20524 (parallel [(set (match_operand:SI 0 "register_operand" "")
20525 (match_operator:SI 3 "arith_or_logical_operator"
20526 [(match_operand:SI 1 "memory_operand" "")
20527 (match_dup 0)]))
20528 (clobber (reg:CC FLAGS_REG))])]
20529 "! optimize_size && ! TARGET_READ_MODIFY"
20530 [(set (match_dup 2) (match_dup 1))
20531 (parallel [(set (match_dup 0)
20532 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20533 (clobber (reg:CC FLAGS_REG))])]
20534 "")
20535
20536 ; Don't do logical operations with memory outputs
20537 ;
20538 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20539 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20540 ; the same decoder scheduling characteristics as the original.
20541
20542 (define_peephole2
20543 [(match_scratch:SI 2 "r")
20544 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20545 (match_operator:SI 3 "arith_or_logical_operator"
20546 [(match_dup 0)
20547 (match_operand:SI 1 "nonmemory_operand" "")]))
20548 (clobber (reg:CC FLAGS_REG))])]
20549 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20550 [(set (match_dup 2) (match_dup 0))
20551 (parallel [(set (match_dup 2)
20552 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20553 (clobber (reg:CC FLAGS_REG))])
20554 (set (match_dup 0) (match_dup 2))]
20555 "")
20556
20557 (define_peephole2
20558 [(match_scratch:SI 2 "r")
20559 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20560 (match_operator:SI 3 "arith_or_logical_operator"
20561 [(match_operand:SI 1 "nonmemory_operand" "")
20562 (match_dup 0)]))
20563 (clobber (reg:CC FLAGS_REG))])]
20564 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20565 [(set (match_dup 2) (match_dup 0))
20566 (parallel [(set (match_dup 2)
20567 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20568 (clobber (reg:CC FLAGS_REG))])
20569 (set (match_dup 0) (match_dup 2))]
20570 "")
20571
20572 ;; Attempt to always use XOR for zeroing registers.
20573 (define_peephole2
20574 [(set (match_operand 0 "register_operand" "")
20575 (match_operand 1 "const0_operand" ""))]
20576 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20577 && (! TARGET_USE_MOV0 || optimize_size)
20578 && GENERAL_REG_P (operands[0])
20579 && peep2_regno_dead_p (0, FLAGS_REG)"
20580 [(parallel [(set (match_dup 0) (const_int 0))
20581 (clobber (reg:CC FLAGS_REG))])]
20582 {
20583 operands[0] = gen_lowpart (word_mode, operands[0]);
20584 })
20585
20586 (define_peephole2
20587 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20588 (const_int 0))]
20589 "(GET_MODE (operands[0]) == QImode
20590 || GET_MODE (operands[0]) == HImode)
20591 && (! TARGET_USE_MOV0 || optimize_size)
20592 && peep2_regno_dead_p (0, FLAGS_REG)"
20593 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20594 (clobber (reg:CC FLAGS_REG))])])
20595
20596 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20597 (define_peephole2
20598 [(set (match_operand 0 "register_operand" "")
20599 (const_int -1))]
20600 "(GET_MODE (operands[0]) == HImode
20601 || GET_MODE (operands[0]) == SImode
20602 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20603 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20604 && peep2_regno_dead_p (0, FLAGS_REG)"
20605 [(parallel [(set (match_dup 0) (const_int -1))
20606 (clobber (reg:CC FLAGS_REG))])]
20607 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20608 operands[0]);")
20609
20610 ;; Attempt to convert simple leas to adds. These can be created by
20611 ;; move expanders.
20612 (define_peephole2
20613 [(set (match_operand:SI 0 "register_operand" "")
20614 (plus:SI (match_dup 0)
20615 (match_operand:SI 1 "nonmemory_operand" "")))]
20616 "peep2_regno_dead_p (0, FLAGS_REG)"
20617 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20618 (clobber (reg:CC FLAGS_REG))])]
20619 "")
20620
20621 (define_peephole2
20622 [(set (match_operand:SI 0 "register_operand" "")
20623 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20624 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20625 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20626 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20627 (clobber (reg:CC FLAGS_REG))])]
20628 "operands[2] = gen_lowpart (SImode, operands[2]);")
20629
20630 (define_peephole2
20631 [(set (match_operand:DI 0 "register_operand" "")
20632 (plus:DI (match_dup 0)
20633 (match_operand:DI 1 "x86_64_general_operand" "")))]
20634 "peep2_regno_dead_p (0, FLAGS_REG)"
20635 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20636 (clobber (reg:CC FLAGS_REG))])]
20637 "")
20638
20639 (define_peephole2
20640 [(set (match_operand:SI 0 "register_operand" "")
20641 (mult:SI (match_dup 0)
20642 (match_operand:SI 1 "const_int_operand" "")))]
20643 "exact_log2 (INTVAL (operands[1])) >= 0
20644 && peep2_regno_dead_p (0, FLAGS_REG)"
20645 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20646 (clobber (reg:CC FLAGS_REG))])]
20647 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20648
20649 (define_peephole2
20650 [(set (match_operand:DI 0 "register_operand" "")
20651 (mult:DI (match_dup 0)
20652 (match_operand:DI 1 "const_int_operand" "")))]
20653 "exact_log2 (INTVAL (operands[1])) >= 0
20654 && peep2_regno_dead_p (0, FLAGS_REG)"
20655 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20656 (clobber (reg:CC FLAGS_REG))])]
20657 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20658
20659 (define_peephole2
20660 [(set (match_operand:SI 0 "register_operand" "")
20661 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20662 (match_operand:DI 2 "const_int_operand" "")) 0))]
20663 "exact_log2 (INTVAL (operands[2])) >= 0
20664 && REGNO (operands[0]) == REGNO (operands[1])
20665 && peep2_regno_dead_p (0, FLAGS_REG)"
20666 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20667 (clobber (reg:CC FLAGS_REG))])]
20668 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20669
20670 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20671 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20672 ;; many CPUs it is also faster, since special hardware to avoid esp
20673 ;; dependencies is present.
20674
20675 ;; While some of these conversions may be done using splitters, we use peepholes
20676 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20677
20678 ;; Convert prologue esp subtractions to push.
20679 ;; We need register to push. In order to keep verify_flow_info happy we have
20680 ;; two choices
20681 ;; - use scratch and clobber it in order to avoid dependencies
20682 ;; - use already live register
20683 ;; We can't use the second way right now, since there is no reliable way how to
20684 ;; verify that given register is live. First choice will also most likely in
20685 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20686 ;; call clobbered registers are dead. We may want to use base pointer as an
20687 ;; alternative when no register is available later.
20688
20689 (define_peephole2
20690 [(match_scratch:SI 0 "r")
20691 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20692 (clobber (reg:CC FLAGS_REG))
20693 (clobber (mem:BLK (scratch)))])]
20694 "optimize_size || !TARGET_SUB_ESP_4"
20695 [(clobber (match_dup 0))
20696 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20697 (clobber (mem:BLK (scratch)))])])
20698
20699 (define_peephole2
20700 [(match_scratch:SI 0 "r")
20701 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20702 (clobber (reg:CC FLAGS_REG))
20703 (clobber (mem:BLK (scratch)))])]
20704 "optimize_size || !TARGET_SUB_ESP_8"
20705 [(clobber (match_dup 0))
20706 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20707 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20708 (clobber (mem:BLK (scratch)))])])
20709
20710 ;; Convert esp subtractions to push.
20711 (define_peephole2
20712 [(match_scratch:SI 0 "r")
20713 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20714 (clobber (reg:CC FLAGS_REG))])]
20715 "optimize_size || !TARGET_SUB_ESP_4"
20716 [(clobber (match_dup 0))
20717 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20718
20719 (define_peephole2
20720 [(match_scratch:SI 0 "r")
20721 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20722 (clobber (reg:CC FLAGS_REG))])]
20723 "optimize_size || !TARGET_SUB_ESP_8"
20724 [(clobber (match_dup 0))
20725 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20726 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20727
20728 ;; Convert epilogue deallocator to pop.
20729 (define_peephole2
20730 [(match_scratch:SI 0 "r")
20731 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20732 (clobber (reg:CC FLAGS_REG))
20733 (clobber (mem:BLK (scratch)))])]
20734 "optimize_size || !TARGET_ADD_ESP_4"
20735 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20736 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20737 (clobber (mem:BLK (scratch)))])]
20738 "")
20739
20740 ;; Two pops case is tricky, since pop causes dependency on destination register.
20741 ;; We use two registers if available.
20742 (define_peephole2
20743 [(match_scratch:SI 0 "r")
20744 (match_scratch:SI 1 "r")
20745 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20746 (clobber (reg:CC FLAGS_REG))
20747 (clobber (mem:BLK (scratch)))])]
20748 "optimize_size || !TARGET_ADD_ESP_8"
20749 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20750 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20751 (clobber (mem:BLK (scratch)))])
20752 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20753 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20754 "")
20755
20756 (define_peephole2
20757 [(match_scratch:SI 0 "r")
20758 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20759 (clobber (reg:CC FLAGS_REG))
20760 (clobber (mem:BLK (scratch)))])]
20761 "optimize_size"
20762 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20763 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20764 (clobber (mem:BLK (scratch)))])
20765 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20766 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20767 "")
20768
20769 ;; Convert esp additions to pop.
20770 (define_peephole2
20771 [(match_scratch:SI 0 "r")
20772 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20773 (clobber (reg:CC FLAGS_REG))])]
20774 ""
20775 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20776 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20777 "")
20778
20779 ;; Two pops case is tricky, since pop causes dependency on destination register.
20780 ;; We use two registers if available.
20781 (define_peephole2
20782 [(match_scratch:SI 0 "r")
20783 (match_scratch:SI 1 "r")
20784 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20785 (clobber (reg:CC FLAGS_REG))])]
20786 ""
20787 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20788 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20789 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20790 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20791 "")
20792
20793 (define_peephole2
20794 [(match_scratch:SI 0 "r")
20795 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20796 (clobber (reg:CC FLAGS_REG))])]
20797 "optimize_size"
20798 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20799 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20800 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20801 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20802 "")
20803 \f
20804 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20805 ;; required and register dies. Similarly for 128 to plus -128.
20806 (define_peephole2
20807 [(set (match_operand 0 "flags_reg_operand" "")
20808 (match_operator 1 "compare_operator"
20809 [(match_operand 2 "register_operand" "")
20810 (match_operand 3 "const_int_operand" "")]))]
20811 "(INTVAL (operands[3]) == -1
20812 || INTVAL (operands[3]) == 1
20813 || INTVAL (operands[3]) == 128)
20814 && ix86_match_ccmode (insn, CCGCmode)
20815 && peep2_reg_dead_p (1, operands[2])"
20816 [(parallel [(set (match_dup 0)
20817 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20818 (clobber (match_dup 2))])]
20819 "")
20820 \f
20821 (define_peephole2
20822 [(match_scratch:DI 0 "r")
20823 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20824 (clobber (reg:CC FLAGS_REG))
20825 (clobber (mem:BLK (scratch)))])]
20826 "optimize_size || !TARGET_SUB_ESP_4"
20827 [(clobber (match_dup 0))
20828 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20829 (clobber (mem:BLK (scratch)))])])
20830
20831 (define_peephole2
20832 [(match_scratch:DI 0 "r")
20833 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20834 (clobber (reg:CC FLAGS_REG))
20835 (clobber (mem:BLK (scratch)))])]
20836 "optimize_size || !TARGET_SUB_ESP_8"
20837 [(clobber (match_dup 0))
20838 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20839 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20840 (clobber (mem:BLK (scratch)))])])
20841
20842 ;; Convert esp subtractions to push.
20843 (define_peephole2
20844 [(match_scratch:DI 0 "r")
20845 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20846 (clobber (reg:CC FLAGS_REG))])]
20847 "optimize_size || !TARGET_SUB_ESP_4"
20848 [(clobber (match_dup 0))
20849 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20850
20851 (define_peephole2
20852 [(match_scratch:DI 0 "r")
20853 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20854 (clobber (reg:CC FLAGS_REG))])]
20855 "optimize_size || !TARGET_SUB_ESP_8"
20856 [(clobber (match_dup 0))
20857 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20858 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20859
20860 ;; Convert epilogue deallocator to pop.
20861 (define_peephole2
20862 [(match_scratch:DI 0 "r")
20863 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20864 (clobber (reg:CC FLAGS_REG))
20865 (clobber (mem:BLK (scratch)))])]
20866 "optimize_size || !TARGET_ADD_ESP_4"
20867 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20868 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20869 (clobber (mem:BLK (scratch)))])]
20870 "")
20871
20872 ;; Two pops case is tricky, since pop causes dependency on destination register.
20873 ;; We use two registers if available.
20874 (define_peephole2
20875 [(match_scratch:DI 0 "r")
20876 (match_scratch:DI 1 "r")
20877 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20878 (clobber (reg:CC FLAGS_REG))
20879 (clobber (mem:BLK (scratch)))])]
20880 "optimize_size || !TARGET_ADD_ESP_8"
20881 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20882 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20883 (clobber (mem:BLK (scratch)))])
20884 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20885 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20886 "")
20887
20888 (define_peephole2
20889 [(match_scratch:DI 0 "r")
20890 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20891 (clobber (reg:CC FLAGS_REG))
20892 (clobber (mem:BLK (scratch)))])]
20893 "optimize_size"
20894 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20895 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20896 (clobber (mem:BLK (scratch)))])
20897 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20898 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20899 "")
20900
20901 ;; Convert esp additions to pop.
20902 (define_peephole2
20903 [(match_scratch:DI 0 "r")
20904 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20905 (clobber (reg:CC FLAGS_REG))])]
20906 ""
20907 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20908 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20909 "")
20910
20911 ;; Two pops case is tricky, since pop causes dependency on destination register.
20912 ;; We use two registers if available.
20913 (define_peephole2
20914 [(match_scratch:DI 0 "r")
20915 (match_scratch:DI 1 "r")
20916 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20917 (clobber (reg:CC FLAGS_REG))])]
20918 ""
20919 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20920 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20921 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20922 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20923 "")
20924
20925 (define_peephole2
20926 [(match_scratch:DI 0 "r")
20927 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20928 (clobber (reg:CC FLAGS_REG))])]
20929 "optimize_size"
20930 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20931 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20932 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20933 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20934 "")
20935 \f
20936 ;; Convert imul by three, five and nine into lea
20937 (define_peephole2
20938 [(parallel
20939 [(set (match_operand:SI 0 "register_operand" "")
20940 (mult:SI (match_operand:SI 1 "register_operand" "")
20941 (match_operand:SI 2 "const_int_operand" "")))
20942 (clobber (reg:CC FLAGS_REG))])]
20943 "INTVAL (operands[2]) == 3
20944 || INTVAL (operands[2]) == 5
20945 || INTVAL (operands[2]) == 9"
20946 [(set (match_dup 0)
20947 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20948 (match_dup 1)))]
20949 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20950
20951 (define_peephole2
20952 [(parallel
20953 [(set (match_operand:SI 0 "register_operand" "")
20954 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20955 (match_operand:SI 2 "const_int_operand" "")))
20956 (clobber (reg:CC FLAGS_REG))])]
20957 "!optimize_size
20958 && (INTVAL (operands[2]) == 3
20959 || INTVAL (operands[2]) == 5
20960 || INTVAL (operands[2]) == 9)"
20961 [(set (match_dup 0) (match_dup 1))
20962 (set (match_dup 0)
20963 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20964 (match_dup 0)))]
20965 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20966
20967 (define_peephole2
20968 [(parallel
20969 [(set (match_operand:DI 0 "register_operand" "")
20970 (mult:DI (match_operand:DI 1 "register_operand" "")
20971 (match_operand:DI 2 "const_int_operand" "")))
20972 (clobber (reg:CC FLAGS_REG))])]
20973 "TARGET_64BIT
20974 && (INTVAL (operands[2]) == 3
20975 || INTVAL (operands[2]) == 5
20976 || INTVAL (operands[2]) == 9)"
20977 [(set (match_dup 0)
20978 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20979 (match_dup 1)))]
20980 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20981
20982 (define_peephole2
20983 [(parallel
20984 [(set (match_operand:DI 0 "register_operand" "")
20985 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20986 (match_operand:DI 2 "const_int_operand" "")))
20987 (clobber (reg:CC FLAGS_REG))])]
20988 "TARGET_64BIT
20989 && !optimize_size
20990 && (INTVAL (operands[2]) == 3
20991 || INTVAL (operands[2]) == 5
20992 || INTVAL (operands[2]) == 9)"
20993 [(set (match_dup 0) (match_dup 1))
20994 (set (match_dup 0)
20995 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20996 (match_dup 0)))]
20997 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20998
20999 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21000 ;; imul $32bit_imm, reg, reg is direct decoded.
21001 (define_peephole2
21002 [(match_scratch:DI 3 "r")
21003 (parallel [(set (match_operand:DI 0 "register_operand" "")
21004 (mult:DI (match_operand:DI 1 "memory_operand" "")
21005 (match_operand:DI 2 "immediate_operand" "")))
21006 (clobber (reg:CC FLAGS_REG))])]
21007 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
21008 && !satisfies_constraint_K (operands[2])"
21009 [(set (match_dup 3) (match_dup 1))
21010 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21011 (clobber (reg:CC FLAGS_REG))])]
21012 "")
21013
21014 (define_peephole2
21015 [(match_scratch:SI 3 "r")
21016 (parallel [(set (match_operand:SI 0 "register_operand" "")
21017 (mult:SI (match_operand:SI 1 "memory_operand" "")
21018 (match_operand:SI 2 "immediate_operand" "")))
21019 (clobber (reg:CC FLAGS_REG))])]
21020 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
21021 && !satisfies_constraint_K (operands[2])"
21022 [(set (match_dup 3) (match_dup 1))
21023 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21024 (clobber (reg:CC FLAGS_REG))])]
21025 "")
21026
21027 (define_peephole2
21028 [(match_scratch:SI 3 "r")
21029 (parallel [(set (match_operand:DI 0 "register_operand" "")
21030 (zero_extend:DI
21031 (mult:SI (match_operand:SI 1 "memory_operand" "")
21032 (match_operand:SI 2 "immediate_operand" ""))))
21033 (clobber (reg:CC FLAGS_REG))])]
21034 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
21035 && !satisfies_constraint_K (operands[2])"
21036 [(set (match_dup 3) (match_dup 1))
21037 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21038 (clobber (reg:CC FLAGS_REG))])]
21039 "")
21040
21041 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21042 ;; Convert it into imul reg, reg
21043 ;; It would be better to force assembler to encode instruction using long
21044 ;; immediate, but there is apparently no way to do so.
21045 (define_peephole2
21046 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21047 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21048 (match_operand:DI 2 "const_int_operand" "")))
21049 (clobber (reg:CC FLAGS_REG))])
21050 (match_scratch:DI 3 "r")]
21051 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
21052 && satisfies_constraint_K (operands[2])"
21053 [(set (match_dup 3) (match_dup 2))
21054 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21055 (clobber (reg:CC FLAGS_REG))])]
21056 {
21057 if (!rtx_equal_p (operands[0], operands[1]))
21058 emit_move_insn (operands[0], operands[1]);
21059 })
21060
21061 (define_peephole2
21062 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21063 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21064 (match_operand:SI 2 "const_int_operand" "")))
21065 (clobber (reg:CC FLAGS_REG))])
21066 (match_scratch:SI 3 "r")]
21067 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
21068 && satisfies_constraint_K (operands[2])"
21069 [(set (match_dup 3) (match_dup 2))
21070 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21071 (clobber (reg:CC FLAGS_REG))])]
21072 {
21073 if (!rtx_equal_p (operands[0], operands[1]))
21074 emit_move_insn (operands[0], operands[1]);
21075 })
21076
21077 (define_peephole2
21078 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21079 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21080 (match_operand:HI 2 "immediate_operand" "")))
21081 (clobber (reg:CC FLAGS_REG))])
21082 (match_scratch:HI 3 "r")]
21083 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
21084 [(set (match_dup 3) (match_dup 2))
21085 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21086 (clobber (reg:CC FLAGS_REG))])]
21087 {
21088 if (!rtx_equal_p (operands[0], operands[1]))
21089 emit_move_insn (operands[0], operands[1]);
21090 })
21091
21092 ;; After splitting up read-modify operations, array accesses with memory
21093 ;; operands might end up in form:
21094 ;; sall $2, %eax
21095 ;; movl 4(%esp), %edx
21096 ;; addl %edx, %eax
21097 ;; instead of pre-splitting:
21098 ;; sall $2, %eax
21099 ;; addl 4(%esp), %eax
21100 ;; Turn it into:
21101 ;; movl 4(%esp), %edx
21102 ;; leal (%edx,%eax,4), %eax
21103
21104 (define_peephole2
21105 [(parallel [(set (match_operand 0 "register_operand" "")
21106 (ashift (match_operand 1 "register_operand" "")
21107 (match_operand 2 "const_int_operand" "")))
21108 (clobber (reg:CC FLAGS_REG))])
21109 (set (match_operand 3 "register_operand")
21110 (match_operand 4 "x86_64_general_operand" ""))
21111 (parallel [(set (match_operand 5 "register_operand" "")
21112 (plus (match_operand 6 "register_operand" "")
21113 (match_operand 7 "register_operand" "")))
21114 (clobber (reg:CC FLAGS_REG))])]
21115 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21116 /* Validate MODE for lea. */
21117 && ((!TARGET_PARTIAL_REG_STALL
21118 && (GET_MODE (operands[0]) == QImode
21119 || GET_MODE (operands[0]) == HImode))
21120 || GET_MODE (operands[0]) == SImode
21121 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21122 /* We reorder load and the shift. */
21123 && !rtx_equal_p (operands[1], operands[3])
21124 && !reg_overlap_mentioned_p (operands[0], operands[4])
21125 /* Last PLUS must consist of operand 0 and 3. */
21126 && !rtx_equal_p (operands[0], operands[3])
21127 && (rtx_equal_p (operands[3], operands[6])
21128 || rtx_equal_p (operands[3], operands[7]))
21129 && (rtx_equal_p (operands[0], operands[6])
21130 || rtx_equal_p (operands[0], operands[7]))
21131 /* The intermediate operand 0 must die or be same as output. */
21132 && (rtx_equal_p (operands[0], operands[5])
21133 || peep2_reg_dead_p (3, operands[0]))"
21134 [(set (match_dup 3) (match_dup 4))
21135 (set (match_dup 0) (match_dup 1))]
21136 {
21137 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21138 int scale = 1 << INTVAL (operands[2]);
21139 rtx index = gen_lowpart (Pmode, operands[1]);
21140 rtx base = gen_lowpart (Pmode, operands[3]);
21141 rtx dest = gen_lowpart (mode, operands[5]);
21142
21143 operands[1] = gen_rtx_PLUS (Pmode, base,
21144 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21145 if (mode != Pmode)
21146 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21147 operands[0] = dest;
21148 })
21149 \f
21150 ;; Call-value patterns last so that the wildcard operand does not
21151 ;; disrupt insn-recog's switch tables.
21152
21153 (define_insn "*call_value_pop_0"
21154 [(set (match_operand 0 "" "")
21155 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21156 (match_operand:SI 2 "" "")))
21157 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21158 (match_operand:SI 3 "immediate_operand" "")))]
21159 "!TARGET_64BIT"
21160 {
21161 if (SIBLING_CALL_P (insn))
21162 return "jmp\t%P1";
21163 else
21164 return "call\t%P1";
21165 }
21166 [(set_attr "type" "callv")])
21167
21168 (define_insn "*call_value_pop_1"
21169 [(set (match_operand 0 "" "")
21170 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21171 (match_operand:SI 2 "" "")))
21172 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21173 (match_operand:SI 3 "immediate_operand" "i")))]
21174 "!TARGET_64BIT"
21175 {
21176 if (constant_call_address_operand (operands[1], Pmode))
21177 {
21178 if (SIBLING_CALL_P (insn))
21179 return "jmp\t%P1";
21180 else
21181 return "call\t%P1";
21182 }
21183 if (SIBLING_CALL_P (insn))
21184 return "jmp\t%A1";
21185 else
21186 return "call\t%A1";
21187 }
21188 [(set_attr "type" "callv")])
21189
21190 (define_insn "*call_value_0"
21191 [(set (match_operand 0 "" "")
21192 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21193 (match_operand:SI 2 "" "")))]
21194 "!TARGET_64BIT"
21195 {
21196 if (SIBLING_CALL_P (insn))
21197 return "jmp\t%P1";
21198 else
21199 return "call\t%P1";
21200 }
21201 [(set_attr "type" "callv")])
21202
21203 (define_insn "*call_value_0_rex64"
21204 [(set (match_operand 0 "" "")
21205 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21206 (match_operand:DI 2 "const_int_operand" "")))]
21207 "TARGET_64BIT"
21208 {
21209 if (SIBLING_CALL_P (insn))
21210 return "jmp\t%P1";
21211 else
21212 return "call\t%P1";
21213 }
21214 [(set_attr "type" "callv")])
21215
21216 (define_insn "*call_value_1"
21217 [(set (match_operand 0 "" "")
21218 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21219 (match_operand:SI 2 "" "")))]
21220 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21221 {
21222 if (constant_call_address_operand (operands[1], Pmode))
21223 return "call\t%P1";
21224 return "call\t%A1";
21225 }
21226 [(set_attr "type" "callv")])
21227
21228 (define_insn "*sibcall_value_1"
21229 [(set (match_operand 0 "" "")
21230 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21231 (match_operand:SI 2 "" "")))]
21232 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21233 {
21234 if (constant_call_address_operand (operands[1], Pmode))
21235 return "jmp\t%P1";
21236 return "jmp\t%A1";
21237 }
21238 [(set_attr "type" "callv")])
21239
21240 (define_insn "*call_value_1_rex64"
21241 [(set (match_operand 0 "" "")
21242 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21243 (match_operand:DI 2 "" "")))]
21244 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21245 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21246 {
21247 if (constant_call_address_operand (operands[1], Pmode))
21248 return "call\t%P1";
21249 return "call\t%A1";
21250 }
21251 [(set_attr "type" "callv")])
21252
21253 (define_insn "*call_value_1_rex64_large"
21254 [(set (match_operand 0 "" "")
21255 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21256 (match_operand:DI 2 "" "")))]
21257 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21258 "call\t%A1"
21259 [(set_attr "type" "callv")])
21260
21261 (define_insn "*sibcall_value_1_rex64"
21262 [(set (match_operand 0 "" "")
21263 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21264 (match_operand:DI 2 "" "")))]
21265 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21266 "jmp\t%P1"
21267 [(set_attr "type" "callv")])
21268
21269 (define_insn "*sibcall_value_1_rex64_v"
21270 [(set (match_operand 0 "" "")
21271 (call (mem:QI (reg:DI R11_REG))
21272 (match_operand:DI 1 "" "")))]
21273 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21274 "jmp\t{*%%}r11"
21275 [(set_attr "type" "callv")])
21276 \f
21277 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21278 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21279 ;; caught for use by garbage collectors and the like. Using an insn that
21280 ;; maps to SIGILL makes it more likely the program will rightfully die.
21281 ;; Keeping with tradition, "6" is in honor of #UD.
21282 (define_insn "trap"
21283 [(trap_if (const_int 1) (const_int 6))]
21284 ""
21285 { return ASM_SHORT "0x0b0f"; }
21286 [(set_attr "length" "2")])
21287
21288 (define_expand "sse_prologue_save"
21289 [(parallel [(set (match_operand:BLK 0 "" "")
21290 (unspec:BLK [(reg:DI 21)
21291 (reg:DI 22)
21292 (reg:DI 23)
21293 (reg:DI 24)
21294 (reg:DI 25)
21295 (reg:DI 26)
21296 (reg:DI 27)
21297 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21298 (use (match_operand:DI 1 "register_operand" ""))
21299 (use (match_operand:DI 2 "immediate_operand" ""))
21300 (use (label_ref:DI (match_operand 3 "" "")))])]
21301 "TARGET_64BIT"
21302 "")
21303
21304 (define_insn "*sse_prologue_save_insn"
21305 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21306 (match_operand:DI 4 "const_int_operand" "n")))
21307 (unspec:BLK [(reg:DI 21)
21308 (reg:DI 22)
21309 (reg:DI 23)
21310 (reg:DI 24)
21311 (reg:DI 25)
21312 (reg:DI 26)
21313 (reg:DI 27)
21314 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21315 (use (match_operand:DI 1 "register_operand" "r"))
21316 (use (match_operand:DI 2 "const_int_operand" "i"))
21317 (use (label_ref:DI (match_operand 3 "" "X")))]
21318 "TARGET_64BIT
21319 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21320 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21321 "*
21322 {
21323 int i;
21324 operands[0] = gen_rtx_MEM (Pmode,
21325 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21326 output_asm_insn (\"jmp\\t%A1\", operands);
21327 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21328 {
21329 operands[4] = adjust_address (operands[0], DImode, i*16);
21330 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21331 PUT_MODE (operands[4], TImode);
21332 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21333 output_asm_insn (\"rex\", operands);
21334 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21335 }
21336 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21337 CODE_LABEL_NUMBER (operands[3]));
21338 return \"\";
21339 }
21340 "
21341 [(set_attr "type" "other")
21342 (set_attr "length_immediate" "0")
21343 (set_attr "length_address" "0")
21344 (set_attr "length" "135")
21345 (set_attr "memory" "store")
21346 (set_attr "modrm" "0")
21347 (set_attr "mode" "DI")])
21348
21349 (define_expand "prefetch"
21350 [(prefetch (match_operand 0 "address_operand" "")
21351 (match_operand:SI 1 "const_int_operand" "")
21352 (match_operand:SI 2 "const_int_operand" ""))]
21353 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21354 {
21355 int rw = INTVAL (operands[1]);
21356 int locality = INTVAL (operands[2]);
21357
21358 gcc_assert (rw == 0 || rw == 1);
21359 gcc_assert (locality >= 0 && locality <= 3);
21360 gcc_assert (GET_MODE (operands[0]) == Pmode
21361 || GET_MODE (operands[0]) == VOIDmode);
21362
21363 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21364 supported by SSE counterpart or the SSE prefetch is not available
21365 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21366 of locality. */
21367 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21368 operands[2] = GEN_INT (3);
21369 else
21370 operands[1] = const0_rtx;
21371 })
21372
21373 (define_insn "*prefetch_sse"
21374 [(prefetch (match_operand:SI 0 "address_operand" "p")
21375 (const_int 0)
21376 (match_operand:SI 1 "const_int_operand" ""))]
21377 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21378 {
21379 static const char * const patterns[4] = {
21380 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21381 };
21382
21383 int locality = INTVAL (operands[1]);
21384 gcc_assert (locality >= 0 && locality <= 3);
21385
21386 return patterns[locality];
21387 }
21388 [(set_attr "type" "sse")
21389 (set_attr "memory" "none")])
21390
21391 (define_insn "*prefetch_sse_rex"
21392 [(prefetch (match_operand:DI 0 "address_operand" "p")
21393 (const_int 0)
21394 (match_operand:SI 1 "const_int_operand" ""))]
21395 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21396 {
21397 static const char * const patterns[4] = {
21398 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21399 };
21400
21401 int locality = INTVAL (operands[1]);
21402 gcc_assert (locality >= 0 && locality <= 3);
21403
21404 return patterns[locality];
21405 }
21406 [(set_attr "type" "sse")
21407 (set_attr "memory" "none")])
21408
21409 (define_insn "*prefetch_3dnow"
21410 [(prefetch (match_operand:SI 0 "address_operand" "p")
21411 (match_operand:SI 1 "const_int_operand" "n")
21412 (const_int 3))]
21413 "TARGET_3DNOW && !TARGET_64BIT"
21414 {
21415 if (INTVAL (operands[1]) == 0)
21416 return "prefetch\t%a0";
21417 else
21418 return "prefetchw\t%a0";
21419 }
21420 [(set_attr "type" "mmx")
21421 (set_attr "memory" "none")])
21422
21423 (define_insn "*prefetch_3dnow_rex"
21424 [(prefetch (match_operand:DI 0 "address_operand" "p")
21425 (match_operand:SI 1 "const_int_operand" "n")
21426 (const_int 3))]
21427 "TARGET_3DNOW && TARGET_64BIT"
21428 {
21429 if (INTVAL (operands[1]) == 0)
21430 return "prefetch\t%a0";
21431 else
21432 return "prefetchw\t%a0";
21433 }
21434 [(set_attr "type" "mmx")
21435 (set_attr "memory" "none")])
21436
21437 (define_expand "stack_protect_set"
21438 [(match_operand 0 "memory_operand" "")
21439 (match_operand 1 "memory_operand" "")]
21440 ""
21441 {
21442 #ifdef TARGET_THREAD_SSP_OFFSET
21443 if (TARGET_64BIT)
21444 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21445 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21446 else
21447 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21448 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21449 #else
21450 if (TARGET_64BIT)
21451 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21452 else
21453 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21454 #endif
21455 DONE;
21456 })
21457
21458 (define_insn "stack_protect_set_si"
21459 [(set (match_operand:SI 0 "memory_operand" "=m")
21460 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21461 (set (match_scratch:SI 2 "=&r") (const_int 0))
21462 (clobber (reg:CC FLAGS_REG))]
21463 ""
21464 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21465 [(set_attr "type" "multi")])
21466
21467 (define_insn "stack_protect_set_di"
21468 [(set (match_operand:DI 0 "memory_operand" "=m")
21469 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21470 (set (match_scratch:DI 2 "=&r") (const_int 0))
21471 (clobber (reg:CC FLAGS_REG))]
21472 "TARGET_64BIT"
21473 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21474 [(set_attr "type" "multi")])
21475
21476 (define_insn "stack_tls_protect_set_si"
21477 [(set (match_operand:SI 0 "memory_operand" "=m")
21478 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21479 (set (match_scratch:SI 2 "=&r") (const_int 0))
21480 (clobber (reg:CC FLAGS_REG))]
21481 ""
21482 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21483 [(set_attr "type" "multi")])
21484
21485 (define_insn "stack_tls_protect_set_di"
21486 [(set (match_operand:DI 0 "memory_operand" "=m")
21487 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21488 (set (match_scratch:DI 2 "=&r") (const_int 0))
21489 (clobber (reg:CC FLAGS_REG))]
21490 "TARGET_64BIT"
21491 {
21492 /* The kernel uses a different segment register for performance reasons; a
21493 system call would not have to trash the userspace segment register,
21494 which would be expensive */
21495 if (ix86_cmodel != CM_KERNEL)
21496 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21497 else
21498 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21499 }
21500 [(set_attr "type" "multi")])
21501
21502 (define_expand "stack_protect_test"
21503 [(match_operand 0 "memory_operand" "")
21504 (match_operand 1 "memory_operand" "")
21505 (match_operand 2 "" "")]
21506 ""
21507 {
21508 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21509 ix86_compare_op0 = operands[0];
21510 ix86_compare_op1 = operands[1];
21511 ix86_compare_emitted = flags;
21512
21513 #ifdef TARGET_THREAD_SSP_OFFSET
21514 if (TARGET_64BIT)
21515 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21516 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21517 else
21518 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21519 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21520 #else
21521 if (TARGET_64BIT)
21522 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21523 else
21524 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21525 #endif
21526 emit_jump_insn (gen_beq (operands[2]));
21527 DONE;
21528 })
21529
21530 (define_insn "stack_protect_test_si"
21531 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21532 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21533 (match_operand:SI 2 "memory_operand" "m")]
21534 UNSPEC_SP_TEST))
21535 (clobber (match_scratch:SI 3 "=&r"))]
21536 ""
21537 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21538 [(set_attr "type" "multi")])
21539
21540 (define_insn "stack_protect_test_di"
21541 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21542 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21543 (match_operand:DI 2 "memory_operand" "m")]
21544 UNSPEC_SP_TEST))
21545 (clobber (match_scratch:DI 3 "=&r"))]
21546 "TARGET_64BIT"
21547 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21548 [(set_attr "type" "multi")])
21549
21550 (define_insn "stack_tls_protect_test_si"
21551 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21552 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21553 (match_operand:SI 2 "const_int_operand" "i")]
21554 UNSPEC_SP_TLS_TEST))
21555 (clobber (match_scratch:SI 3 "=r"))]
21556 ""
21557 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21558 [(set_attr "type" "multi")])
21559
21560 (define_insn "stack_tls_protect_test_di"
21561 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21562 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21563 (match_operand:DI 2 "const_int_operand" "i")]
21564 UNSPEC_SP_TLS_TEST))
21565 (clobber (match_scratch:DI 3 "=r"))]
21566 "TARGET_64BIT"
21567 {
21568 /* The kernel uses a different segment register for performance reasons; a
21569 system call would not have to trash the userspace segment register,
21570 which would be expensive */
21571 if (ix86_cmodel != CM_KERNEL)
21572 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21573 else
21574 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21575 }
21576 [(set_attr "type" "multi")])
21577
21578 (define_mode_iterator CRC32MODE [QI HI SI])
21579 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21580 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21581
21582 (define_insn "sse4_2_crc32<mode>"
21583 [(set (match_operand:SI 0 "register_operand" "=r")
21584 (unspec:SI
21585 [(match_operand:SI 1 "register_operand" "0")
21586 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21587 UNSPEC_CRC32))]
21588 "TARGET_SSE4_2"
21589 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21590 [(set_attr "type" "sselog1")
21591 (set_attr "prefix_rep" "1")
21592 (set_attr "prefix_extra" "1")
21593 (set_attr "mode" "SI")])
21594
21595 (define_insn "sse4_2_crc32di"
21596 [(set (match_operand:DI 0 "register_operand" "=r")
21597 (unspec:DI
21598 [(match_operand:DI 1 "register_operand" "0")
21599 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21600 UNSPEC_CRC32))]
21601 "TARGET_SSE4_2 && TARGET_64BIT"
21602 "crc32q\t{%2, %0|%0, %2}"
21603 [(set_attr "type" "sselog1")
21604 (set_attr "prefix_rep" "1")
21605 (set_attr "prefix_extra" "1")
21606 (set_attr "mode" "DI")])
21607
21608 (include "mmx.md")
21609 (include "sse.md")
21610 (include "sync.md")