]> gcc.gnu.org Git - gcc.git/blob - gcc/config/i386/i386.md
c8bff3e00620c913a0bedb69b1e044d8e1a44bf3
[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
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 2, 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 COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; The special asm out single letter directives following a '%' are:
31 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; operands[1].
33 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
34 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
35 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
36 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
37 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
38 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
39 ;; 'J' Print the appropriate jump operand.
40 ;;
41 ;; 'b' Print the QImode name of the register for the indicated operand.
42 ;; %b0 would print %al if operands[0] is reg 0.
43 ;; 'w' Likewise, print the HImode name of the register.
44 ;; 'k' Likewise, print the SImode name of the register.
45 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
46 ;; 'y' Print "st(0)" instead of "st" as a register.
47
48 ;; UNSPEC usage:
49
50 (define_constants
51 [; Relocation specifiers
52 (UNSPEC_GOT 0)
53 (UNSPEC_GOTOFF 1)
54 (UNSPEC_GOTPCREL 2)
55 (UNSPEC_GOTTPOFF 3)
56 (UNSPEC_TPOFF 4)
57 (UNSPEC_NTPOFF 5)
58 (UNSPEC_DTPOFF 6)
59 (UNSPEC_GOTNTPOFF 7)
60 (UNSPEC_INDNTPOFF 8)
61 (UNSPEC_PLTOFF 9)
62
63 ; Prologue support
64 (UNSPEC_STACK_ALLOC 11)
65 (UNSPEC_SET_GOT 12)
66 (UNSPEC_SSE_PROLOGUE_SAVE 13)
67 (UNSPEC_REG_SAVE 14)
68 (UNSPEC_DEF_CFA 15)
69 (UNSPEC_SET_RIP 16)
70 (UNSPEC_SET_GOT_OFFSET 17)
71
72 ; TLS support
73 (UNSPEC_TP 18)
74 (UNSPEC_TLS_GD 19)
75 (UNSPEC_TLS_LD_BASE 20)
76 (UNSPEC_TLSDESC 21)
77
78 ; Other random patterns
79 (UNSPEC_SCAS 30)
80 (UNSPEC_FNSTSW 31)
81 (UNSPEC_SAHF 32)
82 (UNSPEC_FSTCW 33)
83 (UNSPEC_ADD_CARRY 34)
84 (UNSPEC_FLDCW 35)
85 (UNSPEC_REP 36)
86 (UNSPEC_EH_RETURN 37)
87 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 39)
89
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 40)
92 (UNSPEC_MASKMOV 41)
93 (UNSPEC_MOVMSK 42)
94 (UNSPEC_MOVNT 43)
95 (UNSPEC_MOVU 44)
96 (UNSPEC_RCP 45)
97 (UNSPEC_RSQRT 46)
98 (UNSPEC_SFENCE 47)
99 (UNSPEC_NOP 48) ; prevents combiner cleverness
100 (UNSPEC_PFRCP 49)
101 (UNSPEC_PFRCPIT1 40)
102 (UNSPEC_PFRCPIT2 41)
103 (UNSPEC_PFRSQRT 42)
104 (UNSPEC_PFRSQIT1 43)
105 (UNSPEC_MFENCE 44)
106 (UNSPEC_LFENCE 45)
107 (UNSPEC_PSADBW 46)
108 (UNSPEC_LDDQU 47)
109
110 ; Generic math support
111 (UNSPEC_COPYSIGN 50)
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
114
115 ; x87 Floating point
116 (UNSPEC_SIN 60)
117 (UNSPEC_COS 61)
118 (UNSPEC_FPATAN 62)
119 (UNSPEC_FYL2X 63)
120 (UNSPEC_FYL2XP1 64)
121 (UNSPEC_FRNDINT 65)
122 (UNSPEC_FIST 66)
123 (UNSPEC_F2XM1 67)
124 (UNSPEC_TAN 68)
125 (UNSPEC_FXAM 69)
126
127 ; x87 Rounding
128 (UNSPEC_FRNDINT_FLOOR 70)
129 (UNSPEC_FRNDINT_CEIL 71)
130 (UNSPEC_FRNDINT_TRUNC 72)
131 (UNSPEC_FRNDINT_MASK_PM 73)
132 (UNSPEC_FIST_FLOOR 74)
133 (UNSPEC_FIST_CEIL 75)
134
135 ; x87 Double output FP
136 (UNSPEC_SINCOS_COS 80)
137 (UNSPEC_SINCOS_SIN 81)
138 (UNSPEC_XTRACT_FRACT 84)
139 (UNSPEC_XTRACT_EXP 85)
140 (UNSPEC_FSCALE_FRACT 86)
141 (UNSPEC_FSCALE_EXP 87)
142 (UNSPEC_FPREM_F 88)
143 (UNSPEC_FPREM_U 89)
144 (UNSPEC_FPREM1_F 90)
145 (UNSPEC_FPREM1_U 91)
146
147 (UNSPEC_C2_FLAG 95)
148
149 ; SSP patterns
150 (UNSPEC_SP_SET 100)
151 (UNSPEC_SP_TEST 101)
152 (UNSPEC_SP_TLS_SET 102)
153 (UNSPEC_SP_TLS_TEST 103)
154
155 ; SSSE3
156 (UNSPEC_PSHUFB 120)
157 (UNSPEC_PSIGN 121)
158 (UNSPEC_PALIGNR 122)
159
160 ; For SSE4A support
161 (UNSPEC_EXTRQI 130)
162 (UNSPEC_EXTRQ 131)
163 (UNSPEC_INSERTQI 132)
164 (UNSPEC_INSERTQ 133)
165
166 ; For SSE4.1 support
167 (UNSPEC_BLENDV 134)
168 (UNSPEC_INSERTPS 135)
169 (UNSPEC_DP 136)
170 (UNSPEC_MOVNTDQA 137)
171 (UNSPEC_MPSADBW 138)
172 (UNSPEC_PHMINPOSUW 139)
173 (UNSPEC_PTEST 140)
174 (UNSPEC_ROUND 141)
175
176 ; For SSE4.2 support
177 (UNSPEC_CRC32 143)
178 (UNSPEC_PCMPESTR 144)
179 (UNSPEC_PCMPISTR 145)
180 ])
181
182 (define_constants
183 [(UNSPECV_BLOCKAGE 0)
184 (UNSPECV_STACK_PROBE 1)
185 (UNSPECV_EMMS 2)
186 (UNSPECV_LDMXCSR 3)
187 (UNSPECV_STMXCSR 4)
188 (UNSPECV_FEMMS 5)
189 (UNSPECV_CLFLUSH 6)
190 (UNSPECV_ALIGN 7)
191 (UNSPECV_MONITOR 8)
192 (UNSPECV_MWAIT 9)
193 (UNSPECV_CMPXCHG_1 10)
194 (UNSPECV_CMPXCHG_2 11)
195 (UNSPECV_XCHG 12)
196 (UNSPECV_LOCK 13)
197 (UNSPECV_PROLOGUE_USE 14)
198 ])
199
200 ;; Registers by name.
201 (define_constants
202 [(BP_REG 6)
203 (SP_REG 7)
204 (FLAGS_REG 17)
205 (FPSR_REG 18)
206 (FPCR_REG 19)
207 (R10_REG 39)
208 (R11_REG 40)
209 ])
210
211 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
212 ;; from i386.c.
213
214 ;; In C guard expressions, put expressions which may be compile-time
215 ;; constants first. This allows for better optimization. For
216 ;; example, write "TARGET_64BIT && reload_completed", not
217 ;; "reload_completed && TARGET_64BIT".
218
219 \f
220 ;; Processor type. This attribute must exactly match the processor_type
221 ;; enumeration in i386.h.
222 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
223 nocona,core2,generic32,generic64,amdfam10"
224 (const (symbol_ref "ix86_tune")))
225
226 ;; A basic instruction type. Refinements due to arguments to be
227 ;; provided in other attributes.
228 (define_attr "type"
229 "other,multi,
230 alu,alu1,negnot,imov,imovx,lea,
231 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
232 icmp,test,ibr,setcc,icmov,
233 push,pop,call,callv,leave,
234 str,bitmanip,
235 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
236 sselog,sselog1,sseiadd,sseishft,sseimul,
237 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
238 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
239 (const_string "other"))
240
241 ;; Main data type used by the insn
242 (define_attr "mode"
243 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
244 (const_string "unknown"))
245
246 ;; The CPU unit operations uses.
247 (define_attr "unit" "integer,i387,sse,mmx,unknown"
248 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
249 (const_string "i387")
250 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
251 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
252 (const_string "sse")
253 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
254 (const_string "mmx")
255 (eq_attr "type" "other")
256 (const_string "unknown")]
257 (const_string "integer")))
258
259 ;; The (bounding maximum) length of an instruction immediate.
260 (define_attr "length_immediate" ""
261 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
262 bitmanip")
263 (const_int 0)
264 (eq_attr "unit" "i387,sse,mmx")
265 (const_int 0)
266 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
267 imul,icmp,push,pop")
268 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
269 (eq_attr "type" "imov,test")
270 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
271 (eq_attr "type" "call")
272 (if_then_else (match_operand 0 "constant_call_address_operand" "")
273 (const_int 4)
274 (const_int 0))
275 (eq_attr "type" "callv")
276 (if_then_else (match_operand 1 "constant_call_address_operand" "")
277 (const_int 4)
278 (const_int 0))
279 ;; We don't know the size before shorten_branches. Expect
280 ;; the instruction to fit for better scheduling.
281 (eq_attr "type" "ibr")
282 (const_int 1)
283 ]
284 (symbol_ref "/* Update immediate_length and other attributes! */
285 gcc_unreachable (),1")))
286
287 ;; The (bounding maximum) length of an instruction address.
288 (define_attr "length_address" ""
289 (cond [(eq_attr "type" "str,other,multi,fxch")
290 (const_int 0)
291 (and (eq_attr "type" "call")
292 (match_operand 0 "constant_call_address_operand" ""))
293 (const_int 0)
294 (and (eq_attr "type" "callv")
295 (match_operand 1 "constant_call_address_operand" ""))
296 (const_int 0)
297 ]
298 (symbol_ref "ix86_attr_length_address_default (insn)")))
299
300 ;; Set when length prefix is used.
301 (define_attr "prefix_data16" ""
302 (if_then_else (ior (eq_attr "mode" "HI")
303 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
304 (const_int 1)
305 (const_int 0)))
306
307 ;; Set when string REP prefix is used.
308 (define_attr "prefix_rep" ""
309 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
310 (const_int 1)
311 (const_int 0)))
312
313 ;; Set when 0f opcode prefix is used.
314 (define_attr "prefix_0f" ""
315 (if_then_else
316 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
317 (eq_attr "unit" "sse,mmx"))
318 (const_int 1)
319 (const_int 0)))
320
321 ;; Set when REX opcode prefix is used.
322 (define_attr "prefix_rex" ""
323 (cond [(and (eq_attr "mode" "DI")
324 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
325 (const_int 1)
326 (and (eq_attr "mode" "QI")
327 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
328 (const_int 0)))
329 (const_int 1)
330 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
331 (const_int 0))
332 (const_int 1)
333 ]
334 (const_int 0)))
335
336 ;; There are also additional prefixes in SSSE3.
337 (define_attr "prefix_extra" "" (const_int 0))
338
339 ;; Set when modrm byte is used.
340 (define_attr "modrm" ""
341 (cond [(eq_attr "type" "str,leave")
342 (const_int 0)
343 (eq_attr "unit" "i387")
344 (const_int 0)
345 (and (eq_attr "type" "incdec")
346 (ior (match_operand:SI 1 "register_operand" "")
347 (match_operand:HI 1 "register_operand" "")))
348 (const_int 0)
349 (and (eq_attr "type" "push")
350 (not (match_operand 1 "memory_operand" "")))
351 (const_int 0)
352 (and (eq_attr "type" "pop")
353 (not (match_operand 0 "memory_operand" "")))
354 (const_int 0)
355 (and (eq_attr "type" "imov")
356 (ior (and (match_operand 0 "register_operand" "")
357 (match_operand 1 "immediate_operand" ""))
358 (ior (and (match_operand 0 "ax_reg_operand" "")
359 (match_operand 1 "memory_displacement_only_operand" ""))
360 (and (match_operand 0 "memory_displacement_only_operand" "")
361 (match_operand 1 "ax_reg_operand" "")))))
362 (const_int 0)
363 (and (eq_attr "type" "call")
364 (match_operand 0 "constant_call_address_operand" ""))
365 (const_int 0)
366 (and (eq_attr "type" "callv")
367 (match_operand 1 "constant_call_address_operand" ""))
368 (const_int 0)
369 ]
370 (const_int 1)))
371
372 ;; The (bounding maximum) length of an instruction in bytes.
373 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
374 ;; Later we may want to split them and compute proper length as for
375 ;; other insns.
376 (define_attr "length" ""
377 (cond [(eq_attr "type" "other,multi,fistp,frndint")
378 (const_int 16)
379 (eq_attr "type" "fcmp")
380 (const_int 4)
381 (eq_attr "unit" "i387")
382 (plus (const_int 2)
383 (plus (attr "prefix_data16")
384 (attr "length_address")))]
385 (plus (plus (attr "modrm")
386 (plus (attr "prefix_0f")
387 (plus (attr "prefix_rex")
388 (plus (attr "prefix_extra")
389 (const_int 1)))))
390 (plus (attr "prefix_rep")
391 (plus (attr "prefix_data16")
392 (plus (attr "length_immediate")
393 (attr "length_address")))))))
394
395 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
396 ;; `store' if there is a simple memory reference therein, or `unknown'
397 ;; if the instruction is complex.
398
399 (define_attr "memory" "none,load,store,both,unknown"
400 (cond [(eq_attr "type" "other,multi,str")
401 (const_string "unknown")
402 (eq_attr "type" "lea,fcmov,fpspc")
403 (const_string "none")
404 (eq_attr "type" "fistp,leave")
405 (const_string "both")
406 (eq_attr "type" "frndint")
407 (const_string "load")
408 (eq_attr "type" "push")
409 (if_then_else (match_operand 1 "memory_operand" "")
410 (const_string "both")
411 (const_string "store"))
412 (eq_attr "type" "pop")
413 (if_then_else (match_operand 0 "memory_operand" "")
414 (const_string "both")
415 (const_string "load"))
416 (eq_attr "type" "setcc")
417 (if_then_else (match_operand 0 "memory_operand" "")
418 (const_string "store")
419 (const_string "none"))
420 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
421 (if_then_else (ior (match_operand 0 "memory_operand" "")
422 (match_operand 1 "memory_operand" ""))
423 (const_string "load")
424 (const_string "none"))
425 (eq_attr "type" "ibr")
426 (if_then_else (match_operand 0 "memory_operand" "")
427 (const_string "load")
428 (const_string "none"))
429 (eq_attr "type" "call")
430 (if_then_else (match_operand 0 "constant_call_address_operand" "")
431 (const_string "none")
432 (const_string "load"))
433 (eq_attr "type" "callv")
434 (if_then_else (match_operand 1 "constant_call_address_operand" "")
435 (const_string "none")
436 (const_string "load"))
437 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
438 (match_operand 1 "memory_operand" ""))
439 (const_string "both")
440 (and (match_operand 0 "memory_operand" "")
441 (match_operand 1 "memory_operand" ""))
442 (const_string "both")
443 (match_operand 0 "memory_operand" "")
444 (const_string "store")
445 (match_operand 1 "memory_operand" "")
446 (const_string "load")
447 (and (eq_attr "type"
448 "!alu1,negnot,ishift1,
449 imov,imovx,icmp,test,bitmanip,
450 fmov,fcmp,fsgn,
451 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
452 mmx,mmxmov,mmxcmp,mmxcvt")
453 (match_operand 2 "memory_operand" ""))
454 (const_string "load")
455 (and (eq_attr "type" "icmov")
456 (match_operand 3 "memory_operand" ""))
457 (const_string "load")
458 ]
459 (const_string "none")))
460
461 ;; Indicates if an instruction has both an immediate and a displacement.
462
463 (define_attr "imm_disp" "false,true,unknown"
464 (cond [(eq_attr "type" "other,multi")
465 (const_string "unknown")
466 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
467 (and (match_operand 0 "memory_displacement_operand" "")
468 (match_operand 1 "immediate_operand" "")))
469 (const_string "true")
470 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
471 (and (match_operand 0 "memory_displacement_operand" "")
472 (match_operand 2 "immediate_operand" "")))
473 (const_string "true")
474 ]
475 (const_string "false")))
476
477 ;; Indicates if an FP operation has an integer source.
478
479 (define_attr "fp_int_src" "false,true"
480 (const_string "false"))
481
482 ;; Defines rounding mode of an FP operation.
483
484 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
485 (const_string "any"))
486
487 ;; Describe a user's asm statement.
488 (define_asm_attributes
489 [(set_attr "length" "128")
490 (set_attr "type" "multi")])
491
492 ;; All x87 floating point modes
493 (define_mode_macro X87MODEF [SF DF XF])
494
495 ;; x87 SFmode and DFMode floating point modes
496 (define_mode_macro X87MODEF12 [SF DF])
497
498 ;; All integer modes handled by x87 fisttp operator.
499 (define_mode_macro X87MODEI [HI SI DI])
500
501 ;; All integer modes handled by integer x87 operators.
502 (define_mode_macro X87MODEI12 [HI SI])
503
504 ;; All SSE floating point modes
505 (define_mode_macro SSEMODEF [SF DF])
506
507 ;; All integer modes handled by SSE cvtts?2si* operators.
508 (define_mode_macro SSEMODEI24 [SI DI])
509
510 ;; SSE asm suffix for floating point modes
511 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
512
513 ;; SSE vector mode corresponding to a scalar mode
514 (define_mode_attr ssevecmode
515 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
516 \f
517 ;; Scheduling descriptions
518
519 (include "pentium.md")
520 (include "ppro.md")
521 (include "k6.md")
522 (include "athlon.md")
523 (include "geode.md")
524
525 \f
526 ;; Operand and operator predicates and constraints
527
528 (include "predicates.md")
529 (include "constraints.md")
530
531 \f
532 ;; Compare instructions.
533
534 ;; All compare insns have expanders that save the operands away without
535 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
536 ;; after the cmp) will actually emit the cmpM.
537
538 (define_expand "cmpti"
539 [(set (reg:CC FLAGS_REG)
540 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
541 (match_operand:TI 1 "x86_64_general_operand" "")))]
542 "TARGET_64BIT"
543 {
544 if (MEM_P (operands[0]) && MEM_P (operands[1]))
545 operands[0] = force_reg (TImode, operands[0]);
546 ix86_compare_op0 = operands[0];
547 ix86_compare_op1 = operands[1];
548 DONE;
549 })
550
551 (define_expand "cmpdi"
552 [(set (reg:CC FLAGS_REG)
553 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
554 (match_operand:DI 1 "x86_64_general_operand" "")))]
555 ""
556 {
557 if (MEM_P (operands[0]) && MEM_P (operands[1]))
558 operands[0] = force_reg (DImode, operands[0]);
559 ix86_compare_op0 = operands[0];
560 ix86_compare_op1 = operands[1];
561 DONE;
562 })
563
564 (define_expand "cmpsi"
565 [(set (reg:CC FLAGS_REG)
566 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
567 (match_operand:SI 1 "general_operand" "")))]
568 ""
569 {
570 if (MEM_P (operands[0]) && MEM_P (operands[1]))
571 operands[0] = force_reg (SImode, operands[0]);
572 ix86_compare_op0 = operands[0];
573 ix86_compare_op1 = operands[1];
574 DONE;
575 })
576
577 (define_expand "cmphi"
578 [(set (reg:CC FLAGS_REG)
579 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
580 (match_operand:HI 1 "general_operand" "")))]
581 ""
582 {
583 if (MEM_P (operands[0]) && MEM_P (operands[1]))
584 operands[0] = force_reg (HImode, operands[0]);
585 ix86_compare_op0 = operands[0];
586 ix86_compare_op1 = operands[1];
587 DONE;
588 })
589
590 (define_expand "cmpqi"
591 [(set (reg:CC FLAGS_REG)
592 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
593 (match_operand:QI 1 "general_operand" "")))]
594 "TARGET_QIMODE_MATH"
595 {
596 if (MEM_P (operands[0]) && MEM_P (operands[1]))
597 operands[0] = force_reg (QImode, operands[0]);
598 ix86_compare_op0 = operands[0];
599 ix86_compare_op1 = operands[1];
600 DONE;
601 })
602
603 (define_insn "cmpdi_ccno_1_rex64"
604 [(set (reg FLAGS_REG)
605 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
606 (match_operand:DI 1 "const0_operand" "n,n")))]
607 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
608 "@
609 test{q}\t%0, %0
610 cmp{q}\t{%1, %0|%0, %1}"
611 [(set_attr "type" "test,icmp")
612 (set_attr "length_immediate" "0,1")
613 (set_attr "mode" "DI")])
614
615 (define_insn "*cmpdi_minus_1_rex64"
616 [(set (reg FLAGS_REG)
617 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
618 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
619 (const_int 0)))]
620 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
621 "cmp{q}\t{%1, %0|%0, %1}"
622 [(set_attr "type" "icmp")
623 (set_attr "mode" "DI")])
624
625 (define_expand "cmpdi_1_rex64"
626 [(set (reg:CC FLAGS_REG)
627 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
628 (match_operand:DI 1 "general_operand" "")))]
629 "TARGET_64BIT"
630 "")
631
632 (define_insn "cmpdi_1_insn_rex64"
633 [(set (reg FLAGS_REG)
634 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
635 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
636 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
637 "cmp{q}\t{%1, %0|%0, %1}"
638 [(set_attr "type" "icmp")
639 (set_attr "mode" "DI")])
640
641
642 (define_insn "*cmpsi_ccno_1"
643 [(set (reg FLAGS_REG)
644 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
645 (match_operand:SI 1 "const0_operand" "n,n")))]
646 "ix86_match_ccmode (insn, CCNOmode)"
647 "@
648 test{l}\t%0, %0
649 cmp{l}\t{%1, %0|%0, %1}"
650 [(set_attr "type" "test,icmp")
651 (set_attr "length_immediate" "0,1")
652 (set_attr "mode" "SI")])
653
654 (define_insn "*cmpsi_minus_1"
655 [(set (reg FLAGS_REG)
656 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
657 (match_operand:SI 1 "general_operand" "ri,mr"))
658 (const_int 0)))]
659 "ix86_match_ccmode (insn, CCGOCmode)"
660 "cmp{l}\t{%1, %0|%0, %1}"
661 [(set_attr "type" "icmp")
662 (set_attr "mode" "SI")])
663
664 (define_expand "cmpsi_1"
665 [(set (reg:CC FLAGS_REG)
666 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
667 (match_operand:SI 1 "general_operand" "ri,mr")))]
668 ""
669 "")
670
671 (define_insn "*cmpsi_1_insn"
672 [(set (reg FLAGS_REG)
673 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
674 (match_operand:SI 1 "general_operand" "ri,mr")))]
675 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
676 && ix86_match_ccmode (insn, CCmode)"
677 "cmp{l}\t{%1, %0|%0, %1}"
678 [(set_attr "type" "icmp")
679 (set_attr "mode" "SI")])
680
681 (define_insn "*cmphi_ccno_1"
682 [(set (reg FLAGS_REG)
683 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
684 (match_operand:HI 1 "const0_operand" "n,n")))]
685 "ix86_match_ccmode (insn, CCNOmode)"
686 "@
687 test{w}\t%0, %0
688 cmp{w}\t{%1, %0|%0, %1}"
689 [(set_attr "type" "test,icmp")
690 (set_attr "length_immediate" "0,1")
691 (set_attr "mode" "HI")])
692
693 (define_insn "*cmphi_minus_1"
694 [(set (reg FLAGS_REG)
695 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
696 (match_operand:HI 1 "general_operand" "ri,mr"))
697 (const_int 0)))]
698 "ix86_match_ccmode (insn, CCGOCmode)"
699 "cmp{w}\t{%1, %0|%0, %1}"
700 [(set_attr "type" "icmp")
701 (set_attr "mode" "HI")])
702
703 (define_insn "*cmphi_1"
704 [(set (reg FLAGS_REG)
705 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
706 (match_operand:HI 1 "general_operand" "ri,mr")))]
707 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
708 && ix86_match_ccmode (insn, CCmode)"
709 "cmp{w}\t{%1, %0|%0, %1}"
710 [(set_attr "type" "icmp")
711 (set_attr "mode" "HI")])
712
713 (define_insn "*cmpqi_ccno_1"
714 [(set (reg FLAGS_REG)
715 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
716 (match_operand:QI 1 "const0_operand" "n,n")))]
717 "ix86_match_ccmode (insn, CCNOmode)"
718 "@
719 test{b}\t%0, %0
720 cmp{b}\t{$0, %0|%0, 0}"
721 [(set_attr "type" "test,icmp")
722 (set_attr "length_immediate" "0,1")
723 (set_attr "mode" "QI")])
724
725 (define_insn "*cmpqi_1"
726 [(set (reg FLAGS_REG)
727 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
728 (match_operand:QI 1 "general_operand" "qi,mq")))]
729 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
730 && ix86_match_ccmode (insn, CCmode)"
731 "cmp{b}\t{%1, %0|%0, %1}"
732 [(set_attr "type" "icmp")
733 (set_attr "mode" "QI")])
734
735 (define_insn "*cmpqi_minus_1"
736 [(set (reg FLAGS_REG)
737 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
738 (match_operand:QI 1 "general_operand" "qi,mq"))
739 (const_int 0)))]
740 "ix86_match_ccmode (insn, CCGOCmode)"
741 "cmp{b}\t{%1, %0|%0, %1}"
742 [(set_attr "type" "icmp")
743 (set_attr "mode" "QI")])
744
745 (define_insn "*cmpqi_ext_1"
746 [(set (reg FLAGS_REG)
747 (compare
748 (match_operand:QI 0 "general_operand" "Qm")
749 (subreg:QI
750 (zero_extract:SI
751 (match_operand 1 "ext_register_operand" "Q")
752 (const_int 8)
753 (const_int 8)) 0)))]
754 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
755 "cmp{b}\t{%h1, %0|%0, %h1}"
756 [(set_attr "type" "icmp")
757 (set_attr "mode" "QI")])
758
759 (define_insn "*cmpqi_ext_1_rex64"
760 [(set (reg FLAGS_REG)
761 (compare
762 (match_operand:QI 0 "register_operand" "Q")
763 (subreg:QI
764 (zero_extract:SI
765 (match_operand 1 "ext_register_operand" "Q")
766 (const_int 8)
767 (const_int 8)) 0)))]
768 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
769 "cmp{b}\t{%h1, %0|%0, %h1}"
770 [(set_attr "type" "icmp")
771 (set_attr "mode" "QI")])
772
773 (define_insn "*cmpqi_ext_2"
774 [(set (reg FLAGS_REG)
775 (compare
776 (subreg:QI
777 (zero_extract:SI
778 (match_operand 0 "ext_register_operand" "Q")
779 (const_int 8)
780 (const_int 8)) 0)
781 (match_operand:QI 1 "const0_operand" "n")))]
782 "ix86_match_ccmode (insn, CCNOmode)"
783 "test{b}\t%h0, %h0"
784 [(set_attr "type" "test")
785 (set_attr "length_immediate" "0")
786 (set_attr "mode" "QI")])
787
788 (define_expand "cmpqi_ext_3"
789 [(set (reg:CC FLAGS_REG)
790 (compare:CC
791 (subreg:QI
792 (zero_extract:SI
793 (match_operand 0 "ext_register_operand" "")
794 (const_int 8)
795 (const_int 8)) 0)
796 (match_operand:QI 1 "general_operand" "")))]
797 ""
798 "")
799
800 (define_insn "cmpqi_ext_3_insn"
801 [(set (reg FLAGS_REG)
802 (compare
803 (subreg:QI
804 (zero_extract:SI
805 (match_operand 0 "ext_register_operand" "Q")
806 (const_int 8)
807 (const_int 8)) 0)
808 (match_operand:QI 1 "general_operand" "Qmn")))]
809 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
810 "cmp{b}\t{%1, %h0|%h0, %1}"
811 [(set_attr "type" "icmp")
812 (set_attr "mode" "QI")])
813
814 (define_insn "cmpqi_ext_3_insn_rex64"
815 [(set (reg FLAGS_REG)
816 (compare
817 (subreg:QI
818 (zero_extract:SI
819 (match_operand 0 "ext_register_operand" "Q")
820 (const_int 8)
821 (const_int 8)) 0)
822 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
823 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
824 "cmp{b}\t{%1, %h0|%h0, %1}"
825 [(set_attr "type" "icmp")
826 (set_attr "mode" "QI")])
827
828 (define_insn "*cmpqi_ext_4"
829 [(set (reg FLAGS_REG)
830 (compare
831 (subreg:QI
832 (zero_extract:SI
833 (match_operand 0 "ext_register_operand" "Q")
834 (const_int 8)
835 (const_int 8)) 0)
836 (subreg:QI
837 (zero_extract:SI
838 (match_operand 1 "ext_register_operand" "Q")
839 (const_int 8)
840 (const_int 8)) 0)))]
841 "ix86_match_ccmode (insn, CCmode)"
842 "cmp{b}\t{%h1, %h0|%h0, %h1}"
843 [(set_attr "type" "icmp")
844 (set_attr "mode" "QI")])
845
846 ;; These implement float point compares.
847 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
848 ;; which would allow mix and match FP modes on the compares. Which is what
849 ;; the old patterns did, but with many more of them.
850
851 (define_expand "cmpxf"
852 [(set (reg:CC FLAGS_REG)
853 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
854 (match_operand:XF 1 "nonmemory_operand" "")))]
855 "TARGET_80387"
856 {
857 ix86_compare_op0 = operands[0];
858 ix86_compare_op1 = operands[1];
859 DONE;
860 })
861
862 (define_expand "cmp<mode>"
863 [(set (reg:CC FLAGS_REG)
864 (compare:CC (match_operand:SSEMODEF 0 "cmp_fp_expander_operand" "")
865 (match_operand:SSEMODEF 1 "cmp_fp_expander_operand" "")))]
866 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
867 {
868 ix86_compare_op0 = operands[0];
869 ix86_compare_op1 = operands[1];
870 DONE;
871 })
872
873 ;; FP compares, step 1:
874 ;; Set the FP condition codes.
875 ;;
876 ;; CCFPmode compare with exceptions
877 ;; CCFPUmode compare with no exceptions
878
879 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
880 ;; used to manage the reg stack popping would not be preserved.
881
882 (define_insn "*cmpfp_0"
883 [(set (match_operand:HI 0 "register_operand" "=a")
884 (unspec:HI
885 [(compare:CCFP
886 (match_operand 1 "register_operand" "f")
887 (match_operand 2 "const0_operand" "X"))]
888 UNSPEC_FNSTSW))]
889 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
890 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
891 "* return output_fp_compare (insn, operands, 0, 0);"
892 [(set_attr "type" "multi")
893 (set_attr "unit" "i387")
894 (set (attr "mode")
895 (cond [(match_operand:SF 1 "" "")
896 (const_string "SF")
897 (match_operand:DF 1 "" "")
898 (const_string "DF")
899 ]
900 (const_string "XF")))])
901
902 (define_insn "*cmpfp_xf"
903 [(set (match_operand:HI 0 "register_operand" "=a")
904 (unspec:HI
905 [(compare:CCFP
906 (match_operand:XF 1 "register_operand" "f")
907 (match_operand:XF 2 "register_operand" "f"))]
908 UNSPEC_FNSTSW))]
909 "TARGET_80387"
910 "* return output_fp_compare (insn, operands, 0, 0);"
911 [(set_attr "type" "multi")
912 (set_attr "unit" "i387")
913 (set_attr "mode" "XF")])
914
915 (define_insn "*cmpfp_<mode>"
916 [(set (match_operand:HI 0 "register_operand" "=a")
917 (unspec:HI
918 [(compare:CCFP
919 (match_operand:X87MODEF12 1 "register_operand" "f")
920 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm"))]
921 UNSPEC_FNSTSW))]
922 "TARGET_80387"
923 "* return output_fp_compare (insn, operands, 0, 0);"
924 [(set_attr "type" "multi")
925 (set_attr "unit" "i387")
926 (set_attr "mode" "<MODE>")])
927
928 (define_insn "*cmpfp_u"
929 [(set (match_operand:HI 0 "register_operand" "=a")
930 (unspec:HI
931 [(compare:CCFPU
932 (match_operand 1 "register_operand" "f")
933 (match_operand 2 "register_operand" "f"))]
934 UNSPEC_FNSTSW))]
935 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
936 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
937 "* return output_fp_compare (insn, operands, 0, 1);"
938 [(set_attr "type" "multi")
939 (set_attr "unit" "i387")
940 (set (attr "mode")
941 (cond [(match_operand:SF 1 "" "")
942 (const_string "SF")
943 (match_operand:DF 1 "" "")
944 (const_string "DF")
945 ]
946 (const_string "XF")))])
947
948 (define_insn "*cmpfp_<mode>"
949 [(set (match_operand:HI 0 "register_operand" "=a")
950 (unspec:HI
951 [(compare:CCFP
952 (match_operand 1 "register_operand" "f")
953 (match_operator 3 "float_operator"
954 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
955 UNSPEC_FNSTSW))]
956 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
957 && TARGET_USE_<MODE>MODE_FIOP
958 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
959 "* return output_fp_compare (insn, operands, 0, 0);"
960 [(set_attr "type" "multi")
961 (set_attr "unit" "i387")
962 (set_attr "fp_int_src" "true")
963 (set_attr "mode" "<MODE>")])
964
965 ;; FP compares, step 2
966 ;; Move the fpsw to ax.
967
968 (define_insn "x86_fnstsw_1"
969 [(set (match_operand:HI 0 "register_operand" "=a")
970 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
971 "TARGET_80387"
972 "fnstsw\t%0"
973 [(set_attr "length" "2")
974 (set_attr "mode" "SI")
975 (set_attr "unit" "i387")])
976
977 ;; FP compares, step 3
978 ;; Get ax into flags, general case.
979
980 (define_insn "x86_sahf_1"
981 [(set (reg:CC FLAGS_REG)
982 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
983 UNSPEC_SAHF))]
984 "TARGET_SAHF"
985 {
986 #ifdef HAVE_AS_IX86_SAHF
987 return "sahf";
988 #else
989 return ".byte\t0x9e";
990 #endif
991 }
992 [(set_attr "length" "1")
993 (set_attr "athlon_decode" "vector")
994 (set_attr "amdfam10_decode" "direct")
995 (set_attr "mode" "SI")])
996
997 ;; Pentium Pro can do steps 1 through 3 in one go.
998 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
999 (define_insn "*cmpfp_i_mixed"
1000 [(set (reg:CCFP FLAGS_REG)
1001 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1002 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1003 "TARGET_MIX_SSE_I387
1004 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1005 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006 "* return output_fp_compare (insn, operands, 1, 0);"
1007 [(set_attr "type" "fcmp,ssecomi")
1008 (set (attr "mode")
1009 (if_then_else (match_operand:SF 1 "" "")
1010 (const_string "SF")
1011 (const_string "DF")))
1012 (set_attr "athlon_decode" "vector")
1013 (set_attr "amdfam10_decode" "direct")])
1014
1015 (define_insn "*cmpfp_i_sse"
1016 [(set (reg:CCFP FLAGS_REG)
1017 (compare:CCFP (match_operand 0 "register_operand" "x")
1018 (match_operand 1 "nonimmediate_operand" "xm")))]
1019 "TARGET_SSE_MATH
1020 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022 "* return output_fp_compare (insn, operands, 1, 0);"
1023 [(set_attr "type" "ssecomi")
1024 (set (attr "mode")
1025 (if_then_else (match_operand:SF 1 "" "")
1026 (const_string "SF")
1027 (const_string "DF")))
1028 (set_attr "athlon_decode" "vector")
1029 (set_attr "amdfam10_decode" "direct")])
1030
1031 (define_insn "*cmpfp_i_i387"
1032 [(set (reg:CCFP FLAGS_REG)
1033 (compare:CCFP (match_operand 0 "register_operand" "f")
1034 (match_operand 1 "register_operand" "f")))]
1035 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1036 && TARGET_CMOVE
1037 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1038 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039 "* return output_fp_compare (insn, operands, 1, 0);"
1040 [(set_attr "type" "fcmp")
1041 (set (attr "mode")
1042 (cond [(match_operand:SF 1 "" "")
1043 (const_string "SF")
1044 (match_operand:DF 1 "" "")
1045 (const_string "DF")
1046 ]
1047 (const_string "XF")))
1048 (set_attr "athlon_decode" "vector")
1049 (set_attr "amdfam10_decode" "direct")])
1050
1051 (define_insn "*cmpfp_iu_mixed"
1052 [(set (reg:CCFPU FLAGS_REG)
1053 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1054 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1055 "TARGET_MIX_SSE_I387
1056 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1057 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1058 "* return output_fp_compare (insn, operands, 1, 1);"
1059 [(set_attr "type" "fcmp,ssecomi")
1060 (set (attr "mode")
1061 (if_then_else (match_operand:SF 1 "" "")
1062 (const_string "SF")
1063 (const_string "DF")))
1064 (set_attr "athlon_decode" "vector")
1065 (set_attr "amdfam10_decode" "direct")])
1066
1067 (define_insn "*cmpfp_iu_sse"
1068 [(set (reg:CCFPU FLAGS_REG)
1069 (compare:CCFPU (match_operand 0 "register_operand" "x")
1070 (match_operand 1 "nonimmediate_operand" "xm")))]
1071 "TARGET_SSE_MATH
1072 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1073 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1074 "* return output_fp_compare (insn, operands, 1, 1);"
1075 [(set_attr "type" "ssecomi")
1076 (set (attr "mode")
1077 (if_then_else (match_operand:SF 1 "" "")
1078 (const_string "SF")
1079 (const_string "DF")))
1080 (set_attr "athlon_decode" "vector")
1081 (set_attr "amdfam10_decode" "direct")])
1082
1083 (define_insn "*cmpfp_iu_387"
1084 [(set (reg:CCFPU FLAGS_REG)
1085 (compare:CCFPU (match_operand 0 "register_operand" "f")
1086 (match_operand 1 "register_operand" "f")))]
1087 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1088 && TARGET_CMOVE
1089 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1090 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1091 "* return output_fp_compare (insn, operands, 1, 1);"
1092 [(set_attr "type" "fcmp")
1093 (set (attr "mode")
1094 (cond [(match_operand:SF 1 "" "")
1095 (const_string "SF")
1096 (match_operand:DF 1 "" "")
1097 (const_string "DF")
1098 ]
1099 (const_string "XF")))
1100 (set_attr "athlon_decode" "vector")
1101 (set_attr "amdfam10_decode" "direct")])
1102 \f
1103 ;; Move instructions.
1104
1105 ;; General case of fullword move.
1106
1107 (define_expand "movsi"
1108 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1109 (match_operand:SI 1 "general_operand" ""))]
1110 ""
1111 "ix86_expand_move (SImode, operands); DONE;")
1112
1113 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1114 ;; general_operand.
1115 ;;
1116 ;; %%% We don't use a post-inc memory reference because x86 is not a
1117 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1118 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1119 ;; targets without our curiosities, and it is just as easy to represent
1120 ;; this differently.
1121
1122 (define_insn "*pushsi2"
1123 [(set (match_operand:SI 0 "push_operand" "=<")
1124 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1125 "!TARGET_64BIT"
1126 "push{l}\t%1"
1127 [(set_attr "type" "push")
1128 (set_attr "mode" "SI")])
1129
1130 ;; For 64BIT abi we always round up to 8 bytes.
1131 (define_insn "*pushsi2_rex64"
1132 [(set (match_operand:SI 0 "push_operand" "=X")
1133 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1134 "TARGET_64BIT"
1135 "push{q}\t%q1"
1136 [(set_attr "type" "push")
1137 (set_attr "mode" "SI")])
1138
1139 (define_insn "*pushsi2_prologue"
1140 [(set (match_operand:SI 0 "push_operand" "=<")
1141 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1142 (clobber (mem:BLK (scratch)))]
1143 "!TARGET_64BIT"
1144 "push{l}\t%1"
1145 [(set_attr "type" "push")
1146 (set_attr "mode" "SI")])
1147
1148 (define_insn "*popsi1_epilogue"
1149 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1150 (mem:SI (reg:SI SP_REG)))
1151 (set (reg:SI SP_REG)
1152 (plus:SI (reg:SI SP_REG) (const_int 4)))
1153 (clobber (mem:BLK (scratch)))]
1154 "!TARGET_64BIT"
1155 "pop{l}\t%0"
1156 [(set_attr "type" "pop")
1157 (set_attr "mode" "SI")])
1158
1159 (define_insn "popsi1"
1160 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1161 (mem:SI (reg:SI SP_REG)))
1162 (set (reg:SI SP_REG)
1163 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1164 "!TARGET_64BIT"
1165 "pop{l}\t%0"
1166 [(set_attr "type" "pop")
1167 (set_attr "mode" "SI")])
1168
1169 (define_insn "*movsi_xor"
1170 [(set (match_operand:SI 0 "register_operand" "=r")
1171 (match_operand:SI 1 "const0_operand" "i"))
1172 (clobber (reg:CC FLAGS_REG))]
1173 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1174 "xor{l}\t%0, %0"
1175 [(set_attr "type" "alu1")
1176 (set_attr "mode" "SI")
1177 (set_attr "length_immediate" "0")])
1178
1179 (define_insn "*movsi_or"
1180 [(set (match_operand:SI 0 "register_operand" "=r")
1181 (match_operand:SI 1 "immediate_operand" "i"))
1182 (clobber (reg:CC FLAGS_REG))]
1183 "reload_completed
1184 && operands[1] == constm1_rtx
1185 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1186 {
1187 operands[1] = constm1_rtx;
1188 return "or{l}\t{%1, %0|%0, %1}";
1189 }
1190 [(set_attr "type" "alu1")
1191 (set_attr "mode" "SI")
1192 (set_attr "length_immediate" "1")])
1193
1194 (define_insn "*movsi_1"
1195 [(set (match_operand:SI 0 "nonimmediate_operand"
1196 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1197 (match_operand:SI 1 "general_operand"
1198 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1199 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1200 {
1201 switch (get_attr_type (insn))
1202 {
1203 case TYPE_SSELOG1:
1204 if (get_attr_mode (insn) == MODE_TI)
1205 return "pxor\t%0, %0";
1206 return "xorps\t%0, %0";
1207
1208 case TYPE_SSEMOV:
1209 switch (get_attr_mode (insn))
1210 {
1211 case MODE_TI:
1212 return "movdqa\t{%1, %0|%0, %1}";
1213 case MODE_V4SF:
1214 return "movaps\t{%1, %0|%0, %1}";
1215 case MODE_SI:
1216 return "movd\t{%1, %0|%0, %1}";
1217 case MODE_SF:
1218 return "movss\t{%1, %0|%0, %1}";
1219 default:
1220 gcc_unreachable ();
1221 }
1222
1223 case TYPE_MMXADD:
1224 return "pxor\t%0, %0";
1225
1226 case TYPE_MMXMOV:
1227 if (get_attr_mode (insn) == MODE_DI)
1228 return "movq\t{%1, %0|%0, %1}";
1229 return "movd\t{%1, %0|%0, %1}";
1230
1231 case TYPE_LEA:
1232 return "lea{l}\t{%1, %0|%0, %1}";
1233
1234 default:
1235 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1236 return "mov{l}\t{%1, %0|%0, %1}";
1237 }
1238 }
1239 [(set (attr "type")
1240 (cond [(eq_attr "alternative" "2")
1241 (const_string "mmxadd")
1242 (eq_attr "alternative" "3,4,5")
1243 (const_string "mmxmov")
1244 (eq_attr "alternative" "6")
1245 (const_string "sselog1")
1246 (eq_attr "alternative" "7,8,9,10,11")
1247 (const_string "ssemov")
1248 (match_operand:DI 1 "pic_32bit_operand" "")
1249 (const_string "lea")
1250 ]
1251 (const_string "imov")))
1252 (set (attr "mode")
1253 (cond [(eq_attr "alternative" "2,3")
1254 (const_string "DI")
1255 (eq_attr "alternative" "6,7")
1256 (if_then_else
1257 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1258 (const_string "V4SF")
1259 (const_string "TI"))
1260 (and (eq_attr "alternative" "8,9,10,11")
1261 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1262 (const_string "SF")
1263 ]
1264 (const_string "SI")))])
1265
1266 ;; Stores and loads of ax to arbitrary constant address.
1267 ;; We fake an second form of instruction to force reload to load address
1268 ;; into register when rax is not available
1269 (define_insn "*movabssi_1_rex64"
1270 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1271 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1272 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1273 "@
1274 movabs{l}\t{%1, %P0|%P0, %1}
1275 mov{l}\t{%1, %a0|%a0, %1}"
1276 [(set_attr "type" "imov")
1277 (set_attr "modrm" "0,*")
1278 (set_attr "length_address" "8,0")
1279 (set_attr "length_immediate" "0,*")
1280 (set_attr "memory" "store")
1281 (set_attr "mode" "SI")])
1282
1283 (define_insn "*movabssi_2_rex64"
1284 [(set (match_operand:SI 0 "register_operand" "=a,r")
1285 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1286 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1287 "@
1288 movabs{l}\t{%P1, %0|%0, %P1}
1289 mov{l}\t{%a1, %0|%0, %a1}"
1290 [(set_attr "type" "imov")
1291 (set_attr "modrm" "0,*")
1292 (set_attr "length_address" "8,0")
1293 (set_attr "length_immediate" "0")
1294 (set_attr "memory" "load")
1295 (set_attr "mode" "SI")])
1296
1297 (define_insn "*swapsi"
1298 [(set (match_operand:SI 0 "register_operand" "+r")
1299 (match_operand:SI 1 "register_operand" "+r"))
1300 (set (match_dup 1)
1301 (match_dup 0))]
1302 ""
1303 "xchg{l}\t%1, %0"
1304 [(set_attr "type" "imov")
1305 (set_attr "mode" "SI")
1306 (set_attr "pent_pair" "np")
1307 (set_attr "athlon_decode" "vector")
1308 (set_attr "amdfam10_decode" "double")])
1309
1310 (define_expand "movhi"
1311 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1312 (match_operand:HI 1 "general_operand" ""))]
1313 ""
1314 "ix86_expand_move (HImode, operands); DONE;")
1315
1316 (define_insn "*pushhi2"
1317 [(set (match_operand:HI 0 "push_operand" "=X")
1318 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1319 "!TARGET_64BIT"
1320 "push{l}\t%k1"
1321 [(set_attr "type" "push")
1322 (set_attr "mode" "SI")])
1323
1324 ;; For 64BIT abi we always round up to 8 bytes.
1325 (define_insn "*pushhi2_rex64"
1326 [(set (match_operand:HI 0 "push_operand" "=X")
1327 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1328 "TARGET_64BIT"
1329 "push{q}\t%q1"
1330 [(set_attr "type" "push")
1331 (set_attr "mode" "DI")])
1332
1333 (define_insn "*movhi_1"
1334 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1335 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1336 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1337 {
1338 switch (get_attr_type (insn))
1339 {
1340 case TYPE_IMOVX:
1341 /* movzwl is faster than movw on p2 due to partial word stalls,
1342 though not as fast as an aligned movl. */
1343 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1344 default:
1345 if (get_attr_mode (insn) == MODE_SI)
1346 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1347 else
1348 return "mov{w}\t{%1, %0|%0, %1}";
1349 }
1350 }
1351 [(set (attr "type")
1352 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1353 (const_string "imov")
1354 (and (eq_attr "alternative" "0")
1355 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1356 (const_int 0))
1357 (eq (symbol_ref "TARGET_HIMODE_MATH")
1358 (const_int 0))))
1359 (const_string "imov")
1360 (and (eq_attr "alternative" "1,2")
1361 (match_operand:HI 1 "aligned_operand" ""))
1362 (const_string "imov")
1363 (and (ne (symbol_ref "TARGET_MOVX")
1364 (const_int 0))
1365 (eq_attr "alternative" "0,2"))
1366 (const_string "imovx")
1367 ]
1368 (const_string "imov")))
1369 (set (attr "mode")
1370 (cond [(eq_attr "type" "imovx")
1371 (const_string "SI")
1372 (and (eq_attr "alternative" "1,2")
1373 (match_operand:HI 1 "aligned_operand" ""))
1374 (const_string "SI")
1375 (and (eq_attr "alternative" "0")
1376 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1377 (const_int 0))
1378 (eq (symbol_ref "TARGET_HIMODE_MATH")
1379 (const_int 0))))
1380 (const_string "SI")
1381 ]
1382 (const_string "HI")))])
1383
1384 ;; Stores and loads of ax to arbitrary constant address.
1385 ;; We fake an second form of instruction to force reload to load address
1386 ;; into register when rax is not available
1387 (define_insn "*movabshi_1_rex64"
1388 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1389 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1390 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1391 "@
1392 movabs{w}\t{%1, %P0|%P0, %1}
1393 mov{w}\t{%1, %a0|%a0, %1}"
1394 [(set_attr "type" "imov")
1395 (set_attr "modrm" "0,*")
1396 (set_attr "length_address" "8,0")
1397 (set_attr "length_immediate" "0,*")
1398 (set_attr "memory" "store")
1399 (set_attr "mode" "HI")])
1400
1401 (define_insn "*movabshi_2_rex64"
1402 [(set (match_operand:HI 0 "register_operand" "=a,r")
1403 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1404 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1405 "@
1406 movabs{w}\t{%P1, %0|%0, %P1}
1407 mov{w}\t{%a1, %0|%0, %a1}"
1408 [(set_attr "type" "imov")
1409 (set_attr "modrm" "0,*")
1410 (set_attr "length_address" "8,0")
1411 (set_attr "length_immediate" "0")
1412 (set_attr "memory" "load")
1413 (set_attr "mode" "HI")])
1414
1415 (define_insn "*swaphi_1"
1416 [(set (match_operand:HI 0 "register_operand" "+r")
1417 (match_operand:HI 1 "register_operand" "+r"))
1418 (set (match_dup 1)
1419 (match_dup 0))]
1420 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1421 "xchg{l}\t%k1, %k0"
1422 [(set_attr "type" "imov")
1423 (set_attr "mode" "SI")
1424 (set_attr "pent_pair" "np")
1425 (set_attr "athlon_decode" "vector")
1426 (set_attr "amdfam10_decode" "double")])
1427
1428 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1429 (define_insn "*swaphi_2"
1430 [(set (match_operand:HI 0 "register_operand" "+r")
1431 (match_operand:HI 1 "register_operand" "+r"))
1432 (set (match_dup 1)
1433 (match_dup 0))]
1434 "TARGET_PARTIAL_REG_STALL"
1435 "xchg{w}\t%1, %0"
1436 [(set_attr "type" "imov")
1437 (set_attr "mode" "HI")
1438 (set_attr "pent_pair" "np")
1439 (set_attr "athlon_decode" "vector")])
1440
1441 (define_expand "movstricthi"
1442 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1443 (match_operand:HI 1 "general_operand" ""))]
1444 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1445 {
1446 /* Don't generate memory->memory moves, go through a register */
1447 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1448 operands[1] = force_reg (HImode, operands[1]);
1449 })
1450
1451 (define_insn "*movstricthi_1"
1452 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1453 (match_operand:HI 1 "general_operand" "rn,m"))]
1454 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1455 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1456 "mov{w}\t{%1, %0|%0, %1}"
1457 [(set_attr "type" "imov")
1458 (set_attr "mode" "HI")])
1459
1460 (define_insn "*movstricthi_xor"
1461 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1462 (match_operand:HI 1 "const0_operand" "i"))
1463 (clobber (reg:CC FLAGS_REG))]
1464 "reload_completed
1465 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1466 "xor{w}\t%0, %0"
1467 [(set_attr "type" "alu1")
1468 (set_attr "mode" "HI")
1469 (set_attr "length_immediate" "0")])
1470
1471 (define_expand "movqi"
1472 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1473 (match_operand:QI 1 "general_operand" ""))]
1474 ""
1475 "ix86_expand_move (QImode, operands); DONE;")
1476
1477 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1478 ;; "push a byte". But actually we use pushl, which has the effect
1479 ;; of rounding the amount pushed up to a word.
1480
1481 (define_insn "*pushqi2"
1482 [(set (match_operand:QI 0 "push_operand" "=X")
1483 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1484 "!TARGET_64BIT"
1485 "push{l}\t%k1"
1486 [(set_attr "type" "push")
1487 (set_attr "mode" "SI")])
1488
1489 ;; For 64BIT abi we always round up to 8 bytes.
1490 (define_insn "*pushqi2_rex64"
1491 [(set (match_operand:QI 0 "push_operand" "=X")
1492 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1493 "TARGET_64BIT"
1494 "push{q}\t%q1"
1495 [(set_attr "type" "push")
1496 (set_attr "mode" "DI")])
1497
1498 ;; Situation is quite tricky about when to choose full sized (SImode) move
1499 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1500 ;; partial register dependency machines (such as AMD Athlon), where QImode
1501 ;; moves issue extra dependency and for partial register stalls machines
1502 ;; that don't use QImode patterns (and QImode move cause stall on the next
1503 ;; instruction).
1504 ;;
1505 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1506 ;; register stall machines with, where we use QImode instructions, since
1507 ;; partial register stall can be caused there. Then we use movzx.
1508 (define_insn "*movqi_1"
1509 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1510 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1511 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1512 {
1513 switch (get_attr_type (insn))
1514 {
1515 case TYPE_IMOVX:
1516 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1517 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1518 default:
1519 if (get_attr_mode (insn) == MODE_SI)
1520 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1521 else
1522 return "mov{b}\t{%1, %0|%0, %1}";
1523 }
1524 }
1525 [(set (attr "type")
1526 (cond [(and (eq_attr "alternative" "5")
1527 (not (match_operand:QI 1 "aligned_operand" "")))
1528 (const_string "imovx")
1529 (ne (symbol_ref "optimize_size") (const_int 0))
1530 (const_string "imov")
1531 (and (eq_attr "alternative" "3")
1532 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1533 (const_int 0))
1534 (eq (symbol_ref "TARGET_QIMODE_MATH")
1535 (const_int 0))))
1536 (const_string "imov")
1537 (eq_attr "alternative" "3,5")
1538 (const_string "imovx")
1539 (and (ne (symbol_ref "TARGET_MOVX")
1540 (const_int 0))
1541 (eq_attr "alternative" "2"))
1542 (const_string "imovx")
1543 ]
1544 (const_string "imov")))
1545 (set (attr "mode")
1546 (cond [(eq_attr "alternative" "3,4,5")
1547 (const_string "SI")
1548 (eq_attr "alternative" "6")
1549 (const_string "QI")
1550 (eq_attr "type" "imovx")
1551 (const_string "SI")
1552 (and (eq_attr "type" "imov")
1553 (and (eq_attr "alternative" "0,1")
1554 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1555 (const_int 0))
1556 (and (eq (symbol_ref "optimize_size")
1557 (const_int 0))
1558 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1559 (const_int 0))))))
1560 (const_string "SI")
1561 ;; Avoid partial register stalls when not using QImode arithmetic
1562 (and (eq_attr "type" "imov")
1563 (and (eq_attr "alternative" "0,1")
1564 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1565 (const_int 0))
1566 (eq (symbol_ref "TARGET_QIMODE_MATH")
1567 (const_int 0)))))
1568 (const_string "SI")
1569 ]
1570 (const_string "QI")))])
1571
1572 (define_expand "reload_outqi"
1573 [(parallel [(match_operand:QI 0 "" "=m")
1574 (match_operand:QI 1 "register_operand" "r")
1575 (match_operand:QI 2 "register_operand" "=&q")])]
1576 ""
1577 {
1578 rtx op0, op1, op2;
1579 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1580
1581 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1582 if (! q_regs_operand (op1, QImode))
1583 {
1584 emit_insn (gen_movqi (op2, op1));
1585 op1 = op2;
1586 }
1587 emit_insn (gen_movqi (op0, op1));
1588 DONE;
1589 })
1590
1591 (define_insn "*swapqi_1"
1592 [(set (match_operand:QI 0 "register_operand" "+r")
1593 (match_operand:QI 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" "vector")])
1603
1604 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1605 (define_insn "*swapqi_2"
1606 [(set (match_operand:QI 0 "register_operand" "+q")
1607 (match_operand:QI 1 "register_operand" "+q"))
1608 (set (match_dup 1)
1609 (match_dup 0))]
1610 "TARGET_PARTIAL_REG_STALL"
1611 "xchg{b}\t%1, %0"
1612 [(set_attr "type" "imov")
1613 (set_attr "mode" "QI")
1614 (set_attr "pent_pair" "np")
1615 (set_attr "athlon_decode" "vector")])
1616
1617 (define_expand "movstrictqi"
1618 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1619 (match_operand:QI 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 (QImode, operands[1]);
1625 })
1626
1627 (define_insn "*movstrictqi_1"
1628 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1629 (match_operand:QI 1 "general_operand" "*qn,m"))]
1630 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1631 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1632 "mov{b}\t{%1, %0|%0, %1}"
1633 [(set_attr "type" "imov")
1634 (set_attr "mode" "QI")])
1635
1636 (define_insn "*movstrictqi_xor"
1637 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1638 (match_operand:QI 1 "const0_operand" "i"))
1639 (clobber (reg:CC FLAGS_REG))]
1640 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1641 "xor{b}\t%0, %0"
1642 [(set_attr "type" "alu1")
1643 (set_attr "mode" "QI")
1644 (set_attr "length_immediate" "0")])
1645
1646 (define_insn "*movsi_extv_1"
1647 [(set (match_operand:SI 0 "register_operand" "=R")
1648 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1649 (const_int 8)
1650 (const_int 8)))]
1651 ""
1652 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1653 [(set_attr "type" "imovx")
1654 (set_attr "mode" "SI")])
1655
1656 (define_insn "*movhi_extv_1"
1657 [(set (match_operand:HI 0 "register_operand" "=R")
1658 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1659 (const_int 8)
1660 (const_int 8)))]
1661 ""
1662 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1663 [(set_attr "type" "imovx")
1664 (set_attr "mode" "SI")])
1665
1666 (define_insn "*movqi_extv_1"
1667 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1668 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1669 (const_int 8)
1670 (const_int 8)))]
1671 "!TARGET_64BIT"
1672 {
1673 switch (get_attr_type (insn))
1674 {
1675 case TYPE_IMOVX:
1676 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1677 default:
1678 return "mov{b}\t{%h1, %0|%0, %h1}";
1679 }
1680 }
1681 [(set (attr "type")
1682 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1683 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1684 (ne (symbol_ref "TARGET_MOVX")
1685 (const_int 0))))
1686 (const_string "imovx")
1687 (const_string "imov")))
1688 (set (attr "mode")
1689 (if_then_else (eq_attr "type" "imovx")
1690 (const_string "SI")
1691 (const_string "QI")))])
1692
1693 (define_insn "*movqi_extv_1_rex64"
1694 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1695 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1696 (const_int 8)
1697 (const_int 8)))]
1698 "TARGET_64BIT"
1699 {
1700 switch (get_attr_type (insn))
1701 {
1702 case TYPE_IMOVX:
1703 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1704 default:
1705 return "mov{b}\t{%h1, %0|%0, %h1}";
1706 }
1707 }
1708 [(set (attr "type")
1709 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1710 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1711 (ne (symbol_ref "TARGET_MOVX")
1712 (const_int 0))))
1713 (const_string "imovx")
1714 (const_string "imov")))
1715 (set (attr "mode")
1716 (if_then_else (eq_attr "type" "imovx")
1717 (const_string "SI")
1718 (const_string "QI")))])
1719
1720 ;; Stores and loads of ax to arbitrary constant address.
1721 ;; We fake an second form of instruction to force reload to load address
1722 ;; into register when rax is not available
1723 (define_insn "*movabsqi_1_rex64"
1724 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1725 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1726 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1727 "@
1728 movabs{b}\t{%1, %P0|%P0, %1}
1729 mov{b}\t{%1, %a0|%a0, %1}"
1730 [(set_attr "type" "imov")
1731 (set_attr "modrm" "0,*")
1732 (set_attr "length_address" "8,0")
1733 (set_attr "length_immediate" "0,*")
1734 (set_attr "memory" "store")
1735 (set_attr "mode" "QI")])
1736
1737 (define_insn "*movabsqi_2_rex64"
1738 [(set (match_operand:QI 0 "register_operand" "=a,r")
1739 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1740 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1741 "@
1742 movabs{b}\t{%P1, %0|%0, %P1}
1743 mov{b}\t{%a1, %0|%0, %a1}"
1744 [(set_attr "type" "imov")
1745 (set_attr "modrm" "0,*")
1746 (set_attr "length_address" "8,0")
1747 (set_attr "length_immediate" "0")
1748 (set_attr "memory" "load")
1749 (set_attr "mode" "QI")])
1750
1751 (define_insn "*movdi_extzv_1"
1752 [(set (match_operand:DI 0 "register_operand" "=R")
1753 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1754 (const_int 8)
1755 (const_int 8)))]
1756 "TARGET_64BIT"
1757 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1758 [(set_attr "type" "imovx")
1759 (set_attr "mode" "DI")])
1760
1761 (define_insn "*movsi_extzv_1"
1762 [(set (match_operand:SI 0 "register_operand" "=R")
1763 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1764 (const_int 8)
1765 (const_int 8)))]
1766 ""
1767 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1768 [(set_attr "type" "imovx")
1769 (set_attr "mode" "SI")])
1770
1771 (define_insn "*movqi_extzv_2"
1772 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1773 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1774 (const_int 8)
1775 (const_int 8)) 0))]
1776 "!TARGET_64BIT"
1777 {
1778 switch (get_attr_type (insn))
1779 {
1780 case TYPE_IMOVX:
1781 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1782 default:
1783 return "mov{b}\t{%h1, %0|%0, %h1}";
1784 }
1785 }
1786 [(set (attr "type")
1787 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1788 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1789 (ne (symbol_ref "TARGET_MOVX")
1790 (const_int 0))))
1791 (const_string "imovx")
1792 (const_string "imov")))
1793 (set (attr "mode")
1794 (if_then_else (eq_attr "type" "imovx")
1795 (const_string "SI")
1796 (const_string "QI")))])
1797
1798 (define_insn "*movqi_extzv_2_rex64"
1799 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1800 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1801 (const_int 8)
1802 (const_int 8)) 0))]
1803 "TARGET_64BIT"
1804 {
1805 switch (get_attr_type (insn))
1806 {
1807 case TYPE_IMOVX:
1808 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1809 default:
1810 return "mov{b}\t{%h1, %0|%0, %h1}";
1811 }
1812 }
1813 [(set (attr "type")
1814 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1815 (ne (symbol_ref "TARGET_MOVX")
1816 (const_int 0)))
1817 (const_string "imovx")
1818 (const_string "imov")))
1819 (set (attr "mode")
1820 (if_then_else (eq_attr "type" "imovx")
1821 (const_string "SI")
1822 (const_string "QI")))])
1823
1824 (define_insn "movsi_insv_1"
1825 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1826 (const_int 8)
1827 (const_int 8))
1828 (match_operand:SI 1 "general_operand" "Qmn"))]
1829 "!TARGET_64BIT"
1830 "mov{b}\t{%b1, %h0|%h0, %b1}"
1831 [(set_attr "type" "imov")
1832 (set_attr "mode" "QI")])
1833
1834 (define_insn "*movsi_insv_1_rex64"
1835 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1836 (const_int 8)
1837 (const_int 8))
1838 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1839 "TARGET_64BIT"
1840 "mov{b}\t{%b1, %h0|%h0, %b1}"
1841 [(set_attr "type" "imov")
1842 (set_attr "mode" "QI")])
1843
1844 (define_insn "movdi_insv_1_rex64"
1845 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1846 (const_int 8)
1847 (const_int 8))
1848 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1849 "TARGET_64BIT"
1850 "mov{b}\t{%b1, %h0|%h0, %b1}"
1851 [(set_attr "type" "imov")
1852 (set_attr "mode" "QI")])
1853
1854 (define_insn "*movqi_insv_2"
1855 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1856 (const_int 8)
1857 (const_int 8))
1858 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1859 (const_int 8)))]
1860 ""
1861 "mov{b}\t{%h1, %h0|%h0, %h1}"
1862 [(set_attr "type" "imov")
1863 (set_attr "mode" "QI")])
1864
1865 (define_expand "movdi"
1866 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1867 (match_operand:DI 1 "general_operand" ""))]
1868 ""
1869 "ix86_expand_move (DImode, operands); DONE;")
1870
1871 (define_insn "*pushdi"
1872 [(set (match_operand:DI 0 "push_operand" "=<")
1873 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1874 "!TARGET_64BIT"
1875 "#")
1876
1877 (define_insn "*pushdi2_rex64"
1878 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1879 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1880 "TARGET_64BIT"
1881 "@
1882 push{q}\t%1
1883 #"
1884 [(set_attr "type" "push,multi")
1885 (set_attr "mode" "DI")])
1886
1887 ;; Convert impossible pushes of immediate to existing instructions.
1888 ;; First try to get scratch register and go through it. In case this
1889 ;; fails, push sign extended lower part first and then overwrite
1890 ;; upper part by 32bit move.
1891 (define_peephole2
1892 [(match_scratch:DI 2 "r")
1893 (set (match_operand:DI 0 "push_operand" "")
1894 (match_operand:DI 1 "immediate_operand" ""))]
1895 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1896 && !x86_64_immediate_operand (operands[1], DImode)"
1897 [(set (match_dup 2) (match_dup 1))
1898 (set (match_dup 0) (match_dup 2))]
1899 "")
1900
1901 ;; We need to define this as both peepholer and splitter for case
1902 ;; peephole2 pass is not run.
1903 ;; "&& 1" is needed to keep it from matching the previous pattern.
1904 (define_peephole2
1905 [(set (match_operand:DI 0 "push_operand" "")
1906 (match_operand:DI 1 "immediate_operand" ""))]
1907 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1908 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1909 [(set (match_dup 0) (match_dup 1))
1910 (set (match_dup 2) (match_dup 3))]
1911 "split_di (operands + 1, 1, operands + 2, operands + 3);
1912 operands[1] = gen_lowpart (DImode, operands[2]);
1913 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1914 GEN_INT (4)));
1915 ")
1916
1917 (define_split
1918 [(set (match_operand:DI 0 "push_operand" "")
1919 (match_operand:DI 1 "immediate_operand" ""))]
1920 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1921 ? epilogue_completed : reload_completed)
1922 && !symbolic_operand (operands[1], DImode)
1923 && !x86_64_immediate_operand (operands[1], DImode)"
1924 [(set (match_dup 0) (match_dup 1))
1925 (set (match_dup 2) (match_dup 3))]
1926 "split_di (operands + 1, 1, operands + 2, operands + 3);
1927 operands[1] = gen_lowpart (DImode, operands[2]);
1928 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1929 GEN_INT (4)));
1930 ")
1931
1932 (define_insn "*pushdi2_prologue_rex64"
1933 [(set (match_operand:DI 0 "push_operand" "=<")
1934 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1935 (clobber (mem:BLK (scratch)))]
1936 "TARGET_64BIT"
1937 "push{q}\t%1"
1938 [(set_attr "type" "push")
1939 (set_attr "mode" "DI")])
1940
1941 (define_insn "*popdi1_epilogue_rex64"
1942 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1943 (mem:DI (reg:DI SP_REG)))
1944 (set (reg:DI SP_REG)
1945 (plus:DI (reg:DI SP_REG) (const_int 8)))
1946 (clobber (mem:BLK (scratch)))]
1947 "TARGET_64BIT"
1948 "pop{q}\t%0"
1949 [(set_attr "type" "pop")
1950 (set_attr "mode" "DI")])
1951
1952 (define_insn "popdi1"
1953 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1954 (mem:DI (reg:DI SP_REG)))
1955 (set (reg:DI SP_REG)
1956 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1957 "TARGET_64BIT"
1958 "pop{q}\t%0"
1959 [(set_attr "type" "pop")
1960 (set_attr "mode" "DI")])
1961
1962 (define_insn "*movdi_xor_rex64"
1963 [(set (match_operand:DI 0 "register_operand" "=r")
1964 (match_operand:DI 1 "const0_operand" "i"))
1965 (clobber (reg:CC FLAGS_REG))]
1966 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1967 && reload_completed"
1968 "xor{l}\t%k0, %k0";
1969 [(set_attr "type" "alu1")
1970 (set_attr "mode" "SI")
1971 (set_attr "length_immediate" "0")])
1972
1973 (define_insn "*movdi_or_rex64"
1974 [(set (match_operand:DI 0 "register_operand" "=r")
1975 (match_operand:DI 1 "const_int_operand" "i"))
1976 (clobber (reg:CC FLAGS_REG))]
1977 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
1978 && reload_completed
1979 && operands[1] == constm1_rtx"
1980 {
1981 operands[1] = constm1_rtx;
1982 return "or{q}\t{%1, %0|%0, %1}";
1983 }
1984 [(set_attr "type" "alu1")
1985 (set_attr "mode" "DI")
1986 (set_attr "length_immediate" "1")])
1987
1988 (define_insn "*movdi_2"
1989 [(set (match_operand:DI 0 "nonimmediate_operand"
1990 "=r ,o ,*y,m*y,*y,*Yt,m ,*Yt,*Yt,*x,m ,*x,*x")
1991 (match_operand:DI 1 "general_operand"
1992 "riFo,riF,C ,*y ,m ,C ,*Yt,*Yt,m ,C ,*x,*x,m "))]
1993 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1994 "@
1995 #
1996 #
1997 pxor\t%0, %0
1998 movq\t{%1, %0|%0, %1}
1999 movq\t{%1, %0|%0, %1}
2000 pxor\t%0, %0
2001 movq\t{%1, %0|%0, %1}
2002 movdqa\t{%1, %0|%0, %1}
2003 movq\t{%1, %0|%0, %1}
2004 xorps\t%0, %0
2005 movlps\t{%1, %0|%0, %1}
2006 movaps\t{%1, %0|%0, %1}
2007 movlps\t{%1, %0|%0, %1}"
2008 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2009 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2010
2011 (define_split
2012 [(set (match_operand:DI 0 "push_operand" "")
2013 (match_operand:DI 1 "general_operand" ""))]
2014 "!TARGET_64BIT && reload_completed
2015 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2016 [(const_int 0)]
2017 "ix86_split_long_move (operands); DONE;")
2018
2019 ;; %%% This multiword shite has got to go.
2020 (define_split
2021 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2022 (match_operand:DI 1 "general_operand" ""))]
2023 "!TARGET_64BIT && reload_completed
2024 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2025 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2026 [(const_int 0)]
2027 "ix86_split_long_move (operands); DONE;")
2028
2029 (define_insn "*movdi_1_rex64"
2030 [(set (match_operand:DI 0 "nonimmediate_operand"
2031 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2032 (match_operand:DI 1 "general_operand"
2033 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2034 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2035 {
2036 switch (get_attr_type (insn))
2037 {
2038 case TYPE_SSECVT:
2039 if (SSE_REG_P (operands[0]))
2040 return "movq2dq\t{%1, %0|%0, %1}";
2041 else
2042 return "movdq2q\t{%1, %0|%0, %1}";
2043
2044 case TYPE_SSEMOV:
2045 if (get_attr_mode (insn) == MODE_TI)
2046 return "movdqa\t{%1, %0|%0, %1}";
2047 /* FALLTHRU */
2048
2049 case TYPE_MMXMOV:
2050 /* Moves from and into integer register is done using movd
2051 opcode with REX prefix. */
2052 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2053 return "movd\t{%1, %0|%0, %1}";
2054 return "movq\t{%1, %0|%0, %1}";
2055
2056 case TYPE_SSELOG1:
2057 case TYPE_MMXADD:
2058 return "pxor\t%0, %0";
2059
2060 case TYPE_MULTI:
2061 return "#";
2062
2063 case TYPE_LEA:
2064 return "lea{q}\t{%a1, %0|%0, %a1}";
2065
2066 default:
2067 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2068 if (get_attr_mode (insn) == MODE_SI)
2069 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2070 else if (which_alternative == 2)
2071 return "movabs{q}\t{%1, %0|%0, %1}";
2072 else
2073 return "mov{q}\t{%1, %0|%0, %1}";
2074 }
2075 }
2076 [(set (attr "type")
2077 (cond [(eq_attr "alternative" "5")
2078 (const_string "mmxadd")
2079 (eq_attr "alternative" "6,7,8,9,10")
2080 (const_string "mmxmov")
2081 (eq_attr "alternative" "11")
2082 (const_string "sselog1")
2083 (eq_attr "alternative" "12,13,14,15,16")
2084 (const_string "ssemov")
2085 (eq_attr "alternative" "17,18")
2086 (const_string "ssecvt")
2087 (eq_attr "alternative" "4")
2088 (const_string "multi")
2089 (match_operand:DI 1 "pic_32bit_operand" "")
2090 (const_string "lea")
2091 ]
2092 (const_string "imov")))
2093 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2094 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2095 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2096
2097 ;; Stores and loads of ax to arbitrary constant address.
2098 ;; We fake an second form of instruction to force reload to load address
2099 ;; into register when rax is not available
2100 (define_insn "*movabsdi_1_rex64"
2101 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2102 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2103 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2104 "@
2105 movabs{q}\t{%1, %P0|%P0, %1}
2106 mov{q}\t{%1, %a0|%a0, %1}"
2107 [(set_attr "type" "imov")
2108 (set_attr "modrm" "0,*")
2109 (set_attr "length_address" "8,0")
2110 (set_attr "length_immediate" "0,*")
2111 (set_attr "memory" "store")
2112 (set_attr "mode" "DI")])
2113
2114 (define_insn "*movabsdi_2_rex64"
2115 [(set (match_operand:DI 0 "register_operand" "=a,r")
2116 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2117 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2118 "@
2119 movabs{q}\t{%P1, %0|%0, %P1}
2120 mov{q}\t{%a1, %0|%0, %a1}"
2121 [(set_attr "type" "imov")
2122 (set_attr "modrm" "0,*")
2123 (set_attr "length_address" "8,0")
2124 (set_attr "length_immediate" "0")
2125 (set_attr "memory" "load")
2126 (set_attr "mode" "DI")])
2127
2128 ;; Convert impossible stores of immediate to existing instructions.
2129 ;; First try to get scratch register and go through it. In case this
2130 ;; fails, move by 32bit parts.
2131 (define_peephole2
2132 [(match_scratch:DI 2 "r")
2133 (set (match_operand:DI 0 "memory_operand" "")
2134 (match_operand:DI 1 "immediate_operand" ""))]
2135 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2136 && !x86_64_immediate_operand (operands[1], DImode)"
2137 [(set (match_dup 2) (match_dup 1))
2138 (set (match_dup 0) (match_dup 2))]
2139 "")
2140
2141 ;; We need to define this as both peepholer and splitter for case
2142 ;; peephole2 pass is not run.
2143 ;; "&& 1" is needed to keep it from matching the previous pattern.
2144 (define_peephole2
2145 [(set (match_operand:DI 0 "memory_operand" "")
2146 (match_operand:DI 1 "immediate_operand" ""))]
2147 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2148 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2149 [(set (match_dup 2) (match_dup 3))
2150 (set (match_dup 4) (match_dup 5))]
2151 "split_di (operands, 2, operands + 2, operands + 4);")
2152
2153 (define_split
2154 [(set (match_operand:DI 0 "memory_operand" "")
2155 (match_operand:DI 1 "immediate_operand" ""))]
2156 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2157 ? epilogue_completed : reload_completed)
2158 && !symbolic_operand (operands[1], DImode)
2159 && !x86_64_immediate_operand (operands[1], DImode)"
2160 [(set (match_dup 2) (match_dup 3))
2161 (set (match_dup 4) (match_dup 5))]
2162 "split_di (operands, 2, operands + 2, operands + 4);")
2163
2164 (define_insn "*swapdi_rex64"
2165 [(set (match_operand:DI 0 "register_operand" "+r")
2166 (match_operand:DI 1 "register_operand" "+r"))
2167 (set (match_dup 1)
2168 (match_dup 0))]
2169 "TARGET_64BIT"
2170 "xchg{q}\t%1, %0"
2171 [(set_attr "type" "imov")
2172 (set_attr "mode" "DI")
2173 (set_attr "pent_pair" "np")
2174 (set_attr "athlon_decode" "vector")
2175 (set_attr "amdfam10_decode" "double")])
2176
2177 (define_expand "movti"
2178 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2179 (match_operand:TI 1 "nonimmediate_operand" ""))]
2180 "TARGET_SSE || TARGET_64BIT"
2181 {
2182 if (TARGET_64BIT)
2183 ix86_expand_move (TImode, operands);
2184 else if (push_operand (operands[0], TImode))
2185 ix86_expand_push (TImode, operands[1]);
2186 else
2187 ix86_expand_vector_move (TImode, operands);
2188 DONE;
2189 })
2190
2191 (define_insn "*movti_internal"
2192 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2193 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2194 "TARGET_SSE && !TARGET_64BIT
2195 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2196 {
2197 switch (which_alternative)
2198 {
2199 case 0:
2200 if (get_attr_mode (insn) == MODE_V4SF)
2201 return "xorps\t%0, %0";
2202 else
2203 return "pxor\t%0, %0";
2204 case 1:
2205 case 2:
2206 if (get_attr_mode (insn) == MODE_V4SF)
2207 return "movaps\t{%1, %0|%0, %1}";
2208 else
2209 return "movdqa\t{%1, %0|%0, %1}";
2210 default:
2211 gcc_unreachable ();
2212 }
2213 }
2214 [(set_attr "type" "sselog1,ssemov,ssemov")
2215 (set (attr "mode")
2216 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2217 (ne (symbol_ref "optimize_size") (const_int 0)))
2218 (const_string "V4SF")
2219 (and (eq_attr "alternative" "2")
2220 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2221 (const_int 0)))
2222 (const_string "V4SF")]
2223 (const_string "TI")))])
2224
2225 (define_insn "*movti_rex64"
2226 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2227 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2228 "TARGET_64BIT
2229 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2230 {
2231 switch (which_alternative)
2232 {
2233 case 0:
2234 case 1:
2235 return "#";
2236 case 2:
2237 if (get_attr_mode (insn) == MODE_V4SF)
2238 return "xorps\t%0, %0";
2239 else
2240 return "pxor\t%0, %0";
2241 case 3:
2242 case 4:
2243 if (get_attr_mode (insn) == MODE_V4SF)
2244 return "movaps\t{%1, %0|%0, %1}";
2245 else
2246 return "movdqa\t{%1, %0|%0, %1}";
2247 default:
2248 gcc_unreachable ();
2249 }
2250 }
2251 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2252 (set (attr "mode")
2253 (cond [(eq_attr "alternative" "2,3")
2254 (if_then_else
2255 (ne (symbol_ref "optimize_size")
2256 (const_int 0))
2257 (const_string "V4SF")
2258 (const_string "TI"))
2259 (eq_attr "alternative" "4")
2260 (if_then_else
2261 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2262 (const_int 0))
2263 (ne (symbol_ref "optimize_size")
2264 (const_int 0)))
2265 (const_string "V4SF")
2266 (const_string "TI"))]
2267 (const_string "DI")))])
2268
2269 (define_split
2270 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2271 (match_operand:TI 1 "general_operand" ""))]
2272 "reload_completed && !SSE_REG_P (operands[0])
2273 && !SSE_REG_P (operands[1])"
2274 [(const_int 0)]
2275 "ix86_split_long_move (operands); DONE;")
2276
2277 ;; This expands to what emit_move_complex would generate if we didn't
2278 ;; have a movti pattern. Having this avoids problems with reload on
2279 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2280 ;; to have around all the time.
2281 (define_expand "movcdi"
2282 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2283 (match_operand:CDI 1 "general_operand" ""))]
2284 ""
2285 {
2286 if (push_operand (operands[0], CDImode))
2287 emit_move_complex_push (CDImode, operands[0], operands[1]);
2288 else
2289 emit_move_complex_parts (operands[0], operands[1]);
2290 DONE;
2291 })
2292
2293 (define_expand "movsf"
2294 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2295 (match_operand:SF 1 "general_operand" ""))]
2296 ""
2297 "ix86_expand_move (SFmode, operands); DONE;")
2298
2299 (define_insn "*pushsf"
2300 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2301 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2302 "!TARGET_64BIT"
2303 {
2304 /* Anything else should be already split before reg-stack. */
2305 gcc_assert (which_alternative == 1);
2306 return "push{l}\t%1";
2307 }
2308 [(set_attr "type" "multi,push,multi")
2309 (set_attr "unit" "i387,*,*")
2310 (set_attr "mode" "SF,SI,SF")])
2311
2312 (define_insn "*pushsf_rex64"
2313 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2314 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2315 "TARGET_64BIT"
2316 {
2317 /* Anything else should be already split before reg-stack. */
2318 gcc_assert (which_alternative == 1);
2319 return "push{q}\t%q1";
2320 }
2321 [(set_attr "type" "multi,push,multi")
2322 (set_attr "unit" "i387,*,*")
2323 (set_attr "mode" "SF,DI,SF")])
2324
2325 (define_split
2326 [(set (match_operand:SF 0 "push_operand" "")
2327 (match_operand:SF 1 "memory_operand" ""))]
2328 "reload_completed
2329 && MEM_P (operands[1])
2330 && (operands[2] = find_constant_src (insn))"
2331 [(set (match_dup 0)
2332 (match_dup 2))])
2333
2334
2335 ;; %%% Kill this when call knows how to work this out.
2336 (define_split
2337 [(set (match_operand:SF 0 "push_operand" "")
2338 (match_operand:SF 1 "any_fp_register_operand" ""))]
2339 "!TARGET_64BIT"
2340 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2341 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2342
2343 (define_split
2344 [(set (match_operand:SF 0 "push_operand" "")
2345 (match_operand:SF 1 "any_fp_register_operand" ""))]
2346 "TARGET_64BIT"
2347 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2348 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2349
2350 (define_insn "*movsf_1"
2351 [(set (match_operand:SF 0 "nonimmediate_operand"
2352 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2353 (match_operand:SF 1 "general_operand"
2354 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2355 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2356 && (reload_in_progress || reload_completed
2357 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2358 || (!TARGET_SSE_MATH && optimize_size
2359 && standard_80387_constant_p (operands[1]))
2360 || GET_CODE (operands[1]) != CONST_DOUBLE
2361 || memory_operand (operands[0], SFmode))"
2362 {
2363 switch (which_alternative)
2364 {
2365 case 0:
2366 case 1:
2367 return output_387_reg_move (insn, operands);
2368
2369 case 2:
2370 return standard_80387_constant_opcode (operands[1]);
2371
2372 case 3:
2373 case 4:
2374 return "mov{l}\t{%1, %0|%0, %1}";
2375 case 5:
2376 if (get_attr_mode (insn) == MODE_TI)
2377 return "pxor\t%0, %0";
2378 else
2379 return "xorps\t%0, %0";
2380 case 6:
2381 if (get_attr_mode (insn) == MODE_V4SF)
2382 return "movaps\t{%1, %0|%0, %1}";
2383 else
2384 return "movss\t{%1, %0|%0, %1}";
2385 case 7: case 8:
2386 return "movss\t{%1, %0|%0, %1}";
2387
2388 case 9: case 10:
2389 case 12: case 13: case 14: case 15:
2390 return "movd\t{%1, %0|%0, %1}";
2391
2392 case 11:
2393 return "movq\t{%1, %0|%0, %1}";
2394
2395 default:
2396 gcc_unreachable ();
2397 }
2398 }
2399 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2400 (set (attr "mode")
2401 (cond [(eq_attr "alternative" "3,4,9,10")
2402 (const_string "SI")
2403 (eq_attr "alternative" "5")
2404 (if_then_else
2405 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2406 (const_int 0))
2407 (ne (symbol_ref "TARGET_SSE2")
2408 (const_int 0)))
2409 (eq (symbol_ref "optimize_size")
2410 (const_int 0)))
2411 (const_string "TI")
2412 (const_string "V4SF"))
2413 /* For architectures resolving dependencies on
2414 whole SSE registers use APS move to break dependency
2415 chains, otherwise use short move to avoid extra work.
2416
2417 Do the same for architectures resolving dependencies on
2418 the parts. While in DF mode it is better to always handle
2419 just register parts, the SF mode is different due to lack
2420 of instructions to load just part of the register. It is
2421 better to maintain the whole registers in single format
2422 to avoid problems on using packed logical operations. */
2423 (eq_attr "alternative" "6")
2424 (if_then_else
2425 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2426 (const_int 0))
2427 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2428 (const_int 0)))
2429 (const_string "V4SF")
2430 (const_string "SF"))
2431 (eq_attr "alternative" "11")
2432 (const_string "DI")]
2433 (const_string "SF")))])
2434
2435 (define_insn "*swapsf"
2436 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2437 (match_operand:SF 1 "fp_register_operand" "+f"))
2438 (set (match_dup 1)
2439 (match_dup 0))]
2440 "reload_completed || TARGET_80387"
2441 {
2442 if (STACK_TOP_P (operands[0]))
2443 return "fxch\t%1";
2444 else
2445 return "fxch\t%0";
2446 }
2447 [(set_attr "type" "fxch")
2448 (set_attr "mode" "SF")])
2449
2450 (define_expand "movdf"
2451 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2452 (match_operand:DF 1 "general_operand" ""))]
2453 ""
2454 "ix86_expand_move (DFmode, operands); DONE;")
2455
2456 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2457 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2458 ;; On the average, pushdf using integers can be still shorter. Allow this
2459 ;; pattern for optimize_size too.
2460
2461 (define_insn "*pushdf_nointeger"
2462 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2463 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Yt"))]
2464 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2465 {
2466 /* This insn should be already split before reg-stack. */
2467 gcc_unreachable ();
2468 }
2469 [(set_attr "type" "multi")
2470 (set_attr "unit" "i387,*,*,*")
2471 (set_attr "mode" "DF,SI,SI,DF")])
2472
2473 (define_insn "*pushdf_integer"
2474 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2475 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Yt"))]
2476 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2477 {
2478 /* This insn should be already split before reg-stack. */
2479 gcc_unreachable ();
2480 }
2481 [(set_attr "type" "multi")
2482 (set_attr "unit" "i387,*,*")
2483 (set_attr "mode" "DF,SI,DF")])
2484
2485 ;; %%% Kill this when call knows how to work this out.
2486 (define_split
2487 [(set (match_operand:DF 0 "push_operand" "")
2488 (match_operand:DF 1 "any_fp_register_operand" ""))]
2489 "!TARGET_64BIT && reload_completed"
2490 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2491 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2492 "")
2493
2494 (define_split
2495 [(set (match_operand:DF 0 "push_operand" "")
2496 (match_operand:DF 1 "any_fp_register_operand" ""))]
2497 "TARGET_64BIT && reload_completed"
2498 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2499 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2500 "")
2501
2502 (define_split
2503 [(set (match_operand:DF 0 "push_operand" "")
2504 (match_operand:DF 1 "general_operand" ""))]
2505 "reload_completed"
2506 [(const_int 0)]
2507 "ix86_split_long_move (operands); DONE;")
2508
2509 ;; Moving is usually shorter when only FP registers are used. This separate
2510 ;; movdf pattern avoids the use of integer registers for FP operations
2511 ;; when optimizing for size.
2512
2513 (define_insn "*movdf_nointeger"
2514 [(set (match_operand:DF 0 "nonimmediate_operand"
2515 "=f,m,f,*r ,o ,Yt*x,Yt*x,Yt*x ,m ")
2516 (match_operand:DF 1 "general_operand"
2517 "fm,f,G,*roF,F*r,C ,Yt*x,mYt*x,Yt*x"))]
2518 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2519 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2520 && (reload_in_progress || reload_completed
2521 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2522 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2523 && standard_80387_constant_p (operands[1]))
2524 || GET_CODE (operands[1]) != CONST_DOUBLE
2525 || memory_operand (operands[0], DFmode))"
2526 {
2527 switch (which_alternative)
2528 {
2529 case 0:
2530 case 1:
2531 return output_387_reg_move (insn, operands);
2532
2533 case 2:
2534 return standard_80387_constant_opcode (operands[1]);
2535
2536 case 3:
2537 case 4:
2538 return "#";
2539 case 5:
2540 switch (get_attr_mode (insn))
2541 {
2542 case MODE_V4SF:
2543 return "xorps\t%0, %0";
2544 case MODE_V2DF:
2545 return "xorpd\t%0, %0";
2546 case MODE_TI:
2547 return "pxor\t%0, %0";
2548 default:
2549 gcc_unreachable ();
2550 }
2551 case 6:
2552 case 7:
2553 case 8:
2554 switch (get_attr_mode (insn))
2555 {
2556 case MODE_V4SF:
2557 return "movaps\t{%1, %0|%0, %1}";
2558 case MODE_V2DF:
2559 return "movapd\t{%1, %0|%0, %1}";
2560 case MODE_TI:
2561 return "movdqa\t{%1, %0|%0, %1}";
2562 case MODE_DI:
2563 return "movq\t{%1, %0|%0, %1}";
2564 case MODE_DF:
2565 return "movsd\t{%1, %0|%0, %1}";
2566 case MODE_V1DF:
2567 return "movlpd\t{%1, %0|%0, %1}";
2568 case MODE_V2SF:
2569 return "movlps\t{%1, %0|%0, %1}";
2570 default:
2571 gcc_unreachable ();
2572 }
2573
2574 default:
2575 gcc_unreachable ();
2576 }
2577 }
2578 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2579 (set (attr "mode")
2580 (cond [(eq_attr "alternative" "0,1,2")
2581 (const_string "DF")
2582 (eq_attr "alternative" "3,4")
2583 (const_string "SI")
2584
2585 /* For SSE1, we have many fewer alternatives. */
2586 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2587 (cond [(eq_attr "alternative" "5,6")
2588 (const_string "V4SF")
2589 ]
2590 (const_string "V2SF"))
2591
2592 /* xorps is one byte shorter. */
2593 (eq_attr "alternative" "5")
2594 (cond [(ne (symbol_ref "optimize_size")
2595 (const_int 0))
2596 (const_string "V4SF")
2597 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2598 (const_int 0))
2599 (const_string "TI")
2600 ]
2601 (const_string "V2DF"))
2602
2603 /* For architectures resolving dependencies on
2604 whole SSE registers use APD move to break dependency
2605 chains, otherwise use short move to avoid extra work.
2606
2607 movaps encodes one byte shorter. */
2608 (eq_attr "alternative" "6")
2609 (cond
2610 [(ne (symbol_ref "optimize_size")
2611 (const_int 0))
2612 (const_string "V4SF")
2613 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2614 (const_int 0))
2615 (const_string "V2DF")
2616 ]
2617 (const_string "DF"))
2618 /* For architectures resolving dependencies on register
2619 parts we may avoid extra work to zero out upper part
2620 of register. */
2621 (eq_attr "alternative" "7")
2622 (if_then_else
2623 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2624 (const_int 0))
2625 (const_string "V1DF")
2626 (const_string "DF"))
2627 ]
2628 (const_string "DF")))])
2629
2630 (define_insn "*movdf_integer_rex64"
2631 [(set (match_operand:DF 0 "nonimmediate_operand"
2632 "=f,m,f,r ,m ,Yt*x,Yt*x,Yt*x,m ,Yi,r ")
2633 (match_operand:DF 1 "general_operand"
2634 "fm,f,G,rmF,Fr,C ,Yt*x,m ,Yt*x,r ,Yi"))]
2635 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2636 && (reload_in_progress || reload_completed
2637 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2638 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2639 && standard_80387_constant_p (operands[1]))
2640 || GET_CODE (operands[1]) != CONST_DOUBLE
2641 || memory_operand (operands[0], DFmode))"
2642 {
2643 switch (which_alternative)
2644 {
2645 case 0:
2646 case 1:
2647 return output_387_reg_move (insn, operands);
2648
2649 case 2:
2650 return standard_80387_constant_opcode (operands[1]);
2651
2652 case 3:
2653 case 4:
2654 return "#";
2655
2656 case 5:
2657 switch (get_attr_mode (insn))
2658 {
2659 case MODE_V4SF:
2660 return "xorps\t%0, %0";
2661 case MODE_V2DF:
2662 return "xorpd\t%0, %0";
2663 case MODE_TI:
2664 return "pxor\t%0, %0";
2665 default:
2666 gcc_unreachable ();
2667 }
2668 case 6:
2669 case 7:
2670 case 8:
2671 switch (get_attr_mode (insn))
2672 {
2673 case MODE_V4SF:
2674 return "movaps\t{%1, %0|%0, %1}";
2675 case MODE_V2DF:
2676 return "movapd\t{%1, %0|%0, %1}";
2677 case MODE_TI:
2678 return "movdqa\t{%1, %0|%0, %1}";
2679 case MODE_DI:
2680 return "movq\t{%1, %0|%0, %1}";
2681 case MODE_DF:
2682 return "movsd\t{%1, %0|%0, %1}";
2683 case MODE_V1DF:
2684 return "movlpd\t{%1, %0|%0, %1}";
2685 case MODE_V2SF:
2686 return "movlps\t{%1, %0|%0, %1}";
2687 default:
2688 gcc_unreachable ();
2689 }
2690
2691 case 9:
2692 case 10:
2693 return "movd\t{%1, %0|%0, %1}";
2694
2695 default:
2696 gcc_unreachable();
2697 }
2698 }
2699 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2700 (set (attr "mode")
2701 (cond [(eq_attr "alternative" "0,1,2")
2702 (const_string "DF")
2703 (eq_attr "alternative" "3,4,9,10")
2704 (const_string "DI")
2705
2706 /* For SSE1, we have many fewer alternatives. */
2707 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2708 (cond [(eq_attr "alternative" "5,6")
2709 (const_string "V4SF")
2710 ]
2711 (const_string "V2SF"))
2712
2713 /* xorps is one byte shorter. */
2714 (eq_attr "alternative" "5")
2715 (cond [(ne (symbol_ref "optimize_size")
2716 (const_int 0))
2717 (const_string "V4SF")
2718 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2719 (const_int 0))
2720 (const_string "TI")
2721 ]
2722 (const_string "V2DF"))
2723
2724 /* For architectures resolving dependencies on
2725 whole SSE registers use APD move to break dependency
2726 chains, otherwise use short move to avoid extra work.
2727
2728 movaps encodes one byte shorter. */
2729 (eq_attr "alternative" "6")
2730 (cond
2731 [(ne (symbol_ref "optimize_size")
2732 (const_int 0))
2733 (const_string "V4SF")
2734 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2735 (const_int 0))
2736 (const_string "V2DF")
2737 ]
2738 (const_string "DF"))
2739 /* For architectures resolving dependencies on register
2740 parts we may avoid extra work to zero out upper part
2741 of register. */
2742 (eq_attr "alternative" "7")
2743 (if_then_else
2744 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2745 (const_int 0))
2746 (const_string "V1DF")
2747 (const_string "DF"))
2748 ]
2749 (const_string "DF")))])
2750
2751 (define_insn "*movdf_integer"
2752 [(set (match_operand:DF 0 "nonimmediate_operand"
2753 "=f,m,f,r ,o ,Yt*x,Yt*x,Yt*x,m ")
2754 (match_operand:DF 1 "general_operand"
2755 "fm,f,G,roF,Fr,C ,Yt*x,m ,Yt*x"))]
2756 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2757 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2758 && (reload_in_progress || reload_completed
2759 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2760 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2761 && standard_80387_constant_p (operands[1]))
2762 || GET_CODE (operands[1]) != CONST_DOUBLE
2763 || memory_operand (operands[0], DFmode))"
2764 {
2765 switch (which_alternative)
2766 {
2767 case 0:
2768 case 1:
2769 return output_387_reg_move (insn, operands);
2770
2771 case 2:
2772 return standard_80387_constant_opcode (operands[1]);
2773
2774 case 3:
2775 case 4:
2776 return "#";
2777
2778 case 5:
2779 switch (get_attr_mode (insn))
2780 {
2781 case MODE_V4SF:
2782 return "xorps\t%0, %0";
2783 case MODE_V2DF:
2784 return "xorpd\t%0, %0";
2785 case MODE_TI:
2786 return "pxor\t%0, %0";
2787 default:
2788 gcc_unreachable ();
2789 }
2790 case 6:
2791 case 7:
2792 case 8:
2793 switch (get_attr_mode (insn))
2794 {
2795 case MODE_V4SF:
2796 return "movaps\t{%1, %0|%0, %1}";
2797 case MODE_V2DF:
2798 return "movapd\t{%1, %0|%0, %1}";
2799 case MODE_TI:
2800 return "movdqa\t{%1, %0|%0, %1}";
2801 case MODE_DI:
2802 return "movq\t{%1, %0|%0, %1}";
2803 case MODE_DF:
2804 return "movsd\t{%1, %0|%0, %1}";
2805 case MODE_V1DF:
2806 return "movlpd\t{%1, %0|%0, %1}";
2807 case MODE_V2SF:
2808 return "movlps\t{%1, %0|%0, %1}";
2809 default:
2810 gcc_unreachable ();
2811 }
2812
2813 default:
2814 gcc_unreachable();
2815 }
2816 }
2817 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2818 (set (attr "mode")
2819 (cond [(eq_attr "alternative" "0,1,2")
2820 (const_string "DF")
2821 (eq_attr "alternative" "3,4")
2822 (const_string "SI")
2823
2824 /* For SSE1, we have many fewer alternatives. */
2825 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2826 (cond [(eq_attr "alternative" "5,6")
2827 (const_string "V4SF")
2828 ]
2829 (const_string "V2SF"))
2830
2831 /* xorps is one byte shorter. */
2832 (eq_attr "alternative" "5")
2833 (cond [(ne (symbol_ref "optimize_size")
2834 (const_int 0))
2835 (const_string "V4SF")
2836 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2837 (const_int 0))
2838 (const_string "TI")
2839 ]
2840 (const_string "V2DF"))
2841
2842 /* For architectures resolving dependencies on
2843 whole SSE registers use APD move to break dependency
2844 chains, otherwise use short move to avoid extra work.
2845
2846 movaps encodes one byte shorter. */
2847 (eq_attr "alternative" "6")
2848 (cond
2849 [(ne (symbol_ref "optimize_size")
2850 (const_int 0))
2851 (const_string "V4SF")
2852 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2853 (const_int 0))
2854 (const_string "V2DF")
2855 ]
2856 (const_string "DF"))
2857 /* For architectures resolving dependencies on register
2858 parts we may avoid extra work to zero out upper part
2859 of register. */
2860 (eq_attr "alternative" "7")
2861 (if_then_else
2862 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2863 (const_int 0))
2864 (const_string "V1DF")
2865 (const_string "DF"))
2866 ]
2867 (const_string "DF")))])
2868
2869 (define_split
2870 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2871 (match_operand:DF 1 "general_operand" ""))]
2872 "reload_completed
2873 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2874 && ! (ANY_FP_REG_P (operands[0]) ||
2875 (GET_CODE (operands[0]) == SUBREG
2876 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2877 && ! (ANY_FP_REG_P (operands[1]) ||
2878 (GET_CODE (operands[1]) == SUBREG
2879 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2880 [(const_int 0)]
2881 "ix86_split_long_move (operands); DONE;")
2882
2883 (define_insn "*swapdf"
2884 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2885 (match_operand:DF 1 "fp_register_operand" "+f"))
2886 (set (match_dup 1)
2887 (match_dup 0))]
2888 "reload_completed || TARGET_80387"
2889 {
2890 if (STACK_TOP_P (operands[0]))
2891 return "fxch\t%1";
2892 else
2893 return "fxch\t%0";
2894 }
2895 [(set_attr "type" "fxch")
2896 (set_attr "mode" "DF")])
2897
2898 (define_expand "movxf"
2899 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2900 (match_operand:XF 1 "general_operand" ""))]
2901 ""
2902 "ix86_expand_move (XFmode, operands); DONE;")
2903
2904 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2905 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2906 ;; Pushing using integer instructions is longer except for constants
2907 ;; and direct memory references.
2908 ;; (assuming that any given constant is pushed only once, but this ought to be
2909 ;; handled elsewhere).
2910
2911 (define_insn "*pushxf_nointeger"
2912 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2913 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2914 "optimize_size"
2915 {
2916 /* This insn should be already split before reg-stack. */
2917 gcc_unreachable ();
2918 }
2919 [(set_attr "type" "multi")
2920 (set_attr "unit" "i387,*,*")
2921 (set_attr "mode" "XF,SI,SI")])
2922
2923 (define_insn "*pushxf_integer"
2924 [(set (match_operand:XF 0 "push_operand" "=<,<")
2925 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2926 "!optimize_size"
2927 {
2928 /* This insn should be already split before reg-stack. */
2929 gcc_unreachable ();
2930 }
2931 [(set_attr "type" "multi")
2932 (set_attr "unit" "i387,*")
2933 (set_attr "mode" "XF,SI")])
2934
2935 (define_split
2936 [(set (match_operand 0 "push_operand" "")
2937 (match_operand 1 "general_operand" ""))]
2938 "reload_completed
2939 && (GET_MODE (operands[0]) == XFmode
2940 || GET_MODE (operands[0]) == DFmode)
2941 && !ANY_FP_REG_P (operands[1])"
2942 [(const_int 0)]
2943 "ix86_split_long_move (operands); DONE;")
2944
2945 (define_split
2946 [(set (match_operand:XF 0 "push_operand" "")
2947 (match_operand:XF 1 "any_fp_register_operand" ""))]
2948 "!TARGET_64BIT"
2949 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2950 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2951 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2952
2953 (define_split
2954 [(set (match_operand:XF 0 "push_operand" "")
2955 (match_operand:XF 1 "any_fp_register_operand" ""))]
2956 "TARGET_64BIT"
2957 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2958 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2959 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2960
2961 ;; Do not use integer registers when optimizing for size
2962 (define_insn "*movxf_nointeger"
2963 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2964 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2965 "optimize_size
2966 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2967 && (reload_in_progress || reload_completed
2968 || (optimize_size && standard_80387_constant_p (operands[1]))
2969 || GET_CODE (operands[1]) != CONST_DOUBLE
2970 || memory_operand (operands[0], XFmode))"
2971 {
2972 switch (which_alternative)
2973 {
2974 case 0:
2975 case 1:
2976 return output_387_reg_move (insn, operands);
2977
2978 case 2:
2979 return standard_80387_constant_opcode (operands[1]);
2980
2981 case 3: case 4:
2982 return "#";
2983 default:
2984 gcc_unreachable ();
2985 }
2986 }
2987 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2988 (set_attr "mode" "XF,XF,XF,SI,SI")])
2989
2990 (define_insn "*movxf_integer"
2991 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2992 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2993 "!optimize_size
2994 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2995 && (reload_in_progress || reload_completed
2996 || (optimize_size && standard_80387_constant_p (operands[1]))
2997 || GET_CODE (operands[1]) != CONST_DOUBLE
2998 || memory_operand (operands[0], XFmode))"
2999 {
3000 switch (which_alternative)
3001 {
3002 case 0:
3003 case 1:
3004 return output_387_reg_move (insn, operands);
3005
3006 case 2:
3007 return standard_80387_constant_opcode (operands[1]);
3008
3009 case 3: case 4:
3010 return "#";
3011
3012 default:
3013 gcc_unreachable ();
3014 }
3015 }
3016 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3017 (set_attr "mode" "XF,XF,XF,SI,SI")])
3018
3019 (define_expand "movtf"
3020 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3021 (match_operand:TF 1 "nonimmediate_operand" ""))]
3022 "TARGET_64BIT"
3023 {
3024 ix86_expand_move (TFmode, operands);
3025 DONE;
3026 })
3027
3028 (define_insn "*movtf_internal"
3029 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3030 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3031 "TARGET_64BIT
3032 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3033 {
3034 switch (which_alternative)
3035 {
3036 case 0:
3037 case 1:
3038 if (get_attr_mode (insn) == MODE_V4SF)
3039 return "movaps\t{%1, %0|%0, %1}";
3040 else
3041 return "movdqa\t{%1, %0|%0, %1}";
3042 case 2:
3043 if (get_attr_mode (insn) == MODE_V4SF)
3044 return "xorps\t%0, %0";
3045 else
3046 return "pxor\t%0, %0";
3047 case 3:
3048 case 4:
3049 return "#";
3050 default:
3051 gcc_unreachable ();
3052 }
3053 }
3054 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3055 (set (attr "mode")
3056 (cond [(eq_attr "alternative" "0,2")
3057 (if_then_else
3058 (ne (symbol_ref "optimize_size")
3059 (const_int 0))
3060 (const_string "V4SF")
3061 (const_string "TI"))
3062 (eq_attr "alternative" "1")
3063 (if_then_else
3064 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3065 (const_int 0))
3066 (ne (symbol_ref "optimize_size")
3067 (const_int 0)))
3068 (const_string "V4SF")
3069 (const_string "TI"))]
3070 (const_string "DI")))])
3071
3072 (define_split
3073 [(set (match_operand 0 "nonimmediate_operand" "")
3074 (match_operand 1 "general_operand" ""))]
3075 "reload_completed
3076 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3077 && GET_MODE (operands[0]) == XFmode
3078 && ! (ANY_FP_REG_P (operands[0]) ||
3079 (GET_CODE (operands[0]) == SUBREG
3080 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3081 && ! (ANY_FP_REG_P (operands[1]) ||
3082 (GET_CODE (operands[1]) == SUBREG
3083 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3084 [(const_int 0)]
3085 "ix86_split_long_move (operands); DONE;")
3086
3087 (define_split
3088 [(set (match_operand 0 "register_operand" "")
3089 (match_operand 1 "memory_operand" ""))]
3090 "reload_completed
3091 && MEM_P (operands[1])
3092 && (GET_MODE (operands[0]) == TFmode
3093 || GET_MODE (operands[0]) == XFmode
3094 || GET_MODE (operands[0]) == SFmode
3095 || GET_MODE (operands[0]) == DFmode)
3096 && (operands[2] = find_constant_src (insn))"
3097 [(set (match_dup 0) (match_dup 2))]
3098 {
3099 rtx c = operands[2];
3100 rtx r = operands[0];
3101
3102 if (GET_CODE (r) == SUBREG)
3103 r = SUBREG_REG (r);
3104
3105 if (SSE_REG_P (r))
3106 {
3107 if (!standard_sse_constant_p (c))
3108 FAIL;
3109 }
3110 else if (FP_REG_P (r))
3111 {
3112 if (!standard_80387_constant_p (c))
3113 FAIL;
3114 }
3115 else if (MMX_REG_P (r))
3116 FAIL;
3117 })
3118
3119 (define_split
3120 [(set (match_operand 0 "register_operand" "")
3121 (float_extend (match_operand 1 "memory_operand" "")))]
3122 "reload_completed
3123 && MEM_P (operands[1])
3124 && (GET_MODE (operands[0]) == TFmode
3125 || GET_MODE (operands[0]) == XFmode
3126 || GET_MODE (operands[0]) == SFmode
3127 || GET_MODE (operands[0]) == DFmode)
3128 && (operands[2] = find_constant_src (insn))"
3129 [(set (match_dup 0) (match_dup 2))]
3130 {
3131 rtx c = operands[2];
3132 rtx r = operands[0];
3133
3134 if (GET_CODE (r) == SUBREG)
3135 r = SUBREG_REG (r);
3136
3137 if (SSE_REG_P (r))
3138 {
3139 if (!standard_sse_constant_p (c))
3140 FAIL;
3141 }
3142 else if (FP_REG_P (r))
3143 {
3144 if (!standard_80387_constant_p (c))
3145 FAIL;
3146 }
3147 else if (MMX_REG_P (r))
3148 FAIL;
3149 })
3150
3151 (define_insn "swapxf"
3152 [(set (match_operand:XF 0 "register_operand" "+f")
3153 (match_operand:XF 1 "register_operand" "+f"))
3154 (set (match_dup 1)
3155 (match_dup 0))]
3156 "TARGET_80387"
3157 {
3158 if (STACK_TOP_P (operands[0]))
3159 return "fxch\t%1";
3160 else
3161 return "fxch\t%0";
3162 }
3163 [(set_attr "type" "fxch")
3164 (set_attr "mode" "XF")])
3165
3166 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3167 (define_split
3168 [(set (match_operand:X87MODEF 0 "register_operand" "")
3169 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3170 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3171 && (standard_80387_constant_p (operands[1]) == 8
3172 || standard_80387_constant_p (operands[1]) == 9)"
3173 [(set (match_dup 0)(match_dup 1))
3174 (set (match_dup 0)
3175 (neg:X87MODEF (match_dup 0)))]
3176 {
3177 REAL_VALUE_TYPE r;
3178
3179 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3180 if (real_isnegzero (&r))
3181 operands[1] = CONST0_RTX (<MODE>mode);
3182 else
3183 operands[1] = CONST1_RTX (<MODE>mode);
3184 })
3185
3186 (define_split
3187 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3188 (match_operand:TF 1 "general_operand" ""))]
3189 "reload_completed
3190 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3191 [(const_int 0)]
3192 "ix86_split_long_move (operands); DONE;")
3193 \f
3194 ;; Zero extension instructions
3195
3196 (define_expand "zero_extendhisi2"
3197 [(set (match_operand:SI 0 "register_operand" "")
3198 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3199 ""
3200 {
3201 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3202 {
3203 operands[1] = force_reg (HImode, operands[1]);
3204 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3205 DONE;
3206 }
3207 })
3208
3209 (define_insn "zero_extendhisi2_and"
3210 [(set (match_operand:SI 0 "register_operand" "=r")
3211 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3212 (clobber (reg:CC FLAGS_REG))]
3213 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3214 "#"
3215 [(set_attr "type" "alu1")
3216 (set_attr "mode" "SI")])
3217
3218 (define_split
3219 [(set (match_operand:SI 0 "register_operand" "")
3220 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3221 (clobber (reg:CC FLAGS_REG))]
3222 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3223 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3224 (clobber (reg:CC FLAGS_REG))])]
3225 "")
3226
3227 (define_insn "*zero_extendhisi2_movzwl"
3228 [(set (match_operand:SI 0 "register_operand" "=r")
3229 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3230 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3231 "movz{wl|x}\t{%1, %0|%0, %1}"
3232 [(set_attr "type" "imovx")
3233 (set_attr "mode" "SI")])
3234
3235 (define_expand "zero_extendqihi2"
3236 [(parallel
3237 [(set (match_operand:HI 0 "register_operand" "")
3238 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3239 (clobber (reg:CC FLAGS_REG))])]
3240 ""
3241 "")
3242
3243 (define_insn "*zero_extendqihi2_and"
3244 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3245 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3246 (clobber (reg:CC FLAGS_REG))]
3247 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3248 "#"
3249 [(set_attr "type" "alu1")
3250 (set_attr "mode" "HI")])
3251
3252 (define_insn "*zero_extendqihi2_movzbw_and"
3253 [(set (match_operand:HI 0 "register_operand" "=r,r")
3254 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3255 (clobber (reg:CC FLAGS_REG))]
3256 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3257 "#"
3258 [(set_attr "type" "imovx,alu1")
3259 (set_attr "mode" "HI")])
3260
3261 ; zero extend to SImode here to avoid partial register stalls
3262 (define_insn "*zero_extendqihi2_movzbl"
3263 [(set (match_operand:HI 0 "register_operand" "=r")
3264 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3265 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3266 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3267 [(set_attr "type" "imovx")
3268 (set_attr "mode" "SI")])
3269
3270 ;; For the movzbw case strip only the clobber
3271 (define_split
3272 [(set (match_operand:HI 0 "register_operand" "")
3273 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3274 (clobber (reg:CC FLAGS_REG))]
3275 "reload_completed
3276 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3277 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3278 [(set (match_operand:HI 0 "register_operand" "")
3279 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3280
3281 ;; When source and destination does not overlap, clear destination
3282 ;; first and then do the movb
3283 (define_split
3284 [(set (match_operand:HI 0 "register_operand" "")
3285 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3286 (clobber (reg:CC FLAGS_REG))]
3287 "reload_completed
3288 && ANY_QI_REG_P (operands[0])
3289 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3290 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3291 [(set (match_dup 0) (const_int 0))
3292 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3293 "operands[2] = gen_lowpart (QImode, operands[0]);")
3294
3295 ;; Rest is handled by single and.
3296 (define_split
3297 [(set (match_operand:HI 0 "register_operand" "")
3298 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3299 (clobber (reg:CC FLAGS_REG))]
3300 "reload_completed
3301 && true_regnum (operands[0]) == true_regnum (operands[1])"
3302 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3303 (clobber (reg:CC FLAGS_REG))])]
3304 "")
3305
3306 (define_expand "zero_extendqisi2"
3307 [(parallel
3308 [(set (match_operand:SI 0 "register_operand" "")
3309 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3310 (clobber (reg:CC FLAGS_REG))])]
3311 ""
3312 "")
3313
3314 (define_insn "*zero_extendqisi2_and"
3315 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3316 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3317 (clobber (reg:CC FLAGS_REG))]
3318 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3319 "#"
3320 [(set_attr "type" "alu1")
3321 (set_attr "mode" "SI")])
3322
3323 (define_insn "*zero_extendqisi2_movzbw_and"
3324 [(set (match_operand:SI 0 "register_operand" "=r,r")
3325 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3326 (clobber (reg:CC FLAGS_REG))]
3327 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3328 "#"
3329 [(set_attr "type" "imovx,alu1")
3330 (set_attr "mode" "SI")])
3331
3332 (define_insn "*zero_extendqisi2_movzbw"
3333 [(set (match_operand:SI 0 "register_operand" "=r")
3334 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3335 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3336 "movz{bl|x}\t{%1, %0|%0, %1}"
3337 [(set_attr "type" "imovx")
3338 (set_attr "mode" "SI")])
3339
3340 ;; For the movzbl case strip only the clobber
3341 (define_split
3342 [(set (match_operand:SI 0 "register_operand" "")
3343 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3344 (clobber (reg:CC FLAGS_REG))]
3345 "reload_completed
3346 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3347 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3348 [(set (match_dup 0)
3349 (zero_extend:SI (match_dup 1)))])
3350
3351 ;; When source and destination does not overlap, clear destination
3352 ;; first and then do the movb
3353 (define_split
3354 [(set (match_operand:SI 0 "register_operand" "")
3355 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3356 (clobber (reg:CC FLAGS_REG))]
3357 "reload_completed
3358 && ANY_QI_REG_P (operands[0])
3359 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3360 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3361 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3362 [(set (match_dup 0) (const_int 0))
3363 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3364 "operands[2] = gen_lowpart (QImode, operands[0]);")
3365
3366 ;; Rest is handled by single and.
3367 (define_split
3368 [(set (match_operand:SI 0 "register_operand" "")
3369 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3370 (clobber (reg:CC FLAGS_REG))]
3371 "reload_completed
3372 && true_regnum (operands[0]) == true_regnum (operands[1])"
3373 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3374 (clobber (reg:CC FLAGS_REG))])]
3375 "")
3376
3377 ;; %%% Kill me once multi-word ops are sane.
3378 (define_expand "zero_extendsidi2"
3379 [(set (match_operand:DI 0 "register_operand" "=r")
3380 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3381 ""
3382 {
3383 if (!TARGET_64BIT)
3384 {
3385 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3386 DONE;
3387 }
3388 })
3389
3390 (define_insn "zero_extendsidi2_32"
3391 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Yt")
3392 (zero_extend:DI
3393 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3394 (clobber (reg:CC FLAGS_REG))]
3395 "!TARGET_64BIT"
3396 "@
3397 #
3398 #
3399 #
3400 movd\t{%1, %0|%0, %1}
3401 movd\t{%1, %0|%0, %1}
3402 movd\t{%1, %0|%0, %1}
3403 movd\t{%1, %0|%0, %1}"
3404 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3405 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3406
3407 (define_insn "zero_extendsidi2_rex64"
3408 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Yt")
3409 (zero_extend:DI
3410 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3411 "TARGET_64BIT"
3412 "@
3413 mov\t{%k1, %k0|%k0, %k1}
3414 #
3415 movd\t{%1, %0|%0, %1}
3416 movd\t{%1, %0|%0, %1}
3417 movd\t{%1, %0|%0, %1}
3418 movd\t{%1, %0|%0, %1}"
3419 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3420 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3421
3422 (define_split
3423 [(set (match_operand:DI 0 "memory_operand" "")
3424 (zero_extend:DI (match_dup 0)))]
3425 "TARGET_64BIT"
3426 [(set (match_dup 4) (const_int 0))]
3427 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3428
3429 (define_split
3430 [(set (match_operand:DI 0 "register_operand" "")
3431 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3432 (clobber (reg:CC FLAGS_REG))]
3433 "!TARGET_64BIT && reload_completed
3434 && true_regnum (operands[0]) == true_regnum (operands[1])"
3435 [(set (match_dup 4) (const_int 0))]
3436 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3437
3438 (define_split
3439 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3440 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3441 (clobber (reg:CC FLAGS_REG))]
3442 "!TARGET_64BIT && reload_completed
3443 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3444 [(set (match_dup 3) (match_dup 1))
3445 (set (match_dup 4) (const_int 0))]
3446 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3447
3448 (define_insn "zero_extendhidi2"
3449 [(set (match_operand:DI 0 "register_operand" "=r")
3450 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3451 "TARGET_64BIT"
3452 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3453 [(set_attr "type" "imovx")
3454 (set_attr "mode" "DI")])
3455
3456 (define_insn "zero_extendqidi2"
3457 [(set (match_operand:DI 0 "register_operand" "=r")
3458 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3459 "TARGET_64BIT"
3460 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3461 [(set_attr "type" "imovx")
3462 (set_attr "mode" "DI")])
3463 \f
3464 ;; Sign extension instructions
3465
3466 (define_expand "extendsidi2"
3467 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3468 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3469 (clobber (reg:CC FLAGS_REG))
3470 (clobber (match_scratch:SI 2 ""))])]
3471 ""
3472 {
3473 if (TARGET_64BIT)
3474 {
3475 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3476 DONE;
3477 }
3478 })
3479
3480 (define_insn "*extendsidi2_1"
3481 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3482 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3483 (clobber (reg:CC FLAGS_REG))
3484 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3485 "!TARGET_64BIT"
3486 "#")
3487
3488 (define_insn "extendsidi2_rex64"
3489 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3490 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3491 "TARGET_64BIT"
3492 "@
3493 {cltq|cdqe}
3494 movs{lq|x}\t{%1,%0|%0, %1}"
3495 [(set_attr "type" "imovx")
3496 (set_attr "mode" "DI")
3497 (set_attr "prefix_0f" "0")
3498 (set_attr "modrm" "0,1")])
3499
3500 (define_insn "extendhidi2"
3501 [(set (match_operand:DI 0 "register_operand" "=r")
3502 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3503 "TARGET_64BIT"
3504 "movs{wq|x}\t{%1,%0|%0, %1}"
3505 [(set_attr "type" "imovx")
3506 (set_attr "mode" "DI")])
3507
3508 (define_insn "extendqidi2"
3509 [(set (match_operand:DI 0 "register_operand" "=r")
3510 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3511 "TARGET_64BIT"
3512 "movs{bq|x}\t{%1,%0|%0, %1}"
3513 [(set_attr "type" "imovx")
3514 (set_attr "mode" "DI")])
3515
3516 ;; Extend to memory case when source register does die.
3517 (define_split
3518 [(set (match_operand:DI 0 "memory_operand" "")
3519 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3520 (clobber (reg:CC FLAGS_REG))
3521 (clobber (match_operand:SI 2 "register_operand" ""))]
3522 "(reload_completed
3523 && dead_or_set_p (insn, operands[1])
3524 && !reg_mentioned_p (operands[1], operands[0]))"
3525 [(set (match_dup 3) (match_dup 1))
3526 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3527 (clobber (reg:CC FLAGS_REG))])
3528 (set (match_dup 4) (match_dup 1))]
3529 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3530
3531 ;; Extend to memory case when source register does not die.
3532 (define_split
3533 [(set (match_operand:DI 0 "memory_operand" "")
3534 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3535 (clobber (reg:CC FLAGS_REG))
3536 (clobber (match_operand:SI 2 "register_operand" ""))]
3537 "reload_completed"
3538 [(const_int 0)]
3539 {
3540 split_di (&operands[0], 1, &operands[3], &operands[4]);
3541
3542 emit_move_insn (operands[3], operands[1]);
3543
3544 /* Generate a cltd if possible and doing so it profitable. */
3545 if (true_regnum (operands[1]) == 0
3546 && true_regnum (operands[2]) == 1
3547 && (optimize_size || TARGET_USE_CLTD))
3548 {
3549 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3550 }
3551 else
3552 {
3553 emit_move_insn (operands[2], operands[1]);
3554 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3555 }
3556 emit_move_insn (operands[4], operands[2]);
3557 DONE;
3558 })
3559
3560 ;; Extend to register case. Optimize case where source and destination
3561 ;; registers match and cases where we can use cltd.
3562 (define_split
3563 [(set (match_operand:DI 0 "register_operand" "")
3564 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3565 (clobber (reg:CC FLAGS_REG))
3566 (clobber (match_scratch:SI 2 ""))]
3567 "reload_completed"
3568 [(const_int 0)]
3569 {
3570 split_di (&operands[0], 1, &operands[3], &operands[4]);
3571
3572 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3573 emit_move_insn (operands[3], operands[1]);
3574
3575 /* Generate a cltd if possible and doing so it profitable. */
3576 if (true_regnum (operands[3]) == 0
3577 && (optimize_size || TARGET_USE_CLTD))
3578 {
3579 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3580 DONE;
3581 }
3582
3583 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3584 emit_move_insn (operands[4], operands[1]);
3585
3586 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3587 DONE;
3588 })
3589
3590 (define_insn "extendhisi2"
3591 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3592 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3593 ""
3594 {
3595 switch (get_attr_prefix_0f (insn))
3596 {
3597 case 0:
3598 return "{cwtl|cwde}";
3599 default:
3600 return "movs{wl|x}\t{%1,%0|%0, %1}";
3601 }
3602 }
3603 [(set_attr "type" "imovx")
3604 (set_attr "mode" "SI")
3605 (set (attr "prefix_0f")
3606 ;; movsx is short decodable while cwtl is vector decoded.
3607 (if_then_else (and (eq_attr "cpu" "!k6")
3608 (eq_attr "alternative" "0"))
3609 (const_string "0")
3610 (const_string "1")))
3611 (set (attr "modrm")
3612 (if_then_else (eq_attr "prefix_0f" "0")
3613 (const_string "0")
3614 (const_string "1")))])
3615
3616 (define_insn "*extendhisi2_zext"
3617 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3618 (zero_extend:DI
3619 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3620 "TARGET_64BIT"
3621 {
3622 switch (get_attr_prefix_0f (insn))
3623 {
3624 case 0:
3625 return "{cwtl|cwde}";
3626 default:
3627 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3628 }
3629 }
3630 [(set_attr "type" "imovx")
3631 (set_attr "mode" "SI")
3632 (set (attr "prefix_0f")
3633 ;; movsx is short decodable while cwtl is vector decoded.
3634 (if_then_else (and (eq_attr "cpu" "!k6")
3635 (eq_attr "alternative" "0"))
3636 (const_string "0")
3637 (const_string "1")))
3638 (set (attr "modrm")
3639 (if_then_else (eq_attr "prefix_0f" "0")
3640 (const_string "0")
3641 (const_string "1")))])
3642
3643 (define_insn "extendqihi2"
3644 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3645 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3646 ""
3647 {
3648 switch (get_attr_prefix_0f (insn))
3649 {
3650 case 0:
3651 return "{cbtw|cbw}";
3652 default:
3653 return "movs{bw|x}\t{%1,%0|%0, %1}";
3654 }
3655 }
3656 [(set_attr "type" "imovx")
3657 (set_attr "mode" "HI")
3658 (set (attr "prefix_0f")
3659 ;; movsx is short decodable while cwtl is vector decoded.
3660 (if_then_else (and (eq_attr "cpu" "!k6")
3661 (eq_attr "alternative" "0"))
3662 (const_string "0")
3663 (const_string "1")))
3664 (set (attr "modrm")
3665 (if_then_else (eq_attr "prefix_0f" "0")
3666 (const_string "0")
3667 (const_string "1")))])
3668
3669 (define_insn "extendqisi2"
3670 [(set (match_operand:SI 0 "register_operand" "=r")
3671 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3672 ""
3673 "movs{bl|x}\t{%1,%0|%0, %1}"
3674 [(set_attr "type" "imovx")
3675 (set_attr "mode" "SI")])
3676
3677 (define_insn "*extendqisi2_zext"
3678 [(set (match_operand:DI 0 "register_operand" "=r")
3679 (zero_extend:DI
3680 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3681 "TARGET_64BIT"
3682 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3683 [(set_attr "type" "imovx")
3684 (set_attr "mode" "SI")])
3685 \f
3686 ;; Conversions between float and double.
3687
3688 ;; These are all no-ops in the model used for the 80387. So just
3689 ;; emit moves.
3690
3691 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3692 (define_insn "*dummy_extendsfdf2"
3693 [(set (match_operand:DF 0 "push_operand" "=<")
3694 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3695 "0"
3696 "#")
3697
3698 (define_split
3699 [(set (match_operand:DF 0 "push_operand" "")
3700 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3701 "!TARGET_64BIT"
3702 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3703 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3704
3705 (define_split
3706 [(set (match_operand:DF 0 "push_operand" "")
3707 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3708 "TARGET_64BIT"
3709 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3710 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3711
3712 (define_insn "*dummy_extendsfxf2"
3713 [(set (match_operand:XF 0 "push_operand" "=<")
3714 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3715 "0"
3716 "#")
3717
3718 (define_split
3719 [(set (match_operand:XF 0 "push_operand" "")
3720 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3721 ""
3722 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3723 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3724 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3725
3726 (define_split
3727 [(set (match_operand:XF 0 "push_operand" "")
3728 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3729 "TARGET_64BIT"
3730 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3731 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3732 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3733
3734 (define_split
3735 [(set (match_operand:XF 0 "push_operand" "")
3736 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3737 ""
3738 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3739 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3740 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3741
3742 (define_split
3743 [(set (match_operand:XF 0 "push_operand" "")
3744 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3745 "TARGET_64BIT"
3746 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3747 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3748 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3749
3750 (define_expand "extendsfdf2"
3751 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3752 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3753 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3754 {
3755 /* ??? Needed for compress_float_constant since all fp constants
3756 are LEGITIMATE_CONSTANT_P. */
3757 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3758 {
3759 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3760 && standard_80387_constant_p (operands[1]) > 0)
3761 {
3762 operands[1] = simplify_const_unary_operation
3763 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3764 emit_move_insn_1 (operands[0], operands[1]);
3765 DONE;
3766 }
3767 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3768 }
3769 })
3770
3771 (define_insn "*extendsfdf2_mixed"
3772 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3773 (float_extend:DF
3774 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3775 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3776 {
3777 switch (which_alternative)
3778 {
3779 case 0:
3780 case 1:
3781 return output_387_reg_move (insn, operands);
3782
3783 case 2:
3784 return "cvtss2sd\t{%1, %0|%0, %1}";
3785
3786 default:
3787 gcc_unreachable ();
3788 }
3789 }
3790 [(set_attr "type" "fmov,fmov,ssecvt")
3791 (set_attr "mode" "SF,XF,DF")])
3792
3793 (define_insn "*extendsfdf2_sse"
3794 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3795 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3796 "TARGET_SSE2 && TARGET_SSE_MATH"
3797 "cvtss2sd\t{%1, %0|%0, %1}"
3798 [(set_attr "type" "ssecvt")
3799 (set_attr "mode" "DF")])
3800
3801 (define_insn "*extendsfdf2_i387"
3802 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3803 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3804 "TARGET_80387"
3805 "* return output_387_reg_move (insn, operands);"
3806 [(set_attr "type" "fmov")
3807 (set_attr "mode" "SF,XF")])
3808
3809 (define_expand "extend<mode>xf2"
3810 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3811 (float_extend:XF (match_operand:X87MODEF12 1 "general_operand" "")))]
3812 "TARGET_80387"
3813 {
3814 /* ??? Needed for compress_float_constant since all fp constants
3815 are LEGITIMATE_CONSTANT_P. */
3816 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3817 {
3818 if (standard_80387_constant_p (operands[1]) > 0)
3819 {
3820 operands[1] = simplify_const_unary_operation
3821 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3822 emit_move_insn_1 (operands[0], operands[1]);
3823 DONE;
3824 }
3825 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3826 }
3827 })
3828
3829 (define_insn "*extend<mode>xf2_i387"
3830 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3831 (float_extend:XF
3832 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,f")))]
3833 "TARGET_80387"
3834 "* return output_387_reg_move (insn, operands);"
3835 [(set_attr "type" "fmov")
3836 (set_attr "mode" "<MODE>,XF")])
3837
3838 ;; %%% This seems bad bad news.
3839 ;; This cannot output into an f-reg because there is no way to be sure
3840 ;; of truncating in that case. Otherwise this is just like a simple move
3841 ;; insn. So we pretend we can output to a reg in order to get better
3842 ;; register preferencing, but we really use a stack slot.
3843
3844 ;; Conversion from DFmode to SFmode.
3845
3846 (define_expand "truncdfsf2"
3847 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3848 (float_truncate:SF
3849 (match_operand:DF 1 "nonimmediate_operand" "")))]
3850 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3851 {
3852 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3853 ;
3854 else if (flag_unsafe_math_optimizations)
3855 ;
3856 else
3857 {
3858 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3859 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3860 DONE;
3861 }
3862 })
3863
3864 (define_expand "truncdfsf2_with_temp"
3865 [(parallel [(set (match_operand:SF 0 "" "")
3866 (float_truncate:SF (match_operand:DF 1 "" "")))
3867 (clobber (match_operand:SF 2 "" ""))])]
3868 "")
3869
3870 (define_insn "*truncdfsf_fast_mixed"
3871 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
3872 (float_truncate:SF
3873 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3874 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3875 {
3876 switch (which_alternative)
3877 {
3878 case 0:
3879 case 1:
3880 return output_387_reg_move (insn, operands);
3881 case 2:
3882 return "cvtsd2ss\t{%1, %0|%0, %1}";
3883 default:
3884 gcc_unreachable ();
3885 }
3886 }
3887 [(set_attr "type" "fmov,fmov,ssecvt")
3888 (set_attr "mode" "SF")])
3889
3890 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3891 ;; because nothing we do here is unsafe.
3892 (define_insn "*truncdfsf_fast_sse"
3893 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3894 (float_truncate:SF
3895 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3896 "TARGET_SSE2 && TARGET_SSE_MATH"
3897 "cvtsd2ss\t{%1, %0|%0, %1}"
3898 [(set_attr "type" "ssecvt")
3899 (set_attr "mode" "SF")])
3900
3901 (define_insn "*truncdfsf_fast_i387"
3902 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3903 (float_truncate:SF
3904 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3905 "TARGET_80387 && flag_unsafe_math_optimizations"
3906 "* return output_387_reg_move (insn, operands);"
3907 [(set_attr "type" "fmov")
3908 (set_attr "mode" "SF")])
3909
3910 (define_insn "*truncdfsf_mixed"
3911 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Yt")
3912 (float_truncate:SF
3913 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ytm")))
3914 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3915 "TARGET_MIX_SSE_I387"
3916 {
3917 switch (which_alternative)
3918 {
3919 case 0:
3920 return output_387_reg_move (insn, operands);
3921
3922 case 1:
3923 return "#";
3924 case 2:
3925 return "cvtsd2ss\t{%1, %0|%0, %1}";
3926 default:
3927 gcc_unreachable ();
3928 }
3929 }
3930 [(set_attr "type" "fmov,multi,ssecvt")
3931 (set_attr "unit" "*,i387,*")
3932 (set_attr "mode" "SF")])
3933
3934 (define_insn "*truncdfsf_i387"
3935 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3936 (float_truncate:SF
3937 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3938 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3939 "TARGET_80387"
3940 {
3941 switch (which_alternative)
3942 {
3943 case 0:
3944 return output_387_reg_move (insn, operands);
3945
3946 case 1:
3947 return "#";
3948 default:
3949 gcc_unreachable ();
3950 }
3951 }
3952 [(set_attr "type" "fmov,multi")
3953 (set_attr "unit" "*,i387")
3954 (set_attr "mode" "SF")])
3955
3956 (define_insn "*truncdfsf2_i387_1"
3957 [(set (match_operand:SF 0 "memory_operand" "=m")
3958 (float_truncate:SF
3959 (match_operand:DF 1 "register_operand" "f")))]
3960 "TARGET_80387
3961 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3962 && !TARGET_MIX_SSE_I387"
3963 "* return output_387_reg_move (insn, operands);"
3964 [(set_attr "type" "fmov")
3965 (set_attr "mode" "SF")])
3966
3967 (define_split
3968 [(set (match_operand:SF 0 "register_operand" "")
3969 (float_truncate:SF
3970 (match_operand:DF 1 "fp_register_operand" "")))
3971 (clobber (match_operand 2 "" ""))]
3972 "reload_completed"
3973 [(set (match_dup 2) (match_dup 1))
3974 (set (match_dup 0) (match_dup 2))]
3975 {
3976 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3977 })
3978
3979 ;; Conversion from XFmode to {SF,DF}mode
3980
3981 (define_expand "truncxf<mode>2"
3982 [(parallel [(set (match_operand:X87MODEF12 0 "nonimmediate_operand" "")
3983 (float_truncate:X87MODEF12
3984 (match_operand:XF 1 "register_operand" "")))
3985 (clobber (match_dup 2))])]
3986 "TARGET_80387"
3987 {
3988 if (flag_unsafe_math_optimizations)
3989 {
3990 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3991 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3992 if (reg != operands[0])
3993 emit_move_insn (operands[0], reg);
3994 DONE;
3995 }
3996 else
3997 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_VIRTUAL);
3998 })
3999
4000 (define_insn "*truncxfsf2_mixed"
4001 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4002 (float_truncate:SF
4003 (match_operand:XF 1 "register_operand" "f,f")))
4004 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4005 "TARGET_80387"
4006 {
4007 gcc_assert (!which_alternative);
4008 return output_387_reg_move (insn, operands);
4009 }
4010 [(set_attr "type" "fmov,multi")
4011 (set_attr "unit" "*,i387")
4012 (set_attr "mode" "SF")])
4013
4014 (define_insn "*truncxfdf2_mixed"
4015 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fYt*r")
4016 (float_truncate:DF
4017 (match_operand:XF 1 "register_operand" "f,f")))
4018 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4019 "TARGET_80387"
4020 {
4021 gcc_assert (!which_alternative);
4022 return output_387_reg_move (insn, operands);
4023 }
4024 [(set_attr "type" "fmov,multi")
4025 (set_attr "unit" "*,i387")
4026 (set_attr "mode" "DF")])
4027
4028 (define_insn "truncxf<mode>2_i387_noop"
4029 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
4030 (float_truncate:X87MODEF12
4031 (match_operand:XF 1 "register_operand" "f")))]
4032 "TARGET_80387 && flag_unsafe_math_optimizations"
4033 "* return output_387_reg_move (insn, operands);"
4034 [(set_attr "type" "fmov")
4035 (set_attr "mode" "<MODE>")])
4036
4037 (define_insn "*truncxf<mode>2_i387"
4038 [(set (match_operand:X87MODEF12 0 "memory_operand" "=m")
4039 (float_truncate:X87MODEF12
4040 (match_operand:XF 1 "register_operand" "f")))]
4041 "TARGET_80387"
4042 "* return output_387_reg_move (insn, operands);"
4043 [(set_attr "type" "fmov")
4044 (set_attr "mode" "<MODE>")])
4045
4046 (define_split
4047 [(set (match_operand:X87MODEF12 0 "register_operand" "")
4048 (float_truncate:X87MODEF12
4049 (match_operand:XF 1 "register_operand" "")))
4050 (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4051 "TARGET_80387 && reload_completed"
4052 [(set (match_dup 2) (float_truncate:X87MODEF12 (match_dup 1)))
4053 (set (match_dup 0) (match_dup 2))]
4054 "")
4055
4056 (define_split
4057 [(set (match_operand:X87MODEF12 0 "memory_operand" "")
4058 (float_truncate:X87MODEF12
4059 (match_operand:XF 1 "register_operand" "")))
4060 (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4061 "TARGET_80387"
4062 [(set (match_dup 0) (float_truncate:X87MODEF12 (match_dup 1)))]
4063 "")
4064 \f
4065 ;; Signed conversion to DImode.
4066
4067 (define_expand "fix_truncxfdi2"
4068 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4069 (fix:DI (match_operand:XF 1 "register_operand" "")))
4070 (clobber (reg:CC FLAGS_REG))])]
4071 "TARGET_80387"
4072 {
4073 if (TARGET_FISTTP)
4074 {
4075 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4076 DONE;
4077 }
4078 })
4079
4080 (define_expand "fix_trunc<mode>di2"
4081 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4082 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4083 (clobber (reg:CC FLAGS_REG))])]
4084 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4085 {
4086 if (TARGET_FISTTP
4087 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4088 {
4089 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4090 DONE;
4091 }
4092 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4093 {
4094 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4095 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4096 if (out != operands[0])
4097 emit_move_insn (operands[0], out);
4098 DONE;
4099 }
4100 })
4101
4102 ;; Signed conversion to SImode.
4103
4104 (define_expand "fix_truncxfsi2"
4105 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4106 (fix:SI (match_operand:XF 1 "register_operand" "")))
4107 (clobber (reg:CC FLAGS_REG))])]
4108 "TARGET_80387"
4109 {
4110 if (TARGET_FISTTP)
4111 {
4112 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4113 DONE;
4114 }
4115 })
4116
4117 (define_expand "fix_trunc<mode>si2"
4118 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4119 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4120 (clobber (reg:CC FLAGS_REG))])]
4121 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4122 {
4123 if (TARGET_FISTTP
4124 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4125 {
4126 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4127 DONE;
4128 }
4129 if (SSE_FLOAT_MODE_P (<MODE>mode))
4130 {
4131 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4132 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4133 if (out != operands[0])
4134 emit_move_insn (operands[0], out);
4135 DONE;
4136 }
4137 })
4138
4139 ;; Signed conversion to HImode.
4140
4141 (define_expand "fix_trunc<mode>hi2"
4142 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4143 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4144 (clobber (reg:CC FLAGS_REG))])]
4145 "TARGET_80387
4146 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4147 {
4148 if (TARGET_FISTTP)
4149 {
4150 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4151 DONE;
4152 }
4153 })
4154
4155 ;; Unsigned conversion to SImode.
4156
4157 (define_expand "fixuns_trunc<mode>si2"
4158 [(parallel
4159 [(set (match_operand:SI 0 "register_operand" "")
4160 (unsigned_fix:SI
4161 (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4162 (use (match_dup 2))
4163 (clobber (match_scratch:<ssevecmode> 3 ""))
4164 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4165 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4166 {
4167 enum machine_mode mode = <MODE>mode;
4168 enum machine_mode vecmode = <ssevecmode>mode;
4169 REAL_VALUE_TYPE TWO31r;
4170 rtx two31;
4171
4172 real_ldexp (&TWO31r, &dconst1, 31);
4173 two31 = const_double_from_real_value (TWO31r, mode);
4174 two31 = ix86_build_const_vector (mode, true, two31);
4175 operands[2] = force_reg (vecmode, two31);
4176 })
4177
4178 (define_insn_and_split "*fixuns_trunc<mode>_1"
4179 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4180 (unsigned_fix:SI
4181 (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4182 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4183 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4184 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4185 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4186 "#"
4187 "&& reload_completed"
4188 [(const_int 0)]
4189 {
4190 ix86_split_convert_uns_si_sse (operands);
4191 DONE;
4192 })
4193
4194 ;; Unsigned conversion to HImode.
4195 ;; Without these patterns, we'll try the unsigned SI conversion which
4196 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4197
4198 (define_expand "fixuns_trunc<mode>hi2"
4199 [(set (match_dup 2)
4200 (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4201 (set (match_operand:HI 0 "nonimmediate_operand" "")
4202 (subreg:HI (match_dup 2) 0))]
4203 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4204 "operands[2] = gen_reg_rtx (SImode);")
4205
4206 ;; When SSE is available, it is always faster to use it!
4207 (define_insn "fix_trunc<mode>di_sse"
4208 [(set (match_operand:DI 0 "register_operand" "=r,r")
4209 (fix:DI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4210 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4211 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4212 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4213 [(set_attr "type" "sseicvt")
4214 (set_attr "mode" "<MODE>")
4215 (set_attr "athlon_decode" "double,vector")
4216 (set_attr "amdfam10_decode" "double,double")])
4217
4218 (define_insn "fix_trunc<mode>si_sse"
4219 [(set (match_operand:SI 0 "register_operand" "=r,r")
4220 (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4221 "SSE_FLOAT_MODE_P (<MODE>mode)
4222 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4223 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4224 [(set_attr "type" "sseicvt")
4225 (set_attr "mode" "<MODE>")
4226 (set_attr "athlon_decode" "double,vector")
4227 (set_attr "amdfam10_decode" "double,double")])
4228
4229 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4230 (define_peephole2
4231 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4232 (match_operand:SSEMODEF 1 "memory_operand" ""))
4233 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4234 (fix:SSEMODEI24 (match_dup 0)))]
4235 "TARGET_SHORTEN_X87_SSE
4236 && peep2_reg_dead_p (2, operands[0])"
4237 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4238 "")
4239
4240 ;; Avoid vector decoded forms of the instruction.
4241 (define_peephole2
4242 [(match_scratch:DF 2 "Yt")
4243 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4244 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4245 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4246 [(set (match_dup 2) (match_dup 1))
4247 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4248 "")
4249
4250 (define_peephole2
4251 [(match_scratch:SF 2 "x")
4252 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4253 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4254 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4255 [(set (match_dup 2) (match_dup 1))
4256 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4257 "")
4258
4259 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4260 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4261 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4262 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4263 && TARGET_FISTTP
4264 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4265 && (TARGET_64BIT || <MODE>mode != DImode))
4266 && TARGET_SSE_MATH)
4267 && !(reload_completed || reload_in_progress)"
4268 "#"
4269 "&& 1"
4270 [(const_int 0)]
4271 {
4272 if (memory_operand (operands[0], VOIDmode))
4273 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4274 else
4275 {
4276 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4277 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4278 operands[1],
4279 operands[2]));
4280 }
4281 DONE;
4282 }
4283 [(set_attr "type" "fisttp")
4284 (set_attr "mode" "<MODE>")])
4285
4286 (define_insn "fix_trunc<mode>_i387_fisttp"
4287 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4288 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4289 (clobber (match_scratch:XF 2 "=&1f"))]
4290 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4291 && TARGET_FISTTP
4292 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4293 && (TARGET_64BIT || <MODE>mode != DImode))
4294 && TARGET_SSE_MATH)"
4295 "* return output_fix_trunc (insn, operands, 1);"
4296 [(set_attr "type" "fisttp")
4297 (set_attr "mode" "<MODE>")])
4298
4299 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4300 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4301 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4302 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4303 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4304 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4305 && TARGET_FISTTP
4306 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4307 && (TARGET_64BIT || <MODE>mode != DImode))
4308 && TARGET_SSE_MATH)"
4309 "#"
4310 [(set_attr "type" "fisttp")
4311 (set_attr "mode" "<MODE>")])
4312
4313 (define_split
4314 [(set (match_operand:X87MODEI 0 "register_operand" "")
4315 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4316 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4317 (clobber (match_scratch 3 ""))]
4318 "reload_completed"
4319 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4320 (clobber (match_dup 3))])
4321 (set (match_dup 0) (match_dup 2))]
4322 "")
4323
4324 (define_split
4325 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4326 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4327 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4328 (clobber (match_scratch 3 ""))]
4329 "reload_completed"
4330 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4331 (clobber (match_dup 3))])]
4332 "")
4333
4334 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4335 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4336 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4337 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4338 ;; function in i386.c.
4339 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4340 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4341 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4342 (clobber (reg:CC FLAGS_REG))]
4343 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4344 && !TARGET_FISTTP
4345 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4346 && (TARGET_64BIT || <MODE>mode != DImode))
4347 && !(reload_completed || reload_in_progress)"
4348 "#"
4349 "&& 1"
4350 [(const_int 0)]
4351 {
4352 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4353
4354 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4355 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4356 if (memory_operand (operands[0], VOIDmode))
4357 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4358 operands[2], operands[3]));
4359 else
4360 {
4361 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4362 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4363 operands[2], operands[3],
4364 operands[4]));
4365 }
4366 DONE;
4367 }
4368 [(set_attr "type" "fistp")
4369 (set_attr "i387_cw" "trunc")
4370 (set_attr "mode" "<MODE>")])
4371
4372 (define_insn "fix_truncdi_i387"
4373 [(set (match_operand:DI 0 "memory_operand" "=m")
4374 (fix:DI (match_operand 1 "register_operand" "f")))
4375 (use (match_operand:HI 2 "memory_operand" "m"))
4376 (use (match_operand:HI 3 "memory_operand" "m"))
4377 (clobber (match_scratch:XF 4 "=&1f"))]
4378 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4379 && !TARGET_FISTTP
4380 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4381 "* return output_fix_trunc (insn, operands, 0);"
4382 [(set_attr "type" "fistp")
4383 (set_attr "i387_cw" "trunc")
4384 (set_attr "mode" "DI")])
4385
4386 (define_insn "fix_truncdi_i387_with_temp"
4387 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4388 (fix:DI (match_operand 1 "register_operand" "f,f")))
4389 (use (match_operand:HI 2 "memory_operand" "m,m"))
4390 (use (match_operand:HI 3 "memory_operand" "m,m"))
4391 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4392 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4393 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4394 && !TARGET_FISTTP
4395 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4396 "#"
4397 [(set_attr "type" "fistp")
4398 (set_attr "i387_cw" "trunc")
4399 (set_attr "mode" "DI")])
4400
4401 (define_split
4402 [(set (match_operand:DI 0 "register_operand" "")
4403 (fix:DI (match_operand 1 "register_operand" "")))
4404 (use (match_operand:HI 2 "memory_operand" ""))
4405 (use (match_operand:HI 3 "memory_operand" ""))
4406 (clobber (match_operand:DI 4 "memory_operand" ""))
4407 (clobber (match_scratch 5 ""))]
4408 "reload_completed"
4409 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4410 (use (match_dup 2))
4411 (use (match_dup 3))
4412 (clobber (match_dup 5))])
4413 (set (match_dup 0) (match_dup 4))]
4414 "")
4415
4416 (define_split
4417 [(set (match_operand:DI 0 "memory_operand" "")
4418 (fix:DI (match_operand 1 "register_operand" "")))
4419 (use (match_operand:HI 2 "memory_operand" ""))
4420 (use (match_operand:HI 3 "memory_operand" ""))
4421 (clobber (match_operand:DI 4 "memory_operand" ""))
4422 (clobber (match_scratch 5 ""))]
4423 "reload_completed"
4424 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4425 (use (match_dup 2))
4426 (use (match_dup 3))
4427 (clobber (match_dup 5))])]
4428 "")
4429
4430 (define_insn "fix_trunc<mode>_i387"
4431 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4432 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4433 (use (match_operand:HI 2 "memory_operand" "m"))
4434 (use (match_operand:HI 3 "memory_operand" "m"))]
4435 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4436 && !TARGET_FISTTP
4437 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4438 "* return output_fix_trunc (insn, operands, 0);"
4439 [(set_attr "type" "fistp")
4440 (set_attr "i387_cw" "trunc")
4441 (set_attr "mode" "<MODE>")])
4442
4443 (define_insn "fix_trunc<mode>_i387_with_temp"
4444 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4445 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4446 (use (match_operand:HI 2 "memory_operand" "m,m"))
4447 (use (match_operand:HI 3 "memory_operand" "m,m"))
4448 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4449 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4450 && !TARGET_FISTTP
4451 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4452 "#"
4453 [(set_attr "type" "fistp")
4454 (set_attr "i387_cw" "trunc")
4455 (set_attr "mode" "<MODE>")])
4456
4457 (define_split
4458 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4459 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4460 (use (match_operand:HI 2 "memory_operand" ""))
4461 (use (match_operand:HI 3 "memory_operand" ""))
4462 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4463 "reload_completed"
4464 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4465 (use (match_dup 2))
4466 (use (match_dup 3))])
4467 (set (match_dup 0) (match_dup 4))]
4468 "")
4469
4470 (define_split
4471 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4472 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4473 (use (match_operand:HI 2 "memory_operand" ""))
4474 (use (match_operand:HI 3 "memory_operand" ""))
4475 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4476 "reload_completed"
4477 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4478 (use (match_dup 2))
4479 (use (match_dup 3))])]
4480 "")
4481
4482 (define_insn "x86_fnstcw_1"
4483 [(set (match_operand:HI 0 "memory_operand" "=m")
4484 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4485 "TARGET_80387"
4486 "fnstcw\t%0"
4487 [(set_attr "length" "2")
4488 (set_attr "mode" "HI")
4489 (set_attr "unit" "i387")])
4490
4491 (define_insn "x86_fldcw_1"
4492 [(set (reg:HI FPCR_REG)
4493 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4494 "TARGET_80387"
4495 "fldcw\t%0"
4496 [(set_attr "length" "2")
4497 (set_attr "mode" "HI")
4498 (set_attr "unit" "i387")
4499 (set_attr "athlon_decode" "vector")
4500 (set_attr "amdfam10_decode" "vector")])
4501 \f
4502 ;; Conversion between fixed point and floating point.
4503
4504 ;; Even though we only accept memory inputs, the backend _really_
4505 ;; wants to be able to do this between registers.
4506
4507 (define_expand "floathi<mode>2"
4508 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4509 (float:SSEMODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4510 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4511 {
4512 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4513 {
4514 emit_insn
4515 (gen_floatsi<mode>2 (operands[0],
4516 convert_to_mode (SImode, operands[1], 0)));
4517 DONE;
4518 }
4519 })
4520
4521 (define_insn "*floathi<mode>2_i387"
4522 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4523 (float:X87MODEF12
4524 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4525 "TARGET_80387
4526 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4527 || TARGET_MIX_SSE_I387)"
4528 "@
4529 fild%z1\t%1
4530 #"
4531 [(set_attr "type" "fmov,multi")
4532 (set_attr "mode" "<MODE>")
4533 (set_attr "unit" "*,i387")
4534 (set_attr "fp_int_src" "true")])
4535
4536 (define_expand "floatsi<mode>2"
4537 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4538 (float:SSEMODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4539 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4540 "")
4541
4542 (define_insn "*floatsisf2_mixed"
4543 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4544 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4545 "TARGET_MIX_SSE_I387"
4546 "@
4547 fild%z1\t%1
4548 #
4549 cvtsi2ss\t{%1, %0|%0, %1}
4550 cvtsi2ss\t{%1, %0|%0, %1}"
4551 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4552 (set_attr "mode" "SF")
4553 (set_attr "unit" "*,i387,*,*")
4554 (set_attr "athlon_decode" "*,*,vector,double")
4555 (set_attr "amdfam10_decode" "*,*,vector,double")
4556 (set_attr "fp_int_src" "true")])
4557
4558 (define_insn "*floatsisf2_sse"
4559 [(set (match_operand:SF 0 "register_operand" "=x,x")
4560 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4561 "TARGET_SSE_MATH"
4562 "cvtsi2ss\t{%1, %0|%0, %1}"
4563 [(set_attr "type" "sseicvt")
4564 (set_attr "mode" "SF")
4565 (set_attr "athlon_decode" "vector,double")
4566 (set_attr "amdfam10_decode" "vector,double")
4567 (set_attr "fp_int_src" "true")])
4568
4569 (define_insn "*floatsidf2_mixed"
4570 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4571 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4572 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4573 "@
4574 fild%z1\t%1
4575 #
4576 cvtsi2sd\t{%1, %0|%0, %1}
4577 cvtsi2sd\t{%1, %0|%0, %1}"
4578 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4579 (set_attr "mode" "DF")
4580 (set_attr "unit" "*,i387,*,*")
4581 (set_attr "athlon_decode" "*,*,double,direct")
4582 (set_attr "amdfam10_decode" "*,*,vector,double")
4583 (set_attr "fp_int_src" "true")])
4584
4585 (define_insn "*floatsidf2_sse"
4586 [(set (match_operand:DF 0 "register_operand" "=x,x")
4587 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4588 "TARGET_SSE2 && TARGET_SSE_MATH"
4589 "cvtsi2sd\t{%1, %0|%0, %1}"
4590 [(set_attr "type" "sseicvt")
4591 (set_attr "mode" "DF")
4592 (set_attr "athlon_decode" "double,direct")
4593 (set_attr "amdfam10_decode" "vector,double")
4594 (set_attr "fp_int_src" "true")])
4595
4596 (define_insn "*floatsi<mode>2_i387"
4597 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4598 (float:X87MODEF12
4599 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4600 "TARGET_80387"
4601 "@
4602 fild%z1\t%1
4603 #"
4604 [(set_attr "type" "fmov,multi")
4605 (set_attr "mode" "<MODE>")
4606 (set_attr "unit" "*,i387")
4607 (set_attr "fp_int_src" "true")])
4608
4609 (define_expand "floatdisf2"
4610 [(set (match_operand:SF 0 "register_operand" "")
4611 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4612 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4613 "")
4614
4615 (define_insn "*floatdisf2_mixed"
4616 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4617 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4618 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4619 "@
4620 fild%z1\t%1
4621 #
4622 cvtsi2ss{q}\t{%1, %0|%0, %1}
4623 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4624 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4625 (set_attr "mode" "SF")
4626 (set_attr "unit" "*,i387,*,*")
4627 (set_attr "athlon_decode" "*,*,vector,double")
4628 (set_attr "amdfam10_decode" "*,*,vector,double")
4629 (set_attr "fp_int_src" "true")])
4630
4631 (define_insn "*floatdisf2_sse"
4632 [(set (match_operand:SF 0 "register_operand" "=x,x")
4633 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4634 "TARGET_64BIT && TARGET_SSE_MATH"
4635 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4636 [(set_attr "type" "sseicvt")
4637 (set_attr "mode" "SF")
4638 (set_attr "athlon_decode" "vector,double")
4639 (set_attr "amdfam10_decode" "vector,double")
4640 (set_attr "fp_int_src" "true")])
4641
4642 (define_expand "floatdidf2"
4643 [(set (match_operand:DF 0 "register_operand" "")
4644 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4645 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4646 {
4647 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4648 {
4649 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4650 DONE;
4651 }
4652 })
4653
4654 (define_insn "*floatdidf2_mixed"
4655 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4656 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4657 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4658 "@
4659 fild%z1\t%1
4660 #
4661 cvtsi2sd{q}\t{%1, %0|%0, %1}
4662 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4663 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4664 (set_attr "mode" "DF")
4665 (set_attr "unit" "*,i387,*,*")
4666 (set_attr "athlon_decode" "*,*,double,direct")
4667 (set_attr "amdfam10_decode" "*,*,vector,double")
4668 (set_attr "fp_int_src" "true")])
4669
4670 (define_insn "*floatdidf2_sse"
4671 [(set (match_operand:DF 0 "register_operand" "=x,x")
4672 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4673 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4674 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4675 [(set_attr "type" "sseicvt")
4676 (set_attr "mode" "DF")
4677 (set_attr "athlon_decode" "double,direct")
4678 (set_attr "amdfam10_decode" "vector,double")
4679 (set_attr "fp_int_src" "true")])
4680
4681 (define_insn "*floatdi<mode>2_i387"
4682 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4683 (float:X87MODEF12
4684 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4685 "TARGET_80387"
4686 "@
4687 fild%z1\t%1
4688 #"
4689 [(set_attr "type" "fmov,multi")
4690 (set_attr "mode" "<MODE>")
4691 (set_attr "unit" "*,i387")
4692 (set_attr "fp_int_src" "true")])
4693
4694 (define_insn "float<mode>xf2"
4695 [(set (match_operand:XF 0 "register_operand" "=f,f")
4696 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
4697 "TARGET_80387"
4698 "@
4699 fild%z1\t%1
4700 #"
4701 [(set_attr "type" "fmov,multi")
4702 (set_attr "mode" "XF")
4703 (set_attr "unit" "*,i387")
4704 (set_attr "fp_int_src" "true")])
4705
4706 ;; %%% Kill these when reload knows how to do it.
4707 (define_split
4708 [(set (match_operand 0 "fp_register_operand" "")
4709 (float (match_operand 1 "register_operand" "")))]
4710 "reload_completed
4711 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
4712 [(const_int 0)]
4713 {
4714 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4715 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4716 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4717 ix86_free_from_memory (GET_MODE (operands[1]));
4718 DONE;
4719 })
4720
4721 (define_expand "floatunssisf2"
4722 [(use (match_operand:SF 0 "register_operand" ""))
4723 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4724 "!TARGET_64BIT"
4725 {
4726 if (TARGET_SSE_MATH && TARGET_SSE2)
4727 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4728 else
4729 x86_emit_floatuns (operands);
4730 DONE;
4731 })
4732
4733 (define_expand "floatunssidf2"
4734 [(use (match_operand:DF 0 "register_operand" ""))
4735 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4736 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4737 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
4738
4739 (define_expand "floatunsdisf2"
4740 [(use (match_operand:SF 0 "register_operand" ""))
4741 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4742 "TARGET_64BIT && TARGET_SSE_MATH"
4743 "x86_emit_floatuns (operands); DONE;")
4744
4745 (define_expand "floatunsdidf2"
4746 [(use (match_operand:DF 0 "register_operand" ""))
4747 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4748 "TARGET_SSE_MATH && TARGET_SSE2
4749 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
4750 {
4751 if (TARGET_64BIT)
4752 x86_emit_floatuns (operands);
4753 else
4754 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
4755 DONE;
4756 })
4757 \f
4758 ;; Add instructions
4759
4760 ;; %%% splits for addditi3
4761
4762 (define_expand "addti3"
4763 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4764 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4765 (match_operand:TI 2 "x86_64_general_operand" "")))
4766 (clobber (reg:CC FLAGS_REG))]
4767 "TARGET_64BIT"
4768 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4769
4770 (define_insn "*addti3_1"
4771 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4772 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4773 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4774 (clobber (reg:CC FLAGS_REG))]
4775 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4776 "#")
4777
4778 (define_split
4779 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4780 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4781 (match_operand:TI 2 "x86_64_general_operand" "")))
4782 (clobber (reg:CC FLAGS_REG))]
4783 "TARGET_64BIT && reload_completed"
4784 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4785 UNSPEC_ADD_CARRY))
4786 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4787 (parallel [(set (match_dup 3)
4788 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4789 (match_dup 4))
4790 (match_dup 5)))
4791 (clobber (reg:CC FLAGS_REG))])]
4792 "split_ti (operands+0, 1, operands+0, operands+3);
4793 split_ti (operands+1, 1, operands+1, operands+4);
4794 split_ti (operands+2, 1, operands+2, operands+5);")
4795
4796 ;; %%% splits for addsidi3
4797 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4798 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4799 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4800
4801 (define_expand "adddi3"
4802 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4803 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4804 (match_operand:DI 2 "x86_64_general_operand" "")))
4805 (clobber (reg:CC FLAGS_REG))]
4806 ""
4807 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4808
4809 (define_insn "*adddi3_1"
4810 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4811 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4812 (match_operand:DI 2 "general_operand" "roiF,riF")))
4813 (clobber (reg:CC FLAGS_REG))]
4814 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4815 "#")
4816
4817 (define_split
4818 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4819 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4820 (match_operand:DI 2 "general_operand" "")))
4821 (clobber (reg:CC FLAGS_REG))]
4822 "!TARGET_64BIT && reload_completed"
4823 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4824 UNSPEC_ADD_CARRY))
4825 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4826 (parallel [(set (match_dup 3)
4827 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4828 (match_dup 4))
4829 (match_dup 5)))
4830 (clobber (reg:CC FLAGS_REG))])]
4831 "split_di (operands+0, 1, operands+0, operands+3);
4832 split_di (operands+1, 1, operands+1, operands+4);
4833 split_di (operands+2, 1, operands+2, operands+5);")
4834
4835 (define_insn "adddi3_carry_rex64"
4836 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4837 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4838 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4839 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4840 (clobber (reg:CC FLAGS_REG))]
4841 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4842 "adc{q}\t{%2, %0|%0, %2}"
4843 [(set_attr "type" "alu")
4844 (set_attr "pent_pair" "pu")
4845 (set_attr "mode" "DI")])
4846
4847 (define_insn "*adddi3_cc_rex64"
4848 [(set (reg:CC FLAGS_REG)
4849 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4850 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4851 UNSPEC_ADD_CARRY))
4852 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4853 (plus:DI (match_dup 1) (match_dup 2)))]
4854 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4855 "add{q}\t{%2, %0|%0, %2}"
4856 [(set_attr "type" "alu")
4857 (set_attr "mode" "DI")])
4858
4859 (define_insn "addqi3_carry"
4860 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4861 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4862 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4863 (match_operand:QI 2 "general_operand" "qi,qm")))
4864 (clobber (reg:CC FLAGS_REG))]
4865 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4866 "adc{b}\t{%2, %0|%0, %2}"
4867 [(set_attr "type" "alu")
4868 (set_attr "pent_pair" "pu")
4869 (set_attr "mode" "QI")])
4870
4871 (define_insn "addhi3_carry"
4872 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4873 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4874 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4875 (match_operand:HI 2 "general_operand" "ri,rm")))
4876 (clobber (reg:CC FLAGS_REG))]
4877 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4878 "adc{w}\t{%2, %0|%0, %2}"
4879 [(set_attr "type" "alu")
4880 (set_attr "pent_pair" "pu")
4881 (set_attr "mode" "HI")])
4882
4883 (define_insn "addsi3_carry"
4884 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4885 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4886 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4887 (match_operand:SI 2 "general_operand" "ri,rm")))
4888 (clobber (reg:CC FLAGS_REG))]
4889 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4890 "adc{l}\t{%2, %0|%0, %2}"
4891 [(set_attr "type" "alu")
4892 (set_attr "pent_pair" "pu")
4893 (set_attr "mode" "SI")])
4894
4895 (define_insn "*addsi3_carry_zext"
4896 [(set (match_operand:DI 0 "register_operand" "=r")
4897 (zero_extend:DI
4898 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4899 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4900 (match_operand:SI 2 "general_operand" "rim"))))
4901 (clobber (reg:CC FLAGS_REG))]
4902 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4903 "adc{l}\t{%2, %k0|%k0, %2}"
4904 [(set_attr "type" "alu")
4905 (set_attr "pent_pair" "pu")
4906 (set_attr "mode" "SI")])
4907
4908 (define_insn "*addsi3_cc"
4909 [(set (reg:CC FLAGS_REG)
4910 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4911 (match_operand:SI 2 "general_operand" "ri,rm")]
4912 UNSPEC_ADD_CARRY))
4913 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4914 (plus:SI (match_dup 1) (match_dup 2)))]
4915 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4916 "add{l}\t{%2, %0|%0, %2}"
4917 [(set_attr "type" "alu")
4918 (set_attr "mode" "SI")])
4919
4920 (define_insn "addqi3_cc"
4921 [(set (reg:CC FLAGS_REG)
4922 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4923 (match_operand:QI 2 "general_operand" "qi,qm")]
4924 UNSPEC_ADD_CARRY))
4925 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4926 (plus:QI (match_dup 1) (match_dup 2)))]
4927 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4928 "add{b}\t{%2, %0|%0, %2}"
4929 [(set_attr "type" "alu")
4930 (set_attr "mode" "QI")])
4931
4932 (define_expand "addsi3"
4933 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4934 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4935 (match_operand:SI 2 "general_operand" "")))
4936 (clobber (reg:CC FLAGS_REG))])]
4937 ""
4938 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4939
4940 (define_insn "*lea_1"
4941 [(set (match_operand:SI 0 "register_operand" "=r")
4942 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4943 "!TARGET_64BIT"
4944 "lea{l}\t{%a1, %0|%0, %a1}"
4945 [(set_attr "type" "lea")
4946 (set_attr "mode" "SI")])
4947
4948 (define_insn "*lea_1_rex64"
4949 [(set (match_operand:SI 0 "register_operand" "=r")
4950 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4951 "TARGET_64BIT"
4952 "lea{l}\t{%a1, %0|%0, %a1}"
4953 [(set_attr "type" "lea")
4954 (set_attr "mode" "SI")])
4955
4956 (define_insn "*lea_1_zext"
4957 [(set (match_operand:DI 0 "register_operand" "=r")
4958 (zero_extend:DI
4959 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4960 "TARGET_64BIT"
4961 "lea{l}\t{%a1, %k0|%k0, %a1}"
4962 [(set_attr "type" "lea")
4963 (set_attr "mode" "SI")])
4964
4965 (define_insn "*lea_2_rex64"
4966 [(set (match_operand:DI 0 "register_operand" "=r")
4967 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4968 "TARGET_64BIT"
4969 "lea{q}\t{%a1, %0|%0, %a1}"
4970 [(set_attr "type" "lea")
4971 (set_attr "mode" "DI")])
4972
4973 ;; The lea patterns for non-Pmodes needs to be matched by several
4974 ;; insns converted to real lea by splitters.
4975
4976 (define_insn_and_split "*lea_general_1"
4977 [(set (match_operand 0 "register_operand" "=r")
4978 (plus (plus (match_operand 1 "index_register_operand" "l")
4979 (match_operand 2 "register_operand" "r"))
4980 (match_operand 3 "immediate_operand" "i")))]
4981 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4982 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4983 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4984 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4985 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4986 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4987 || GET_MODE (operands[3]) == VOIDmode)"
4988 "#"
4989 "&& reload_completed"
4990 [(const_int 0)]
4991 {
4992 rtx pat;
4993 operands[0] = gen_lowpart (SImode, operands[0]);
4994 operands[1] = gen_lowpart (Pmode, operands[1]);
4995 operands[2] = gen_lowpart (Pmode, operands[2]);
4996 operands[3] = gen_lowpart (Pmode, operands[3]);
4997 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4998 operands[3]);
4999 if (Pmode != SImode)
5000 pat = gen_rtx_SUBREG (SImode, pat, 0);
5001 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5002 DONE;
5003 }
5004 [(set_attr "type" "lea")
5005 (set_attr "mode" "SI")])
5006
5007 (define_insn_and_split "*lea_general_1_zext"
5008 [(set (match_operand:DI 0 "register_operand" "=r")
5009 (zero_extend:DI
5010 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5011 (match_operand:SI 2 "register_operand" "r"))
5012 (match_operand:SI 3 "immediate_operand" "i"))))]
5013 "TARGET_64BIT"
5014 "#"
5015 "&& reload_completed"
5016 [(set (match_dup 0)
5017 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5018 (match_dup 2))
5019 (match_dup 3)) 0)))]
5020 {
5021 operands[1] = gen_lowpart (Pmode, operands[1]);
5022 operands[2] = gen_lowpart (Pmode, operands[2]);
5023 operands[3] = gen_lowpart (Pmode, operands[3]);
5024 }
5025 [(set_attr "type" "lea")
5026 (set_attr "mode" "SI")])
5027
5028 (define_insn_and_split "*lea_general_2"
5029 [(set (match_operand 0 "register_operand" "=r")
5030 (plus (mult (match_operand 1 "index_register_operand" "l")
5031 (match_operand 2 "const248_operand" "i"))
5032 (match_operand 3 "nonmemory_operand" "ri")))]
5033 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5034 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5035 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5036 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5037 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5038 || GET_MODE (operands[3]) == VOIDmode)"
5039 "#"
5040 "&& reload_completed"
5041 [(const_int 0)]
5042 {
5043 rtx pat;
5044 operands[0] = gen_lowpart (SImode, operands[0]);
5045 operands[1] = gen_lowpart (Pmode, operands[1]);
5046 operands[3] = gen_lowpart (Pmode, operands[3]);
5047 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5048 operands[3]);
5049 if (Pmode != SImode)
5050 pat = gen_rtx_SUBREG (SImode, pat, 0);
5051 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5052 DONE;
5053 }
5054 [(set_attr "type" "lea")
5055 (set_attr "mode" "SI")])
5056
5057 (define_insn_and_split "*lea_general_2_zext"
5058 [(set (match_operand:DI 0 "register_operand" "=r")
5059 (zero_extend:DI
5060 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5061 (match_operand:SI 2 "const248_operand" "n"))
5062 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5063 "TARGET_64BIT"
5064 "#"
5065 "&& reload_completed"
5066 [(set (match_dup 0)
5067 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5068 (match_dup 2))
5069 (match_dup 3)) 0)))]
5070 {
5071 operands[1] = gen_lowpart (Pmode, operands[1]);
5072 operands[3] = gen_lowpart (Pmode, operands[3]);
5073 }
5074 [(set_attr "type" "lea")
5075 (set_attr "mode" "SI")])
5076
5077 (define_insn_and_split "*lea_general_3"
5078 [(set (match_operand 0 "register_operand" "=r")
5079 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5080 (match_operand 2 "const248_operand" "i"))
5081 (match_operand 3 "register_operand" "r"))
5082 (match_operand 4 "immediate_operand" "i")))]
5083 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5084 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5085 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5086 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5087 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5088 "#"
5089 "&& reload_completed"
5090 [(const_int 0)]
5091 {
5092 rtx pat;
5093 operands[0] = gen_lowpart (SImode, operands[0]);
5094 operands[1] = gen_lowpart (Pmode, operands[1]);
5095 operands[3] = gen_lowpart (Pmode, operands[3]);
5096 operands[4] = gen_lowpart (Pmode, operands[4]);
5097 pat = gen_rtx_PLUS (Pmode,
5098 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5099 operands[2]),
5100 operands[3]),
5101 operands[4]);
5102 if (Pmode != SImode)
5103 pat = gen_rtx_SUBREG (SImode, pat, 0);
5104 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5105 DONE;
5106 }
5107 [(set_attr "type" "lea")
5108 (set_attr "mode" "SI")])
5109
5110 (define_insn_and_split "*lea_general_3_zext"
5111 [(set (match_operand:DI 0 "register_operand" "=r")
5112 (zero_extend:DI
5113 (plus:SI (plus:SI (mult:SI
5114 (match_operand:SI 1 "index_register_operand" "l")
5115 (match_operand:SI 2 "const248_operand" "n"))
5116 (match_operand:SI 3 "register_operand" "r"))
5117 (match_operand:SI 4 "immediate_operand" "i"))))]
5118 "TARGET_64BIT"
5119 "#"
5120 "&& reload_completed"
5121 [(set (match_dup 0)
5122 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5123 (match_dup 2))
5124 (match_dup 3))
5125 (match_dup 4)) 0)))]
5126 {
5127 operands[1] = gen_lowpart (Pmode, operands[1]);
5128 operands[3] = gen_lowpart (Pmode, operands[3]);
5129 operands[4] = gen_lowpart (Pmode, operands[4]);
5130 }
5131 [(set_attr "type" "lea")
5132 (set_attr "mode" "SI")])
5133
5134 (define_insn "*adddi_1_rex64"
5135 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5136 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5137 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5138 (clobber (reg:CC FLAGS_REG))]
5139 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5140 {
5141 switch (get_attr_type (insn))
5142 {
5143 case TYPE_LEA:
5144 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5145 return "lea{q}\t{%a2, %0|%0, %a2}";
5146
5147 case TYPE_INCDEC:
5148 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5149 if (operands[2] == const1_rtx)
5150 return "inc{q}\t%0";
5151 else
5152 {
5153 gcc_assert (operands[2] == constm1_rtx);
5154 return "dec{q}\t%0";
5155 }
5156
5157 default:
5158 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5159
5160 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5161 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5162 if (CONST_INT_P (operands[2])
5163 /* Avoid overflows. */
5164 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5165 && (INTVAL (operands[2]) == 128
5166 || (INTVAL (operands[2]) < 0
5167 && INTVAL (operands[2]) != -128)))
5168 {
5169 operands[2] = GEN_INT (-INTVAL (operands[2]));
5170 return "sub{q}\t{%2, %0|%0, %2}";
5171 }
5172 return "add{q}\t{%2, %0|%0, %2}";
5173 }
5174 }
5175 [(set (attr "type")
5176 (cond [(eq_attr "alternative" "2")
5177 (const_string "lea")
5178 ; Current assemblers are broken and do not allow @GOTOFF in
5179 ; ought but a memory context.
5180 (match_operand:DI 2 "pic_symbolic_operand" "")
5181 (const_string "lea")
5182 (match_operand:DI 2 "incdec_operand" "")
5183 (const_string "incdec")
5184 ]
5185 (const_string "alu")))
5186 (set_attr "mode" "DI")])
5187
5188 ;; Convert lea to the lea pattern to avoid flags dependency.
5189 (define_split
5190 [(set (match_operand:DI 0 "register_operand" "")
5191 (plus:DI (match_operand:DI 1 "register_operand" "")
5192 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5193 (clobber (reg:CC FLAGS_REG))]
5194 "TARGET_64BIT && reload_completed
5195 && true_regnum (operands[0]) != true_regnum (operands[1])"
5196 [(set (match_dup 0)
5197 (plus:DI (match_dup 1)
5198 (match_dup 2)))]
5199 "")
5200
5201 (define_insn "*adddi_2_rex64"
5202 [(set (reg FLAGS_REG)
5203 (compare
5204 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5205 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5206 (const_int 0)))
5207 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5208 (plus:DI (match_dup 1) (match_dup 2)))]
5209 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5210 && ix86_binary_operator_ok (PLUS, DImode, operands)
5211 /* Current assemblers are broken and do not allow @GOTOFF in
5212 ought but a memory context. */
5213 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5214 {
5215 switch (get_attr_type (insn))
5216 {
5217 case TYPE_INCDEC:
5218 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5219 if (operands[2] == const1_rtx)
5220 return "inc{q}\t%0";
5221 else
5222 {
5223 gcc_assert (operands[2] == constm1_rtx);
5224 return "dec{q}\t%0";
5225 }
5226
5227 default:
5228 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5229 /* ???? We ought to handle there the 32bit case too
5230 - do we need new constraint? */
5231 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5232 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5233 if (CONST_INT_P (operands[2])
5234 /* Avoid overflows. */
5235 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5236 && (INTVAL (operands[2]) == 128
5237 || (INTVAL (operands[2]) < 0
5238 && INTVAL (operands[2]) != -128)))
5239 {
5240 operands[2] = GEN_INT (-INTVAL (operands[2]));
5241 return "sub{q}\t{%2, %0|%0, %2}";
5242 }
5243 return "add{q}\t{%2, %0|%0, %2}";
5244 }
5245 }
5246 [(set (attr "type")
5247 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5248 (const_string "incdec")
5249 (const_string "alu")))
5250 (set_attr "mode" "DI")])
5251
5252 (define_insn "*adddi_3_rex64"
5253 [(set (reg FLAGS_REG)
5254 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5255 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5256 (clobber (match_scratch:DI 0 "=r"))]
5257 "TARGET_64BIT
5258 && ix86_match_ccmode (insn, CCZmode)
5259 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5260 /* Current assemblers are broken and do not allow @GOTOFF in
5261 ought but a memory context. */
5262 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5263 {
5264 switch (get_attr_type (insn))
5265 {
5266 case TYPE_INCDEC:
5267 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5268 if (operands[2] == const1_rtx)
5269 return "inc{q}\t%0";
5270 else
5271 {
5272 gcc_assert (operands[2] == constm1_rtx);
5273 return "dec{q}\t%0";
5274 }
5275
5276 default:
5277 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5278 /* ???? We ought to handle there the 32bit case too
5279 - do we need new constraint? */
5280 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5281 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5282 if (CONST_INT_P (operands[2])
5283 /* Avoid overflows. */
5284 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5285 && (INTVAL (operands[2]) == 128
5286 || (INTVAL (operands[2]) < 0
5287 && INTVAL (operands[2]) != -128)))
5288 {
5289 operands[2] = GEN_INT (-INTVAL (operands[2]));
5290 return "sub{q}\t{%2, %0|%0, %2}";
5291 }
5292 return "add{q}\t{%2, %0|%0, %2}";
5293 }
5294 }
5295 [(set (attr "type")
5296 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5297 (const_string "incdec")
5298 (const_string "alu")))
5299 (set_attr "mode" "DI")])
5300
5301 ; For comparisons against 1, -1 and 128, we may generate better code
5302 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5303 ; is matched then. We can't accept general immediate, because for
5304 ; case of overflows, the result is messed up.
5305 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5306 ; when negated.
5307 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5308 ; only for comparisons not depending on it.
5309 (define_insn "*adddi_4_rex64"
5310 [(set (reg FLAGS_REG)
5311 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5312 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5313 (clobber (match_scratch:DI 0 "=rm"))]
5314 "TARGET_64BIT
5315 && ix86_match_ccmode (insn, CCGCmode)"
5316 {
5317 switch (get_attr_type (insn))
5318 {
5319 case TYPE_INCDEC:
5320 if (operands[2] == constm1_rtx)
5321 return "inc{q}\t%0";
5322 else
5323 {
5324 gcc_assert (operands[2] == const1_rtx);
5325 return "dec{q}\t%0";
5326 }
5327
5328 default:
5329 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5330 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5331 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5332 if ((INTVAL (operands[2]) == -128
5333 || (INTVAL (operands[2]) > 0
5334 && INTVAL (operands[2]) != 128))
5335 /* Avoid overflows. */
5336 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5337 return "sub{q}\t{%2, %0|%0, %2}";
5338 operands[2] = GEN_INT (-INTVAL (operands[2]));
5339 return "add{q}\t{%2, %0|%0, %2}";
5340 }
5341 }
5342 [(set (attr "type")
5343 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5344 (const_string "incdec")
5345 (const_string "alu")))
5346 (set_attr "mode" "DI")])
5347
5348 (define_insn "*adddi_5_rex64"
5349 [(set (reg FLAGS_REG)
5350 (compare
5351 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5352 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5353 (const_int 0)))
5354 (clobber (match_scratch:DI 0 "=r"))]
5355 "TARGET_64BIT
5356 && ix86_match_ccmode (insn, CCGOCmode)
5357 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5358 /* Current assemblers are broken and do not allow @GOTOFF in
5359 ought but a memory context. */
5360 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5361 {
5362 switch (get_attr_type (insn))
5363 {
5364 case TYPE_INCDEC:
5365 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5366 if (operands[2] == const1_rtx)
5367 return "inc{q}\t%0";
5368 else
5369 {
5370 gcc_assert (operands[2] == constm1_rtx);
5371 return "dec{q}\t%0";
5372 }
5373
5374 default:
5375 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5376 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5377 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5378 if (CONST_INT_P (operands[2])
5379 /* Avoid overflows. */
5380 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5381 && (INTVAL (operands[2]) == 128
5382 || (INTVAL (operands[2]) < 0
5383 && INTVAL (operands[2]) != -128)))
5384 {
5385 operands[2] = GEN_INT (-INTVAL (operands[2]));
5386 return "sub{q}\t{%2, %0|%0, %2}";
5387 }
5388 return "add{q}\t{%2, %0|%0, %2}";
5389 }
5390 }
5391 [(set (attr "type")
5392 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5393 (const_string "incdec")
5394 (const_string "alu")))
5395 (set_attr "mode" "DI")])
5396
5397
5398 (define_insn "*addsi_1"
5399 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5400 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5401 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5402 (clobber (reg:CC FLAGS_REG))]
5403 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5404 {
5405 switch (get_attr_type (insn))
5406 {
5407 case TYPE_LEA:
5408 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5409 return "lea{l}\t{%a2, %0|%0, %a2}";
5410
5411 case TYPE_INCDEC:
5412 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5413 if (operands[2] == const1_rtx)
5414 return "inc{l}\t%0";
5415 else
5416 {
5417 gcc_assert (operands[2] == constm1_rtx);
5418 return "dec{l}\t%0";
5419 }
5420
5421 default:
5422 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5423
5424 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5425 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5426 if (CONST_INT_P (operands[2])
5427 && (INTVAL (operands[2]) == 128
5428 || (INTVAL (operands[2]) < 0
5429 && INTVAL (operands[2]) != -128)))
5430 {
5431 operands[2] = GEN_INT (-INTVAL (operands[2]));
5432 return "sub{l}\t{%2, %0|%0, %2}";
5433 }
5434 return "add{l}\t{%2, %0|%0, %2}";
5435 }
5436 }
5437 [(set (attr "type")
5438 (cond [(eq_attr "alternative" "2")
5439 (const_string "lea")
5440 ; Current assemblers are broken and do not allow @GOTOFF in
5441 ; ought but a memory context.
5442 (match_operand:SI 2 "pic_symbolic_operand" "")
5443 (const_string "lea")
5444 (match_operand:SI 2 "incdec_operand" "")
5445 (const_string "incdec")
5446 ]
5447 (const_string "alu")))
5448 (set_attr "mode" "SI")])
5449
5450 ;; Convert lea to the lea pattern to avoid flags dependency.
5451 (define_split
5452 [(set (match_operand 0 "register_operand" "")
5453 (plus (match_operand 1 "register_operand" "")
5454 (match_operand 2 "nonmemory_operand" "")))
5455 (clobber (reg:CC FLAGS_REG))]
5456 "reload_completed
5457 && true_regnum (operands[0]) != true_regnum (operands[1])"
5458 [(const_int 0)]
5459 {
5460 rtx pat;
5461 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5462 may confuse gen_lowpart. */
5463 if (GET_MODE (operands[0]) != Pmode)
5464 {
5465 operands[1] = gen_lowpart (Pmode, operands[1]);
5466 operands[2] = gen_lowpart (Pmode, operands[2]);
5467 }
5468 operands[0] = gen_lowpart (SImode, operands[0]);
5469 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5470 if (Pmode != SImode)
5471 pat = gen_rtx_SUBREG (SImode, pat, 0);
5472 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5473 DONE;
5474 })
5475
5476 ;; It may seem that nonimmediate operand is proper one for operand 1.
5477 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5478 ;; we take care in ix86_binary_operator_ok to not allow two memory
5479 ;; operands so proper swapping will be done in reload. This allow
5480 ;; patterns constructed from addsi_1 to match.
5481 (define_insn "addsi_1_zext"
5482 [(set (match_operand:DI 0 "register_operand" "=r,r")
5483 (zero_extend:DI
5484 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5485 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5486 (clobber (reg:CC FLAGS_REG))]
5487 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5488 {
5489 switch (get_attr_type (insn))
5490 {
5491 case TYPE_LEA:
5492 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5493 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5494
5495 case TYPE_INCDEC:
5496 if (operands[2] == const1_rtx)
5497 return "inc{l}\t%k0";
5498 else
5499 {
5500 gcc_assert (operands[2] == constm1_rtx);
5501 return "dec{l}\t%k0";
5502 }
5503
5504 default:
5505 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5506 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5507 if (CONST_INT_P (operands[2])
5508 && (INTVAL (operands[2]) == 128
5509 || (INTVAL (operands[2]) < 0
5510 && INTVAL (operands[2]) != -128)))
5511 {
5512 operands[2] = GEN_INT (-INTVAL (operands[2]));
5513 return "sub{l}\t{%2, %k0|%k0, %2}";
5514 }
5515 return "add{l}\t{%2, %k0|%k0, %2}";
5516 }
5517 }
5518 [(set (attr "type")
5519 (cond [(eq_attr "alternative" "1")
5520 (const_string "lea")
5521 ; Current assemblers are broken and do not allow @GOTOFF in
5522 ; ought but a memory context.
5523 (match_operand:SI 2 "pic_symbolic_operand" "")
5524 (const_string "lea")
5525 (match_operand:SI 2 "incdec_operand" "")
5526 (const_string "incdec")
5527 ]
5528 (const_string "alu")))
5529 (set_attr "mode" "SI")])
5530
5531 ;; Convert lea to the lea pattern to avoid flags dependency.
5532 (define_split
5533 [(set (match_operand:DI 0 "register_operand" "")
5534 (zero_extend:DI
5535 (plus:SI (match_operand:SI 1 "register_operand" "")
5536 (match_operand:SI 2 "nonmemory_operand" ""))))
5537 (clobber (reg:CC FLAGS_REG))]
5538 "TARGET_64BIT && reload_completed
5539 && true_regnum (operands[0]) != true_regnum (operands[1])"
5540 [(set (match_dup 0)
5541 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5542 {
5543 operands[1] = gen_lowpart (Pmode, operands[1]);
5544 operands[2] = gen_lowpart (Pmode, operands[2]);
5545 })
5546
5547 (define_insn "*addsi_2"
5548 [(set (reg FLAGS_REG)
5549 (compare
5550 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5551 (match_operand:SI 2 "general_operand" "rmni,rni"))
5552 (const_int 0)))
5553 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5554 (plus:SI (match_dup 1) (match_dup 2)))]
5555 "ix86_match_ccmode (insn, CCGOCmode)
5556 && ix86_binary_operator_ok (PLUS, SImode, operands)
5557 /* Current assemblers are broken and do not allow @GOTOFF in
5558 ought but a memory context. */
5559 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5560 {
5561 switch (get_attr_type (insn))
5562 {
5563 case TYPE_INCDEC:
5564 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5565 if (operands[2] == const1_rtx)
5566 return "inc{l}\t%0";
5567 else
5568 {
5569 gcc_assert (operands[2] == constm1_rtx);
5570 return "dec{l}\t%0";
5571 }
5572
5573 default:
5574 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5575 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5576 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5577 if (CONST_INT_P (operands[2])
5578 && (INTVAL (operands[2]) == 128
5579 || (INTVAL (operands[2]) < 0
5580 && INTVAL (operands[2]) != -128)))
5581 {
5582 operands[2] = GEN_INT (-INTVAL (operands[2]));
5583 return "sub{l}\t{%2, %0|%0, %2}";
5584 }
5585 return "add{l}\t{%2, %0|%0, %2}";
5586 }
5587 }
5588 [(set (attr "type")
5589 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5590 (const_string "incdec")
5591 (const_string "alu")))
5592 (set_attr "mode" "SI")])
5593
5594 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5595 (define_insn "*addsi_2_zext"
5596 [(set (reg FLAGS_REG)
5597 (compare
5598 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5599 (match_operand:SI 2 "general_operand" "rmni"))
5600 (const_int 0)))
5601 (set (match_operand:DI 0 "register_operand" "=r")
5602 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5603 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5604 && ix86_binary_operator_ok (PLUS, SImode, operands)
5605 /* Current assemblers are broken and do not allow @GOTOFF in
5606 ought but a memory context. */
5607 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5608 {
5609 switch (get_attr_type (insn))
5610 {
5611 case TYPE_INCDEC:
5612 if (operands[2] == const1_rtx)
5613 return "inc{l}\t%k0";
5614 else
5615 {
5616 gcc_assert (operands[2] == constm1_rtx);
5617 return "dec{l}\t%k0";
5618 }
5619
5620 default:
5621 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5622 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5623 if (CONST_INT_P (operands[2])
5624 && (INTVAL (operands[2]) == 128
5625 || (INTVAL (operands[2]) < 0
5626 && INTVAL (operands[2]) != -128)))
5627 {
5628 operands[2] = GEN_INT (-INTVAL (operands[2]));
5629 return "sub{l}\t{%2, %k0|%k0, %2}";
5630 }
5631 return "add{l}\t{%2, %k0|%k0, %2}";
5632 }
5633 }
5634 [(set (attr "type")
5635 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5636 (const_string "incdec")
5637 (const_string "alu")))
5638 (set_attr "mode" "SI")])
5639
5640 (define_insn "*addsi_3"
5641 [(set (reg FLAGS_REG)
5642 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5643 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5644 (clobber (match_scratch:SI 0 "=r"))]
5645 "ix86_match_ccmode (insn, CCZmode)
5646 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5647 /* Current assemblers are broken and do not allow @GOTOFF in
5648 ought but a memory context. */
5649 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5650 {
5651 switch (get_attr_type (insn))
5652 {
5653 case TYPE_INCDEC:
5654 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5655 if (operands[2] == const1_rtx)
5656 return "inc{l}\t%0";
5657 else
5658 {
5659 gcc_assert (operands[2] == constm1_rtx);
5660 return "dec{l}\t%0";
5661 }
5662
5663 default:
5664 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5665 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5666 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5667 if (CONST_INT_P (operands[2])
5668 && (INTVAL (operands[2]) == 128
5669 || (INTVAL (operands[2]) < 0
5670 && INTVAL (operands[2]) != -128)))
5671 {
5672 operands[2] = GEN_INT (-INTVAL (operands[2]));
5673 return "sub{l}\t{%2, %0|%0, %2}";
5674 }
5675 return "add{l}\t{%2, %0|%0, %2}";
5676 }
5677 }
5678 [(set (attr "type")
5679 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5680 (const_string "incdec")
5681 (const_string "alu")))
5682 (set_attr "mode" "SI")])
5683
5684 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5685 (define_insn "*addsi_3_zext"
5686 [(set (reg FLAGS_REG)
5687 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5688 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5689 (set (match_operand:DI 0 "register_operand" "=r")
5690 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5691 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5692 && ix86_binary_operator_ok (PLUS, SImode, operands)
5693 /* Current assemblers are broken and do not allow @GOTOFF in
5694 ought but a memory context. */
5695 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5696 {
5697 switch (get_attr_type (insn))
5698 {
5699 case TYPE_INCDEC:
5700 if (operands[2] == const1_rtx)
5701 return "inc{l}\t%k0";
5702 else
5703 {
5704 gcc_assert (operands[2] == constm1_rtx);
5705 return "dec{l}\t%k0";
5706 }
5707
5708 default:
5709 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5710 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5711 if (CONST_INT_P (operands[2])
5712 && (INTVAL (operands[2]) == 128
5713 || (INTVAL (operands[2]) < 0
5714 && INTVAL (operands[2]) != -128)))
5715 {
5716 operands[2] = GEN_INT (-INTVAL (operands[2]));
5717 return "sub{l}\t{%2, %k0|%k0, %2}";
5718 }
5719 return "add{l}\t{%2, %k0|%k0, %2}";
5720 }
5721 }
5722 [(set (attr "type")
5723 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5724 (const_string "incdec")
5725 (const_string "alu")))
5726 (set_attr "mode" "SI")])
5727
5728 ; For comparisons against 1, -1 and 128, we may generate better code
5729 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5730 ; is matched then. We can't accept general immediate, because for
5731 ; case of overflows, the result is messed up.
5732 ; This pattern also don't hold of 0x80000000, since the value overflows
5733 ; when negated.
5734 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5735 ; only for comparisons not depending on it.
5736 (define_insn "*addsi_4"
5737 [(set (reg FLAGS_REG)
5738 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5739 (match_operand:SI 2 "const_int_operand" "n")))
5740 (clobber (match_scratch:SI 0 "=rm"))]
5741 "ix86_match_ccmode (insn, CCGCmode)
5742 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5743 {
5744 switch (get_attr_type (insn))
5745 {
5746 case TYPE_INCDEC:
5747 if (operands[2] == constm1_rtx)
5748 return "inc{l}\t%0";
5749 else
5750 {
5751 gcc_assert (operands[2] == const1_rtx);
5752 return "dec{l}\t%0";
5753 }
5754
5755 default:
5756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5757 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5758 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5759 if ((INTVAL (operands[2]) == -128
5760 || (INTVAL (operands[2]) > 0
5761 && INTVAL (operands[2]) != 128)))
5762 return "sub{l}\t{%2, %0|%0, %2}";
5763 operands[2] = GEN_INT (-INTVAL (operands[2]));
5764 return "add{l}\t{%2, %0|%0, %2}";
5765 }
5766 }
5767 [(set (attr "type")
5768 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5769 (const_string "incdec")
5770 (const_string "alu")))
5771 (set_attr "mode" "SI")])
5772
5773 (define_insn "*addsi_5"
5774 [(set (reg FLAGS_REG)
5775 (compare
5776 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5777 (match_operand:SI 2 "general_operand" "rmni"))
5778 (const_int 0)))
5779 (clobber (match_scratch:SI 0 "=r"))]
5780 "ix86_match_ccmode (insn, CCGOCmode)
5781 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5782 /* Current assemblers are broken and do not allow @GOTOFF in
5783 ought but a memory context. */
5784 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5785 {
5786 switch (get_attr_type (insn))
5787 {
5788 case TYPE_INCDEC:
5789 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5790 if (operands[2] == const1_rtx)
5791 return "inc{l}\t%0";
5792 else
5793 {
5794 gcc_assert (operands[2] == constm1_rtx);
5795 return "dec{l}\t%0";
5796 }
5797
5798 default:
5799 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5800 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5801 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5802 if (CONST_INT_P (operands[2])
5803 && (INTVAL (operands[2]) == 128
5804 || (INTVAL (operands[2]) < 0
5805 && INTVAL (operands[2]) != -128)))
5806 {
5807 operands[2] = GEN_INT (-INTVAL (operands[2]));
5808 return "sub{l}\t{%2, %0|%0, %2}";
5809 }
5810 return "add{l}\t{%2, %0|%0, %2}";
5811 }
5812 }
5813 [(set (attr "type")
5814 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5815 (const_string "incdec")
5816 (const_string "alu")))
5817 (set_attr "mode" "SI")])
5818
5819 (define_expand "addhi3"
5820 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5821 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5822 (match_operand:HI 2 "general_operand" "")))
5823 (clobber (reg:CC FLAGS_REG))])]
5824 "TARGET_HIMODE_MATH"
5825 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5826
5827 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5828 ;; type optimizations enabled by define-splits. This is not important
5829 ;; for PII, and in fact harmful because of partial register stalls.
5830
5831 (define_insn "*addhi_1_lea"
5832 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5833 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5834 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5835 (clobber (reg:CC FLAGS_REG))]
5836 "!TARGET_PARTIAL_REG_STALL
5837 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5838 {
5839 switch (get_attr_type (insn))
5840 {
5841 case TYPE_LEA:
5842 return "#";
5843 case TYPE_INCDEC:
5844 if (operands[2] == const1_rtx)
5845 return "inc{w}\t%0";
5846 else
5847 {
5848 gcc_assert (operands[2] == constm1_rtx);
5849 return "dec{w}\t%0";
5850 }
5851
5852 default:
5853 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5854 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5855 if (CONST_INT_P (operands[2])
5856 && (INTVAL (operands[2]) == 128
5857 || (INTVAL (operands[2]) < 0
5858 && INTVAL (operands[2]) != -128)))
5859 {
5860 operands[2] = GEN_INT (-INTVAL (operands[2]));
5861 return "sub{w}\t{%2, %0|%0, %2}";
5862 }
5863 return "add{w}\t{%2, %0|%0, %2}";
5864 }
5865 }
5866 [(set (attr "type")
5867 (if_then_else (eq_attr "alternative" "2")
5868 (const_string "lea")
5869 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5870 (const_string "incdec")
5871 (const_string "alu"))))
5872 (set_attr "mode" "HI,HI,SI")])
5873
5874 (define_insn "*addhi_1"
5875 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5876 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5877 (match_operand:HI 2 "general_operand" "ri,rm")))
5878 (clobber (reg:CC FLAGS_REG))]
5879 "TARGET_PARTIAL_REG_STALL
5880 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5881 {
5882 switch (get_attr_type (insn))
5883 {
5884 case TYPE_INCDEC:
5885 if (operands[2] == const1_rtx)
5886 return "inc{w}\t%0";
5887 else
5888 {
5889 gcc_assert (operands[2] == constm1_rtx);
5890 return "dec{w}\t%0";
5891 }
5892
5893 default:
5894 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5895 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5896 if (CONST_INT_P (operands[2])
5897 && (INTVAL (operands[2]) == 128
5898 || (INTVAL (operands[2]) < 0
5899 && INTVAL (operands[2]) != -128)))
5900 {
5901 operands[2] = GEN_INT (-INTVAL (operands[2]));
5902 return "sub{w}\t{%2, %0|%0, %2}";
5903 }
5904 return "add{w}\t{%2, %0|%0, %2}";
5905 }
5906 }
5907 [(set (attr "type")
5908 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5909 (const_string "incdec")
5910 (const_string "alu")))
5911 (set_attr "mode" "HI")])
5912
5913 (define_insn "*addhi_2"
5914 [(set (reg FLAGS_REG)
5915 (compare
5916 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5917 (match_operand:HI 2 "general_operand" "rmni,rni"))
5918 (const_int 0)))
5919 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5920 (plus:HI (match_dup 1) (match_dup 2)))]
5921 "ix86_match_ccmode (insn, CCGOCmode)
5922 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5923 {
5924 switch (get_attr_type (insn))
5925 {
5926 case TYPE_INCDEC:
5927 if (operands[2] == const1_rtx)
5928 return "inc{w}\t%0";
5929 else
5930 {
5931 gcc_assert (operands[2] == constm1_rtx);
5932 return "dec{w}\t%0";
5933 }
5934
5935 default:
5936 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5937 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5938 if (CONST_INT_P (operands[2])
5939 && (INTVAL (operands[2]) == 128
5940 || (INTVAL (operands[2]) < 0
5941 && INTVAL (operands[2]) != -128)))
5942 {
5943 operands[2] = GEN_INT (-INTVAL (operands[2]));
5944 return "sub{w}\t{%2, %0|%0, %2}";
5945 }
5946 return "add{w}\t{%2, %0|%0, %2}";
5947 }
5948 }
5949 [(set (attr "type")
5950 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5951 (const_string "incdec")
5952 (const_string "alu")))
5953 (set_attr "mode" "HI")])
5954
5955 (define_insn "*addhi_3"
5956 [(set (reg FLAGS_REG)
5957 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5958 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5959 (clobber (match_scratch:HI 0 "=r"))]
5960 "ix86_match_ccmode (insn, CCZmode)
5961 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5962 {
5963 switch (get_attr_type (insn))
5964 {
5965 case TYPE_INCDEC:
5966 if (operands[2] == const1_rtx)
5967 return "inc{w}\t%0";
5968 else
5969 {
5970 gcc_assert (operands[2] == constm1_rtx);
5971 return "dec{w}\t%0";
5972 }
5973
5974 default:
5975 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5976 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5977 if (CONST_INT_P (operands[2])
5978 && (INTVAL (operands[2]) == 128
5979 || (INTVAL (operands[2]) < 0
5980 && INTVAL (operands[2]) != -128)))
5981 {
5982 operands[2] = GEN_INT (-INTVAL (operands[2]));
5983 return "sub{w}\t{%2, %0|%0, %2}";
5984 }
5985 return "add{w}\t{%2, %0|%0, %2}";
5986 }
5987 }
5988 [(set (attr "type")
5989 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5990 (const_string "incdec")
5991 (const_string "alu")))
5992 (set_attr "mode" "HI")])
5993
5994 ; See comments above addsi_4 for details.
5995 (define_insn "*addhi_4"
5996 [(set (reg FLAGS_REG)
5997 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5998 (match_operand:HI 2 "const_int_operand" "n")))
5999 (clobber (match_scratch:HI 0 "=rm"))]
6000 "ix86_match_ccmode (insn, CCGCmode)
6001 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6002 {
6003 switch (get_attr_type (insn))
6004 {
6005 case TYPE_INCDEC:
6006 if (operands[2] == constm1_rtx)
6007 return "inc{w}\t%0";
6008 else
6009 {
6010 gcc_assert (operands[2] == const1_rtx);
6011 return "dec{w}\t%0";
6012 }
6013
6014 default:
6015 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6016 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6017 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6018 if ((INTVAL (operands[2]) == -128
6019 || (INTVAL (operands[2]) > 0
6020 && INTVAL (operands[2]) != 128)))
6021 return "sub{w}\t{%2, %0|%0, %2}";
6022 operands[2] = GEN_INT (-INTVAL (operands[2]));
6023 return "add{w}\t{%2, %0|%0, %2}";
6024 }
6025 }
6026 [(set (attr "type")
6027 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6028 (const_string "incdec")
6029 (const_string "alu")))
6030 (set_attr "mode" "SI")])
6031
6032
6033 (define_insn "*addhi_5"
6034 [(set (reg FLAGS_REG)
6035 (compare
6036 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6037 (match_operand:HI 2 "general_operand" "rmni"))
6038 (const_int 0)))
6039 (clobber (match_scratch:HI 0 "=r"))]
6040 "ix86_match_ccmode (insn, CCGOCmode)
6041 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6042 {
6043 switch (get_attr_type (insn))
6044 {
6045 case TYPE_INCDEC:
6046 if (operands[2] == const1_rtx)
6047 return "inc{w}\t%0";
6048 else
6049 {
6050 gcc_assert (operands[2] == constm1_rtx);
6051 return "dec{w}\t%0";
6052 }
6053
6054 default:
6055 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6056 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6057 if (CONST_INT_P (operands[2])
6058 && (INTVAL (operands[2]) == 128
6059 || (INTVAL (operands[2]) < 0
6060 && INTVAL (operands[2]) != -128)))
6061 {
6062 operands[2] = GEN_INT (-INTVAL (operands[2]));
6063 return "sub{w}\t{%2, %0|%0, %2}";
6064 }
6065 return "add{w}\t{%2, %0|%0, %2}";
6066 }
6067 }
6068 [(set (attr "type")
6069 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6070 (const_string "incdec")
6071 (const_string "alu")))
6072 (set_attr "mode" "HI")])
6073
6074 (define_expand "addqi3"
6075 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6076 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6077 (match_operand:QI 2 "general_operand" "")))
6078 (clobber (reg:CC FLAGS_REG))])]
6079 "TARGET_QIMODE_MATH"
6080 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6081
6082 ;; %%% Potential partial reg stall on alternative 2. What to do?
6083 (define_insn "*addqi_1_lea"
6084 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6085 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6086 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6087 (clobber (reg:CC FLAGS_REG))]
6088 "!TARGET_PARTIAL_REG_STALL
6089 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6090 {
6091 int widen = (which_alternative == 2);
6092 switch (get_attr_type (insn))
6093 {
6094 case TYPE_LEA:
6095 return "#";
6096 case TYPE_INCDEC:
6097 if (operands[2] == const1_rtx)
6098 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6099 else
6100 {
6101 gcc_assert (operands[2] == constm1_rtx);
6102 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6103 }
6104
6105 default:
6106 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6107 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6108 if (CONST_INT_P (operands[2])
6109 && (INTVAL (operands[2]) == 128
6110 || (INTVAL (operands[2]) < 0
6111 && INTVAL (operands[2]) != -128)))
6112 {
6113 operands[2] = GEN_INT (-INTVAL (operands[2]));
6114 if (widen)
6115 return "sub{l}\t{%2, %k0|%k0, %2}";
6116 else
6117 return "sub{b}\t{%2, %0|%0, %2}";
6118 }
6119 if (widen)
6120 return "add{l}\t{%k2, %k0|%k0, %k2}";
6121 else
6122 return "add{b}\t{%2, %0|%0, %2}";
6123 }
6124 }
6125 [(set (attr "type")
6126 (if_then_else (eq_attr "alternative" "3")
6127 (const_string "lea")
6128 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6129 (const_string "incdec")
6130 (const_string "alu"))))
6131 (set_attr "mode" "QI,QI,SI,SI")])
6132
6133 (define_insn "*addqi_1"
6134 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6135 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6136 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6137 (clobber (reg:CC FLAGS_REG))]
6138 "TARGET_PARTIAL_REG_STALL
6139 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6140 {
6141 int widen = (which_alternative == 2);
6142 switch (get_attr_type (insn))
6143 {
6144 case TYPE_INCDEC:
6145 if (operands[2] == const1_rtx)
6146 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6147 else
6148 {
6149 gcc_assert (operands[2] == constm1_rtx);
6150 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6151 }
6152
6153 default:
6154 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6155 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6156 if (CONST_INT_P (operands[2])
6157 && (INTVAL (operands[2]) == 128
6158 || (INTVAL (operands[2]) < 0
6159 && INTVAL (operands[2]) != -128)))
6160 {
6161 operands[2] = GEN_INT (-INTVAL (operands[2]));
6162 if (widen)
6163 return "sub{l}\t{%2, %k0|%k0, %2}";
6164 else
6165 return "sub{b}\t{%2, %0|%0, %2}";
6166 }
6167 if (widen)
6168 return "add{l}\t{%k2, %k0|%k0, %k2}";
6169 else
6170 return "add{b}\t{%2, %0|%0, %2}";
6171 }
6172 }
6173 [(set (attr "type")
6174 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6175 (const_string "incdec")
6176 (const_string "alu")))
6177 (set_attr "mode" "QI,QI,SI")])
6178
6179 (define_insn "*addqi_1_slp"
6180 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6181 (plus:QI (match_dup 0)
6182 (match_operand:QI 1 "general_operand" "qn,qnm")))
6183 (clobber (reg:CC FLAGS_REG))]
6184 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6185 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6186 {
6187 switch (get_attr_type (insn))
6188 {
6189 case TYPE_INCDEC:
6190 if (operands[1] == const1_rtx)
6191 return "inc{b}\t%0";
6192 else
6193 {
6194 gcc_assert (operands[1] == constm1_rtx);
6195 return "dec{b}\t%0";
6196 }
6197
6198 default:
6199 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6200 if (CONST_INT_P (operands[1])
6201 && INTVAL (operands[1]) < 0)
6202 {
6203 operands[1] = GEN_INT (-INTVAL (operands[1]));
6204 return "sub{b}\t{%1, %0|%0, %1}";
6205 }
6206 return "add{b}\t{%1, %0|%0, %1}";
6207 }
6208 }
6209 [(set (attr "type")
6210 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6211 (const_string "incdec")
6212 (const_string "alu1")))
6213 (set (attr "memory")
6214 (if_then_else (match_operand 1 "memory_operand" "")
6215 (const_string "load")
6216 (const_string "none")))
6217 (set_attr "mode" "QI")])
6218
6219 (define_insn "*addqi_2"
6220 [(set (reg FLAGS_REG)
6221 (compare
6222 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6223 (match_operand:QI 2 "general_operand" "qmni,qni"))
6224 (const_int 0)))
6225 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6226 (plus:QI (match_dup 1) (match_dup 2)))]
6227 "ix86_match_ccmode (insn, CCGOCmode)
6228 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6229 {
6230 switch (get_attr_type (insn))
6231 {
6232 case TYPE_INCDEC:
6233 if (operands[2] == const1_rtx)
6234 return "inc{b}\t%0";
6235 else
6236 {
6237 gcc_assert (operands[2] == constm1_rtx
6238 || (CONST_INT_P (operands[2])
6239 && INTVAL (operands[2]) == 255));
6240 return "dec{b}\t%0";
6241 }
6242
6243 default:
6244 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6245 if (CONST_INT_P (operands[2])
6246 && INTVAL (operands[2]) < 0)
6247 {
6248 operands[2] = GEN_INT (-INTVAL (operands[2]));
6249 return "sub{b}\t{%2, %0|%0, %2}";
6250 }
6251 return "add{b}\t{%2, %0|%0, %2}";
6252 }
6253 }
6254 [(set (attr "type")
6255 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6256 (const_string "incdec")
6257 (const_string "alu")))
6258 (set_attr "mode" "QI")])
6259
6260 (define_insn "*addqi_3"
6261 [(set (reg FLAGS_REG)
6262 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6263 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6264 (clobber (match_scratch:QI 0 "=q"))]
6265 "ix86_match_ccmode (insn, CCZmode)
6266 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6267 {
6268 switch (get_attr_type (insn))
6269 {
6270 case TYPE_INCDEC:
6271 if (operands[2] == const1_rtx)
6272 return "inc{b}\t%0";
6273 else
6274 {
6275 gcc_assert (operands[2] == constm1_rtx
6276 || (CONST_INT_P (operands[2])
6277 && INTVAL (operands[2]) == 255));
6278 return "dec{b}\t%0";
6279 }
6280
6281 default:
6282 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6283 if (CONST_INT_P (operands[2])
6284 && INTVAL (operands[2]) < 0)
6285 {
6286 operands[2] = GEN_INT (-INTVAL (operands[2]));
6287 return "sub{b}\t{%2, %0|%0, %2}";
6288 }
6289 return "add{b}\t{%2, %0|%0, %2}";
6290 }
6291 }
6292 [(set (attr "type")
6293 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6294 (const_string "incdec")
6295 (const_string "alu")))
6296 (set_attr "mode" "QI")])
6297
6298 ; See comments above addsi_4 for details.
6299 (define_insn "*addqi_4"
6300 [(set (reg FLAGS_REG)
6301 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6302 (match_operand:QI 2 "const_int_operand" "n")))
6303 (clobber (match_scratch:QI 0 "=qm"))]
6304 "ix86_match_ccmode (insn, CCGCmode)
6305 && (INTVAL (operands[2]) & 0xff) != 0x80"
6306 {
6307 switch (get_attr_type (insn))
6308 {
6309 case TYPE_INCDEC:
6310 if (operands[2] == constm1_rtx
6311 || (CONST_INT_P (operands[2])
6312 && INTVAL (operands[2]) == 255))
6313 return "inc{b}\t%0";
6314 else
6315 {
6316 gcc_assert (operands[2] == const1_rtx);
6317 return "dec{b}\t%0";
6318 }
6319
6320 default:
6321 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6322 if (INTVAL (operands[2]) < 0)
6323 {
6324 operands[2] = GEN_INT (-INTVAL (operands[2]));
6325 return "add{b}\t{%2, %0|%0, %2}";
6326 }
6327 return "sub{b}\t{%2, %0|%0, %2}";
6328 }
6329 }
6330 [(set (attr "type")
6331 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6332 (const_string "incdec")
6333 (const_string "alu")))
6334 (set_attr "mode" "QI")])
6335
6336
6337 (define_insn "*addqi_5"
6338 [(set (reg FLAGS_REG)
6339 (compare
6340 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6341 (match_operand:QI 2 "general_operand" "qmni"))
6342 (const_int 0)))
6343 (clobber (match_scratch:QI 0 "=q"))]
6344 "ix86_match_ccmode (insn, CCGOCmode)
6345 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6346 {
6347 switch (get_attr_type (insn))
6348 {
6349 case TYPE_INCDEC:
6350 if (operands[2] == const1_rtx)
6351 return "inc{b}\t%0";
6352 else
6353 {
6354 gcc_assert (operands[2] == constm1_rtx
6355 || (CONST_INT_P (operands[2])
6356 && INTVAL (operands[2]) == 255));
6357 return "dec{b}\t%0";
6358 }
6359
6360 default:
6361 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6362 if (CONST_INT_P (operands[2])
6363 && INTVAL (operands[2]) < 0)
6364 {
6365 operands[2] = GEN_INT (-INTVAL (operands[2]));
6366 return "sub{b}\t{%2, %0|%0, %2}";
6367 }
6368 return "add{b}\t{%2, %0|%0, %2}";
6369 }
6370 }
6371 [(set (attr "type")
6372 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6373 (const_string "incdec")
6374 (const_string "alu")))
6375 (set_attr "mode" "QI")])
6376
6377
6378 (define_insn "addqi_ext_1"
6379 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6380 (const_int 8)
6381 (const_int 8))
6382 (plus:SI
6383 (zero_extract:SI
6384 (match_operand 1 "ext_register_operand" "0")
6385 (const_int 8)
6386 (const_int 8))
6387 (match_operand:QI 2 "general_operand" "Qmn")))
6388 (clobber (reg:CC FLAGS_REG))]
6389 "!TARGET_64BIT"
6390 {
6391 switch (get_attr_type (insn))
6392 {
6393 case TYPE_INCDEC:
6394 if (operands[2] == const1_rtx)
6395 return "inc{b}\t%h0";
6396 else
6397 {
6398 gcc_assert (operands[2] == constm1_rtx
6399 || (CONST_INT_P (operands[2])
6400 && INTVAL (operands[2]) == 255));
6401 return "dec{b}\t%h0";
6402 }
6403
6404 default:
6405 return "add{b}\t{%2, %h0|%h0, %2}";
6406 }
6407 }
6408 [(set (attr "type")
6409 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6410 (const_string "incdec")
6411 (const_string "alu")))
6412 (set_attr "mode" "QI")])
6413
6414 (define_insn "*addqi_ext_1_rex64"
6415 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6416 (const_int 8)
6417 (const_int 8))
6418 (plus:SI
6419 (zero_extract:SI
6420 (match_operand 1 "ext_register_operand" "0")
6421 (const_int 8)
6422 (const_int 8))
6423 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6424 (clobber (reg:CC FLAGS_REG))]
6425 "TARGET_64BIT"
6426 {
6427 switch (get_attr_type (insn))
6428 {
6429 case TYPE_INCDEC:
6430 if (operands[2] == const1_rtx)
6431 return "inc{b}\t%h0";
6432 else
6433 {
6434 gcc_assert (operands[2] == constm1_rtx
6435 || (CONST_INT_P (operands[2])
6436 && INTVAL (operands[2]) == 255));
6437 return "dec{b}\t%h0";
6438 }
6439
6440 default:
6441 return "add{b}\t{%2, %h0|%h0, %2}";
6442 }
6443 }
6444 [(set (attr "type")
6445 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6446 (const_string "incdec")
6447 (const_string "alu")))
6448 (set_attr "mode" "QI")])
6449
6450 (define_insn "*addqi_ext_2"
6451 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6452 (const_int 8)
6453 (const_int 8))
6454 (plus:SI
6455 (zero_extract:SI
6456 (match_operand 1 "ext_register_operand" "%0")
6457 (const_int 8)
6458 (const_int 8))
6459 (zero_extract:SI
6460 (match_operand 2 "ext_register_operand" "Q")
6461 (const_int 8)
6462 (const_int 8))))
6463 (clobber (reg:CC FLAGS_REG))]
6464 ""
6465 "add{b}\t{%h2, %h0|%h0, %h2}"
6466 [(set_attr "type" "alu")
6467 (set_attr "mode" "QI")])
6468
6469 ;; The patterns that match these are at the end of this file.
6470
6471 (define_expand "addxf3"
6472 [(set (match_operand:XF 0 "register_operand" "")
6473 (plus:XF (match_operand:XF 1 "register_operand" "")
6474 (match_operand:XF 2 "register_operand" "")))]
6475 "TARGET_80387"
6476 "")
6477
6478 (define_expand "adddf3"
6479 [(set (match_operand:DF 0 "register_operand" "")
6480 (plus:DF (match_operand:DF 1 "register_operand" "")
6481 (match_operand:DF 2 "nonimmediate_operand" "")))]
6482 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6483 "")
6484
6485 (define_expand "addsf3"
6486 [(set (match_operand:SF 0 "register_operand" "")
6487 (plus:SF (match_operand:SF 1 "register_operand" "")
6488 (match_operand:SF 2 "nonimmediate_operand" "")))]
6489 "TARGET_80387 || TARGET_SSE_MATH"
6490 "")
6491 \f
6492 ;; Subtract instructions
6493
6494 ;; %%% splits for subditi3
6495
6496 (define_expand "subti3"
6497 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6498 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6499 (match_operand:TI 2 "x86_64_general_operand" "")))
6500 (clobber (reg:CC FLAGS_REG))])]
6501 "TARGET_64BIT"
6502 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6503
6504 (define_insn "*subti3_1"
6505 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6506 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6507 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6508 (clobber (reg:CC FLAGS_REG))]
6509 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6510 "#")
6511
6512 (define_split
6513 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6514 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6515 (match_operand:TI 2 "x86_64_general_operand" "")))
6516 (clobber (reg:CC FLAGS_REG))]
6517 "TARGET_64BIT && reload_completed"
6518 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6519 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6520 (parallel [(set (match_dup 3)
6521 (minus:DI (match_dup 4)
6522 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6523 (match_dup 5))))
6524 (clobber (reg:CC FLAGS_REG))])]
6525 "split_ti (operands+0, 1, operands+0, operands+3);
6526 split_ti (operands+1, 1, operands+1, operands+4);
6527 split_ti (operands+2, 1, operands+2, operands+5);")
6528
6529 ;; %%% splits for subsidi3
6530
6531 (define_expand "subdi3"
6532 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6533 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6534 (match_operand:DI 2 "x86_64_general_operand" "")))
6535 (clobber (reg:CC FLAGS_REG))])]
6536 ""
6537 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6538
6539 (define_insn "*subdi3_1"
6540 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6541 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6542 (match_operand:DI 2 "general_operand" "roiF,riF")))
6543 (clobber (reg:CC FLAGS_REG))]
6544 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6545 "#")
6546
6547 (define_split
6548 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6549 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6550 (match_operand:DI 2 "general_operand" "")))
6551 (clobber (reg:CC FLAGS_REG))]
6552 "!TARGET_64BIT && reload_completed"
6553 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6554 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6555 (parallel [(set (match_dup 3)
6556 (minus:SI (match_dup 4)
6557 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6558 (match_dup 5))))
6559 (clobber (reg:CC FLAGS_REG))])]
6560 "split_di (operands+0, 1, operands+0, operands+3);
6561 split_di (operands+1, 1, operands+1, operands+4);
6562 split_di (operands+2, 1, operands+2, operands+5);")
6563
6564 (define_insn "subdi3_carry_rex64"
6565 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6566 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6567 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6568 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6569 (clobber (reg:CC FLAGS_REG))]
6570 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6571 "sbb{q}\t{%2, %0|%0, %2}"
6572 [(set_attr "type" "alu")
6573 (set_attr "pent_pair" "pu")
6574 (set_attr "mode" "DI")])
6575
6576 (define_insn "*subdi_1_rex64"
6577 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6578 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6579 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6580 (clobber (reg:CC FLAGS_REG))]
6581 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6582 "sub{q}\t{%2, %0|%0, %2}"
6583 [(set_attr "type" "alu")
6584 (set_attr "mode" "DI")])
6585
6586 (define_insn "*subdi_2_rex64"
6587 [(set (reg FLAGS_REG)
6588 (compare
6589 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6590 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6591 (const_int 0)))
6592 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6593 (minus:DI (match_dup 1) (match_dup 2)))]
6594 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6595 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6596 "sub{q}\t{%2, %0|%0, %2}"
6597 [(set_attr "type" "alu")
6598 (set_attr "mode" "DI")])
6599
6600 (define_insn "*subdi_3_rex63"
6601 [(set (reg FLAGS_REG)
6602 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6603 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6604 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6605 (minus:DI (match_dup 1) (match_dup 2)))]
6606 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6607 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6608 "sub{q}\t{%2, %0|%0, %2}"
6609 [(set_attr "type" "alu")
6610 (set_attr "mode" "DI")])
6611
6612 (define_insn "subqi3_carry"
6613 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6614 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6615 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6616 (match_operand:QI 2 "general_operand" "qi,qm"))))
6617 (clobber (reg:CC FLAGS_REG))]
6618 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6619 "sbb{b}\t{%2, %0|%0, %2}"
6620 [(set_attr "type" "alu")
6621 (set_attr "pent_pair" "pu")
6622 (set_attr "mode" "QI")])
6623
6624 (define_insn "subhi3_carry"
6625 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6626 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6627 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6628 (match_operand:HI 2 "general_operand" "ri,rm"))))
6629 (clobber (reg:CC FLAGS_REG))]
6630 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6631 "sbb{w}\t{%2, %0|%0, %2}"
6632 [(set_attr "type" "alu")
6633 (set_attr "pent_pair" "pu")
6634 (set_attr "mode" "HI")])
6635
6636 (define_insn "subsi3_carry"
6637 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6638 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6639 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6640 (match_operand:SI 2 "general_operand" "ri,rm"))))
6641 (clobber (reg:CC FLAGS_REG))]
6642 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6643 "sbb{l}\t{%2, %0|%0, %2}"
6644 [(set_attr "type" "alu")
6645 (set_attr "pent_pair" "pu")
6646 (set_attr "mode" "SI")])
6647
6648 (define_insn "subsi3_carry_zext"
6649 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6650 (zero_extend:DI
6651 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6652 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6653 (match_operand:SI 2 "general_operand" "ri,rm")))))
6654 (clobber (reg:CC FLAGS_REG))]
6655 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6656 "sbb{l}\t{%2, %k0|%k0, %2}"
6657 [(set_attr "type" "alu")
6658 (set_attr "pent_pair" "pu")
6659 (set_attr "mode" "SI")])
6660
6661 (define_expand "subsi3"
6662 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6663 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6664 (match_operand:SI 2 "general_operand" "")))
6665 (clobber (reg:CC FLAGS_REG))])]
6666 ""
6667 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6668
6669 (define_insn "*subsi_1"
6670 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6671 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6672 (match_operand:SI 2 "general_operand" "ri,rm")))
6673 (clobber (reg:CC FLAGS_REG))]
6674 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6675 "sub{l}\t{%2, %0|%0, %2}"
6676 [(set_attr "type" "alu")
6677 (set_attr "mode" "SI")])
6678
6679 (define_insn "*subsi_1_zext"
6680 [(set (match_operand:DI 0 "register_operand" "=r")
6681 (zero_extend:DI
6682 (minus:SI (match_operand:SI 1 "register_operand" "0")
6683 (match_operand:SI 2 "general_operand" "rim"))))
6684 (clobber (reg:CC FLAGS_REG))]
6685 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6686 "sub{l}\t{%2, %k0|%k0, %2}"
6687 [(set_attr "type" "alu")
6688 (set_attr "mode" "SI")])
6689
6690 (define_insn "*subsi_2"
6691 [(set (reg FLAGS_REG)
6692 (compare
6693 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6694 (match_operand:SI 2 "general_operand" "ri,rm"))
6695 (const_int 0)))
6696 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6697 (minus:SI (match_dup 1) (match_dup 2)))]
6698 "ix86_match_ccmode (insn, CCGOCmode)
6699 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6700 "sub{l}\t{%2, %0|%0, %2}"
6701 [(set_attr "type" "alu")
6702 (set_attr "mode" "SI")])
6703
6704 (define_insn "*subsi_2_zext"
6705 [(set (reg FLAGS_REG)
6706 (compare
6707 (minus:SI (match_operand:SI 1 "register_operand" "0")
6708 (match_operand:SI 2 "general_operand" "rim"))
6709 (const_int 0)))
6710 (set (match_operand:DI 0 "register_operand" "=r")
6711 (zero_extend:DI
6712 (minus:SI (match_dup 1)
6713 (match_dup 2))))]
6714 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6715 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6716 "sub{l}\t{%2, %k0|%k0, %2}"
6717 [(set_attr "type" "alu")
6718 (set_attr "mode" "SI")])
6719
6720 (define_insn "*subsi_3"
6721 [(set (reg FLAGS_REG)
6722 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6723 (match_operand:SI 2 "general_operand" "ri,rm")))
6724 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6725 (minus:SI (match_dup 1) (match_dup 2)))]
6726 "ix86_match_ccmode (insn, CCmode)
6727 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6728 "sub{l}\t{%2, %0|%0, %2}"
6729 [(set_attr "type" "alu")
6730 (set_attr "mode" "SI")])
6731
6732 (define_insn "*subsi_3_zext"
6733 [(set (reg FLAGS_REG)
6734 (compare (match_operand:SI 1 "register_operand" "0")
6735 (match_operand:SI 2 "general_operand" "rim")))
6736 (set (match_operand:DI 0 "register_operand" "=r")
6737 (zero_extend:DI
6738 (minus:SI (match_dup 1)
6739 (match_dup 2))))]
6740 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6741 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6742 "sub{l}\t{%2, %1|%1, %2}"
6743 [(set_attr "type" "alu")
6744 (set_attr "mode" "DI")])
6745
6746 (define_expand "subhi3"
6747 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6748 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6749 (match_operand:HI 2 "general_operand" "")))
6750 (clobber (reg:CC FLAGS_REG))])]
6751 "TARGET_HIMODE_MATH"
6752 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6753
6754 (define_insn "*subhi_1"
6755 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6756 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6757 (match_operand:HI 2 "general_operand" "ri,rm")))
6758 (clobber (reg:CC FLAGS_REG))]
6759 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6760 "sub{w}\t{%2, %0|%0, %2}"
6761 [(set_attr "type" "alu")
6762 (set_attr "mode" "HI")])
6763
6764 (define_insn "*subhi_2"
6765 [(set (reg FLAGS_REG)
6766 (compare
6767 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6768 (match_operand:HI 2 "general_operand" "ri,rm"))
6769 (const_int 0)))
6770 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6771 (minus:HI (match_dup 1) (match_dup 2)))]
6772 "ix86_match_ccmode (insn, CCGOCmode)
6773 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6774 "sub{w}\t{%2, %0|%0, %2}"
6775 [(set_attr "type" "alu")
6776 (set_attr "mode" "HI")])
6777
6778 (define_insn "*subhi_3"
6779 [(set (reg FLAGS_REG)
6780 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6781 (match_operand:HI 2 "general_operand" "ri,rm")))
6782 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6783 (minus:HI (match_dup 1) (match_dup 2)))]
6784 "ix86_match_ccmode (insn, CCmode)
6785 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6786 "sub{w}\t{%2, %0|%0, %2}"
6787 [(set_attr "type" "alu")
6788 (set_attr "mode" "HI")])
6789
6790 (define_expand "subqi3"
6791 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6792 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6793 (match_operand:QI 2 "general_operand" "")))
6794 (clobber (reg:CC FLAGS_REG))])]
6795 "TARGET_QIMODE_MATH"
6796 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6797
6798 (define_insn "*subqi_1"
6799 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6800 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6801 (match_operand:QI 2 "general_operand" "qn,qmn")))
6802 (clobber (reg:CC FLAGS_REG))]
6803 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6804 "sub{b}\t{%2, %0|%0, %2}"
6805 [(set_attr "type" "alu")
6806 (set_attr "mode" "QI")])
6807
6808 (define_insn "*subqi_1_slp"
6809 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6810 (minus:QI (match_dup 0)
6811 (match_operand:QI 1 "general_operand" "qn,qmn")))
6812 (clobber (reg:CC FLAGS_REG))]
6813 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6814 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6815 "sub{b}\t{%1, %0|%0, %1}"
6816 [(set_attr "type" "alu1")
6817 (set_attr "mode" "QI")])
6818
6819 (define_insn "*subqi_2"
6820 [(set (reg FLAGS_REG)
6821 (compare
6822 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6823 (match_operand:QI 2 "general_operand" "qi,qm"))
6824 (const_int 0)))
6825 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6826 (minus:HI (match_dup 1) (match_dup 2)))]
6827 "ix86_match_ccmode (insn, CCGOCmode)
6828 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6829 "sub{b}\t{%2, %0|%0, %2}"
6830 [(set_attr "type" "alu")
6831 (set_attr "mode" "QI")])
6832
6833 (define_insn "*subqi_3"
6834 [(set (reg FLAGS_REG)
6835 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6836 (match_operand:QI 2 "general_operand" "qi,qm")))
6837 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6838 (minus:HI (match_dup 1) (match_dup 2)))]
6839 "ix86_match_ccmode (insn, CCmode)
6840 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6841 "sub{b}\t{%2, %0|%0, %2}"
6842 [(set_attr "type" "alu")
6843 (set_attr "mode" "QI")])
6844
6845 ;; The patterns that match these are at the end of this file.
6846
6847 (define_expand "subxf3"
6848 [(set (match_operand:XF 0 "register_operand" "")
6849 (minus:XF (match_operand:XF 1 "register_operand" "")
6850 (match_operand:XF 2 "register_operand" "")))]
6851 "TARGET_80387"
6852 "")
6853
6854 (define_expand "subdf3"
6855 [(set (match_operand:DF 0 "register_operand" "")
6856 (minus:DF (match_operand:DF 1 "register_operand" "")
6857 (match_operand:DF 2 "nonimmediate_operand" "")))]
6858 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6859 "")
6860
6861 (define_expand "subsf3"
6862 [(set (match_operand:SF 0 "register_operand" "")
6863 (minus:SF (match_operand:SF 1 "register_operand" "")
6864 (match_operand:SF 2 "nonimmediate_operand" "")))]
6865 "TARGET_80387 || TARGET_SSE_MATH"
6866 "")
6867 \f
6868 ;; Multiply instructions
6869
6870 (define_expand "muldi3"
6871 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6872 (mult:DI (match_operand:DI 1 "register_operand" "")
6873 (match_operand:DI 2 "x86_64_general_operand" "")))
6874 (clobber (reg:CC FLAGS_REG))])]
6875 "TARGET_64BIT"
6876 "")
6877
6878 ;; On AMDFAM10
6879 ;; IMUL reg64, reg64, imm8 Direct
6880 ;; IMUL reg64, mem64, imm8 VectorPath
6881 ;; IMUL reg64, reg64, imm32 Direct
6882 ;; IMUL reg64, mem64, imm32 VectorPath
6883 ;; IMUL reg64, reg64 Direct
6884 ;; IMUL reg64, mem64 Direct
6885
6886 (define_insn "*muldi3_1_rex64"
6887 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6888 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6889 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6890 (clobber (reg:CC FLAGS_REG))]
6891 "TARGET_64BIT
6892 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6893 "@
6894 imul{q}\t{%2, %1, %0|%0, %1, %2}
6895 imul{q}\t{%2, %1, %0|%0, %1, %2}
6896 imul{q}\t{%2, %0|%0, %2}"
6897 [(set_attr "type" "imul")
6898 (set_attr "prefix_0f" "0,0,1")
6899 (set (attr "athlon_decode")
6900 (cond [(eq_attr "cpu" "athlon")
6901 (const_string "vector")
6902 (eq_attr "alternative" "1")
6903 (const_string "vector")
6904 (and (eq_attr "alternative" "2")
6905 (match_operand 1 "memory_operand" ""))
6906 (const_string "vector")]
6907 (const_string "direct")))
6908 (set (attr "amdfam10_decode")
6909 (cond [(and (eq_attr "alternative" "0,1")
6910 (match_operand 1 "memory_operand" ""))
6911 (const_string "vector")]
6912 (const_string "direct")))
6913 (set_attr "mode" "DI")])
6914
6915 (define_expand "mulsi3"
6916 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6917 (mult:SI (match_operand:SI 1 "register_operand" "")
6918 (match_operand:SI 2 "general_operand" "")))
6919 (clobber (reg:CC FLAGS_REG))])]
6920 ""
6921 "")
6922
6923 ;; On AMDFAM10
6924 ;; IMUL reg32, reg32, imm8 Direct
6925 ;; IMUL reg32, mem32, imm8 VectorPath
6926 ;; IMUL reg32, reg32, imm32 Direct
6927 ;; IMUL reg32, mem32, imm32 VectorPath
6928 ;; IMUL reg32, reg32 Direct
6929 ;; IMUL reg32, mem32 Direct
6930
6931 (define_insn "*mulsi3_1"
6932 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6933 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6934 (match_operand:SI 2 "general_operand" "K,i,mr")))
6935 (clobber (reg:CC FLAGS_REG))]
6936 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6937 "@
6938 imul{l}\t{%2, %1, %0|%0, %1, %2}
6939 imul{l}\t{%2, %1, %0|%0, %1, %2}
6940 imul{l}\t{%2, %0|%0, %2}"
6941 [(set_attr "type" "imul")
6942 (set_attr "prefix_0f" "0,0,1")
6943 (set (attr "athlon_decode")
6944 (cond [(eq_attr "cpu" "athlon")
6945 (const_string "vector")
6946 (eq_attr "alternative" "1")
6947 (const_string "vector")
6948 (and (eq_attr "alternative" "2")
6949 (match_operand 1 "memory_operand" ""))
6950 (const_string "vector")]
6951 (const_string "direct")))
6952 (set (attr "amdfam10_decode")
6953 (cond [(and (eq_attr "alternative" "0,1")
6954 (match_operand 1 "memory_operand" ""))
6955 (const_string "vector")]
6956 (const_string "direct")))
6957 (set_attr "mode" "SI")])
6958
6959 (define_insn "*mulsi3_1_zext"
6960 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6961 (zero_extend:DI
6962 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6963 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6964 (clobber (reg:CC FLAGS_REG))]
6965 "TARGET_64BIT
6966 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6967 "@
6968 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6969 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6970 imul{l}\t{%2, %k0|%k0, %2}"
6971 [(set_attr "type" "imul")
6972 (set_attr "prefix_0f" "0,0,1")
6973 (set (attr "athlon_decode")
6974 (cond [(eq_attr "cpu" "athlon")
6975 (const_string "vector")
6976 (eq_attr "alternative" "1")
6977 (const_string "vector")
6978 (and (eq_attr "alternative" "2")
6979 (match_operand 1 "memory_operand" ""))
6980 (const_string "vector")]
6981 (const_string "direct")))
6982 (set (attr "amdfam10_decode")
6983 (cond [(and (eq_attr "alternative" "0,1")
6984 (match_operand 1 "memory_operand" ""))
6985 (const_string "vector")]
6986 (const_string "direct")))
6987 (set_attr "mode" "SI")])
6988
6989 (define_expand "mulhi3"
6990 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6991 (mult:HI (match_operand:HI 1 "register_operand" "")
6992 (match_operand:HI 2 "general_operand" "")))
6993 (clobber (reg:CC FLAGS_REG))])]
6994 "TARGET_HIMODE_MATH"
6995 "")
6996
6997 ;; On AMDFAM10
6998 ;; IMUL reg16, reg16, imm8 VectorPath
6999 ;; IMUL reg16, mem16, imm8 VectorPath
7000 ;; IMUL reg16, reg16, imm16 VectorPath
7001 ;; IMUL reg16, mem16, imm16 VectorPath
7002 ;; IMUL reg16, reg16 Direct
7003 ;; IMUL reg16, mem16 Direct
7004 (define_insn "*mulhi3_1"
7005 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7006 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7007 (match_operand:HI 2 "general_operand" "K,i,mr")))
7008 (clobber (reg:CC FLAGS_REG))]
7009 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7010 "@
7011 imul{w}\t{%2, %1, %0|%0, %1, %2}
7012 imul{w}\t{%2, %1, %0|%0, %1, %2}
7013 imul{w}\t{%2, %0|%0, %2}"
7014 [(set_attr "type" "imul")
7015 (set_attr "prefix_0f" "0,0,1")
7016 (set (attr "athlon_decode")
7017 (cond [(eq_attr "cpu" "athlon")
7018 (const_string "vector")
7019 (eq_attr "alternative" "1,2")
7020 (const_string "vector")]
7021 (const_string "direct")))
7022 (set (attr "amdfam10_decode")
7023 (cond [(eq_attr "alternative" "0,1")
7024 (const_string "vector")]
7025 (const_string "direct")))
7026 (set_attr "mode" "HI")])
7027
7028 (define_expand "mulqi3"
7029 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7030 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7031 (match_operand:QI 2 "register_operand" "")))
7032 (clobber (reg:CC FLAGS_REG))])]
7033 "TARGET_QIMODE_MATH"
7034 "")
7035
7036 ;;On AMDFAM10
7037 ;; MUL reg8 Direct
7038 ;; MUL mem8 Direct
7039
7040 (define_insn "*mulqi3_1"
7041 [(set (match_operand:QI 0 "register_operand" "=a")
7042 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7043 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7044 (clobber (reg:CC FLAGS_REG))]
7045 "TARGET_QIMODE_MATH
7046 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7047 "mul{b}\t%2"
7048 [(set_attr "type" "imul")
7049 (set_attr "length_immediate" "0")
7050 (set (attr "athlon_decode")
7051 (if_then_else (eq_attr "cpu" "athlon")
7052 (const_string "vector")
7053 (const_string "direct")))
7054 (set_attr "amdfam10_decode" "direct")
7055 (set_attr "mode" "QI")])
7056
7057 (define_expand "umulqihi3"
7058 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7059 (mult:HI (zero_extend:HI
7060 (match_operand:QI 1 "nonimmediate_operand" ""))
7061 (zero_extend:HI
7062 (match_operand:QI 2 "register_operand" ""))))
7063 (clobber (reg:CC FLAGS_REG))])]
7064 "TARGET_QIMODE_MATH"
7065 "")
7066
7067 (define_insn "*umulqihi3_1"
7068 [(set (match_operand:HI 0 "register_operand" "=a")
7069 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7070 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7071 (clobber (reg:CC FLAGS_REG))]
7072 "TARGET_QIMODE_MATH
7073 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7074 "mul{b}\t%2"
7075 [(set_attr "type" "imul")
7076 (set_attr "length_immediate" "0")
7077 (set (attr "athlon_decode")
7078 (if_then_else (eq_attr "cpu" "athlon")
7079 (const_string "vector")
7080 (const_string "direct")))
7081 (set_attr "amdfam10_decode" "direct")
7082 (set_attr "mode" "QI")])
7083
7084 (define_expand "mulqihi3"
7085 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7086 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7087 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7088 (clobber (reg:CC FLAGS_REG))])]
7089 "TARGET_QIMODE_MATH"
7090 "")
7091
7092 (define_insn "*mulqihi3_insn"
7093 [(set (match_operand:HI 0 "register_operand" "=a")
7094 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7095 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7096 (clobber (reg:CC FLAGS_REG))]
7097 "TARGET_QIMODE_MATH
7098 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7099 "imul{b}\t%2"
7100 [(set_attr "type" "imul")
7101 (set_attr "length_immediate" "0")
7102 (set (attr "athlon_decode")
7103 (if_then_else (eq_attr "cpu" "athlon")
7104 (const_string "vector")
7105 (const_string "direct")))
7106 (set_attr "amdfam10_decode" "direct")
7107 (set_attr "mode" "QI")])
7108
7109 (define_expand "umulditi3"
7110 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7111 (mult:TI (zero_extend:TI
7112 (match_operand:DI 1 "nonimmediate_operand" ""))
7113 (zero_extend:TI
7114 (match_operand:DI 2 "register_operand" ""))))
7115 (clobber (reg:CC FLAGS_REG))])]
7116 "TARGET_64BIT"
7117 "")
7118
7119 (define_insn "*umulditi3_insn"
7120 [(set (match_operand:TI 0 "register_operand" "=A")
7121 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7122 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7123 (clobber (reg:CC FLAGS_REG))]
7124 "TARGET_64BIT
7125 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7126 "mul{q}\t%2"
7127 [(set_attr "type" "imul")
7128 (set_attr "length_immediate" "0")
7129 (set (attr "athlon_decode")
7130 (if_then_else (eq_attr "cpu" "athlon")
7131 (const_string "vector")
7132 (const_string "double")))
7133 (set_attr "amdfam10_decode" "double")
7134 (set_attr "mode" "DI")])
7135
7136 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7137 (define_expand "umulsidi3"
7138 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7139 (mult:DI (zero_extend:DI
7140 (match_operand:SI 1 "nonimmediate_operand" ""))
7141 (zero_extend:DI
7142 (match_operand:SI 2 "register_operand" ""))))
7143 (clobber (reg:CC FLAGS_REG))])]
7144 "!TARGET_64BIT"
7145 "")
7146
7147 (define_insn "*umulsidi3_insn"
7148 [(set (match_operand:DI 0 "register_operand" "=A")
7149 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7150 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7151 (clobber (reg:CC FLAGS_REG))]
7152 "!TARGET_64BIT
7153 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7154 "mul{l}\t%2"
7155 [(set_attr "type" "imul")
7156 (set_attr "length_immediate" "0")
7157 (set (attr "athlon_decode")
7158 (if_then_else (eq_attr "cpu" "athlon")
7159 (const_string "vector")
7160 (const_string "double")))
7161 (set_attr "amdfam10_decode" "double")
7162 (set_attr "mode" "SI")])
7163
7164 (define_expand "mulditi3"
7165 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7166 (mult:TI (sign_extend:TI
7167 (match_operand:DI 1 "nonimmediate_operand" ""))
7168 (sign_extend:TI
7169 (match_operand:DI 2 "register_operand" ""))))
7170 (clobber (reg:CC FLAGS_REG))])]
7171 "TARGET_64BIT"
7172 "")
7173
7174 (define_insn "*mulditi3_insn"
7175 [(set (match_operand:TI 0 "register_operand" "=A")
7176 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7177 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7178 (clobber (reg:CC FLAGS_REG))]
7179 "TARGET_64BIT
7180 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7181 "imul{q}\t%2"
7182 [(set_attr "type" "imul")
7183 (set_attr "length_immediate" "0")
7184 (set (attr "athlon_decode")
7185 (if_then_else (eq_attr "cpu" "athlon")
7186 (const_string "vector")
7187 (const_string "double")))
7188 (set_attr "amdfam10_decode" "double")
7189 (set_attr "mode" "DI")])
7190
7191 (define_expand "mulsidi3"
7192 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7193 (mult:DI (sign_extend:DI
7194 (match_operand:SI 1 "nonimmediate_operand" ""))
7195 (sign_extend:DI
7196 (match_operand:SI 2 "register_operand" ""))))
7197 (clobber (reg:CC FLAGS_REG))])]
7198 "!TARGET_64BIT"
7199 "")
7200
7201 (define_insn "*mulsidi3_insn"
7202 [(set (match_operand:DI 0 "register_operand" "=A")
7203 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7204 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7205 (clobber (reg:CC FLAGS_REG))]
7206 "!TARGET_64BIT
7207 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7208 "imul{l}\t%2"
7209 [(set_attr "type" "imul")
7210 (set_attr "length_immediate" "0")
7211 (set (attr "athlon_decode")
7212 (if_then_else (eq_attr "cpu" "athlon")
7213 (const_string "vector")
7214 (const_string "double")))
7215 (set_attr "amdfam10_decode" "double")
7216 (set_attr "mode" "SI")])
7217
7218 (define_expand "umuldi3_highpart"
7219 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7220 (truncate:DI
7221 (lshiftrt:TI
7222 (mult:TI (zero_extend:TI
7223 (match_operand:DI 1 "nonimmediate_operand" ""))
7224 (zero_extend:TI
7225 (match_operand:DI 2 "register_operand" "")))
7226 (const_int 64))))
7227 (clobber (match_scratch:DI 3 ""))
7228 (clobber (reg:CC FLAGS_REG))])]
7229 "TARGET_64BIT"
7230 "")
7231
7232 (define_insn "*umuldi3_highpart_rex64"
7233 [(set (match_operand:DI 0 "register_operand" "=d")
7234 (truncate:DI
7235 (lshiftrt:TI
7236 (mult:TI (zero_extend:TI
7237 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7238 (zero_extend:TI
7239 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7240 (const_int 64))))
7241 (clobber (match_scratch:DI 3 "=1"))
7242 (clobber (reg:CC FLAGS_REG))]
7243 "TARGET_64BIT
7244 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7245 "mul{q}\t%2"
7246 [(set_attr "type" "imul")
7247 (set_attr "length_immediate" "0")
7248 (set (attr "athlon_decode")
7249 (if_then_else (eq_attr "cpu" "athlon")
7250 (const_string "vector")
7251 (const_string "double")))
7252 (set_attr "amdfam10_decode" "double")
7253 (set_attr "mode" "DI")])
7254
7255 (define_expand "umulsi3_highpart"
7256 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7257 (truncate:SI
7258 (lshiftrt:DI
7259 (mult:DI (zero_extend:DI
7260 (match_operand:SI 1 "nonimmediate_operand" ""))
7261 (zero_extend:DI
7262 (match_operand:SI 2 "register_operand" "")))
7263 (const_int 32))))
7264 (clobber (match_scratch:SI 3 ""))
7265 (clobber (reg:CC FLAGS_REG))])]
7266 ""
7267 "")
7268
7269 (define_insn "*umulsi3_highpart_insn"
7270 [(set (match_operand:SI 0 "register_operand" "=d")
7271 (truncate:SI
7272 (lshiftrt:DI
7273 (mult:DI (zero_extend:DI
7274 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7275 (zero_extend:DI
7276 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7277 (const_int 32))))
7278 (clobber (match_scratch:SI 3 "=1"))
7279 (clobber (reg:CC FLAGS_REG))]
7280 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7281 "mul{l}\t%2"
7282 [(set_attr "type" "imul")
7283 (set_attr "length_immediate" "0")
7284 (set (attr "athlon_decode")
7285 (if_then_else (eq_attr "cpu" "athlon")
7286 (const_string "vector")
7287 (const_string "double")))
7288 (set_attr "amdfam10_decode" "double")
7289 (set_attr "mode" "SI")])
7290
7291 (define_insn "*umulsi3_highpart_zext"
7292 [(set (match_operand:DI 0 "register_operand" "=d")
7293 (zero_extend:DI (truncate:SI
7294 (lshiftrt:DI
7295 (mult:DI (zero_extend:DI
7296 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7297 (zero_extend:DI
7298 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7299 (const_int 32)))))
7300 (clobber (match_scratch:SI 3 "=1"))
7301 (clobber (reg:CC FLAGS_REG))]
7302 "TARGET_64BIT
7303 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7304 "mul{l}\t%2"
7305 [(set_attr "type" "imul")
7306 (set_attr "length_immediate" "0")
7307 (set (attr "athlon_decode")
7308 (if_then_else (eq_attr "cpu" "athlon")
7309 (const_string "vector")
7310 (const_string "double")))
7311 (set_attr "amdfam10_decode" "double")
7312 (set_attr "mode" "SI")])
7313
7314 (define_expand "smuldi3_highpart"
7315 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7316 (truncate:DI
7317 (lshiftrt:TI
7318 (mult:TI (sign_extend:TI
7319 (match_operand:DI 1 "nonimmediate_operand" ""))
7320 (sign_extend:TI
7321 (match_operand:DI 2 "register_operand" "")))
7322 (const_int 64))))
7323 (clobber (match_scratch:DI 3 ""))
7324 (clobber (reg:CC FLAGS_REG))])]
7325 "TARGET_64BIT"
7326 "")
7327
7328 (define_insn "*smuldi3_highpart_rex64"
7329 [(set (match_operand:DI 0 "register_operand" "=d")
7330 (truncate:DI
7331 (lshiftrt:TI
7332 (mult:TI (sign_extend:TI
7333 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7334 (sign_extend:TI
7335 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7336 (const_int 64))))
7337 (clobber (match_scratch:DI 3 "=1"))
7338 (clobber (reg:CC FLAGS_REG))]
7339 "TARGET_64BIT
7340 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7341 "imul{q}\t%2"
7342 [(set_attr "type" "imul")
7343 (set (attr "athlon_decode")
7344 (if_then_else (eq_attr "cpu" "athlon")
7345 (const_string "vector")
7346 (const_string "double")))
7347 (set_attr "amdfam10_decode" "double")
7348 (set_attr "mode" "DI")])
7349
7350 (define_expand "smulsi3_highpart"
7351 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7352 (truncate:SI
7353 (lshiftrt:DI
7354 (mult:DI (sign_extend:DI
7355 (match_operand:SI 1 "nonimmediate_operand" ""))
7356 (sign_extend:DI
7357 (match_operand:SI 2 "register_operand" "")))
7358 (const_int 32))))
7359 (clobber (match_scratch:SI 3 ""))
7360 (clobber (reg:CC FLAGS_REG))])]
7361 ""
7362 "")
7363
7364 (define_insn "*smulsi3_highpart_insn"
7365 [(set (match_operand:SI 0 "register_operand" "=d")
7366 (truncate:SI
7367 (lshiftrt:DI
7368 (mult:DI (sign_extend:DI
7369 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7370 (sign_extend:DI
7371 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7372 (const_int 32))))
7373 (clobber (match_scratch:SI 3 "=1"))
7374 (clobber (reg:CC FLAGS_REG))]
7375 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7376 "imul{l}\t%2"
7377 [(set_attr "type" "imul")
7378 (set (attr "athlon_decode")
7379 (if_then_else (eq_attr "cpu" "athlon")
7380 (const_string "vector")
7381 (const_string "double")))
7382 (set_attr "amdfam10_decode" "double")
7383 (set_attr "mode" "SI")])
7384
7385 (define_insn "*smulsi3_highpart_zext"
7386 [(set (match_operand:DI 0 "register_operand" "=d")
7387 (zero_extend:DI (truncate:SI
7388 (lshiftrt:DI
7389 (mult:DI (sign_extend:DI
7390 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7391 (sign_extend:DI
7392 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7393 (const_int 32)))))
7394 (clobber (match_scratch:SI 3 "=1"))
7395 (clobber (reg:CC FLAGS_REG))]
7396 "TARGET_64BIT
7397 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7398 "imul{l}\t%2"
7399 [(set_attr "type" "imul")
7400 (set (attr "athlon_decode")
7401 (if_then_else (eq_attr "cpu" "athlon")
7402 (const_string "vector")
7403 (const_string "double")))
7404 (set_attr "amdfam10_decode" "double")
7405 (set_attr "mode" "SI")])
7406
7407 ;; The patterns that match these are at the end of this file.
7408
7409 (define_expand "mulxf3"
7410 [(set (match_operand:XF 0 "register_operand" "")
7411 (mult:XF (match_operand:XF 1 "register_operand" "")
7412 (match_operand:XF 2 "register_operand" "")))]
7413 "TARGET_80387"
7414 "")
7415
7416 (define_expand "muldf3"
7417 [(set (match_operand:DF 0 "register_operand" "")
7418 (mult:DF (match_operand:DF 1 "register_operand" "")
7419 (match_operand:DF 2 "nonimmediate_operand" "")))]
7420 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7421 "")
7422
7423 (define_expand "mulsf3"
7424 [(set (match_operand:SF 0 "register_operand" "")
7425 (mult:SF (match_operand:SF 1 "register_operand" "")
7426 (match_operand:SF 2 "nonimmediate_operand" "")))]
7427 "TARGET_80387 || TARGET_SSE_MATH"
7428 "")
7429 \f
7430 ;; Divide instructions
7431
7432 (define_insn "divqi3"
7433 [(set (match_operand:QI 0 "register_operand" "=a")
7434 (div:QI (match_operand:HI 1 "register_operand" "0")
7435 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7436 (clobber (reg:CC FLAGS_REG))]
7437 "TARGET_QIMODE_MATH"
7438 "idiv{b}\t%2"
7439 [(set_attr "type" "idiv")
7440 (set_attr "mode" "QI")])
7441
7442 (define_insn "udivqi3"
7443 [(set (match_operand:QI 0 "register_operand" "=a")
7444 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7445 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7446 (clobber (reg:CC FLAGS_REG))]
7447 "TARGET_QIMODE_MATH"
7448 "div{b}\t%2"
7449 [(set_attr "type" "idiv")
7450 (set_attr "mode" "QI")])
7451
7452 ;; The patterns that match these are at the end of this file.
7453
7454 (define_expand "divxf3"
7455 [(set (match_operand:XF 0 "register_operand" "")
7456 (div:XF (match_operand:XF 1 "register_operand" "")
7457 (match_operand:XF 2 "register_operand" "")))]
7458 "TARGET_80387"
7459 "")
7460
7461 (define_expand "divdf3"
7462 [(set (match_operand:DF 0 "register_operand" "")
7463 (div:DF (match_operand:DF 1 "register_operand" "")
7464 (match_operand:DF 2 "nonimmediate_operand" "")))]
7465 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7466 "")
7467
7468 (define_expand "divsf3"
7469 [(set (match_operand:SF 0 "register_operand" "")
7470 (div:SF (match_operand:SF 1 "register_operand" "")
7471 (match_operand:SF 2 "nonimmediate_operand" "")))]
7472 "TARGET_80387 || TARGET_SSE_MATH"
7473 {
7474 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
7475 && flag_finite_math_only && !flag_trapping_math
7476 && flag_unsafe_math_optimizations)
7477 {
7478 ix86_emit_swdivsf (operands[0], operands[1],
7479 operands[2], SFmode);
7480 DONE;
7481 }
7482 })
7483 \f
7484 ;; Remainder instructions.
7485
7486 (define_expand "divmoddi4"
7487 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7488 (div:DI (match_operand:DI 1 "register_operand" "")
7489 (match_operand:DI 2 "nonimmediate_operand" "")))
7490 (set (match_operand:DI 3 "register_operand" "")
7491 (mod:DI (match_dup 1) (match_dup 2)))
7492 (clobber (reg:CC FLAGS_REG))])]
7493 "TARGET_64BIT"
7494 "")
7495
7496 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7497 ;; Penalize eax case slightly because it results in worse scheduling
7498 ;; of code.
7499 (define_insn "*divmoddi4_nocltd_rex64"
7500 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7501 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7502 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7503 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7504 (mod:DI (match_dup 2) (match_dup 3)))
7505 (clobber (reg:CC FLAGS_REG))]
7506 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7507 "#"
7508 [(set_attr "type" "multi")])
7509
7510 (define_insn "*divmoddi4_cltd_rex64"
7511 [(set (match_operand:DI 0 "register_operand" "=a")
7512 (div:DI (match_operand:DI 2 "register_operand" "a")
7513 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7514 (set (match_operand:DI 1 "register_operand" "=&d")
7515 (mod:DI (match_dup 2) (match_dup 3)))
7516 (clobber (reg:CC FLAGS_REG))]
7517 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7518 "#"
7519 [(set_attr "type" "multi")])
7520
7521 (define_insn "*divmoddi_noext_rex64"
7522 [(set (match_operand:DI 0 "register_operand" "=a")
7523 (div:DI (match_operand:DI 1 "register_operand" "0")
7524 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7525 (set (match_operand:DI 3 "register_operand" "=d")
7526 (mod:DI (match_dup 1) (match_dup 2)))
7527 (use (match_operand:DI 4 "register_operand" "3"))
7528 (clobber (reg:CC FLAGS_REG))]
7529 "TARGET_64BIT"
7530 "idiv{q}\t%2"
7531 [(set_attr "type" "idiv")
7532 (set_attr "mode" "DI")])
7533
7534 (define_split
7535 [(set (match_operand:DI 0 "register_operand" "")
7536 (div:DI (match_operand:DI 1 "register_operand" "")
7537 (match_operand:DI 2 "nonimmediate_operand" "")))
7538 (set (match_operand:DI 3 "register_operand" "")
7539 (mod:DI (match_dup 1) (match_dup 2)))
7540 (clobber (reg:CC FLAGS_REG))]
7541 "TARGET_64BIT && reload_completed"
7542 [(parallel [(set (match_dup 3)
7543 (ashiftrt:DI (match_dup 4) (const_int 63)))
7544 (clobber (reg:CC FLAGS_REG))])
7545 (parallel [(set (match_dup 0)
7546 (div:DI (reg:DI 0) (match_dup 2)))
7547 (set (match_dup 3)
7548 (mod:DI (reg:DI 0) (match_dup 2)))
7549 (use (match_dup 3))
7550 (clobber (reg:CC FLAGS_REG))])]
7551 {
7552 /* Avoid use of cltd in favor of a mov+shift. */
7553 if (!TARGET_USE_CLTD && !optimize_size)
7554 {
7555 if (true_regnum (operands[1]))
7556 emit_move_insn (operands[0], operands[1]);
7557 else
7558 emit_move_insn (operands[3], operands[1]);
7559 operands[4] = operands[3];
7560 }
7561 else
7562 {
7563 gcc_assert (!true_regnum (operands[1]));
7564 operands[4] = operands[1];
7565 }
7566 })
7567
7568
7569 (define_expand "divmodsi4"
7570 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7571 (div:SI (match_operand:SI 1 "register_operand" "")
7572 (match_operand:SI 2 "nonimmediate_operand" "")))
7573 (set (match_operand:SI 3 "register_operand" "")
7574 (mod:SI (match_dup 1) (match_dup 2)))
7575 (clobber (reg:CC FLAGS_REG))])]
7576 ""
7577 "")
7578
7579 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7580 ;; Penalize eax case slightly because it results in worse scheduling
7581 ;; of code.
7582 (define_insn "*divmodsi4_nocltd"
7583 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7584 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7585 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7586 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7587 (mod:SI (match_dup 2) (match_dup 3)))
7588 (clobber (reg:CC FLAGS_REG))]
7589 "!optimize_size && !TARGET_USE_CLTD"
7590 "#"
7591 [(set_attr "type" "multi")])
7592
7593 (define_insn "*divmodsi4_cltd"
7594 [(set (match_operand:SI 0 "register_operand" "=a")
7595 (div:SI (match_operand:SI 2 "register_operand" "a")
7596 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7597 (set (match_operand:SI 1 "register_operand" "=&d")
7598 (mod:SI (match_dup 2) (match_dup 3)))
7599 (clobber (reg:CC FLAGS_REG))]
7600 "optimize_size || TARGET_USE_CLTD"
7601 "#"
7602 [(set_attr "type" "multi")])
7603
7604 (define_insn "*divmodsi_noext"
7605 [(set (match_operand:SI 0 "register_operand" "=a")
7606 (div:SI (match_operand:SI 1 "register_operand" "0")
7607 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7608 (set (match_operand:SI 3 "register_operand" "=d")
7609 (mod:SI (match_dup 1) (match_dup 2)))
7610 (use (match_operand:SI 4 "register_operand" "3"))
7611 (clobber (reg:CC FLAGS_REG))]
7612 ""
7613 "idiv{l}\t%2"
7614 [(set_attr "type" "idiv")
7615 (set_attr "mode" "SI")])
7616
7617 (define_split
7618 [(set (match_operand:SI 0 "register_operand" "")
7619 (div:SI (match_operand:SI 1 "register_operand" "")
7620 (match_operand:SI 2 "nonimmediate_operand" "")))
7621 (set (match_operand:SI 3 "register_operand" "")
7622 (mod:SI (match_dup 1) (match_dup 2)))
7623 (clobber (reg:CC FLAGS_REG))]
7624 "reload_completed"
7625 [(parallel [(set (match_dup 3)
7626 (ashiftrt:SI (match_dup 4) (const_int 31)))
7627 (clobber (reg:CC FLAGS_REG))])
7628 (parallel [(set (match_dup 0)
7629 (div:SI (reg:SI 0) (match_dup 2)))
7630 (set (match_dup 3)
7631 (mod:SI (reg:SI 0) (match_dup 2)))
7632 (use (match_dup 3))
7633 (clobber (reg:CC FLAGS_REG))])]
7634 {
7635 /* Avoid use of cltd in favor of a mov+shift. */
7636 if (!TARGET_USE_CLTD && !optimize_size)
7637 {
7638 if (true_regnum (operands[1]))
7639 emit_move_insn (operands[0], operands[1]);
7640 else
7641 emit_move_insn (operands[3], operands[1]);
7642 operands[4] = operands[3];
7643 }
7644 else
7645 {
7646 gcc_assert (!true_regnum (operands[1]));
7647 operands[4] = operands[1];
7648 }
7649 })
7650 ;; %%% Split me.
7651 (define_insn "divmodhi4"
7652 [(set (match_operand:HI 0 "register_operand" "=a")
7653 (div:HI (match_operand:HI 1 "register_operand" "0")
7654 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7655 (set (match_operand:HI 3 "register_operand" "=&d")
7656 (mod:HI (match_dup 1) (match_dup 2)))
7657 (clobber (reg:CC FLAGS_REG))]
7658 "TARGET_HIMODE_MATH"
7659 "cwtd\;idiv{w}\t%2"
7660 [(set_attr "type" "multi")
7661 (set_attr "length_immediate" "0")
7662 (set_attr "mode" "SI")])
7663
7664 (define_insn "udivmoddi4"
7665 [(set (match_operand:DI 0 "register_operand" "=a")
7666 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7667 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7668 (set (match_operand:DI 3 "register_operand" "=&d")
7669 (umod:DI (match_dup 1) (match_dup 2)))
7670 (clobber (reg:CC FLAGS_REG))]
7671 "TARGET_64BIT"
7672 "xor{q}\t%3, %3\;div{q}\t%2"
7673 [(set_attr "type" "multi")
7674 (set_attr "length_immediate" "0")
7675 (set_attr "mode" "DI")])
7676
7677 (define_insn "*udivmoddi4_noext"
7678 [(set (match_operand:DI 0 "register_operand" "=a")
7679 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7680 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7681 (set (match_operand:DI 3 "register_operand" "=d")
7682 (umod:DI (match_dup 1) (match_dup 2)))
7683 (use (match_dup 3))
7684 (clobber (reg:CC FLAGS_REG))]
7685 "TARGET_64BIT"
7686 "div{q}\t%2"
7687 [(set_attr "type" "idiv")
7688 (set_attr "mode" "DI")])
7689
7690 (define_split
7691 [(set (match_operand:DI 0 "register_operand" "")
7692 (udiv:DI (match_operand:DI 1 "register_operand" "")
7693 (match_operand:DI 2 "nonimmediate_operand" "")))
7694 (set (match_operand:DI 3 "register_operand" "")
7695 (umod:DI (match_dup 1) (match_dup 2)))
7696 (clobber (reg:CC FLAGS_REG))]
7697 "TARGET_64BIT && reload_completed"
7698 [(set (match_dup 3) (const_int 0))
7699 (parallel [(set (match_dup 0)
7700 (udiv:DI (match_dup 1) (match_dup 2)))
7701 (set (match_dup 3)
7702 (umod:DI (match_dup 1) (match_dup 2)))
7703 (use (match_dup 3))
7704 (clobber (reg:CC FLAGS_REG))])]
7705 "")
7706
7707 (define_insn "udivmodsi4"
7708 [(set (match_operand:SI 0 "register_operand" "=a")
7709 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7710 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7711 (set (match_operand:SI 3 "register_operand" "=&d")
7712 (umod:SI (match_dup 1) (match_dup 2)))
7713 (clobber (reg:CC FLAGS_REG))]
7714 ""
7715 "xor{l}\t%3, %3\;div{l}\t%2"
7716 [(set_attr "type" "multi")
7717 (set_attr "length_immediate" "0")
7718 (set_attr "mode" "SI")])
7719
7720 (define_insn "*udivmodsi4_noext"
7721 [(set (match_operand:SI 0 "register_operand" "=a")
7722 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7723 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7724 (set (match_operand:SI 3 "register_operand" "=d")
7725 (umod:SI (match_dup 1) (match_dup 2)))
7726 (use (match_dup 3))
7727 (clobber (reg:CC FLAGS_REG))]
7728 ""
7729 "div{l}\t%2"
7730 [(set_attr "type" "idiv")
7731 (set_attr "mode" "SI")])
7732
7733 (define_split
7734 [(set (match_operand:SI 0 "register_operand" "")
7735 (udiv:SI (match_operand:SI 1 "register_operand" "")
7736 (match_operand:SI 2 "nonimmediate_operand" "")))
7737 (set (match_operand:SI 3 "register_operand" "")
7738 (umod:SI (match_dup 1) (match_dup 2)))
7739 (clobber (reg:CC FLAGS_REG))]
7740 "reload_completed"
7741 [(set (match_dup 3) (const_int 0))
7742 (parallel [(set (match_dup 0)
7743 (udiv:SI (match_dup 1) (match_dup 2)))
7744 (set (match_dup 3)
7745 (umod:SI (match_dup 1) (match_dup 2)))
7746 (use (match_dup 3))
7747 (clobber (reg:CC FLAGS_REG))])]
7748 "")
7749
7750 (define_expand "udivmodhi4"
7751 [(set (match_dup 4) (const_int 0))
7752 (parallel [(set (match_operand:HI 0 "register_operand" "")
7753 (udiv:HI (match_operand:HI 1 "register_operand" "")
7754 (match_operand:HI 2 "nonimmediate_operand" "")))
7755 (set (match_operand:HI 3 "register_operand" "")
7756 (umod:HI (match_dup 1) (match_dup 2)))
7757 (use (match_dup 4))
7758 (clobber (reg:CC FLAGS_REG))])]
7759 "TARGET_HIMODE_MATH"
7760 "operands[4] = gen_reg_rtx (HImode);")
7761
7762 (define_insn "*udivmodhi_noext"
7763 [(set (match_operand:HI 0 "register_operand" "=a")
7764 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7765 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7766 (set (match_operand:HI 3 "register_operand" "=d")
7767 (umod:HI (match_dup 1) (match_dup 2)))
7768 (use (match_operand:HI 4 "register_operand" "3"))
7769 (clobber (reg:CC FLAGS_REG))]
7770 ""
7771 "div{w}\t%2"
7772 [(set_attr "type" "idiv")
7773 (set_attr "mode" "HI")])
7774
7775 ;; We cannot use div/idiv for double division, because it causes
7776 ;; "division by zero" on the overflow and that's not what we expect
7777 ;; from truncate. Because true (non truncating) double division is
7778 ;; never generated, we can't create this insn anyway.
7779 ;
7780 ;(define_insn ""
7781 ; [(set (match_operand:SI 0 "register_operand" "=a")
7782 ; (truncate:SI
7783 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7784 ; (zero_extend:DI
7785 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7786 ; (set (match_operand:SI 3 "register_operand" "=d")
7787 ; (truncate:SI
7788 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7789 ; (clobber (reg:CC FLAGS_REG))]
7790 ; ""
7791 ; "div{l}\t{%2, %0|%0, %2}"
7792 ; [(set_attr "type" "idiv")])
7793 \f
7794 ;;- Logical AND instructions
7795
7796 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7797 ;; Note that this excludes ah.
7798
7799 (define_insn "*testdi_1_rex64"
7800 [(set (reg FLAGS_REG)
7801 (compare
7802 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7803 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7804 (const_int 0)))]
7805 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7806 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7807 "@
7808 test{l}\t{%k1, %k0|%k0, %k1}
7809 test{l}\t{%k1, %k0|%k0, %k1}
7810 test{q}\t{%1, %0|%0, %1}
7811 test{q}\t{%1, %0|%0, %1}
7812 test{q}\t{%1, %0|%0, %1}"
7813 [(set_attr "type" "test")
7814 (set_attr "modrm" "0,1,0,1,1")
7815 (set_attr "mode" "SI,SI,DI,DI,DI")
7816 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7817
7818 (define_insn "testsi_1"
7819 [(set (reg FLAGS_REG)
7820 (compare
7821 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7822 (match_operand:SI 1 "general_operand" "in,in,rin"))
7823 (const_int 0)))]
7824 "ix86_match_ccmode (insn, CCNOmode)
7825 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7826 "test{l}\t{%1, %0|%0, %1}"
7827 [(set_attr "type" "test")
7828 (set_attr "modrm" "0,1,1")
7829 (set_attr "mode" "SI")
7830 (set_attr "pent_pair" "uv,np,uv")])
7831
7832 (define_expand "testsi_ccno_1"
7833 [(set (reg:CCNO FLAGS_REG)
7834 (compare:CCNO
7835 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7836 (match_operand:SI 1 "nonmemory_operand" ""))
7837 (const_int 0)))]
7838 ""
7839 "")
7840
7841 (define_insn "*testhi_1"
7842 [(set (reg FLAGS_REG)
7843 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7844 (match_operand:HI 1 "general_operand" "n,n,rn"))
7845 (const_int 0)))]
7846 "ix86_match_ccmode (insn, CCNOmode)
7847 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7848 "test{w}\t{%1, %0|%0, %1}"
7849 [(set_attr "type" "test")
7850 (set_attr "modrm" "0,1,1")
7851 (set_attr "mode" "HI")
7852 (set_attr "pent_pair" "uv,np,uv")])
7853
7854 (define_expand "testqi_ccz_1"
7855 [(set (reg:CCZ FLAGS_REG)
7856 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7857 (match_operand:QI 1 "nonmemory_operand" ""))
7858 (const_int 0)))]
7859 ""
7860 "")
7861
7862 (define_insn "*testqi_1_maybe_si"
7863 [(set (reg FLAGS_REG)
7864 (compare
7865 (and:QI
7866 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7867 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7868 (const_int 0)))]
7869 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7870 && ix86_match_ccmode (insn,
7871 CONST_INT_P (operands[1])
7872 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7873 {
7874 if (which_alternative == 3)
7875 {
7876 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7877 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7878 return "test{l}\t{%1, %k0|%k0, %1}";
7879 }
7880 return "test{b}\t{%1, %0|%0, %1}";
7881 }
7882 [(set_attr "type" "test")
7883 (set_attr "modrm" "0,1,1,1")
7884 (set_attr "mode" "QI,QI,QI,SI")
7885 (set_attr "pent_pair" "uv,np,uv,np")])
7886
7887 (define_insn "*testqi_1"
7888 [(set (reg FLAGS_REG)
7889 (compare
7890 (and:QI
7891 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7892 (match_operand:QI 1 "general_operand" "n,n,qn"))
7893 (const_int 0)))]
7894 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7895 && ix86_match_ccmode (insn, CCNOmode)"
7896 "test{b}\t{%1, %0|%0, %1}"
7897 [(set_attr "type" "test")
7898 (set_attr "modrm" "0,1,1")
7899 (set_attr "mode" "QI")
7900 (set_attr "pent_pair" "uv,np,uv")])
7901
7902 (define_expand "testqi_ext_ccno_0"
7903 [(set (reg:CCNO FLAGS_REG)
7904 (compare:CCNO
7905 (and:SI
7906 (zero_extract:SI
7907 (match_operand 0 "ext_register_operand" "")
7908 (const_int 8)
7909 (const_int 8))
7910 (match_operand 1 "const_int_operand" ""))
7911 (const_int 0)))]
7912 ""
7913 "")
7914
7915 (define_insn "*testqi_ext_0"
7916 [(set (reg FLAGS_REG)
7917 (compare
7918 (and:SI
7919 (zero_extract:SI
7920 (match_operand 0 "ext_register_operand" "Q")
7921 (const_int 8)
7922 (const_int 8))
7923 (match_operand 1 "const_int_operand" "n"))
7924 (const_int 0)))]
7925 "ix86_match_ccmode (insn, CCNOmode)"
7926 "test{b}\t{%1, %h0|%h0, %1}"
7927 [(set_attr "type" "test")
7928 (set_attr "mode" "QI")
7929 (set_attr "length_immediate" "1")
7930 (set_attr "pent_pair" "np")])
7931
7932 (define_insn "*testqi_ext_1"
7933 [(set (reg FLAGS_REG)
7934 (compare
7935 (and:SI
7936 (zero_extract:SI
7937 (match_operand 0 "ext_register_operand" "Q")
7938 (const_int 8)
7939 (const_int 8))
7940 (zero_extend:SI
7941 (match_operand:QI 1 "general_operand" "Qm")))
7942 (const_int 0)))]
7943 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7944 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7945 "test{b}\t{%1, %h0|%h0, %1}"
7946 [(set_attr "type" "test")
7947 (set_attr "mode" "QI")])
7948
7949 (define_insn "*testqi_ext_1_rex64"
7950 [(set (reg FLAGS_REG)
7951 (compare
7952 (and:SI
7953 (zero_extract:SI
7954 (match_operand 0 "ext_register_operand" "Q")
7955 (const_int 8)
7956 (const_int 8))
7957 (zero_extend:SI
7958 (match_operand:QI 1 "register_operand" "Q")))
7959 (const_int 0)))]
7960 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7961 "test{b}\t{%1, %h0|%h0, %1}"
7962 [(set_attr "type" "test")
7963 (set_attr "mode" "QI")])
7964
7965 (define_insn "*testqi_ext_2"
7966 [(set (reg FLAGS_REG)
7967 (compare
7968 (and:SI
7969 (zero_extract:SI
7970 (match_operand 0 "ext_register_operand" "Q")
7971 (const_int 8)
7972 (const_int 8))
7973 (zero_extract:SI
7974 (match_operand 1 "ext_register_operand" "Q")
7975 (const_int 8)
7976 (const_int 8)))
7977 (const_int 0)))]
7978 "ix86_match_ccmode (insn, CCNOmode)"
7979 "test{b}\t{%h1, %h0|%h0, %h1}"
7980 [(set_attr "type" "test")
7981 (set_attr "mode" "QI")])
7982
7983 ;; Combine likes to form bit extractions for some tests. Humor it.
7984 (define_insn "*testqi_ext_3"
7985 [(set (reg FLAGS_REG)
7986 (compare (zero_extract:SI
7987 (match_operand 0 "nonimmediate_operand" "rm")
7988 (match_operand:SI 1 "const_int_operand" "")
7989 (match_operand:SI 2 "const_int_operand" ""))
7990 (const_int 0)))]
7991 "ix86_match_ccmode (insn, CCNOmode)
7992 && INTVAL (operands[1]) > 0
7993 && INTVAL (operands[2]) >= 0
7994 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7995 && (GET_MODE (operands[0]) == SImode
7996 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7997 || GET_MODE (operands[0]) == HImode
7998 || GET_MODE (operands[0]) == QImode)"
7999 "#")
8000
8001 (define_insn "*testqi_ext_3_rex64"
8002 [(set (reg FLAGS_REG)
8003 (compare (zero_extract:DI
8004 (match_operand 0 "nonimmediate_operand" "rm")
8005 (match_operand:DI 1 "const_int_operand" "")
8006 (match_operand:DI 2 "const_int_operand" ""))
8007 (const_int 0)))]
8008 "TARGET_64BIT
8009 && ix86_match_ccmode (insn, CCNOmode)
8010 && INTVAL (operands[1]) > 0
8011 && INTVAL (operands[2]) >= 0
8012 /* Ensure that resulting mask is zero or sign extended operand. */
8013 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8014 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8015 && INTVAL (operands[1]) > 32))
8016 && (GET_MODE (operands[0]) == SImode
8017 || GET_MODE (operands[0]) == DImode
8018 || GET_MODE (operands[0]) == HImode
8019 || GET_MODE (operands[0]) == QImode)"
8020 "#")
8021
8022 (define_split
8023 [(set (match_operand 0 "flags_reg_operand" "")
8024 (match_operator 1 "compare_operator"
8025 [(zero_extract
8026 (match_operand 2 "nonimmediate_operand" "")
8027 (match_operand 3 "const_int_operand" "")
8028 (match_operand 4 "const_int_operand" ""))
8029 (const_int 0)]))]
8030 "ix86_match_ccmode (insn, CCNOmode)"
8031 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8032 {
8033 rtx val = operands[2];
8034 HOST_WIDE_INT len = INTVAL (operands[3]);
8035 HOST_WIDE_INT pos = INTVAL (operands[4]);
8036 HOST_WIDE_INT mask;
8037 enum machine_mode mode, submode;
8038
8039 mode = GET_MODE (val);
8040 if (MEM_P (val))
8041 {
8042 /* ??? Combine likes to put non-volatile mem extractions in QImode
8043 no matter the size of the test. So find a mode that works. */
8044 if (! MEM_VOLATILE_P (val))
8045 {
8046 mode = smallest_mode_for_size (pos + len, MODE_INT);
8047 val = adjust_address (val, mode, 0);
8048 }
8049 }
8050 else if (GET_CODE (val) == SUBREG
8051 && (submode = GET_MODE (SUBREG_REG (val)),
8052 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8053 && pos + len <= GET_MODE_BITSIZE (submode))
8054 {
8055 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8056 mode = submode;
8057 val = SUBREG_REG (val);
8058 }
8059 else if (mode == HImode && pos + len <= 8)
8060 {
8061 /* Small HImode tests can be converted to QImode. */
8062 mode = QImode;
8063 val = gen_lowpart (QImode, val);
8064 }
8065
8066 if (len == HOST_BITS_PER_WIDE_INT)
8067 mask = -1;
8068 else
8069 mask = ((HOST_WIDE_INT)1 << len) - 1;
8070 mask <<= pos;
8071
8072 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8073 })
8074
8075 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8076 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8077 ;; this is relatively important trick.
8078 ;; Do the conversion only post-reload to avoid limiting of the register class
8079 ;; to QI regs.
8080 (define_split
8081 [(set (match_operand 0 "flags_reg_operand" "")
8082 (match_operator 1 "compare_operator"
8083 [(and (match_operand 2 "register_operand" "")
8084 (match_operand 3 "const_int_operand" ""))
8085 (const_int 0)]))]
8086 "reload_completed
8087 && QI_REG_P (operands[2])
8088 && GET_MODE (operands[2]) != QImode
8089 && ((ix86_match_ccmode (insn, CCZmode)
8090 && !(INTVAL (operands[3]) & ~(255 << 8)))
8091 || (ix86_match_ccmode (insn, CCNOmode)
8092 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8093 [(set (match_dup 0)
8094 (match_op_dup 1
8095 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8096 (match_dup 3))
8097 (const_int 0)]))]
8098 "operands[2] = gen_lowpart (SImode, operands[2]);
8099 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8100
8101 (define_split
8102 [(set (match_operand 0 "flags_reg_operand" "")
8103 (match_operator 1 "compare_operator"
8104 [(and (match_operand 2 "nonimmediate_operand" "")
8105 (match_operand 3 "const_int_operand" ""))
8106 (const_int 0)]))]
8107 "reload_completed
8108 && GET_MODE (operands[2]) != QImode
8109 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8110 && ((ix86_match_ccmode (insn, CCZmode)
8111 && !(INTVAL (operands[3]) & ~255))
8112 || (ix86_match_ccmode (insn, CCNOmode)
8113 && !(INTVAL (operands[3]) & ~127)))"
8114 [(set (match_dup 0)
8115 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8116 (const_int 0)]))]
8117 "operands[2] = gen_lowpart (QImode, operands[2]);
8118 operands[3] = gen_lowpart (QImode, operands[3]);")
8119
8120
8121 ;; %%% This used to optimize known byte-wide and operations to memory,
8122 ;; and sometimes to QImode registers. If this is considered useful,
8123 ;; it should be done with splitters.
8124
8125 (define_expand "anddi3"
8126 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8127 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8128 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8129 (clobber (reg:CC FLAGS_REG))]
8130 "TARGET_64BIT"
8131 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8132
8133 (define_insn "*anddi_1_rex64"
8134 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8135 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8136 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8137 (clobber (reg:CC FLAGS_REG))]
8138 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8139 {
8140 switch (get_attr_type (insn))
8141 {
8142 case TYPE_IMOVX:
8143 {
8144 enum machine_mode mode;
8145
8146 gcc_assert (CONST_INT_P (operands[2]));
8147 if (INTVAL (operands[2]) == 0xff)
8148 mode = QImode;
8149 else
8150 {
8151 gcc_assert (INTVAL (operands[2]) == 0xffff);
8152 mode = HImode;
8153 }
8154
8155 operands[1] = gen_lowpart (mode, operands[1]);
8156 if (mode == QImode)
8157 return "movz{bq|x}\t{%1,%0|%0, %1}";
8158 else
8159 return "movz{wq|x}\t{%1,%0|%0, %1}";
8160 }
8161
8162 default:
8163 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8164 if (get_attr_mode (insn) == MODE_SI)
8165 return "and{l}\t{%k2, %k0|%k0, %k2}";
8166 else
8167 return "and{q}\t{%2, %0|%0, %2}";
8168 }
8169 }
8170 [(set_attr "type" "alu,alu,alu,imovx")
8171 (set_attr "length_immediate" "*,*,*,0")
8172 (set_attr "mode" "SI,DI,DI,DI")])
8173
8174 (define_insn "*anddi_2"
8175 [(set (reg FLAGS_REG)
8176 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8177 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8178 (const_int 0)))
8179 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8180 (and:DI (match_dup 1) (match_dup 2)))]
8181 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8182 && ix86_binary_operator_ok (AND, DImode, operands)"
8183 "@
8184 and{l}\t{%k2, %k0|%k0, %k2}
8185 and{q}\t{%2, %0|%0, %2}
8186 and{q}\t{%2, %0|%0, %2}"
8187 [(set_attr "type" "alu")
8188 (set_attr "mode" "SI,DI,DI")])
8189
8190 (define_expand "andsi3"
8191 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8192 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8193 (match_operand:SI 2 "general_operand" "")))
8194 (clobber (reg:CC FLAGS_REG))]
8195 ""
8196 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8197
8198 (define_insn "*andsi_1"
8199 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8200 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8201 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8202 (clobber (reg:CC FLAGS_REG))]
8203 "ix86_binary_operator_ok (AND, SImode, operands)"
8204 {
8205 switch (get_attr_type (insn))
8206 {
8207 case TYPE_IMOVX:
8208 {
8209 enum machine_mode mode;
8210
8211 gcc_assert (CONST_INT_P (operands[2]));
8212 if (INTVAL (operands[2]) == 0xff)
8213 mode = QImode;
8214 else
8215 {
8216 gcc_assert (INTVAL (operands[2]) == 0xffff);
8217 mode = HImode;
8218 }
8219
8220 operands[1] = gen_lowpart (mode, operands[1]);
8221 if (mode == QImode)
8222 return "movz{bl|x}\t{%1,%0|%0, %1}";
8223 else
8224 return "movz{wl|x}\t{%1,%0|%0, %1}";
8225 }
8226
8227 default:
8228 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8229 return "and{l}\t{%2, %0|%0, %2}";
8230 }
8231 }
8232 [(set_attr "type" "alu,alu,imovx")
8233 (set_attr "length_immediate" "*,*,0")
8234 (set_attr "mode" "SI")])
8235
8236 (define_split
8237 [(set (match_operand 0 "register_operand" "")
8238 (and (match_dup 0)
8239 (const_int -65536)))
8240 (clobber (reg:CC FLAGS_REG))]
8241 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8242 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8243 "operands[1] = gen_lowpart (HImode, operands[0]);")
8244
8245 (define_split
8246 [(set (match_operand 0 "ext_register_operand" "")
8247 (and (match_dup 0)
8248 (const_int -256)))
8249 (clobber (reg:CC FLAGS_REG))]
8250 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8251 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8252 "operands[1] = gen_lowpart (QImode, operands[0]);")
8253
8254 (define_split
8255 [(set (match_operand 0 "ext_register_operand" "")
8256 (and (match_dup 0)
8257 (const_int -65281)))
8258 (clobber (reg:CC FLAGS_REG))]
8259 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8260 [(parallel [(set (zero_extract:SI (match_dup 0)
8261 (const_int 8)
8262 (const_int 8))
8263 (xor:SI
8264 (zero_extract:SI (match_dup 0)
8265 (const_int 8)
8266 (const_int 8))
8267 (zero_extract:SI (match_dup 0)
8268 (const_int 8)
8269 (const_int 8))))
8270 (clobber (reg:CC FLAGS_REG))])]
8271 "operands[0] = gen_lowpart (SImode, operands[0]);")
8272
8273 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8274 (define_insn "*andsi_1_zext"
8275 [(set (match_operand:DI 0 "register_operand" "=r")
8276 (zero_extend:DI
8277 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8278 (match_operand:SI 2 "general_operand" "rim"))))
8279 (clobber (reg:CC FLAGS_REG))]
8280 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8281 "and{l}\t{%2, %k0|%k0, %2}"
8282 [(set_attr "type" "alu")
8283 (set_attr "mode" "SI")])
8284
8285 (define_insn "*andsi_2"
8286 [(set (reg FLAGS_REG)
8287 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8288 (match_operand:SI 2 "general_operand" "rim,ri"))
8289 (const_int 0)))
8290 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8291 (and:SI (match_dup 1) (match_dup 2)))]
8292 "ix86_match_ccmode (insn, CCNOmode)
8293 && ix86_binary_operator_ok (AND, SImode, operands)"
8294 "and{l}\t{%2, %0|%0, %2}"
8295 [(set_attr "type" "alu")
8296 (set_attr "mode" "SI")])
8297
8298 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8299 (define_insn "*andsi_2_zext"
8300 [(set (reg FLAGS_REG)
8301 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8302 (match_operand:SI 2 "general_operand" "rim"))
8303 (const_int 0)))
8304 (set (match_operand:DI 0 "register_operand" "=r")
8305 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8306 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8307 && ix86_binary_operator_ok (AND, SImode, operands)"
8308 "and{l}\t{%2, %k0|%k0, %2}"
8309 [(set_attr "type" "alu")
8310 (set_attr "mode" "SI")])
8311
8312 (define_expand "andhi3"
8313 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8314 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8315 (match_operand:HI 2 "general_operand" "")))
8316 (clobber (reg:CC FLAGS_REG))]
8317 "TARGET_HIMODE_MATH"
8318 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8319
8320 (define_insn "*andhi_1"
8321 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8322 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8323 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8324 (clobber (reg:CC FLAGS_REG))]
8325 "ix86_binary_operator_ok (AND, HImode, operands)"
8326 {
8327 switch (get_attr_type (insn))
8328 {
8329 case TYPE_IMOVX:
8330 gcc_assert (CONST_INT_P (operands[2]));
8331 gcc_assert (INTVAL (operands[2]) == 0xff);
8332 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8333
8334 default:
8335 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8336
8337 return "and{w}\t{%2, %0|%0, %2}";
8338 }
8339 }
8340 [(set_attr "type" "alu,alu,imovx")
8341 (set_attr "length_immediate" "*,*,0")
8342 (set_attr "mode" "HI,HI,SI")])
8343
8344 (define_insn "*andhi_2"
8345 [(set (reg FLAGS_REG)
8346 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8347 (match_operand:HI 2 "general_operand" "rim,ri"))
8348 (const_int 0)))
8349 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8350 (and:HI (match_dup 1) (match_dup 2)))]
8351 "ix86_match_ccmode (insn, CCNOmode)
8352 && ix86_binary_operator_ok (AND, HImode, operands)"
8353 "and{w}\t{%2, %0|%0, %2}"
8354 [(set_attr "type" "alu")
8355 (set_attr "mode" "HI")])
8356
8357 (define_expand "andqi3"
8358 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8359 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8360 (match_operand:QI 2 "general_operand" "")))
8361 (clobber (reg:CC FLAGS_REG))]
8362 "TARGET_QIMODE_MATH"
8363 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8364
8365 ;; %%% Potential partial reg stall on alternative 2. What to do?
8366 (define_insn "*andqi_1"
8367 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8368 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8369 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8370 (clobber (reg:CC FLAGS_REG))]
8371 "ix86_binary_operator_ok (AND, QImode, operands)"
8372 "@
8373 and{b}\t{%2, %0|%0, %2}
8374 and{b}\t{%2, %0|%0, %2}
8375 and{l}\t{%k2, %k0|%k0, %k2}"
8376 [(set_attr "type" "alu")
8377 (set_attr "mode" "QI,QI,SI")])
8378
8379 (define_insn "*andqi_1_slp"
8380 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8381 (and:QI (match_dup 0)
8382 (match_operand:QI 1 "general_operand" "qi,qmi")))
8383 (clobber (reg:CC FLAGS_REG))]
8384 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8385 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8386 "and{b}\t{%1, %0|%0, %1}"
8387 [(set_attr "type" "alu1")
8388 (set_attr "mode" "QI")])
8389
8390 (define_insn "*andqi_2_maybe_si"
8391 [(set (reg FLAGS_REG)
8392 (compare (and:QI
8393 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8394 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8395 (const_int 0)))
8396 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8397 (and:QI (match_dup 1) (match_dup 2)))]
8398 "ix86_binary_operator_ok (AND, QImode, operands)
8399 && ix86_match_ccmode (insn,
8400 CONST_INT_P (operands[2])
8401 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8402 {
8403 if (which_alternative == 2)
8404 {
8405 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8406 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8407 return "and{l}\t{%2, %k0|%k0, %2}";
8408 }
8409 return "and{b}\t{%2, %0|%0, %2}";
8410 }
8411 [(set_attr "type" "alu")
8412 (set_attr "mode" "QI,QI,SI")])
8413
8414 (define_insn "*andqi_2"
8415 [(set (reg FLAGS_REG)
8416 (compare (and:QI
8417 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8418 (match_operand:QI 2 "general_operand" "qim,qi"))
8419 (const_int 0)))
8420 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8421 (and:QI (match_dup 1) (match_dup 2)))]
8422 "ix86_match_ccmode (insn, CCNOmode)
8423 && ix86_binary_operator_ok (AND, QImode, operands)"
8424 "and{b}\t{%2, %0|%0, %2}"
8425 [(set_attr "type" "alu")
8426 (set_attr "mode" "QI")])
8427
8428 (define_insn "*andqi_2_slp"
8429 [(set (reg FLAGS_REG)
8430 (compare (and:QI
8431 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8432 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8433 (const_int 0)))
8434 (set (strict_low_part (match_dup 0))
8435 (and:QI (match_dup 0) (match_dup 1)))]
8436 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8437 && ix86_match_ccmode (insn, CCNOmode)
8438 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8439 "and{b}\t{%1, %0|%0, %1}"
8440 [(set_attr "type" "alu1")
8441 (set_attr "mode" "QI")])
8442
8443 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8444 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8445 ;; for a QImode operand, which of course failed.
8446
8447 (define_insn "andqi_ext_0"
8448 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8449 (const_int 8)
8450 (const_int 8))
8451 (and:SI
8452 (zero_extract:SI
8453 (match_operand 1 "ext_register_operand" "0")
8454 (const_int 8)
8455 (const_int 8))
8456 (match_operand 2 "const_int_operand" "n")))
8457 (clobber (reg:CC FLAGS_REG))]
8458 ""
8459 "and{b}\t{%2, %h0|%h0, %2}"
8460 [(set_attr "type" "alu")
8461 (set_attr "length_immediate" "1")
8462 (set_attr "mode" "QI")])
8463
8464 ;; Generated by peephole translating test to and. This shows up
8465 ;; often in fp comparisons.
8466
8467 (define_insn "*andqi_ext_0_cc"
8468 [(set (reg FLAGS_REG)
8469 (compare
8470 (and:SI
8471 (zero_extract:SI
8472 (match_operand 1 "ext_register_operand" "0")
8473 (const_int 8)
8474 (const_int 8))
8475 (match_operand 2 "const_int_operand" "n"))
8476 (const_int 0)))
8477 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8478 (const_int 8)
8479 (const_int 8))
8480 (and:SI
8481 (zero_extract:SI
8482 (match_dup 1)
8483 (const_int 8)
8484 (const_int 8))
8485 (match_dup 2)))]
8486 "ix86_match_ccmode (insn, CCNOmode)"
8487 "and{b}\t{%2, %h0|%h0, %2}"
8488 [(set_attr "type" "alu")
8489 (set_attr "length_immediate" "1")
8490 (set_attr "mode" "QI")])
8491
8492 (define_insn "*andqi_ext_1"
8493 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8494 (const_int 8)
8495 (const_int 8))
8496 (and:SI
8497 (zero_extract:SI
8498 (match_operand 1 "ext_register_operand" "0")
8499 (const_int 8)
8500 (const_int 8))
8501 (zero_extend:SI
8502 (match_operand:QI 2 "general_operand" "Qm"))))
8503 (clobber (reg:CC FLAGS_REG))]
8504 "!TARGET_64BIT"
8505 "and{b}\t{%2, %h0|%h0, %2}"
8506 [(set_attr "type" "alu")
8507 (set_attr "length_immediate" "0")
8508 (set_attr "mode" "QI")])
8509
8510 (define_insn "*andqi_ext_1_rex64"
8511 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8512 (const_int 8)
8513 (const_int 8))
8514 (and:SI
8515 (zero_extract:SI
8516 (match_operand 1 "ext_register_operand" "0")
8517 (const_int 8)
8518 (const_int 8))
8519 (zero_extend:SI
8520 (match_operand 2 "ext_register_operand" "Q"))))
8521 (clobber (reg:CC FLAGS_REG))]
8522 "TARGET_64BIT"
8523 "and{b}\t{%2, %h0|%h0, %2}"
8524 [(set_attr "type" "alu")
8525 (set_attr "length_immediate" "0")
8526 (set_attr "mode" "QI")])
8527
8528 (define_insn "*andqi_ext_2"
8529 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8530 (const_int 8)
8531 (const_int 8))
8532 (and:SI
8533 (zero_extract:SI
8534 (match_operand 1 "ext_register_operand" "%0")
8535 (const_int 8)
8536 (const_int 8))
8537 (zero_extract:SI
8538 (match_operand 2 "ext_register_operand" "Q")
8539 (const_int 8)
8540 (const_int 8))))
8541 (clobber (reg:CC FLAGS_REG))]
8542 ""
8543 "and{b}\t{%h2, %h0|%h0, %h2}"
8544 [(set_attr "type" "alu")
8545 (set_attr "length_immediate" "0")
8546 (set_attr "mode" "QI")])
8547
8548 ;; Convert wide AND instructions with immediate operand to shorter QImode
8549 ;; equivalents when possible.
8550 ;; Don't do the splitting with memory operands, since it introduces risk
8551 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8552 ;; for size, but that can (should?) be handled by generic code instead.
8553 (define_split
8554 [(set (match_operand 0 "register_operand" "")
8555 (and (match_operand 1 "register_operand" "")
8556 (match_operand 2 "const_int_operand" "")))
8557 (clobber (reg:CC FLAGS_REG))]
8558 "reload_completed
8559 && QI_REG_P (operands[0])
8560 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8561 && !(~INTVAL (operands[2]) & ~(255 << 8))
8562 && GET_MODE (operands[0]) != QImode"
8563 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8564 (and:SI (zero_extract:SI (match_dup 1)
8565 (const_int 8) (const_int 8))
8566 (match_dup 2)))
8567 (clobber (reg:CC FLAGS_REG))])]
8568 "operands[0] = gen_lowpart (SImode, operands[0]);
8569 operands[1] = gen_lowpart (SImode, operands[1]);
8570 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8571
8572 ;; Since AND can be encoded with sign extended immediate, this is only
8573 ;; profitable when 7th bit is not set.
8574 (define_split
8575 [(set (match_operand 0 "register_operand" "")
8576 (and (match_operand 1 "general_operand" "")
8577 (match_operand 2 "const_int_operand" "")))
8578 (clobber (reg:CC FLAGS_REG))]
8579 "reload_completed
8580 && ANY_QI_REG_P (operands[0])
8581 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8582 && !(~INTVAL (operands[2]) & ~255)
8583 && !(INTVAL (operands[2]) & 128)
8584 && GET_MODE (operands[0]) != QImode"
8585 [(parallel [(set (strict_low_part (match_dup 0))
8586 (and:QI (match_dup 1)
8587 (match_dup 2)))
8588 (clobber (reg:CC FLAGS_REG))])]
8589 "operands[0] = gen_lowpart (QImode, operands[0]);
8590 operands[1] = gen_lowpart (QImode, operands[1]);
8591 operands[2] = gen_lowpart (QImode, operands[2]);")
8592 \f
8593 ;; Logical inclusive OR instructions
8594
8595 ;; %%% This used to optimize known byte-wide and operations to memory.
8596 ;; If this is considered useful, it should be done with splitters.
8597
8598 (define_expand "iordi3"
8599 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8600 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8601 (match_operand:DI 2 "x86_64_general_operand" "")))
8602 (clobber (reg:CC FLAGS_REG))]
8603 "TARGET_64BIT"
8604 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8605
8606 (define_insn "*iordi_1_rex64"
8607 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8608 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8609 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8610 (clobber (reg:CC FLAGS_REG))]
8611 "TARGET_64BIT
8612 && ix86_binary_operator_ok (IOR, DImode, operands)"
8613 "or{q}\t{%2, %0|%0, %2}"
8614 [(set_attr "type" "alu")
8615 (set_attr "mode" "DI")])
8616
8617 (define_insn "*iordi_2_rex64"
8618 [(set (reg FLAGS_REG)
8619 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8620 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8621 (const_int 0)))
8622 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8623 (ior:DI (match_dup 1) (match_dup 2)))]
8624 "TARGET_64BIT
8625 && ix86_match_ccmode (insn, CCNOmode)
8626 && ix86_binary_operator_ok (IOR, DImode, operands)"
8627 "or{q}\t{%2, %0|%0, %2}"
8628 [(set_attr "type" "alu")
8629 (set_attr "mode" "DI")])
8630
8631 (define_insn "*iordi_3_rex64"
8632 [(set (reg FLAGS_REG)
8633 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8634 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8635 (const_int 0)))
8636 (clobber (match_scratch:DI 0 "=r"))]
8637 "TARGET_64BIT
8638 && ix86_match_ccmode (insn, CCNOmode)
8639 && ix86_binary_operator_ok (IOR, DImode, operands)"
8640 "or{q}\t{%2, %0|%0, %2}"
8641 [(set_attr "type" "alu")
8642 (set_attr "mode" "DI")])
8643
8644
8645 (define_expand "iorsi3"
8646 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8647 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8648 (match_operand:SI 2 "general_operand" "")))
8649 (clobber (reg:CC FLAGS_REG))]
8650 ""
8651 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8652
8653 (define_insn "*iorsi_1"
8654 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8655 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8656 (match_operand:SI 2 "general_operand" "ri,rmi")))
8657 (clobber (reg:CC FLAGS_REG))]
8658 "ix86_binary_operator_ok (IOR, SImode, operands)"
8659 "or{l}\t{%2, %0|%0, %2}"
8660 [(set_attr "type" "alu")
8661 (set_attr "mode" "SI")])
8662
8663 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8664 (define_insn "*iorsi_1_zext"
8665 [(set (match_operand:DI 0 "register_operand" "=rm")
8666 (zero_extend:DI
8667 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8668 (match_operand:SI 2 "general_operand" "rim"))))
8669 (clobber (reg:CC FLAGS_REG))]
8670 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8671 "or{l}\t{%2, %k0|%k0, %2}"
8672 [(set_attr "type" "alu")
8673 (set_attr "mode" "SI")])
8674
8675 (define_insn "*iorsi_1_zext_imm"
8676 [(set (match_operand:DI 0 "register_operand" "=rm")
8677 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8678 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8679 (clobber (reg:CC FLAGS_REG))]
8680 "TARGET_64BIT"
8681 "or{l}\t{%2, %k0|%k0, %2}"
8682 [(set_attr "type" "alu")
8683 (set_attr "mode" "SI")])
8684
8685 (define_insn "*iorsi_2"
8686 [(set (reg FLAGS_REG)
8687 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8688 (match_operand:SI 2 "general_operand" "rim,ri"))
8689 (const_int 0)))
8690 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8691 (ior:SI (match_dup 1) (match_dup 2)))]
8692 "ix86_match_ccmode (insn, CCNOmode)
8693 && ix86_binary_operator_ok (IOR, SImode, operands)"
8694 "or{l}\t{%2, %0|%0, %2}"
8695 [(set_attr "type" "alu")
8696 (set_attr "mode" "SI")])
8697
8698 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8699 ;; ??? Special case for immediate operand is missing - it is tricky.
8700 (define_insn "*iorsi_2_zext"
8701 [(set (reg FLAGS_REG)
8702 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8703 (match_operand:SI 2 "general_operand" "rim"))
8704 (const_int 0)))
8705 (set (match_operand:DI 0 "register_operand" "=r")
8706 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8707 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8708 && ix86_binary_operator_ok (IOR, SImode, operands)"
8709 "or{l}\t{%2, %k0|%k0, %2}"
8710 [(set_attr "type" "alu")
8711 (set_attr "mode" "SI")])
8712
8713 (define_insn "*iorsi_2_zext_imm"
8714 [(set (reg FLAGS_REG)
8715 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8716 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8717 (const_int 0)))
8718 (set (match_operand:DI 0 "register_operand" "=r")
8719 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8720 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8721 && ix86_binary_operator_ok (IOR, SImode, operands)"
8722 "or{l}\t{%2, %k0|%k0, %2}"
8723 [(set_attr "type" "alu")
8724 (set_attr "mode" "SI")])
8725
8726 (define_insn "*iorsi_3"
8727 [(set (reg FLAGS_REG)
8728 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8729 (match_operand:SI 2 "general_operand" "rim"))
8730 (const_int 0)))
8731 (clobber (match_scratch:SI 0 "=r"))]
8732 "ix86_match_ccmode (insn, CCNOmode)
8733 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8734 "or{l}\t{%2, %0|%0, %2}"
8735 [(set_attr "type" "alu")
8736 (set_attr "mode" "SI")])
8737
8738 (define_expand "iorhi3"
8739 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8740 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8741 (match_operand:HI 2 "general_operand" "")))
8742 (clobber (reg:CC FLAGS_REG))]
8743 "TARGET_HIMODE_MATH"
8744 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8745
8746 (define_insn "*iorhi_1"
8747 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8748 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8749 (match_operand:HI 2 "general_operand" "rmi,ri")))
8750 (clobber (reg:CC FLAGS_REG))]
8751 "ix86_binary_operator_ok (IOR, HImode, operands)"
8752 "or{w}\t{%2, %0|%0, %2}"
8753 [(set_attr "type" "alu")
8754 (set_attr "mode" "HI")])
8755
8756 (define_insn "*iorhi_2"
8757 [(set (reg FLAGS_REG)
8758 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8759 (match_operand:HI 2 "general_operand" "rim,ri"))
8760 (const_int 0)))
8761 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8762 (ior:HI (match_dup 1) (match_dup 2)))]
8763 "ix86_match_ccmode (insn, CCNOmode)
8764 && ix86_binary_operator_ok (IOR, HImode, operands)"
8765 "or{w}\t{%2, %0|%0, %2}"
8766 [(set_attr "type" "alu")
8767 (set_attr "mode" "HI")])
8768
8769 (define_insn "*iorhi_3"
8770 [(set (reg FLAGS_REG)
8771 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8772 (match_operand:HI 2 "general_operand" "rim"))
8773 (const_int 0)))
8774 (clobber (match_scratch:HI 0 "=r"))]
8775 "ix86_match_ccmode (insn, CCNOmode)
8776 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8777 "or{w}\t{%2, %0|%0, %2}"
8778 [(set_attr "type" "alu")
8779 (set_attr "mode" "HI")])
8780
8781 (define_expand "iorqi3"
8782 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8783 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8784 (match_operand:QI 2 "general_operand" "")))
8785 (clobber (reg:CC FLAGS_REG))]
8786 "TARGET_QIMODE_MATH"
8787 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8788
8789 ;; %%% Potential partial reg stall on alternative 2. What to do?
8790 (define_insn "*iorqi_1"
8791 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8792 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8793 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8794 (clobber (reg:CC FLAGS_REG))]
8795 "ix86_binary_operator_ok (IOR, QImode, operands)"
8796 "@
8797 or{b}\t{%2, %0|%0, %2}
8798 or{b}\t{%2, %0|%0, %2}
8799 or{l}\t{%k2, %k0|%k0, %k2}"
8800 [(set_attr "type" "alu")
8801 (set_attr "mode" "QI,QI,SI")])
8802
8803 (define_insn "*iorqi_1_slp"
8804 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8805 (ior:QI (match_dup 0)
8806 (match_operand:QI 1 "general_operand" "qmi,qi")))
8807 (clobber (reg:CC FLAGS_REG))]
8808 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8809 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8810 "or{b}\t{%1, %0|%0, %1}"
8811 [(set_attr "type" "alu1")
8812 (set_attr "mode" "QI")])
8813
8814 (define_insn "*iorqi_2"
8815 [(set (reg FLAGS_REG)
8816 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8817 (match_operand:QI 2 "general_operand" "qim,qi"))
8818 (const_int 0)))
8819 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8820 (ior:QI (match_dup 1) (match_dup 2)))]
8821 "ix86_match_ccmode (insn, CCNOmode)
8822 && ix86_binary_operator_ok (IOR, QImode, operands)"
8823 "or{b}\t{%2, %0|%0, %2}"
8824 [(set_attr "type" "alu")
8825 (set_attr "mode" "QI")])
8826
8827 (define_insn "*iorqi_2_slp"
8828 [(set (reg FLAGS_REG)
8829 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8830 (match_operand:QI 1 "general_operand" "qim,qi"))
8831 (const_int 0)))
8832 (set (strict_low_part (match_dup 0))
8833 (ior:QI (match_dup 0) (match_dup 1)))]
8834 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8835 && ix86_match_ccmode (insn, CCNOmode)
8836 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8837 "or{b}\t{%1, %0|%0, %1}"
8838 [(set_attr "type" "alu1")
8839 (set_attr "mode" "QI")])
8840
8841 (define_insn "*iorqi_3"
8842 [(set (reg FLAGS_REG)
8843 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8844 (match_operand:QI 2 "general_operand" "qim"))
8845 (const_int 0)))
8846 (clobber (match_scratch:QI 0 "=q"))]
8847 "ix86_match_ccmode (insn, CCNOmode)
8848 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8849 "or{b}\t{%2, %0|%0, %2}"
8850 [(set_attr "type" "alu")
8851 (set_attr "mode" "QI")])
8852
8853 (define_insn "iorqi_ext_0"
8854 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8855 (const_int 8)
8856 (const_int 8))
8857 (ior:SI
8858 (zero_extract:SI
8859 (match_operand 1 "ext_register_operand" "0")
8860 (const_int 8)
8861 (const_int 8))
8862 (match_operand 2 "const_int_operand" "n")))
8863 (clobber (reg:CC FLAGS_REG))]
8864 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8865 "or{b}\t{%2, %h0|%h0, %2}"
8866 [(set_attr "type" "alu")
8867 (set_attr "length_immediate" "1")
8868 (set_attr "mode" "QI")])
8869
8870 (define_insn "*iorqi_ext_1"
8871 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8872 (const_int 8)
8873 (const_int 8))
8874 (ior:SI
8875 (zero_extract:SI
8876 (match_operand 1 "ext_register_operand" "0")
8877 (const_int 8)
8878 (const_int 8))
8879 (zero_extend:SI
8880 (match_operand:QI 2 "general_operand" "Qm"))))
8881 (clobber (reg:CC FLAGS_REG))]
8882 "!TARGET_64BIT
8883 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8884 "or{b}\t{%2, %h0|%h0, %2}"
8885 [(set_attr "type" "alu")
8886 (set_attr "length_immediate" "0")
8887 (set_attr "mode" "QI")])
8888
8889 (define_insn "*iorqi_ext_1_rex64"
8890 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8891 (const_int 8)
8892 (const_int 8))
8893 (ior:SI
8894 (zero_extract:SI
8895 (match_operand 1 "ext_register_operand" "0")
8896 (const_int 8)
8897 (const_int 8))
8898 (zero_extend:SI
8899 (match_operand 2 "ext_register_operand" "Q"))))
8900 (clobber (reg:CC FLAGS_REG))]
8901 "TARGET_64BIT
8902 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8903 "or{b}\t{%2, %h0|%h0, %2}"
8904 [(set_attr "type" "alu")
8905 (set_attr "length_immediate" "0")
8906 (set_attr "mode" "QI")])
8907
8908 (define_insn "*iorqi_ext_2"
8909 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8910 (const_int 8)
8911 (const_int 8))
8912 (ior:SI
8913 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8914 (const_int 8)
8915 (const_int 8))
8916 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8917 (const_int 8)
8918 (const_int 8))))
8919 (clobber (reg:CC FLAGS_REG))]
8920 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8921 "ior{b}\t{%h2, %h0|%h0, %h2}"
8922 [(set_attr "type" "alu")
8923 (set_attr "length_immediate" "0")
8924 (set_attr "mode" "QI")])
8925
8926 (define_split
8927 [(set (match_operand 0 "register_operand" "")
8928 (ior (match_operand 1 "register_operand" "")
8929 (match_operand 2 "const_int_operand" "")))
8930 (clobber (reg:CC FLAGS_REG))]
8931 "reload_completed
8932 && QI_REG_P (operands[0])
8933 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8934 && !(INTVAL (operands[2]) & ~(255 << 8))
8935 && GET_MODE (operands[0]) != QImode"
8936 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8937 (ior:SI (zero_extract:SI (match_dup 1)
8938 (const_int 8) (const_int 8))
8939 (match_dup 2)))
8940 (clobber (reg:CC FLAGS_REG))])]
8941 "operands[0] = gen_lowpart (SImode, operands[0]);
8942 operands[1] = gen_lowpart (SImode, operands[1]);
8943 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8944
8945 ;; Since OR can be encoded with sign extended immediate, this is only
8946 ;; profitable when 7th bit is set.
8947 (define_split
8948 [(set (match_operand 0 "register_operand" "")
8949 (ior (match_operand 1 "general_operand" "")
8950 (match_operand 2 "const_int_operand" "")))
8951 (clobber (reg:CC FLAGS_REG))]
8952 "reload_completed
8953 && ANY_QI_REG_P (operands[0])
8954 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8955 && !(INTVAL (operands[2]) & ~255)
8956 && (INTVAL (operands[2]) & 128)
8957 && GET_MODE (operands[0]) != QImode"
8958 [(parallel [(set (strict_low_part (match_dup 0))
8959 (ior:QI (match_dup 1)
8960 (match_dup 2)))
8961 (clobber (reg:CC FLAGS_REG))])]
8962 "operands[0] = gen_lowpart (QImode, operands[0]);
8963 operands[1] = gen_lowpart (QImode, operands[1]);
8964 operands[2] = gen_lowpart (QImode, operands[2]);")
8965 \f
8966 ;; Logical XOR instructions
8967
8968 ;; %%% This used to optimize known byte-wide and operations to memory.
8969 ;; If this is considered useful, it should be done with splitters.
8970
8971 (define_expand "xordi3"
8972 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8973 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8974 (match_operand:DI 2 "x86_64_general_operand" "")))
8975 (clobber (reg:CC FLAGS_REG))]
8976 "TARGET_64BIT"
8977 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8978
8979 (define_insn "*xordi_1_rex64"
8980 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8981 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8982 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8983 (clobber (reg:CC FLAGS_REG))]
8984 "TARGET_64BIT
8985 && ix86_binary_operator_ok (XOR, DImode, operands)"
8986 "@
8987 xor{q}\t{%2, %0|%0, %2}
8988 xor{q}\t{%2, %0|%0, %2}"
8989 [(set_attr "type" "alu")
8990 (set_attr "mode" "DI,DI")])
8991
8992 (define_insn "*xordi_2_rex64"
8993 [(set (reg FLAGS_REG)
8994 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8995 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8996 (const_int 0)))
8997 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8998 (xor:DI (match_dup 1) (match_dup 2)))]
8999 "TARGET_64BIT
9000 && ix86_match_ccmode (insn, CCNOmode)
9001 && ix86_binary_operator_ok (XOR, DImode, operands)"
9002 "@
9003 xor{q}\t{%2, %0|%0, %2}
9004 xor{q}\t{%2, %0|%0, %2}"
9005 [(set_attr "type" "alu")
9006 (set_attr "mode" "DI,DI")])
9007
9008 (define_insn "*xordi_3_rex64"
9009 [(set (reg FLAGS_REG)
9010 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9011 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9012 (const_int 0)))
9013 (clobber (match_scratch:DI 0 "=r"))]
9014 "TARGET_64BIT
9015 && ix86_match_ccmode (insn, CCNOmode)
9016 && ix86_binary_operator_ok (XOR, DImode, operands)"
9017 "xor{q}\t{%2, %0|%0, %2}"
9018 [(set_attr "type" "alu")
9019 (set_attr "mode" "DI")])
9020
9021 (define_expand "xorsi3"
9022 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9023 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9024 (match_operand:SI 2 "general_operand" "")))
9025 (clobber (reg:CC FLAGS_REG))]
9026 ""
9027 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9028
9029 (define_insn "*xorsi_1"
9030 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9031 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9032 (match_operand:SI 2 "general_operand" "ri,rm")))
9033 (clobber (reg:CC FLAGS_REG))]
9034 "ix86_binary_operator_ok (XOR, SImode, operands)"
9035 "xor{l}\t{%2, %0|%0, %2}"
9036 [(set_attr "type" "alu")
9037 (set_attr "mode" "SI")])
9038
9039 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9040 ;; Add speccase for immediates
9041 (define_insn "*xorsi_1_zext"
9042 [(set (match_operand:DI 0 "register_operand" "=r")
9043 (zero_extend:DI
9044 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9045 (match_operand:SI 2 "general_operand" "rim"))))
9046 (clobber (reg:CC FLAGS_REG))]
9047 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9048 "xor{l}\t{%2, %k0|%k0, %2}"
9049 [(set_attr "type" "alu")
9050 (set_attr "mode" "SI")])
9051
9052 (define_insn "*xorsi_1_zext_imm"
9053 [(set (match_operand:DI 0 "register_operand" "=r")
9054 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9055 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9056 (clobber (reg:CC FLAGS_REG))]
9057 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9058 "xor{l}\t{%2, %k0|%k0, %2}"
9059 [(set_attr "type" "alu")
9060 (set_attr "mode" "SI")])
9061
9062 (define_insn "*xorsi_2"
9063 [(set (reg FLAGS_REG)
9064 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9065 (match_operand:SI 2 "general_operand" "rim,ri"))
9066 (const_int 0)))
9067 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9068 (xor:SI (match_dup 1) (match_dup 2)))]
9069 "ix86_match_ccmode (insn, CCNOmode)
9070 && ix86_binary_operator_ok (XOR, SImode, operands)"
9071 "xor{l}\t{%2, %0|%0, %2}"
9072 [(set_attr "type" "alu")
9073 (set_attr "mode" "SI")])
9074
9075 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9076 ;; ??? Special case for immediate operand is missing - it is tricky.
9077 (define_insn "*xorsi_2_zext"
9078 [(set (reg FLAGS_REG)
9079 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9080 (match_operand:SI 2 "general_operand" "rim"))
9081 (const_int 0)))
9082 (set (match_operand:DI 0 "register_operand" "=r")
9083 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9084 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9085 && ix86_binary_operator_ok (XOR, SImode, operands)"
9086 "xor{l}\t{%2, %k0|%k0, %2}"
9087 [(set_attr "type" "alu")
9088 (set_attr "mode" "SI")])
9089
9090 (define_insn "*xorsi_2_zext_imm"
9091 [(set (reg FLAGS_REG)
9092 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9093 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9094 (const_int 0)))
9095 (set (match_operand:DI 0 "register_operand" "=r")
9096 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9097 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9098 && ix86_binary_operator_ok (XOR, SImode, operands)"
9099 "xor{l}\t{%2, %k0|%k0, %2}"
9100 [(set_attr "type" "alu")
9101 (set_attr "mode" "SI")])
9102
9103 (define_insn "*xorsi_3"
9104 [(set (reg FLAGS_REG)
9105 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9106 (match_operand:SI 2 "general_operand" "rim"))
9107 (const_int 0)))
9108 (clobber (match_scratch:SI 0 "=r"))]
9109 "ix86_match_ccmode (insn, CCNOmode)
9110 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9111 "xor{l}\t{%2, %0|%0, %2}"
9112 [(set_attr "type" "alu")
9113 (set_attr "mode" "SI")])
9114
9115 (define_expand "xorhi3"
9116 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9117 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9118 (match_operand:HI 2 "general_operand" "")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "TARGET_HIMODE_MATH"
9121 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9122
9123 (define_insn "*xorhi_1"
9124 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9125 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9126 (match_operand:HI 2 "general_operand" "rmi,ri")))
9127 (clobber (reg:CC FLAGS_REG))]
9128 "ix86_binary_operator_ok (XOR, HImode, operands)"
9129 "xor{w}\t{%2, %0|%0, %2}"
9130 [(set_attr "type" "alu")
9131 (set_attr "mode" "HI")])
9132
9133 (define_insn "*xorhi_2"
9134 [(set (reg FLAGS_REG)
9135 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9136 (match_operand:HI 2 "general_operand" "rim,ri"))
9137 (const_int 0)))
9138 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9139 (xor:HI (match_dup 1) (match_dup 2)))]
9140 "ix86_match_ccmode (insn, CCNOmode)
9141 && ix86_binary_operator_ok (XOR, HImode, operands)"
9142 "xor{w}\t{%2, %0|%0, %2}"
9143 [(set_attr "type" "alu")
9144 (set_attr "mode" "HI")])
9145
9146 (define_insn "*xorhi_3"
9147 [(set (reg FLAGS_REG)
9148 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9149 (match_operand:HI 2 "general_operand" "rim"))
9150 (const_int 0)))
9151 (clobber (match_scratch:HI 0 "=r"))]
9152 "ix86_match_ccmode (insn, CCNOmode)
9153 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9154 "xor{w}\t{%2, %0|%0, %2}"
9155 [(set_attr "type" "alu")
9156 (set_attr "mode" "HI")])
9157
9158 (define_expand "xorqi3"
9159 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9160 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9161 (match_operand:QI 2 "general_operand" "")))
9162 (clobber (reg:CC FLAGS_REG))]
9163 "TARGET_QIMODE_MATH"
9164 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9165
9166 ;; %%% Potential partial reg stall on alternative 2. What to do?
9167 (define_insn "*xorqi_1"
9168 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9169 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9170 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9171 (clobber (reg:CC FLAGS_REG))]
9172 "ix86_binary_operator_ok (XOR, QImode, operands)"
9173 "@
9174 xor{b}\t{%2, %0|%0, %2}
9175 xor{b}\t{%2, %0|%0, %2}
9176 xor{l}\t{%k2, %k0|%k0, %k2}"
9177 [(set_attr "type" "alu")
9178 (set_attr "mode" "QI,QI,SI")])
9179
9180 (define_insn "*xorqi_1_slp"
9181 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9182 (xor:QI (match_dup 0)
9183 (match_operand:QI 1 "general_operand" "qi,qmi")))
9184 (clobber (reg:CC FLAGS_REG))]
9185 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9186 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9187 "xor{b}\t{%1, %0|%0, %1}"
9188 [(set_attr "type" "alu1")
9189 (set_attr "mode" "QI")])
9190
9191 (define_insn "xorqi_ext_0"
9192 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9193 (const_int 8)
9194 (const_int 8))
9195 (xor:SI
9196 (zero_extract:SI
9197 (match_operand 1 "ext_register_operand" "0")
9198 (const_int 8)
9199 (const_int 8))
9200 (match_operand 2 "const_int_operand" "n")))
9201 (clobber (reg:CC FLAGS_REG))]
9202 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9203 "xor{b}\t{%2, %h0|%h0, %2}"
9204 [(set_attr "type" "alu")
9205 (set_attr "length_immediate" "1")
9206 (set_attr "mode" "QI")])
9207
9208 (define_insn "*xorqi_ext_1"
9209 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9210 (const_int 8)
9211 (const_int 8))
9212 (xor:SI
9213 (zero_extract:SI
9214 (match_operand 1 "ext_register_operand" "0")
9215 (const_int 8)
9216 (const_int 8))
9217 (zero_extend:SI
9218 (match_operand:QI 2 "general_operand" "Qm"))))
9219 (clobber (reg:CC FLAGS_REG))]
9220 "!TARGET_64BIT
9221 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9222 "xor{b}\t{%2, %h0|%h0, %2}"
9223 [(set_attr "type" "alu")
9224 (set_attr "length_immediate" "0")
9225 (set_attr "mode" "QI")])
9226
9227 (define_insn "*xorqi_ext_1_rex64"
9228 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9229 (const_int 8)
9230 (const_int 8))
9231 (xor:SI
9232 (zero_extract:SI
9233 (match_operand 1 "ext_register_operand" "0")
9234 (const_int 8)
9235 (const_int 8))
9236 (zero_extend:SI
9237 (match_operand 2 "ext_register_operand" "Q"))))
9238 (clobber (reg:CC FLAGS_REG))]
9239 "TARGET_64BIT
9240 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9241 "xor{b}\t{%2, %h0|%h0, %2}"
9242 [(set_attr "type" "alu")
9243 (set_attr "length_immediate" "0")
9244 (set_attr "mode" "QI")])
9245
9246 (define_insn "*xorqi_ext_2"
9247 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9248 (const_int 8)
9249 (const_int 8))
9250 (xor:SI
9251 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9252 (const_int 8)
9253 (const_int 8))
9254 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9255 (const_int 8)
9256 (const_int 8))))
9257 (clobber (reg:CC FLAGS_REG))]
9258 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9259 "xor{b}\t{%h2, %h0|%h0, %h2}"
9260 [(set_attr "type" "alu")
9261 (set_attr "length_immediate" "0")
9262 (set_attr "mode" "QI")])
9263
9264 (define_insn "*xorqi_cc_1"
9265 [(set (reg FLAGS_REG)
9266 (compare
9267 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9268 (match_operand:QI 2 "general_operand" "qim,qi"))
9269 (const_int 0)))
9270 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9271 (xor:QI (match_dup 1) (match_dup 2)))]
9272 "ix86_match_ccmode (insn, CCNOmode)
9273 && ix86_binary_operator_ok (XOR, QImode, operands)"
9274 "xor{b}\t{%2, %0|%0, %2}"
9275 [(set_attr "type" "alu")
9276 (set_attr "mode" "QI")])
9277
9278 (define_insn "*xorqi_2_slp"
9279 [(set (reg FLAGS_REG)
9280 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9281 (match_operand:QI 1 "general_operand" "qim,qi"))
9282 (const_int 0)))
9283 (set (strict_low_part (match_dup 0))
9284 (xor:QI (match_dup 0) (match_dup 1)))]
9285 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9286 && ix86_match_ccmode (insn, CCNOmode)
9287 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9288 "xor{b}\t{%1, %0|%0, %1}"
9289 [(set_attr "type" "alu1")
9290 (set_attr "mode" "QI")])
9291
9292 (define_insn "*xorqi_cc_2"
9293 [(set (reg FLAGS_REG)
9294 (compare
9295 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9296 (match_operand:QI 2 "general_operand" "qim"))
9297 (const_int 0)))
9298 (clobber (match_scratch:QI 0 "=q"))]
9299 "ix86_match_ccmode (insn, CCNOmode)
9300 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9301 "xor{b}\t{%2, %0|%0, %2}"
9302 [(set_attr "type" "alu")
9303 (set_attr "mode" "QI")])
9304
9305 (define_insn "*xorqi_cc_ext_1"
9306 [(set (reg FLAGS_REG)
9307 (compare
9308 (xor:SI
9309 (zero_extract:SI
9310 (match_operand 1 "ext_register_operand" "0")
9311 (const_int 8)
9312 (const_int 8))
9313 (match_operand:QI 2 "general_operand" "qmn"))
9314 (const_int 0)))
9315 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9316 (const_int 8)
9317 (const_int 8))
9318 (xor:SI
9319 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9320 (match_dup 2)))]
9321 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9322 "xor{b}\t{%2, %h0|%h0, %2}"
9323 [(set_attr "type" "alu")
9324 (set_attr "mode" "QI")])
9325
9326 (define_insn "*xorqi_cc_ext_1_rex64"
9327 [(set (reg FLAGS_REG)
9328 (compare
9329 (xor:SI
9330 (zero_extract:SI
9331 (match_operand 1 "ext_register_operand" "0")
9332 (const_int 8)
9333 (const_int 8))
9334 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9335 (const_int 0)))
9336 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9337 (const_int 8)
9338 (const_int 8))
9339 (xor:SI
9340 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9341 (match_dup 2)))]
9342 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9343 "xor{b}\t{%2, %h0|%h0, %2}"
9344 [(set_attr "type" "alu")
9345 (set_attr "mode" "QI")])
9346
9347 (define_expand "xorqi_cc_ext_1"
9348 [(parallel [
9349 (set (reg:CCNO FLAGS_REG)
9350 (compare:CCNO
9351 (xor:SI
9352 (zero_extract:SI
9353 (match_operand 1 "ext_register_operand" "")
9354 (const_int 8)
9355 (const_int 8))
9356 (match_operand:QI 2 "general_operand" ""))
9357 (const_int 0)))
9358 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9359 (const_int 8)
9360 (const_int 8))
9361 (xor:SI
9362 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9363 (match_dup 2)))])]
9364 ""
9365 "")
9366
9367 (define_split
9368 [(set (match_operand 0 "register_operand" "")
9369 (xor (match_operand 1 "register_operand" "")
9370 (match_operand 2 "const_int_operand" "")))
9371 (clobber (reg:CC FLAGS_REG))]
9372 "reload_completed
9373 && QI_REG_P (operands[0])
9374 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9375 && !(INTVAL (operands[2]) & ~(255 << 8))
9376 && GET_MODE (operands[0]) != QImode"
9377 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9378 (xor:SI (zero_extract:SI (match_dup 1)
9379 (const_int 8) (const_int 8))
9380 (match_dup 2)))
9381 (clobber (reg:CC FLAGS_REG))])]
9382 "operands[0] = gen_lowpart (SImode, operands[0]);
9383 operands[1] = gen_lowpart (SImode, operands[1]);
9384 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9385
9386 ;; Since XOR can be encoded with sign extended immediate, this is only
9387 ;; profitable when 7th bit is set.
9388 (define_split
9389 [(set (match_operand 0 "register_operand" "")
9390 (xor (match_operand 1 "general_operand" "")
9391 (match_operand 2 "const_int_operand" "")))
9392 (clobber (reg:CC FLAGS_REG))]
9393 "reload_completed
9394 && ANY_QI_REG_P (operands[0])
9395 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9396 && !(INTVAL (operands[2]) & ~255)
9397 && (INTVAL (operands[2]) & 128)
9398 && GET_MODE (operands[0]) != QImode"
9399 [(parallel [(set (strict_low_part (match_dup 0))
9400 (xor:QI (match_dup 1)
9401 (match_dup 2)))
9402 (clobber (reg:CC FLAGS_REG))])]
9403 "operands[0] = gen_lowpart (QImode, operands[0]);
9404 operands[1] = gen_lowpart (QImode, operands[1]);
9405 operands[2] = gen_lowpart (QImode, operands[2]);")
9406 \f
9407 ;; Negation instructions
9408
9409 (define_expand "negti2"
9410 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9411 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9412 (clobber (reg:CC FLAGS_REG))])]
9413 "TARGET_64BIT"
9414 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9415
9416 (define_insn "*negti2_1"
9417 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9418 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9419 (clobber (reg:CC FLAGS_REG))]
9420 "TARGET_64BIT
9421 && ix86_unary_operator_ok (NEG, TImode, operands)"
9422 "#")
9423
9424 (define_split
9425 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9426 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9427 (clobber (reg:CC FLAGS_REG))]
9428 "TARGET_64BIT && reload_completed"
9429 [(parallel
9430 [(set (reg:CCZ FLAGS_REG)
9431 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9432 (set (match_dup 0) (neg:DI (match_dup 2)))])
9433 (parallel
9434 [(set (match_dup 1)
9435 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9436 (match_dup 3))
9437 (const_int 0)))
9438 (clobber (reg:CC FLAGS_REG))])
9439 (parallel
9440 [(set (match_dup 1)
9441 (neg:DI (match_dup 1)))
9442 (clobber (reg:CC FLAGS_REG))])]
9443 "split_ti (operands+1, 1, operands+2, operands+3);
9444 split_ti (operands+0, 1, operands+0, operands+1);")
9445
9446 (define_expand "negdi2"
9447 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9448 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9449 (clobber (reg:CC FLAGS_REG))])]
9450 ""
9451 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9452
9453 (define_insn "*negdi2_1"
9454 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9455 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9456 (clobber (reg:CC FLAGS_REG))]
9457 "!TARGET_64BIT
9458 && ix86_unary_operator_ok (NEG, DImode, operands)"
9459 "#")
9460
9461 (define_split
9462 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9463 (neg:DI (match_operand:DI 1 "general_operand" "")))
9464 (clobber (reg:CC FLAGS_REG))]
9465 "!TARGET_64BIT && reload_completed"
9466 [(parallel
9467 [(set (reg:CCZ FLAGS_REG)
9468 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9469 (set (match_dup 0) (neg:SI (match_dup 2)))])
9470 (parallel
9471 [(set (match_dup 1)
9472 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9473 (match_dup 3))
9474 (const_int 0)))
9475 (clobber (reg:CC FLAGS_REG))])
9476 (parallel
9477 [(set (match_dup 1)
9478 (neg:SI (match_dup 1)))
9479 (clobber (reg:CC FLAGS_REG))])]
9480 "split_di (operands+1, 1, operands+2, operands+3);
9481 split_di (operands+0, 1, operands+0, operands+1);")
9482
9483 (define_insn "*negdi2_1_rex64"
9484 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9485 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9486 (clobber (reg:CC FLAGS_REG))]
9487 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9488 "neg{q}\t%0"
9489 [(set_attr "type" "negnot")
9490 (set_attr "mode" "DI")])
9491
9492 ;; The problem with neg is that it does not perform (compare x 0),
9493 ;; it really performs (compare 0 x), which leaves us with the zero
9494 ;; flag being the only useful item.
9495
9496 (define_insn "*negdi2_cmpz_rex64"
9497 [(set (reg:CCZ FLAGS_REG)
9498 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9499 (const_int 0)))
9500 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9501 (neg:DI (match_dup 1)))]
9502 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9503 "neg{q}\t%0"
9504 [(set_attr "type" "negnot")
9505 (set_attr "mode" "DI")])
9506
9507
9508 (define_expand "negsi2"
9509 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9510 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9511 (clobber (reg:CC FLAGS_REG))])]
9512 ""
9513 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9514
9515 (define_insn "*negsi2_1"
9516 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9517 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9518 (clobber (reg:CC FLAGS_REG))]
9519 "ix86_unary_operator_ok (NEG, SImode, operands)"
9520 "neg{l}\t%0"
9521 [(set_attr "type" "negnot")
9522 (set_attr "mode" "SI")])
9523
9524 ;; Combine is quite creative about this pattern.
9525 (define_insn "*negsi2_1_zext"
9526 [(set (match_operand:DI 0 "register_operand" "=r")
9527 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9528 (const_int 32)))
9529 (const_int 32)))
9530 (clobber (reg:CC FLAGS_REG))]
9531 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9532 "neg{l}\t%k0"
9533 [(set_attr "type" "negnot")
9534 (set_attr "mode" "SI")])
9535
9536 ;; The problem with neg is that it does not perform (compare x 0),
9537 ;; it really performs (compare 0 x), which leaves us with the zero
9538 ;; flag being the only useful item.
9539
9540 (define_insn "*negsi2_cmpz"
9541 [(set (reg:CCZ FLAGS_REG)
9542 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9543 (const_int 0)))
9544 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9545 (neg:SI (match_dup 1)))]
9546 "ix86_unary_operator_ok (NEG, SImode, operands)"
9547 "neg{l}\t%0"
9548 [(set_attr "type" "negnot")
9549 (set_attr "mode" "SI")])
9550
9551 (define_insn "*negsi2_cmpz_zext"
9552 [(set (reg:CCZ FLAGS_REG)
9553 (compare:CCZ (lshiftrt:DI
9554 (neg:DI (ashift:DI
9555 (match_operand:DI 1 "register_operand" "0")
9556 (const_int 32)))
9557 (const_int 32))
9558 (const_int 0)))
9559 (set (match_operand:DI 0 "register_operand" "=r")
9560 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9561 (const_int 32)))
9562 (const_int 32)))]
9563 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9564 "neg{l}\t%k0"
9565 [(set_attr "type" "negnot")
9566 (set_attr "mode" "SI")])
9567
9568 (define_expand "neghi2"
9569 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9570 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9571 (clobber (reg:CC FLAGS_REG))])]
9572 "TARGET_HIMODE_MATH"
9573 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9574
9575 (define_insn "*neghi2_1"
9576 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9577 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9578 (clobber (reg:CC FLAGS_REG))]
9579 "ix86_unary_operator_ok (NEG, HImode, operands)"
9580 "neg{w}\t%0"
9581 [(set_attr "type" "negnot")
9582 (set_attr "mode" "HI")])
9583
9584 (define_insn "*neghi2_cmpz"
9585 [(set (reg:CCZ FLAGS_REG)
9586 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9587 (const_int 0)))
9588 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9589 (neg:HI (match_dup 1)))]
9590 "ix86_unary_operator_ok (NEG, HImode, operands)"
9591 "neg{w}\t%0"
9592 [(set_attr "type" "negnot")
9593 (set_attr "mode" "HI")])
9594
9595 (define_expand "negqi2"
9596 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9597 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9598 (clobber (reg:CC FLAGS_REG))])]
9599 "TARGET_QIMODE_MATH"
9600 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9601
9602 (define_insn "*negqi2_1"
9603 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9604 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9605 (clobber (reg:CC FLAGS_REG))]
9606 "ix86_unary_operator_ok (NEG, QImode, operands)"
9607 "neg{b}\t%0"
9608 [(set_attr "type" "negnot")
9609 (set_attr "mode" "QI")])
9610
9611 (define_insn "*negqi2_cmpz"
9612 [(set (reg:CCZ FLAGS_REG)
9613 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9614 (const_int 0)))
9615 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9616 (neg:QI (match_dup 1)))]
9617 "ix86_unary_operator_ok (NEG, QImode, operands)"
9618 "neg{b}\t%0"
9619 [(set_attr "type" "negnot")
9620 (set_attr "mode" "QI")])
9621
9622 ;; Changing of sign for FP values is doable using integer unit too.
9623
9624 (define_expand "negsf2"
9625 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9626 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9627 "TARGET_80387 || TARGET_SSE_MATH"
9628 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9629
9630 (define_expand "abssf2"
9631 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9632 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9633 "TARGET_80387 || TARGET_SSE_MATH"
9634 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9635
9636 (define_insn "*absnegsf2_mixed"
9637 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9638 (match_operator:SF 3 "absneg_operator"
9639 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9640 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9641 (clobber (reg:CC FLAGS_REG))]
9642 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9643 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9644 "#")
9645
9646 (define_insn "*absnegsf2_sse"
9647 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9648 (match_operator:SF 3 "absneg_operator"
9649 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9650 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9651 (clobber (reg:CC FLAGS_REG))]
9652 "TARGET_SSE_MATH
9653 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9654 "#")
9655
9656 (define_insn "*absnegsf2_i387"
9657 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9658 (match_operator:SF 3 "absneg_operator"
9659 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9660 (use (match_operand 2 "" ""))
9661 (clobber (reg:CC FLAGS_REG))]
9662 "TARGET_80387 && !TARGET_SSE_MATH
9663 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9664 "#")
9665
9666 (define_expand "negdf2"
9667 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9668 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9669 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9670 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9671
9672 (define_expand "absdf2"
9673 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9674 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9675 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9676 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9677
9678 (define_insn "*absnegdf2_mixed"
9679 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
9680 (match_operator:DF 3 "absneg_operator"
9681 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9682 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
9683 (clobber (reg:CC FLAGS_REG))]
9684 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9685 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9686 "#")
9687
9688 (define_insn "*absnegdf2_sse"
9689 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
9690 (match_operator:DF 3 "absneg_operator"
9691 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
9692 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
9693 (clobber (reg:CC FLAGS_REG))]
9694 "TARGET_SSE2 && TARGET_SSE_MATH
9695 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9696 "#")
9697
9698 (define_insn "*absnegdf2_i387"
9699 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9700 (match_operator:DF 3 "absneg_operator"
9701 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9702 (use (match_operand 2 "" ""))
9703 (clobber (reg:CC FLAGS_REG))]
9704 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9705 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9706 "#")
9707
9708 (define_expand "negxf2"
9709 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9710 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9711 "TARGET_80387"
9712 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9713
9714 (define_expand "absxf2"
9715 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9716 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9717 "TARGET_80387"
9718 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9719
9720 (define_insn "*absnegxf2_i387"
9721 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9722 (match_operator:XF 3 "absneg_operator"
9723 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9724 (use (match_operand 2 "" ""))
9725 (clobber (reg:CC FLAGS_REG))]
9726 "TARGET_80387
9727 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9728 "#")
9729
9730 (define_expand "negtf2"
9731 [(set (match_operand:TF 0 "nonimmediate_operand" "")
9732 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
9733 "TARGET_64BIT"
9734 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
9735
9736 (define_expand "abstf2"
9737 [(set (match_operand:TF 0 "nonimmediate_operand" "")
9738 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
9739 "TARGET_64BIT"
9740 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
9741
9742 (define_insn "*absnegtf2_sse"
9743 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x,m")
9744 (match_operator:TF 3 "absneg_operator"
9745 [(match_operand:TF 1 "nonimmediate_operand" "0, x,0")]))
9746 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0,X"))
9747 (clobber (reg:CC FLAGS_REG))]
9748 "TARGET_64BIT
9749 && ix86_unary_operator_ok (GET_CODE (operands[3]), TFmode, operands)"
9750 "#")
9751
9752 ;; Splitters for fp abs and neg.
9753
9754 (define_split
9755 [(set (match_operand 0 "fp_register_operand" "")
9756 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9757 (use (match_operand 2 "" ""))
9758 (clobber (reg:CC FLAGS_REG))]
9759 "reload_completed"
9760 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9761
9762 (define_split
9763 [(set (match_operand 0 "register_operand" "")
9764 (match_operator 3 "absneg_operator"
9765 [(match_operand 1 "register_operand" "")]))
9766 (use (match_operand 2 "nonimmediate_operand" ""))
9767 (clobber (reg:CC FLAGS_REG))]
9768 "reload_completed && SSE_REG_P (operands[0])"
9769 [(set (match_dup 0) (match_dup 3))]
9770 {
9771 enum machine_mode mode = GET_MODE (operands[0]);
9772 enum machine_mode vmode = GET_MODE (operands[2]);
9773 rtx tmp;
9774
9775 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9776 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9777 if (operands_match_p (operands[0], operands[2]))
9778 {
9779 tmp = operands[1];
9780 operands[1] = operands[2];
9781 operands[2] = tmp;
9782 }
9783 if (GET_CODE (operands[3]) == ABS)
9784 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9785 else
9786 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9787 operands[3] = tmp;
9788 })
9789
9790 (define_split
9791 [(set (match_operand:SF 0 "register_operand" "")
9792 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9793 (use (match_operand:V4SF 2 "" ""))
9794 (clobber (reg:CC FLAGS_REG))]
9795 "reload_completed"
9796 [(parallel [(set (match_dup 0) (match_dup 1))
9797 (clobber (reg:CC FLAGS_REG))])]
9798 {
9799 rtx tmp;
9800 operands[0] = gen_lowpart (SImode, operands[0]);
9801 if (GET_CODE (operands[1]) == ABS)
9802 {
9803 tmp = gen_int_mode (0x7fffffff, SImode);
9804 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9805 }
9806 else
9807 {
9808 tmp = gen_int_mode (0x80000000, SImode);
9809 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9810 }
9811 operands[1] = tmp;
9812 })
9813
9814 (define_split
9815 [(set (match_operand:DF 0 "register_operand" "")
9816 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9817 (use (match_operand 2 "" ""))
9818 (clobber (reg:CC FLAGS_REG))]
9819 "reload_completed"
9820 [(parallel [(set (match_dup 0) (match_dup 1))
9821 (clobber (reg:CC FLAGS_REG))])]
9822 {
9823 rtx tmp;
9824 if (TARGET_64BIT)
9825 {
9826 tmp = gen_lowpart (DImode, operands[0]);
9827 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9828 operands[0] = tmp;
9829
9830 if (GET_CODE (operands[1]) == ABS)
9831 tmp = const0_rtx;
9832 else
9833 tmp = gen_rtx_NOT (DImode, tmp);
9834 }
9835 else
9836 {
9837 operands[0] = gen_highpart (SImode, operands[0]);
9838 if (GET_CODE (operands[1]) == ABS)
9839 {
9840 tmp = gen_int_mode (0x7fffffff, SImode);
9841 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9842 }
9843 else
9844 {
9845 tmp = gen_int_mode (0x80000000, SImode);
9846 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9847 }
9848 }
9849 operands[1] = tmp;
9850 })
9851
9852 (define_split
9853 [(set (match_operand:XF 0 "register_operand" "")
9854 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9855 (use (match_operand 2 "" ""))
9856 (clobber (reg:CC FLAGS_REG))]
9857 "reload_completed"
9858 [(parallel [(set (match_dup 0) (match_dup 1))
9859 (clobber (reg:CC FLAGS_REG))])]
9860 {
9861 rtx tmp;
9862 operands[0] = gen_rtx_REG (SImode,
9863 true_regnum (operands[0])
9864 + (TARGET_64BIT ? 1 : 2));
9865 if (GET_CODE (operands[1]) == ABS)
9866 {
9867 tmp = GEN_INT (0x7fff);
9868 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9869 }
9870 else
9871 {
9872 tmp = GEN_INT (0x8000);
9873 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9874 }
9875 operands[1] = tmp;
9876 })
9877
9878 (define_split
9879 [(set (match_operand 0 "memory_operand" "")
9880 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9881 (use (match_operand 2 "" ""))
9882 (clobber (reg:CC FLAGS_REG))]
9883 "reload_completed"
9884 [(parallel [(set (match_dup 0) (match_dup 1))
9885 (clobber (reg:CC FLAGS_REG))])]
9886 {
9887 enum machine_mode mode = GET_MODE (operands[0]);
9888 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9889 rtx tmp;
9890
9891 operands[0] = adjust_address (operands[0], QImode, size - 1);
9892 if (GET_CODE (operands[1]) == ABS)
9893 {
9894 tmp = gen_int_mode (0x7f, QImode);
9895 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9896 }
9897 else
9898 {
9899 tmp = gen_int_mode (0x80, QImode);
9900 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9901 }
9902 operands[1] = tmp;
9903 })
9904
9905 ;; Conditionalize these after reload. If they match before reload, we
9906 ;; lose the clobber and ability to use integer instructions.
9907
9908 (define_insn "*negsf2_1"
9909 [(set (match_operand:SF 0 "register_operand" "=f")
9910 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9911 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9912 "fchs"
9913 [(set_attr "type" "fsgn")
9914 (set_attr "mode" "SF")])
9915
9916 (define_insn "*negdf2_1"
9917 [(set (match_operand:DF 0 "register_operand" "=f")
9918 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9919 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9920 "fchs"
9921 [(set_attr "type" "fsgn")
9922 (set_attr "mode" "DF")])
9923
9924 (define_insn "*negxf2_1"
9925 [(set (match_operand:XF 0 "register_operand" "=f")
9926 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9927 "TARGET_80387"
9928 "fchs"
9929 [(set_attr "type" "fsgn")
9930 (set_attr "mode" "XF")])
9931
9932 (define_insn "*abssf2_1"
9933 [(set (match_operand:SF 0 "register_operand" "=f")
9934 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9935 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9936 "fabs"
9937 [(set_attr "type" "fsgn")
9938 (set_attr "mode" "SF")])
9939
9940 (define_insn "*absdf2_1"
9941 [(set (match_operand:DF 0 "register_operand" "=f")
9942 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9943 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9944 "fabs"
9945 [(set_attr "type" "fsgn")
9946 (set_attr "mode" "DF")])
9947
9948 (define_insn "*absxf2_1"
9949 [(set (match_operand:XF 0 "register_operand" "=f")
9950 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9951 "TARGET_80387"
9952 "fabs"
9953 [(set_attr "type" "fsgn")
9954 (set_attr "mode" "DF")])
9955
9956 (define_insn "*negextendsfdf2"
9957 [(set (match_operand:DF 0 "register_operand" "=f")
9958 (neg:DF (float_extend:DF
9959 (match_operand:SF 1 "register_operand" "0"))))]
9960 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9961 "fchs"
9962 [(set_attr "type" "fsgn")
9963 (set_attr "mode" "DF")])
9964
9965 (define_insn "*negextenddfxf2"
9966 [(set (match_operand:XF 0 "register_operand" "=f")
9967 (neg:XF (float_extend:XF
9968 (match_operand:DF 1 "register_operand" "0"))))]
9969 "TARGET_80387"
9970 "fchs"
9971 [(set_attr "type" "fsgn")
9972 (set_attr "mode" "XF")])
9973
9974 (define_insn "*negextendsfxf2"
9975 [(set (match_operand:XF 0 "register_operand" "=f")
9976 (neg:XF (float_extend:XF
9977 (match_operand:SF 1 "register_operand" "0"))))]
9978 "TARGET_80387"
9979 "fchs"
9980 [(set_attr "type" "fsgn")
9981 (set_attr "mode" "XF")])
9982
9983 (define_insn "*absextendsfdf2"
9984 [(set (match_operand:DF 0 "register_operand" "=f")
9985 (abs:DF (float_extend:DF
9986 (match_operand:SF 1 "register_operand" "0"))))]
9987 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9988 "fabs"
9989 [(set_attr "type" "fsgn")
9990 (set_attr "mode" "DF")])
9991
9992 (define_insn "*absextenddfxf2"
9993 [(set (match_operand:XF 0 "register_operand" "=f")
9994 (abs:XF (float_extend:XF
9995 (match_operand:DF 1 "register_operand" "0"))))]
9996 "TARGET_80387"
9997 "fabs"
9998 [(set_attr "type" "fsgn")
9999 (set_attr "mode" "XF")])
10000
10001 (define_insn "*absextendsfxf2"
10002 [(set (match_operand:XF 0 "register_operand" "=f")
10003 (abs:XF (float_extend:XF
10004 (match_operand:SF 1 "register_operand" "0"))))]
10005 "TARGET_80387"
10006 "fabs"
10007 [(set_attr "type" "fsgn")
10008 (set_attr "mode" "XF")])
10009
10010 ;; Copysign instructions
10011
10012 (define_mode_macro CSGNMODE [SF DF TF])
10013 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10014
10015 (define_expand "copysign<mode>3"
10016 [(match_operand:CSGNMODE 0 "register_operand" "")
10017 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10018 (match_operand:CSGNMODE 2 "register_operand" "")]
10019 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10020 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10021 {
10022 ix86_expand_copysign (operands);
10023 DONE;
10024 })
10025
10026 (define_insn_and_split "copysign<mode>3_const"
10027 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10028 (unspec:CSGNMODE
10029 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10030 (match_operand:CSGNMODE 2 "register_operand" "0")
10031 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10032 UNSPEC_COPYSIGN))]
10033 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10034 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10035 "#"
10036 "&& reload_completed"
10037 [(const_int 0)]
10038 {
10039 ix86_split_copysign_const (operands);
10040 DONE;
10041 })
10042
10043 (define_insn "copysign<mode>3_var"
10044 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10045 (unspec:CSGNMODE
10046 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10047 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10048 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10049 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10050 UNSPEC_COPYSIGN))
10051 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10052 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10053 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10054 "#")
10055
10056 (define_split
10057 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10058 (unspec:CSGNMODE
10059 [(match_operand:CSGNMODE 2 "register_operand" "")
10060 (match_operand:CSGNMODE 3 "register_operand" "")
10061 (match_operand:<CSGNVMODE> 4 "" "")
10062 (match_operand:<CSGNVMODE> 5 "" "")]
10063 UNSPEC_COPYSIGN))
10064 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10065 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10066 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10067 && reload_completed"
10068 [(const_int 0)]
10069 {
10070 ix86_split_copysign_var (operands);
10071 DONE;
10072 })
10073 \f
10074 ;; One complement instructions
10075
10076 (define_expand "one_cmpldi2"
10077 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10078 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10079 "TARGET_64BIT"
10080 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10081
10082 (define_insn "*one_cmpldi2_1_rex64"
10083 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10084 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10085 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10086 "not{q}\t%0"
10087 [(set_attr "type" "negnot")
10088 (set_attr "mode" "DI")])
10089
10090 (define_insn "*one_cmpldi2_2_rex64"
10091 [(set (reg FLAGS_REG)
10092 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10093 (const_int 0)))
10094 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10095 (not:DI (match_dup 1)))]
10096 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10097 && ix86_unary_operator_ok (NOT, DImode, operands)"
10098 "#"
10099 [(set_attr "type" "alu1")
10100 (set_attr "mode" "DI")])
10101
10102 (define_split
10103 [(set (match_operand 0 "flags_reg_operand" "")
10104 (match_operator 2 "compare_operator"
10105 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10106 (const_int 0)]))
10107 (set (match_operand:DI 1 "nonimmediate_operand" "")
10108 (not:DI (match_dup 3)))]
10109 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10110 [(parallel [(set (match_dup 0)
10111 (match_op_dup 2
10112 [(xor:DI (match_dup 3) (const_int -1))
10113 (const_int 0)]))
10114 (set (match_dup 1)
10115 (xor:DI (match_dup 3) (const_int -1)))])]
10116 "")
10117
10118 (define_expand "one_cmplsi2"
10119 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10120 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10121 ""
10122 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10123
10124 (define_insn "*one_cmplsi2_1"
10125 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10126 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10127 "ix86_unary_operator_ok (NOT, SImode, operands)"
10128 "not{l}\t%0"
10129 [(set_attr "type" "negnot")
10130 (set_attr "mode" "SI")])
10131
10132 ;; ??? Currently never generated - xor is used instead.
10133 (define_insn "*one_cmplsi2_1_zext"
10134 [(set (match_operand:DI 0 "register_operand" "=r")
10135 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10136 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10137 "not{l}\t%k0"
10138 [(set_attr "type" "negnot")
10139 (set_attr "mode" "SI")])
10140
10141 (define_insn "*one_cmplsi2_2"
10142 [(set (reg FLAGS_REG)
10143 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10144 (const_int 0)))
10145 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10146 (not:SI (match_dup 1)))]
10147 "ix86_match_ccmode (insn, CCNOmode)
10148 && ix86_unary_operator_ok (NOT, SImode, operands)"
10149 "#"
10150 [(set_attr "type" "alu1")
10151 (set_attr "mode" "SI")])
10152
10153 (define_split
10154 [(set (match_operand 0 "flags_reg_operand" "")
10155 (match_operator 2 "compare_operator"
10156 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10157 (const_int 0)]))
10158 (set (match_operand:SI 1 "nonimmediate_operand" "")
10159 (not:SI (match_dup 3)))]
10160 "ix86_match_ccmode (insn, CCNOmode)"
10161 [(parallel [(set (match_dup 0)
10162 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10163 (const_int 0)]))
10164 (set (match_dup 1)
10165 (xor:SI (match_dup 3) (const_int -1)))])]
10166 "")
10167
10168 ;; ??? Currently never generated - xor is used instead.
10169 (define_insn "*one_cmplsi2_2_zext"
10170 [(set (reg FLAGS_REG)
10171 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10172 (const_int 0)))
10173 (set (match_operand:DI 0 "register_operand" "=r")
10174 (zero_extend:DI (not:SI (match_dup 1))))]
10175 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10176 && ix86_unary_operator_ok (NOT, SImode, operands)"
10177 "#"
10178 [(set_attr "type" "alu1")
10179 (set_attr "mode" "SI")])
10180
10181 (define_split
10182 [(set (match_operand 0 "flags_reg_operand" "")
10183 (match_operator 2 "compare_operator"
10184 [(not:SI (match_operand:SI 3 "register_operand" ""))
10185 (const_int 0)]))
10186 (set (match_operand:DI 1 "register_operand" "")
10187 (zero_extend:DI (not:SI (match_dup 3))))]
10188 "ix86_match_ccmode (insn, CCNOmode)"
10189 [(parallel [(set (match_dup 0)
10190 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10191 (const_int 0)]))
10192 (set (match_dup 1)
10193 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10194 "")
10195
10196 (define_expand "one_cmplhi2"
10197 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10198 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10199 "TARGET_HIMODE_MATH"
10200 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10201
10202 (define_insn "*one_cmplhi2_1"
10203 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10204 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10205 "ix86_unary_operator_ok (NOT, HImode, operands)"
10206 "not{w}\t%0"
10207 [(set_attr "type" "negnot")
10208 (set_attr "mode" "HI")])
10209
10210 (define_insn "*one_cmplhi2_2"
10211 [(set (reg FLAGS_REG)
10212 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10213 (const_int 0)))
10214 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10215 (not:HI (match_dup 1)))]
10216 "ix86_match_ccmode (insn, CCNOmode)
10217 && ix86_unary_operator_ok (NEG, HImode, operands)"
10218 "#"
10219 [(set_attr "type" "alu1")
10220 (set_attr "mode" "HI")])
10221
10222 (define_split
10223 [(set (match_operand 0 "flags_reg_operand" "")
10224 (match_operator 2 "compare_operator"
10225 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10226 (const_int 0)]))
10227 (set (match_operand:HI 1 "nonimmediate_operand" "")
10228 (not:HI (match_dup 3)))]
10229 "ix86_match_ccmode (insn, CCNOmode)"
10230 [(parallel [(set (match_dup 0)
10231 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10232 (const_int 0)]))
10233 (set (match_dup 1)
10234 (xor:HI (match_dup 3) (const_int -1)))])]
10235 "")
10236
10237 ;; %%% Potential partial reg stall on alternative 1. What to do?
10238 (define_expand "one_cmplqi2"
10239 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10240 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10241 "TARGET_QIMODE_MATH"
10242 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10243
10244 (define_insn "*one_cmplqi2_1"
10245 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10246 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10247 "ix86_unary_operator_ok (NOT, QImode, operands)"
10248 "@
10249 not{b}\t%0
10250 not{l}\t%k0"
10251 [(set_attr "type" "negnot")
10252 (set_attr "mode" "QI,SI")])
10253
10254 (define_insn "*one_cmplqi2_2"
10255 [(set (reg FLAGS_REG)
10256 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10257 (const_int 0)))
10258 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10259 (not:QI (match_dup 1)))]
10260 "ix86_match_ccmode (insn, CCNOmode)
10261 && ix86_unary_operator_ok (NOT, QImode, operands)"
10262 "#"
10263 [(set_attr "type" "alu1")
10264 (set_attr "mode" "QI")])
10265
10266 (define_split
10267 [(set (match_operand 0 "flags_reg_operand" "")
10268 (match_operator 2 "compare_operator"
10269 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10270 (const_int 0)]))
10271 (set (match_operand:QI 1 "nonimmediate_operand" "")
10272 (not:QI (match_dup 3)))]
10273 "ix86_match_ccmode (insn, CCNOmode)"
10274 [(parallel [(set (match_dup 0)
10275 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10276 (const_int 0)]))
10277 (set (match_dup 1)
10278 (xor:QI (match_dup 3) (const_int -1)))])]
10279 "")
10280 \f
10281 ;; Arithmetic shift instructions
10282
10283 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10284 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10285 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10286 ;; from the assembler input.
10287 ;;
10288 ;; This instruction shifts the target reg/mem as usual, but instead of
10289 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10290 ;; is a left shift double, bits are taken from the high order bits of
10291 ;; reg, else if the insn is a shift right double, bits are taken from the
10292 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10293 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10294 ;;
10295 ;; Since sh[lr]d does not change the `reg' operand, that is done
10296 ;; separately, making all shifts emit pairs of shift double and normal
10297 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10298 ;; support a 63 bit shift, each shift where the count is in a reg expands
10299 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10300 ;;
10301 ;; If the shift count is a constant, we need never emit more than one
10302 ;; shift pair, instead using moves and sign extension for counts greater
10303 ;; than 31.
10304
10305 (define_expand "ashlti3"
10306 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10307 (ashift:TI (match_operand:TI 1 "register_operand" "")
10308 (match_operand:QI 2 "nonmemory_operand" "")))
10309 (clobber (reg:CC FLAGS_REG))])]
10310 "TARGET_64BIT"
10311 {
10312 if (! immediate_operand (operands[2], QImode))
10313 {
10314 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10315 DONE;
10316 }
10317 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10318 DONE;
10319 })
10320
10321 (define_insn "ashlti3_1"
10322 [(set (match_operand:TI 0 "register_operand" "=r")
10323 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10324 (match_operand:QI 2 "register_operand" "c")))
10325 (clobber (match_scratch:DI 3 "=&r"))
10326 (clobber (reg:CC FLAGS_REG))]
10327 "TARGET_64BIT"
10328 "#"
10329 [(set_attr "type" "multi")])
10330
10331 ;; This pattern must be defined before *ashlti3_2 to prevent
10332 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10333
10334 (define_insn "sse2_ashlti3"
10335 [(set (match_operand:TI 0 "register_operand" "=x")
10336 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10337 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10338 "TARGET_SSE2"
10339 {
10340 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10341 return "pslldq\t{%2, %0|%0, %2}";
10342 }
10343 [(set_attr "type" "sseishft")
10344 (set_attr "prefix_data16" "1")
10345 (set_attr "mode" "TI")])
10346
10347 (define_insn "*ashlti3_2"
10348 [(set (match_operand:TI 0 "register_operand" "=r")
10349 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10350 (match_operand:QI 2 "immediate_operand" "O")))
10351 (clobber (reg:CC FLAGS_REG))]
10352 "TARGET_64BIT"
10353 "#"
10354 [(set_attr "type" "multi")])
10355
10356 (define_split
10357 [(set (match_operand:TI 0 "register_operand" "")
10358 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10359 (match_operand:QI 2 "register_operand" "")))
10360 (clobber (match_scratch:DI 3 ""))
10361 (clobber (reg:CC FLAGS_REG))]
10362 "TARGET_64BIT && reload_completed"
10363 [(const_int 0)]
10364 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10365
10366 (define_split
10367 [(set (match_operand:TI 0 "register_operand" "")
10368 (ashift:TI (match_operand:TI 1 "register_operand" "")
10369 (match_operand:QI 2 "immediate_operand" "")))
10370 (clobber (reg:CC FLAGS_REG))]
10371 "TARGET_64BIT && reload_completed"
10372 [(const_int 0)]
10373 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10374
10375 (define_insn "x86_64_shld"
10376 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10377 (ior:DI (ashift:DI (match_dup 0)
10378 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10379 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10380 (minus:QI (const_int 64) (match_dup 2)))))
10381 (clobber (reg:CC FLAGS_REG))]
10382 "TARGET_64BIT"
10383 "@
10384 shld{q}\t{%2, %1, %0|%0, %1, %2}
10385 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10386 [(set_attr "type" "ishift")
10387 (set_attr "prefix_0f" "1")
10388 (set_attr "mode" "DI")
10389 (set_attr "athlon_decode" "vector")
10390 (set_attr "amdfam10_decode" "vector")])
10391
10392 (define_expand "x86_64_shift_adj"
10393 [(set (reg:CCZ FLAGS_REG)
10394 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10395 (const_int 64))
10396 (const_int 0)))
10397 (set (match_operand:DI 0 "register_operand" "")
10398 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10399 (match_operand:DI 1 "register_operand" "")
10400 (match_dup 0)))
10401 (set (match_dup 1)
10402 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10403 (match_operand:DI 3 "register_operand" "r")
10404 (match_dup 1)))]
10405 "TARGET_64BIT"
10406 "")
10407
10408 (define_expand "ashldi3"
10409 [(set (match_operand:DI 0 "shiftdi_operand" "")
10410 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10411 (match_operand:QI 2 "nonmemory_operand" "")))]
10412 ""
10413 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10414
10415 (define_insn "*ashldi3_1_rex64"
10416 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10417 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10418 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10421 {
10422 switch (get_attr_type (insn))
10423 {
10424 case TYPE_ALU:
10425 gcc_assert (operands[2] == const1_rtx);
10426 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10427 return "add{q}\t%0, %0";
10428
10429 case TYPE_LEA:
10430 gcc_assert (CONST_INT_P (operands[2]));
10431 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10432 operands[1] = gen_rtx_MULT (DImode, operands[1],
10433 GEN_INT (1 << INTVAL (operands[2])));
10434 return "lea{q}\t{%a1, %0|%0, %a1}";
10435
10436 default:
10437 if (REG_P (operands[2]))
10438 return "sal{q}\t{%b2, %0|%0, %b2}";
10439 else if (operands[2] == const1_rtx
10440 && (TARGET_SHIFT1 || optimize_size))
10441 return "sal{q}\t%0";
10442 else
10443 return "sal{q}\t{%2, %0|%0, %2}";
10444 }
10445 }
10446 [(set (attr "type")
10447 (cond [(eq_attr "alternative" "1")
10448 (const_string "lea")
10449 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10450 (const_int 0))
10451 (match_operand 0 "register_operand" ""))
10452 (match_operand 2 "const1_operand" ""))
10453 (const_string "alu")
10454 ]
10455 (const_string "ishift")))
10456 (set_attr "mode" "DI")])
10457
10458 ;; Convert lea to the lea pattern to avoid flags dependency.
10459 (define_split
10460 [(set (match_operand:DI 0 "register_operand" "")
10461 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10462 (match_operand:QI 2 "immediate_operand" "")))
10463 (clobber (reg:CC FLAGS_REG))]
10464 "TARGET_64BIT && reload_completed
10465 && true_regnum (operands[0]) != true_regnum (operands[1])"
10466 [(set (match_dup 0)
10467 (mult:DI (match_dup 1)
10468 (match_dup 2)))]
10469 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10470
10471 ;; This pattern can't accept a variable shift count, since shifts by
10472 ;; zero don't affect the flags. We assume that shifts by constant
10473 ;; zero are optimized away.
10474 (define_insn "*ashldi3_cmp_rex64"
10475 [(set (reg FLAGS_REG)
10476 (compare
10477 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10478 (match_operand:QI 2 "immediate_operand" "e"))
10479 (const_int 0)))
10480 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10481 (ashift:DI (match_dup 1) (match_dup 2)))]
10482 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10483 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10484 && (optimize_size
10485 || !TARGET_PARTIAL_FLAG_REG_STALL
10486 || (operands[2] == const1_rtx
10487 && (TARGET_SHIFT1
10488 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10489 {
10490 switch (get_attr_type (insn))
10491 {
10492 case TYPE_ALU:
10493 gcc_assert (operands[2] == const1_rtx);
10494 return "add{q}\t%0, %0";
10495
10496 default:
10497 if (REG_P (operands[2]))
10498 return "sal{q}\t{%b2, %0|%0, %b2}";
10499 else if (operands[2] == const1_rtx
10500 && (TARGET_SHIFT1 || optimize_size))
10501 return "sal{q}\t%0";
10502 else
10503 return "sal{q}\t{%2, %0|%0, %2}";
10504 }
10505 }
10506 [(set (attr "type")
10507 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10508 (const_int 0))
10509 (match_operand 0 "register_operand" ""))
10510 (match_operand 2 "const1_operand" ""))
10511 (const_string "alu")
10512 ]
10513 (const_string "ishift")))
10514 (set_attr "mode" "DI")])
10515
10516 (define_insn "*ashldi3_cconly_rex64"
10517 [(set (reg FLAGS_REG)
10518 (compare
10519 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10520 (match_operand:QI 2 "immediate_operand" "e"))
10521 (const_int 0)))
10522 (clobber (match_scratch:DI 0 "=r"))]
10523 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10524 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10525 && (optimize_size
10526 || !TARGET_PARTIAL_FLAG_REG_STALL
10527 || (operands[2] == const1_rtx
10528 && (TARGET_SHIFT1
10529 || TARGET_DOUBLE_WITH_ADD)))"
10530 {
10531 switch (get_attr_type (insn))
10532 {
10533 case TYPE_ALU:
10534 gcc_assert (operands[2] == const1_rtx);
10535 return "add{q}\t%0, %0";
10536
10537 default:
10538 if (REG_P (operands[2]))
10539 return "sal{q}\t{%b2, %0|%0, %b2}";
10540 else if (operands[2] == const1_rtx
10541 && (TARGET_SHIFT1 || optimize_size))
10542 return "sal{q}\t%0";
10543 else
10544 return "sal{q}\t{%2, %0|%0, %2}";
10545 }
10546 }
10547 [(set (attr "type")
10548 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10549 (const_int 0))
10550 (match_operand 0 "register_operand" ""))
10551 (match_operand 2 "const1_operand" ""))
10552 (const_string "alu")
10553 ]
10554 (const_string "ishift")))
10555 (set_attr "mode" "DI")])
10556
10557 (define_insn "*ashldi3_1"
10558 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10559 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10560 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10561 (clobber (reg:CC FLAGS_REG))]
10562 "!TARGET_64BIT"
10563 "#"
10564 [(set_attr "type" "multi")])
10565
10566 ;; By default we don't ask for a scratch register, because when DImode
10567 ;; values are manipulated, registers are already at a premium. But if
10568 ;; we have one handy, we won't turn it away.
10569 (define_peephole2
10570 [(match_scratch:SI 3 "r")
10571 (parallel [(set (match_operand:DI 0 "register_operand" "")
10572 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10573 (match_operand:QI 2 "nonmemory_operand" "")))
10574 (clobber (reg:CC FLAGS_REG))])
10575 (match_dup 3)]
10576 "!TARGET_64BIT && TARGET_CMOVE"
10577 [(const_int 0)]
10578 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10579
10580 (define_split
10581 [(set (match_operand:DI 0 "register_operand" "")
10582 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10583 (match_operand:QI 2 "nonmemory_operand" "")))
10584 (clobber (reg:CC FLAGS_REG))]
10585 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10586 ? epilogue_completed : reload_completed)"
10587 [(const_int 0)]
10588 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10589
10590 (define_insn "x86_shld_1"
10591 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10592 (ior:SI (ashift:SI (match_dup 0)
10593 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10594 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10595 (minus:QI (const_int 32) (match_dup 2)))))
10596 (clobber (reg:CC FLAGS_REG))]
10597 ""
10598 "@
10599 shld{l}\t{%2, %1, %0|%0, %1, %2}
10600 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10601 [(set_attr "type" "ishift")
10602 (set_attr "prefix_0f" "1")
10603 (set_attr "mode" "SI")
10604 (set_attr "pent_pair" "np")
10605 (set_attr "athlon_decode" "vector")
10606 (set_attr "amdfam10_decode" "vector")])
10607
10608 (define_expand "x86_shift_adj_1"
10609 [(set (reg:CCZ FLAGS_REG)
10610 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10611 (const_int 32))
10612 (const_int 0)))
10613 (set (match_operand:SI 0 "register_operand" "")
10614 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10615 (match_operand:SI 1 "register_operand" "")
10616 (match_dup 0)))
10617 (set (match_dup 1)
10618 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10619 (match_operand:SI 3 "register_operand" "r")
10620 (match_dup 1)))]
10621 "TARGET_CMOVE"
10622 "")
10623
10624 (define_expand "x86_shift_adj_2"
10625 [(use (match_operand:SI 0 "register_operand" ""))
10626 (use (match_operand:SI 1 "register_operand" ""))
10627 (use (match_operand:QI 2 "register_operand" ""))]
10628 ""
10629 {
10630 rtx label = gen_label_rtx ();
10631 rtx tmp;
10632
10633 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10634
10635 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10636 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10637 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10638 gen_rtx_LABEL_REF (VOIDmode, label),
10639 pc_rtx);
10640 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10641 JUMP_LABEL (tmp) = label;
10642
10643 emit_move_insn (operands[0], operands[1]);
10644 ix86_expand_clear (operands[1]);
10645
10646 emit_label (label);
10647 LABEL_NUSES (label) = 1;
10648
10649 DONE;
10650 })
10651
10652 (define_expand "ashlsi3"
10653 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10654 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10655 (match_operand:QI 2 "nonmemory_operand" "")))
10656 (clobber (reg:CC FLAGS_REG))]
10657 ""
10658 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10659
10660 (define_insn "*ashlsi3_1"
10661 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10662 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10663 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10664 (clobber (reg:CC FLAGS_REG))]
10665 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10666 {
10667 switch (get_attr_type (insn))
10668 {
10669 case TYPE_ALU:
10670 gcc_assert (operands[2] == const1_rtx);
10671 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10672 return "add{l}\t%0, %0";
10673
10674 case TYPE_LEA:
10675 return "#";
10676
10677 default:
10678 if (REG_P (operands[2]))
10679 return "sal{l}\t{%b2, %0|%0, %b2}";
10680 else if (operands[2] == const1_rtx
10681 && (TARGET_SHIFT1 || optimize_size))
10682 return "sal{l}\t%0";
10683 else
10684 return "sal{l}\t{%2, %0|%0, %2}";
10685 }
10686 }
10687 [(set (attr "type")
10688 (cond [(eq_attr "alternative" "1")
10689 (const_string "lea")
10690 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10691 (const_int 0))
10692 (match_operand 0 "register_operand" ""))
10693 (match_operand 2 "const1_operand" ""))
10694 (const_string "alu")
10695 ]
10696 (const_string "ishift")))
10697 (set_attr "mode" "SI")])
10698
10699 ;; Convert lea to the lea pattern to avoid flags dependency.
10700 (define_split
10701 [(set (match_operand 0 "register_operand" "")
10702 (ashift (match_operand 1 "index_register_operand" "")
10703 (match_operand:QI 2 "const_int_operand" "")))
10704 (clobber (reg:CC FLAGS_REG))]
10705 "reload_completed
10706 && true_regnum (operands[0]) != true_regnum (operands[1])
10707 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10708 [(const_int 0)]
10709 {
10710 rtx pat;
10711 enum machine_mode mode = GET_MODE (operands[0]);
10712
10713 if (GET_MODE_SIZE (mode) < 4)
10714 operands[0] = gen_lowpart (SImode, operands[0]);
10715 if (mode != Pmode)
10716 operands[1] = gen_lowpart (Pmode, operands[1]);
10717 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10718
10719 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10720 if (Pmode != SImode)
10721 pat = gen_rtx_SUBREG (SImode, pat, 0);
10722 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10723 DONE;
10724 })
10725
10726 ;; Rare case of shifting RSP is handled by generating move and shift
10727 (define_split
10728 [(set (match_operand 0 "register_operand" "")
10729 (ashift (match_operand 1 "register_operand" "")
10730 (match_operand:QI 2 "const_int_operand" "")))
10731 (clobber (reg:CC FLAGS_REG))]
10732 "reload_completed
10733 && true_regnum (operands[0]) != true_regnum (operands[1])"
10734 [(const_int 0)]
10735 {
10736 rtx pat, clob;
10737 emit_move_insn (operands[0], operands[1]);
10738 pat = gen_rtx_SET (VOIDmode, operands[0],
10739 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10740 operands[0], operands[2]));
10741 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10742 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10743 DONE;
10744 })
10745
10746 (define_insn "*ashlsi3_1_zext"
10747 [(set (match_operand:DI 0 "register_operand" "=r,r")
10748 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10749 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10750 (clobber (reg:CC FLAGS_REG))]
10751 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10752 {
10753 switch (get_attr_type (insn))
10754 {
10755 case TYPE_ALU:
10756 gcc_assert (operands[2] == const1_rtx);
10757 return "add{l}\t%k0, %k0";
10758
10759 case TYPE_LEA:
10760 return "#";
10761
10762 default:
10763 if (REG_P (operands[2]))
10764 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10765 else if (operands[2] == const1_rtx
10766 && (TARGET_SHIFT1 || optimize_size))
10767 return "sal{l}\t%k0";
10768 else
10769 return "sal{l}\t{%2, %k0|%k0, %2}";
10770 }
10771 }
10772 [(set (attr "type")
10773 (cond [(eq_attr "alternative" "1")
10774 (const_string "lea")
10775 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10776 (const_int 0))
10777 (match_operand 2 "const1_operand" ""))
10778 (const_string "alu")
10779 ]
10780 (const_string "ishift")))
10781 (set_attr "mode" "SI")])
10782
10783 ;; Convert lea to the lea pattern to avoid flags dependency.
10784 (define_split
10785 [(set (match_operand:DI 0 "register_operand" "")
10786 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10787 (match_operand:QI 2 "const_int_operand" ""))))
10788 (clobber (reg:CC FLAGS_REG))]
10789 "TARGET_64BIT && reload_completed
10790 && true_regnum (operands[0]) != true_regnum (operands[1])"
10791 [(set (match_dup 0) (zero_extend:DI
10792 (subreg:SI (mult:SI (match_dup 1)
10793 (match_dup 2)) 0)))]
10794 {
10795 operands[1] = gen_lowpart (Pmode, operands[1]);
10796 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10797 })
10798
10799 ;; This pattern can't accept a variable shift count, since shifts by
10800 ;; zero don't affect the flags. We assume that shifts by constant
10801 ;; zero are optimized away.
10802 (define_insn "*ashlsi3_cmp"
10803 [(set (reg FLAGS_REG)
10804 (compare
10805 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10806 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10807 (const_int 0)))
10808 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10809 (ashift:SI (match_dup 1) (match_dup 2)))]
10810 "ix86_match_ccmode (insn, CCGOCmode)
10811 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10812 && (optimize_size
10813 || !TARGET_PARTIAL_FLAG_REG_STALL
10814 || (operands[2] == const1_rtx
10815 && (TARGET_SHIFT1
10816 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10817 {
10818 switch (get_attr_type (insn))
10819 {
10820 case TYPE_ALU:
10821 gcc_assert (operands[2] == const1_rtx);
10822 return "add{l}\t%0, %0";
10823
10824 default:
10825 if (REG_P (operands[2]))
10826 return "sal{l}\t{%b2, %0|%0, %b2}";
10827 else if (operands[2] == const1_rtx
10828 && (TARGET_SHIFT1 || optimize_size))
10829 return "sal{l}\t%0";
10830 else
10831 return "sal{l}\t{%2, %0|%0, %2}";
10832 }
10833 }
10834 [(set (attr "type")
10835 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10836 (const_int 0))
10837 (match_operand 0 "register_operand" ""))
10838 (match_operand 2 "const1_operand" ""))
10839 (const_string "alu")
10840 ]
10841 (const_string "ishift")))
10842 (set_attr "mode" "SI")])
10843
10844 (define_insn "*ashlsi3_cconly"
10845 [(set (reg FLAGS_REG)
10846 (compare
10847 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10848 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10849 (const_int 0)))
10850 (clobber (match_scratch:SI 0 "=r"))]
10851 "ix86_match_ccmode (insn, CCGOCmode)
10852 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10853 && (optimize_size
10854 || !TARGET_PARTIAL_FLAG_REG_STALL
10855 || (operands[2] == const1_rtx
10856 && (TARGET_SHIFT1
10857 || TARGET_DOUBLE_WITH_ADD)))"
10858 {
10859 switch (get_attr_type (insn))
10860 {
10861 case TYPE_ALU:
10862 gcc_assert (operands[2] == const1_rtx);
10863 return "add{l}\t%0, %0";
10864
10865 default:
10866 if (REG_P (operands[2]))
10867 return "sal{l}\t{%b2, %0|%0, %b2}";
10868 else if (operands[2] == const1_rtx
10869 && (TARGET_SHIFT1 || optimize_size))
10870 return "sal{l}\t%0";
10871 else
10872 return "sal{l}\t{%2, %0|%0, %2}";
10873 }
10874 }
10875 [(set (attr "type")
10876 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10877 (const_int 0))
10878 (match_operand 0 "register_operand" ""))
10879 (match_operand 2 "const1_operand" ""))
10880 (const_string "alu")
10881 ]
10882 (const_string "ishift")))
10883 (set_attr "mode" "SI")])
10884
10885 (define_insn "*ashlsi3_cmp_zext"
10886 [(set (reg FLAGS_REG)
10887 (compare
10888 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10889 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10890 (const_int 0)))
10891 (set (match_operand:DI 0 "register_operand" "=r")
10892 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10893 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10894 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10895 && (optimize_size
10896 || !TARGET_PARTIAL_FLAG_REG_STALL
10897 || (operands[2] == const1_rtx
10898 && (TARGET_SHIFT1
10899 || TARGET_DOUBLE_WITH_ADD)))"
10900 {
10901 switch (get_attr_type (insn))
10902 {
10903 case TYPE_ALU:
10904 gcc_assert (operands[2] == const1_rtx);
10905 return "add{l}\t%k0, %k0";
10906
10907 default:
10908 if (REG_P (operands[2]))
10909 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10910 else if (operands[2] == const1_rtx
10911 && (TARGET_SHIFT1 || optimize_size))
10912 return "sal{l}\t%k0";
10913 else
10914 return "sal{l}\t{%2, %k0|%k0, %2}";
10915 }
10916 }
10917 [(set (attr "type")
10918 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10919 (const_int 0))
10920 (match_operand 2 "const1_operand" ""))
10921 (const_string "alu")
10922 ]
10923 (const_string "ishift")))
10924 (set_attr "mode" "SI")])
10925
10926 (define_expand "ashlhi3"
10927 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10928 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10929 (match_operand:QI 2 "nonmemory_operand" "")))
10930 (clobber (reg:CC FLAGS_REG))]
10931 "TARGET_HIMODE_MATH"
10932 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10933
10934 (define_insn "*ashlhi3_1_lea"
10935 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10936 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10937 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10938 (clobber (reg:CC FLAGS_REG))]
10939 "!TARGET_PARTIAL_REG_STALL
10940 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10941 {
10942 switch (get_attr_type (insn))
10943 {
10944 case TYPE_LEA:
10945 return "#";
10946 case TYPE_ALU:
10947 gcc_assert (operands[2] == const1_rtx);
10948 return "add{w}\t%0, %0";
10949
10950 default:
10951 if (REG_P (operands[2]))
10952 return "sal{w}\t{%b2, %0|%0, %b2}";
10953 else if (operands[2] == const1_rtx
10954 && (TARGET_SHIFT1 || optimize_size))
10955 return "sal{w}\t%0";
10956 else
10957 return "sal{w}\t{%2, %0|%0, %2}";
10958 }
10959 }
10960 [(set (attr "type")
10961 (cond [(eq_attr "alternative" "1")
10962 (const_string "lea")
10963 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10964 (const_int 0))
10965 (match_operand 0 "register_operand" ""))
10966 (match_operand 2 "const1_operand" ""))
10967 (const_string "alu")
10968 ]
10969 (const_string "ishift")))
10970 (set_attr "mode" "HI,SI")])
10971
10972 (define_insn "*ashlhi3_1"
10973 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10974 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10975 (match_operand:QI 2 "nonmemory_operand" "cI")))
10976 (clobber (reg:CC FLAGS_REG))]
10977 "TARGET_PARTIAL_REG_STALL
10978 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10979 {
10980 switch (get_attr_type (insn))
10981 {
10982 case TYPE_ALU:
10983 gcc_assert (operands[2] == const1_rtx);
10984 return "add{w}\t%0, %0";
10985
10986 default:
10987 if (REG_P (operands[2]))
10988 return "sal{w}\t{%b2, %0|%0, %b2}";
10989 else if (operands[2] == const1_rtx
10990 && (TARGET_SHIFT1 || optimize_size))
10991 return "sal{w}\t%0";
10992 else
10993 return "sal{w}\t{%2, %0|%0, %2}";
10994 }
10995 }
10996 [(set (attr "type")
10997 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10998 (const_int 0))
10999 (match_operand 0 "register_operand" ""))
11000 (match_operand 2 "const1_operand" ""))
11001 (const_string "alu")
11002 ]
11003 (const_string "ishift")))
11004 (set_attr "mode" "HI")])
11005
11006 ;; This pattern can't accept a variable shift count, since shifts by
11007 ;; zero don't affect the flags. We assume that shifts by constant
11008 ;; zero are optimized away.
11009 (define_insn "*ashlhi3_cmp"
11010 [(set (reg FLAGS_REG)
11011 (compare
11012 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11013 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11014 (const_int 0)))
11015 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11016 (ashift:HI (match_dup 1) (match_dup 2)))]
11017 "ix86_match_ccmode (insn, CCGOCmode)
11018 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11019 && (optimize_size
11020 || !TARGET_PARTIAL_FLAG_REG_STALL
11021 || (operands[2] == const1_rtx
11022 && (TARGET_SHIFT1
11023 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11024 {
11025 switch (get_attr_type (insn))
11026 {
11027 case TYPE_ALU:
11028 gcc_assert (operands[2] == const1_rtx);
11029 return "add{w}\t%0, %0";
11030
11031 default:
11032 if (REG_P (operands[2]))
11033 return "sal{w}\t{%b2, %0|%0, %b2}";
11034 else if (operands[2] == const1_rtx
11035 && (TARGET_SHIFT1 || optimize_size))
11036 return "sal{w}\t%0";
11037 else
11038 return "sal{w}\t{%2, %0|%0, %2}";
11039 }
11040 }
11041 [(set (attr "type")
11042 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11043 (const_int 0))
11044 (match_operand 0 "register_operand" ""))
11045 (match_operand 2 "const1_operand" ""))
11046 (const_string "alu")
11047 ]
11048 (const_string "ishift")))
11049 (set_attr "mode" "HI")])
11050
11051 (define_insn "*ashlhi3_cconly"
11052 [(set (reg FLAGS_REG)
11053 (compare
11054 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11055 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11056 (const_int 0)))
11057 (clobber (match_scratch:HI 0 "=r"))]
11058 "ix86_match_ccmode (insn, CCGOCmode)
11059 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11060 && (optimize_size
11061 || !TARGET_PARTIAL_FLAG_REG_STALL
11062 || (operands[2] == const1_rtx
11063 && (TARGET_SHIFT1
11064 || TARGET_DOUBLE_WITH_ADD)))"
11065 {
11066 switch (get_attr_type (insn))
11067 {
11068 case TYPE_ALU:
11069 gcc_assert (operands[2] == const1_rtx);
11070 return "add{w}\t%0, %0";
11071
11072 default:
11073 if (REG_P (operands[2]))
11074 return "sal{w}\t{%b2, %0|%0, %b2}";
11075 else if (operands[2] == const1_rtx
11076 && (TARGET_SHIFT1 || optimize_size))
11077 return "sal{w}\t%0";
11078 else
11079 return "sal{w}\t{%2, %0|%0, %2}";
11080 }
11081 }
11082 [(set (attr "type")
11083 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11084 (const_int 0))
11085 (match_operand 0 "register_operand" ""))
11086 (match_operand 2 "const1_operand" ""))
11087 (const_string "alu")
11088 ]
11089 (const_string "ishift")))
11090 (set_attr "mode" "HI")])
11091
11092 (define_expand "ashlqi3"
11093 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11094 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11095 (match_operand:QI 2 "nonmemory_operand" "")))
11096 (clobber (reg:CC FLAGS_REG))]
11097 "TARGET_QIMODE_MATH"
11098 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11099
11100 ;; %%% Potential partial reg stall on alternative 2. What to do?
11101
11102 (define_insn "*ashlqi3_1_lea"
11103 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11104 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11105 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11106 (clobber (reg:CC FLAGS_REG))]
11107 "!TARGET_PARTIAL_REG_STALL
11108 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11109 {
11110 switch (get_attr_type (insn))
11111 {
11112 case TYPE_LEA:
11113 return "#";
11114 case TYPE_ALU:
11115 gcc_assert (operands[2] == const1_rtx);
11116 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11117 return "add{l}\t%k0, %k0";
11118 else
11119 return "add{b}\t%0, %0";
11120
11121 default:
11122 if (REG_P (operands[2]))
11123 {
11124 if (get_attr_mode (insn) == MODE_SI)
11125 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11126 else
11127 return "sal{b}\t{%b2, %0|%0, %b2}";
11128 }
11129 else if (operands[2] == const1_rtx
11130 && (TARGET_SHIFT1 || optimize_size))
11131 {
11132 if (get_attr_mode (insn) == MODE_SI)
11133 return "sal{l}\t%0";
11134 else
11135 return "sal{b}\t%0";
11136 }
11137 else
11138 {
11139 if (get_attr_mode (insn) == MODE_SI)
11140 return "sal{l}\t{%2, %k0|%k0, %2}";
11141 else
11142 return "sal{b}\t{%2, %0|%0, %2}";
11143 }
11144 }
11145 }
11146 [(set (attr "type")
11147 (cond [(eq_attr "alternative" "2")
11148 (const_string "lea")
11149 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11150 (const_int 0))
11151 (match_operand 0 "register_operand" ""))
11152 (match_operand 2 "const1_operand" ""))
11153 (const_string "alu")
11154 ]
11155 (const_string "ishift")))
11156 (set_attr "mode" "QI,SI,SI")])
11157
11158 (define_insn "*ashlqi3_1"
11159 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11160 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11161 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11162 (clobber (reg:CC FLAGS_REG))]
11163 "TARGET_PARTIAL_REG_STALL
11164 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11165 {
11166 switch (get_attr_type (insn))
11167 {
11168 case TYPE_ALU:
11169 gcc_assert (operands[2] == const1_rtx);
11170 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11171 return "add{l}\t%k0, %k0";
11172 else
11173 return "add{b}\t%0, %0";
11174
11175 default:
11176 if (REG_P (operands[2]))
11177 {
11178 if (get_attr_mode (insn) == MODE_SI)
11179 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11180 else
11181 return "sal{b}\t{%b2, %0|%0, %b2}";
11182 }
11183 else if (operands[2] == const1_rtx
11184 && (TARGET_SHIFT1 || optimize_size))
11185 {
11186 if (get_attr_mode (insn) == MODE_SI)
11187 return "sal{l}\t%0";
11188 else
11189 return "sal{b}\t%0";
11190 }
11191 else
11192 {
11193 if (get_attr_mode (insn) == MODE_SI)
11194 return "sal{l}\t{%2, %k0|%k0, %2}";
11195 else
11196 return "sal{b}\t{%2, %0|%0, %2}";
11197 }
11198 }
11199 }
11200 [(set (attr "type")
11201 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11202 (const_int 0))
11203 (match_operand 0 "register_operand" ""))
11204 (match_operand 2 "const1_operand" ""))
11205 (const_string "alu")
11206 ]
11207 (const_string "ishift")))
11208 (set_attr "mode" "QI,SI")])
11209
11210 ;; This pattern can't accept a variable shift count, since shifts by
11211 ;; zero don't affect the flags. We assume that shifts by constant
11212 ;; zero are optimized away.
11213 (define_insn "*ashlqi3_cmp"
11214 [(set (reg FLAGS_REG)
11215 (compare
11216 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11217 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11218 (const_int 0)))
11219 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11220 (ashift:QI (match_dup 1) (match_dup 2)))]
11221 "ix86_match_ccmode (insn, CCGOCmode)
11222 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11223 && (optimize_size
11224 || !TARGET_PARTIAL_FLAG_REG_STALL
11225 || (operands[2] == const1_rtx
11226 && (TARGET_SHIFT1
11227 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11228 {
11229 switch (get_attr_type (insn))
11230 {
11231 case TYPE_ALU:
11232 gcc_assert (operands[2] == const1_rtx);
11233 return "add{b}\t%0, %0";
11234
11235 default:
11236 if (REG_P (operands[2]))
11237 return "sal{b}\t{%b2, %0|%0, %b2}";
11238 else if (operands[2] == const1_rtx
11239 && (TARGET_SHIFT1 || optimize_size))
11240 return "sal{b}\t%0";
11241 else
11242 return "sal{b}\t{%2, %0|%0, %2}";
11243 }
11244 }
11245 [(set (attr "type")
11246 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11247 (const_int 0))
11248 (match_operand 0 "register_operand" ""))
11249 (match_operand 2 "const1_operand" ""))
11250 (const_string "alu")
11251 ]
11252 (const_string "ishift")))
11253 (set_attr "mode" "QI")])
11254
11255 (define_insn "*ashlqi3_cconly"
11256 [(set (reg FLAGS_REG)
11257 (compare
11258 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11259 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11260 (const_int 0)))
11261 (clobber (match_scratch:QI 0 "=q"))]
11262 "ix86_match_ccmode (insn, CCGOCmode)
11263 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11264 && (optimize_size
11265 || !TARGET_PARTIAL_FLAG_REG_STALL
11266 || (operands[2] == const1_rtx
11267 && (TARGET_SHIFT1
11268 || TARGET_DOUBLE_WITH_ADD)))"
11269 {
11270 switch (get_attr_type (insn))
11271 {
11272 case TYPE_ALU:
11273 gcc_assert (operands[2] == const1_rtx);
11274 return "add{b}\t%0, %0";
11275
11276 default:
11277 if (REG_P (operands[2]))
11278 return "sal{b}\t{%b2, %0|%0, %b2}";
11279 else if (operands[2] == const1_rtx
11280 && (TARGET_SHIFT1 || optimize_size))
11281 return "sal{b}\t%0";
11282 else
11283 return "sal{b}\t{%2, %0|%0, %2}";
11284 }
11285 }
11286 [(set (attr "type")
11287 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11288 (const_int 0))
11289 (match_operand 0 "register_operand" ""))
11290 (match_operand 2 "const1_operand" ""))
11291 (const_string "alu")
11292 ]
11293 (const_string "ishift")))
11294 (set_attr "mode" "QI")])
11295
11296 ;; See comment above `ashldi3' about how this works.
11297
11298 (define_expand "ashrti3"
11299 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11300 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11301 (match_operand:QI 2 "nonmemory_operand" "")))
11302 (clobber (reg:CC FLAGS_REG))])]
11303 "TARGET_64BIT"
11304 {
11305 if (! immediate_operand (operands[2], QImode))
11306 {
11307 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11308 DONE;
11309 }
11310 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11311 DONE;
11312 })
11313
11314 (define_insn "ashrti3_1"
11315 [(set (match_operand:TI 0 "register_operand" "=r")
11316 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11317 (match_operand:QI 2 "register_operand" "c")))
11318 (clobber (match_scratch:DI 3 "=&r"))
11319 (clobber (reg:CC FLAGS_REG))]
11320 "TARGET_64BIT"
11321 "#"
11322 [(set_attr "type" "multi")])
11323
11324 (define_insn "*ashrti3_2"
11325 [(set (match_operand:TI 0 "register_operand" "=r")
11326 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11327 (match_operand:QI 2 "immediate_operand" "O")))
11328 (clobber (reg:CC FLAGS_REG))]
11329 "TARGET_64BIT"
11330 "#"
11331 [(set_attr "type" "multi")])
11332
11333 (define_split
11334 [(set (match_operand:TI 0 "register_operand" "")
11335 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11336 (match_operand:QI 2 "register_operand" "")))
11337 (clobber (match_scratch:DI 3 ""))
11338 (clobber (reg:CC FLAGS_REG))]
11339 "TARGET_64BIT && reload_completed"
11340 [(const_int 0)]
11341 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11342
11343 (define_split
11344 [(set (match_operand:TI 0 "register_operand" "")
11345 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11346 (match_operand:QI 2 "immediate_operand" "")))
11347 (clobber (reg:CC FLAGS_REG))]
11348 "TARGET_64BIT && reload_completed"
11349 [(const_int 0)]
11350 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11351
11352 (define_insn "x86_64_shrd"
11353 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11354 (ior:DI (ashiftrt:DI (match_dup 0)
11355 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11356 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11357 (minus:QI (const_int 64) (match_dup 2)))))
11358 (clobber (reg:CC FLAGS_REG))]
11359 "TARGET_64BIT"
11360 "@
11361 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11362 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11363 [(set_attr "type" "ishift")
11364 (set_attr "prefix_0f" "1")
11365 (set_attr "mode" "DI")
11366 (set_attr "athlon_decode" "vector")
11367 (set_attr "amdfam10_decode" "vector")])
11368
11369 (define_expand "ashrdi3"
11370 [(set (match_operand:DI 0 "shiftdi_operand" "")
11371 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11372 (match_operand:QI 2 "nonmemory_operand" "")))]
11373 ""
11374 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11375
11376 (define_insn "*ashrdi3_63_rex64"
11377 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11378 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11379 (match_operand:DI 2 "const_int_operand" "i,i")))
11380 (clobber (reg:CC FLAGS_REG))]
11381 "TARGET_64BIT && INTVAL (operands[2]) == 63
11382 && (TARGET_USE_CLTD || optimize_size)
11383 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11384 "@
11385 {cqto|cqo}
11386 sar{q}\t{%2, %0|%0, %2}"
11387 [(set_attr "type" "imovx,ishift")
11388 (set_attr "prefix_0f" "0,*")
11389 (set_attr "length_immediate" "0,*")
11390 (set_attr "modrm" "0,1")
11391 (set_attr "mode" "DI")])
11392
11393 (define_insn "*ashrdi3_1_one_bit_rex64"
11394 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11395 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11396 (match_operand:QI 2 "const1_operand" "")))
11397 (clobber (reg:CC FLAGS_REG))]
11398 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11399 && (TARGET_SHIFT1 || optimize_size)"
11400 "sar{q}\t%0"
11401 [(set_attr "type" "ishift")
11402 (set (attr "length")
11403 (if_then_else (match_operand:DI 0 "register_operand" "")
11404 (const_string "2")
11405 (const_string "*")))])
11406
11407 (define_insn "*ashrdi3_1_rex64"
11408 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11409 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11410 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11411 (clobber (reg:CC FLAGS_REG))]
11412 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11413 "@
11414 sar{q}\t{%2, %0|%0, %2}
11415 sar{q}\t{%b2, %0|%0, %b2}"
11416 [(set_attr "type" "ishift")
11417 (set_attr "mode" "DI")])
11418
11419 ;; This pattern can't accept a variable shift count, since shifts by
11420 ;; zero don't affect the flags. We assume that shifts by constant
11421 ;; zero are optimized away.
11422 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11423 [(set (reg FLAGS_REG)
11424 (compare
11425 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11426 (match_operand:QI 2 "const1_operand" ""))
11427 (const_int 0)))
11428 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11429 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11430 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11431 && (TARGET_SHIFT1 || optimize_size)
11432 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11433 "sar{q}\t%0"
11434 [(set_attr "type" "ishift")
11435 (set (attr "length")
11436 (if_then_else (match_operand:DI 0 "register_operand" "")
11437 (const_string "2")
11438 (const_string "*")))])
11439
11440 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11441 [(set (reg FLAGS_REG)
11442 (compare
11443 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11444 (match_operand:QI 2 "const1_operand" ""))
11445 (const_int 0)))
11446 (clobber (match_scratch:DI 0 "=r"))]
11447 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11448 && (TARGET_SHIFT1 || optimize_size)
11449 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11450 "sar{q}\t%0"
11451 [(set_attr "type" "ishift")
11452 (set_attr "length" "2")])
11453
11454 ;; This pattern can't accept a variable shift count, since shifts by
11455 ;; zero don't affect the flags. We assume that shifts by constant
11456 ;; zero are optimized away.
11457 (define_insn "*ashrdi3_cmp_rex64"
11458 [(set (reg FLAGS_REG)
11459 (compare
11460 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11461 (match_operand:QI 2 "const_int_operand" "n"))
11462 (const_int 0)))
11463 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11464 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11465 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11466 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11467 && (optimize_size
11468 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11469 "sar{q}\t{%2, %0|%0, %2}"
11470 [(set_attr "type" "ishift")
11471 (set_attr "mode" "DI")])
11472
11473 (define_insn "*ashrdi3_cconly_rex64"
11474 [(set (reg FLAGS_REG)
11475 (compare
11476 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11477 (match_operand:QI 2 "const_int_operand" "n"))
11478 (const_int 0)))
11479 (clobber (match_scratch:DI 0 "=r"))]
11480 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11481 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11482 && (optimize_size
11483 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11484 "sar{q}\t{%2, %0|%0, %2}"
11485 [(set_attr "type" "ishift")
11486 (set_attr "mode" "DI")])
11487
11488 (define_insn "*ashrdi3_1"
11489 [(set (match_operand:DI 0 "register_operand" "=r")
11490 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11491 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11492 (clobber (reg:CC FLAGS_REG))]
11493 "!TARGET_64BIT"
11494 "#"
11495 [(set_attr "type" "multi")])
11496
11497 ;; By default we don't ask for a scratch register, because when DImode
11498 ;; values are manipulated, registers are already at a premium. But if
11499 ;; we have one handy, we won't turn it away.
11500 (define_peephole2
11501 [(match_scratch:SI 3 "r")
11502 (parallel [(set (match_operand:DI 0 "register_operand" "")
11503 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11504 (match_operand:QI 2 "nonmemory_operand" "")))
11505 (clobber (reg:CC FLAGS_REG))])
11506 (match_dup 3)]
11507 "!TARGET_64BIT && TARGET_CMOVE"
11508 [(const_int 0)]
11509 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11510
11511 (define_split
11512 [(set (match_operand:DI 0 "register_operand" "")
11513 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11514 (match_operand:QI 2 "nonmemory_operand" "")))
11515 (clobber (reg:CC FLAGS_REG))]
11516 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11517 ? epilogue_completed : reload_completed)"
11518 [(const_int 0)]
11519 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11520
11521 (define_insn "x86_shrd_1"
11522 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11523 (ior:SI (ashiftrt:SI (match_dup 0)
11524 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11525 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11526 (minus:QI (const_int 32) (match_dup 2)))))
11527 (clobber (reg:CC FLAGS_REG))]
11528 ""
11529 "@
11530 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11531 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11532 [(set_attr "type" "ishift")
11533 (set_attr "prefix_0f" "1")
11534 (set_attr "pent_pair" "np")
11535 (set_attr "mode" "SI")])
11536
11537 (define_expand "x86_shift_adj_3"
11538 [(use (match_operand:SI 0 "register_operand" ""))
11539 (use (match_operand:SI 1 "register_operand" ""))
11540 (use (match_operand:QI 2 "register_operand" ""))]
11541 ""
11542 {
11543 rtx label = gen_label_rtx ();
11544 rtx tmp;
11545
11546 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11547
11548 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11549 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11550 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11551 gen_rtx_LABEL_REF (VOIDmode, label),
11552 pc_rtx);
11553 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11554 JUMP_LABEL (tmp) = label;
11555
11556 emit_move_insn (operands[0], operands[1]);
11557 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11558
11559 emit_label (label);
11560 LABEL_NUSES (label) = 1;
11561
11562 DONE;
11563 })
11564
11565 (define_insn "ashrsi3_31"
11566 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11567 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11568 (match_operand:SI 2 "const_int_operand" "i,i")))
11569 (clobber (reg:CC FLAGS_REG))]
11570 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11571 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11572 "@
11573 {cltd|cdq}
11574 sar{l}\t{%2, %0|%0, %2}"
11575 [(set_attr "type" "imovx,ishift")
11576 (set_attr "prefix_0f" "0,*")
11577 (set_attr "length_immediate" "0,*")
11578 (set_attr "modrm" "0,1")
11579 (set_attr "mode" "SI")])
11580
11581 (define_insn "*ashrsi3_31_zext"
11582 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11583 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11584 (match_operand:SI 2 "const_int_operand" "i,i"))))
11585 (clobber (reg:CC FLAGS_REG))]
11586 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11587 && INTVAL (operands[2]) == 31
11588 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11589 "@
11590 {cltd|cdq}
11591 sar{l}\t{%2, %k0|%k0, %2}"
11592 [(set_attr "type" "imovx,ishift")
11593 (set_attr "prefix_0f" "0,*")
11594 (set_attr "length_immediate" "0,*")
11595 (set_attr "modrm" "0,1")
11596 (set_attr "mode" "SI")])
11597
11598 (define_expand "ashrsi3"
11599 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11600 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11601 (match_operand:QI 2 "nonmemory_operand" "")))
11602 (clobber (reg:CC FLAGS_REG))]
11603 ""
11604 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11605
11606 (define_insn "*ashrsi3_1_one_bit"
11607 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11608 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11609 (match_operand:QI 2 "const1_operand" "")))
11610 (clobber (reg:CC FLAGS_REG))]
11611 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11612 && (TARGET_SHIFT1 || optimize_size)"
11613 "sar{l}\t%0"
11614 [(set_attr "type" "ishift")
11615 (set (attr "length")
11616 (if_then_else (match_operand:SI 0 "register_operand" "")
11617 (const_string "2")
11618 (const_string "*")))])
11619
11620 (define_insn "*ashrsi3_1_one_bit_zext"
11621 [(set (match_operand:DI 0 "register_operand" "=r")
11622 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11623 (match_operand:QI 2 "const1_operand" ""))))
11624 (clobber (reg:CC FLAGS_REG))]
11625 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11626 && (TARGET_SHIFT1 || optimize_size)"
11627 "sar{l}\t%k0"
11628 [(set_attr "type" "ishift")
11629 (set_attr "length" "2")])
11630
11631 (define_insn "*ashrsi3_1"
11632 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11633 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11634 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11635 (clobber (reg:CC FLAGS_REG))]
11636 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11637 "@
11638 sar{l}\t{%2, %0|%0, %2}
11639 sar{l}\t{%b2, %0|%0, %b2}"
11640 [(set_attr "type" "ishift")
11641 (set_attr "mode" "SI")])
11642
11643 (define_insn "*ashrsi3_1_zext"
11644 [(set (match_operand:DI 0 "register_operand" "=r,r")
11645 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11646 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11647 (clobber (reg:CC FLAGS_REG))]
11648 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11649 "@
11650 sar{l}\t{%2, %k0|%k0, %2}
11651 sar{l}\t{%b2, %k0|%k0, %b2}"
11652 [(set_attr "type" "ishift")
11653 (set_attr "mode" "SI")])
11654
11655 ;; This pattern can't accept a variable shift count, since shifts by
11656 ;; zero don't affect the flags. We assume that shifts by constant
11657 ;; zero are optimized away.
11658 (define_insn "*ashrsi3_one_bit_cmp"
11659 [(set (reg FLAGS_REG)
11660 (compare
11661 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11662 (match_operand:QI 2 "const1_operand" ""))
11663 (const_int 0)))
11664 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11665 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11666 "ix86_match_ccmode (insn, CCGOCmode)
11667 && (TARGET_SHIFT1 || optimize_size)
11668 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11669 "sar{l}\t%0"
11670 [(set_attr "type" "ishift")
11671 (set (attr "length")
11672 (if_then_else (match_operand:SI 0 "register_operand" "")
11673 (const_string "2")
11674 (const_string "*")))])
11675
11676 (define_insn "*ashrsi3_one_bit_cconly"
11677 [(set (reg FLAGS_REG)
11678 (compare
11679 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11680 (match_operand:QI 2 "const1_operand" ""))
11681 (const_int 0)))
11682 (clobber (match_scratch:SI 0 "=r"))]
11683 "ix86_match_ccmode (insn, CCGOCmode)
11684 && (TARGET_SHIFT1 || optimize_size)
11685 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11686 "sar{l}\t%0"
11687 [(set_attr "type" "ishift")
11688 (set_attr "length" "2")])
11689
11690 (define_insn "*ashrsi3_one_bit_cmp_zext"
11691 [(set (reg FLAGS_REG)
11692 (compare
11693 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11694 (match_operand:QI 2 "const1_operand" ""))
11695 (const_int 0)))
11696 (set (match_operand:DI 0 "register_operand" "=r")
11697 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11698 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11699 && (TARGET_SHIFT1 || optimize_size)
11700 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11701 "sar{l}\t%k0"
11702 [(set_attr "type" "ishift")
11703 (set_attr "length" "2")])
11704
11705 ;; This pattern can't accept a variable shift count, since shifts by
11706 ;; zero don't affect the flags. We assume that shifts by constant
11707 ;; zero are optimized away.
11708 (define_insn "*ashrsi3_cmp"
11709 [(set (reg FLAGS_REG)
11710 (compare
11711 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11712 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11713 (const_int 0)))
11714 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11715 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11716 "ix86_match_ccmode (insn, CCGOCmode)
11717 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11718 && (optimize_size
11719 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11720 "sar{l}\t{%2, %0|%0, %2}"
11721 [(set_attr "type" "ishift")
11722 (set_attr "mode" "SI")])
11723
11724 (define_insn "*ashrsi3_cconly"
11725 [(set (reg FLAGS_REG)
11726 (compare
11727 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11728 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11729 (const_int 0)))
11730 (clobber (match_scratch:SI 0 "=r"))]
11731 "ix86_match_ccmode (insn, CCGOCmode)
11732 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11733 && (optimize_size
11734 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11735 "sar{l}\t{%2, %0|%0, %2}"
11736 [(set_attr "type" "ishift")
11737 (set_attr "mode" "SI")])
11738
11739 (define_insn "*ashrsi3_cmp_zext"
11740 [(set (reg FLAGS_REG)
11741 (compare
11742 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11743 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11744 (const_int 0)))
11745 (set (match_operand:DI 0 "register_operand" "=r")
11746 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11747 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11748 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11749 && (optimize_size
11750 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11751 "sar{l}\t{%2, %k0|%k0, %2}"
11752 [(set_attr "type" "ishift")
11753 (set_attr "mode" "SI")])
11754
11755 (define_expand "ashrhi3"
11756 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11757 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11758 (match_operand:QI 2 "nonmemory_operand" "")))
11759 (clobber (reg:CC FLAGS_REG))]
11760 "TARGET_HIMODE_MATH"
11761 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11762
11763 (define_insn "*ashrhi3_1_one_bit"
11764 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11765 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11766 (match_operand:QI 2 "const1_operand" "")))
11767 (clobber (reg:CC FLAGS_REG))]
11768 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11769 && (TARGET_SHIFT1 || optimize_size)"
11770 "sar{w}\t%0"
11771 [(set_attr "type" "ishift")
11772 (set (attr "length")
11773 (if_then_else (match_operand 0 "register_operand" "")
11774 (const_string "2")
11775 (const_string "*")))])
11776
11777 (define_insn "*ashrhi3_1"
11778 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11779 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11780 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11781 (clobber (reg:CC FLAGS_REG))]
11782 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11783 "@
11784 sar{w}\t{%2, %0|%0, %2}
11785 sar{w}\t{%b2, %0|%0, %b2}"
11786 [(set_attr "type" "ishift")
11787 (set_attr "mode" "HI")])
11788
11789 ;; This pattern can't accept a variable shift count, since shifts by
11790 ;; zero don't affect the flags. We assume that shifts by constant
11791 ;; zero are optimized away.
11792 (define_insn "*ashrhi3_one_bit_cmp"
11793 [(set (reg FLAGS_REG)
11794 (compare
11795 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11796 (match_operand:QI 2 "const1_operand" ""))
11797 (const_int 0)))
11798 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11799 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11800 "ix86_match_ccmode (insn, CCGOCmode)
11801 && (TARGET_SHIFT1 || optimize_size)
11802 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11803 "sar{w}\t%0"
11804 [(set_attr "type" "ishift")
11805 (set (attr "length")
11806 (if_then_else (match_operand 0 "register_operand" "")
11807 (const_string "2")
11808 (const_string "*")))])
11809
11810 (define_insn "*ashrhi3_one_bit_cconly"
11811 [(set (reg FLAGS_REG)
11812 (compare
11813 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11814 (match_operand:QI 2 "const1_operand" ""))
11815 (const_int 0)))
11816 (clobber (match_scratch:HI 0 "=r"))]
11817 "ix86_match_ccmode (insn, CCGOCmode)
11818 && (TARGET_SHIFT1 || optimize_size)
11819 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11820 "sar{w}\t%0"
11821 [(set_attr "type" "ishift")
11822 (set_attr "length" "2")])
11823
11824 ;; This pattern can't accept a variable shift count, since shifts by
11825 ;; zero don't affect the flags. We assume that shifts by constant
11826 ;; zero are optimized away.
11827 (define_insn "*ashrhi3_cmp"
11828 [(set (reg FLAGS_REG)
11829 (compare
11830 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11831 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11832 (const_int 0)))
11833 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11834 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11835 "ix86_match_ccmode (insn, CCGOCmode)
11836 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11837 && (optimize_size
11838 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11839 "sar{w}\t{%2, %0|%0, %2}"
11840 [(set_attr "type" "ishift")
11841 (set_attr "mode" "HI")])
11842
11843 (define_insn "*ashrhi3_cconly"
11844 [(set (reg FLAGS_REG)
11845 (compare
11846 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11847 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11848 (const_int 0)))
11849 (clobber (match_scratch:HI 0 "=r"))]
11850 "ix86_match_ccmode (insn, CCGOCmode)
11851 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11852 && (optimize_size
11853 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11854 "sar{w}\t{%2, %0|%0, %2}"
11855 [(set_attr "type" "ishift")
11856 (set_attr "mode" "HI")])
11857
11858 (define_expand "ashrqi3"
11859 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11860 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11861 (match_operand:QI 2 "nonmemory_operand" "")))
11862 (clobber (reg:CC FLAGS_REG))]
11863 "TARGET_QIMODE_MATH"
11864 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11865
11866 (define_insn "*ashrqi3_1_one_bit"
11867 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11868 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11869 (match_operand:QI 2 "const1_operand" "")))
11870 (clobber (reg:CC FLAGS_REG))]
11871 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11872 && (TARGET_SHIFT1 || optimize_size)"
11873 "sar{b}\t%0"
11874 [(set_attr "type" "ishift")
11875 (set (attr "length")
11876 (if_then_else (match_operand 0 "register_operand" "")
11877 (const_string "2")
11878 (const_string "*")))])
11879
11880 (define_insn "*ashrqi3_1_one_bit_slp"
11881 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11882 (ashiftrt:QI (match_dup 0)
11883 (match_operand:QI 1 "const1_operand" "")))
11884 (clobber (reg:CC FLAGS_REG))]
11885 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11886 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11887 && (TARGET_SHIFT1 || optimize_size)"
11888 "sar{b}\t%0"
11889 [(set_attr "type" "ishift1")
11890 (set (attr "length")
11891 (if_then_else (match_operand 0 "register_operand" "")
11892 (const_string "2")
11893 (const_string "*")))])
11894
11895 (define_insn "*ashrqi3_1"
11896 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11897 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11898 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11899 (clobber (reg:CC FLAGS_REG))]
11900 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11901 "@
11902 sar{b}\t{%2, %0|%0, %2}
11903 sar{b}\t{%b2, %0|%0, %b2}"
11904 [(set_attr "type" "ishift")
11905 (set_attr "mode" "QI")])
11906
11907 (define_insn "*ashrqi3_1_slp"
11908 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11909 (ashiftrt:QI (match_dup 0)
11910 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11911 (clobber (reg:CC FLAGS_REG))]
11912 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11913 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11914 "@
11915 sar{b}\t{%1, %0|%0, %1}
11916 sar{b}\t{%b1, %0|%0, %b1}"
11917 [(set_attr "type" "ishift1")
11918 (set_attr "mode" "QI")])
11919
11920 ;; This pattern can't accept a variable shift count, since shifts by
11921 ;; zero don't affect the flags. We assume that shifts by constant
11922 ;; zero are optimized away.
11923 (define_insn "*ashrqi3_one_bit_cmp"
11924 [(set (reg FLAGS_REG)
11925 (compare
11926 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11927 (match_operand:QI 2 "const1_operand" "I"))
11928 (const_int 0)))
11929 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11930 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11931 "ix86_match_ccmode (insn, CCGOCmode)
11932 && (TARGET_SHIFT1 || optimize_size)
11933 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11934 "sar{b}\t%0"
11935 [(set_attr "type" "ishift")
11936 (set (attr "length")
11937 (if_then_else (match_operand 0 "register_operand" "")
11938 (const_string "2")
11939 (const_string "*")))])
11940
11941 (define_insn "*ashrqi3_one_bit_cconly"
11942 [(set (reg FLAGS_REG)
11943 (compare
11944 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11945 (match_operand:QI 2 "const1_operand" "I"))
11946 (const_int 0)))
11947 (clobber (match_scratch:QI 0 "=q"))]
11948 "ix86_match_ccmode (insn, CCGOCmode)
11949 && (TARGET_SHIFT1 || optimize_size)
11950 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11951 "sar{b}\t%0"
11952 [(set_attr "type" "ishift")
11953 (set_attr "length" "2")])
11954
11955 ;; This pattern can't accept a variable shift count, since shifts by
11956 ;; zero don't affect the flags. We assume that shifts by constant
11957 ;; zero are optimized away.
11958 (define_insn "*ashrqi3_cmp"
11959 [(set (reg FLAGS_REG)
11960 (compare
11961 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11962 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11963 (const_int 0)))
11964 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11965 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11966 "ix86_match_ccmode (insn, CCGOCmode)
11967 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11968 && (optimize_size
11969 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11970 "sar{b}\t{%2, %0|%0, %2}"
11971 [(set_attr "type" "ishift")
11972 (set_attr "mode" "QI")])
11973
11974 (define_insn "*ashrqi3_cconly"
11975 [(set (reg FLAGS_REG)
11976 (compare
11977 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11978 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11979 (const_int 0)))
11980 (clobber (match_scratch:QI 0 "=q"))]
11981 "ix86_match_ccmode (insn, CCGOCmode)
11982 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11983 && (optimize_size
11984 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11985 "sar{b}\t{%2, %0|%0, %2}"
11986 [(set_attr "type" "ishift")
11987 (set_attr "mode" "QI")])
11988
11989 \f
11990 ;; Logical shift instructions
11991
11992 ;; See comment above `ashldi3' about how this works.
11993
11994 (define_expand "lshrti3"
11995 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11996 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11997 (match_operand:QI 2 "nonmemory_operand" "")))
11998 (clobber (reg:CC FLAGS_REG))])]
11999 "TARGET_64BIT"
12000 {
12001 if (! immediate_operand (operands[2], QImode))
12002 {
12003 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12004 DONE;
12005 }
12006 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12007 DONE;
12008 })
12009
12010 (define_insn "lshrti3_1"
12011 [(set (match_operand:TI 0 "register_operand" "=r")
12012 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12013 (match_operand:QI 2 "register_operand" "c")))
12014 (clobber (match_scratch:DI 3 "=&r"))
12015 (clobber (reg:CC FLAGS_REG))]
12016 "TARGET_64BIT"
12017 "#"
12018 [(set_attr "type" "multi")])
12019
12020 ;; This pattern must be defined before *lshrti3_2 to prevent
12021 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12022
12023 (define_insn "sse2_lshrti3"
12024 [(set (match_operand:TI 0 "register_operand" "=x")
12025 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12026 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12027 "TARGET_SSE2"
12028 {
12029 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12030 return "psrldq\t{%2, %0|%0, %2}";
12031 }
12032 [(set_attr "type" "sseishft")
12033 (set_attr "prefix_data16" "1")
12034 (set_attr "mode" "TI")])
12035
12036 (define_insn "*lshrti3_2"
12037 [(set (match_operand:TI 0 "register_operand" "=r")
12038 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12039 (match_operand:QI 2 "immediate_operand" "O")))
12040 (clobber (reg:CC FLAGS_REG))]
12041 "TARGET_64BIT"
12042 "#"
12043 [(set_attr "type" "multi")])
12044
12045 (define_split
12046 [(set (match_operand:TI 0 "register_operand" "")
12047 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12048 (match_operand:QI 2 "register_operand" "")))
12049 (clobber (match_scratch:DI 3 ""))
12050 (clobber (reg:CC FLAGS_REG))]
12051 "TARGET_64BIT && reload_completed"
12052 [(const_int 0)]
12053 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12054
12055 (define_split
12056 [(set (match_operand:TI 0 "register_operand" "")
12057 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12058 (match_operand:QI 2 "immediate_operand" "")))
12059 (clobber (reg:CC FLAGS_REG))]
12060 "TARGET_64BIT && reload_completed"
12061 [(const_int 0)]
12062 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12063
12064 (define_expand "lshrdi3"
12065 [(set (match_operand:DI 0 "shiftdi_operand" "")
12066 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12067 (match_operand:QI 2 "nonmemory_operand" "")))]
12068 ""
12069 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12070
12071 (define_insn "*lshrdi3_1_one_bit_rex64"
12072 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12073 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12074 (match_operand:QI 2 "const1_operand" "")))
12075 (clobber (reg:CC FLAGS_REG))]
12076 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12077 && (TARGET_SHIFT1 || optimize_size)"
12078 "shr{q}\t%0"
12079 [(set_attr "type" "ishift")
12080 (set (attr "length")
12081 (if_then_else (match_operand:DI 0 "register_operand" "")
12082 (const_string "2")
12083 (const_string "*")))])
12084
12085 (define_insn "*lshrdi3_1_rex64"
12086 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12087 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12088 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12089 (clobber (reg:CC FLAGS_REG))]
12090 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12091 "@
12092 shr{q}\t{%2, %0|%0, %2}
12093 shr{q}\t{%b2, %0|%0, %b2}"
12094 [(set_attr "type" "ishift")
12095 (set_attr "mode" "DI")])
12096
12097 ;; This pattern can't accept a variable shift count, since shifts by
12098 ;; zero don't affect the flags. We assume that shifts by constant
12099 ;; zero are optimized away.
12100 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12101 [(set (reg FLAGS_REG)
12102 (compare
12103 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12104 (match_operand:QI 2 "const1_operand" ""))
12105 (const_int 0)))
12106 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12107 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12108 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12109 && (TARGET_SHIFT1 || optimize_size)
12110 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12111 "shr{q}\t%0"
12112 [(set_attr "type" "ishift")
12113 (set (attr "length")
12114 (if_then_else (match_operand:DI 0 "register_operand" "")
12115 (const_string "2")
12116 (const_string "*")))])
12117
12118 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12119 [(set (reg FLAGS_REG)
12120 (compare
12121 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12122 (match_operand:QI 2 "const1_operand" ""))
12123 (const_int 0)))
12124 (clobber (match_scratch:DI 0 "=r"))]
12125 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12126 && (TARGET_SHIFT1 || optimize_size)
12127 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12128 "shr{q}\t%0"
12129 [(set_attr "type" "ishift")
12130 (set_attr "length" "2")])
12131
12132 ;; This pattern can't accept a variable shift count, since shifts by
12133 ;; zero don't affect the flags. We assume that shifts by constant
12134 ;; zero are optimized away.
12135 (define_insn "*lshrdi3_cmp_rex64"
12136 [(set (reg FLAGS_REG)
12137 (compare
12138 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12139 (match_operand:QI 2 "const_int_operand" "e"))
12140 (const_int 0)))
12141 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12142 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12143 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12144 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12145 && (optimize_size
12146 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12147 "shr{q}\t{%2, %0|%0, %2}"
12148 [(set_attr "type" "ishift")
12149 (set_attr "mode" "DI")])
12150
12151 (define_insn "*lshrdi3_cconly_rex64"
12152 [(set (reg FLAGS_REG)
12153 (compare
12154 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12155 (match_operand:QI 2 "const_int_operand" "e"))
12156 (const_int 0)))
12157 (clobber (match_scratch:DI 0 "=r"))]
12158 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12159 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12160 && (optimize_size
12161 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12162 "shr{q}\t{%2, %0|%0, %2}"
12163 [(set_attr "type" "ishift")
12164 (set_attr "mode" "DI")])
12165
12166 (define_insn "*lshrdi3_1"
12167 [(set (match_operand:DI 0 "register_operand" "=r")
12168 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12169 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12170 (clobber (reg:CC FLAGS_REG))]
12171 "!TARGET_64BIT"
12172 "#"
12173 [(set_attr "type" "multi")])
12174
12175 ;; By default we don't ask for a scratch register, because when DImode
12176 ;; values are manipulated, registers are already at a premium. But if
12177 ;; we have one handy, we won't turn it away.
12178 (define_peephole2
12179 [(match_scratch:SI 3 "r")
12180 (parallel [(set (match_operand:DI 0 "register_operand" "")
12181 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12182 (match_operand:QI 2 "nonmemory_operand" "")))
12183 (clobber (reg:CC FLAGS_REG))])
12184 (match_dup 3)]
12185 "!TARGET_64BIT && TARGET_CMOVE"
12186 [(const_int 0)]
12187 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12188
12189 (define_split
12190 [(set (match_operand:DI 0 "register_operand" "")
12191 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12192 (match_operand:QI 2 "nonmemory_operand" "")))
12193 (clobber (reg:CC FLAGS_REG))]
12194 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12195 ? epilogue_completed : reload_completed)"
12196 [(const_int 0)]
12197 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12198
12199 (define_expand "lshrsi3"
12200 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12201 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12202 (match_operand:QI 2 "nonmemory_operand" "")))
12203 (clobber (reg:CC FLAGS_REG))]
12204 ""
12205 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12206
12207 (define_insn "*lshrsi3_1_one_bit"
12208 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12209 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12210 (match_operand:QI 2 "const1_operand" "")))
12211 (clobber (reg:CC FLAGS_REG))]
12212 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12213 && (TARGET_SHIFT1 || optimize_size)"
12214 "shr{l}\t%0"
12215 [(set_attr "type" "ishift")
12216 (set (attr "length")
12217 (if_then_else (match_operand:SI 0 "register_operand" "")
12218 (const_string "2")
12219 (const_string "*")))])
12220
12221 (define_insn "*lshrsi3_1_one_bit_zext"
12222 [(set (match_operand:DI 0 "register_operand" "=r")
12223 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12224 (match_operand:QI 2 "const1_operand" "")))
12225 (clobber (reg:CC FLAGS_REG))]
12226 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12227 && (TARGET_SHIFT1 || optimize_size)"
12228 "shr{l}\t%k0"
12229 [(set_attr "type" "ishift")
12230 (set_attr "length" "2")])
12231
12232 (define_insn "*lshrsi3_1"
12233 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12234 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12235 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12236 (clobber (reg:CC FLAGS_REG))]
12237 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12238 "@
12239 shr{l}\t{%2, %0|%0, %2}
12240 shr{l}\t{%b2, %0|%0, %b2}"
12241 [(set_attr "type" "ishift")
12242 (set_attr "mode" "SI")])
12243
12244 (define_insn "*lshrsi3_1_zext"
12245 [(set (match_operand:DI 0 "register_operand" "=r,r")
12246 (zero_extend:DI
12247 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12248 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12249 (clobber (reg:CC FLAGS_REG))]
12250 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12251 "@
12252 shr{l}\t{%2, %k0|%k0, %2}
12253 shr{l}\t{%b2, %k0|%k0, %b2}"
12254 [(set_attr "type" "ishift")
12255 (set_attr "mode" "SI")])
12256
12257 ;; This pattern can't accept a variable shift count, since shifts by
12258 ;; zero don't affect the flags. We assume that shifts by constant
12259 ;; zero are optimized away.
12260 (define_insn "*lshrsi3_one_bit_cmp"
12261 [(set (reg FLAGS_REG)
12262 (compare
12263 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12264 (match_operand:QI 2 "const1_operand" ""))
12265 (const_int 0)))
12266 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12267 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12268 "ix86_match_ccmode (insn, CCGOCmode)
12269 && (TARGET_SHIFT1 || optimize_size)
12270 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12271 "shr{l}\t%0"
12272 [(set_attr "type" "ishift")
12273 (set (attr "length")
12274 (if_then_else (match_operand:SI 0 "register_operand" "")
12275 (const_string "2")
12276 (const_string "*")))])
12277
12278 (define_insn "*lshrsi3_one_bit_cconly"
12279 [(set (reg FLAGS_REG)
12280 (compare
12281 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12282 (match_operand:QI 2 "const1_operand" ""))
12283 (const_int 0)))
12284 (clobber (match_scratch:SI 0 "=r"))]
12285 "ix86_match_ccmode (insn, CCGOCmode)
12286 && (TARGET_SHIFT1 || optimize_size)
12287 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12288 "shr{l}\t%0"
12289 [(set_attr "type" "ishift")
12290 (set_attr "length" "2")])
12291
12292 (define_insn "*lshrsi3_cmp_one_bit_zext"
12293 [(set (reg FLAGS_REG)
12294 (compare
12295 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12296 (match_operand:QI 2 "const1_operand" ""))
12297 (const_int 0)))
12298 (set (match_operand:DI 0 "register_operand" "=r")
12299 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12300 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12301 && (TARGET_SHIFT1 || optimize_size)
12302 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12303 "shr{l}\t%k0"
12304 [(set_attr "type" "ishift")
12305 (set_attr "length" "2")])
12306
12307 ;; This pattern can't accept a variable shift count, since shifts by
12308 ;; zero don't affect the flags. We assume that shifts by constant
12309 ;; zero are optimized away.
12310 (define_insn "*lshrsi3_cmp"
12311 [(set (reg FLAGS_REG)
12312 (compare
12313 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12314 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12315 (const_int 0)))
12316 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12317 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12318 "ix86_match_ccmode (insn, CCGOCmode)
12319 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12320 && (optimize_size
12321 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12322 "shr{l}\t{%2, %0|%0, %2}"
12323 [(set_attr "type" "ishift")
12324 (set_attr "mode" "SI")])
12325
12326 (define_insn "*lshrsi3_cconly"
12327 [(set (reg FLAGS_REG)
12328 (compare
12329 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12330 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12331 (const_int 0)))
12332 (clobber (match_scratch:SI 0 "=r"))]
12333 "ix86_match_ccmode (insn, CCGOCmode)
12334 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12335 && (optimize_size
12336 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12337 "shr{l}\t{%2, %0|%0, %2}"
12338 [(set_attr "type" "ishift")
12339 (set_attr "mode" "SI")])
12340
12341 (define_insn "*lshrsi3_cmp_zext"
12342 [(set (reg FLAGS_REG)
12343 (compare
12344 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12345 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12346 (const_int 0)))
12347 (set (match_operand:DI 0 "register_operand" "=r")
12348 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12349 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12350 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12351 && (optimize_size
12352 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12353 "shr{l}\t{%2, %k0|%k0, %2}"
12354 [(set_attr "type" "ishift")
12355 (set_attr "mode" "SI")])
12356
12357 (define_expand "lshrhi3"
12358 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12359 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12360 (match_operand:QI 2 "nonmemory_operand" "")))
12361 (clobber (reg:CC FLAGS_REG))]
12362 "TARGET_HIMODE_MATH"
12363 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12364
12365 (define_insn "*lshrhi3_1_one_bit"
12366 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12367 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const1_operand" "")))
12369 (clobber (reg:CC FLAGS_REG))]
12370 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12371 && (TARGET_SHIFT1 || optimize_size)"
12372 "shr{w}\t%0"
12373 [(set_attr "type" "ishift")
12374 (set (attr "length")
12375 (if_then_else (match_operand 0 "register_operand" "")
12376 (const_string "2")
12377 (const_string "*")))])
12378
12379 (define_insn "*lshrhi3_1"
12380 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12381 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12382 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12383 (clobber (reg:CC FLAGS_REG))]
12384 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12385 "@
12386 shr{w}\t{%2, %0|%0, %2}
12387 shr{w}\t{%b2, %0|%0, %b2}"
12388 [(set_attr "type" "ishift")
12389 (set_attr "mode" "HI")])
12390
12391 ;; This pattern can't accept a variable shift count, since shifts by
12392 ;; zero don't affect the flags. We assume that shifts by constant
12393 ;; zero are optimized away.
12394 (define_insn "*lshrhi3_one_bit_cmp"
12395 [(set (reg FLAGS_REG)
12396 (compare
12397 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12398 (match_operand:QI 2 "const1_operand" ""))
12399 (const_int 0)))
12400 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12401 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12402 "ix86_match_ccmode (insn, CCGOCmode)
12403 && (TARGET_SHIFT1 || optimize_size)
12404 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12405 "shr{w}\t%0"
12406 [(set_attr "type" "ishift")
12407 (set (attr "length")
12408 (if_then_else (match_operand:SI 0 "register_operand" "")
12409 (const_string "2")
12410 (const_string "*")))])
12411
12412 (define_insn "*lshrhi3_one_bit_cconly"
12413 [(set (reg FLAGS_REG)
12414 (compare
12415 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12416 (match_operand:QI 2 "const1_operand" ""))
12417 (const_int 0)))
12418 (clobber (match_scratch:HI 0 "=r"))]
12419 "ix86_match_ccmode (insn, CCGOCmode)
12420 && (TARGET_SHIFT1 || optimize_size)
12421 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12422 "shr{w}\t%0"
12423 [(set_attr "type" "ishift")
12424 (set_attr "length" "2")])
12425
12426 ;; This pattern can't accept a variable shift count, since shifts by
12427 ;; zero don't affect the flags. We assume that shifts by constant
12428 ;; zero are optimized away.
12429 (define_insn "*lshrhi3_cmp"
12430 [(set (reg FLAGS_REG)
12431 (compare
12432 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12433 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12434 (const_int 0)))
12435 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12436 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12437 "ix86_match_ccmode (insn, CCGOCmode)
12438 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12439 && (optimize_size
12440 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12441 "shr{w}\t{%2, %0|%0, %2}"
12442 [(set_attr "type" "ishift")
12443 (set_attr "mode" "HI")])
12444
12445 (define_insn "*lshrhi3_cconly"
12446 [(set (reg FLAGS_REG)
12447 (compare
12448 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12449 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12450 (const_int 0)))
12451 (clobber (match_scratch:HI 0 "=r"))]
12452 "ix86_match_ccmode (insn, CCGOCmode)
12453 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12454 && (optimize_size
12455 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12456 "shr{w}\t{%2, %0|%0, %2}"
12457 [(set_attr "type" "ishift")
12458 (set_attr "mode" "HI")])
12459
12460 (define_expand "lshrqi3"
12461 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12462 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12463 (match_operand:QI 2 "nonmemory_operand" "")))
12464 (clobber (reg:CC FLAGS_REG))]
12465 "TARGET_QIMODE_MATH"
12466 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12467
12468 (define_insn "*lshrqi3_1_one_bit"
12469 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12470 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12471 (match_operand:QI 2 "const1_operand" "")))
12472 (clobber (reg:CC FLAGS_REG))]
12473 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12474 && (TARGET_SHIFT1 || optimize_size)"
12475 "shr{b}\t%0"
12476 [(set_attr "type" "ishift")
12477 (set (attr "length")
12478 (if_then_else (match_operand 0 "register_operand" "")
12479 (const_string "2")
12480 (const_string "*")))])
12481
12482 (define_insn "*lshrqi3_1_one_bit_slp"
12483 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12484 (lshiftrt:QI (match_dup 0)
12485 (match_operand:QI 1 "const1_operand" "")))
12486 (clobber (reg:CC FLAGS_REG))]
12487 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12488 && (TARGET_SHIFT1 || optimize_size)"
12489 "shr{b}\t%0"
12490 [(set_attr "type" "ishift1")
12491 (set (attr "length")
12492 (if_then_else (match_operand 0 "register_operand" "")
12493 (const_string "2")
12494 (const_string "*")))])
12495
12496 (define_insn "*lshrqi3_1"
12497 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12498 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12499 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12500 (clobber (reg:CC FLAGS_REG))]
12501 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12502 "@
12503 shr{b}\t{%2, %0|%0, %2}
12504 shr{b}\t{%b2, %0|%0, %b2}"
12505 [(set_attr "type" "ishift")
12506 (set_attr "mode" "QI")])
12507
12508 (define_insn "*lshrqi3_1_slp"
12509 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12510 (lshiftrt:QI (match_dup 0)
12511 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12512 (clobber (reg:CC FLAGS_REG))]
12513 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12514 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12515 "@
12516 shr{b}\t{%1, %0|%0, %1}
12517 shr{b}\t{%b1, %0|%0, %b1}"
12518 [(set_attr "type" "ishift1")
12519 (set_attr "mode" "QI")])
12520
12521 ;; This pattern can't accept a variable shift count, since shifts by
12522 ;; zero don't affect the flags. We assume that shifts by constant
12523 ;; zero are optimized away.
12524 (define_insn "*lshrqi2_one_bit_cmp"
12525 [(set (reg FLAGS_REG)
12526 (compare
12527 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12528 (match_operand:QI 2 "const1_operand" ""))
12529 (const_int 0)))
12530 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12531 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12532 "ix86_match_ccmode (insn, CCGOCmode)
12533 && (TARGET_SHIFT1 || optimize_size)
12534 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12535 "shr{b}\t%0"
12536 [(set_attr "type" "ishift")
12537 (set (attr "length")
12538 (if_then_else (match_operand:SI 0 "register_operand" "")
12539 (const_string "2")
12540 (const_string "*")))])
12541
12542 (define_insn "*lshrqi2_one_bit_cconly"
12543 [(set (reg FLAGS_REG)
12544 (compare
12545 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12546 (match_operand:QI 2 "const1_operand" ""))
12547 (const_int 0)))
12548 (clobber (match_scratch:QI 0 "=q"))]
12549 "ix86_match_ccmode (insn, CCGOCmode)
12550 && (TARGET_SHIFT1 || optimize_size)
12551 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12552 "shr{b}\t%0"
12553 [(set_attr "type" "ishift")
12554 (set_attr "length" "2")])
12555
12556 ;; This pattern can't accept a variable shift count, since shifts by
12557 ;; zero don't affect the flags. We assume that shifts by constant
12558 ;; zero are optimized away.
12559 (define_insn "*lshrqi2_cmp"
12560 [(set (reg FLAGS_REG)
12561 (compare
12562 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12563 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12564 (const_int 0)))
12565 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12566 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12567 "ix86_match_ccmode (insn, CCGOCmode)
12568 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12569 && (optimize_size
12570 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12571 "shr{b}\t{%2, %0|%0, %2}"
12572 [(set_attr "type" "ishift")
12573 (set_attr "mode" "QI")])
12574
12575 (define_insn "*lshrqi2_cconly"
12576 [(set (reg FLAGS_REG)
12577 (compare
12578 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12579 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12580 (const_int 0)))
12581 (clobber (match_scratch:QI 0 "=q"))]
12582 "ix86_match_ccmode (insn, CCGOCmode)
12583 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12584 && (optimize_size
12585 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12586 "shr{b}\t{%2, %0|%0, %2}"
12587 [(set_attr "type" "ishift")
12588 (set_attr "mode" "QI")])
12589 \f
12590 ;; Rotate instructions
12591
12592 (define_expand "rotldi3"
12593 [(set (match_operand:DI 0 "shiftdi_operand" "")
12594 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12595 (match_operand:QI 2 "nonmemory_operand" "")))
12596 (clobber (reg:CC FLAGS_REG))]
12597 ""
12598 {
12599 if (TARGET_64BIT)
12600 {
12601 ix86_expand_binary_operator (ROTATE, DImode, operands);
12602 DONE;
12603 }
12604 if (!const_1_to_31_operand (operands[2], VOIDmode))
12605 FAIL;
12606 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12607 DONE;
12608 })
12609
12610 ;; Implement rotation using two double-precision shift instructions
12611 ;; and a scratch register.
12612 (define_insn_and_split "ix86_rotldi3"
12613 [(set (match_operand:DI 0 "register_operand" "=r")
12614 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12615 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12616 (clobber (reg:CC FLAGS_REG))
12617 (clobber (match_scratch:SI 3 "=&r"))]
12618 "!TARGET_64BIT"
12619 ""
12620 "&& reload_completed"
12621 [(set (match_dup 3) (match_dup 4))
12622 (parallel
12623 [(set (match_dup 4)
12624 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12625 (lshiftrt:SI (match_dup 5)
12626 (minus:QI (const_int 32) (match_dup 2)))))
12627 (clobber (reg:CC FLAGS_REG))])
12628 (parallel
12629 [(set (match_dup 5)
12630 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12631 (lshiftrt:SI (match_dup 3)
12632 (minus:QI (const_int 32) (match_dup 2)))))
12633 (clobber (reg:CC FLAGS_REG))])]
12634 "split_di (operands, 1, operands + 4, operands + 5);")
12635
12636 (define_insn "*rotlsi3_1_one_bit_rex64"
12637 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12638 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12639 (match_operand:QI 2 "const1_operand" "")))
12640 (clobber (reg:CC FLAGS_REG))]
12641 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12642 && (TARGET_SHIFT1 || optimize_size)"
12643 "rol{q}\t%0"
12644 [(set_attr "type" "rotate")
12645 (set (attr "length")
12646 (if_then_else (match_operand:DI 0 "register_operand" "")
12647 (const_string "2")
12648 (const_string "*")))])
12649
12650 (define_insn "*rotldi3_1_rex64"
12651 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12652 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12653 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12654 (clobber (reg:CC FLAGS_REG))]
12655 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12656 "@
12657 rol{q}\t{%2, %0|%0, %2}
12658 rol{q}\t{%b2, %0|%0, %b2}"
12659 [(set_attr "type" "rotate")
12660 (set_attr "mode" "DI")])
12661
12662 (define_expand "rotlsi3"
12663 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12664 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12665 (match_operand:QI 2 "nonmemory_operand" "")))
12666 (clobber (reg:CC FLAGS_REG))]
12667 ""
12668 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12669
12670 (define_insn "*rotlsi3_1_one_bit"
12671 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12672 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12673 (match_operand:QI 2 "const1_operand" "")))
12674 (clobber (reg:CC FLAGS_REG))]
12675 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12676 && (TARGET_SHIFT1 || optimize_size)"
12677 "rol{l}\t%0"
12678 [(set_attr "type" "rotate")
12679 (set (attr "length")
12680 (if_then_else (match_operand:SI 0 "register_operand" "")
12681 (const_string "2")
12682 (const_string "*")))])
12683
12684 (define_insn "*rotlsi3_1_one_bit_zext"
12685 [(set (match_operand:DI 0 "register_operand" "=r")
12686 (zero_extend:DI
12687 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12688 (match_operand:QI 2 "const1_operand" ""))))
12689 (clobber (reg:CC FLAGS_REG))]
12690 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12691 && (TARGET_SHIFT1 || optimize_size)"
12692 "rol{l}\t%k0"
12693 [(set_attr "type" "rotate")
12694 (set_attr "length" "2")])
12695
12696 (define_insn "*rotlsi3_1"
12697 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12698 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12699 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12700 (clobber (reg:CC FLAGS_REG))]
12701 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12702 "@
12703 rol{l}\t{%2, %0|%0, %2}
12704 rol{l}\t{%b2, %0|%0, %b2}"
12705 [(set_attr "type" "rotate")
12706 (set_attr "mode" "SI")])
12707
12708 (define_insn "*rotlsi3_1_zext"
12709 [(set (match_operand:DI 0 "register_operand" "=r,r")
12710 (zero_extend:DI
12711 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12712 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12713 (clobber (reg:CC FLAGS_REG))]
12714 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12715 "@
12716 rol{l}\t{%2, %k0|%k0, %2}
12717 rol{l}\t{%b2, %k0|%k0, %b2}"
12718 [(set_attr "type" "rotate")
12719 (set_attr "mode" "SI")])
12720
12721 (define_expand "rotlhi3"
12722 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12723 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12724 (match_operand:QI 2 "nonmemory_operand" "")))
12725 (clobber (reg:CC FLAGS_REG))]
12726 "TARGET_HIMODE_MATH"
12727 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12728
12729 (define_insn "*rotlhi3_1_one_bit"
12730 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12731 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12732 (match_operand:QI 2 "const1_operand" "")))
12733 (clobber (reg:CC FLAGS_REG))]
12734 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12735 && (TARGET_SHIFT1 || optimize_size)"
12736 "rol{w}\t%0"
12737 [(set_attr "type" "rotate")
12738 (set (attr "length")
12739 (if_then_else (match_operand 0 "register_operand" "")
12740 (const_string "2")
12741 (const_string "*")))])
12742
12743 (define_insn "*rotlhi3_1"
12744 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12745 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12746 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12747 (clobber (reg:CC FLAGS_REG))]
12748 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12749 "@
12750 rol{w}\t{%2, %0|%0, %2}
12751 rol{w}\t{%b2, %0|%0, %b2}"
12752 [(set_attr "type" "rotate")
12753 (set_attr "mode" "HI")])
12754
12755 (define_split
12756 [(set (match_operand:HI 0 "register_operand" "")
12757 (rotate:HI (match_dup 0) (const_int 8)))
12758 (clobber (reg:CC FLAGS_REG))]
12759 "reload_completed"
12760 [(parallel [(set (strict_low_part (match_dup 0))
12761 (bswap:HI (match_dup 0)))
12762 (clobber (reg:CC FLAGS_REG))])]
12763 "")
12764
12765 (define_expand "rotlqi3"
12766 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12767 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12768 (match_operand:QI 2 "nonmemory_operand" "")))
12769 (clobber (reg:CC FLAGS_REG))]
12770 "TARGET_QIMODE_MATH"
12771 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12772
12773 (define_insn "*rotlqi3_1_one_bit_slp"
12774 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12775 (rotate:QI (match_dup 0)
12776 (match_operand:QI 1 "const1_operand" "")))
12777 (clobber (reg:CC FLAGS_REG))]
12778 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12779 && (TARGET_SHIFT1 || optimize_size)"
12780 "rol{b}\t%0"
12781 [(set_attr "type" "rotate1")
12782 (set (attr "length")
12783 (if_then_else (match_operand 0 "register_operand" "")
12784 (const_string "2")
12785 (const_string "*")))])
12786
12787 (define_insn "*rotlqi3_1_one_bit"
12788 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12789 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12790 (match_operand:QI 2 "const1_operand" "")))
12791 (clobber (reg:CC FLAGS_REG))]
12792 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12793 && (TARGET_SHIFT1 || optimize_size)"
12794 "rol{b}\t%0"
12795 [(set_attr "type" "rotate")
12796 (set (attr "length")
12797 (if_then_else (match_operand 0 "register_operand" "")
12798 (const_string "2")
12799 (const_string "*")))])
12800
12801 (define_insn "*rotlqi3_1_slp"
12802 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12803 (rotate:QI (match_dup 0)
12804 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12805 (clobber (reg:CC FLAGS_REG))]
12806 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12808 "@
12809 rol{b}\t{%1, %0|%0, %1}
12810 rol{b}\t{%b1, %0|%0, %b1}"
12811 [(set_attr "type" "rotate1")
12812 (set_attr "mode" "QI")])
12813
12814 (define_insn "*rotlqi3_1"
12815 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12816 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12817 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12818 (clobber (reg:CC FLAGS_REG))]
12819 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12820 "@
12821 rol{b}\t{%2, %0|%0, %2}
12822 rol{b}\t{%b2, %0|%0, %b2}"
12823 [(set_attr "type" "rotate")
12824 (set_attr "mode" "QI")])
12825
12826 (define_expand "rotrdi3"
12827 [(set (match_operand:DI 0 "shiftdi_operand" "")
12828 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12829 (match_operand:QI 2 "nonmemory_operand" "")))
12830 (clobber (reg:CC FLAGS_REG))]
12831 ""
12832 {
12833 if (TARGET_64BIT)
12834 {
12835 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12836 DONE;
12837 }
12838 if (!const_1_to_31_operand (operands[2], VOIDmode))
12839 FAIL;
12840 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12841 DONE;
12842 })
12843
12844 ;; Implement rotation using two double-precision shift instructions
12845 ;; and a scratch register.
12846 (define_insn_and_split "ix86_rotrdi3"
12847 [(set (match_operand:DI 0 "register_operand" "=r")
12848 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12849 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12850 (clobber (reg:CC FLAGS_REG))
12851 (clobber (match_scratch:SI 3 "=&r"))]
12852 "!TARGET_64BIT"
12853 ""
12854 "&& reload_completed"
12855 [(set (match_dup 3) (match_dup 4))
12856 (parallel
12857 [(set (match_dup 4)
12858 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12859 (ashift:SI (match_dup 5)
12860 (minus:QI (const_int 32) (match_dup 2)))))
12861 (clobber (reg:CC FLAGS_REG))])
12862 (parallel
12863 [(set (match_dup 5)
12864 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12865 (ashift:SI (match_dup 3)
12866 (minus:QI (const_int 32) (match_dup 2)))))
12867 (clobber (reg:CC FLAGS_REG))])]
12868 "split_di (operands, 1, operands + 4, operands + 5);")
12869
12870 (define_insn "*rotrdi3_1_one_bit_rex64"
12871 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12872 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12873 (match_operand:QI 2 "const1_operand" "")))
12874 (clobber (reg:CC FLAGS_REG))]
12875 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12876 && (TARGET_SHIFT1 || optimize_size)"
12877 "ror{q}\t%0"
12878 [(set_attr "type" "rotate")
12879 (set (attr "length")
12880 (if_then_else (match_operand:DI 0 "register_operand" "")
12881 (const_string "2")
12882 (const_string "*")))])
12883
12884 (define_insn "*rotrdi3_1_rex64"
12885 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12886 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12887 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12888 (clobber (reg:CC FLAGS_REG))]
12889 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12890 "@
12891 ror{q}\t{%2, %0|%0, %2}
12892 ror{q}\t{%b2, %0|%0, %b2}"
12893 [(set_attr "type" "rotate")
12894 (set_attr "mode" "DI")])
12895
12896 (define_expand "rotrsi3"
12897 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12898 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12899 (match_operand:QI 2 "nonmemory_operand" "")))
12900 (clobber (reg:CC FLAGS_REG))]
12901 ""
12902 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12903
12904 (define_insn "*rotrsi3_1_one_bit"
12905 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12906 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12907 (match_operand:QI 2 "const1_operand" "")))
12908 (clobber (reg:CC FLAGS_REG))]
12909 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12910 && (TARGET_SHIFT1 || optimize_size)"
12911 "ror{l}\t%0"
12912 [(set_attr "type" "rotate")
12913 (set (attr "length")
12914 (if_then_else (match_operand:SI 0 "register_operand" "")
12915 (const_string "2")
12916 (const_string "*")))])
12917
12918 (define_insn "*rotrsi3_1_one_bit_zext"
12919 [(set (match_operand:DI 0 "register_operand" "=r")
12920 (zero_extend:DI
12921 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12922 (match_operand:QI 2 "const1_operand" ""))))
12923 (clobber (reg:CC FLAGS_REG))]
12924 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12925 && (TARGET_SHIFT1 || optimize_size)"
12926 "ror{l}\t%k0"
12927 [(set_attr "type" "rotate")
12928 (set (attr "length")
12929 (if_then_else (match_operand:SI 0 "register_operand" "")
12930 (const_string "2")
12931 (const_string "*")))])
12932
12933 (define_insn "*rotrsi3_1"
12934 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12935 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12936 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12937 (clobber (reg:CC FLAGS_REG))]
12938 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12939 "@
12940 ror{l}\t{%2, %0|%0, %2}
12941 ror{l}\t{%b2, %0|%0, %b2}"
12942 [(set_attr "type" "rotate")
12943 (set_attr "mode" "SI")])
12944
12945 (define_insn "*rotrsi3_1_zext"
12946 [(set (match_operand:DI 0 "register_operand" "=r,r")
12947 (zero_extend:DI
12948 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12949 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12950 (clobber (reg:CC FLAGS_REG))]
12951 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12952 "@
12953 ror{l}\t{%2, %k0|%k0, %2}
12954 ror{l}\t{%b2, %k0|%k0, %b2}"
12955 [(set_attr "type" "rotate")
12956 (set_attr "mode" "SI")])
12957
12958 (define_expand "rotrhi3"
12959 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12960 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12961 (match_operand:QI 2 "nonmemory_operand" "")))
12962 (clobber (reg:CC FLAGS_REG))]
12963 "TARGET_HIMODE_MATH"
12964 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12965
12966 (define_insn "*rotrhi3_one_bit"
12967 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12968 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12969 (match_operand:QI 2 "const1_operand" "")))
12970 (clobber (reg:CC FLAGS_REG))]
12971 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12972 && (TARGET_SHIFT1 || optimize_size)"
12973 "ror{w}\t%0"
12974 [(set_attr "type" "rotate")
12975 (set (attr "length")
12976 (if_then_else (match_operand 0 "register_operand" "")
12977 (const_string "2")
12978 (const_string "*")))])
12979
12980 (define_insn "*rotrhi3_1"
12981 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12982 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12983 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12984 (clobber (reg:CC FLAGS_REG))]
12985 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12986 "@
12987 ror{w}\t{%2, %0|%0, %2}
12988 ror{w}\t{%b2, %0|%0, %b2}"
12989 [(set_attr "type" "rotate")
12990 (set_attr "mode" "HI")])
12991
12992 (define_split
12993 [(set (match_operand:HI 0 "register_operand" "")
12994 (rotatert:HI (match_dup 0) (const_int 8)))
12995 (clobber (reg:CC FLAGS_REG))]
12996 "reload_completed"
12997 [(parallel [(set (strict_low_part (match_dup 0))
12998 (bswap:HI (match_dup 0)))
12999 (clobber (reg:CC FLAGS_REG))])]
13000 "")
13001
13002 (define_expand "rotrqi3"
13003 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13004 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13005 (match_operand:QI 2 "nonmemory_operand" "")))
13006 (clobber (reg:CC FLAGS_REG))]
13007 "TARGET_QIMODE_MATH"
13008 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13009
13010 (define_insn "*rotrqi3_1_one_bit"
13011 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13012 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13013 (match_operand:QI 2 "const1_operand" "")))
13014 (clobber (reg:CC FLAGS_REG))]
13015 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13016 && (TARGET_SHIFT1 || optimize_size)"
13017 "ror{b}\t%0"
13018 [(set_attr "type" "rotate")
13019 (set (attr "length")
13020 (if_then_else (match_operand 0 "register_operand" "")
13021 (const_string "2")
13022 (const_string "*")))])
13023
13024 (define_insn "*rotrqi3_1_one_bit_slp"
13025 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13026 (rotatert:QI (match_dup 0)
13027 (match_operand:QI 1 "const1_operand" "")))
13028 (clobber (reg:CC FLAGS_REG))]
13029 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13030 && (TARGET_SHIFT1 || optimize_size)"
13031 "ror{b}\t%0"
13032 [(set_attr "type" "rotate1")
13033 (set (attr "length")
13034 (if_then_else (match_operand 0 "register_operand" "")
13035 (const_string "2")
13036 (const_string "*")))])
13037
13038 (define_insn "*rotrqi3_1"
13039 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13040 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13041 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13042 (clobber (reg:CC FLAGS_REG))]
13043 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13044 "@
13045 ror{b}\t{%2, %0|%0, %2}
13046 ror{b}\t{%b2, %0|%0, %b2}"
13047 [(set_attr "type" "rotate")
13048 (set_attr "mode" "QI")])
13049
13050 (define_insn "*rotrqi3_1_slp"
13051 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13052 (rotatert:QI (match_dup 0)
13053 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13054 (clobber (reg:CC FLAGS_REG))]
13055 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13056 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13057 "@
13058 ror{b}\t{%1, %0|%0, %1}
13059 ror{b}\t{%b1, %0|%0, %b1}"
13060 [(set_attr "type" "rotate1")
13061 (set_attr "mode" "QI")])
13062 \f
13063 ;; Bit set / bit test instructions
13064
13065 (define_expand "extv"
13066 [(set (match_operand:SI 0 "register_operand" "")
13067 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13068 (match_operand:SI 2 "const8_operand" "")
13069 (match_operand:SI 3 "const8_operand" "")))]
13070 ""
13071 {
13072 /* Handle extractions from %ah et al. */
13073 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13074 FAIL;
13075
13076 /* From mips.md: extract_bit_field doesn't verify that our source
13077 matches the predicate, so check it again here. */
13078 if (! ext_register_operand (operands[1], VOIDmode))
13079 FAIL;
13080 })
13081
13082 (define_expand "extzv"
13083 [(set (match_operand:SI 0 "register_operand" "")
13084 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13085 (match_operand:SI 2 "const8_operand" "")
13086 (match_operand:SI 3 "const8_operand" "")))]
13087 ""
13088 {
13089 /* Handle extractions from %ah et al. */
13090 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13091 FAIL;
13092
13093 /* From mips.md: extract_bit_field doesn't verify that our source
13094 matches the predicate, so check it again here. */
13095 if (! ext_register_operand (operands[1], VOIDmode))
13096 FAIL;
13097 })
13098
13099 (define_expand "insv"
13100 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13101 (match_operand 1 "const8_operand" "")
13102 (match_operand 2 "const8_operand" ""))
13103 (match_operand 3 "register_operand" ""))]
13104 ""
13105 {
13106 /* Handle insertions to %ah et al. */
13107 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13108 FAIL;
13109
13110 /* From mips.md: insert_bit_field doesn't verify that our source
13111 matches the predicate, so check it again here. */
13112 if (! ext_register_operand (operands[0], VOIDmode))
13113 FAIL;
13114
13115 if (TARGET_64BIT)
13116 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13117 else
13118 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13119
13120 DONE;
13121 })
13122
13123 ;; %%% bts, btr, btc, bt.
13124 ;; In general these instructions are *slow* when applied to memory,
13125 ;; since they enforce atomic operation. When applied to registers,
13126 ;; it depends on the cpu implementation. They're never faster than
13127 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13128 ;; no point. But in 64-bit, we can't hold the relevant immediates
13129 ;; within the instruction itself, so operating on bits in the high
13130 ;; 32-bits of a register becomes easier.
13131 ;;
13132 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13133 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13134 ;; negdf respectively, so they can never be disabled entirely.
13135
13136 (define_insn "*btsq"
13137 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13138 (const_int 1)
13139 (match_operand:DI 1 "const_0_to_63_operand" ""))
13140 (const_int 1))
13141 (clobber (reg:CC FLAGS_REG))]
13142 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13143 "bts{q} %1,%0"
13144 [(set_attr "type" "alu1")])
13145
13146 (define_insn "*btrq"
13147 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13148 (const_int 1)
13149 (match_operand:DI 1 "const_0_to_63_operand" ""))
13150 (const_int 0))
13151 (clobber (reg:CC FLAGS_REG))]
13152 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13153 "btr{q} %1,%0"
13154 [(set_attr "type" "alu1")])
13155
13156 (define_insn "*btcq"
13157 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13158 (const_int 1)
13159 (match_operand:DI 1 "const_0_to_63_operand" ""))
13160 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13161 (clobber (reg:CC FLAGS_REG))]
13162 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13163 "btc{q} %1,%0"
13164 [(set_attr "type" "alu1")])
13165
13166 ;; Allow Nocona to avoid these instructions if a register is available.
13167
13168 (define_peephole2
13169 [(match_scratch:DI 2 "r")
13170 (parallel [(set (zero_extract:DI
13171 (match_operand:DI 0 "register_operand" "")
13172 (const_int 1)
13173 (match_operand:DI 1 "const_0_to_63_operand" ""))
13174 (const_int 1))
13175 (clobber (reg:CC FLAGS_REG))])]
13176 "TARGET_64BIT && !TARGET_USE_BT"
13177 [(const_int 0)]
13178 {
13179 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13180 rtx op1;
13181
13182 if (HOST_BITS_PER_WIDE_INT >= 64)
13183 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13184 else if (i < HOST_BITS_PER_WIDE_INT)
13185 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13186 else
13187 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13188
13189 op1 = immed_double_const (lo, hi, DImode);
13190 if (i >= 31)
13191 {
13192 emit_move_insn (operands[2], op1);
13193 op1 = operands[2];
13194 }
13195
13196 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13197 DONE;
13198 })
13199
13200 (define_peephole2
13201 [(match_scratch:DI 2 "r")
13202 (parallel [(set (zero_extract:DI
13203 (match_operand:DI 0 "register_operand" "")
13204 (const_int 1)
13205 (match_operand:DI 1 "const_0_to_63_operand" ""))
13206 (const_int 0))
13207 (clobber (reg:CC FLAGS_REG))])]
13208 "TARGET_64BIT && !TARGET_USE_BT"
13209 [(const_int 0)]
13210 {
13211 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13212 rtx op1;
13213
13214 if (HOST_BITS_PER_WIDE_INT >= 64)
13215 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13216 else if (i < HOST_BITS_PER_WIDE_INT)
13217 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13218 else
13219 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13220
13221 op1 = immed_double_const (~lo, ~hi, DImode);
13222 if (i >= 32)
13223 {
13224 emit_move_insn (operands[2], op1);
13225 op1 = operands[2];
13226 }
13227
13228 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13229 DONE;
13230 })
13231
13232 (define_peephole2
13233 [(match_scratch:DI 2 "r")
13234 (parallel [(set (zero_extract:DI
13235 (match_operand:DI 0 "register_operand" "")
13236 (const_int 1)
13237 (match_operand:DI 1 "const_0_to_63_operand" ""))
13238 (not:DI (zero_extract:DI
13239 (match_dup 0) (const_int 1) (match_dup 1))))
13240 (clobber (reg:CC FLAGS_REG))])]
13241 "TARGET_64BIT && !TARGET_USE_BT"
13242 [(const_int 0)]
13243 {
13244 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13245 rtx op1;
13246
13247 if (HOST_BITS_PER_WIDE_INT >= 64)
13248 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13249 else if (i < HOST_BITS_PER_WIDE_INT)
13250 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13251 else
13252 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13253
13254 op1 = immed_double_const (lo, hi, DImode);
13255 if (i >= 31)
13256 {
13257 emit_move_insn (operands[2], op1);
13258 op1 = operands[2];
13259 }
13260
13261 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13262 DONE;
13263 })
13264 \f
13265 ;; Store-flag instructions.
13266
13267 ;; For all sCOND expanders, also expand the compare or test insn that
13268 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13269
13270 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13271 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13272 ;; way, which can later delete the movzx if only QImode is needed.
13273
13274 (define_expand "seq"
13275 [(set (match_operand:QI 0 "register_operand" "")
13276 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13277 ""
13278 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13279
13280 (define_expand "sne"
13281 [(set (match_operand:QI 0 "register_operand" "")
13282 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13283 ""
13284 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13285
13286 (define_expand "sgt"
13287 [(set (match_operand:QI 0 "register_operand" "")
13288 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13289 ""
13290 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13291
13292 (define_expand "sgtu"
13293 [(set (match_operand:QI 0 "register_operand" "")
13294 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13295 ""
13296 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13297
13298 (define_expand "slt"
13299 [(set (match_operand:QI 0 "register_operand" "")
13300 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13301 ""
13302 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13303
13304 (define_expand "sltu"
13305 [(set (match_operand:QI 0 "register_operand" "")
13306 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13307 ""
13308 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13309
13310 (define_expand "sge"
13311 [(set (match_operand:QI 0 "register_operand" "")
13312 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13313 ""
13314 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13315
13316 (define_expand "sgeu"
13317 [(set (match_operand:QI 0 "register_operand" "")
13318 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13319 ""
13320 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13321
13322 (define_expand "sle"
13323 [(set (match_operand:QI 0 "register_operand" "")
13324 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13325 ""
13326 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13327
13328 (define_expand "sleu"
13329 [(set (match_operand:QI 0 "register_operand" "")
13330 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13331 ""
13332 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13333
13334 (define_expand "sunordered"
13335 [(set (match_operand:QI 0 "register_operand" "")
13336 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13337 "TARGET_80387 || TARGET_SSE"
13338 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13339
13340 (define_expand "sordered"
13341 [(set (match_operand:QI 0 "register_operand" "")
13342 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13343 "TARGET_80387"
13344 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13345
13346 (define_expand "suneq"
13347 [(set (match_operand:QI 0 "register_operand" "")
13348 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13349 "TARGET_80387 || TARGET_SSE"
13350 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13351
13352 (define_expand "sunge"
13353 [(set (match_operand:QI 0 "register_operand" "")
13354 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13355 "TARGET_80387 || TARGET_SSE"
13356 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13357
13358 (define_expand "sungt"
13359 [(set (match_operand:QI 0 "register_operand" "")
13360 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13361 "TARGET_80387 || TARGET_SSE"
13362 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13363
13364 (define_expand "sunle"
13365 [(set (match_operand:QI 0 "register_operand" "")
13366 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13367 "TARGET_80387 || TARGET_SSE"
13368 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13369
13370 (define_expand "sunlt"
13371 [(set (match_operand:QI 0 "register_operand" "")
13372 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13373 "TARGET_80387 || TARGET_SSE"
13374 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13375
13376 (define_expand "sltgt"
13377 [(set (match_operand:QI 0 "register_operand" "")
13378 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13379 "TARGET_80387 || TARGET_SSE"
13380 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13381
13382 (define_insn "*setcc_1"
13383 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13384 (match_operator:QI 1 "ix86_comparison_operator"
13385 [(reg FLAGS_REG) (const_int 0)]))]
13386 ""
13387 "set%C1\t%0"
13388 [(set_attr "type" "setcc")
13389 (set_attr "mode" "QI")])
13390
13391 (define_insn "*setcc_2"
13392 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13393 (match_operator:QI 1 "ix86_comparison_operator"
13394 [(reg FLAGS_REG) (const_int 0)]))]
13395 ""
13396 "set%C1\t%0"
13397 [(set_attr "type" "setcc")
13398 (set_attr "mode" "QI")])
13399
13400 ;; In general it is not safe to assume too much about CCmode registers,
13401 ;; so simplify-rtx stops when it sees a second one. Under certain
13402 ;; conditions this is safe on x86, so help combine not create
13403 ;;
13404 ;; seta %al
13405 ;; testb %al, %al
13406 ;; sete %al
13407
13408 (define_split
13409 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13410 (ne:QI (match_operator 1 "ix86_comparison_operator"
13411 [(reg FLAGS_REG) (const_int 0)])
13412 (const_int 0)))]
13413 ""
13414 [(set (match_dup 0) (match_dup 1))]
13415 {
13416 PUT_MODE (operands[1], QImode);
13417 })
13418
13419 (define_split
13420 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13421 (ne:QI (match_operator 1 "ix86_comparison_operator"
13422 [(reg FLAGS_REG) (const_int 0)])
13423 (const_int 0)))]
13424 ""
13425 [(set (match_dup 0) (match_dup 1))]
13426 {
13427 PUT_MODE (operands[1], QImode);
13428 })
13429
13430 (define_split
13431 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13432 (eq:QI (match_operator 1 "ix86_comparison_operator"
13433 [(reg FLAGS_REG) (const_int 0)])
13434 (const_int 0)))]
13435 ""
13436 [(set (match_dup 0) (match_dup 1))]
13437 {
13438 rtx new_op1 = copy_rtx (operands[1]);
13439 operands[1] = new_op1;
13440 PUT_MODE (new_op1, QImode);
13441 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13442 GET_MODE (XEXP (new_op1, 0))));
13443
13444 /* Make sure that (a) the CCmode we have for the flags is strong
13445 enough for the reversed compare or (b) we have a valid FP compare. */
13446 if (! ix86_comparison_operator (new_op1, VOIDmode))
13447 FAIL;
13448 })
13449
13450 (define_split
13451 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13452 (eq:QI (match_operator 1 "ix86_comparison_operator"
13453 [(reg FLAGS_REG) (const_int 0)])
13454 (const_int 0)))]
13455 ""
13456 [(set (match_dup 0) (match_dup 1))]
13457 {
13458 rtx new_op1 = copy_rtx (operands[1]);
13459 operands[1] = new_op1;
13460 PUT_MODE (new_op1, QImode);
13461 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13462 GET_MODE (XEXP (new_op1, 0))));
13463
13464 /* Make sure that (a) the CCmode we have for the flags is strong
13465 enough for the reversed compare or (b) we have a valid FP compare. */
13466 if (! ix86_comparison_operator (new_op1, VOIDmode))
13467 FAIL;
13468 })
13469
13470 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13471 ;; subsequent logical operations are used to imitate conditional moves.
13472 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13473 ;; it directly.
13474
13475 (define_insn "*sse_setccsf"
13476 [(set (match_operand:SF 0 "register_operand" "=x")
13477 (match_operator:SF 1 "sse_comparison_operator"
13478 [(match_operand:SF 2 "register_operand" "0")
13479 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13480 "TARGET_SSE"
13481 "cmp%D1ss\t{%3, %0|%0, %3}"
13482 [(set_attr "type" "ssecmp")
13483 (set_attr "mode" "SF")])
13484
13485 (define_insn "*sse_setccdf"
13486 [(set (match_operand:DF 0 "register_operand" "=x")
13487 (match_operator:DF 1 "sse_comparison_operator"
13488 [(match_operand:DF 2 "register_operand" "0")
13489 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13490 "TARGET_SSE2"
13491 "cmp%D1sd\t{%3, %0|%0, %3}"
13492 [(set_attr "type" "ssecmp")
13493 (set_attr "mode" "DF")])
13494 \f
13495 ;; Basic conditional jump instructions.
13496 ;; We ignore the overflow flag for signed branch instructions.
13497
13498 ;; For all bCOND expanders, also expand the compare or test insn that
13499 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13500
13501 (define_expand "beq"
13502 [(set (pc)
13503 (if_then_else (match_dup 1)
13504 (label_ref (match_operand 0 "" ""))
13505 (pc)))]
13506 ""
13507 "ix86_expand_branch (EQ, operands[0]); DONE;")
13508
13509 (define_expand "bne"
13510 [(set (pc)
13511 (if_then_else (match_dup 1)
13512 (label_ref (match_operand 0 "" ""))
13513 (pc)))]
13514 ""
13515 "ix86_expand_branch (NE, operands[0]); DONE;")
13516
13517 (define_expand "bgt"
13518 [(set (pc)
13519 (if_then_else (match_dup 1)
13520 (label_ref (match_operand 0 "" ""))
13521 (pc)))]
13522 ""
13523 "ix86_expand_branch (GT, operands[0]); DONE;")
13524
13525 (define_expand "bgtu"
13526 [(set (pc)
13527 (if_then_else (match_dup 1)
13528 (label_ref (match_operand 0 "" ""))
13529 (pc)))]
13530 ""
13531 "ix86_expand_branch (GTU, operands[0]); DONE;")
13532
13533 (define_expand "blt"
13534 [(set (pc)
13535 (if_then_else (match_dup 1)
13536 (label_ref (match_operand 0 "" ""))
13537 (pc)))]
13538 ""
13539 "ix86_expand_branch (LT, operands[0]); DONE;")
13540
13541 (define_expand "bltu"
13542 [(set (pc)
13543 (if_then_else (match_dup 1)
13544 (label_ref (match_operand 0 "" ""))
13545 (pc)))]
13546 ""
13547 "ix86_expand_branch (LTU, operands[0]); DONE;")
13548
13549 (define_expand "bge"
13550 [(set (pc)
13551 (if_then_else (match_dup 1)
13552 (label_ref (match_operand 0 "" ""))
13553 (pc)))]
13554 ""
13555 "ix86_expand_branch (GE, operands[0]); DONE;")
13556
13557 (define_expand "bgeu"
13558 [(set (pc)
13559 (if_then_else (match_dup 1)
13560 (label_ref (match_operand 0 "" ""))
13561 (pc)))]
13562 ""
13563 "ix86_expand_branch (GEU, operands[0]); DONE;")
13564
13565 (define_expand "ble"
13566 [(set (pc)
13567 (if_then_else (match_dup 1)
13568 (label_ref (match_operand 0 "" ""))
13569 (pc)))]
13570 ""
13571 "ix86_expand_branch (LE, operands[0]); DONE;")
13572
13573 (define_expand "bleu"
13574 [(set (pc)
13575 (if_then_else (match_dup 1)
13576 (label_ref (match_operand 0 "" ""))
13577 (pc)))]
13578 ""
13579 "ix86_expand_branch (LEU, operands[0]); DONE;")
13580
13581 (define_expand "bunordered"
13582 [(set (pc)
13583 (if_then_else (match_dup 1)
13584 (label_ref (match_operand 0 "" ""))
13585 (pc)))]
13586 "TARGET_80387 || TARGET_SSE_MATH"
13587 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13588
13589 (define_expand "bordered"
13590 [(set (pc)
13591 (if_then_else (match_dup 1)
13592 (label_ref (match_operand 0 "" ""))
13593 (pc)))]
13594 "TARGET_80387 || TARGET_SSE_MATH"
13595 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13596
13597 (define_expand "buneq"
13598 [(set (pc)
13599 (if_then_else (match_dup 1)
13600 (label_ref (match_operand 0 "" ""))
13601 (pc)))]
13602 "TARGET_80387 || TARGET_SSE_MATH"
13603 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13604
13605 (define_expand "bunge"
13606 [(set (pc)
13607 (if_then_else (match_dup 1)
13608 (label_ref (match_operand 0 "" ""))
13609 (pc)))]
13610 "TARGET_80387 || TARGET_SSE_MATH"
13611 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13612
13613 (define_expand "bungt"
13614 [(set (pc)
13615 (if_then_else (match_dup 1)
13616 (label_ref (match_operand 0 "" ""))
13617 (pc)))]
13618 "TARGET_80387 || TARGET_SSE_MATH"
13619 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13620
13621 (define_expand "bunle"
13622 [(set (pc)
13623 (if_then_else (match_dup 1)
13624 (label_ref (match_operand 0 "" ""))
13625 (pc)))]
13626 "TARGET_80387 || TARGET_SSE_MATH"
13627 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13628
13629 (define_expand "bunlt"
13630 [(set (pc)
13631 (if_then_else (match_dup 1)
13632 (label_ref (match_operand 0 "" ""))
13633 (pc)))]
13634 "TARGET_80387 || TARGET_SSE_MATH"
13635 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13636
13637 (define_expand "bltgt"
13638 [(set (pc)
13639 (if_then_else (match_dup 1)
13640 (label_ref (match_operand 0 "" ""))
13641 (pc)))]
13642 "TARGET_80387 || TARGET_SSE_MATH"
13643 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13644
13645 (define_insn "*jcc_1"
13646 [(set (pc)
13647 (if_then_else (match_operator 1 "ix86_comparison_operator"
13648 [(reg FLAGS_REG) (const_int 0)])
13649 (label_ref (match_operand 0 "" ""))
13650 (pc)))]
13651 ""
13652 "%+j%C1\t%l0"
13653 [(set_attr "type" "ibr")
13654 (set_attr "modrm" "0")
13655 (set (attr "length")
13656 (if_then_else (and (ge (minus (match_dup 0) (pc))
13657 (const_int -126))
13658 (lt (minus (match_dup 0) (pc))
13659 (const_int 128)))
13660 (const_int 2)
13661 (const_int 6)))])
13662
13663 (define_insn "*jcc_2"
13664 [(set (pc)
13665 (if_then_else (match_operator 1 "ix86_comparison_operator"
13666 [(reg FLAGS_REG) (const_int 0)])
13667 (pc)
13668 (label_ref (match_operand 0 "" ""))))]
13669 ""
13670 "%+j%c1\t%l0"
13671 [(set_attr "type" "ibr")
13672 (set_attr "modrm" "0")
13673 (set (attr "length")
13674 (if_then_else (and (ge (minus (match_dup 0) (pc))
13675 (const_int -126))
13676 (lt (minus (match_dup 0) (pc))
13677 (const_int 128)))
13678 (const_int 2)
13679 (const_int 6)))])
13680
13681 ;; In general it is not safe to assume too much about CCmode registers,
13682 ;; so simplify-rtx stops when it sees a second one. Under certain
13683 ;; conditions this is safe on x86, so help combine not create
13684 ;;
13685 ;; seta %al
13686 ;; testb %al, %al
13687 ;; je Lfoo
13688
13689 (define_split
13690 [(set (pc)
13691 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13692 [(reg FLAGS_REG) (const_int 0)])
13693 (const_int 0))
13694 (label_ref (match_operand 1 "" ""))
13695 (pc)))]
13696 ""
13697 [(set (pc)
13698 (if_then_else (match_dup 0)
13699 (label_ref (match_dup 1))
13700 (pc)))]
13701 {
13702 PUT_MODE (operands[0], VOIDmode);
13703 })
13704
13705 (define_split
13706 [(set (pc)
13707 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13708 [(reg FLAGS_REG) (const_int 0)])
13709 (const_int 0))
13710 (label_ref (match_operand 1 "" ""))
13711 (pc)))]
13712 ""
13713 [(set (pc)
13714 (if_then_else (match_dup 0)
13715 (label_ref (match_dup 1))
13716 (pc)))]
13717 {
13718 rtx new_op0 = copy_rtx (operands[0]);
13719 operands[0] = new_op0;
13720 PUT_MODE (new_op0, VOIDmode);
13721 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13722 GET_MODE (XEXP (new_op0, 0))));
13723
13724 /* Make sure that (a) the CCmode we have for the flags is strong
13725 enough for the reversed compare or (b) we have a valid FP compare. */
13726 if (! ix86_comparison_operator (new_op0, VOIDmode))
13727 FAIL;
13728 })
13729
13730 ;; Define combination compare-and-branch fp compare instructions to use
13731 ;; during early optimization. Splitting the operation apart early makes
13732 ;; for bad code when we want to reverse the operation.
13733
13734 (define_insn "*fp_jcc_1_mixed"
13735 [(set (pc)
13736 (if_then_else (match_operator 0 "comparison_operator"
13737 [(match_operand 1 "register_operand" "f,x")
13738 (match_operand 2 "nonimmediate_operand" "f,xm")])
13739 (label_ref (match_operand 3 "" ""))
13740 (pc)))
13741 (clobber (reg:CCFP FPSR_REG))
13742 (clobber (reg:CCFP FLAGS_REG))]
13743 "TARGET_MIX_SSE_I387
13744 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13745 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13746 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13747 "#")
13748
13749 (define_insn "*fp_jcc_1_sse"
13750 [(set (pc)
13751 (if_then_else (match_operator 0 "comparison_operator"
13752 [(match_operand 1 "register_operand" "x")
13753 (match_operand 2 "nonimmediate_operand" "xm")])
13754 (label_ref (match_operand 3 "" ""))
13755 (pc)))
13756 (clobber (reg:CCFP FPSR_REG))
13757 (clobber (reg:CCFP FLAGS_REG))]
13758 "TARGET_SSE_MATH
13759 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13760 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13761 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13762 "#")
13763
13764 (define_insn "*fp_jcc_1_387"
13765 [(set (pc)
13766 (if_then_else (match_operator 0 "comparison_operator"
13767 [(match_operand 1 "register_operand" "f")
13768 (match_operand 2 "register_operand" "f")])
13769 (label_ref (match_operand 3 "" ""))
13770 (pc)))
13771 (clobber (reg:CCFP FPSR_REG))
13772 (clobber (reg:CCFP FLAGS_REG))]
13773 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13774 && TARGET_CMOVE
13775 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13776 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13777 "#")
13778
13779 (define_insn "*fp_jcc_2_mixed"
13780 [(set (pc)
13781 (if_then_else (match_operator 0 "comparison_operator"
13782 [(match_operand 1 "register_operand" "f,x")
13783 (match_operand 2 "nonimmediate_operand" "f,xm")])
13784 (pc)
13785 (label_ref (match_operand 3 "" ""))))
13786 (clobber (reg:CCFP FPSR_REG))
13787 (clobber (reg:CCFP FLAGS_REG))]
13788 "TARGET_MIX_SSE_I387
13789 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13790 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13791 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13792 "#")
13793
13794 (define_insn "*fp_jcc_2_sse"
13795 [(set (pc)
13796 (if_then_else (match_operator 0 "comparison_operator"
13797 [(match_operand 1 "register_operand" "x")
13798 (match_operand 2 "nonimmediate_operand" "xm")])
13799 (pc)
13800 (label_ref (match_operand 3 "" ""))))
13801 (clobber (reg:CCFP FPSR_REG))
13802 (clobber (reg:CCFP FLAGS_REG))]
13803 "TARGET_SSE_MATH
13804 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13805 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13806 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13807 "#")
13808
13809 (define_insn "*fp_jcc_2_387"
13810 [(set (pc)
13811 (if_then_else (match_operator 0 "comparison_operator"
13812 [(match_operand 1 "register_operand" "f")
13813 (match_operand 2 "register_operand" "f")])
13814 (pc)
13815 (label_ref (match_operand 3 "" ""))))
13816 (clobber (reg:CCFP FPSR_REG))
13817 (clobber (reg:CCFP FLAGS_REG))]
13818 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13819 && TARGET_CMOVE
13820 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13821 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13822 "#")
13823
13824 (define_insn "*fp_jcc_3_387"
13825 [(set (pc)
13826 (if_then_else (match_operator 0 "comparison_operator"
13827 [(match_operand 1 "register_operand" "f")
13828 (match_operand 2 "nonimmediate_operand" "fm")])
13829 (label_ref (match_operand 3 "" ""))
13830 (pc)))
13831 (clobber (reg:CCFP FPSR_REG))
13832 (clobber (reg:CCFP FLAGS_REG))
13833 (clobber (match_scratch:HI 4 "=a"))]
13834 "TARGET_80387
13835 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13836 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13837 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13838 && SELECT_CC_MODE (GET_CODE (operands[0]),
13839 operands[1], operands[2]) == CCFPmode
13840 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13841 "#")
13842
13843 (define_insn "*fp_jcc_4_387"
13844 [(set (pc)
13845 (if_then_else (match_operator 0 "comparison_operator"
13846 [(match_operand 1 "register_operand" "f")
13847 (match_operand 2 "nonimmediate_operand" "fm")])
13848 (pc)
13849 (label_ref (match_operand 3 "" ""))))
13850 (clobber (reg:CCFP FPSR_REG))
13851 (clobber (reg:CCFP FLAGS_REG))
13852 (clobber (match_scratch:HI 4 "=a"))]
13853 "TARGET_80387
13854 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13855 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13856 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13857 && SELECT_CC_MODE (GET_CODE (operands[0]),
13858 operands[1], operands[2]) == CCFPmode
13859 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13860 "#")
13861
13862 (define_insn "*fp_jcc_5_387"
13863 [(set (pc)
13864 (if_then_else (match_operator 0 "comparison_operator"
13865 [(match_operand 1 "register_operand" "f")
13866 (match_operand 2 "register_operand" "f")])
13867 (label_ref (match_operand 3 "" ""))
13868 (pc)))
13869 (clobber (reg:CCFP FPSR_REG))
13870 (clobber (reg:CCFP FLAGS_REG))
13871 (clobber (match_scratch:HI 4 "=a"))]
13872 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13873 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13874 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13875 "#")
13876
13877 (define_insn "*fp_jcc_6_387"
13878 [(set (pc)
13879 (if_then_else (match_operator 0 "comparison_operator"
13880 [(match_operand 1 "register_operand" "f")
13881 (match_operand 2 "register_operand" "f")])
13882 (pc)
13883 (label_ref (match_operand 3 "" ""))))
13884 (clobber (reg:CCFP FPSR_REG))
13885 (clobber (reg:CCFP FLAGS_REG))
13886 (clobber (match_scratch:HI 4 "=a"))]
13887 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13888 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13889 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13890 "#")
13891
13892 (define_insn "*fp_jcc_7_387"
13893 [(set (pc)
13894 (if_then_else (match_operator 0 "comparison_operator"
13895 [(match_operand 1 "register_operand" "f")
13896 (match_operand 2 "const0_operand" "X")])
13897 (label_ref (match_operand 3 "" ""))
13898 (pc)))
13899 (clobber (reg:CCFP FPSR_REG))
13900 (clobber (reg:CCFP FLAGS_REG))
13901 (clobber (match_scratch:HI 4 "=a"))]
13902 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13903 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13904 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13905 && SELECT_CC_MODE (GET_CODE (operands[0]),
13906 operands[1], operands[2]) == CCFPmode
13907 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13908 "#")
13909
13910 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13911 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13912 ;; with a precedence over other operators and is always put in the first
13913 ;; place. Swap condition and operands to match ficom instruction.
13914
13915 (define_insn "*fp_jcc_8<mode>_387"
13916 [(set (pc)
13917 (if_then_else (match_operator 0 "comparison_operator"
13918 [(match_operator 1 "float_operator"
13919 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13920 (match_operand 3 "register_operand" "f,f")])
13921 (label_ref (match_operand 4 "" ""))
13922 (pc)))
13923 (clobber (reg:CCFP FPSR_REG))
13924 (clobber (reg:CCFP FLAGS_REG))
13925 (clobber (match_scratch:HI 5 "=a,a"))]
13926 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13927 && TARGET_USE_<MODE>MODE_FIOP
13928 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13929 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13930 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13931 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13932 "#")
13933
13934 (define_split
13935 [(set (pc)
13936 (if_then_else (match_operator 0 "comparison_operator"
13937 [(match_operand 1 "register_operand" "")
13938 (match_operand 2 "nonimmediate_operand" "")])
13939 (match_operand 3 "" "")
13940 (match_operand 4 "" "")))
13941 (clobber (reg:CCFP FPSR_REG))
13942 (clobber (reg:CCFP FLAGS_REG))]
13943 "reload_completed"
13944 [(const_int 0)]
13945 {
13946 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13947 operands[3], operands[4], NULL_RTX, NULL_RTX);
13948 DONE;
13949 })
13950
13951 (define_split
13952 [(set (pc)
13953 (if_then_else (match_operator 0 "comparison_operator"
13954 [(match_operand 1 "register_operand" "")
13955 (match_operand 2 "general_operand" "")])
13956 (match_operand 3 "" "")
13957 (match_operand 4 "" "")))
13958 (clobber (reg:CCFP FPSR_REG))
13959 (clobber (reg:CCFP FLAGS_REG))
13960 (clobber (match_scratch:HI 5 "=a"))]
13961 "reload_completed"
13962 [(const_int 0)]
13963 {
13964 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13965 operands[3], operands[4], operands[5], NULL_RTX);
13966 DONE;
13967 })
13968
13969 (define_split
13970 [(set (pc)
13971 (if_then_else (match_operator 0 "comparison_operator"
13972 [(match_operator 1 "float_operator"
13973 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13974 (match_operand 3 "register_operand" "")])
13975 (match_operand 4 "" "")
13976 (match_operand 5 "" "")))
13977 (clobber (reg:CCFP FPSR_REG))
13978 (clobber (reg:CCFP FLAGS_REG))
13979 (clobber (match_scratch:HI 6 "=a"))]
13980 "reload_completed"
13981 [(const_int 0)]
13982 {
13983 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13984 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13985 operands[3], operands[7],
13986 operands[4], operands[5], operands[6], NULL_RTX);
13987 DONE;
13988 })
13989
13990 ;; %%% Kill this when reload knows how to do it.
13991 (define_split
13992 [(set (pc)
13993 (if_then_else (match_operator 0 "comparison_operator"
13994 [(match_operator 1 "float_operator"
13995 [(match_operand:X87MODEI12 2 "register_operand" "")])
13996 (match_operand 3 "register_operand" "")])
13997 (match_operand 4 "" "")
13998 (match_operand 5 "" "")))
13999 (clobber (reg:CCFP FPSR_REG))
14000 (clobber (reg:CCFP FLAGS_REG))
14001 (clobber (match_scratch:HI 6 "=a"))]
14002 "reload_completed"
14003 [(const_int 0)]
14004 {
14005 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14006 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14007 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14008 operands[3], operands[7],
14009 operands[4], operands[5], operands[6], operands[2]);
14010 DONE;
14011 })
14012 \f
14013 ;; Unconditional and other jump instructions
14014
14015 (define_insn "jump"
14016 [(set (pc)
14017 (label_ref (match_operand 0 "" "")))]
14018 ""
14019 "jmp\t%l0"
14020 [(set_attr "type" "ibr")
14021 (set (attr "length")
14022 (if_then_else (and (ge (minus (match_dup 0) (pc))
14023 (const_int -126))
14024 (lt (minus (match_dup 0) (pc))
14025 (const_int 128)))
14026 (const_int 2)
14027 (const_int 5)))
14028 (set_attr "modrm" "0")])
14029
14030 (define_expand "indirect_jump"
14031 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14032 ""
14033 "")
14034
14035 (define_insn "*indirect_jump"
14036 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14037 "!TARGET_64BIT"
14038 "jmp\t%A0"
14039 [(set_attr "type" "ibr")
14040 (set_attr "length_immediate" "0")])
14041
14042 (define_insn "*indirect_jump_rtx64"
14043 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14044 "TARGET_64BIT"
14045 "jmp\t%A0"
14046 [(set_attr "type" "ibr")
14047 (set_attr "length_immediate" "0")])
14048
14049 (define_expand "tablejump"
14050 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14051 (use (label_ref (match_operand 1 "" "")))])]
14052 ""
14053 {
14054 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14055 relative. Convert the relative address to an absolute address. */
14056 if (flag_pic)
14057 {
14058 rtx op0, op1;
14059 enum rtx_code code;
14060
14061 /* We can't use @GOTOFF for text labels on VxWorks;
14062 see gotoff_operand. */
14063 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14064 {
14065 code = PLUS;
14066 op0 = operands[0];
14067 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14068 }
14069 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14070 {
14071 code = PLUS;
14072 op0 = operands[0];
14073 op1 = pic_offset_table_rtx;
14074 }
14075 else
14076 {
14077 code = MINUS;
14078 op0 = pic_offset_table_rtx;
14079 op1 = operands[0];
14080 }
14081
14082 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14083 OPTAB_DIRECT);
14084 }
14085 })
14086
14087 (define_insn "*tablejump_1"
14088 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14089 (use (label_ref (match_operand 1 "" "")))]
14090 "!TARGET_64BIT"
14091 "jmp\t%A0"
14092 [(set_attr "type" "ibr")
14093 (set_attr "length_immediate" "0")])
14094
14095 (define_insn "*tablejump_1_rtx64"
14096 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14097 (use (label_ref (match_operand 1 "" "")))]
14098 "TARGET_64BIT"
14099 "jmp\t%A0"
14100 [(set_attr "type" "ibr")
14101 (set_attr "length_immediate" "0")])
14102 \f
14103 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14104
14105 (define_peephole2
14106 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14107 (set (match_operand:QI 1 "register_operand" "")
14108 (match_operator:QI 2 "ix86_comparison_operator"
14109 [(reg FLAGS_REG) (const_int 0)]))
14110 (set (match_operand 3 "q_regs_operand" "")
14111 (zero_extend (match_dup 1)))]
14112 "(peep2_reg_dead_p (3, operands[1])
14113 || operands_match_p (operands[1], operands[3]))
14114 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14115 [(set (match_dup 4) (match_dup 0))
14116 (set (strict_low_part (match_dup 5))
14117 (match_dup 2))]
14118 {
14119 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14120 operands[5] = gen_lowpart (QImode, operands[3]);
14121 ix86_expand_clear (operands[3]);
14122 })
14123
14124 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14125
14126 (define_peephole2
14127 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14128 (set (match_operand:QI 1 "register_operand" "")
14129 (match_operator:QI 2 "ix86_comparison_operator"
14130 [(reg FLAGS_REG) (const_int 0)]))
14131 (parallel [(set (match_operand 3 "q_regs_operand" "")
14132 (zero_extend (match_dup 1)))
14133 (clobber (reg:CC FLAGS_REG))])]
14134 "(peep2_reg_dead_p (3, operands[1])
14135 || operands_match_p (operands[1], operands[3]))
14136 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14137 [(set (match_dup 4) (match_dup 0))
14138 (set (strict_low_part (match_dup 5))
14139 (match_dup 2))]
14140 {
14141 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14142 operands[5] = gen_lowpart (QImode, operands[3]);
14143 ix86_expand_clear (operands[3]);
14144 })
14145 \f
14146 ;; Call instructions.
14147
14148 ;; The predicates normally associated with named expanders are not properly
14149 ;; checked for calls. This is a bug in the generic code, but it isn't that
14150 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14151
14152 ;; Call subroutine returning no value.
14153
14154 (define_expand "call_pop"
14155 [(parallel [(call (match_operand:QI 0 "" "")
14156 (match_operand:SI 1 "" ""))
14157 (set (reg:SI SP_REG)
14158 (plus:SI (reg:SI SP_REG)
14159 (match_operand:SI 3 "" "")))])]
14160 "!TARGET_64BIT"
14161 {
14162 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14163 DONE;
14164 })
14165
14166 (define_insn "*call_pop_0"
14167 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14168 (match_operand:SI 1 "" ""))
14169 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14170 (match_operand:SI 2 "immediate_operand" "")))]
14171 "!TARGET_64BIT"
14172 {
14173 if (SIBLING_CALL_P (insn))
14174 return "jmp\t%P0";
14175 else
14176 return "call\t%P0";
14177 }
14178 [(set_attr "type" "call")])
14179
14180 (define_insn "*call_pop_1"
14181 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14182 (match_operand:SI 1 "" ""))
14183 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14184 (match_operand:SI 2 "immediate_operand" "i")))]
14185 "!TARGET_64BIT"
14186 {
14187 if (constant_call_address_operand (operands[0], Pmode))
14188 {
14189 if (SIBLING_CALL_P (insn))
14190 return "jmp\t%P0";
14191 else
14192 return "call\t%P0";
14193 }
14194 if (SIBLING_CALL_P (insn))
14195 return "jmp\t%A0";
14196 else
14197 return "call\t%A0";
14198 }
14199 [(set_attr "type" "call")])
14200
14201 (define_expand "call"
14202 [(call (match_operand:QI 0 "" "")
14203 (match_operand 1 "" ""))
14204 (use (match_operand 2 "" ""))]
14205 ""
14206 {
14207 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14208 DONE;
14209 })
14210
14211 (define_expand "sibcall"
14212 [(call (match_operand:QI 0 "" "")
14213 (match_operand 1 "" ""))
14214 (use (match_operand 2 "" ""))]
14215 ""
14216 {
14217 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14218 DONE;
14219 })
14220
14221 (define_insn "*call_0"
14222 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14223 (match_operand 1 "" ""))]
14224 ""
14225 {
14226 if (SIBLING_CALL_P (insn))
14227 return "jmp\t%P0";
14228 else
14229 return "call\t%P0";
14230 }
14231 [(set_attr "type" "call")])
14232
14233 (define_insn "*call_1"
14234 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14235 (match_operand 1 "" ""))]
14236 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14237 {
14238 if (constant_call_address_operand (operands[0], Pmode))
14239 return "call\t%P0";
14240 return "call\t%A0";
14241 }
14242 [(set_attr "type" "call")])
14243
14244 (define_insn "*sibcall_1"
14245 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14246 (match_operand 1 "" ""))]
14247 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14248 {
14249 if (constant_call_address_operand (operands[0], Pmode))
14250 return "jmp\t%P0";
14251 return "jmp\t%A0";
14252 }
14253 [(set_attr "type" "call")])
14254
14255 (define_insn "*call_1_rex64"
14256 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14257 (match_operand 1 "" ""))]
14258 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14259 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14260 {
14261 if (constant_call_address_operand (operands[0], Pmode))
14262 return "call\t%P0";
14263 return "call\t%A0";
14264 }
14265 [(set_attr "type" "call")])
14266
14267 (define_insn "*call_1_rex64_large"
14268 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14269 (match_operand 1 "" ""))]
14270 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14271 "call\t%A0"
14272 [(set_attr "type" "call")])
14273
14274 (define_insn "*sibcall_1_rex64"
14275 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14276 (match_operand 1 "" ""))]
14277 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14278 "jmp\t%P0"
14279 [(set_attr "type" "call")])
14280
14281 (define_insn "*sibcall_1_rex64_v"
14282 [(call (mem:QI (reg:DI R11_REG))
14283 (match_operand 0 "" ""))]
14284 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14285 "jmp\t*%%r11"
14286 [(set_attr "type" "call")])
14287
14288
14289 ;; Call subroutine, returning value in operand 0
14290
14291 (define_expand "call_value_pop"
14292 [(parallel [(set (match_operand 0 "" "")
14293 (call (match_operand:QI 1 "" "")
14294 (match_operand:SI 2 "" "")))
14295 (set (reg:SI SP_REG)
14296 (plus:SI (reg:SI SP_REG)
14297 (match_operand:SI 4 "" "")))])]
14298 "!TARGET_64BIT"
14299 {
14300 ix86_expand_call (operands[0], operands[1], operands[2],
14301 operands[3], operands[4], 0);
14302 DONE;
14303 })
14304
14305 (define_expand "call_value"
14306 [(set (match_operand 0 "" "")
14307 (call (match_operand:QI 1 "" "")
14308 (match_operand:SI 2 "" "")))
14309 (use (match_operand:SI 3 "" ""))]
14310 ;; Operand 2 not used on the i386.
14311 ""
14312 {
14313 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14314 DONE;
14315 })
14316
14317 (define_expand "sibcall_value"
14318 [(set (match_operand 0 "" "")
14319 (call (match_operand:QI 1 "" "")
14320 (match_operand:SI 2 "" "")))
14321 (use (match_operand:SI 3 "" ""))]
14322 ;; Operand 2 not used on the i386.
14323 ""
14324 {
14325 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14326 DONE;
14327 })
14328
14329 ;; Call subroutine returning any type.
14330
14331 (define_expand "untyped_call"
14332 [(parallel [(call (match_operand 0 "" "")
14333 (const_int 0))
14334 (match_operand 1 "" "")
14335 (match_operand 2 "" "")])]
14336 ""
14337 {
14338 int i;
14339
14340 /* In order to give reg-stack an easier job in validating two
14341 coprocessor registers as containing a possible return value,
14342 simply pretend the untyped call returns a complex long double
14343 value. */
14344
14345 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14346 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14347 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14348 NULL, 0);
14349
14350 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14351 {
14352 rtx set = XVECEXP (operands[2], 0, i);
14353 emit_move_insn (SET_DEST (set), SET_SRC (set));
14354 }
14355
14356 /* The optimizer does not know that the call sets the function value
14357 registers we stored in the result block. We avoid problems by
14358 claiming that all hard registers are used and clobbered at this
14359 point. */
14360 emit_insn (gen_blockage ());
14361
14362 DONE;
14363 })
14364 \f
14365 ;; Prologue and epilogue instructions
14366
14367 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14368 ;; all of memory. This blocks insns from being moved across this point.
14369
14370 (define_insn "blockage"
14371 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14372 ""
14373 ""
14374 [(set_attr "length" "0")])
14375
14376 ;; As USE insns aren't meaningful after reload, this is used instead
14377 ;; to prevent deleting instructions setting registers for PIC code
14378 (define_insn "prologue_use"
14379 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14380 ""
14381 ""
14382 [(set_attr "length" "0")])
14383
14384 ;; Insn emitted into the body of a function to return from a function.
14385 ;; This is only done if the function's epilogue is known to be simple.
14386 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14387
14388 (define_expand "return"
14389 [(return)]
14390 "ix86_can_use_return_insn_p ()"
14391 {
14392 if (current_function_pops_args)
14393 {
14394 rtx popc = GEN_INT (current_function_pops_args);
14395 emit_jump_insn (gen_return_pop_internal (popc));
14396 DONE;
14397 }
14398 })
14399
14400 (define_insn "return_internal"
14401 [(return)]
14402 "reload_completed"
14403 "ret"
14404 [(set_attr "length" "1")
14405 (set_attr "length_immediate" "0")
14406 (set_attr "modrm" "0")])
14407
14408 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14409 ;; instruction Athlon and K8 have.
14410
14411 (define_insn "return_internal_long"
14412 [(return)
14413 (unspec [(const_int 0)] UNSPEC_REP)]
14414 "reload_completed"
14415 "rep {;} ret"
14416 [(set_attr "length" "1")
14417 (set_attr "length_immediate" "0")
14418 (set_attr "prefix_rep" "1")
14419 (set_attr "modrm" "0")])
14420
14421 (define_insn "return_pop_internal"
14422 [(return)
14423 (use (match_operand:SI 0 "const_int_operand" ""))]
14424 "reload_completed"
14425 "ret\t%0"
14426 [(set_attr "length" "3")
14427 (set_attr "length_immediate" "2")
14428 (set_attr "modrm" "0")])
14429
14430 (define_insn "return_indirect_internal"
14431 [(return)
14432 (use (match_operand:SI 0 "register_operand" "r"))]
14433 "reload_completed"
14434 "jmp\t%A0"
14435 [(set_attr "type" "ibr")
14436 (set_attr "length_immediate" "0")])
14437
14438 (define_insn "nop"
14439 [(const_int 0)]
14440 ""
14441 "nop"
14442 [(set_attr "length" "1")
14443 (set_attr "length_immediate" "0")
14444 (set_attr "modrm" "0")])
14445
14446 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14447 ;; branch prediction penalty for the third jump in a 16-byte
14448 ;; block on K8.
14449
14450 (define_insn "align"
14451 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14452 ""
14453 {
14454 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14455 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14456 #else
14457 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14458 The align insn is used to avoid 3 jump instructions in the row to improve
14459 branch prediction and the benefits hardly outweigh the cost of extra 8
14460 nops on the average inserted by full alignment pseudo operation. */
14461 #endif
14462 return "";
14463 }
14464 [(set_attr "length" "16")])
14465
14466 (define_expand "prologue"
14467 [(const_int 1)]
14468 ""
14469 "ix86_expand_prologue (); DONE;")
14470
14471 (define_insn "set_got"
14472 [(set (match_operand:SI 0 "register_operand" "=r")
14473 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14474 (clobber (reg:CC FLAGS_REG))]
14475 "!TARGET_64BIT"
14476 { return output_set_got (operands[0], NULL_RTX); }
14477 [(set_attr "type" "multi")
14478 (set_attr "length" "12")])
14479
14480 (define_insn "set_got_labelled"
14481 [(set (match_operand:SI 0 "register_operand" "=r")
14482 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14483 UNSPEC_SET_GOT))
14484 (clobber (reg:CC FLAGS_REG))]
14485 "!TARGET_64BIT"
14486 { return output_set_got (operands[0], operands[1]); }
14487 [(set_attr "type" "multi")
14488 (set_attr "length" "12")])
14489
14490 (define_insn "set_got_rex64"
14491 [(set (match_operand:DI 0 "register_operand" "=r")
14492 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14493 "TARGET_64BIT"
14494 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14495 [(set_attr "type" "lea")
14496 (set_attr "length" "6")])
14497
14498 (define_insn "set_rip_rex64"
14499 [(set (match_operand:DI 0 "register_operand" "=r")
14500 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14501 "TARGET_64BIT"
14502 "lea{q}\t%l1(%%rip), %0"
14503 [(set_attr "type" "lea")
14504 (set_attr "length" "6")])
14505
14506 (define_insn "set_got_offset_rex64"
14507 [(set (match_operand:DI 0 "register_operand" "=r")
14508 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14509 "TARGET_64BIT"
14510 "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14511 [(set_attr "type" "imov")
14512 (set_attr "length" "11")])
14513
14514 (define_expand "epilogue"
14515 [(const_int 1)]
14516 ""
14517 "ix86_expand_epilogue (1); DONE;")
14518
14519 (define_expand "sibcall_epilogue"
14520 [(const_int 1)]
14521 ""
14522 "ix86_expand_epilogue (0); DONE;")
14523
14524 (define_expand "eh_return"
14525 [(use (match_operand 0 "register_operand" ""))]
14526 ""
14527 {
14528 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14529
14530 /* Tricky bit: we write the address of the handler to which we will
14531 be returning into someone else's stack frame, one word below the
14532 stack address we wish to restore. */
14533 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14534 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14535 tmp = gen_rtx_MEM (Pmode, tmp);
14536 emit_move_insn (tmp, ra);
14537
14538 if (Pmode == SImode)
14539 emit_jump_insn (gen_eh_return_si (sa));
14540 else
14541 emit_jump_insn (gen_eh_return_di (sa));
14542 emit_barrier ();
14543 DONE;
14544 })
14545
14546 (define_insn_and_split "eh_return_si"
14547 [(set (pc)
14548 (unspec [(match_operand:SI 0 "register_operand" "c")]
14549 UNSPEC_EH_RETURN))]
14550 "!TARGET_64BIT"
14551 "#"
14552 "reload_completed"
14553 [(const_int 1)]
14554 "ix86_expand_epilogue (2); DONE;")
14555
14556 (define_insn_and_split "eh_return_di"
14557 [(set (pc)
14558 (unspec [(match_operand:DI 0 "register_operand" "c")]
14559 UNSPEC_EH_RETURN))]
14560 "TARGET_64BIT"
14561 "#"
14562 "reload_completed"
14563 [(const_int 1)]
14564 "ix86_expand_epilogue (2); DONE;")
14565
14566 (define_insn "leave"
14567 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14568 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14569 (clobber (mem:BLK (scratch)))]
14570 "!TARGET_64BIT"
14571 "leave"
14572 [(set_attr "type" "leave")])
14573
14574 (define_insn "leave_rex64"
14575 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14576 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14577 (clobber (mem:BLK (scratch)))]
14578 "TARGET_64BIT"
14579 "leave"
14580 [(set_attr "type" "leave")])
14581 \f
14582 (define_expand "ffssi2"
14583 [(parallel
14584 [(set (match_operand:SI 0 "register_operand" "")
14585 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14586 (clobber (match_scratch:SI 2 ""))
14587 (clobber (reg:CC FLAGS_REG))])]
14588 ""
14589 "")
14590
14591 (define_insn_and_split "*ffs_cmove"
14592 [(set (match_operand:SI 0 "register_operand" "=r")
14593 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14594 (clobber (match_scratch:SI 2 "=&r"))
14595 (clobber (reg:CC FLAGS_REG))]
14596 "TARGET_CMOVE"
14597 "#"
14598 "&& reload_completed"
14599 [(set (match_dup 2) (const_int -1))
14600 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14601 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14602 (set (match_dup 0) (if_then_else:SI
14603 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14604 (match_dup 2)
14605 (match_dup 0)))
14606 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14607 (clobber (reg:CC FLAGS_REG))])]
14608 "")
14609
14610 (define_insn_and_split "*ffs_no_cmove"
14611 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14612 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14613 (clobber (match_scratch:SI 2 "=&q"))
14614 (clobber (reg:CC FLAGS_REG))]
14615 ""
14616 "#"
14617 "reload_completed"
14618 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14619 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14620 (set (strict_low_part (match_dup 3))
14621 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14622 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14623 (clobber (reg:CC FLAGS_REG))])
14624 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14625 (clobber (reg:CC FLAGS_REG))])
14626 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14627 (clobber (reg:CC FLAGS_REG))])]
14628 {
14629 operands[3] = gen_lowpart (QImode, operands[2]);
14630 ix86_expand_clear (operands[2]);
14631 })
14632
14633 (define_insn "*ffssi_1"
14634 [(set (reg:CCZ FLAGS_REG)
14635 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14636 (const_int 0)))
14637 (set (match_operand:SI 0 "register_operand" "=r")
14638 (ctz:SI (match_dup 1)))]
14639 ""
14640 "bsf{l}\t{%1, %0|%0, %1}"
14641 [(set_attr "prefix_0f" "1")])
14642
14643 (define_expand "ffsdi2"
14644 [(parallel
14645 [(set (match_operand:DI 0 "register_operand" "")
14646 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14647 (clobber (match_scratch:DI 2 ""))
14648 (clobber (reg:CC FLAGS_REG))])]
14649 "TARGET_64BIT && TARGET_CMOVE"
14650 "")
14651
14652 (define_insn_and_split "*ffs_rex64"
14653 [(set (match_operand:DI 0 "register_operand" "=r")
14654 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14655 (clobber (match_scratch:DI 2 "=&r"))
14656 (clobber (reg:CC FLAGS_REG))]
14657 "TARGET_64BIT && TARGET_CMOVE"
14658 "#"
14659 "&& reload_completed"
14660 [(set (match_dup 2) (const_int -1))
14661 (parallel [(set (reg:CCZ FLAGS_REG)
14662 (compare:CCZ (match_dup 1) (const_int 0)))
14663 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14664 (set (match_dup 0) (if_then_else:DI
14665 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14666 (match_dup 2)
14667 (match_dup 0)))
14668 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14669 (clobber (reg:CC FLAGS_REG))])]
14670 "")
14671
14672 (define_insn "*ffsdi_1"
14673 [(set (reg:CCZ FLAGS_REG)
14674 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14675 (const_int 0)))
14676 (set (match_operand:DI 0 "register_operand" "=r")
14677 (ctz:DI (match_dup 1)))]
14678 "TARGET_64BIT"
14679 "bsf{q}\t{%1, %0|%0, %1}"
14680 [(set_attr "prefix_0f" "1")])
14681
14682 (define_insn "ctzsi2"
14683 [(set (match_operand:SI 0 "register_operand" "=r")
14684 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14685 (clobber (reg:CC FLAGS_REG))]
14686 ""
14687 "bsf{l}\t{%1, %0|%0, %1}"
14688 [(set_attr "prefix_0f" "1")])
14689
14690 (define_insn "ctzdi2"
14691 [(set (match_operand:DI 0 "register_operand" "=r")
14692 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14693 (clobber (reg:CC FLAGS_REG))]
14694 "TARGET_64BIT"
14695 "bsf{q}\t{%1, %0|%0, %1}"
14696 [(set_attr "prefix_0f" "1")])
14697
14698 (define_expand "clzsi2"
14699 [(parallel
14700 [(set (match_operand:SI 0 "register_operand" "")
14701 (minus:SI (const_int 31)
14702 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14703 (clobber (reg:CC FLAGS_REG))])
14704 (parallel
14705 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14706 (clobber (reg:CC FLAGS_REG))])]
14707 ""
14708 {
14709 if (TARGET_ABM)
14710 {
14711 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14712 DONE;
14713 }
14714 })
14715
14716 (define_insn "clzsi2_abm"
14717 [(set (match_operand:SI 0 "register_operand" "=r")
14718 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14719 (clobber (reg:CC FLAGS_REG))]
14720 "TARGET_ABM"
14721 "lzcnt{l}\t{%1, %0|%0, %1}"
14722 [(set_attr "prefix_rep" "1")
14723 (set_attr "type" "bitmanip")
14724 (set_attr "mode" "SI")])
14725
14726 (define_insn "*bsr"
14727 [(set (match_operand:SI 0 "register_operand" "=r")
14728 (minus:SI (const_int 31)
14729 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14730 (clobber (reg:CC FLAGS_REG))]
14731 ""
14732 "bsr{l}\t{%1, %0|%0, %1}"
14733 [(set_attr "prefix_0f" "1")
14734 (set_attr "mode" "SI")])
14735
14736 (define_insn "popcountsi2"
14737 [(set (match_operand:SI 0 "register_operand" "=r")
14738 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14739 (clobber (reg:CC FLAGS_REG))]
14740 "TARGET_POPCNT"
14741 "popcnt{l}\t{%1, %0|%0, %1}"
14742 [(set_attr "prefix_rep" "1")
14743 (set_attr "type" "bitmanip")
14744 (set_attr "mode" "SI")])
14745
14746 (define_insn "*popcountsi2_cmp"
14747 [(set (reg FLAGS_REG)
14748 (compare
14749 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14750 (const_int 0)))
14751 (set (match_operand:SI 0 "register_operand" "=r")
14752 (popcount:SI (match_dup 1)))]
14753 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14754 "popcnt{l}\t{%1, %0|%0, %1}"
14755 [(set_attr "prefix_rep" "1")
14756 (set_attr "type" "bitmanip")
14757 (set_attr "mode" "SI")])
14758
14759 (define_insn "*popcountsi2_cmp_zext"
14760 [(set (reg FLAGS_REG)
14761 (compare
14762 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14763 (const_int 0)))
14764 (set (match_operand:DI 0 "register_operand" "=r")
14765 (zero_extend:DI(popcount:SI (match_dup 1))))]
14766 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14767 "popcnt{l}\t{%1, %0|%0, %1}"
14768 [(set_attr "prefix_rep" "1")
14769 (set_attr "type" "bitmanip")
14770 (set_attr "mode" "SI")])
14771
14772 (define_expand "bswapsi2"
14773 [(set (match_operand:SI 0 "register_operand" "")
14774 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14775 ""
14776 {
14777 if (!TARGET_BSWAP)
14778 {
14779 rtx x = operands[0];
14780
14781 emit_move_insn (x, operands[1]);
14782 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14783 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14784 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14785 DONE;
14786 }
14787 })
14788
14789 (define_insn "*bswapsi_1"
14790 [(set (match_operand:SI 0 "register_operand" "=r")
14791 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14792 "TARGET_BSWAP"
14793 "bswap\t%0"
14794 [(set_attr "prefix_0f" "1")
14795 (set_attr "length" "2")])
14796
14797 (define_insn "*bswaphi_lowpart_1"
14798 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14799 (bswap:HI (match_dup 0)))
14800 (clobber (reg:CC FLAGS_REG))]
14801 "TARGET_USE_XCHGB || optimize_size"
14802 "@
14803 xchg{b}\t{%h0, %b0|%b0, %h0}
14804 rol{w}\t{$8, %0|%0, 8}"
14805 [(set_attr "length" "2,4")
14806 (set_attr "mode" "QI,HI")])
14807
14808 (define_insn "bswaphi_lowpart"
14809 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14810 (bswap:HI (match_dup 0)))
14811 (clobber (reg:CC FLAGS_REG))]
14812 ""
14813 "rol{w}\t{$8, %0|%0, 8}"
14814 [(set_attr "length" "4")
14815 (set_attr "mode" "HI")])
14816
14817 (define_insn "bswapdi2"
14818 [(set (match_operand:DI 0 "register_operand" "=r")
14819 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14820 "TARGET_64BIT"
14821 "bswap\t%0"
14822 [(set_attr "prefix_0f" "1")
14823 (set_attr "length" "3")])
14824
14825 (define_expand "clzdi2"
14826 [(parallel
14827 [(set (match_operand:DI 0 "register_operand" "")
14828 (minus:DI (const_int 63)
14829 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14830 (clobber (reg:CC FLAGS_REG))])
14831 (parallel
14832 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14833 (clobber (reg:CC FLAGS_REG))])]
14834 "TARGET_64BIT"
14835 {
14836 if (TARGET_ABM)
14837 {
14838 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14839 DONE;
14840 }
14841 })
14842
14843 (define_insn "clzdi2_abm"
14844 [(set (match_operand:DI 0 "register_operand" "=r")
14845 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14846 (clobber (reg:CC FLAGS_REG))]
14847 "TARGET_64BIT && TARGET_ABM"
14848 "lzcnt{q}\t{%1, %0|%0, %1}"
14849 [(set_attr "prefix_rep" "1")
14850 (set_attr "type" "bitmanip")
14851 (set_attr "mode" "DI")])
14852
14853 (define_insn "*bsr_rex64"
14854 [(set (match_operand:DI 0 "register_operand" "=r")
14855 (minus:DI (const_int 63)
14856 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14857 (clobber (reg:CC FLAGS_REG))]
14858 "TARGET_64BIT"
14859 "bsr{q}\t{%1, %0|%0, %1}"
14860 [(set_attr "prefix_0f" "1")
14861 (set_attr "mode" "DI")])
14862
14863 (define_insn "popcountdi2"
14864 [(set (match_operand:DI 0 "register_operand" "=r")
14865 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14866 (clobber (reg:CC FLAGS_REG))]
14867 "TARGET_64BIT && TARGET_POPCNT"
14868 "popcnt{q}\t{%1, %0|%0, %1}"
14869 [(set_attr "prefix_rep" "1")
14870 (set_attr "type" "bitmanip")
14871 (set_attr "mode" "DI")])
14872
14873 (define_insn "*popcountdi2_cmp"
14874 [(set (reg FLAGS_REG)
14875 (compare
14876 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14877 (const_int 0)))
14878 (set (match_operand:DI 0 "register_operand" "=r")
14879 (popcount:DI (match_dup 1)))]
14880 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14881 "popcnt{q}\t{%1, %0|%0, %1}"
14882 [(set_attr "prefix_rep" "1")
14883 (set_attr "type" "bitmanip")
14884 (set_attr "mode" "DI")])
14885
14886 (define_expand "clzhi2"
14887 [(parallel
14888 [(set (match_operand:HI 0 "register_operand" "")
14889 (minus:HI (const_int 15)
14890 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14891 (clobber (reg:CC FLAGS_REG))])
14892 (parallel
14893 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14894 (clobber (reg:CC FLAGS_REG))])]
14895 ""
14896 {
14897 if (TARGET_ABM)
14898 {
14899 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14900 DONE;
14901 }
14902 })
14903
14904 (define_insn "clzhi2_abm"
14905 [(set (match_operand:HI 0 "register_operand" "=r")
14906 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14907 (clobber (reg:CC FLAGS_REG))]
14908 "TARGET_ABM"
14909 "lzcnt{w}\t{%1, %0|%0, %1}"
14910 [(set_attr "prefix_rep" "1")
14911 (set_attr "type" "bitmanip")
14912 (set_attr "mode" "HI")])
14913
14914 (define_insn "*bsrhi"
14915 [(set (match_operand:HI 0 "register_operand" "=r")
14916 (minus:HI (const_int 15)
14917 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14918 (clobber (reg:CC FLAGS_REG))]
14919 ""
14920 "bsr{w}\t{%1, %0|%0, %1}"
14921 [(set_attr "prefix_0f" "1")
14922 (set_attr "mode" "HI")])
14923
14924 (define_insn "popcounthi2"
14925 [(set (match_operand:HI 0 "register_operand" "=r")
14926 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14927 (clobber (reg:CC FLAGS_REG))]
14928 "TARGET_POPCNT"
14929 "popcnt{w}\t{%1, %0|%0, %1}"
14930 [(set_attr "prefix_rep" "1")
14931 (set_attr "type" "bitmanip")
14932 (set_attr "mode" "HI")])
14933
14934 (define_insn "*popcounthi2_cmp"
14935 [(set (reg FLAGS_REG)
14936 (compare
14937 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14938 (const_int 0)))
14939 (set (match_operand:HI 0 "register_operand" "=r")
14940 (popcount:HI (match_dup 1)))]
14941 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14942 "popcnt{w}\t{%1, %0|%0, %1}"
14943 [(set_attr "prefix_rep" "1")
14944 (set_attr "type" "bitmanip")
14945 (set_attr "mode" "HI")])
14946
14947 (define_expand "paritydi2"
14948 [(set (match_operand:DI 0 "register_operand" "")
14949 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
14950 "! TARGET_POPCNT"
14951 {
14952 rtx scratch = gen_reg_rtx (QImode);
14953 rtx cond;
14954
14955 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14956 NULL_RTX, operands[1]));
14957
14958 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14959 gen_rtx_REG (CCmode, FLAGS_REG),
14960 const0_rtx);
14961 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14962
14963 if (TARGET_64BIT)
14964 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14965 else
14966 {
14967 rtx tmp = gen_reg_rtx (SImode);
14968
14969 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14970 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14971 }
14972 DONE;
14973 })
14974
14975 (define_insn_and_split "paritydi2_cmp"
14976 [(set (reg:CC FLAGS_REG)
14977 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
14978 (clobber (match_scratch:DI 0 "=r,X"))
14979 (clobber (match_scratch:SI 1 "=r,r"))
14980 (clobber (match_scratch:HI 2 "=Q,Q"))]
14981 "! TARGET_POPCNT"
14982 "#"
14983 "&& reload_completed"
14984 [(parallel
14985 [(set (match_dup 1)
14986 (xor:SI (match_dup 1) (match_dup 4)))
14987 (clobber (reg:CC FLAGS_REG))])
14988 (parallel
14989 [(set (reg:CC FLAGS_REG)
14990 (parity:CC (match_dup 1)))
14991 (clobber (match_dup 1))
14992 (clobber (match_dup 2))])]
14993 {
14994 operands[4] = gen_lowpart (SImode, operands[3]);
14995
14996 if (MEM_P (operands[3]))
14997 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
14998 else if (! TARGET_64BIT)
14999 operands[1] = gen_highpart (SImode, operands[3]);
15000 else
15001 {
15002 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15003 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15004 }
15005 })
15006
15007 (define_expand "paritysi2"
15008 [(set (match_operand:SI 0 "register_operand" "")
15009 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15010 "! TARGET_POPCNT"
15011 {
15012 rtx scratch = gen_reg_rtx (QImode);
15013 rtx cond;
15014
15015 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15016
15017 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15018 gen_rtx_REG (CCmode, FLAGS_REG),
15019 const0_rtx);
15020 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15021
15022 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15023 DONE;
15024 })
15025
15026 (define_insn_and_split "paritysi2_cmp"
15027 [(set (reg:CC FLAGS_REG)
15028 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15029 (clobber (match_scratch:SI 0 "=r,X"))
15030 (clobber (match_scratch:HI 1 "=Q,Q"))]
15031 "! TARGET_POPCNT"
15032 "#"
15033 "&& reload_completed"
15034 [(parallel
15035 [(set (match_dup 1)
15036 (xor:HI (match_dup 1) (match_dup 3)))
15037 (clobber (reg:CC FLAGS_REG))])
15038 (parallel
15039 [(set (reg:CC FLAGS_REG)
15040 (parity:CC (match_dup 1)))
15041 (clobber (match_dup 1))])]
15042 {
15043 operands[3] = gen_lowpart (HImode, operands[2]);
15044
15045 if (MEM_P (operands[2]))
15046 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15047 else
15048 {
15049 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15050 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15051 }
15052 })
15053
15054 (define_insn "*parityhi2_cmp"
15055 [(set (reg:CC FLAGS_REG)
15056 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15057 (clobber (match_scratch:HI 0 "=Q"))]
15058 "! TARGET_POPCNT"
15059 "xor{b}\t{%h0, %b0|%b0, %h0}"
15060 [(set_attr "length" "2")
15061 (set_attr "mode" "HI")])
15062
15063 (define_insn "*parityqi2_cmp"
15064 [(set (reg:CC FLAGS_REG)
15065 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15066 "! TARGET_POPCNT"
15067 "test{b}\t%0, %0"
15068 [(set_attr "length" "2")
15069 (set_attr "mode" "QI")])
15070 \f
15071 ;; Thread-local storage patterns for ELF.
15072 ;;
15073 ;; Note that these code sequences must appear exactly as shown
15074 ;; in order to allow linker relaxation.
15075
15076 (define_insn "*tls_global_dynamic_32_gnu"
15077 [(set (match_operand:SI 0 "register_operand" "=a")
15078 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15079 (match_operand:SI 2 "tls_symbolic_operand" "")
15080 (match_operand:SI 3 "call_insn_operand" "")]
15081 UNSPEC_TLS_GD))
15082 (clobber (match_scratch:SI 4 "=d"))
15083 (clobber (match_scratch:SI 5 "=c"))
15084 (clobber (reg:CC FLAGS_REG))]
15085 "!TARGET_64BIT && TARGET_GNU_TLS"
15086 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15087 [(set_attr "type" "multi")
15088 (set_attr "length" "12")])
15089
15090 (define_insn "*tls_global_dynamic_32_sun"
15091 [(set (match_operand:SI 0 "register_operand" "=a")
15092 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15093 (match_operand:SI 2 "tls_symbolic_operand" "")
15094 (match_operand:SI 3 "call_insn_operand" "")]
15095 UNSPEC_TLS_GD))
15096 (clobber (match_scratch:SI 4 "=d"))
15097 (clobber (match_scratch:SI 5 "=c"))
15098 (clobber (reg:CC FLAGS_REG))]
15099 "!TARGET_64BIT && TARGET_SUN_TLS"
15100 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15101 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15102 [(set_attr "type" "multi")
15103 (set_attr "length" "14")])
15104
15105 (define_expand "tls_global_dynamic_32"
15106 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15107 (unspec:SI
15108 [(match_dup 2)
15109 (match_operand:SI 1 "tls_symbolic_operand" "")
15110 (match_dup 3)]
15111 UNSPEC_TLS_GD))
15112 (clobber (match_scratch:SI 4 ""))
15113 (clobber (match_scratch:SI 5 ""))
15114 (clobber (reg:CC FLAGS_REG))])]
15115 ""
15116 {
15117 if (flag_pic)
15118 operands[2] = pic_offset_table_rtx;
15119 else
15120 {
15121 operands[2] = gen_reg_rtx (Pmode);
15122 emit_insn (gen_set_got (operands[2]));
15123 }
15124 if (TARGET_GNU2_TLS)
15125 {
15126 emit_insn (gen_tls_dynamic_gnu2_32
15127 (operands[0], operands[1], operands[2]));
15128 DONE;
15129 }
15130 operands[3] = ix86_tls_get_addr ();
15131 })
15132
15133 (define_insn "*tls_global_dynamic_64"
15134 [(set (match_operand:DI 0 "register_operand" "=a")
15135 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15136 (match_operand:DI 3 "" "")))
15137 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15138 UNSPEC_TLS_GD)]
15139 "TARGET_64BIT"
15140 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15141 [(set_attr "type" "multi")
15142 (set_attr "length" "16")])
15143
15144 (define_expand "tls_global_dynamic_64"
15145 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15146 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15147 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15148 UNSPEC_TLS_GD)])]
15149 ""
15150 {
15151 if (TARGET_GNU2_TLS)
15152 {
15153 emit_insn (gen_tls_dynamic_gnu2_64
15154 (operands[0], operands[1]));
15155 DONE;
15156 }
15157 operands[2] = ix86_tls_get_addr ();
15158 })
15159
15160 (define_insn "*tls_local_dynamic_base_32_gnu"
15161 [(set (match_operand:SI 0 "register_operand" "=a")
15162 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15163 (match_operand:SI 2 "call_insn_operand" "")]
15164 UNSPEC_TLS_LD_BASE))
15165 (clobber (match_scratch:SI 3 "=d"))
15166 (clobber (match_scratch:SI 4 "=c"))
15167 (clobber (reg:CC FLAGS_REG))]
15168 "!TARGET_64BIT && TARGET_GNU_TLS"
15169 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15170 [(set_attr "type" "multi")
15171 (set_attr "length" "11")])
15172
15173 (define_insn "*tls_local_dynamic_base_32_sun"
15174 [(set (match_operand:SI 0 "register_operand" "=a")
15175 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15176 (match_operand:SI 2 "call_insn_operand" "")]
15177 UNSPEC_TLS_LD_BASE))
15178 (clobber (match_scratch:SI 3 "=d"))
15179 (clobber (match_scratch:SI 4 "=c"))
15180 (clobber (reg:CC FLAGS_REG))]
15181 "!TARGET_64BIT && TARGET_SUN_TLS"
15182 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15183 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15184 [(set_attr "type" "multi")
15185 (set_attr "length" "13")])
15186
15187 (define_expand "tls_local_dynamic_base_32"
15188 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15189 (unspec:SI [(match_dup 1) (match_dup 2)]
15190 UNSPEC_TLS_LD_BASE))
15191 (clobber (match_scratch:SI 3 ""))
15192 (clobber (match_scratch:SI 4 ""))
15193 (clobber (reg:CC FLAGS_REG))])]
15194 ""
15195 {
15196 if (flag_pic)
15197 operands[1] = pic_offset_table_rtx;
15198 else
15199 {
15200 operands[1] = gen_reg_rtx (Pmode);
15201 emit_insn (gen_set_got (operands[1]));
15202 }
15203 if (TARGET_GNU2_TLS)
15204 {
15205 emit_insn (gen_tls_dynamic_gnu2_32
15206 (operands[0], ix86_tls_module_base (), operands[1]));
15207 DONE;
15208 }
15209 operands[2] = ix86_tls_get_addr ();
15210 })
15211
15212 (define_insn "*tls_local_dynamic_base_64"
15213 [(set (match_operand:DI 0 "register_operand" "=a")
15214 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15215 (match_operand:DI 2 "" "")))
15216 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15217 "TARGET_64BIT"
15218 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15219 [(set_attr "type" "multi")
15220 (set_attr "length" "12")])
15221
15222 (define_expand "tls_local_dynamic_base_64"
15223 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15224 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15225 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15226 ""
15227 {
15228 if (TARGET_GNU2_TLS)
15229 {
15230 emit_insn (gen_tls_dynamic_gnu2_64
15231 (operands[0], ix86_tls_module_base ()));
15232 DONE;
15233 }
15234 operands[1] = ix86_tls_get_addr ();
15235 })
15236
15237 ;; Local dynamic of a single variable is a lose. Show combine how
15238 ;; to convert that back to global dynamic.
15239
15240 (define_insn_and_split "*tls_local_dynamic_32_once"
15241 [(set (match_operand:SI 0 "register_operand" "=a")
15242 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15243 (match_operand:SI 2 "call_insn_operand" "")]
15244 UNSPEC_TLS_LD_BASE)
15245 (const:SI (unspec:SI
15246 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15247 UNSPEC_DTPOFF))))
15248 (clobber (match_scratch:SI 4 "=d"))
15249 (clobber (match_scratch:SI 5 "=c"))
15250 (clobber (reg:CC FLAGS_REG))]
15251 ""
15252 "#"
15253 ""
15254 [(parallel [(set (match_dup 0)
15255 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15256 UNSPEC_TLS_GD))
15257 (clobber (match_dup 4))
15258 (clobber (match_dup 5))
15259 (clobber (reg:CC FLAGS_REG))])]
15260 "")
15261
15262 ;; Load and add the thread base pointer from %gs:0.
15263
15264 (define_insn "*load_tp_si"
15265 [(set (match_operand:SI 0 "register_operand" "=r")
15266 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15267 "!TARGET_64BIT"
15268 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15269 [(set_attr "type" "imov")
15270 (set_attr "modrm" "0")
15271 (set_attr "length" "7")
15272 (set_attr "memory" "load")
15273 (set_attr "imm_disp" "false")])
15274
15275 (define_insn "*add_tp_si"
15276 [(set (match_operand:SI 0 "register_operand" "=r")
15277 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15278 (match_operand:SI 1 "register_operand" "0")))
15279 (clobber (reg:CC FLAGS_REG))]
15280 "!TARGET_64BIT"
15281 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15282 [(set_attr "type" "alu")
15283 (set_attr "modrm" "0")
15284 (set_attr "length" "7")
15285 (set_attr "memory" "load")
15286 (set_attr "imm_disp" "false")])
15287
15288 (define_insn "*load_tp_di"
15289 [(set (match_operand:DI 0 "register_operand" "=r")
15290 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15291 "TARGET_64BIT"
15292 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15293 [(set_attr "type" "imov")
15294 (set_attr "modrm" "0")
15295 (set_attr "length" "7")
15296 (set_attr "memory" "load")
15297 (set_attr "imm_disp" "false")])
15298
15299 (define_insn "*add_tp_di"
15300 [(set (match_operand:DI 0 "register_operand" "=r")
15301 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15302 (match_operand:DI 1 "register_operand" "0")))
15303 (clobber (reg:CC FLAGS_REG))]
15304 "TARGET_64BIT"
15305 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15306 [(set_attr "type" "alu")
15307 (set_attr "modrm" "0")
15308 (set_attr "length" "7")
15309 (set_attr "memory" "load")
15310 (set_attr "imm_disp" "false")])
15311
15312 ;; GNU2 TLS patterns can be split.
15313
15314 (define_expand "tls_dynamic_gnu2_32"
15315 [(set (match_dup 3)
15316 (plus:SI (match_operand:SI 2 "register_operand" "")
15317 (const:SI
15318 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15319 UNSPEC_TLSDESC))))
15320 (parallel
15321 [(set (match_operand:SI 0 "register_operand" "")
15322 (unspec:SI [(match_dup 1) (match_dup 3)
15323 (match_dup 2) (reg:SI SP_REG)]
15324 UNSPEC_TLSDESC))
15325 (clobber (reg:CC FLAGS_REG))])]
15326 "!TARGET_64BIT && TARGET_GNU2_TLS"
15327 {
15328 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15329 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15330 })
15331
15332 (define_insn "*tls_dynamic_lea_32"
15333 [(set (match_operand:SI 0 "register_operand" "=r")
15334 (plus:SI (match_operand:SI 1 "register_operand" "b")
15335 (const:SI
15336 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15337 UNSPEC_TLSDESC))))]
15338 "!TARGET_64BIT && TARGET_GNU2_TLS"
15339 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15340 [(set_attr "type" "lea")
15341 (set_attr "mode" "SI")
15342 (set_attr "length" "6")
15343 (set_attr "length_address" "4")])
15344
15345 (define_insn "*tls_dynamic_call_32"
15346 [(set (match_operand:SI 0 "register_operand" "=a")
15347 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15348 (match_operand:SI 2 "register_operand" "0")
15349 ;; we have to make sure %ebx still points to the GOT
15350 (match_operand:SI 3 "register_operand" "b")
15351 (reg:SI SP_REG)]
15352 UNSPEC_TLSDESC))
15353 (clobber (reg:CC FLAGS_REG))]
15354 "!TARGET_64BIT && TARGET_GNU2_TLS"
15355 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15356 [(set_attr "type" "call")
15357 (set_attr "length" "2")
15358 (set_attr "length_address" "0")])
15359
15360 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15361 [(set (match_operand:SI 0 "register_operand" "=&a")
15362 (plus:SI
15363 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15364 (match_operand:SI 4 "" "")
15365 (match_operand:SI 2 "register_operand" "b")
15366 (reg:SI SP_REG)]
15367 UNSPEC_TLSDESC)
15368 (const:SI (unspec:SI
15369 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15370 UNSPEC_DTPOFF))))
15371 (clobber (reg:CC FLAGS_REG))]
15372 "!TARGET_64BIT && TARGET_GNU2_TLS"
15373 "#"
15374 ""
15375 [(set (match_dup 0) (match_dup 5))]
15376 {
15377 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15378 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15379 })
15380
15381 (define_expand "tls_dynamic_gnu2_64"
15382 [(set (match_dup 2)
15383 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15384 UNSPEC_TLSDESC))
15385 (parallel
15386 [(set (match_operand:DI 0 "register_operand" "")
15387 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15388 UNSPEC_TLSDESC))
15389 (clobber (reg:CC FLAGS_REG))])]
15390 "TARGET_64BIT && TARGET_GNU2_TLS"
15391 {
15392 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15393 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15394 })
15395
15396 (define_insn "*tls_dynamic_lea_64"
15397 [(set (match_operand:DI 0 "register_operand" "=r")
15398 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15399 UNSPEC_TLSDESC))]
15400 "TARGET_64BIT && TARGET_GNU2_TLS"
15401 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15402 [(set_attr "type" "lea")
15403 (set_attr "mode" "DI")
15404 (set_attr "length" "7")
15405 (set_attr "length_address" "4")])
15406
15407 (define_insn "*tls_dynamic_call_64"
15408 [(set (match_operand:DI 0 "register_operand" "=a")
15409 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15410 (match_operand:DI 2 "register_operand" "0")
15411 (reg:DI SP_REG)]
15412 UNSPEC_TLSDESC))
15413 (clobber (reg:CC FLAGS_REG))]
15414 "TARGET_64BIT && TARGET_GNU2_TLS"
15415 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15416 [(set_attr "type" "call")
15417 (set_attr "length" "2")
15418 (set_attr "length_address" "0")])
15419
15420 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15421 [(set (match_operand:DI 0 "register_operand" "=&a")
15422 (plus:DI
15423 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15424 (match_operand:DI 3 "" "")
15425 (reg:DI SP_REG)]
15426 UNSPEC_TLSDESC)
15427 (const:DI (unspec:DI
15428 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15429 UNSPEC_DTPOFF))))
15430 (clobber (reg:CC FLAGS_REG))]
15431 "TARGET_64BIT && TARGET_GNU2_TLS"
15432 "#"
15433 ""
15434 [(set (match_dup 0) (match_dup 4))]
15435 {
15436 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15437 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15438 })
15439
15440 ;;
15441 \f
15442 ;; These patterns match the binary 387 instructions for addM3, subM3,
15443 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15444 ;; SFmode. The first is the normal insn, the second the same insn but
15445 ;; with one operand a conversion, and the third the same insn but with
15446 ;; the other operand a conversion. The conversion may be SFmode or
15447 ;; SImode if the target mode DFmode, but only SImode if the target mode
15448 ;; is SFmode.
15449
15450 ;; Gcc is slightly more smart about handling normal two address instructions
15451 ;; so use special patterns for add and mull.
15452
15453 (define_insn "*fop_sf_comm_mixed"
15454 [(set (match_operand:SF 0 "register_operand" "=f,x")
15455 (match_operator:SF 3 "binary_fp_operator"
15456 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15457 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15458 "TARGET_MIX_SSE_I387
15459 && COMMUTATIVE_ARITH_P (operands[3])
15460 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15461 "* return output_387_binary_op (insn, operands);"
15462 [(set (attr "type")
15463 (if_then_else (eq_attr "alternative" "1")
15464 (if_then_else (match_operand:SF 3 "mult_operator" "")
15465 (const_string "ssemul")
15466 (const_string "sseadd"))
15467 (if_then_else (match_operand:SF 3 "mult_operator" "")
15468 (const_string "fmul")
15469 (const_string "fop"))))
15470 (set_attr "mode" "SF")])
15471
15472 (define_insn "*fop_sf_comm_sse"
15473 [(set (match_operand:SF 0 "register_operand" "=x")
15474 (match_operator:SF 3 "binary_fp_operator"
15475 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15476 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15477 "TARGET_SSE_MATH
15478 && COMMUTATIVE_ARITH_P (operands[3])
15479 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15480 "* return output_387_binary_op (insn, operands);"
15481 [(set (attr "type")
15482 (if_then_else (match_operand:SF 3 "mult_operator" "")
15483 (const_string "ssemul")
15484 (const_string "sseadd")))
15485 (set_attr "mode" "SF")])
15486
15487 (define_insn "*fop_sf_comm_i387"
15488 [(set (match_operand:SF 0 "register_operand" "=f")
15489 (match_operator:SF 3 "binary_fp_operator"
15490 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15491 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15492 "TARGET_80387
15493 && COMMUTATIVE_ARITH_P (operands[3])
15494 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15495 "* return output_387_binary_op (insn, operands);"
15496 [(set (attr "type")
15497 (if_then_else (match_operand:SF 3 "mult_operator" "")
15498 (const_string "fmul")
15499 (const_string "fop")))
15500 (set_attr "mode" "SF")])
15501
15502 (define_insn "*fop_sf_1_mixed"
15503 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15504 (match_operator:SF 3 "binary_fp_operator"
15505 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15506 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15507 "TARGET_MIX_SSE_I387
15508 && !COMMUTATIVE_ARITH_P (operands[3])
15509 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15510 "* return output_387_binary_op (insn, operands);"
15511 [(set (attr "type")
15512 (cond [(and (eq_attr "alternative" "2")
15513 (match_operand:SF 3 "mult_operator" ""))
15514 (const_string "ssemul")
15515 (and (eq_attr "alternative" "2")
15516 (match_operand:SF 3 "div_operator" ""))
15517 (const_string "ssediv")
15518 (eq_attr "alternative" "2")
15519 (const_string "sseadd")
15520 (match_operand:SF 3 "mult_operator" "")
15521 (const_string "fmul")
15522 (match_operand:SF 3 "div_operator" "")
15523 (const_string "fdiv")
15524 ]
15525 (const_string "fop")))
15526 (set_attr "mode" "SF")])
15527
15528 (define_insn "*rcpsf2_sse"
15529 [(set (match_operand:SF 0 "register_operand" "=x")
15530 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15531 UNSPEC_RCP))]
15532 "TARGET_SSE_MATH"
15533 "rcpss\t{%1, %0|%0, %1}"
15534 [(set_attr "type" "sse")
15535 (set_attr "mode" "SF")])
15536
15537 (define_insn "*fop_sf_1_sse"
15538 [(set (match_operand:SF 0 "register_operand" "=x")
15539 (match_operator:SF 3 "binary_fp_operator"
15540 [(match_operand:SF 1 "register_operand" "0")
15541 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15542 "TARGET_SSE_MATH
15543 && !COMMUTATIVE_ARITH_P (operands[3])"
15544 "* return output_387_binary_op (insn, operands);"
15545 [(set (attr "type")
15546 (cond [(match_operand:SF 3 "mult_operator" "")
15547 (const_string "ssemul")
15548 (match_operand:SF 3 "div_operator" "")
15549 (const_string "ssediv")
15550 ]
15551 (const_string "sseadd")))
15552 (set_attr "mode" "SF")])
15553
15554 ;; This pattern is not fully shadowed by the pattern above.
15555 (define_insn "*fop_sf_1_i387"
15556 [(set (match_operand:SF 0 "register_operand" "=f,f")
15557 (match_operator:SF 3 "binary_fp_operator"
15558 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15559 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15560 "TARGET_80387 && !TARGET_SSE_MATH
15561 && !COMMUTATIVE_ARITH_P (operands[3])
15562 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15563 "* return output_387_binary_op (insn, operands);"
15564 [(set (attr "type")
15565 (cond [(match_operand:SF 3 "mult_operator" "")
15566 (const_string "fmul")
15567 (match_operand:SF 3 "div_operator" "")
15568 (const_string "fdiv")
15569 ]
15570 (const_string "fop")))
15571 (set_attr "mode" "SF")])
15572
15573 ;; ??? Add SSE splitters for these!
15574 (define_insn "*fop_sf_2<mode>_i387"
15575 [(set (match_operand:SF 0 "register_operand" "=f,f")
15576 (match_operator:SF 3 "binary_fp_operator"
15577 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15578 (match_operand:SF 2 "register_operand" "0,0")]))]
15579 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15580 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15581 [(set (attr "type")
15582 (cond [(match_operand:SF 3 "mult_operator" "")
15583 (const_string "fmul")
15584 (match_operand:SF 3 "div_operator" "")
15585 (const_string "fdiv")
15586 ]
15587 (const_string "fop")))
15588 (set_attr "fp_int_src" "true")
15589 (set_attr "mode" "<MODE>")])
15590
15591 (define_insn "*fop_sf_3<mode>_i387"
15592 [(set (match_operand:SF 0 "register_operand" "=f,f")
15593 (match_operator:SF 3 "binary_fp_operator"
15594 [(match_operand:SF 1 "register_operand" "0,0")
15595 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15596 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15597 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15598 [(set (attr "type")
15599 (cond [(match_operand:SF 3 "mult_operator" "")
15600 (const_string "fmul")
15601 (match_operand:SF 3 "div_operator" "")
15602 (const_string "fdiv")
15603 ]
15604 (const_string "fop")))
15605 (set_attr "fp_int_src" "true")
15606 (set_attr "mode" "<MODE>")])
15607
15608 (define_insn "*fop_df_comm_mixed"
15609 [(set (match_operand:DF 0 "register_operand" "=f,x")
15610 (match_operator:DF 3 "binary_fp_operator"
15611 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15612 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15613 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15614 && COMMUTATIVE_ARITH_P (operands[3])
15615 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15616 "* return output_387_binary_op (insn, operands);"
15617 [(set (attr "type")
15618 (if_then_else (eq_attr "alternative" "1")
15619 (if_then_else (match_operand:DF 3 "mult_operator" "")
15620 (const_string "ssemul")
15621 (const_string "sseadd"))
15622 (if_then_else (match_operand:DF 3 "mult_operator" "")
15623 (const_string "fmul")
15624 (const_string "fop"))))
15625 (set_attr "mode" "DF")])
15626
15627 (define_insn "*fop_df_comm_sse"
15628 [(set (match_operand:DF 0 "register_operand" "=x")
15629 (match_operator:DF 3 "binary_fp_operator"
15630 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15631 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15632 "TARGET_SSE2 && TARGET_SSE_MATH
15633 && COMMUTATIVE_ARITH_P (operands[3])
15634 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15635 "* return output_387_binary_op (insn, operands);"
15636 [(set (attr "type")
15637 (if_then_else (match_operand:DF 3 "mult_operator" "")
15638 (const_string "ssemul")
15639 (const_string "sseadd")))
15640 (set_attr "mode" "DF")])
15641
15642 (define_insn "*fop_df_comm_i387"
15643 [(set (match_operand:DF 0 "register_operand" "=f")
15644 (match_operator:DF 3 "binary_fp_operator"
15645 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15646 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15647 "TARGET_80387
15648 && COMMUTATIVE_ARITH_P (operands[3])
15649 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15650 "* return output_387_binary_op (insn, operands);"
15651 [(set (attr "type")
15652 (if_then_else (match_operand:DF 3 "mult_operator" "")
15653 (const_string "fmul")
15654 (const_string "fop")))
15655 (set_attr "mode" "DF")])
15656
15657 (define_insn "*fop_df_1_mixed"
15658 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15659 (match_operator:DF 3 "binary_fp_operator"
15660 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15661 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15662 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15663 && !COMMUTATIVE_ARITH_P (operands[3])
15664 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15665 "* return output_387_binary_op (insn, operands);"
15666 [(set (attr "type")
15667 (cond [(and (eq_attr "alternative" "2")
15668 (match_operand:DF 3 "mult_operator" ""))
15669 (const_string "ssemul")
15670 (and (eq_attr "alternative" "2")
15671 (match_operand:DF 3 "div_operator" ""))
15672 (const_string "ssediv")
15673 (eq_attr "alternative" "2")
15674 (const_string "sseadd")
15675 (match_operand:DF 3 "mult_operator" "")
15676 (const_string "fmul")
15677 (match_operand:DF 3 "div_operator" "")
15678 (const_string "fdiv")
15679 ]
15680 (const_string "fop")))
15681 (set_attr "mode" "DF")])
15682
15683 (define_insn "*fop_df_1_sse"
15684 [(set (match_operand:DF 0 "register_operand" "=x")
15685 (match_operator:DF 3 "binary_fp_operator"
15686 [(match_operand:DF 1 "register_operand" "0")
15687 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15688 "TARGET_SSE2 && TARGET_SSE_MATH
15689 && !COMMUTATIVE_ARITH_P (operands[3])"
15690 "* return output_387_binary_op (insn, operands);"
15691 [(set_attr "mode" "DF")
15692 (set (attr "type")
15693 (cond [(match_operand:DF 3 "mult_operator" "")
15694 (const_string "ssemul")
15695 (match_operand:DF 3 "div_operator" "")
15696 (const_string "ssediv")
15697 ]
15698 (const_string "sseadd")))])
15699
15700 ;; This pattern is not fully shadowed by the pattern above.
15701 (define_insn "*fop_df_1_i387"
15702 [(set (match_operand:DF 0 "register_operand" "=f,f")
15703 (match_operator:DF 3 "binary_fp_operator"
15704 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15705 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15706 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15707 && !COMMUTATIVE_ARITH_P (operands[3])
15708 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15709 "* return output_387_binary_op (insn, operands);"
15710 [(set (attr "type")
15711 (cond [(match_operand:DF 3 "mult_operator" "")
15712 (const_string "fmul")
15713 (match_operand:DF 3 "div_operator" "")
15714 (const_string "fdiv")
15715 ]
15716 (const_string "fop")))
15717 (set_attr "mode" "DF")])
15718
15719 ;; ??? Add SSE splitters for these!
15720 (define_insn "*fop_df_2<mode>_i387"
15721 [(set (match_operand:DF 0 "register_operand" "=f,f")
15722 (match_operator:DF 3 "binary_fp_operator"
15723 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15724 (match_operand:DF 2 "register_operand" "0,0")]))]
15725 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15726 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15727 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15728 [(set (attr "type")
15729 (cond [(match_operand:DF 3 "mult_operator" "")
15730 (const_string "fmul")
15731 (match_operand:DF 3 "div_operator" "")
15732 (const_string "fdiv")
15733 ]
15734 (const_string "fop")))
15735 (set_attr "fp_int_src" "true")
15736 (set_attr "mode" "<MODE>")])
15737
15738 (define_insn "*fop_df_3<mode>_i387"
15739 [(set (match_operand:DF 0 "register_operand" "=f,f")
15740 (match_operator:DF 3 "binary_fp_operator"
15741 [(match_operand:DF 1 "register_operand" "0,0")
15742 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15743 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15744 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15745 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15746 [(set (attr "type")
15747 (cond [(match_operand:DF 3 "mult_operator" "")
15748 (const_string "fmul")
15749 (match_operand:DF 3 "div_operator" "")
15750 (const_string "fdiv")
15751 ]
15752 (const_string "fop")))
15753 (set_attr "fp_int_src" "true")
15754 (set_attr "mode" "<MODE>")])
15755
15756 (define_insn "*fop_df_4_i387"
15757 [(set (match_operand:DF 0 "register_operand" "=f,f")
15758 (match_operator:DF 3 "binary_fp_operator"
15759 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15760 (match_operand:DF 2 "register_operand" "0,f")]))]
15761 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15762 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15763 "* return output_387_binary_op (insn, operands);"
15764 [(set (attr "type")
15765 (cond [(match_operand:DF 3 "mult_operator" "")
15766 (const_string "fmul")
15767 (match_operand:DF 3 "div_operator" "")
15768 (const_string "fdiv")
15769 ]
15770 (const_string "fop")))
15771 (set_attr "mode" "SF")])
15772
15773 (define_insn "*fop_df_5_i387"
15774 [(set (match_operand:DF 0 "register_operand" "=f,f")
15775 (match_operator:DF 3 "binary_fp_operator"
15776 [(match_operand:DF 1 "register_operand" "0,f")
15777 (float_extend:DF
15778 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15779 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15780 "* return output_387_binary_op (insn, operands);"
15781 [(set (attr "type")
15782 (cond [(match_operand:DF 3 "mult_operator" "")
15783 (const_string "fmul")
15784 (match_operand:DF 3 "div_operator" "")
15785 (const_string "fdiv")
15786 ]
15787 (const_string "fop")))
15788 (set_attr "mode" "SF")])
15789
15790 (define_insn "*fop_df_6_i387"
15791 [(set (match_operand:DF 0 "register_operand" "=f,f")
15792 (match_operator:DF 3 "binary_fp_operator"
15793 [(float_extend:DF
15794 (match_operand:SF 1 "register_operand" "0,f"))
15795 (float_extend:DF
15796 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15797 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15798 "* return output_387_binary_op (insn, operands);"
15799 [(set (attr "type")
15800 (cond [(match_operand:DF 3 "mult_operator" "")
15801 (const_string "fmul")
15802 (match_operand:DF 3 "div_operator" "")
15803 (const_string "fdiv")
15804 ]
15805 (const_string "fop")))
15806 (set_attr "mode" "SF")])
15807
15808 (define_insn "*fop_xf_comm_i387"
15809 [(set (match_operand:XF 0 "register_operand" "=f")
15810 (match_operator:XF 3 "binary_fp_operator"
15811 [(match_operand:XF 1 "register_operand" "%0")
15812 (match_operand:XF 2 "register_operand" "f")]))]
15813 "TARGET_80387
15814 && COMMUTATIVE_ARITH_P (operands[3])"
15815 "* return output_387_binary_op (insn, operands);"
15816 [(set (attr "type")
15817 (if_then_else (match_operand:XF 3 "mult_operator" "")
15818 (const_string "fmul")
15819 (const_string "fop")))
15820 (set_attr "mode" "XF")])
15821
15822 (define_insn "*fop_xf_1_i387"
15823 [(set (match_operand:XF 0 "register_operand" "=f,f")
15824 (match_operator:XF 3 "binary_fp_operator"
15825 [(match_operand:XF 1 "register_operand" "0,f")
15826 (match_operand:XF 2 "register_operand" "f,0")]))]
15827 "TARGET_80387
15828 && !COMMUTATIVE_ARITH_P (operands[3])"
15829 "* return output_387_binary_op (insn, operands);"
15830 [(set (attr "type")
15831 (cond [(match_operand:XF 3 "mult_operator" "")
15832 (const_string "fmul")
15833 (match_operand:XF 3 "div_operator" "")
15834 (const_string "fdiv")
15835 ]
15836 (const_string "fop")))
15837 (set_attr "mode" "XF")])
15838
15839 (define_insn "*fop_xf_2<mode>_i387"
15840 [(set (match_operand:XF 0 "register_operand" "=f,f")
15841 (match_operator:XF 3 "binary_fp_operator"
15842 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15843 (match_operand:XF 2 "register_operand" "0,0")]))]
15844 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15845 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15846 [(set (attr "type")
15847 (cond [(match_operand:XF 3 "mult_operator" "")
15848 (const_string "fmul")
15849 (match_operand:XF 3 "div_operator" "")
15850 (const_string "fdiv")
15851 ]
15852 (const_string "fop")))
15853 (set_attr "fp_int_src" "true")
15854 (set_attr "mode" "<MODE>")])
15855
15856 (define_insn "*fop_xf_3<mode>_i387"
15857 [(set (match_operand:XF 0 "register_operand" "=f,f")
15858 (match_operator:XF 3 "binary_fp_operator"
15859 [(match_operand:XF 1 "register_operand" "0,0")
15860 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15861 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15862 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15863 [(set (attr "type")
15864 (cond [(match_operand:XF 3 "mult_operator" "")
15865 (const_string "fmul")
15866 (match_operand:XF 3 "div_operator" "")
15867 (const_string "fdiv")
15868 ]
15869 (const_string "fop")))
15870 (set_attr "fp_int_src" "true")
15871 (set_attr "mode" "<MODE>")])
15872
15873 (define_insn "*fop_xf_4_i387"
15874 [(set (match_operand:XF 0 "register_operand" "=f,f")
15875 (match_operator:XF 3 "binary_fp_operator"
15876 [(float_extend:XF
15877 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15878 (match_operand:XF 2 "register_operand" "0,f")]))]
15879 "TARGET_80387"
15880 "* return output_387_binary_op (insn, operands);"
15881 [(set (attr "type")
15882 (cond [(match_operand:XF 3 "mult_operator" "")
15883 (const_string "fmul")
15884 (match_operand:XF 3 "div_operator" "")
15885 (const_string "fdiv")
15886 ]
15887 (const_string "fop")))
15888 (set_attr "mode" "SF")])
15889
15890 (define_insn "*fop_xf_5_i387"
15891 [(set (match_operand:XF 0 "register_operand" "=f,f")
15892 (match_operator:XF 3 "binary_fp_operator"
15893 [(match_operand:XF 1 "register_operand" "0,f")
15894 (float_extend:XF
15895 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15896 "TARGET_80387"
15897 "* return output_387_binary_op (insn, operands);"
15898 [(set (attr "type")
15899 (cond [(match_operand:XF 3 "mult_operator" "")
15900 (const_string "fmul")
15901 (match_operand:XF 3 "div_operator" "")
15902 (const_string "fdiv")
15903 ]
15904 (const_string "fop")))
15905 (set_attr "mode" "SF")])
15906
15907 (define_insn "*fop_xf_6_i387"
15908 [(set (match_operand:XF 0 "register_operand" "=f,f")
15909 (match_operator:XF 3 "binary_fp_operator"
15910 [(float_extend:XF
15911 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15912 (float_extend:XF
15913 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15914 "TARGET_80387"
15915 "* return output_387_binary_op (insn, operands);"
15916 [(set (attr "type")
15917 (cond [(match_operand:XF 3 "mult_operator" "")
15918 (const_string "fmul")
15919 (match_operand:XF 3 "div_operator" "")
15920 (const_string "fdiv")
15921 ]
15922 (const_string "fop")))
15923 (set_attr "mode" "SF")])
15924
15925 (define_split
15926 [(set (match_operand 0 "register_operand" "")
15927 (match_operator 3 "binary_fp_operator"
15928 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15929 (match_operand 2 "register_operand" "")]))]
15930 "reload_completed
15931 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15932 [(const_int 0)]
15933 {
15934 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15935 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15936 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15937 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15938 GET_MODE (operands[3]),
15939 operands[4],
15940 operands[2])));
15941 ix86_free_from_memory (GET_MODE (operands[1]));
15942 DONE;
15943 })
15944
15945 (define_split
15946 [(set (match_operand 0 "register_operand" "")
15947 (match_operator 3 "binary_fp_operator"
15948 [(match_operand 1 "register_operand" "")
15949 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15950 "reload_completed
15951 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15952 [(const_int 0)]
15953 {
15954 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15955 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15956 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15957 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15958 GET_MODE (operands[3]),
15959 operands[1],
15960 operands[4])));
15961 ix86_free_from_memory (GET_MODE (operands[2]));
15962 DONE;
15963 })
15964 \f
15965 ;; FPU special functions.
15966
15967 ;; This pattern implements a no-op XFmode truncation for
15968 ;; all fancy i386 XFmode math functions.
15969
15970 (define_insn "truncxf<mode>2_i387_noop_unspec"
15971 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15972 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15973 UNSPEC_TRUNC_NOOP))]
15974 "TARGET_USE_FANCY_MATH_387"
15975 "* return output_387_reg_move (insn, operands);"
15976 [(set_attr "type" "fmov")
15977 (set_attr "mode" "<MODE>")])
15978
15979 (define_insn "sqrtxf2"
15980 [(set (match_operand:XF 0 "register_operand" "=f")
15981 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15982 "TARGET_USE_FANCY_MATH_387"
15983 "fsqrt"
15984 [(set_attr "type" "fpspc")
15985 (set_attr "mode" "XF")
15986 (set_attr "athlon_decode" "direct")
15987 (set_attr "amdfam10_decode" "direct")])
15988
15989 (define_insn "sqrt_extend<mode>xf2_i387"
15990 [(set (match_operand:XF 0 "register_operand" "=f")
15991 (sqrt:XF
15992 (float_extend:XF
15993 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15994 "TARGET_USE_FANCY_MATH_387"
15995 "fsqrt"
15996 [(set_attr "type" "fpspc")
15997 (set_attr "mode" "XF")
15998 (set_attr "athlon_decode" "direct")
15999 (set_attr "amdfam10_decode" "direct")])
16000
16001 (define_insn "*rsqrtsf2_sse"
16002 [(set (match_operand:SF 0 "register_operand" "=x")
16003 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16004 UNSPEC_RSQRT))]
16005 "TARGET_SSE_MATH"
16006 "rsqrtss\t{%1, %0|%0, %1}"
16007 [(set_attr "type" "sse")
16008 (set_attr "mode" "SF")])
16009
16010 (define_expand "rsqrtsf2"
16011 [(set (match_operand:SF 0 "register_operand" "=x")
16012 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16013 UNSPEC_RSQRT))]
16014 "TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16015 && flag_finite_math_only && !flag_trapping_math
16016 && flag_unsafe_math_optimizations"
16017 {
16018 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16019 DONE;
16020 })
16021
16022 (define_insn "*sqrt<mode>2_sse"
16023 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16024 (sqrt:SSEMODEF
16025 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16026 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16027 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16028 [(set_attr "type" "sse")
16029 (set_attr "mode" "<MODE>")
16030 (set_attr "athlon_decode" "*")
16031 (set_attr "amdfam10_decode" "*")])
16032
16033 (define_expand "sqrt<mode>2"
16034 [(set (match_operand:X87MODEF12 0 "register_operand" "")
16035 (sqrt:X87MODEF12
16036 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16037 "TARGET_USE_FANCY_MATH_387
16038 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16039 {
16040 if (<MODE>mode == SFmode
16041 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16042 && flag_finite_math_only && !flag_trapping_math
16043 && flag_unsafe_math_optimizations)
16044 {
16045 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16046 DONE;
16047 }
16048
16049 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16050 {
16051 rtx op0 = gen_reg_rtx (XFmode);
16052 rtx op1 = force_reg (<MODE>mode, operands[1]);
16053
16054 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16055 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16056 DONE;
16057 }
16058 })
16059
16060 (define_insn "fpremxf4_i387"
16061 [(set (match_operand:XF 0 "register_operand" "=f")
16062 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16063 (match_operand:XF 3 "register_operand" "1")]
16064 UNSPEC_FPREM_F))
16065 (set (match_operand:XF 1 "register_operand" "=u")
16066 (unspec:XF [(match_dup 2) (match_dup 3)]
16067 UNSPEC_FPREM_U))
16068 (set (reg:CCFP FPSR_REG)
16069 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16070 UNSPEC_C2_FLAG))]
16071 "TARGET_USE_FANCY_MATH_387"
16072 "fprem"
16073 [(set_attr "type" "fpspc")
16074 (set_attr "mode" "XF")])
16075
16076 (define_expand "fmodxf3"
16077 [(use (match_operand:XF 0 "register_operand" ""))
16078 (use (match_operand:XF 1 "register_operand" ""))
16079 (use (match_operand:XF 2 "register_operand" ""))]
16080 "TARGET_USE_FANCY_MATH_387"
16081 {
16082 rtx label = gen_label_rtx ();
16083
16084 emit_label (label);
16085
16086 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16087 operands[1], operands[2]));
16088 ix86_emit_fp_unordered_jump (label);
16089 LABEL_NUSES (label) = 1;
16090
16091 emit_move_insn (operands[0], operands[1]);
16092 DONE;
16093 })
16094
16095 (define_expand "fmod<mode>3"
16096 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16097 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16098 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16099 "TARGET_USE_FANCY_MATH_387"
16100 {
16101 rtx label = gen_label_rtx ();
16102
16103 rtx op1 = gen_reg_rtx (XFmode);
16104 rtx op2 = gen_reg_rtx (XFmode);
16105
16106 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16107 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16108
16109 emit_label (label);
16110 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16111 ix86_emit_fp_unordered_jump (label);
16112 LABEL_NUSES (label) = 1;
16113
16114 /* Truncate the result properly for strict SSE math. */
16115 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16116 && !TARGET_MIX_SSE_I387)
16117 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16118 else
16119 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16120
16121 DONE;
16122 })
16123
16124 (define_insn "fprem1xf4_i387"
16125 [(set (match_operand:XF 0 "register_operand" "=f")
16126 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16127 (match_operand:XF 3 "register_operand" "1")]
16128 UNSPEC_FPREM1_F))
16129 (set (match_operand:XF 1 "register_operand" "=u")
16130 (unspec:XF [(match_dup 2) (match_dup 3)]
16131 UNSPEC_FPREM1_U))
16132 (set (reg:CCFP FPSR_REG)
16133 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16134 UNSPEC_C2_FLAG))]
16135 "TARGET_USE_FANCY_MATH_387"
16136 "fprem1"
16137 [(set_attr "type" "fpspc")
16138 (set_attr "mode" "XF")])
16139
16140 (define_expand "remainderxf3"
16141 [(use (match_operand:XF 0 "register_operand" ""))
16142 (use (match_operand:XF 1 "register_operand" ""))
16143 (use (match_operand:XF 2 "register_operand" ""))]
16144 "TARGET_USE_FANCY_MATH_387"
16145 {
16146 rtx label = gen_label_rtx ();
16147
16148 emit_label (label);
16149
16150 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16151 operands[1], operands[2]));
16152 ix86_emit_fp_unordered_jump (label);
16153 LABEL_NUSES (label) = 1;
16154
16155 emit_move_insn (operands[0], operands[1]);
16156 DONE;
16157 })
16158
16159 (define_expand "remainder<mode>3"
16160 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16161 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16162 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16163 "TARGET_USE_FANCY_MATH_387"
16164 {
16165 rtx label = gen_label_rtx ();
16166
16167 rtx op1 = gen_reg_rtx (XFmode);
16168 rtx op2 = gen_reg_rtx (XFmode);
16169
16170 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16171 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16172
16173 emit_label (label);
16174
16175 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16176 ix86_emit_fp_unordered_jump (label);
16177 LABEL_NUSES (label) = 1;
16178
16179 /* Truncate the result properly for strict SSE math. */
16180 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16181 && !TARGET_MIX_SSE_I387)
16182 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16183 else
16184 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16185
16186 DONE;
16187 })
16188
16189 (define_insn "*sinxf2_i387"
16190 [(set (match_operand:XF 0 "register_operand" "=f")
16191 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16192 "TARGET_USE_FANCY_MATH_387
16193 && flag_unsafe_math_optimizations"
16194 "fsin"
16195 [(set_attr "type" "fpspc")
16196 (set_attr "mode" "XF")])
16197
16198 (define_insn "*sin_extend<mode>xf2_i387"
16199 [(set (match_operand:XF 0 "register_operand" "=f")
16200 (unspec:XF [(float_extend:XF
16201 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16202 UNSPEC_SIN))]
16203 "TARGET_USE_FANCY_MATH_387
16204 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16205 || TARGET_MIX_SSE_I387)
16206 && flag_unsafe_math_optimizations"
16207 "fsin"
16208 [(set_attr "type" "fpspc")
16209 (set_attr "mode" "XF")])
16210
16211 (define_insn "*cosxf2_i387"
16212 [(set (match_operand:XF 0 "register_operand" "=f")
16213 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16214 "TARGET_USE_FANCY_MATH_387
16215 && flag_unsafe_math_optimizations"
16216 "fcos"
16217 [(set_attr "type" "fpspc")
16218 (set_attr "mode" "XF")])
16219
16220 (define_insn "*cos_extend<mode>xf2_i387"
16221 [(set (match_operand:XF 0 "register_operand" "=f")
16222 (unspec:XF [(float_extend:XF
16223 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16224 UNSPEC_COS))]
16225 "TARGET_USE_FANCY_MATH_387
16226 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16227 || TARGET_MIX_SSE_I387)
16228 && flag_unsafe_math_optimizations"
16229 "fcos"
16230 [(set_attr "type" "fpspc")
16231 (set_attr "mode" "XF")])
16232
16233 ;; When sincos pattern is defined, sin and cos builtin functions will be
16234 ;; expanded to sincos pattern with one of its outputs left unused.
16235 ;; CSE pass will figure out if two sincos patterns can be combined,
16236 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16237 ;; depending on the unused output.
16238
16239 (define_insn "sincosxf3"
16240 [(set (match_operand:XF 0 "register_operand" "=f")
16241 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16242 UNSPEC_SINCOS_COS))
16243 (set (match_operand:XF 1 "register_operand" "=u")
16244 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16245 "TARGET_USE_FANCY_MATH_387
16246 && flag_unsafe_math_optimizations"
16247 "fsincos"
16248 [(set_attr "type" "fpspc")
16249 (set_attr "mode" "XF")])
16250
16251 (define_split
16252 [(set (match_operand:XF 0 "register_operand" "")
16253 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16254 UNSPEC_SINCOS_COS))
16255 (set (match_operand:XF 1 "register_operand" "")
16256 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16257 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16258 && !reload_completed && !reload_in_progress"
16259 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16260 "")
16261
16262 (define_split
16263 [(set (match_operand:XF 0 "register_operand" "")
16264 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16265 UNSPEC_SINCOS_COS))
16266 (set (match_operand:XF 1 "register_operand" "")
16267 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16268 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16269 && !reload_completed && !reload_in_progress"
16270 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16271 "")
16272
16273 (define_insn "sincos_extend<mode>xf3_i387"
16274 [(set (match_operand:XF 0 "register_operand" "=f")
16275 (unspec:XF [(float_extend:XF
16276 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16277 UNSPEC_SINCOS_COS))
16278 (set (match_operand:XF 1 "register_operand" "=u")
16279 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16280 "TARGET_USE_FANCY_MATH_387
16281 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16282 || TARGET_MIX_SSE_I387)
16283 && flag_unsafe_math_optimizations"
16284 "fsincos"
16285 [(set_attr "type" "fpspc")
16286 (set_attr "mode" "XF")])
16287
16288 (define_split
16289 [(set (match_operand:XF 0 "register_operand" "")
16290 (unspec:XF [(float_extend:XF
16291 (match_operand:X87MODEF12 2 "register_operand" ""))]
16292 UNSPEC_SINCOS_COS))
16293 (set (match_operand:XF 1 "register_operand" "")
16294 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16295 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16296 && !reload_completed && !reload_in_progress"
16297 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16298 "")
16299
16300 (define_split
16301 [(set (match_operand:XF 0 "register_operand" "")
16302 (unspec:XF [(float_extend:XF
16303 (match_operand:X87MODEF12 2 "register_operand" ""))]
16304 UNSPEC_SINCOS_COS))
16305 (set (match_operand:XF 1 "register_operand" "")
16306 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16307 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16308 && !reload_completed && !reload_in_progress"
16309 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16310 "")
16311
16312 (define_expand "sincos<mode>3"
16313 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16314 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16315 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16316 "TARGET_USE_FANCY_MATH_387
16317 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16318 || TARGET_MIX_SSE_I387)
16319 && flag_unsafe_math_optimizations"
16320 {
16321 rtx op0 = gen_reg_rtx (XFmode);
16322 rtx op1 = gen_reg_rtx (XFmode);
16323
16324 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16325 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16326 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16327 DONE;
16328 })
16329
16330 (define_insn "fptanxf4_i387"
16331 [(set (match_operand:XF 0 "register_operand" "=f")
16332 (match_operand:XF 3 "const_double_operand" "F"))
16333 (set (match_operand:XF 1 "register_operand" "=u")
16334 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16335 UNSPEC_TAN))]
16336 "TARGET_USE_FANCY_MATH_387
16337 && flag_unsafe_math_optimizations
16338 && standard_80387_constant_p (operands[3]) == 2"
16339 "fptan"
16340 [(set_attr "type" "fpspc")
16341 (set_attr "mode" "XF")])
16342
16343 (define_insn "fptan_extend<mode>xf4_i387"
16344 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16345 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16346 (set (match_operand:XF 1 "register_operand" "=u")
16347 (unspec:XF [(float_extend:XF
16348 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16349 UNSPEC_TAN))]
16350 "TARGET_USE_FANCY_MATH_387
16351 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16352 || TARGET_MIX_SSE_I387)
16353 && flag_unsafe_math_optimizations
16354 && standard_80387_constant_p (operands[3]) == 2"
16355 "fptan"
16356 [(set_attr "type" "fpspc")
16357 (set_attr "mode" "XF")])
16358
16359 (define_expand "tanxf2"
16360 [(use (match_operand:XF 0 "register_operand" ""))
16361 (use (match_operand:XF 1 "register_operand" ""))]
16362 "TARGET_USE_FANCY_MATH_387
16363 && flag_unsafe_math_optimizations"
16364 {
16365 rtx one = gen_reg_rtx (XFmode);
16366 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16367
16368 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16369 DONE;
16370 })
16371
16372 (define_expand "tan<mode>2"
16373 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16374 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16375 "TARGET_USE_FANCY_MATH_387
16376 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16377 || TARGET_MIX_SSE_I387)
16378 && flag_unsafe_math_optimizations"
16379 {
16380 rtx op0 = gen_reg_rtx (XFmode);
16381
16382 rtx one = gen_reg_rtx (<MODE>mode);
16383 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16384
16385 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16386 operands[1], op2));
16387 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16388 DONE;
16389 })
16390
16391 (define_insn "*fpatanxf3_i387"
16392 [(set (match_operand:XF 0 "register_operand" "=f")
16393 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16394 (match_operand:XF 2 "register_operand" "u")]
16395 UNSPEC_FPATAN))
16396 (clobber (match_scratch:XF 3 "=2"))]
16397 "TARGET_USE_FANCY_MATH_387
16398 && flag_unsafe_math_optimizations"
16399 "fpatan"
16400 [(set_attr "type" "fpspc")
16401 (set_attr "mode" "XF")])
16402
16403 (define_insn "fpatan_extend<mode>xf3_i387"
16404 [(set (match_operand:XF 0 "register_operand" "=f")
16405 (unspec:XF [(float_extend:XF
16406 (match_operand:X87MODEF12 1 "register_operand" "0"))
16407 (float_extend:XF
16408 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16409 UNSPEC_FPATAN))
16410 (clobber (match_scratch:XF 3 "=2"))]
16411 "TARGET_USE_FANCY_MATH_387
16412 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16413 || TARGET_MIX_SSE_I387)
16414 && flag_unsafe_math_optimizations"
16415 "fpatan"
16416 [(set_attr "type" "fpspc")
16417 (set_attr "mode" "XF")])
16418
16419 (define_expand "atan2xf3"
16420 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16421 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16422 (match_operand:XF 1 "register_operand" "")]
16423 UNSPEC_FPATAN))
16424 (clobber (match_scratch:XF 3 ""))])]
16425 "TARGET_USE_FANCY_MATH_387
16426 && flag_unsafe_math_optimizations"
16427 "")
16428
16429 (define_expand "atan2<mode>3"
16430 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16431 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16432 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16433 "TARGET_USE_FANCY_MATH_387
16434 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16435 || TARGET_MIX_SSE_I387)
16436 && flag_unsafe_math_optimizations"
16437 {
16438 rtx op0 = gen_reg_rtx (XFmode);
16439
16440 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16441 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16442 DONE;
16443 })
16444
16445 (define_expand "atanxf2"
16446 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16447 (unspec:XF [(match_dup 2)
16448 (match_operand:XF 1 "register_operand" "")]
16449 UNSPEC_FPATAN))
16450 (clobber (match_scratch:XF 3 ""))])]
16451 "TARGET_USE_FANCY_MATH_387
16452 && flag_unsafe_math_optimizations"
16453 {
16454 operands[2] = gen_reg_rtx (XFmode);
16455 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16456 })
16457
16458 (define_expand "atan<mode>2"
16459 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16460 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16461 "TARGET_USE_FANCY_MATH_387
16462 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16463 || TARGET_MIX_SSE_I387)
16464 && flag_unsafe_math_optimizations"
16465 {
16466 rtx op0 = gen_reg_rtx (XFmode);
16467
16468 rtx op2 = gen_reg_rtx (<MODE>mode);
16469 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16470
16471 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16472 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16473 DONE;
16474 })
16475
16476 (define_expand "asinxf2"
16477 [(set (match_dup 2)
16478 (mult:XF (match_operand:XF 1 "register_operand" "")
16479 (match_dup 1)))
16480 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16481 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16482 (parallel [(set (match_operand:XF 0 "register_operand" "")
16483 (unspec:XF [(match_dup 5) (match_dup 1)]
16484 UNSPEC_FPATAN))
16485 (clobber (match_scratch:XF 6 ""))])]
16486 "TARGET_USE_FANCY_MATH_387
16487 && flag_unsafe_math_optimizations && !optimize_size"
16488 {
16489 int i;
16490
16491 for (i = 2; i < 6; i++)
16492 operands[i] = gen_reg_rtx (XFmode);
16493
16494 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16495 })
16496
16497 (define_expand "asin<mode>2"
16498 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16499 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16500 "TARGET_USE_FANCY_MATH_387
16501 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16502 || TARGET_MIX_SSE_I387)
16503 && flag_unsafe_math_optimizations && !optimize_size"
16504 {
16505 rtx op0 = gen_reg_rtx (XFmode);
16506 rtx op1 = gen_reg_rtx (XFmode);
16507
16508 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16509 emit_insn (gen_asinxf2 (op0, op1));
16510 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16511 DONE;
16512 })
16513
16514 (define_expand "acosxf2"
16515 [(set (match_dup 2)
16516 (mult:XF (match_operand:XF 1 "register_operand" "")
16517 (match_dup 1)))
16518 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16519 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16520 (parallel [(set (match_operand:XF 0 "register_operand" "")
16521 (unspec:XF [(match_dup 1) (match_dup 5)]
16522 UNSPEC_FPATAN))
16523 (clobber (match_scratch:XF 6 ""))])]
16524 "TARGET_USE_FANCY_MATH_387
16525 && flag_unsafe_math_optimizations && !optimize_size"
16526 {
16527 int i;
16528
16529 for (i = 2; i < 6; i++)
16530 operands[i] = gen_reg_rtx (XFmode);
16531
16532 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16533 })
16534
16535 (define_expand "acos<mode>2"
16536 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16537 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16538 "TARGET_USE_FANCY_MATH_387
16539 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16540 || TARGET_MIX_SSE_I387)
16541 && flag_unsafe_math_optimizations && !optimize_size"
16542 {
16543 rtx op0 = gen_reg_rtx (XFmode);
16544 rtx op1 = gen_reg_rtx (XFmode);
16545
16546 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16547 emit_insn (gen_acosxf2 (op0, op1));
16548 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16549 DONE;
16550 })
16551
16552 (define_insn "fyl2xxf3_i387"
16553 [(set (match_operand:XF 0 "register_operand" "=f")
16554 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16555 (match_operand:XF 2 "register_operand" "u")]
16556 UNSPEC_FYL2X))
16557 (clobber (match_scratch:XF 3 "=2"))]
16558 "TARGET_USE_FANCY_MATH_387
16559 && flag_unsafe_math_optimizations"
16560 "fyl2x"
16561 [(set_attr "type" "fpspc")
16562 (set_attr "mode" "XF")])
16563
16564 (define_insn "fyl2x_extend<mode>xf3_i387"
16565 [(set (match_operand:XF 0 "register_operand" "=f")
16566 (unspec:XF [(float_extend:XF
16567 (match_operand:X87MODEF12 1 "register_operand" "0"))
16568 (match_operand:XF 2 "register_operand" "u")]
16569 UNSPEC_FYL2X))
16570 (clobber (match_scratch:XF 3 "=2"))]
16571 "TARGET_USE_FANCY_MATH_387
16572 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16573 || TARGET_MIX_SSE_I387)
16574 && flag_unsafe_math_optimizations"
16575 "fyl2x"
16576 [(set_attr "type" "fpspc")
16577 (set_attr "mode" "XF")])
16578
16579 (define_expand "logxf2"
16580 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16581 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16582 (match_dup 2)] UNSPEC_FYL2X))
16583 (clobber (match_scratch:XF 3 ""))])]
16584 "TARGET_USE_FANCY_MATH_387
16585 && flag_unsafe_math_optimizations"
16586 {
16587 operands[2] = gen_reg_rtx (XFmode);
16588 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16589 })
16590
16591 (define_expand "log<mode>2"
16592 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16593 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16594 "TARGET_USE_FANCY_MATH_387
16595 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16596 || TARGET_MIX_SSE_I387)
16597 && flag_unsafe_math_optimizations"
16598 {
16599 rtx op0 = gen_reg_rtx (XFmode);
16600
16601 rtx op2 = gen_reg_rtx (XFmode);
16602 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16603
16604 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16605 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16606 DONE;
16607 })
16608
16609 (define_expand "log10xf2"
16610 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16611 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16612 (match_dup 2)] UNSPEC_FYL2X))
16613 (clobber (match_scratch:XF 3 ""))])]
16614 "TARGET_USE_FANCY_MATH_387
16615 && flag_unsafe_math_optimizations"
16616 {
16617 operands[2] = gen_reg_rtx (XFmode);
16618 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16619 })
16620
16621 (define_expand "log10<mode>2"
16622 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16623 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16624 "TARGET_USE_FANCY_MATH_387
16625 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16626 || TARGET_MIX_SSE_I387)
16627 && flag_unsafe_math_optimizations"
16628 {
16629 rtx op0 = gen_reg_rtx (XFmode);
16630
16631 rtx op2 = gen_reg_rtx (XFmode);
16632 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16633
16634 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16635 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16636 DONE;
16637 })
16638
16639 (define_expand "log2xf2"
16640 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16641 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16642 (match_dup 2)] UNSPEC_FYL2X))
16643 (clobber (match_scratch:XF 3 ""))])]
16644 "TARGET_USE_FANCY_MATH_387
16645 && flag_unsafe_math_optimizations"
16646 {
16647 operands[2] = gen_reg_rtx (XFmode);
16648 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16649 })
16650
16651 (define_expand "log2<mode>2"
16652 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16653 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16654 "TARGET_USE_FANCY_MATH_387
16655 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16656 || TARGET_MIX_SSE_I387)
16657 && flag_unsafe_math_optimizations"
16658 {
16659 rtx op0 = gen_reg_rtx (XFmode);
16660
16661 rtx op2 = gen_reg_rtx (XFmode);
16662 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16663
16664 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16665 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16666 DONE;
16667 })
16668
16669 (define_insn "fyl2xp1xf3_i387"
16670 [(set (match_operand:XF 0 "register_operand" "=f")
16671 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16672 (match_operand:XF 2 "register_operand" "u")]
16673 UNSPEC_FYL2XP1))
16674 (clobber (match_scratch:XF 3 "=2"))]
16675 "TARGET_USE_FANCY_MATH_387
16676 && flag_unsafe_math_optimizations"
16677 "fyl2xp1"
16678 [(set_attr "type" "fpspc")
16679 (set_attr "mode" "XF")])
16680
16681 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16682 [(set (match_operand:XF 0 "register_operand" "=f")
16683 (unspec:XF [(float_extend:XF
16684 (match_operand:X87MODEF12 1 "register_operand" "0"))
16685 (match_operand:XF 2 "register_operand" "u")]
16686 UNSPEC_FYL2XP1))
16687 (clobber (match_scratch:XF 3 "=2"))]
16688 "TARGET_USE_FANCY_MATH_387
16689 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16690 || TARGET_MIX_SSE_I387)
16691 && flag_unsafe_math_optimizations"
16692 "fyl2xp1"
16693 [(set_attr "type" "fpspc")
16694 (set_attr "mode" "XF")])
16695
16696 (define_expand "log1pxf2"
16697 [(use (match_operand:XF 0 "register_operand" ""))
16698 (use (match_operand:XF 1 "register_operand" ""))]
16699 "TARGET_USE_FANCY_MATH_387
16700 && flag_unsafe_math_optimizations && !optimize_size"
16701 {
16702 ix86_emit_i387_log1p (operands[0], operands[1]);
16703 DONE;
16704 })
16705
16706 (define_expand "log1p<mode>2"
16707 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16708 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16709 "TARGET_USE_FANCY_MATH_387
16710 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16711 || TARGET_MIX_SSE_I387)
16712 && flag_unsafe_math_optimizations && !optimize_size"
16713 {
16714 rtx op0 = gen_reg_rtx (XFmode);
16715
16716 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16717
16718 ix86_emit_i387_log1p (op0, operands[1]);
16719 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16720 DONE;
16721 })
16722
16723 (define_insn "fxtractxf3_i387"
16724 [(set (match_operand:XF 0 "register_operand" "=f")
16725 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16726 UNSPEC_XTRACT_FRACT))
16727 (set (match_operand:XF 1 "register_operand" "=u")
16728 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16729 "TARGET_USE_FANCY_MATH_387
16730 && flag_unsafe_math_optimizations"
16731 "fxtract"
16732 [(set_attr "type" "fpspc")
16733 (set_attr "mode" "XF")])
16734
16735 (define_insn "fxtract_extend<mode>xf3_i387"
16736 [(set (match_operand:XF 0 "register_operand" "=f")
16737 (unspec:XF [(float_extend:XF
16738 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16739 UNSPEC_XTRACT_FRACT))
16740 (set (match_operand:XF 1 "register_operand" "=u")
16741 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16742 "TARGET_USE_FANCY_MATH_387
16743 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16744 || TARGET_MIX_SSE_I387)
16745 && flag_unsafe_math_optimizations"
16746 "fxtract"
16747 [(set_attr "type" "fpspc")
16748 (set_attr "mode" "XF")])
16749
16750 (define_expand "logbxf2"
16751 [(parallel [(set (match_dup 2)
16752 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16753 UNSPEC_XTRACT_FRACT))
16754 (set (match_operand:XF 0 "register_operand" "")
16755 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16756 "TARGET_USE_FANCY_MATH_387
16757 && flag_unsafe_math_optimizations"
16758 {
16759 operands[2] = gen_reg_rtx (XFmode);
16760 })
16761
16762 (define_expand "logb<mode>2"
16763 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16764 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16765 "TARGET_USE_FANCY_MATH_387
16766 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16767 || TARGET_MIX_SSE_I387)
16768 && flag_unsafe_math_optimizations"
16769 {
16770 rtx op0 = gen_reg_rtx (XFmode);
16771 rtx op1 = gen_reg_rtx (XFmode);
16772
16773 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16774 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16775 DONE;
16776 })
16777
16778 (define_expand "ilogbxf2"
16779 [(use (match_operand:SI 0 "register_operand" ""))
16780 (use (match_operand:XF 1 "register_operand" ""))]
16781 "TARGET_USE_FANCY_MATH_387
16782 && flag_unsafe_math_optimizations && !optimize_size"
16783 {
16784 rtx op0 = gen_reg_rtx (XFmode);
16785 rtx op1 = gen_reg_rtx (XFmode);
16786
16787 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16788 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16789 DONE;
16790 })
16791
16792 (define_expand "ilogb<mode>2"
16793 [(use (match_operand:SI 0 "register_operand" ""))
16794 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16795 "TARGET_USE_FANCY_MATH_387
16796 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16797 || TARGET_MIX_SSE_I387)
16798 && flag_unsafe_math_optimizations && !optimize_size"
16799 {
16800 rtx op0 = gen_reg_rtx (XFmode);
16801 rtx op1 = gen_reg_rtx (XFmode);
16802
16803 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16804 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16805 DONE;
16806 })
16807
16808 (define_insn "*f2xm1xf2_i387"
16809 [(set (match_operand:XF 0 "register_operand" "=f")
16810 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16811 UNSPEC_F2XM1))]
16812 "TARGET_USE_FANCY_MATH_387
16813 && flag_unsafe_math_optimizations"
16814 "f2xm1"
16815 [(set_attr "type" "fpspc")
16816 (set_attr "mode" "XF")])
16817
16818 (define_insn "*fscalexf4_i387"
16819 [(set (match_operand:XF 0 "register_operand" "=f")
16820 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16821 (match_operand:XF 3 "register_operand" "1")]
16822 UNSPEC_FSCALE_FRACT))
16823 (set (match_operand:XF 1 "register_operand" "=u")
16824 (unspec:XF [(match_dup 2) (match_dup 3)]
16825 UNSPEC_FSCALE_EXP))]
16826 "TARGET_USE_FANCY_MATH_387
16827 && flag_unsafe_math_optimizations"
16828 "fscale"
16829 [(set_attr "type" "fpspc")
16830 (set_attr "mode" "XF")])
16831
16832 (define_expand "expNcorexf3"
16833 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16834 (match_operand:XF 2 "register_operand" "")))
16835 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16836 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16837 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16838 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16839 (parallel [(set (match_operand:XF 0 "register_operand" "")
16840 (unspec:XF [(match_dup 8) (match_dup 4)]
16841 UNSPEC_FSCALE_FRACT))
16842 (set (match_dup 9)
16843 (unspec:XF [(match_dup 8) (match_dup 4)]
16844 UNSPEC_FSCALE_EXP))])]
16845 "TARGET_USE_FANCY_MATH_387
16846 && flag_unsafe_math_optimizations && !optimize_size"
16847 {
16848 int i;
16849
16850 for (i = 3; i < 10; i++)
16851 operands[i] = gen_reg_rtx (XFmode);
16852
16853 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16854 })
16855
16856 (define_expand "expxf2"
16857 [(use (match_operand:XF 0 "register_operand" ""))
16858 (use (match_operand:XF 1 "register_operand" ""))]
16859 "TARGET_USE_FANCY_MATH_387
16860 && flag_unsafe_math_optimizations && !optimize_size"
16861 {
16862 rtx op2 = gen_reg_rtx (XFmode);
16863 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16864
16865 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16866 DONE;
16867 })
16868
16869 (define_expand "exp<mode>2"
16870 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16871 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16872 "TARGET_USE_FANCY_MATH_387
16873 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16874 || TARGET_MIX_SSE_I387)
16875 && flag_unsafe_math_optimizations && !optimize_size"
16876 {
16877 rtx op0 = gen_reg_rtx (XFmode);
16878 rtx op1 = gen_reg_rtx (XFmode);
16879
16880 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16881 emit_insn (gen_expxf2 (op0, op1));
16882 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16883 DONE;
16884 })
16885
16886 (define_expand "exp10xf2"
16887 [(use (match_operand:XF 0 "register_operand" ""))
16888 (use (match_operand:XF 1 "register_operand" ""))]
16889 "TARGET_USE_FANCY_MATH_387
16890 && flag_unsafe_math_optimizations && !optimize_size"
16891 {
16892 rtx op2 = gen_reg_rtx (XFmode);
16893 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16894
16895 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16896 DONE;
16897 })
16898
16899 (define_expand "exp10<mode>2"
16900 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16901 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16902 "TARGET_USE_FANCY_MATH_387
16903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16904 || TARGET_MIX_SSE_I387)
16905 && flag_unsafe_math_optimizations && !optimize_size"
16906 {
16907 rtx op0 = gen_reg_rtx (XFmode);
16908 rtx op1 = gen_reg_rtx (XFmode);
16909
16910 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16911 emit_insn (gen_exp10xf2 (op0, op1));
16912 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16913 DONE;
16914 })
16915
16916 (define_expand "exp2xf2"
16917 [(use (match_operand:XF 0 "register_operand" ""))
16918 (use (match_operand:XF 1 "register_operand" ""))]
16919 "TARGET_USE_FANCY_MATH_387
16920 && flag_unsafe_math_optimizations && !optimize_size"
16921 {
16922 rtx op2 = gen_reg_rtx (XFmode);
16923 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16924
16925 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16926 DONE;
16927 })
16928
16929 (define_expand "exp2<mode>2"
16930 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16931 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16932 "TARGET_USE_FANCY_MATH_387
16933 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16934 || TARGET_MIX_SSE_I387)
16935 && flag_unsafe_math_optimizations && !optimize_size"
16936 {
16937 rtx op0 = gen_reg_rtx (XFmode);
16938 rtx op1 = gen_reg_rtx (XFmode);
16939
16940 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16941 emit_insn (gen_exp2xf2 (op0, op1));
16942 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16943 DONE;
16944 })
16945
16946 (define_expand "expm1xf2"
16947 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16948 (match_dup 2)))
16949 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16950 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16951 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16952 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16953 (parallel [(set (match_dup 7)
16954 (unspec:XF [(match_dup 6) (match_dup 4)]
16955 UNSPEC_FSCALE_FRACT))
16956 (set (match_dup 8)
16957 (unspec:XF [(match_dup 6) (match_dup 4)]
16958 UNSPEC_FSCALE_EXP))])
16959 (parallel [(set (match_dup 10)
16960 (unspec:XF [(match_dup 9) (match_dup 8)]
16961 UNSPEC_FSCALE_FRACT))
16962 (set (match_dup 11)
16963 (unspec:XF [(match_dup 9) (match_dup 8)]
16964 UNSPEC_FSCALE_EXP))])
16965 (set (match_dup 12) (minus:XF (match_dup 10)
16966 (float_extend:XF (match_dup 13))))
16967 (set (match_operand:XF 0 "register_operand" "")
16968 (plus:XF (match_dup 12) (match_dup 7)))]
16969 "TARGET_USE_FANCY_MATH_387
16970 && flag_unsafe_math_optimizations && !optimize_size"
16971 {
16972 int i;
16973
16974 for (i = 2; i < 13; i++)
16975 operands[i] = gen_reg_rtx (XFmode);
16976
16977 operands[13]
16978 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16979
16980 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16981 })
16982
16983 (define_expand "expm1<mode>2"
16984 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16985 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16986 "TARGET_USE_FANCY_MATH_387
16987 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16988 || TARGET_MIX_SSE_I387)
16989 && flag_unsafe_math_optimizations && !optimize_size"
16990 {
16991 rtx op0 = gen_reg_rtx (XFmode);
16992 rtx op1 = gen_reg_rtx (XFmode);
16993
16994 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16995 emit_insn (gen_expm1xf2 (op0, op1));
16996 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16997 DONE;
16998 })
16999
17000 (define_expand "ldexpxf3"
17001 [(set (match_dup 3)
17002 (float:XF (match_operand:SI 2 "register_operand" "")))
17003 (parallel [(set (match_operand:XF 0 " register_operand" "")
17004 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17005 (match_dup 3)]
17006 UNSPEC_FSCALE_FRACT))
17007 (set (match_dup 4)
17008 (unspec:XF [(match_dup 1) (match_dup 3)]
17009 UNSPEC_FSCALE_EXP))])]
17010 "TARGET_USE_FANCY_MATH_387
17011 && flag_unsafe_math_optimizations && !optimize_size"
17012 {
17013 operands[3] = gen_reg_rtx (XFmode);
17014 operands[4] = gen_reg_rtx (XFmode);
17015 })
17016
17017 (define_expand "ldexp<mode>3"
17018 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17019 (use (match_operand:X87MODEF12 1 "general_operand" ""))
17020 (use (match_operand:SI 2 "register_operand" ""))]
17021 "TARGET_USE_FANCY_MATH_387
17022 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17023 || TARGET_MIX_SSE_I387)
17024 && flag_unsafe_math_optimizations && !optimize_size"
17025 {
17026 rtx op0 = gen_reg_rtx (XFmode);
17027 rtx op1 = gen_reg_rtx (XFmode);
17028
17029 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17030 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17031 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17032 DONE;
17033 })
17034
17035 (define_expand "scalbxf3"
17036 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17037 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17038 (match_operand:XF 2 "register_operand" "")]
17039 UNSPEC_FSCALE_FRACT))
17040 (set (match_dup 3)
17041 (unspec:XF [(match_dup 1) (match_dup 2)]
17042 UNSPEC_FSCALE_EXP))])]
17043 "TARGET_USE_FANCY_MATH_387
17044 && flag_unsafe_math_optimizations && !optimize_size"
17045 {
17046 operands[3] = gen_reg_rtx (XFmode);
17047 })
17048
17049 (define_expand "scalb<mode>3"
17050 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17051 (use (match_operand:X87MODEF12 1 "general_operand" ""))
17052 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
17053 "TARGET_USE_FANCY_MATH_387
17054 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17055 || TARGET_MIX_SSE_I387)
17056 && flag_unsafe_math_optimizations && !optimize_size"
17057 {
17058 rtx op0 = gen_reg_rtx (XFmode);
17059 rtx op1 = gen_reg_rtx (XFmode);
17060 rtx op2 = gen_reg_rtx (XFmode);
17061
17062 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17063 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17064 emit_insn (gen_scalbxf3 (op0, op1, op2));
17065 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17066 DONE;
17067 })
17068 \f
17069
17070 (define_insn "sse4_1_round<mode>2"
17071 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
17072 (unspec:SSEMODEF [(match_operand:SSEMODEF 1 "register_operand" "x")
17073 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17074 UNSPEC_ROUND))]
17075 "TARGET_SSE4_1"
17076 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17077 [(set_attr "type" "ssecvt")
17078 (set_attr "prefix_extra" "1")
17079 (set_attr "mode" "<MODE>")])
17080
17081 (define_insn "rintxf2"
17082 [(set (match_operand:XF 0 "register_operand" "=f")
17083 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17084 UNSPEC_FRNDINT))]
17085 "TARGET_USE_FANCY_MATH_387
17086 && flag_unsafe_math_optimizations"
17087 "frndint"
17088 [(set_attr "type" "fpspc")
17089 (set_attr "mode" "XF")])
17090
17091 (define_expand "rint<mode>2"
17092 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17093 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17094 "(TARGET_USE_FANCY_MATH_387
17095 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17096 || TARGET_MIX_SSE_I387)
17097 && flag_unsafe_math_optimizations)
17098 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17099 && !flag_trapping_math
17100 && (TARGET_SSE4_1 || !optimize_size))"
17101 {
17102 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17103 && !flag_trapping_math
17104 && (TARGET_SSE4_1 || !optimize_size))
17105 {
17106 if (TARGET_SSE4_1)
17107 emit_insn (gen_sse4_1_round<mode>2
17108 (operands[0], operands[1], GEN_INT (0x04)));
17109 else
17110 ix86_expand_rint (operand0, operand1);
17111 }
17112 else
17113 {
17114 rtx op0 = gen_reg_rtx (XFmode);
17115 rtx op1 = gen_reg_rtx (XFmode);
17116
17117 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17118 emit_insn (gen_rintxf2 (op0, op1));
17119
17120 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17121 }
17122 DONE;
17123 })
17124
17125 (define_expand "round<mode>2"
17126 [(match_operand:SSEMODEF 0 "register_operand" "")
17127 (match_operand:SSEMODEF 1 "nonimmediate_operand" "")]
17128 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17129 && !flag_trapping_math && !flag_rounding_math
17130 && !optimize_size"
17131 {
17132 if (TARGET_64BIT || (<MODE>mode != DFmode))
17133 ix86_expand_round (operand0, operand1);
17134 else
17135 ix86_expand_rounddf_32 (operand0, operand1);
17136 DONE;
17137 })
17138
17139 (define_insn_and_split "*fistdi2_1"
17140 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17141 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17142 UNSPEC_FIST))]
17143 "TARGET_USE_FANCY_MATH_387
17144 && !(reload_completed || reload_in_progress)"
17145 "#"
17146 "&& 1"
17147 [(const_int 0)]
17148 {
17149 if (memory_operand (operands[0], VOIDmode))
17150 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17151 else
17152 {
17153 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17154 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17155 operands[2]));
17156 }
17157 DONE;
17158 }
17159 [(set_attr "type" "fpspc")
17160 (set_attr "mode" "DI")])
17161
17162 (define_insn "fistdi2"
17163 [(set (match_operand:DI 0 "memory_operand" "=m")
17164 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17165 UNSPEC_FIST))
17166 (clobber (match_scratch:XF 2 "=&1f"))]
17167 "TARGET_USE_FANCY_MATH_387"
17168 "* return output_fix_trunc (insn, operands, 0);"
17169 [(set_attr "type" "fpspc")
17170 (set_attr "mode" "DI")])
17171
17172 (define_insn "fistdi2_with_temp"
17173 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17174 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17175 UNSPEC_FIST))
17176 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17177 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17178 "TARGET_USE_FANCY_MATH_387"
17179 "#"
17180 [(set_attr "type" "fpspc")
17181 (set_attr "mode" "DI")])
17182
17183 (define_split
17184 [(set (match_operand:DI 0 "register_operand" "")
17185 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17186 UNSPEC_FIST))
17187 (clobber (match_operand:DI 2 "memory_operand" ""))
17188 (clobber (match_scratch 3 ""))]
17189 "reload_completed"
17190 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17191 (clobber (match_dup 3))])
17192 (set (match_dup 0) (match_dup 2))]
17193 "")
17194
17195 (define_split
17196 [(set (match_operand:DI 0 "memory_operand" "")
17197 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17198 UNSPEC_FIST))
17199 (clobber (match_operand:DI 2 "memory_operand" ""))
17200 (clobber (match_scratch 3 ""))]
17201 "reload_completed"
17202 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17203 (clobber (match_dup 3))])]
17204 "")
17205
17206 (define_insn_and_split "*fist<mode>2_1"
17207 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17208 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17209 UNSPEC_FIST))]
17210 "TARGET_USE_FANCY_MATH_387
17211 && !(reload_completed || reload_in_progress)"
17212 "#"
17213 "&& 1"
17214 [(const_int 0)]
17215 {
17216 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17217 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17218 operands[2]));
17219 DONE;
17220 }
17221 [(set_attr "type" "fpspc")
17222 (set_attr "mode" "<MODE>")])
17223
17224 (define_insn "fist<mode>2"
17225 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17226 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17227 UNSPEC_FIST))]
17228 "TARGET_USE_FANCY_MATH_387"
17229 "* return output_fix_trunc (insn, operands, 0);"
17230 [(set_attr "type" "fpspc")
17231 (set_attr "mode" "<MODE>")])
17232
17233 (define_insn "fist<mode>2_with_temp"
17234 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17235 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17236 UNSPEC_FIST))
17237 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17238 "TARGET_USE_FANCY_MATH_387"
17239 "#"
17240 [(set_attr "type" "fpspc")
17241 (set_attr "mode" "<MODE>")])
17242
17243 (define_split
17244 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17245 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17246 UNSPEC_FIST))
17247 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17248 "reload_completed"
17249 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17250 (set (match_dup 0) (match_dup 2))]
17251 "")
17252
17253 (define_split
17254 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17255 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17256 UNSPEC_FIST))
17257 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17258 "reload_completed"
17259 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17260 "")
17261
17262 (define_expand "lrintxf<mode>2"
17263 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17264 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17265 UNSPEC_FIST))]
17266 "TARGET_USE_FANCY_MATH_387"
17267 "")
17268
17269 (define_expand "lrint<SSEMODEF:mode><SSEMODEI24:mode>2"
17270 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17271 (unspec:SSEMODEI24 [(match_operand:SSEMODEF 1 "register_operand" "")]
17272 UNSPEC_FIX_NOTRUNC))]
17273 "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17274 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17275 "")
17276
17277 (define_expand "lround<SSEMODEF:mode><SSEMODEI24:mode>2"
17278 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17279 (match_operand:SSEMODEF 1 "register_operand" "")]
17280 "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17281 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17282 && !flag_trapping_math && !flag_rounding_math
17283 && !optimize_size"
17284 {
17285 ix86_expand_lround (operand0, operand1);
17286 DONE;
17287 })
17288
17289 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17290 (define_insn_and_split "frndintxf2_floor"
17291 [(set (match_operand:XF 0 "register_operand" "=f")
17292 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17293 UNSPEC_FRNDINT_FLOOR))
17294 (clobber (reg:CC FLAGS_REG))]
17295 "TARGET_USE_FANCY_MATH_387
17296 && flag_unsafe_math_optimizations
17297 && !(reload_completed || reload_in_progress)"
17298 "#"
17299 "&& 1"
17300 [(const_int 0)]
17301 {
17302 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17303
17304 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17305 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17306
17307 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17308 operands[2], operands[3]));
17309 DONE;
17310 }
17311 [(set_attr "type" "frndint")
17312 (set_attr "i387_cw" "floor")
17313 (set_attr "mode" "XF")])
17314
17315 (define_insn "frndintxf2_floor_i387"
17316 [(set (match_operand:XF 0 "register_operand" "=f")
17317 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17318 UNSPEC_FRNDINT_FLOOR))
17319 (use (match_operand:HI 2 "memory_operand" "m"))
17320 (use (match_operand:HI 3 "memory_operand" "m"))]
17321 "TARGET_USE_FANCY_MATH_387
17322 && flag_unsafe_math_optimizations"
17323 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17324 [(set_attr "type" "frndint")
17325 (set_attr "i387_cw" "floor")
17326 (set_attr "mode" "XF")])
17327
17328 (define_expand "floorxf2"
17329 [(use (match_operand:XF 0 "register_operand" ""))
17330 (use (match_operand:XF 1 "register_operand" ""))]
17331 "TARGET_USE_FANCY_MATH_387
17332 && flag_unsafe_math_optimizations && !optimize_size"
17333 {
17334 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17335 DONE;
17336 })
17337
17338 (define_expand "floor<mode>2"
17339 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17340 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17341 "(TARGET_USE_FANCY_MATH_387
17342 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17343 || TARGET_MIX_SSE_I387)
17344 && flag_unsafe_math_optimizations && !optimize_size)
17345 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17346 && !flag_trapping_math
17347 && (TARGET_SSE4_1 || !optimize_size))"
17348 {
17349 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17350 && !flag_trapping_math
17351 && (TARGET_SSE4_1 || !optimize_size))
17352 {
17353 if (TARGET_SSE4_1)
17354 emit_insn (gen_sse4_1_round<mode>2
17355 (operands[0], operands[1], GEN_INT (0x01)));
17356 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17357 ix86_expand_floorceil (operand0, operand1, true);
17358 else
17359 ix86_expand_floorceildf_32 (operand0, operand1, true);
17360 }
17361 else
17362 {
17363 rtx op0 = gen_reg_rtx (XFmode);
17364 rtx op1 = gen_reg_rtx (XFmode);
17365
17366 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17367 emit_insn (gen_frndintxf2_floor (op0, op1));
17368
17369 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17370 }
17371 DONE;
17372 })
17373
17374 (define_insn_and_split "*fist<mode>2_floor_1"
17375 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17376 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17377 UNSPEC_FIST_FLOOR))
17378 (clobber (reg:CC FLAGS_REG))]
17379 "TARGET_USE_FANCY_MATH_387
17380 && flag_unsafe_math_optimizations
17381 && !(reload_completed || reload_in_progress)"
17382 "#"
17383 "&& 1"
17384 [(const_int 0)]
17385 {
17386 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17387
17388 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17389 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17390 if (memory_operand (operands[0], VOIDmode))
17391 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17392 operands[2], operands[3]));
17393 else
17394 {
17395 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17396 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17397 operands[2], operands[3],
17398 operands[4]));
17399 }
17400 DONE;
17401 }
17402 [(set_attr "type" "fistp")
17403 (set_attr "i387_cw" "floor")
17404 (set_attr "mode" "<MODE>")])
17405
17406 (define_insn "fistdi2_floor"
17407 [(set (match_operand:DI 0 "memory_operand" "=m")
17408 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17409 UNSPEC_FIST_FLOOR))
17410 (use (match_operand:HI 2 "memory_operand" "m"))
17411 (use (match_operand:HI 3 "memory_operand" "m"))
17412 (clobber (match_scratch:XF 4 "=&1f"))]
17413 "TARGET_USE_FANCY_MATH_387
17414 && flag_unsafe_math_optimizations"
17415 "* return output_fix_trunc (insn, operands, 0);"
17416 [(set_attr "type" "fistp")
17417 (set_attr "i387_cw" "floor")
17418 (set_attr "mode" "DI")])
17419
17420 (define_insn "fistdi2_floor_with_temp"
17421 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17422 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17423 UNSPEC_FIST_FLOOR))
17424 (use (match_operand:HI 2 "memory_operand" "m,m"))
17425 (use (match_operand:HI 3 "memory_operand" "m,m"))
17426 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17427 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17428 "TARGET_USE_FANCY_MATH_387
17429 && flag_unsafe_math_optimizations"
17430 "#"
17431 [(set_attr "type" "fistp")
17432 (set_attr "i387_cw" "floor")
17433 (set_attr "mode" "DI")])
17434
17435 (define_split
17436 [(set (match_operand:DI 0 "register_operand" "")
17437 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17438 UNSPEC_FIST_FLOOR))
17439 (use (match_operand:HI 2 "memory_operand" ""))
17440 (use (match_operand:HI 3 "memory_operand" ""))
17441 (clobber (match_operand:DI 4 "memory_operand" ""))
17442 (clobber (match_scratch 5 ""))]
17443 "reload_completed"
17444 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17445 (use (match_dup 2))
17446 (use (match_dup 3))
17447 (clobber (match_dup 5))])
17448 (set (match_dup 0) (match_dup 4))]
17449 "")
17450
17451 (define_split
17452 [(set (match_operand:DI 0 "memory_operand" "")
17453 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17454 UNSPEC_FIST_FLOOR))
17455 (use (match_operand:HI 2 "memory_operand" ""))
17456 (use (match_operand:HI 3 "memory_operand" ""))
17457 (clobber (match_operand:DI 4 "memory_operand" ""))
17458 (clobber (match_scratch 5 ""))]
17459 "reload_completed"
17460 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17461 (use (match_dup 2))
17462 (use (match_dup 3))
17463 (clobber (match_dup 5))])]
17464 "")
17465
17466 (define_insn "fist<mode>2_floor"
17467 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17468 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17469 UNSPEC_FIST_FLOOR))
17470 (use (match_operand:HI 2 "memory_operand" "m"))
17471 (use (match_operand:HI 3 "memory_operand" "m"))]
17472 "TARGET_USE_FANCY_MATH_387
17473 && flag_unsafe_math_optimizations"
17474 "* return output_fix_trunc (insn, operands, 0);"
17475 [(set_attr "type" "fistp")
17476 (set_attr "i387_cw" "floor")
17477 (set_attr "mode" "<MODE>")])
17478
17479 (define_insn "fist<mode>2_floor_with_temp"
17480 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17481 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17482 UNSPEC_FIST_FLOOR))
17483 (use (match_operand:HI 2 "memory_operand" "m,m"))
17484 (use (match_operand:HI 3 "memory_operand" "m,m"))
17485 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17486 "TARGET_USE_FANCY_MATH_387
17487 && flag_unsafe_math_optimizations"
17488 "#"
17489 [(set_attr "type" "fistp")
17490 (set_attr "i387_cw" "floor")
17491 (set_attr "mode" "<MODE>")])
17492
17493 (define_split
17494 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17495 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17496 UNSPEC_FIST_FLOOR))
17497 (use (match_operand:HI 2 "memory_operand" ""))
17498 (use (match_operand:HI 3 "memory_operand" ""))
17499 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17500 "reload_completed"
17501 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17502 UNSPEC_FIST_FLOOR))
17503 (use (match_dup 2))
17504 (use (match_dup 3))])
17505 (set (match_dup 0) (match_dup 4))]
17506 "")
17507
17508 (define_split
17509 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17510 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17511 UNSPEC_FIST_FLOOR))
17512 (use (match_operand:HI 2 "memory_operand" ""))
17513 (use (match_operand:HI 3 "memory_operand" ""))
17514 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17515 "reload_completed"
17516 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17517 UNSPEC_FIST_FLOOR))
17518 (use (match_dup 2))
17519 (use (match_dup 3))])]
17520 "")
17521
17522 (define_expand "lfloorxf<mode>2"
17523 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17524 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17525 UNSPEC_FIST_FLOOR))
17526 (clobber (reg:CC FLAGS_REG))])]
17527 "TARGET_USE_FANCY_MATH_387
17528 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17529 && flag_unsafe_math_optimizations"
17530 "")
17531
17532 (define_expand "lfloor<mode>di2"
17533 [(match_operand:DI 0 "nonimmediate_operand" "")
17534 (match_operand:SSEMODEF 1 "register_operand" "")]
17535 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17536 && !flag_trapping_math
17537 && !optimize_size"
17538 {
17539 ix86_expand_lfloorceil (operand0, operand1, true);
17540 DONE;
17541 })
17542
17543 (define_expand "lfloor<mode>si2"
17544 [(match_operand:SI 0 "nonimmediate_operand" "")
17545 (match_operand:SSEMODEF 1 "register_operand" "")]
17546 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17547 && !flag_trapping_math
17548 && (!optimize_size || !TARGET_64BIT)"
17549 {
17550 ix86_expand_lfloorceil (operand0, operand1, true);
17551 DONE;
17552 })
17553
17554 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17555 (define_insn_and_split "frndintxf2_ceil"
17556 [(set (match_operand:XF 0 "register_operand" "=f")
17557 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17558 UNSPEC_FRNDINT_CEIL))
17559 (clobber (reg:CC FLAGS_REG))]
17560 "TARGET_USE_FANCY_MATH_387
17561 && flag_unsafe_math_optimizations
17562 && !(reload_completed || reload_in_progress)"
17563 "#"
17564 "&& 1"
17565 [(const_int 0)]
17566 {
17567 ix86_optimize_mode_switching[I387_CEIL] = 1;
17568
17569 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17570 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17571
17572 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17573 operands[2], operands[3]));
17574 DONE;
17575 }
17576 [(set_attr "type" "frndint")
17577 (set_attr "i387_cw" "ceil")
17578 (set_attr "mode" "XF")])
17579
17580 (define_insn "frndintxf2_ceil_i387"
17581 [(set (match_operand:XF 0 "register_operand" "=f")
17582 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17583 UNSPEC_FRNDINT_CEIL))
17584 (use (match_operand:HI 2 "memory_operand" "m"))
17585 (use (match_operand:HI 3 "memory_operand" "m"))]
17586 "TARGET_USE_FANCY_MATH_387
17587 && flag_unsafe_math_optimizations"
17588 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17589 [(set_attr "type" "frndint")
17590 (set_attr "i387_cw" "ceil")
17591 (set_attr "mode" "XF")])
17592
17593 (define_expand "ceilxf2"
17594 [(use (match_operand:XF 0 "register_operand" ""))
17595 (use (match_operand:XF 1 "register_operand" ""))]
17596 "TARGET_USE_FANCY_MATH_387
17597 && flag_unsafe_math_optimizations && !optimize_size"
17598 {
17599 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17600 DONE;
17601 })
17602
17603 (define_expand "ceil<mode>2"
17604 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17605 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17606 "(TARGET_USE_FANCY_MATH_387
17607 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17608 || TARGET_MIX_SSE_I387)
17609 && flag_unsafe_math_optimizations && !optimize_size)
17610 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17611 && !flag_trapping_math
17612 && (TARGET_SSE4_1 || !optimize_size))"
17613 {
17614 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17615 && !flag_trapping_math
17616 && (TARGET_SSE4_1 || !optimize_size))
17617 {
17618 if (TARGET_SSE4_1)
17619 emit_insn (gen_sse4_1_round<mode>2
17620 (operands[0], operands[1], GEN_INT (0x02)));
17621 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17622 ix86_expand_floorceil (operand0, operand1, false);
17623 else
17624 ix86_expand_floorceildf_32 (operand0, operand1, false);
17625 }
17626 else
17627 {
17628 rtx op0 = gen_reg_rtx (XFmode);
17629 rtx op1 = gen_reg_rtx (XFmode);
17630
17631 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17632 emit_insn (gen_frndintxf2_ceil (op0, op1));
17633
17634 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17635 }
17636 DONE;
17637 })
17638
17639 (define_insn_and_split "*fist<mode>2_ceil_1"
17640 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17641 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17642 UNSPEC_FIST_CEIL))
17643 (clobber (reg:CC FLAGS_REG))]
17644 "TARGET_USE_FANCY_MATH_387
17645 && flag_unsafe_math_optimizations
17646 && !(reload_completed || reload_in_progress)"
17647 "#"
17648 "&& 1"
17649 [(const_int 0)]
17650 {
17651 ix86_optimize_mode_switching[I387_CEIL] = 1;
17652
17653 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17654 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17655 if (memory_operand (operands[0], VOIDmode))
17656 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17657 operands[2], operands[3]));
17658 else
17659 {
17660 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17661 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17662 operands[2], operands[3],
17663 operands[4]));
17664 }
17665 DONE;
17666 }
17667 [(set_attr "type" "fistp")
17668 (set_attr "i387_cw" "ceil")
17669 (set_attr "mode" "<MODE>")])
17670
17671 (define_insn "fistdi2_ceil"
17672 [(set (match_operand:DI 0 "memory_operand" "=m")
17673 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17674 UNSPEC_FIST_CEIL))
17675 (use (match_operand:HI 2 "memory_operand" "m"))
17676 (use (match_operand:HI 3 "memory_operand" "m"))
17677 (clobber (match_scratch:XF 4 "=&1f"))]
17678 "TARGET_USE_FANCY_MATH_387
17679 && flag_unsafe_math_optimizations"
17680 "* return output_fix_trunc (insn, operands, 0);"
17681 [(set_attr "type" "fistp")
17682 (set_attr "i387_cw" "ceil")
17683 (set_attr "mode" "DI")])
17684
17685 (define_insn "fistdi2_ceil_with_temp"
17686 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17687 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17688 UNSPEC_FIST_CEIL))
17689 (use (match_operand:HI 2 "memory_operand" "m,m"))
17690 (use (match_operand:HI 3 "memory_operand" "m,m"))
17691 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17692 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17693 "TARGET_USE_FANCY_MATH_387
17694 && flag_unsafe_math_optimizations"
17695 "#"
17696 [(set_attr "type" "fistp")
17697 (set_attr "i387_cw" "ceil")
17698 (set_attr "mode" "DI")])
17699
17700 (define_split
17701 [(set (match_operand:DI 0 "register_operand" "")
17702 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17703 UNSPEC_FIST_CEIL))
17704 (use (match_operand:HI 2 "memory_operand" ""))
17705 (use (match_operand:HI 3 "memory_operand" ""))
17706 (clobber (match_operand:DI 4 "memory_operand" ""))
17707 (clobber (match_scratch 5 ""))]
17708 "reload_completed"
17709 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17710 (use (match_dup 2))
17711 (use (match_dup 3))
17712 (clobber (match_dup 5))])
17713 (set (match_dup 0) (match_dup 4))]
17714 "")
17715
17716 (define_split
17717 [(set (match_operand:DI 0 "memory_operand" "")
17718 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17719 UNSPEC_FIST_CEIL))
17720 (use (match_operand:HI 2 "memory_operand" ""))
17721 (use (match_operand:HI 3 "memory_operand" ""))
17722 (clobber (match_operand:DI 4 "memory_operand" ""))
17723 (clobber (match_scratch 5 ""))]
17724 "reload_completed"
17725 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17726 (use (match_dup 2))
17727 (use (match_dup 3))
17728 (clobber (match_dup 5))])]
17729 "")
17730
17731 (define_insn "fist<mode>2_ceil"
17732 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17733 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17734 UNSPEC_FIST_CEIL))
17735 (use (match_operand:HI 2 "memory_operand" "m"))
17736 (use (match_operand:HI 3 "memory_operand" "m"))]
17737 "TARGET_USE_FANCY_MATH_387
17738 && flag_unsafe_math_optimizations"
17739 "* return output_fix_trunc (insn, operands, 0);"
17740 [(set_attr "type" "fistp")
17741 (set_attr "i387_cw" "ceil")
17742 (set_attr "mode" "<MODE>")])
17743
17744 (define_insn "fist<mode>2_ceil_with_temp"
17745 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17746 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17747 UNSPEC_FIST_CEIL))
17748 (use (match_operand:HI 2 "memory_operand" "m,m"))
17749 (use (match_operand:HI 3 "memory_operand" "m,m"))
17750 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17751 "TARGET_USE_FANCY_MATH_387
17752 && flag_unsafe_math_optimizations"
17753 "#"
17754 [(set_attr "type" "fistp")
17755 (set_attr "i387_cw" "ceil")
17756 (set_attr "mode" "<MODE>")])
17757
17758 (define_split
17759 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17760 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17761 UNSPEC_FIST_CEIL))
17762 (use (match_operand:HI 2 "memory_operand" ""))
17763 (use (match_operand:HI 3 "memory_operand" ""))
17764 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17765 "reload_completed"
17766 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17767 UNSPEC_FIST_CEIL))
17768 (use (match_dup 2))
17769 (use (match_dup 3))])
17770 (set (match_dup 0) (match_dup 4))]
17771 "")
17772
17773 (define_split
17774 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17775 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17776 UNSPEC_FIST_CEIL))
17777 (use (match_operand:HI 2 "memory_operand" ""))
17778 (use (match_operand:HI 3 "memory_operand" ""))
17779 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17780 "reload_completed"
17781 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17782 UNSPEC_FIST_CEIL))
17783 (use (match_dup 2))
17784 (use (match_dup 3))])]
17785 "")
17786
17787 (define_expand "lceilxf<mode>2"
17788 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17789 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17790 UNSPEC_FIST_CEIL))
17791 (clobber (reg:CC FLAGS_REG))])]
17792 "TARGET_USE_FANCY_MATH_387
17793 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17794 && flag_unsafe_math_optimizations"
17795 "")
17796
17797 (define_expand "lceil<mode>di2"
17798 [(match_operand:DI 0 "nonimmediate_operand" "")
17799 (match_operand:SSEMODEF 1 "register_operand" "")]
17800 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17801 && !flag_trapping_math"
17802 {
17803 ix86_expand_lfloorceil (operand0, operand1, false);
17804 DONE;
17805 })
17806
17807 (define_expand "lceil<mode>si2"
17808 [(match_operand:SI 0 "nonimmediate_operand" "")
17809 (match_operand:SSEMODEF 1 "register_operand" "")]
17810 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17811 && !flag_trapping_math"
17812 {
17813 ix86_expand_lfloorceil (operand0, operand1, false);
17814 DONE;
17815 })
17816
17817 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17818 (define_insn_and_split "frndintxf2_trunc"
17819 [(set (match_operand:XF 0 "register_operand" "=f")
17820 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17821 UNSPEC_FRNDINT_TRUNC))
17822 (clobber (reg:CC FLAGS_REG))]
17823 "TARGET_USE_FANCY_MATH_387
17824 && flag_unsafe_math_optimizations
17825 && !(reload_completed || reload_in_progress)"
17826 "#"
17827 "&& 1"
17828 [(const_int 0)]
17829 {
17830 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17831
17832 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17833 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17834
17835 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17836 operands[2], operands[3]));
17837 DONE;
17838 }
17839 [(set_attr "type" "frndint")
17840 (set_attr "i387_cw" "trunc")
17841 (set_attr "mode" "XF")])
17842
17843 (define_insn "frndintxf2_trunc_i387"
17844 [(set (match_operand:XF 0 "register_operand" "=f")
17845 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17846 UNSPEC_FRNDINT_TRUNC))
17847 (use (match_operand:HI 2 "memory_operand" "m"))
17848 (use (match_operand:HI 3 "memory_operand" "m"))]
17849 "TARGET_USE_FANCY_MATH_387
17850 && flag_unsafe_math_optimizations"
17851 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17852 [(set_attr "type" "frndint")
17853 (set_attr "i387_cw" "trunc")
17854 (set_attr "mode" "XF")])
17855
17856 (define_expand "btruncxf2"
17857 [(use (match_operand:XF 0 "register_operand" ""))
17858 (use (match_operand:XF 1 "register_operand" ""))]
17859 "TARGET_USE_FANCY_MATH_387
17860 && flag_unsafe_math_optimizations && !optimize_size"
17861 {
17862 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17863 DONE;
17864 })
17865
17866 (define_expand "btrunc<mode>2"
17867 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17868 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17869 "(TARGET_USE_FANCY_MATH_387
17870 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17871 || TARGET_MIX_SSE_I387)
17872 && flag_unsafe_math_optimizations && !optimize_size)
17873 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17874 && !flag_trapping_math
17875 && (TARGET_SSE4_1 || !optimize_size))"
17876 {
17877 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17878 && !flag_trapping_math
17879 && (TARGET_SSE4_1 || !optimize_size))
17880 {
17881 if (TARGET_SSE4_1)
17882 emit_insn (gen_sse4_1_round<mode>2
17883 (operands[0], operands[1], GEN_INT (0x03)));
17884 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17885 ix86_expand_trunc (operand0, operand1);
17886 else
17887 ix86_expand_truncdf_32 (operand0, operand1);
17888 }
17889 else
17890 {
17891 rtx op0 = gen_reg_rtx (XFmode);
17892 rtx op1 = gen_reg_rtx (XFmode);
17893
17894 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17895 emit_insn (gen_frndintxf2_trunc (op0, op1));
17896
17897 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17898 }
17899 DONE;
17900 })
17901
17902 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17903 (define_insn_and_split "frndintxf2_mask_pm"
17904 [(set (match_operand:XF 0 "register_operand" "=f")
17905 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17906 UNSPEC_FRNDINT_MASK_PM))
17907 (clobber (reg:CC FLAGS_REG))]
17908 "TARGET_USE_FANCY_MATH_387
17909 && flag_unsafe_math_optimizations
17910 && !(reload_completed || reload_in_progress)"
17911 "#"
17912 "&& 1"
17913 [(const_int 0)]
17914 {
17915 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17916
17917 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17918 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17919
17920 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17921 operands[2], operands[3]));
17922 DONE;
17923 }
17924 [(set_attr "type" "frndint")
17925 (set_attr "i387_cw" "mask_pm")
17926 (set_attr "mode" "XF")])
17927
17928 (define_insn "frndintxf2_mask_pm_i387"
17929 [(set (match_operand:XF 0 "register_operand" "=f")
17930 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17931 UNSPEC_FRNDINT_MASK_PM))
17932 (use (match_operand:HI 2 "memory_operand" "m"))
17933 (use (match_operand:HI 3 "memory_operand" "m"))]
17934 "TARGET_USE_FANCY_MATH_387
17935 && flag_unsafe_math_optimizations"
17936 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17937 [(set_attr "type" "frndint")
17938 (set_attr "i387_cw" "mask_pm")
17939 (set_attr "mode" "XF")])
17940
17941 (define_expand "nearbyintxf2"
17942 [(use (match_operand:XF 0 "register_operand" ""))
17943 (use (match_operand:XF 1 "register_operand" ""))]
17944 "TARGET_USE_FANCY_MATH_387
17945 && flag_unsafe_math_optimizations"
17946 {
17947 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17948
17949 DONE;
17950 })
17951
17952 (define_expand "nearbyintdf2"
17953 [(use (match_operand:DF 0 "register_operand" ""))
17954 (use (match_operand:DF 1 "register_operand" ""))]
17955 "TARGET_USE_FANCY_MATH_387
17956 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17957 && flag_unsafe_math_optimizations"
17958 {
17959 rtx op0 = gen_reg_rtx (XFmode);
17960 rtx op1 = gen_reg_rtx (XFmode);
17961
17962 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17963 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17964
17965 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17966 DONE;
17967 })
17968
17969 (define_expand "nearbyintsf2"
17970 [(use (match_operand:SF 0 "register_operand" ""))
17971 (use (match_operand:SF 1 "register_operand" ""))]
17972 "TARGET_USE_FANCY_MATH_387
17973 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17974 && flag_unsafe_math_optimizations"
17975 {
17976 rtx op0 = gen_reg_rtx (XFmode);
17977 rtx op1 = gen_reg_rtx (XFmode);
17978
17979 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17980 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17981
17982 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17983 DONE;
17984 })
17985
17986 (define_insn "fxam<mode>2_i387"
17987 [(set (match_operand:HI 0 "register_operand" "=a")
17988 (unspec:HI
17989 [(match_operand:X87MODEF 1 "register_operand" "f")]
17990 UNSPEC_FXAM))]
17991 "TARGET_USE_FANCY_MATH_387"
17992 "fxam\n\tfnstsw\t%0"
17993 [(set_attr "type" "multi")
17994 (set_attr "unit" "i387")
17995 (set_attr "mode" "<MODE>")])
17996
17997 (define_expand "isinf<mode>2"
17998 [(use (match_operand:SI 0 "register_operand" ""))
17999 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18000 "TARGET_USE_FANCY_MATH_387
18001 && TARGET_C99_FUNCTIONS
18002 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18003 || TARGET_MIX_SSE_I387)"
18004 {
18005 rtx mask = GEN_INT (0x45);
18006 rtx val = GEN_INT (0x05);
18007
18008 rtx cond;
18009
18010 rtx scratch = gen_reg_rtx (HImode);
18011 rtx res = gen_reg_rtx (QImode);
18012
18013 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18014 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18015 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18016 cond = gen_rtx_fmt_ee (EQ, QImode,
18017 gen_rtx_REG (CCmode, FLAGS_REG),
18018 const0_rtx);
18019 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18020 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18021 DONE;
18022 })
18023
18024 \f
18025 ;; Block operation instructions
18026
18027 (define_expand "movmemsi"
18028 [(use (match_operand:BLK 0 "memory_operand" ""))
18029 (use (match_operand:BLK 1 "memory_operand" ""))
18030 (use (match_operand:SI 2 "nonmemory_operand" ""))
18031 (use (match_operand:SI 3 "const_int_operand" ""))
18032 (use (match_operand:SI 4 "const_int_operand" ""))
18033 (use (match_operand:SI 5 "const_int_operand" ""))]
18034 ""
18035 {
18036 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18037 operands[4], operands[5]))
18038 DONE;
18039 else
18040 FAIL;
18041 })
18042
18043 (define_expand "movmemdi"
18044 [(use (match_operand:BLK 0 "memory_operand" ""))
18045 (use (match_operand:BLK 1 "memory_operand" ""))
18046 (use (match_operand:DI 2 "nonmemory_operand" ""))
18047 (use (match_operand:DI 3 "const_int_operand" ""))
18048 (use (match_operand:SI 4 "const_int_operand" ""))
18049 (use (match_operand:SI 5 "const_int_operand" ""))]
18050 "TARGET_64BIT"
18051 {
18052 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18053 operands[4], operands[5]))
18054 DONE;
18055 else
18056 FAIL;
18057 })
18058
18059 ;; Most CPUs don't like single string operations
18060 ;; Handle this case here to simplify previous expander.
18061
18062 (define_expand "strmov"
18063 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18064 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18065 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18066 (clobber (reg:CC FLAGS_REG))])
18067 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18068 (clobber (reg:CC FLAGS_REG))])]
18069 ""
18070 {
18071 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18072
18073 /* If .md ever supports :P for Pmode, these can be directly
18074 in the pattern above. */
18075 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18076 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18077
18078 if (TARGET_SINGLE_STRINGOP || optimize_size)
18079 {
18080 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18081 operands[2], operands[3],
18082 operands[5], operands[6]));
18083 DONE;
18084 }
18085
18086 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18087 })
18088
18089 (define_expand "strmov_singleop"
18090 [(parallel [(set (match_operand 1 "memory_operand" "")
18091 (match_operand 3 "memory_operand" ""))
18092 (set (match_operand 0 "register_operand" "")
18093 (match_operand 4 "" ""))
18094 (set (match_operand 2 "register_operand" "")
18095 (match_operand 5 "" ""))])]
18096 "TARGET_SINGLE_STRINGOP || optimize_size"
18097 "")
18098
18099 (define_insn "*strmovdi_rex_1"
18100 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18101 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18102 (set (match_operand:DI 0 "register_operand" "=D")
18103 (plus:DI (match_dup 2)
18104 (const_int 8)))
18105 (set (match_operand:DI 1 "register_operand" "=S")
18106 (plus:DI (match_dup 3)
18107 (const_int 8)))]
18108 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18109 "movsq"
18110 [(set_attr "type" "str")
18111 (set_attr "mode" "DI")
18112 (set_attr "memory" "both")])
18113
18114 (define_insn "*strmovsi_1"
18115 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18116 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18117 (set (match_operand:SI 0 "register_operand" "=D")
18118 (plus:SI (match_dup 2)
18119 (const_int 4)))
18120 (set (match_operand:SI 1 "register_operand" "=S")
18121 (plus:SI (match_dup 3)
18122 (const_int 4)))]
18123 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18124 "{movsl|movsd}"
18125 [(set_attr "type" "str")
18126 (set_attr "mode" "SI")
18127 (set_attr "memory" "both")])
18128
18129 (define_insn "*strmovsi_rex_1"
18130 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18131 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18132 (set (match_operand:DI 0 "register_operand" "=D")
18133 (plus:DI (match_dup 2)
18134 (const_int 4)))
18135 (set (match_operand:DI 1 "register_operand" "=S")
18136 (plus:DI (match_dup 3)
18137 (const_int 4)))]
18138 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18139 "{movsl|movsd}"
18140 [(set_attr "type" "str")
18141 (set_attr "mode" "SI")
18142 (set_attr "memory" "both")])
18143
18144 (define_insn "*strmovhi_1"
18145 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18146 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18147 (set (match_operand:SI 0 "register_operand" "=D")
18148 (plus:SI (match_dup 2)
18149 (const_int 2)))
18150 (set (match_operand:SI 1 "register_operand" "=S")
18151 (plus:SI (match_dup 3)
18152 (const_int 2)))]
18153 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18154 "movsw"
18155 [(set_attr "type" "str")
18156 (set_attr "memory" "both")
18157 (set_attr "mode" "HI")])
18158
18159 (define_insn "*strmovhi_rex_1"
18160 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18161 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18162 (set (match_operand:DI 0 "register_operand" "=D")
18163 (plus:DI (match_dup 2)
18164 (const_int 2)))
18165 (set (match_operand:DI 1 "register_operand" "=S")
18166 (plus:DI (match_dup 3)
18167 (const_int 2)))]
18168 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18169 "movsw"
18170 [(set_attr "type" "str")
18171 (set_attr "memory" "both")
18172 (set_attr "mode" "HI")])
18173
18174 (define_insn "*strmovqi_1"
18175 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18176 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18177 (set (match_operand:SI 0 "register_operand" "=D")
18178 (plus:SI (match_dup 2)
18179 (const_int 1)))
18180 (set (match_operand:SI 1 "register_operand" "=S")
18181 (plus:SI (match_dup 3)
18182 (const_int 1)))]
18183 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18184 "movsb"
18185 [(set_attr "type" "str")
18186 (set_attr "memory" "both")
18187 (set_attr "mode" "QI")])
18188
18189 (define_insn "*strmovqi_rex_1"
18190 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18191 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18192 (set (match_operand:DI 0 "register_operand" "=D")
18193 (plus:DI (match_dup 2)
18194 (const_int 1)))
18195 (set (match_operand:DI 1 "register_operand" "=S")
18196 (plus:DI (match_dup 3)
18197 (const_int 1)))]
18198 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18199 "movsb"
18200 [(set_attr "type" "str")
18201 (set_attr "memory" "both")
18202 (set_attr "mode" "QI")])
18203
18204 (define_expand "rep_mov"
18205 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18206 (set (match_operand 0 "register_operand" "")
18207 (match_operand 5 "" ""))
18208 (set (match_operand 2 "register_operand" "")
18209 (match_operand 6 "" ""))
18210 (set (match_operand 1 "memory_operand" "")
18211 (match_operand 3 "memory_operand" ""))
18212 (use (match_dup 4))])]
18213 ""
18214 "")
18215
18216 (define_insn "*rep_movdi_rex64"
18217 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18218 (set (match_operand:DI 0 "register_operand" "=D")
18219 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18220 (const_int 3))
18221 (match_operand:DI 3 "register_operand" "0")))
18222 (set (match_operand:DI 1 "register_operand" "=S")
18223 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18224 (match_operand:DI 4 "register_operand" "1")))
18225 (set (mem:BLK (match_dup 3))
18226 (mem:BLK (match_dup 4)))
18227 (use (match_dup 5))]
18228 "TARGET_64BIT"
18229 "{rep\;movsq|rep movsq}"
18230 [(set_attr "type" "str")
18231 (set_attr "prefix_rep" "1")
18232 (set_attr "memory" "both")
18233 (set_attr "mode" "DI")])
18234
18235 (define_insn "*rep_movsi"
18236 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18237 (set (match_operand:SI 0 "register_operand" "=D")
18238 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18239 (const_int 2))
18240 (match_operand:SI 3 "register_operand" "0")))
18241 (set (match_operand:SI 1 "register_operand" "=S")
18242 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18243 (match_operand:SI 4 "register_operand" "1")))
18244 (set (mem:BLK (match_dup 3))
18245 (mem:BLK (match_dup 4)))
18246 (use (match_dup 5))]
18247 "!TARGET_64BIT"
18248 "{rep\;movsl|rep movsd}"
18249 [(set_attr "type" "str")
18250 (set_attr "prefix_rep" "1")
18251 (set_attr "memory" "both")
18252 (set_attr "mode" "SI")])
18253
18254 (define_insn "*rep_movsi_rex64"
18255 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18256 (set (match_operand:DI 0 "register_operand" "=D")
18257 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18258 (const_int 2))
18259 (match_operand:DI 3 "register_operand" "0")))
18260 (set (match_operand:DI 1 "register_operand" "=S")
18261 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18262 (match_operand:DI 4 "register_operand" "1")))
18263 (set (mem:BLK (match_dup 3))
18264 (mem:BLK (match_dup 4)))
18265 (use (match_dup 5))]
18266 "TARGET_64BIT"
18267 "{rep\;movsl|rep movsd}"
18268 [(set_attr "type" "str")
18269 (set_attr "prefix_rep" "1")
18270 (set_attr "memory" "both")
18271 (set_attr "mode" "SI")])
18272
18273 (define_insn "*rep_movqi"
18274 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18275 (set (match_operand:SI 0 "register_operand" "=D")
18276 (plus:SI (match_operand:SI 3 "register_operand" "0")
18277 (match_operand:SI 5 "register_operand" "2")))
18278 (set (match_operand:SI 1 "register_operand" "=S")
18279 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18280 (set (mem:BLK (match_dup 3))
18281 (mem:BLK (match_dup 4)))
18282 (use (match_dup 5))]
18283 "!TARGET_64BIT"
18284 "{rep\;movsb|rep movsb}"
18285 [(set_attr "type" "str")
18286 (set_attr "prefix_rep" "1")
18287 (set_attr "memory" "both")
18288 (set_attr "mode" "SI")])
18289
18290 (define_insn "*rep_movqi_rex64"
18291 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18292 (set (match_operand:DI 0 "register_operand" "=D")
18293 (plus:DI (match_operand:DI 3 "register_operand" "0")
18294 (match_operand:DI 5 "register_operand" "2")))
18295 (set (match_operand:DI 1 "register_operand" "=S")
18296 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18297 (set (mem:BLK (match_dup 3))
18298 (mem:BLK (match_dup 4)))
18299 (use (match_dup 5))]
18300 "TARGET_64BIT"
18301 "{rep\;movsb|rep movsb}"
18302 [(set_attr "type" "str")
18303 (set_attr "prefix_rep" "1")
18304 (set_attr "memory" "both")
18305 (set_attr "mode" "SI")])
18306
18307 (define_expand "setmemsi"
18308 [(use (match_operand:BLK 0 "memory_operand" ""))
18309 (use (match_operand:SI 1 "nonmemory_operand" ""))
18310 (use (match_operand 2 "const_int_operand" ""))
18311 (use (match_operand 3 "const_int_operand" ""))
18312 (use (match_operand:SI 4 "const_int_operand" ""))
18313 (use (match_operand:SI 5 "const_int_operand" ""))]
18314 ""
18315 {
18316 if (ix86_expand_setmem (operands[0], operands[1],
18317 operands[2], operands[3],
18318 operands[4], operands[5]))
18319 DONE;
18320 else
18321 FAIL;
18322 })
18323
18324 (define_expand "setmemdi"
18325 [(use (match_operand:BLK 0 "memory_operand" ""))
18326 (use (match_operand:DI 1 "nonmemory_operand" ""))
18327 (use (match_operand 2 "const_int_operand" ""))
18328 (use (match_operand 3 "const_int_operand" ""))
18329 (use (match_operand 4 "const_int_operand" ""))
18330 (use (match_operand 5 "const_int_operand" ""))]
18331 "TARGET_64BIT"
18332 {
18333 if (ix86_expand_setmem (operands[0], operands[1],
18334 operands[2], operands[3],
18335 operands[4], operands[5]))
18336 DONE;
18337 else
18338 FAIL;
18339 })
18340
18341 ;; Most CPUs don't like single string operations
18342 ;; Handle this case here to simplify previous expander.
18343
18344 (define_expand "strset"
18345 [(set (match_operand 1 "memory_operand" "")
18346 (match_operand 2 "register_operand" ""))
18347 (parallel [(set (match_operand 0 "register_operand" "")
18348 (match_dup 3))
18349 (clobber (reg:CC FLAGS_REG))])]
18350 ""
18351 {
18352 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18353 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18354
18355 /* If .md ever supports :P for Pmode, this can be directly
18356 in the pattern above. */
18357 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18358 GEN_INT (GET_MODE_SIZE (GET_MODE
18359 (operands[2]))));
18360 if (TARGET_SINGLE_STRINGOP || optimize_size)
18361 {
18362 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18363 operands[3]));
18364 DONE;
18365 }
18366 })
18367
18368 (define_expand "strset_singleop"
18369 [(parallel [(set (match_operand 1 "memory_operand" "")
18370 (match_operand 2 "register_operand" ""))
18371 (set (match_operand 0 "register_operand" "")
18372 (match_operand 3 "" ""))])]
18373 "TARGET_SINGLE_STRINGOP || optimize_size"
18374 "")
18375
18376 (define_insn "*strsetdi_rex_1"
18377 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18378 (match_operand:DI 2 "register_operand" "a"))
18379 (set (match_operand:DI 0 "register_operand" "=D")
18380 (plus:DI (match_dup 1)
18381 (const_int 8)))]
18382 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18383 "stosq"
18384 [(set_attr "type" "str")
18385 (set_attr "memory" "store")
18386 (set_attr "mode" "DI")])
18387
18388 (define_insn "*strsetsi_1"
18389 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18390 (match_operand:SI 2 "register_operand" "a"))
18391 (set (match_operand:SI 0 "register_operand" "=D")
18392 (plus:SI (match_dup 1)
18393 (const_int 4)))]
18394 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18395 "{stosl|stosd}"
18396 [(set_attr "type" "str")
18397 (set_attr "memory" "store")
18398 (set_attr "mode" "SI")])
18399
18400 (define_insn "*strsetsi_rex_1"
18401 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18402 (match_operand:SI 2 "register_operand" "a"))
18403 (set (match_operand:DI 0 "register_operand" "=D")
18404 (plus:DI (match_dup 1)
18405 (const_int 4)))]
18406 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18407 "{stosl|stosd}"
18408 [(set_attr "type" "str")
18409 (set_attr "memory" "store")
18410 (set_attr "mode" "SI")])
18411
18412 (define_insn "*strsethi_1"
18413 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18414 (match_operand:HI 2 "register_operand" "a"))
18415 (set (match_operand:SI 0 "register_operand" "=D")
18416 (plus:SI (match_dup 1)
18417 (const_int 2)))]
18418 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18419 "stosw"
18420 [(set_attr "type" "str")
18421 (set_attr "memory" "store")
18422 (set_attr "mode" "HI")])
18423
18424 (define_insn "*strsethi_rex_1"
18425 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18426 (match_operand:HI 2 "register_operand" "a"))
18427 (set (match_operand:DI 0 "register_operand" "=D")
18428 (plus:DI (match_dup 1)
18429 (const_int 2)))]
18430 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18431 "stosw"
18432 [(set_attr "type" "str")
18433 (set_attr "memory" "store")
18434 (set_attr "mode" "HI")])
18435
18436 (define_insn "*strsetqi_1"
18437 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18438 (match_operand:QI 2 "register_operand" "a"))
18439 (set (match_operand:SI 0 "register_operand" "=D")
18440 (plus:SI (match_dup 1)
18441 (const_int 1)))]
18442 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18443 "stosb"
18444 [(set_attr "type" "str")
18445 (set_attr "memory" "store")
18446 (set_attr "mode" "QI")])
18447
18448 (define_insn "*strsetqi_rex_1"
18449 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18450 (match_operand:QI 2 "register_operand" "a"))
18451 (set (match_operand:DI 0 "register_operand" "=D")
18452 (plus:DI (match_dup 1)
18453 (const_int 1)))]
18454 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18455 "stosb"
18456 [(set_attr "type" "str")
18457 (set_attr "memory" "store")
18458 (set_attr "mode" "QI")])
18459
18460 (define_expand "rep_stos"
18461 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18462 (set (match_operand 0 "register_operand" "")
18463 (match_operand 4 "" ""))
18464 (set (match_operand 2 "memory_operand" "") (const_int 0))
18465 (use (match_operand 3 "register_operand" ""))
18466 (use (match_dup 1))])]
18467 ""
18468 "")
18469
18470 (define_insn "*rep_stosdi_rex64"
18471 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18472 (set (match_operand:DI 0 "register_operand" "=D")
18473 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18474 (const_int 3))
18475 (match_operand:DI 3 "register_operand" "0")))
18476 (set (mem:BLK (match_dup 3))
18477 (const_int 0))
18478 (use (match_operand:DI 2 "register_operand" "a"))
18479 (use (match_dup 4))]
18480 "TARGET_64BIT"
18481 "{rep\;stosq|rep stosq}"
18482 [(set_attr "type" "str")
18483 (set_attr "prefix_rep" "1")
18484 (set_attr "memory" "store")
18485 (set_attr "mode" "DI")])
18486
18487 (define_insn "*rep_stossi"
18488 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18489 (set (match_operand:SI 0 "register_operand" "=D")
18490 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18491 (const_int 2))
18492 (match_operand:SI 3 "register_operand" "0")))
18493 (set (mem:BLK (match_dup 3))
18494 (const_int 0))
18495 (use (match_operand:SI 2 "register_operand" "a"))
18496 (use (match_dup 4))]
18497 "!TARGET_64BIT"
18498 "{rep\;stosl|rep stosd}"
18499 [(set_attr "type" "str")
18500 (set_attr "prefix_rep" "1")
18501 (set_attr "memory" "store")
18502 (set_attr "mode" "SI")])
18503
18504 (define_insn "*rep_stossi_rex64"
18505 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18506 (set (match_operand:DI 0 "register_operand" "=D")
18507 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18508 (const_int 2))
18509 (match_operand:DI 3 "register_operand" "0")))
18510 (set (mem:BLK (match_dup 3))
18511 (const_int 0))
18512 (use (match_operand:SI 2 "register_operand" "a"))
18513 (use (match_dup 4))]
18514 "TARGET_64BIT"
18515 "{rep\;stosl|rep stosd}"
18516 [(set_attr "type" "str")
18517 (set_attr "prefix_rep" "1")
18518 (set_attr "memory" "store")
18519 (set_attr "mode" "SI")])
18520
18521 (define_insn "*rep_stosqi"
18522 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18523 (set (match_operand:SI 0 "register_operand" "=D")
18524 (plus:SI (match_operand:SI 3 "register_operand" "0")
18525 (match_operand:SI 4 "register_operand" "1")))
18526 (set (mem:BLK (match_dup 3))
18527 (const_int 0))
18528 (use (match_operand:QI 2 "register_operand" "a"))
18529 (use (match_dup 4))]
18530 "!TARGET_64BIT"
18531 "{rep\;stosb|rep stosb}"
18532 [(set_attr "type" "str")
18533 (set_attr "prefix_rep" "1")
18534 (set_attr "memory" "store")
18535 (set_attr "mode" "QI")])
18536
18537 (define_insn "*rep_stosqi_rex64"
18538 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18539 (set (match_operand:DI 0 "register_operand" "=D")
18540 (plus:DI (match_operand:DI 3 "register_operand" "0")
18541 (match_operand:DI 4 "register_operand" "1")))
18542 (set (mem:BLK (match_dup 3))
18543 (const_int 0))
18544 (use (match_operand:QI 2 "register_operand" "a"))
18545 (use (match_dup 4))]
18546 "TARGET_64BIT"
18547 "{rep\;stosb|rep stosb}"
18548 [(set_attr "type" "str")
18549 (set_attr "prefix_rep" "1")
18550 (set_attr "memory" "store")
18551 (set_attr "mode" "QI")])
18552
18553 (define_expand "cmpstrnsi"
18554 [(set (match_operand:SI 0 "register_operand" "")
18555 (compare:SI (match_operand:BLK 1 "general_operand" "")
18556 (match_operand:BLK 2 "general_operand" "")))
18557 (use (match_operand 3 "general_operand" ""))
18558 (use (match_operand 4 "immediate_operand" ""))]
18559 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18560 {
18561 rtx addr1, addr2, out, outlow, count, countreg, align;
18562
18563 /* Can't use this if the user has appropriated esi or edi. */
18564 if (global_regs[4] || global_regs[5])
18565 FAIL;
18566
18567 out = operands[0];
18568 if (!REG_P (out))
18569 out = gen_reg_rtx (SImode);
18570
18571 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18572 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18573 if (addr1 != XEXP (operands[1], 0))
18574 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18575 if (addr2 != XEXP (operands[2], 0))
18576 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18577
18578 count = operands[3];
18579 countreg = ix86_zero_extend_to_Pmode (count);
18580
18581 /* %%% Iff we are testing strict equality, we can use known alignment
18582 to good advantage. This may be possible with combine, particularly
18583 once cc0 is dead. */
18584 align = operands[4];
18585
18586 if (CONST_INT_P (count))
18587 {
18588 if (INTVAL (count) == 0)
18589 {
18590 emit_move_insn (operands[0], const0_rtx);
18591 DONE;
18592 }
18593 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18594 operands[1], operands[2]));
18595 }
18596 else
18597 {
18598 if (TARGET_64BIT)
18599 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18600 else
18601 emit_insn (gen_cmpsi_1 (countreg, countreg));
18602 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18603 operands[1], operands[2]));
18604 }
18605
18606 outlow = gen_lowpart (QImode, out);
18607 emit_insn (gen_cmpintqi (outlow));
18608 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18609
18610 if (operands[0] != out)
18611 emit_move_insn (operands[0], out);
18612
18613 DONE;
18614 })
18615
18616 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18617
18618 (define_expand "cmpintqi"
18619 [(set (match_dup 1)
18620 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18621 (set (match_dup 2)
18622 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18623 (parallel [(set (match_operand:QI 0 "register_operand" "")
18624 (minus:QI (match_dup 1)
18625 (match_dup 2)))
18626 (clobber (reg:CC FLAGS_REG))])]
18627 ""
18628 "operands[1] = gen_reg_rtx (QImode);
18629 operands[2] = gen_reg_rtx (QImode);")
18630
18631 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18632 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18633
18634 (define_expand "cmpstrnqi_nz_1"
18635 [(parallel [(set (reg:CC FLAGS_REG)
18636 (compare:CC (match_operand 4 "memory_operand" "")
18637 (match_operand 5 "memory_operand" "")))
18638 (use (match_operand 2 "register_operand" ""))
18639 (use (match_operand:SI 3 "immediate_operand" ""))
18640 (clobber (match_operand 0 "register_operand" ""))
18641 (clobber (match_operand 1 "register_operand" ""))
18642 (clobber (match_dup 2))])]
18643 ""
18644 "")
18645
18646 (define_insn "*cmpstrnqi_nz_1"
18647 [(set (reg:CC FLAGS_REG)
18648 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18649 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18650 (use (match_operand:SI 6 "register_operand" "2"))
18651 (use (match_operand:SI 3 "immediate_operand" "i"))
18652 (clobber (match_operand:SI 0 "register_operand" "=S"))
18653 (clobber (match_operand:SI 1 "register_operand" "=D"))
18654 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18655 "!TARGET_64BIT"
18656 "repz{\;| }cmpsb"
18657 [(set_attr "type" "str")
18658 (set_attr "mode" "QI")
18659 (set_attr "prefix_rep" "1")])
18660
18661 (define_insn "*cmpstrnqi_nz_rex_1"
18662 [(set (reg:CC FLAGS_REG)
18663 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18664 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18665 (use (match_operand:DI 6 "register_operand" "2"))
18666 (use (match_operand:SI 3 "immediate_operand" "i"))
18667 (clobber (match_operand:DI 0 "register_operand" "=S"))
18668 (clobber (match_operand:DI 1 "register_operand" "=D"))
18669 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18670 "TARGET_64BIT"
18671 "repz{\;| }cmpsb"
18672 [(set_attr "type" "str")
18673 (set_attr "mode" "QI")
18674 (set_attr "prefix_rep" "1")])
18675
18676 ;; The same, but the count is not known to not be zero.
18677
18678 (define_expand "cmpstrnqi_1"
18679 [(parallel [(set (reg:CC FLAGS_REG)
18680 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18681 (const_int 0))
18682 (compare:CC (match_operand 4 "memory_operand" "")
18683 (match_operand 5 "memory_operand" ""))
18684 (const_int 0)))
18685 (use (match_operand:SI 3 "immediate_operand" ""))
18686 (use (reg:CC FLAGS_REG))
18687 (clobber (match_operand 0 "register_operand" ""))
18688 (clobber (match_operand 1 "register_operand" ""))
18689 (clobber (match_dup 2))])]
18690 ""
18691 "")
18692
18693 (define_insn "*cmpstrnqi_1"
18694 [(set (reg:CC FLAGS_REG)
18695 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18696 (const_int 0))
18697 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18698 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18699 (const_int 0)))
18700 (use (match_operand:SI 3 "immediate_operand" "i"))
18701 (use (reg:CC FLAGS_REG))
18702 (clobber (match_operand:SI 0 "register_operand" "=S"))
18703 (clobber (match_operand:SI 1 "register_operand" "=D"))
18704 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18705 "!TARGET_64BIT"
18706 "repz{\;| }cmpsb"
18707 [(set_attr "type" "str")
18708 (set_attr "mode" "QI")
18709 (set_attr "prefix_rep" "1")])
18710
18711 (define_insn "*cmpstrnqi_rex_1"
18712 [(set (reg:CC FLAGS_REG)
18713 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18714 (const_int 0))
18715 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18716 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18717 (const_int 0)))
18718 (use (match_operand:SI 3 "immediate_operand" "i"))
18719 (use (reg:CC FLAGS_REG))
18720 (clobber (match_operand:DI 0 "register_operand" "=S"))
18721 (clobber (match_operand:DI 1 "register_operand" "=D"))
18722 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18723 "TARGET_64BIT"
18724 "repz{\;| }cmpsb"
18725 [(set_attr "type" "str")
18726 (set_attr "mode" "QI")
18727 (set_attr "prefix_rep" "1")])
18728
18729 (define_expand "strlensi"
18730 [(set (match_operand:SI 0 "register_operand" "")
18731 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18732 (match_operand:QI 2 "immediate_operand" "")
18733 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18734 ""
18735 {
18736 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18737 DONE;
18738 else
18739 FAIL;
18740 })
18741
18742 (define_expand "strlendi"
18743 [(set (match_operand:DI 0 "register_operand" "")
18744 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18745 (match_operand:QI 2 "immediate_operand" "")
18746 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18747 ""
18748 {
18749 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18750 DONE;
18751 else
18752 FAIL;
18753 })
18754
18755 (define_expand "strlenqi_1"
18756 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18757 (clobber (match_operand 1 "register_operand" ""))
18758 (clobber (reg:CC FLAGS_REG))])]
18759 ""
18760 "")
18761
18762 (define_insn "*strlenqi_1"
18763 [(set (match_operand:SI 0 "register_operand" "=&c")
18764 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18765 (match_operand:QI 2 "register_operand" "a")
18766 (match_operand:SI 3 "immediate_operand" "i")
18767 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18768 (clobber (match_operand:SI 1 "register_operand" "=D"))
18769 (clobber (reg:CC FLAGS_REG))]
18770 "!TARGET_64BIT"
18771 "repnz{\;| }scasb"
18772 [(set_attr "type" "str")
18773 (set_attr "mode" "QI")
18774 (set_attr "prefix_rep" "1")])
18775
18776 (define_insn "*strlenqi_rex_1"
18777 [(set (match_operand:DI 0 "register_operand" "=&c")
18778 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18779 (match_operand:QI 2 "register_operand" "a")
18780 (match_operand:DI 3 "immediate_operand" "i")
18781 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18782 (clobber (match_operand:DI 1 "register_operand" "=D"))
18783 (clobber (reg:CC FLAGS_REG))]
18784 "TARGET_64BIT"
18785 "repnz{\;| }scasb"
18786 [(set_attr "type" "str")
18787 (set_attr "mode" "QI")
18788 (set_attr "prefix_rep" "1")])
18789
18790 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18791 ;; handled in combine, but it is not currently up to the task.
18792 ;; When used for their truth value, the cmpstrn* expanders generate
18793 ;; code like this:
18794 ;;
18795 ;; repz cmpsb
18796 ;; seta %al
18797 ;; setb %dl
18798 ;; cmpb %al, %dl
18799 ;; jcc label
18800 ;;
18801 ;; The intermediate three instructions are unnecessary.
18802
18803 ;; This one handles cmpstrn*_nz_1...
18804 (define_peephole2
18805 [(parallel[
18806 (set (reg:CC FLAGS_REG)
18807 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18808 (mem:BLK (match_operand 5 "register_operand" ""))))
18809 (use (match_operand 6 "register_operand" ""))
18810 (use (match_operand:SI 3 "immediate_operand" ""))
18811 (clobber (match_operand 0 "register_operand" ""))
18812 (clobber (match_operand 1 "register_operand" ""))
18813 (clobber (match_operand 2 "register_operand" ""))])
18814 (set (match_operand:QI 7 "register_operand" "")
18815 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18816 (set (match_operand:QI 8 "register_operand" "")
18817 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18818 (set (reg FLAGS_REG)
18819 (compare (match_dup 7) (match_dup 8)))
18820 ]
18821 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18822 [(parallel[
18823 (set (reg:CC FLAGS_REG)
18824 (compare:CC (mem:BLK (match_dup 4))
18825 (mem:BLK (match_dup 5))))
18826 (use (match_dup 6))
18827 (use (match_dup 3))
18828 (clobber (match_dup 0))
18829 (clobber (match_dup 1))
18830 (clobber (match_dup 2))])]
18831 "")
18832
18833 ;; ...and this one handles cmpstrn*_1.
18834 (define_peephole2
18835 [(parallel[
18836 (set (reg:CC FLAGS_REG)
18837 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18838 (const_int 0))
18839 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18840 (mem:BLK (match_operand 5 "register_operand" "")))
18841 (const_int 0)))
18842 (use (match_operand:SI 3 "immediate_operand" ""))
18843 (use (reg:CC FLAGS_REG))
18844 (clobber (match_operand 0 "register_operand" ""))
18845 (clobber (match_operand 1 "register_operand" ""))
18846 (clobber (match_operand 2 "register_operand" ""))])
18847 (set (match_operand:QI 7 "register_operand" "")
18848 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18849 (set (match_operand:QI 8 "register_operand" "")
18850 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18851 (set (reg FLAGS_REG)
18852 (compare (match_dup 7) (match_dup 8)))
18853 ]
18854 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18855 [(parallel[
18856 (set (reg:CC FLAGS_REG)
18857 (if_then_else:CC (ne (match_dup 6)
18858 (const_int 0))
18859 (compare:CC (mem:BLK (match_dup 4))
18860 (mem:BLK (match_dup 5)))
18861 (const_int 0)))
18862 (use (match_dup 3))
18863 (use (reg:CC FLAGS_REG))
18864 (clobber (match_dup 0))
18865 (clobber (match_dup 1))
18866 (clobber (match_dup 2))])]
18867 "")
18868
18869
18870 \f
18871 ;; Conditional move instructions.
18872
18873 (define_expand "movdicc"
18874 [(set (match_operand:DI 0 "register_operand" "")
18875 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18876 (match_operand:DI 2 "general_operand" "")
18877 (match_operand:DI 3 "general_operand" "")))]
18878 "TARGET_64BIT"
18879 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18880
18881 (define_insn "x86_movdicc_0_m1_rex64"
18882 [(set (match_operand:DI 0 "register_operand" "=r")
18883 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18884 (const_int -1)
18885 (const_int 0)))
18886 (clobber (reg:CC FLAGS_REG))]
18887 "TARGET_64BIT"
18888 "sbb{q}\t%0, %0"
18889 ; Since we don't have the proper number of operands for an alu insn,
18890 ; fill in all the blanks.
18891 [(set_attr "type" "alu")
18892 (set_attr "pent_pair" "pu")
18893 (set_attr "memory" "none")
18894 (set_attr "imm_disp" "false")
18895 (set_attr "mode" "DI")
18896 (set_attr "length_immediate" "0")])
18897
18898 (define_insn "*movdicc_c_rex64"
18899 [(set (match_operand:DI 0 "register_operand" "=r,r")
18900 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18901 [(reg FLAGS_REG) (const_int 0)])
18902 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18903 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18904 "TARGET_64BIT && TARGET_CMOVE
18905 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18906 "@
18907 cmov%O2%C1\t{%2, %0|%0, %2}
18908 cmov%O2%c1\t{%3, %0|%0, %3}"
18909 [(set_attr "type" "icmov")
18910 (set_attr "mode" "DI")])
18911
18912 (define_expand "movsicc"
18913 [(set (match_operand:SI 0 "register_operand" "")
18914 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18915 (match_operand:SI 2 "general_operand" "")
18916 (match_operand:SI 3 "general_operand" "")))]
18917 ""
18918 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18919
18920 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18921 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18922 ;; So just document what we're doing explicitly.
18923
18924 (define_insn "x86_movsicc_0_m1"
18925 [(set (match_operand:SI 0 "register_operand" "=r")
18926 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18927 (const_int -1)
18928 (const_int 0)))
18929 (clobber (reg:CC FLAGS_REG))]
18930 ""
18931 "sbb{l}\t%0, %0"
18932 ; Since we don't have the proper number of operands for an alu insn,
18933 ; fill in all the blanks.
18934 [(set_attr "type" "alu")
18935 (set_attr "pent_pair" "pu")
18936 (set_attr "memory" "none")
18937 (set_attr "imm_disp" "false")
18938 (set_attr "mode" "SI")
18939 (set_attr "length_immediate" "0")])
18940
18941 (define_insn "*movsicc_noc"
18942 [(set (match_operand:SI 0 "register_operand" "=r,r")
18943 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18944 [(reg FLAGS_REG) (const_int 0)])
18945 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18946 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18947 "TARGET_CMOVE
18948 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18949 "@
18950 cmov%O2%C1\t{%2, %0|%0, %2}
18951 cmov%O2%c1\t{%3, %0|%0, %3}"
18952 [(set_attr "type" "icmov")
18953 (set_attr "mode" "SI")])
18954
18955 (define_expand "movhicc"
18956 [(set (match_operand:HI 0 "register_operand" "")
18957 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18958 (match_operand:HI 2 "general_operand" "")
18959 (match_operand:HI 3 "general_operand" "")))]
18960 "TARGET_HIMODE_MATH"
18961 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18962
18963 (define_insn "*movhicc_noc"
18964 [(set (match_operand:HI 0 "register_operand" "=r,r")
18965 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18966 [(reg FLAGS_REG) (const_int 0)])
18967 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18968 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18969 "TARGET_CMOVE
18970 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18971 "@
18972 cmov%O2%C1\t{%2, %0|%0, %2}
18973 cmov%O2%c1\t{%3, %0|%0, %3}"
18974 [(set_attr "type" "icmov")
18975 (set_attr "mode" "HI")])
18976
18977 (define_expand "movqicc"
18978 [(set (match_operand:QI 0 "register_operand" "")
18979 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18980 (match_operand:QI 2 "general_operand" "")
18981 (match_operand:QI 3 "general_operand" "")))]
18982 "TARGET_QIMODE_MATH"
18983 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18984
18985 (define_insn_and_split "*movqicc_noc"
18986 [(set (match_operand:QI 0 "register_operand" "=r,r")
18987 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18988 [(match_operand 4 "flags_reg_operand" "")
18989 (const_int 0)])
18990 (match_operand:QI 2 "register_operand" "r,0")
18991 (match_operand:QI 3 "register_operand" "0,r")))]
18992 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18993 "#"
18994 "&& reload_completed"
18995 [(set (match_dup 0)
18996 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18997 (match_dup 2)
18998 (match_dup 3)))]
18999 "operands[0] = gen_lowpart (SImode, operands[0]);
19000 operands[2] = gen_lowpart (SImode, operands[2]);
19001 operands[3] = gen_lowpart (SImode, operands[3]);"
19002 [(set_attr "type" "icmov")
19003 (set_attr "mode" "SI")])
19004
19005 (define_expand "movsfcc"
19006 [(set (match_operand:SF 0 "register_operand" "")
19007 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19008 (match_operand:SF 2 "register_operand" "")
19009 (match_operand:SF 3 "register_operand" "")))]
19010 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19011 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19012
19013 (define_insn "*movsfcc_1_387"
19014 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19015 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19016 [(reg FLAGS_REG) (const_int 0)])
19017 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19018 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19019 "TARGET_80387 && TARGET_CMOVE
19020 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19021 "@
19022 fcmov%F1\t{%2, %0|%0, %2}
19023 fcmov%f1\t{%3, %0|%0, %3}
19024 cmov%O2%C1\t{%2, %0|%0, %2}
19025 cmov%O2%c1\t{%3, %0|%0, %3}"
19026 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19027 (set_attr "mode" "SF,SF,SI,SI")])
19028
19029 (define_expand "movdfcc"
19030 [(set (match_operand:DF 0 "register_operand" "")
19031 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19032 (match_operand:DF 2 "register_operand" "")
19033 (match_operand:DF 3 "register_operand" "")))]
19034 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19035 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19036
19037 (define_insn "*movdfcc_1"
19038 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19039 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19040 [(reg FLAGS_REG) (const_int 0)])
19041 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19042 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19043 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19044 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19045 "@
19046 fcmov%F1\t{%2, %0|%0, %2}
19047 fcmov%f1\t{%3, %0|%0, %3}
19048 #
19049 #"
19050 [(set_attr "type" "fcmov,fcmov,multi,multi")
19051 (set_attr "mode" "DF")])
19052
19053 (define_insn "*movdfcc_1_rex64"
19054 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19055 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19056 [(reg FLAGS_REG) (const_int 0)])
19057 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19058 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19059 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19060 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19061 "@
19062 fcmov%F1\t{%2, %0|%0, %2}
19063 fcmov%f1\t{%3, %0|%0, %3}
19064 cmov%O2%C1\t{%2, %0|%0, %2}
19065 cmov%O2%c1\t{%3, %0|%0, %3}"
19066 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19067 (set_attr "mode" "DF")])
19068
19069 (define_split
19070 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19071 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19072 [(match_operand 4 "flags_reg_operand" "")
19073 (const_int 0)])
19074 (match_operand:DF 2 "nonimmediate_operand" "")
19075 (match_operand:DF 3 "nonimmediate_operand" "")))]
19076 "!TARGET_64BIT && reload_completed"
19077 [(set (match_dup 2)
19078 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19079 (match_dup 5)
19080 (match_dup 7)))
19081 (set (match_dup 3)
19082 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19083 (match_dup 6)
19084 (match_dup 8)))]
19085 "split_di (operands+2, 1, operands+5, operands+6);
19086 split_di (operands+3, 1, operands+7, operands+8);
19087 split_di (operands, 1, operands+2, operands+3);")
19088
19089 (define_expand "movxfcc"
19090 [(set (match_operand:XF 0 "register_operand" "")
19091 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19092 (match_operand:XF 2 "register_operand" "")
19093 (match_operand:XF 3 "register_operand" "")))]
19094 "TARGET_80387 && TARGET_CMOVE"
19095 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19096
19097 (define_insn "*movxfcc_1"
19098 [(set (match_operand:XF 0 "register_operand" "=f,f")
19099 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19100 [(reg FLAGS_REG) (const_int 0)])
19101 (match_operand:XF 2 "register_operand" "f,0")
19102 (match_operand:XF 3 "register_operand" "0,f")))]
19103 "TARGET_80387 && TARGET_CMOVE"
19104 "@
19105 fcmov%F1\t{%2, %0|%0, %2}
19106 fcmov%f1\t{%3, %0|%0, %3}"
19107 [(set_attr "type" "fcmov")
19108 (set_attr "mode" "XF")])
19109
19110 ;; These versions of the min/max patterns are intentionally ignorant of
19111 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19112 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19113 ;; are undefined in this condition, we're certain this is correct.
19114
19115 (define_insn "sminsf3"
19116 [(set (match_operand:SF 0 "register_operand" "=x")
19117 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19118 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19119 "TARGET_SSE_MATH"
19120 "minss\t{%2, %0|%0, %2}"
19121 [(set_attr "type" "sseadd")
19122 (set_attr "mode" "SF")])
19123
19124 (define_insn "smaxsf3"
19125 [(set (match_operand:SF 0 "register_operand" "=x")
19126 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19127 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19128 "TARGET_SSE_MATH"
19129 "maxss\t{%2, %0|%0, %2}"
19130 [(set_attr "type" "sseadd")
19131 (set_attr "mode" "SF")])
19132
19133 (define_insn "smindf3"
19134 [(set (match_operand:DF 0 "register_operand" "=x")
19135 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19136 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19137 "TARGET_SSE2 && TARGET_SSE_MATH"
19138 "minsd\t{%2, %0|%0, %2}"
19139 [(set_attr "type" "sseadd")
19140 (set_attr "mode" "DF")])
19141
19142 (define_insn "smaxdf3"
19143 [(set (match_operand:DF 0 "register_operand" "=x")
19144 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19145 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19146 "TARGET_SSE2 && TARGET_SSE_MATH"
19147 "maxsd\t{%2, %0|%0, %2}"
19148 [(set_attr "type" "sseadd")
19149 (set_attr "mode" "DF")])
19150
19151 ;; These versions of the min/max patterns implement exactly the operations
19152 ;; min = (op1 < op2 ? op1 : op2)
19153 ;; max = (!(op1 < op2) ? op1 : op2)
19154 ;; Their operands are not commutative, and thus they may be used in the
19155 ;; presence of -0.0 and NaN.
19156
19157 (define_insn "*ieee_sminsf3"
19158 [(set (match_operand:SF 0 "register_operand" "=x")
19159 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19160 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19161 UNSPEC_IEEE_MIN))]
19162 "TARGET_SSE_MATH"
19163 "minss\t{%2, %0|%0, %2}"
19164 [(set_attr "type" "sseadd")
19165 (set_attr "mode" "SF")])
19166
19167 (define_insn "*ieee_smaxsf3"
19168 [(set (match_operand:SF 0 "register_operand" "=x")
19169 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19170 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19171 UNSPEC_IEEE_MAX))]
19172 "TARGET_SSE_MATH"
19173 "maxss\t{%2, %0|%0, %2}"
19174 [(set_attr "type" "sseadd")
19175 (set_attr "mode" "SF")])
19176
19177 (define_insn "*ieee_smindf3"
19178 [(set (match_operand:DF 0 "register_operand" "=x")
19179 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19180 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19181 UNSPEC_IEEE_MIN))]
19182 "TARGET_SSE2 && TARGET_SSE_MATH"
19183 "minsd\t{%2, %0|%0, %2}"
19184 [(set_attr "type" "sseadd")
19185 (set_attr "mode" "DF")])
19186
19187 (define_insn "*ieee_smaxdf3"
19188 [(set (match_operand:DF 0 "register_operand" "=x")
19189 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19190 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19191 UNSPEC_IEEE_MAX))]
19192 "TARGET_SSE2 && TARGET_SSE_MATH"
19193 "maxsd\t{%2, %0|%0, %2}"
19194 [(set_attr "type" "sseadd")
19195 (set_attr "mode" "DF")])
19196
19197 ;; Make two stack loads independent:
19198 ;; fld aa fld aa
19199 ;; fld %st(0) -> fld bb
19200 ;; fmul bb fmul %st(1), %st
19201 ;;
19202 ;; Actually we only match the last two instructions for simplicity.
19203 (define_peephole2
19204 [(set (match_operand 0 "fp_register_operand" "")
19205 (match_operand 1 "fp_register_operand" ""))
19206 (set (match_dup 0)
19207 (match_operator 2 "binary_fp_operator"
19208 [(match_dup 0)
19209 (match_operand 3 "memory_operand" "")]))]
19210 "REGNO (operands[0]) != REGNO (operands[1])"
19211 [(set (match_dup 0) (match_dup 3))
19212 (set (match_dup 0) (match_dup 4))]
19213
19214 ;; The % modifier is not operational anymore in peephole2's, so we have to
19215 ;; swap the operands manually in the case of addition and multiplication.
19216 "if (COMMUTATIVE_ARITH_P (operands[2]))
19217 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19218 operands[0], operands[1]);
19219 else
19220 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19221 operands[1], operands[0]);")
19222
19223 ;; Conditional addition patterns
19224 (define_expand "addqicc"
19225 [(match_operand:QI 0 "register_operand" "")
19226 (match_operand 1 "comparison_operator" "")
19227 (match_operand:QI 2 "register_operand" "")
19228 (match_operand:QI 3 "const_int_operand" "")]
19229 ""
19230 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19231
19232 (define_expand "addhicc"
19233 [(match_operand:HI 0 "register_operand" "")
19234 (match_operand 1 "comparison_operator" "")
19235 (match_operand:HI 2 "register_operand" "")
19236 (match_operand:HI 3 "const_int_operand" "")]
19237 ""
19238 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19239
19240 (define_expand "addsicc"
19241 [(match_operand:SI 0 "register_operand" "")
19242 (match_operand 1 "comparison_operator" "")
19243 (match_operand:SI 2 "register_operand" "")
19244 (match_operand:SI 3 "const_int_operand" "")]
19245 ""
19246 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19247
19248 (define_expand "adddicc"
19249 [(match_operand:DI 0 "register_operand" "")
19250 (match_operand 1 "comparison_operator" "")
19251 (match_operand:DI 2 "register_operand" "")
19252 (match_operand:DI 3 "const_int_operand" "")]
19253 "TARGET_64BIT"
19254 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19255
19256 \f
19257 ;; Misc patterns (?)
19258
19259 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19260 ;; Otherwise there will be nothing to keep
19261 ;;
19262 ;; [(set (reg ebp) (reg esp))]
19263 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19264 ;; (clobber (eflags)]
19265 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19266 ;;
19267 ;; in proper program order.
19268 (define_insn "pro_epilogue_adjust_stack_1"
19269 [(set (match_operand:SI 0 "register_operand" "=r,r")
19270 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19271 (match_operand:SI 2 "immediate_operand" "i,i")))
19272 (clobber (reg:CC FLAGS_REG))
19273 (clobber (mem:BLK (scratch)))]
19274 "!TARGET_64BIT"
19275 {
19276 switch (get_attr_type (insn))
19277 {
19278 case TYPE_IMOV:
19279 return "mov{l}\t{%1, %0|%0, %1}";
19280
19281 case TYPE_ALU:
19282 if (CONST_INT_P (operands[2])
19283 && (INTVAL (operands[2]) == 128
19284 || (INTVAL (operands[2]) < 0
19285 && INTVAL (operands[2]) != -128)))
19286 {
19287 operands[2] = GEN_INT (-INTVAL (operands[2]));
19288 return "sub{l}\t{%2, %0|%0, %2}";
19289 }
19290 return "add{l}\t{%2, %0|%0, %2}";
19291
19292 case TYPE_LEA:
19293 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19294 return "lea{l}\t{%a2, %0|%0, %a2}";
19295
19296 default:
19297 gcc_unreachable ();
19298 }
19299 }
19300 [(set (attr "type")
19301 (cond [(eq_attr "alternative" "0")
19302 (const_string "alu")
19303 (match_operand:SI 2 "const0_operand" "")
19304 (const_string "imov")
19305 ]
19306 (const_string "lea")))
19307 (set_attr "mode" "SI")])
19308
19309 (define_insn "pro_epilogue_adjust_stack_rex64"
19310 [(set (match_operand:DI 0 "register_operand" "=r,r")
19311 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19312 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19313 (clobber (reg:CC FLAGS_REG))
19314 (clobber (mem:BLK (scratch)))]
19315 "TARGET_64BIT"
19316 {
19317 switch (get_attr_type (insn))
19318 {
19319 case TYPE_IMOV:
19320 return "mov{q}\t{%1, %0|%0, %1}";
19321
19322 case TYPE_ALU:
19323 if (CONST_INT_P (operands[2])
19324 /* Avoid overflows. */
19325 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19326 && (INTVAL (operands[2]) == 128
19327 || (INTVAL (operands[2]) < 0
19328 && INTVAL (operands[2]) != -128)))
19329 {
19330 operands[2] = GEN_INT (-INTVAL (operands[2]));
19331 return "sub{q}\t{%2, %0|%0, %2}";
19332 }
19333 return "add{q}\t{%2, %0|%0, %2}";
19334
19335 case TYPE_LEA:
19336 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19337 return "lea{q}\t{%a2, %0|%0, %a2}";
19338
19339 default:
19340 gcc_unreachable ();
19341 }
19342 }
19343 [(set (attr "type")
19344 (cond [(eq_attr "alternative" "0")
19345 (const_string "alu")
19346 (match_operand:DI 2 "const0_operand" "")
19347 (const_string "imov")
19348 ]
19349 (const_string "lea")))
19350 (set_attr "mode" "DI")])
19351
19352 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19353 [(set (match_operand:DI 0 "register_operand" "=r,r")
19354 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19355 (match_operand:DI 3 "immediate_operand" "i,i")))
19356 (use (match_operand:DI 2 "register_operand" "r,r"))
19357 (clobber (reg:CC FLAGS_REG))
19358 (clobber (mem:BLK (scratch)))]
19359 "TARGET_64BIT"
19360 {
19361 switch (get_attr_type (insn))
19362 {
19363 case TYPE_ALU:
19364 return "add{q}\t{%2, %0|%0, %2}";
19365
19366 case TYPE_LEA:
19367 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19368 return "lea{q}\t{%a2, %0|%0, %a2}";
19369
19370 default:
19371 gcc_unreachable ();
19372 }
19373 }
19374 [(set_attr "type" "alu,lea")
19375 (set_attr "mode" "DI")])
19376
19377 (define_insn "allocate_stack_worker_32"
19378 [(set (match_operand:SI 0 "register_operand" "+a")
19379 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19380 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19381 (clobber (reg:CC FLAGS_REG))]
19382 "!TARGET_64BIT && TARGET_STACK_PROBE"
19383 "call\t__alloca"
19384 [(set_attr "type" "multi")
19385 (set_attr "length" "5")])
19386
19387 (define_insn "allocate_stack_worker_64"
19388 [(set (match_operand:DI 0 "register_operand" "=a")
19389 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19390 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19391 (clobber (reg:DI R10_REG))
19392 (clobber (reg:DI R11_REG))
19393 (clobber (reg:CC FLAGS_REG))]
19394 "TARGET_64BIT && TARGET_STACK_PROBE"
19395 "call\t___chkstk"
19396 [(set_attr "type" "multi")
19397 (set_attr "length" "5")])
19398
19399 (define_expand "allocate_stack"
19400 [(match_operand 0 "register_operand" "")
19401 (match_operand 1 "general_operand" "")]
19402 "TARGET_STACK_PROBE"
19403 {
19404 rtx x;
19405
19406 #ifndef CHECK_STACK_LIMIT
19407 #define CHECK_STACK_LIMIT 0
19408 #endif
19409
19410 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19411 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19412 {
19413 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19414 stack_pointer_rtx, 0, OPTAB_DIRECT);
19415 if (x != stack_pointer_rtx)
19416 emit_move_insn (stack_pointer_rtx, x);
19417 }
19418 else
19419 {
19420 x = copy_to_mode_reg (Pmode, operands[1]);
19421 if (TARGET_64BIT)
19422 x = gen_allocate_stack_worker_64 (x);
19423 else
19424 x = gen_allocate_stack_worker_32 (x);
19425 emit_insn (x);
19426 }
19427
19428 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19429 DONE;
19430 })
19431
19432 (define_expand "builtin_setjmp_receiver"
19433 [(label_ref (match_operand 0 "" ""))]
19434 "!TARGET_64BIT && flag_pic"
19435 {
19436 if (TARGET_MACHO)
19437 {
19438 rtx xops[3];
19439 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19440 rtx label_rtx = gen_label_rtx ();
19441 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19442 xops[0] = xops[1] = picreg;
19443 xops[2] = gen_rtx_CONST (SImode,
19444 gen_rtx_MINUS (SImode,
19445 gen_rtx_LABEL_REF (SImode, label_rtx),
19446 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19447 ix86_expand_binary_operator (MINUS, SImode, xops);
19448 }
19449 else
19450 emit_insn (gen_set_got (pic_offset_table_rtx));
19451 DONE;
19452 })
19453 \f
19454 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19455
19456 (define_split
19457 [(set (match_operand 0 "register_operand" "")
19458 (match_operator 3 "promotable_binary_operator"
19459 [(match_operand 1 "register_operand" "")
19460 (match_operand 2 "aligned_operand" "")]))
19461 (clobber (reg:CC FLAGS_REG))]
19462 "! TARGET_PARTIAL_REG_STALL && reload_completed
19463 && ((GET_MODE (operands[0]) == HImode
19464 && ((!optimize_size && !TARGET_FAST_PREFIX)
19465 /* ??? next two lines just !satisfies_constraint_K (...) */
19466 || !CONST_INT_P (operands[2])
19467 || satisfies_constraint_K (operands[2])))
19468 || (GET_MODE (operands[0]) == QImode
19469 && (TARGET_PROMOTE_QImode || optimize_size)))"
19470 [(parallel [(set (match_dup 0)
19471 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19472 (clobber (reg:CC FLAGS_REG))])]
19473 "operands[0] = gen_lowpart (SImode, operands[0]);
19474 operands[1] = gen_lowpart (SImode, operands[1]);
19475 if (GET_CODE (operands[3]) != ASHIFT)
19476 operands[2] = gen_lowpart (SImode, operands[2]);
19477 PUT_MODE (operands[3], SImode);")
19478
19479 ; Promote the QImode tests, as i386 has encoding of the AND
19480 ; instruction with 32-bit sign-extended immediate and thus the
19481 ; instruction size is unchanged, except in the %eax case for
19482 ; which it is increased by one byte, hence the ! optimize_size.
19483 (define_split
19484 [(set (match_operand 0 "flags_reg_operand" "")
19485 (match_operator 2 "compare_operator"
19486 [(and (match_operand 3 "aligned_operand" "")
19487 (match_operand 4 "const_int_operand" ""))
19488 (const_int 0)]))
19489 (set (match_operand 1 "register_operand" "")
19490 (and (match_dup 3) (match_dup 4)))]
19491 "! TARGET_PARTIAL_REG_STALL && reload_completed
19492 /* Ensure that the operand will remain sign-extended immediate. */
19493 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19494 && ! optimize_size
19495 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19496 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19497 [(parallel [(set (match_dup 0)
19498 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19499 (const_int 0)]))
19500 (set (match_dup 1)
19501 (and:SI (match_dup 3) (match_dup 4)))])]
19502 {
19503 operands[4]
19504 = gen_int_mode (INTVAL (operands[4])
19505 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19506 operands[1] = gen_lowpart (SImode, operands[1]);
19507 operands[3] = gen_lowpart (SImode, operands[3]);
19508 })
19509
19510 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19511 ; the TEST instruction with 32-bit sign-extended immediate and thus
19512 ; the instruction size would at least double, which is not what we
19513 ; want even with ! optimize_size.
19514 (define_split
19515 [(set (match_operand 0 "flags_reg_operand" "")
19516 (match_operator 1 "compare_operator"
19517 [(and (match_operand:HI 2 "aligned_operand" "")
19518 (match_operand:HI 3 "const_int_operand" ""))
19519 (const_int 0)]))]
19520 "! TARGET_PARTIAL_REG_STALL && reload_completed
19521 /* Ensure that the operand will remain sign-extended immediate. */
19522 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19523 && ! TARGET_FAST_PREFIX
19524 && ! optimize_size"
19525 [(set (match_dup 0)
19526 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19527 (const_int 0)]))]
19528 {
19529 operands[3]
19530 = gen_int_mode (INTVAL (operands[3])
19531 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19532 operands[2] = gen_lowpart (SImode, operands[2]);
19533 })
19534
19535 (define_split
19536 [(set (match_operand 0 "register_operand" "")
19537 (neg (match_operand 1 "register_operand" "")))
19538 (clobber (reg:CC FLAGS_REG))]
19539 "! TARGET_PARTIAL_REG_STALL && reload_completed
19540 && (GET_MODE (operands[0]) == HImode
19541 || (GET_MODE (operands[0]) == QImode
19542 && (TARGET_PROMOTE_QImode || optimize_size)))"
19543 [(parallel [(set (match_dup 0)
19544 (neg:SI (match_dup 1)))
19545 (clobber (reg:CC FLAGS_REG))])]
19546 "operands[0] = gen_lowpart (SImode, operands[0]);
19547 operands[1] = gen_lowpart (SImode, operands[1]);")
19548
19549 (define_split
19550 [(set (match_operand 0 "register_operand" "")
19551 (not (match_operand 1 "register_operand" "")))]
19552 "! TARGET_PARTIAL_REG_STALL && reload_completed
19553 && (GET_MODE (operands[0]) == HImode
19554 || (GET_MODE (operands[0]) == QImode
19555 && (TARGET_PROMOTE_QImode || optimize_size)))"
19556 [(set (match_dup 0)
19557 (not:SI (match_dup 1)))]
19558 "operands[0] = gen_lowpart (SImode, operands[0]);
19559 operands[1] = gen_lowpart (SImode, operands[1]);")
19560
19561 (define_split
19562 [(set (match_operand 0 "register_operand" "")
19563 (if_then_else (match_operator 1 "comparison_operator"
19564 [(reg FLAGS_REG) (const_int 0)])
19565 (match_operand 2 "register_operand" "")
19566 (match_operand 3 "register_operand" "")))]
19567 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19568 && (GET_MODE (operands[0]) == HImode
19569 || (GET_MODE (operands[0]) == QImode
19570 && (TARGET_PROMOTE_QImode || optimize_size)))"
19571 [(set (match_dup 0)
19572 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19573 "operands[0] = gen_lowpart (SImode, operands[0]);
19574 operands[2] = gen_lowpart (SImode, operands[2]);
19575 operands[3] = gen_lowpart (SImode, operands[3]);")
19576
19577 \f
19578 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19579 ;; transform a complex memory operation into two memory to register operations.
19580
19581 ;; Don't push memory operands
19582 (define_peephole2
19583 [(set (match_operand:SI 0 "push_operand" "")
19584 (match_operand:SI 1 "memory_operand" ""))
19585 (match_scratch:SI 2 "r")]
19586 "!optimize_size && !TARGET_PUSH_MEMORY
19587 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19588 [(set (match_dup 2) (match_dup 1))
19589 (set (match_dup 0) (match_dup 2))]
19590 "")
19591
19592 (define_peephole2
19593 [(set (match_operand:DI 0 "push_operand" "")
19594 (match_operand:DI 1 "memory_operand" ""))
19595 (match_scratch:DI 2 "r")]
19596 "!optimize_size && !TARGET_PUSH_MEMORY
19597 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19598 [(set (match_dup 2) (match_dup 1))
19599 (set (match_dup 0) (match_dup 2))]
19600 "")
19601
19602 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19603 ;; SImode pushes.
19604 (define_peephole2
19605 [(set (match_operand:SF 0 "push_operand" "")
19606 (match_operand:SF 1 "memory_operand" ""))
19607 (match_scratch:SF 2 "r")]
19608 "!optimize_size && !TARGET_PUSH_MEMORY
19609 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19610 [(set (match_dup 2) (match_dup 1))
19611 (set (match_dup 0) (match_dup 2))]
19612 "")
19613
19614 (define_peephole2
19615 [(set (match_operand:HI 0 "push_operand" "")
19616 (match_operand:HI 1 "memory_operand" ""))
19617 (match_scratch:HI 2 "r")]
19618 "!optimize_size && !TARGET_PUSH_MEMORY
19619 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19620 [(set (match_dup 2) (match_dup 1))
19621 (set (match_dup 0) (match_dup 2))]
19622 "")
19623
19624 (define_peephole2
19625 [(set (match_operand:QI 0 "push_operand" "")
19626 (match_operand:QI 1 "memory_operand" ""))
19627 (match_scratch:QI 2 "q")]
19628 "!optimize_size && !TARGET_PUSH_MEMORY
19629 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19630 [(set (match_dup 2) (match_dup 1))
19631 (set (match_dup 0) (match_dup 2))]
19632 "")
19633
19634 ;; Don't move an immediate directly to memory when the instruction
19635 ;; gets too big.
19636 (define_peephole2
19637 [(match_scratch:SI 1 "r")
19638 (set (match_operand:SI 0 "memory_operand" "")
19639 (const_int 0))]
19640 "! optimize_size
19641 && ! TARGET_USE_MOV0
19642 && TARGET_SPLIT_LONG_MOVES
19643 && get_attr_length (insn) >= ix86_cost->large_insn
19644 && peep2_regno_dead_p (0, FLAGS_REG)"
19645 [(parallel [(set (match_dup 1) (const_int 0))
19646 (clobber (reg:CC FLAGS_REG))])
19647 (set (match_dup 0) (match_dup 1))]
19648 "")
19649
19650 (define_peephole2
19651 [(match_scratch:HI 1 "r")
19652 (set (match_operand:HI 0 "memory_operand" "")
19653 (const_int 0))]
19654 "! optimize_size
19655 && ! TARGET_USE_MOV0
19656 && TARGET_SPLIT_LONG_MOVES
19657 && get_attr_length (insn) >= ix86_cost->large_insn
19658 && peep2_regno_dead_p (0, FLAGS_REG)"
19659 [(parallel [(set (match_dup 2) (const_int 0))
19660 (clobber (reg:CC FLAGS_REG))])
19661 (set (match_dup 0) (match_dup 1))]
19662 "operands[2] = gen_lowpart (SImode, operands[1]);")
19663
19664 (define_peephole2
19665 [(match_scratch:QI 1 "q")
19666 (set (match_operand:QI 0 "memory_operand" "")
19667 (const_int 0))]
19668 "! optimize_size
19669 && ! TARGET_USE_MOV0
19670 && TARGET_SPLIT_LONG_MOVES
19671 && get_attr_length (insn) >= ix86_cost->large_insn
19672 && peep2_regno_dead_p (0, FLAGS_REG)"
19673 [(parallel [(set (match_dup 2) (const_int 0))
19674 (clobber (reg:CC FLAGS_REG))])
19675 (set (match_dup 0) (match_dup 1))]
19676 "operands[2] = gen_lowpart (SImode, operands[1]);")
19677
19678 (define_peephole2
19679 [(match_scratch:SI 2 "r")
19680 (set (match_operand:SI 0 "memory_operand" "")
19681 (match_operand:SI 1 "immediate_operand" ""))]
19682 "! optimize_size
19683 && get_attr_length (insn) >= ix86_cost->large_insn
19684 && TARGET_SPLIT_LONG_MOVES"
19685 [(set (match_dup 2) (match_dup 1))
19686 (set (match_dup 0) (match_dup 2))]
19687 "")
19688
19689 (define_peephole2
19690 [(match_scratch:HI 2 "r")
19691 (set (match_operand:HI 0 "memory_operand" "")
19692 (match_operand:HI 1 "immediate_operand" ""))]
19693 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19694 && TARGET_SPLIT_LONG_MOVES"
19695 [(set (match_dup 2) (match_dup 1))
19696 (set (match_dup 0) (match_dup 2))]
19697 "")
19698
19699 (define_peephole2
19700 [(match_scratch:QI 2 "q")
19701 (set (match_operand:QI 0 "memory_operand" "")
19702 (match_operand:QI 1 "immediate_operand" ""))]
19703 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19704 && TARGET_SPLIT_LONG_MOVES"
19705 [(set (match_dup 2) (match_dup 1))
19706 (set (match_dup 0) (match_dup 2))]
19707 "")
19708
19709 ;; Don't compare memory with zero, load and use a test instead.
19710 (define_peephole2
19711 [(set (match_operand 0 "flags_reg_operand" "")
19712 (match_operator 1 "compare_operator"
19713 [(match_operand:SI 2 "memory_operand" "")
19714 (const_int 0)]))
19715 (match_scratch:SI 3 "r")]
19716 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19717 [(set (match_dup 3) (match_dup 2))
19718 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19719 "")
19720
19721 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19722 ;; Don't split NOTs with a displacement operand, because resulting XOR
19723 ;; will not be pairable anyway.
19724 ;;
19725 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19726 ;; represented using a modRM byte. The XOR replacement is long decoded,
19727 ;; so this split helps here as well.
19728 ;;
19729 ;; Note: Can't do this as a regular split because we can't get proper
19730 ;; lifetime information then.
19731
19732 (define_peephole2
19733 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19734 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19735 "!optimize_size
19736 && peep2_regno_dead_p (0, FLAGS_REG)
19737 && ((TARGET_NOT_UNPAIRABLE
19738 && (!MEM_P (operands[0])
19739 || !memory_displacement_operand (operands[0], SImode)))
19740 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))"
19741 [(parallel [(set (match_dup 0)
19742 (xor:SI (match_dup 1) (const_int -1)))
19743 (clobber (reg:CC FLAGS_REG))])]
19744 "")
19745
19746 (define_peephole2
19747 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19748 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19749 "!optimize_size
19750 && peep2_regno_dead_p (0, FLAGS_REG)
19751 && ((TARGET_NOT_UNPAIRABLE
19752 && (!MEM_P (operands[0])
19753 || !memory_displacement_operand (operands[0], HImode)))
19754 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))"
19755 [(parallel [(set (match_dup 0)
19756 (xor:HI (match_dup 1) (const_int -1)))
19757 (clobber (reg:CC FLAGS_REG))])]
19758 "")
19759
19760 (define_peephole2
19761 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19762 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19763 "!optimize_size
19764 && peep2_regno_dead_p (0, FLAGS_REG)
19765 && ((TARGET_NOT_UNPAIRABLE
19766 && (!MEM_P (operands[0])
19767 || !memory_displacement_operand (operands[0], QImode)))
19768 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))"
19769 [(parallel [(set (match_dup 0)
19770 (xor:QI (match_dup 1) (const_int -1)))
19771 (clobber (reg:CC FLAGS_REG))])]
19772 "")
19773
19774 ;; Non pairable "test imm, reg" instructions can be translated to
19775 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19776 ;; byte opcode instead of two, have a short form for byte operands),
19777 ;; so do it for other CPUs as well. Given that the value was dead,
19778 ;; this should not create any new dependencies. Pass on the sub-word
19779 ;; versions if we're concerned about partial register stalls.
19780
19781 (define_peephole2
19782 [(set (match_operand 0 "flags_reg_operand" "")
19783 (match_operator 1 "compare_operator"
19784 [(and:SI (match_operand:SI 2 "register_operand" "")
19785 (match_operand:SI 3 "immediate_operand" ""))
19786 (const_int 0)]))]
19787 "ix86_match_ccmode (insn, CCNOmode)
19788 && (true_regnum (operands[2]) != 0
19789 || satisfies_constraint_K (operands[3]))
19790 && peep2_reg_dead_p (1, operands[2])"
19791 [(parallel
19792 [(set (match_dup 0)
19793 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19794 (const_int 0)]))
19795 (set (match_dup 2)
19796 (and:SI (match_dup 2) (match_dup 3)))])]
19797 "")
19798
19799 ;; We don't need to handle HImode case, because it will be promoted to SImode
19800 ;; on ! TARGET_PARTIAL_REG_STALL
19801
19802 (define_peephole2
19803 [(set (match_operand 0 "flags_reg_operand" "")
19804 (match_operator 1 "compare_operator"
19805 [(and:QI (match_operand:QI 2 "register_operand" "")
19806 (match_operand:QI 3 "immediate_operand" ""))
19807 (const_int 0)]))]
19808 "! TARGET_PARTIAL_REG_STALL
19809 && ix86_match_ccmode (insn, CCNOmode)
19810 && true_regnum (operands[2]) != 0
19811 && peep2_reg_dead_p (1, operands[2])"
19812 [(parallel
19813 [(set (match_dup 0)
19814 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19815 (const_int 0)]))
19816 (set (match_dup 2)
19817 (and:QI (match_dup 2) (match_dup 3)))])]
19818 "")
19819
19820 (define_peephole2
19821 [(set (match_operand 0 "flags_reg_operand" "")
19822 (match_operator 1 "compare_operator"
19823 [(and:SI
19824 (zero_extract:SI
19825 (match_operand 2 "ext_register_operand" "")
19826 (const_int 8)
19827 (const_int 8))
19828 (match_operand 3 "const_int_operand" ""))
19829 (const_int 0)]))]
19830 "! TARGET_PARTIAL_REG_STALL
19831 && ix86_match_ccmode (insn, CCNOmode)
19832 && true_regnum (operands[2]) != 0
19833 && peep2_reg_dead_p (1, operands[2])"
19834 [(parallel [(set (match_dup 0)
19835 (match_op_dup 1
19836 [(and:SI
19837 (zero_extract:SI
19838 (match_dup 2)
19839 (const_int 8)
19840 (const_int 8))
19841 (match_dup 3))
19842 (const_int 0)]))
19843 (set (zero_extract:SI (match_dup 2)
19844 (const_int 8)
19845 (const_int 8))
19846 (and:SI
19847 (zero_extract:SI
19848 (match_dup 2)
19849 (const_int 8)
19850 (const_int 8))
19851 (match_dup 3)))])]
19852 "")
19853
19854 ;; Don't do logical operations with memory inputs.
19855 (define_peephole2
19856 [(match_scratch:SI 2 "r")
19857 (parallel [(set (match_operand:SI 0 "register_operand" "")
19858 (match_operator:SI 3 "arith_or_logical_operator"
19859 [(match_dup 0)
19860 (match_operand:SI 1 "memory_operand" "")]))
19861 (clobber (reg:CC FLAGS_REG))])]
19862 "! optimize_size && ! TARGET_READ_MODIFY"
19863 [(set (match_dup 2) (match_dup 1))
19864 (parallel [(set (match_dup 0)
19865 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19866 (clobber (reg:CC FLAGS_REG))])]
19867 "")
19868
19869 (define_peephole2
19870 [(match_scratch:SI 2 "r")
19871 (parallel [(set (match_operand:SI 0 "register_operand" "")
19872 (match_operator:SI 3 "arith_or_logical_operator"
19873 [(match_operand:SI 1 "memory_operand" "")
19874 (match_dup 0)]))
19875 (clobber (reg:CC FLAGS_REG))])]
19876 "! optimize_size && ! TARGET_READ_MODIFY"
19877 [(set (match_dup 2) (match_dup 1))
19878 (parallel [(set (match_dup 0)
19879 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19880 (clobber (reg:CC FLAGS_REG))])]
19881 "")
19882
19883 ; Don't do logical operations with memory outputs
19884 ;
19885 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19886 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19887 ; the same decoder scheduling characteristics as the original.
19888
19889 (define_peephole2
19890 [(match_scratch:SI 2 "r")
19891 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19892 (match_operator:SI 3 "arith_or_logical_operator"
19893 [(match_dup 0)
19894 (match_operand:SI 1 "nonmemory_operand" "")]))
19895 (clobber (reg:CC FLAGS_REG))])]
19896 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19897 [(set (match_dup 2) (match_dup 0))
19898 (parallel [(set (match_dup 2)
19899 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19900 (clobber (reg:CC FLAGS_REG))])
19901 (set (match_dup 0) (match_dup 2))]
19902 "")
19903
19904 (define_peephole2
19905 [(match_scratch:SI 2 "r")
19906 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19907 (match_operator:SI 3 "arith_or_logical_operator"
19908 [(match_operand:SI 1 "nonmemory_operand" "")
19909 (match_dup 0)]))
19910 (clobber (reg:CC FLAGS_REG))])]
19911 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19912 [(set (match_dup 2) (match_dup 0))
19913 (parallel [(set (match_dup 2)
19914 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19915 (clobber (reg:CC FLAGS_REG))])
19916 (set (match_dup 0) (match_dup 2))]
19917 "")
19918
19919 ;; Attempt to always use XOR for zeroing registers.
19920 (define_peephole2
19921 [(set (match_operand 0 "register_operand" "")
19922 (match_operand 1 "const0_operand" ""))]
19923 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19924 && (! TARGET_USE_MOV0 || optimize_size)
19925 && GENERAL_REG_P (operands[0])
19926 && peep2_regno_dead_p (0, FLAGS_REG)"
19927 [(parallel [(set (match_dup 0) (const_int 0))
19928 (clobber (reg:CC FLAGS_REG))])]
19929 {
19930 operands[0] = gen_lowpart (word_mode, operands[0]);
19931 })
19932
19933 (define_peephole2
19934 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19935 (const_int 0))]
19936 "(GET_MODE (operands[0]) == QImode
19937 || GET_MODE (operands[0]) == HImode)
19938 && (! TARGET_USE_MOV0 || optimize_size)
19939 && peep2_regno_dead_p (0, FLAGS_REG)"
19940 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19941 (clobber (reg:CC FLAGS_REG))])])
19942
19943 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19944 (define_peephole2
19945 [(set (match_operand 0 "register_operand" "")
19946 (const_int -1))]
19947 "(GET_MODE (operands[0]) == HImode
19948 || GET_MODE (operands[0]) == SImode
19949 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19950 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
19951 && peep2_regno_dead_p (0, FLAGS_REG)"
19952 [(parallel [(set (match_dup 0) (const_int -1))
19953 (clobber (reg:CC FLAGS_REG))])]
19954 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19955 operands[0]);")
19956
19957 ;; Attempt to convert simple leas to adds. These can be created by
19958 ;; move expanders.
19959 (define_peephole2
19960 [(set (match_operand:SI 0 "register_operand" "")
19961 (plus:SI (match_dup 0)
19962 (match_operand:SI 1 "nonmemory_operand" "")))]
19963 "peep2_regno_dead_p (0, FLAGS_REG)"
19964 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19965 (clobber (reg:CC FLAGS_REG))])]
19966 "")
19967
19968 (define_peephole2
19969 [(set (match_operand:SI 0 "register_operand" "")
19970 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19971 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19972 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19973 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19974 (clobber (reg:CC FLAGS_REG))])]
19975 "operands[2] = gen_lowpart (SImode, operands[2]);")
19976
19977 (define_peephole2
19978 [(set (match_operand:DI 0 "register_operand" "")
19979 (plus:DI (match_dup 0)
19980 (match_operand:DI 1 "x86_64_general_operand" "")))]
19981 "peep2_regno_dead_p (0, FLAGS_REG)"
19982 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19983 (clobber (reg:CC FLAGS_REG))])]
19984 "")
19985
19986 (define_peephole2
19987 [(set (match_operand:SI 0 "register_operand" "")
19988 (mult:SI (match_dup 0)
19989 (match_operand:SI 1 "const_int_operand" "")))]
19990 "exact_log2 (INTVAL (operands[1])) >= 0
19991 && peep2_regno_dead_p (0, FLAGS_REG)"
19992 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19993 (clobber (reg:CC FLAGS_REG))])]
19994 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19995
19996 (define_peephole2
19997 [(set (match_operand:DI 0 "register_operand" "")
19998 (mult:DI (match_dup 0)
19999 (match_operand:DI 1 "const_int_operand" "")))]
20000 "exact_log2 (INTVAL (operands[1])) >= 0
20001 && peep2_regno_dead_p (0, FLAGS_REG)"
20002 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20003 (clobber (reg:CC FLAGS_REG))])]
20004 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20005
20006 (define_peephole2
20007 [(set (match_operand:SI 0 "register_operand" "")
20008 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20009 (match_operand:DI 2 "const_int_operand" "")) 0))]
20010 "exact_log2 (INTVAL (operands[2])) >= 0
20011 && REGNO (operands[0]) == REGNO (operands[1])
20012 && peep2_regno_dead_p (0, FLAGS_REG)"
20013 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20014 (clobber (reg:CC FLAGS_REG))])]
20015 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20016
20017 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20018 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20019 ;; many CPUs it is also faster, since special hardware to avoid esp
20020 ;; dependencies is present.
20021
20022 ;; While some of these conversions may be done using splitters, we use peepholes
20023 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20024
20025 ;; Convert prologue esp subtractions to push.
20026 ;; We need register to push. In order to keep verify_flow_info happy we have
20027 ;; two choices
20028 ;; - use scratch and clobber it in order to avoid dependencies
20029 ;; - use already live register
20030 ;; We can't use the second way right now, since there is no reliable way how to
20031 ;; verify that given register is live. First choice will also most likely in
20032 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20033 ;; call clobbered registers are dead. We may want to use base pointer as an
20034 ;; alternative when no register is available later.
20035
20036 (define_peephole2
20037 [(match_scratch:SI 0 "r")
20038 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20039 (clobber (reg:CC FLAGS_REG))
20040 (clobber (mem:BLK (scratch)))])]
20041 "optimize_size || !TARGET_SUB_ESP_4"
20042 [(clobber (match_dup 0))
20043 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20044 (clobber (mem:BLK (scratch)))])])
20045
20046 (define_peephole2
20047 [(match_scratch:SI 0 "r")
20048 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20049 (clobber (reg:CC FLAGS_REG))
20050 (clobber (mem:BLK (scratch)))])]
20051 "optimize_size || !TARGET_SUB_ESP_8"
20052 [(clobber (match_dup 0))
20053 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20054 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20055 (clobber (mem:BLK (scratch)))])])
20056
20057 ;; Convert esp subtractions to push.
20058 (define_peephole2
20059 [(match_scratch:SI 0 "r")
20060 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20061 (clobber (reg:CC FLAGS_REG))])]
20062 "optimize_size || !TARGET_SUB_ESP_4"
20063 [(clobber (match_dup 0))
20064 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20065
20066 (define_peephole2
20067 [(match_scratch:SI 0 "r")
20068 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20069 (clobber (reg:CC FLAGS_REG))])]
20070 "optimize_size || !TARGET_SUB_ESP_8"
20071 [(clobber (match_dup 0))
20072 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20073 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20074
20075 ;; Convert epilogue deallocator to pop.
20076 (define_peephole2
20077 [(match_scratch:SI 0 "r")
20078 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20079 (clobber (reg:CC FLAGS_REG))
20080 (clobber (mem:BLK (scratch)))])]
20081 "optimize_size || !TARGET_ADD_ESP_4"
20082 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20083 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20084 (clobber (mem:BLK (scratch)))])]
20085 "")
20086
20087 ;; Two pops case is tricky, since pop causes dependency on destination register.
20088 ;; We use two registers if available.
20089 (define_peephole2
20090 [(match_scratch:SI 0 "r")
20091 (match_scratch:SI 1 "r")
20092 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20093 (clobber (reg:CC FLAGS_REG))
20094 (clobber (mem:BLK (scratch)))])]
20095 "optimize_size || !TARGET_ADD_ESP_8"
20096 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20097 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20098 (clobber (mem:BLK (scratch)))])
20099 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20100 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20101 "")
20102
20103 (define_peephole2
20104 [(match_scratch:SI 0 "r")
20105 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20106 (clobber (reg:CC FLAGS_REG))
20107 (clobber (mem:BLK (scratch)))])]
20108 "optimize_size"
20109 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20110 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20111 (clobber (mem:BLK (scratch)))])
20112 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20113 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20114 "")
20115
20116 ;; Convert esp additions to pop.
20117 (define_peephole2
20118 [(match_scratch:SI 0 "r")
20119 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20120 (clobber (reg:CC FLAGS_REG))])]
20121 ""
20122 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20123 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20124 "")
20125
20126 ;; Two pops case is tricky, since pop causes dependency on destination register.
20127 ;; We use two registers if available.
20128 (define_peephole2
20129 [(match_scratch:SI 0 "r")
20130 (match_scratch:SI 1 "r")
20131 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20132 (clobber (reg:CC FLAGS_REG))])]
20133 ""
20134 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20135 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20136 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20137 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20138 "")
20139
20140 (define_peephole2
20141 [(match_scratch:SI 0 "r")
20142 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20143 (clobber (reg:CC FLAGS_REG))])]
20144 "optimize_size"
20145 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20146 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20147 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20148 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20149 "")
20150 \f
20151 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20152 ;; required and register dies. Similarly for 128 to plus -128.
20153 (define_peephole2
20154 [(set (match_operand 0 "flags_reg_operand" "")
20155 (match_operator 1 "compare_operator"
20156 [(match_operand 2 "register_operand" "")
20157 (match_operand 3 "const_int_operand" "")]))]
20158 "(INTVAL (operands[3]) == -1
20159 || INTVAL (operands[3]) == 1
20160 || INTVAL (operands[3]) == 128)
20161 && ix86_match_ccmode (insn, CCGCmode)
20162 && peep2_reg_dead_p (1, operands[2])"
20163 [(parallel [(set (match_dup 0)
20164 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20165 (clobber (match_dup 2))])]
20166 "")
20167 \f
20168 (define_peephole2
20169 [(match_scratch:DI 0 "r")
20170 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20171 (clobber (reg:CC FLAGS_REG))
20172 (clobber (mem:BLK (scratch)))])]
20173 "optimize_size || !TARGET_SUB_ESP_4"
20174 [(clobber (match_dup 0))
20175 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20176 (clobber (mem:BLK (scratch)))])])
20177
20178 (define_peephole2
20179 [(match_scratch:DI 0 "r")
20180 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20181 (clobber (reg:CC FLAGS_REG))
20182 (clobber (mem:BLK (scratch)))])]
20183 "optimize_size || !TARGET_SUB_ESP_8"
20184 [(clobber (match_dup 0))
20185 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20186 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20187 (clobber (mem:BLK (scratch)))])])
20188
20189 ;; Convert esp subtractions to push.
20190 (define_peephole2
20191 [(match_scratch:DI 0 "r")
20192 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20193 (clobber (reg:CC FLAGS_REG))])]
20194 "optimize_size || !TARGET_SUB_ESP_4"
20195 [(clobber (match_dup 0))
20196 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20197
20198 (define_peephole2
20199 [(match_scratch:DI 0 "r")
20200 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20201 (clobber (reg:CC FLAGS_REG))])]
20202 "optimize_size || !TARGET_SUB_ESP_8"
20203 [(clobber (match_dup 0))
20204 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20205 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20206
20207 ;; Convert epilogue deallocator to pop.
20208 (define_peephole2
20209 [(match_scratch:DI 0 "r")
20210 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20211 (clobber (reg:CC FLAGS_REG))
20212 (clobber (mem:BLK (scratch)))])]
20213 "optimize_size || !TARGET_ADD_ESP_4"
20214 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20215 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20216 (clobber (mem:BLK (scratch)))])]
20217 "")
20218
20219 ;; Two pops case is tricky, since pop causes dependency on destination register.
20220 ;; We use two registers if available.
20221 (define_peephole2
20222 [(match_scratch:DI 0 "r")
20223 (match_scratch:DI 1 "r")
20224 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20225 (clobber (reg:CC FLAGS_REG))
20226 (clobber (mem:BLK (scratch)))])]
20227 "optimize_size || !TARGET_ADD_ESP_8"
20228 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20229 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20230 (clobber (mem:BLK (scratch)))])
20231 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20232 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20233 "")
20234
20235 (define_peephole2
20236 [(match_scratch:DI 0 "r")
20237 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20238 (clobber (reg:CC FLAGS_REG))
20239 (clobber (mem:BLK (scratch)))])]
20240 "optimize_size"
20241 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20242 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20243 (clobber (mem:BLK (scratch)))])
20244 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20245 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20246 "")
20247
20248 ;; Convert esp additions to pop.
20249 (define_peephole2
20250 [(match_scratch:DI 0 "r")
20251 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20252 (clobber (reg:CC FLAGS_REG))])]
20253 ""
20254 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20255 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20256 "")
20257
20258 ;; Two pops case is tricky, since pop causes dependency on destination register.
20259 ;; We use two registers if available.
20260 (define_peephole2
20261 [(match_scratch:DI 0 "r")
20262 (match_scratch:DI 1 "r")
20263 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20264 (clobber (reg:CC FLAGS_REG))])]
20265 ""
20266 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20267 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20268 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20269 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20270 "")
20271
20272 (define_peephole2
20273 [(match_scratch:DI 0 "r")
20274 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20275 (clobber (reg:CC FLAGS_REG))])]
20276 "optimize_size"
20277 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20278 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20279 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20280 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20281 "")
20282 \f
20283 ;; Convert imul by three, five and nine into lea
20284 (define_peephole2
20285 [(parallel
20286 [(set (match_operand:SI 0 "register_operand" "")
20287 (mult:SI (match_operand:SI 1 "register_operand" "")
20288 (match_operand:SI 2 "const_int_operand" "")))
20289 (clobber (reg:CC FLAGS_REG))])]
20290 "INTVAL (operands[2]) == 3
20291 || INTVAL (operands[2]) == 5
20292 || INTVAL (operands[2]) == 9"
20293 [(set (match_dup 0)
20294 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20295 (match_dup 1)))]
20296 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20297
20298 (define_peephole2
20299 [(parallel
20300 [(set (match_operand:SI 0 "register_operand" "")
20301 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20302 (match_operand:SI 2 "const_int_operand" "")))
20303 (clobber (reg:CC FLAGS_REG))])]
20304 "!optimize_size
20305 && (INTVAL (operands[2]) == 3
20306 || INTVAL (operands[2]) == 5
20307 || INTVAL (operands[2]) == 9)"
20308 [(set (match_dup 0) (match_dup 1))
20309 (set (match_dup 0)
20310 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20311 (match_dup 0)))]
20312 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20313
20314 (define_peephole2
20315 [(parallel
20316 [(set (match_operand:DI 0 "register_operand" "")
20317 (mult:DI (match_operand:DI 1 "register_operand" "")
20318 (match_operand:DI 2 "const_int_operand" "")))
20319 (clobber (reg:CC FLAGS_REG))])]
20320 "TARGET_64BIT
20321 && (INTVAL (operands[2]) == 3
20322 || INTVAL (operands[2]) == 5
20323 || INTVAL (operands[2]) == 9)"
20324 [(set (match_dup 0)
20325 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20326 (match_dup 1)))]
20327 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20328
20329 (define_peephole2
20330 [(parallel
20331 [(set (match_operand:DI 0 "register_operand" "")
20332 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20333 (match_operand:DI 2 "const_int_operand" "")))
20334 (clobber (reg:CC FLAGS_REG))])]
20335 "TARGET_64BIT
20336 && !optimize_size
20337 && (INTVAL (operands[2]) == 3
20338 || INTVAL (operands[2]) == 5
20339 || INTVAL (operands[2]) == 9)"
20340 [(set (match_dup 0) (match_dup 1))
20341 (set (match_dup 0)
20342 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20343 (match_dup 0)))]
20344 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20345
20346 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20347 ;; imul $32bit_imm, reg, reg is direct decoded.
20348 (define_peephole2
20349 [(match_scratch:DI 3 "r")
20350 (parallel [(set (match_operand:DI 0 "register_operand" "")
20351 (mult:DI (match_operand:DI 1 "memory_operand" "")
20352 (match_operand:DI 2 "immediate_operand" "")))
20353 (clobber (reg:CC FLAGS_REG))])]
20354 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20355 && !satisfies_constraint_K (operands[2])"
20356 [(set (match_dup 3) (match_dup 1))
20357 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20358 (clobber (reg:CC FLAGS_REG))])]
20359 "")
20360
20361 (define_peephole2
20362 [(match_scratch:SI 3 "r")
20363 (parallel [(set (match_operand:SI 0 "register_operand" "")
20364 (mult:SI (match_operand:SI 1 "memory_operand" "")
20365 (match_operand:SI 2 "immediate_operand" "")))
20366 (clobber (reg:CC FLAGS_REG))])]
20367 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20368 && !satisfies_constraint_K (operands[2])"
20369 [(set (match_dup 3) (match_dup 1))
20370 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20371 (clobber (reg:CC FLAGS_REG))])]
20372 "")
20373
20374 (define_peephole2
20375 [(match_scratch:SI 3 "r")
20376 (parallel [(set (match_operand:DI 0 "register_operand" "")
20377 (zero_extend:DI
20378 (mult:SI (match_operand:SI 1 "memory_operand" "")
20379 (match_operand:SI 2 "immediate_operand" ""))))
20380 (clobber (reg:CC FLAGS_REG))])]
20381 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20382 && !satisfies_constraint_K (operands[2])"
20383 [(set (match_dup 3) (match_dup 1))
20384 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20385 (clobber (reg:CC FLAGS_REG))])]
20386 "")
20387
20388 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20389 ;; Convert it into imul reg, reg
20390 ;; It would be better to force assembler to encode instruction using long
20391 ;; immediate, but there is apparently no way to do so.
20392 (define_peephole2
20393 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20394 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20395 (match_operand:DI 2 "const_int_operand" "")))
20396 (clobber (reg:CC FLAGS_REG))])
20397 (match_scratch:DI 3 "r")]
20398 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20399 && satisfies_constraint_K (operands[2])"
20400 [(set (match_dup 3) (match_dup 2))
20401 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20402 (clobber (reg:CC FLAGS_REG))])]
20403 {
20404 if (!rtx_equal_p (operands[0], operands[1]))
20405 emit_move_insn (operands[0], operands[1]);
20406 })
20407
20408 (define_peephole2
20409 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20410 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20411 (match_operand:SI 2 "const_int_operand" "")))
20412 (clobber (reg:CC FLAGS_REG))])
20413 (match_scratch:SI 3 "r")]
20414 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20415 && satisfies_constraint_K (operands[2])"
20416 [(set (match_dup 3) (match_dup 2))
20417 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20418 (clobber (reg:CC FLAGS_REG))])]
20419 {
20420 if (!rtx_equal_p (operands[0], operands[1]))
20421 emit_move_insn (operands[0], operands[1]);
20422 })
20423
20424 (define_peephole2
20425 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20426 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20427 (match_operand:HI 2 "immediate_operand" "")))
20428 (clobber (reg:CC FLAGS_REG))])
20429 (match_scratch:HI 3 "r")]
20430 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20431 [(set (match_dup 3) (match_dup 2))
20432 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20433 (clobber (reg:CC FLAGS_REG))])]
20434 {
20435 if (!rtx_equal_p (operands[0], operands[1]))
20436 emit_move_insn (operands[0], operands[1]);
20437 })
20438
20439 ;; After splitting up read-modify operations, array accesses with memory
20440 ;; operands might end up in form:
20441 ;; sall $2, %eax
20442 ;; movl 4(%esp), %edx
20443 ;; addl %edx, %eax
20444 ;; instead of pre-splitting:
20445 ;; sall $2, %eax
20446 ;; addl 4(%esp), %eax
20447 ;; Turn it into:
20448 ;; movl 4(%esp), %edx
20449 ;; leal (%edx,%eax,4), %eax
20450
20451 (define_peephole2
20452 [(parallel [(set (match_operand 0 "register_operand" "")
20453 (ashift (match_operand 1 "register_operand" "")
20454 (match_operand 2 "const_int_operand" "")))
20455 (clobber (reg:CC FLAGS_REG))])
20456 (set (match_operand 3 "register_operand")
20457 (match_operand 4 "x86_64_general_operand" ""))
20458 (parallel [(set (match_operand 5 "register_operand" "")
20459 (plus (match_operand 6 "register_operand" "")
20460 (match_operand 7 "register_operand" "")))
20461 (clobber (reg:CC FLAGS_REG))])]
20462 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20463 /* Validate MODE for lea. */
20464 && ((!TARGET_PARTIAL_REG_STALL
20465 && (GET_MODE (operands[0]) == QImode
20466 || GET_MODE (operands[0]) == HImode))
20467 || GET_MODE (operands[0]) == SImode
20468 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20469 /* We reorder load and the shift. */
20470 && !rtx_equal_p (operands[1], operands[3])
20471 && !reg_overlap_mentioned_p (operands[0], operands[4])
20472 /* Last PLUS must consist of operand 0 and 3. */
20473 && !rtx_equal_p (operands[0], operands[3])
20474 && (rtx_equal_p (operands[3], operands[6])
20475 || rtx_equal_p (operands[3], operands[7]))
20476 && (rtx_equal_p (operands[0], operands[6])
20477 || rtx_equal_p (operands[0], operands[7]))
20478 /* The intermediate operand 0 must die or be same as output. */
20479 && (rtx_equal_p (operands[0], operands[5])
20480 || peep2_reg_dead_p (3, operands[0]))"
20481 [(set (match_dup 3) (match_dup 4))
20482 (set (match_dup 0) (match_dup 1))]
20483 {
20484 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20485 int scale = 1 << INTVAL (operands[2]);
20486 rtx index = gen_lowpart (Pmode, operands[1]);
20487 rtx base = gen_lowpart (Pmode, operands[3]);
20488 rtx dest = gen_lowpart (mode, operands[5]);
20489
20490 operands[1] = gen_rtx_PLUS (Pmode, base,
20491 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20492 if (mode != Pmode)
20493 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20494 operands[0] = dest;
20495 })
20496 \f
20497 ;; Call-value patterns last so that the wildcard operand does not
20498 ;; disrupt insn-recog's switch tables.
20499
20500 (define_insn "*call_value_pop_0"
20501 [(set (match_operand 0 "" "")
20502 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20503 (match_operand:SI 2 "" "")))
20504 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20505 (match_operand:SI 3 "immediate_operand" "")))]
20506 "!TARGET_64BIT"
20507 {
20508 if (SIBLING_CALL_P (insn))
20509 return "jmp\t%P1";
20510 else
20511 return "call\t%P1";
20512 }
20513 [(set_attr "type" "callv")])
20514
20515 (define_insn "*call_value_pop_1"
20516 [(set (match_operand 0 "" "")
20517 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20518 (match_operand:SI 2 "" "")))
20519 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20520 (match_operand:SI 3 "immediate_operand" "i")))]
20521 "!TARGET_64BIT"
20522 {
20523 if (constant_call_address_operand (operands[1], Pmode))
20524 {
20525 if (SIBLING_CALL_P (insn))
20526 return "jmp\t%P1";
20527 else
20528 return "call\t%P1";
20529 }
20530 if (SIBLING_CALL_P (insn))
20531 return "jmp\t%A1";
20532 else
20533 return "call\t%A1";
20534 }
20535 [(set_attr "type" "callv")])
20536
20537 (define_insn "*call_value_0"
20538 [(set (match_operand 0 "" "")
20539 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20540 (match_operand:SI 2 "" "")))]
20541 "!TARGET_64BIT"
20542 {
20543 if (SIBLING_CALL_P (insn))
20544 return "jmp\t%P1";
20545 else
20546 return "call\t%P1";
20547 }
20548 [(set_attr "type" "callv")])
20549
20550 (define_insn "*call_value_0_rex64"
20551 [(set (match_operand 0 "" "")
20552 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20553 (match_operand:DI 2 "const_int_operand" "")))]
20554 "TARGET_64BIT"
20555 {
20556 if (SIBLING_CALL_P (insn))
20557 return "jmp\t%P1";
20558 else
20559 return "call\t%P1";
20560 }
20561 [(set_attr "type" "callv")])
20562
20563 (define_insn "*call_value_1"
20564 [(set (match_operand 0 "" "")
20565 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20566 (match_operand:SI 2 "" "")))]
20567 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20568 {
20569 if (constant_call_address_operand (operands[1], Pmode))
20570 return "call\t%P1";
20571 return "call\t%A1";
20572 }
20573 [(set_attr "type" "callv")])
20574
20575 (define_insn "*sibcall_value_1"
20576 [(set (match_operand 0 "" "")
20577 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20578 (match_operand:SI 2 "" "")))]
20579 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20580 {
20581 if (constant_call_address_operand (operands[1], Pmode))
20582 return "jmp\t%P1";
20583 return "jmp\t%A1";
20584 }
20585 [(set_attr "type" "callv")])
20586
20587 (define_insn "*call_value_1_rex64"
20588 [(set (match_operand 0 "" "")
20589 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20590 (match_operand:DI 2 "" "")))]
20591 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20592 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20593 {
20594 if (constant_call_address_operand (operands[1], Pmode))
20595 return "call\t%P1";
20596 return "call\t%A1";
20597 }
20598 [(set_attr "type" "callv")])
20599
20600 (define_insn "*call_value_1_rex64_large"
20601 [(set (match_operand 0 "" "")
20602 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20603 (match_operand:DI 2 "" "")))]
20604 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20605 "call\t%A1"
20606 [(set_attr "type" "callv")])
20607
20608 (define_insn "*sibcall_value_1_rex64"
20609 [(set (match_operand 0 "" "")
20610 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20611 (match_operand:DI 2 "" "")))]
20612 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20613 "jmp\t%P1"
20614 [(set_attr "type" "callv")])
20615
20616 (define_insn "*sibcall_value_1_rex64_v"
20617 [(set (match_operand 0 "" "")
20618 (call (mem:QI (reg:DI R11_REG))
20619 (match_operand:DI 1 "" "")))]
20620 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20621 "jmp\t*%%r11"
20622 [(set_attr "type" "callv")])
20623 \f
20624 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20625 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20626 ;; caught for use by garbage collectors and the like. Using an insn that
20627 ;; maps to SIGILL makes it more likely the program will rightfully die.
20628 ;; Keeping with tradition, "6" is in honor of #UD.
20629 (define_insn "trap"
20630 [(trap_if (const_int 1) (const_int 6))]
20631 ""
20632 { return ASM_SHORT "0x0b0f"; }
20633 [(set_attr "length" "2")])
20634
20635 (define_expand "sse_prologue_save"
20636 [(parallel [(set (match_operand:BLK 0 "" "")
20637 (unspec:BLK [(reg:DI 21)
20638 (reg:DI 22)
20639 (reg:DI 23)
20640 (reg:DI 24)
20641 (reg:DI 25)
20642 (reg:DI 26)
20643 (reg:DI 27)
20644 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20645 (use (match_operand:DI 1 "register_operand" ""))
20646 (use (match_operand:DI 2 "immediate_operand" ""))
20647 (use (label_ref:DI (match_operand 3 "" "")))])]
20648 "TARGET_64BIT"
20649 "")
20650
20651 (define_insn "*sse_prologue_save_insn"
20652 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20653 (match_operand:DI 4 "const_int_operand" "n")))
20654 (unspec:BLK [(reg:DI 21)
20655 (reg:DI 22)
20656 (reg:DI 23)
20657 (reg:DI 24)
20658 (reg:DI 25)
20659 (reg:DI 26)
20660 (reg:DI 27)
20661 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20662 (use (match_operand:DI 1 "register_operand" "r"))
20663 (use (match_operand:DI 2 "const_int_operand" "i"))
20664 (use (label_ref:DI (match_operand 3 "" "X")))]
20665 "TARGET_64BIT
20666 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20667 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20668 "*
20669 {
20670 int i;
20671 operands[0] = gen_rtx_MEM (Pmode,
20672 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20673 output_asm_insn (\"jmp\\t%A1\", operands);
20674 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20675 {
20676 operands[4] = adjust_address (operands[0], DImode, i*16);
20677 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20678 PUT_MODE (operands[4], TImode);
20679 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20680 output_asm_insn (\"rex\", operands);
20681 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20682 }
20683 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20684 CODE_LABEL_NUMBER (operands[3]));
20685 return \"\";
20686 }
20687 "
20688 [(set_attr "type" "other")
20689 (set_attr "length_immediate" "0")
20690 (set_attr "length_address" "0")
20691 (set_attr "length" "135")
20692 (set_attr "memory" "store")
20693 (set_attr "modrm" "0")
20694 (set_attr "mode" "DI")])
20695
20696 (define_expand "prefetch"
20697 [(prefetch (match_operand 0 "address_operand" "")
20698 (match_operand:SI 1 "const_int_operand" "")
20699 (match_operand:SI 2 "const_int_operand" ""))]
20700 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20701 {
20702 int rw = INTVAL (operands[1]);
20703 int locality = INTVAL (operands[2]);
20704
20705 gcc_assert (rw == 0 || rw == 1);
20706 gcc_assert (locality >= 0 && locality <= 3);
20707 gcc_assert (GET_MODE (operands[0]) == Pmode
20708 || GET_MODE (operands[0]) == VOIDmode);
20709
20710 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20711 supported by SSE counterpart or the SSE prefetch is not available
20712 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20713 of locality. */
20714 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20715 operands[2] = GEN_INT (3);
20716 else
20717 operands[1] = const0_rtx;
20718 })
20719
20720 (define_insn "*prefetch_sse"
20721 [(prefetch (match_operand:SI 0 "address_operand" "p")
20722 (const_int 0)
20723 (match_operand:SI 1 "const_int_operand" ""))]
20724 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20725 {
20726 static const char * const patterns[4] = {
20727 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20728 };
20729
20730 int locality = INTVAL (operands[1]);
20731 gcc_assert (locality >= 0 && locality <= 3);
20732
20733 return patterns[locality];
20734 }
20735 [(set_attr "type" "sse")
20736 (set_attr "memory" "none")])
20737
20738 (define_insn "*prefetch_sse_rex"
20739 [(prefetch (match_operand:DI 0 "address_operand" "p")
20740 (const_int 0)
20741 (match_operand:SI 1 "const_int_operand" ""))]
20742 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20743 {
20744 static const char * const patterns[4] = {
20745 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20746 };
20747
20748 int locality = INTVAL (operands[1]);
20749 gcc_assert (locality >= 0 && locality <= 3);
20750
20751 return patterns[locality];
20752 }
20753 [(set_attr "type" "sse")
20754 (set_attr "memory" "none")])
20755
20756 (define_insn "*prefetch_3dnow"
20757 [(prefetch (match_operand:SI 0 "address_operand" "p")
20758 (match_operand:SI 1 "const_int_operand" "n")
20759 (const_int 3))]
20760 "TARGET_3DNOW && !TARGET_64BIT"
20761 {
20762 if (INTVAL (operands[1]) == 0)
20763 return "prefetch\t%a0";
20764 else
20765 return "prefetchw\t%a0";
20766 }
20767 [(set_attr "type" "mmx")
20768 (set_attr "memory" "none")])
20769
20770 (define_insn "*prefetch_3dnow_rex"
20771 [(prefetch (match_operand:DI 0 "address_operand" "p")
20772 (match_operand:SI 1 "const_int_operand" "n")
20773 (const_int 3))]
20774 "TARGET_3DNOW && TARGET_64BIT"
20775 {
20776 if (INTVAL (operands[1]) == 0)
20777 return "prefetch\t%a0";
20778 else
20779 return "prefetchw\t%a0";
20780 }
20781 [(set_attr "type" "mmx")
20782 (set_attr "memory" "none")])
20783
20784 (define_expand "stack_protect_set"
20785 [(match_operand 0 "memory_operand" "")
20786 (match_operand 1 "memory_operand" "")]
20787 ""
20788 {
20789 #ifdef TARGET_THREAD_SSP_OFFSET
20790 if (TARGET_64BIT)
20791 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20792 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20793 else
20794 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20795 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20796 #else
20797 if (TARGET_64BIT)
20798 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20799 else
20800 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20801 #endif
20802 DONE;
20803 })
20804
20805 (define_insn "stack_protect_set_si"
20806 [(set (match_operand:SI 0 "memory_operand" "=m")
20807 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20808 (set (match_scratch:SI 2 "=&r") (const_int 0))
20809 (clobber (reg:CC FLAGS_REG))]
20810 ""
20811 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20812 [(set_attr "type" "multi")])
20813
20814 (define_insn "stack_protect_set_di"
20815 [(set (match_operand:DI 0 "memory_operand" "=m")
20816 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20817 (set (match_scratch:DI 2 "=&r") (const_int 0))
20818 (clobber (reg:CC FLAGS_REG))]
20819 "TARGET_64BIT"
20820 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20821 [(set_attr "type" "multi")])
20822
20823 (define_insn "stack_tls_protect_set_si"
20824 [(set (match_operand:SI 0 "memory_operand" "=m")
20825 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20826 (set (match_scratch:SI 2 "=&r") (const_int 0))
20827 (clobber (reg:CC FLAGS_REG))]
20828 ""
20829 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20830 [(set_attr "type" "multi")])
20831
20832 (define_insn "stack_tls_protect_set_di"
20833 [(set (match_operand:DI 0 "memory_operand" "=m")
20834 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20835 (set (match_scratch:DI 2 "=&r") (const_int 0))
20836 (clobber (reg:CC FLAGS_REG))]
20837 "TARGET_64BIT"
20838 {
20839 /* The kernel uses a different segment register for performance reasons; a
20840 system call would not have to trash the userspace segment register,
20841 which would be expensive */
20842 if (ix86_cmodel != CM_KERNEL)
20843 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20844 else
20845 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20846 }
20847 [(set_attr "type" "multi")])
20848
20849 (define_expand "stack_protect_test"
20850 [(match_operand 0 "memory_operand" "")
20851 (match_operand 1 "memory_operand" "")
20852 (match_operand 2 "" "")]
20853 ""
20854 {
20855 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20856 ix86_compare_op0 = operands[0];
20857 ix86_compare_op1 = operands[1];
20858 ix86_compare_emitted = flags;
20859
20860 #ifdef TARGET_THREAD_SSP_OFFSET
20861 if (TARGET_64BIT)
20862 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20863 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20864 else
20865 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20866 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20867 #else
20868 if (TARGET_64BIT)
20869 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20870 else
20871 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20872 #endif
20873 emit_jump_insn (gen_beq (operands[2]));
20874 DONE;
20875 })
20876
20877 (define_insn "stack_protect_test_si"
20878 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20879 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20880 (match_operand:SI 2 "memory_operand" "m")]
20881 UNSPEC_SP_TEST))
20882 (clobber (match_scratch:SI 3 "=&r"))]
20883 ""
20884 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20885 [(set_attr "type" "multi")])
20886
20887 (define_insn "stack_protect_test_di"
20888 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20889 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20890 (match_operand:DI 2 "memory_operand" "m")]
20891 UNSPEC_SP_TEST))
20892 (clobber (match_scratch:DI 3 "=&r"))]
20893 "TARGET_64BIT"
20894 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20895 [(set_attr "type" "multi")])
20896
20897 (define_insn "stack_tls_protect_test_si"
20898 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20899 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20900 (match_operand:SI 2 "const_int_operand" "i")]
20901 UNSPEC_SP_TLS_TEST))
20902 (clobber (match_scratch:SI 3 "=r"))]
20903 ""
20904 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20905 [(set_attr "type" "multi")])
20906
20907 (define_insn "stack_tls_protect_test_di"
20908 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20909 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20910 (match_operand:DI 2 "const_int_operand" "i")]
20911 UNSPEC_SP_TLS_TEST))
20912 (clobber (match_scratch:DI 3 "=r"))]
20913 "TARGET_64BIT"
20914 {
20915 /* The kernel uses a different segment register for performance reasons; a
20916 system call would not have to trash the userspace segment register,
20917 which would be expensive */
20918 if (ix86_cmodel != CM_KERNEL)
20919 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20920 else
20921 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20922 }
20923 [(set_attr "type" "multi")])
20924
20925 (define_mode_macro CRC32MODE [QI HI SI])
20926 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
20927 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
20928
20929 (define_insn "sse4_2_crc32<mode>"
20930 [(set (match_operand:SI 0 "register_operand" "=r")
20931 (unspec:SI
20932 [(match_operand:SI 1 "register_operand" "0")
20933 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
20934 UNSPEC_CRC32))]
20935 "TARGET_SSE4_2"
20936 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
20937 [(set_attr "type" "sselog1")
20938 (set_attr "prefix_rep" "1")
20939 (set_attr "prefix_extra" "1")
20940 (set_attr "mode" "SI")])
20941
20942 (define_insn "sse4_2_crc32di"
20943 [(set (match_operand:DI 0 "register_operand" "=r")
20944 (unspec:DI
20945 [(match_operand:DI 1 "register_operand" "0")
20946 (match_operand:DI 2 "nonimmediate_operand" "rm")]
20947 UNSPEC_CRC32))]
20948 "TARGET_SSE4_2 && TARGET_64BIT"
20949 "crc32q\t{%2, %0|%0, %2}"
20950 [(set_attr "type" "sselog1")
20951 (set_attr "prefix_rep" "1")
20952 (set_attr "prefix_extra" "1")
20953 (set_attr "mode" "DI")])
20954
20955 (include "mmx.md")
20956 (include "sse.md")
20957 (include "sync.md")
This page took 0.928151 seconds and 4 git commands to generate.