i386.md (paritydi2, paritysi2): New expanders.
[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 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;; operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
64
65 ; Prologue support
66 (UNSPEC_STACK_ALLOC 11)
67 (UNSPEC_SET_GOT 12)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_REG_SAVE 14)
70 (UNSPEC_DEF_CFA 15)
71
72 ; TLS support
73 (UNSPEC_TP 16)
74 (UNSPEC_TLS_GD 17)
75 (UNSPEC_TLS_LD_BASE 18)
76 (UNSPEC_TLSDESC 19)
77
78 ; Other random patterns
79 (UNSPEC_SCAS 20)
80 (UNSPEC_FNSTSW 21)
81 (UNSPEC_SAHF 22)
82 (UNSPEC_FSTCW 23)
83 (UNSPEC_ADD_CARRY 24)
84 (UNSPEC_FLDCW 25)
85 (UNSPEC_REP 26)
86 (UNSPEC_EH_RETURN 27)
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 29)
89
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 30)
92 (UNSPEC_MASKMOV 31)
93 (UNSPEC_MOVMSK 32)
94 (UNSPEC_MOVNT 33)
95 (UNSPEC_MOVU 34)
96 (UNSPEC_RCP 35)
97 (UNSPEC_RSQRT 36)
98 (UNSPEC_SFENCE 37)
99 (UNSPEC_NOP 38) ; prevents combiner cleverness
100 (UNSPEC_PFRCP 39)
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 ; SSP patterns
148 (UNSPEC_SP_SET 100)
149 (UNSPEC_SP_TEST 101)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
152
153 ; SSSE3
154 (UNSPEC_PSHUFB 120)
155 (UNSPEC_PSIGN 121)
156 (UNSPEC_PALIGNR 122)
157
158 ; For SSE4A support
159 (UNSPEC_EXTRQI 130)
160 (UNSPEC_EXTRQ 131)
161 (UNSPEC_INSERTQI 132)
162 (UNSPEC_INSERTQ 133)
163 ])
164
165 (define_constants
166 [(UNSPECV_BLOCKAGE 0)
167 (UNSPECV_STACK_PROBE 1)
168 (UNSPECV_EMMS 2)
169 (UNSPECV_LDMXCSR 3)
170 (UNSPECV_STMXCSR 4)
171 (UNSPECV_FEMMS 5)
172 (UNSPECV_CLFLUSH 6)
173 (UNSPECV_ALIGN 7)
174 (UNSPECV_MONITOR 8)
175 (UNSPECV_MWAIT 9)
176 (UNSPECV_CMPXCHG_1 10)
177 (UNSPECV_CMPXCHG_2 11)
178 (UNSPECV_XCHG 12)
179 (UNSPECV_LOCK 13)
180 ])
181
182 ;; Registers by name.
183 (define_constants
184 [(BP_REG 6)
185 (SP_REG 7)
186 (FLAGS_REG 17)
187 (FPSR_REG 18)
188 (FPCR_REG 19)
189 (R10_REG 39)
190 (R11_REG 40)
191 ])
192
193 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
194 ;; from i386.c.
195
196 ;; In C guard expressions, put expressions which may be compile-time
197 ;; constants first. This allows for better optimization. For
198 ;; example, write "TARGET_64BIT && reload_completed", not
199 ;; "reload_completed && TARGET_64BIT".
200
201 \f
202 ;; Processor type. This attribute must exactly match the processor_type
203 ;; enumeration in i386.h.
204 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
205 nocona,core2,generic32,generic64,amdfam10"
206 (const (symbol_ref "ix86_tune")))
207
208 ;; A basic instruction type. Refinements due to arguments to be
209 ;; provided in other attributes.
210 (define_attr "type"
211 "other,multi,
212 alu,alu1,negnot,imov,imovx,lea,
213 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
214 icmp,test,ibr,setcc,icmov,
215 push,pop,call,callv,leave,
216 str,bitmanip,
217 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
218 sselog,sselog1,sseiadd,sseishft,sseimul,
219 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
220 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
221 (const_string "other"))
222
223 ;; Main data type used by the insn
224 (define_attr "mode"
225 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
226 (const_string "unknown"))
227
228 ;; The CPU unit operations uses.
229 (define_attr "unit" "integer,i387,sse,mmx,unknown"
230 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
231 (const_string "i387")
232 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
233 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
234 (const_string "sse")
235 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
236 (const_string "mmx")
237 (eq_attr "type" "other")
238 (const_string "unknown")]
239 (const_string "integer")))
240
241 ;; The (bounding maximum) length of an instruction immediate.
242 (define_attr "length_immediate" ""
243 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
244 bitmanip")
245 (const_int 0)
246 (eq_attr "unit" "i387,sse,mmx")
247 (const_int 0)
248 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
249 imul,icmp,push,pop")
250 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
251 (eq_attr "type" "imov,test")
252 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
253 (eq_attr "type" "call")
254 (if_then_else (match_operand 0 "constant_call_address_operand" "")
255 (const_int 4)
256 (const_int 0))
257 (eq_attr "type" "callv")
258 (if_then_else (match_operand 1 "constant_call_address_operand" "")
259 (const_int 4)
260 (const_int 0))
261 ;; We don't know the size before shorten_branches. Expect
262 ;; the instruction to fit for better scheduling.
263 (eq_attr "type" "ibr")
264 (const_int 1)
265 ]
266 (symbol_ref "/* Update immediate_length and other attributes! */
267 gcc_unreachable (),1")))
268
269 ;; The (bounding maximum) length of an instruction address.
270 (define_attr "length_address" ""
271 (cond [(eq_attr "type" "str,other,multi,fxch")
272 (const_int 0)
273 (and (eq_attr "type" "call")
274 (match_operand 0 "constant_call_address_operand" ""))
275 (const_int 0)
276 (and (eq_attr "type" "callv")
277 (match_operand 1 "constant_call_address_operand" ""))
278 (const_int 0)
279 ]
280 (symbol_ref "ix86_attr_length_address_default (insn)")))
281
282 ;; Set when length prefix is used.
283 (define_attr "prefix_data16" ""
284 (if_then_else (ior (eq_attr "mode" "HI")
285 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
286 (const_int 1)
287 (const_int 0)))
288
289 ;; Set when string REP prefix is used.
290 (define_attr "prefix_rep" ""
291 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
292 (const_int 1)
293 (const_int 0)))
294
295 ;; Set when 0f opcode prefix is used.
296 (define_attr "prefix_0f" ""
297 (if_then_else
298 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
299 (eq_attr "unit" "sse,mmx"))
300 (const_int 1)
301 (const_int 0)))
302
303 ;; Set when REX opcode prefix is used.
304 (define_attr "prefix_rex" ""
305 (cond [(and (eq_attr "mode" "DI")
306 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
307 (const_int 1)
308 (and (eq_attr "mode" "QI")
309 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
310 (const_int 0)))
311 (const_int 1)
312 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
313 (const_int 0))
314 (const_int 1)
315 ]
316 (const_int 0)))
317
318 ;; Set when modrm byte is used.
319 (define_attr "modrm" ""
320 (cond [(eq_attr "type" "str,leave")
321 (const_int 0)
322 (eq_attr "unit" "i387")
323 (const_int 0)
324 (and (eq_attr "type" "incdec")
325 (ior (match_operand:SI 1 "register_operand" "")
326 (match_operand:HI 1 "register_operand" "")))
327 (const_int 0)
328 (and (eq_attr "type" "push")
329 (not (match_operand 1 "memory_operand" "")))
330 (const_int 0)
331 (and (eq_attr "type" "pop")
332 (not (match_operand 0 "memory_operand" "")))
333 (const_int 0)
334 (and (eq_attr "type" "imov")
335 (ior (and (match_operand 0 "register_operand" "")
336 (match_operand 1 "immediate_operand" ""))
337 (ior (and (match_operand 0 "ax_reg_operand" "")
338 (match_operand 1 "memory_displacement_only_operand" ""))
339 (and (match_operand 0 "memory_displacement_only_operand" "")
340 (match_operand 1 "ax_reg_operand" "")))))
341 (const_int 0)
342 (and (eq_attr "type" "call")
343 (match_operand 0 "constant_call_address_operand" ""))
344 (const_int 0)
345 (and (eq_attr "type" "callv")
346 (match_operand 1 "constant_call_address_operand" ""))
347 (const_int 0)
348 ]
349 (const_int 1)))
350
351 ;; The (bounding maximum) length of an instruction in bytes.
352 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
353 ;; Later we may want to split them and compute proper length as for
354 ;; other insns.
355 (define_attr "length" ""
356 (cond [(eq_attr "type" "other,multi,fistp,frndint")
357 (const_int 16)
358 (eq_attr "type" "fcmp")
359 (const_int 4)
360 (eq_attr "unit" "i387")
361 (plus (const_int 2)
362 (plus (attr "prefix_data16")
363 (attr "length_address")))]
364 (plus (plus (attr "modrm")
365 (plus (attr "prefix_0f")
366 (plus (attr "prefix_rex")
367 (const_int 1))))
368 (plus (attr "prefix_rep")
369 (plus (attr "prefix_data16")
370 (plus (attr "length_immediate")
371 (attr "length_address")))))))
372
373 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
374 ;; `store' if there is a simple memory reference therein, or `unknown'
375 ;; if the instruction is complex.
376
377 (define_attr "memory" "none,load,store,both,unknown"
378 (cond [(eq_attr "type" "other,multi,str")
379 (const_string "unknown")
380 (eq_attr "type" "lea,fcmov,fpspc")
381 (const_string "none")
382 (eq_attr "type" "fistp,leave")
383 (const_string "both")
384 (eq_attr "type" "frndint")
385 (const_string "load")
386 (eq_attr "type" "push")
387 (if_then_else (match_operand 1 "memory_operand" "")
388 (const_string "both")
389 (const_string "store"))
390 (eq_attr "type" "pop")
391 (if_then_else (match_operand 0 "memory_operand" "")
392 (const_string "both")
393 (const_string "load"))
394 (eq_attr "type" "setcc")
395 (if_then_else (match_operand 0 "memory_operand" "")
396 (const_string "store")
397 (const_string "none"))
398 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
399 (if_then_else (ior (match_operand 0 "memory_operand" "")
400 (match_operand 1 "memory_operand" ""))
401 (const_string "load")
402 (const_string "none"))
403 (eq_attr "type" "ibr")
404 (if_then_else (match_operand 0 "memory_operand" "")
405 (const_string "load")
406 (const_string "none"))
407 (eq_attr "type" "call")
408 (if_then_else (match_operand 0 "constant_call_address_operand" "")
409 (const_string "none")
410 (const_string "load"))
411 (eq_attr "type" "callv")
412 (if_then_else (match_operand 1 "constant_call_address_operand" "")
413 (const_string "none")
414 (const_string "load"))
415 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
416 (match_operand 1 "memory_operand" ""))
417 (const_string "both")
418 (and (match_operand 0 "memory_operand" "")
419 (match_operand 1 "memory_operand" ""))
420 (const_string "both")
421 (match_operand 0 "memory_operand" "")
422 (const_string "store")
423 (match_operand 1 "memory_operand" "")
424 (const_string "load")
425 (and (eq_attr "type"
426 "!alu1,negnot,ishift1,
427 imov,imovx,icmp,test,bitmanip,
428 fmov,fcmp,fsgn,
429 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
430 mmx,mmxmov,mmxcmp,mmxcvt")
431 (match_operand 2 "memory_operand" ""))
432 (const_string "load")
433 (and (eq_attr "type" "icmov")
434 (match_operand 3 "memory_operand" ""))
435 (const_string "load")
436 ]
437 (const_string "none")))
438
439 ;; Indicates if an instruction has both an immediate and a displacement.
440
441 (define_attr "imm_disp" "false,true,unknown"
442 (cond [(eq_attr "type" "other,multi")
443 (const_string "unknown")
444 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
445 (and (match_operand 0 "memory_displacement_operand" "")
446 (match_operand 1 "immediate_operand" "")))
447 (const_string "true")
448 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
449 (and (match_operand 0 "memory_displacement_operand" "")
450 (match_operand 2 "immediate_operand" "")))
451 (const_string "true")
452 ]
453 (const_string "false")))
454
455 ;; Indicates if an FP operation has an integer source.
456
457 (define_attr "fp_int_src" "false,true"
458 (const_string "false"))
459
460 ;; Defines rounding mode of an FP operation.
461
462 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
463 (const_string "any"))
464
465 ;; Describe a user's asm statement.
466 (define_asm_attributes
467 [(set_attr "length" "128")
468 (set_attr "type" "multi")])
469
470 ;; All x87 floating point modes
471 (define_mode_macro X87MODEF [SF DF XF])
472
473 ;; x87 SFmode and DFMode floating point modes
474 (define_mode_macro X87MODEF12 [SF DF])
475
476 ;; All integer modes handled by x87 fisttp operator.
477 (define_mode_macro X87MODEI [HI SI DI])
478
479 ;; All integer modes handled by integer x87 operators.
480 (define_mode_macro X87MODEI12 [HI SI])
481
482 ;; All SSE floating point modes
483 (define_mode_macro SSEMODEF [SF DF])
484
485 ;; All integer modes handled by SSE cvtts?2si* operators.
486 (define_mode_macro SSEMODEI24 [SI DI])
487
488 ;; SSE asm suffix for floating point modes
489 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
490
491 \f
492 ;; Scheduling descriptions
493
494 (include "pentium.md")
495 (include "ppro.md")
496 (include "k6.md")
497 (include "athlon.md")
498 (include "geode.md")
499
500 \f
501 ;; Operand and operator predicates and constraints
502
503 (include "predicates.md")
504 (include "constraints.md")
505
506 \f
507 ;; Compare instructions.
508
509 ;; All compare insns have expanders that save the operands away without
510 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
511 ;; after the cmp) will actually emit the cmpM.
512
513 (define_expand "cmpti"
514 [(set (reg:CC FLAGS_REG)
515 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
516 (match_operand:TI 1 "x86_64_general_operand" "")))]
517 "TARGET_64BIT"
518 {
519 if (MEM_P (operands[0]) && MEM_P (operands[1]))
520 operands[0] = force_reg (TImode, operands[0]);
521 ix86_compare_op0 = operands[0];
522 ix86_compare_op1 = operands[1];
523 DONE;
524 })
525
526 (define_expand "cmpdi"
527 [(set (reg:CC FLAGS_REG)
528 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
529 (match_operand:DI 1 "x86_64_general_operand" "")))]
530 ""
531 {
532 if (MEM_P (operands[0]) && MEM_P (operands[1]))
533 operands[0] = force_reg (DImode, operands[0]);
534 ix86_compare_op0 = operands[0];
535 ix86_compare_op1 = operands[1];
536 DONE;
537 })
538
539 (define_expand "cmpsi"
540 [(set (reg:CC FLAGS_REG)
541 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
542 (match_operand:SI 1 "general_operand" "")))]
543 ""
544 {
545 if (MEM_P (operands[0]) && MEM_P (operands[1]))
546 operands[0] = force_reg (SImode, operands[0]);
547 ix86_compare_op0 = operands[0];
548 ix86_compare_op1 = operands[1];
549 DONE;
550 })
551
552 (define_expand "cmphi"
553 [(set (reg:CC FLAGS_REG)
554 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
555 (match_operand:HI 1 "general_operand" "")))]
556 ""
557 {
558 if (MEM_P (operands[0]) && MEM_P (operands[1]))
559 operands[0] = force_reg (HImode, operands[0]);
560 ix86_compare_op0 = operands[0];
561 ix86_compare_op1 = operands[1];
562 DONE;
563 })
564
565 (define_expand "cmpqi"
566 [(set (reg:CC FLAGS_REG)
567 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
568 (match_operand:QI 1 "general_operand" "")))]
569 "TARGET_QIMODE_MATH"
570 {
571 if (MEM_P (operands[0]) && MEM_P (operands[1]))
572 operands[0] = force_reg (QImode, operands[0]);
573 ix86_compare_op0 = operands[0];
574 ix86_compare_op1 = operands[1];
575 DONE;
576 })
577
578 (define_insn "cmpdi_ccno_1_rex64"
579 [(set (reg FLAGS_REG)
580 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
581 (match_operand:DI 1 "const0_operand" "n,n")))]
582 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
583 "@
584 test{q}\t{%0, %0|%0, %0}
585 cmp{q}\t{%1, %0|%0, %1}"
586 [(set_attr "type" "test,icmp")
587 (set_attr "length_immediate" "0,1")
588 (set_attr "mode" "DI")])
589
590 (define_insn "*cmpdi_minus_1_rex64"
591 [(set (reg FLAGS_REG)
592 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
593 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
594 (const_int 0)))]
595 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
596 "cmp{q}\t{%1, %0|%0, %1}"
597 [(set_attr "type" "icmp")
598 (set_attr "mode" "DI")])
599
600 (define_expand "cmpdi_1_rex64"
601 [(set (reg:CC FLAGS_REG)
602 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
603 (match_operand:DI 1 "general_operand" "")))]
604 "TARGET_64BIT"
605 "")
606
607 (define_insn "cmpdi_1_insn_rex64"
608 [(set (reg FLAGS_REG)
609 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
610 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
611 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
612 "cmp{q}\t{%1, %0|%0, %1}"
613 [(set_attr "type" "icmp")
614 (set_attr "mode" "DI")])
615
616
617 (define_insn "*cmpsi_ccno_1"
618 [(set (reg FLAGS_REG)
619 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
620 (match_operand:SI 1 "const0_operand" "n,n")))]
621 "ix86_match_ccmode (insn, CCNOmode)"
622 "@
623 test{l}\t{%0, %0|%0, %0}
624 cmp{l}\t{%1, %0|%0, %1}"
625 [(set_attr "type" "test,icmp")
626 (set_attr "length_immediate" "0,1")
627 (set_attr "mode" "SI")])
628
629 (define_insn "*cmpsi_minus_1"
630 [(set (reg FLAGS_REG)
631 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632 (match_operand:SI 1 "general_operand" "ri,mr"))
633 (const_int 0)))]
634 "ix86_match_ccmode (insn, CCGOCmode)"
635 "cmp{l}\t{%1, %0|%0, %1}"
636 [(set_attr "type" "icmp")
637 (set_attr "mode" "SI")])
638
639 (define_expand "cmpsi_1"
640 [(set (reg:CC FLAGS_REG)
641 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
642 (match_operand:SI 1 "general_operand" "ri,mr")))]
643 ""
644 "")
645
646 (define_insn "*cmpsi_1_insn"
647 [(set (reg FLAGS_REG)
648 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
649 (match_operand:SI 1 "general_operand" "ri,mr")))]
650 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
651 && ix86_match_ccmode (insn, CCmode)"
652 "cmp{l}\t{%1, %0|%0, %1}"
653 [(set_attr "type" "icmp")
654 (set_attr "mode" "SI")])
655
656 (define_insn "*cmphi_ccno_1"
657 [(set (reg FLAGS_REG)
658 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
659 (match_operand:HI 1 "const0_operand" "n,n")))]
660 "ix86_match_ccmode (insn, CCNOmode)"
661 "@
662 test{w}\t{%0, %0|%0, %0}
663 cmp{w}\t{%1, %0|%0, %1}"
664 [(set_attr "type" "test,icmp")
665 (set_attr "length_immediate" "0,1")
666 (set_attr "mode" "HI")])
667
668 (define_insn "*cmphi_minus_1"
669 [(set (reg FLAGS_REG)
670 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
671 (match_operand:HI 1 "general_operand" "ri,mr"))
672 (const_int 0)))]
673 "ix86_match_ccmode (insn, CCGOCmode)"
674 "cmp{w}\t{%1, %0|%0, %1}"
675 [(set_attr "type" "icmp")
676 (set_attr "mode" "HI")])
677
678 (define_insn "*cmphi_1"
679 [(set (reg FLAGS_REG)
680 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
681 (match_operand:HI 1 "general_operand" "ri,mr")))]
682 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
683 && ix86_match_ccmode (insn, CCmode)"
684 "cmp{w}\t{%1, %0|%0, %1}"
685 [(set_attr "type" "icmp")
686 (set_attr "mode" "HI")])
687
688 (define_insn "*cmpqi_ccno_1"
689 [(set (reg FLAGS_REG)
690 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
691 (match_operand:QI 1 "const0_operand" "n,n")))]
692 "ix86_match_ccmode (insn, CCNOmode)"
693 "@
694 test{b}\t{%0, %0|%0, %0}
695 cmp{b}\t{$0, %0|%0, 0}"
696 [(set_attr "type" "test,icmp")
697 (set_attr "length_immediate" "0,1")
698 (set_attr "mode" "QI")])
699
700 (define_insn "*cmpqi_1"
701 [(set (reg FLAGS_REG)
702 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
703 (match_operand:QI 1 "general_operand" "qi,mq")))]
704 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
705 && ix86_match_ccmode (insn, CCmode)"
706 "cmp{b}\t{%1, %0|%0, %1}"
707 [(set_attr "type" "icmp")
708 (set_attr "mode" "QI")])
709
710 (define_insn "*cmpqi_minus_1"
711 [(set (reg FLAGS_REG)
712 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
713 (match_operand:QI 1 "general_operand" "qi,mq"))
714 (const_int 0)))]
715 "ix86_match_ccmode (insn, CCGOCmode)"
716 "cmp{b}\t{%1, %0|%0, %1}"
717 [(set_attr "type" "icmp")
718 (set_attr "mode" "QI")])
719
720 (define_insn "*cmpqi_ext_1"
721 [(set (reg FLAGS_REG)
722 (compare
723 (match_operand:QI 0 "general_operand" "Qm")
724 (subreg:QI
725 (zero_extract:SI
726 (match_operand 1 "ext_register_operand" "Q")
727 (const_int 8)
728 (const_int 8)) 0)))]
729 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
730 "cmp{b}\t{%h1, %0|%0, %h1}"
731 [(set_attr "type" "icmp")
732 (set_attr "mode" "QI")])
733
734 (define_insn "*cmpqi_ext_1_rex64"
735 [(set (reg FLAGS_REG)
736 (compare
737 (match_operand:QI 0 "register_operand" "Q")
738 (subreg:QI
739 (zero_extract:SI
740 (match_operand 1 "ext_register_operand" "Q")
741 (const_int 8)
742 (const_int 8)) 0)))]
743 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
744 "cmp{b}\t{%h1, %0|%0, %h1}"
745 [(set_attr "type" "icmp")
746 (set_attr "mode" "QI")])
747
748 (define_insn "*cmpqi_ext_2"
749 [(set (reg FLAGS_REG)
750 (compare
751 (subreg:QI
752 (zero_extract:SI
753 (match_operand 0 "ext_register_operand" "Q")
754 (const_int 8)
755 (const_int 8)) 0)
756 (match_operand:QI 1 "const0_operand" "n")))]
757 "ix86_match_ccmode (insn, CCNOmode)"
758 "test{b}\t%h0, %h0"
759 [(set_attr "type" "test")
760 (set_attr "length_immediate" "0")
761 (set_attr "mode" "QI")])
762
763 (define_expand "cmpqi_ext_3"
764 [(set (reg:CC FLAGS_REG)
765 (compare:CC
766 (subreg:QI
767 (zero_extract:SI
768 (match_operand 0 "ext_register_operand" "")
769 (const_int 8)
770 (const_int 8)) 0)
771 (match_operand:QI 1 "general_operand" "")))]
772 ""
773 "")
774
775 (define_insn "cmpqi_ext_3_insn"
776 [(set (reg FLAGS_REG)
777 (compare
778 (subreg:QI
779 (zero_extract:SI
780 (match_operand 0 "ext_register_operand" "Q")
781 (const_int 8)
782 (const_int 8)) 0)
783 (match_operand:QI 1 "general_operand" "Qmn")))]
784 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
785 "cmp{b}\t{%1, %h0|%h0, %1}"
786 [(set_attr "type" "icmp")
787 (set_attr "mode" "QI")])
788
789 (define_insn "cmpqi_ext_3_insn_rex64"
790 [(set (reg FLAGS_REG)
791 (compare
792 (subreg:QI
793 (zero_extract:SI
794 (match_operand 0 "ext_register_operand" "Q")
795 (const_int 8)
796 (const_int 8)) 0)
797 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
798 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
799 "cmp{b}\t{%1, %h0|%h0, %1}"
800 [(set_attr "type" "icmp")
801 (set_attr "mode" "QI")])
802
803 (define_insn "*cmpqi_ext_4"
804 [(set (reg FLAGS_REG)
805 (compare
806 (subreg:QI
807 (zero_extract:SI
808 (match_operand 0 "ext_register_operand" "Q")
809 (const_int 8)
810 (const_int 8)) 0)
811 (subreg:QI
812 (zero_extract:SI
813 (match_operand 1 "ext_register_operand" "Q")
814 (const_int 8)
815 (const_int 8)) 0)))]
816 "ix86_match_ccmode (insn, CCmode)"
817 "cmp{b}\t{%h1, %h0|%h0, %h1}"
818 [(set_attr "type" "icmp")
819 (set_attr "mode" "QI")])
820
821 ;; These implement float point compares.
822 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
823 ;; which would allow mix and match FP modes on the compares. Which is what
824 ;; the old patterns did, but with many more of them.
825
826 (define_expand "cmpxf"
827 [(set (reg:CC FLAGS_REG)
828 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
829 (match_operand:XF 1 "nonmemory_operand" "")))]
830 "TARGET_80387"
831 {
832 ix86_compare_op0 = operands[0];
833 ix86_compare_op1 = operands[1];
834 DONE;
835 })
836
837 (define_expand "cmpdf"
838 [(set (reg:CC FLAGS_REG)
839 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
840 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
841 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
842 {
843 ix86_compare_op0 = operands[0];
844 ix86_compare_op1 = operands[1];
845 DONE;
846 })
847
848 (define_expand "cmpsf"
849 [(set (reg:CC FLAGS_REG)
850 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
851 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
852 "TARGET_80387 || TARGET_SSE_MATH"
853 {
854 ix86_compare_op0 = operands[0];
855 ix86_compare_op1 = operands[1];
856 DONE;
857 })
858
859 ;; FP compares, step 1:
860 ;; Set the FP condition codes.
861 ;;
862 ;; CCFPmode compare with exceptions
863 ;; CCFPUmode compare with no exceptions
864
865 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
866 ;; used to manage the reg stack popping would not be preserved.
867
868 (define_insn "*cmpfp_0"
869 [(set (match_operand:HI 0 "register_operand" "=a")
870 (unspec:HI
871 [(compare:CCFP
872 (match_operand 1 "register_operand" "f")
873 (match_operand 2 "const0_operand" "X"))]
874 UNSPEC_FNSTSW))]
875 "TARGET_80387
876 && FLOAT_MODE_P (GET_MODE (operands[1]))
877 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
878 "* return output_fp_compare (insn, operands, 0, 0);"
879 [(set_attr "type" "multi")
880 (set_attr "unit" "i387")
881 (set (attr "mode")
882 (cond [(match_operand:SF 1 "" "")
883 (const_string "SF")
884 (match_operand:DF 1 "" "")
885 (const_string "DF")
886 ]
887 (const_string "XF")))])
888
889 (define_insn "*cmpfp_sf"
890 [(set (match_operand:HI 0 "register_operand" "=a")
891 (unspec:HI
892 [(compare:CCFP
893 (match_operand:SF 1 "register_operand" "f")
894 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
895 UNSPEC_FNSTSW))]
896 "TARGET_80387"
897 "* return output_fp_compare (insn, operands, 0, 0);"
898 [(set_attr "type" "multi")
899 (set_attr "unit" "i387")
900 (set_attr "mode" "SF")])
901
902 (define_insn "*cmpfp_df"
903 [(set (match_operand:HI 0 "register_operand" "=a")
904 (unspec:HI
905 [(compare:CCFP
906 (match_operand:DF 1 "register_operand" "f")
907 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
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" "DF")])
914
915 (define_insn "*cmpfp_xf"
916 [(set (match_operand:HI 0 "register_operand" "=a")
917 (unspec:HI
918 [(compare:CCFP
919 (match_operand:XF 1 "register_operand" "f")
920 (match_operand:XF 2 "register_operand" "f"))]
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" "XF")])
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 "TARGET_80387
936 && FLOAT_MODE_P (GET_MODE (operands[1]))
937 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
938 "* return output_fp_compare (insn, operands, 0, 1);"
939 [(set_attr "type" "multi")
940 (set_attr "unit" "i387")
941 (set (attr "mode")
942 (cond [(match_operand:SF 1 "" "")
943 (const_string "SF")
944 (match_operand:DF 1 "" "")
945 (const_string "DF")
946 ]
947 (const_string "XF")))])
948
949 (define_insn "*cmpfp_<mode>"
950 [(set (match_operand:HI 0 "register_operand" "=a")
951 (unspec:HI
952 [(compare:CCFP
953 (match_operand 1 "register_operand" "f")
954 (match_operator 3 "float_operator"
955 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
956 UNSPEC_FNSTSW))]
957 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
958 && FLOAT_MODE_P (GET_MODE (operands[1]))
959 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
960 "* return output_fp_compare (insn, operands, 0, 0);"
961 [(set_attr "type" "multi")
962 (set_attr "unit" "i387")
963 (set_attr "fp_int_src" "true")
964 (set_attr "mode" "<MODE>")])
965
966 ;; FP compares, step 2
967 ;; Move the fpsw to ax.
968
969 (define_insn "x86_fnstsw_1"
970 [(set (match_operand:HI 0 "register_operand" "=a")
971 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
972 "TARGET_80387"
973 "fnstsw\t%0"
974 [(set_attr "length" "2")
975 (set_attr "mode" "SI")
976 (set_attr "unit" "i387")])
977
978 ;; FP compares, step 3
979 ;; Get ax into flags, general case.
980
981 (define_insn "x86_sahf_1"
982 [(set (reg:CC FLAGS_REG)
983 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
984 "!TARGET_64BIT"
985 "sahf"
986 [(set_attr "length" "1")
987 (set_attr "athlon_decode" "vector")
988 (set_attr "amdfam10_decode" "direct")
989 (set_attr "mode" "SI")])
990
991 ;; Pentium Pro can do steps 1 through 3 in one go.
992 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
993 (define_insn "*cmpfp_i_mixed"
994 [(set (reg:CCFP FLAGS_REG)
995 (compare:CCFP (match_operand 0 "register_operand" "f,x")
996 (match_operand 1 "nonimmediate_operand" "f,xm")))]
997 "TARGET_MIX_SSE_I387
998 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000 "* return output_fp_compare (insn, operands, 1, 0);"
1001 [(set_attr "type" "fcmp,ssecomi")
1002 (set (attr "mode")
1003 (if_then_else (match_operand:SF 1 "" "")
1004 (const_string "SF")
1005 (const_string "DF")))
1006 (set_attr "athlon_decode" "vector")
1007 (set_attr "amdfam10_decode" "direct")])
1008
1009 (define_insn "*cmpfp_i_sse"
1010 [(set (reg:CCFP FLAGS_REG)
1011 (compare:CCFP (match_operand 0 "register_operand" "x")
1012 (match_operand 1 "nonimmediate_operand" "xm")))]
1013 "TARGET_SSE_MATH
1014 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016 "* return output_fp_compare (insn, operands, 1, 0);"
1017 [(set_attr "type" "ssecomi")
1018 (set (attr "mode")
1019 (if_then_else (match_operand:SF 1 "" "")
1020 (const_string "SF")
1021 (const_string "DF")))
1022 (set_attr "athlon_decode" "vector")
1023 (set_attr "amdfam10_decode" "direct")])
1024
1025 (define_insn "*cmpfp_i_i387"
1026 [(set (reg:CCFP FLAGS_REG)
1027 (compare:CCFP (match_operand 0 "register_operand" "f")
1028 (match_operand 1 "register_operand" "f")))]
1029 "TARGET_80387 && TARGET_CMOVE
1030 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1031 && FLOAT_MODE_P (GET_MODE (operands[0]))
1032 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033 "* return output_fp_compare (insn, operands, 1, 0);"
1034 [(set_attr "type" "fcmp")
1035 (set (attr "mode")
1036 (cond [(match_operand:SF 1 "" "")
1037 (const_string "SF")
1038 (match_operand:DF 1 "" "")
1039 (const_string "DF")
1040 ]
1041 (const_string "XF")))
1042 (set_attr "athlon_decode" "vector")
1043 (set_attr "amdfam10_decode" "direct")])
1044
1045 (define_insn "*cmpfp_iu_mixed"
1046 [(set (reg:CCFPU FLAGS_REG)
1047 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1048 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1049 "TARGET_MIX_SSE_I387
1050 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1051 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1052 "* return output_fp_compare (insn, operands, 1, 1);"
1053 [(set_attr "type" "fcmp,ssecomi")
1054 (set (attr "mode")
1055 (if_then_else (match_operand:SF 1 "" "")
1056 (const_string "SF")
1057 (const_string "DF")))
1058 (set_attr "athlon_decode" "vector")
1059 (set_attr "amdfam10_decode" "direct")])
1060
1061 (define_insn "*cmpfp_iu_sse"
1062 [(set (reg:CCFPU FLAGS_REG)
1063 (compare:CCFPU (match_operand 0 "register_operand" "x")
1064 (match_operand 1 "nonimmediate_operand" "xm")))]
1065 "TARGET_SSE_MATH
1066 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1067 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1068 "* return output_fp_compare (insn, operands, 1, 1);"
1069 [(set_attr "type" "ssecomi")
1070 (set (attr "mode")
1071 (if_then_else (match_operand:SF 1 "" "")
1072 (const_string "SF")
1073 (const_string "DF")))
1074 (set_attr "athlon_decode" "vector")
1075 (set_attr "amdfam10_decode" "direct")])
1076
1077 (define_insn "*cmpfp_iu_387"
1078 [(set (reg:CCFPU FLAGS_REG)
1079 (compare:CCFPU (match_operand 0 "register_operand" "f")
1080 (match_operand 1 "register_operand" "f")))]
1081 "TARGET_80387 && TARGET_CMOVE
1082 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1083 && FLOAT_MODE_P (GET_MODE (operands[0]))
1084 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1085 "* return output_fp_compare (insn, operands, 1, 1);"
1086 [(set_attr "type" "fcmp")
1087 (set (attr "mode")
1088 (cond [(match_operand:SF 1 "" "")
1089 (const_string "SF")
1090 (match_operand:DF 1 "" "")
1091 (const_string "DF")
1092 ]
1093 (const_string "XF")))
1094 (set_attr "athlon_decode" "vector")
1095 (set_attr "amdfam10_decode" "direct")])
1096 \f
1097 ;; Move instructions.
1098
1099 ;; General case of fullword move.
1100
1101 (define_expand "movsi"
1102 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1103 (match_operand:SI 1 "general_operand" ""))]
1104 ""
1105 "ix86_expand_move (SImode, operands); DONE;")
1106
1107 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1108 ;; general_operand.
1109 ;;
1110 ;; %%% We don't use a post-inc memory reference because x86 is not a
1111 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1112 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1113 ;; targets without our curiosities, and it is just as easy to represent
1114 ;; this differently.
1115
1116 (define_insn "*pushsi2"
1117 [(set (match_operand:SI 0 "push_operand" "=<")
1118 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1119 "!TARGET_64BIT"
1120 "push{l}\t%1"
1121 [(set_attr "type" "push")
1122 (set_attr "mode" "SI")])
1123
1124 ;; For 64BIT abi we always round up to 8 bytes.
1125 (define_insn "*pushsi2_rex64"
1126 [(set (match_operand:SI 0 "push_operand" "=X")
1127 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1128 "TARGET_64BIT"
1129 "push{q}\t%q1"
1130 [(set_attr "type" "push")
1131 (set_attr "mode" "SI")])
1132
1133 (define_insn "*pushsi2_prologue"
1134 [(set (match_operand:SI 0 "push_operand" "=<")
1135 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1136 (clobber (mem:BLK (scratch)))]
1137 "!TARGET_64BIT"
1138 "push{l}\t%1"
1139 [(set_attr "type" "push")
1140 (set_attr "mode" "SI")])
1141
1142 (define_insn "*popsi1_epilogue"
1143 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1144 (mem:SI (reg:SI SP_REG)))
1145 (set (reg:SI SP_REG)
1146 (plus:SI (reg:SI SP_REG) (const_int 4)))
1147 (clobber (mem:BLK (scratch)))]
1148 "!TARGET_64BIT"
1149 "pop{l}\t%0"
1150 [(set_attr "type" "pop")
1151 (set_attr "mode" "SI")])
1152
1153 (define_insn "popsi1"
1154 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1155 (mem:SI (reg:SI SP_REG)))
1156 (set (reg:SI SP_REG)
1157 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1158 "!TARGET_64BIT"
1159 "pop{l}\t%0"
1160 [(set_attr "type" "pop")
1161 (set_attr "mode" "SI")])
1162
1163 (define_insn "*movsi_xor"
1164 [(set (match_operand:SI 0 "register_operand" "=r")
1165 (match_operand:SI 1 "const0_operand" "i"))
1166 (clobber (reg:CC FLAGS_REG))]
1167 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1168 "xor{l}\t{%0, %0|%0, %0}"
1169 [(set_attr "type" "alu1")
1170 (set_attr "mode" "SI")
1171 (set_attr "length_immediate" "0")])
1172
1173 (define_insn "*movsi_or"
1174 [(set (match_operand:SI 0 "register_operand" "=r")
1175 (match_operand:SI 1 "immediate_operand" "i"))
1176 (clobber (reg:CC FLAGS_REG))]
1177 "reload_completed
1178 && operands[1] == constm1_rtx
1179 && (TARGET_PENTIUM || optimize_size)"
1180 {
1181 operands[1] = constm1_rtx;
1182 return "or{l}\t{%1, %0|%0, %1}";
1183 }
1184 [(set_attr "type" "alu1")
1185 (set_attr "mode" "SI")
1186 (set_attr "length_immediate" "1")])
1187
1188 (define_insn "*movsi_1"
1189 [(set (match_operand:SI 0 "nonimmediate_operand"
1190 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1191 (match_operand:SI 1 "general_operand"
1192 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1193 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1194 {
1195 switch (get_attr_type (insn))
1196 {
1197 case TYPE_SSELOG1:
1198 if (get_attr_mode (insn) == MODE_TI)
1199 return "pxor\t%0, %0";
1200 return "xorps\t%0, %0";
1201
1202 case TYPE_SSEMOV:
1203 switch (get_attr_mode (insn))
1204 {
1205 case MODE_TI:
1206 return "movdqa\t{%1, %0|%0, %1}";
1207 case MODE_V4SF:
1208 return "movaps\t{%1, %0|%0, %1}";
1209 case MODE_SI:
1210 return "movd\t{%1, %0|%0, %1}";
1211 case MODE_SF:
1212 return "movss\t{%1, %0|%0, %1}";
1213 default:
1214 gcc_unreachable ();
1215 }
1216
1217 case TYPE_MMXADD:
1218 return "pxor\t%0, %0";
1219
1220 case TYPE_MMXMOV:
1221 if (get_attr_mode (insn) == MODE_DI)
1222 return "movq\t{%1, %0|%0, %1}";
1223 return "movd\t{%1, %0|%0, %1}";
1224
1225 case TYPE_LEA:
1226 return "lea{l}\t{%1, %0|%0, %1}";
1227
1228 default:
1229 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1230 return "mov{l}\t{%1, %0|%0, %1}";
1231 }
1232 }
1233 [(set (attr "type")
1234 (cond [(eq_attr "alternative" "2")
1235 (const_string "mmxadd")
1236 (eq_attr "alternative" "3,4,5")
1237 (const_string "mmxmov")
1238 (eq_attr "alternative" "6")
1239 (const_string "sselog1")
1240 (eq_attr "alternative" "7,8,9,10,11")
1241 (const_string "ssemov")
1242 (match_operand:DI 1 "pic_32bit_operand" "")
1243 (const_string "lea")
1244 ]
1245 (const_string "imov")))
1246 (set (attr "mode")
1247 (cond [(eq_attr "alternative" "2,3")
1248 (const_string "DI")
1249 (eq_attr "alternative" "6,7")
1250 (if_then_else
1251 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1252 (const_string "V4SF")
1253 (const_string "TI"))
1254 (and (eq_attr "alternative" "8,9,10,11")
1255 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1256 (const_string "SF")
1257 ]
1258 (const_string "SI")))])
1259
1260 ;; Stores and loads of ax to arbitrary constant address.
1261 ;; We fake an second form of instruction to force reload to load address
1262 ;; into register when rax is not available
1263 (define_insn "*movabssi_1_rex64"
1264 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1265 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1266 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1267 "@
1268 movabs{l}\t{%1, %P0|%P0, %1}
1269 mov{l}\t{%1, %a0|%a0, %1}"
1270 [(set_attr "type" "imov")
1271 (set_attr "modrm" "0,*")
1272 (set_attr "length_address" "8,0")
1273 (set_attr "length_immediate" "0,*")
1274 (set_attr "memory" "store")
1275 (set_attr "mode" "SI")])
1276
1277 (define_insn "*movabssi_2_rex64"
1278 [(set (match_operand:SI 0 "register_operand" "=a,r")
1279 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1280 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1281 "@
1282 movabs{l}\t{%P1, %0|%0, %P1}
1283 mov{l}\t{%a1, %0|%0, %a1}"
1284 [(set_attr "type" "imov")
1285 (set_attr "modrm" "0,*")
1286 (set_attr "length_address" "8,0")
1287 (set_attr "length_immediate" "0")
1288 (set_attr "memory" "load")
1289 (set_attr "mode" "SI")])
1290
1291 (define_insn "*swapsi"
1292 [(set (match_operand:SI 0 "register_operand" "+r")
1293 (match_operand:SI 1 "register_operand" "+r"))
1294 (set (match_dup 1)
1295 (match_dup 0))]
1296 ""
1297 "xchg{l}\t%1, %0"
1298 [(set_attr "type" "imov")
1299 (set_attr "mode" "SI")
1300 (set_attr "pent_pair" "np")
1301 (set_attr "athlon_decode" "vector")
1302 (set_attr "amdfam10_decode" "double")])
1303
1304 (define_expand "movhi"
1305 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1306 (match_operand:HI 1 "general_operand" ""))]
1307 ""
1308 "ix86_expand_move (HImode, operands); DONE;")
1309
1310 (define_insn "*pushhi2"
1311 [(set (match_operand:HI 0 "push_operand" "=X")
1312 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1313 "!TARGET_64BIT"
1314 "push{l}\t%k1"
1315 [(set_attr "type" "push")
1316 (set_attr "mode" "SI")])
1317
1318 ;; For 64BIT abi we always round up to 8 bytes.
1319 (define_insn "*pushhi2_rex64"
1320 [(set (match_operand:HI 0 "push_operand" "=X")
1321 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1322 "TARGET_64BIT"
1323 "push{q}\t%q1"
1324 [(set_attr "type" "push")
1325 (set_attr "mode" "DI")])
1326
1327 (define_insn "*movhi_1"
1328 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1329 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1330 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1331 {
1332 switch (get_attr_type (insn))
1333 {
1334 case TYPE_IMOVX:
1335 /* movzwl is faster than movw on p2 due to partial word stalls,
1336 though not as fast as an aligned movl. */
1337 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1338 default:
1339 if (get_attr_mode (insn) == MODE_SI)
1340 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1341 else
1342 return "mov{w}\t{%1, %0|%0, %1}";
1343 }
1344 }
1345 [(set (attr "type")
1346 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1347 (const_string "imov")
1348 (and (eq_attr "alternative" "0")
1349 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1350 (const_int 0))
1351 (eq (symbol_ref "TARGET_HIMODE_MATH")
1352 (const_int 0))))
1353 (const_string "imov")
1354 (and (eq_attr "alternative" "1,2")
1355 (match_operand:HI 1 "aligned_operand" ""))
1356 (const_string "imov")
1357 (and (ne (symbol_ref "TARGET_MOVX")
1358 (const_int 0))
1359 (eq_attr "alternative" "0,2"))
1360 (const_string "imovx")
1361 ]
1362 (const_string "imov")))
1363 (set (attr "mode")
1364 (cond [(eq_attr "type" "imovx")
1365 (const_string "SI")
1366 (and (eq_attr "alternative" "1,2")
1367 (match_operand:HI 1 "aligned_operand" ""))
1368 (const_string "SI")
1369 (and (eq_attr "alternative" "0")
1370 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1371 (const_int 0))
1372 (eq (symbol_ref "TARGET_HIMODE_MATH")
1373 (const_int 0))))
1374 (const_string "SI")
1375 ]
1376 (const_string "HI")))])
1377
1378 ;; Stores and loads of ax to arbitrary constant address.
1379 ;; We fake an second form of instruction to force reload to load address
1380 ;; into register when rax is not available
1381 (define_insn "*movabshi_1_rex64"
1382 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1383 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1384 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1385 "@
1386 movabs{w}\t{%1, %P0|%P0, %1}
1387 mov{w}\t{%1, %a0|%a0, %1}"
1388 [(set_attr "type" "imov")
1389 (set_attr "modrm" "0,*")
1390 (set_attr "length_address" "8,0")
1391 (set_attr "length_immediate" "0,*")
1392 (set_attr "memory" "store")
1393 (set_attr "mode" "HI")])
1394
1395 (define_insn "*movabshi_2_rex64"
1396 [(set (match_operand:HI 0 "register_operand" "=a,r")
1397 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1398 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1399 "@
1400 movabs{w}\t{%P1, %0|%0, %P1}
1401 mov{w}\t{%a1, %0|%0, %a1}"
1402 [(set_attr "type" "imov")
1403 (set_attr "modrm" "0,*")
1404 (set_attr "length_address" "8,0")
1405 (set_attr "length_immediate" "0")
1406 (set_attr "memory" "load")
1407 (set_attr "mode" "HI")])
1408
1409 (define_insn "*swaphi_1"
1410 [(set (match_operand:HI 0 "register_operand" "+r")
1411 (match_operand:HI 1 "register_operand" "+r"))
1412 (set (match_dup 1)
1413 (match_dup 0))]
1414 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1415 "xchg{l}\t%k1, %k0"
1416 [(set_attr "type" "imov")
1417 (set_attr "mode" "SI")
1418 (set_attr "pent_pair" "np")
1419 (set_attr "athlon_decode" "vector")
1420 (set_attr "amdfam10_decode" "double")])
1421
1422 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1423 (define_insn "*swaphi_2"
1424 [(set (match_operand:HI 0 "register_operand" "+r")
1425 (match_operand:HI 1 "register_operand" "+r"))
1426 (set (match_dup 1)
1427 (match_dup 0))]
1428 "TARGET_PARTIAL_REG_STALL"
1429 "xchg{w}\t%1, %0"
1430 [(set_attr "type" "imov")
1431 (set_attr "mode" "HI")
1432 (set_attr "pent_pair" "np")
1433 (set_attr "athlon_decode" "vector")])
1434
1435 (define_expand "movstricthi"
1436 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1437 (match_operand:HI 1 "general_operand" ""))]
1438 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1439 {
1440 /* Don't generate memory->memory moves, go through a register */
1441 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1442 operands[1] = force_reg (HImode, operands[1]);
1443 })
1444
1445 (define_insn "*movstricthi_1"
1446 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1447 (match_operand:HI 1 "general_operand" "rn,m"))]
1448 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1449 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1450 "mov{w}\t{%1, %0|%0, %1}"
1451 [(set_attr "type" "imov")
1452 (set_attr "mode" "HI")])
1453
1454 (define_insn "*movstricthi_xor"
1455 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1456 (match_operand:HI 1 "const0_operand" "i"))
1457 (clobber (reg:CC FLAGS_REG))]
1458 "reload_completed
1459 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1460 "xor{w}\t{%0, %0|%0, %0}"
1461 [(set_attr "type" "alu1")
1462 (set_attr "mode" "HI")
1463 (set_attr "length_immediate" "0")])
1464
1465 (define_expand "movqi"
1466 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1467 (match_operand:QI 1 "general_operand" ""))]
1468 ""
1469 "ix86_expand_move (QImode, operands); DONE;")
1470
1471 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1472 ;; "push a byte". But actually we use pushl, which has the effect
1473 ;; of rounding the amount pushed up to a word.
1474
1475 (define_insn "*pushqi2"
1476 [(set (match_operand:QI 0 "push_operand" "=X")
1477 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1478 "!TARGET_64BIT"
1479 "push{l}\t%k1"
1480 [(set_attr "type" "push")
1481 (set_attr "mode" "SI")])
1482
1483 ;; For 64BIT abi we always round up to 8 bytes.
1484 (define_insn "*pushqi2_rex64"
1485 [(set (match_operand:QI 0 "push_operand" "=X")
1486 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1487 "TARGET_64BIT"
1488 "push{q}\t%q1"
1489 [(set_attr "type" "push")
1490 (set_attr "mode" "DI")])
1491
1492 ;; Situation is quite tricky about when to choose full sized (SImode) move
1493 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1494 ;; partial register dependency machines (such as AMD Athlon), where QImode
1495 ;; moves issue extra dependency and for partial register stalls machines
1496 ;; that don't use QImode patterns (and QImode move cause stall on the next
1497 ;; instruction).
1498 ;;
1499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1500 ;; register stall machines with, where we use QImode instructions, since
1501 ;; partial register stall can be caused there. Then we use movzx.
1502 (define_insn "*movqi_1"
1503 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1504 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1505 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1506 {
1507 switch (get_attr_type (insn))
1508 {
1509 case TYPE_IMOVX:
1510 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1511 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1512 default:
1513 if (get_attr_mode (insn) == MODE_SI)
1514 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1515 else
1516 return "mov{b}\t{%1, %0|%0, %1}";
1517 }
1518 }
1519 [(set (attr "type")
1520 (cond [(and (eq_attr "alternative" "5")
1521 (not (match_operand:QI 1 "aligned_operand" "")))
1522 (const_string "imovx")
1523 (ne (symbol_ref "optimize_size") (const_int 0))
1524 (const_string "imov")
1525 (and (eq_attr "alternative" "3")
1526 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527 (const_int 0))
1528 (eq (symbol_ref "TARGET_QIMODE_MATH")
1529 (const_int 0))))
1530 (const_string "imov")
1531 (eq_attr "alternative" "3,5")
1532 (const_string "imovx")
1533 (and (ne (symbol_ref "TARGET_MOVX")
1534 (const_int 0))
1535 (eq_attr "alternative" "2"))
1536 (const_string "imovx")
1537 ]
1538 (const_string "imov")))
1539 (set (attr "mode")
1540 (cond [(eq_attr "alternative" "3,4,5")
1541 (const_string "SI")
1542 (eq_attr "alternative" "6")
1543 (const_string "QI")
1544 (eq_attr "type" "imovx")
1545 (const_string "SI")
1546 (and (eq_attr "type" "imov")
1547 (and (eq_attr "alternative" "0,1")
1548 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1549 (const_int 0))
1550 (and (eq (symbol_ref "optimize_size")
1551 (const_int 0))
1552 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1553 (const_int 0))))))
1554 (const_string "SI")
1555 ;; Avoid partial register stalls when not using QImode arithmetic
1556 (and (eq_attr "type" "imov")
1557 (and (eq_attr "alternative" "0,1")
1558 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1559 (const_int 0))
1560 (eq (symbol_ref "TARGET_QIMODE_MATH")
1561 (const_int 0)))))
1562 (const_string "SI")
1563 ]
1564 (const_string "QI")))])
1565
1566 (define_expand "reload_outqi"
1567 [(parallel [(match_operand:QI 0 "" "=m")
1568 (match_operand:QI 1 "register_operand" "r")
1569 (match_operand:QI 2 "register_operand" "=&q")])]
1570 ""
1571 {
1572 rtx op0, op1, op2;
1573 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1574
1575 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1576 if (! q_regs_operand (op1, QImode))
1577 {
1578 emit_insn (gen_movqi (op2, op1));
1579 op1 = op2;
1580 }
1581 emit_insn (gen_movqi (op0, op1));
1582 DONE;
1583 })
1584
1585 (define_insn "*swapqi_1"
1586 [(set (match_operand:QI 0 "register_operand" "+r")
1587 (match_operand:QI 1 "register_operand" "+r"))
1588 (set (match_dup 1)
1589 (match_dup 0))]
1590 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1591 "xchg{l}\t%k1, %k0"
1592 [(set_attr "type" "imov")
1593 (set_attr "mode" "SI")
1594 (set_attr "pent_pair" "np")
1595 (set_attr "athlon_decode" "vector")
1596 (set_attr "amdfam10_decode" "vector")])
1597
1598 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1599 (define_insn "*swapqi_2"
1600 [(set (match_operand:QI 0 "register_operand" "+q")
1601 (match_operand:QI 1 "register_operand" "+q"))
1602 (set (match_dup 1)
1603 (match_dup 0))]
1604 "TARGET_PARTIAL_REG_STALL"
1605 "xchg{b}\t%1, %0"
1606 [(set_attr "type" "imov")
1607 (set_attr "mode" "QI")
1608 (set_attr "pent_pair" "np")
1609 (set_attr "athlon_decode" "vector")])
1610
1611 (define_expand "movstrictqi"
1612 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1613 (match_operand:QI 1 "general_operand" ""))]
1614 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1615 {
1616 /* Don't generate memory->memory moves, go through a register. */
1617 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1618 operands[1] = force_reg (QImode, operands[1]);
1619 })
1620
1621 (define_insn "*movstrictqi_1"
1622 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1623 (match_operand:QI 1 "general_operand" "*qn,m"))]
1624 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1625 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1626 "mov{b}\t{%1, %0|%0, %1}"
1627 [(set_attr "type" "imov")
1628 (set_attr "mode" "QI")])
1629
1630 (define_insn "*movstrictqi_xor"
1631 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1632 (match_operand:QI 1 "const0_operand" "i"))
1633 (clobber (reg:CC FLAGS_REG))]
1634 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1635 "xor{b}\t{%0, %0|%0, %0}"
1636 [(set_attr "type" "alu1")
1637 (set_attr "mode" "QI")
1638 (set_attr "length_immediate" "0")])
1639
1640 (define_insn "*movsi_extv_1"
1641 [(set (match_operand:SI 0 "register_operand" "=R")
1642 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1643 (const_int 8)
1644 (const_int 8)))]
1645 ""
1646 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1647 [(set_attr "type" "imovx")
1648 (set_attr "mode" "SI")])
1649
1650 (define_insn "*movhi_extv_1"
1651 [(set (match_operand:HI 0 "register_operand" "=R")
1652 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1653 (const_int 8)
1654 (const_int 8)))]
1655 ""
1656 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1657 [(set_attr "type" "imovx")
1658 (set_attr "mode" "SI")])
1659
1660 (define_insn "*movqi_extv_1"
1661 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1662 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1663 (const_int 8)
1664 (const_int 8)))]
1665 "!TARGET_64BIT"
1666 {
1667 switch (get_attr_type (insn))
1668 {
1669 case TYPE_IMOVX:
1670 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1671 default:
1672 return "mov{b}\t{%h1, %0|%0, %h1}";
1673 }
1674 }
1675 [(set (attr "type")
1676 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1677 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1678 (ne (symbol_ref "TARGET_MOVX")
1679 (const_int 0))))
1680 (const_string "imovx")
1681 (const_string "imov")))
1682 (set (attr "mode")
1683 (if_then_else (eq_attr "type" "imovx")
1684 (const_string "SI")
1685 (const_string "QI")))])
1686
1687 (define_insn "*movqi_extv_1_rex64"
1688 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1689 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1690 (const_int 8)
1691 (const_int 8)))]
1692 "TARGET_64BIT"
1693 {
1694 switch (get_attr_type (insn))
1695 {
1696 case TYPE_IMOVX:
1697 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1698 default:
1699 return "mov{b}\t{%h1, %0|%0, %h1}";
1700 }
1701 }
1702 [(set (attr "type")
1703 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1704 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1705 (ne (symbol_ref "TARGET_MOVX")
1706 (const_int 0))))
1707 (const_string "imovx")
1708 (const_string "imov")))
1709 (set (attr "mode")
1710 (if_then_else (eq_attr "type" "imovx")
1711 (const_string "SI")
1712 (const_string "QI")))])
1713
1714 ;; Stores and loads of ax to arbitrary constant address.
1715 ;; We fake an second form of instruction to force reload to load address
1716 ;; into register when rax is not available
1717 (define_insn "*movabsqi_1_rex64"
1718 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1719 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1720 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1721 "@
1722 movabs{b}\t{%1, %P0|%P0, %1}
1723 mov{b}\t{%1, %a0|%a0, %1}"
1724 [(set_attr "type" "imov")
1725 (set_attr "modrm" "0,*")
1726 (set_attr "length_address" "8,0")
1727 (set_attr "length_immediate" "0,*")
1728 (set_attr "memory" "store")
1729 (set_attr "mode" "QI")])
1730
1731 (define_insn "*movabsqi_2_rex64"
1732 [(set (match_operand:QI 0 "register_operand" "=a,r")
1733 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1734 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1735 "@
1736 movabs{b}\t{%P1, %0|%0, %P1}
1737 mov{b}\t{%a1, %0|%0, %a1}"
1738 [(set_attr "type" "imov")
1739 (set_attr "modrm" "0,*")
1740 (set_attr "length_address" "8,0")
1741 (set_attr "length_immediate" "0")
1742 (set_attr "memory" "load")
1743 (set_attr "mode" "QI")])
1744
1745 (define_insn "*movdi_extzv_1"
1746 [(set (match_operand:DI 0 "register_operand" "=R")
1747 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1748 (const_int 8)
1749 (const_int 8)))]
1750 "TARGET_64BIT"
1751 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1752 [(set_attr "type" "imovx")
1753 (set_attr "mode" "DI")])
1754
1755 (define_insn "*movsi_extzv_1"
1756 [(set (match_operand:SI 0 "register_operand" "=R")
1757 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1758 (const_int 8)
1759 (const_int 8)))]
1760 ""
1761 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1762 [(set_attr "type" "imovx")
1763 (set_attr "mode" "SI")])
1764
1765 (define_insn "*movqi_extzv_2"
1766 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1767 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1768 (const_int 8)
1769 (const_int 8)) 0))]
1770 "!TARGET_64BIT"
1771 {
1772 switch (get_attr_type (insn))
1773 {
1774 case TYPE_IMOVX:
1775 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1776 default:
1777 return "mov{b}\t{%h1, %0|%0, %h1}";
1778 }
1779 }
1780 [(set (attr "type")
1781 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1782 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1783 (ne (symbol_ref "TARGET_MOVX")
1784 (const_int 0))))
1785 (const_string "imovx")
1786 (const_string "imov")))
1787 (set (attr "mode")
1788 (if_then_else (eq_attr "type" "imovx")
1789 (const_string "SI")
1790 (const_string "QI")))])
1791
1792 (define_insn "*movqi_extzv_2_rex64"
1793 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1794 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1795 (const_int 8)
1796 (const_int 8)) 0))]
1797 "TARGET_64BIT"
1798 {
1799 switch (get_attr_type (insn))
1800 {
1801 case TYPE_IMOVX:
1802 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1803 default:
1804 return "mov{b}\t{%h1, %0|%0, %h1}";
1805 }
1806 }
1807 [(set (attr "type")
1808 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1809 (ne (symbol_ref "TARGET_MOVX")
1810 (const_int 0)))
1811 (const_string "imovx")
1812 (const_string "imov")))
1813 (set (attr "mode")
1814 (if_then_else (eq_attr "type" "imovx")
1815 (const_string "SI")
1816 (const_string "QI")))])
1817
1818 (define_insn "movsi_insv_1"
1819 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1820 (const_int 8)
1821 (const_int 8))
1822 (match_operand:SI 1 "general_operand" "Qmn"))]
1823 "!TARGET_64BIT"
1824 "mov{b}\t{%b1, %h0|%h0, %b1}"
1825 [(set_attr "type" "imov")
1826 (set_attr "mode" "QI")])
1827
1828 (define_insn "*movsi_insv_1_rex64"
1829 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1830 (const_int 8)
1831 (const_int 8))
1832 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1833 "TARGET_64BIT"
1834 "mov{b}\t{%b1, %h0|%h0, %b1}"
1835 [(set_attr "type" "imov")
1836 (set_attr "mode" "QI")])
1837
1838 (define_insn "movdi_insv_1_rex64"
1839 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1840 (const_int 8)
1841 (const_int 8))
1842 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1843 "TARGET_64BIT"
1844 "mov{b}\t{%b1, %h0|%h0, %b1}"
1845 [(set_attr "type" "imov")
1846 (set_attr "mode" "QI")])
1847
1848 (define_insn "*movqi_insv_2"
1849 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1850 (const_int 8)
1851 (const_int 8))
1852 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1853 (const_int 8)))]
1854 ""
1855 "mov{b}\t{%h1, %h0|%h0, %h1}"
1856 [(set_attr "type" "imov")
1857 (set_attr "mode" "QI")])
1858
1859 (define_expand "movdi"
1860 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1861 (match_operand:DI 1 "general_operand" ""))]
1862 ""
1863 "ix86_expand_move (DImode, operands); DONE;")
1864
1865 (define_insn "*pushdi"
1866 [(set (match_operand:DI 0 "push_operand" "=<")
1867 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1868 "!TARGET_64BIT"
1869 "#")
1870
1871 (define_insn "*pushdi2_rex64"
1872 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1873 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1874 "TARGET_64BIT"
1875 "@
1876 push{q}\t%1
1877 #"
1878 [(set_attr "type" "push,multi")
1879 (set_attr "mode" "DI")])
1880
1881 ;; Convert impossible pushes of immediate to existing instructions.
1882 ;; First try to get scratch register and go through it. In case this
1883 ;; fails, push sign extended lower part first and then overwrite
1884 ;; upper part by 32bit move.
1885 (define_peephole2
1886 [(match_scratch:DI 2 "r")
1887 (set (match_operand:DI 0 "push_operand" "")
1888 (match_operand:DI 1 "immediate_operand" ""))]
1889 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1890 && !x86_64_immediate_operand (operands[1], DImode)"
1891 [(set (match_dup 2) (match_dup 1))
1892 (set (match_dup 0) (match_dup 2))]
1893 "")
1894
1895 ;; We need to define this as both peepholer and splitter for case
1896 ;; peephole2 pass is not run.
1897 ;; "&& 1" is needed to keep it from matching the previous pattern.
1898 (define_peephole2
1899 [(set (match_operand:DI 0 "push_operand" "")
1900 (match_operand:DI 1 "immediate_operand" ""))]
1901 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1902 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1903 [(set (match_dup 0) (match_dup 1))
1904 (set (match_dup 2) (match_dup 3))]
1905 "split_di (operands + 1, 1, operands + 2, operands + 3);
1906 operands[1] = gen_lowpart (DImode, operands[2]);
1907 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1908 GEN_INT (4)));
1909 ")
1910
1911 (define_split
1912 [(set (match_operand:DI 0 "push_operand" "")
1913 (match_operand:DI 1 "immediate_operand" ""))]
1914 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1915 ? flow2_completed : reload_completed)
1916 && !symbolic_operand (operands[1], DImode)
1917 && !x86_64_immediate_operand (operands[1], DImode)"
1918 [(set (match_dup 0) (match_dup 1))
1919 (set (match_dup 2) (match_dup 3))]
1920 "split_di (operands + 1, 1, operands + 2, operands + 3);
1921 operands[1] = gen_lowpart (DImode, operands[2]);
1922 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1923 GEN_INT (4)));
1924 ")
1925
1926 (define_insn "*pushdi2_prologue_rex64"
1927 [(set (match_operand:DI 0 "push_operand" "=<")
1928 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1929 (clobber (mem:BLK (scratch)))]
1930 "TARGET_64BIT"
1931 "push{q}\t%1"
1932 [(set_attr "type" "push")
1933 (set_attr "mode" "DI")])
1934
1935 (define_insn "*popdi1_epilogue_rex64"
1936 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1937 (mem:DI (reg:DI SP_REG)))
1938 (set (reg:DI SP_REG)
1939 (plus:DI (reg:DI SP_REG) (const_int 8)))
1940 (clobber (mem:BLK (scratch)))]
1941 "TARGET_64BIT"
1942 "pop{q}\t%0"
1943 [(set_attr "type" "pop")
1944 (set_attr "mode" "DI")])
1945
1946 (define_insn "popdi1"
1947 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1948 (mem:DI (reg:DI SP_REG)))
1949 (set (reg:DI SP_REG)
1950 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1951 "TARGET_64BIT"
1952 "pop{q}\t%0"
1953 [(set_attr "type" "pop")
1954 (set_attr "mode" "DI")])
1955
1956 (define_insn "*movdi_xor_rex64"
1957 [(set (match_operand:DI 0 "register_operand" "=r")
1958 (match_operand:DI 1 "const0_operand" "i"))
1959 (clobber (reg:CC FLAGS_REG))]
1960 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1961 && reload_completed"
1962 "xor{l}\t{%k0, %k0|%k0, %k0}"
1963 [(set_attr "type" "alu1")
1964 (set_attr "mode" "SI")
1965 (set_attr "length_immediate" "0")])
1966
1967 (define_insn "*movdi_or_rex64"
1968 [(set (match_operand:DI 0 "register_operand" "=r")
1969 (match_operand:DI 1 "const_int_operand" "i"))
1970 (clobber (reg:CC FLAGS_REG))]
1971 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1972 && reload_completed
1973 && operands[1] == constm1_rtx"
1974 {
1975 operands[1] = constm1_rtx;
1976 return "or{q}\t{%1, %0|%0, %1}";
1977 }
1978 [(set_attr "type" "alu1")
1979 (set_attr "mode" "DI")
1980 (set_attr "length_immediate" "1")])
1981
1982 (define_insn "*movdi_2"
1983 [(set (match_operand:DI 0 "nonimmediate_operand"
1984 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
1985 (match_operand:DI 1 "general_operand"
1986 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
1987 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1988 "@
1989 #
1990 #
1991 pxor\t%0, %0
1992 movq\t{%1, %0|%0, %1}
1993 movq\t{%1, %0|%0, %1}
1994 pxor\t%0, %0
1995 movq\t{%1, %0|%0, %1}
1996 movdqa\t{%1, %0|%0, %1}
1997 movq\t{%1, %0|%0, %1}
1998 xorps\t%0, %0
1999 movlps\t{%1, %0|%0, %1}
2000 movaps\t{%1, %0|%0, %1}
2001 movlps\t{%1, %0|%0, %1}"
2002 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2003 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2004
2005 (define_split
2006 [(set (match_operand:DI 0 "push_operand" "")
2007 (match_operand:DI 1 "general_operand" ""))]
2008 "!TARGET_64BIT && reload_completed
2009 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2010 [(const_int 0)]
2011 "ix86_split_long_move (operands); DONE;")
2012
2013 ;; %%% This multiword shite has got to go.
2014 (define_split
2015 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2016 (match_operand:DI 1 "general_operand" ""))]
2017 "!TARGET_64BIT && reload_completed
2018 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2019 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2020 [(const_int 0)]
2021 "ix86_split_long_move (operands); DONE;")
2022
2023 (define_insn "*movdi_1_rex64"
2024 [(set (match_operand:DI 0 "nonimmediate_operand"
2025 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2026 (match_operand:DI 1 "general_operand"
2027 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2028 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2029 {
2030 switch (get_attr_type (insn))
2031 {
2032 case TYPE_SSECVT:
2033 if (SSE_REG_P (operands[0]))
2034 return "movq2dq\t{%1, %0|%0, %1}";
2035 else
2036 return "movdq2q\t{%1, %0|%0, %1}";
2037
2038 case TYPE_SSEMOV:
2039 if (get_attr_mode (insn) == MODE_TI)
2040 return "movdqa\t{%1, %0|%0, %1}";
2041 /* FALLTHRU */
2042
2043 case TYPE_MMXMOV:
2044 /* Moves from and into integer register is done using movd
2045 opcode with REX prefix. */
2046 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2047 return "movd\t{%1, %0|%0, %1}";
2048 return "movq\t{%1, %0|%0, %1}";
2049
2050 case TYPE_SSELOG1:
2051 case TYPE_MMXADD:
2052 return "pxor\t%0, %0";
2053
2054 case TYPE_MULTI:
2055 return "#";
2056
2057 case TYPE_LEA:
2058 return "lea{q}\t{%a1, %0|%0, %a1}";
2059
2060 default:
2061 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2062 if (get_attr_mode (insn) == MODE_SI)
2063 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2064 else if (which_alternative == 2)
2065 return "movabs{q}\t{%1, %0|%0, %1}";
2066 else
2067 return "mov{q}\t{%1, %0|%0, %1}";
2068 }
2069 }
2070 [(set (attr "type")
2071 (cond [(eq_attr "alternative" "5")
2072 (const_string "mmxadd")
2073 (eq_attr "alternative" "6,7,8,9,10")
2074 (const_string "mmxmov")
2075 (eq_attr "alternative" "11")
2076 (const_string "sselog1")
2077 (eq_attr "alternative" "12,13,14,15,16")
2078 (const_string "ssemov")
2079 (eq_attr "alternative" "17,18")
2080 (const_string "ssecvt")
2081 (eq_attr "alternative" "4")
2082 (const_string "multi")
2083 (match_operand:DI 1 "pic_32bit_operand" "")
2084 (const_string "lea")
2085 ]
2086 (const_string "imov")))
2087 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2088 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2089 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2090
2091 ;; Stores and loads of ax to arbitrary constant address.
2092 ;; We fake an second form of instruction to force reload to load address
2093 ;; into register when rax is not available
2094 (define_insn "*movabsdi_1_rex64"
2095 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2096 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2097 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2098 "@
2099 movabs{q}\t{%1, %P0|%P0, %1}
2100 mov{q}\t{%1, %a0|%a0, %1}"
2101 [(set_attr "type" "imov")
2102 (set_attr "modrm" "0,*")
2103 (set_attr "length_address" "8,0")
2104 (set_attr "length_immediate" "0,*")
2105 (set_attr "memory" "store")
2106 (set_attr "mode" "DI")])
2107
2108 (define_insn "*movabsdi_2_rex64"
2109 [(set (match_operand:DI 0 "register_operand" "=a,r")
2110 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2111 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2112 "@
2113 movabs{q}\t{%P1, %0|%0, %P1}
2114 mov{q}\t{%a1, %0|%0, %a1}"
2115 [(set_attr "type" "imov")
2116 (set_attr "modrm" "0,*")
2117 (set_attr "length_address" "8,0")
2118 (set_attr "length_immediate" "0")
2119 (set_attr "memory" "load")
2120 (set_attr "mode" "DI")])
2121
2122 ;; Convert impossible stores of immediate to existing instructions.
2123 ;; First try to get scratch register and go through it. In case this
2124 ;; fails, move by 32bit parts.
2125 (define_peephole2
2126 [(match_scratch:DI 2 "r")
2127 (set (match_operand:DI 0 "memory_operand" "")
2128 (match_operand:DI 1 "immediate_operand" ""))]
2129 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130 && !x86_64_immediate_operand (operands[1], DImode)"
2131 [(set (match_dup 2) (match_dup 1))
2132 (set (match_dup 0) (match_dup 2))]
2133 "")
2134
2135 ;; We need to define this as both peepholer and splitter for case
2136 ;; peephole2 pass is not run.
2137 ;; "&& 1" is needed to keep it from matching the previous pattern.
2138 (define_peephole2
2139 [(set (match_operand:DI 0 "memory_operand" "")
2140 (match_operand:DI 1 "immediate_operand" ""))]
2141 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2142 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2143 [(set (match_dup 2) (match_dup 3))
2144 (set (match_dup 4) (match_dup 5))]
2145 "split_di (operands, 2, operands + 2, operands + 4);")
2146
2147 (define_split
2148 [(set (match_operand:DI 0 "memory_operand" "")
2149 (match_operand:DI 1 "immediate_operand" ""))]
2150 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151 ? flow2_completed : reload_completed)
2152 && !symbolic_operand (operands[1], DImode)
2153 && !x86_64_immediate_operand (operands[1], DImode)"
2154 [(set (match_dup 2) (match_dup 3))
2155 (set (match_dup 4) (match_dup 5))]
2156 "split_di (operands, 2, operands + 2, operands + 4);")
2157
2158 (define_insn "*swapdi_rex64"
2159 [(set (match_operand:DI 0 "register_operand" "+r")
2160 (match_operand:DI 1 "register_operand" "+r"))
2161 (set (match_dup 1)
2162 (match_dup 0))]
2163 "TARGET_64BIT"
2164 "xchg{q}\t%1, %0"
2165 [(set_attr "type" "imov")
2166 (set_attr "mode" "DI")
2167 (set_attr "pent_pair" "np")
2168 (set_attr "athlon_decode" "vector")
2169 (set_attr "amdfam10_decode" "double")])
2170
2171 (define_expand "movti"
2172 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2173 (match_operand:TI 1 "nonimmediate_operand" ""))]
2174 "TARGET_SSE || TARGET_64BIT"
2175 {
2176 if (TARGET_64BIT)
2177 ix86_expand_move (TImode, operands);
2178 else
2179 ix86_expand_vector_move (TImode, operands);
2180 DONE;
2181 })
2182
2183 (define_insn "*movti_internal"
2184 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2185 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2186 "TARGET_SSE && !TARGET_64BIT
2187 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2188 {
2189 switch (which_alternative)
2190 {
2191 case 0:
2192 if (get_attr_mode (insn) == MODE_V4SF)
2193 return "xorps\t%0, %0";
2194 else
2195 return "pxor\t%0, %0";
2196 case 1:
2197 case 2:
2198 if (get_attr_mode (insn) == MODE_V4SF)
2199 return "movaps\t{%1, %0|%0, %1}";
2200 else
2201 return "movdqa\t{%1, %0|%0, %1}";
2202 default:
2203 gcc_unreachable ();
2204 }
2205 }
2206 [(set_attr "type" "sselog1,ssemov,ssemov")
2207 (set (attr "mode")
2208 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2209 (ne (symbol_ref "optimize_size") (const_int 0)))
2210 (const_string "V4SF")
2211 (and (eq_attr "alternative" "2")
2212 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2213 (const_int 0)))
2214 (const_string "V4SF")]
2215 (const_string "TI")))])
2216
2217 (define_insn "*movti_rex64"
2218 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2219 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2220 "TARGET_64BIT
2221 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2222 {
2223 switch (which_alternative)
2224 {
2225 case 0:
2226 case 1:
2227 return "#";
2228 case 2:
2229 if (get_attr_mode (insn) == MODE_V4SF)
2230 return "xorps\t%0, %0";
2231 else
2232 return "pxor\t%0, %0";
2233 case 3:
2234 case 4:
2235 if (get_attr_mode (insn) == MODE_V4SF)
2236 return "movaps\t{%1, %0|%0, %1}";
2237 else
2238 return "movdqa\t{%1, %0|%0, %1}";
2239 default:
2240 gcc_unreachable ();
2241 }
2242 }
2243 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2244 (set (attr "mode")
2245 (cond [(eq_attr "alternative" "2,3")
2246 (if_then_else
2247 (ne (symbol_ref "optimize_size")
2248 (const_int 0))
2249 (const_string "V4SF")
2250 (const_string "TI"))
2251 (eq_attr "alternative" "4")
2252 (if_then_else
2253 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2254 (const_int 0))
2255 (ne (symbol_ref "optimize_size")
2256 (const_int 0)))
2257 (const_string "V4SF")
2258 (const_string "TI"))]
2259 (const_string "DI")))])
2260
2261 (define_split
2262 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2263 (match_operand:TI 1 "general_operand" ""))]
2264 "reload_completed && !SSE_REG_P (operands[0])
2265 && !SSE_REG_P (operands[1])"
2266 [(const_int 0)]
2267 "ix86_split_long_move (operands); DONE;")
2268
2269 (define_expand "movsf"
2270 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2271 (match_operand:SF 1 "general_operand" ""))]
2272 ""
2273 "ix86_expand_move (SFmode, operands); DONE;")
2274
2275 (define_insn "*pushsf"
2276 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2277 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2278 "!TARGET_64BIT"
2279 {
2280 /* Anything else should be already split before reg-stack. */
2281 gcc_assert (which_alternative == 1);
2282 return "push{l}\t%1";
2283 }
2284 [(set_attr "type" "multi,push,multi")
2285 (set_attr "unit" "i387,*,*")
2286 (set_attr "mode" "SF,SI,SF")])
2287
2288 (define_insn "*pushsf_rex64"
2289 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2290 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2291 "TARGET_64BIT"
2292 {
2293 /* Anything else should be already split before reg-stack. */
2294 gcc_assert (which_alternative == 1);
2295 return "push{q}\t%q1";
2296 }
2297 [(set_attr "type" "multi,push,multi")
2298 (set_attr "unit" "i387,*,*")
2299 (set_attr "mode" "SF,DI,SF")])
2300
2301 (define_split
2302 [(set (match_operand:SF 0 "push_operand" "")
2303 (match_operand:SF 1 "memory_operand" ""))]
2304 "reload_completed
2305 && MEM_P (operands[1])
2306 && constant_pool_reference_p (operands[1])"
2307 [(set (match_dup 0)
2308 (match_dup 1))]
2309 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2310
2311
2312 ;; %%% Kill this when call knows how to work this out.
2313 (define_split
2314 [(set (match_operand:SF 0 "push_operand" "")
2315 (match_operand:SF 1 "any_fp_register_operand" ""))]
2316 "!TARGET_64BIT"
2317 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2318 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2319
2320 (define_split
2321 [(set (match_operand:SF 0 "push_operand" "")
2322 (match_operand:SF 1 "any_fp_register_operand" ""))]
2323 "TARGET_64BIT"
2324 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2325 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2326
2327 (define_insn "*movsf_1"
2328 [(set (match_operand:SF 0 "nonimmediate_operand"
2329 "=f,m,f,r ,m ,x,x,x ,m,*y,m ,*y,Yi,r ,*Ym,r ")
2330 (match_operand:SF 1 "general_operand"
2331 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y,r ,Yi,r ,*Ym"))]
2332 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2333 && (reload_in_progress || reload_completed
2334 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2335 || (!TARGET_SSE_MATH && optimize_size
2336 && standard_80387_constant_p (operands[1]))
2337 || GET_CODE (operands[1]) != CONST_DOUBLE
2338 || memory_operand (operands[0], SFmode))"
2339 {
2340 switch (which_alternative)
2341 {
2342 case 0:
2343 return output_387_reg_move (insn, operands);
2344
2345 case 1:
2346 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2347 return "fstp%z0\t%y0";
2348 else
2349 return "fst%z0\t%y0";
2350
2351 case 2:
2352 return standard_80387_constant_opcode (operands[1]);
2353
2354 case 3:
2355 case 4:
2356 return "mov{l}\t{%1, %0|%0, %1}";
2357 case 5:
2358 if (get_attr_mode (insn) == MODE_TI)
2359 return "pxor\t%0, %0";
2360 else
2361 return "xorps\t%0, %0";
2362 case 6:
2363 if (get_attr_mode (insn) == MODE_V4SF)
2364 return "movaps\t{%1, %0|%0, %1}";
2365 else
2366 return "movss\t{%1, %0|%0, %1}";
2367 case 7: case 8:
2368 return "movss\t{%1, %0|%0, %1}";
2369
2370 case 9: case 10:
2371 case 12: case 13: case 14: case 15:
2372 return "movd\t{%1, %0|%0, %1}";
2373
2374 case 11:
2375 return "movq\t{%1, %0|%0, %1}";
2376
2377 default:
2378 gcc_unreachable ();
2379 }
2380 }
2381 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2382 (set (attr "mode")
2383 (cond [(eq_attr "alternative" "3,4,9,10")
2384 (const_string "SI")
2385 (eq_attr "alternative" "5")
2386 (if_then_else
2387 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2388 (const_int 0))
2389 (ne (symbol_ref "TARGET_SSE2")
2390 (const_int 0)))
2391 (eq (symbol_ref "optimize_size")
2392 (const_int 0)))
2393 (const_string "TI")
2394 (const_string "V4SF"))
2395 /* For architectures resolving dependencies on
2396 whole SSE registers use APS move to break dependency
2397 chains, otherwise use short move to avoid extra work.
2398
2399 Do the same for architectures resolving dependencies on
2400 the parts. While in DF mode it is better to always handle
2401 just register parts, the SF mode is different due to lack
2402 of instructions to load just part of the register. It is
2403 better to maintain the whole registers in single format
2404 to avoid problems on using packed logical operations. */
2405 (eq_attr "alternative" "6")
2406 (if_then_else
2407 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2408 (const_int 0))
2409 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2410 (const_int 0)))
2411 (const_string "V4SF")
2412 (const_string "SF"))
2413 (eq_attr "alternative" "11")
2414 (const_string "DI")]
2415 (const_string "SF")))])
2416
2417 (define_insn "*swapsf"
2418 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2419 (match_operand:SF 1 "fp_register_operand" "+f"))
2420 (set (match_dup 1)
2421 (match_dup 0))]
2422 "reload_completed || TARGET_80387"
2423 {
2424 if (STACK_TOP_P (operands[0]))
2425 return "fxch\t%1";
2426 else
2427 return "fxch\t%0";
2428 }
2429 [(set_attr "type" "fxch")
2430 (set_attr "mode" "SF")])
2431
2432 (define_expand "movdf"
2433 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2434 (match_operand:DF 1 "general_operand" ""))]
2435 ""
2436 "ix86_expand_move (DFmode, operands); DONE;")
2437
2438 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2439 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2440 ;; On the average, pushdf using integers can be still shorter. Allow this
2441 ;; pattern for optimize_size too.
2442
2443 (define_insn "*pushdf_nointeger"
2444 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2445 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2446 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2447 {
2448 /* This insn should be already split before reg-stack. */
2449 gcc_unreachable ();
2450 }
2451 [(set_attr "type" "multi")
2452 (set_attr "unit" "i387,*,*,*")
2453 (set_attr "mode" "DF,SI,SI,DF")])
2454
2455 (define_insn "*pushdf_integer"
2456 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2457 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2458 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2459 {
2460 /* This insn should be already split before reg-stack. */
2461 gcc_unreachable ();
2462 }
2463 [(set_attr "type" "multi")
2464 (set_attr "unit" "i387,*,*")
2465 (set_attr "mode" "DF,SI,DF")])
2466
2467 ;; %%% Kill this when call knows how to work this out.
2468 (define_split
2469 [(set (match_operand:DF 0 "push_operand" "")
2470 (match_operand:DF 1 "any_fp_register_operand" ""))]
2471 "!TARGET_64BIT && reload_completed"
2472 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2473 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2474 "")
2475
2476 (define_split
2477 [(set (match_operand:DF 0 "push_operand" "")
2478 (match_operand:DF 1 "any_fp_register_operand" ""))]
2479 "TARGET_64BIT && reload_completed"
2480 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2481 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2482 "")
2483
2484 (define_split
2485 [(set (match_operand:DF 0 "push_operand" "")
2486 (match_operand:DF 1 "general_operand" ""))]
2487 "reload_completed"
2488 [(const_int 0)]
2489 "ix86_split_long_move (operands); DONE;")
2490
2491 ;; Moving is usually shorter when only FP registers are used. This separate
2492 ;; movdf pattern avoids the use of integer registers for FP operations
2493 ;; when optimizing for size.
2494
2495 (define_insn "*movdf_nointeger"
2496 [(set (match_operand:DF 0 "nonimmediate_operand"
2497 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2498 (match_operand:DF 1 "general_operand"
2499 "fm,f,G,*roF,F*r,C ,Y2*x,mY2*x,Y2*x"))]
2500 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2501 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2502 && (reload_in_progress || reload_completed
2503 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2504 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2505 && standard_80387_constant_p (operands[1]))
2506 || GET_CODE (operands[1]) != CONST_DOUBLE
2507 || memory_operand (operands[0], DFmode))"
2508 {
2509 switch (which_alternative)
2510 {
2511 case 0:
2512 return output_387_reg_move (insn, operands);
2513
2514 case 1:
2515 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2516 return "fstp%z0\t%y0";
2517 else
2518 return "fst%z0\t%y0";
2519
2520 case 2:
2521 return standard_80387_constant_opcode (operands[1]);
2522
2523 case 3:
2524 case 4:
2525 return "#";
2526 case 5:
2527 switch (get_attr_mode (insn))
2528 {
2529 case MODE_V4SF:
2530 return "xorps\t%0, %0";
2531 case MODE_V2DF:
2532 return "xorpd\t%0, %0";
2533 case MODE_TI:
2534 return "pxor\t%0, %0";
2535 default:
2536 gcc_unreachable ();
2537 }
2538 case 6:
2539 case 7:
2540 case 8:
2541 switch (get_attr_mode (insn))
2542 {
2543 case MODE_V4SF:
2544 return "movaps\t{%1, %0|%0, %1}";
2545 case MODE_V2DF:
2546 return "movapd\t{%1, %0|%0, %1}";
2547 case MODE_TI:
2548 return "movdqa\t{%1, %0|%0, %1}";
2549 case MODE_DI:
2550 return "movq\t{%1, %0|%0, %1}";
2551 case MODE_DF:
2552 return "movsd\t{%1, %0|%0, %1}";
2553 case MODE_V1DF:
2554 return "movlpd\t{%1, %0|%0, %1}";
2555 case MODE_V2SF:
2556 return "movlps\t{%1, %0|%0, %1}";
2557 default:
2558 gcc_unreachable ();
2559 }
2560
2561 default:
2562 gcc_unreachable ();
2563 }
2564 }
2565 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2566 (set (attr "mode")
2567 (cond [(eq_attr "alternative" "0,1,2")
2568 (const_string "DF")
2569 (eq_attr "alternative" "3,4")
2570 (const_string "SI")
2571
2572 /* For SSE1, we have many fewer alternatives. */
2573 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2574 (cond [(eq_attr "alternative" "5,6")
2575 (const_string "V4SF")
2576 ]
2577 (const_string "V2SF"))
2578
2579 /* xorps is one byte shorter. */
2580 (eq_attr "alternative" "5")
2581 (cond [(ne (symbol_ref "optimize_size")
2582 (const_int 0))
2583 (const_string "V4SF")
2584 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2585 (const_int 0))
2586 (const_string "TI")
2587 ]
2588 (const_string "V2DF"))
2589
2590 /* For architectures resolving dependencies on
2591 whole SSE registers use APD move to break dependency
2592 chains, otherwise use short move to avoid extra work.
2593
2594 movaps encodes one byte shorter. */
2595 (eq_attr "alternative" "6")
2596 (cond
2597 [(ne (symbol_ref "optimize_size")
2598 (const_int 0))
2599 (const_string "V4SF")
2600 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2601 (const_int 0))
2602 (const_string "V2DF")
2603 ]
2604 (const_string "DF"))
2605 /* For architectures resolving dependencies on register
2606 parts we may avoid extra work to zero out upper part
2607 of register. */
2608 (eq_attr "alternative" "7")
2609 (if_then_else
2610 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2611 (const_int 0))
2612 (const_string "V1DF")
2613 (const_string "DF"))
2614 ]
2615 (const_string "DF")))])
2616
2617 (define_insn "*movdf_integer_rex64"
2618 [(set (match_operand:DF 0 "nonimmediate_operand"
2619 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2620 (match_operand:DF 1 "general_operand"
2621 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2622 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2623 && (reload_in_progress || reload_completed
2624 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2625 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2626 && standard_80387_constant_p (operands[1]))
2627 || GET_CODE (operands[1]) != CONST_DOUBLE
2628 || memory_operand (operands[0], DFmode))"
2629 {
2630 switch (which_alternative)
2631 {
2632 case 0:
2633 return output_387_reg_move (insn, operands);
2634
2635 case 1:
2636 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2637 return "fstp%z0\t%y0";
2638 else
2639 return "fst%z0\t%y0";
2640
2641 case 2:
2642 return standard_80387_constant_opcode (operands[1]);
2643
2644 case 3:
2645 case 4:
2646 return "#";
2647
2648 case 5:
2649 switch (get_attr_mode (insn))
2650 {
2651 case MODE_V4SF:
2652 return "xorps\t%0, %0";
2653 case MODE_V2DF:
2654 return "xorpd\t%0, %0";
2655 case MODE_TI:
2656 return "pxor\t%0, %0";
2657 default:
2658 gcc_unreachable ();
2659 }
2660 case 6:
2661 case 7:
2662 case 8:
2663 switch (get_attr_mode (insn))
2664 {
2665 case MODE_V4SF:
2666 return "movaps\t{%1, %0|%0, %1}";
2667 case MODE_V2DF:
2668 return "movapd\t{%1, %0|%0, %1}";
2669 case MODE_TI:
2670 return "movdqa\t{%1, %0|%0, %1}";
2671 case MODE_DI:
2672 return "movq\t{%1, %0|%0, %1}";
2673 case MODE_DF:
2674 return "movsd\t{%1, %0|%0, %1}";
2675 case MODE_V1DF:
2676 return "movlpd\t{%1, %0|%0, %1}";
2677 case MODE_V2SF:
2678 return "movlps\t{%1, %0|%0, %1}";
2679 default:
2680 gcc_unreachable ();
2681 }
2682
2683 case 9:
2684 case 10:
2685 return "movd\t{%1, %0|%0, %1}";
2686
2687 default:
2688 gcc_unreachable();
2689 }
2690 }
2691 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2692 (set (attr "mode")
2693 (cond [(eq_attr "alternative" "0,1,2")
2694 (const_string "DF")
2695 (eq_attr "alternative" "3,4,9,10")
2696 (const_string "DI")
2697
2698 /* For SSE1, we have many fewer alternatives. */
2699 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2700 (cond [(eq_attr "alternative" "5,6")
2701 (const_string "V4SF")
2702 ]
2703 (const_string "V2SF"))
2704
2705 /* xorps is one byte shorter. */
2706 (eq_attr "alternative" "5")
2707 (cond [(ne (symbol_ref "optimize_size")
2708 (const_int 0))
2709 (const_string "V4SF")
2710 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2711 (const_int 0))
2712 (const_string "TI")
2713 ]
2714 (const_string "V2DF"))
2715
2716 /* For architectures resolving dependencies on
2717 whole SSE registers use APD move to break dependency
2718 chains, otherwise use short move to avoid extra work.
2719
2720 movaps encodes one byte shorter. */
2721 (eq_attr "alternative" "6")
2722 (cond
2723 [(ne (symbol_ref "optimize_size")
2724 (const_int 0))
2725 (const_string "V4SF")
2726 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2727 (const_int 0))
2728 (const_string "V2DF")
2729 ]
2730 (const_string "DF"))
2731 /* For architectures resolving dependencies on register
2732 parts we may avoid extra work to zero out upper part
2733 of register. */
2734 (eq_attr "alternative" "7")
2735 (if_then_else
2736 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2737 (const_int 0))
2738 (const_string "V1DF")
2739 (const_string "DF"))
2740 ]
2741 (const_string "DF")))])
2742
2743 (define_insn "*movdf_integer"
2744 [(set (match_operand:DF 0 "nonimmediate_operand"
2745 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2746 (match_operand:DF 1 "general_operand"
2747 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2748 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2749 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2750 && (reload_in_progress || reload_completed
2751 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2752 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2753 && standard_80387_constant_p (operands[1]))
2754 || GET_CODE (operands[1]) != CONST_DOUBLE
2755 || memory_operand (operands[0], DFmode))"
2756 {
2757 switch (which_alternative)
2758 {
2759 case 0:
2760 return output_387_reg_move (insn, operands);
2761
2762 case 1:
2763 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2764 return "fstp%z0\t%y0";
2765 else
2766 return "fst%z0\t%y0";
2767
2768 case 2:
2769 return standard_80387_constant_opcode (operands[1]);
2770
2771 case 3:
2772 case 4:
2773 return "#";
2774
2775 case 5:
2776 switch (get_attr_mode (insn))
2777 {
2778 case MODE_V4SF:
2779 return "xorps\t%0, %0";
2780 case MODE_V2DF:
2781 return "xorpd\t%0, %0";
2782 case MODE_TI:
2783 return "pxor\t%0, %0";
2784 default:
2785 gcc_unreachable ();
2786 }
2787 case 6:
2788 case 7:
2789 case 8:
2790 switch (get_attr_mode (insn))
2791 {
2792 case MODE_V4SF:
2793 return "movaps\t{%1, %0|%0, %1}";
2794 case MODE_V2DF:
2795 return "movapd\t{%1, %0|%0, %1}";
2796 case MODE_TI:
2797 return "movdqa\t{%1, %0|%0, %1}";
2798 case MODE_DI:
2799 return "movq\t{%1, %0|%0, %1}";
2800 case MODE_DF:
2801 return "movsd\t{%1, %0|%0, %1}";
2802 case MODE_V1DF:
2803 return "movlpd\t{%1, %0|%0, %1}";
2804 case MODE_V2SF:
2805 return "movlps\t{%1, %0|%0, %1}";
2806 default:
2807 gcc_unreachable ();
2808 }
2809
2810 default:
2811 gcc_unreachable();
2812 }
2813 }
2814 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2815 (set (attr "mode")
2816 (cond [(eq_attr "alternative" "0,1,2")
2817 (const_string "DF")
2818 (eq_attr "alternative" "3,4")
2819 (const_string "SI")
2820
2821 /* For SSE1, we have many fewer alternatives. */
2822 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2823 (cond [(eq_attr "alternative" "5,6")
2824 (const_string "V4SF")
2825 ]
2826 (const_string "V2SF"))
2827
2828 /* xorps is one byte shorter. */
2829 (eq_attr "alternative" "5")
2830 (cond [(ne (symbol_ref "optimize_size")
2831 (const_int 0))
2832 (const_string "V4SF")
2833 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2834 (const_int 0))
2835 (const_string "TI")
2836 ]
2837 (const_string "V2DF"))
2838
2839 /* For architectures resolving dependencies on
2840 whole SSE registers use APD move to break dependency
2841 chains, otherwise use short move to avoid extra work.
2842
2843 movaps encodes one byte shorter. */
2844 (eq_attr "alternative" "6")
2845 (cond
2846 [(ne (symbol_ref "optimize_size")
2847 (const_int 0))
2848 (const_string "V4SF")
2849 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2850 (const_int 0))
2851 (const_string "V2DF")
2852 ]
2853 (const_string "DF"))
2854 /* For architectures resolving dependencies on register
2855 parts we may avoid extra work to zero out upper part
2856 of register. */
2857 (eq_attr "alternative" "7")
2858 (if_then_else
2859 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2860 (const_int 0))
2861 (const_string "V1DF")
2862 (const_string "DF"))
2863 ]
2864 (const_string "DF")))])
2865
2866 (define_split
2867 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2868 (match_operand:DF 1 "general_operand" ""))]
2869 "reload_completed
2870 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871 && ! (ANY_FP_REG_P (operands[0]) ||
2872 (GET_CODE (operands[0]) == SUBREG
2873 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2874 && ! (ANY_FP_REG_P (operands[1]) ||
2875 (GET_CODE (operands[1]) == SUBREG
2876 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2877 [(const_int 0)]
2878 "ix86_split_long_move (operands); DONE;")
2879
2880 (define_insn "*swapdf"
2881 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2882 (match_operand:DF 1 "fp_register_operand" "+f"))
2883 (set (match_dup 1)
2884 (match_dup 0))]
2885 "reload_completed || TARGET_80387"
2886 {
2887 if (STACK_TOP_P (operands[0]))
2888 return "fxch\t%1";
2889 else
2890 return "fxch\t%0";
2891 }
2892 [(set_attr "type" "fxch")
2893 (set_attr "mode" "DF")])
2894
2895 (define_expand "movxf"
2896 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2897 (match_operand:XF 1 "general_operand" ""))]
2898 ""
2899 "ix86_expand_move (XFmode, operands); DONE;")
2900
2901 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2902 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2903 ;; Pushing using integer instructions is longer except for constants
2904 ;; and direct memory references.
2905 ;; (assuming that any given constant is pushed only once, but this ought to be
2906 ;; handled elsewhere).
2907
2908 (define_insn "*pushxf_nointeger"
2909 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2910 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2911 "optimize_size"
2912 {
2913 /* This insn should be already split before reg-stack. */
2914 gcc_unreachable ();
2915 }
2916 [(set_attr "type" "multi")
2917 (set_attr "unit" "i387,*,*")
2918 (set_attr "mode" "XF,SI,SI")])
2919
2920 (define_insn "*pushxf_integer"
2921 [(set (match_operand:XF 0 "push_operand" "=<,<")
2922 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2923 "!optimize_size"
2924 {
2925 /* This insn should be already split before reg-stack. */
2926 gcc_unreachable ();
2927 }
2928 [(set_attr "type" "multi")
2929 (set_attr "unit" "i387,*")
2930 (set_attr "mode" "XF,SI")])
2931
2932 (define_split
2933 [(set (match_operand 0 "push_operand" "")
2934 (match_operand 1 "general_operand" ""))]
2935 "reload_completed
2936 && (GET_MODE (operands[0]) == XFmode
2937 || GET_MODE (operands[0]) == DFmode)
2938 && !ANY_FP_REG_P (operands[1])"
2939 [(const_int 0)]
2940 "ix86_split_long_move (operands); DONE;")
2941
2942 (define_split
2943 [(set (match_operand:XF 0 "push_operand" "")
2944 (match_operand:XF 1 "any_fp_register_operand" ""))]
2945 "!TARGET_64BIT"
2946 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2947 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2948 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2949
2950 (define_split
2951 [(set (match_operand:XF 0 "push_operand" "")
2952 (match_operand:XF 1 "any_fp_register_operand" ""))]
2953 "TARGET_64BIT"
2954 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2955 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2956 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2957
2958 ;; Do not use integer registers when optimizing for size
2959 (define_insn "*movxf_nointeger"
2960 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2961 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2962 "optimize_size
2963 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2964 && (reload_in_progress || reload_completed
2965 || (optimize_size && standard_80387_constant_p (operands[1]))
2966 || GET_CODE (operands[1]) != CONST_DOUBLE
2967 || memory_operand (operands[0], XFmode))"
2968 {
2969 switch (which_alternative)
2970 {
2971 case 0:
2972 return output_387_reg_move (insn, operands);
2973
2974 case 1:
2975 /* There is no non-popping store to memory for XFmode. So if
2976 we need one, follow the store with a load. */
2977 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2978 return "fstp%z0\t%y0\;fld%z0\t%y0";
2979 else
2980 return "fstp%z0\t%y0";
2981
2982 case 2:
2983 return standard_80387_constant_opcode (operands[1]);
2984
2985 case 3: case 4:
2986 return "#";
2987 default:
2988 gcc_unreachable ();
2989 }
2990 }
2991 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2992 (set_attr "mode" "XF,XF,XF,SI,SI")])
2993
2994 (define_insn "*movxf_integer"
2995 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2996 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2997 "!optimize_size
2998 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2999 && (reload_in_progress || reload_completed
3000 || (optimize_size && standard_80387_constant_p (operands[1]))
3001 || GET_CODE (operands[1]) != CONST_DOUBLE
3002 || memory_operand (operands[0], XFmode))"
3003 {
3004 switch (which_alternative)
3005 {
3006 case 0:
3007 return output_387_reg_move (insn, operands);
3008
3009 case 1:
3010 /* There is no non-popping store to memory for XFmode. So if
3011 we need one, follow the store with a load. */
3012 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3013 return "fstp%z0\t%y0\;fld%z0\t%y0";
3014 else
3015 return "fstp%z0\t%y0";
3016
3017 case 2:
3018 return standard_80387_constant_opcode (operands[1]);
3019
3020 case 3: case 4:
3021 return "#";
3022
3023 default:
3024 gcc_unreachable ();
3025 }
3026 }
3027 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3028 (set_attr "mode" "XF,XF,XF,SI,SI")])
3029
3030 (define_split
3031 [(set (match_operand 0 "nonimmediate_operand" "")
3032 (match_operand 1 "general_operand" ""))]
3033 "reload_completed
3034 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3035 && GET_MODE (operands[0]) == XFmode
3036 && ! (ANY_FP_REG_P (operands[0]) ||
3037 (GET_CODE (operands[0]) == SUBREG
3038 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3039 && ! (ANY_FP_REG_P (operands[1]) ||
3040 (GET_CODE (operands[1]) == SUBREG
3041 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3042 [(const_int 0)]
3043 "ix86_split_long_move (operands); DONE;")
3044
3045 (define_split
3046 [(set (match_operand 0 "register_operand" "")
3047 (match_operand 1 "memory_operand" ""))]
3048 "reload_completed
3049 && MEM_P (operands[1])
3050 && (GET_MODE (operands[0]) == XFmode
3051 || GET_MODE (operands[0]) == SFmode
3052 || GET_MODE (operands[0]) == DFmode)
3053 && constant_pool_reference_p (operands[1])"
3054 [(set (match_dup 0) (match_dup 1))]
3055 {
3056 rtx c = avoid_constant_pool_reference (operands[1]);
3057 rtx r = operands[0];
3058
3059 if (GET_CODE (r) == SUBREG)
3060 r = SUBREG_REG (r);
3061
3062 if (SSE_REG_P (r))
3063 {
3064 if (!standard_sse_constant_p (c))
3065 FAIL;
3066 }
3067 else if (FP_REG_P (r))
3068 {
3069 if (!standard_80387_constant_p (c))
3070 FAIL;
3071 }
3072 else if (MMX_REG_P (r))
3073 FAIL;
3074
3075 operands[1] = c;
3076 })
3077
3078 (define_split
3079 [(set (match_operand 0 "register_operand" "")
3080 (float_extend (match_operand 1 "memory_operand" "")))]
3081 "reload_completed
3082 && MEM_P (operands[1])
3083 && (GET_MODE (operands[0]) == XFmode
3084 || GET_MODE (operands[0]) == SFmode
3085 || GET_MODE (operands[0]) == DFmode)
3086 && constant_pool_reference_p (operands[1])"
3087 [(set (match_dup 0) (match_dup 1))]
3088 {
3089 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3090 rtx r = operands[0];
3091
3092 if (GET_CODE (r) == SUBREG)
3093 r = SUBREG_REG (r);
3094
3095 if (SSE_REG_P (r))
3096 {
3097 if (!standard_sse_constant_p (c))
3098 FAIL;
3099 }
3100 else if (FP_REG_P (r))
3101 {
3102 if (!standard_80387_constant_p (c))
3103 FAIL;
3104 }
3105 else if (MMX_REG_P (r))
3106 FAIL;
3107
3108 operands[1] = c;
3109 })
3110
3111 (define_insn "swapxf"
3112 [(set (match_operand:XF 0 "register_operand" "+f")
3113 (match_operand:XF 1 "register_operand" "+f"))
3114 (set (match_dup 1)
3115 (match_dup 0))]
3116 "TARGET_80387"
3117 {
3118 if (STACK_TOP_P (operands[0]))
3119 return "fxch\t%1";
3120 else
3121 return "fxch\t%0";
3122 }
3123 [(set_attr "type" "fxch")
3124 (set_attr "mode" "XF")])
3125
3126 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3127 (define_split
3128 [(set (match_operand:X87MODEF 0 "register_operand" "")
3129 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3130 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3131 && (standard_80387_constant_p (operands[1]) == 8
3132 || standard_80387_constant_p (operands[1]) == 9)"
3133 [(set (match_dup 0)(match_dup 1))
3134 (set (match_dup 0)
3135 (neg:X87MODEF (match_dup 0)))]
3136 {
3137 REAL_VALUE_TYPE r;
3138
3139 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3140 if (real_isnegzero (&r))
3141 operands[1] = CONST0_RTX (<MODE>mode);
3142 else
3143 operands[1] = CONST1_RTX (<MODE>mode);
3144 })
3145
3146 (define_expand "movtf"
3147 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3148 (match_operand:TF 1 "nonimmediate_operand" ""))]
3149 "TARGET_64BIT"
3150 {
3151 ix86_expand_move (TFmode, operands);
3152 DONE;
3153 })
3154
3155 (define_insn "*movtf_internal"
3156 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3157 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3158 "TARGET_64BIT
3159 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3160 {
3161 switch (which_alternative)
3162 {
3163 case 0:
3164 case 1:
3165 return "#";
3166 case 2:
3167 if (get_attr_mode (insn) == MODE_V4SF)
3168 return "xorps\t%0, %0";
3169 else
3170 return "pxor\t%0, %0";
3171 case 3:
3172 case 4:
3173 if (get_attr_mode (insn) == MODE_V4SF)
3174 return "movaps\t{%1, %0|%0, %1}";
3175 else
3176 return "movdqa\t{%1, %0|%0, %1}";
3177 default:
3178 gcc_unreachable ();
3179 }
3180 }
3181 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3182 (set (attr "mode")
3183 (cond [(eq_attr "alternative" "2,3")
3184 (if_then_else
3185 (ne (symbol_ref "optimize_size")
3186 (const_int 0))
3187 (const_string "V4SF")
3188 (const_string "TI"))
3189 (eq_attr "alternative" "4")
3190 (if_then_else
3191 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3192 (const_int 0))
3193 (ne (symbol_ref "optimize_size")
3194 (const_int 0)))
3195 (const_string "V4SF")
3196 (const_string "TI"))]
3197 (const_string "DI")))])
3198
3199 (define_split
3200 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3201 (match_operand:TF 1 "general_operand" ""))]
3202 "reload_completed && !SSE_REG_P (operands[0])
3203 && !SSE_REG_P (operands[1])"
3204 [(const_int 0)]
3205 "ix86_split_long_move (operands); DONE;")
3206 \f
3207 ;; Zero extension instructions
3208
3209 (define_expand "zero_extendhisi2"
3210 [(set (match_operand:SI 0 "register_operand" "")
3211 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3212 ""
3213 {
3214 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3215 {
3216 operands[1] = force_reg (HImode, operands[1]);
3217 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3218 DONE;
3219 }
3220 })
3221
3222 (define_insn "zero_extendhisi2_and"
3223 [(set (match_operand:SI 0 "register_operand" "=r")
3224 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3225 (clobber (reg:CC FLAGS_REG))]
3226 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3227 "#"
3228 [(set_attr "type" "alu1")
3229 (set_attr "mode" "SI")])
3230
3231 (define_split
3232 [(set (match_operand:SI 0 "register_operand" "")
3233 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3234 (clobber (reg:CC FLAGS_REG))]
3235 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3236 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3237 (clobber (reg:CC FLAGS_REG))])]
3238 "")
3239
3240 (define_insn "*zero_extendhisi2_movzwl"
3241 [(set (match_operand:SI 0 "register_operand" "=r")
3242 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3244 "movz{wl|x}\t{%1, %0|%0, %1}"
3245 [(set_attr "type" "imovx")
3246 (set_attr "mode" "SI")])
3247
3248 (define_expand "zero_extendqihi2"
3249 [(parallel
3250 [(set (match_operand:HI 0 "register_operand" "")
3251 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3252 (clobber (reg:CC FLAGS_REG))])]
3253 ""
3254 "")
3255
3256 (define_insn "*zero_extendqihi2_and"
3257 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3258 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3259 (clobber (reg:CC FLAGS_REG))]
3260 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3261 "#"
3262 [(set_attr "type" "alu1")
3263 (set_attr "mode" "HI")])
3264
3265 (define_insn "*zero_extendqihi2_movzbw_and"
3266 [(set (match_operand:HI 0 "register_operand" "=r,r")
3267 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3268 (clobber (reg:CC FLAGS_REG))]
3269 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3270 "#"
3271 [(set_attr "type" "imovx,alu1")
3272 (set_attr "mode" "HI")])
3273
3274 ; zero extend to SImode here to avoid partial register stalls
3275 (define_insn "*zero_extendqihi2_movzbl"
3276 [(set (match_operand:HI 0 "register_operand" "=r")
3277 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3279 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3280 [(set_attr "type" "imovx")
3281 (set_attr "mode" "SI")])
3282
3283 ;; For the movzbw case strip only the clobber
3284 (define_split
3285 [(set (match_operand:HI 0 "register_operand" "")
3286 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3287 (clobber (reg:CC FLAGS_REG))]
3288 "reload_completed
3289 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3290 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3291 [(set (match_operand:HI 0 "register_operand" "")
3292 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3293
3294 ;; When source and destination does not overlap, clear destination
3295 ;; first and then do the movb
3296 (define_split
3297 [(set (match_operand:HI 0 "register_operand" "")
3298 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3299 (clobber (reg:CC FLAGS_REG))]
3300 "reload_completed
3301 && ANY_QI_REG_P (operands[0])
3302 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3303 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3304 [(set (match_dup 0) (const_int 0))
3305 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3306 "operands[2] = gen_lowpart (QImode, operands[0]);")
3307
3308 ;; Rest is handled by single and.
3309 (define_split
3310 [(set (match_operand:HI 0 "register_operand" "")
3311 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3312 (clobber (reg:CC FLAGS_REG))]
3313 "reload_completed
3314 && true_regnum (operands[0]) == true_regnum (operands[1])"
3315 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3316 (clobber (reg:CC FLAGS_REG))])]
3317 "")
3318
3319 (define_expand "zero_extendqisi2"
3320 [(parallel
3321 [(set (match_operand:SI 0 "register_operand" "")
3322 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3323 (clobber (reg:CC FLAGS_REG))])]
3324 ""
3325 "")
3326
3327 (define_insn "*zero_extendqisi2_and"
3328 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3329 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3330 (clobber (reg:CC FLAGS_REG))]
3331 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3332 "#"
3333 [(set_attr "type" "alu1")
3334 (set_attr "mode" "SI")])
3335
3336 (define_insn "*zero_extendqisi2_movzbw_and"
3337 [(set (match_operand:SI 0 "register_operand" "=r,r")
3338 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3339 (clobber (reg:CC FLAGS_REG))]
3340 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3341 "#"
3342 [(set_attr "type" "imovx,alu1")
3343 (set_attr "mode" "SI")])
3344
3345 (define_insn "*zero_extendqisi2_movzbw"
3346 [(set (match_operand:SI 0 "register_operand" "=r")
3347 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3348 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3349 "movz{bl|x}\t{%1, %0|%0, %1}"
3350 [(set_attr "type" "imovx")
3351 (set_attr "mode" "SI")])
3352
3353 ;; For the movzbl case strip only the clobber
3354 (define_split
3355 [(set (match_operand:SI 0 "register_operand" "")
3356 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3357 (clobber (reg:CC FLAGS_REG))]
3358 "reload_completed
3359 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3360 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3361 [(set (match_dup 0)
3362 (zero_extend:SI (match_dup 1)))])
3363
3364 ;; When source and destination does not overlap, clear destination
3365 ;; first and then do the movb
3366 (define_split
3367 [(set (match_operand:SI 0 "register_operand" "")
3368 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3369 (clobber (reg:CC FLAGS_REG))]
3370 "reload_completed
3371 && ANY_QI_REG_P (operands[0])
3372 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3373 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3374 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3375 [(set (match_dup 0) (const_int 0))
3376 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3377 "operands[2] = gen_lowpart (QImode, operands[0]);")
3378
3379 ;; Rest is handled by single and.
3380 (define_split
3381 [(set (match_operand:SI 0 "register_operand" "")
3382 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3383 (clobber (reg:CC FLAGS_REG))]
3384 "reload_completed
3385 && true_regnum (operands[0]) == true_regnum (operands[1])"
3386 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3387 (clobber (reg:CC FLAGS_REG))])]
3388 "")
3389
3390 ;; %%% Kill me once multi-word ops are sane.
3391 (define_expand "zero_extendsidi2"
3392 [(set (match_operand:DI 0 "register_operand" "=r")
3393 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3394 ""
3395 {
3396 if (!TARGET_64BIT)
3397 {
3398 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3399 DONE;
3400 }
3401 })
3402
3403 (define_insn "zero_extendsidi2_32"
3404 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,*y,?*Yi,*Y2")
3405 (zero_extend:DI
3406 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3407 (clobber (reg:CC FLAGS_REG))]
3408 "!TARGET_64BIT"
3409 "@
3410 #
3411 #
3412 #
3413 movd\t{%1, %0|%0, %1}
3414 movd\t{%1, %0|%0, %1}
3415 movd\t{%1, %0|%0, %1}
3416 movd\t{%1, %0|%0, %1}"
3417 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3418 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3419
3420 (define_insn "zero_extendsidi2_rex64"
3421 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,*y,?*Yi,*Y2")
3422 (zero_extend:DI
3423 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3424 "TARGET_64BIT"
3425 "@
3426 mov\t{%k1, %k0|%k0, %k1}
3427 #
3428 movd\t{%1, %0|%0, %1}
3429 movd\t{%1, %0|%0, %1}
3430 movd\t{%1, %0|%0, %1}
3431 movd\t{%1, %0|%0, %1}"
3432 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3433 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3434
3435 (define_split
3436 [(set (match_operand:DI 0 "memory_operand" "")
3437 (zero_extend:DI (match_dup 0)))]
3438 "TARGET_64BIT"
3439 [(set (match_dup 4) (const_int 0))]
3440 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3441
3442 (define_split
3443 [(set (match_operand:DI 0 "register_operand" "")
3444 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3445 (clobber (reg:CC FLAGS_REG))]
3446 "!TARGET_64BIT && reload_completed
3447 && true_regnum (operands[0]) == true_regnum (operands[1])"
3448 [(set (match_dup 4) (const_int 0))]
3449 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3450
3451 (define_split
3452 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3453 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3454 (clobber (reg:CC FLAGS_REG))]
3455 "!TARGET_64BIT && reload_completed
3456 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3457 [(set (match_dup 3) (match_dup 1))
3458 (set (match_dup 4) (const_int 0))]
3459 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3460
3461 (define_insn "zero_extendhidi2"
3462 [(set (match_operand:DI 0 "register_operand" "=r")
3463 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3464 "TARGET_64BIT"
3465 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3466 [(set_attr "type" "imovx")
3467 (set_attr "mode" "DI")])
3468
3469 (define_insn "zero_extendqidi2"
3470 [(set (match_operand:DI 0 "register_operand" "=r")
3471 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3472 "TARGET_64BIT"
3473 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3474 [(set_attr "type" "imovx")
3475 (set_attr "mode" "DI")])
3476 \f
3477 ;; Sign extension instructions
3478
3479 (define_expand "extendsidi2"
3480 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3481 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3482 (clobber (reg:CC FLAGS_REG))
3483 (clobber (match_scratch:SI 2 ""))])]
3484 ""
3485 {
3486 if (TARGET_64BIT)
3487 {
3488 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3489 DONE;
3490 }
3491 })
3492
3493 (define_insn "*extendsidi2_1"
3494 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3495 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3496 (clobber (reg:CC FLAGS_REG))
3497 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3498 "!TARGET_64BIT"
3499 "#")
3500
3501 (define_insn "extendsidi2_rex64"
3502 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3503 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3504 "TARGET_64BIT"
3505 "@
3506 {cltq|cdqe}
3507 movs{lq|x}\t{%1,%0|%0, %1}"
3508 [(set_attr "type" "imovx")
3509 (set_attr "mode" "DI")
3510 (set_attr "prefix_0f" "0")
3511 (set_attr "modrm" "0,1")])
3512
3513 (define_insn "extendhidi2"
3514 [(set (match_operand:DI 0 "register_operand" "=r")
3515 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3516 "TARGET_64BIT"
3517 "movs{wq|x}\t{%1,%0|%0, %1}"
3518 [(set_attr "type" "imovx")
3519 (set_attr "mode" "DI")])
3520
3521 (define_insn "extendqidi2"
3522 [(set (match_operand:DI 0 "register_operand" "=r")
3523 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3524 "TARGET_64BIT"
3525 "movs{bq|x}\t{%1,%0|%0, %1}"
3526 [(set_attr "type" "imovx")
3527 (set_attr "mode" "DI")])
3528
3529 ;; Extend to memory case when source register does die.
3530 (define_split
3531 [(set (match_operand:DI 0 "memory_operand" "")
3532 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3533 (clobber (reg:CC FLAGS_REG))
3534 (clobber (match_operand:SI 2 "register_operand" ""))]
3535 "(reload_completed
3536 && dead_or_set_p (insn, operands[1])
3537 && !reg_mentioned_p (operands[1], operands[0]))"
3538 [(set (match_dup 3) (match_dup 1))
3539 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3540 (clobber (reg:CC FLAGS_REG))])
3541 (set (match_dup 4) (match_dup 1))]
3542 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3543
3544 ;; Extend to memory case when source register does not die.
3545 (define_split
3546 [(set (match_operand:DI 0 "memory_operand" "")
3547 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3548 (clobber (reg:CC FLAGS_REG))
3549 (clobber (match_operand:SI 2 "register_operand" ""))]
3550 "reload_completed"
3551 [(const_int 0)]
3552 {
3553 split_di (&operands[0], 1, &operands[3], &operands[4]);
3554
3555 emit_move_insn (operands[3], operands[1]);
3556
3557 /* Generate a cltd if possible and doing so it profitable. */
3558 if (true_regnum (operands[1]) == 0
3559 && true_regnum (operands[2]) == 1
3560 && (optimize_size || TARGET_USE_CLTD))
3561 {
3562 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3563 }
3564 else
3565 {
3566 emit_move_insn (operands[2], operands[1]);
3567 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3568 }
3569 emit_move_insn (operands[4], operands[2]);
3570 DONE;
3571 })
3572
3573 ;; Extend to register case. Optimize case where source and destination
3574 ;; registers match and cases where we can use cltd.
3575 (define_split
3576 [(set (match_operand:DI 0 "register_operand" "")
3577 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3578 (clobber (reg:CC FLAGS_REG))
3579 (clobber (match_scratch:SI 2 ""))]
3580 "reload_completed"
3581 [(const_int 0)]
3582 {
3583 split_di (&operands[0], 1, &operands[3], &operands[4]);
3584
3585 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3586 emit_move_insn (operands[3], operands[1]);
3587
3588 /* Generate a cltd if possible and doing so it profitable. */
3589 if (true_regnum (operands[3]) == 0
3590 && (optimize_size || TARGET_USE_CLTD))
3591 {
3592 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3593 DONE;
3594 }
3595
3596 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3597 emit_move_insn (operands[4], operands[1]);
3598
3599 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3600 DONE;
3601 })
3602
3603 (define_insn "extendhisi2"
3604 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3605 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3606 ""
3607 {
3608 switch (get_attr_prefix_0f (insn))
3609 {
3610 case 0:
3611 return "{cwtl|cwde}";
3612 default:
3613 return "movs{wl|x}\t{%1,%0|%0, %1}";
3614 }
3615 }
3616 [(set_attr "type" "imovx")
3617 (set_attr "mode" "SI")
3618 (set (attr "prefix_0f")
3619 ;; movsx is short decodable while cwtl is vector decoded.
3620 (if_then_else (and (eq_attr "cpu" "!k6")
3621 (eq_attr "alternative" "0"))
3622 (const_string "0")
3623 (const_string "1")))
3624 (set (attr "modrm")
3625 (if_then_else (eq_attr "prefix_0f" "0")
3626 (const_string "0")
3627 (const_string "1")))])
3628
3629 (define_insn "*extendhisi2_zext"
3630 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3631 (zero_extend:DI
3632 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3633 "TARGET_64BIT"
3634 {
3635 switch (get_attr_prefix_0f (insn))
3636 {
3637 case 0:
3638 return "{cwtl|cwde}";
3639 default:
3640 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3641 }
3642 }
3643 [(set_attr "type" "imovx")
3644 (set_attr "mode" "SI")
3645 (set (attr "prefix_0f")
3646 ;; movsx is short decodable while cwtl is vector decoded.
3647 (if_then_else (and (eq_attr "cpu" "!k6")
3648 (eq_attr "alternative" "0"))
3649 (const_string "0")
3650 (const_string "1")))
3651 (set (attr "modrm")
3652 (if_then_else (eq_attr "prefix_0f" "0")
3653 (const_string "0")
3654 (const_string "1")))])
3655
3656 (define_insn "extendqihi2"
3657 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3658 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3659 ""
3660 {
3661 switch (get_attr_prefix_0f (insn))
3662 {
3663 case 0:
3664 return "{cbtw|cbw}";
3665 default:
3666 return "movs{bw|x}\t{%1,%0|%0, %1}";
3667 }
3668 }
3669 [(set_attr "type" "imovx")
3670 (set_attr "mode" "HI")
3671 (set (attr "prefix_0f")
3672 ;; movsx is short decodable while cwtl is vector decoded.
3673 (if_then_else (and (eq_attr "cpu" "!k6")
3674 (eq_attr "alternative" "0"))
3675 (const_string "0")
3676 (const_string "1")))
3677 (set (attr "modrm")
3678 (if_then_else (eq_attr "prefix_0f" "0")
3679 (const_string "0")
3680 (const_string "1")))])
3681
3682 (define_insn "extendqisi2"
3683 [(set (match_operand:SI 0 "register_operand" "=r")
3684 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3685 ""
3686 "movs{bl|x}\t{%1,%0|%0, %1}"
3687 [(set_attr "type" "imovx")
3688 (set_attr "mode" "SI")])
3689
3690 (define_insn "*extendqisi2_zext"
3691 [(set (match_operand:DI 0 "register_operand" "=r")
3692 (zero_extend:DI
3693 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3694 "TARGET_64BIT"
3695 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3696 [(set_attr "type" "imovx")
3697 (set_attr "mode" "SI")])
3698 \f
3699 ;; Conversions between float and double.
3700
3701 ;; These are all no-ops in the model used for the 80387. So just
3702 ;; emit moves.
3703
3704 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3705 (define_insn "*dummy_extendsfdf2"
3706 [(set (match_operand:DF 0 "push_operand" "=<")
3707 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3708 "0"
3709 "#")
3710
3711 (define_split
3712 [(set (match_operand:DF 0 "push_operand" "")
3713 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3714 "!TARGET_64BIT"
3715 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3716 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3717
3718 (define_split
3719 [(set (match_operand:DF 0 "push_operand" "")
3720 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3721 "TARGET_64BIT"
3722 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3723 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3724
3725 (define_insn "*dummy_extendsfxf2"
3726 [(set (match_operand:XF 0 "push_operand" "=<")
3727 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3728 "0"
3729 "#")
3730
3731 (define_split
3732 [(set (match_operand:XF 0 "push_operand" "")
3733 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3734 ""
3735 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3736 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3737 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3738
3739 (define_split
3740 [(set (match_operand:XF 0 "push_operand" "")
3741 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3742 "TARGET_64BIT"
3743 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3744 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3745 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3746
3747 (define_split
3748 [(set (match_operand:XF 0 "push_operand" "")
3749 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3750 ""
3751 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3752 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3753 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3754
3755 (define_split
3756 [(set (match_operand:XF 0 "push_operand" "")
3757 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3758 "TARGET_64BIT"
3759 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3760 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3761 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3762
3763 (define_expand "extendsfdf2"
3764 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3765 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3766 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3767 {
3768 /* ??? Needed for compress_float_constant since all fp constants
3769 are LEGITIMATE_CONSTANT_P. */
3770 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3771 {
3772 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3773 && standard_80387_constant_p (operands[1]) > 0)
3774 {
3775 operands[1] = simplify_const_unary_operation
3776 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3777 emit_move_insn_1 (operands[0], operands[1]);
3778 DONE;
3779 }
3780 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3781 }
3782 })
3783
3784 (define_insn "*extendsfdf2_mixed"
3785 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3786 (float_extend:DF
3787 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3788 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3789 {
3790 switch (which_alternative)
3791 {
3792 case 0:
3793 return output_387_reg_move (insn, operands);
3794
3795 case 1:
3796 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3797 return "fstp%z0\t%y0";
3798 else
3799 return "fst%z0\t%y0";
3800
3801 case 2:
3802 return "cvtss2sd\t{%1, %0|%0, %1}";
3803
3804 default:
3805 gcc_unreachable ();
3806 }
3807 }
3808 [(set_attr "type" "fmov,fmov,ssecvt")
3809 (set_attr "mode" "SF,XF,DF")])
3810
3811 (define_insn "*extendsfdf2_sse"
3812 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3813 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3814 "TARGET_SSE2 && TARGET_SSE_MATH"
3815 "cvtss2sd\t{%1, %0|%0, %1}"
3816 [(set_attr "type" "ssecvt")
3817 (set_attr "mode" "DF")])
3818
3819 (define_insn "*extendsfdf2_i387"
3820 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3821 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3822 "TARGET_80387"
3823 {
3824 switch (which_alternative)
3825 {
3826 case 0:
3827 return output_387_reg_move (insn, operands);
3828
3829 case 1:
3830 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3831 return "fstp%z0\t%y0";
3832 else
3833 return "fst%z0\t%y0";
3834
3835 default:
3836 gcc_unreachable ();
3837 }
3838 }
3839 [(set_attr "type" "fmov")
3840 (set_attr "mode" "SF,XF")])
3841
3842 (define_expand "extendsfxf2"
3843 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3844 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3845 "TARGET_80387"
3846 {
3847 /* ??? Needed for compress_float_constant since all fp constants
3848 are LEGITIMATE_CONSTANT_P. */
3849 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3850 {
3851 if (standard_80387_constant_p (operands[1]) > 0)
3852 {
3853 operands[1] = simplify_const_unary_operation
3854 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3855 emit_move_insn_1 (operands[0], operands[1]);
3856 DONE;
3857 }
3858 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3859 }
3860 })
3861
3862 (define_insn "*extendsfxf2_i387"
3863 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3864 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3865 "TARGET_80387"
3866 {
3867 switch (which_alternative)
3868 {
3869 case 0:
3870 return output_387_reg_move (insn, operands);
3871
3872 case 1:
3873 /* There is no non-popping store to memory for XFmode. So if
3874 we need one, follow the store with a load. */
3875 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3876 return "fstp%z0\t%y0";
3877 else
3878 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3879
3880 default:
3881 gcc_unreachable ();
3882 }
3883 }
3884 [(set_attr "type" "fmov")
3885 (set_attr "mode" "SF,XF")])
3886
3887 (define_expand "extenddfxf2"
3888 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3889 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3890 "TARGET_80387"
3891 {
3892 /* ??? Needed for compress_float_constant since all fp constants
3893 are LEGITIMATE_CONSTANT_P. */
3894 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3895 {
3896 if (standard_80387_constant_p (operands[1]) > 0)
3897 {
3898 operands[1] = simplify_const_unary_operation
3899 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3900 emit_move_insn_1 (operands[0], operands[1]);
3901 DONE;
3902 }
3903 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3904 }
3905 })
3906
3907 (define_insn "*extenddfxf2_i387"
3908 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3909 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3910 "TARGET_80387"
3911 {
3912 switch (which_alternative)
3913 {
3914 case 0:
3915 return output_387_reg_move (insn, operands);
3916
3917 case 1:
3918 /* There is no non-popping store to memory for XFmode. So if
3919 we need one, follow the store with a load. */
3920 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3922 else
3923 return "fstp%z0\t%y0";
3924
3925 default:
3926 gcc_unreachable ();
3927 }
3928 }
3929 [(set_attr "type" "fmov")
3930 (set_attr "mode" "DF,XF")])
3931
3932 ;; %%% This seems bad bad news.
3933 ;; This cannot output into an f-reg because there is no way to be sure
3934 ;; of truncating in that case. Otherwise this is just like a simple move
3935 ;; insn. So we pretend we can output to a reg in order to get better
3936 ;; register preferencing, but we really use a stack slot.
3937
3938 ;; Conversion from DFmode to SFmode.
3939
3940 (define_expand "truncdfsf2"
3941 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3942 (float_truncate:SF
3943 (match_operand:DF 1 "nonimmediate_operand" "")))]
3944 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3945 {
3946 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3947 ;
3948 else if (flag_unsafe_math_optimizations)
3949 ;
3950 else
3951 {
3952 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3953 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3954 DONE;
3955 }
3956 })
3957
3958 (define_expand "truncdfsf2_with_temp"
3959 [(parallel [(set (match_operand:SF 0 "" "")
3960 (float_truncate:SF (match_operand:DF 1 "" "")))
3961 (clobber (match_operand:SF 2 "" ""))])]
3962 "")
3963
3964 (define_insn "*truncdfsf_fast_mixed"
3965 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
3966 (float_truncate:SF
3967 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3968 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3969 {
3970 switch (which_alternative)
3971 {
3972 case 0:
3973 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974 return "fstp%z0\t%y0";
3975 else
3976 return "fst%z0\t%y0";
3977 case 1:
3978 return output_387_reg_move (insn, operands);
3979 case 2:
3980 return "cvtsd2ss\t{%1, %0|%0, %1}";
3981 default:
3982 gcc_unreachable ();
3983 }
3984 }
3985 [(set_attr "type" "fmov,fmov,ssecvt")
3986 (set_attr "mode" "SF")])
3987
3988 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3989 ;; because nothing we do here is unsafe.
3990 (define_insn "*truncdfsf_fast_sse"
3991 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3992 (float_truncate:SF
3993 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3994 "TARGET_SSE2 && TARGET_SSE_MATH"
3995 "cvtsd2ss\t{%1, %0|%0, %1}"
3996 [(set_attr "type" "ssecvt")
3997 (set_attr "mode" "SF")])
3998
3999 (define_insn "*truncdfsf_fast_i387"
4000 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4001 (float_truncate:SF
4002 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4003 "TARGET_80387 && flag_unsafe_math_optimizations"
4004 "* return output_387_reg_move (insn, operands);"
4005 [(set_attr "type" "fmov")
4006 (set_attr "mode" "SF")])
4007
4008 (define_insn "*truncdfsf_mixed"
4009 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4010 (float_truncate:SF
4011 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4012 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4013 "TARGET_MIX_SSE_I387"
4014 {
4015 switch (which_alternative)
4016 {
4017 case 0:
4018 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4019 return "fstp%z0\t%y0";
4020 else
4021 return "fst%z0\t%y0";
4022 case 1:
4023 return "#";
4024 case 2:
4025 return "cvtsd2ss\t{%1, %0|%0, %1}";
4026 default:
4027 gcc_unreachable ();
4028 }
4029 }
4030 [(set_attr "type" "fmov,multi,ssecvt")
4031 (set_attr "unit" "*,i387,*")
4032 (set_attr "mode" "SF")])
4033
4034 (define_insn "*truncdfsf_i387"
4035 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4036 (float_truncate:SF
4037 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4038 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4039 "TARGET_80387"
4040 {
4041 switch (which_alternative)
4042 {
4043 case 0:
4044 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4045 return "fstp%z0\t%y0";
4046 else
4047 return "fst%z0\t%y0";
4048 case 1:
4049 return "#";
4050 default:
4051 gcc_unreachable ();
4052 }
4053 }
4054 [(set_attr "type" "fmov,multi")
4055 (set_attr "unit" "*,i387")
4056 (set_attr "mode" "SF")])
4057
4058 (define_insn "*truncdfsf2_i387_1"
4059 [(set (match_operand:SF 0 "memory_operand" "=m")
4060 (float_truncate:SF
4061 (match_operand:DF 1 "register_operand" "f")))]
4062 "TARGET_80387
4063 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4064 && !TARGET_MIX_SSE_I387"
4065 {
4066 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4067 return "fstp%z0\t%y0";
4068 else
4069 return "fst%z0\t%y0";
4070 }
4071 [(set_attr "type" "fmov")
4072 (set_attr "mode" "SF")])
4073
4074 (define_split
4075 [(set (match_operand:SF 0 "register_operand" "")
4076 (float_truncate:SF
4077 (match_operand:DF 1 "fp_register_operand" "")))
4078 (clobber (match_operand 2 "" ""))]
4079 "reload_completed"
4080 [(set (match_dup 2) (match_dup 1))
4081 (set (match_dup 0) (match_dup 2))]
4082 {
4083 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4084 })
4085
4086 ;; Conversion from XFmode to SFmode.
4087
4088 (define_expand "truncxfsf2"
4089 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4090 (float_truncate:SF
4091 (match_operand:XF 1 "register_operand" "")))
4092 (clobber (match_dup 2))])]
4093 "TARGET_80387"
4094 {
4095 if (flag_unsafe_math_optimizations)
4096 {
4097 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4098 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4099 if (reg != operands[0])
4100 emit_move_insn (operands[0], reg);
4101 DONE;
4102 }
4103 else
4104 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4105 })
4106
4107 (define_insn "*truncxfsf2_mixed"
4108 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4109 (float_truncate:SF
4110 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4111 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4112 "TARGET_80387"
4113 {
4114 gcc_assert (!which_alternative);
4115 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4116 return "fstp%z0\t%y0";
4117 else
4118 return "fst%z0\t%y0";
4119 }
4120 [(set_attr "type" "fmov,multi,multi,multi")
4121 (set_attr "unit" "*,i387,i387,i387")
4122 (set_attr "mode" "SF")])
4123
4124 (define_insn "truncxfsf2_i387_noop"
4125 [(set (match_operand:SF 0 "register_operand" "=f")
4126 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4127 "TARGET_80387 && flag_unsafe_math_optimizations"
4128 "* return output_387_reg_move (insn, operands);"
4129 [(set_attr "type" "fmov")
4130 (set_attr "mode" "SF")])
4131
4132 (define_insn "*truncxfsf2_i387"
4133 [(set (match_operand:SF 0 "memory_operand" "=m")
4134 (float_truncate:SF
4135 (match_operand:XF 1 "register_operand" "f")))]
4136 "TARGET_80387"
4137 {
4138 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4139 return "fstp%z0\t%y0";
4140 else
4141 return "fst%z0\t%y0";
4142 }
4143 [(set_attr "type" "fmov")
4144 (set_attr "mode" "SF")])
4145
4146 (define_split
4147 [(set (match_operand:SF 0 "register_operand" "")
4148 (float_truncate:SF
4149 (match_operand:XF 1 "register_operand" "")))
4150 (clobber (match_operand:SF 2 "memory_operand" ""))]
4151 "TARGET_80387 && reload_completed"
4152 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4153 (set (match_dup 0) (match_dup 2))]
4154 "")
4155
4156 (define_split
4157 [(set (match_operand:SF 0 "memory_operand" "")
4158 (float_truncate:SF
4159 (match_operand:XF 1 "register_operand" "")))
4160 (clobber (match_operand:SF 2 "memory_operand" ""))]
4161 "TARGET_80387"
4162 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4163 "")
4164
4165 ;; Conversion from XFmode to DFmode.
4166
4167 (define_expand "truncxfdf2"
4168 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4169 (float_truncate:DF
4170 (match_operand:XF 1 "register_operand" "")))
4171 (clobber (match_dup 2))])]
4172 "TARGET_80387"
4173 {
4174 if (flag_unsafe_math_optimizations)
4175 {
4176 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4177 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4178 if (reg != operands[0])
4179 emit_move_insn (operands[0], reg);
4180 DONE;
4181 }
4182 else
4183 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4184 })
4185
4186 (define_insn "*truncxfdf2_mixed"
4187 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4188 (float_truncate:DF
4189 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4190 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4191 "TARGET_80387"
4192 {
4193 gcc_assert (!which_alternative);
4194 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4195 return "fstp%z0\t%y0";
4196 else
4197 return "fst%z0\t%y0";
4198 }
4199 [(set_attr "type" "fmov,multi,multi,multi")
4200 (set_attr "unit" "*,i387,i387,i387")
4201 (set_attr "mode" "DF")])
4202
4203 (define_insn "truncxfdf2_i387_noop"
4204 [(set (match_operand:DF 0 "register_operand" "=f")
4205 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4206 "TARGET_80387 && flag_unsafe_math_optimizations"
4207 "* return output_387_reg_move (insn, operands);"
4208 [(set_attr "type" "fmov")
4209 (set_attr "mode" "DF")])
4210
4211 (define_insn "*truncxfdf2_i387"
4212 [(set (match_operand:DF 0 "memory_operand" "=m")
4213 (float_truncate:DF
4214 (match_operand:XF 1 "register_operand" "f")))]
4215 "TARGET_80387"
4216 {
4217 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4218 return "fstp%z0\t%y0";
4219 else
4220 return "fst%z0\t%y0";
4221 }
4222 [(set_attr "type" "fmov")
4223 (set_attr "mode" "DF")])
4224
4225 (define_split
4226 [(set (match_operand:DF 0 "register_operand" "")
4227 (float_truncate:DF
4228 (match_operand:XF 1 "register_operand" "")))
4229 (clobber (match_operand:DF 2 "memory_operand" ""))]
4230 "TARGET_80387 && reload_completed"
4231 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4232 (set (match_dup 0) (match_dup 2))]
4233 "")
4234
4235 (define_split
4236 [(set (match_operand:DF 0 "memory_operand" "")
4237 (float_truncate:DF
4238 (match_operand:XF 1 "register_operand" "")))
4239 (clobber (match_operand:DF 2 "memory_operand" ""))]
4240 "TARGET_80387"
4241 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4242 "")
4243 \f
4244 ;; Signed conversion to DImode.
4245
4246 (define_expand "fix_truncxfdi2"
4247 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248 (fix:DI (match_operand:XF 1 "register_operand" "")))
4249 (clobber (reg:CC FLAGS_REG))])]
4250 "TARGET_80387"
4251 {
4252 if (TARGET_FISTTP)
4253 {
4254 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4255 DONE;
4256 }
4257 })
4258
4259 (define_expand "fix_trunc<mode>di2"
4260 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4262 (clobber (reg:CC FLAGS_REG))])]
4263 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4264 {
4265 if (TARGET_FISTTP
4266 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4267 {
4268 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4269 DONE;
4270 }
4271 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4272 {
4273 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275 if (out != operands[0])
4276 emit_move_insn (operands[0], out);
4277 DONE;
4278 }
4279 })
4280
4281 ;; Signed conversion to SImode.
4282
4283 (define_expand "fix_truncxfsi2"
4284 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285 (fix:SI (match_operand:XF 1 "register_operand" "")))
4286 (clobber (reg:CC FLAGS_REG))])]
4287 "TARGET_80387"
4288 {
4289 if (TARGET_FISTTP)
4290 {
4291 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4292 DONE;
4293 }
4294 })
4295
4296 (define_expand "fix_trunc<mode>si2"
4297 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4299 (clobber (reg:CC FLAGS_REG))])]
4300 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4301 {
4302 if (TARGET_FISTTP
4303 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4304 {
4305 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4306 DONE;
4307 }
4308 if (SSE_FLOAT_MODE_P (<MODE>mode))
4309 {
4310 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312 if (out != operands[0])
4313 emit_move_insn (operands[0], out);
4314 DONE;
4315 }
4316 })
4317
4318 ;; Signed conversion to HImode.
4319
4320 (define_expand "fix_trunc<mode>hi2"
4321 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323 (clobber (reg:CC FLAGS_REG))])]
4324 "TARGET_80387
4325 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4326 {
4327 if (TARGET_FISTTP)
4328 {
4329 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4330 DONE;
4331 }
4332 })
4333
4334 ;; Unsigned conversion to SImode.
4335
4336 (define_expand "fixuns_trunc<mode>si2"
4337 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4338 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))]
4339 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4340 && TARGET_KEEPS_VECTOR_ALIGNED_STACK && !optimize_size"
4341 {
4342 ix86_expand_convert_uns_si_sse (operands[0], operands[1]);
4343 DONE;
4344 })
4345
4346 ;; Unsigned conversion to HImode.
4347 ;; Without these patterns, we'll try the unsigned SI conversion which
4348 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4349
4350 (define_expand "fixuns_truncsfhi2"
4351 [(set (match_dup 2)
4352 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))
4353 (set (match_operand:HI 0 "nonimmediate_operand" "")
4354 (subreg:HI (match_dup 2) 0))]
4355 "TARGET_SSE_MATH"
4356 "operands[2] = gen_reg_rtx (SImode);")
4357
4358 (define_expand "fixuns_truncdfhi2"
4359 [(set (match_dup 2)
4360 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))
4361 (set (match_operand:HI 0 "nonimmediate_operand" "")
4362 (subreg:HI (match_dup 2) 0))]
4363 "TARGET_SSE_MATH"
4364 "operands[2] = gen_reg_rtx (SImode);")
4365
4366 ;; When SSE is available, it is always faster to use it!
4367 (define_insn "fix_truncsfdi_sse"
4368 [(set (match_operand:DI 0 "register_operand" "=r,r")
4369 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4370 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4371 "cvttss2si{q}\t{%1, %0|%0, %1}"
4372 [(set_attr "type" "sseicvt")
4373 (set_attr "mode" "SF")
4374 (set_attr "athlon_decode" "double,vector")
4375 (set_attr "amdfam10_decode" "double,double")])
4376
4377 (define_insn "fix_truncdfdi_sse"
4378 [(set (match_operand:DI 0 "register_operand" "=r,r")
4379 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4380 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4381 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4382 [(set_attr "type" "sseicvt")
4383 (set_attr "mode" "DF")
4384 (set_attr "athlon_decode" "double,vector")
4385 (set_attr "amdfam10_decode" "double,double")])
4386
4387 (define_insn "fix_truncsfsi_sse"
4388 [(set (match_operand:SI 0 "register_operand" "=r,r")
4389 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4390 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4391 "cvttss2si\t{%1, %0|%0, %1}"
4392 [(set_attr "type" "sseicvt")
4393 (set_attr "mode" "DF")
4394 (set_attr "athlon_decode" "double,vector")
4395 (set_attr "amdfam10_decode" "double,double")])
4396
4397 (define_insn "fix_truncdfsi_sse"
4398 [(set (match_operand:SI 0 "register_operand" "=r,r")
4399 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4400 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4401 "cvttsd2si\t{%1, %0|%0, %1}"
4402 [(set_attr "type" "sseicvt")
4403 (set_attr "mode" "DF")
4404 (set_attr "athlon_decode" "double,vector")
4405 (set_attr "amdfam10_decode" "double,double")])
4406
4407 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4408 (define_peephole2
4409 [(set (match_operand:DF 0 "register_operand" "")
4410 (match_operand:DF 1 "memory_operand" ""))
4411 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4412 (fix:SSEMODEI24 (match_dup 0)))]
4413 "!TARGET_K8
4414 && peep2_reg_dead_p (2, operands[0])"
4415 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4416 "")
4417
4418 (define_peephole2
4419 [(set (match_operand:SF 0 "register_operand" "")
4420 (match_operand:SF 1 "memory_operand" ""))
4421 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4422 (fix:SSEMODEI24 (match_dup 0)))]
4423 "!TARGET_K8
4424 && peep2_reg_dead_p (2, operands[0])"
4425 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4426 "")
4427
4428 ;; Avoid vector decoded forms of the instruction.
4429 (define_peephole2
4430 [(match_scratch:DF 2 "Y")
4431 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4432 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4433 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4434 [(set (match_dup 2) (match_dup 1))
4435 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4436 "")
4437
4438 (define_peephole2
4439 [(match_scratch:SF 2 "x")
4440 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4441 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4442 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4443 [(set (match_dup 2) (match_dup 1))
4444 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4445 "")
4446
4447 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4448 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4449 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4450 "TARGET_FISTTP
4451 && FLOAT_MODE_P (GET_MODE (operands[1]))
4452 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4453 && (TARGET_64BIT || <MODE>mode != DImode))
4454 && TARGET_SSE_MATH)
4455 && !(reload_completed || reload_in_progress)"
4456 "#"
4457 "&& 1"
4458 [(const_int 0)]
4459 {
4460 if (memory_operand (operands[0], VOIDmode))
4461 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4462 else
4463 {
4464 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4465 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4466 operands[1],
4467 operands[2]));
4468 }
4469 DONE;
4470 }
4471 [(set_attr "type" "fisttp")
4472 (set_attr "mode" "<MODE>")])
4473
4474 (define_insn "fix_trunc<mode>_i387_fisttp"
4475 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4476 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4477 (clobber (match_scratch:XF 2 "=&1f"))]
4478 "TARGET_FISTTP
4479 && FLOAT_MODE_P (GET_MODE (operands[1]))
4480 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4481 && (TARGET_64BIT || <MODE>mode != DImode))
4482 && TARGET_SSE_MATH)"
4483 "* return output_fix_trunc (insn, operands, 1);"
4484 [(set_attr "type" "fisttp")
4485 (set_attr "mode" "<MODE>")])
4486
4487 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4488 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4489 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4490 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4491 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4492 "TARGET_FISTTP
4493 && FLOAT_MODE_P (GET_MODE (operands[1]))
4494 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && (TARGET_64BIT || <MODE>mode != DImode))
4496 && TARGET_SSE_MATH)"
4497 "#"
4498 [(set_attr "type" "fisttp")
4499 (set_attr "mode" "<MODE>")])
4500
4501 (define_split
4502 [(set (match_operand:X87MODEI 0 "register_operand" "")
4503 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4504 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4505 (clobber (match_scratch 3 ""))]
4506 "reload_completed"
4507 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4508 (clobber (match_dup 3))])
4509 (set (match_dup 0) (match_dup 2))]
4510 "")
4511
4512 (define_split
4513 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4514 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4515 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4516 (clobber (match_scratch 3 ""))]
4517 "reload_completed"
4518 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4519 (clobber (match_dup 3))])]
4520 "")
4521
4522 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4523 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4524 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4525 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4526 ;; function in i386.c.
4527 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4528 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4529 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4530 (clobber (reg:CC FLAGS_REG))]
4531 "TARGET_80387 && !TARGET_FISTTP
4532 && FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4534 && (TARGET_64BIT || <MODE>mode != DImode))
4535 && !(reload_completed || reload_in_progress)"
4536 "#"
4537 "&& 1"
4538 [(const_int 0)]
4539 {
4540 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4541
4542 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4543 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4544 if (memory_operand (operands[0], VOIDmode))
4545 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4546 operands[2], operands[3]));
4547 else
4548 {
4549 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4550 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4551 operands[2], operands[3],
4552 operands[4]));
4553 }
4554 DONE;
4555 }
4556 [(set_attr "type" "fistp")
4557 (set_attr "i387_cw" "trunc")
4558 (set_attr "mode" "<MODE>")])
4559
4560 (define_insn "fix_truncdi_i387"
4561 [(set (match_operand:DI 0 "memory_operand" "=m")
4562 (fix:DI (match_operand 1 "register_operand" "f")))
4563 (use (match_operand:HI 2 "memory_operand" "m"))
4564 (use (match_operand:HI 3 "memory_operand" "m"))
4565 (clobber (match_scratch:XF 4 "=&1f"))]
4566 "TARGET_80387 && !TARGET_FISTTP
4567 && FLOAT_MODE_P (GET_MODE (operands[1]))
4568 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4569 "* return output_fix_trunc (insn, operands, 0);"
4570 [(set_attr "type" "fistp")
4571 (set_attr "i387_cw" "trunc")
4572 (set_attr "mode" "DI")])
4573
4574 (define_insn "fix_truncdi_i387_with_temp"
4575 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4576 (fix:DI (match_operand 1 "register_operand" "f,f")))
4577 (use (match_operand:HI 2 "memory_operand" "m,m"))
4578 (use (match_operand:HI 3 "memory_operand" "m,m"))
4579 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4580 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4581 "TARGET_80387 && !TARGET_FISTTP
4582 && FLOAT_MODE_P (GET_MODE (operands[1]))
4583 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4584 "#"
4585 [(set_attr "type" "fistp")
4586 (set_attr "i387_cw" "trunc")
4587 (set_attr "mode" "DI")])
4588
4589 (define_split
4590 [(set (match_operand:DI 0 "register_operand" "")
4591 (fix:DI (match_operand 1 "register_operand" "")))
4592 (use (match_operand:HI 2 "memory_operand" ""))
4593 (use (match_operand:HI 3 "memory_operand" ""))
4594 (clobber (match_operand:DI 4 "memory_operand" ""))
4595 (clobber (match_scratch 5 ""))]
4596 "reload_completed"
4597 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4598 (use (match_dup 2))
4599 (use (match_dup 3))
4600 (clobber (match_dup 5))])
4601 (set (match_dup 0) (match_dup 4))]
4602 "")
4603
4604 (define_split
4605 [(set (match_operand:DI 0 "memory_operand" "")
4606 (fix:DI (match_operand 1 "register_operand" "")))
4607 (use (match_operand:HI 2 "memory_operand" ""))
4608 (use (match_operand:HI 3 "memory_operand" ""))
4609 (clobber (match_operand:DI 4 "memory_operand" ""))
4610 (clobber (match_scratch 5 ""))]
4611 "reload_completed"
4612 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4613 (use (match_dup 2))
4614 (use (match_dup 3))
4615 (clobber (match_dup 5))])]
4616 "")
4617
4618 (define_insn "fix_trunc<mode>_i387"
4619 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4620 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4621 (use (match_operand:HI 2 "memory_operand" "m"))
4622 (use (match_operand:HI 3 "memory_operand" "m"))]
4623 "TARGET_80387 && !TARGET_FISTTP
4624 && FLOAT_MODE_P (GET_MODE (operands[1]))
4625 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4626 "* return output_fix_trunc (insn, operands, 0);"
4627 [(set_attr "type" "fistp")
4628 (set_attr "i387_cw" "trunc")
4629 (set_attr "mode" "<MODE>")])
4630
4631 (define_insn "fix_trunc<mode>_i387_with_temp"
4632 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4633 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4634 (use (match_operand:HI 2 "memory_operand" "m,m"))
4635 (use (match_operand:HI 3 "memory_operand" "m,m"))
4636 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4637 "TARGET_80387 && !TARGET_FISTTP
4638 && FLOAT_MODE_P (GET_MODE (operands[1]))
4639 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4640 "#"
4641 [(set_attr "type" "fistp")
4642 (set_attr "i387_cw" "trunc")
4643 (set_attr "mode" "<MODE>")])
4644
4645 (define_split
4646 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4647 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4648 (use (match_operand:HI 2 "memory_operand" ""))
4649 (use (match_operand:HI 3 "memory_operand" ""))
4650 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4651 "reload_completed"
4652 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4653 (use (match_dup 2))
4654 (use (match_dup 3))])
4655 (set (match_dup 0) (match_dup 4))]
4656 "")
4657
4658 (define_split
4659 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4660 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4661 (use (match_operand:HI 2 "memory_operand" ""))
4662 (use (match_operand:HI 3 "memory_operand" ""))
4663 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4664 "reload_completed"
4665 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4666 (use (match_dup 2))
4667 (use (match_dup 3))])]
4668 "")
4669
4670 (define_insn "x86_fnstcw_1"
4671 [(set (match_operand:HI 0 "memory_operand" "=m")
4672 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4673 "TARGET_80387"
4674 "fnstcw\t%0"
4675 [(set_attr "length" "2")
4676 (set_attr "mode" "HI")
4677 (set_attr "unit" "i387")])
4678
4679 (define_insn "x86_fldcw_1"
4680 [(set (reg:HI FPCR_REG)
4681 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4682 "TARGET_80387"
4683 "fldcw\t%0"
4684 [(set_attr "length" "2")
4685 (set_attr "mode" "HI")
4686 (set_attr "unit" "i387")
4687 (set_attr "athlon_decode" "vector")
4688 (set_attr "amdfam10_decode" "vector")])
4689 \f
4690 ;; Conversion between fixed point and floating point.
4691
4692 ;; Even though we only accept memory inputs, the backend _really_
4693 ;; wants to be able to do this between registers.
4694
4695 (define_expand "floathisf2"
4696 [(set (match_operand:SF 0 "register_operand" "")
4697 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4698 "TARGET_80387 || TARGET_SSE_MATH"
4699 {
4700 if (TARGET_SSE_MATH)
4701 {
4702 emit_insn (gen_floatsisf2 (operands[0],
4703 convert_to_mode (SImode, operands[1], 0)));
4704 DONE;
4705 }
4706 })
4707
4708 (define_insn "*floathisf2_i387"
4709 [(set (match_operand:SF 0 "register_operand" "=f,f")
4710 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4711 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4712 "@
4713 fild%z1\t%1
4714 #"
4715 [(set_attr "type" "fmov,multi")
4716 (set_attr "mode" "SF")
4717 (set_attr "unit" "*,i387")
4718 (set_attr "fp_int_src" "true")])
4719
4720 (define_expand "floatsisf2"
4721 [(set (match_operand:SF 0 "register_operand" "")
4722 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4723 "TARGET_80387 || TARGET_SSE_MATH"
4724 "")
4725
4726 (define_insn "*floatsisf2_mixed"
4727 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4728 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4729 "TARGET_MIX_SSE_I387"
4730 "@
4731 fild%z1\t%1
4732 #
4733 cvtsi2ss\t{%1, %0|%0, %1}
4734 cvtsi2ss\t{%1, %0|%0, %1}"
4735 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4736 (set_attr "mode" "SF")
4737 (set_attr "unit" "*,i387,*,*")
4738 (set_attr "athlon_decode" "*,*,vector,double")
4739 (set_attr "amdfam10_decode" "*,*,vector,double")
4740 (set_attr "fp_int_src" "true")])
4741
4742 (define_insn "*floatsisf2_sse"
4743 [(set (match_operand:SF 0 "register_operand" "=x,x")
4744 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4745 "TARGET_SSE_MATH"
4746 "cvtsi2ss\t{%1, %0|%0, %1}"
4747 [(set_attr "type" "sseicvt")
4748 (set_attr "mode" "SF")
4749 (set_attr "athlon_decode" "vector,double")
4750 (set_attr "amdfam10_decode" "vector,double")
4751 (set_attr "fp_int_src" "true")])
4752
4753 (define_insn "*floatsisf2_i387"
4754 [(set (match_operand:SF 0 "register_operand" "=f,f")
4755 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4756 "TARGET_80387"
4757 "@
4758 fild%z1\t%1
4759 #"
4760 [(set_attr "type" "fmov,multi")
4761 (set_attr "mode" "SF")
4762 (set_attr "unit" "*,i387")
4763 (set_attr "fp_int_src" "true")])
4764
4765 (define_expand "floatdisf2"
4766 [(set (match_operand:SF 0 "register_operand" "")
4767 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4768 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4769 "")
4770
4771 (define_insn "*floatdisf2_mixed"
4772 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4773 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4774 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4775 "@
4776 fild%z1\t%1
4777 #
4778 cvtsi2ss{q}\t{%1, %0|%0, %1}
4779 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4780 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4781 (set_attr "mode" "SF")
4782 (set_attr "unit" "*,i387,*,*")
4783 (set_attr "athlon_decode" "*,*,vector,double")
4784 (set_attr "amdfam10_decode" "*,*,vector,double")
4785 (set_attr "fp_int_src" "true")])
4786
4787 (define_insn "*floatdisf2_sse"
4788 [(set (match_operand:SF 0 "register_operand" "=x,x")
4789 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4790 "TARGET_64BIT && TARGET_SSE_MATH"
4791 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4792 [(set_attr "type" "sseicvt")
4793 (set_attr "mode" "SF")
4794 (set_attr "athlon_decode" "vector,double")
4795 (set_attr "amdfam10_decode" "vector,double")
4796 (set_attr "fp_int_src" "true")])
4797
4798 (define_insn "*floatdisf2_i387"
4799 [(set (match_operand:SF 0 "register_operand" "=f,f")
4800 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4801 "TARGET_80387"
4802 "@
4803 fild%z1\t%1
4804 #"
4805 [(set_attr "type" "fmov,multi")
4806 (set_attr "mode" "SF")
4807 (set_attr "unit" "*,i387")
4808 (set_attr "fp_int_src" "true")])
4809
4810 (define_expand "floathidf2"
4811 [(set (match_operand:DF 0 "register_operand" "")
4812 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4813 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4814 {
4815 if (TARGET_SSE2 && TARGET_SSE_MATH)
4816 {
4817 emit_insn (gen_floatsidf2 (operands[0],
4818 convert_to_mode (SImode, operands[1], 0)));
4819 DONE;
4820 }
4821 })
4822
4823 (define_insn "*floathidf2_i387"
4824 [(set (match_operand:DF 0 "register_operand" "=f,f")
4825 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4826 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4827 "@
4828 fild%z1\t%1
4829 #"
4830 [(set_attr "type" "fmov,multi")
4831 (set_attr "mode" "DF")
4832 (set_attr "unit" "*,i387")
4833 (set_attr "fp_int_src" "true")])
4834
4835 (define_expand "floatsidf2"
4836 [(set (match_operand:DF 0 "register_operand" "")
4837 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4838 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4839 "")
4840
4841 (define_insn "*floatsidf2_mixed"
4842 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4843 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4844 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4845 "@
4846 fild%z1\t%1
4847 #
4848 cvtsi2sd\t{%1, %0|%0, %1}
4849 cvtsi2sd\t{%1, %0|%0, %1}"
4850 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4851 (set_attr "mode" "DF")
4852 (set_attr "unit" "*,i387,*,*")
4853 (set_attr "athlon_decode" "*,*,double,direct")
4854 (set_attr "amdfam10_decode" "*,*,vector,double")
4855 (set_attr "fp_int_src" "true")])
4856
4857 (define_insn "*floatsidf2_sse"
4858 [(set (match_operand:DF 0 "register_operand" "=x,x")
4859 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4860 "TARGET_SSE2 && TARGET_SSE_MATH"
4861 "cvtsi2sd\t{%1, %0|%0, %1}"
4862 [(set_attr "type" "sseicvt")
4863 (set_attr "mode" "DF")
4864 (set_attr "athlon_decode" "double,direct")
4865 (set_attr "amdfam10_decode" "vector,double")
4866 (set_attr "fp_int_src" "true")])
4867
4868 (define_insn "*floatsidf2_i387"
4869 [(set (match_operand:DF 0 "register_operand" "=f,f")
4870 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4871 "TARGET_80387"
4872 "@
4873 fild%z1\t%1
4874 #"
4875 [(set_attr "type" "fmov,multi")
4876 (set_attr "mode" "DF")
4877 (set_attr "unit" "*,i387")
4878 (set_attr "fp_int_src" "true")])
4879
4880 (define_expand "floatdidf2"
4881 [(set (match_operand:DF 0 "register_operand" "")
4882 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4883 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4884 {
4885 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4886 {
4887 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4888 DONE;
4889 }
4890 })
4891
4892 (define_insn "*floatdidf2_mixed"
4893 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4894 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4895 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4896 "@
4897 fild%z1\t%1
4898 #
4899 cvtsi2sd{q}\t{%1, %0|%0, %1}
4900 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4901 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4902 (set_attr "mode" "DF")
4903 (set_attr "unit" "*,i387,*,*")
4904 (set_attr "athlon_decode" "*,*,double,direct")
4905 (set_attr "amdfam10_decode" "*,*,vector,double")
4906 (set_attr "fp_int_src" "true")])
4907
4908 (define_insn "*floatdidf2_sse"
4909 [(set (match_operand:DF 0 "register_operand" "=x,x")
4910 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4911 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4912 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4913 [(set_attr "type" "sseicvt")
4914 (set_attr "mode" "DF")
4915 (set_attr "athlon_decode" "double,direct")
4916 (set_attr "amdfam10_decode" "vector,double")
4917 (set_attr "fp_int_src" "true")])
4918
4919 (define_insn "*floatdidf2_i387"
4920 [(set (match_operand:DF 0 "register_operand" "=f,f")
4921 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4922 "TARGET_80387"
4923 "@
4924 fild%z1\t%1
4925 #"
4926 [(set_attr "type" "fmov,multi")
4927 (set_attr "mode" "DF")
4928 (set_attr "unit" "*,i387")
4929 (set_attr "fp_int_src" "true")])
4930
4931 (define_insn "floathixf2"
4932 [(set (match_operand:XF 0 "register_operand" "=f,f")
4933 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4934 "TARGET_80387"
4935 "@
4936 fild%z1\t%1
4937 #"
4938 [(set_attr "type" "fmov,multi")
4939 (set_attr "mode" "XF")
4940 (set_attr "unit" "*,i387")
4941 (set_attr "fp_int_src" "true")])
4942
4943 (define_insn "floatsixf2"
4944 [(set (match_operand:XF 0 "register_operand" "=f,f")
4945 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4946 "TARGET_80387"
4947 "@
4948 fild%z1\t%1
4949 #"
4950 [(set_attr "type" "fmov,multi")
4951 (set_attr "mode" "XF")
4952 (set_attr "unit" "*,i387")
4953 (set_attr "fp_int_src" "true")])
4954
4955 (define_insn "floatdixf2"
4956 [(set (match_operand:XF 0 "register_operand" "=f,f")
4957 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4958 "TARGET_80387"
4959 "@
4960 fild%z1\t%1
4961 #"
4962 [(set_attr "type" "fmov,multi")
4963 (set_attr "mode" "XF")
4964 (set_attr "unit" "*,i387")
4965 (set_attr "fp_int_src" "true")])
4966
4967 ;; %%% Kill these when reload knows how to do it.
4968 (define_split
4969 [(set (match_operand 0 "fp_register_operand" "")
4970 (float (match_operand 1 "register_operand" "")))]
4971 "reload_completed
4972 && TARGET_80387
4973 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4974 [(const_int 0)]
4975 {
4976 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4977 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4978 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4979 ix86_free_from_memory (GET_MODE (operands[1]));
4980 DONE;
4981 })
4982
4983 (define_expand "floatunssisf2"
4984 [(use (match_operand:SF 0 "register_operand" ""))
4985 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4986 "!TARGET_64BIT"
4987 {
4988 if (TARGET_SSE_MATH && TARGET_SSE2)
4989 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4990 else
4991 x86_emit_floatuns (operands);
4992 DONE;
4993 })
4994
4995 (define_expand "floatunssidf2"
4996 [(use (match_operand:DF 0 "register_operand" ""))
4997 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4998 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4999 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5000
5001 (define_expand "floatunsdisf2"
5002 [(use (match_operand:SF 0 "register_operand" ""))
5003 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5004 "TARGET_64BIT && TARGET_SSE_MATH"
5005 "x86_emit_floatuns (operands); DONE;")
5006
5007 (define_expand "floatunsdidf2"
5008 [(use (match_operand:DF 0 "register_operand" ""))
5009 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5010 "TARGET_SSE_MATH && TARGET_SSE2
5011 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5012 {
5013 if (TARGET_64BIT)
5014 x86_emit_floatuns (operands);
5015 else
5016 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5017 DONE;
5018 })
5019 \f
5020 ;; SSE extract/set expanders
5021
5022 \f
5023 ;; Add instructions
5024
5025 ;; %%% splits for addditi3
5026
5027 (define_expand "addti3"
5028 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5029 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5030 (match_operand:TI 2 "x86_64_general_operand" "")))
5031 (clobber (reg:CC FLAGS_REG))]
5032 "TARGET_64BIT"
5033 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5034
5035 (define_insn "*addti3_1"
5036 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5037 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5038 (match_operand:TI 2 "general_operand" "roiF,riF")))
5039 (clobber (reg:CC FLAGS_REG))]
5040 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5041 "#")
5042
5043 (define_split
5044 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5045 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5046 (match_operand:TI 2 "general_operand" "")))
5047 (clobber (reg:CC FLAGS_REG))]
5048 "TARGET_64BIT && reload_completed"
5049 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5050 UNSPEC_ADD_CARRY))
5051 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5052 (parallel [(set (match_dup 3)
5053 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5054 (match_dup 4))
5055 (match_dup 5)))
5056 (clobber (reg:CC FLAGS_REG))])]
5057 "split_ti (operands+0, 1, operands+0, operands+3);
5058 split_ti (operands+1, 1, operands+1, operands+4);
5059 split_ti (operands+2, 1, operands+2, operands+5);")
5060
5061 ;; %%% splits for addsidi3
5062 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5063 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5064 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5065
5066 (define_expand "adddi3"
5067 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5068 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5069 (match_operand:DI 2 "x86_64_general_operand" "")))
5070 (clobber (reg:CC FLAGS_REG))]
5071 ""
5072 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5073
5074 (define_insn "*adddi3_1"
5075 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5076 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5077 (match_operand:DI 2 "general_operand" "roiF,riF")))
5078 (clobber (reg:CC FLAGS_REG))]
5079 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5080 "#")
5081
5082 (define_split
5083 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5084 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5085 (match_operand:DI 2 "general_operand" "")))
5086 (clobber (reg:CC FLAGS_REG))]
5087 "!TARGET_64BIT && reload_completed"
5088 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5089 UNSPEC_ADD_CARRY))
5090 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5091 (parallel [(set (match_dup 3)
5092 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5093 (match_dup 4))
5094 (match_dup 5)))
5095 (clobber (reg:CC FLAGS_REG))])]
5096 "split_di (operands+0, 1, operands+0, operands+3);
5097 split_di (operands+1, 1, operands+1, operands+4);
5098 split_di (operands+2, 1, operands+2, operands+5);")
5099
5100 (define_insn "adddi3_carry_rex64"
5101 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5102 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5103 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5104 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5105 (clobber (reg:CC FLAGS_REG))]
5106 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5107 "adc{q}\t{%2, %0|%0, %2}"
5108 [(set_attr "type" "alu")
5109 (set_attr "pent_pair" "pu")
5110 (set_attr "mode" "DI")])
5111
5112 (define_insn "*adddi3_cc_rex64"
5113 [(set (reg:CC FLAGS_REG)
5114 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5115 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5116 UNSPEC_ADD_CARRY))
5117 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5118 (plus:DI (match_dup 1) (match_dup 2)))]
5119 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5120 "add{q}\t{%2, %0|%0, %2}"
5121 [(set_attr "type" "alu")
5122 (set_attr "mode" "DI")])
5123
5124 (define_insn "addqi3_carry"
5125 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5126 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5127 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5128 (match_operand:QI 2 "general_operand" "qi,qm")))
5129 (clobber (reg:CC FLAGS_REG))]
5130 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5131 "adc{b}\t{%2, %0|%0, %2}"
5132 [(set_attr "type" "alu")
5133 (set_attr "pent_pair" "pu")
5134 (set_attr "mode" "QI")])
5135
5136 (define_insn "addhi3_carry"
5137 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5138 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5139 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5140 (match_operand:HI 2 "general_operand" "ri,rm")))
5141 (clobber (reg:CC FLAGS_REG))]
5142 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5143 "adc{w}\t{%2, %0|%0, %2}"
5144 [(set_attr "type" "alu")
5145 (set_attr "pent_pair" "pu")
5146 (set_attr "mode" "HI")])
5147
5148 (define_insn "addsi3_carry"
5149 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5150 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5151 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5152 (match_operand:SI 2 "general_operand" "ri,rm")))
5153 (clobber (reg:CC FLAGS_REG))]
5154 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5155 "adc{l}\t{%2, %0|%0, %2}"
5156 [(set_attr "type" "alu")
5157 (set_attr "pent_pair" "pu")
5158 (set_attr "mode" "SI")])
5159
5160 (define_insn "*addsi3_carry_zext"
5161 [(set (match_operand:DI 0 "register_operand" "=r")
5162 (zero_extend:DI
5163 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5164 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5165 (match_operand:SI 2 "general_operand" "rim"))))
5166 (clobber (reg:CC FLAGS_REG))]
5167 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5168 "adc{l}\t{%2, %k0|%k0, %2}"
5169 [(set_attr "type" "alu")
5170 (set_attr "pent_pair" "pu")
5171 (set_attr "mode" "SI")])
5172
5173 (define_insn "*addsi3_cc"
5174 [(set (reg:CC FLAGS_REG)
5175 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5176 (match_operand:SI 2 "general_operand" "ri,rm")]
5177 UNSPEC_ADD_CARRY))
5178 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5179 (plus:SI (match_dup 1) (match_dup 2)))]
5180 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5181 "add{l}\t{%2, %0|%0, %2}"
5182 [(set_attr "type" "alu")
5183 (set_attr "mode" "SI")])
5184
5185 (define_insn "addqi3_cc"
5186 [(set (reg:CC FLAGS_REG)
5187 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5188 (match_operand:QI 2 "general_operand" "qi,qm")]
5189 UNSPEC_ADD_CARRY))
5190 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5191 (plus:QI (match_dup 1) (match_dup 2)))]
5192 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5193 "add{b}\t{%2, %0|%0, %2}"
5194 [(set_attr "type" "alu")
5195 (set_attr "mode" "QI")])
5196
5197 (define_expand "addsi3"
5198 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5199 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5200 (match_operand:SI 2 "general_operand" "")))
5201 (clobber (reg:CC FLAGS_REG))])]
5202 ""
5203 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5204
5205 (define_insn "*lea_1"
5206 [(set (match_operand:SI 0 "register_operand" "=r")
5207 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5208 "!TARGET_64BIT"
5209 "lea{l}\t{%a1, %0|%0, %a1}"
5210 [(set_attr "type" "lea")
5211 (set_attr "mode" "SI")])
5212
5213 (define_insn "*lea_1_rex64"
5214 [(set (match_operand:SI 0 "register_operand" "=r")
5215 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5216 "TARGET_64BIT"
5217 "lea{l}\t{%a1, %0|%0, %a1}"
5218 [(set_attr "type" "lea")
5219 (set_attr "mode" "SI")])
5220
5221 (define_insn "*lea_1_zext"
5222 [(set (match_operand:DI 0 "register_operand" "=r")
5223 (zero_extend:DI
5224 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5225 "TARGET_64BIT"
5226 "lea{l}\t{%a1, %k0|%k0, %a1}"
5227 [(set_attr "type" "lea")
5228 (set_attr "mode" "SI")])
5229
5230 (define_insn "*lea_2_rex64"
5231 [(set (match_operand:DI 0 "register_operand" "=r")
5232 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5233 "TARGET_64BIT"
5234 "lea{q}\t{%a1, %0|%0, %a1}"
5235 [(set_attr "type" "lea")
5236 (set_attr "mode" "DI")])
5237
5238 ;; The lea patterns for non-Pmodes needs to be matched by several
5239 ;; insns converted to real lea by splitters.
5240
5241 (define_insn_and_split "*lea_general_1"
5242 [(set (match_operand 0 "register_operand" "=r")
5243 (plus (plus (match_operand 1 "index_register_operand" "l")
5244 (match_operand 2 "register_operand" "r"))
5245 (match_operand 3 "immediate_operand" "i")))]
5246 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5247 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5248 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5249 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5250 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5251 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5252 || GET_MODE (operands[3]) == VOIDmode)"
5253 "#"
5254 "&& reload_completed"
5255 [(const_int 0)]
5256 {
5257 rtx pat;
5258 operands[0] = gen_lowpart (SImode, operands[0]);
5259 operands[1] = gen_lowpart (Pmode, operands[1]);
5260 operands[2] = gen_lowpart (Pmode, operands[2]);
5261 operands[3] = gen_lowpart (Pmode, operands[3]);
5262 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5263 operands[3]);
5264 if (Pmode != SImode)
5265 pat = gen_rtx_SUBREG (SImode, pat, 0);
5266 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5267 DONE;
5268 }
5269 [(set_attr "type" "lea")
5270 (set_attr "mode" "SI")])
5271
5272 (define_insn_and_split "*lea_general_1_zext"
5273 [(set (match_operand:DI 0 "register_operand" "=r")
5274 (zero_extend:DI
5275 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5276 (match_operand:SI 2 "register_operand" "r"))
5277 (match_operand:SI 3 "immediate_operand" "i"))))]
5278 "TARGET_64BIT"
5279 "#"
5280 "&& reload_completed"
5281 [(set (match_dup 0)
5282 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5283 (match_dup 2))
5284 (match_dup 3)) 0)))]
5285 {
5286 operands[1] = gen_lowpart (Pmode, operands[1]);
5287 operands[2] = gen_lowpart (Pmode, operands[2]);
5288 operands[3] = gen_lowpart (Pmode, operands[3]);
5289 }
5290 [(set_attr "type" "lea")
5291 (set_attr "mode" "SI")])
5292
5293 (define_insn_and_split "*lea_general_2"
5294 [(set (match_operand 0 "register_operand" "=r")
5295 (plus (mult (match_operand 1 "index_register_operand" "l")
5296 (match_operand 2 "const248_operand" "i"))
5297 (match_operand 3 "nonmemory_operand" "ri")))]
5298 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5299 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5300 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5301 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5302 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5303 || GET_MODE (operands[3]) == VOIDmode)"
5304 "#"
5305 "&& reload_completed"
5306 [(const_int 0)]
5307 {
5308 rtx pat;
5309 operands[0] = gen_lowpart (SImode, operands[0]);
5310 operands[1] = gen_lowpart (Pmode, operands[1]);
5311 operands[3] = gen_lowpart (Pmode, operands[3]);
5312 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5313 operands[3]);
5314 if (Pmode != SImode)
5315 pat = gen_rtx_SUBREG (SImode, pat, 0);
5316 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5317 DONE;
5318 }
5319 [(set_attr "type" "lea")
5320 (set_attr "mode" "SI")])
5321
5322 (define_insn_and_split "*lea_general_2_zext"
5323 [(set (match_operand:DI 0 "register_operand" "=r")
5324 (zero_extend:DI
5325 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5326 (match_operand:SI 2 "const248_operand" "n"))
5327 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5328 "TARGET_64BIT"
5329 "#"
5330 "&& reload_completed"
5331 [(set (match_dup 0)
5332 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5333 (match_dup 2))
5334 (match_dup 3)) 0)))]
5335 {
5336 operands[1] = gen_lowpart (Pmode, operands[1]);
5337 operands[3] = gen_lowpart (Pmode, operands[3]);
5338 }
5339 [(set_attr "type" "lea")
5340 (set_attr "mode" "SI")])
5341
5342 (define_insn_and_split "*lea_general_3"
5343 [(set (match_operand 0 "register_operand" "=r")
5344 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5345 (match_operand 2 "const248_operand" "i"))
5346 (match_operand 3 "register_operand" "r"))
5347 (match_operand 4 "immediate_operand" "i")))]
5348 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5349 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5350 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5351 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5352 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5353 "#"
5354 "&& reload_completed"
5355 [(const_int 0)]
5356 {
5357 rtx pat;
5358 operands[0] = gen_lowpart (SImode, operands[0]);
5359 operands[1] = gen_lowpart (Pmode, operands[1]);
5360 operands[3] = gen_lowpart (Pmode, operands[3]);
5361 operands[4] = gen_lowpart (Pmode, operands[4]);
5362 pat = gen_rtx_PLUS (Pmode,
5363 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5364 operands[2]),
5365 operands[3]),
5366 operands[4]);
5367 if (Pmode != SImode)
5368 pat = gen_rtx_SUBREG (SImode, pat, 0);
5369 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5370 DONE;
5371 }
5372 [(set_attr "type" "lea")
5373 (set_attr "mode" "SI")])
5374
5375 (define_insn_and_split "*lea_general_3_zext"
5376 [(set (match_operand:DI 0 "register_operand" "=r")
5377 (zero_extend:DI
5378 (plus:SI (plus:SI (mult:SI
5379 (match_operand:SI 1 "index_register_operand" "l")
5380 (match_operand:SI 2 "const248_operand" "n"))
5381 (match_operand:SI 3 "register_operand" "r"))
5382 (match_operand:SI 4 "immediate_operand" "i"))))]
5383 "TARGET_64BIT"
5384 "#"
5385 "&& reload_completed"
5386 [(set (match_dup 0)
5387 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5388 (match_dup 2))
5389 (match_dup 3))
5390 (match_dup 4)) 0)))]
5391 {
5392 operands[1] = gen_lowpart (Pmode, operands[1]);
5393 operands[3] = gen_lowpart (Pmode, operands[3]);
5394 operands[4] = gen_lowpart (Pmode, operands[4]);
5395 }
5396 [(set_attr "type" "lea")
5397 (set_attr "mode" "SI")])
5398
5399 (define_insn "*adddi_1_rex64"
5400 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5401 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5402 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5403 (clobber (reg:CC FLAGS_REG))]
5404 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5405 {
5406 switch (get_attr_type (insn))
5407 {
5408 case TYPE_LEA:
5409 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5410 return "lea{q}\t{%a2, %0|%0, %a2}";
5411
5412 case TYPE_INCDEC:
5413 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5414 if (operands[2] == const1_rtx)
5415 return "inc{q}\t%0";
5416 else
5417 {
5418 gcc_assert (operands[2] == constm1_rtx);
5419 return "dec{q}\t%0";
5420 }
5421
5422 default:
5423 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5424
5425 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5426 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5427 if (CONST_INT_P (operands[2])
5428 /* Avoid overflows. */
5429 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5430 && (INTVAL (operands[2]) == 128
5431 || (INTVAL (operands[2]) < 0
5432 && INTVAL (operands[2]) != -128)))
5433 {
5434 operands[2] = GEN_INT (-INTVAL (operands[2]));
5435 return "sub{q}\t{%2, %0|%0, %2}";
5436 }
5437 return "add{q}\t{%2, %0|%0, %2}";
5438 }
5439 }
5440 [(set (attr "type")
5441 (cond [(eq_attr "alternative" "2")
5442 (const_string "lea")
5443 ; Current assemblers are broken and do not allow @GOTOFF in
5444 ; ought but a memory context.
5445 (match_operand:DI 2 "pic_symbolic_operand" "")
5446 (const_string "lea")
5447 (match_operand:DI 2 "incdec_operand" "")
5448 (const_string "incdec")
5449 ]
5450 (const_string "alu")))
5451 (set_attr "mode" "DI")])
5452
5453 ;; Convert lea to the lea pattern to avoid flags dependency.
5454 (define_split
5455 [(set (match_operand:DI 0 "register_operand" "")
5456 (plus:DI (match_operand:DI 1 "register_operand" "")
5457 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5458 (clobber (reg:CC FLAGS_REG))]
5459 "TARGET_64BIT && reload_completed
5460 && true_regnum (operands[0]) != true_regnum (operands[1])"
5461 [(set (match_dup 0)
5462 (plus:DI (match_dup 1)
5463 (match_dup 2)))]
5464 "")
5465
5466 (define_insn "*adddi_2_rex64"
5467 [(set (reg FLAGS_REG)
5468 (compare
5469 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5470 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5471 (const_int 0)))
5472 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5473 (plus:DI (match_dup 1) (match_dup 2)))]
5474 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5475 && ix86_binary_operator_ok (PLUS, DImode, operands)
5476 /* Current assemblers are broken and do not allow @GOTOFF in
5477 ought but a memory context. */
5478 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5479 {
5480 switch (get_attr_type (insn))
5481 {
5482 case TYPE_INCDEC:
5483 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5484 if (operands[2] == const1_rtx)
5485 return "inc{q}\t%0";
5486 else
5487 {
5488 gcc_assert (operands[2] == constm1_rtx);
5489 return "dec{q}\t%0";
5490 }
5491
5492 default:
5493 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5494 /* ???? We ought to handle there the 32bit case too
5495 - do we need new constraint? */
5496 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5497 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5498 if (CONST_INT_P (operands[2])
5499 /* Avoid overflows. */
5500 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5501 && (INTVAL (operands[2]) == 128
5502 || (INTVAL (operands[2]) < 0
5503 && INTVAL (operands[2]) != -128)))
5504 {
5505 operands[2] = GEN_INT (-INTVAL (operands[2]));
5506 return "sub{q}\t{%2, %0|%0, %2}";
5507 }
5508 return "add{q}\t{%2, %0|%0, %2}";
5509 }
5510 }
5511 [(set (attr "type")
5512 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5513 (const_string "incdec")
5514 (const_string "alu")))
5515 (set_attr "mode" "DI")])
5516
5517 (define_insn "*adddi_3_rex64"
5518 [(set (reg FLAGS_REG)
5519 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5520 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5521 (clobber (match_scratch:DI 0 "=r"))]
5522 "TARGET_64BIT
5523 && ix86_match_ccmode (insn, CCZmode)
5524 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5525 /* Current assemblers are broken and do not allow @GOTOFF in
5526 ought but a memory context. */
5527 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5528 {
5529 switch (get_attr_type (insn))
5530 {
5531 case TYPE_INCDEC:
5532 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5533 if (operands[2] == const1_rtx)
5534 return "inc{q}\t%0";
5535 else
5536 {
5537 gcc_assert (operands[2] == constm1_rtx);
5538 return "dec{q}\t%0";
5539 }
5540
5541 default:
5542 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5543 /* ???? We ought to handle there the 32bit case too
5544 - do we need new constraint? */
5545 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5546 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5547 if (CONST_INT_P (operands[2])
5548 /* Avoid overflows. */
5549 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5550 && (INTVAL (operands[2]) == 128
5551 || (INTVAL (operands[2]) < 0
5552 && INTVAL (operands[2]) != -128)))
5553 {
5554 operands[2] = GEN_INT (-INTVAL (operands[2]));
5555 return "sub{q}\t{%2, %0|%0, %2}";
5556 }
5557 return "add{q}\t{%2, %0|%0, %2}";
5558 }
5559 }
5560 [(set (attr "type")
5561 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5562 (const_string "incdec")
5563 (const_string "alu")))
5564 (set_attr "mode" "DI")])
5565
5566 ; For comparisons against 1, -1 and 128, we may generate better code
5567 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5568 ; is matched then. We can't accept general immediate, because for
5569 ; case of overflows, the result is messed up.
5570 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5571 ; when negated.
5572 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5573 ; only for comparisons not depending on it.
5574 (define_insn "*adddi_4_rex64"
5575 [(set (reg FLAGS_REG)
5576 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5577 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5578 (clobber (match_scratch:DI 0 "=rm"))]
5579 "TARGET_64BIT
5580 && ix86_match_ccmode (insn, CCGCmode)"
5581 {
5582 switch (get_attr_type (insn))
5583 {
5584 case TYPE_INCDEC:
5585 if (operands[2] == constm1_rtx)
5586 return "inc{q}\t%0";
5587 else
5588 {
5589 gcc_assert (operands[2] == const1_rtx);
5590 return "dec{q}\t%0";
5591 }
5592
5593 default:
5594 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5595 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5596 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5597 if ((INTVAL (operands[2]) == -128
5598 || (INTVAL (operands[2]) > 0
5599 && INTVAL (operands[2]) != 128))
5600 /* Avoid overflows. */
5601 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5602 return "sub{q}\t{%2, %0|%0, %2}";
5603 operands[2] = GEN_INT (-INTVAL (operands[2]));
5604 return "add{q}\t{%2, %0|%0, %2}";
5605 }
5606 }
5607 [(set (attr "type")
5608 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5609 (const_string "incdec")
5610 (const_string "alu")))
5611 (set_attr "mode" "DI")])
5612
5613 (define_insn "*adddi_5_rex64"
5614 [(set (reg FLAGS_REG)
5615 (compare
5616 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5617 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5618 (const_int 0)))
5619 (clobber (match_scratch:DI 0 "=r"))]
5620 "TARGET_64BIT
5621 && ix86_match_ccmode (insn, CCGOCmode)
5622 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5623 /* Current assemblers are broken and do not allow @GOTOFF in
5624 ought but a memory context. */
5625 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5626 {
5627 switch (get_attr_type (insn))
5628 {
5629 case TYPE_INCDEC:
5630 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5631 if (operands[2] == const1_rtx)
5632 return "inc{q}\t%0";
5633 else
5634 {
5635 gcc_assert (operands[2] == constm1_rtx);
5636 return "dec{q}\t%0";
5637 }
5638
5639 default:
5640 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5642 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5643 if (CONST_INT_P (operands[2])
5644 /* Avoid overflows. */
5645 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5646 && (INTVAL (operands[2]) == 128
5647 || (INTVAL (operands[2]) < 0
5648 && INTVAL (operands[2]) != -128)))
5649 {
5650 operands[2] = GEN_INT (-INTVAL (operands[2]));
5651 return "sub{q}\t{%2, %0|%0, %2}";
5652 }
5653 return "add{q}\t{%2, %0|%0, %2}";
5654 }
5655 }
5656 [(set (attr "type")
5657 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5658 (const_string "incdec")
5659 (const_string "alu")))
5660 (set_attr "mode" "DI")])
5661
5662
5663 (define_insn "*addsi_1"
5664 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5665 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5666 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5667 (clobber (reg:CC FLAGS_REG))]
5668 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5669 {
5670 switch (get_attr_type (insn))
5671 {
5672 case TYPE_LEA:
5673 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5674 return "lea{l}\t{%a2, %0|%0, %a2}";
5675
5676 case TYPE_INCDEC:
5677 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5678 if (operands[2] == const1_rtx)
5679 return "inc{l}\t%0";
5680 else
5681 {
5682 gcc_assert (operands[2] == constm1_rtx);
5683 return "dec{l}\t%0";
5684 }
5685
5686 default:
5687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5688
5689 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5690 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5691 if (CONST_INT_P (operands[2])
5692 && (INTVAL (operands[2]) == 128
5693 || (INTVAL (operands[2]) < 0
5694 && INTVAL (operands[2]) != -128)))
5695 {
5696 operands[2] = GEN_INT (-INTVAL (operands[2]));
5697 return "sub{l}\t{%2, %0|%0, %2}";
5698 }
5699 return "add{l}\t{%2, %0|%0, %2}";
5700 }
5701 }
5702 [(set (attr "type")
5703 (cond [(eq_attr "alternative" "2")
5704 (const_string "lea")
5705 ; Current assemblers are broken and do not allow @GOTOFF in
5706 ; ought but a memory context.
5707 (match_operand:SI 2 "pic_symbolic_operand" "")
5708 (const_string "lea")
5709 (match_operand:SI 2 "incdec_operand" "")
5710 (const_string "incdec")
5711 ]
5712 (const_string "alu")))
5713 (set_attr "mode" "SI")])
5714
5715 ;; Convert lea to the lea pattern to avoid flags dependency.
5716 (define_split
5717 [(set (match_operand 0 "register_operand" "")
5718 (plus (match_operand 1 "register_operand" "")
5719 (match_operand 2 "nonmemory_operand" "")))
5720 (clobber (reg:CC FLAGS_REG))]
5721 "reload_completed
5722 && true_regnum (operands[0]) != true_regnum (operands[1])"
5723 [(const_int 0)]
5724 {
5725 rtx pat;
5726 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5727 may confuse gen_lowpart. */
5728 if (GET_MODE (operands[0]) != Pmode)
5729 {
5730 operands[1] = gen_lowpart (Pmode, operands[1]);
5731 operands[2] = gen_lowpart (Pmode, operands[2]);
5732 }
5733 operands[0] = gen_lowpart (SImode, operands[0]);
5734 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5735 if (Pmode != SImode)
5736 pat = gen_rtx_SUBREG (SImode, pat, 0);
5737 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5738 DONE;
5739 })
5740
5741 ;; It may seem that nonimmediate operand is proper one for operand 1.
5742 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5743 ;; we take care in ix86_binary_operator_ok to not allow two memory
5744 ;; operands so proper swapping will be done in reload. This allow
5745 ;; patterns constructed from addsi_1 to match.
5746 (define_insn "addsi_1_zext"
5747 [(set (match_operand:DI 0 "register_operand" "=r,r")
5748 (zero_extend:DI
5749 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5750 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5751 (clobber (reg:CC FLAGS_REG))]
5752 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5753 {
5754 switch (get_attr_type (insn))
5755 {
5756 case TYPE_LEA:
5757 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5758 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5759
5760 case TYPE_INCDEC:
5761 if (operands[2] == const1_rtx)
5762 return "inc{l}\t%k0";
5763 else
5764 {
5765 gcc_assert (operands[2] == constm1_rtx);
5766 return "dec{l}\t%k0";
5767 }
5768
5769 default:
5770 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5771 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5772 if (CONST_INT_P (operands[2])
5773 && (INTVAL (operands[2]) == 128
5774 || (INTVAL (operands[2]) < 0
5775 && INTVAL (operands[2]) != -128)))
5776 {
5777 operands[2] = GEN_INT (-INTVAL (operands[2]));
5778 return "sub{l}\t{%2, %k0|%k0, %2}";
5779 }
5780 return "add{l}\t{%2, %k0|%k0, %2}";
5781 }
5782 }
5783 [(set (attr "type")
5784 (cond [(eq_attr "alternative" "1")
5785 (const_string "lea")
5786 ; Current assemblers are broken and do not allow @GOTOFF in
5787 ; ought but a memory context.
5788 (match_operand:SI 2 "pic_symbolic_operand" "")
5789 (const_string "lea")
5790 (match_operand:SI 2 "incdec_operand" "")
5791 (const_string "incdec")
5792 ]
5793 (const_string "alu")))
5794 (set_attr "mode" "SI")])
5795
5796 ;; Convert lea to the lea pattern to avoid flags dependency.
5797 (define_split
5798 [(set (match_operand:DI 0 "register_operand" "")
5799 (zero_extend:DI
5800 (plus:SI (match_operand:SI 1 "register_operand" "")
5801 (match_operand:SI 2 "nonmemory_operand" ""))))
5802 (clobber (reg:CC FLAGS_REG))]
5803 "TARGET_64BIT && reload_completed
5804 && true_regnum (operands[0]) != true_regnum (operands[1])"
5805 [(set (match_dup 0)
5806 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5807 {
5808 operands[1] = gen_lowpart (Pmode, operands[1]);
5809 operands[2] = gen_lowpart (Pmode, operands[2]);
5810 })
5811
5812 (define_insn "*addsi_2"
5813 [(set (reg FLAGS_REG)
5814 (compare
5815 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5816 (match_operand:SI 2 "general_operand" "rmni,rni"))
5817 (const_int 0)))
5818 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5819 (plus:SI (match_dup 1) (match_dup 2)))]
5820 "ix86_match_ccmode (insn, CCGOCmode)
5821 && ix86_binary_operator_ok (PLUS, SImode, operands)
5822 /* Current assemblers are broken and do not allow @GOTOFF in
5823 ought but a memory context. */
5824 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5825 {
5826 switch (get_attr_type (insn))
5827 {
5828 case TYPE_INCDEC:
5829 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5830 if (operands[2] == const1_rtx)
5831 return "inc{l}\t%0";
5832 else
5833 {
5834 gcc_assert (operands[2] == constm1_rtx);
5835 return "dec{l}\t%0";
5836 }
5837
5838 default:
5839 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5840 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5841 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5842 if (CONST_INT_P (operands[2])
5843 && (INTVAL (operands[2]) == 128
5844 || (INTVAL (operands[2]) < 0
5845 && INTVAL (operands[2]) != -128)))
5846 {
5847 operands[2] = GEN_INT (-INTVAL (operands[2]));
5848 return "sub{l}\t{%2, %0|%0, %2}";
5849 }
5850 return "add{l}\t{%2, %0|%0, %2}";
5851 }
5852 }
5853 [(set (attr "type")
5854 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5855 (const_string "incdec")
5856 (const_string "alu")))
5857 (set_attr "mode" "SI")])
5858
5859 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5860 (define_insn "*addsi_2_zext"
5861 [(set (reg FLAGS_REG)
5862 (compare
5863 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5864 (match_operand:SI 2 "general_operand" "rmni"))
5865 (const_int 0)))
5866 (set (match_operand:DI 0 "register_operand" "=r")
5867 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5868 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5869 && ix86_binary_operator_ok (PLUS, SImode, operands)
5870 /* Current assemblers are broken and do not allow @GOTOFF in
5871 ought but a memory context. */
5872 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5873 {
5874 switch (get_attr_type (insn))
5875 {
5876 case TYPE_INCDEC:
5877 if (operands[2] == const1_rtx)
5878 return "inc{l}\t%k0";
5879 else
5880 {
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{l}\t%k0";
5883 }
5884
5885 default:
5886 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5887 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5888 if (CONST_INT_P (operands[2])
5889 && (INTVAL (operands[2]) == 128
5890 || (INTVAL (operands[2]) < 0
5891 && INTVAL (operands[2]) != -128)))
5892 {
5893 operands[2] = GEN_INT (-INTVAL (operands[2]));
5894 return "sub{l}\t{%2, %k0|%k0, %2}";
5895 }
5896 return "add{l}\t{%2, %k0|%k0, %2}";
5897 }
5898 }
5899 [(set (attr "type")
5900 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set_attr "mode" "SI")])
5904
5905 (define_insn "*addsi_3"
5906 [(set (reg FLAGS_REG)
5907 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5908 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5909 (clobber (match_scratch:SI 0 "=r"))]
5910 "ix86_match_ccmode (insn, CCZmode)
5911 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5912 /* Current assemblers are broken and do not allow @GOTOFF in
5913 ought but a memory context. */
5914 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5915 {
5916 switch (get_attr_type (insn))
5917 {
5918 case TYPE_INCDEC:
5919 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5920 if (operands[2] == const1_rtx)
5921 return "inc{l}\t%0";
5922 else
5923 {
5924 gcc_assert (operands[2] == constm1_rtx);
5925 return "dec{l}\t%0";
5926 }
5927
5928 default:
5929 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5930 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5931 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5932 if (CONST_INT_P (operands[2])
5933 && (INTVAL (operands[2]) == 128
5934 || (INTVAL (operands[2]) < 0
5935 && INTVAL (operands[2]) != -128)))
5936 {
5937 operands[2] = GEN_INT (-INTVAL (operands[2]));
5938 return "sub{l}\t{%2, %0|%0, %2}";
5939 }
5940 return "add{l}\t{%2, %0|%0, %2}";
5941 }
5942 }
5943 [(set (attr "type")
5944 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5945 (const_string "incdec")
5946 (const_string "alu")))
5947 (set_attr "mode" "SI")])
5948
5949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5950 (define_insn "*addsi_3_zext"
5951 [(set (reg FLAGS_REG)
5952 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5953 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5954 (set (match_operand:DI 0 "register_operand" "=r")
5955 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5956 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5957 && ix86_binary_operator_ok (PLUS, SImode, operands)
5958 /* Current assemblers are broken and do not allow @GOTOFF in
5959 ought but a memory context. */
5960 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5961 {
5962 switch (get_attr_type (insn))
5963 {
5964 case TYPE_INCDEC:
5965 if (operands[2] == const1_rtx)
5966 return "inc{l}\t%k0";
5967 else
5968 {
5969 gcc_assert (operands[2] == constm1_rtx);
5970 return "dec{l}\t%k0";
5971 }
5972
5973 default:
5974 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5975 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5976 if (CONST_INT_P (operands[2])
5977 && (INTVAL (operands[2]) == 128
5978 || (INTVAL (operands[2]) < 0
5979 && INTVAL (operands[2]) != -128)))
5980 {
5981 operands[2] = GEN_INT (-INTVAL (operands[2]));
5982 return "sub{l}\t{%2, %k0|%k0, %2}";
5983 }
5984 return "add{l}\t{%2, %k0|%k0, %2}";
5985 }
5986 }
5987 [(set (attr "type")
5988 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5989 (const_string "incdec")
5990 (const_string "alu")))
5991 (set_attr "mode" "SI")])
5992
5993 ; For comparisons against 1, -1 and 128, we may generate better code
5994 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5995 ; is matched then. We can't accept general immediate, because for
5996 ; case of overflows, the result is messed up.
5997 ; This pattern also don't hold of 0x80000000, since the value overflows
5998 ; when negated.
5999 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6000 ; only for comparisons not depending on it.
6001 (define_insn "*addsi_4"
6002 [(set (reg FLAGS_REG)
6003 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6004 (match_operand:SI 2 "const_int_operand" "n")))
6005 (clobber (match_scratch:SI 0 "=rm"))]
6006 "ix86_match_ccmode (insn, CCGCmode)
6007 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6008 {
6009 switch (get_attr_type (insn))
6010 {
6011 case TYPE_INCDEC:
6012 if (operands[2] == constm1_rtx)
6013 return "inc{l}\t%0";
6014 else
6015 {
6016 gcc_assert (operands[2] == const1_rtx);
6017 return "dec{l}\t%0";
6018 }
6019
6020 default:
6021 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6022 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6023 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6024 if ((INTVAL (operands[2]) == -128
6025 || (INTVAL (operands[2]) > 0
6026 && INTVAL (operands[2]) != 128)))
6027 return "sub{l}\t{%2, %0|%0, %2}";
6028 operands[2] = GEN_INT (-INTVAL (operands[2]));
6029 return "add{l}\t{%2, %0|%0, %2}";
6030 }
6031 }
6032 [(set (attr "type")
6033 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6034 (const_string "incdec")
6035 (const_string "alu")))
6036 (set_attr "mode" "SI")])
6037
6038 (define_insn "*addsi_5"
6039 [(set (reg FLAGS_REG)
6040 (compare
6041 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6042 (match_operand:SI 2 "general_operand" "rmni"))
6043 (const_int 0)))
6044 (clobber (match_scratch:SI 0 "=r"))]
6045 "ix86_match_ccmode (insn, CCGOCmode)
6046 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6047 /* Current assemblers are broken and do not allow @GOTOFF in
6048 ought but a memory context. */
6049 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6050 {
6051 switch (get_attr_type (insn))
6052 {
6053 case TYPE_INCDEC:
6054 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6055 if (operands[2] == const1_rtx)
6056 return "inc{l}\t%0";
6057 else
6058 {
6059 gcc_assert (operands[2] == constm1_rtx);
6060 return "dec{l}\t%0";
6061 }
6062
6063 default:
6064 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6065 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6066 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6067 if (CONST_INT_P (operands[2])
6068 && (INTVAL (operands[2]) == 128
6069 || (INTVAL (operands[2]) < 0
6070 && INTVAL (operands[2]) != -128)))
6071 {
6072 operands[2] = GEN_INT (-INTVAL (operands[2]));
6073 return "sub{l}\t{%2, %0|%0, %2}";
6074 }
6075 return "add{l}\t{%2, %0|%0, %2}";
6076 }
6077 }
6078 [(set (attr "type")
6079 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6080 (const_string "incdec")
6081 (const_string "alu")))
6082 (set_attr "mode" "SI")])
6083
6084 (define_expand "addhi3"
6085 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6086 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6087 (match_operand:HI 2 "general_operand" "")))
6088 (clobber (reg:CC FLAGS_REG))])]
6089 "TARGET_HIMODE_MATH"
6090 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6091
6092 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6093 ;; type optimizations enabled by define-splits. This is not important
6094 ;; for PII, and in fact harmful because of partial register stalls.
6095
6096 (define_insn "*addhi_1_lea"
6097 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6098 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6099 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6100 (clobber (reg:CC FLAGS_REG))]
6101 "!TARGET_PARTIAL_REG_STALL
6102 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6103 {
6104 switch (get_attr_type (insn))
6105 {
6106 case TYPE_LEA:
6107 return "#";
6108 case TYPE_INCDEC:
6109 if (operands[2] == const1_rtx)
6110 return "inc{w}\t%0";
6111 else
6112 {
6113 gcc_assert (operands[2] == constm1_rtx);
6114 return "dec{w}\t%0";
6115 }
6116
6117 default:
6118 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6119 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6120 if (CONST_INT_P (operands[2])
6121 && (INTVAL (operands[2]) == 128
6122 || (INTVAL (operands[2]) < 0
6123 && INTVAL (operands[2]) != -128)))
6124 {
6125 operands[2] = GEN_INT (-INTVAL (operands[2]));
6126 return "sub{w}\t{%2, %0|%0, %2}";
6127 }
6128 return "add{w}\t{%2, %0|%0, %2}";
6129 }
6130 }
6131 [(set (attr "type")
6132 (if_then_else (eq_attr "alternative" "2")
6133 (const_string "lea")
6134 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6135 (const_string "incdec")
6136 (const_string "alu"))))
6137 (set_attr "mode" "HI,HI,SI")])
6138
6139 (define_insn "*addhi_1"
6140 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6141 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6142 (match_operand:HI 2 "general_operand" "ri,rm")))
6143 (clobber (reg:CC FLAGS_REG))]
6144 "TARGET_PARTIAL_REG_STALL
6145 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6146 {
6147 switch (get_attr_type (insn))
6148 {
6149 case TYPE_INCDEC:
6150 if (operands[2] == const1_rtx)
6151 return "inc{w}\t%0";
6152 else
6153 {
6154 gcc_assert (operands[2] == constm1_rtx);
6155 return "dec{w}\t%0";
6156 }
6157
6158 default:
6159 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6160 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6161 if (CONST_INT_P (operands[2])
6162 && (INTVAL (operands[2]) == 128
6163 || (INTVAL (operands[2]) < 0
6164 && INTVAL (operands[2]) != -128)))
6165 {
6166 operands[2] = GEN_INT (-INTVAL (operands[2]));
6167 return "sub{w}\t{%2, %0|%0, %2}";
6168 }
6169 return "add{w}\t{%2, %0|%0, %2}";
6170 }
6171 }
6172 [(set (attr "type")
6173 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6174 (const_string "incdec")
6175 (const_string "alu")))
6176 (set_attr "mode" "HI")])
6177
6178 (define_insn "*addhi_2"
6179 [(set (reg FLAGS_REG)
6180 (compare
6181 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6182 (match_operand:HI 2 "general_operand" "rmni,rni"))
6183 (const_int 0)))
6184 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6185 (plus:HI (match_dup 1) (match_dup 2)))]
6186 "ix86_match_ccmode (insn, CCGOCmode)
6187 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6188 {
6189 switch (get_attr_type (insn))
6190 {
6191 case TYPE_INCDEC:
6192 if (operands[2] == const1_rtx)
6193 return "inc{w}\t%0";
6194 else
6195 {
6196 gcc_assert (operands[2] == constm1_rtx);
6197 return "dec{w}\t%0";
6198 }
6199
6200 default:
6201 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6202 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6203 if (CONST_INT_P (operands[2])
6204 && (INTVAL (operands[2]) == 128
6205 || (INTVAL (operands[2]) < 0
6206 && INTVAL (operands[2]) != -128)))
6207 {
6208 operands[2] = GEN_INT (-INTVAL (operands[2]));
6209 return "sub{w}\t{%2, %0|%0, %2}";
6210 }
6211 return "add{w}\t{%2, %0|%0, %2}";
6212 }
6213 }
6214 [(set (attr "type")
6215 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6216 (const_string "incdec")
6217 (const_string "alu")))
6218 (set_attr "mode" "HI")])
6219
6220 (define_insn "*addhi_3"
6221 [(set (reg FLAGS_REG)
6222 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6223 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6224 (clobber (match_scratch:HI 0 "=r"))]
6225 "ix86_match_ccmode (insn, CCZmode)
6226 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6227 {
6228 switch (get_attr_type (insn))
6229 {
6230 case TYPE_INCDEC:
6231 if (operands[2] == const1_rtx)
6232 return "inc{w}\t%0";
6233 else
6234 {
6235 gcc_assert (operands[2] == constm1_rtx);
6236 return "dec{w}\t%0";
6237 }
6238
6239 default:
6240 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6241 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6242 if (CONST_INT_P (operands[2])
6243 && (INTVAL (operands[2]) == 128
6244 || (INTVAL (operands[2]) < 0
6245 && INTVAL (operands[2]) != -128)))
6246 {
6247 operands[2] = GEN_INT (-INTVAL (operands[2]));
6248 return "sub{w}\t{%2, %0|%0, %2}";
6249 }
6250 return "add{w}\t{%2, %0|%0, %2}";
6251 }
6252 }
6253 [(set (attr "type")
6254 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6255 (const_string "incdec")
6256 (const_string "alu")))
6257 (set_attr "mode" "HI")])
6258
6259 ; See comments above addsi_4 for details.
6260 (define_insn "*addhi_4"
6261 [(set (reg FLAGS_REG)
6262 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6263 (match_operand:HI 2 "const_int_operand" "n")))
6264 (clobber (match_scratch:HI 0 "=rm"))]
6265 "ix86_match_ccmode (insn, CCGCmode)
6266 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6267 {
6268 switch (get_attr_type (insn))
6269 {
6270 case TYPE_INCDEC:
6271 if (operands[2] == constm1_rtx)
6272 return "inc{w}\t%0";
6273 else
6274 {
6275 gcc_assert (operands[2] == const1_rtx);
6276 return "dec{w}\t%0";
6277 }
6278
6279 default:
6280 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6281 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6282 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6283 if ((INTVAL (operands[2]) == -128
6284 || (INTVAL (operands[2]) > 0
6285 && INTVAL (operands[2]) != 128)))
6286 return "sub{w}\t{%2, %0|%0, %2}";
6287 operands[2] = GEN_INT (-INTVAL (operands[2]));
6288 return "add{w}\t{%2, %0|%0, %2}";
6289 }
6290 }
6291 [(set (attr "type")
6292 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6293 (const_string "incdec")
6294 (const_string "alu")))
6295 (set_attr "mode" "SI")])
6296
6297
6298 (define_insn "*addhi_5"
6299 [(set (reg FLAGS_REG)
6300 (compare
6301 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6302 (match_operand:HI 2 "general_operand" "rmni"))
6303 (const_int 0)))
6304 (clobber (match_scratch:HI 0 "=r"))]
6305 "ix86_match_ccmode (insn, CCGOCmode)
6306 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6307 {
6308 switch (get_attr_type (insn))
6309 {
6310 case TYPE_INCDEC:
6311 if (operands[2] == const1_rtx)
6312 return "inc{w}\t%0";
6313 else
6314 {
6315 gcc_assert (operands[2] == constm1_rtx);
6316 return "dec{w}\t%0";
6317 }
6318
6319 default:
6320 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6321 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6322 if (CONST_INT_P (operands[2])
6323 && (INTVAL (operands[2]) == 128
6324 || (INTVAL (operands[2]) < 0
6325 && INTVAL (operands[2]) != -128)))
6326 {
6327 operands[2] = GEN_INT (-INTVAL (operands[2]));
6328 return "sub{w}\t{%2, %0|%0, %2}";
6329 }
6330 return "add{w}\t{%2, %0|%0, %2}";
6331 }
6332 }
6333 [(set (attr "type")
6334 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6335 (const_string "incdec")
6336 (const_string "alu")))
6337 (set_attr "mode" "HI")])
6338
6339 (define_expand "addqi3"
6340 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6341 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6342 (match_operand:QI 2 "general_operand" "")))
6343 (clobber (reg:CC FLAGS_REG))])]
6344 "TARGET_QIMODE_MATH"
6345 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6346
6347 ;; %%% Potential partial reg stall on alternative 2. What to do?
6348 (define_insn "*addqi_1_lea"
6349 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6350 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6351 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6352 (clobber (reg:CC FLAGS_REG))]
6353 "!TARGET_PARTIAL_REG_STALL
6354 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6355 {
6356 int widen = (which_alternative == 2);
6357 switch (get_attr_type (insn))
6358 {
6359 case TYPE_LEA:
6360 return "#";
6361 case TYPE_INCDEC:
6362 if (operands[2] == const1_rtx)
6363 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6364 else
6365 {
6366 gcc_assert (operands[2] == constm1_rtx);
6367 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6368 }
6369
6370 default:
6371 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6372 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6373 if (CONST_INT_P (operands[2])
6374 && (INTVAL (operands[2]) == 128
6375 || (INTVAL (operands[2]) < 0
6376 && INTVAL (operands[2]) != -128)))
6377 {
6378 operands[2] = GEN_INT (-INTVAL (operands[2]));
6379 if (widen)
6380 return "sub{l}\t{%2, %k0|%k0, %2}";
6381 else
6382 return "sub{b}\t{%2, %0|%0, %2}";
6383 }
6384 if (widen)
6385 return "add{l}\t{%k2, %k0|%k0, %k2}";
6386 else
6387 return "add{b}\t{%2, %0|%0, %2}";
6388 }
6389 }
6390 [(set (attr "type")
6391 (if_then_else (eq_attr "alternative" "3")
6392 (const_string "lea")
6393 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6394 (const_string "incdec")
6395 (const_string "alu"))))
6396 (set_attr "mode" "QI,QI,SI,SI")])
6397
6398 (define_insn "*addqi_1"
6399 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6400 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6401 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6402 (clobber (reg:CC FLAGS_REG))]
6403 "TARGET_PARTIAL_REG_STALL
6404 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6405 {
6406 int widen = (which_alternative == 2);
6407 switch (get_attr_type (insn))
6408 {
6409 case TYPE_INCDEC:
6410 if (operands[2] == const1_rtx)
6411 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6412 else
6413 {
6414 gcc_assert (operands[2] == constm1_rtx);
6415 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6416 }
6417
6418 default:
6419 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6420 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6421 if (CONST_INT_P (operands[2])
6422 && (INTVAL (operands[2]) == 128
6423 || (INTVAL (operands[2]) < 0
6424 && INTVAL (operands[2]) != -128)))
6425 {
6426 operands[2] = GEN_INT (-INTVAL (operands[2]));
6427 if (widen)
6428 return "sub{l}\t{%2, %k0|%k0, %2}";
6429 else
6430 return "sub{b}\t{%2, %0|%0, %2}";
6431 }
6432 if (widen)
6433 return "add{l}\t{%k2, %k0|%k0, %k2}";
6434 else
6435 return "add{b}\t{%2, %0|%0, %2}";
6436 }
6437 }
6438 [(set (attr "type")
6439 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6440 (const_string "incdec")
6441 (const_string "alu")))
6442 (set_attr "mode" "QI,QI,SI")])
6443
6444 (define_insn "*addqi_1_slp"
6445 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6446 (plus:QI (match_dup 0)
6447 (match_operand:QI 1 "general_operand" "qn,qnm")))
6448 (clobber (reg:CC FLAGS_REG))]
6449 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6450 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6451 {
6452 switch (get_attr_type (insn))
6453 {
6454 case TYPE_INCDEC:
6455 if (operands[1] == const1_rtx)
6456 return "inc{b}\t%0";
6457 else
6458 {
6459 gcc_assert (operands[1] == constm1_rtx);
6460 return "dec{b}\t%0";
6461 }
6462
6463 default:
6464 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6465 if (CONST_INT_P (operands[1])
6466 && INTVAL (operands[1]) < 0)
6467 {
6468 operands[1] = GEN_INT (-INTVAL (operands[1]));
6469 return "sub{b}\t{%1, %0|%0, %1}";
6470 }
6471 return "add{b}\t{%1, %0|%0, %1}";
6472 }
6473 }
6474 [(set (attr "type")
6475 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6476 (const_string "incdec")
6477 (const_string "alu1")))
6478 (set (attr "memory")
6479 (if_then_else (match_operand 1 "memory_operand" "")
6480 (const_string "load")
6481 (const_string "none")))
6482 (set_attr "mode" "QI")])
6483
6484 (define_insn "*addqi_2"
6485 [(set (reg FLAGS_REG)
6486 (compare
6487 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6488 (match_operand:QI 2 "general_operand" "qmni,qni"))
6489 (const_int 0)))
6490 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6491 (plus:QI (match_dup 1) (match_dup 2)))]
6492 "ix86_match_ccmode (insn, CCGOCmode)
6493 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6494 {
6495 switch (get_attr_type (insn))
6496 {
6497 case TYPE_INCDEC:
6498 if (operands[2] == const1_rtx)
6499 return "inc{b}\t%0";
6500 else
6501 {
6502 gcc_assert (operands[2] == constm1_rtx
6503 || (CONST_INT_P (operands[2])
6504 && INTVAL (operands[2]) == 255));
6505 return "dec{b}\t%0";
6506 }
6507
6508 default:
6509 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6510 if (CONST_INT_P (operands[2])
6511 && INTVAL (operands[2]) < 0)
6512 {
6513 operands[2] = GEN_INT (-INTVAL (operands[2]));
6514 return "sub{b}\t{%2, %0|%0, %2}";
6515 }
6516 return "add{b}\t{%2, %0|%0, %2}";
6517 }
6518 }
6519 [(set (attr "type")
6520 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6521 (const_string "incdec")
6522 (const_string "alu")))
6523 (set_attr "mode" "QI")])
6524
6525 (define_insn "*addqi_3"
6526 [(set (reg FLAGS_REG)
6527 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6528 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6529 (clobber (match_scratch:QI 0 "=q"))]
6530 "ix86_match_ccmode (insn, CCZmode)
6531 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6532 {
6533 switch (get_attr_type (insn))
6534 {
6535 case TYPE_INCDEC:
6536 if (operands[2] == const1_rtx)
6537 return "inc{b}\t%0";
6538 else
6539 {
6540 gcc_assert (operands[2] == constm1_rtx
6541 || (CONST_INT_P (operands[2])
6542 && INTVAL (operands[2]) == 255));
6543 return "dec{b}\t%0";
6544 }
6545
6546 default:
6547 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6548 if (CONST_INT_P (operands[2])
6549 && INTVAL (operands[2]) < 0)
6550 {
6551 operands[2] = GEN_INT (-INTVAL (operands[2]));
6552 return "sub{b}\t{%2, %0|%0, %2}";
6553 }
6554 return "add{b}\t{%2, %0|%0, %2}";
6555 }
6556 }
6557 [(set (attr "type")
6558 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6559 (const_string "incdec")
6560 (const_string "alu")))
6561 (set_attr "mode" "QI")])
6562
6563 ; See comments above addsi_4 for details.
6564 (define_insn "*addqi_4"
6565 [(set (reg FLAGS_REG)
6566 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6567 (match_operand:QI 2 "const_int_operand" "n")))
6568 (clobber (match_scratch:QI 0 "=qm"))]
6569 "ix86_match_ccmode (insn, CCGCmode)
6570 && (INTVAL (operands[2]) & 0xff) != 0x80"
6571 {
6572 switch (get_attr_type (insn))
6573 {
6574 case TYPE_INCDEC:
6575 if (operands[2] == constm1_rtx
6576 || (CONST_INT_P (operands[2])
6577 && INTVAL (operands[2]) == 255))
6578 return "inc{b}\t%0";
6579 else
6580 {
6581 gcc_assert (operands[2] == const1_rtx);
6582 return "dec{b}\t%0";
6583 }
6584
6585 default:
6586 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6587 if (INTVAL (operands[2]) < 0)
6588 {
6589 operands[2] = GEN_INT (-INTVAL (operands[2]));
6590 return "add{b}\t{%2, %0|%0, %2}";
6591 }
6592 return "sub{b}\t{%2, %0|%0, %2}";
6593 }
6594 }
6595 [(set (attr "type")
6596 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6597 (const_string "incdec")
6598 (const_string "alu")))
6599 (set_attr "mode" "QI")])
6600
6601
6602 (define_insn "*addqi_5"
6603 [(set (reg FLAGS_REG)
6604 (compare
6605 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6606 (match_operand:QI 2 "general_operand" "qmni"))
6607 (const_int 0)))
6608 (clobber (match_scratch:QI 0 "=q"))]
6609 "ix86_match_ccmode (insn, CCGOCmode)
6610 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6611 {
6612 switch (get_attr_type (insn))
6613 {
6614 case TYPE_INCDEC:
6615 if (operands[2] == const1_rtx)
6616 return "inc{b}\t%0";
6617 else
6618 {
6619 gcc_assert (operands[2] == constm1_rtx
6620 || (CONST_INT_P (operands[2])
6621 && INTVAL (operands[2]) == 255));
6622 return "dec{b}\t%0";
6623 }
6624
6625 default:
6626 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6627 if (CONST_INT_P (operands[2])
6628 && INTVAL (operands[2]) < 0)
6629 {
6630 operands[2] = GEN_INT (-INTVAL (operands[2]));
6631 return "sub{b}\t{%2, %0|%0, %2}";
6632 }
6633 return "add{b}\t{%2, %0|%0, %2}";
6634 }
6635 }
6636 [(set (attr "type")
6637 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6638 (const_string "incdec")
6639 (const_string "alu")))
6640 (set_attr "mode" "QI")])
6641
6642
6643 (define_insn "addqi_ext_1"
6644 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6645 (const_int 8)
6646 (const_int 8))
6647 (plus:SI
6648 (zero_extract:SI
6649 (match_operand 1 "ext_register_operand" "0")
6650 (const_int 8)
6651 (const_int 8))
6652 (match_operand:QI 2 "general_operand" "Qmn")))
6653 (clobber (reg:CC FLAGS_REG))]
6654 "!TARGET_64BIT"
6655 {
6656 switch (get_attr_type (insn))
6657 {
6658 case TYPE_INCDEC:
6659 if (operands[2] == const1_rtx)
6660 return "inc{b}\t%h0";
6661 else
6662 {
6663 gcc_assert (operands[2] == constm1_rtx
6664 || (CONST_INT_P (operands[2])
6665 && INTVAL (operands[2]) == 255));
6666 return "dec{b}\t%h0";
6667 }
6668
6669 default:
6670 return "add{b}\t{%2, %h0|%h0, %2}";
6671 }
6672 }
6673 [(set (attr "type")
6674 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6675 (const_string "incdec")
6676 (const_string "alu")))
6677 (set_attr "mode" "QI")])
6678
6679 (define_insn "*addqi_ext_1_rex64"
6680 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6681 (const_int 8)
6682 (const_int 8))
6683 (plus:SI
6684 (zero_extract:SI
6685 (match_operand 1 "ext_register_operand" "0")
6686 (const_int 8)
6687 (const_int 8))
6688 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6689 (clobber (reg:CC FLAGS_REG))]
6690 "TARGET_64BIT"
6691 {
6692 switch (get_attr_type (insn))
6693 {
6694 case TYPE_INCDEC:
6695 if (operands[2] == const1_rtx)
6696 return "inc{b}\t%h0";
6697 else
6698 {
6699 gcc_assert (operands[2] == constm1_rtx
6700 || (CONST_INT_P (operands[2])
6701 && INTVAL (operands[2]) == 255));
6702 return "dec{b}\t%h0";
6703 }
6704
6705 default:
6706 return "add{b}\t{%2, %h0|%h0, %2}";
6707 }
6708 }
6709 [(set (attr "type")
6710 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6711 (const_string "incdec")
6712 (const_string "alu")))
6713 (set_attr "mode" "QI")])
6714
6715 (define_insn "*addqi_ext_2"
6716 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6717 (const_int 8)
6718 (const_int 8))
6719 (plus:SI
6720 (zero_extract:SI
6721 (match_operand 1 "ext_register_operand" "%0")
6722 (const_int 8)
6723 (const_int 8))
6724 (zero_extract:SI
6725 (match_operand 2 "ext_register_operand" "Q")
6726 (const_int 8)
6727 (const_int 8))))
6728 (clobber (reg:CC FLAGS_REG))]
6729 ""
6730 "add{b}\t{%h2, %h0|%h0, %h2}"
6731 [(set_attr "type" "alu")
6732 (set_attr "mode" "QI")])
6733
6734 ;; The patterns that match these are at the end of this file.
6735
6736 (define_expand "addxf3"
6737 [(set (match_operand:XF 0 "register_operand" "")
6738 (plus:XF (match_operand:XF 1 "register_operand" "")
6739 (match_operand:XF 2 "register_operand" "")))]
6740 "TARGET_80387"
6741 "")
6742
6743 (define_expand "adddf3"
6744 [(set (match_operand:DF 0 "register_operand" "")
6745 (plus:DF (match_operand:DF 1 "register_operand" "")
6746 (match_operand:DF 2 "nonimmediate_operand" "")))]
6747 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6748 "")
6749
6750 (define_expand "addsf3"
6751 [(set (match_operand:SF 0 "register_operand" "")
6752 (plus:SF (match_operand:SF 1 "register_operand" "")
6753 (match_operand:SF 2 "nonimmediate_operand" "")))]
6754 "TARGET_80387 || TARGET_SSE_MATH"
6755 "")
6756 \f
6757 ;; Subtract instructions
6758
6759 ;; %%% splits for subditi3
6760
6761 (define_expand "subti3"
6762 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6763 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6764 (match_operand:TI 2 "x86_64_general_operand" "")))
6765 (clobber (reg:CC FLAGS_REG))])]
6766 "TARGET_64BIT"
6767 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6768
6769 (define_insn "*subti3_1"
6770 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6771 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6772 (match_operand:TI 2 "general_operand" "roiF,riF")))
6773 (clobber (reg:CC FLAGS_REG))]
6774 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6775 "#")
6776
6777 (define_split
6778 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6779 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6780 (match_operand:TI 2 "general_operand" "")))
6781 (clobber (reg:CC FLAGS_REG))]
6782 "TARGET_64BIT && reload_completed"
6783 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6784 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6785 (parallel [(set (match_dup 3)
6786 (minus:DI (match_dup 4)
6787 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6788 (match_dup 5))))
6789 (clobber (reg:CC FLAGS_REG))])]
6790 "split_ti (operands+0, 1, operands+0, operands+3);
6791 split_ti (operands+1, 1, operands+1, operands+4);
6792 split_ti (operands+2, 1, operands+2, operands+5);")
6793
6794 ;; %%% splits for subsidi3
6795
6796 (define_expand "subdi3"
6797 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6798 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6799 (match_operand:DI 2 "x86_64_general_operand" "")))
6800 (clobber (reg:CC FLAGS_REG))])]
6801 ""
6802 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6803
6804 (define_insn "*subdi3_1"
6805 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6806 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6807 (match_operand:DI 2 "general_operand" "roiF,riF")))
6808 (clobber (reg:CC FLAGS_REG))]
6809 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6810 "#")
6811
6812 (define_split
6813 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6814 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6815 (match_operand:DI 2 "general_operand" "")))
6816 (clobber (reg:CC FLAGS_REG))]
6817 "!TARGET_64BIT && reload_completed"
6818 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6819 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6820 (parallel [(set (match_dup 3)
6821 (minus:SI (match_dup 4)
6822 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6823 (match_dup 5))))
6824 (clobber (reg:CC FLAGS_REG))])]
6825 "split_di (operands+0, 1, operands+0, operands+3);
6826 split_di (operands+1, 1, operands+1, operands+4);
6827 split_di (operands+2, 1, operands+2, operands+5);")
6828
6829 (define_insn "subdi3_carry_rex64"
6830 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6831 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6832 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6833 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6834 (clobber (reg:CC FLAGS_REG))]
6835 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6836 "sbb{q}\t{%2, %0|%0, %2}"
6837 [(set_attr "type" "alu")
6838 (set_attr "pent_pair" "pu")
6839 (set_attr "mode" "DI")])
6840
6841 (define_insn "*subdi_1_rex64"
6842 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6843 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6844 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6845 (clobber (reg:CC FLAGS_REG))]
6846 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6847 "sub{q}\t{%2, %0|%0, %2}"
6848 [(set_attr "type" "alu")
6849 (set_attr "mode" "DI")])
6850
6851 (define_insn "*subdi_2_rex64"
6852 [(set (reg FLAGS_REG)
6853 (compare
6854 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6855 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6856 (const_int 0)))
6857 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6858 (minus:DI (match_dup 1) (match_dup 2)))]
6859 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6860 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6861 "sub{q}\t{%2, %0|%0, %2}"
6862 [(set_attr "type" "alu")
6863 (set_attr "mode" "DI")])
6864
6865 (define_insn "*subdi_3_rex63"
6866 [(set (reg FLAGS_REG)
6867 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6868 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6869 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6870 (minus:DI (match_dup 1) (match_dup 2)))]
6871 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6872 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6873 "sub{q}\t{%2, %0|%0, %2}"
6874 [(set_attr "type" "alu")
6875 (set_attr "mode" "DI")])
6876
6877 (define_insn "subqi3_carry"
6878 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6879 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6880 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6881 (match_operand:QI 2 "general_operand" "qi,qm"))))
6882 (clobber (reg:CC FLAGS_REG))]
6883 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6884 "sbb{b}\t{%2, %0|%0, %2}"
6885 [(set_attr "type" "alu")
6886 (set_attr "pent_pair" "pu")
6887 (set_attr "mode" "QI")])
6888
6889 (define_insn "subhi3_carry"
6890 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6891 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6892 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6893 (match_operand:HI 2 "general_operand" "ri,rm"))))
6894 (clobber (reg:CC FLAGS_REG))]
6895 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6896 "sbb{w}\t{%2, %0|%0, %2}"
6897 [(set_attr "type" "alu")
6898 (set_attr "pent_pair" "pu")
6899 (set_attr "mode" "HI")])
6900
6901 (define_insn "subsi3_carry"
6902 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6903 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6904 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6905 (match_operand:SI 2 "general_operand" "ri,rm"))))
6906 (clobber (reg:CC FLAGS_REG))]
6907 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6908 "sbb{l}\t{%2, %0|%0, %2}"
6909 [(set_attr "type" "alu")
6910 (set_attr "pent_pair" "pu")
6911 (set_attr "mode" "SI")])
6912
6913 (define_insn "subsi3_carry_zext"
6914 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6915 (zero_extend:DI
6916 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6917 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6918 (match_operand:SI 2 "general_operand" "ri,rm")))))
6919 (clobber (reg:CC FLAGS_REG))]
6920 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6921 "sbb{l}\t{%2, %k0|%k0, %2}"
6922 [(set_attr "type" "alu")
6923 (set_attr "pent_pair" "pu")
6924 (set_attr "mode" "SI")])
6925
6926 (define_expand "subsi3"
6927 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6928 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6929 (match_operand:SI 2 "general_operand" "")))
6930 (clobber (reg:CC FLAGS_REG))])]
6931 ""
6932 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6933
6934 (define_insn "*subsi_1"
6935 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6936 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6937 (match_operand:SI 2 "general_operand" "ri,rm")))
6938 (clobber (reg:CC FLAGS_REG))]
6939 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6940 "sub{l}\t{%2, %0|%0, %2}"
6941 [(set_attr "type" "alu")
6942 (set_attr "mode" "SI")])
6943
6944 (define_insn "*subsi_1_zext"
6945 [(set (match_operand:DI 0 "register_operand" "=r")
6946 (zero_extend:DI
6947 (minus:SI (match_operand:SI 1 "register_operand" "0")
6948 (match_operand:SI 2 "general_operand" "rim"))))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6951 "sub{l}\t{%2, %k0|%k0, %2}"
6952 [(set_attr "type" "alu")
6953 (set_attr "mode" "SI")])
6954
6955 (define_insn "*subsi_2"
6956 [(set (reg FLAGS_REG)
6957 (compare
6958 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6959 (match_operand:SI 2 "general_operand" "ri,rm"))
6960 (const_int 0)))
6961 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6962 (minus:SI (match_dup 1) (match_dup 2)))]
6963 "ix86_match_ccmode (insn, CCGOCmode)
6964 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6965 "sub{l}\t{%2, %0|%0, %2}"
6966 [(set_attr "type" "alu")
6967 (set_attr "mode" "SI")])
6968
6969 (define_insn "*subsi_2_zext"
6970 [(set (reg FLAGS_REG)
6971 (compare
6972 (minus:SI (match_operand:SI 1 "register_operand" "0")
6973 (match_operand:SI 2 "general_operand" "rim"))
6974 (const_int 0)))
6975 (set (match_operand:DI 0 "register_operand" "=r")
6976 (zero_extend:DI
6977 (minus:SI (match_dup 1)
6978 (match_dup 2))))]
6979 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6980 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6981 "sub{l}\t{%2, %k0|%k0, %2}"
6982 [(set_attr "type" "alu")
6983 (set_attr "mode" "SI")])
6984
6985 (define_insn "*subsi_3"
6986 [(set (reg FLAGS_REG)
6987 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6988 (match_operand:SI 2 "general_operand" "ri,rm")))
6989 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6990 (minus:SI (match_dup 1) (match_dup 2)))]
6991 "ix86_match_ccmode (insn, CCmode)
6992 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6993 "sub{l}\t{%2, %0|%0, %2}"
6994 [(set_attr "type" "alu")
6995 (set_attr "mode" "SI")])
6996
6997 (define_insn "*subsi_3_zext"
6998 [(set (reg FLAGS_REG)
6999 (compare (match_operand:SI 1 "register_operand" "0")
7000 (match_operand:SI 2 "general_operand" "rim")))
7001 (set (match_operand:DI 0 "register_operand" "=r")
7002 (zero_extend:DI
7003 (minus:SI (match_dup 1)
7004 (match_dup 2))))]
7005 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7006 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7007 "sub{l}\t{%2, %1|%1, %2}"
7008 [(set_attr "type" "alu")
7009 (set_attr "mode" "DI")])
7010
7011 (define_expand "subhi3"
7012 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7013 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7014 (match_operand:HI 2 "general_operand" "")))
7015 (clobber (reg:CC FLAGS_REG))])]
7016 "TARGET_HIMODE_MATH"
7017 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7018
7019 (define_insn "*subhi_1"
7020 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7021 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7022 (match_operand:HI 2 "general_operand" "ri,rm")))
7023 (clobber (reg:CC FLAGS_REG))]
7024 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7025 "sub{w}\t{%2, %0|%0, %2}"
7026 [(set_attr "type" "alu")
7027 (set_attr "mode" "HI")])
7028
7029 (define_insn "*subhi_2"
7030 [(set (reg FLAGS_REG)
7031 (compare
7032 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7033 (match_operand:HI 2 "general_operand" "ri,rm"))
7034 (const_int 0)))
7035 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7036 (minus:HI (match_dup 1) (match_dup 2)))]
7037 "ix86_match_ccmode (insn, CCGOCmode)
7038 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7039 "sub{w}\t{%2, %0|%0, %2}"
7040 [(set_attr "type" "alu")
7041 (set_attr "mode" "HI")])
7042
7043 (define_insn "*subhi_3"
7044 [(set (reg FLAGS_REG)
7045 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7046 (match_operand:HI 2 "general_operand" "ri,rm")))
7047 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7048 (minus:HI (match_dup 1) (match_dup 2)))]
7049 "ix86_match_ccmode (insn, CCmode)
7050 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7051 "sub{w}\t{%2, %0|%0, %2}"
7052 [(set_attr "type" "alu")
7053 (set_attr "mode" "HI")])
7054
7055 (define_expand "subqi3"
7056 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7057 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7058 (match_operand:QI 2 "general_operand" "")))
7059 (clobber (reg:CC FLAGS_REG))])]
7060 "TARGET_QIMODE_MATH"
7061 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7062
7063 (define_insn "*subqi_1"
7064 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7065 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7066 (match_operand:QI 2 "general_operand" "qn,qmn")))
7067 (clobber (reg:CC FLAGS_REG))]
7068 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7069 "sub{b}\t{%2, %0|%0, %2}"
7070 [(set_attr "type" "alu")
7071 (set_attr "mode" "QI")])
7072
7073 (define_insn "*subqi_1_slp"
7074 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7075 (minus:QI (match_dup 0)
7076 (match_operand:QI 1 "general_operand" "qn,qmn")))
7077 (clobber (reg:CC FLAGS_REG))]
7078 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7079 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7080 "sub{b}\t{%1, %0|%0, %1}"
7081 [(set_attr "type" "alu1")
7082 (set_attr "mode" "QI")])
7083
7084 (define_insn "*subqi_2"
7085 [(set (reg FLAGS_REG)
7086 (compare
7087 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7088 (match_operand:QI 2 "general_operand" "qi,qm"))
7089 (const_int 0)))
7090 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7091 (minus:HI (match_dup 1) (match_dup 2)))]
7092 "ix86_match_ccmode (insn, CCGOCmode)
7093 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7094 "sub{b}\t{%2, %0|%0, %2}"
7095 [(set_attr "type" "alu")
7096 (set_attr "mode" "QI")])
7097
7098 (define_insn "*subqi_3"
7099 [(set (reg FLAGS_REG)
7100 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7101 (match_operand:QI 2 "general_operand" "qi,qm")))
7102 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7103 (minus:HI (match_dup 1) (match_dup 2)))]
7104 "ix86_match_ccmode (insn, CCmode)
7105 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7106 "sub{b}\t{%2, %0|%0, %2}"
7107 [(set_attr "type" "alu")
7108 (set_attr "mode" "QI")])
7109
7110 ;; The patterns that match these are at the end of this file.
7111
7112 (define_expand "subxf3"
7113 [(set (match_operand:XF 0 "register_operand" "")
7114 (minus:XF (match_operand:XF 1 "register_operand" "")
7115 (match_operand:XF 2 "register_operand" "")))]
7116 "TARGET_80387"
7117 "")
7118
7119 (define_expand "subdf3"
7120 [(set (match_operand:DF 0 "register_operand" "")
7121 (minus:DF (match_operand:DF 1 "register_operand" "")
7122 (match_operand:DF 2 "nonimmediate_operand" "")))]
7123 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7124 "")
7125
7126 (define_expand "subsf3"
7127 [(set (match_operand:SF 0 "register_operand" "")
7128 (minus:SF (match_operand:SF 1 "register_operand" "")
7129 (match_operand:SF 2 "nonimmediate_operand" "")))]
7130 "TARGET_80387 || TARGET_SSE_MATH"
7131 "")
7132 \f
7133 ;; Multiply instructions
7134
7135 (define_expand "muldi3"
7136 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7137 (mult:DI (match_operand:DI 1 "register_operand" "")
7138 (match_operand:DI 2 "x86_64_general_operand" "")))
7139 (clobber (reg:CC FLAGS_REG))])]
7140 "TARGET_64BIT"
7141 "")
7142
7143 ;; On AMDFAM10
7144 ;; IMUL reg64, reg64, imm8 Direct
7145 ;; IMUL reg64, mem64, imm8 VectorPath
7146 ;; IMUL reg64, reg64, imm32 Direct
7147 ;; IMUL reg64, mem64, imm32 VectorPath
7148 ;; IMUL reg64, reg64 Direct
7149 ;; IMUL reg64, mem64 Direct
7150
7151 (define_insn "*muldi3_1_rex64"
7152 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7153 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7154 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7155 (clobber (reg:CC FLAGS_REG))]
7156 "TARGET_64BIT
7157 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7158 "@
7159 imul{q}\t{%2, %1, %0|%0, %1, %2}
7160 imul{q}\t{%2, %1, %0|%0, %1, %2}
7161 imul{q}\t{%2, %0|%0, %2}"
7162 [(set_attr "type" "imul")
7163 (set_attr "prefix_0f" "0,0,1")
7164 (set (attr "athlon_decode")
7165 (cond [(eq_attr "cpu" "athlon")
7166 (const_string "vector")
7167 (eq_attr "alternative" "1")
7168 (const_string "vector")
7169 (and (eq_attr "alternative" "2")
7170 (match_operand 1 "memory_operand" ""))
7171 (const_string "vector")]
7172 (const_string "direct")))
7173 (set (attr "amdfam10_decode")
7174 (cond [(and (eq_attr "alternative" "0,1")
7175 (match_operand 1 "memory_operand" ""))
7176 (const_string "vector")]
7177 (const_string "direct")))
7178 (set_attr "mode" "DI")])
7179
7180 (define_expand "mulsi3"
7181 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7182 (mult:SI (match_operand:SI 1 "register_operand" "")
7183 (match_operand:SI 2 "general_operand" "")))
7184 (clobber (reg:CC FLAGS_REG))])]
7185 ""
7186 "")
7187
7188 ;; On AMDFAM10
7189 ;; IMUL reg32, reg32, imm8 Direct
7190 ;; IMUL reg32, mem32, imm8 VectorPath
7191 ;; IMUL reg32, reg32, imm32 Direct
7192 ;; IMUL reg32, mem32, imm32 VectorPath
7193 ;; IMUL reg32, reg32 Direct
7194 ;; IMUL reg32, mem32 Direct
7195
7196 (define_insn "*mulsi3_1"
7197 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7198 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7199 (match_operand:SI 2 "general_operand" "K,i,mr")))
7200 (clobber (reg:CC FLAGS_REG))]
7201 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7202 "@
7203 imul{l}\t{%2, %1, %0|%0, %1, %2}
7204 imul{l}\t{%2, %1, %0|%0, %1, %2}
7205 imul{l}\t{%2, %0|%0, %2}"
7206 [(set_attr "type" "imul")
7207 (set_attr "prefix_0f" "0,0,1")
7208 (set (attr "athlon_decode")
7209 (cond [(eq_attr "cpu" "athlon")
7210 (const_string "vector")
7211 (eq_attr "alternative" "1")
7212 (const_string "vector")
7213 (and (eq_attr "alternative" "2")
7214 (match_operand 1 "memory_operand" ""))
7215 (const_string "vector")]
7216 (const_string "direct")))
7217 (set (attr "amdfam10_decode")
7218 (cond [(and (eq_attr "alternative" "0,1")
7219 (match_operand 1 "memory_operand" ""))
7220 (const_string "vector")]
7221 (const_string "direct")))
7222 (set_attr "mode" "SI")])
7223
7224 (define_insn "*mulsi3_1_zext"
7225 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7226 (zero_extend:DI
7227 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7228 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7229 (clobber (reg:CC FLAGS_REG))]
7230 "TARGET_64BIT
7231 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7232 "@
7233 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7234 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7235 imul{l}\t{%2, %k0|%k0, %2}"
7236 [(set_attr "type" "imul")
7237 (set_attr "prefix_0f" "0,0,1")
7238 (set (attr "athlon_decode")
7239 (cond [(eq_attr "cpu" "athlon")
7240 (const_string "vector")
7241 (eq_attr "alternative" "1")
7242 (const_string "vector")
7243 (and (eq_attr "alternative" "2")
7244 (match_operand 1 "memory_operand" ""))
7245 (const_string "vector")]
7246 (const_string "direct")))
7247 (set (attr "amdfam10_decode")
7248 (cond [(and (eq_attr "alternative" "0,1")
7249 (match_operand 1 "memory_operand" ""))
7250 (const_string "vector")]
7251 (const_string "direct")))
7252 (set_attr "mode" "SI")])
7253
7254 (define_expand "mulhi3"
7255 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7256 (mult:HI (match_operand:HI 1 "register_operand" "")
7257 (match_operand:HI 2 "general_operand" "")))
7258 (clobber (reg:CC FLAGS_REG))])]
7259 "TARGET_HIMODE_MATH"
7260 "")
7261
7262 ;; On AMDFAM10
7263 ;; IMUL reg16, reg16, imm8 VectorPath
7264 ;; IMUL reg16, mem16, imm8 VectorPath
7265 ;; IMUL reg16, reg16, imm16 VectorPath
7266 ;; IMUL reg16, mem16, imm16 VectorPath
7267 ;; IMUL reg16, reg16 Direct
7268 ;; IMUL reg16, mem16 Direct
7269 (define_insn "*mulhi3_1"
7270 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7271 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7272 (match_operand:HI 2 "general_operand" "K,i,mr")))
7273 (clobber (reg:CC FLAGS_REG))]
7274 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7275 "@
7276 imul{w}\t{%2, %1, %0|%0, %1, %2}
7277 imul{w}\t{%2, %1, %0|%0, %1, %2}
7278 imul{w}\t{%2, %0|%0, %2}"
7279 [(set_attr "type" "imul")
7280 (set_attr "prefix_0f" "0,0,1")
7281 (set (attr "athlon_decode")
7282 (cond [(eq_attr "cpu" "athlon")
7283 (const_string "vector")
7284 (eq_attr "alternative" "1,2")
7285 (const_string "vector")]
7286 (const_string "direct")))
7287 (set (attr "amdfam10_decode")
7288 (cond [(eq_attr "alternative" "0,1")
7289 (const_string "vector")]
7290 (const_string "direct")))
7291 (set_attr "mode" "HI")])
7292
7293 (define_expand "mulqi3"
7294 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7295 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7296 (match_operand:QI 2 "register_operand" "")))
7297 (clobber (reg:CC FLAGS_REG))])]
7298 "TARGET_QIMODE_MATH"
7299 "")
7300
7301 ;;On AMDFAM10
7302 ;; MUL reg8 Direct
7303 ;; MUL mem8 Direct
7304
7305 (define_insn "*mulqi3_1"
7306 [(set (match_operand:QI 0 "register_operand" "=a")
7307 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7308 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7309 (clobber (reg:CC FLAGS_REG))]
7310 "TARGET_QIMODE_MATH
7311 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7312 "mul{b}\t%2"
7313 [(set_attr "type" "imul")
7314 (set_attr "length_immediate" "0")
7315 (set (attr "athlon_decode")
7316 (if_then_else (eq_attr "cpu" "athlon")
7317 (const_string "vector")
7318 (const_string "direct")))
7319 (set_attr "amdfam10_decode" "direct")
7320 (set_attr "mode" "QI")])
7321
7322 (define_expand "umulqihi3"
7323 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7324 (mult:HI (zero_extend:HI
7325 (match_operand:QI 1 "nonimmediate_operand" ""))
7326 (zero_extend:HI
7327 (match_operand:QI 2 "register_operand" ""))))
7328 (clobber (reg:CC FLAGS_REG))])]
7329 "TARGET_QIMODE_MATH"
7330 "")
7331
7332 (define_insn "*umulqihi3_1"
7333 [(set (match_operand:HI 0 "register_operand" "=a")
7334 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7335 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7336 (clobber (reg:CC FLAGS_REG))]
7337 "TARGET_QIMODE_MATH
7338 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7339 "mul{b}\t%2"
7340 [(set_attr "type" "imul")
7341 (set_attr "length_immediate" "0")
7342 (set (attr "athlon_decode")
7343 (if_then_else (eq_attr "cpu" "athlon")
7344 (const_string "vector")
7345 (const_string "direct")))
7346 (set_attr "amdfam10_decode" "direct")
7347 (set_attr "mode" "QI")])
7348
7349 (define_expand "mulqihi3"
7350 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7351 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7352 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7353 (clobber (reg:CC FLAGS_REG))])]
7354 "TARGET_QIMODE_MATH"
7355 "")
7356
7357 (define_insn "*mulqihi3_insn"
7358 [(set (match_operand:HI 0 "register_operand" "=a")
7359 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7360 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7361 (clobber (reg:CC FLAGS_REG))]
7362 "TARGET_QIMODE_MATH
7363 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7364 "imul{b}\t%2"
7365 [(set_attr "type" "imul")
7366 (set_attr "length_immediate" "0")
7367 (set (attr "athlon_decode")
7368 (if_then_else (eq_attr "cpu" "athlon")
7369 (const_string "vector")
7370 (const_string "direct")))
7371 (set_attr "amdfam10_decode" "direct")
7372 (set_attr "mode" "QI")])
7373
7374 (define_expand "umulditi3"
7375 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7376 (mult:TI (zero_extend:TI
7377 (match_operand:DI 1 "nonimmediate_operand" ""))
7378 (zero_extend:TI
7379 (match_operand:DI 2 "register_operand" ""))))
7380 (clobber (reg:CC FLAGS_REG))])]
7381 "TARGET_64BIT"
7382 "")
7383
7384 (define_insn "*umulditi3_insn"
7385 [(set (match_operand:TI 0 "register_operand" "=A")
7386 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7387 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7388 (clobber (reg:CC FLAGS_REG))]
7389 "TARGET_64BIT
7390 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7391 "mul{q}\t%2"
7392 [(set_attr "type" "imul")
7393 (set_attr "length_immediate" "0")
7394 (set (attr "athlon_decode")
7395 (if_then_else (eq_attr "cpu" "athlon")
7396 (const_string "vector")
7397 (const_string "double")))
7398 (set_attr "amdfam10_decode" "double")
7399 (set_attr "mode" "DI")])
7400
7401 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7402 (define_expand "umulsidi3"
7403 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7404 (mult:DI (zero_extend:DI
7405 (match_operand:SI 1 "nonimmediate_operand" ""))
7406 (zero_extend:DI
7407 (match_operand:SI 2 "register_operand" ""))))
7408 (clobber (reg:CC FLAGS_REG))])]
7409 "!TARGET_64BIT"
7410 "")
7411
7412 (define_insn "*umulsidi3_insn"
7413 [(set (match_operand:DI 0 "register_operand" "=A")
7414 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7415 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7416 (clobber (reg:CC FLAGS_REG))]
7417 "!TARGET_64BIT
7418 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7419 "mul{l}\t%2"
7420 [(set_attr "type" "imul")
7421 (set_attr "length_immediate" "0")
7422 (set (attr "athlon_decode")
7423 (if_then_else (eq_attr "cpu" "athlon")
7424 (const_string "vector")
7425 (const_string "double")))
7426 (set_attr "amdfam10_decode" "double")
7427 (set_attr "mode" "SI")])
7428
7429 (define_expand "mulditi3"
7430 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7431 (mult:TI (sign_extend:TI
7432 (match_operand:DI 1 "nonimmediate_operand" ""))
7433 (sign_extend:TI
7434 (match_operand:DI 2 "register_operand" ""))))
7435 (clobber (reg:CC FLAGS_REG))])]
7436 "TARGET_64BIT"
7437 "")
7438
7439 (define_insn "*mulditi3_insn"
7440 [(set (match_operand:TI 0 "register_operand" "=A")
7441 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7442 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7443 (clobber (reg:CC FLAGS_REG))]
7444 "TARGET_64BIT
7445 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7446 "imul{q}\t%2"
7447 [(set_attr "type" "imul")
7448 (set_attr "length_immediate" "0")
7449 (set (attr "athlon_decode")
7450 (if_then_else (eq_attr "cpu" "athlon")
7451 (const_string "vector")
7452 (const_string "double")))
7453 (set_attr "amdfam10_decode" "double")
7454 (set_attr "mode" "DI")])
7455
7456 (define_expand "mulsidi3"
7457 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7458 (mult:DI (sign_extend:DI
7459 (match_operand:SI 1 "nonimmediate_operand" ""))
7460 (sign_extend:DI
7461 (match_operand:SI 2 "register_operand" ""))))
7462 (clobber (reg:CC FLAGS_REG))])]
7463 "!TARGET_64BIT"
7464 "")
7465
7466 (define_insn "*mulsidi3_insn"
7467 [(set (match_operand:DI 0 "register_operand" "=A")
7468 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7469 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7470 (clobber (reg:CC FLAGS_REG))]
7471 "!TARGET_64BIT
7472 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7473 "imul{l}\t%2"
7474 [(set_attr "type" "imul")
7475 (set_attr "length_immediate" "0")
7476 (set (attr "athlon_decode")
7477 (if_then_else (eq_attr "cpu" "athlon")
7478 (const_string "vector")
7479 (const_string "double")))
7480 (set_attr "amdfam10_decode" "double")
7481 (set_attr "mode" "SI")])
7482
7483 (define_expand "umuldi3_highpart"
7484 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7485 (truncate:DI
7486 (lshiftrt:TI
7487 (mult:TI (zero_extend:TI
7488 (match_operand:DI 1 "nonimmediate_operand" ""))
7489 (zero_extend:TI
7490 (match_operand:DI 2 "register_operand" "")))
7491 (const_int 64))))
7492 (clobber (match_scratch:DI 3 ""))
7493 (clobber (reg:CC FLAGS_REG))])]
7494 "TARGET_64BIT"
7495 "")
7496
7497 (define_insn "*umuldi3_highpart_rex64"
7498 [(set (match_operand:DI 0 "register_operand" "=d")
7499 (truncate:DI
7500 (lshiftrt:TI
7501 (mult:TI (zero_extend:TI
7502 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7503 (zero_extend:TI
7504 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7505 (const_int 64))))
7506 (clobber (match_scratch:DI 3 "=1"))
7507 (clobber (reg:CC FLAGS_REG))]
7508 "TARGET_64BIT
7509 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7510 "mul{q}\t%2"
7511 [(set_attr "type" "imul")
7512 (set_attr "length_immediate" "0")
7513 (set (attr "athlon_decode")
7514 (if_then_else (eq_attr "cpu" "athlon")
7515 (const_string "vector")
7516 (const_string "double")))
7517 (set_attr "amdfam10_decode" "double")
7518 (set_attr "mode" "DI")])
7519
7520 (define_expand "umulsi3_highpart"
7521 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7522 (truncate:SI
7523 (lshiftrt:DI
7524 (mult:DI (zero_extend:DI
7525 (match_operand:SI 1 "nonimmediate_operand" ""))
7526 (zero_extend:DI
7527 (match_operand:SI 2 "register_operand" "")))
7528 (const_int 32))))
7529 (clobber (match_scratch:SI 3 ""))
7530 (clobber (reg:CC FLAGS_REG))])]
7531 ""
7532 "")
7533
7534 (define_insn "*umulsi3_highpart_insn"
7535 [(set (match_operand:SI 0 "register_operand" "=d")
7536 (truncate:SI
7537 (lshiftrt:DI
7538 (mult:DI (zero_extend:DI
7539 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7540 (zero_extend:DI
7541 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7542 (const_int 32))))
7543 (clobber (match_scratch:SI 3 "=1"))
7544 (clobber (reg:CC FLAGS_REG))]
7545 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7546 "mul{l}\t%2"
7547 [(set_attr "type" "imul")
7548 (set_attr "length_immediate" "0")
7549 (set (attr "athlon_decode")
7550 (if_then_else (eq_attr "cpu" "athlon")
7551 (const_string "vector")
7552 (const_string "double")))
7553 (set_attr "amdfam10_decode" "double")
7554 (set_attr "mode" "SI")])
7555
7556 (define_insn "*umulsi3_highpart_zext"
7557 [(set (match_operand:DI 0 "register_operand" "=d")
7558 (zero_extend:DI (truncate:SI
7559 (lshiftrt:DI
7560 (mult:DI (zero_extend:DI
7561 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7562 (zero_extend:DI
7563 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7564 (const_int 32)))))
7565 (clobber (match_scratch:SI 3 "=1"))
7566 (clobber (reg:CC FLAGS_REG))]
7567 "TARGET_64BIT
7568 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7569 "mul{l}\t%2"
7570 [(set_attr "type" "imul")
7571 (set_attr "length_immediate" "0")
7572 (set (attr "athlon_decode")
7573 (if_then_else (eq_attr "cpu" "athlon")
7574 (const_string "vector")
7575 (const_string "double")))
7576 (set_attr "amdfam10_decode" "double")
7577 (set_attr "mode" "SI")])
7578
7579 (define_expand "smuldi3_highpart"
7580 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7581 (truncate:DI
7582 (lshiftrt:TI
7583 (mult:TI (sign_extend:TI
7584 (match_operand:DI 1 "nonimmediate_operand" ""))
7585 (sign_extend:TI
7586 (match_operand:DI 2 "register_operand" "")))
7587 (const_int 64))))
7588 (clobber (match_scratch:DI 3 ""))
7589 (clobber (reg:CC FLAGS_REG))])]
7590 "TARGET_64BIT"
7591 "")
7592
7593 (define_insn "*smuldi3_highpart_rex64"
7594 [(set (match_operand:DI 0 "register_operand" "=d")
7595 (truncate:DI
7596 (lshiftrt:TI
7597 (mult:TI (sign_extend:TI
7598 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7599 (sign_extend:TI
7600 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7601 (const_int 64))))
7602 (clobber (match_scratch:DI 3 "=1"))
7603 (clobber (reg:CC FLAGS_REG))]
7604 "TARGET_64BIT
7605 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7606 "imul{q}\t%2"
7607 [(set_attr "type" "imul")
7608 (set (attr "athlon_decode")
7609 (if_then_else (eq_attr "cpu" "athlon")
7610 (const_string "vector")
7611 (const_string "double")))
7612 (set_attr "amdfam10_decode" "double")
7613 (set_attr "mode" "DI")])
7614
7615 (define_expand "smulsi3_highpart"
7616 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7617 (truncate:SI
7618 (lshiftrt:DI
7619 (mult:DI (sign_extend:DI
7620 (match_operand:SI 1 "nonimmediate_operand" ""))
7621 (sign_extend:DI
7622 (match_operand:SI 2 "register_operand" "")))
7623 (const_int 32))))
7624 (clobber (match_scratch:SI 3 ""))
7625 (clobber (reg:CC FLAGS_REG))])]
7626 ""
7627 "")
7628
7629 (define_insn "*smulsi3_highpart_insn"
7630 [(set (match_operand:SI 0 "register_operand" "=d")
7631 (truncate:SI
7632 (lshiftrt:DI
7633 (mult:DI (sign_extend:DI
7634 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7635 (sign_extend:DI
7636 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7637 (const_int 32))))
7638 (clobber (match_scratch:SI 3 "=1"))
7639 (clobber (reg:CC FLAGS_REG))]
7640 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7641 "imul{l}\t%2"
7642 [(set_attr "type" "imul")
7643 (set (attr "athlon_decode")
7644 (if_then_else (eq_attr "cpu" "athlon")
7645 (const_string "vector")
7646 (const_string "double")))
7647 (set_attr "amdfam10_decode" "double")
7648 (set_attr "mode" "SI")])
7649
7650 (define_insn "*smulsi3_highpart_zext"
7651 [(set (match_operand:DI 0 "register_operand" "=d")
7652 (zero_extend:DI (truncate:SI
7653 (lshiftrt:DI
7654 (mult:DI (sign_extend:DI
7655 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7656 (sign_extend:DI
7657 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7658 (const_int 32)))))
7659 (clobber (match_scratch:SI 3 "=1"))
7660 (clobber (reg:CC FLAGS_REG))]
7661 "TARGET_64BIT
7662 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7663 "imul{l}\t%2"
7664 [(set_attr "type" "imul")
7665 (set (attr "athlon_decode")
7666 (if_then_else (eq_attr "cpu" "athlon")
7667 (const_string "vector")
7668 (const_string "double")))
7669 (set_attr "amdfam10_decode" "double")
7670 (set_attr "mode" "SI")])
7671
7672 ;; The patterns that match these are at the end of this file.
7673
7674 (define_expand "mulxf3"
7675 [(set (match_operand:XF 0 "register_operand" "")
7676 (mult:XF (match_operand:XF 1 "register_operand" "")
7677 (match_operand:XF 2 "register_operand" "")))]
7678 "TARGET_80387"
7679 "")
7680
7681 (define_expand "muldf3"
7682 [(set (match_operand:DF 0 "register_operand" "")
7683 (mult:DF (match_operand:DF 1 "register_operand" "")
7684 (match_operand:DF 2 "nonimmediate_operand" "")))]
7685 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7686 "")
7687
7688 (define_expand "mulsf3"
7689 [(set (match_operand:SF 0 "register_operand" "")
7690 (mult:SF (match_operand:SF 1 "register_operand" "")
7691 (match_operand:SF 2 "nonimmediate_operand" "")))]
7692 "TARGET_80387 || TARGET_SSE_MATH"
7693 "")
7694 \f
7695 ;; Divide instructions
7696
7697 (define_insn "divqi3"
7698 [(set (match_operand:QI 0 "register_operand" "=a")
7699 (div:QI (match_operand:HI 1 "register_operand" "0")
7700 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7701 (clobber (reg:CC FLAGS_REG))]
7702 "TARGET_QIMODE_MATH"
7703 "idiv{b}\t%2"
7704 [(set_attr "type" "idiv")
7705 (set_attr "mode" "QI")])
7706
7707 (define_insn "udivqi3"
7708 [(set (match_operand:QI 0 "register_operand" "=a")
7709 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7710 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7711 (clobber (reg:CC FLAGS_REG))]
7712 "TARGET_QIMODE_MATH"
7713 "div{b}\t%2"
7714 [(set_attr "type" "idiv")
7715 (set_attr "mode" "QI")])
7716
7717 ;; The patterns that match these are at the end of this file.
7718
7719 (define_expand "divxf3"
7720 [(set (match_operand:XF 0 "register_operand" "")
7721 (div:XF (match_operand:XF 1 "register_operand" "")
7722 (match_operand:XF 2 "register_operand" "")))]
7723 "TARGET_80387"
7724 "")
7725
7726 (define_expand "divdf3"
7727 [(set (match_operand:DF 0 "register_operand" "")
7728 (div:DF (match_operand:DF 1 "register_operand" "")
7729 (match_operand:DF 2 "nonimmediate_operand" "")))]
7730 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7731 "")
7732
7733 (define_expand "divsf3"
7734 [(set (match_operand:SF 0 "register_operand" "")
7735 (div:SF (match_operand:SF 1 "register_operand" "")
7736 (match_operand:SF 2 "nonimmediate_operand" "")))]
7737 "TARGET_80387 || TARGET_SSE_MATH"
7738 "")
7739 \f
7740 ;; Remainder instructions.
7741
7742 (define_expand "divmoddi4"
7743 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7744 (div:DI (match_operand:DI 1 "register_operand" "")
7745 (match_operand:DI 2 "nonimmediate_operand" "")))
7746 (set (match_operand:DI 3 "register_operand" "")
7747 (mod:DI (match_dup 1) (match_dup 2)))
7748 (clobber (reg:CC FLAGS_REG))])]
7749 "TARGET_64BIT"
7750 "")
7751
7752 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7753 ;; Penalize eax case slightly because it results in worse scheduling
7754 ;; of code.
7755 (define_insn "*divmoddi4_nocltd_rex64"
7756 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7757 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7758 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7759 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7760 (mod:DI (match_dup 2) (match_dup 3)))
7761 (clobber (reg:CC FLAGS_REG))]
7762 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7763 "#"
7764 [(set_attr "type" "multi")])
7765
7766 (define_insn "*divmoddi4_cltd_rex64"
7767 [(set (match_operand:DI 0 "register_operand" "=a")
7768 (div:DI (match_operand:DI 2 "register_operand" "a")
7769 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7770 (set (match_operand:DI 1 "register_operand" "=&d")
7771 (mod:DI (match_dup 2) (match_dup 3)))
7772 (clobber (reg:CC FLAGS_REG))]
7773 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7774 "#"
7775 [(set_attr "type" "multi")])
7776
7777 (define_insn "*divmoddi_noext_rex64"
7778 [(set (match_operand:DI 0 "register_operand" "=a")
7779 (div:DI (match_operand:DI 1 "register_operand" "0")
7780 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7781 (set (match_operand:DI 3 "register_operand" "=d")
7782 (mod:DI (match_dup 1) (match_dup 2)))
7783 (use (match_operand:DI 4 "register_operand" "3"))
7784 (clobber (reg:CC FLAGS_REG))]
7785 "TARGET_64BIT"
7786 "idiv{q}\t%2"
7787 [(set_attr "type" "idiv")
7788 (set_attr "mode" "DI")])
7789
7790 (define_split
7791 [(set (match_operand:DI 0 "register_operand" "")
7792 (div:DI (match_operand:DI 1 "register_operand" "")
7793 (match_operand:DI 2 "nonimmediate_operand" "")))
7794 (set (match_operand:DI 3 "register_operand" "")
7795 (mod:DI (match_dup 1) (match_dup 2)))
7796 (clobber (reg:CC FLAGS_REG))]
7797 "TARGET_64BIT && reload_completed"
7798 [(parallel [(set (match_dup 3)
7799 (ashiftrt:DI (match_dup 4) (const_int 63)))
7800 (clobber (reg:CC FLAGS_REG))])
7801 (parallel [(set (match_dup 0)
7802 (div:DI (reg:DI 0) (match_dup 2)))
7803 (set (match_dup 3)
7804 (mod:DI (reg:DI 0) (match_dup 2)))
7805 (use (match_dup 3))
7806 (clobber (reg:CC FLAGS_REG))])]
7807 {
7808 /* Avoid use of cltd in favor of a mov+shift. */
7809 if (!TARGET_USE_CLTD && !optimize_size)
7810 {
7811 if (true_regnum (operands[1]))
7812 emit_move_insn (operands[0], operands[1]);
7813 else
7814 emit_move_insn (operands[3], operands[1]);
7815 operands[4] = operands[3];
7816 }
7817 else
7818 {
7819 gcc_assert (!true_regnum (operands[1]));
7820 operands[4] = operands[1];
7821 }
7822 })
7823
7824
7825 (define_expand "divmodsi4"
7826 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7827 (div:SI (match_operand:SI 1 "register_operand" "")
7828 (match_operand:SI 2 "nonimmediate_operand" "")))
7829 (set (match_operand:SI 3 "register_operand" "")
7830 (mod:SI (match_dup 1) (match_dup 2)))
7831 (clobber (reg:CC FLAGS_REG))])]
7832 ""
7833 "")
7834
7835 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7836 ;; Penalize eax case slightly because it results in worse scheduling
7837 ;; of code.
7838 (define_insn "*divmodsi4_nocltd"
7839 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7840 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7841 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7842 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7843 (mod:SI (match_dup 2) (match_dup 3)))
7844 (clobber (reg:CC FLAGS_REG))]
7845 "!optimize_size && !TARGET_USE_CLTD"
7846 "#"
7847 [(set_attr "type" "multi")])
7848
7849 (define_insn "*divmodsi4_cltd"
7850 [(set (match_operand:SI 0 "register_operand" "=a")
7851 (div:SI (match_operand:SI 2 "register_operand" "a")
7852 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7853 (set (match_operand:SI 1 "register_operand" "=&d")
7854 (mod:SI (match_dup 2) (match_dup 3)))
7855 (clobber (reg:CC FLAGS_REG))]
7856 "optimize_size || TARGET_USE_CLTD"
7857 "#"
7858 [(set_attr "type" "multi")])
7859
7860 (define_insn "*divmodsi_noext"
7861 [(set (match_operand:SI 0 "register_operand" "=a")
7862 (div:SI (match_operand:SI 1 "register_operand" "0")
7863 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7864 (set (match_operand:SI 3 "register_operand" "=d")
7865 (mod:SI (match_dup 1) (match_dup 2)))
7866 (use (match_operand:SI 4 "register_operand" "3"))
7867 (clobber (reg:CC FLAGS_REG))]
7868 ""
7869 "idiv{l}\t%2"
7870 [(set_attr "type" "idiv")
7871 (set_attr "mode" "SI")])
7872
7873 (define_split
7874 [(set (match_operand:SI 0 "register_operand" "")
7875 (div:SI (match_operand:SI 1 "register_operand" "")
7876 (match_operand:SI 2 "nonimmediate_operand" "")))
7877 (set (match_operand:SI 3 "register_operand" "")
7878 (mod:SI (match_dup 1) (match_dup 2)))
7879 (clobber (reg:CC FLAGS_REG))]
7880 "reload_completed"
7881 [(parallel [(set (match_dup 3)
7882 (ashiftrt:SI (match_dup 4) (const_int 31)))
7883 (clobber (reg:CC FLAGS_REG))])
7884 (parallel [(set (match_dup 0)
7885 (div:SI (reg:SI 0) (match_dup 2)))
7886 (set (match_dup 3)
7887 (mod:SI (reg:SI 0) (match_dup 2)))
7888 (use (match_dup 3))
7889 (clobber (reg:CC FLAGS_REG))])]
7890 {
7891 /* Avoid use of cltd in favor of a mov+shift. */
7892 if (!TARGET_USE_CLTD && !optimize_size)
7893 {
7894 if (true_regnum (operands[1]))
7895 emit_move_insn (operands[0], operands[1]);
7896 else
7897 emit_move_insn (operands[3], operands[1]);
7898 operands[4] = operands[3];
7899 }
7900 else
7901 {
7902 gcc_assert (!true_regnum (operands[1]));
7903 operands[4] = operands[1];
7904 }
7905 })
7906 ;; %%% Split me.
7907 (define_insn "divmodhi4"
7908 [(set (match_operand:HI 0 "register_operand" "=a")
7909 (div:HI (match_operand:HI 1 "register_operand" "0")
7910 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7911 (set (match_operand:HI 3 "register_operand" "=&d")
7912 (mod:HI (match_dup 1) (match_dup 2)))
7913 (clobber (reg:CC FLAGS_REG))]
7914 "TARGET_HIMODE_MATH"
7915 "cwtd\;idiv{w}\t%2"
7916 [(set_attr "type" "multi")
7917 (set_attr "length_immediate" "0")
7918 (set_attr "mode" "SI")])
7919
7920 (define_insn "udivmoddi4"
7921 [(set (match_operand:DI 0 "register_operand" "=a")
7922 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7923 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7924 (set (match_operand:DI 3 "register_operand" "=&d")
7925 (umod:DI (match_dup 1) (match_dup 2)))
7926 (clobber (reg:CC FLAGS_REG))]
7927 "TARGET_64BIT"
7928 "xor{q}\t%3, %3\;div{q}\t%2"
7929 [(set_attr "type" "multi")
7930 (set_attr "length_immediate" "0")
7931 (set_attr "mode" "DI")])
7932
7933 (define_insn "*udivmoddi4_noext"
7934 [(set (match_operand:DI 0 "register_operand" "=a")
7935 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7936 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7937 (set (match_operand:DI 3 "register_operand" "=d")
7938 (umod:DI (match_dup 1) (match_dup 2)))
7939 (use (match_dup 3))
7940 (clobber (reg:CC FLAGS_REG))]
7941 "TARGET_64BIT"
7942 "div{q}\t%2"
7943 [(set_attr "type" "idiv")
7944 (set_attr "mode" "DI")])
7945
7946 (define_split
7947 [(set (match_operand:DI 0 "register_operand" "")
7948 (udiv:DI (match_operand:DI 1 "register_operand" "")
7949 (match_operand:DI 2 "nonimmediate_operand" "")))
7950 (set (match_operand:DI 3 "register_operand" "")
7951 (umod:DI (match_dup 1) (match_dup 2)))
7952 (clobber (reg:CC FLAGS_REG))]
7953 "TARGET_64BIT && reload_completed"
7954 [(set (match_dup 3) (const_int 0))
7955 (parallel [(set (match_dup 0)
7956 (udiv:DI (match_dup 1) (match_dup 2)))
7957 (set (match_dup 3)
7958 (umod:DI (match_dup 1) (match_dup 2)))
7959 (use (match_dup 3))
7960 (clobber (reg:CC FLAGS_REG))])]
7961 "")
7962
7963 (define_insn "udivmodsi4"
7964 [(set (match_operand:SI 0 "register_operand" "=a")
7965 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7966 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7967 (set (match_operand:SI 3 "register_operand" "=&d")
7968 (umod:SI (match_dup 1) (match_dup 2)))
7969 (clobber (reg:CC FLAGS_REG))]
7970 ""
7971 "xor{l}\t%3, %3\;div{l}\t%2"
7972 [(set_attr "type" "multi")
7973 (set_attr "length_immediate" "0")
7974 (set_attr "mode" "SI")])
7975
7976 (define_insn "*udivmodsi4_noext"
7977 [(set (match_operand:SI 0 "register_operand" "=a")
7978 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7979 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7980 (set (match_operand:SI 3 "register_operand" "=d")
7981 (umod:SI (match_dup 1) (match_dup 2)))
7982 (use (match_dup 3))
7983 (clobber (reg:CC FLAGS_REG))]
7984 ""
7985 "div{l}\t%2"
7986 [(set_attr "type" "idiv")
7987 (set_attr "mode" "SI")])
7988
7989 (define_split
7990 [(set (match_operand:SI 0 "register_operand" "")
7991 (udiv:SI (match_operand:SI 1 "register_operand" "")
7992 (match_operand:SI 2 "nonimmediate_operand" "")))
7993 (set (match_operand:SI 3 "register_operand" "")
7994 (umod:SI (match_dup 1) (match_dup 2)))
7995 (clobber (reg:CC FLAGS_REG))]
7996 "reload_completed"
7997 [(set (match_dup 3) (const_int 0))
7998 (parallel [(set (match_dup 0)
7999 (udiv:SI (match_dup 1) (match_dup 2)))
8000 (set (match_dup 3)
8001 (umod:SI (match_dup 1) (match_dup 2)))
8002 (use (match_dup 3))
8003 (clobber (reg:CC FLAGS_REG))])]
8004 "")
8005
8006 (define_expand "udivmodhi4"
8007 [(set (match_dup 4) (const_int 0))
8008 (parallel [(set (match_operand:HI 0 "register_operand" "")
8009 (udiv:HI (match_operand:HI 1 "register_operand" "")
8010 (match_operand:HI 2 "nonimmediate_operand" "")))
8011 (set (match_operand:HI 3 "register_operand" "")
8012 (umod:HI (match_dup 1) (match_dup 2)))
8013 (use (match_dup 4))
8014 (clobber (reg:CC FLAGS_REG))])]
8015 "TARGET_HIMODE_MATH"
8016 "operands[4] = gen_reg_rtx (HImode);")
8017
8018 (define_insn "*udivmodhi_noext"
8019 [(set (match_operand:HI 0 "register_operand" "=a")
8020 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8021 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8022 (set (match_operand:HI 3 "register_operand" "=d")
8023 (umod:HI (match_dup 1) (match_dup 2)))
8024 (use (match_operand:HI 4 "register_operand" "3"))
8025 (clobber (reg:CC FLAGS_REG))]
8026 ""
8027 "div{w}\t%2"
8028 [(set_attr "type" "idiv")
8029 (set_attr "mode" "HI")])
8030
8031 ;; We cannot use div/idiv for double division, because it causes
8032 ;; "division by zero" on the overflow and that's not what we expect
8033 ;; from truncate. Because true (non truncating) double division is
8034 ;; never generated, we can't create this insn anyway.
8035 ;
8036 ;(define_insn ""
8037 ; [(set (match_operand:SI 0 "register_operand" "=a")
8038 ; (truncate:SI
8039 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8040 ; (zero_extend:DI
8041 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8042 ; (set (match_operand:SI 3 "register_operand" "=d")
8043 ; (truncate:SI
8044 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8045 ; (clobber (reg:CC FLAGS_REG))]
8046 ; ""
8047 ; "div{l}\t{%2, %0|%0, %2}"
8048 ; [(set_attr "type" "idiv")])
8049 \f
8050 ;;- Logical AND instructions
8051
8052 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8053 ;; Note that this excludes ah.
8054
8055 (define_insn "*testdi_1_rex64"
8056 [(set (reg FLAGS_REG)
8057 (compare
8058 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8059 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8060 (const_int 0)))]
8061 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8062 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8063 "@
8064 test{l}\t{%k1, %k0|%k0, %k1}
8065 test{l}\t{%k1, %k0|%k0, %k1}
8066 test{q}\t{%1, %0|%0, %1}
8067 test{q}\t{%1, %0|%0, %1}
8068 test{q}\t{%1, %0|%0, %1}"
8069 [(set_attr "type" "test")
8070 (set_attr "modrm" "0,1,0,1,1")
8071 (set_attr "mode" "SI,SI,DI,DI,DI")
8072 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8073
8074 (define_insn "testsi_1"
8075 [(set (reg FLAGS_REG)
8076 (compare
8077 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8078 (match_operand:SI 1 "general_operand" "in,in,rin"))
8079 (const_int 0)))]
8080 "ix86_match_ccmode (insn, CCNOmode)
8081 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8082 "test{l}\t{%1, %0|%0, %1}"
8083 [(set_attr "type" "test")
8084 (set_attr "modrm" "0,1,1")
8085 (set_attr "mode" "SI")
8086 (set_attr "pent_pair" "uv,np,uv")])
8087
8088 (define_expand "testsi_ccno_1"
8089 [(set (reg:CCNO FLAGS_REG)
8090 (compare:CCNO
8091 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8092 (match_operand:SI 1 "nonmemory_operand" ""))
8093 (const_int 0)))]
8094 ""
8095 "")
8096
8097 (define_insn "*testhi_1"
8098 [(set (reg FLAGS_REG)
8099 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8100 (match_operand:HI 1 "general_operand" "n,n,rn"))
8101 (const_int 0)))]
8102 "ix86_match_ccmode (insn, CCNOmode)
8103 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8104 "test{w}\t{%1, %0|%0, %1}"
8105 [(set_attr "type" "test")
8106 (set_attr "modrm" "0,1,1")
8107 (set_attr "mode" "HI")
8108 (set_attr "pent_pair" "uv,np,uv")])
8109
8110 (define_expand "testqi_ccz_1"
8111 [(set (reg:CCZ FLAGS_REG)
8112 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8113 (match_operand:QI 1 "nonmemory_operand" ""))
8114 (const_int 0)))]
8115 ""
8116 "")
8117
8118 (define_insn "*testqi_1_maybe_si"
8119 [(set (reg FLAGS_REG)
8120 (compare
8121 (and:QI
8122 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8123 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8124 (const_int 0)))]
8125 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8126 && ix86_match_ccmode (insn,
8127 CONST_INT_P (operands[1])
8128 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8129 {
8130 if (which_alternative == 3)
8131 {
8132 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8133 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8134 return "test{l}\t{%1, %k0|%k0, %1}";
8135 }
8136 return "test{b}\t{%1, %0|%0, %1}";
8137 }
8138 [(set_attr "type" "test")
8139 (set_attr "modrm" "0,1,1,1")
8140 (set_attr "mode" "QI,QI,QI,SI")
8141 (set_attr "pent_pair" "uv,np,uv,np")])
8142
8143 (define_insn "*testqi_1"
8144 [(set (reg FLAGS_REG)
8145 (compare
8146 (and:QI
8147 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8148 (match_operand:QI 1 "general_operand" "n,n,qn"))
8149 (const_int 0)))]
8150 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8151 && ix86_match_ccmode (insn, CCNOmode)"
8152 "test{b}\t{%1, %0|%0, %1}"
8153 [(set_attr "type" "test")
8154 (set_attr "modrm" "0,1,1")
8155 (set_attr "mode" "QI")
8156 (set_attr "pent_pair" "uv,np,uv")])
8157
8158 (define_expand "testqi_ext_ccno_0"
8159 [(set (reg:CCNO FLAGS_REG)
8160 (compare:CCNO
8161 (and:SI
8162 (zero_extract:SI
8163 (match_operand 0 "ext_register_operand" "")
8164 (const_int 8)
8165 (const_int 8))
8166 (match_operand 1 "const_int_operand" ""))
8167 (const_int 0)))]
8168 ""
8169 "")
8170
8171 (define_insn "*testqi_ext_0"
8172 [(set (reg FLAGS_REG)
8173 (compare
8174 (and:SI
8175 (zero_extract:SI
8176 (match_operand 0 "ext_register_operand" "Q")
8177 (const_int 8)
8178 (const_int 8))
8179 (match_operand 1 "const_int_operand" "n"))
8180 (const_int 0)))]
8181 "ix86_match_ccmode (insn, CCNOmode)"
8182 "test{b}\t{%1, %h0|%h0, %1}"
8183 [(set_attr "type" "test")
8184 (set_attr "mode" "QI")
8185 (set_attr "length_immediate" "1")
8186 (set_attr "pent_pair" "np")])
8187
8188 (define_insn "*testqi_ext_1"
8189 [(set (reg FLAGS_REG)
8190 (compare
8191 (and:SI
8192 (zero_extract:SI
8193 (match_operand 0 "ext_register_operand" "Q")
8194 (const_int 8)
8195 (const_int 8))
8196 (zero_extend:SI
8197 (match_operand:QI 1 "general_operand" "Qm")))
8198 (const_int 0)))]
8199 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8200 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8201 "test{b}\t{%1, %h0|%h0, %1}"
8202 [(set_attr "type" "test")
8203 (set_attr "mode" "QI")])
8204
8205 (define_insn "*testqi_ext_1_rex64"
8206 [(set (reg FLAGS_REG)
8207 (compare
8208 (and:SI
8209 (zero_extract:SI
8210 (match_operand 0 "ext_register_operand" "Q")
8211 (const_int 8)
8212 (const_int 8))
8213 (zero_extend:SI
8214 (match_operand:QI 1 "register_operand" "Q")))
8215 (const_int 0)))]
8216 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8217 "test{b}\t{%1, %h0|%h0, %1}"
8218 [(set_attr "type" "test")
8219 (set_attr "mode" "QI")])
8220
8221 (define_insn "*testqi_ext_2"
8222 [(set (reg FLAGS_REG)
8223 (compare
8224 (and:SI
8225 (zero_extract:SI
8226 (match_operand 0 "ext_register_operand" "Q")
8227 (const_int 8)
8228 (const_int 8))
8229 (zero_extract:SI
8230 (match_operand 1 "ext_register_operand" "Q")
8231 (const_int 8)
8232 (const_int 8)))
8233 (const_int 0)))]
8234 "ix86_match_ccmode (insn, CCNOmode)"
8235 "test{b}\t{%h1, %h0|%h0, %h1}"
8236 [(set_attr "type" "test")
8237 (set_attr "mode" "QI")])
8238
8239 ;; Combine likes to form bit extractions for some tests. Humor it.
8240 (define_insn "*testqi_ext_3"
8241 [(set (reg FLAGS_REG)
8242 (compare (zero_extract:SI
8243 (match_operand 0 "nonimmediate_operand" "rm")
8244 (match_operand:SI 1 "const_int_operand" "")
8245 (match_operand:SI 2 "const_int_operand" ""))
8246 (const_int 0)))]
8247 "ix86_match_ccmode (insn, CCNOmode)
8248 && INTVAL (operands[1]) > 0
8249 && INTVAL (operands[2]) >= 0
8250 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8251 && (GET_MODE (operands[0]) == SImode
8252 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8253 || GET_MODE (operands[0]) == HImode
8254 || GET_MODE (operands[0]) == QImode)"
8255 "#")
8256
8257 (define_insn "*testqi_ext_3_rex64"
8258 [(set (reg FLAGS_REG)
8259 (compare (zero_extract:DI
8260 (match_operand 0 "nonimmediate_operand" "rm")
8261 (match_operand:DI 1 "const_int_operand" "")
8262 (match_operand:DI 2 "const_int_operand" ""))
8263 (const_int 0)))]
8264 "TARGET_64BIT
8265 && ix86_match_ccmode (insn, CCNOmode)
8266 && INTVAL (operands[1]) > 0
8267 && INTVAL (operands[2]) >= 0
8268 /* Ensure that resulting mask is zero or sign extended operand. */
8269 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8270 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8271 && INTVAL (operands[1]) > 32))
8272 && (GET_MODE (operands[0]) == SImode
8273 || GET_MODE (operands[0]) == DImode
8274 || GET_MODE (operands[0]) == HImode
8275 || GET_MODE (operands[0]) == QImode)"
8276 "#")
8277
8278 (define_split
8279 [(set (match_operand 0 "flags_reg_operand" "")
8280 (match_operator 1 "compare_operator"
8281 [(zero_extract
8282 (match_operand 2 "nonimmediate_operand" "")
8283 (match_operand 3 "const_int_operand" "")
8284 (match_operand 4 "const_int_operand" ""))
8285 (const_int 0)]))]
8286 "ix86_match_ccmode (insn, CCNOmode)"
8287 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8288 {
8289 rtx val = operands[2];
8290 HOST_WIDE_INT len = INTVAL (operands[3]);
8291 HOST_WIDE_INT pos = INTVAL (operands[4]);
8292 HOST_WIDE_INT mask;
8293 enum machine_mode mode, submode;
8294
8295 mode = GET_MODE (val);
8296 if (MEM_P (val))
8297 {
8298 /* ??? Combine likes to put non-volatile mem extractions in QImode
8299 no matter the size of the test. So find a mode that works. */
8300 if (! MEM_VOLATILE_P (val))
8301 {
8302 mode = smallest_mode_for_size (pos + len, MODE_INT);
8303 val = adjust_address (val, mode, 0);
8304 }
8305 }
8306 else if (GET_CODE (val) == SUBREG
8307 && (submode = GET_MODE (SUBREG_REG (val)),
8308 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8309 && pos + len <= GET_MODE_BITSIZE (submode))
8310 {
8311 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8312 mode = submode;
8313 val = SUBREG_REG (val);
8314 }
8315 else if (mode == HImode && pos + len <= 8)
8316 {
8317 /* Small HImode tests can be converted to QImode. */
8318 mode = QImode;
8319 val = gen_lowpart (QImode, val);
8320 }
8321
8322 if (len == HOST_BITS_PER_WIDE_INT)
8323 mask = -1;
8324 else
8325 mask = ((HOST_WIDE_INT)1 << len) - 1;
8326 mask <<= pos;
8327
8328 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8329 })
8330
8331 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8332 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8333 ;; this is relatively important trick.
8334 ;; Do the conversion only post-reload to avoid limiting of the register class
8335 ;; to QI regs.
8336 (define_split
8337 [(set (match_operand 0 "flags_reg_operand" "")
8338 (match_operator 1 "compare_operator"
8339 [(and (match_operand 2 "register_operand" "")
8340 (match_operand 3 "const_int_operand" ""))
8341 (const_int 0)]))]
8342 "reload_completed
8343 && QI_REG_P (operands[2])
8344 && GET_MODE (operands[2]) != QImode
8345 && ((ix86_match_ccmode (insn, CCZmode)
8346 && !(INTVAL (operands[3]) & ~(255 << 8)))
8347 || (ix86_match_ccmode (insn, CCNOmode)
8348 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8349 [(set (match_dup 0)
8350 (match_op_dup 1
8351 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8352 (match_dup 3))
8353 (const_int 0)]))]
8354 "operands[2] = gen_lowpart (SImode, operands[2]);
8355 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8356
8357 (define_split
8358 [(set (match_operand 0 "flags_reg_operand" "")
8359 (match_operator 1 "compare_operator"
8360 [(and (match_operand 2 "nonimmediate_operand" "")
8361 (match_operand 3 "const_int_operand" ""))
8362 (const_int 0)]))]
8363 "reload_completed
8364 && GET_MODE (operands[2]) != QImode
8365 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8366 && ((ix86_match_ccmode (insn, CCZmode)
8367 && !(INTVAL (operands[3]) & ~255))
8368 || (ix86_match_ccmode (insn, CCNOmode)
8369 && !(INTVAL (operands[3]) & ~127)))"
8370 [(set (match_dup 0)
8371 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8372 (const_int 0)]))]
8373 "operands[2] = gen_lowpart (QImode, operands[2]);
8374 operands[3] = gen_lowpart (QImode, operands[3]);")
8375
8376
8377 ;; %%% This used to optimize known byte-wide and operations to memory,
8378 ;; and sometimes to QImode registers. If this is considered useful,
8379 ;; it should be done with splitters.
8380
8381 (define_expand "anddi3"
8382 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8383 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8384 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8385 (clobber (reg:CC FLAGS_REG))]
8386 "TARGET_64BIT"
8387 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8388
8389 (define_insn "*anddi_1_rex64"
8390 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8391 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8392 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8393 (clobber (reg:CC FLAGS_REG))]
8394 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8395 {
8396 switch (get_attr_type (insn))
8397 {
8398 case TYPE_IMOVX:
8399 {
8400 enum machine_mode mode;
8401
8402 gcc_assert (CONST_INT_P (operands[2]));
8403 if (INTVAL (operands[2]) == 0xff)
8404 mode = QImode;
8405 else
8406 {
8407 gcc_assert (INTVAL (operands[2]) == 0xffff);
8408 mode = HImode;
8409 }
8410
8411 operands[1] = gen_lowpart (mode, operands[1]);
8412 if (mode == QImode)
8413 return "movz{bq|x}\t{%1,%0|%0, %1}";
8414 else
8415 return "movz{wq|x}\t{%1,%0|%0, %1}";
8416 }
8417
8418 default:
8419 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8420 if (get_attr_mode (insn) == MODE_SI)
8421 return "and{l}\t{%k2, %k0|%k0, %k2}";
8422 else
8423 return "and{q}\t{%2, %0|%0, %2}";
8424 }
8425 }
8426 [(set_attr "type" "alu,alu,alu,imovx")
8427 (set_attr "length_immediate" "*,*,*,0")
8428 (set_attr "mode" "SI,DI,DI,DI")])
8429
8430 (define_insn "*anddi_2"
8431 [(set (reg FLAGS_REG)
8432 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8433 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8434 (const_int 0)))
8435 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8436 (and:DI (match_dup 1) (match_dup 2)))]
8437 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8438 && ix86_binary_operator_ok (AND, DImode, operands)"
8439 "@
8440 and{l}\t{%k2, %k0|%k0, %k2}
8441 and{q}\t{%2, %0|%0, %2}
8442 and{q}\t{%2, %0|%0, %2}"
8443 [(set_attr "type" "alu")
8444 (set_attr "mode" "SI,DI,DI")])
8445
8446 (define_expand "andsi3"
8447 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8448 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8449 (match_operand:SI 2 "general_operand" "")))
8450 (clobber (reg:CC FLAGS_REG))]
8451 ""
8452 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8453
8454 (define_insn "*andsi_1"
8455 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8456 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8457 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8458 (clobber (reg:CC FLAGS_REG))]
8459 "ix86_binary_operator_ok (AND, SImode, operands)"
8460 {
8461 switch (get_attr_type (insn))
8462 {
8463 case TYPE_IMOVX:
8464 {
8465 enum machine_mode mode;
8466
8467 gcc_assert (CONST_INT_P (operands[2]));
8468 if (INTVAL (operands[2]) == 0xff)
8469 mode = QImode;
8470 else
8471 {
8472 gcc_assert (INTVAL (operands[2]) == 0xffff);
8473 mode = HImode;
8474 }
8475
8476 operands[1] = gen_lowpart (mode, operands[1]);
8477 if (mode == QImode)
8478 return "movz{bl|x}\t{%1,%0|%0, %1}";
8479 else
8480 return "movz{wl|x}\t{%1,%0|%0, %1}";
8481 }
8482
8483 default:
8484 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8485 return "and{l}\t{%2, %0|%0, %2}";
8486 }
8487 }
8488 [(set_attr "type" "alu,alu,imovx")
8489 (set_attr "length_immediate" "*,*,0")
8490 (set_attr "mode" "SI")])
8491
8492 (define_split
8493 [(set (match_operand 0 "register_operand" "")
8494 (and (match_dup 0)
8495 (const_int -65536)))
8496 (clobber (reg:CC FLAGS_REG))]
8497 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8498 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8499 "operands[1] = gen_lowpart (HImode, operands[0]);")
8500
8501 (define_split
8502 [(set (match_operand 0 "ext_register_operand" "")
8503 (and (match_dup 0)
8504 (const_int -256)))
8505 (clobber (reg:CC FLAGS_REG))]
8506 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8507 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8508 "operands[1] = gen_lowpart (QImode, operands[0]);")
8509
8510 (define_split
8511 [(set (match_operand 0 "ext_register_operand" "")
8512 (and (match_dup 0)
8513 (const_int -65281)))
8514 (clobber (reg:CC FLAGS_REG))]
8515 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8516 [(parallel [(set (zero_extract:SI (match_dup 0)
8517 (const_int 8)
8518 (const_int 8))
8519 (xor:SI
8520 (zero_extract:SI (match_dup 0)
8521 (const_int 8)
8522 (const_int 8))
8523 (zero_extract:SI (match_dup 0)
8524 (const_int 8)
8525 (const_int 8))))
8526 (clobber (reg:CC FLAGS_REG))])]
8527 "operands[0] = gen_lowpart (SImode, operands[0]);")
8528
8529 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8530 (define_insn "*andsi_1_zext"
8531 [(set (match_operand:DI 0 "register_operand" "=r")
8532 (zero_extend:DI
8533 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8534 (match_operand:SI 2 "general_operand" "rim"))))
8535 (clobber (reg:CC FLAGS_REG))]
8536 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8537 "and{l}\t{%2, %k0|%k0, %2}"
8538 [(set_attr "type" "alu")
8539 (set_attr "mode" "SI")])
8540
8541 (define_insn "*andsi_2"
8542 [(set (reg FLAGS_REG)
8543 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8544 (match_operand:SI 2 "general_operand" "rim,ri"))
8545 (const_int 0)))
8546 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8547 (and:SI (match_dup 1) (match_dup 2)))]
8548 "ix86_match_ccmode (insn, CCNOmode)
8549 && ix86_binary_operator_ok (AND, SImode, operands)"
8550 "and{l}\t{%2, %0|%0, %2}"
8551 [(set_attr "type" "alu")
8552 (set_attr "mode" "SI")])
8553
8554 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8555 (define_insn "*andsi_2_zext"
8556 [(set (reg FLAGS_REG)
8557 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8558 (match_operand:SI 2 "general_operand" "rim"))
8559 (const_int 0)))
8560 (set (match_operand:DI 0 "register_operand" "=r")
8561 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8562 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8563 && ix86_binary_operator_ok (AND, SImode, operands)"
8564 "and{l}\t{%2, %k0|%k0, %2}"
8565 [(set_attr "type" "alu")
8566 (set_attr "mode" "SI")])
8567
8568 (define_expand "andhi3"
8569 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8570 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8571 (match_operand:HI 2 "general_operand" "")))
8572 (clobber (reg:CC FLAGS_REG))]
8573 "TARGET_HIMODE_MATH"
8574 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8575
8576 (define_insn "*andhi_1"
8577 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8578 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8579 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8580 (clobber (reg:CC FLAGS_REG))]
8581 "ix86_binary_operator_ok (AND, HImode, operands)"
8582 {
8583 switch (get_attr_type (insn))
8584 {
8585 case TYPE_IMOVX:
8586 gcc_assert (CONST_INT_P (operands[2]));
8587 gcc_assert (INTVAL (operands[2]) == 0xff);
8588 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8589
8590 default:
8591 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8592
8593 return "and{w}\t{%2, %0|%0, %2}";
8594 }
8595 }
8596 [(set_attr "type" "alu,alu,imovx")
8597 (set_attr "length_immediate" "*,*,0")
8598 (set_attr "mode" "HI,HI,SI")])
8599
8600 (define_insn "*andhi_2"
8601 [(set (reg FLAGS_REG)
8602 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8603 (match_operand:HI 2 "general_operand" "rim,ri"))
8604 (const_int 0)))
8605 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8606 (and:HI (match_dup 1) (match_dup 2)))]
8607 "ix86_match_ccmode (insn, CCNOmode)
8608 && ix86_binary_operator_ok (AND, HImode, operands)"
8609 "and{w}\t{%2, %0|%0, %2}"
8610 [(set_attr "type" "alu")
8611 (set_attr "mode" "HI")])
8612
8613 (define_expand "andqi3"
8614 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8615 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8616 (match_operand:QI 2 "general_operand" "")))
8617 (clobber (reg:CC FLAGS_REG))]
8618 "TARGET_QIMODE_MATH"
8619 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8620
8621 ;; %%% Potential partial reg stall on alternative 2. What to do?
8622 (define_insn "*andqi_1"
8623 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8624 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8625 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8626 (clobber (reg:CC FLAGS_REG))]
8627 "ix86_binary_operator_ok (AND, QImode, operands)"
8628 "@
8629 and{b}\t{%2, %0|%0, %2}
8630 and{b}\t{%2, %0|%0, %2}
8631 and{l}\t{%k2, %k0|%k0, %k2}"
8632 [(set_attr "type" "alu")
8633 (set_attr "mode" "QI,QI,SI")])
8634
8635 (define_insn "*andqi_1_slp"
8636 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8637 (and:QI (match_dup 0)
8638 (match_operand:QI 1 "general_operand" "qi,qmi")))
8639 (clobber (reg:CC FLAGS_REG))]
8640 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8641 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8642 "and{b}\t{%1, %0|%0, %1}"
8643 [(set_attr "type" "alu1")
8644 (set_attr "mode" "QI")])
8645
8646 (define_insn "*andqi_2_maybe_si"
8647 [(set (reg FLAGS_REG)
8648 (compare (and:QI
8649 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8650 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8651 (const_int 0)))
8652 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8653 (and:QI (match_dup 1) (match_dup 2)))]
8654 "ix86_binary_operator_ok (AND, QImode, operands)
8655 && ix86_match_ccmode (insn,
8656 CONST_INT_P (operands[2])
8657 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8658 {
8659 if (which_alternative == 2)
8660 {
8661 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8662 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8663 return "and{l}\t{%2, %k0|%k0, %2}";
8664 }
8665 return "and{b}\t{%2, %0|%0, %2}";
8666 }
8667 [(set_attr "type" "alu")
8668 (set_attr "mode" "QI,QI,SI")])
8669
8670 (define_insn "*andqi_2"
8671 [(set (reg FLAGS_REG)
8672 (compare (and:QI
8673 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8674 (match_operand:QI 2 "general_operand" "qim,qi"))
8675 (const_int 0)))
8676 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8677 (and:QI (match_dup 1) (match_dup 2)))]
8678 "ix86_match_ccmode (insn, CCNOmode)
8679 && ix86_binary_operator_ok (AND, QImode, operands)"
8680 "and{b}\t{%2, %0|%0, %2}"
8681 [(set_attr "type" "alu")
8682 (set_attr "mode" "QI")])
8683
8684 (define_insn "*andqi_2_slp"
8685 [(set (reg FLAGS_REG)
8686 (compare (and:QI
8687 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8688 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8689 (const_int 0)))
8690 (set (strict_low_part (match_dup 0))
8691 (and:QI (match_dup 0) (match_dup 1)))]
8692 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8693 && ix86_match_ccmode (insn, CCNOmode)
8694 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8695 "and{b}\t{%1, %0|%0, %1}"
8696 [(set_attr "type" "alu1")
8697 (set_attr "mode" "QI")])
8698
8699 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8700 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8701 ;; for a QImode operand, which of course failed.
8702
8703 (define_insn "andqi_ext_0"
8704 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8705 (const_int 8)
8706 (const_int 8))
8707 (and:SI
8708 (zero_extract:SI
8709 (match_operand 1 "ext_register_operand" "0")
8710 (const_int 8)
8711 (const_int 8))
8712 (match_operand 2 "const_int_operand" "n")))
8713 (clobber (reg:CC FLAGS_REG))]
8714 ""
8715 "and{b}\t{%2, %h0|%h0, %2}"
8716 [(set_attr "type" "alu")
8717 (set_attr "length_immediate" "1")
8718 (set_attr "mode" "QI")])
8719
8720 ;; Generated by peephole translating test to and. This shows up
8721 ;; often in fp comparisons.
8722
8723 (define_insn "*andqi_ext_0_cc"
8724 [(set (reg FLAGS_REG)
8725 (compare
8726 (and:SI
8727 (zero_extract:SI
8728 (match_operand 1 "ext_register_operand" "0")
8729 (const_int 8)
8730 (const_int 8))
8731 (match_operand 2 "const_int_operand" "n"))
8732 (const_int 0)))
8733 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8734 (const_int 8)
8735 (const_int 8))
8736 (and:SI
8737 (zero_extract:SI
8738 (match_dup 1)
8739 (const_int 8)
8740 (const_int 8))
8741 (match_dup 2)))]
8742 "ix86_match_ccmode (insn, CCNOmode)"
8743 "and{b}\t{%2, %h0|%h0, %2}"
8744 [(set_attr "type" "alu")
8745 (set_attr "length_immediate" "1")
8746 (set_attr "mode" "QI")])
8747
8748 (define_insn "*andqi_ext_1"
8749 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8750 (const_int 8)
8751 (const_int 8))
8752 (and:SI
8753 (zero_extract:SI
8754 (match_operand 1 "ext_register_operand" "0")
8755 (const_int 8)
8756 (const_int 8))
8757 (zero_extend:SI
8758 (match_operand:QI 2 "general_operand" "Qm"))))
8759 (clobber (reg:CC FLAGS_REG))]
8760 "!TARGET_64BIT"
8761 "and{b}\t{%2, %h0|%h0, %2}"
8762 [(set_attr "type" "alu")
8763 (set_attr "length_immediate" "0")
8764 (set_attr "mode" "QI")])
8765
8766 (define_insn "*andqi_ext_1_rex64"
8767 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8768 (const_int 8)
8769 (const_int 8))
8770 (and:SI
8771 (zero_extract:SI
8772 (match_operand 1 "ext_register_operand" "0")
8773 (const_int 8)
8774 (const_int 8))
8775 (zero_extend:SI
8776 (match_operand 2 "ext_register_operand" "Q"))))
8777 (clobber (reg:CC FLAGS_REG))]
8778 "TARGET_64BIT"
8779 "and{b}\t{%2, %h0|%h0, %2}"
8780 [(set_attr "type" "alu")
8781 (set_attr "length_immediate" "0")
8782 (set_attr "mode" "QI")])
8783
8784 (define_insn "*andqi_ext_2"
8785 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8786 (const_int 8)
8787 (const_int 8))
8788 (and:SI
8789 (zero_extract:SI
8790 (match_operand 1 "ext_register_operand" "%0")
8791 (const_int 8)
8792 (const_int 8))
8793 (zero_extract:SI
8794 (match_operand 2 "ext_register_operand" "Q")
8795 (const_int 8)
8796 (const_int 8))))
8797 (clobber (reg:CC FLAGS_REG))]
8798 ""
8799 "and{b}\t{%h2, %h0|%h0, %h2}"
8800 [(set_attr "type" "alu")
8801 (set_attr "length_immediate" "0")
8802 (set_attr "mode" "QI")])
8803
8804 ;; Convert wide AND instructions with immediate operand to shorter QImode
8805 ;; equivalents when possible.
8806 ;; Don't do the splitting with memory operands, since it introduces risk
8807 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8808 ;; for size, but that can (should?) be handled by generic code instead.
8809 (define_split
8810 [(set (match_operand 0 "register_operand" "")
8811 (and (match_operand 1 "register_operand" "")
8812 (match_operand 2 "const_int_operand" "")))
8813 (clobber (reg:CC FLAGS_REG))]
8814 "reload_completed
8815 && QI_REG_P (operands[0])
8816 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8817 && !(~INTVAL (operands[2]) & ~(255 << 8))
8818 && GET_MODE (operands[0]) != QImode"
8819 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8820 (and:SI (zero_extract:SI (match_dup 1)
8821 (const_int 8) (const_int 8))
8822 (match_dup 2)))
8823 (clobber (reg:CC FLAGS_REG))])]
8824 "operands[0] = gen_lowpart (SImode, operands[0]);
8825 operands[1] = gen_lowpart (SImode, operands[1]);
8826 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8827
8828 ;; Since AND can be encoded with sign extended immediate, this is only
8829 ;; profitable when 7th bit is not set.
8830 (define_split
8831 [(set (match_operand 0 "register_operand" "")
8832 (and (match_operand 1 "general_operand" "")
8833 (match_operand 2 "const_int_operand" "")))
8834 (clobber (reg:CC FLAGS_REG))]
8835 "reload_completed
8836 && ANY_QI_REG_P (operands[0])
8837 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8838 && !(~INTVAL (operands[2]) & ~255)
8839 && !(INTVAL (operands[2]) & 128)
8840 && GET_MODE (operands[0]) != QImode"
8841 [(parallel [(set (strict_low_part (match_dup 0))
8842 (and:QI (match_dup 1)
8843 (match_dup 2)))
8844 (clobber (reg:CC FLAGS_REG))])]
8845 "operands[0] = gen_lowpart (QImode, operands[0]);
8846 operands[1] = gen_lowpart (QImode, operands[1]);
8847 operands[2] = gen_lowpart (QImode, operands[2]);")
8848 \f
8849 ;; Logical inclusive OR instructions
8850
8851 ;; %%% This used to optimize known byte-wide and operations to memory.
8852 ;; If this is considered useful, it should be done with splitters.
8853
8854 (define_expand "iordi3"
8855 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8856 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8857 (match_operand:DI 2 "x86_64_general_operand" "")))
8858 (clobber (reg:CC FLAGS_REG))]
8859 "TARGET_64BIT"
8860 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8861
8862 (define_insn "*iordi_1_rex64"
8863 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8864 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8865 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8866 (clobber (reg:CC FLAGS_REG))]
8867 "TARGET_64BIT
8868 && ix86_binary_operator_ok (IOR, DImode, operands)"
8869 "or{q}\t{%2, %0|%0, %2}"
8870 [(set_attr "type" "alu")
8871 (set_attr "mode" "DI")])
8872
8873 (define_insn "*iordi_2_rex64"
8874 [(set (reg FLAGS_REG)
8875 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8876 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8877 (const_int 0)))
8878 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8879 (ior:DI (match_dup 1) (match_dup 2)))]
8880 "TARGET_64BIT
8881 && ix86_match_ccmode (insn, CCNOmode)
8882 && ix86_binary_operator_ok (IOR, DImode, operands)"
8883 "or{q}\t{%2, %0|%0, %2}"
8884 [(set_attr "type" "alu")
8885 (set_attr "mode" "DI")])
8886
8887 (define_insn "*iordi_3_rex64"
8888 [(set (reg FLAGS_REG)
8889 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8890 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8891 (const_int 0)))
8892 (clobber (match_scratch:DI 0 "=r"))]
8893 "TARGET_64BIT
8894 && ix86_match_ccmode (insn, CCNOmode)
8895 && ix86_binary_operator_ok (IOR, DImode, operands)"
8896 "or{q}\t{%2, %0|%0, %2}"
8897 [(set_attr "type" "alu")
8898 (set_attr "mode" "DI")])
8899
8900
8901 (define_expand "iorsi3"
8902 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8903 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8904 (match_operand:SI 2 "general_operand" "")))
8905 (clobber (reg:CC FLAGS_REG))]
8906 ""
8907 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8908
8909 (define_insn "*iorsi_1"
8910 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8911 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8912 (match_operand:SI 2 "general_operand" "ri,rmi")))
8913 (clobber (reg:CC FLAGS_REG))]
8914 "ix86_binary_operator_ok (IOR, SImode, operands)"
8915 "or{l}\t{%2, %0|%0, %2}"
8916 [(set_attr "type" "alu")
8917 (set_attr "mode" "SI")])
8918
8919 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8920 (define_insn "*iorsi_1_zext"
8921 [(set (match_operand:DI 0 "register_operand" "=rm")
8922 (zero_extend:DI
8923 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8924 (match_operand:SI 2 "general_operand" "rim"))))
8925 (clobber (reg:CC FLAGS_REG))]
8926 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8927 "or{l}\t{%2, %k0|%k0, %2}"
8928 [(set_attr "type" "alu")
8929 (set_attr "mode" "SI")])
8930
8931 (define_insn "*iorsi_1_zext_imm"
8932 [(set (match_operand:DI 0 "register_operand" "=rm")
8933 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8934 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8935 (clobber (reg:CC FLAGS_REG))]
8936 "TARGET_64BIT"
8937 "or{l}\t{%2, %k0|%k0, %2}"
8938 [(set_attr "type" "alu")
8939 (set_attr "mode" "SI")])
8940
8941 (define_insn "*iorsi_2"
8942 [(set (reg FLAGS_REG)
8943 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8944 (match_operand:SI 2 "general_operand" "rim,ri"))
8945 (const_int 0)))
8946 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8947 (ior:SI (match_dup 1) (match_dup 2)))]
8948 "ix86_match_ccmode (insn, CCNOmode)
8949 && ix86_binary_operator_ok (IOR, SImode, operands)"
8950 "or{l}\t{%2, %0|%0, %2}"
8951 [(set_attr "type" "alu")
8952 (set_attr "mode" "SI")])
8953
8954 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8955 ;; ??? Special case for immediate operand is missing - it is tricky.
8956 (define_insn "*iorsi_2_zext"
8957 [(set (reg FLAGS_REG)
8958 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8959 (match_operand:SI 2 "general_operand" "rim"))
8960 (const_int 0)))
8961 (set (match_operand:DI 0 "register_operand" "=r")
8962 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8963 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8964 && ix86_binary_operator_ok (IOR, SImode, operands)"
8965 "or{l}\t{%2, %k0|%k0, %2}"
8966 [(set_attr "type" "alu")
8967 (set_attr "mode" "SI")])
8968
8969 (define_insn "*iorsi_2_zext_imm"
8970 [(set (reg FLAGS_REG)
8971 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8972 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8973 (const_int 0)))
8974 (set (match_operand:DI 0 "register_operand" "=r")
8975 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8976 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8977 && ix86_binary_operator_ok (IOR, SImode, operands)"
8978 "or{l}\t{%2, %k0|%k0, %2}"
8979 [(set_attr "type" "alu")
8980 (set_attr "mode" "SI")])
8981
8982 (define_insn "*iorsi_3"
8983 [(set (reg FLAGS_REG)
8984 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8985 (match_operand:SI 2 "general_operand" "rim"))
8986 (const_int 0)))
8987 (clobber (match_scratch:SI 0 "=r"))]
8988 "ix86_match_ccmode (insn, CCNOmode)
8989 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8990 "or{l}\t{%2, %0|%0, %2}"
8991 [(set_attr "type" "alu")
8992 (set_attr "mode" "SI")])
8993
8994 (define_expand "iorhi3"
8995 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8996 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8997 (match_operand:HI 2 "general_operand" "")))
8998 (clobber (reg:CC FLAGS_REG))]
8999 "TARGET_HIMODE_MATH"
9000 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9001
9002 (define_insn "*iorhi_1"
9003 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9004 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9005 (match_operand:HI 2 "general_operand" "rmi,ri")))
9006 (clobber (reg:CC FLAGS_REG))]
9007 "ix86_binary_operator_ok (IOR, HImode, operands)"
9008 "or{w}\t{%2, %0|%0, %2}"
9009 [(set_attr "type" "alu")
9010 (set_attr "mode" "HI")])
9011
9012 (define_insn "*iorhi_2"
9013 [(set (reg FLAGS_REG)
9014 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9015 (match_operand:HI 2 "general_operand" "rim,ri"))
9016 (const_int 0)))
9017 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9018 (ior:HI (match_dup 1) (match_dup 2)))]
9019 "ix86_match_ccmode (insn, CCNOmode)
9020 && ix86_binary_operator_ok (IOR, HImode, operands)"
9021 "or{w}\t{%2, %0|%0, %2}"
9022 [(set_attr "type" "alu")
9023 (set_attr "mode" "HI")])
9024
9025 (define_insn "*iorhi_3"
9026 [(set (reg FLAGS_REG)
9027 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9028 (match_operand:HI 2 "general_operand" "rim"))
9029 (const_int 0)))
9030 (clobber (match_scratch:HI 0 "=r"))]
9031 "ix86_match_ccmode (insn, CCNOmode)
9032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9033 "or{w}\t{%2, %0|%0, %2}"
9034 [(set_attr "type" "alu")
9035 (set_attr "mode" "HI")])
9036
9037 (define_expand "iorqi3"
9038 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9039 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9040 (match_operand:QI 2 "general_operand" "")))
9041 (clobber (reg:CC FLAGS_REG))]
9042 "TARGET_QIMODE_MATH"
9043 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9044
9045 ;; %%% Potential partial reg stall on alternative 2. What to do?
9046 (define_insn "*iorqi_1"
9047 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9048 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9049 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9050 (clobber (reg:CC FLAGS_REG))]
9051 "ix86_binary_operator_ok (IOR, QImode, operands)"
9052 "@
9053 or{b}\t{%2, %0|%0, %2}
9054 or{b}\t{%2, %0|%0, %2}
9055 or{l}\t{%k2, %k0|%k0, %k2}"
9056 [(set_attr "type" "alu")
9057 (set_attr "mode" "QI,QI,SI")])
9058
9059 (define_insn "*iorqi_1_slp"
9060 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9061 (ior:QI (match_dup 0)
9062 (match_operand:QI 1 "general_operand" "qmi,qi")))
9063 (clobber (reg:CC FLAGS_REG))]
9064 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9065 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9066 "or{b}\t{%1, %0|%0, %1}"
9067 [(set_attr "type" "alu1")
9068 (set_attr "mode" "QI")])
9069
9070 (define_insn "*iorqi_2"
9071 [(set (reg FLAGS_REG)
9072 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9073 (match_operand:QI 2 "general_operand" "qim,qi"))
9074 (const_int 0)))
9075 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9076 (ior:QI (match_dup 1) (match_dup 2)))]
9077 "ix86_match_ccmode (insn, CCNOmode)
9078 && ix86_binary_operator_ok (IOR, QImode, operands)"
9079 "or{b}\t{%2, %0|%0, %2}"
9080 [(set_attr "type" "alu")
9081 (set_attr "mode" "QI")])
9082
9083 (define_insn "*iorqi_2_slp"
9084 [(set (reg FLAGS_REG)
9085 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9086 (match_operand:QI 1 "general_operand" "qim,qi"))
9087 (const_int 0)))
9088 (set (strict_low_part (match_dup 0))
9089 (ior:QI (match_dup 0) (match_dup 1)))]
9090 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9091 && ix86_match_ccmode (insn, CCNOmode)
9092 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9093 "or{b}\t{%1, %0|%0, %1}"
9094 [(set_attr "type" "alu1")
9095 (set_attr "mode" "QI")])
9096
9097 (define_insn "*iorqi_3"
9098 [(set (reg FLAGS_REG)
9099 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9100 (match_operand:QI 2 "general_operand" "qim"))
9101 (const_int 0)))
9102 (clobber (match_scratch:QI 0 "=q"))]
9103 "ix86_match_ccmode (insn, CCNOmode)
9104 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9105 "or{b}\t{%2, %0|%0, %2}"
9106 [(set_attr "type" "alu")
9107 (set_attr "mode" "QI")])
9108
9109 (define_insn "iorqi_ext_0"
9110 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9111 (const_int 8)
9112 (const_int 8))
9113 (ior:SI
9114 (zero_extract:SI
9115 (match_operand 1 "ext_register_operand" "0")
9116 (const_int 8)
9117 (const_int 8))
9118 (match_operand 2 "const_int_operand" "n")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9121 "or{b}\t{%2, %h0|%h0, %2}"
9122 [(set_attr "type" "alu")
9123 (set_attr "length_immediate" "1")
9124 (set_attr "mode" "QI")])
9125
9126 (define_insn "*iorqi_ext_1"
9127 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9128 (const_int 8)
9129 (const_int 8))
9130 (ior:SI
9131 (zero_extract:SI
9132 (match_operand 1 "ext_register_operand" "0")
9133 (const_int 8)
9134 (const_int 8))
9135 (zero_extend:SI
9136 (match_operand:QI 2 "general_operand" "Qm"))))
9137 (clobber (reg:CC FLAGS_REG))]
9138 "!TARGET_64BIT
9139 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9140 "or{b}\t{%2, %h0|%h0, %2}"
9141 [(set_attr "type" "alu")
9142 (set_attr "length_immediate" "0")
9143 (set_attr "mode" "QI")])
9144
9145 (define_insn "*iorqi_ext_1_rex64"
9146 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9147 (const_int 8)
9148 (const_int 8))
9149 (ior:SI
9150 (zero_extract:SI
9151 (match_operand 1 "ext_register_operand" "0")
9152 (const_int 8)
9153 (const_int 8))
9154 (zero_extend:SI
9155 (match_operand 2 "ext_register_operand" "Q"))))
9156 (clobber (reg:CC FLAGS_REG))]
9157 "TARGET_64BIT
9158 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9159 "or{b}\t{%2, %h0|%h0, %2}"
9160 [(set_attr "type" "alu")
9161 (set_attr "length_immediate" "0")
9162 (set_attr "mode" "QI")])
9163
9164 (define_insn "*iorqi_ext_2"
9165 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9166 (const_int 8)
9167 (const_int 8))
9168 (ior:SI
9169 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9170 (const_int 8)
9171 (const_int 8))
9172 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9173 (const_int 8)
9174 (const_int 8))))
9175 (clobber (reg:CC FLAGS_REG))]
9176 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9177 "ior{b}\t{%h2, %h0|%h0, %h2}"
9178 [(set_attr "type" "alu")
9179 (set_attr "length_immediate" "0")
9180 (set_attr "mode" "QI")])
9181
9182 (define_split
9183 [(set (match_operand 0 "register_operand" "")
9184 (ior (match_operand 1 "register_operand" "")
9185 (match_operand 2 "const_int_operand" "")))
9186 (clobber (reg:CC FLAGS_REG))]
9187 "reload_completed
9188 && QI_REG_P (operands[0])
9189 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9190 && !(INTVAL (operands[2]) & ~(255 << 8))
9191 && GET_MODE (operands[0]) != QImode"
9192 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9193 (ior:SI (zero_extract:SI (match_dup 1)
9194 (const_int 8) (const_int 8))
9195 (match_dup 2)))
9196 (clobber (reg:CC FLAGS_REG))])]
9197 "operands[0] = gen_lowpart (SImode, operands[0]);
9198 operands[1] = gen_lowpart (SImode, operands[1]);
9199 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9200
9201 ;; Since OR can be encoded with sign extended immediate, this is only
9202 ;; profitable when 7th bit is set.
9203 (define_split
9204 [(set (match_operand 0 "register_operand" "")
9205 (ior (match_operand 1 "general_operand" "")
9206 (match_operand 2 "const_int_operand" "")))
9207 (clobber (reg:CC FLAGS_REG))]
9208 "reload_completed
9209 && ANY_QI_REG_P (operands[0])
9210 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9211 && !(INTVAL (operands[2]) & ~255)
9212 && (INTVAL (operands[2]) & 128)
9213 && GET_MODE (operands[0]) != QImode"
9214 [(parallel [(set (strict_low_part (match_dup 0))
9215 (ior:QI (match_dup 1)
9216 (match_dup 2)))
9217 (clobber (reg:CC FLAGS_REG))])]
9218 "operands[0] = gen_lowpart (QImode, operands[0]);
9219 operands[1] = gen_lowpart (QImode, operands[1]);
9220 operands[2] = gen_lowpart (QImode, operands[2]);")
9221 \f
9222 ;; Logical XOR instructions
9223
9224 ;; %%% This used to optimize known byte-wide and operations to memory.
9225 ;; If this is considered useful, it should be done with splitters.
9226
9227 (define_expand "xordi3"
9228 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9229 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9230 (match_operand:DI 2 "x86_64_general_operand" "")))
9231 (clobber (reg:CC FLAGS_REG))]
9232 "TARGET_64BIT"
9233 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9234
9235 (define_insn "*xordi_1_rex64"
9236 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9237 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9238 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9239 (clobber (reg:CC FLAGS_REG))]
9240 "TARGET_64BIT
9241 && ix86_binary_operator_ok (XOR, DImode, operands)"
9242 "@
9243 xor{q}\t{%2, %0|%0, %2}
9244 xor{q}\t{%2, %0|%0, %2}"
9245 [(set_attr "type" "alu")
9246 (set_attr "mode" "DI,DI")])
9247
9248 (define_insn "*xordi_2_rex64"
9249 [(set (reg FLAGS_REG)
9250 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9251 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9252 (const_int 0)))
9253 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9254 (xor:DI (match_dup 1) (match_dup 2)))]
9255 "TARGET_64BIT
9256 && ix86_match_ccmode (insn, CCNOmode)
9257 && ix86_binary_operator_ok (XOR, DImode, operands)"
9258 "@
9259 xor{q}\t{%2, %0|%0, %2}
9260 xor{q}\t{%2, %0|%0, %2}"
9261 [(set_attr "type" "alu")
9262 (set_attr "mode" "DI,DI")])
9263
9264 (define_insn "*xordi_3_rex64"
9265 [(set (reg FLAGS_REG)
9266 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9267 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9268 (const_int 0)))
9269 (clobber (match_scratch:DI 0 "=r"))]
9270 "TARGET_64BIT
9271 && ix86_match_ccmode (insn, CCNOmode)
9272 && ix86_binary_operator_ok (XOR, DImode, operands)"
9273 "xor{q}\t{%2, %0|%0, %2}"
9274 [(set_attr "type" "alu")
9275 (set_attr "mode" "DI")])
9276
9277 (define_expand "xorsi3"
9278 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9279 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9280 (match_operand:SI 2 "general_operand" "")))
9281 (clobber (reg:CC FLAGS_REG))]
9282 ""
9283 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9284
9285 (define_insn "*xorsi_1"
9286 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9287 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9288 (match_operand:SI 2 "general_operand" "ri,rm")))
9289 (clobber (reg:CC FLAGS_REG))]
9290 "ix86_binary_operator_ok (XOR, SImode, operands)"
9291 "xor{l}\t{%2, %0|%0, %2}"
9292 [(set_attr "type" "alu")
9293 (set_attr "mode" "SI")])
9294
9295 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9296 ;; Add speccase for immediates
9297 (define_insn "*xorsi_1_zext"
9298 [(set (match_operand:DI 0 "register_operand" "=r")
9299 (zero_extend:DI
9300 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9301 (match_operand:SI 2 "general_operand" "rim"))))
9302 (clobber (reg:CC FLAGS_REG))]
9303 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9304 "xor{l}\t{%2, %k0|%k0, %2}"
9305 [(set_attr "type" "alu")
9306 (set_attr "mode" "SI")])
9307
9308 (define_insn "*xorsi_1_zext_imm"
9309 [(set (match_operand:DI 0 "register_operand" "=r")
9310 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9311 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9312 (clobber (reg:CC FLAGS_REG))]
9313 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9314 "xor{l}\t{%2, %k0|%k0, %2}"
9315 [(set_attr "type" "alu")
9316 (set_attr "mode" "SI")])
9317
9318 (define_insn "*xorsi_2"
9319 [(set (reg FLAGS_REG)
9320 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9321 (match_operand:SI 2 "general_operand" "rim,ri"))
9322 (const_int 0)))
9323 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9324 (xor:SI (match_dup 1) (match_dup 2)))]
9325 "ix86_match_ccmode (insn, CCNOmode)
9326 && ix86_binary_operator_ok (XOR, SImode, operands)"
9327 "xor{l}\t{%2, %0|%0, %2}"
9328 [(set_attr "type" "alu")
9329 (set_attr "mode" "SI")])
9330
9331 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9332 ;; ??? Special case for immediate operand is missing - it is tricky.
9333 (define_insn "*xorsi_2_zext"
9334 [(set (reg FLAGS_REG)
9335 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9336 (match_operand:SI 2 "general_operand" "rim"))
9337 (const_int 0)))
9338 (set (match_operand:DI 0 "register_operand" "=r")
9339 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9340 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9341 && ix86_binary_operator_ok (XOR, SImode, operands)"
9342 "xor{l}\t{%2, %k0|%k0, %2}"
9343 [(set_attr "type" "alu")
9344 (set_attr "mode" "SI")])
9345
9346 (define_insn "*xorsi_2_zext_imm"
9347 [(set (reg FLAGS_REG)
9348 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9349 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9350 (const_int 0)))
9351 (set (match_operand:DI 0 "register_operand" "=r")
9352 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9353 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9354 && ix86_binary_operator_ok (XOR, SImode, operands)"
9355 "xor{l}\t{%2, %k0|%k0, %2}"
9356 [(set_attr "type" "alu")
9357 (set_attr "mode" "SI")])
9358
9359 (define_insn "*xorsi_3"
9360 [(set (reg FLAGS_REG)
9361 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9362 (match_operand:SI 2 "general_operand" "rim"))
9363 (const_int 0)))
9364 (clobber (match_scratch:SI 0 "=r"))]
9365 "ix86_match_ccmode (insn, CCNOmode)
9366 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9367 "xor{l}\t{%2, %0|%0, %2}"
9368 [(set_attr "type" "alu")
9369 (set_attr "mode" "SI")])
9370
9371 (define_expand "xorhi3"
9372 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9373 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9374 (match_operand:HI 2 "general_operand" "")))
9375 (clobber (reg:CC FLAGS_REG))]
9376 "TARGET_HIMODE_MATH"
9377 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9378
9379 (define_insn "*xorhi_1"
9380 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9381 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9382 (match_operand:HI 2 "general_operand" "rmi,ri")))
9383 (clobber (reg:CC FLAGS_REG))]
9384 "ix86_binary_operator_ok (XOR, HImode, operands)"
9385 "xor{w}\t{%2, %0|%0, %2}"
9386 [(set_attr "type" "alu")
9387 (set_attr "mode" "HI")])
9388
9389 (define_insn "*xorhi_2"
9390 [(set (reg FLAGS_REG)
9391 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9392 (match_operand:HI 2 "general_operand" "rim,ri"))
9393 (const_int 0)))
9394 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9395 (xor:HI (match_dup 1) (match_dup 2)))]
9396 "ix86_match_ccmode (insn, CCNOmode)
9397 && ix86_binary_operator_ok (XOR, HImode, operands)"
9398 "xor{w}\t{%2, %0|%0, %2}"
9399 [(set_attr "type" "alu")
9400 (set_attr "mode" "HI")])
9401
9402 (define_insn "*xorhi_3"
9403 [(set (reg FLAGS_REG)
9404 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9405 (match_operand:HI 2 "general_operand" "rim"))
9406 (const_int 0)))
9407 (clobber (match_scratch:HI 0 "=r"))]
9408 "ix86_match_ccmode (insn, CCNOmode)
9409 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9410 "xor{w}\t{%2, %0|%0, %2}"
9411 [(set_attr "type" "alu")
9412 (set_attr "mode" "HI")])
9413
9414 (define_expand "xorqi3"
9415 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9416 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9417 (match_operand:QI 2 "general_operand" "")))
9418 (clobber (reg:CC FLAGS_REG))]
9419 "TARGET_QIMODE_MATH"
9420 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9421
9422 ;; %%% Potential partial reg stall on alternative 2. What to do?
9423 (define_insn "*xorqi_1"
9424 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9425 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9426 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9427 (clobber (reg:CC FLAGS_REG))]
9428 "ix86_binary_operator_ok (XOR, QImode, operands)"
9429 "@
9430 xor{b}\t{%2, %0|%0, %2}
9431 xor{b}\t{%2, %0|%0, %2}
9432 xor{l}\t{%k2, %k0|%k0, %k2}"
9433 [(set_attr "type" "alu")
9434 (set_attr "mode" "QI,QI,SI")])
9435
9436 (define_insn "*xorqi_1_slp"
9437 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9438 (xor:QI (match_dup 0)
9439 (match_operand:QI 1 "general_operand" "qi,qmi")))
9440 (clobber (reg:CC FLAGS_REG))]
9441 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9442 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9443 "xor{b}\t{%1, %0|%0, %1}"
9444 [(set_attr "type" "alu1")
9445 (set_attr "mode" "QI")])
9446
9447 (define_insn "xorqi_ext_0"
9448 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9449 (const_int 8)
9450 (const_int 8))
9451 (xor:SI
9452 (zero_extract:SI
9453 (match_operand 1 "ext_register_operand" "0")
9454 (const_int 8)
9455 (const_int 8))
9456 (match_operand 2 "const_int_operand" "n")))
9457 (clobber (reg:CC FLAGS_REG))]
9458 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9459 "xor{b}\t{%2, %h0|%h0, %2}"
9460 [(set_attr "type" "alu")
9461 (set_attr "length_immediate" "1")
9462 (set_attr "mode" "QI")])
9463
9464 (define_insn "*xorqi_ext_1"
9465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9466 (const_int 8)
9467 (const_int 8))
9468 (xor:SI
9469 (zero_extract:SI
9470 (match_operand 1 "ext_register_operand" "0")
9471 (const_int 8)
9472 (const_int 8))
9473 (zero_extend:SI
9474 (match_operand:QI 2 "general_operand" "Qm"))))
9475 (clobber (reg:CC FLAGS_REG))]
9476 "!TARGET_64BIT
9477 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9478 "xor{b}\t{%2, %h0|%h0, %2}"
9479 [(set_attr "type" "alu")
9480 (set_attr "length_immediate" "0")
9481 (set_attr "mode" "QI")])
9482
9483 (define_insn "*xorqi_ext_1_rex64"
9484 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9485 (const_int 8)
9486 (const_int 8))
9487 (xor:SI
9488 (zero_extract:SI
9489 (match_operand 1 "ext_register_operand" "0")
9490 (const_int 8)
9491 (const_int 8))
9492 (zero_extend:SI
9493 (match_operand 2 "ext_register_operand" "Q"))))
9494 (clobber (reg:CC FLAGS_REG))]
9495 "TARGET_64BIT
9496 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9497 "xor{b}\t{%2, %h0|%h0, %2}"
9498 [(set_attr "type" "alu")
9499 (set_attr "length_immediate" "0")
9500 (set_attr "mode" "QI")])
9501
9502 (define_insn "*xorqi_ext_2"
9503 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9504 (const_int 8)
9505 (const_int 8))
9506 (xor:SI
9507 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9508 (const_int 8)
9509 (const_int 8))
9510 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9511 (const_int 8)
9512 (const_int 8))))
9513 (clobber (reg:CC FLAGS_REG))]
9514 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9515 "xor{b}\t{%h2, %h0|%h0, %h2}"
9516 [(set_attr "type" "alu")
9517 (set_attr "length_immediate" "0")
9518 (set_attr "mode" "QI")])
9519
9520 (define_insn "*xorqi_cc_1"
9521 [(set (reg FLAGS_REG)
9522 (compare
9523 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9524 (match_operand:QI 2 "general_operand" "qim,qi"))
9525 (const_int 0)))
9526 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9527 (xor:QI (match_dup 1) (match_dup 2)))]
9528 "ix86_match_ccmode (insn, CCNOmode)
9529 && ix86_binary_operator_ok (XOR, QImode, operands)"
9530 "xor{b}\t{%2, %0|%0, %2}"
9531 [(set_attr "type" "alu")
9532 (set_attr "mode" "QI")])
9533
9534 (define_insn "*xorqi_2_slp"
9535 [(set (reg FLAGS_REG)
9536 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9537 (match_operand:QI 1 "general_operand" "qim,qi"))
9538 (const_int 0)))
9539 (set (strict_low_part (match_dup 0))
9540 (xor:QI (match_dup 0) (match_dup 1)))]
9541 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9542 && ix86_match_ccmode (insn, CCNOmode)
9543 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9544 "xor{b}\t{%1, %0|%0, %1}"
9545 [(set_attr "type" "alu1")
9546 (set_attr "mode" "QI")])
9547
9548 (define_insn "*xorqi_cc_2"
9549 [(set (reg FLAGS_REG)
9550 (compare
9551 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9552 (match_operand:QI 2 "general_operand" "qim"))
9553 (const_int 0)))
9554 (clobber (match_scratch:QI 0 "=q"))]
9555 "ix86_match_ccmode (insn, CCNOmode)
9556 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9557 "xor{b}\t{%2, %0|%0, %2}"
9558 [(set_attr "type" "alu")
9559 (set_attr "mode" "QI")])
9560
9561 (define_insn "*xorqi_cc_ext_1"
9562 [(set (reg FLAGS_REG)
9563 (compare
9564 (xor:SI
9565 (zero_extract:SI
9566 (match_operand 1 "ext_register_operand" "0")
9567 (const_int 8)
9568 (const_int 8))
9569 (match_operand:QI 2 "general_operand" "qmn"))
9570 (const_int 0)))
9571 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9572 (const_int 8)
9573 (const_int 8))
9574 (xor:SI
9575 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9576 (match_dup 2)))]
9577 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9578 "xor{b}\t{%2, %h0|%h0, %2}"
9579 [(set_attr "type" "alu")
9580 (set_attr "mode" "QI")])
9581
9582 (define_insn "*xorqi_cc_ext_1_rex64"
9583 [(set (reg FLAGS_REG)
9584 (compare
9585 (xor:SI
9586 (zero_extract:SI
9587 (match_operand 1 "ext_register_operand" "0")
9588 (const_int 8)
9589 (const_int 8))
9590 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9591 (const_int 0)))
9592 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9593 (const_int 8)
9594 (const_int 8))
9595 (xor:SI
9596 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9597 (match_dup 2)))]
9598 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9599 "xor{b}\t{%2, %h0|%h0, %2}"
9600 [(set_attr "type" "alu")
9601 (set_attr "mode" "QI")])
9602
9603 (define_expand "xorqi_cc_ext_1"
9604 [(parallel [
9605 (set (reg:CCNO FLAGS_REG)
9606 (compare:CCNO
9607 (xor:SI
9608 (zero_extract:SI
9609 (match_operand 1 "ext_register_operand" "")
9610 (const_int 8)
9611 (const_int 8))
9612 (match_operand:QI 2 "general_operand" ""))
9613 (const_int 0)))
9614 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9615 (const_int 8)
9616 (const_int 8))
9617 (xor:SI
9618 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9619 (match_dup 2)))])]
9620 ""
9621 "")
9622
9623 (define_split
9624 [(set (match_operand 0 "register_operand" "")
9625 (xor (match_operand 1 "register_operand" "")
9626 (match_operand 2 "const_int_operand" "")))
9627 (clobber (reg:CC FLAGS_REG))]
9628 "reload_completed
9629 && QI_REG_P (operands[0])
9630 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9631 && !(INTVAL (operands[2]) & ~(255 << 8))
9632 && GET_MODE (operands[0]) != QImode"
9633 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9634 (xor:SI (zero_extract:SI (match_dup 1)
9635 (const_int 8) (const_int 8))
9636 (match_dup 2)))
9637 (clobber (reg:CC FLAGS_REG))])]
9638 "operands[0] = gen_lowpart (SImode, operands[0]);
9639 operands[1] = gen_lowpart (SImode, operands[1]);
9640 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9641
9642 ;; Since XOR can be encoded with sign extended immediate, this is only
9643 ;; profitable when 7th bit is set.
9644 (define_split
9645 [(set (match_operand 0 "register_operand" "")
9646 (xor (match_operand 1 "general_operand" "")
9647 (match_operand 2 "const_int_operand" "")))
9648 (clobber (reg:CC FLAGS_REG))]
9649 "reload_completed
9650 && ANY_QI_REG_P (operands[0])
9651 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9652 && !(INTVAL (operands[2]) & ~255)
9653 && (INTVAL (operands[2]) & 128)
9654 && GET_MODE (operands[0]) != QImode"
9655 [(parallel [(set (strict_low_part (match_dup 0))
9656 (xor:QI (match_dup 1)
9657 (match_dup 2)))
9658 (clobber (reg:CC FLAGS_REG))])]
9659 "operands[0] = gen_lowpart (QImode, operands[0]);
9660 operands[1] = gen_lowpart (QImode, operands[1]);
9661 operands[2] = gen_lowpart (QImode, operands[2]);")
9662 \f
9663 ;; Negation instructions
9664
9665 (define_expand "negti2"
9666 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9667 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9668 (clobber (reg:CC FLAGS_REG))])]
9669 "TARGET_64BIT"
9670 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9671
9672 (define_insn "*negti2_1"
9673 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9674 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9675 (clobber (reg:CC FLAGS_REG))]
9676 "TARGET_64BIT
9677 && ix86_unary_operator_ok (NEG, TImode, operands)"
9678 "#")
9679
9680 (define_split
9681 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9682 (neg:TI (match_operand:TI 1 "general_operand" "")))
9683 (clobber (reg:CC FLAGS_REG))]
9684 "TARGET_64BIT && reload_completed"
9685 [(parallel
9686 [(set (reg:CCZ FLAGS_REG)
9687 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9688 (set (match_dup 0) (neg:DI (match_dup 2)))])
9689 (parallel
9690 [(set (match_dup 1)
9691 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9692 (match_dup 3))
9693 (const_int 0)))
9694 (clobber (reg:CC FLAGS_REG))])
9695 (parallel
9696 [(set (match_dup 1)
9697 (neg:DI (match_dup 1)))
9698 (clobber (reg:CC FLAGS_REG))])]
9699 "split_ti (operands+1, 1, operands+2, operands+3);
9700 split_ti (operands+0, 1, operands+0, operands+1);")
9701
9702 (define_expand "negdi2"
9703 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9704 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9705 (clobber (reg:CC FLAGS_REG))])]
9706 ""
9707 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9708
9709 (define_insn "*negdi2_1"
9710 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9711 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9712 (clobber (reg:CC FLAGS_REG))]
9713 "!TARGET_64BIT
9714 && ix86_unary_operator_ok (NEG, DImode, operands)"
9715 "#")
9716
9717 (define_split
9718 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9719 (neg:DI (match_operand:DI 1 "general_operand" "")))
9720 (clobber (reg:CC FLAGS_REG))]
9721 "!TARGET_64BIT && reload_completed"
9722 [(parallel
9723 [(set (reg:CCZ FLAGS_REG)
9724 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9725 (set (match_dup 0) (neg:SI (match_dup 2)))])
9726 (parallel
9727 [(set (match_dup 1)
9728 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9729 (match_dup 3))
9730 (const_int 0)))
9731 (clobber (reg:CC FLAGS_REG))])
9732 (parallel
9733 [(set (match_dup 1)
9734 (neg:SI (match_dup 1)))
9735 (clobber (reg:CC FLAGS_REG))])]
9736 "split_di (operands+1, 1, operands+2, operands+3);
9737 split_di (operands+0, 1, operands+0, operands+1);")
9738
9739 (define_insn "*negdi2_1_rex64"
9740 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9741 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9742 (clobber (reg:CC FLAGS_REG))]
9743 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9744 "neg{q}\t%0"
9745 [(set_attr "type" "negnot")
9746 (set_attr "mode" "DI")])
9747
9748 ;; The problem with neg is that it does not perform (compare x 0),
9749 ;; it really performs (compare 0 x), which leaves us with the zero
9750 ;; flag being the only useful item.
9751
9752 (define_insn "*negdi2_cmpz_rex64"
9753 [(set (reg:CCZ FLAGS_REG)
9754 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9755 (const_int 0)))
9756 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9757 (neg:DI (match_dup 1)))]
9758 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9759 "neg{q}\t%0"
9760 [(set_attr "type" "negnot")
9761 (set_attr "mode" "DI")])
9762
9763
9764 (define_expand "negsi2"
9765 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9766 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9767 (clobber (reg:CC FLAGS_REG))])]
9768 ""
9769 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9770
9771 (define_insn "*negsi2_1"
9772 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9773 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9774 (clobber (reg:CC FLAGS_REG))]
9775 "ix86_unary_operator_ok (NEG, SImode, operands)"
9776 "neg{l}\t%0"
9777 [(set_attr "type" "negnot")
9778 (set_attr "mode" "SI")])
9779
9780 ;; Combine is quite creative about this pattern.
9781 (define_insn "*negsi2_1_zext"
9782 [(set (match_operand:DI 0 "register_operand" "=r")
9783 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9784 (const_int 32)))
9785 (const_int 32)))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9788 "neg{l}\t%k0"
9789 [(set_attr "type" "negnot")
9790 (set_attr "mode" "SI")])
9791
9792 ;; The problem with neg is that it does not perform (compare x 0),
9793 ;; it really performs (compare 0 x), which leaves us with the zero
9794 ;; flag being the only useful item.
9795
9796 (define_insn "*negsi2_cmpz"
9797 [(set (reg:CCZ FLAGS_REG)
9798 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9799 (const_int 0)))
9800 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9801 (neg:SI (match_dup 1)))]
9802 "ix86_unary_operator_ok (NEG, SImode, operands)"
9803 "neg{l}\t%0"
9804 [(set_attr "type" "negnot")
9805 (set_attr "mode" "SI")])
9806
9807 (define_insn "*negsi2_cmpz_zext"
9808 [(set (reg:CCZ FLAGS_REG)
9809 (compare:CCZ (lshiftrt:DI
9810 (neg:DI (ashift:DI
9811 (match_operand:DI 1 "register_operand" "0")
9812 (const_int 32)))
9813 (const_int 32))
9814 (const_int 0)))
9815 (set (match_operand:DI 0 "register_operand" "=r")
9816 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9817 (const_int 32)))
9818 (const_int 32)))]
9819 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9820 "neg{l}\t%k0"
9821 [(set_attr "type" "negnot")
9822 (set_attr "mode" "SI")])
9823
9824 (define_expand "neghi2"
9825 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9826 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9827 (clobber (reg:CC FLAGS_REG))])]
9828 "TARGET_HIMODE_MATH"
9829 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9830
9831 (define_insn "*neghi2_1"
9832 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9833 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9834 (clobber (reg:CC FLAGS_REG))]
9835 "ix86_unary_operator_ok (NEG, HImode, operands)"
9836 "neg{w}\t%0"
9837 [(set_attr "type" "negnot")
9838 (set_attr "mode" "HI")])
9839
9840 (define_insn "*neghi2_cmpz"
9841 [(set (reg:CCZ FLAGS_REG)
9842 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9843 (const_int 0)))
9844 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9845 (neg:HI (match_dup 1)))]
9846 "ix86_unary_operator_ok (NEG, HImode, operands)"
9847 "neg{w}\t%0"
9848 [(set_attr "type" "negnot")
9849 (set_attr "mode" "HI")])
9850
9851 (define_expand "negqi2"
9852 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9853 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9854 (clobber (reg:CC FLAGS_REG))])]
9855 "TARGET_QIMODE_MATH"
9856 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9857
9858 (define_insn "*negqi2_1"
9859 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9860 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9861 (clobber (reg:CC FLAGS_REG))]
9862 "ix86_unary_operator_ok (NEG, QImode, operands)"
9863 "neg{b}\t%0"
9864 [(set_attr "type" "negnot")
9865 (set_attr "mode" "QI")])
9866
9867 (define_insn "*negqi2_cmpz"
9868 [(set (reg:CCZ FLAGS_REG)
9869 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9870 (const_int 0)))
9871 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9872 (neg:QI (match_dup 1)))]
9873 "ix86_unary_operator_ok (NEG, QImode, operands)"
9874 "neg{b}\t%0"
9875 [(set_attr "type" "negnot")
9876 (set_attr "mode" "QI")])
9877
9878 ;; Changing of sign for FP values is doable using integer unit too.
9879
9880 (define_expand "negsf2"
9881 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9882 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9883 "TARGET_80387 || TARGET_SSE_MATH"
9884 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9885
9886 (define_expand "abssf2"
9887 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9888 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9889 "TARGET_80387 || TARGET_SSE_MATH"
9890 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9891
9892 (define_insn "*absnegsf2_mixed"
9893 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9894 (match_operator:SF 3 "absneg_operator"
9895 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9896 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9897 (clobber (reg:CC FLAGS_REG))]
9898 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9899 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9900 "#")
9901
9902 (define_insn "*absnegsf2_sse"
9903 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9904 (match_operator:SF 3 "absneg_operator"
9905 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9906 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9907 (clobber (reg:CC FLAGS_REG))]
9908 "TARGET_SSE_MATH
9909 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9910 "#")
9911
9912 (define_insn "*absnegsf2_i387"
9913 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9914 (match_operator:SF 3 "absneg_operator"
9915 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9916 (use (match_operand 2 "" ""))
9917 (clobber (reg:CC FLAGS_REG))]
9918 "TARGET_80387 && !TARGET_SSE_MATH
9919 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9920 "#")
9921
9922 (define_expand "copysignsf3"
9923 [(match_operand:SF 0 "register_operand" "")
9924 (match_operand:SF 1 "nonmemory_operand" "")
9925 (match_operand:SF 2 "register_operand" "")]
9926 "TARGET_SSE_MATH"
9927 {
9928 ix86_expand_copysign (operands);
9929 DONE;
9930 })
9931
9932 (define_insn_and_split "copysignsf3_const"
9933 [(set (match_operand:SF 0 "register_operand" "=x")
9934 (unspec:SF
9935 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9936 (match_operand:SF 2 "register_operand" "0")
9937 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9938 UNSPEC_COPYSIGN))]
9939 "TARGET_SSE_MATH"
9940 "#"
9941 "&& reload_completed"
9942 [(const_int 0)]
9943 {
9944 ix86_split_copysign_const (operands);
9945 DONE;
9946 })
9947
9948 (define_insn "copysignsf3_var"
9949 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9950 (unspec:SF
9951 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9952 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9953 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9954 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9955 UNSPEC_COPYSIGN))
9956 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9957 "TARGET_SSE_MATH"
9958 "#")
9959
9960 (define_split
9961 [(set (match_operand:SF 0 "register_operand" "")
9962 (unspec:SF
9963 [(match_operand:SF 2 "register_operand" "")
9964 (match_operand:SF 3 "register_operand" "")
9965 (match_operand:V4SF 4 "" "")
9966 (match_operand:V4SF 5 "" "")]
9967 UNSPEC_COPYSIGN))
9968 (clobber (match_scratch:V4SF 1 ""))]
9969 "TARGET_SSE_MATH && reload_completed"
9970 [(const_int 0)]
9971 {
9972 ix86_split_copysign_var (operands);
9973 DONE;
9974 })
9975
9976 (define_expand "negdf2"
9977 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9978 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9979 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9980 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9981
9982 (define_expand "absdf2"
9983 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9984 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9985 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9986 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9987
9988 (define_insn "*absnegdf2_mixed"
9989 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
9990 (match_operator:DF 3 "absneg_operator"
9991 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9992 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
9993 (clobber (reg:CC FLAGS_REG))]
9994 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9995 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9996 "#")
9997
9998 (define_insn "*absnegdf2_sse"
9999 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
10000 (match_operator:DF 3 "absneg_operator"
10001 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10002 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
10003 (clobber (reg:CC FLAGS_REG))]
10004 "TARGET_SSE2 && TARGET_SSE_MATH
10005 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10006 "#")
10007
10008 (define_insn "*absnegdf2_i387"
10009 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10010 (match_operator:DF 3 "absneg_operator"
10011 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10012 (use (match_operand 2 "" ""))
10013 (clobber (reg:CC FLAGS_REG))]
10014 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10015 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10016 "#")
10017
10018 (define_expand "copysigndf3"
10019 [(match_operand:DF 0 "register_operand" "")
10020 (match_operand:DF 1 "nonmemory_operand" "")
10021 (match_operand:DF 2 "register_operand" "")]
10022 "TARGET_SSE2 && TARGET_SSE_MATH"
10023 {
10024 ix86_expand_copysign (operands);
10025 DONE;
10026 })
10027
10028 (define_insn_and_split "copysigndf3_const"
10029 [(set (match_operand:DF 0 "register_operand" "=x")
10030 (unspec:DF
10031 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
10032 (match_operand:DF 2 "register_operand" "0")
10033 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10034 UNSPEC_COPYSIGN))]
10035 "TARGET_SSE2 && TARGET_SSE_MATH"
10036 "#"
10037 "&& reload_completed"
10038 [(const_int 0)]
10039 {
10040 ix86_split_copysign_const (operands);
10041 DONE;
10042 })
10043
10044 (define_insn "copysigndf3_var"
10045 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
10046 (unspec:DF
10047 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
10048 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
10049 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10050 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10051 UNSPEC_COPYSIGN))
10052 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
10053 "TARGET_SSE2 && TARGET_SSE_MATH"
10054 "#")
10055
10056 (define_split
10057 [(set (match_operand:DF 0 "register_operand" "")
10058 (unspec:DF
10059 [(match_operand:DF 2 "register_operand" "")
10060 (match_operand:DF 3 "register_operand" "")
10061 (match_operand:V2DF 4 "" "")
10062 (match_operand:V2DF 5 "" "")]
10063 UNSPEC_COPYSIGN))
10064 (clobber (match_scratch:V2DF 1 ""))]
10065 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10066 [(const_int 0)]
10067 {
10068 ix86_split_copysign_var (operands);
10069 DONE;
10070 })
10071
10072 (define_expand "negxf2"
10073 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10074 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10075 "TARGET_80387"
10076 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10077
10078 (define_expand "absxf2"
10079 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10080 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10081 "TARGET_80387"
10082 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10083
10084 (define_insn "*absnegxf2_i387"
10085 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10086 (match_operator:XF 3 "absneg_operator"
10087 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10088 (use (match_operand 2 "" ""))
10089 (clobber (reg:CC FLAGS_REG))]
10090 "TARGET_80387
10091 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10092 "#")
10093
10094 ;; Splitters for fp abs and neg.
10095
10096 (define_split
10097 [(set (match_operand 0 "fp_register_operand" "")
10098 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10099 (use (match_operand 2 "" ""))
10100 (clobber (reg:CC FLAGS_REG))]
10101 "reload_completed"
10102 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10103
10104 (define_split
10105 [(set (match_operand 0 "register_operand" "")
10106 (match_operator 3 "absneg_operator"
10107 [(match_operand 1 "register_operand" "")]))
10108 (use (match_operand 2 "nonimmediate_operand" ""))
10109 (clobber (reg:CC FLAGS_REG))]
10110 "reload_completed && SSE_REG_P (operands[0])"
10111 [(set (match_dup 0) (match_dup 3))]
10112 {
10113 enum machine_mode mode = GET_MODE (operands[0]);
10114 enum machine_mode vmode = GET_MODE (operands[2]);
10115 rtx tmp;
10116
10117 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10118 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10119 if (operands_match_p (operands[0], operands[2]))
10120 {
10121 tmp = operands[1];
10122 operands[1] = operands[2];
10123 operands[2] = tmp;
10124 }
10125 if (GET_CODE (operands[3]) == ABS)
10126 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10127 else
10128 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10129 operands[3] = tmp;
10130 })
10131
10132 (define_split
10133 [(set (match_operand:SF 0 "register_operand" "")
10134 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10135 (use (match_operand:V4SF 2 "" ""))
10136 (clobber (reg:CC FLAGS_REG))]
10137 "reload_completed"
10138 [(parallel [(set (match_dup 0) (match_dup 1))
10139 (clobber (reg:CC FLAGS_REG))])]
10140 {
10141 rtx tmp;
10142 operands[0] = gen_lowpart (SImode, operands[0]);
10143 if (GET_CODE (operands[1]) == ABS)
10144 {
10145 tmp = gen_int_mode (0x7fffffff, SImode);
10146 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10147 }
10148 else
10149 {
10150 tmp = gen_int_mode (0x80000000, SImode);
10151 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10152 }
10153 operands[1] = tmp;
10154 })
10155
10156 (define_split
10157 [(set (match_operand:DF 0 "register_operand" "")
10158 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10159 (use (match_operand 2 "" ""))
10160 (clobber (reg:CC FLAGS_REG))]
10161 "reload_completed"
10162 [(parallel [(set (match_dup 0) (match_dup 1))
10163 (clobber (reg:CC FLAGS_REG))])]
10164 {
10165 rtx tmp;
10166 if (TARGET_64BIT)
10167 {
10168 tmp = gen_lowpart (DImode, operands[0]);
10169 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10170 operands[0] = tmp;
10171
10172 if (GET_CODE (operands[1]) == ABS)
10173 tmp = const0_rtx;
10174 else
10175 tmp = gen_rtx_NOT (DImode, tmp);
10176 }
10177 else
10178 {
10179 operands[0] = gen_highpart (SImode, operands[0]);
10180 if (GET_CODE (operands[1]) == ABS)
10181 {
10182 tmp = gen_int_mode (0x7fffffff, SImode);
10183 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10184 }
10185 else
10186 {
10187 tmp = gen_int_mode (0x80000000, SImode);
10188 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10189 }
10190 }
10191 operands[1] = tmp;
10192 })
10193
10194 (define_split
10195 [(set (match_operand:XF 0 "register_operand" "")
10196 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10197 (use (match_operand 2 "" ""))
10198 (clobber (reg:CC FLAGS_REG))]
10199 "reload_completed"
10200 [(parallel [(set (match_dup 0) (match_dup 1))
10201 (clobber (reg:CC FLAGS_REG))])]
10202 {
10203 rtx tmp;
10204 operands[0] = gen_rtx_REG (SImode,
10205 true_regnum (operands[0])
10206 + (TARGET_64BIT ? 1 : 2));
10207 if (GET_CODE (operands[1]) == ABS)
10208 {
10209 tmp = GEN_INT (0x7fff);
10210 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10211 }
10212 else
10213 {
10214 tmp = GEN_INT (0x8000);
10215 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10216 }
10217 operands[1] = tmp;
10218 })
10219
10220 (define_split
10221 [(set (match_operand 0 "memory_operand" "")
10222 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10223 (use (match_operand 2 "" ""))
10224 (clobber (reg:CC FLAGS_REG))]
10225 "reload_completed"
10226 [(parallel [(set (match_dup 0) (match_dup 1))
10227 (clobber (reg:CC FLAGS_REG))])]
10228 {
10229 enum machine_mode mode = GET_MODE (operands[0]);
10230 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10231 rtx tmp;
10232
10233 operands[0] = adjust_address (operands[0], QImode, size - 1);
10234 if (GET_CODE (operands[1]) == ABS)
10235 {
10236 tmp = gen_int_mode (0x7f, QImode);
10237 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10238 }
10239 else
10240 {
10241 tmp = gen_int_mode (0x80, QImode);
10242 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10243 }
10244 operands[1] = tmp;
10245 })
10246
10247 ;; Conditionalize these after reload. If they match before reload, we
10248 ;; lose the clobber and ability to use integer instructions.
10249
10250 (define_insn "*negsf2_1"
10251 [(set (match_operand:SF 0 "register_operand" "=f")
10252 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10253 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10254 "fchs"
10255 [(set_attr "type" "fsgn")
10256 (set_attr "mode" "SF")])
10257
10258 (define_insn "*negdf2_1"
10259 [(set (match_operand:DF 0 "register_operand" "=f")
10260 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10261 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10262 "fchs"
10263 [(set_attr "type" "fsgn")
10264 (set_attr "mode" "DF")])
10265
10266 (define_insn "*negxf2_1"
10267 [(set (match_operand:XF 0 "register_operand" "=f")
10268 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10269 "TARGET_80387"
10270 "fchs"
10271 [(set_attr "type" "fsgn")
10272 (set_attr "mode" "XF")])
10273
10274 (define_insn "*abssf2_1"
10275 [(set (match_operand:SF 0 "register_operand" "=f")
10276 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10277 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10278 "fabs"
10279 [(set_attr "type" "fsgn")
10280 (set_attr "mode" "SF")])
10281
10282 (define_insn "*absdf2_1"
10283 [(set (match_operand:DF 0 "register_operand" "=f")
10284 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10285 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10286 "fabs"
10287 [(set_attr "type" "fsgn")
10288 (set_attr "mode" "DF")])
10289
10290 (define_insn "*absxf2_1"
10291 [(set (match_operand:XF 0 "register_operand" "=f")
10292 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10293 "TARGET_80387"
10294 "fabs"
10295 [(set_attr "type" "fsgn")
10296 (set_attr "mode" "DF")])
10297
10298 (define_insn "*negextendsfdf2"
10299 [(set (match_operand:DF 0 "register_operand" "=f")
10300 (neg:DF (float_extend:DF
10301 (match_operand:SF 1 "register_operand" "0"))))]
10302 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10303 "fchs"
10304 [(set_attr "type" "fsgn")
10305 (set_attr "mode" "DF")])
10306
10307 (define_insn "*negextenddfxf2"
10308 [(set (match_operand:XF 0 "register_operand" "=f")
10309 (neg:XF (float_extend:XF
10310 (match_operand:DF 1 "register_operand" "0"))))]
10311 "TARGET_80387"
10312 "fchs"
10313 [(set_attr "type" "fsgn")
10314 (set_attr "mode" "XF")])
10315
10316 (define_insn "*negextendsfxf2"
10317 [(set (match_operand:XF 0 "register_operand" "=f")
10318 (neg:XF (float_extend:XF
10319 (match_operand:SF 1 "register_operand" "0"))))]
10320 "TARGET_80387"
10321 "fchs"
10322 [(set_attr "type" "fsgn")
10323 (set_attr "mode" "XF")])
10324
10325 (define_insn "*absextendsfdf2"
10326 [(set (match_operand:DF 0 "register_operand" "=f")
10327 (abs:DF (float_extend:DF
10328 (match_operand:SF 1 "register_operand" "0"))))]
10329 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10330 "fabs"
10331 [(set_attr "type" "fsgn")
10332 (set_attr "mode" "DF")])
10333
10334 (define_insn "*absextenddfxf2"
10335 [(set (match_operand:XF 0 "register_operand" "=f")
10336 (abs:XF (float_extend:XF
10337 (match_operand:DF 1 "register_operand" "0"))))]
10338 "TARGET_80387"
10339 "fabs"
10340 [(set_attr "type" "fsgn")
10341 (set_attr "mode" "XF")])
10342
10343 (define_insn "*absextendsfxf2"
10344 [(set (match_operand:XF 0 "register_operand" "=f")
10345 (abs:XF (float_extend:XF
10346 (match_operand:SF 1 "register_operand" "0"))))]
10347 "TARGET_80387"
10348 "fabs"
10349 [(set_attr "type" "fsgn")
10350 (set_attr "mode" "XF")])
10351 \f
10352 ;; One complement instructions
10353
10354 (define_expand "one_cmpldi2"
10355 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10356 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10357 "TARGET_64BIT"
10358 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10359
10360 (define_insn "*one_cmpldi2_1_rex64"
10361 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10362 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10363 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10364 "not{q}\t%0"
10365 [(set_attr "type" "negnot")
10366 (set_attr "mode" "DI")])
10367
10368 (define_insn "*one_cmpldi2_2_rex64"
10369 [(set (reg FLAGS_REG)
10370 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10371 (const_int 0)))
10372 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10373 (not:DI (match_dup 1)))]
10374 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10375 && ix86_unary_operator_ok (NOT, DImode, operands)"
10376 "#"
10377 [(set_attr "type" "alu1")
10378 (set_attr "mode" "DI")])
10379
10380 (define_split
10381 [(set (match_operand 0 "flags_reg_operand" "")
10382 (match_operator 2 "compare_operator"
10383 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10384 (const_int 0)]))
10385 (set (match_operand:DI 1 "nonimmediate_operand" "")
10386 (not:DI (match_dup 3)))]
10387 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10388 [(parallel [(set (match_dup 0)
10389 (match_op_dup 2
10390 [(xor:DI (match_dup 3) (const_int -1))
10391 (const_int 0)]))
10392 (set (match_dup 1)
10393 (xor:DI (match_dup 3) (const_int -1)))])]
10394 "")
10395
10396 (define_expand "one_cmplsi2"
10397 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10398 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10399 ""
10400 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10401
10402 (define_insn "*one_cmplsi2_1"
10403 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10404 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10405 "ix86_unary_operator_ok (NOT, SImode, operands)"
10406 "not{l}\t%0"
10407 [(set_attr "type" "negnot")
10408 (set_attr "mode" "SI")])
10409
10410 ;; ??? Currently never generated - xor is used instead.
10411 (define_insn "*one_cmplsi2_1_zext"
10412 [(set (match_operand:DI 0 "register_operand" "=r")
10413 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10414 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10415 "not{l}\t%k0"
10416 [(set_attr "type" "negnot")
10417 (set_attr "mode" "SI")])
10418
10419 (define_insn "*one_cmplsi2_2"
10420 [(set (reg FLAGS_REG)
10421 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10422 (const_int 0)))
10423 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10424 (not:SI (match_dup 1)))]
10425 "ix86_match_ccmode (insn, CCNOmode)
10426 && ix86_unary_operator_ok (NOT, SImode, operands)"
10427 "#"
10428 [(set_attr "type" "alu1")
10429 (set_attr "mode" "SI")])
10430
10431 (define_split
10432 [(set (match_operand 0 "flags_reg_operand" "")
10433 (match_operator 2 "compare_operator"
10434 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10435 (const_int 0)]))
10436 (set (match_operand:SI 1 "nonimmediate_operand" "")
10437 (not:SI (match_dup 3)))]
10438 "ix86_match_ccmode (insn, CCNOmode)"
10439 [(parallel [(set (match_dup 0)
10440 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10441 (const_int 0)]))
10442 (set (match_dup 1)
10443 (xor:SI (match_dup 3) (const_int -1)))])]
10444 "")
10445
10446 ;; ??? Currently never generated - xor is used instead.
10447 (define_insn "*one_cmplsi2_2_zext"
10448 [(set (reg FLAGS_REG)
10449 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10450 (const_int 0)))
10451 (set (match_operand:DI 0 "register_operand" "=r")
10452 (zero_extend:DI (not:SI (match_dup 1))))]
10453 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10454 && ix86_unary_operator_ok (NOT, SImode, operands)"
10455 "#"
10456 [(set_attr "type" "alu1")
10457 (set_attr "mode" "SI")])
10458
10459 (define_split
10460 [(set (match_operand 0 "flags_reg_operand" "")
10461 (match_operator 2 "compare_operator"
10462 [(not:SI (match_operand:SI 3 "register_operand" ""))
10463 (const_int 0)]))
10464 (set (match_operand:DI 1 "register_operand" "")
10465 (zero_extend:DI (not:SI (match_dup 3))))]
10466 "ix86_match_ccmode (insn, CCNOmode)"
10467 [(parallel [(set (match_dup 0)
10468 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10469 (const_int 0)]))
10470 (set (match_dup 1)
10471 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10472 "")
10473
10474 (define_expand "one_cmplhi2"
10475 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10476 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10477 "TARGET_HIMODE_MATH"
10478 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10479
10480 (define_insn "*one_cmplhi2_1"
10481 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10482 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10483 "ix86_unary_operator_ok (NOT, HImode, operands)"
10484 "not{w}\t%0"
10485 [(set_attr "type" "negnot")
10486 (set_attr "mode" "HI")])
10487
10488 (define_insn "*one_cmplhi2_2"
10489 [(set (reg FLAGS_REG)
10490 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10491 (const_int 0)))
10492 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10493 (not:HI (match_dup 1)))]
10494 "ix86_match_ccmode (insn, CCNOmode)
10495 && ix86_unary_operator_ok (NEG, HImode, operands)"
10496 "#"
10497 [(set_attr "type" "alu1")
10498 (set_attr "mode" "HI")])
10499
10500 (define_split
10501 [(set (match_operand 0 "flags_reg_operand" "")
10502 (match_operator 2 "compare_operator"
10503 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10504 (const_int 0)]))
10505 (set (match_operand:HI 1 "nonimmediate_operand" "")
10506 (not:HI (match_dup 3)))]
10507 "ix86_match_ccmode (insn, CCNOmode)"
10508 [(parallel [(set (match_dup 0)
10509 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10510 (const_int 0)]))
10511 (set (match_dup 1)
10512 (xor:HI (match_dup 3) (const_int -1)))])]
10513 "")
10514
10515 ;; %%% Potential partial reg stall on alternative 1. What to do?
10516 (define_expand "one_cmplqi2"
10517 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10518 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10519 "TARGET_QIMODE_MATH"
10520 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10521
10522 (define_insn "*one_cmplqi2_1"
10523 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10524 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10525 "ix86_unary_operator_ok (NOT, QImode, operands)"
10526 "@
10527 not{b}\t%0
10528 not{l}\t%k0"
10529 [(set_attr "type" "negnot")
10530 (set_attr "mode" "QI,SI")])
10531
10532 (define_insn "*one_cmplqi2_2"
10533 [(set (reg FLAGS_REG)
10534 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10535 (const_int 0)))
10536 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10537 (not:QI (match_dup 1)))]
10538 "ix86_match_ccmode (insn, CCNOmode)
10539 && ix86_unary_operator_ok (NOT, QImode, operands)"
10540 "#"
10541 [(set_attr "type" "alu1")
10542 (set_attr "mode" "QI")])
10543
10544 (define_split
10545 [(set (match_operand 0 "flags_reg_operand" "")
10546 (match_operator 2 "compare_operator"
10547 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10548 (const_int 0)]))
10549 (set (match_operand:QI 1 "nonimmediate_operand" "")
10550 (not:QI (match_dup 3)))]
10551 "ix86_match_ccmode (insn, CCNOmode)"
10552 [(parallel [(set (match_dup 0)
10553 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10554 (const_int 0)]))
10555 (set (match_dup 1)
10556 (xor:QI (match_dup 3) (const_int -1)))])]
10557 "")
10558 \f
10559 ;; Arithmetic shift instructions
10560
10561 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10562 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10563 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10564 ;; from the assembler input.
10565 ;;
10566 ;; This instruction shifts the target reg/mem as usual, but instead of
10567 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10568 ;; is a left shift double, bits are taken from the high order bits of
10569 ;; reg, else if the insn is a shift right double, bits are taken from the
10570 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10571 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10572 ;;
10573 ;; Since sh[lr]d does not change the `reg' operand, that is done
10574 ;; separately, making all shifts emit pairs of shift double and normal
10575 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10576 ;; support a 63 bit shift, each shift where the count is in a reg expands
10577 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10578 ;;
10579 ;; If the shift count is a constant, we need never emit more than one
10580 ;; shift pair, instead using moves and sign extension for counts greater
10581 ;; than 31.
10582
10583 (define_expand "ashlti3"
10584 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10585 (ashift:TI (match_operand:TI 1 "register_operand" "")
10586 (match_operand:QI 2 "nonmemory_operand" "")))
10587 (clobber (reg:CC FLAGS_REG))])]
10588 "TARGET_64BIT"
10589 {
10590 if (! immediate_operand (operands[2], QImode))
10591 {
10592 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10593 DONE;
10594 }
10595 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10596 DONE;
10597 })
10598
10599 (define_insn "ashlti3_1"
10600 [(set (match_operand:TI 0 "register_operand" "=r")
10601 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10602 (match_operand:QI 2 "register_operand" "c")))
10603 (clobber (match_scratch:DI 3 "=&r"))
10604 (clobber (reg:CC FLAGS_REG))]
10605 "TARGET_64BIT"
10606 "#"
10607 [(set_attr "type" "multi")])
10608
10609 (define_insn "*ashlti3_2"
10610 [(set (match_operand:TI 0 "register_operand" "=r")
10611 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10612 (match_operand:QI 2 "immediate_operand" "O")))
10613 (clobber (reg:CC FLAGS_REG))]
10614 "TARGET_64BIT"
10615 "#"
10616 [(set_attr "type" "multi")])
10617
10618 (define_split
10619 [(set (match_operand:TI 0 "register_operand" "")
10620 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10621 (match_operand:QI 2 "register_operand" "")))
10622 (clobber (match_scratch:DI 3 ""))
10623 (clobber (reg:CC FLAGS_REG))]
10624 "TARGET_64BIT && reload_completed"
10625 [(const_int 0)]
10626 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10627
10628 (define_split
10629 [(set (match_operand:TI 0 "register_operand" "")
10630 (ashift:TI (match_operand:TI 1 "register_operand" "")
10631 (match_operand:QI 2 "immediate_operand" "")))
10632 (clobber (reg:CC FLAGS_REG))]
10633 "TARGET_64BIT && reload_completed"
10634 [(const_int 0)]
10635 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10636
10637 (define_insn "x86_64_shld"
10638 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10639 (ior:DI (ashift:DI (match_dup 0)
10640 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10641 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10642 (minus:QI (const_int 64) (match_dup 2)))))
10643 (clobber (reg:CC FLAGS_REG))]
10644 "TARGET_64BIT"
10645 "@
10646 shld{q}\t{%2, %1, %0|%0, %1, %2}
10647 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10648 [(set_attr "type" "ishift")
10649 (set_attr "prefix_0f" "1")
10650 (set_attr "mode" "DI")
10651 (set_attr "athlon_decode" "vector")
10652 (set_attr "amdfam10_decode" "vector")])
10653
10654 (define_expand "x86_64_shift_adj"
10655 [(set (reg:CCZ FLAGS_REG)
10656 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10657 (const_int 64))
10658 (const_int 0)))
10659 (set (match_operand:DI 0 "register_operand" "")
10660 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10661 (match_operand:DI 1 "register_operand" "")
10662 (match_dup 0)))
10663 (set (match_dup 1)
10664 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10665 (match_operand:DI 3 "register_operand" "r")
10666 (match_dup 1)))]
10667 "TARGET_64BIT"
10668 "")
10669
10670 (define_expand "ashldi3"
10671 [(set (match_operand:DI 0 "shiftdi_operand" "")
10672 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10673 (match_operand:QI 2 "nonmemory_operand" "")))]
10674 ""
10675 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10676
10677 (define_insn "*ashldi3_1_rex64"
10678 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10679 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10680 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10681 (clobber (reg:CC FLAGS_REG))]
10682 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10683 {
10684 switch (get_attr_type (insn))
10685 {
10686 case TYPE_ALU:
10687 gcc_assert (operands[2] == const1_rtx);
10688 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10689 return "add{q}\t{%0, %0|%0, %0}";
10690
10691 case TYPE_LEA:
10692 gcc_assert (CONST_INT_P (operands[2]));
10693 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10694 operands[1] = gen_rtx_MULT (DImode, operands[1],
10695 GEN_INT (1 << INTVAL (operands[2])));
10696 return "lea{q}\t{%a1, %0|%0, %a1}";
10697
10698 default:
10699 if (REG_P (operands[2]))
10700 return "sal{q}\t{%b2, %0|%0, %b2}";
10701 else if (operands[2] == const1_rtx
10702 && (TARGET_SHIFT1 || optimize_size))
10703 return "sal{q}\t%0";
10704 else
10705 return "sal{q}\t{%2, %0|%0, %2}";
10706 }
10707 }
10708 [(set (attr "type")
10709 (cond [(eq_attr "alternative" "1")
10710 (const_string "lea")
10711 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10712 (const_int 0))
10713 (match_operand 0 "register_operand" ""))
10714 (match_operand 2 "const1_operand" ""))
10715 (const_string "alu")
10716 ]
10717 (const_string "ishift")))
10718 (set_attr "mode" "DI")])
10719
10720 ;; Convert lea to the lea pattern to avoid flags dependency.
10721 (define_split
10722 [(set (match_operand:DI 0 "register_operand" "")
10723 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10724 (match_operand:QI 2 "immediate_operand" "")))
10725 (clobber (reg:CC FLAGS_REG))]
10726 "TARGET_64BIT && reload_completed
10727 && true_regnum (operands[0]) != true_regnum (operands[1])"
10728 [(set (match_dup 0)
10729 (mult:DI (match_dup 1)
10730 (match_dup 2)))]
10731 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10732
10733 ;; This pattern can't accept a variable shift count, since shifts by
10734 ;; zero don't affect the flags. We assume that shifts by constant
10735 ;; zero are optimized away.
10736 (define_insn "*ashldi3_cmp_rex64"
10737 [(set (reg FLAGS_REG)
10738 (compare
10739 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10740 (match_operand:QI 2 "immediate_operand" "e"))
10741 (const_int 0)))
10742 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10743 (ashift:DI (match_dup 1) (match_dup 2)))]
10744 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10745 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10746 && (optimize_size
10747 || !TARGET_PARTIAL_FLAG_REG_STALL
10748 || (operands[2] == const1_rtx
10749 && (TARGET_SHIFT1
10750 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10751 {
10752 switch (get_attr_type (insn))
10753 {
10754 case TYPE_ALU:
10755 gcc_assert (operands[2] == const1_rtx);
10756 return "add{q}\t{%0, %0|%0, %0}";
10757
10758 default:
10759 if (REG_P (operands[2]))
10760 return "sal{q}\t{%b2, %0|%0, %b2}";
10761 else if (operands[2] == const1_rtx
10762 && (TARGET_SHIFT1 || optimize_size))
10763 return "sal{q}\t%0";
10764 else
10765 return "sal{q}\t{%2, %0|%0, %2}";
10766 }
10767 }
10768 [(set (attr "type")
10769 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10770 (const_int 0))
10771 (match_operand 0 "register_operand" ""))
10772 (match_operand 2 "const1_operand" ""))
10773 (const_string "alu")
10774 ]
10775 (const_string "ishift")))
10776 (set_attr "mode" "DI")])
10777
10778 (define_insn "*ashldi3_cconly_rex64"
10779 [(set (reg FLAGS_REG)
10780 (compare
10781 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10782 (match_operand:QI 2 "immediate_operand" "e"))
10783 (const_int 0)))
10784 (clobber (match_scratch:DI 0 "=r"))]
10785 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10786 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10787 && (optimize_size
10788 || !TARGET_PARTIAL_FLAG_REG_STALL
10789 || (operands[2] == const1_rtx
10790 && (TARGET_SHIFT1
10791 || TARGET_DOUBLE_WITH_ADD)))"
10792 {
10793 switch (get_attr_type (insn))
10794 {
10795 case TYPE_ALU:
10796 gcc_assert (operands[2] == const1_rtx);
10797 return "add{q}\t{%0, %0|%0, %0}";
10798
10799 default:
10800 if (REG_P (operands[2]))
10801 return "sal{q}\t{%b2, %0|%0, %b2}";
10802 else if (operands[2] == const1_rtx
10803 && (TARGET_SHIFT1 || optimize_size))
10804 return "sal{q}\t%0";
10805 else
10806 return "sal{q}\t{%2, %0|%0, %2}";
10807 }
10808 }
10809 [(set (attr "type")
10810 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10811 (const_int 0))
10812 (match_operand 0 "register_operand" ""))
10813 (match_operand 2 "const1_operand" ""))
10814 (const_string "alu")
10815 ]
10816 (const_string "ishift")))
10817 (set_attr "mode" "DI")])
10818
10819 (define_insn "*ashldi3_1"
10820 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10821 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10822 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10823 (clobber (reg:CC FLAGS_REG))]
10824 "!TARGET_64BIT"
10825 "#"
10826 [(set_attr "type" "multi")])
10827
10828 ;; By default we don't ask for a scratch register, because when DImode
10829 ;; values are manipulated, registers are already at a premium. But if
10830 ;; we have one handy, we won't turn it away.
10831 (define_peephole2
10832 [(match_scratch:SI 3 "r")
10833 (parallel [(set (match_operand:DI 0 "register_operand" "")
10834 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10835 (match_operand:QI 2 "nonmemory_operand" "")))
10836 (clobber (reg:CC FLAGS_REG))])
10837 (match_dup 3)]
10838 "!TARGET_64BIT && TARGET_CMOVE"
10839 [(const_int 0)]
10840 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10841
10842 (define_split
10843 [(set (match_operand:DI 0 "register_operand" "")
10844 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10845 (match_operand:QI 2 "nonmemory_operand" "")))
10846 (clobber (reg:CC FLAGS_REG))]
10847 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10848 ? flow2_completed : reload_completed)"
10849 [(const_int 0)]
10850 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10851
10852 (define_insn "x86_shld_1"
10853 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10854 (ior:SI (ashift:SI (match_dup 0)
10855 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10856 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10857 (minus:QI (const_int 32) (match_dup 2)))))
10858 (clobber (reg:CC FLAGS_REG))]
10859 ""
10860 "@
10861 shld{l}\t{%2, %1, %0|%0, %1, %2}
10862 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10863 [(set_attr "type" "ishift")
10864 (set_attr "prefix_0f" "1")
10865 (set_attr "mode" "SI")
10866 (set_attr "pent_pair" "np")
10867 (set_attr "athlon_decode" "vector")
10868 (set_attr "amdfam10_decode" "vector")])
10869
10870 (define_expand "x86_shift_adj_1"
10871 [(set (reg:CCZ FLAGS_REG)
10872 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10873 (const_int 32))
10874 (const_int 0)))
10875 (set (match_operand:SI 0 "register_operand" "")
10876 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10877 (match_operand:SI 1 "register_operand" "")
10878 (match_dup 0)))
10879 (set (match_dup 1)
10880 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10881 (match_operand:SI 3 "register_operand" "r")
10882 (match_dup 1)))]
10883 "TARGET_CMOVE"
10884 "")
10885
10886 (define_expand "x86_shift_adj_2"
10887 [(use (match_operand:SI 0 "register_operand" ""))
10888 (use (match_operand:SI 1 "register_operand" ""))
10889 (use (match_operand:QI 2 "register_operand" ""))]
10890 ""
10891 {
10892 rtx label = gen_label_rtx ();
10893 rtx tmp;
10894
10895 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10896
10897 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10898 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10899 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10900 gen_rtx_LABEL_REF (VOIDmode, label),
10901 pc_rtx);
10902 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10903 JUMP_LABEL (tmp) = label;
10904
10905 emit_move_insn (operands[0], operands[1]);
10906 ix86_expand_clear (operands[1]);
10907
10908 emit_label (label);
10909 LABEL_NUSES (label) = 1;
10910
10911 DONE;
10912 })
10913
10914 (define_expand "ashlsi3"
10915 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10916 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10917 (match_operand:QI 2 "nonmemory_operand" "")))
10918 (clobber (reg:CC FLAGS_REG))]
10919 ""
10920 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10921
10922 (define_insn "*ashlsi3_1"
10923 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10924 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10925 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10926 (clobber (reg:CC FLAGS_REG))]
10927 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10928 {
10929 switch (get_attr_type (insn))
10930 {
10931 case TYPE_ALU:
10932 gcc_assert (operands[2] == const1_rtx);
10933 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10934 return "add{l}\t{%0, %0|%0, %0}";
10935
10936 case TYPE_LEA:
10937 return "#";
10938
10939 default:
10940 if (REG_P (operands[2]))
10941 return "sal{l}\t{%b2, %0|%0, %b2}";
10942 else if (operands[2] == const1_rtx
10943 && (TARGET_SHIFT1 || optimize_size))
10944 return "sal{l}\t%0";
10945 else
10946 return "sal{l}\t{%2, %0|%0, %2}";
10947 }
10948 }
10949 [(set (attr "type")
10950 (cond [(eq_attr "alternative" "1")
10951 (const_string "lea")
10952 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10953 (const_int 0))
10954 (match_operand 0 "register_operand" ""))
10955 (match_operand 2 "const1_operand" ""))
10956 (const_string "alu")
10957 ]
10958 (const_string "ishift")))
10959 (set_attr "mode" "SI")])
10960
10961 ;; Convert lea to the lea pattern to avoid flags dependency.
10962 (define_split
10963 [(set (match_operand 0 "register_operand" "")
10964 (ashift (match_operand 1 "index_register_operand" "")
10965 (match_operand:QI 2 "const_int_operand" "")))
10966 (clobber (reg:CC FLAGS_REG))]
10967 "reload_completed
10968 && true_regnum (operands[0]) != true_regnum (operands[1])
10969 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10970 [(const_int 0)]
10971 {
10972 rtx pat;
10973 enum machine_mode mode = GET_MODE (operands[0]);
10974
10975 if (GET_MODE_SIZE (mode) < 4)
10976 operands[0] = gen_lowpart (SImode, operands[0]);
10977 if (mode != Pmode)
10978 operands[1] = gen_lowpart (Pmode, operands[1]);
10979 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10980
10981 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10982 if (Pmode != SImode)
10983 pat = gen_rtx_SUBREG (SImode, pat, 0);
10984 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10985 DONE;
10986 })
10987
10988 ;; Rare case of shifting RSP is handled by generating move and shift
10989 (define_split
10990 [(set (match_operand 0 "register_operand" "")
10991 (ashift (match_operand 1 "register_operand" "")
10992 (match_operand:QI 2 "const_int_operand" "")))
10993 (clobber (reg:CC FLAGS_REG))]
10994 "reload_completed
10995 && true_regnum (operands[0]) != true_regnum (operands[1])"
10996 [(const_int 0)]
10997 {
10998 rtx pat, clob;
10999 emit_move_insn (operands[0], operands[1]);
11000 pat = gen_rtx_SET (VOIDmode, operands[0],
11001 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11002 operands[0], operands[2]));
11003 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11004 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11005 DONE;
11006 })
11007
11008 (define_insn "*ashlsi3_1_zext"
11009 [(set (match_operand:DI 0 "register_operand" "=r,r")
11010 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11011 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11012 (clobber (reg:CC FLAGS_REG))]
11013 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11014 {
11015 switch (get_attr_type (insn))
11016 {
11017 case TYPE_ALU:
11018 gcc_assert (operands[2] == const1_rtx);
11019 return "add{l}\t{%k0, %k0|%k0, %k0}";
11020
11021 case TYPE_LEA:
11022 return "#";
11023
11024 default:
11025 if (REG_P (operands[2]))
11026 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11027 else if (operands[2] == const1_rtx
11028 && (TARGET_SHIFT1 || optimize_size))
11029 return "sal{l}\t%k0";
11030 else
11031 return "sal{l}\t{%2, %k0|%k0, %2}";
11032 }
11033 }
11034 [(set (attr "type")
11035 (cond [(eq_attr "alternative" "1")
11036 (const_string "lea")
11037 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11038 (const_int 0))
11039 (match_operand 2 "const1_operand" ""))
11040 (const_string "alu")
11041 ]
11042 (const_string "ishift")))
11043 (set_attr "mode" "SI")])
11044
11045 ;; Convert lea to the lea pattern to avoid flags dependency.
11046 (define_split
11047 [(set (match_operand:DI 0 "register_operand" "")
11048 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11049 (match_operand:QI 2 "const_int_operand" ""))))
11050 (clobber (reg:CC FLAGS_REG))]
11051 "TARGET_64BIT && reload_completed
11052 && true_regnum (operands[0]) != true_regnum (operands[1])"
11053 [(set (match_dup 0) (zero_extend:DI
11054 (subreg:SI (mult:SI (match_dup 1)
11055 (match_dup 2)) 0)))]
11056 {
11057 operands[1] = gen_lowpart (Pmode, operands[1]);
11058 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11059 })
11060
11061 ;; This pattern can't accept a variable shift count, since shifts by
11062 ;; zero don't affect the flags. We assume that shifts by constant
11063 ;; zero are optimized away.
11064 (define_insn "*ashlsi3_cmp"
11065 [(set (reg FLAGS_REG)
11066 (compare
11067 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11068 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11069 (const_int 0)))
11070 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11071 (ashift:SI (match_dup 1) (match_dup 2)))]
11072 "ix86_match_ccmode (insn, CCGOCmode)
11073 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11074 && (optimize_size
11075 || !TARGET_PARTIAL_FLAG_REG_STALL
11076 || (operands[2] == const1_rtx
11077 && (TARGET_SHIFT1
11078 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11079 {
11080 switch (get_attr_type (insn))
11081 {
11082 case TYPE_ALU:
11083 gcc_assert (operands[2] == const1_rtx);
11084 return "add{l}\t{%0, %0|%0, %0}";
11085
11086 default:
11087 if (REG_P (operands[2]))
11088 return "sal{l}\t{%b2, %0|%0, %b2}";
11089 else if (operands[2] == const1_rtx
11090 && (TARGET_SHIFT1 || optimize_size))
11091 return "sal{l}\t%0";
11092 else
11093 return "sal{l}\t{%2, %0|%0, %2}";
11094 }
11095 }
11096 [(set (attr "type")
11097 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11098 (const_int 0))
11099 (match_operand 0 "register_operand" ""))
11100 (match_operand 2 "const1_operand" ""))
11101 (const_string "alu")
11102 ]
11103 (const_string "ishift")))
11104 (set_attr "mode" "SI")])
11105
11106 (define_insn "*ashlsi3_cconly"
11107 [(set (reg FLAGS_REG)
11108 (compare
11109 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11110 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11111 (const_int 0)))
11112 (clobber (match_scratch:SI 0 "=r"))]
11113 "ix86_match_ccmode (insn, CCGOCmode)
11114 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11115 && (optimize_size
11116 || !TARGET_PARTIAL_FLAG_REG_STALL
11117 || (operands[2] == const1_rtx
11118 && (TARGET_SHIFT1
11119 || TARGET_DOUBLE_WITH_ADD)))"
11120 {
11121 switch (get_attr_type (insn))
11122 {
11123 case TYPE_ALU:
11124 gcc_assert (operands[2] == const1_rtx);
11125 return "add{l}\t{%0, %0|%0, %0}";
11126
11127 default:
11128 if (REG_P (operands[2]))
11129 return "sal{l}\t{%b2, %0|%0, %b2}";
11130 else if (operands[2] == const1_rtx
11131 && (TARGET_SHIFT1 || optimize_size))
11132 return "sal{l}\t%0";
11133 else
11134 return "sal{l}\t{%2, %0|%0, %2}";
11135 }
11136 }
11137 [(set (attr "type")
11138 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11139 (const_int 0))
11140 (match_operand 0 "register_operand" ""))
11141 (match_operand 2 "const1_operand" ""))
11142 (const_string "alu")
11143 ]
11144 (const_string "ishift")))
11145 (set_attr "mode" "SI")])
11146
11147 (define_insn "*ashlsi3_cmp_zext"
11148 [(set (reg FLAGS_REG)
11149 (compare
11150 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11151 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11152 (const_int 0)))
11153 (set (match_operand:DI 0 "register_operand" "=r")
11154 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11155 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11156 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11157 && (optimize_size
11158 || !TARGET_PARTIAL_FLAG_REG_STALL
11159 || (operands[2] == const1_rtx
11160 && (TARGET_SHIFT1
11161 || TARGET_DOUBLE_WITH_ADD)))"
11162 {
11163 switch (get_attr_type (insn))
11164 {
11165 case TYPE_ALU:
11166 gcc_assert (operands[2] == const1_rtx);
11167 return "add{l}\t{%k0, %k0|%k0, %k0}";
11168
11169 default:
11170 if (REG_P (operands[2]))
11171 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11172 else if (operands[2] == const1_rtx
11173 && (TARGET_SHIFT1 || optimize_size))
11174 return "sal{l}\t%k0";
11175 else
11176 return "sal{l}\t{%2, %k0|%k0, %2}";
11177 }
11178 }
11179 [(set (attr "type")
11180 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11181 (const_int 0))
11182 (match_operand 2 "const1_operand" ""))
11183 (const_string "alu")
11184 ]
11185 (const_string "ishift")))
11186 (set_attr "mode" "SI")])
11187
11188 (define_expand "ashlhi3"
11189 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11190 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11191 (match_operand:QI 2 "nonmemory_operand" "")))
11192 (clobber (reg:CC FLAGS_REG))]
11193 "TARGET_HIMODE_MATH"
11194 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11195
11196 (define_insn "*ashlhi3_1_lea"
11197 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11198 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11199 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11200 (clobber (reg:CC FLAGS_REG))]
11201 "!TARGET_PARTIAL_REG_STALL
11202 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11203 {
11204 switch (get_attr_type (insn))
11205 {
11206 case TYPE_LEA:
11207 return "#";
11208 case TYPE_ALU:
11209 gcc_assert (operands[2] == const1_rtx);
11210 return "add{w}\t{%0, %0|%0, %0}";
11211
11212 default:
11213 if (REG_P (operands[2]))
11214 return "sal{w}\t{%b2, %0|%0, %b2}";
11215 else if (operands[2] == const1_rtx
11216 && (TARGET_SHIFT1 || optimize_size))
11217 return "sal{w}\t%0";
11218 else
11219 return "sal{w}\t{%2, %0|%0, %2}";
11220 }
11221 }
11222 [(set (attr "type")
11223 (cond [(eq_attr "alternative" "1")
11224 (const_string "lea")
11225 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11226 (const_int 0))
11227 (match_operand 0 "register_operand" ""))
11228 (match_operand 2 "const1_operand" ""))
11229 (const_string "alu")
11230 ]
11231 (const_string "ishift")))
11232 (set_attr "mode" "HI,SI")])
11233
11234 (define_insn "*ashlhi3_1"
11235 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11236 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11237 (match_operand:QI 2 "nonmemory_operand" "cI")))
11238 (clobber (reg:CC FLAGS_REG))]
11239 "TARGET_PARTIAL_REG_STALL
11240 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11241 {
11242 switch (get_attr_type (insn))
11243 {
11244 case TYPE_ALU:
11245 gcc_assert (operands[2] == const1_rtx);
11246 return "add{w}\t{%0, %0|%0, %0}";
11247
11248 default:
11249 if (REG_P (operands[2]))
11250 return "sal{w}\t{%b2, %0|%0, %b2}";
11251 else if (operands[2] == const1_rtx
11252 && (TARGET_SHIFT1 || optimize_size))
11253 return "sal{w}\t%0";
11254 else
11255 return "sal{w}\t{%2, %0|%0, %2}";
11256 }
11257 }
11258 [(set (attr "type")
11259 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11260 (const_int 0))
11261 (match_operand 0 "register_operand" ""))
11262 (match_operand 2 "const1_operand" ""))
11263 (const_string "alu")
11264 ]
11265 (const_string "ishift")))
11266 (set_attr "mode" "HI")])
11267
11268 ;; This pattern can't accept a variable shift count, since shifts by
11269 ;; zero don't affect the flags. We assume that shifts by constant
11270 ;; zero are optimized away.
11271 (define_insn "*ashlhi3_cmp"
11272 [(set (reg FLAGS_REG)
11273 (compare
11274 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11275 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11276 (const_int 0)))
11277 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11278 (ashift:HI (match_dup 1) (match_dup 2)))]
11279 "ix86_match_ccmode (insn, CCGOCmode)
11280 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11281 && (optimize_size
11282 || !TARGET_PARTIAL_FLAG_REG_STALL
11283 || (operands[2] == const1_rtx
11284 && (TARGET_SHIFT1
11285 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11286 {
11287 switch (get_attr_type (insn))
11288 {
11289 case TYPE_ALU:
11290 gcc_assert (operands[2] == const1_rtx);
11291 return "add{w}\t{%0, %0|%0, %0}";
11292
11293 default:
11294 if (REG_P (operands[2]))
11295 return "sal{w}\t{%b2, %0|%0, %b2}";
11296 else if (operands[2] == const1_rtx
11297 && (TARGET_SHIFT1 || optimize_size))
11298 return "sal{w}\t%0";
11299 else
11300 return "sal{w}\t{%2, %0|%0, %2}";
11301 }
11302 }
11303 [(set (attr "type")
11304 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11305 (const_int 0))
11306 (match_operand 0 "register_operand" ""))
11307 (match_operand 2 "const1_operand" ""))
11308 (const_string "alu")
11309 ]
11310 (const_string "ishift")))
11311 (set_attr "mode" "HI")])
11312
11313 (define_insn "*ashlhi3_cconly"
11314 [(set (reg FLAGS_REG)
11315 (compare
11316 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11317 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11318 (const_int 0)))
11319 (clobber (match_scratch:HI 0 "=r"))]
11320 "ix86_match_ccmode (insn, CCGOCmode)
11321 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11322 && (optimize_size
11323 || !TARGET_PARTIAL_FLAG_REG_STALL
11324 || (operands[2] == const1_rtx
11325 && (TARGET_SHIFT1
11326 || TARGET_DOUBLE_WITH_ADD)))"
11327 {
11328 switch (get_attr_type (insn))
11329 {
11330 case TYPE_ALU:
11331 gcc_assert (operands[2] == const1_rtx);
11332 return "add{w}\t{%0, %0|%0, %0}";
11333
11334 default:
11335 if (REG_P (operands[2]))
11336 return "sal{w}\t{%b2, %0|%0, %b2}";
11337 else if (operands[2] == const1_rtx
11338 && (TARGET_SHIFT1 || optimize_size))
11339 return "sal{w}\t%0";
11340 else
11341 return "sal{w}\t{%2, %0|%0, %2}";
11342 }
11343 }
11344 [(set (attr "type")
11345 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11346 (const_int 0))
11347 (match_operand 0 "register_operand" ""))
11348 (match_operand 2 "const1_operand" ""))
11349 (const_string "alu")
11350 ]
11351 (const_string "ishift")))
11352 (set_attr "mode" "HI")])
11353
11354 (define_expand "ashlqi3"
11355 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11356 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11357 (match_operand:QI 2 "nonmemory_operand" "")))
11358 (clobber (reg:CC FLAGS_REG))]
11359 "TARGET_QIMODE_MATH"
11360 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11361
11362 ;; %%% Potential partial reg stall on alternative 2. What to do?
11363
11364 (define_insn "*ashlqi3_1_lea"
11365 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11366 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11367 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11368 (clobber (reg:CC FLAGS_REG))]
11369 "!TARGET_PARTIAL_REG_STALL
11370 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11371 {
11372 switch (get_attr_type (insn))
11373 {
11374 case TYPE_LEA:
11375 return "#";
11376 case TYPE_ALU:
11377 gcc_assert (operands[2] == const1_rtx);
11378 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11379 return "add{l}\t{%k0, %k0|%k0, %k0}";
11380 else
11381 return "add{b}\t{%0, %0|%0, %0}";
11382
11383 default:
11384 if (REG_P (operands[2]))
11385 {
11386 if (get_attr_mode (insn) == MODE_SI)
11387 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11388 else
11389 return "sal{b}\t{%b2, %0|%0, %b2}";
11390 }
11391 else if (operands[2] == const1_rtx
11392 && (TARGET_SHIFT1 || optimize_size))
11393 {
11394 if (get_attr_mode (insn) == MODE_SI)
11395 return "sal{l}\t%0";
11396 else
11397 return "sal{b}\t%0";
11398 }
11399 else
11400 {
11401 if (get_attr_mode (insn) == MODE_SI)
11402 return "sal{l}\t{%2, %k0|%k0, %2}";
11403 else
11404 return "sal{b}\t{%2, %0|%0, %2}";
11405 }
11406 }
11407 }
11408 [(set (attr "type")
11409 (cond [(eq_attr "alternative" "2")
11410 (const_string "lea")
11411 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11412 (const_int 0))
11413 (match_operand 0 "register_operand" ""))
11414 (match_operand 2 "const1_operand" ""))
11415 (const_string "alu")
11416 ]
11417 (const_string "ishift")))
11418 (set_attr "mode" "QI,SI,SI")])
11419
11420 (define_insn "*ashlqi3_1"
11421 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11422 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11423 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11424 (clobber (reg:CC FLAGS_REG))]
11425 "TARGET_PARTIAL_REG_STALL
11426 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11427 {
11428 switch (get_attr_type (insn))
11429 {
11430 case TYPE_ALU:
11431 gcc_assert (operands[2] == const1_rtx);
11432 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11433 return "add{l}\t{%k0, %k0|%k0, %k0}";
11434 else
11435 return "add{b}\t{%0, %0|%0, %0}";
11436
11437 default:
11438 if (REG_P (operands[2]))
11439 {
11440 if (get_attr_mode (insn) == MODE_SI)
11441 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11442 else
11443 return "sal{b}\t{%b2, %0|%0, %b2}";
11444 }
11445 else if (operands[2] == const1_rtx
11446 && (TARGET_SHIFT1 || optimize_size))
11447 {
11448 if (get_attr_mode (insn) == MODE_SI)
11449 return "sal{l}\t%0";
11450 else
11451 return "sal{b}\t%0";
11452 }
11453 else
11454 {
11455 if (get_attr_mode (insn) == MODE_SI)
11456 return "sal{l}\t{%2, %k0|%k0, %2}";
11457 else
11458 return "sal{b}\t{%2, %0|%0, %2}";
11459 }
11460 }
11461 }
11462 [(set (attr "type")
11463 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11464 (const_int 0))
11465 (match_operand 0 "register_operand" ""))
11466 (match_operand 2 "const1_operand" ""))
11467 (const_string "alu")
11468 ]
11469 (const_string "ishift")))
11470 (set_attr "mode" "QI,SI")])
11471
11472 ;; This pattern can't accept a variable shift count, since shifts by
11473 ;; zero don't affect the flags. We assume that shifts by constant
11474 ;; zero are optimized away.
11475 (define_insn "*ashlqi3_cmp"
11476 [(set (reg FLAGS_REG)
11477 (compare
11478 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11479 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11480 (const_int 0)))
11481 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11482 (ashift:QI (match_dup 1) (match_dup 2)))]
11483 "ix86_match_ccmode (insn, CCGOCmode)
11484 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11485 && (optimize_size
11486 || !TARGET_PARTIAL_FLAG_REG_STALL
11487 || (operands[2] == const1_rtx
11488 && (TARGET_SHIFT1
11489 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11490 {
11491 switch (get_attr_type (insn))
11492 {
11493 case TYPE_ALU:
11494 gcc_assert (operands[2] == const1_rtx);
11495 return "add{b}\t{%0, %0|%0, %0}";
11496
11497 default:
11498 if (REG_P (operands[2]))
11499 return "sal{b}\t{%b2, %0|%0, %b2}";
11500 else if (operands[2] == const1_rtx
11501 && (TARGET_SHIFT1 || optimize_size))
11502 return "sal{b}\t%0";
11503 else
11504 return "sal{b}\t{%2, %0|%0, %2}";
11505 }
11506 }
11507 [(set (attr "type")
11508 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11509 (const_int 0))
11510 (match_operand 0 "register_operand" ""))
11511 (match_operand 2 "const1_operand" ""))
11512 (const_string "alu")
11513 ]
11514 (const_string "ishift")))
11515 (set_attr "mode" "QI")])
11516
11517 (define_insn "*ashlqi3_cconly"
11518 [(set (reg FLAGS_REG)
11519 (compare
11520 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11521 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11522 (const_int 0)))
11523 (clobber (match_scratch:QI 0 "=q"))]
11524 "ix86_match_ccmode (insn, CCGOCmode)
11525 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11526 && (optimize_size
11527 || !TARGET_PARTIAL_FLAG_REG_STALL
11528 || (operands[2] == const1_rtx
11529 && (TARGET_SHIFT1
11530 || TARGET_DOUBLE_WITH_ADD)))"
11531 {
11532 switch (get_attr_type (insn))
11533 {
11534 case TYPE_ALU:
11535 gcc_assert (operands[2] == const1_rtx);
11536 return "add{b}\t{%0, %0|%0, %0}";
11537
11538 default:
11539 if (REG_P (operands[2]))
11540 return "sal{b}\t{%b2, %0|%0, %b2}";
11541 else if (operands[2] == const1_rtx
11542 && (TARGET_SHIFT1 || optimize_size))
11543 return "sal{b}\t%0";
11544 else
11545 return "sal{b}\t{%2, %0|%0, %2}";
11546 }
11547 }
11548 [(set (attr "type")
11549 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11550 (const_int 0))
11551 (match_operand 0 "register_operand" ""))
11552 (match_operand 2 "const1_operand" ""))
11553 (const_string "alu")
11554 ]
11555 (const_string "ishift")))
11556 (set_attr "mode" "QI")])
11557
11558 ;; See comment above `ashldi3' about how this works.
11559
11560 (define_expand "ashrti3"
11561 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11562 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11563 (match_operand:QI 2 "nonmemory_operand" "")))
11564 (clobber (reg:CC FLAGS_REG))])]
11565 "TARGET_64BIT"
11566 {
11567 if (! immediate_operand (operands[2], QImode))
11568 {
11569 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11570 DONE;
11571 }
11572 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11573 DONE;
11574 })
11575
11576 (define_insn "ashrti3_1"
11577 [(set (match_operand:TI 0 "register_operand" "=r")
11578 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11579 (match_operand:QI 2 "register_operand" "c")))
11580 (clobber (match_scratch:DI 3 "=&r"))
11581 (clobber (reg:CC FLAGS_REG))]
11582 "TARGET_64BIT"
11583 "#"
11584 [(set_attr "type" "multi")])
11585
11586 (define_insn "*ashrti3_2"
11587 [(set (match_operand:TI 0 "register_operand" "=r")
11588 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11589 (match_operand:QI 2 "immediate_operand" "O")))
11590 (clobber (reg:CC FLAGS_REG))]
11591 "TARGET_64BIT"
11592 "#"
11593 [(set_attr "type" "multi")])
11594
11595 (define_split
11596 [(set (match_operand:TI 0 "register_operand" "")
11597 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11598 (match_operand:QI 2 "register_operand" "")))
11599 (clobber (match_scratch:DI 3 ""))
11600 (clobber (reg:CC FLAGS_REG))]
11601 "TARGET_64BIT && reload_completed"
11602 [(const_int 0)]
11603 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11604
11605 (define_split
11606 [(set (match_operand:TI 0 "register_operand" "")
11607 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11608 (match_operand:QI 2 "immediate_operand" "")))
11609 (clobber (reg:CC FLAGS_REG))]
11610 "TARGET_64BIT && reload_completed"
11611 [(const_int 0)]
11612 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11613
11614 (define_insn "x86_64_shrd"
11615 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11616 (ior:DI (ashiftrt:DI (match_dup 0)
11617 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11618 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11619 (minus:QI (const_int 64) (match_dup 2)))))
11620 (clobber (reg:CC FLAGS_REG))]
11621 "TARGET_64BIT"
11622 "@
11623 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11624 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11625 [(set_attr "type" "ishift")
11626 (set_attr "prefix_0f" "1")
11627 (set_attr "mode" "DI")
11628 (set_attr "athlon_decode" "vector")
11629 (set_attr "amdfam10_decode" "vector")])
11630
11631 (define_expand "ashrdi3"
11632 [(set (match_operand:DI 0 "shiftdi_operand" "")
11633 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11634 (match_operand:QI 2 "nonmemory_operand" "")))]
11635 ""
11636 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11637
11638 (define_insn "*ashrdi3_63_rex64"
11639 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11640 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11641 (match_operand:DI 2 "const_int_operand" "i,i")))
11642 (clobber (reg:CC FLAGS_REG))]
11643 "TARGET_64BIT && INTVAL (operands[2]) == 63
11644 && (TARGET_USE_CLTD || optimize_size)
11645 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11646 "@
11647 {cqto|cqo}
11648 sar{q}\t{%2, %0|%0, %2}"
11649 [(set_attr "type" "imovx,ishift")
11650 (set_attr "prefix_0f" "0,*")
11651 (set_attr "length_immediate" "0,*")
11652 (set_attr "modrm" "0,1")
11653 (set_attr "mode" "DI")])
11654
11655 (define_insn "*ashrdi3_1_one_bit_rex64"
11656 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11657 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11658 (match_operand:QI 2 "const1_operand" "")))
11659 (clobber (reg:CC FLAGS_REG))]
11660 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11661 && (TARGET_SHIFT1 || optimize_size)"
11662 "sar{q}\t%0"
11663 [(set_attr "type" "ishift")
11664 (set (attr "length")
11665 (if_then_else (match_operand:DI 0 "register_operand" "")
11666 (const_string "2")
11667 (const_string "*")))])
11668
11669 (define_insn "*ashrdi3_1_rex64"
11670 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11671 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11672 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11673 (clobber (reg:CC FLAGS_REG))]
11674 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11675 "@
11676 sar{q}\t{%2, %0|%0, %2}
11677 sar{q}\t{%b2, %0|%0, %b2}"
11678 [(set_attr "type" "ishift")
11679 (set_attr "mode" "DI")])
11680
11681 ;; This pattern can't accept a variable shift count, since shifts by
11682 ;; zero don't affect the flags. We assume that shifts by constant
11683 ;; zero are optimized away.
11684 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11685 [(set (reg FLAGS_REG)
11686 (compare
11687 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11688 (match_operand:QI 2 "const1_operand" ""))
11689 (const_int 0)))
11690 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11691 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11692 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11693 && (TARGET_SHIFT1 || optimize_size)
11694 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11695 "sar{q}\t%0"
11696 [(set_attr "type" "ishift")
11697 (set (attr "length")
11698 (if_then_else (match_operand:DI 0 "register_operand" "")
11699 (const_string "2")
11700 (const_string "*")))])
11701
11702 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11703 [(set (reg FLAGS_REG)
11704 (compare
11705 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11706 (match_operand:QI 2 "const1_operand" ""))
11707 (const_int 0)))
11708 (clobber (match_scratch:DI 0 "=r"))]
11709 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11710 && (TARGET_SHIFT1 || optimize_size)
11711 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11712 "sar{q}\t%0"
11713 [(set_attr "type" "ishift")
11714 (set_attr "length" "2")])
11715
11716 ;; This pattern can't accept a variable shift count, since shifts by
11717 ;; zero don't affect the flags. We assume that shifts by constant
11718 ;; zero are optimized away.
11719 (define_insn "*ashrdi3_cmp_rex64"
11720 [(set (reg FLAGS_REG)
11721 (compare
11722 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11723 (match_operand:QI 2 "const_int_operand" "n"))
11724 (const_int 0)))
11725 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11726 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11727 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11728 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11729 && (optimize_size
11730 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11731 "sar{q}\t{%2, %0|%0, %2}"
11732 [(set_attr "type" "ishift")
11733 (set_attr "mode" "DI")])
11734
11735 (define_insn "*ashrdi3_cconly_rex64"
11736 [(set (reg FLAGS_REG)
11737 (compare
11738 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11739 (match_operand:QI 2 "const_int_operand" "n"))
11740 (const_int 0)))
11741 (clobber (match_scratch:DI 0 "=r"))]
11742 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11743 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11744 && (optimize_size
11745 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11746 "sar{q}\t{%2, %0|%0, %2}"
11747 [(set_attr "type" "ishift")
11748 (set_attr "mode" "DI")])
11749
11750 (define_insn "*ashrdi3_1"
11751 [(set (match_operand:DI 0 "register_operand" "=r")
11752 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11753 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11754 (clobber (reg:CC FLAGS_REG))]
11755 "!TARGET_64BIT"
11756 "#"
11757 [(set_attr "type" "multi")])
11758
11759 ;; By default we don't ask for a scratch register, because when DImode
11760 ;; values are manipulated, registers are already at a premium. But if
11761 ;; we have one handy, we won't turn it away.
11762 (define_peephole2
11763 [(match_scratch:SI 3 "r")
11764 (parallel [(set (match_operand:DI 0 "register_operand" "")
11765 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11766 (match_operand:QI 2 "nonmemory_operand" "")))
11767 (clobber (reg:CC FLAGS_REG))])
11768 (match_dup 3)]
11769 "!TARGET_64BIT && TARGET_CMOVE"
11770 [(const_int 0)]
11771 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11772
11773 (define_split
11774 [(set (match_operand:DI 0 "register_operand" "")
11775 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11776 (match_operand:QI 2 "nonmemory_operand" "")))
11777 (clobber (reg:CC FLAGS_REG))]
11778 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11779 ? flow2_completed : reload_completed)"
11780 [(const_int 0)]
11781 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11782
11783 (define_insn "x86_shrd_1"
11784 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11785 (ior:SI (ashiftrt:SI (match_dup 0)
11786 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11787 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11788 (minus:QI (const_int 32) (match_dup 2)))))
11789 (clobber (reg:CC FLAGS_REG))]
11790 ""
11791 "@
11792 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11793 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11794 [(set_attr "type" "ishift")
11795 (set_attr "prefix_0f" "1")
11796 (set_attr "pent_pair" "np")
11797 (set_attr "mode" "SI")])
11798
11799 (define_expand "x86_shift_adj_3"
11800 [(use (match_operand:SI 0 "register_operand" ""))
11801 (use (match_operand:SI 1 "register_operand" ""))
11802 (use (match_operand:QI 2 "register_operand" ""))]
11803 ""
11804 {
11805 rtx label = gen_label_rtx ();
11806 rtx tmp;
11807
11808 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11809
11810 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11811 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11812 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11813 gen_rtx_LABEL_REF (VOIDmode, label),
11814 pc_rtx);
11815 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11816 JUMP_LABEL (tmp) = label;
11817
11818 emit_move_insn (operands[0], operands[1]);
11819 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11820
11821 emit_label (label);
11822 LABEL_NUSES (label) = 1;
11823
11824 DONE;
11825 })
11826
11827 (define_insn "ashrsi3_31"
11828 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11829 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11830 (match_operand:SI 2 "const_int_operand" "i,i")))
11831 (clobber (reg:CC FLAGS_REG))]
11832 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11833 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11834 "@
11835 {cltd|cdq}
11836 sar{l}\t{%2, %0|%0, %2}"
11837 [(set_attr "type" "imovx,ishift")
11838 (set_attr "prefix_0f" "0,*")
11839 (set_attr "length_immediate" "0,*")
11840 (set_attr "modrm" "0,1")
11841 (set_attr "mode" "SI")])
11842
11843 (define_insn "*ashrsi3_31_zext"
11844 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11845 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11846 (match_operand:SI 2 "const_int_operand" "i,i"))))
11847 (clobber (reg:CC FLAGS_REG))]
11848 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11849 && INTVAL (operands[2]) == 31
11850 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11851 "@
11852 {cltd|cdq}
11853 sar{l}\t{%2, %k0|%k0, %2}"
11854 [(set_attr "type" "imovx,ishift")
11855 (set_attr "prefix_0f" "0,*")
11856 (set_attr "length_immediate" "0,*")
11857 (set_attr "modrm" "0,1")
11858 (set_attr "mode" "SI")])
11859
11860 (define_expand "ashrsi3"
11861 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11862 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11863 (match_operand:QI 2 "nonmemory_operand" "")))
11864 (clobber (reg:CC FLAGS_REG))]
11865 ""
11866 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11867
11868 (define_insn "*ashrsi3_1_one_bit"
11869 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11870 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11871 (match_operand:QI 2 "const1_operand" "")))
11872 (clobber (reg:CC FLAGS_REG))]
11873 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11874 && (TARGET_SHIFT1 || optimize_size)"
11875 "sar{l}\t%0"
11876 [(set_attr "type" "ishift")
11877 (set (attr "length")
11878 (if_then_else (match_operand:SI 0 "register_operand" "")
11879 (const_string "2")
11880 (const_string "*")))])
11881
11882 (define_insn "*ashrsi3_1_one_bit_zext"
11883 [(set (match_operand:DI 0 "register_operand" "=r")
11884 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11885 (match_operand:QI 2 "const1_operand" ""))))
11886 (clobber (reg:CC FLAGS_REG))]
11887 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11888 && (TARGET_SHIFT1 || optimize_size)"
11889 "sar{l}\t%k0"
11890 [(set_attr "type" "ishift")
11891 (set_attr "length" "2")])
11892
11893 (define_insn "*ashrsi3_1"
11894 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11895 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11896 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11897 (clobber (reg:CC FLAGS_REG))]
11898 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11899 "@
11900 sar{l}\t{%2, %0|%0, %2}
11901 sar{l}\t{%b2, %0|%0, %b2}"
11902 [(set_attr "type" "ishift")
11903 (set_attr "mode" "SI")])
11904
11905 (define_insn "*ashrsi3_1_zext"
11906 [(set (match_operand:DI 0 "register_operand" "=r,r")
11907 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11908 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11909 (clobber (reg:CC FLAGS_REG))]
11910 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11911 "@
11912 sar{l}\t{%2, %k0|%k0, %2}
11913 sar{l}\t{%b2, %k0|%k0, %b2}"
11914 [(set_attr "type" "ishift")
11915 (set_attr "mode" "SI")])
11916
11917 ;; This pattern can't accept a variable shift count, since shifts by
11918 ;; zero don't affect the flags. We assume that shifts by constant
11919 ;; zero are optimized away.
11920 (define_insn "*ashrsi3_one_bit_cmp"
11921 [(set (reg FLAGS_REG)
11922 (compare
11923 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11924 (match_operand:QI 2 "const1_operand" ""))
11925 (const_int 0)))
11926 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11927 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11928 "ix86_match_ccmode (insn, CCGOCmode)
11929 && (TARGET_SHIFT1 || optimize_size)
11930 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11931 "sar{l}\t%0"
11932 [(set_attr "type" "ishift")
11933 (set (attr "length")
11934 (if_then_else (match_operand:SI 0 "register_operand" "")
11935 (const_string "2")
11936 (const_string "*")))])
11937
11938 (define_insn "*ashrsi3_one_bit_cconly"
11939 [(set (reg FLAGS_REG)
11940 (compare
11941 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11942 (match_operand:QI 2 "const1_operand" ""))
11943 (const_int 0)))
11944 (clobber (match_scratch:SI 0 "=r"))]
11945 "ix86_match_ccmode (insn, CCGOCmode)
11946 && (TARGET_SHIFT1 || optimize_size)
11947 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11948 "sar{l}\t%0"
11949 [(set_attr "type" "ishift")
11950 (set_attr "length" "2")])
11951
11952 (define_insn "*ashrsi3_one_bit_cmp_zext"
11953 [(set (reg FLAGS_REG)
11954 (compare
11955 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11956 (match_operand:QI 2 "const1_operand" ""))
11957 (const_int 0)))
11958 (set (match_operand:DI 0 "register_operand" "=r")
11959 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11960 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11961 && (TARGET_SHIFT1 || optimize_size)
11962 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11963 "sar{l}\t%k0"
11964 [(set_attr "type" "ishift")
11965 (set_attr "length" "2")])
11966
11967 ;; This pattern can't accept a variable shift count, since shifts by
11968 ;; zero don't affect the flags. We assume that shifts by constant
11969 ;; zero are optimized away.
11970 (define_insn "*ashrsi3_cmp"
11971 [(set (reg FLAGS_REG)
11972 (compare
11973 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11974 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11975 (const_int 0)))
11976 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11977 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11978 "ix86_match_ccmode (insn, CCGOCmode)
11979 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11980 && (optimize_size
11981 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11982 "sar{l}\t{%2, %0|%0, %2}"
11983 [(set_attr "type" "ishift")
11984 (set_attr "mode" "SI")])
11985
11986 (define_insn "*ashrsi3_cconly"
11987 [(set (reg FLAGS_REG)
11988 (compare
11989 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11990 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11991 (const_int 0)))
11992 (clobber (match_scratch:SI 0 "=r"))]
11993 "ix86_match_ccmode (insn, CCGOCmode)
11994 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11995 && (optimize_size
11996 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11997 "sar{l}\t{%2, %0|%0, %2}"
11998 [(set_attr "type" "ishift")
11999 (set_attr "mode" "SI")])
12000
12001 (define_insn "*ashrsi3_cmp_zext"
12002 [(set (reg FLAGS_REG)
12003 (compare
12004 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12005 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12006 (const_int 0)))
12007 (set (match_operand:DI 0 "register_operand" "=r")
12008 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12009 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12010 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12011 && (optimize_size
12012 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12013 "sar{l}\t{%2, %k0|%k0, %2}"
12014 [(set_attr "type" "ishift")
12015 (set_attr "mode" "SI")])
12016
12017 (define_expand "ashrhi3"
12018 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12019 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12020 (match_operand:QI 2 "nonmemory_operand" "")))
12021 (clobber (reg:CC FLAGS_REG))]
12022 "TARGET_HIMODE_MATH"
12023 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12024
12025 (define_insn "*ashrhi3_1_one_bit"
12026 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12027 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12028 (match_operand:QI 2 "const1_operand" "")))
12029 (clobber (reg:CC FLAGS_REG))]
12030 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12031 && (TARGET_SHIFT1 || optimize_size)"
12032 "sar{w}\t%0"
12033 [(set_attr "type" "ishift")
12034 (set (attr "length")
12035 (if_then_else (match_operand 0 "register_operand" "")
12036 (const_string "2")
12037 (const_string "*")))])
12038
12039 (define_insn "*ashrhi3_1"
12040 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12041 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12042 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12043 (clobber (reg:CC FLAGS_REG))]
12044 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12045 "@
12046 sar{w}\t{%2, %0|%0, %2}
12047 sar{w}\t{%b2, %0|%0, %b2}"
12048 [(set_attr "type" "ishift")
12049 (set_attr "mode" "HI")])
12050
12051 ;; This pattern can't accept a variable shift count, since shifts by
12052 ;; zero don't affect the flags. We assume that shifts by constant
12053 ;; zero are optimized away.
12054 (define_insn "*ashrhi3_one_bit_cmp"
12055 [(set (reg FLAGS_REG)
12056 (compare
12057 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12058 (match_operand:QI 2 "const1_operand" ""))
12059 (const_int 0)))
12060 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12061 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12062 "ix86_match_ccmode (insn, CCGOCmode)
12063 && (TARGET_SHIFT1 || optimize_size)
12064 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12065 "sar{w}\t%0"
12066 [(set_attr "type" "ishift")
12067 (set (attr "length")
12068 (if_then_else (match_operand 0 "register_operand" "")
12069 (const_string "2")
12070 (const_string "*")))])
12071
12072 (define_insn "*ashrhi3_one_bit_cconly"
12073 [(set (reg FLAGS_REG)
12074 (compare
12075 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12076 (match_operand:QI 2 "const1_operand" ""))
12077 (const_int 0)))
12078 (clobber (match_scratch:HI 0 "=r"))]
12079 "ix86_match_ccmode (insn, CCGOCmode)
12080 && (TARGET_SHIFT1 || optimize_size)
12081 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12082 "sar{w}\t%0"
12083 [(set_attr "type" "ishift")
12084 (set_attr "length" "2")])
12085
12086 ;; This pattern can't accept a variable shift count, since shifts by
12087 ;; zero don't affect the flags. We assume that shifts by constant
12088 ;; zero are optimized away.
12089 (define_insn "*ashrhi3_cmp"
12090 [(set (reg FLAGS_REG)
12091 (compare
12092 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12093 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12094 (const_int 0)))
12095 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12096 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12097 "ix86_match_ccmode (insn, CCGOCmode)
12098 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12099 && (optimize_size
12100 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12101 "sar{w}\t{%2, %0|%0, %2}"
12102 [(set_attr "type" "ishift")
12103 (set_attr "mode" "HI")])
12104
12105 (define_insn "*ashrhi3_cconly"
12106 [(set (reg FLAGS_REG)
12107 (compare
12108 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12109 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12110 (const_int 0)))
12111 (clobber (match_scratch:HI 0 "=r"))]
12112 "ix86_match_ccmode (insn, CCGOCmode)
12113 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12114 && (optimize_size
12115 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12116 "sar{w}\t{%2, %0|%0, %2}"
12117 [(set_attr "type" "ishift")
12118 (set_attr "mode" "HI")])
12119
12120 (define_expand "ashrqi3"
12121 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12122 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12123 (match_operand:QI 2 "nonmemory_operand" "")))
12124 (clobber (reg:CC FLAGS_REG))]
12125 "TARGET_QIMODE_MATH"
12126 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12127
12128 (define_insn "*ashrqi3_1_one_bit"
12129 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12130 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12131 (match_operand:QI 2 "const1_operand" "")))
12132 (clobber (reg:CC FLAGS_REG))]
12133 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12134 && (TARGET_SHIFT1 || optimize_size)"
12135 "sar{b}\t%0"
12136 [(set_attr "type" "ishift")
12137 (set (attr "length")
12138 (if_then_else (match_operand 0 "register_operand" "")
12139 (const_string "2")
12140 (const_string "*")))])
12141
12142 (define_insn "*ashrqi3_1_one_bit_slp"
12143 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12144 (ashiftrt:QI (match_dup 0)
12145 (match_operand:QI 1 "const1_operand" "")))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12148 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12149 && (TARGET_SHIFT1 || optimize_size)"
12150 "sar{b}\t%0"
12151 [(set_attr "type" "ishift1")
12152 (set (attr "length")
12153 (if_then_else (match_operand 0 "register_operand" "")
12154 (const_string "2")
12155 (const_string "*")))])
12156
12157 (define_insn "*ashrqi3_1"
12158 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12159 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12160 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12161 (clobber (reg:CC FLAGS_REG))]
12162 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12163 "@
12164 sar{b}\t{%2, %0|%0, %2}
12165 sar{b}\t{%b2, %0|%0, %b2}"
12166 [(set_attr "type" "ishift")
12167 (set_attr "mode" "QI")])
12168
12169 (define_insn "*ashrqi3_1_slp"
12170 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12171 (ashiftrt:QI (match_dup 0)
12172 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12173 (clobber (reg:CC FLAGS_REG))]
12174 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12175 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12176 "@
12177 sar{b}\t{%1, %0|%0, %1}
12178 sar{b}\t{%b1, %0|%0, %b1}"
12179 [(set_attr "type" "ishift1")
12180 (set_attr "mode" "QI")])
12181
12182 ;; This pattern can't accept a variable shift count, since shifts by
12183 ;; zero don't affect the flags. We assume that shifts by constant
12184 ;; zero are optimized away.
12185 (define_insn "*ashrqi3_one_bit_cmp"
12186 [(set (reg FLAGS_REG)
12187 (compare
12188 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12189 (match_operand:QI 2 "const1_operand" "I"))
12190 (const_int 0)))
12191 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12192 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12193 "ix86_match_ccmode (insn, CCGOCmode)
12194 && (TARGET_SHIFT1 || optimize_size)
12195 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12196 "sar{b}\t%0"
12197 [(set_attr "type" "ishift")
12198 (set (attr "length")
12199 (if_then_else (match_operand 0 "register_operand" "")
12200 (const_string "2")
12201 (const_string "*")))])
12202
12203 (define_insn "*ashrqi3_one_bit_cconly"
12204 [(set (reg FLAGS_REG)
12205 (compare
12206 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12207 (match_operand:QI 2 "const1_operand" "I"))
12208 (const_int 0)))
12209 (clobber (match_scratch:QI 0 "=q"))]
12210 "ix86_match_ccmode (insn, CCGOCmode)
12211 && (TARGET_SHIFT1 || optimize_size)
12212 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12213 "sar{b}\t%0"
12214 [(set_attr "type" "ishift")
12215 (set_attr "length" "2")])
12216
12217 ;; This pattern can't accept a variable shift count, since shifts by
12218 ;; zero don't affect the flags. We assume that shifts by constant
12219 ;; zero are optimized away.
12220 (define_insn "*ashrqi3_cmp"
12221 [(set (reg FLAGS_REG)
12222 (compare
12223 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12224 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12225 (const_int 0)))
12226 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12227 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12228 "ix86_match_ccmode (insn, CCGOCmode)
12229 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12230 && (optimize_size
12231 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12232 "sar{b}\t{%2, %0|%0, %2}"
12233 [(set_attr "type" "ishift")
12234 (set_attr "mode" "QI")])
12235
12236 (define_insn "*ashrqi3_cconly"
12237 [(set (reg FLAGS_REG)
12238 (compare
12239 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12240 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12241 (const_int 0)))
12242 (clobber (match_scratch:QI 0 "=q"))]
12243 "ix86_match_ccmode (insn, CCGOCmode)
12244 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12245 && (optimize_size
12246 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12247 "sar{b}\t{%2, %0|%0, %2}"
12248 [(set_attr "type" "ishift")
12249 (set_attr "mode" "QI")])
12250
12251 \f
12252 ;; Logical shift instructions
12253
12254 ;; See comment above `ashldi3' about how this works.
12255
12256 (define_expand "lshrti3"
12257 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12258 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12259 (match_operand:QI 2 "nonmemory_operand" "")))
12260 (clobber (reg:CC FLAGS_REG))])]
12261 "TARGET_64BIT"
12262 {
12263 if (! immediate_operand (operands[2], QImode))
12264 {
12265 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12266 DONE;
12267 }
12268 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12269 DONE;
12270 })
12271
12272 (define_insn "lshrti3_1"
12273 [(set (match_operand:TI 0 "register_operand" "=r")
12274 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12275 (match_operand:QI 2 "register_operand" "c")))
12276 (clobber (match_scratch:DI 3 "=&r"))
12277 (clobber (reg:CC FLAGS_REG))]
12278 "TARGET_64BIT"
12279 "#"
12280 [(set_attr "type" "multi")])
12281
12282 (define_insn "*lshrti3_2"
12283 [(set (match_operand:TI 0 "register_operand" "=r")
12284 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12285 (match_operand:QI 2 "immediate_operand" "O")))
12286 (clobber (reg:CC FLAGS_REG))]
12287 "TARGET_64BIT"
12288 "#"
12289 [(set_attr "type" "multi")])
12290
12291 (define_split
12292 [(set (match_operand:TI 0 "register_operand" "")
12293 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12294 (match_operand:QI 2 "register_operand" "")))
12295 (clobber (match_scratch:DI 3 ""))
12296 (clobber (reg:CC FLAGS_REG))]
12297 "TARGET_64BIT && reload_completed"
12298 [(const_int 0)]
12299 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12300
12301 (define_split
12302 [(set (match_operand:TI 0 "register_operand" "")
12303 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12304 (match_operand:QI 2 "immediate_operand" "")))
12305 (clobber (reg:CC FLAGS_REG))]
12306 "TARGET_64BIT && reload_completed"
12307 [(const_int 0)]
12308 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12309
12310 (define_expand "lshrdi3"
12311 [(set (match_operand:DI 0 "shiftdi_operand" "")
12312 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12313 (match_operand:QI 2 "nonmemory_operand" "")))]
12314 ""
12315 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12316
12317 (define_insn "*lshrdi3_1_one_bit_rex64"
12318 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12319 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12320 (match_operand:QI 2 "const1_operand" "")))
12321 (clobber (reg:CC FLAGS_REG))]
12322 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12323 && (TARGET_SHIFT1 || optimize_size)"
12324 "shr{q}\t%0"
12325 [(set_attr "type" "ishift")
12326 (set (attr "length")
12327 (if_then_else (match_operand:DI 0 "register_operand" "")
12328 (const_string "2")
12329 (const_string "*")))])
12330
12331 (define_insn "*lshrdi3_1_rex64"
12332 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12333 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12334 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12335 (clobber (reg:CC FLAGS_REG))]
12336 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12337 "@
12338 shr{q}\t{%2, %0|%0, %2}
12339 shr{q}\t{%b2, %0|%0, %b2}"
12340 [(set_attr "type" "ishift")
12341 (set_attr "mode" "DI")])
12342
12343 ;; This pattern can't accept a variable shift count, since shifts by
12344 ;; zero don't affect the flags. We assume that shifts by constant
12345 ;; zero are optimized away.
12346 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12347 [(set (reg FLAGS_REG)
12348 (compare
12349 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12350 (match_operand:QI 2 "const1_operand" ""))
12351 (const_int 0)))
12352 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12353 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12354 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12355 && (TARGET_SHIFT1 || optimize_size)
12356 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12357 "shr{q}\t%0"
12358 [(set_attr "type" "ishift")
12359 (set (attr "length")
12360 (if_then_else (match_operand:DI 0 "register_operand" "")
12361 (const_string "2")
12362 (const_string "*")))])
12363
12364 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12365 [(set (reg FLAGS_REG)
12366 (compare
12367 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const1_operand" ""))
12369 (const_int 0)))
12370 (clobber (match_scratch:DI 0 "=r"))]
12371 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12372 && (TARGET_SHIFT1 || optimize_size)
12373 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12374 "shr{q}\t%0"
12375 [(set_attr "type" "ishift")
12376 (set_attr "length" "2")])
12377
12378 ;; This pattern can't accept a variable shift count, since shifts by
12379 ;; zero don't affect the flags. We assume that shifts by constant
12380 ;; zero are optimized away.
12381 (define_insn "*lshrdi3_cmp_rex64"
12382 [(set (reg FLAGS_REG)
12383 (compare
12384 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12385 (match_operand:QI 2 "const_int_operand" "e"))
12386 (const_int 0)))
12387 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12388 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12389 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12390 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12391 && (optimize_size
12392 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12393 "shr{q}\t{%2, %0|%0, %2}"
12394 [(set_attr "type" "ishift")
12395 (set_attr "mode" "DI")])
12396
12397 (define_insn "*lshrdi3_cconly_rex64"
12398 [(set (reg FLAGS_REG)
12399 (compare
12400 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12401 (match_operand:QI 2 "const_int_operand" "e"))
12402 (const_int 0)))
12403 (clobber (match_scratch:DI 0 "=r"))]
12404 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12405 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12406 && (optimize_size
12407 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12408 "shr{q}\t{%2, %0|%0, %2}"
12409 [(set_attr "type" "ishift")
12410 (set_attr "mode" "DI")])
12411
12412 (define_insn "*lshrdi3_1"
12413 [(set (match_operand:DI 0 "register_operand" "=r")
12414 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12415 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12416 (clobber (reg:CC FLAGS_REG))]
12417 "!TARGET_64BIT"
12418 "#"
12419 [(set_attr "type" "multi")])
12420
12421 ;; By default we don't ask for a scratch register, because when DImode
12422 ;; values are manipulated, registers are already at a premium. But if
12423 ;; we have one handy, we won't turn it away.
12424 (define_peephole2
12425 [(match_scratch:SI 3 "r")
12426 (parallel [(set (match_operand:DI 0 "register_operand" "")
12427 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12428 (match_operand:QI 2 "nonmemory_operand" "")))
12429 (clobber (reg:CC FLAGS_REG))])
12430 (match_dup 3)]
12431 "!TARGET_64BIT && TARGET_CMOVE"
12432 [(const_int 0)]
12433 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12434
12435 (define_split
12436 [(set (match_operand:DI 0 "register_operand" "")
12437 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12438 (match_operand:QI 2 "nonmemory_operand" "")))
12439 (clobber (reg:CC FLAGS_REG))]
12440 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12441 ? flow2_completed : reload_completed)"
12442 [(const_int 0)]
12443 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12444
12445 (define_expand "lshrsi3"
12446 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12447 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12448 (match_operand:QI 2 "nonmemory_operand" "")))
12449 (clobber (reg:CC FLAGS_REG))]
12450 ""
12451 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12452
12453 (define_insn "*lshrsi3_1_one_bit"
12454 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12455 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12456 (match_operand:QI 2 "const1_operand" "")))
12457 (clobber (reg:CC FLAGS_REG))]
12458 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12459 && (TARGET_SHIFT1 || optimize_size)"
12460 "shr{l}\t%0"
12461 [(set_attr "type" "ishift")
12462 (set (attr "length")
12463 (if_then_else (match_operand:SI 0 "register_operand" "")
12464 (const_string "2")
12465 (const_string "*")))])
12466
12467 (define_insn "*lshrsi3_1_one_bit_zext"
12468 [(set (match_operand:DI 0 "register_operand" "=r")
12469 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12470 (match_operand:QI 2 "const1_operand" "")))
12471 (clobber (reg:CC FLAGS_REG))]
12472 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12473 && (TARGET_SHIFT1 || optimize_size)"
12474 "shr{l}\t%k0"
12475 [(set_attr "type" "ishift")
12476 (set_attr "length" "2")])
12477
12478 (define_insn "*lshrsi3_1"
12479 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12480 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12481 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12482 (clobber (reg:CC FLAGS_REG))]
12483 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12484 "@
12485 shr{l}\t{%2, %0|%0, %2}
12486 shr{l}\t{%b2, %0|%0, %b2}"
12487 [(set_attr "type" "ishift")
12488 (set_attr "mode" "SI")])
12489
12490 (define_insn "*lshrsi3_1_zext"
12491 [(set (match_operand:DI 0 "register_operand" "=r,r")
12492 (zero_extend:DI
12493 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12494 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12495 (clobber (reg:CC FLAGS_REG))]
12496 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12497 "@
12498 shr{l}\t{%2, %k0|%k0, %2}
12499 shr{l}\t{%b2, %k0|%k0, %b2}"
12500 [(set_attr "type" "ishift")
12501 (set_attr "mode" "SI")])
12502
12503 ;; This pattern can't accept a variable shift count, since shifts by
12504 ;; zero don't affect the flags. We assume that shifts by constant
12505 ;; zero are optimized away.
12506 (define_insn "*lshrsi3_one_bit_cmp"
12507 [(set (reg FLAGS_REG)
12508 (compare
12509 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12510 (match_operand:QI 2 "const1_operand" ""))
12511 (const_int 0)))
12512 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12513 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12514 "ix86_match_ccmode (insn, CCGOCmode)
12515 && (TARGET_SHIFT1 || optimize_size)
12516 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12517 "shr{l}\t%0"
12518 [(set_attr "type" "ishift")
12519 (set (attr "length")
12520 (if_then_else (match_operand:SI 0 "register_operand" "")
12521 (const_string "2")
12522 (const_string "*")))])
12523
12524 (define_insn "*lshrsi3_one_bit_cconly"
12525 [(set (reg FLAGS_REG)
12526 (compare
12527 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12528 (match_operand:QI 2 "const1_operand" ""))
12529 (const_int 0)))
12530 (clobber (match_scratch:SI 0 "=r"))]
12531 "ix86_match_ccmode (insn, CCGOCmode)
12532 && (TARGET_SHIFT1 || optimize_size)
12533 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12534 "shr{l}\t%0"
12535 [(set_attr "type" "ishift")
12536 (set_attr "length" "2")])
12537
12538 (define_insn "*lshrsi3_cmp_one_bit_zext"
12539 [(set (reg FLAGS_REG)
12540 (compare
12541 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12542 (match_operand:QI 2 "const1_operand" ""))
12543 (const_int 0)))
12544 (set (match_operand:DI 0 "register_operand" "=r")
12545 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12546 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12547 && (TARGET_SHIFT1 || optimize_size)
12548 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12549 "shr{l}\t%k0"
12550 [(set_attr "type" "ishift")
12551 (set_attr "length" "2")])
12552
12553 ;; This pattern can't accept a variable shift count, since shifts by
12554 ;; zero don't affect the flags. We assume that shifts by constant
12555 ;; zero are optimized away.
12556 (define_insn "*lshrsi3_cmp"
12557 [(set (reg FLAGS_REG)
12558 (compare
12559 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12560 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12561 (const_int 0)))
12562 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12563 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12564 "ix86_match_ccmode (insn, CCGOCmode)
12565 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12566 && (optimize_size
12567 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12568 "shr{l}\t{%2, %0|%0, %2}"
12569 [(set_attr "type" "ishift")
12570 (set_attr "mode" "SI")])
12571
12572 (define_insn "*lshrsi3_cconly"
12573 [(set (reg FLAGS_REG)
12574 (compare
12575 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12576 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12577 (const_int 0)))
12578 (clobber (match_scratch:SI 0 "=r"))]
12579 "ix86_match_ccmode (insn, CCGOCmode)
12580 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12581 && (optimize_size
12582 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12583 "shr{l}\t{%2, %0|%0, %2}"
12584 [(set_attr "type" "ishift")
12585 (set_attr "mode" "SI")])
12586
12587 (define_insn "*lshrsi3_cmp_zext"
12588 [(set (reg FLAGS_REG)
12589 (compare
12590 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12591 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12592 (const_int 0)))
12593 (set (match_operand:DI 0 "register_operand" "=r")
12594 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12595 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12596 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12597 && (optimize_size
12598 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12599 "shr{l}\t{%2, %k0|%k0, %2}"
12600 [(set_attr "type" "ishift")
12601 (set_attr "mode" "SI")])
12602
12603 (define_expand "lshrhi3"
12604 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12605 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12606 (match_operand:QI 2 "nonmemory_operand" "")))
12607 (clobber (reg:CC FLAGS_REG))]
12608 "TARGET_HIMODE_MATH"
12609 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12610
12611 (define_insn "*lshrhi3_1_one_bit"
12612 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12613 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12614 (match_operand:QI 2 "const1_operand" "")))
12615 (clobber (reg:CC FLAGS_REG))]
12616 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12617 && (TARGET_SHIFT1 || optimize_size)"
12618 "shr{w}\t%0"
12619 [(set_attr "type" "ishift")
12620 (set (attr "length")
12621 (if_then_else (match_operand 0 "register_operand" "")
12622 (const_string "2")
12623 (const_string "*")))])
12624
12625 (define_insn "*lshrhi3_1"
12626 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12627 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12628 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12629 (clobber (reg:CC FLAGS_REG))]
12630 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12631 "@
12632 shr{w}\t{%2, %0|%0, %2}
12633 shr{w}\t{%b2, %0|%0, %b2}"
12634 [(set_attr "type" "ishift")
12635 (set_attr "mode" "HI")])
12636
12637 ;; This pattern can't accept a variable shift count, since shifts by
12638 ;; zero don't affect the flags. We assume that shifts by constant
12639 ;; zero are optimized away.
12640 (define_insn "*lshrhi3_one_bit_cmp"
12641 [(set (reg FLAGS_REG)
12642 (compare
12643 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12644 (match_operand:QI 2 "const1_operand" ""))
12645 (const_int 0)))
12646 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12647 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12648 "ix86_match_ccmode (insn, CCGOCmode)
12649 && (TARGET_SHIFT1 || optimize_size)
12650 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12651 "shr{w}\t%0"
12652 [(set_attr "type" "ishift")
12653 (set (attr "length")
12654 (if_then_else (match_operand:SI 0 "register_operand" "")
12655 (const_string "2")
12656 (const_string "*")))])
12657
12658 (define_insn "*lshrhi3_one_bit_cconly"
12659 [(set (reg FLAGS_REG)
12660 (compare
12661 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12662 (match_operand:QI 2 "const1_operand" ""))
12663 (const_int 0)))
12664 (clobber (match_scratch:HI 0 "=r"))]
12665 "ix86_match_ccmode (insn, CCGOCmode)
12666 && (TARGET_SHIFT1 || optimize_size)
12667 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12668 "shr{w}\t%0"
12669 [(set_attr "type" "ishift")
12670 (set_attr "length" "2")])
12671
12672 ;; This pattern can't accept a variable shift count, since shifts by
12673 ;; zero don't affect the flags. We assume that shifts by constant
12674 ;; zero are optimized away.
12675 (define_insn "*lshrhi3_cmp"
12676 [(set (reg FLAGS_REG)
12677 (compare
12678 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12679 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12680 (const_int 0)))
12681 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12682 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12683 "ix86_match_ccmode (insn, CCGOCmode)
12684 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12685 && (optimize_size
12686 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12687 "shr{w}\t{%2, %0|%0, %2}"
12688 [(set_attr "type" "ishift")
12689 (set_attr "mode" "HI")])
12690
12691 (define_insn "*lshrhi3_cconly"
12692 [(set (reg FLAGS_REG)
12693 (compare
12694 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12695 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12696 (const_int 0)))
12697 (clobber (match_scratch:HI 0 "=r"))]
12698 "ix86_match_ccmode (insn, CCGOCmode)
12699 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12700 && (optimize_size
12701 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12702 "shr{w}\t{%2, %0|%0, %2}"
12703 [(set_attr "type" "ishift")
12704 (set_attr "mode" "HI")])
12705
12706 (define_expand "lshrqi3"
12707 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12708 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12709 (match_operand:QI 2 "nonmemory_operand" "")))
12710 (clobber (reg:CC FLAGS_REG))]
12711 "TARGET_QIMODE_MATH"
12712 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12713
12714 (define_insn "*lshrqi3_1_one_bit"
12715 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12716 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12717 (match_operand:QI 2 "const1_operand" "")))
12718 (clobber (reg:CC FLAGS_REG))]
12719 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12720 && (TARGET_SHIFT1 || optimize_size)"
12721 "shr{b}\t%0"
12722 [(set_attr "type" "ishift")
12723 (set (attr "length")
12724 (if_then_else (match_operand 0 "register_operand" "")
12725 (const_string "2")
12726 (const_string "*")))])
12727
12728 (define_insn "*lshrqi3_1_one_bit_slp"
12729 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12730 (lshiftrt:QI (match_dup 0)
12731 (match_operand:QI 1 "const1_operand" "")))
12732 (clobber (reg:CC FLAGS_REG))]
12733 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12734 && (TARGET_SHIFT1 || optimize_size)"
12735 "shr{b}\t%0"
12736 [(set_attr "type" "ishift1")
12737 (set (attr "length")
12738 (if_then_else (match_operand 0 "register_operand" "")
12739 (const_string "2")
12740 (const_string "*")))])
12741
12742 (define_insn "*lshrqi3_1"
12743 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12744 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12745 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12746 (clobber (reg:CC FLAGS_REG))]
12747 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12748 "@
12749 shr{b}\t{%2, %0|%0, %2}
12750 shr{b}\t{%b2, %0|%0, %b2}"
12751 [(set_attr "type" "ishift")
12752 (set_attr "mode" "QI")])
12753
12754 (define_insn "*lshrqi3_1_slp"
12755 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12756 (lshiftrt:QI (match_dup 0)
12757 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12758 (clobber (reg:CC FLAGS_REG))]
12759 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12760 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12761 "@
12762 shr{b}\t{%1, %0|%0, %1}
12763 shr{b}\t{%b1, %0|%0, %b1}"
12764 [(set_attr "type" "ishift1")
12765 (set_attr "mode" "QI")])
12766
12767 ;; This pattern can't accept a variable shift count, since shifts by
12768 ;; zero don't affect the flags. We assume that shifts by constant
12769 ;; zero are optimized away.
12770 (define_insn "*lshrqi2_one_bit_cmp"
12771 [(set (reg FLAGS_REG)
12772 (compare
12773 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12774 (match_operand:QI 2 "const1_operand" ""))
12775 (const_int 0)))
12776 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12777 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12778 "ix86_match_ccmode (insn, CCGOCmode)
12779 && (TARGET_SHIFT1 || optimize_size)
12780 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12781 "shr{b}\t%0"
12782 [(set_attr "type" "ishift")
12783 (set (attr "length")
12784 (if_then_else (match_operand:SI 0 "register_operand" "")
12785 (const_string "2")
12786 (const_string "*")))])
12787
12788 (define_insn "*lshrqi2_one_bit_cconly"
12789 [(set (reg FLAGS_REG)
12790 (compare
12791 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12792 (match_operand:QI 2 "const1_operand" ""))
12793 (const_int 0)))
12794 (clobber (match_scratch:QI 0 "=q"))]
12795 "ix86_match_ccmode (insn, CCGOCmode)
12796 && (TARGET_SHIFT1 || optimize_size)
12797 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12798 "shr{b}\t%0"
12799 [(set_attr "type" "ishift")
12800 (set_attr "length" "2")])
12801
12802 ;; This pattern can't accept a variable shift count, since shifts by
12803 ;; zero don't affect the flags. We assume that shifts by constant
12804 ;; zero are optimized away.
12805 (define_insn "*lshrqi2_cmp"
12806 [(set (reg FLAGS_REG)
12807 (compare
12808 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12809 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12810 (const_int 0)))
12811 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12812 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12813 "ix86_match_ccmode (insn, CCGOCmode)
12814 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12815 && (optimize_size
12816 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12817 "shr{b}\t{%2, %0|%0, %2}"
12818 [(set_attr "type" "ishift")
12819 (set_attr "mode" "QI")])
12820
12821 (define_insn "*lshrqi2_cconly"
12822 [(set (reg FLAGS_REG)
12823 (compare
12824 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12825 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12826 (const_int 0)))
12827 (clobber (match_scratch:QI 0 "=q"))]
12828 "ix86_match_ccmode (insn, CCGOCmode)
12829 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12830 && (optimize_size
12831 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12832 "shr{b}\t{%2, %0|%0, %2}"
12833 [(set_attr "type" "ishift")
12834 (set_attr "mode" "QI")])
12835 \f
12836 ;; Rotate instructions
12837
12838 (define_expand "rotldi3"
12839 [(set (match_operand:DI 0 "shiftdi_operand" "")
12840 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12841 (match_operand:QI 2 "nonmemory_operand" "")))
12842 (clobber (reg:CC FLAGS_REG))]
12843 ""
12844 {
12845 if (TARGET_64BIT)
12846 {
12847 ix86_expand_binary_operator (ROTATE, DImode, operands);
12848 DONE;
12849 }
12850 if (!const_1_to_31_operand (operands[2], VOIDmode))
12851 FAIL;
12852 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12853 DONE;
12854 })
12855
12856 ;; Implement rotation using two double-precision shift instructions
12857 ;; and a scratch register.
12858 (define_insn_and_split "ix86_rotldi3"
12859 [(set (match_operand:DI 0 "register_operand" "=r")
12860 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12861 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12862 (clobber (reg:CC FLAGS_REG))
12863 (clobber (match_scratch:SI 3 "=&r"))]
12864 "!TARGET_64BIT"
12865 ""
12866 "&& reload_completed"
12867 [(set (match_dup 3) (match_dup 4))
12868 (parallel
12869 [(set (match_dup 4)
12870 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12871 (lshiftrt:SI (match_dup 5)
12872 (minus:QI (const_int 32) (match_dup 2)))))
12873 (clobber (reg:CC FLAGS_REG))])
12874 (parallel
12875 [(set (match_dup 5)
12876 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12877 (lshiftrt:SI (match_dup 3)
12878 (minus:QI (const_int 32) (match_dup 2)))))
12879 (clobber (reg:CC FLAGS_REG))])]
12880 "split_di (operands, 1, operands + 4, operands + 5);")
12881
12882 (define_insn "*rotlsi3_1_one_bit_rex64"
12883 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12884 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12885 (match_operand:QI 2 "const1_operand" "")))
12886 (clobber (reg:CC FLAGS_REG))]
12887 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12888 && (TARGET_SHIFT1 || optimize_size)"
12889 "rol{q}\t%0"
12890 [(set_attr "type" "rotate")
12891 (set (attr "length")
12892 (if_then_else (match_operand:DI 0 "register_operand" "")
12893 (const_string "2")
12894 (const_string "*")))])
12895
12896 (define_insn "*rotldi3_1_rex64"
12897 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12898 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12899 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12900 (clobber (reg:CC FLAGS_REG))]
12901 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12902 "@
12903 rol{q}\t{%2, %0|%0, %2}
12904 rol{q}\t{%b2, %0|%0, %b2}"
12905 [(set_attr "type" "rotate")
12906 (set_attr "mode" "DI")])
12907
12908 (define_expand "rotlsi3"
12909 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12910 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12911 (match_operand:QI 2 "nonmemory_operand" "")))
12912 (clobber (reg:CC FLAGS_REG))]
12913 ""
12914 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12915
12916 (define_insn "*rotlsi3_1_one_bit"
12917 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12918 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12919 (match_operand:QI 2 "const1_operand" "")))
12920 (clobber (reg:CC FLAGS_REG))]
12921 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12922 && (TARGET_SHIFT1 || optimize_size)"
12923 "rol{l}\t%0"
12924 [(set_attr "type" "rotate")
12925 (set (attr "length")
12926 (if_then_else (match_operand:SI 0 "register_operand" "")
12927 (const_string "2")
12928 (const_string "*")))])
12929
12930 (define_insn "*rotlsi3_1_one_bit_zext"
12931 [(set (match_operand:DI 0 "register_operand" "=r")
12932 (zero_extend:DI
12933 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12934 (match_operand:QI 2 "const1_operand" ""))))
12935 (clobber (reg:CC FLAGS_REG))]
12936 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12937 && (TARGET_SHIFT1 || optimize_size)"
12938 "rol{l}\t%k0"
12939 [(set_attr "type" "rotate")
12940 (set_attr "length" "2")])
12941
12942 (define_insn "*rotlsi3_1"
12943 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12944 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12945 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12946 (clobber (reg:CC FLAGS_REG))]
12947 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12948 "@
12949 rol{l}\t{%2, %0|%0, %2}
12950 rol{l}\t{%b2, %0|%0, %b2}"
12951 [(set_attr "type" "rotate")
12952 (set_attr "mode" "SI")])
12953
12954 (define_insn "*rotlsi3_1_zext"
12955 [(set (match_operand:DI 0 "register_operand" "=r,r")
12956 (zero_extend:DI
12957 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12958 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12959 (clobber (reg:CC FLAGS_REG))]
12960 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12961 "@
12962 rol{l}\t{%2, %k0|%k0, %2}
12963 rol{l}\t{%b2, %k0|%k0, %b2}"
12964 [(set_attr "type" "rotate")
12965 (set_attr "mode" "SI")])
12966
12967 (define_expand "rotlhi3"
12968 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12969 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12970 (match_operand:QI 2 "nonmemory_operand" "")))
12971 (clobber (reg:CC FLAGS_REG))]
12972 "TARGET_HIMODE_MATH"
12973 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12974
12975 (define_insn "*rotlhi3_1_one_bit"
12976 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12977 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12978 (match_operand:QI 2 "const1_operand" "")))
12979 (clobber (reg:CC FLAGS_REG))]
12980 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12981 && (TARGET_SHIFT1 || optimize_size)"
12982 "rol{w}\t%0"
12983 [(set_attr "type" "rotate")
12984 (set (attr "length")
12985 (if_then_else (match_operand 0 "register_operand" "")
12986 (const_string "2")
12987 (const_string "*")))])
12988
12989 (define_insn "*rotlhi3_1"
12990 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12991 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12992 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12993 (clobber (reg:CC FLAGS_REG))]
12994 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12995 "@
12996 rol{w}\t{%2, %0|%0, %2}
12997 rol{w}\t{%b2, %0|%0, %b2}"
12998 [(set_attr "type" "rotate")
12999 (set_attr "mode" "HI")])
13000
13001 (define_expand "rotlqi3"
13002 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13003 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13004 (match_operand:QI 2 "nonmemory_operand" "")))
13005 (clobber (reg:CC FLAGS_REG))]
13006 "TARGET_QIMODE_MATH"
13007 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13008
13009 (define_insn "*rotlqi3_1_one_bit_slp"
13010 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13011 (rotate:QI (match_dup 0)
13012 (match_operand:QI 1 "const1_operand" "")))
13013 (clobber (reg:CC FLAGS_REG))]
13014 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13015 && (TARGET_SHIFT1 || optimize_size)"
13016 "rol{b}\t%0"
13017 [(set_attr "type" "rotate1")
13018 (set (attr "length")
13019 (if_then_else (match_operand 0 "register_operand" "")
13020 (const_string "2")
13021 (const_string "*")))])
13022
13023 (define_insn "*rotlqi3_1_one_bit"
13024 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13025 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13026 (match_operand:QI 2 "const1_operand" "")))
13027 (clobber (reg:CC FLAGS_REG))]
13028 "ix86_binary_operator_ok (ROTATE, QImode, operands)
13029 && (TARGET_SHIFT1 || optimize_size)"
13030 "rol{b}\t%0"
13031 [(set_attr "type" "rotate")
13032 (set (attr "length")
13033 (if_then_else (match_operand 0 "register_operand" "")
13034 (const_string "2")
13035 (const_string "*")))])
13036
13037 (define_insn "*rotlqi3_1_slp"
13038 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13039 (rotate:QI (match_dup 0)
13040 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13041 (clobber (reg:CC FLAGS_REG))]
13042 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13043 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13044 "@
13045 rol{b}\t{%1, %0|%0, %1}
13046 rol{b}\t{%b1, %0|%0, %b1}"
13047 [(set_attr "type" "rotate1")
13048 (set_attr "mode" "QI")])
13049
13050 (define_insn "*rotlqi3_1"
13051 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13052 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13053 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13054 (clobber (reg:CC FLAGS_REG))]
13055 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13056 "@
13057 rol{b}\t{%2, %0|%0, %2}
13058 rol{b}\t{%b2, %0|%0, %b2}"
13059 [(set_attr "type" "rotate")
13060 (set_attr "mode" "QI")])
13061
13062 (define_expand "rotrdi3"
13063 [(set (match_operand:DI 0 "shiftdi_operand" "")
13064 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13065 (match_operand:QI 2 "nonmemory_operand" "")))
13066 (clobber (reg:CC FLAGS_REG))]
13067 ""
13068 {
13069 if (TARGET_64BIT)
13070 {
13071 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13072 DONE;
13073 }
13074 if (!const_1_to_31_operand (operands[2], VOIDmode))
13075 FAIL;
13076 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13077 DONE;
13078 })
13079
13080 ;; Implement rotation using two double-precision shift instructions
13081 ;; and a scratch register.
13082 (define_insn_and_split "ix86_rotrdi3"
13083 [(set (match_operand:DI 0 "register_operand" "=r")
13084 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13085 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13086 (clobber (reg:CC FLAGS_REG))
13087 (clobber (match_scratch:SI 3 "=&r"))]
13088 "!TARGET_64BIT"
13089 ""
13090 "&& reload_completed"
13091 [(set (match_dup 3) (match_dup 4))
13092 (parallel
13093 [(set (match_dup 4)
13094 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13095 (ashift:SI (match_dup 5)
13096 (minus:QI (const_int 32) (match_dup 2)))))
13097 (clobber (reg:CC FLAGS_REG))])
13098 (parallel
13099 [(set (match_dup 5)
13100 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13101 (ashift:SI (match_dup 3)
13102 (minus:QI (const_int 32) (match_dup 2)))))
13103 (clobber (reg:CC FLAGS_REG))])]
13104 "split_di (operands, 1, operands + 4, operands + 5);")
13105
13106 (define_insn "*rotrdi3_1_one_bit_rex64"
13107 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13108 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13109 (match_operand:QI 2 "const1_operand" "")))
13110 (clobber (reg:CC FLAGS_REG))]
13111 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13112 && (TARGET_SHIFT1 || optimize_size)"
13113 "ror{q}\t%0"
13114 [(set_attr "type" "rotate")
13115 (set (attr "length")
13116 (if_then_else (match_operand:DI 0 "register_operand" "")
13117 (const_string "2")
13118 (const_string "*")))])
13119
13120 (define_insn "*rotrdi3_1_rex64"
13121 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13122 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13123 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13124 (clobber (reg:CC FLAGS_REG))]
13125 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13126 "@
13127 ror{q}\t{%2, %0|%0, %2}
13128 ror{q}\t{%b2, %0|%0, %b2}"
13129 [(set_attr "type" "rotate")
13130 (set_attr "mode" "DI")])
13131
13132 (define_expand "rotrsi3"
13133 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13134 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13135 (match_operand:QI 2 "nonmemory_operand" "")))
13136 (clobber (reg:CC FLAGS_REG))]
13137 ""
13138 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13139
13140 (define_insn "*rotrsi3_1_one_bit"
13141 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13142 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13143 (match_operand:QI 2 "const1_operand" "")))
13144 (clobber (reg:CC FLAGS_REG))]
13145 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13146 && (TARGET_SHIFT1 || optimize_size)"
13147 "ror{l}\t%0"
13148 [(set_attr "type" "rotate")
13149 (set (attr "length")
13150 (if_then_else (match_operand:SI 0 "register_operand" "")
13151 (const_string "2")
13152 (const_string "*")))])
13153
13154 (define_insn "*rotrsi3_1_one_bit_zext"
13155 [(set (match_operand:DI 0 "register_operand" "=r")
13156 (zero_extend:DI
13157 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13158 (match_operand:QI 2 "const1_operand" ""))))
13159 (clobber (reg:CC FLAGS_REG))]
13160 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13161 && (TARGET_SHIFT1 || optimize_size)"
13162 "ror{l}\t%k0"
13163 [(set_attr "type" "rotate")
13164 (set (attr "length")
13165 (if_then_else (match_operand:SI 0 "register_operand" "")
13166 (const_string "2")
13167 (const_string "*")))])
13168
13169 (define_insn "*rotrsi3_1"
13170 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13171 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13172 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13173 (clobber (reg:CC FLAGS_REG))]
13174 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13175 "@
13176 ror{l}\t{%2, %0|%0, %2}
13177 ror{l}\t{%b2, %0|%0, %b2}"
13178 [(set_attr "type" "rotate")
13179 (set_attr "mode" "SI")])
13180
13181 (define_insn "*rotrsi3_1_zext"
13182 [(set (match_operand:DI 0 "register_operand" "=r,r")
13183 (zero_extend:DI
13184 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13185 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13186 (clobber (reg:CC FLAGS_REG))]
13187 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13188 "@
13189 ror{l}\t{%2, %k0|%k0, %2}
13190 ror{l}\t{%b2, %k0|%k0, %b2}"
13191 [(set_attr "type" "rotate")
13192 (set_attr "mode" "SI")])
13193
13194 (define_expand "rotrhi3"
13195 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13196 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13197 (match_operand:QI 2 "nonmemory_operand" "")))
13198 (clobber (reg:CC FLAGS_REG))]
13199 "TARGET_HIMODE_MATH"
13200 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13201
13202 (define_insn "*rotrhi3_one_bit"
13203 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13204 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13205 (match_operand:QI 2 "const1_operand" "")))
13206 (clobber (reg:CC FLAGS_REG))]
13207 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13208 && (TARGET_SHIFT1 || optimize_size)"
13209 "ror{w}\t%0"
13210 [(set_attr "type" "rotate")
13211 (set (attr "length")
13212 (if_then_else (match_operand 0 "register_operand" "")
13213 (const_string "2")
13214 (const_string "*")))])
13215
13216 (define_insn "*rotrhi3"
13217 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13218 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13219 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13220 (clobber (reg:CC FLAGS_REG))]
13221 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13222 "@
13223 ror{w}\t{%2, %0|%0, %2}
13224 ror{w}\t{%b2, %0|%0, %b2}"
13225 [(set_attr "type" "rotate")
13226 (set_attr "mode" "HI")])
13227
13228 (define_expand "rotrqi3"
13229 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13230 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13231 (match_operand:QI 2 "nonmemory_operand" "")))
13232 (clobber (reg:CC FLAGS_REG))]
13233 "TARGET_QIMODE_MATH"
13234 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13235
13236 (define_insn "*rotrqi3_1_one_bit"
13237 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13238 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13239 (match_operand:QI 2 "const1_operand" "")))
13240 (clobber (reg:CC FLAGS_REG))]
13241 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13242 && (TARGET_SHIFT1 || optimize_size)"
13243 "ror{b}\t%0"
13244 [(set_attr "type" "rotate")
13245 (set (attr "length")
13246 (if_then_else (match_operand 0 "register_operand" "")
13247 (const_string "2")
13248 (const_string "*")))])
13249
13250 (define_insn "*rotrqi3_1_one_bit_slp"
13251 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13252 (rotatert:QI (match_dup 0)
13253 (match_operand:QI 1 "const1_operand" "")))
13254 (clobber (reg:CC FLAGS_REG))]
13255 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13256 && (TARGET_SHIFT1 || optimize_size)"
13257 "ror{b}\t%0"
13258 [(set_attr "type" "rotate1")
13259 (set (attr "length")
13260 (if_then_else (match_operand 0 "register_operand" "")
13261 (const_string "2")
13262 (const_string "*")))])
13263
13264 (define_insn "*rotrqi3_1"
13265 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13266 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13267 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13268 (clobber (reg:CC FLAGS_REG))]
13269 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13270 "@
13271 ror{b}\t{%2, %0|%0, %2}
13272 ror{b}\t{%b2, %0|%0, %b2}"
13273 [(set_attr "type" "rotate")
13274 (set_attr "mode" "QI")])
13275
13276 (define_insn "*rotrqi3_1_slp"
13277 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13278 (rotatert:QI (match_dup 0)
13279 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13280 (clobber (reg:CC FLAGS_REG))]
13281 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13282 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13283 "@
13284 ror{b}\t{%1, %0|%0, %1}
13285 ror{b}\t{%b1, %0|%0, %b1}"
13286 [(set_attr "type" "rotate1")
13287 (set_attr "mode" "QI")])
13288 \f
13289 ;; Bit set / bit test instructions
13290
13291 (define_expand "extv"
13292 [(set (match_operand:SI 0 "register_operand" "")
13293 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13294 (match_operand:SI 2 "const8_operand" "")
13295 (match_operand:SI 3 "const8_operand" "")))]
13296 ""
13297 {
13298 /* Handle extractions from %ah et al. */
13299 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13300 FAIL;
13301
13302 /* From mips.md: extract_bit_field doesn't verify that our source
13303 matches the predicate, so check it again here. */
13304 if (! ext_register_operand (operands[1], VOIDmode))
13305 FAIL;
13306 })
13307
13308 (define_expand "extzv"
13309 [(set (match_operand:SI 0 "register_operand" "")
13310 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13311 (match_operand:SI 2 "const8_operand" "")
13312 (match_operand:SI 3 "const8_operand" "")))]
13313 ""
13314 {
13315 /* Handle extractions from %ah et al. */
13316 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13317 FAIL;
13318
13319 /* From mips.md: extract_bit_field doesn't verify that our source
13320 matches the predicate, so check it again here. */
13321 if (! ext_register_operand (operands[1], VOIDmode))
13322 FAIL;
13323 })
13324
13325 (define_expand "insv"
13326 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13327 (match_operand 1 "const8_operand" "")
13328 (match_operand 2 "const8_operand" ""))
13329 (match_operand 3 "register_operand" ""))]
13330 ""
13331 {
13332 /* Handle insertions to %ah et al. */
13333 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13334 FAIL;
13335
13336 /* From mips.md: insert_bit_field doesn't verify that our source
13337 matches the predicate, so check it again here. */
13338 if (! ext_register_operand (operands[0], VOIDmode))
13339 FAIL;
13340
13341 if (TARGET_64BIT)
13342 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13343 else
13344 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13345
13346 DONE;
13347 })
13348
13349 ;; %%% bts, btr, btc, bt.
13350 ;; In general these instructions are *slow* when applied to memory,
13351 ;; since they enforce atomic operation. When applied to registers,
13352 ;; it depends on the cpu implementation. They're never faster than
13353 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13354 ;; no point. But in 64-bit, we can't hold the relevant immediates
13355 ;; within the instruction itself, so operating on bits in the high
13356 ;; 32-bits of a register becomes easier.
13357 ;;
13358 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13359 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13360 ;; negdf respectively, so they can never be disabled entirely.
13361
13362 (define_insn "*btsq"
13363 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13364 (const_int 1)
13365 (match_operand:DI 1 "const_0_to_63_operand" ""))
13366 (const_int 1))
13367 (clobber (reg:CC FLAGS_REG))]
13368 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13369 "bts{q} %1,%0"
13370 [(set_attr "type" "alu1")])
13371
13372 (define_insn "*btrq"
13373 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13374 (const_int 1)
13375 (match_operand:DI 1 "const_0_to_63_operand" ""))
13376 (const_int 0))
13377 (clobber (reg:CC FLAGS_REG))]
13378 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13379 "btr{q} %1,%0"
13380 [(set_attr "type" "alu1")])
13381
13382 (define_insn "*btcq"
13383 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13384 (const_int 1)
13385 (match_operand:DI 1 "const_0_to_63_operand" ""))
13386 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13387 (clobber (reg:CC FLAGS_REG))]
13388 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13389 "btc{q} %1,%0"
13390 [(set_attr "type" "alu1")])
13391
13392 ;; Allow Nocona to avoid these instructions if a register is available.
13393
13394 (define_peephole2
13395 [(match_scratch:DI 2 "r")
13396 (parallel [(set (zero_extract:DI
13397 (match_operand:DI 0 "register_operand" "")
13398 (const_int 1)
13399 (match_operand:DI 1 "const_0_to_63_operand" ""))
13400 (const_int 1))
13401 (clobber (reg:CC FLAGS_REG))])]
13402 "TARGET_64BIT && !TARGET_USE_BT"
13403 [(const_int 0)]
13404 {
13405 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13406 rtx op1;
13407
13408 if (HOST_BITS_PER_WIDE_INT >= 64)
13409 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13410 else if (i < HOST_BITS_PER_WIDE_INT)
13411 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13412 else
13413 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13414
13415 op1 = immed_double_const (lo, hi, DImode);
13416 if (i >= 31)
13417 {
13418 emit_move_insn (operands[2], op1);
13419 op1 = operands[2];
13420 }
13421
13422 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13423 DONE;
13424 })
13425
13426 (define_peephole2
13427 [(match_scratch:DI 2 "r")
13428 (parallel [(set (zero_extract:DI
13429 (match_operand:DI 0 "register_operand" "")
13430 (const_int 1)
13431 (match_operand:DI 1 "const_0_to_63_operand" ""))
13432 (const_int 0))
13433 (clobber (reg:CC FLAGS_REG))])]
13434 "TARGET_64BIT && !TARGET_USE_BT"
13435 [(const_int 0)]
13436 {
13437 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13438 rtx op1;
13439
13440 if (HOST_BITS_PER_WIDE_INT >= 64)
13441 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13442 else if (i < HOST_BITS_PER_WIDE_INT)
13443 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13444 else
13445 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13446
13447 op1 = immed_double_const (~lo, ~hi, DImode);
13448 if (i >= 32)
13449 {
13450 emit_move_insn (operands[2], op1);
13451 op1 = operands[2];
13452 }
13453
13454 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13455 DONE;
13456 })
13457
13458 (define_peephole2
13459 [(match_scratch:DI 2 "r")
13460 (parallel [(set (zero_extract:DI
13461 (match_operand:DI 0 "register_operand" "")
13462 (const_int 1)
13463 (match_operand:DI 1 "const_0_to_63_operand" ""))
13464 (not:DI (zero_extract:DI
13465 (match_dup 0) (const_int 1) (match_dup 1))))
13466 (clobber (reg:CC FLAGS_REG))])]
13467 "TARGET_64BIT && !TARGET_USE_BT"
13468 [(const_int 0)]
13469 {
13470 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13471 rtx op1;
13472
13473 if (HOST_BITS_PER_WIDE_INT >= 64)
13474 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13475 else if (i < HOST_BITS_PER_WIDE_INT)
13476 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13477 else
13478 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13479
13480 op1 = immed_double_const (lo, hi, DImode);
13481 if (i >= 31)
13482 {
13483 emit_move_insn (operands[2], op1);
13484 op1 = operands[2];
13485 }
13486
13487 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13488 DONE;
13489 })
13490 \f
13491 ;; Store-flag instructions.
13492
13493 ;; For all sCOND expanders, also expand the compare or test insn that
13494 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13495
13496 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13497 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13498 ;; way, which can later delete the movzx if only QImode is needed.
13499
13500 (define_expand "seq"
13501 [(set (match_operand:QI 0 "register_operand" "")
13502 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13503 ""
13504 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13505
13506 (define_expand "sne"
13507 [(set (match_operand:QI 0 "register_operand" "")
13508 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13509 ""
13510 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13511
13512 (define_expand "sgt"
13513 [(set (match_operand:QI 0 "register_operand" "")
13514 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13515 ""
13516 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13517
13518 (define_expand "sgtu"
13519 [(set (match_operand:QI 0 "register_operand" "")
13520 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13521 ""
13522 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13523
13524 (define_expand "slt"
13525 [(set (match_operand:QI 0 "register_operand" "")
13526 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13527 ""
13528 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13529
13530 (define_expand "sltu"
13531 [(set (match_operand:QI 0 "register_operand" "")
13532 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13533 ""
13534 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13535
13536 (define_expand "sge"
13537 [(set (match_operand:QI 0 "register_operand" "")
13538 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13539 ""
13540 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13541
13542 (define_expand "sgeu"
13543 [(set (match_operand:QI 0 "register_operand" "")
13544 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13545 ""
13546 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13547
13548 (define_expand "sle"
13549 [(set (match_operand:QI 0 "register_operand" "")
13550 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13551 ""
13552 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13553
13554 (define_expand "sleu"
13555 [(set (match_operand:QI 0 "register_operand" "")
13556 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13557 ""
13558 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13559
13560 (define_expand "sunordered"
13561 [(set (match_operand:QI 0 "register_operand" "")
13562 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13563 "TARGET_80387 || TARGET_SSE"
13564 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13565
13566 (define_expand "sordered"
13567 [(set (match_operand:QI 0 "register_operand" "")
13568 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13569 "TARGET_80387"
13570 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13571
13572 (define_expand "suneq"
13573 [(set (match_operand:QI 0 "register_operand" "")
13574 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13575 "TARGET_80387 || TARGET_SSE"
13576 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13577
13578 (define_expand "sunge"
13579 [(set (match_operand:QI 0 "register_operand" "")
13580 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13581 "TARGET_80387 || TARGET_SSE"
13582 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13583
13584 (define_expand "sungt"
13585 [(set (match_operand:QI 0 "register_operand" "")
13586 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13587 "TARGET_80387 || TARGET_SSE"
13588 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13589
13590 (define_expand "sunle"
13591 [(set (match_operand:QI 0 "register_operand" "")
13592 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13593 "TARGET_80387 || TARGET_SSE"
13594 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13595
13596 (define_expand "sunlt"
13597 [(set (match_operand:QI 0 "register_operand" "")
13598 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13599 "TARGET_80387 || TARGET_SSE"
13600 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13601
13602 (define_expand "sltgt"
13603 [(set (match_operand:QI 0 "register_operand" "")
13604 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13605 "TARGET_80387 || TARGET_SSE"
13606 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13607
13608 (define_insn "*setcc_1"
13609 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13610 (match_operator:QI 1 "ix86_comparison_operator"
13611 [(reg FLAGS_REG) (const_int 0)]))]
13612 ""
13613 "set%C1\t%0"
13614 [(set_attr "type" "setcc")
13615 (set_attr "mode" "QI")])
13616
13617 (define_insn "*setcc_2"
13618 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13619 (match_operator:QI 1 "ix86_comparison_operator"
13620 [(reg FLAGS_REG) (const_int 0)]))]
13621 ""
13622 "set%C1\t%0"
13623 [(set_attr "type" "setcc")
13624 (set_attr "mode" "QI")])
13625
13626 ;; In general it is not safe to assume too much about CCmode registers,
13627 ;; so simplify-rtx stops when it sees a second one. Under certain
13628 ;; conditions this is safe on x86, so help combine not create
13629 ;;
13630 ;; seta %al
13631 ;; testb %al, %al
13632 ;; sete %al
13633
13634 (define_split
13635 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13636 (ne:QI (match_operator 1 "ix86_comparison_operator"
13637 [(reg FLAGS_REG) (const_int 0)])
13638 (const_int 0)))]
13639 ""
13640 [(set (match_dup 0) (match_dup 1))]
13641 {
13642 PUT_MODE (operands[1], QImode);
13643 })
13644
13645 (define_split
13646 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13647 (ne:QI (match_operator 1 "ix86_comparison_operator"
13648 [(reg FLAGS_REG) (const_int 0)])
13649 (const_int 0)))]
13650 ""
13651 [(set (match_dup 0) (match_dup 1))]
13652 {
13653 PUT_MODE (operands[1], QImode);
13654 })
13655
13656 (define_split
13657 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13658 (eq:QI (match_operator 1 "ix86_comparison_operator"
13659 [(reg FLAGS_REG) (const_int 0)])
13660 (const_int 0)))]
13661 ""
13662 [(set (match_dup 0) (match_dup 1))]
13663 {
13664 rtx new_op1 = copy_rtx (operands[1]);
13665 operands[1] = new_op1;
13666 PUT_MODE (new_op1, QImode);
13667 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13668 GET_MODE (XEXP (new_op1, 0))));
13669
13670 /* Make sure that (a) the CCmode we have for the flags is strong
13671 enough for the reversed compare or (b) we have a valid FP compare. */
13672 if (! ix86_comparison_operator (new_op1, VOIDmode))
13673 FAIL;
13674 })
13675
13676 (define_split
13677 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13678 (eq:QI (match_operator 1 "ix86_comparison_operator"
13679 [(reg FLAGS_REG) (const_int 0)])
13680 (const_int 0)))]
13681 ""
13682 [(set (match_dup 0) (match_dup 1))]
13683 {
13684 rtx new_op1 = copy_rtx (operands[1]);
13685 operands[1] = new_op1;
13686 PUT_MODE (new_op1, QImode);
13687 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13688 GET_MODE (XEXP (new_op1, 0))));
13689
13690 /* Make sure that (a) the CCmode we have for the flags is strong
13691 enough for the reversed compare or (b) we have a valid FP compare. */
13692 if (! ix86_comparison_operator (new_op1, VOIDmode))
13693 FAIL;
13694 })
13695
13696 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13697 ;; subsequent logical operations are used to imitate conditional moves.
13698 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13699 ;; it directly.
13700
13701 (define_insn "*sse_setccsf"
13702 [(set (match_operand:SF 0 "register_operand" "=x")
13703 (match_operator:SF 1 "sse_comparison_operator"
13704 [(match_operand:SF 2 "register_operand" "0")
13705 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13706 "TARGET_SSE"
13707 "cmp%D1ss\t{%3, %0|%0, %3}"
13708 [(set_attr "type" "ssecmp")
13709 (set_attr "mode" "SF")])
13710
13711 (define_insn "*sse_setccdf"
13712 [(set (match_operand:DF 0 "register_operand" "=x")
13713 (match_operator:DF 1 "sse_comparison_operator"
13714 [(match_operand:DF 2 "register_operand" "0")
13715 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13716 "TARGET_SSE2"
13717 "cmp%D1sd\t{%3, %0|%0, %3}"
13718 [(set_attr "type" "ssecmp")
13719 (set_attr "mode" "DF")])
13720 \f
13721 ;; Basic conditional jump instructions.
13722 ;; We ignore the overflow flag for signed branch instructions.
13723
13724 ;; For all bCOND expanders, also expand the compare or test insn that
13725 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13726
13727 (define_expand "beq"
13728 [(set (pc)
13729 (if_then_else (match_dup 1)
13730 (label_ref (match_operand 0 "" ""))
13731 (pc)))]
13732 ""
13733 "ix86_expand_branch (EQ, operands[0]); DONE;")
13734
13735 (define_expand "bne"
13736 [(set (pc)
13737 (if_then_else (match_dup 1)
13738 (label_ref (match_operand 0 "" ""))
13739 (pc)))]
13740 ""
13741 "ix86_expand_branch (NE, operands[0]); DONE;")
13742
13743 (define_expand "bgt"
13744 [(set (pc)
13745 (if_then_else (match_dup 1)
13746 (label_ref (match_operand 0 "" ""))
13747 (pc)))]
13748 ""
13749 "ix86_expand_branch (GT, operands[0]); DONE;")
13750
13751 (define_expand "bgtu"
13752 [(set (pc)
13753 (if_then_else (match_dup 1)
13754 (label_ref (match_operand 0 "" ""))
13755 (pc)))]
13756 ""
13757 "ix86_expand_branch (GTU, operands[0]); DONE;")
13758
13759 (define_expand "blt"
13760 [(set (pc)
13761 (if_then_else (match_dup 1)
13762 (label_ref (match_operand 0 "" ""))
13763 (pc)))]
13764 ""
13765 "ix86_expand_branch (LT, operands[0]); DONE;")
13766
13767 (define_expand "bltu"
13768 [(set (pc)
13769 (if_then_else (match_dup 1)
13770 (label_ref (match_operand 0 "" ""))
13771 (pc)))]
13772 ""
13773 "ix86_expand_branch (LTU, operands[0]); DONE;")
13774
13775 (define_expand "bge"
13776 [(set (pc)
13777 (if_then_else (match_dup 1)
13778 (label_ref (match_operand 0 "" ""))
13779 (pc)))]
13780 ""
13781 "ix86_expand_branch (GE, operands[0]); DONE;")
13782
13783 (define_expand "bgeu"
13784 [(set (pc)
13785 (if_then_else (match_dup 1)
13786 (label_ref (match_operand 0 "" ""))
13787 (pc)))]
13788 ""
13789 "ix86_expand_branch (GEU, operands[0]); DONE;")
13790
13791 (define_expand "ble"
13792 [(set (pc)
13793 (if_then_else (match_dup 1)
13794 (label_ref (match_operand 0 "" ""))
13795 (pc)))]
13796 ""
13797 "ix86_expand_branch (LE, operands[0]); DONE;")
13798
13799 (define_expand "bleu"
13800 [(set (pc)
13801 (if_then_else (match_dup 1)
13802 (label_ref (match_operand 0 "" ""))
13803 (pc)))]
13804 ""
13805 "ix86_expand_branch (LEU, operands[0]); DONE;")
13806
13807 (define_expand "bunordered"
13808 [(set (pc)
13809 (if_then_else (match_dup 1)
13810 (label_ref (match_operand 0 "" ""))
13811 (pc)))]
13812 "TARGET_80387 || TARGET_SSE_MATH"
13813 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13814
13815 (define_expand "bordered"
13816 [(set (pc)
13817 (if_then_else (match_dup 1)
13818 (label_ref (match_operand 0 "" ""))
13819 (pc)))]
13820 "TARGET_80387 || TARGET_SSE_MATH"
13821 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13822
13823 (define_expand "buneq"
13824 [(set (pc)
13825 (if_then_else (match_dup 1)
13826 (label_ref (match_operand 0 "" ""))
13827 (pc)))]
13828 "TARGET_80387 || TARGET_SSE_MATH"
13829 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13830
13831 (define_expand "bunge"
13832 [(set (pc)
13833 (if_then_else (match_dup 1)
13834 (label_ref (match_operand 0 "" ""))
13835 (pc)))]
13836 "TARGET_80387 || TARGET_SSE_MATH"
13837 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13838
13839 (define_expand "bungt"
13840 [(set (pc)
13841 (if_then_else (match_dup 1)
13842 (label_ref (match_operand 0 "" ""))
13843 (pc)))]
13844 "TARGET_80387 || TARGET_SSE_MATH"
13845 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13846
13847 (define_expand "bunle"
13848 [(set (pc)
13849 (if_then_else (match_dup 1)
13850 (label_ref (match_operand 0 "" ""))
13851 (pc)))]
13852 "TARGET_80387 || TARGET_SSE_MATH"
13853 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13854
13855 (define_expand "bunlt"
13856 [(set (pc)
13857 (if_then_else (match_dup 1)
13858 (label_ref (match_operand 0 "" ""))
13859 (pc)))]
13860 "TARGET_80387 || TARGET_SSE_MATH"
13861 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13862
13863 (define_expand "bltgt"
13864 [(set (pc)
13865 (if_then_else (match_dup 1)
13866 (label_ref (match_operand 0 "" ""))
13867 (pc)))]
13868 "TARGET_80387 || TARGET_SSE_MATH"
13869 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13870
13871 (define_insn "*jcc_1"
13872 [(set (pc)
13873 (if_then_else (match_operator 1 "ix86_comparison_operator"
13874 [(reg FLAGS_REG) (const_int 0)])
13875 (label_ref (match_operand 0 "" ""))
13876 (pc)))]
13877 ""
13878 "%+j%C1\t%l0"
13879 [(set_attr "type" "ibr")
13880 (set_attr "modrm" "0")
13881 (set (attr "length")
13882 (if_then_else (and (ge (minus (match_dup 0) (pc))
13883 (const_int -126))
13884 (lt (minus (match_dup 0) (pc))
13885 (const_int 128)))
13886 (const_int 2)
13887 (const_int 6)))])
13888
13889 (define_insn "*jcc_2"
13890 [(set (pc)
13891 (if_then_else (match_operator 1 "ix86_comparison_operator"
13892 [(reg FLAGS_REG) (const_int 0)])
13893 (pc)
13894 (label_ref (match_operand 0 "" ""))))]
13895 ""
13896 "%+j%c1\t%l0"
13897 [(set_attr "type" "ibr")
13898 (set_attr "modrm" "0")
13899 (set (attr "length")
13900 (if_then_else (and (ge (minus (match_dup 0) (pc))
13901 (const_int -126))
13902 (lt (minus (match_dup 0) (pc))
13903 (const_int 128)))
13904 (const_int 2)
13905 (const_int 6)))])
13906
13907 ;; In general it is not safe to assume too much about CCmode registers,
13908 ;; so simplify-rtx stops when it sees a second one. Under certain
13909 ;; conditions this is safe on x86, so help combine not create
13910 ;;
13911 ;; seta %al
13912 ;; testb %al, %al
13913 ;; je Lfoo
13914
13915 (define_split
13916 [(set (pc)
13917 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13918 [(reg FLAGS_REG) (const_int 0)])
13919 (const_int 0))
13920 (label_ref (match_operand 1 "" ""))
13921 (pc)))]
13922 ""
13923 [(set (pc)
13924 (if_then_else (match_dup 0)
13925 (label_ref (match_dup 1))
13926 (pc)))]
13927 {
13928 PUT_MODE (operands[0], VOIDmode);
13929 })
13930
13931 (define_split
13932 [(set (pc)
13933 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13934 [(reg FLAGS_REG) (const_int 0)])
13935 (const_int 0))
13936 (label_ref (match_operand 1 "" ""))
13937 (pc)))]
13938 ""
13939 [(set (pc)
13940 (if_then_else (match_dup 0)
13941 (label_ref (match_dup 1))
13942 (pc)))]
13943 {
13944 rtx new_op0 = copy_rtx (operands[0]);
13945 operands[0] = new_op0;
13946 PUT_MODE (new_op0, VOIDmode);
13947 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13948 GET_MODE (XEXP (new_op0, 0))));
13949
13950 /* Make sure that (a) the CCmode we have for the flags is strong
13951 enough for the reversed compare or (b) we have a valid FP compare. */
13952 if (! ix86_comparison_operator (new_op0, VOIDmode))
13953 FAIL;
13954 })
13955
13956 ;; Define combination compare-and-branch fp compare instructions to use
13957 ;; during early optimization. Splitting the operation apart early makes
13958 ;; for bad code when we want to reverse the operation.
13959
13960 (define_insn "*fp_jcc_1_mixed"
13961 [(set (pc)
13962 (if_then_else (match_operator 0 "comparison_operator"
13963 [(match_operand 1 "register_operand" "f,x")
13964 (match_operand 2 "nonimmediate_operand" "f,xm")])
13965 (label_ref (match_operand 3 "" ""))
13966 (pc)))
13967 (clobber (reg:CCFP FPSR_REG))
13968 (clobber (reg:CCFP FLAGS_REG))]
13969 "TARGET_MIX_SSE_I387
13970 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13971 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13972 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13973 "#")
13974
13975 (define_insn "*fp_jcc_1_sse"
13976 [(set (pc)
13977 (if_then_else (match_operator 0 "comparison_operator"
13978 [(match_operand 1 "register_operand" "x")
13979 (match_operand 2 "nonimmediate_operand" "xm")])
13980 (label_ref (match_operand 3 "" ""))
13981 (pc)))
13982 (clobber (reg:CCFP FPSR_REG))
13983 (clobber (reg:CCFP FLAGS_REG))]
13984 "TARGET_SSE_MATH
13985 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13986 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13987 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13988 "#")
13989
13990 (define_insn "*fp_jcc_1_387"
13991 [(set (pc)
13992 (if_then_else (match_operator 0 "comparison_operator"
13993 [(match_operand 1 "register_operand" "f")
13994 (match_operand 2 "register_operand" "f")])
13995 (label_ref (match_operand 3 "" ""))
13996 (pc)))
13997 (clobber (reg:CCFP FPSR_REG))
13998 (clobber (reg:CCFP FLAGS_REG))]
13999 "TARGET_CMOVE && TARGET_80387
14000 && FLOAT_MODE_P (GET_MODE (operands[1]))
14001 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14002 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14003 "#")
14004
14005 (define_insn "*fp_jcc_2_mixed"
14006 [(set (pc)
14007 (if_then_else (match_operator 0 "comparison_operator"
14008 [(match_operand 1 "register_operand" "f,x")
14009 (match_operand 2 "nonimmediate_operand" "f,xm")])
14010 (pc)
14011 (label_ref (match_operand 3 "" ""))))
14012 (clobber (reg:CCFP FPSR_REG))
14013 (clobber (reg:CCFP FLAGS_REG))]
14014 "TARGET_MIX_SSE_I387
14015 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14016 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14017 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14018 "#")
14019
14020 (define_insn "*fp_jcc_2_sse"
14021 [(set (pc)
14022 (if_then_else (match_operator 0 "comparison_operator"
14023 [(match_operand 1 "register_operand" "x")
14024 (match_operand 2 "nonimmediate_operand" "xm")])
14025 (pc)
14026 (label_ref (match_operand 3 "" ""))))
14027 (clobber (reg:CCFP FPSR_REG))
14028 (clobber (reg:CCFP FLAGS_REG))]
14029 "TARGET_SSE_MATH
14030 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14031 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14032 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14033 "#")
14034
14035 (define_insn "*fp_jcc_2_387"
14036 [(set (pc)
14037 (if_then_else (match_operator 0 "comparison_operator"
14038 [(match_operand 1 "register_operand" "f")
14039 (match_operand 2 "register_operand" "f")])
14040 (pc)
14041 (label_ref (match_operand 3 "" ""))))
14042 (clobber (reg:CCFP FPSR_REG))
14043 (clobber (reg:CCFP FLAGS_REG))]
14044 "TARGET_CMOVE && TARGET_80387
14045 && FLOAT_MODE_P (GET_MODE (operands[1]))
14046 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14047 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14048 "#")
14049
14050 (define_insn "*fp_jcc_3_387"
14051 [(set (pc)
14052 (if_then_else (match_operator 0 "comparison_operator"
14053 [(match_operand 1 "register_operand" "f")
14054 (match_operand 2 "nonimmediate_operand" "fm")])
14055 (label_ref (match_operand 3 "" ""))
14056 (pc)))
14057 (clobber (reg:CCFP FPSR_REG))
14058 (clobber (reg:CCFP FLAGS_REG))
14059 (clobber (match_scratch:HI 4 "=a"))]
14060 "TARGET_80387
14061 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14062 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14063 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14064 && SELECT_CC_MODE (GET_CODE (operands[0]),
14065 operands[1], operands[2]) == CCFPmode
14066 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14067 "#")
14068
14069 (define_insn "*fp_jcc_4_387"
14070 [(set (pc)
14071 (if_then_else (match_operator 0 "comparison_operator"
14072 [(match_operand 1 "register_operand" "f")
14073 (match_operand 2 "nonimmediate_operand" "fm")])
14074 (pc)
14075 (label_ref (match_operand 3 "" ""))))
14076 (clobber (reg:CCFP FPSR_REG))
14077 (clobber (reg:CCFP FLAGS_REG))
14078 (clobber (match_scratch:HI 4 "=a"))]
14079 "TARGET_80387
14080 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14081 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14082 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14083 && SELECT_CC_MODE (GET_CODE (operands[0]),
14084 operands[1], operands[2]) == CCFPmode
14085 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14086 "#")
14087
14088 (define_insn "*fp_jcc_5_387"
14089 [(set (pc)
14090 (if_then_else (match_operator 0 "comparison_operator"
14091 [(match_operand 1 "register_operand" "f")
14092 (match_operand 2 "register_operand" "f")])
14093 (label_ref (match_operand 3 "" ""))
14094 (pc)))
14095 (clobber (reg:CCFP FPSR_REG))
14096 (clobber (reg:CCFP FLAGS_REG))
14097 (clobber (match_scratch:HI 4 "=a"))]
14098 "TARGET_80387
14099 && FLOAT_MODE_P (GET_MODE (operands[1]))
14100 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14101 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14102 "#")
14103
14104 (define_insn "*fp_jcc_6_387"
14105 [(set (pc)
14106 (if_then_else (match_operator 0 "comparison_operator"
14107 [(match_operand 1 "register_operand" "f")
14108 (match_operand 2 "register_operand" "f")])
14109 (pc)
14110 (label_ref (match_operand 3 "" ""))))
14111 (clobber (reg:CCFP FPSR_REG))
14112 (clobber (reg:CCFP FLAGS_REG))
14113 (clobber (match_scratch:HI 4 "=a"))]
14114 "TARGET_80387
14115 && FLOAT_MODE_P (GET_MODE (operands[1]))
14116 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14117 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14118 "#")
14119
14120 (define_insn "*fp_jcc_7_387"
14121 [(set (pc)
14122 (if_then_else (match_operator 0 "comparison_operator"
14123 [(match_operand 1 "register_operand" "f")
14124 (match_operand 2 "const0_operand" "X")])
14125 (label_ref (match_operand 3 "" ""))
14126 (pc)))
14127 (clobber (reg:CCFP FPSR_REG))
14128 (clobber (reg:CCFP FLAGS_REG))
14129 (clobber (match_scratch:HI 4 "=a"))]
14130 "TARGET_80387
14131 && FLOAT_MODE_P (GET_MODE (operands[1]))
14132 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14133 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14134 && SELECT_CC_MODE (GET_CODE (operands[0]),
14135 operands[1], operands[2]) == CCFPmode
14136 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14137 "#")
14138
14139 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14140 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14141 ;; with a precedence over other operators and is always put in the first
14142 ;; place. Swap condition and operands to match ficom instruction.
14143
14144 (define_insn "*fp_jcc_8<mode>_387"
14145 [(set (pc)
14146 (if_then_else (match_operator 0 "comparison_operator"
14147 [(match_operator 1 "float_operator"
14148 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14149 (match_operand 3 "register_operand" "f,f")])
14150 (label_ref (match_operand 4 "" ""))
14151 (pc)))
14152 (clobber (reg:CCFP FPSR_REG))
14153 (clobber (reg:CCFP FLAGS_REG))
14154 (clobber (match_scratch:HI 5 "=a,a"))]
14155 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14156 && FLOAT_MODE_P (GET_MODE (operands[3]))
14157 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14158 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14159 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14160 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14161 "#")
14162
14163 (define_split
14164 [(set (pc)
14165 (if_then_else (match_operator 0 "comparison_operator"
14166 [(match_operand 1 "register_operand" "")
14167 (match_operand 2 "nonimmediate_operand" "")])
14168 (match_operand 3 "" "")
14169 (match_operand 4 "" "")))
14170 (clobber (reg:CCFP FPSR_REG))
14171 (clobber (reg:CCFP FLAGS_REG))]
14172 "reload_completed"
14173 [(const_int 0)]
14174 {
14175 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14176 operands[3], operands[4], NULL_RTX, NULL_RTX);
14177 DONE;
14178 })
14179
14180 (define_split
14181 [(set (pc)
14182 (if_then_else (match_operator 0 "comparison_operator"
14183 [(match_operand 1 "register_operand" "")
14184 (match_operand 2 "general_operand" "")])
14185 (match_operand 3 "" "")
14186 (match_operand 4 "" "")))
14187 (clobber (reg:CCFP FPSR_REG))
14188 (clobber (reg:CCFP FLAGS_REG))
14189 (clobber (match_scratch:HI 5 "=a"))]
14190 "reload_completed"
14191 [(const_int 0)]
14192 {
14193 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14194 operands[3], operands[4], operands[5], NULL_RTX);
14195 DONE;
14196 })
14197
14198 (define_split
14199 [(set (pc)
14200 (if_then_else (match_operator 0 "comparison_operator"
14201 [(match_operator 1 "float_operator"
14202 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14203 (match_operand 3 "register_operand" "")])
14204 (match_operand 4 "" "")
14205 (match_operand 5 "" "")))
14206 (clobber (reg:CCFP FPSR_REG))
14207 (clobber (reg:CCFP FLAGS_REG))
14208 (clobber (match_scratch:HI 6 "=a"))]
14209 "reload_completed"
14210 [(const_int 0)]
14211 {
14212 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14213 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14214 operands[3], operands[7],
14215 operands[4], operands[5], operands[6], NULL_RTX);
14216 DONE;
14217 })
14218
14219 ;; %%% Kill this when reload knows how to do it.
14220 (define_split
14221 [(set (pc)
14222 (if_then_else (match_operator 0 "comparison_operator"
14223 [(match_operator 1 "float_operator"
14224 [(match_operand:X87MODEI12 2 "register_operand" "")])
14225 (match_operand 3 "register_operand" "")])
14226 (match_operand 4 "" "")
14227 (match_operand 5 "" "")))
14228 (clobber (reg:CCFP FPSR_REG))
14229 (clobber (reg:CCFP FLAGS_REG))
14230 (clobber (match_scratch:HI 6 "=a"))]
14231 "reload_completed"
14232 [(const_int 0)]
14233 {
14234 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14235 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14236 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14237 operands[3], operands[7],
14238 operands[4], operands[5], operands[6], operands[2]);
14239 DONE;
14240 })
14241 \f
14242 ;; Unconditional and other jump instructions
14243
14244 (define_insn "jump"
14245 [(set (pc)
14246 (label_ref (match_operand 0 "" "")))]
14247 ""
14248 "jmp\t%l0"
14249 [(set_attr "type" "ibr")
14250 (set (attr "length")
14251 (if_then_else (and (ge (minus (match_dup 0) (pc))
14252 (const_int -126))
14253 (lt (minus (match_dup 0) (pc))
14254 (const_int 128)))
14255 (const_int 2)
14256 (const_int 5)))
14257 (set_attr "modrm" "0")])
14258
14259 (define_expand "indirect_jump"
14260 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14261 ""
14262 "")
14263
14264 (define_insn "*indirect_jump"
14265 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14266 "!TARGET_64BIT"
14267 "jmp\t%A0"
14268 [(set_attr "type" "ibr")
14269 (set_attr "length_immediate" "0")])
14270
14271 (define_insn "*indirect_jump_rtx64"
14272 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14273 "TARGET_64BIT"
14274 "jmp\t%A0"
14275 [(set_attr "type" "ibr")
14276 (set_attr "length_immediate" "0")])
14277
14278 (define_expand "tablejump"
14279 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14280 (use (label_ref (match_operand 1 "" "")))])]
14281 ""
14282 {
14283 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14284 relative. Convert the relative address to an absolute address. */
14285 if (flag_pic)
14286 {
14287 rtx op0, op1;
14288 enum rtx_code code;
14289
14290 if (TARGET_64BIT)
14291 {
14292 code = PLUS;
14293 op0 = operands[0];
14294 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14295 }
14296 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14297 {
14298 code = PLUS;
14299 op0 = operands[0];
14300 op1 = pic_offset_table_rtx;
14301 }
14302 else
14303 {
14304 code = MINUS;
14305 op0 = pic_offset_table_rtx;
14306 op1 = operands[0];
14307 }
14308
14309 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14310 OPTAB_DIRECT);
14311 }
14312 })
14313
14314 (define_insn "*tablejump_1"
14315 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14316 (use (label_ref (match_operand 1 "" "")))]
14317 "!TARGET_64BIT"
14318 "jmp\t%A0"
14319 [(set_attr "type" "ibr")
14320 (set_attr "length_immediate" "0")])
14321
14322 (define_insn "*tablejump_1_rtx64"
14323 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14324 (use (label_ref (match_operand 1 "" "")))]
14325 "TARGET_64BIT"
14326 "jmp\t%A0"
14327 [(set_attr "type" "ibr")
14328 (set_attr "length_immediate" "0")])
14329 \f
14330 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14331
14332 (define_peephole2
14333 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14334 (set (match_operand:QI 1 "register_operand" "")
14335 (match_operator:QI 2 "ix86_comparison_operator"
14336 [(reg FLAGS_REG) (const_int 0)]))
14337 (set (match_operand 3 "q_regs_operand" "")
14338 (zero_extend (match_dup 1)))]
14339 "(peep2_reg_dead_p (3, operands[1])
14340 || operands_match_p (operands[1], operands[3]))
14341 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14342 [(set (match_dup 4) (match_dup 0))
14343 (set (strict_low_part (match_dup 5))
14344 (match_dup 2))]
14345 {
14346 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14347 operands[5] = gen_lowpart (QImode, operands[3]);
14348 ix86_expand_clear (operands[3]);
14349 })
14350
14351 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14352
14353 (define_peephole2
14354 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14355 (set (match_operand:QI 1 "register_operand" "")
14356 (match_operator:QI 2 "ix86_comparison_operator"
14357 [(reg FLAGS_REG) (const_int 0)]))
14358 (parallel [(set (match_operand 3 "q_regs_operand" "")
14359 (zero_extend (match_dup 1)))
14360 (clobber (reg:CC FLAGS_REG))])]
14361 "(peep2_reg_dead_p (3, operands[1])
14362 || operands_match_p (operands[1], operands[3]))
14363 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14364 [(set (match_dup 4) (match_dup 0))
14365 (set (strict_low_part (match_dup 5))
14366 (match_dup 2))]
14367 {
14368 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14369 operands[5] = gen_lowpart (QImode, operands[3]);
14370 ix86_expand_clear (operands[3]);
14371 })
14372 \f
14373 ;; Call instructions.
14374
14375 ;; The predicates normally associated with named expanders are not properly
14376 ;; checked for calls. This is a bug in the generic code, but it isn't that
14377 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14378
14379 ;; Call subroutine returning no value.
14380
14381 (define_expand "call_pop"
14382 [(parallel [(call (match_operand:QI 0 "" "")
14383 (match_operand:SI 1 "" ""))
14384 (set (reg:SI SP_REG)
14385 (plus:SI (reg:SI SP_REG)
14386 (match_operand:SI 3 "" "")))])]
14387 "!TARGET_64BIT"
14388 {
14389 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14390 DONE;
14391 })
14392
14393 (define_insn "*call_pop_0"
14394 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14395 (match_operand:SI 1 "" ""))
14396 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14397 (match_operand:SI 2 "immediate_operand" "")))]
14398 "!TARGET_64BIT"
14399 {
14400 if (SIBLING_CALL_P (insn))
14401 return "jmp\t%P0";
14402 else
14403 return "call\t%P0";
14404 }
14405 [(set_attr "type" "call")])
14406
14407 (define_insn "*call_pop_1"
14408 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14409 (match_operand:SI 1 "" ""))
14410 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14411 (match_operand:SI 2 "immediate_operand" "i")))]
14412 "!TARGET_64BIT"
14413 {
14414 if (constant_call_address_operand (operands[0], Pmode))
14415 {
14416 if (SIBLING_CALL_P (insn))
14417 return "jmp\t%P0";
14418 else
14419 return "call\t%P0";
14420 }
14421 if (SIBLING_CALL_P (insn))
14422 return "jmp\t%A0";
14423 else
14424 return "call\t%A0";
14425 }
14426 [(set_attr "type" "call")])
14427
14428 (define_expand "call"
14429 [(call (match_operand:QI 0 "" "")
14430 (match_operand 1 "" ""))
14431 (use (match_operand 2 "" ""))]
14432 ""
14433 {
14434 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14435 DONE;
14436 })
14437
14438 (define_expand "sibcall"
14439 [(call (match_operand:QI 0 "" "")
14440 (match_operand 1 "" ""))
14441 (use (match_operand 2 "" ""))]
14442 ""
14443 {
14444 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14445 DONE;
14446 })
14447
14448 (define_insn "*call_0"
14449 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14450 (match_operand 1 "" ""))]
14451 ""
14452 {
14453 if (SIBLING_CALL_P (insn))
14454 return "jmp\t%P0";
14455 else
14456 return "call\t%P0";
14457 }
14458 [(set_attr "type" "call")])
14459
14460 (define_insn "*call_1"
14461 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14462 (match_operand 1 "" ""))]
14463 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14464 {
14465 if (constant_call_address_operand (operands[0], Pmode))
14466 return "call\t%P0";
14467 return "call\t%A0";
14468 }
14469 [(set_attr "type" "call")])
14470
14471 (define_insn "*sibcall_1"
14472 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14473 (match_operand 1 "" ""))]
14474 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14475 {
14476 if (constant_call_address_operand (operands[0], Pmode))
14477 return "jmp\t%P0";
14478 return "jmp\t%A0";
14479 }
14480 [(set_attr "type" "call")])
14481
14482 (define_insn "*call_1_rex64"
14483 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14484 (match_operand 1 "" ""))]
14485 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14486 {
14487 if (constant_call_address_operand (operands[0], Pmode))
14488 return "call\t%P0";
14489 return "call\t%A0";
14490 }
14491 [(set_attr "type" "call")])
14492
14493 (define_insn "*sibcall_1_rex64"
14494 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14495 (match_operand 1 "" ""))]
14496 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14497 "jmp\t%P0"
14498 [(set_attr "type" "call")])
14499
14500 (define_insn "*sibcall_1_rex64_v"
14501 [(call (mem:QI (reg:DI R11_REG))
14502 (match_operand 0 "" ""))]
14503 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14504 "jmp\t*%%r11"
14505 [(set_attr "type" "call")])
14506
14507
14508 ;; Call subroutine, returning value in operand 0
14509
14510 (define_expand "call_value_pop"
14511 [(parallel [(set (match_operand 0 "" "")
14512 (call (match_operand:QI 1 "" "")
14513 (match_operand:SI 2 "" "")))
14514 (set (reg:SI SP_REG)
14515 (plus:SI (reg:SI SP_REG)
14516 (match_operand:SI 4 "" "")))])]
14517 "!TARGET_64BIT"
14518 {
14519 ix86_expand_call (operands[0], operands[1], operands[2],
14520 operands[3], operands[4], 0);
14521 DONE;
14522 })
14523
14524 (define_expand "call_value"
14525 [(set (match_operand 0 "" "")
14526 (call (match_operand:QI 1 "" "")
14527 (match_operand:SI 2 "" "")))
14528 (use (match_operand:SI 3 "" ""))]
14529 ;; Operand 2 not used on the i386.
14530 ""
14531 {
14532 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14533 DONE;
14534 })
14535
14536 (define_expand "sibcall_value"
14537 [(set (match_operand 0 "" "")
14538 (call (match_operand:QI 1 "" "")
14539 (match_operand:SI 2 "" "")))
14540 (use (match_operand:SI 3 "" ""))]
14541 ;; Operand 2 not used on the i386.
14542 ""
14543 {
14544 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14545 DONE;
14546 })
14547
14548 ;; Call subroutine returning any type.
14549
14550 (define_expand "untyped_call"
14551 [(parallel [(call (match_operand 0 "" "")
14552 (const_int 0))
14553 (match_operand 1 "" "")
14554 (match_operand 2 "" "")])]
14555 ""
14556 {
14557 int i;
14558
14559 /* In order to give reg-stack an easier job in validating two
14560 coprocessor registers as containing a possible return value,
14561 simply pretend the untyped call returns a complex long double
14562 value. */
14563
14564 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14565 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14566 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14567 NULL, 0);
14568
14569 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14570 {
14571 rtx set = XVECEXP (operands[2], 0, i);
14572 emit_move_insn (SET_DEST (set), SET_SRC (set));
14573 }
14574
14575 /* The optimizer does not know that the call sets the function value
14576 registers we stored in the result block. We avoid problems by
14577 claiming that all hard registers are used and clobbered at this
14578 point. */
14579 emit_insn (gen_blockage (const0_rtx));
14580
14581 DONE;
14582 })
14583 \f
14584 ;; Prologue and epilogue instructions
14585
14586 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14587 ;; all of memory. This blocks insns from being moved across this point.
14588
14589 (define_insn "blockage"
14590 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14591 ""
14592 ""
14593 [(set_attr "length" "0")])
14594
14595 ;; Insn emitted into the body of a function to return from a function.
14596 ;; This is only done if the function's epilogue is known to be simple.
14597 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14598
14599 (define_expand "return"
14600 [(return)]
14601 "ix86_can_use_return_insn_p ()"
14602 {
14603 if (current_function_pops_args)
14604 {
14605 rtx popc = GEN_INT (current_function_pops_args);
14606 emit_jump_insn (gen_return_pop_internal (popc));
14607 DONE;
14608 }
14609 })
14610
14611 (define_insn "return_internal"
14612 [(return)]
14613 "reload_completed"
14614 "ret"
14615 [(set_attr "length" "1")
14616 (set_attr "length_immediate" "0")
14617 (set_attr "modrm" "0")])
14618
14619 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14620 ;; instruction Athlon and K8 have.
14621
14622 (define_insn "return_internal_long"
14623 [(return)
14624 (unspec [(const_int 0)] UNSPEC_REP)]
14625 "reload_completed"
14626 "rep {;} ret"
14627 [(set_attr "length" "1")
14628 (set_attr "length_immediate" "0")
14629 (set_attr "prefix_rep" "1")
14630 (set_attr "modrm" "0")])
14631
14632 (define_insn "return_pop_internal"
14633 [(return)
14634 (use (match_operand:SI 0 "const_int_operand" ""))]
14635 "reload_completed"
14636 "ret\t%0"
14637 [(set_attr "length" "3")
14638 (set_attr "length_immediate" "2")
14639 (set_attr "modrm" "0")])
14640
14641 (define_insn "return_indirect_internal"
14642 [(return)
14643 (use (match_operand:SI 0 "register_operand" "r"))]
14644 "reload_completed"
14645 "jmp\t%A0"
14646 [(set_attr "type" "ibr")
14647 (set_attr "length_immediate" "0")])
14648
14649 (define_insn "nop"
14650 [(const_int 0)]
14651 ""
14652 "nop"
14653 [(set_attr "length" "1")
14654 (set_attr "length_immediate" "0")
14655 (set_attr "modrm" "0")])
14656
14657 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14658 ;; branch prediction penalty for the third jump in a 16-byte
14659 ;; block on K8.
14660
14661 (define_insn "align"
14662 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14663 ""
14664 {
14665 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14666 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14667 #else
14668 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14669 The align insn is used to avoid 3 jump instructions in the row to improve
14670 branch prediction and the benefits hardly outweigh the cost of extra 8
14671 nops on the average inserted by full alignment pseudo operation. */
14672 #endif
14673 return "";
14674 }
14675 [(set_attr "length" "16")])
14676
14677 (define_expand "prologue"
14678 [(const_int 1)]
14679 ""
14680 "ix86_expand_prologue (); DONE;")
14681
14682 (define_insn "set_got"
14683 [(set (match_operand:SI 0 "register_operand" "=r")
14684 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14685 (clobber (reg:CC FLAGS_REG))]
14686 "!TARGET_64BIT"
14687 { return output_set_got (operands[0], NULL_RTX); }
14688 [(set_attr "type" "multi")
14689 (set_attr "length" "12")])
14690
14691 (define_insn "set_got_labelled"
14692 [(set (match_operand:SI 0 "register_operand" "=r")
14693 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14694 UNSPEC_SET_GOT))
14695 (clobber (reg:CC FLAGS_REG))]
14696 "!TARGET_64BIT"
14697 { return output_set_got (operands[0], operands[1]); }
14698 [(set_attr "type" "multi")
14699 (set_attr "length" "12")])
14700
14701 (define_insn "set_got_rex64"
14702 [(set (match_operand:DI 0 "register_operand" "=r")
14703 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14704 "TARGET_64BIT"
14705 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14706 [(set_attr "type" "lea")
14707 (set_attr "length" "6")])
14708
14709 (define_expand "epilogue"
14710 [(const_int 1)]
14711 ""
14712 "ix86_expand_epilogue (1); DONE;")
14713
14714 (define_expand "sibcall_epilogue"
14715 [(const_int 1)]
14716 ""
14717 "ix86_expand_epilogue (0); DONE;")
14718
14719 (define_expand "eh_return"
14720 [(use (match_operand 0 "register_operand" ""))]
14721 ""
14722 {
14723 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14724
14725 /* Tricky bit: we write the address of the handler to which we will
14726 be returning into someone else's stack frame, one word below the
14727 stack address we wish to restore. */
14728 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14729 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14730 tmp = gen_rtx_MEM (Pmode, tmp);
14731 emit_move_insn (tmp, ra);
14732
14733 if (Pmode == SImode)
14734 emit_jump_insn (gen_eh_return_si (sa));
14735 else
14736 emit_jump_insn (gen_eh_return_di (sa));
14737 emit_barrier ();
14738 DONE;
14739 })
14740
14741 (define_insn_and_split "eh_return_si"
14742 [(set (pc)
14743 (unspec [(match_operand:SI 0 "register_operand" "c")]
14744 UNSPEC_EH_RETURN))]
14745 "!TARGET_64BIT"
14746 "#"
14747 "reload_completed"
14748 [(const_int 1)]
14749 "ix86_expand_epilogue (2); DONE;")
14750
14751 (define_insn_and_split "eh_return_di"
14752 [(set (pc)
14753 (unspec [(match_operand:DI 0 "register_operand" "c")]
14754 UNSPEC_EH_RETURN))]
14755 "TARGET_64BIT"
14756 "#"
14757 "reload_completed"
14758 [(const_int 1)]
14759 "ix86_expand_epilogue (2); DONE;")
14760
14761 (define_insn "leave"
14762 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14763 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14764 (clobber (mem:BLK (scratch)))]
14765 "!TARGET_64BIT"
14766 "leave"
14767 [(set_attr "type" "leave")])
14768
14769 (define_insn "leave_rex64"
14770 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14771 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14772 (clobber (mem:BLK (scratch)))]
14773 "TARGET_64BIT"
14774 "leave"
14775 [(set_attr "type" "leave")])
14776 \f
14777 (define_expand "ffssi2"
14778 [(parallel
14779 [(set (match_operand:SI 0 "register_operand" "")
14780 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14781 (clobber (match_scratch:SI 2 ""))
14782 (clobber (reg:CC FLAGS_REG))])]
14783 ""
14784 "")
14785
14786 (define_insn_and_split "*ffs_cmove"
14787 [(set (match_operand:SI 0 "register_operand" "=r")
14788 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14789 (clobber (match_scratch:SI 2 "=&r"))
14790 (clobber (reg:CC FLAGS_REG))]
14791 "TARGET_CMOVE"
14792 "#"
14793 "&& reload_completed"
14794 [(set (match_dup 2) (const_int -1))
14795 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14796 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14797 (set (match_dup 0) (if_then_else:SI
14798 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14799 (match_dup 2)
14800 (match_dup 0)))
14801 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14802 (clobber (reg:CC FLAGS_REG))])]
14803 "")
14804
14805 (define_insn_and_split "*ffs_no_cmove"
14806 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14807 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14808 (clobber (match_scratch:SI 2 "=&q"))
14809 (clobber (reg:CC FLAGS_REG))]
14810 ""
14811 "#"
14812 "reload_completed"
14813 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14814 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14815 (set (strict_low_part (match_dup 3))
14816 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14817 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14818 (clobber (reg:CC FLAGS_REG))])
14819 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14820 (clobber (reg:CC FLAGS_REG))])
14821 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14822 (clobber (reg:CC FLAGS_REG))])]
14823 {
14824 operands[3] = gen_lowpart (QImode, operands[2]);
14825 ix86_expand_clear (operands[2]);
14826 })
14827
14828 (define_insn "*ffssi_1"
14829 [(set (reg:CCZ FLAGS_REG)
14830 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14831 (const_int 0)))
14832 (set (match_operand:SI 0 "register_operand" "=r")
14833 (ctz:SI (match_dup 1)))]
14834 ""
14835 "bsf{l}\t{%1, %0|%0, %1}"
14836 [(set_attr "prefix_0f" "1")])
14837
14838 (define_expand "ffsdi2"
14839 [(parallel
14840 [(set (match_operand:DI 0 "register_operand" "")
14841 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14842 (clobber (match_scratch:DI 2 ""))
14843 (clobber (reg:CC FLAGS_REG))])]
14844 "TARGET_64BIT && TARGET_CMOVE"
14845 "")
14846
14847 (define_insn_and_split "*ffs_rex64"
14848 [(set (match_operand:DI 0 "register_operand" "=r")
14849 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14850 (clobber (match_scratch:DI 2 "=&r"))
14851 (clobber (reg:CC FLAGS_REG))]
14852 "TARGET_64BIT && TARGET_CMOVE"
14853 "#"
14854 "&& reload_completed"
14855 [(set (match_dup 2) (const_int -1))
14856 (parallel [(set (reg:CCZ FLAGS_REG)
14857 (compare:CCZ (match_dup 1) (const_int 0)))
14858 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14859 (set (match_dup 0) (if_then_else:DI
14860 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14861 (match_dup 2)
14862 (match_dup 0)))
14863 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14864 (clobber (reg:CC FLAGS_REG))])]
14865 "")
14866
14867 (define_insn "*ffsdi_1"
14868 [(set (reg:CCZ FLAGS_REG)
14869 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14870 (const_int 0)))
14871 (set (match_operand:DI 0 "register_operand" "=r")
14872 (ctz:DI (match_dup 1)))]
14873 "TARGET_64BIT"
14874 "bsf{q}\t{%1, %0|%0, %1}"
14875 [(set_attr "prefix_0f" "1")])
14876
14877 (define_insn "ctzsi2"
14878 [(set (match_operand:SI 0 "register_operand" "=r")
14879 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14880 (clobber (reg:CC FLAGS_REG))]
14881 ""
14882 "bsf{l}\t{%1, %0|%0, %1}"
14883 [(set_attr "prefix_0f" "1")])
14884
14885 (define_insn "ctzdi2"
14886 [(set (match_operand:DI 0 "register_operand" "=r")
14887 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14888 (clobber (reg:CC FLAGS_REG))]
14889 "TARGET_64BIT"
14890 "bsf{q}\t{%1, %0|%0, %1}"
14891 [(set_attr "prefix_0f" "1")])
14892
14893 (define_expand "clzsi2"
14894 [(parallel
14895 [(set (match_operand:SI 0 "register_operand" "")
14896 (minus:SI (const_int 31)
14897 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14898 (clobber (reg:CC FLAGS_REG))])
14899 (parallel
14900 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14901 (clobber (reg:CC FLAGS_REG))])]
14902 ""
14903 {
14904 if (TARGET_ABM)
14905 {
14906 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14907 DONE;
14908 }
14909 })
14910
14911 (define_insn "clzsi2_abm"
14912 [(set (match_operand:SI 0 "register_operand" "=r")
14913 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14914 (clobber (reg:CC FLAGS_REG))]
14915 "TARGET_ABM"
14916 "lzcnt{l}\t{%1, %0|%0, %1}"
14917 [(set_attr "prefix_rep" "1")
14918 (set_attr "type" "bitmanip")
14919 (set_attr "mode" "SI")])
14920
14921 (define_insn "*bsr"
14922 [(set (match_operand:SI 0 "register_operand" "=r")
14923 (minus:SI (const_int 31)
14924 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14925 (clobber (reg:CC FLAGS_REG))]
14926 ""
14927 "bsr{l}\t{%1, %0|%0, %1}"
14928 [(set_attr "prefix_0f" "1")
14929 (set_attr "mode" "SI")])
14930
14931 (define_insn "popcountsi2"
14932 [(set (match_operand:SI 0 "register_operand" "=r")
14933 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14934 (clobber (reg:CC FLAGS_REG))]
14935 "TARGET_POPCNT"
14936 "popcnt{l}\t{%1, %0|%0, %1}"
14937 [(set_attr "prefix_rep" "1")
14938 (set_attr "type" "bitmanip")
14939 (set_attr "mode" "SI")])
14940
14941 (define_insn "*popcountsi2_cmp"
14942 [(set (reg FLAGS_REG)
14943 (compare
14944 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14945 (const_int 0)))
14946 (set (match_operand:SI 0 "register_operand" "=r")
14947 (popcount:SI (match_dup 1)))]
14948 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14949 "popcnt{l}\t{%1, %0|%0, %1}"
14950 [(set_attr "prefix_rep" "1")
14951 (set_attr "type" "bitmanip")
14952 (set_attr "mode" "SI")])
14953
14954 (define_insn "*popcountsi2_cmp_zext"
14955 [(set (reg FLAGS_REG)
14956 (compare
14957 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14958 (const_int 0)))
14959 (set (match_operand:DI 0 "register_operand" "=r")
14960 (zero_extend:DI(popcount:SI (match_dup 1))))]
14961 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14962 "popcnt{l}\t{%1, %0|%0, %1}"
14963 [(set_attr "prefix_rep" "1")
14964 (set_attr "type" "bitmanip")
14965 (set_attr "mode" "SI")])
14966
14967 (define_insn "bswapsi2"
14968 [(set (match_operand:SI 0 "register_operand" "=r")
14969 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14970 (clobber (reg:CC FLAGS_REG))]
14971 "TARGET_BSWAP"
14972 "bswap\t%k0"
14973 [(set_attr "prefix_0f" "1")
14974 (set_attr "length" "2")])
14975
14976 (define_insn "*bswapdi2_rex"
14977 [(set (match_operand:DI 0 "register_operand" "=r")
14978 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14979 (clobber (reg:CC FLAGS_REG))]
14980 "TARGET_64BIT && TARGET_BSWAP"
14981 "bswap\t%0"
14982 [(set_attr "prefix_0f" "1")
14983 (set_attr "length" "3")])
14984
14985 (define_expand "bswapdi2"
14986 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14987 (bswap:DI (match_operand:DI 1 "register_operand" "")))
14988 (clobber (reg:CC FLAGS_REG))])]
14989 "TARGET_BSWAP"
14990 {
14991 if (!TARGET_64BIT)
14992 {
14993 rtx tmp1, tmp2;
14994 tmp1 = gen_reg_rtx (SImode);
14995 tmp2 = gen_reg_rtx (SImode);
14996 emit_insn (gen_bswapsi2 (tmp1, gen_lowpart (SImode, operands[1])));
14997 emit_insn (gen_bswapsi2 (tmp2, gen_highpart (SImode, operands[1])));
14998 emit_move_insn (gen_lowpart (SImode, operands[0]), tmp2);
14999 emit_move_insn (gen_highpart (SImode, operands[0]), tmp1);
15000 DONE;
15001 }
15002 })
15003
15004 (define_expand "clzdi2"
15005 [(parallel
15006 [(set (match_operand:DI 0 "register_operand" "")
15007 (minus:DI (const_int 63)
15008 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15009 (clobber (reg:CC FLAGS_REG))])
15010 (parallel
15011 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15012 (clobber (reg:CC FLAGS_REG))])]
15013 "TARGET_64BIT"
15014 {
15015 if (TARGET_ABM)
15016 {
15017 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15018 DONE;
15019 }
15020 })
15021
15022 (define_insn "clzdi2_abm"
15023 [(set (match_operand:DI 0 "register_operand" "=r")
15024 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15025 (clobber (reg:CC FLAGS_REG))]
15026 "TARGET_64BIT && TARGET_ABM"
15027 "lzcnt{q}\t{%1, %0|%0, %1}"
15028 [(set_attr "prefix_rep" "1")
15029 (set_attr "type" "bitmanip")
15030 (set_attr "mode" "DI")])
15031
15032 (define_insn "*bsr_rex64"
15033 [(set (match_operand:DI 0 "register_operand" "=r")
15034 (minus:DI (const_int 63)
15035 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15036 (clobber (reg:CC FLAGS_REG))]
15037 "TARGET_64BIT"
15038 "bsr{q}\t{%1, %0|%0, %1}"
15039 [(set_attr "prefix_0f" "1")
15040 (set_attr "mode" "DI")])
15041
15042 (define_insn "popcountdi2"
15043 [(set (match_operand:DI 0 "register_operand" "=r")
15044 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15045 (clobber (reg:CC FLAGS_REG))]
15046 "TARGET_64BIT && TARGET_POPCNT"
15047 "popcnt{q}\t{%1, %0|%0, %1}"
15048 [(set_attr "prefix_rep" "1")
15049 (set_attr "type" "bitmanip")
15050 (set_attr "mode" "DI")])
15051
15052 (define_insn "*popcountdi2_cmp"
15053 [(set (reg FLAGS_REG)
15054 (compare
15055 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15056 (const_int 0)))
15057 (set (match_operand:DI 0 "register_operand" "=r")
15058 (popcount:DI (match_dup 1)))]
15059 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15060 "popcnt{q}\t{%1, %0|%0, %1}"
15061 [(set_attr "prefix_rep" "1")
15062 (set_attr "type" "bitmanip")
15063 (set_attr "mode" "DI")])
15064
15065 (define_expand "clzhi2"
15066 [(parallel
15067 [(set (match_operand:HI 0 "register_operand" "")
15068 (minus:HI (const_int 15)
15069 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15070 (clobber (reg:CC FLAGS_REG))])
15071 (parallel
15072 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15073 (clobber (reg:CC FLAGS_REG))])]
15074 ""
15075 {
15076 if (TARGET_ABM)
15077 {
15078 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15079 DONE;
15080 }
15081 })
15082
15083 (define_insn "clzhi2_abm"
15084 [(set (match_operand:HI 0 "register_operand" "=r")
15085 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15086 (clobber (reg:CC FLAGS_REG))]
15087 "TARGET_ABM"
15088 "lzcnt{w}\t{%1, %0|%0, %1}"
15089 [(set_attr "prefix_rep" "1")
15090 (set_attr "type" "bitmanip")
15091 (set_attr "mode" "HI")])
15092
15093 (define_insn "*bsrhi"
15094 [(set (match_operand:HI 0 "register_operand" "=r")
15095 (minus:HI (const_int 15)
15096 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15097 (clobber (reg:CC FLAGS_REG))]
15098 ""
15099 "bsr{w}\t{%1, %0|%0, %1}"
15100 [(set_attr "prefix_0f" "1")
15101 (set_attr "mode" "HI")])
15102
15103 (define_insn "popcounthi2"
15104 [(set (match_operand:HI 0 "register_operand" "=r")
15105 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15106 (clobber (reg:CC FLAGS_REG))]
15107 "TARGET_POPCNT"
15108 "popcnt{w}\t{%1, %0|%0, %1}"
15109 [(set_attr "prefix_rep" "1")
15110 (set_attr "type" "bitmanip")
15111 (set_attr "mode" "HI")])
15112
15113 (define_insn "*popcounthi2_cmp"
15114 [(set (reg FLAGS_REG)
15115 (compare
15116 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15117 (const_int 0)))
15118 (set (match_operand:HI 0 "register_operand" "=r")
15119 (popcount:HI (match_dup 1)))]
15120 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15121 "popcnt{w}\t{%1, %0|%0, %1}"
15122 [(set_attr "prefix_rep" "1")
15123 (set_attr "type" "bitmanip")
15124 (set_attr "mode" "HI")])
15125
15126 (define_expand "paritydi2"
15127 [(set (match_operand:DI 0 "register_operand" "")
15128 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15129 "! TARGET_POPCNT"
15130 {
15131 rtx scratch = gen_reg_rtx (QImode);
15132 rtx cond;
15133
15134 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15135 NULL_RTX, operands[1]));
15136
15137 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15138 gen_rtx_REG (CCmode, FLAGS_REG),
15139 const0_rtx);
15140 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15141
15142 if (TARGET_64BIT)
15143 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15144 else
15145 {
15146 rtx tmp = gen_reg_rtx (SImode);
15147
15148 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15149 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15150 }
15151 DONE;
15152 })
15153
15154 (define_insn_and_split "paritydi2_cmp"
15155 [(set (reg:CC FLAGS_REG)
15156 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15157 (clobber (match_scratch:DI 0 "=r,X"))
15158 (clobber (match_scratch:SI 1 "=r,r"))
15159 (clobber (match_scratch:HI 2 "=Q,Q"))]
15160 "! TARGET_POPCNT"
15161 "#"
15162 "&& reload_completed"
15163 [(parallel
15164 [(set (match_dup 1)
15165 (xor:SI (match_dup 1) (match_dup 4)))
15166 (clobber (reg:CC FLAGS_REG))])
15167 (parallel
15168 [(set (reg:CC FLAGS_REG)
15169 (parity:CC (match_dup 1)))
15170 (clobber (match_dup 1))
15171 (clobber (match_dup 2))])]
15172 {
15173 operands[4] = gen_lowpart (SImode, operands[3]);
15174
15175 if (MEM_P (operands[3]))
15176 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15177 else if (! TARGET_64BIT)
15178 operands[1] = gen_highpart (SImode, operands[3]);
15179 else
15180 {
15181 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15182 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15183 }
15184 })
15185
15186 (define_expand "paritysi2"
15187 [(set (match_operand:SI 0 "register_operand" "")
15188 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15189 "! TARGET_POPCNT"
15190 {
15191 rtx scratch = gen_reg_rtx (QImode);
15192 rtx cond;
15193
15194 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15195
15196 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15197 gen_rtx_REG (CCmode, FLAGS_REG),
15198 const0_rtx);
15199 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15200
15201 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15202 DONE;
15203 })
15204
15205 (define_insn_and_split "paritysi2_cmp"
15206 [(set (reg:CC FLAGS_REG)
15207 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15208 (clobber (match_scratch:SI 0 "=r,X"))
15209 (clobber (match_scratch:HI 1 "=Q,Q"))]
15210 "! TARGET_POPCNT"
15211 "#"
15212 "&& reload_completed"
15213 [(parallel
15214 [(set (match_dup 1)
15215 (xor:HI (match_dup 1) (match_dup 3)))
15216 (clobber (reg:CC FLAGS_REG))])
15217 (parallel
15218 [(set (reg:CC FLAGS_REG)
15219 (parity:CC (match_dup 1)))
15220 (clobber (match_dup 1))])]
15221 {
15222 operands[3] = gen_lowpart (HImode, operands[2]);
15223
15224 if (MEM_P (operands[2]))
15225 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15226 else
15227 {
15228 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15229 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15230 }
15231 })
15232
15233 (define_insn "*parityhi2_cmp"
15234 [(set (reg:CC FLAGS_REG)
15235 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15236 (clobber (match_scratch:HI 0 "=Q"))]
15237 "! TARGET_POPCNT"
15238 "xor{b}\t{%h0, %b0|%b0, %h0}"
15239 [(set_attr "length" "2")
15240 (set_attr "mode" "HI")])
15241
15242 (define_insn "*parityqi2_cmp"
15243 [(set (reg:CC FLAGS_REG)
15244 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15245 "! TARGET_POPCNT"
15246 "test{b}\t%0, %0"
15247 [(set_attr "length" "2")
15248 (set_attr "mode" "QI")])
15249 \f
15250 ;; Thread-local storage patterns for ELF.
15251 ;;
15252 ;; Note that these code sequences must appear exactly as shown
15253 ;; in order to allow linker relaxation.
15254
15255 (define_insn "*tls_global_dynamic_32_gnu"
15256 [(set (match_operand:SI 0 "register_operand" "=a")
15257 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15258 (match_operand:SI 2 "tls_symbolic_operand" "")
15259 (match_operand:SI 3 "call_insn_operand" "")]
15260 UNSPEC_TLS_GD))
15261 (clobber (match_scratch:SI 4 "=d"))
15262 (clobber (match_scratch:SI 5 "=c"))
15263 (clobber (reg:CC FLAGS_REG))]
15264 "!TARGET_64BIT && TARGET_GNU_TLS"
15265 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15266 [(set_attr "type" "multi")
15267 (set_attr "length" "12")])
15268
15269 (define_insn "*tls_global_dynamic_32_sun"
15270 [(set (match_operand:SI 0 "register_operand" "=a")
15271 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15272 (match_operand:SI 2 "tls_symbolic_operand" "")
15273 (match_operand:SI 3 "call_insn_operand" "")]
15274 UNSPEC_TLS_GD))
15275 (clobber (match_scratch:SI 4 "=d"))
15276 (clobber (match_scratch:SI 5 "=c"))
15277 (clobber (reg:CC FLAGS_REG))]
15278 "!TARGET_64BIT && TARGET_SUN_TLS"
15279 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15280 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15281 [(set_attr "type" "multi")
15282 (set_attr "length" "14")])
15283
15284 (define_expand "tls_global_dynamic_32"
15285 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15286 (unspec:SI
15287 [(match_dup 2)
15288 (match_operand:SI 1 "tls_symbolic_operand" "")
15289 (match_dup 3)]
15290 UNSPEC_TLS_GD))
15291 (clobber (match_scratch:SI 4 ""))
15292 (clobber (match_scratch:SI 5 ""))
15293 (clobber (reg:CC FLAGS_REG))])]
15294 ""
15295 {
15296 if (flag_pic)
15297 operands[2] = pic_offset_table_rtx;
15298 else
15299 {
15300 operands[2] = gen_reg_rtx (Pmode);
15301 emit_insn (gen_set_got (operands[2]));
15302 }
15303 if (TARGET_GNU2_TLS)
15304 {
15305 emit_insn (gen_tls_dynamic_gnu2_32
15306 (operands[0], operands[1], operands[2]));
15307 DONE;
15308 }
15309 operands[3] = ix86_tls_get_addr ();
15310 })
15311
15312 (define_insn "*tls_global_dynamic_64"
15313 [(set (match_operand:DI 0 "register_operand" "=a")
15314 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15315 (match_operand:DI 3 "" "")))
15316 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15317 UNSPEC_TLS_GD)]
15318 "TARGET_64BIT"
15319 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15320 [(set_attr "type" "multi")
15321 (set_attr "length" "16")])
15322
15323 (define_expand "tls_global_dynamic_64"
15324 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15325 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15326 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15327 UNSPEC_TLS_GD)])]
15328 ""
15329 {
15330 if (TARGET_GNU2_TLS)
15331 {
15332 emit_insn (gen_tls_dynamic_gnu2_64
15333 (operands[0], operands[1]));
15334 DONE;
15335 }
15336 operands[2] = ix86_tls_get_addr ();
15337 })
15338
15339 (define_insn "*tls_local_dynamic_base_32_gnu"
15340 [(set (match_operand:SI 0 "register_operand" "=a")
15341 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15342 (match_operand:SI 2 "call_insn_operand" "")]
15343 UNSPEC_TLS_LD_BASE))
15344 (clobber (match_scratch:SI 3 "=d"))
15345 (clobber (match_scratch:SI 4 "=c"))
15346 (clobber (reg:CC FLAGS_REG))]
15347 "!TARGET_64BIT && TARGET_GNU_TLS"
15348 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15349 [(set_attr "type" "multi")
15350 (set_attr "length" "11")])
15351
15352 (define_insn "*tls_local_dynamic_base_32_sun"
15353 [(set (match_operand:SI 0 "register_operand" "=a")
15354 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15355 (match_operand:SI 2 "call_insn_operand" "")]
15356 UNSPEC_TLS_LD_BASE))
15357 (clobber (match_scratch:SI 3 "=d"))
15358 (clobber (match_scratch:SI 4 "=c"))
15359 (clobber (reg:CC FLAGS_REG))]
15360 "!TARGET_64BIT && TARGET_SUN_TLS"
15361 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15362 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15363 [(set_attr "type" "multi")
15364 (set_attr "length" "13")])
15365
15366 (define_expand "tls_local_dynamic_base_32"
15367 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15368 (unspec:SI [(match_dup 1) (match_dup 2)]
15369 UNSPEC_TLS_LD_BASE))
15370 (clobber (match_scratch:SI 3 ""))
15371 (clobber (match_scratch:SI 4 ""))
15372 (clobber (reg:CC FLAGS_REG))])]
15373 ""
15374 {
15375 if (flag_pic)
15376 operands[1] = pic_offset_table_rtx;
15377 else
15378 {
15379 operands[1] = gen_reg_rtx (Pmode);
15380 emit_insn (gen_set_got (operands[1]));
15381 }
15382 if (TARGET_GNU2_TLS)
15383 {
15384 emit_insn (gen_tls_dynamic_gnu2_32
15385 (operands[0], ix86_tls_module_base (), operands[1]));
15386 DONE;
15387 }
15388 operands[2] = ix86_tls_get_addr ();
15389 })
15390
15391 (define_insn "*tls_local_dynamic_base_64"
15392 [(set (match_operand:DI 0 "register_operand" "=a")
15393 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15394 (match_operand:DI 2 "" "")))
15395 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15396 "TARGET_64BIT"
15397 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15398 [(set_attr "type" "multi")
15399 (set_attr "length" "12")])
15400
15401 (define_expand "tls_local_dynamic_base_64"
15402 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15403 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15404 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15405 ""
15406 {
15407 if (TARGET_GNU2_TLS)
15408 {
15409 emit_insn (gen_tls_dynamic_gnu2_64
15410 (operands[0], ix86_tls_module_base ()));
15411 DONE;
15412 }
15413 operands[1] = ix86_tls_get_addr ();
15414 })
15415
15416 ;; Local dynamic of a single variable is a lose. Show combine how
15417 ;; to convert that back to global dynamic.
15418
15419 (define_insn_and_split "*tls_local_dynamic_32_once"
15420 [(set (match_operand:SI 0 "register_operand" "=a")
15421 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15422 (match_operand:SI 2 "call_insn_operand" "")]
15423 UNSPEC_TLS_LD_BASE)
15424 (const:SI (unspec:SI
15425 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15426 UNSPEC_DTPOFF))))
15427 (clobber (match_scratch:SI 4 "=d"))
15428 (clobber (match_scratch:SI 5 "=c"))
15429 (clobber (reg:CC FLAGS_REG))]
15430 ""
15431 "#"
15432 ""
15433 [(parallel [(set (match_dup 0)
15434 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15435 UNSPEC_TLS_GD))
15436 (clobber (match_dup 4))
15437 (clobber (match_dup 5))
15438 (clobber (reg:CC FLAGS_REG))])]
15439 "")
15440
15441 ;; Load and add the thread base pointer from %gs:0.
15442
15443 (define_insn "*load_tp_si"
15444 [(set (match_operand:SI 0 "register_operand" "=r")
15445 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15446 "!TARGET_64BIT"
15447 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15448 [(set_attr "type" "imov")
15449 (set_attr "modrm" "0")
15450 (set_attr "length" "7")
15451 (set_attr "memory" "load")
15452 (set_attr "imm_disp" "false")])
15453
15454 (define_insn "*add_tp_si"
15455 [(set (match_operand:SI 0 "register_operand" "=r")
15456 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15457 (match_operand:SI 1 "register_operand" "0")))
15458 (clobber (reg:CC FLAGS_REG))]
15459 "!TARGET_64BIT"
15460 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15461 [(set_attr "type" "alu")
15462 (set_attr "modrm" "0")
15463 (set_attr "length" "7")
15464 (set_attr "memory" "load")
15465 (set_attr "imm_disp" "false")])
15466
15467 (define_insn "*load_tp_di"
15468 [(set (match_operand:DI 0 "register_operand" "=r")
15469 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15470 "TARGET_64BIT"
15471 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15472 [(set_attr "type" "imov")
15473 (set_attr "modrm" "0")
15474 (set_attr "length" "7")
15475 (set_attr "memory" "load")
15476 (set_attr "imm_disp" "false")])
15477
15478 (define_insn "*add_tp_di"
15479 [(set (match_operand:DI 0 "register_operand" "=r")
15480 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15481 (match_operand:DI 1 "register_operand" "0")))
15482 (clobber (reg:CC FLAGS_REG))]
15483 "TARGET_64BIT"
15484 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15485 [(set_attr "type" "alu")
15486 (set_attr "modrm" "0")
15487 (set_attr "length" "7")
15488 (set_attr "memory" "load")
15489 (set_attr "imm_disp" "false")])
15490
15491 ;; GNU2 TLS patterns can be split.
15492
15493 (define_expand "tls_dynamic_gnu2_32"
15494 [(set (match_dup 3)
15495 (plus:SI (match_operand:SI 2 "register_operand" "")
15496 (const:SI
15497 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15498 UNSPEC_TLSDESC))))
15499 (parallel
15500 [(set (match_operand:SI 0 "register_operand" "")
15501 (unspec:SI [(match_dup 1) (match_dup 3)
15502 (match_dup 2) (reg:SI SP_REG)]
15503 UNSPEC_TLSDESC))
15504 (clobber (reg:CC FLAGS_REG))])]
15505 "!TARGET_64BIT && TARGET_GNU2_TLS"
15506 {
15507 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15508 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15509 })
15510
15511 (define_insn "*tls_dynamic_lea_32"
15512 [(set (match_operand:SI 0 "register_operand" "=r")
15513 (plus:SI (match_operand:SI 1 "register_operand" "b")
15514 (const:SI
15515 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15516 UNSPEC_TLSDESC))))]
15517 "!TARGET_64BIT && TARGET_GNU2_TLS"
15518 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15519 [(set_attr "type" "lea")
15520 (set_attr "mode" "SI")
15521 (set_attr "length" "6")
15522 (set_attr "length_address" "4")])
15523
15524 (define_insn "*tls_dynamic_call_32"
15525 [(set (match_operand:SI 0 "register_operand" "=a")
15526 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15527 (match_operand:SI 2 "register_operand" "0")
15528 ;; we have to make sure %ebx still points to the GOT
15529 (match_operand:SI 3 "register_operand" "b")
15530 (reg:SI SP_REG)]
15531 UNSPEC_TLSDESC))
15532 (clobber (reg:CC FLAGS_REG))]
15533 "!TARGET_64BIT && TARGET_GNU2_TLS"
15534 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15535 [(set_attr "type" "call")
15536 (set_attr "length" "2")
15537 (set_attr "length_address" "0")])
15538
15539 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15540 [(set (match_operand:SI 0 "register_operand" "=&a")
15541 (plus:SI
15542 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15543 (match_operand:SI 4 "" "")
15544 (match_operand:SI 2 "register_operand" "b")
15545 (reg:SI SP_REG)]
15546 UNSPEC_TLSDESC)
15547 (const:SI (unspec:SI
15548 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15549 UNSPEC_DTPOFF))))
15550 (clobber (reg:CC FLAGS_REG))]
15551 "!TARGET_64BIT && TARGET_GNU2_TLS"
15552 "#"
15553 ""
15554 [(set (match_dup 0) (match_dup 5))]
15555 {
15556 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15557 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15558 })
15559
15560 (define_expand "tls_dynamic_gnu2_64"
15561 [(set (match_dup 2)
15562 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15563 UNSPEC_TLSDESC))
15564 (parallel
15565 [(set (match_operand:DI 0 "register_operand" "")
15566 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15567 UNSPEC_TLSDESC))
15568 (clobber (reg:CC FLAGS_REG))])]
15569 "TARGET_64BIT && TARGET_GNU2_TLS"
15570 {
15571 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15572 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15573 })
15574
15575 (define_insn "*tls_dynamic_lea_64"
15576 [(set (match_operand:DI 0 "register_operand" "=r")
15577 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15578 UNSPEC_TLSDESC))]
15579 "TARGET_64BIT && TARGET_GNU2_TLS"
15580 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15581 [(set_attr "type" "lea")
15582 (set_attr "mode" "DI")
15583 (set_attr "length" "7")
15584 (set_attr "length_address" "4")])
15585
15586 (define_insn "*tls_dynamic_call_64"
15587 [(set (match_operand:DI 0 "register_operand" "=a")
15588 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15589 (match_operand:DI 2 "register_operand" "0")
15590 (reg:DI SP_REG)]
15591 UNSPEC_TLSDESC))
15592 (clobber (reg:CC FLAGS_REG))]
15593 "TARGET_64BIT && TARGET_GNU2_TLS"
15594 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15595 [(set_attr "type" "call")
15596 (set_attr "length" "2")
15597 (set_attr "length_address" "0")])
15598
15599 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15600 [(set (match_operand:DI 0 "register_operand" "=&a")
15601 (plus:DI
15602 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15603 (match_operand:DI 3 "" "")
15604 (reg:DI SP_REG)]
15605 UNSPEC_TLSDESC)
15606 (const:DI (unspec:DI
15607 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15608 UNSPEC_DTPOFF))))
15609 (clobber (reg:CC FLAGS_REG))]
15610 "TARGET_64BIT && TARGET_GNU2_TLS"
15611 "#"
15612 ""
15613 [(set (match_dup 0) (match_dup 4))]
15614 {
15615 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15616 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15617 })
15618
15619 ;;
15620 \f
15621 ;; These patterns match the binary 387 instructions for addM3, subM3,
15622 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15623 ;; SFmode. The first is the normal insn, the second the same insn but
15624 ;; with one operand a conversion, and the third the same insn but with
15625 ;; the other operand a conversion. The conversion may be SFmode or
15626 ;; SImode if the target mode DFmode, but only SImode if the target mode
15627 ;; is SFmode.
15628
15629 ;; Gcc is slightly more smart about handling normal two address instructions
15630 ;; so use special patterns for add and mull.
15631
15632 (define_insn "*fop_sf_comm_mixed"
15633 [(set (match_operand:SF 0 "register_operand" "=f,x")
15634 (match_operator:SF 3 "binary_fp_operator"
15635 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15636 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15637 "TARGET_MIX_SSE_I387
15638 && COMMUTATIVE_ARITH_P (operands[3])
15639 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15640 "* return output_387_binary_op (insn, operands);"
15641 [(set (attr "type")
15642 (if_then_else (eq_attr "alternative" "1")
15643 (if_then_else (match_operand:SF 3 "mult_operator" "")
15644 (const_string "ssemul")
15645 (const_string "sseadd"))
15646 (if_then_else (match_operand:SF 3 "mult_operator" "")
15647 (const_string "fmul")
15648 (const_string "fop"))))
15649 (set_attr "mode" "SF")])
15650
15651 (define_insn "*fop_sf_comm_sse"
15652 [(set (match_operand:SF 0 "register_operand" "=x")
15653 (match_operator:SF 3 "binary_fp_operator"
15654 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15655 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15656 "TARGET_SSE_MATH
15657 && COMMUTATIVE_ARITH_P (operands[3])
15658 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15659 "* return output_387_binary_op (insn, operands);"
15660 [(set (attr "type")
15661 (if_then_else (match_operand:SF 3 "mult_operator" "")
15662 (const_string "ssemul")
15663 (const_string "sseadd")))
15664 (set_attr "mode" "SF")])
15665
15666 (define_insn "*fop_sf_comm_i387"
15667 [(set (match_operand:SF 0 "register_operand" "=f")
15668 (match_operator:SF 3 "binary_fp_operator"
15669 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15670 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15671 "TARGET_80387
15672 && COMMUTATIVE_ARITH_P (operands[3])
15673 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15674 "* return output_387_binary_op (insn, operands);"
15675 [(set (attr "type")
15676 (if_then_else (match_operand:SF 3 "mult_operator" "")
15677 (const_string "fmul")
15678 (const_string "fop")))
15679 (set_attr "mode" "SF")])
15680
15681 (define_insn "*fop_sf_1_mixed"
15682 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15683 (match_operator:SF 3 "binary_fp_operator"
15684 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15685 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15686 "TARGET_MIX_SSE_I387
15687 && !COMMUTATIVE_ARITH_P (operands[3])
15688 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15689 "* return output_387_binary_op (insn, operands);"
15690 [(set (attr "type")
15691 (cond [(and (eq_attr "alternative" "2")
15692 (match_operand:SF 3 "mult_operator" ""))
15693 (const_string "ssemul")
15694 (and (eq_attr "alternative" "2")
15695 (match_operand:SF 3 "div_operator" ""))
15696 (const_string "ssediv")
15697 (eq_attr "alternative" "2")
15698 (const_string "sseadd")
15699 (match_operand:SF 3 "mult_operator" "")
15700 (const_string "fmul")
15701 (match_operand:SF 3 "div_operator" "")
15702 (const_string "fdiv")
15703 ]
15704 (const_string "fop")))
15705 (set_attr "mode" "SF")])
15706
15707 (define_insn "*fop_sf_1_sse"
15708 [(set (match_operand:SF 0 "register_operand" "=x")
15709 (match_operator:SF 3 "binary_fp_operator"
15710 [(match_operand:SF 1 "register_operand" "0")
15711 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15712 "TARGET_SSE_MATH
15713 && !COMMUTATIVE_ARITH_P (operands[3])"
15714 "* return output_387_binary_op (insn, operands);"
15715 [(set (attr "type")
15716 (cond [(match_operand:SF 3 "mult_operator" "")
15717 (const_string "ssemul")
15718 (match_operand:SF 3 "div_operator" "")
15719 (const_string "ssediv")
15720 ]
15721 (const_string "sseadd")))
15722 (set_attr "mode" "SF")])
15723
15724 ;; This pattern is not fully shadowed by the pattern above.
15725 (define_insn "*fop_sf_1_i387"
15726 [(set (match_operand:SF 0 "register_operand" "=f,f")
15727 (match_operator:SF 3 "binary_fp_operator"
15728 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15729 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15730 "TARGET_80387 && !TARGET_SSE_MATH
15731 && !COMMUTATIVE_ARITH_P (operands[3])
15732 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15733 "* return output_387_binary_op (insn, operands);"
15734 [(set (attr "type")
15735 (cond [(match_operand:SF 3 "mult_operator" "")
15736 (const_string "fmul")
15737 (match_operand:SF 3 "div_operator" "")
15738 (const_string "fdiv")
15739 ]
15740 (const_string "fop")))
15741 (set_attr "mode" "SF")])
15742
15743 ;; ??? Add SSE splitters for these!
15744 (define_insn "*fop_sf_2<mode>_i387"
15745 [(set (match_operand:SF 0 "register_operand" "=f,f")
15746 (match_operator:SF 3 "binary_fp_operator"
15747 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15748 (match_operand:SF 2 "register_operand" "0,0")]))]
15749 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15750 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15751 [(set (attr "type")
15752 (cond [(match_operand:SF 3 "mult_operator" "")
15753 (const_string "fmul")
15754 (match_operand:SF 3 "div_operator" "")
15755 (const_string "fdiv")
15756 ]
15757 (const_string "fop")))
15758 (set_attr "fp_int_src" "true")
15759 (set_attr "mode" "<MODE>")])
15760
15761 (define_insn "*fop_sf_3<mode>_i387"
15762 [(set (match_operand:SF 0 "register_operand" "=f,f")
15763 (match_operator:SF 3 "binary_fp_operator"
15764 [(match_operand:SF 1 "register_operand" "0,0")
15765 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15766 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15767 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15768 [(set (attr "type")
15769 (cond [(match_operand:SF 3 "mult_operator" "")
15770 (const_string "fmul")
15771 (match_operand:SF 3 "div_operator" "")
15772 (const_string "fdiv")
15773 ]
15774 (const_string "fop")))
15775 (set_attr "fp_int_src" "true")
15776 (set_attr "mode" "<MODE>")])
15777
15778 (define_insn "*fop_df_comm_mixed"
15779 [(set (match_operand:DF 0 "register_operand" "=f,x")
15780 (match_operator:DF 3 "binary_fp_operator"
15781 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15782 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15783 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15784 && COMMUTATIVE_ARITH_P (operands[3])
15785 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15786 "* return output_387_binary_op (insn, operands);"
15787 [(set (attr "type")
15788 (if_then_else (eq_attr "alternative" "1")
15789 (if_then_else (match_operand:DF 3 "mult_operator" "")
15790 (const_string "ssemul")
15791 (const_string "sseadd"))
15792 (if_then_else (match_operand:DF 3 "mult_operator" "")
15793 (const_string "fmul")
15794 (const_string "fop"))))
15795 (set_attr "mode" "DF")])
15796
15797 (define_insn "*fop_df_comm_sse"
15798 [(set (match_operand:DF 0 "register_operand" "=x")
15799 (match_operator:DF 3 "binary_fp_operator"
15800 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15801 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15802 "TARGET_SSE2 && TARGET_SSE_MATH
15803 && COMMUTATIVE_ARITH_P (operands[3])
15804 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15805 "* return output_387_binary_op (insn, operands);"
15806 [(set (attr "type")
15807 (if_then_else (match_operand:DF 3 "mult_operator" "")
15808 (const_string "ssemul")
15809 (const_string "sseadd")))
15810 (set_attr "mode" "DF")])
15811
15812 (define_insn "*fop_df_comm_i387"
15813 [(set (match_operand:DF 0 "register_operand" "=f")
15814 (match_operator:DF 3 "binary_fp_operator"
15815 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15816 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15817 "TARGET_80387
15818 && COMMUTATIVE_ARITH_P (operands[3])
15819 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15820 "* return output_387_binary_op (insn, operands);"
15821 [(set (attr "type")
15822 (if_then_else (match_operand:DF 3 "mult_operator" "")
15823 (const_string "fmul")
15824 (const_string "fop")))
15825 (set_attr "mode" "DF")])
15826
15827 (define_insn "*fop_df_1_mixed"
15828 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15829 (match_operator:DF 3 "binary_fp_operator"
15830 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15831 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15832 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15833 && !COMMUTATIVE_ARITH_P (operands[3])
15834 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15835 "* return output_387_binary_op (insn, operands);"
15836 [(set (attr "type")
15837 (cond [(and (eq_attr "alternative" "2")
15838 (match_operand:DF 3 "mult_operator" ""))
15839 (const_string "ssemul")
15840 (and (eq_attr "alternative" "2")
15841 (match_operand:DF 3 "div_operator" ""))
15842 (const_string "ssediv")
15843 (eq_attr "alternative" "2")
15844 (const_string "sseadd")
15845 (match_operand:DF 3 "mult_operator" "")
15846 (const_string "fmul")
15847 (match_operand:DF 3 "div_operator" "")
15848 (const_string "fdiv")
15849 ]
15850 (const_string "fop")))
15851 (set_attr "mode" "DF")])
15852
15853 (define_insn "*fop_df_1_sse"
15854 [(set (match_operand:DF 0 "register_operand" "=x")
15855 (match_operator:DF 3 "binary_fp_operator"
15856 [(match_operand:DF 1 "register_operand" "0")
15857 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15858 "TARGET_SSE2 && TARGET_SSE_MATH
15859 && !COMMUTATIVE_ARITH_P (operands[3])"
15860 "* return output_387_binary_op (insn, operands);"
15861 [(set_attr "mode" "DF")
15862 (set (attr "type")
15863 (cond [(match_operand:DF 3 "mult_operator" "")
15864 (const_string "ssemul")
15865 (match_operand:DF 3 "div_operator" "")
15866 (const_string "ssediv")
15867 ]
15868 (const_string "sseadd")))])
15869
15870 ;; This pattern is not fully shadowed by the pattern above.
15871 (define_insn "*fop_df_1_i387"
15872 [(set (match_operand:DF 0 "register_operand" "=f,f")
15873 (match_operator:DF 3 "binary_fp_operator"
15874 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15875 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15876 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15877 && !COMMUTATIVE_ARITH_P (operands[3])
15878 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15879 "* return output_387_binary_op (insn, operands);"
15880 [(set (attr "type")
15881 (cond [(match_operand:DF 3 "mult_operator" "")
15882 (const_string "fmul")
15883 (match_operand:DF 3 "div_operator" "")
15884 (const_string "fdiv")
15885 ]
15886 (const_string "fop")))
15887 (set_attr "mode" "DF")])
15888
15889 ;; ??? Add SSE splitters for these!
15890 (define_insn "*fop_df_2<mode>_i387"
15891 [(set (match_operand:DF 0 "register_operand" "=f,f")
15892 (match_operator:DF 3 "binary_fp_operator"
15893 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15894 (match_operand:DF 2 "register_operand" "0,0")]))]
15895 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15896 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15897 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15898 [(set (attr "type")
15899 (cond [(match_operand:DF 3 "mult_operator" "")
15900 (const_string "fmul")
15901 (match_operand:DF 3 "div_operator" "")
15902 (const_string "fdiv")
15903 ]
15904 (const_string "fop")))
15905 (set_attr "fp_int_src" "true")
15906 (set_attr "mode" "<MODE>")])
15907
15908 (define_insn "*fop_df_3<mode>_i387"
15909 [(set (match_operand:DF 0 "register_operand" "=f,f")
15910 (match_operator:DF 3 "binary_fp_operator"
15911 [(match_operand:DF 1 "register_operand" "0,0")
15912 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15913 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15914 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15915 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15916 [(set (attr "type")
15917 (cond [(match_operand:DF 3 "mult_operator" "")
15918 (const_string "fmul")
15919 (match_operand:DF 3 "div_operator" "")
15920 (const_string "fdiv")
15921 ]
15922 (const_string "fop")))
15923 (set_attr "fp_int_src" "true")
15924 (set_attr "mode" "<MODE>")])
15925
15926 (define_insn "*fop_df_4_i387"
15927 [(set (match_operand:DF 0 "register_operand" "=f,f")
15928 (match_operator:DF 3 "binary_fp_operator"
15929 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15930 (match_operand:DF 2 "register_operand" "0,f")]))]
15931 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15932 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15933 "* return output_387_binary_op (insn, operands);"
15934 [(set (attr "type")
15935 (cond [(match_operand:DF 3 "mult_operator" "")
15936 (const_string "fmul")
15937 (match_operand:DF 3 "div_operator" "")
15938 (const_string "fdiv")
15939 ]
15940 (const_string "fop")))
15941 (set_attr "mode" "SF")])
15942
15943 (define_insn "*fop_df_5_i387"
15944 [(set (match_operand:DF 0 "register_operand" "=f,f")
15945 (match_operator:DF 3 "binary_fp_operator"
15946 [(match_operand:DF 1 "register_operand" "0,f")
15947 (float_extend:DF
15948 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15949 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15950 "* return output_387_binary_op (insn, operands);"
15951 [(set (attr "type")
15952 (cond [(match_operand:DF 3 "mult_operator" "")
15953 (const_string "fmul")
15954 (match_operand:DF 3 "div_operator" "")
15955 (const_string "fdiv")
15956 ]
15957 (const_string "fop")))
15958 (set_attr "mode" "SF")])
15959
15960 (define_insn "*fop_df_6_i387"
15961 [(set (match_operand:DF 0 "register_operand" "=f,f")
15962 (match_operator:DF 3 "binary_fp_operator"
15963 [(float_extend:DF
15964 (match_operand:SF 1 "register_operand" "0,f"))
15965 (float_extend:DF
15966 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15967 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15968 "* return output_387_binary_op (insn, operands);"
15969 [(set (attr "type")
15970 (cond [(match_operand:DF 3 "mult_operator" "")
15971 (const_string "fmul")
15972 (match_operand:DF 3 "div_operator" "")
15973 (const_string "fdiv")
15974 ]
15975 (const_string "fop")))
15976 (set_attr "mode" "SF")])
15977
15978 (define_insn "*fop_xf_comm_i387"
15979 [(set (match_operand:XF 0 "register_operand" "=f")
15980 (match_operator:XF 3 "binary_fp_operator"
15981 [(match_operand:XF 1 "register_operand" "%0")
15982 (match_operand:XF 2 "register_operand" "f")]))]
15983 "TARGET_80387
15984 && COMMUTATIVE_ARITH_P (operands[3])"
15985 "* return output_387_binary_op (insn, operands);"
15986 [(set (attr "type")
15987 (if_then_else (match_operand:XF 3 "mult_operator" "")
15988 (const_string "fmul")
15989 (const_string "fop")))
15990 (set_attr "mode" "XF")])
15991
15992 (define_insn "*fop_xf_1_i387"
15993 [(set (match_operand:XF 0 "register_operand" "=f,f")
15994 (match_operator:XF 3 "binary_fp_operator"
15995 [(match_operand:XF 1 "register_operand" "0,f")
15996 (match_operand:XF 2 "register_operand" "f,0")]))]
15997 "TARGET_80387
15998 && !COMMUTATIVE_ARITH_P (operands[3])"
15999 "* return output_387_binary_op (insn, operands);"
16000 [(set (attr "type")
16001 (cond [(match_operand:XF 3 "mult_operator" "")
16002 (const_string "fmul")
16003 (match_operand:XF 3 "div_operator" "")
16004 (const_string "fdiv")
16005 ]
16006 (const_string "fop")))
16007 (set_attr "mode" "XF")])
16008
16009 (define_insn "*fop_xf_2<mode>_i387"
16010 [(set (match_operand:XF 0 "register_operand" "=f,f")
16011 (match_operator:XF 3 "binary_fp_operator"
16012 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16013 (match_operand:XF 2 "register_operand" "0,0")]))]
16014 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16015 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16016 [(set (attr "type")
16017 (cond [(match_operand:XF 3 "mult_operator" "")
16018 (const_string "fmul")
16019 (match_operand:XF 3 "div_operator" "")
16020 (const_string "fdiv")
16021 ]
16022 (const_string "fop")))
16023 (set_attr "fp_int_src" "true")
16024 (set_attr "mode" "<MODE>")])
16025
16026 (define_insn "*fop_xf_3<mode>_i387"
16027 [(set (match_operand:XF 0 "register_operand" "=f,f")
16028 (match_operator:XF 3 "binary_fp_operator"
16029 [(match_operand:XF 1 "register_operand" "0,0")
16030 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16031 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16032 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16033 [(set (attr "type")
16034 (cond [(match_operand:XF 3 "mult_operator" "")
16035 (const_string "fmul")
16036 (match_operand:XF 3 "div_operator" "")
16037 (const_string "fdiv")
16038 ]
16039 (const_string "fop")))
16040 (set_attr "fp_int_src" "true")
16041 (set_attr "mode" "<MODE>")])
16042
16043 (define_insn "*fop_xf_4_i387"
16044 [(set (match_operand:XF 0 "register_operand" "=f,f")
16045 (match_operator:XF 3 "binary_fp_operator"
16046 [(float_extend:XF
16047 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
16048 (match_operand:XF 2 "register_operand" "0,f")]))]
16049 "TARGET_80387"
16050 "* return output_387_binary_op (insn, operands);"
16051 [(set (attr "type")
16052 (cond [(match_operand:XF 3 "mult_operator" "")
16053 (const_string "fmul")
16054 (match_operand:XF 3 "div_operator" "")
16055 (const_string "fdiv")
16056 ]
16057 (const_string "fop")))
16058 (set_attr "mode" "SF")])
16059
16060 (define_insn "*fop_xf_5_i387"
16061 [(set (match_operand:XF 0 "register_operand" "=f,f")
16062 (match_operator:XF 3 "binary_fp_operator"
16063 [(match_operand:XF 1 "register_operand" "0,f")
16064 (float_extend:XF
16065 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16066 "TARGET_80387"
16067 "* return output_387_binary_op (insn, operands);"
16068 [(set (attr "type")
16069 (cond [(match_operand:XF 3 "mult_operator" "")
16070 (const_string "fmul")
16071 (match_operand:XF 3 "div_operator" "")
16072 (const_string "fdiv")
16073 ]
16074 (const_string "fop")))
16075 (set_attr "mode" "SF")])
16076
16077 (define_insn "*fop_xf_6_i387"
16078 [(set (match_operand:XF 0 "register_operand" "=f,f")
16079 (match_operator:XF 3 "binary_fp_operator"
16080 [(float_extend:XF
16081 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
16082 (float_extend:XF
16083 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16084 "TARGET_80387"
16085 "* return output_387_binary_op (insn, operands);"
16086 [(set (attr "type")
16087 (cond [(match_operand:XF 3 "mult_operator" "")
16088 (const_string "fmul")
16089 (match_operand:XF 3 "div_operator" "")
16090 (const_string "fdiv")
16091 ]
16092 (const_string "fop")))
16093 (set_attr "mode" "SF")])
16094
16095 (define_split
16096 [(set (match_operand 0 "register_operand" "")
16097 (match_operator 3 "binary_fp_operator"
16098 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16099 (match_operand 2 "register_operand" "")]))]
16100 "TARGET_80387 && reload_completed
16101 && FLOAT_MODE_P (GET_MODE (operands[0]))"
16102 [(const_int 0)]
16103 {
16104 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16105 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16106 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16107 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16108 GET_MODE (operands[3]),
16109 operands[4],
16110 operands[2])));
16111 ix86_free_from_memory (GET_MODE (operands[1]));
16112 DONE;
16113 })
16114
16115 (define_split
16116 [(set (match_operand 0 "register_operand" "")
16117 (match_operator 3 "binary_fp_operator"
16118 [(match_operand 1 "register_operand" "")
16119 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16120 "TARGET_80387 && reload_completed
16121 && FLOAT_MODE_P (GET_MODE (operands[0]))"
16122 [(const_int 0)]
16123 {
16124 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16125 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16126 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16127 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16128 GET_MODE (operands[3]),
16129 operands[1],
16130 operands[4])));
16131 ix86_free_from_memory (GET_MODE (operands[2]));
16132 DONE;
16133 })
16134 \f
16135 ;; FPU special functions.
16136
16137 ;; This pattern implements a no-op XFmode truncation for
16138 ;; all fancy i386 XFmode math functions.
16139
16140 (define_insn "truncxf<mode>2_i387_noop_unspec"
16141 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16142 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16143 UNSPEC_TRUNC_NOOP))]
16144 "TARGET_USE_FANCY_MATH_387"
16145 "* return output_387_reg_move (insn, operands);"
16146 [(set_attr "type" "fmov")
16147 (set_attr "mode" "<MODE>")])
16148
16149 (define_insn "sqrtxf2"
16150 [(set (match_operand:XF 0 "register_operand" "=f")
16151 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16152 "TARGET_USE_FANCY_MATH_387"
16153 "fsqrt"
16154 [(set_attr "type" "fpspc")
16155 (set_attr "mode" "XF")
16156 (set_attr "athlon_decode" "direct")
16157 (set_attr "amdfam10_decode" "direct")])
16158
16159 (define_insn "sqrt_extend<mode>xf2_i387"
16160 [(set (match_operand:XF 0 "register_operand" "=f")
16161 (sqrt:XF
16162 (float_extend:XF
16163 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16164 "TARGET_USE_FANCY_MATH_387"
16165 "fsqrt"
16166 [(set_attr "type" "fpspc")
16167 (set_attr "mode" "XF")
16168 (set_attr "athlon_decode" "direct")
16169 (set_attr "amdfam10_decode" "direct")])
16170
16171 (define_insn "*sqrt<mode>2_sse"
16172 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16173 (sqrt:SSEMODEF
16174 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16175 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16176 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16177 [(set_attr "type" "sse")
16178 (set_attr "mode" "<MODE>")
16179 (set_attr "athlon_decode" "*")
16180 (set_attr "amdfam10_decode" "*")])
16181
16182 (define_expand "sqrt<mode>2"
16183 [(set (match_operand:X87MODEF12 0 "register_operand" "")
16184 (sqrt:X87MODEF12
16185 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16186 "TARGET_USE_FANCY_MATH_387
16187 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16188 {
16189 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16190 {
16191 rtx op0 = gen_reg_rtx (XFmode);
16192 rtx op1 = force_reg (<MODE>mode, operands[1]);
16193
16194 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16195 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16196 DONE;
16197 }
16198 })
16199
16200 (define_insn "fpremxf4_i387"
16201 [(set (match_operand:XF 0 "register_operand" "=f")
16202 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16203 (match_operand:XF 3 "register_operand" "1")]
16204 UNSPEC_FPREM_F))
16205 (set (match_operand:XF 1 "register_operand" "=u")
16206 (unspec:XF [(match_dup 2) (match_dup 3)]
16207 UNSPEC_FPREM_U))
16208 (set (reg:CCFP FPSR_REG)
16209 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16210 "TARGET_USE_FANCY_MATH_387"
16211 "fprem"
16212 [(set_attr "type" "fpspc")
16213 (set_attr "mode" "XF")])
16214
16215 (define_expand "fmodxf3"
16216 [(use (match_operand:XF 0 "register_operand" ""))
16217 (use (match_operand:XF 1 "register_operand" ""))
16218 (use (match_operand:XF 2 "register_operand" ""))]
16219 "TARGET_USE_FANCY_MATH_387"
16220 {
16221 rtx label = gen_label_rtx ();
16222
16223 emit_label (label);
16224
16225 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16226 operands[1], operands[2]));
16227 ix86_emit_fp_unordered_jump (label);
16228
16229 emit_move_insn (operands[0], operands[1]);
16230 DONE;
16231 })
16232
16233 (define_expand "fmod<mode>3"
16234 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16235 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16236 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16237 "TARGET_USE_FANCY_MATH_387"
16238 {
16239 rtx label = gen_label_rtx ();
16240
16241 rtx op1 = gen_reg_rtx (XFmode);
16242 rtx op2 = gen_reg_rtx (XFmode);
16243
16244 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16245 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16246
16247 emit_label (label);
16248 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16249 ix86_emit_fp_unordered_jump (label);
16250
16251 /* Truncate the result properly for strict SSE math. */
16252 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16253 && !TARGET_MIX_SSE_I387)
16254 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16255 else
16256 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16257
16258 DONE;
16259 })
16260
16261 (define_insn "fprem1xf4_i387"
16262 [(set (match_operand:XF 0 "register_operand" "=f")
16263 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16264 (match_operand:XF 3 "register_operand" "1")]
16265 UNSPEC_FPREM1_F))
16266 (set (match_operand:XF 1 "register_operand" "=u")
16267 (unspec:XF [(match_dup 2) (match_dup 3)]
16268 UNSPEC_FPREM1_U))
16269 (set (reg:CCFP FPSR_REG)
16270 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16271 "TARGET_USE_FANCY_MATH_387"
16272 "fprem1"
16273 [(set_attr "type" "fpspc")
16274 (set_attr "mode" "XF")])
16275
16276 (define_expand "remainderxf3"
16277 [(use (match_operand:XF 0 "register_operand" ""))
16278 (use (match_operand:XF 1 "register_operand" ""))
16279 (use (match_operand:XF 2 "register_operand" ""))]
16280 "TARGET_USE_FANCY_MATH_387"
16281 {
16282 rtx label = gen_label_rtx ();
16283
16284 emit_label (label);
16285
16286 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16287 operands[1], operands[2]));
16288 ix86_emit_fp_unordered_jump (label);
16289
16290 emit_move_insn (operands[0], operands[1]);
16291 DONE;
16292 })
16293
16294 (define_expand "remainder<mode>3"
16295 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16296 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16297 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16298 "TARGET_USE_FANCY_MATH_387"
16299 {
16300 rtx label = gen_label_rtx ();
16301
16302 rtx op1 = gen_reg_rtx (XFmode);
16303 rtx op2 = gen_reg_rtx (XFmode);
16304
16305 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16306 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16307
16308 emit_label (label);
16309
16310 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16311 ix86_emit_fp_unordered_jump (label);
16312
16313 /* Truncate the result properly for strict SSE math. */
16314 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16315 && !TARGET_MIX_SSE_I387)
16316 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16317 else
16318 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16319
16320 DONE;
16321 })
16322
16323 (define_insn "*sinxf2_i387"
16324 [(set (match_operand:XF 0 "register_operand" "=f")
16325 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16326 "TARGET_USE_FANCY_MATH_387
16327 && flag_unsafe_math_optimizations"
16328 "fsin"
16329 [(set_attr "type" "fpspc")
16330 (set_attr "mode" "XF")])
16331
16332 (define_insn "*sin_extend<mode>xf2_i387"
16333 [(set (match_operand:XF 0 "register_operand" "=f")
16334 (unspec:XF [(float_extend:XF
16335 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16336 UNSPEC_SIN))]
16337 "TARGET_USE_FANCY_MATH_387
16338 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16339 || TARGET_MIX_SSE_I387)
16340 && flag_unsafe_math_optimizations"
16341 "fsin"
16342 [(set_attr "type" "fpspc")
16343 (set_attr "mode" "XF")])
16344
16345 (define_insn "*cosxf2_i387"
16346 [(set (match_operand:XF 0 "register_operand" "=f")
16347 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16348 "TARGET_USE_FANCY_MATH_387
16349 && flag_unsafe_math_optimizations"
16350 "fcos"
16351 [(set_attr "type" "fpspc")
16352 (set_attr "mode" "XF")])
16353
16354 (define_insn "*cos_extend<mode>xf2_i387"
16355 [(set (match_operand:XF 0 "register_operand" "=f")
16356 (unspec:XF [(float_extend:XF
16357 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16358 UNSPEC_COS))]
16359 "TARGET_USE_FANCY_MATH_387
16360 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16361 || TARGET_MIX_SSE_I387)
16362 && flag_unsafe_math_optimizations"
16363 "fcos"
16364 [(set_attr "type" "fpspc")
16365 (set_attr "mode" "XF")])
16366
16367 ;; When sincos pattern is defined, sin and cos builtin functions will be
16368 ;; expanded to sincos pattern with one of its outputs left unused.
16369 ;; CSE pass will figure out if two sincos patterns can be combined,
16370 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16371 ;; depending on the unused output.
16372
16373 (define_insn "sincosxf3"
16374 [(set (match_operand:XF 0 "register_operand" "=f")
16375 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16376 UNSPEC_SINCOS_COS))
16377 (set (match_operand:XF 1 "register_operand" "=u")
16378 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16379 "TARGET_USE_FANCY_MATH_387
16380 && flag_unsafe_math_optimizations"
16381 "fsincos"
16382 [(set_attr "type" "fpspc")
16383 (set_attr "mode" "XF")])
16384
16385 (define_split
16386 [(set (match_operand:XF 0 "register_operand" "")
16387 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16388 UNSPEC_SINCOS_COS))
16389 (set (match_operand:XF 1 "register_operand" "")
16390 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16391 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16392 && !reload_completed && !reload_in_progress"
16393 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16394 "")
16395
16396 (define_split
16397 [(set (match_operand:XF 0 "register_operand" "")
16398 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16399 UNSPEC_SINCOS_COS))
16400 (set (match_operand:XF 1 "register_operand" "")
16401 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16402 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16403 && !reload_completed && !reload_in_progress"
16404 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16405 "")
16406
16407 (define_insn "sincos_extend<mode>xf3_i387"
16408 [(set (match_operand:XF 0 "register_operand" "=f")
16409 (unspec:XF [(float_extend:XF
16410 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16411 UNSPEC_SINCOS_COS))
16412 (set (match_operand:XF 1 "register_operand" "=u")
16413 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16414 "TARGET_USE_FANCY_MATH_387
16415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16416 || TARGET_MIX_SSE_I387)
16417 && flag_unsafe_math_optimizations"
16418 "fsincos"
16419 [(set_attr "type" "fpspc")
16420 (set_attr "mode" "XF")])
16421
16422 (define_split
16423 [(set (match_operand:XF 0 "register_operand" "")
16424 (unspec:XF [(float_extend:XF
16425 (match_operand:X87MODEF12 2 "register_operand" ""))]
16426 UNSPEC_SINCOS_COS))
16427 (set (match_operand:XF 1 "register_operand" "")
16428 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16429 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16430 && !reload_completed && !reload_in_progress"
16431 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16432 "")
16433
16434 (define_split
16435 [(set (match_operand:XF 0 "register_operand" "")
16436 (unspec:XF [(float_extend:XF
16437 (match_operand:X87MODEF12 2 "register_operand" ""))]
16438 UNSPEC_SINCOS_COS))
16439 (set (match_operand:XF 1 "register_operand" "")
16440 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16441 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16442 && !reload_completed && !reload_in_progress"
16443 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16444 "")
16445
16446 (define_expand "sincos<mode>3"
16447 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16448 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16449 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16450 "TARGET_USE_FANCY_MATH_387
16451 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16452 || TARGET_MIX_SSE_I387)
16453 && flag_unsafe_math_optimizations"
16454 {
16455 rtx op0 = gen_reg_rtx (XFmode);
16456 rtx op1 = gen_reg_rtx (XFmode);
16457
16458 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16459 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16460 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16461 DONE;
16462 })
16463
16464 (define_insn "fptanxf4_i387"
16465 [(set (match_operand:XF 0 "register_operand" "=f")
16466 (match_operand:XF 3 "const_double_operand" "F"))
16467 (set (match_operand:XF 1 "register_operand" "=u")
16468 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16469 UNSPEC_TAN))]
16470 "TARGET_USE_FANCY_MATH_387
16471 && flag_unsafe_math_optimizations
16472 && standard_80387_constant_p (operands[3]) == 2"
16473 "fptan"
16474 [(set_attr "type" "fpspc")
16475 (set_attr "mode" "XF")])
16476
16477 (define_insn "fptan_extend<mode>xf4_i387"
16478 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16479 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16480 (set (match_operand:XF 1 "register_operand" "=u")
16481 (unspec:XF [(float_extend:XF
16482 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16483 UNSPEC_TAN))]
16484 "TARGET_USE_FANCY_MATH_387
16485 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16486 || TARGET_MIX_SSE_I387)
16487 && flag_unsafe_math_optimizations
16488 && standard_80387_constant_p (operands[3]) == 2"
16489 "fptan"
16490 [(set_attr "type" "fpspc")
16491 (set_attr "mode" "XF")])
16492
16493 (define_expand "tanxf2"
16494 [(use (match_operand:XF 0 "register_operand" ""))
16495 (use (match_operand:XF 1 "register_operand" ""))]
16496 "TARGET_USE_FANCY_MATH_387
16497 && flag_unsafe_math_optimizations"
16498 {
16499 rtx one = gen_reg_rtx (XFmode);
16500 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16501
16502 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16503 DONE;
16504 })
16505
16506 (define_expand "tan<mode>2"
16507 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16508 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16509 "TARGET_USE_FANCY_MATH_387
16510 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16511 || TARGET_MIX_SSE_I387)
16512 && flag_unsafe_math_optimizations"
16513 {
16514 rtx op0 = gen_reg_rtx (XFmode);
16515
16516 rtx one = gen_reg_rtx (<MODE>mode);
16517 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16518
16519 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16520 operands[1], op2));
16521 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16522 DONE;
16523 })
16524
16525 (define_insn "*fpatanxf3_i387"
16526 [(set (match_operand:XF 0 "register_operand" "=f")
16527 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16528 (match_operand:XF 2 "register_operand" "u")]
16529 UNSPEC_FPATAN))
16530 (clobber (match_scratch:XF 3 "=2"))]
16531 "TARGET_USE_FANCY_MATH_387
16532 && flag_unsafe_math_optimizations"
16533 "fpatan"
16534 [(set_attr "type" "fpspc")
16535 (set_attr "mode" "XF")])
16536
16537 (define_insn "fpatan_extend<mode>xf3_i387"
16538 [(set (match_operand:XF 0 "register_operand" "=f")
16539 (unspec:XF [(float_extend:XF
16540 (match_operand:X87MODEF12 1 "register_operand" "0"))
16541 (float_extend:XF
16542 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16543 UNSPEC_FPATAN))
16544 (clobber (match_scratch:XF 3 "=2"))]
16545 "TARGET_USE_FANCY_MATH_387
16546 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16547 || TARGET_MIX_SSE_I387)
16548 && flag_unsafe_math_optimizations"
16549 "fpatan"
16550 [(set_attr "type" "fpspc")
16551 (set_attr "mode" "XF")])
16552
16553 (define_expand "atan2xf3"
16554 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16555 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16556 (match_operand:XF 1 "register_operand" "")]
16557 UNSPEC_FPATAN))
16558 (clobber (match_scratch:XF 3 ""))])]
16559 "TARGET_USE_FANCY_MATH_387
16560 && flag_unsafe_math_optimizations"
16561 "")
16562
16563 (define_expand "atan2<mode>3"
16564 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16565 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16566 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16567 "TARGET_USE_FANCY_MATH_387
16568 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16569 || TARGET_MIX_SSE_I387)
16570 && flag_unsafe_math_optimizations"
16571 {
16572 rtx op0 = gen_reg_rtx (XFmode);
16573
16574 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16575 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16576 DONE;
16577 })
16578
16579 (define_expand "atanxf2"
16580 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16581 (unspec:XF [(match_dup 2)
16582 (match_operand:XF 1 "register_operand" "")]
16583 UNSPEC_FPATAN))
16584 (clobber (match_scratch:XF 3 ""))])]
16585 "TARGET_USE_FANCY_MATH_387
16586 && flag_unsafe_math_optimizations"
16587 {
16588 operands[2] = gen_reg_rtx (XFmode);
16589 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16590 })
16591
16592 (define_expand "atan<mode>2"
16593 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16594 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16595 "TARGET_USE_FANCY_MATH_387
16596 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16597 || TARGET_MIX_SSE_I387)
16598 && flag_unsafe_math_optimizations"
16599 {
16600 rtx op0 = gen_reg_rtx (XFmode);
16601
16602 rtx op2 = gen_reg_rtx (<MODE>mode);
16603 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16604
16605 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16606 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16607 DONE;
16608 })
16609
16610 (define_expand "asinxf2"
16611 [(set (match_dup 2)
16612 (mult:XF (match_operand:XF 1 "register_operand" "")
16613 (match_dup 1)))
16614 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16615 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16616 (parallel [(set (match_operand:XF 0 "register_operand" "")
16617 (unspec:XF [(match_dup 5) (match_dup 1)]
16618 UNSPEC_FPATAN))
16619 (clobber (match_scratch:XF 6 ""))])]
16620 "TARGET_USE_FANCY_MATH_387
16621 && flag_unsafe_math_optimizations && !optimize_size"
16622 {
16623 int i;
16624
16625 for (i = 2; i < 6; i++)
16626 operands[i] = gen_reg_rtx (XFmode);
16627
16628 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16629 })
16630
16631 (define_expand "asin<mode>2"
16632 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16633 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16634 "TARGET_USE_FANCY_MATH_387
16635 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16636 || TARGET_MIX_SSE_I387)
16637 && flag_unsafe_math_optimizations && !optimize_size"
16638 {
16639 rtx op0 = gen_reg_rtx (XFmode);
16640 rtx op1 = gen_reg_rtx (XFmode);
16641
16642 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16643 emit_insn (gen_asinxf2 (op0, op1));
16644 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16645 DONE;
16646 })
16647
16648 (define_expand "acosxf2"
16649 [(set (match_dup 2)
16650 (mult:XF (match_operand:XF 1 "register_operand" "")
16651 (match_dup 1)))
16652 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16653 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16654 (parallel [(set (match_operand:XF 0 "register_operand" "")
16655 (unspec:XF [(match_dup 1) (match_dup 5)]
16656 UNSPEC_FPATAN))
16657 (clobber (match_scratch:XF 6 ""))])]
16658 "TARGET_USE_FANCY_MATH_387
16659 && flag_unsafe_math_optimizations && !optimize_size"
16660 {
16661 int i;
16662
16663 for (i = 2; i < 6; i++)
16664 operands[i] = gen_reg_rtx (XFmode);
16665
16666 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16667 })
16668
16669 (define_expand "acos<mode>2"
16670 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16671 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16672 "TARGET_USE_FANCY_MATH_387
16673 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16674 || TARGET_MIX_SSE_I387)
16675 && flag_unsafe_math_optimizations && !optimize_size"
16676 {
16677 rtx op0 = gen_reg_rtx (XFmode);
16678 rtx op1 = gen_reg_rtx (XFmode);
16679
16680 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16681 emit_insn (gen_acosxf2 (op0, op1));
16682 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16683 DONE;
16684 })
16685
16686 (define_insn "fyl2xxf3_i387"
16687 [(set (match_operand:XF 0 "register_operand" "=f")
16688 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16689 (match_operand:XF 2 "register_operand" "u")]
16690 UNSPEC_FYL2X))
16691 (clobber (match_scratch:XF 3 "=2"))]
16692 "TARGET_USE_FANCY_MATH_387
16693 && flag_unsafe_math_optimizations"
16694 "fyl2x"
16695 [(set_attr "type" "fpspc")
16696 (set_attr "mode" "XF")])
16697
16698 (define_insn "fyl2x_extend<mode>xf3_i387"
16699 [(set (match_operand:XF 0 "register_operand" "=f")
16700 (unspec:XF [(float_extend:XF
16701 (match_operand:X87MODEF12 1 "register_operand" "0"))
16702 (match_operand:XF 2 "register_operand" "u")]
16703 UNSPEC_FYL2X))
16704 (clobber (match_scratch:XF 3 "=2"))]
16705 "TARGET_USE_FANCY_MATH_387
16706 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16707 || TARGET_MIX_SSE_I387)
16708 && flag_unsafe_math_optimizations"
16709 "fyl2x"
16710 [(set_attr "type" "fpspc")
16711 (set_attr "mode" "XF")])
16712
16713 (define_expand "logxf2"
16714 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16715 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16716 (match_dup 2)] UNSPEC_FYL2X))
16717 (clobber (match_scratch:XF 3 ""))])]
16718 "TARGET_USE_FANCY_MATH_387
16719 && flag_unsafe_math_optimizations"
16720 {
16721 operands[2] = gen_reg_rtx (XFmode);
16722 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16723 })
16724
16725 (define_expand "log<mode>2"
16726 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16727 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16728 "TARGET_USE_FANCY_MATH_387
16729 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16730 || TARGET_MIX_SSE_I387)
16731 && flag_unsafe_math_optimizations"
16732 {
16733 rtx op0 = gen_reg_rtx (XFmode);
16734
16735 rtx op2 = gen_reg_rtx (XFmode);
16736 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16737
16738 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16739 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16740 DONE;
16741 })
16742
16743 (define_expand "log10xf2"
16744 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16745 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16746 (match_dup 2)] UNSPEC_FYL2X))
16747 (clobber (match_scratch:XF 3 ""))])]
16748 "TARGET_USE_FANCY_MATH_387
16749 && flag_unsafe_math_optimizations"
16750 {
16751 operands[2] = gen_reg_rtx (XFmode);
16752 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16753 })
16754
16755 (define_expand "log10<mode>2"
16756 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16757 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16758 "TARGET_USE_FANCY_MATH_387
16759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16760 || TARGET_MIX_SSE_I387)
16761 && flag_unsafe_math_optimizations"
16762 {
16763 rtx op0 = gen_reg_rtx (XFmode);
16764
16765 rtx op2 = gen_reg_rtx (XFmode);
16766 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16767
16768 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16769 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16770 DONE;
16771 })
16772
16773 (define_expand "log2xf2"
16774 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16775 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16776 (match_dup 2)] UNSPEC_FYL2X))
16777 (clobber (match_scratch:XF 3 ""))])]
16778 "TARGET_USE_FANCY_MATH_387
16779 && flag_unsafe_math_optimizations"
16780 {
16781 operands[2] = gen_reg_rtx (XFmode);
16782 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16783 })
16784
16785 (define_expand "log2<mode>2"
16786 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16787 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16788 "TARGET_USE_FANCY_MATH_387
16789 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16790 || TARGET_MIX_SSE_I387)
16791 && flag_unsafe_math_optimizations"
16792 {
16793 rtx op0 = gen_reg_rtx (XFmode);
16794
16795 rtx op2 = gen_reg_rtx (XFmode);
16796 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16797
16798 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16799 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16800 DONE;
16801 })
16802
16803 (define_insn "fyl2xp1xf3_i387"
16804 [(set (match_operand:XF 0 "register_operand" "=f")
16805 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16806 (match_operand:XF 2 "register_operand" "u")]
16807 UNSPEC_FYL2XP1))
16808 (clobber (match_scratch:XF 3 "=2"))]
16809 "TARGET_USE_FANCY_MATH_387
16810 && flag_unsafe_math_optimizations"
16811 "fyl2xp1"
16812 [(set_attr "type" "fpspc")
16813 (set_attr "mode" "XF")])
16814
16815 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16816 [(set (match_operand:XF 0 "register_operand" "=f")
16817 (unspec:XF [(float_extend:XF
16818 (match_operand:X87MODEF12 1 "register_operand" "0"))
16819 (match_operand:XF 2 "register_operand" "u")]
16820 UNSPEC_FYL2XP1))
16821 (clobber (match_scratch:XF 3 "=2"))]
16822 "TARGET_USE_FANCY_MATH_387
16823 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16824 || TARGET_MIX_SSE_I387)
16825 && flag_unsafe_math_optimizations"
16826 "fyl2xp1"
16827 [(set_attr "type" "fpspc")
16828 (set_attr "mode" "XF")])
16829
16830 (define_expand "log1pxf2"
16831 [(use (match_operand:XF 0 "register_operand" ""))
16832 (use (match_operand:XF 1 "register_operand" ""))]
16833 "TARGET_USE_FANCY_MATH_387
16834 && flag_unsafe_math_optimizations && !optimize_size"
16835 {
16836 ix86_emit_i387_log1p (operands[0], operands[1]);
16837 DONE;
16838 })
16839
16840 (define_expand "log1p<mode>2"
16841 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16842 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16843 "TARGET_USE_FANCY_MATH_387
16844 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16845 || TARGET_MIX_SSE_I387)
16846 && flag_unsafe_math_optimizations && !optimize_size"
16847 {
16848 rtx op0 = gen_reg_rtx (XFmode);
16849
16850 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16851
16852 ix86_emit_i387_log1p (op0, operands[1]);
16853 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16854 DONE;
16855 })
16856
16857 (define_insn "fxtractxf3_i387"
16858 [(set (match_operand:XF 0 "register_operand" "=f")
16859 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16860 UNSPEC_XTRACT_FRACT))
16861 (set (match_operand:XF 1 "register_operand" "=u")
16862 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16863 "TARGET_USE_FANCY_MATH_387
16864 && flag_unsafe_math_optimizations"
16865 "fxtract"
16866 [(set_attr "type" "fpspc")
16867 (set_attr "mode" "XF")])
16868
16869 (define_insn "fxtract_extend<mode>xf3_i387"
16870 [(set (match_operand:XF 0 "register_operand" "=f")
16871 (unspec:XF [(float_extend:XF
16872 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16873 UNSPEC_XTRACT_FRACT))
16874 (set (match_operand:XF 1 "register_operand" "=u")
16875 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16876 "TARGET_USE_FANCY_MATH_387
16877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16878 || TARGET_MIX_SSE_I387)
16879 && flag_unsafe_math_optimizations"
16880 "fxtract"
16881 [(set_attr "type" "fpspc")
16882 (set_attr "mode" "XF")])
16883
16884 (define_expand "logbxf2"
16885 [(parallel [(set (match_dup 2)
16886 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16887 UNSPEC_XTRACT_FRACT))
16888 (set (match_operand:XF 0 "register_operand" "")
16889 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16890 "TARGET_USE_FANCY_MATH_387
16891 && flag_unsafe_math_optimizations"
16892 {
16893 operands[2] = gen_reg_rtx (XFmode);
16894 })
16895
16896 (define_expand "logb<mode>2"
16897 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16898 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16899 "TARGET_USE_FANCY_MATH_387
16900 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16901 || TARGET_MIX_SSE_I387)
16902 && flag_unsafe_math_optimizations"
16903 {
16904 rtx op0 = gen_reg_rtx (XFmode);
16905 rtx op1 = gen_reg_rtx (XFmode);
16906
16907 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16908 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16909 DONE;
16910 })
16911
16912 (define_expand "ilogbxf2"
16913 [(use (match_operand:SI 0 "register_operand" ""))
16914 (use (match_operand:XF 1 "register_operand" ""))]
16915 "TARGET_USE_FANCY_MATH_387
16916 && flag_unsafe_math_optimizations && !optimize_size"
16917 {
16918 rtx op0 = gen_reg_rtx (XFmode);
16919 rtx op1 = gen_reg_rtx (XFmode);
16920
16921 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16922 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16923 DONE;
16924 })
16925
16926 (define_expand "ilogb<mode>2"
16927 [(use (match_operand:SI 0 "register_operand" ""))
16928 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16929 "TARGET_USE_FANCY_MATH_387
16930 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16931 || TARGET_MIX_SSE_I387)
16932 && flag_unsafe_math_optimizations && !optimize_size"
16933 {
16934 rtx op0 = gen_reg_rtx (XFmode);
16935 rtx op1 = gen_reg_rtx (XFmode);
16936
16937 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16938 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16939 DONE;
16940 })
16941
16942 (define_insn "*f2xm1xf2_i387"
16943 [(set (match_operand:XF 0 "register_operand" "=f")
16944 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16945 UNSPEC_F2XM1))]
16946 "TARGET_USE_FANCY_MATH_387
16947 && flag_unsafe_math_optimizations"
16948 "f2xm1"
16949 [(set_attr "type" "fpspc")
16950 (set_attr "mode" "XF")])
16951
16952 (define_insn "*fscalexf4_i387"
16953 [(set (match_operand:XF 0 "register_operand" "=f")
16954 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16955 (match_operand:XF 3 "register_operand" "1")]
16956 UNSPEC_FSCALE_FRACT))
16957 (set (match_operand:XF 1 "register_operand" "=u")
16958 (unspec:XF [(match_dup 2) (match_dup 3)]
16959 UNSPEC_FSCALE_EXP))]
16960 "TARGET_USE_FANCY_MATH_387
16961 && flag_unsafe_math_optimizations"
16962 "fscale"
16963 [(set_attr "type" "fpspc")
16964 (set_attr "mode" "XF")])
16965
16966 (define_expand "expNcorexf3"
16967 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16968 (match_operand:XF 2 "register_operand" "")))
16969 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16970 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16971 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16972 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16973 (parallel [(set (match_operand:XF 0 "register_operand" "")
16974 (unspec:XF [(match_dup 8) (match_dup 4)]
16975 UNSPEC_FSCALE_FRACT))
16976 (set (match_dup 9)
16977 (unspec:XF [(match_dup 8) (match_dup 4)]
16978 UNSPEC_FSCALE_EXP))])]
16979 "TARGET_USE_FANCY_MATH_387
16980 && flag_unsafe_math_optimizations && !optimize_size"
16981 {
16982 int i;
16983
16984 for (i = 3; i < 10; i++)
16985 operands[i] = gen_reg_rtx (XFmode);
16986
16987 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16988 })
16989
16990 (define_expand "expxf2"
16991 [(use (match_operand:XF 0 "register_operand" ""))
16992 (use (match_operand:XF 1 "register_operand" ""))]
16993 "TARGET_USE_FANCY_MATH_387
16994 && flag_unsafe_math_optimizations && !optimize_size"
16995 {
16996 rtx op2 = gen_reg_rtx (XFmode);
16997 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16998
16999 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17000 DONE;
17001 })
17002
17003 (define_expand "exp<mode>2"
17004 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17005 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17006 "TARGET_USE_FANCY_MATH_387
17007 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17008 || TARGET_MIX_SSE_I387)
17009 && flag_unsafe_math_optimizations && !optimize_size"
17010 {
17011 rtx op0 = gen_reg_rtx (XFmode);
17012 rtx op1 = gen_reg_rtx (XFmode);
17013
17014 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17015 emit_insn (gen_expxf2 (op0, op1));
17016 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17017 DONE;
17018 })
17019
17020 (define_expand "exp10xf2"
17021 [(use (match_operand:XF 0 "register_operand" ""))
17022 (use (match_operand:XF 1 "register_operand" ""))]
17023 "TARGET_USE_FANCY_MATH_387
17024 && flag_unsafe_math_optimizations && !optimize_size"
17025 {
17026 rtx op2 = gen_reg_rtx (XFmode);
17027 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17028
17029 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17030 DONE;
17031 })
17032
17033 (define_expand "exp10<mode>2"
17034 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17035 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17036 "TARGET_USE_FANCY_MATH_387
17037 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17038 || TARGET_MIX_SSE_I387)
17039 && flag_unsafe_math_optimizations && !optimize_size"
17040 {
17041 rtx op0 = gen_reg_rtx (XFmode);
17042 rtx op1 = gen_reg_rtx (XFmode);
17043
17044 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17045 emit_insn (gen_exp10xf2 (op0, op1));
17046 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17047 DONE;
17048 })
17049
17050 (define_expand "exp2xf2"
17051 [(use (match_operand:XF 0 "register_operand" ""))
17052 (use (match_operand:XF 1 "register_operand" ""))]
17053 "TARGET_USE_FANCY_MATH_387
17054 && flag_unsafe_math_optimizations && !optimize_size"
17055 {
17056 rtx op2 = gen_reg_rtx (XFmode);
17057 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17058
17059 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17060 DONE;
17061 })
17062
17063 (define_expand "exp2<mode>2"
17064 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17065 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17066 "TARGET_USE_FANCY_MATH_387
17067 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17068 || TARGET_MIX_SSE_I387)
17069 && flag_unsafe_math_optimizations && !optimize_size"
17070 {
17071 rtx op0 = gen_reg_rtx (XFmode);
17072 rtx op1 = gen_reg_rtx (XFmode);
17073
17074 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17075 emit_insn (gen_exp2xf2 (op0, op1));
17076 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17077 DONE;
17078 })
17079
17080 (define_expand "expm1xf2"
17081 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17082 (match_dup 2)))
17083 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17084 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17085 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17086 (parallel [(set (match_dup 7)
17087 (unspec:XF [(match_dup 6) (match_dup 4)]
17088 UNSPEC_FSCALE_FRACT))
17089 (set (match_dup 8)
17090 (unspec:XF [(match_dup 6) (match_dup 4)]
17091 UNSPEC_FSCALE_EXP))])
17092 (parallel [(set (match_dup 10)
17093 (unspec:XF [(match_dup 9) (match_dup 8)]
17094 UNSPEC_FSCALE_FRACT))
17095 (set (match_dup 11)
17096 (unspec:XF [(match_dup 9) (match_dup 8)]
17097 UNSPEC_FSCALE_EXP))])
17098 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17099 (set (match_operand:XF 0 "register_operand" "")
17100 (plus:XF (match_dup 12) (match_dup 7)))]
17101 "TARGET_USE_FANCY_MATH_387
17102 && flag_unsafe_math_optimizations && !optimize_size"
17103 {
17104 int i;
17105
17106 for (i = 2; i < 13; i++)
17107 operands[i] = gen_reg_rtx (XFmode);
17108
17109 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17110 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17111 })
17112
17113 (define_expand "expm1<mode>2"
17114 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17115 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17116 "TARGET_USE_FANCY_MATH_387
17117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17118 || TARGET_MIX_SSE_I387)
17119 && flag_unsafe_math_optimizations && !optimize_size"
17120 {
17121 rtx op0 = gen_reg_rtx (XFmode);
17122 rtx op1 = gen_reg_rtx (XFmode);
17123
17124 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17125 emit_insn (gen_expm1xf2 (op0, op1));
17126 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17127 DONE;
17128 })
17129
17130 (define_expand "ldexpxf3"
17131 [(set (match_dup 3)
17132 (float:XF (match_operand:SI 2 "register_operand" "")))
17133 (parallel [(set (match_operand:XF 0 " register_operand" "")
17134 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17135 (match_dup 3)]
17136 UNSPEC_FSCALE_FRACT))
17137 (set (match_dup 4)
17138 (unspec:XF [(match_dup 1) (match_dup 3)]
17139 UNSPEC_FSCALE_EXP))])]
17140 "TARGET_USE_FANCY_MATH_387
17141 && flag_unsafe_math_optimizations && !optimize_size"
17142 {
17143 operands[3] = gen_reg_rtx (XFmode);
17144 operands[4] = gen_reg_rtx (XFmode);
17145 })
17146
17147 (define_expand "ldexp<mode>3"
17148 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17149 (use (match_operand:X87MODEF12 1 "general_operand" ""))
17150 (use (match_operand:SI 2 "register_operand" ""))]
17151 "TARGET_USE_FANCY_MATH_387
17152 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17153 || TARGET_MIX_SSE_I387)
17154 && flag_unsafe_math_optimizations && !optimize_size"
17155 {
17156 rtx op0 = gen_reg_rtx (XFmode);
17157 rtx op1 = gen_reg_rtx (XFmode);
17158
17159 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17160 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17161 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17162 DONE;
17163 })
17164 \f
17165
17166 (define_insn "frndintxf2"
17167 [(set (match_operand:XF 0 "register_operand" "=f")
17168 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17169 UNSPEC_FRNDINT))]
17170 "TARGET_USE_FANCY_MATH_387
17171 && flag_unsafe_math_optimizations"
17172 "frndint"
17173 [(set_attr "type" "fpspc")
17174 (set_attr "mode" "XF")])
17175
17176 (define_expand "rintdf2"
17177 [(use (match_operand:DF 0 "register_operand" ""))
17178 (use (match_operand:DF 1 "register_operand" ""))]
17179 "(TARGET_USE_FANCY_MATH_387
17180 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17181 && flag_unsafe_math_optimizations)
17182 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17183 && !flag_trapping_math
17184 && !optimize_size)"
17185 {
17186 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17187 && !flag_trapping_math
17188 && !optimize_size)
17189 ix86_expand_rint (operand0, operand1);
17190 else
17191 {
17192 rtx op0 = gen_reg_rtx (XFmode);
17193 rtx op1 = gen_reg_rtx (XFmode);
17194
17195 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17196 emit_insn (gen_frndintxf2 (op0, op1));
17197
17198 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17199 }
17200 DONE;
17201 })
17202
17203 (define_expand "rintsf2"
17204 [(use (match_operand:SF 0 "register_operand" ""))
17205 (use (match_operand:SF 1 "register_operand" ""))]
17206 "(TARGET_USE_FANCY_MATH_387
17207 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17208 && flag_unsafe_math_optimizations)
17209 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17210 && !flag_trapping_math
17211 && !optimize_size)"
17212 {
17213 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17214 && !flag_trapping_math
17215 && !optimize_size)
17216 ix86_expand_rint (operand0, operand1);
17217 else
17218 {
17219 rtx op0 = gen_reg_rtx (XFmode);
17220 rtx op1 = gen_reg_rtx (XFmode);
17221
17222 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17223 emit_insn (gen_frndintxf2 (op0, op1));
17224
17225 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17226 }
17227 DONE;
17228 })
17229
17230 (define_expand "rintxf2"
17231 [(use (match_operand:XF 0 "register_operand" ""))
17232 (use (match_operand:XF 1 "register_operand" ""))]
17233 "TARGET_USE_FANCY_MATH_387
17234 && flag_unsafe_math_optimizations && !optimize_size"
17235 {
17236 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17237 DONE;
17238 })
17239
17240 (define_expand "roundsf2"
17241 [(match_operand:SF 0 "register_operand" "")
17242 (match_operand:SF 1 "nonimmediate_operand" "")]
17243 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17244 && !flag_trapping_math && !flag_rounding_math
17245 && !optimize_size"
17246 {
17247 ix86_expand_round (operand0, operand1);
17248 DONE;
17249 })
17250
17251 (define_expand "rounddf2"
17252 [(match_operand:DF 0 "register_operand" "")
17253 (match_operand:DF 1 "nonimmediate_operand" "")]
17254 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17255 && !flag_trapping_math && !flag_rounding_math
17256 && !optimize_size"
17257 {
17258 if (TARGET_64BIT)
17259 ix86_expand_round (operand0, operand1);
17260 else
17261 ix86_expand_rounddf_32 (operand0, operand1);
17262 DONE;
17263 })
17264
17265 (define_insn_and_split "*fistdi2_1"
17266 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17267 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17268 UNSPEC_FIST))]
17269 "TARGET_USE_FANCY_MATH_387
17270 && !(reload_completed || reload_in_progress)"
17271 "#"
17272 "&& 1"
17273 [(const_int 0)]
17274 {
17275 if (memory_operand (operands[0], VOIDmode))
17276 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17277 else
17278 {
17279 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17280 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17281 operands[2]));
17282 }
17283 DONE;
17284 }
17285 [(set_attr "type" "fpspc")
17286 (set_attr "mode" "DI")])
17287
17288 (define_insn "fistdi2"
17289 [(set (match_operand:DI 0 "memory_operand" "=m")
17290 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17291 UNSPEC_FIST))
17292 (clobber (match_scratch:XF 2 "=&1f"))]
17293 "TARGET_USE_FANCY_MATH_387"
17294 "* return output_fix_trunc (insn, operands, 0);"
17295 [(set_attr "type" "fpspc")
17296 (set_attr "mode" "DI")])
17297
17298 (define_insn "fistdi2_with_temp"
17299 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17300 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17301 UNSPEC_FIST))
17302 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17303 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17304 "TARGET_USE_FANCY_MATH_387"
17305 "#"
17306 [(set_attr "type" "fpspc")
17307 (set_attr "mode" "DI")])
17308
17309 (define_split
17310 [(set (match_operand:DI 0 "register_operand" "")
17311 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17312 UNSPEC_FIST))
17313 (clobber (match_operand:DI 2 "memory_operand" ""))
17314 (clobber (match_scratch 3 ""))]
17315 "reload_completed"
17316 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17317 (clobber (match_dup 3))])
17318 (set (match_dup 0) (match_dup 2))]
17319 "")
17320
17321 (define_split
17322 [(set (match_operand:DI 0 "memory_operand" "")
17323 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17324 UNSPEC_FIST))
17325 (clobber (match_operand:DI 2 "memory_operand" ""))
17326 (clobber (match_scratch 3 ""))]
17327 "reload_completed"
17328 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17329 (clobber (match_dup 3))])]
17330 "")
17331
17332 (define_insn_and_split "*fist<mode>2_1"
17333 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17334 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17335 UNSPEC_FIST))]
17336 "TARGET_USE_FANCY_MATH_387
17337 && !(reload_completed || reload_in_progress)"
17338 "#"
17339 "&& 1"
17340 [(const_int 0)]
17341 {
17342 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17343 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17344 operands[2]));
17345 DONE;
17346 }
17347 [(set_attr "type" "fpspc")
17348 (set_attr "mode" "<MODE>")])
17349
17350 (define_insn "fist<mode>2"
17351 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17352 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17353 UNSPEC_FIST))]
17354 "TARGET_USE_FANCY_MATH_387"
17355 "* return output_fix_trunc (insn, operands, 0);"
17356 [(set_attr "type" "fpspc")
17357 (set_attr "mode" "<MODE>")])
17358
17359 (define_insn "fist<mode>2_with_temp"
17360 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17361 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17362 UNSPEC_FIST))
17363 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17364 "TARGET_USE_FANCY_MATH_387"
17365 "#"
17366 [(set_attr "type" "fpspc")
17367 (set_attr "mode" "<MODE>")])
17368
17369 (define_split
17370 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17371 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17372 UNSPEC_FIST))
17373 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17374 "reload_completed"
17375 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17376 UNSPEC_FIST))
17377 (set (match_dup 0) (match_dup 2))]
17378 "")
17379
17380 (define_split
17381 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17382 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17383 UNSPEC_FIST))
17384 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17385 "reload_completed"
17386 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17387 UNSPEC_FIST))]
17388 "")
17389
17390 (define_expand "lrintxf<mode>2"
17391 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17392 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17393 UNSPEC_FIST))]
17394 "TARGET_USE_FANCY_MATH_387"
17395 "")
17396
17397 (define_expand "lrint<mode>di2"
17398 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17399 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17400 UNSPEC_FIX_NOTRUNC))]
17401 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17402 "")
17403
17404 (define_expand "lrint<mode>si2"
17405 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17406 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17407 UNSPEC_FIX_NOTRUNC))]
17408 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17409 "")
17410
17411 (define_expand "lround<mode>di2"
17412 [(match_operand:DI 0 "nonimmediate_operand" "")
17413 (match_operand:SSEMODEF 1 "register_operand" "")]
17414 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17415 && !flag_trapping_math && !flag_rounding_math
17416 && !optimize_size"
17417 {
17418 ix86_expand_lround (operand0, operand1);
17419 DONE;
17420 })
17421
17422 (define_expand "lround<mode>si2"
17423 [(match_operand:SI 0 "nonimmediate_operand" "")
17424 (match_operand:SSEMODEF 1 "register_operand" "")]
17425 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17426 && !flag_trapping_math && !flag_rounding_math
17427 && !optimize_size"
17428 {
17429 ix86_expand_lround (operand0, operand1);
17430 DONE;
17431 })
17432
17433 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17434 (define_insn_and_split "frndintxf2_floor"
17435 [(set (match_operand:XF 0 "register_operand" "=f")
17436 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17437 UNSPEC_FRNDINT_FLOOR))
17438 (clobber (reg:CC FLAGS_REG))]
17439 "TARGET_USE_FANCY_MATH_387
17440 && flag_unsafe_math_optimizations
17441 && !(reload_completed || reload_in_progress)"
17442 "#"
17443 "&& 1"
17444 [(const_int 0)]
17445 {
17446 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17447
17448 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17449 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17450
17451 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17452 operands[2], operands[3]));
17453 DONE;
17454 }
17455 [(set_attr "type" "frndint")
17456 (set_attr "i387_cw" "floor")
17457 (set_attr "mode" "XF")])
17458
17459 (define_insn "frndintxf2_floor_i387"
17460 [(set (match_operand:XF 0 "register_operand" "=f")
17461 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17462 UNSPEC_FRNDINT_FLOOR))
17463 (use (match_operand:HI 2 "memory_operand" "m"))
17464 (use (match_operand:HI 3 "memory_operand" "m"))]
17465 "TARGET_USE_FANCY_MATH_387
17466 && flag_unsafe_math_optimizations"
17467 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17468 [(set_attr "type" "frndint")
17469 (set_attr "i387_cw" "floor")
17470 (set_attr "mode" "XF")])
17471
17472 (define_expand "floorxf2"
17473 [(use (match_operand:XF 0 "register_operand" ""))
17474 (use (match_operand:XF 1 "register_operand" ""))]
17475 "TARGET_USE_FANCY_MATH_387
17476 && flag_unsafe_math_optimizations && !optimize_size"
17477 {
17478 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17479 DONE;
17480 })
17481
17482 (define_expand "floordf2"
17483 [(use (match_operand:DF 0 "register_operand" ""))
17484 (use (match_operand:DF 1 "register_operand" ""))]
17485 "((TARGET_USE_FANCY_MATH_387
17486 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17487 && flag_unsafe_math_optimizations)
17488 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17489 && !flag_trapping_math))
17490 && !optimize_size"
17491 {
17492 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17493 && !flag_trapping_math)
17494 {
17495 if (TARGET_64BIT)
17496 ix86_expand_floorceil (operand0, operand1, true);
17497 else
17498 ix86_expand_floorceildf_32 (operand0, operand1, true);
17499 }
17500 else
17501 {
17502 rtx op0 = gen_reg_rtx (XFmode);
17503 rtx op1 = gen_reg_rtx (XFmode);
17504
17505 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17506 emit_insn (gen_frndintxf2_floor (op0, op1));
17507
17508 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17509 }
17510 DONE;
17511 })
17512
17513 (define_expand "floorsf2"
17514 [(use (match_operand:SF 0 "register_operand" ""))
17515 (use (match_operand:SF 1 "register_operand" ""))]
17516 "((TARGET_USE_FANCY_MATH_387
17517 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17518 && flag_unsafe_math_optimizations)
17519 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17520 && !flag_trapping_math))
17521 && !optimize_size"
17522 {
17523 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17524 && !flag_trapping_math)
17525 ix86_expand_floorceil (operand0, operand1, true);
17526 else
17527 {
17528 rtx op0 = gen_reg_rtx (XFmode);
17529 rtx op1 = gen_reg_rtx (XFmode);
17530
17531 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17532 emit_insn (gen_frndintxf2_floor (op0, op1));
17533
17534 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17535 }
17536 DONE;
17537 })
17538
17539 (define_insn_and_split "*fist<mode>2_floor_1"
17540 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17541 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17542 UNSPEC_FIST_FLOOR))
17543 (clobber (reg:CC FLAGS_REG))]
17544 "TARGET_USE_FANCY_MATH_387
17545 && flag_unsafe_math_optimizations
17546 && !(reload_completed || reload_in_progress)"
17547 "#"
17548 "&& 1"
17549 [(const_int 0)]
17550 {
17551 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17552
17553 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17554 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17555 if (memory_operand (operands[0], VOIDmode))
17556 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17557 operands[2], operands[3]));
17558 else
17559 {
17560 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17561 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17562 operands[2], operands[3],
17563 operands[4]));
17564 }
17565 DONE;
17566 }
17567 [(set_attr "type" "fistp")
17568 (set_attr "i387_cw" "floor")
17569 (set_attr "mode" "<MODE>")])
17570
17571 (define_insn "fistdi2_floor"
17572 [(set (match_operand:DI 0 "memory_operand" "=m")
17573 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17574 UNSPEC_FIST_FLOOR))
17575 (use (match_operand:HI 2 "memory_operand" "m"))
17576 (use (match_operand:HI 3 "memory_operand" "m"))
17577 (clobber (match_scratch:XF 4 "=&1f"))]
17578 "TARGET_USE_FANCY_MATH_387
17579 && flag_unsafe_math_optimizations"
17580 "* return output_fix_trunc (insn, operands, 0);"
17581 [(set_attr "type" "fistp")
17582 (set_attr "i387_cw" "floor")
17583 (set_attr "mode" "DI")])
17584
17585 (define_insn "fistdi2_floor_with_temp"
17586 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17587 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17588 UNSPEC_FIST_FLOOR))
17589 (use (match_operand:HI 2 "memory_operand" "m,m"))
17590 (use (match_operand:HI 3 "memory_operand" "m,m"))
17591 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17592 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17593 "TARGET_USE_FANCY_MATH_387
17594 && flag_unsafe_math_optimizations"
17595 "#"
17596 [(set_attr "type" "fistp")
17597 (set_attr "i387_cw" "floor")
17598 (set_attr "mode" "DI")])
17599
17600 (define_split
17601 [(set (match_operand:DI 0 "register_operand" "")
17602 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17603 UNSPEC_FIST_FLOOR))
17604 (use (match_operand:HI 2 "memory_operand" ""))
17605 (use (match_operand:HI 3 "memory_operand" ""))
17606 (clobber (match_operand:DI 4 "memory_operand" ""))
17607 (clobber (match_scratch 5 ""))]
17608 "reload_completed"
17609 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17610 (use (match_dup 2))
17611 (use (match_dup 3))
17612 (clobber (match_dup 5))])
17613 (set (match_dup 0) (match_dup 4))]
17614 "")
17615
17616 (define_split
17617 [(set (match_operand:DI 0 "memory_operand" "")
17618 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17619 UNSPEC_FIST_FLOOR))
17620 (use (match_operand:HI 2 "memory_operand" ""))
17621 (use (match_operand:HI 3 "memory_operand" ""))
17622 (clobber (match_operand:DI 4 "memory_operand" ""))
17623 (clobber (match_scratch 5 ""))]
17624 "reload_completed"
17625 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17626 (use (match_dup 2))
17627 (use (match_dup 3))
17628 (clobber (match_dup 5))])]
17629 "")
17630
17631 (define_insn "fist<mode>2_floor"
17632 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17633 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17634 UNSPEC_FIST_FLOOR))
17635 (use (match_operand:HI 2 "memory_operand" "m"))
17636 (use (match_operand:HI 3 "memory_operand" "m"))]
17637 "TARGET_USE_FANCY_MATH_387
17638 && flag_unsafe_math_optimizations"
17639 "* return output_fix_trunc (insn, operands, 0);"
17640 [(set_attr "type" "fistp")
17641 (set_attr "i387_cw" "floor")
17642 (set_attr "mode" "<MODE>")])
17643
17644 (define_insn "fist<mode>2_floor_with_temp"
17645 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17646 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17647 UNSPEC_FIST_FLOOR))
17648 (use (match_operand:HI 2 "memory_operand" "m,m"))
17649 (use (match_operand:HI 3 "memory_operand" "m,m"))
17650 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17651 "TARGET_USE_FANCY_MATH_387
17652 && flag_unsafe_math_optimizations"
17653 "#"
17654 [(set_attr "type" "fistp")
17655 (set_attr "i387_cw" "floor")
17656 (set_attr "mode" "<MODE>")])
17657
17658 (define_split
17659 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17660 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17661 UNSPEC_FIST_FLOOR))
17662 (use (match_operand:HI 2 "memory_operand" ""))
17663 (use (match_operand:HI 3 "memory_operand" ""))
17664 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17665 "reload_completed"
17666 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17667 UNSPEC_FIST_FLOOR))
17668 (use (match_dup 2))
17669 (use (match_dup 3))])
17670 (set (match_dup 0) (match_dup 4))]
17671 "")
17672
17673 (define_split
17674 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17675 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17676 UNSPEC_FIST_FLOOR))
17677 (use (match_operand:HI 2 "memory_operand" ""))
17678 (use (match_operand:HI 3 "memory_operand" ""))
17679 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17680 "reload_completed"
17681 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17682 UNSPEC_FIST_FLOOR))
17683 (use (match_dup 2))
17684 (use (match_dup 3))])]
17685 "")
17686
17687 (define_expand "lfloorxf<mode>2"
17688 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17689 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17690 UNSPEC_FIST_FLOOR))
17691 (clobber (reg:CC FLAGS_REG))])]
17692 "TARGET_USE_FANCY_MATH_387
17693 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17694 && flag_unsafe_math_optimizations"
17695 "")
17696
17697 (define_expand "lfloor<mode>di2"
17698 [(match_operand:DI 0 "nonimmediate_operand" "")
17699 (match_operand:SSEMODEF 1 "register_operand" "")]
17700 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17701 && !flag_trapping_math
17702 && !optimize_size"
17703 {
17704 ix86_expand_lfloorceil (operand0, operand1, true);
17705 DONE;
17706 })
17707
17708 (define_expand "lfloor<mode>si2"
17709 [(match_operand:SI 0 "nonimmediate_operand" "")
17710 (match_operand:SSEMODEF 1 "register_operand" "")]
17711 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17712 && !flag_trapping_math
17713 && (!optimize_size || !TARGET_64BIT)"
17714 {
17715 ix86_expand_lfloorceil (operand0, operand1, true);
17716 DONE;
17717 })
17718
17719 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17720 (define_insn_and_split "frndintxf2_ceil"
17721 [(set (match_operand:XF 0 "register_operand" "=f")
17722 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17723 UNSPEC_FRNDINT_CEIL))
17724 (clobber (reg:CC FLAGS_REG))]
17725 "TARGET_USE_FANCY_MATH_387
17726 && flag_unsafe_math_optimizations
17727 && !(reload_completed || reload_in_progress)"
17728 "#"
17729 "&& 1"
17730 [(const_int 0)]
17731 {
17732 ix86_optimize_mode_switching[I387_CEIL] = 1;
17733
17734 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17735 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17736
17737 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17738 operands[2], operands[3]));
17739 DONE;
17740 }
17741 [(set_attr "type" "frndint")
17742 (set_attr "i387_cw" "ceil")
17743 (set_attr "mode" "XF")])
17744
17745 (define_insn "frndintxf2_ceil_i387"
17746 [(set (match_operand:XF 0 "register_operand" "=f")
17747 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17748 UNSPEC_FRNDINT_CEIL))
17749 (use (match_operand:HI 2 "memory_operand" "m"))
17750 (use (match_operand:HI 3 "memory_operand" "m"))]
17751 "TARGET_USE_FANCY_MATH_387
17752 && flag_unsafe_math_optimizations"
17753 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17754 [(set_attr "type" "frndint")
17755 (set_attr "i387_cw" "ceil")
17756 (set_attr "mode" "XF")])
17757
17758 (define_expand "ceilxf2"
17759 [(use (match_operand:XF 0 "register_operand" ""))
17760 (use (match_operand:XF 1 "register_operand" ""))]
17761 "TARGET_USE_FANCY_MATH_387
17762 && flag_unsafe_math_optimizations && !optimize_size"
17763 {
17764 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17765 DONE;
17766 })
17767
17768 (define_expand "ceildf2"
17769 [(use (match_operand:DF 0 "register_operand" ""))
17770 (use (match_operand:DF 1 "register_operand" ""))]
17771 "((TARGET_USE_FANCY_MATH_387
17772 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17773 && flag_unsafe_math_optimizations)
17774 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17775 && !flag_trapping_math))
17776 && !optimize_size"
17777 {
17778 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17779 && !flag_trapping_math)
17780 {
17781 if (TARGET_64BIT)
17782 ix86_expand_floorceil (operand0, operand1, false);
17783 else
17784 ix86_expand_floorceildf_32 (operand0, operand1, false);
17785 }
17786 else
17787 {
17788 rtx op0 = gen_reg_rtx (XFmode);
17789 rtx op1 = gen_reg_rtx (XFmode);
17790
17791 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17792 emit_insn (gen_frndintxf2_ceil (op0, op1));
17793
17794 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17795 }
17796 DONE;
17797 })
17798
17799 (define_expand "ceilsf2"
17800 [(use (match_operand:SF 0 "register_operand" ""))
17801 (use (match_operand:SF 1 "register_operand" ""))]
17802 "((TARGET_USE_FANCY_MATH_387
17803 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17804 && flag_unsafe_math_optimizations)
17805 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17806 && !flag_trapping_math))
17807 && !optimize_size"
17808 {
17809 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17810 && !flag_trapping_math)
17811 ix86_expand_floorceil (operand0, operand1, false);
17812 else
17813 {
17814 rtx op0 = gen_reg_rtx (XFmode);
17815 rtx op1 = gen_reg_rtx (XFmode);
17816
17817 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17818 emit_insn (gen_frndintxf2_ceil (op0, op1));
17819
17820 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17821 }
17822 DONE;
17823 })
17824
17825 (define_insn_and_split "*fist<mode>2_ceil_1"
17826 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17827 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17828 UNSPEC_FIST_CEIL))
17829 (clobber (reg:CC FLAGS_REG))]
17830 "TARGET_USE_FANCY_MATH_387
17831 && flag_unsafe_math_optimizations
17832 && !(reload_completed || reload_in_progress)"
17833 "#"
17834 "&& 1"
17835 [(const_int 0)]
17836 {
17837 ix86_optimize_mode_switching[I387_CEIL] = 1;
17838
17839 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17840 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17841 if (memory_operand (operands[0], VOIDmode))
17842 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17843 operands[2], operands[3]));
17844 else
17845 {
17846 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17847 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17848 operands[2], operands[3],
17849 operands[4]));
17850 }
17851 DONE;
17852 }
17853 [(set_attr "type" "fistp")
17854 (set_attr "i387_cw" "ceil")
17855 (set_attr "mode" "<MODE>")])
17856
17857 (define_insn "fistdi2_ceil"
17858 [(set (match_operand:DI 0 "memory_operand" "=m")
17859 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17860 UNSPEC_FIST_CEIL))
17861 (use (match_operand:HI 2 "memory_operand" "m"))
17862 (use (match_operand:HI 3 "memory_operand" "m"))
17863 (clobber (match_scratch:XF 4 "=&1f"))]
17864 "TARGET_USE_FANCY_MATH_387
17865 && flag_unsafe_math_optimizations"
17866 "* return output_fix_trunc (insn, operands, 0);"
17867 [(set_attr "type" "fistp")
17868 (set_attr "i387_cw" "ceil")
17869 (set_attr "mode" "DI")])
17870
17871 (define_insn "fistdi2_ceil_with_temp"
17872 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17873 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17874 UNSPEC_FIST_CEIL))
17875 (use (match_operand:HI 2 "memory_operand" "m,m"))
17876 (use (match_operand:HI 3 "memory_operand" "m,m"))
17877 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17878 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17879 "TARGET_USE_FANCY_MATH_387
17880 && flag_unsafe_math_optimizations"
17881 "#"
17882 [(set_attr "type" "fistp")
17883 (set_attr "i387_cw" "ceil")
17884 (set_attr "mode" "DI")])
17885
17886 (define_split
17887 [(set (match_operand:DI 0 "register_operand" "")
17888 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17889 UNSPEC_FIST_CEIL))
17890 (use (match_operand:HI 2 "memory_operand" ""))
17891 (use (match_operand:HI 3 "memory_operand" ""))
17892 (clobber (match_operand:DI 4 "memory_operand" ""))
17893 (clobber (match_scratch 5 ""))]
17894 "reload_completed"
17895 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17896 (use (match_dup 2))
17897 (use (match_dup 3))
17898 (clobber (match_dup 5))])
17899 (set (match_dup 0) (match_dup 4))]
17900 "")
17901
17902 (define_split
17903 [(set (match_operand:DI 0 "memory_operand" "")
17904 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17905 UNSPEC_FIST_CEIL))
17906 (use (match_operand:HI 2 "memory_operand" ""))
17907 (use (match_operand:HI 3 "memory_operand" ""))
17908 (clobber (match_operand:DI 4 "memory_operand" ""))
17909 (clobber (match_scratch 5 ""))]
17910 "reload_completed"
17911 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17912 (use (match_dup 2))
17913 (use (match_dup 3))
17914 (clobber (match_dup 5))])]
17915 "")
17916
17917 (define_insn "fist<mode>2_ceil"
17918 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17919 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17920 UNSPEC_FIST_CEIL))
17921 (use (match_operand:HI 2 "memory_operand" "m"))
17922 (use (match_operand:HI 3 "memory_operand" "m"))]
17923 "TARGET_USE_FANCY_MATH_387
17924 && flag_unsafe_math_optimizations"
17925 "* return output_fix_trunc (insn, operands, 0);"
17926 [(set_attr "type" "fistp")
17927 (set_attr "i387_cw" "ceil")
17928 (set_attr "mode" "<MODE>")])
17929
17930 (define_insn "fist<mode>2_ceil_with_temp"
17931 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17932 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17933 UNSPEC_FIST_CEIL))
17934 (use (match_operand:HI 2 "memory_operand" "m,m"))
17935 (use (match_operand:HI 3 "memory_operand" "m,m"))
17936 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17937 "TARGET_USE_FANCY_MATH_387
17938 && flag_unsafe_math_optimizations"
17939 "#"
17940 [(set_attr "type" "fistp")
17941 (set_attr "i387_cw" "ceil")
17942 (set_attr "mode" "<MODE>")])
17943
17944 (define_split
17945 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17946 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17947 UNSPEC_FIST_CEIL))
17948 (use (match_operand:HI 2 "memory_operand" ""))
17949 (use (match_operand:HI 3 "memory_operand" ""))
17950 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17951 "reload_completed"
17952 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17953 UNSPEC_FIST_CEIL))
17954 (use (match_dup 2))
17955 (use (match_dup 3))])
17956 (set (match_dup 0) (match_dup 4))]
17957 "")
17958
17959 (define_split
17960 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17961 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17962 UNSPEC_FIST_CEIL))
17963 (use (match_operand:HI 2 "memory_operand" ""))
17964 (use (match_operand:HI 3 "memory_operand" ""))
17965 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17966 "reload_completed"
17967 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17968 UNSPEC_FIST_CEIL))
17969 (use (match_dup 2))
17970 (use (match_dup 3))])]
17971 "")
17972
17973 (define_expand "lceilxf<mode>2"
17974 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17975 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17976 UNSPEC_FIST_CEIL))
17977 (clobber (reg:CC FLAGS_REG))])]
17978 "TARGET_USE_FANCY_MATH_387
17979 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17980 && flag_unsafe_math_optimizations"
17981 "")
17982
17983 (define_expand "lceil<mode>di2"
17984 [(match_operand:DI 0 "nonimmediate_operand" "")
17985 (match_operand:SSEMODEF 1 "register_operand" "")]
17986 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17987 && !flag_trapping_math"
17988 {
17989 ix86_expand_lfloorceil (operand0, operand1, false);
17990 DONE;
17991 })
17992
17993 (define_expand "lceil<mode>si2"
17994 [(match_operand:SI 0 "nonimmediate_operand" "")
17995 (match_operand:SSEMODEF 1 "register_operand" "")]
17996 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17997 && !flag_trapping_math"
17998 {
17999 ix86_expand_lfloorceil (operand0, operand1, false);
18000 DONE;
18001 })
18002
18003 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18004 (define_insn_and_split "frndintxf2_trunc"
18005 [(set (match_operand:XF 0 "register_operand" "=f")
18006 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18007 UNSPEC_FRNDINT_TRUNC))
18008 (clobber (reg:CC FLAGS_REG))]
18009 "TARGET_USE_FANCY_MATH_387
18010 && flag_unsafe_math_optimizations
18011 && !(reload_completed || reload_in_progress)"
18012 "#"
18013 "&& 1"
18014 [(const_int 0)]
18015 {
18016 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18017
18018 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18019 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18020
18021 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18022 operands[2], operands[3]));
18023 DONE;
18024 }
18025 [(set_attr "type" "frndint")
18026 (set_attr "i387_cw" "trunc")
18027 (set_attr "mode" "XF")])
18028
18029 (define_insn "frndintxf2_trunc_i387"
18030 [(set (match_operand:XF 0 "register_operand" "=f")
18031 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18032 UNSPEC_FRNDINT_TRUNC))
18033 (use (match_operand:HI 2 "memory_operand" "m"))
18034 (use (match_operand:HI 3 "memory_operand" "m"))]
18035 "TARGET_USE_FANCY_MATH_387
18036 && flag_unsafe_math_optimizations"
18037 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18038 [(set_attr "type" "frndint")
18039 (set_attr "i387_cw" "trunc")
18040 (set_attr "mode" "XF")])
18041
18042 (define_expand "btruncxf2"
18043 [(use (match_operand:XF 0 "register_operand" ""))
18044 (use (match_operand:XF 1 "register_operand" ""))]
18045 "TARGET_USE_FANCY_MATH_387
18046 && flag_unsafe_math_optimizations && !optimize_size"
18047 {
18048 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18049 DONE;
18050 })
18051
18052 (define_expand "btruncdf2"
18053 [(use (match_operand:DF 0 "register_operand" ""))
18054 (use (match_operand:DF 1 "register_operand" ""))]
18055 "((TARGET_USE_FANCY_MATH_387
18056 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18057 && flag_unsafe_math_optimizations)
18058 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18059 && !flag_trapping_math))
18060 && !optimize_size"
18061 {
18062 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18063 && !flag_trapping_math)
18064 {
18065 if (TARGET_64BIT)
18066 ix86_expand_trunc (operand0, operand1);
18067 else
18068 ix86_expand_truncdf_32 (operand0, operand1);
18069 }
18070 else
18071 {
18072 rtx op0 = gen_reg_rtx (XFmode);
18073 rtx op1 = gen_reg_rtx (XFmode);
18074
18075 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18076 emit_insn (gen_frndintxf2_trunc (op0, op1));
18077
18078 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18079 }
18080 DONE;
18081 })
18082
18083 (define_expand "btruncsf2"
18084 [(use (match_operand:SF 0 "register_operand" ""))
18085 (use (match_operand:SF 1 "register_operand" ""))]
18086 "((TARGET_USE_FANCY_MATH_387
18087 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18088 && flag_unsafe_math_optimizations)
18089 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18090 && !flag_trapping_math))
18091 && !optimize_size"
18092 {
18093 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18094 && !flag_trapping_math)
18095 ix86_expand_trunc (operand0, operand1);
18096 else
18097 {
18098 rtx op0 = gen_reg_rtx (XFmode);
18099 rtx op1 = gen_reg_rtx (XFmode);
18100
18101 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18102 emit_insn (gen_frndintxf2_trunc (op0, op1));
18103
18104 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18105 }
18106 DONE;
18107 })
18108
18109 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18110 (define_insn_and_split "frndintxf2_mask_pm"
18111 [(set (match_operand:XF 0 "register_operand" "=f")
18112 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18113 UNSPEC_FRNDINT_MASK_PM))
18114 (clobber (reg:CC FLAGS_REG))]
18115 "TARGET_USE_FANCY_MATH_387
18116 && flag_unsafe_math_optimizations
18117 && !(reload_completed || reload_in_progress)"
18118 "#"
18119 "&& 1"
18120 [(const_int 0)]
18121 {
18122 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18123
18124 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18125 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18126
18127 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18128 operands[2], operands[3]));
18129 DONE;
18130 }
18131 [(set_attr "type" "frndint")
18132 (set_attr "i387_cw" "mask_pm")
18133 (set_attr "mode" "XF")])
18134
18135 (define_insn "frndintxf2_mask_pm_i387"
18136 [(set (match_operand:XF 0 "register_operand" "=f")
18137 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18138 UNSPEC_FRNDINT_MASK_PM))
18139 (use (match_operand:HI 2 "memory_operand" "m"))
18140 (use (match_operand:HI 3 "memory_operand" "m"))]
18141 "TARGET_USE_FANCY_MATH_387
18142 && flag_unsafe_math_optimizations"
18143 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18144 [(set_attr "type" "frndint")
18145 (set_attr "i387_cw" "mask_pm")
18146 (set_attr "mode" "XF")])
18147
18148 (define_expand "nearbyintxf2"
18149 [(use (match_operand:XF 0 "register_operand" ""))
18150 (use (match_operand:XF 1 "register_operand" ""))]
18151 "TARGET_USE_FANCY_MATH_387
18152 && flag_unsafe_math_optimizations"
18153 {
18154 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18155
18156 DONE;
18157 })
18158
18159 (define_expand "nearbyintdf2"
18160 [(use (match_operand:DF 0 "register_operand" ""))
18161 (use (match_operand:DF 1 "register_operand" ""))]
18162 "TARGET_USE_FANCY_MATH_387
18163 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18164 && flag_unsafe_math_optimizations"
18165 {
18166 rtx op0 = gen_reg_rtx (XFmode);
18167 rtx op1 = gen_reg_rtx (XFmode);
18168
18169 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18170 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18171
18172 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18173 DONE;
18174 })
18175
18176 (define_expand "nearbyintsf2"
18177 [(use (match_operand:SF 0 "register_operand" ""))
18178 (use (match_operand:SF 1 "register_operand" ""))]
18179 "TARGET_USE_FANCY_MATH_387
18180 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18181 && flag_unsafe_math_optimizations"
18182 {
18183 rtx op0 = gen_reg_rtx (XFmode);
18184 rtx op1 = gen_reg_rtx (XFmode);
18185
18186 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18187 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18188
18189 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18190 DONE;
18191 })
18192
18193 (define_insn "fxam<mode>2_i387"
18194 [(set (match_operand:HI 0 "register_operand" "=a")
18195 (unspec:HI
18196 [(match_operand:X87MODEF 1 "register_operand" "f")]
18197 UNSPEC_FXAM))]
18198 "TARGET_USE_FANCY_MATH_387"
18199 "fxam\n\tfnstsw\t%0"
18200 [(set_attr "type" "multi")
18201 (set_attr "unit" "i387")
18202 (set_attr "mode" "<MODE>")])
18203
18204 (define_expand "isinf<mode>2"
18205 [(use (match_operand:SI 0 "register_operand" ""))
18206 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18207 "TARGET_USE_FANCY_MATH_387
18208 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18209 || TARGET_MIX_SSE_I387)"
18210 {
18211 rtx mask = GEN_INT (0x45);
18212 rtx val = GEN_INT (0x05);
18213
18214 rtx cond;
18215
18216 rtx scratch = gen_reg_rtx (HImode);
18217 rtx res = gen_reg_rtx (QImode);
18218
18219 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18220 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18221 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18222 cond = gen_rtx_fmt_ee (EQ, QImode,
18223 gen_rtx_REG (CCmode, FLAGS_REG),
18224 const0_rtx);
18225 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18226 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18227 DONE;
18228 })
18229
18230 \f
18231 ;; Block operation instructions
18232
18233 (define_expand "movmemsi"
18234 [(use (match_operand:BLK 0 "memory_operand" ""))
18235 (use (match_operand:BLK 1 "memory_operand" ""))
18236 (use (match_operand:SI 2 "nonmemory_operand" ""))
18237 (use (match_operand:SI 3 "const_int_operand" ""))
18238 (use (match_operand:SI 4 "const_int_operand" ""))
18239 (use (match_operand:SI 5 "const_int_operand" ""))]
18240 ""
18241 {
18242 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18243 operands[4], operands[5]))
18244 DONE;
18245 else
18246 FAIL;
18247 })
18248
18249 (define_expand "movmemdi"
18250 [(use (match_operand:BLK 0 "memory_operand" ""))
18251 (use (match_operand:BLK 1 "memory_operand" ""))
18252 (use (match_operand:DI 2 "nonmemory_operand" ""))
18253 (use (match_operand:DI 3 "const_int_operand" ""))
18254 (use (match_operand:SI 4 "const_int_operand" ""))
18255 (use (match_operand:SI 5 "const_int_operand" ""))]
18256 "TARGET_64BIT"
18257 {
18258 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18259 operands[4], operands[5]))
18260 DONE;
18261 else
18262 FAIL;
18263 })
18264
18265 ;; Most CPUs don't like single string operations
18266 ;; Handle this case here to simplify previous expander.
18267
18268 (define_expand "strmov"
18269 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18270 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18271 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18272 (clobber (reg:CC FLAGS_REG))])
18273 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18274 (clobber (reg:CC FLAGS_REG))])]
18275 ""
18276 {
18277 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18278
18279 /* If .md ever supports :P for Pmode, these can be directly
18280 in the pattern above. */
18281 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18282 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18283
18284 if (TARGET_SINGLE_STRINGOP || optimize_size)
18285 {
18286 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18287 operands[2], operands[3],
18288 operands[5], operands[6]));
18289 DONE;
18290 }
18291
18292 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18293 })
18294
18295 (define_expand "strmov_singleop"
18296 [(parallel [(set (match_operand 1 "memory_operand" "")
18297 (match_operand 3 "memory_operand" ""))
18298 (set (match_operand 0 "register_operand" "")
18299 (match_operand 4 "" ""))
18300 (set (match_operand 2 "register_operand" "")
18301 (match_operand 5 "" ""))])]
18302 "TARGET_SINGLE_STRINGOP || optimize_size"
18303 "")
18304
18305 (define_insn "*strmovdi_rex_1"
18306 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18307 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18308 (set (match_operand:DI 0 "register_operand" "=D")
18309 (plus:DI (match_dup 2)
18310 (const_int 8)))
18311 (set (match_operand:DI 1 "register_operand" "=S")
18312 (plus:DI (match_dup 3)
18313 (const_int 8)))]
18314 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18315 "movsq"
18316 [(set_attr "type" "str")
18317 (set_attr "mode" "DI")
18318 (set_attr "memory" "both")])
18319
18320 (define_insn "*strmovsi_1"
18321 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18322 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18323 (set (match_operand:SI 0 "register_operand" "=D")
18324 (plus:SI (match_dup 2)
18325 (const_int 4)))
18326 (set (match_operand:SI 1 "register_operand" "=S")
18327 (plus:SI (match_dup 3)
18328 (const_int 4)))]
18329 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18330 "{movsl|movsd}"
18331 [(set_attr "type" "str")
18332 (set_attr "mode" "SI")
18333 (set_attr "memory" "both")])
18334
18335 (define_insn "*strmovsi_rex_1"
18336 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18337 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18338 (set (match_operand:DI 0 "register_operand" "=D")
18339 (plus:DI (match_dup 2)
18340 (const_int 4)))
18341 (set (match_operand:DI 1 "register_operand" "=S")
18342 (plus:DI (match_dup 3)
18343 (const_int 4)))]
18344 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18345 "{movsl|movsd}"
18346 [(set_attr "type" "str")
18347 (set_attr "mode" "SI")
18348 (set_attr "memory" "both")])
18349
18350 (define_insn "*strmovhi_1"
18351 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18352 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18353 (set (match_operand:SI 0 "register_operand" "=D")
18354 (plus:SI (match_dup 2)
18355 (const_int 2)))
18356 (set (match_operand:SI 1 "register_operand" "=S")
18357 (plus:SI (match_dup 3)
18358 (const_int 2)))]
18359 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18360 "movsw"
18361 [(set_attr "type" "str")
18362 (set_attr "memory" "both")
18363 (set_attr "mode" "HI")])
18364
18365 (define_insn "*strmovhi_rex_1"
18366 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18367 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18368 (set (match_operand:DI 0 "register_operand" "=D")
18369 (plus:DI (match_dup 2)
18370 (const_int 2)))
18371 (set (match_operand:DI 1 "register_operand" "=S")
18372 (plus:DI (match_dup 3)
18373 (const_int 2)))]
18374 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18375 "movsw"
18376 [(set_attr "type" "str")
18377 (set_attr "memory" "both")
18378 (set_attr "mode" "HI")])
18379
18380 (define_insn "*strmovqi_1"
18381 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18382 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18383 (set (match_operand:SI 0 "register_operand" "=D")
18384 (plus:SI (match_dup 2)
18385 (const_int 1)))
18386 (set (match_operand:SI 1 "register_operand" "=S")
18387 (plus:SI (match_dup 3)
18388 (const_int 1)))]
18389 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18390 "movsb"
18391 [(set_attr "type" "str")
18392 (set_attr "memory" "both")
18393 (set_attr "mode" "QI")])
18394
18395 (define_insn "*strmovqi_rex_1"
18396 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18397 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18398 (set (match_operand:DI 0 "register_operand" "=D")
18399 (plus:DI (match_dup 2)
18400 (const_int 1)))
18401 (set (match_operand:DI 1 "register_operand" "=S")
18402 (plus:DI (match_dup 3)
18403 (const_int 1)))]
18404 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18405 "movsb"
18406 [(set_attr "type" "str")
18407 (set_attr "memory" "both")
18408 (set_attr "mode" "QI")])
18409
18410 (define_expand "rep_mov"
18411 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18412 (set (match_operand 0 "register_operand" "")
18413 (match_operand 5 "" ""))
18414 (set (match_operand 2 "register_operand" "")
18415 (match_operand 6 "" ""))
18416 (set (match_operand 1 "memory_operand" "")
18417 (match_operand 3 "memory_operand" ""))
18418 (use (match_dup 4))])]
18419 ""
18420 "")
18421
18422 (define_insn "*rep_movdi_rex64"
18423 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18424 (set (match_operand:DI 0 "register_operand" "=D")
18425 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18426 (const_int 3))
18427 (match_operand:DI 3 "register_operand" "0")))
18428 (set (match_operand:DI 1 "register_operand" "=S")
18429 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18430 (match_operand:DI 4 "register_operand" "1")))
18431 (set (mem:BLK (match_dup 3))
18432 (mem:BLK (match_dup 4)))
18433 (use (match_dup 5))]
18434 "TARGET_64BIT"
18435 "{rep\;movsq|rep movsq}"
18436 [(set_attr "type" "str")
18437 (set_attr "prefix_rep" "1")
18438 (set_attr "memory" "both")
18439 (set_attr "mode" "DI")])
18440
18441 (define_insn "*rep_movsi"
18442 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18443 (set (match_operand:SI 0 "register_operand" "=D")
18444 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18445 (const_int 2))
18446 (match_operand:SI 3 "register_operand" "0")))
18447 (set (match_operand:SI 1 "register_operand" "=S")
18448 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18449 (match_operand:SI 4 "register_operand" "1")))
18450 (set (mem:BLK (match_dup 3))
18451 (mem:BLK (match_dup 4)))
18452 (use (match_dup 5))]
18453 "!TARGET_64BIT"
18454 "{rep\;movsl|rep movsd}"
18455 [(set_attr "type" "str")
18456 (set_attr "prefix_rep" "1")
18457 (set_attr "memory" "both")
18458 (set_attr "mode" "SI")])
18459
18460 (define_insn "*rep_movsi_rex64"
18461 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18462 (set (match_operand:DI 0 "register_operand" "=D")
18463 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18464 (const_int 2))
18465 (match_operand:DI 3 "register_operand" "0")))
18466 (set (match_operand:DI 1 "register_operand" "=S")
18467 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18468 (match_operand:DI 4 "register_operand" "1")))
18469 (set (mem:BLK (match_dup 3))
18470 (mem:BLK (match_dup 4)))
18471 (use (match_dup 5))]
18472 "TARGET_64BIT"
18473 "{rep\;movsl|rep movsd}"
18474 [(set_attr "type" "str")
18475 (set_attr "prefix_rep" "1")
18476 (set_attr "memory" "both")
18477 (set_attr "mode" "SI")])
18478
18479 (define_insn "*rep_movqi"
18480 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18481 (set (match_operand:SI 0 "register_operand" "=D")
18482 (plus:SI (match_operand:SI 3 "register_operand" "0")
18483 (match_operand:SI 5 "register_operand" "2")))
18484 (set (match_operand:SI 1 "register_operand" "=S")
18485 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18486 (set (mem:BLK (match_dup 3))
18487 (mem:BLK (match_dup 4)))
18488 (use (match_dup 5))]
18489 "!TARGET_64BIT"
18490 "{rep\;movsb|rep movsb}"
18491 [(set_attr "type" "str")
18492 (set_attr "prefix_rep" "1")
18493 (set_attr "memory" "both")
18494 (set_attr "mode" "SI")])
18495
18496 (define_insn "*rep_movqi_rex64"
18497 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18498 (set (match_operand:DI 0 "register_operand" "=D")
18499 (plus:DI (match_operand:DI 3 "register_operand" "0")
18500 (match_operand:DI 5 "register_operand" "2")))
18501 (set (match_operand:DI 1 "register_operand" "=S")
18502 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18503 (set (mem:BLK (match_dup 3))
18504 (mem:BLK (match_dup 4)))
18505 (use (match_dup 5))]
18506 "TARGET_64BIT"
18507 "{rep\;movsb|rep movsb}"
18508 [(set_attr "type" "str")
18509 (set_attr "prefix_rep" "1")
18510 (set_attr "memory" "both")
18511 (set_attr "mode" "SI")])
18512
18513 (define_expand "setmemsi"
18514 [(use (match_operand:BLK 0 "memory_operand" ""))
18515 (use (match_operand:SI 1 "nonmemory_operand" ""))
18516 (use (match_operand 2 "const_int_operand" ""))
18517 (use (match_operand 3 "const_int_operand" ""))
18518 (use (match_operand:SI 4 "const_int_operand" ""))
18519 (use (match_operand:SI 5 "const_int_operand" ""))]
18520 ""
18521 {
18522 if (ix86_expand_setmem (operands[0], operands[1],
18523 operands[2], operands[3],
18524 operands[4], operands[5]))
18525 DONE;
18526 else
18527 FAIL;
18528 })
18529
18530 (define_expand "setmemdi"
18531 [(use (match_operand:BLK 0 "memory_operand" ""))
18532 (use (match_operand:DI 1 "nonmemory_operand" ""))
18533 (use (match_operand 2 "const_int_operand" ""))
18534 (use (match_operand 3 "const_int_operand" ""))
18535 (use (match_operand 4 "const_int_operand" ""))
18536 (use (match_operand 5 "const_int_operand" ""))]
18537 "TARGET_64BIT"
18538 {
18539 if (ix86_expand_setmem (operands[0], operands[1],
18540 operands[2], operands[3],
18541 operands[4], operands[5]))
18542 DONE;
18543 else
18544 FAIL;
18545 })
18546
18547 ;; Most CPUs don't like single string operations
18548 ;; Handle this case here to simplify previous expander.
18549
18550 (define_expand "strset"
18551 [(set (match_operand 1 "memory_operand" "")
18552 (match_operand 2 "register_operand" ""))
18553 (parallel [(set (match_operand 0 "register_operand" "")
18554 (match_dup 3))
18555 (clobber (reg:CC FLAGS_REG))])]
18556 ""
18557 {
18558 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18559 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18560
18561 /* If .md ever supports :P for Pmode, this can be directly
18562 in the pattern above. */
18563 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18564 GEN_INT (GET_MODE_SIZE (GET_MODE
18565 (operands[2]))));
18566 if (TARGET_SINGLE_STRINGOP || optimize_size)
18567 {
18568 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18569 operands[3]));
18570 DONE;
18571 }
18572 })
18573
18574 (define_expand "strset_singleop"
18575 [(parallel [(set (match_operand 1 "memory_operand" "")
18576 (match_operand 2 "register_operand" ""))
18577 (set (match_operand 0 "register_operand" "")
18578 (match_operand 3 "" ""))])]
18579 "TARGET_SINGLE_STRINGOP || optimize_size"
18580 "")
18581
18582 (define_insn "*strsetdi_rex_1"
18583 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18584 (match_operand:DI 2 "register_operand" "a"))
18585 (set (match_operand:DI 0 "register_operand" "=D")
18586 (plus:DI (match_dup 1)
18587 (const_int 8)))]
18588 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18589 "stosq"
18590 [(set_attr "type" "str")
18591 (set_attr "memory" "store")
18592 (set_attr "mode" "DI")])
18593
18594 (define_insn "*strsetsi_1"
18595 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18596 (match_operand:SI 2 "register_operand" "a"))
18597 (set (match_operand:SI 0 "register_operand" "=D")
18598 (plus:SI (match_dup 1)
18599 (const_int 4)))]
18600 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18601 "{stosl|stosd}"
18602 [(set_attr "type" "str")
18603 (set_attr "memory" "store")
18604 (set_attr "mode" "SI")])
18605
18606 (define_insn "*strsetsi_rex_1"
18607 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18608 (match_operand:SI 2 "register_operand" "a"))
18609 (set (match_operand:DI 0 "register_operand" "=D")
18610 (plus:DI (match_dup 1)
18611 (const_int 4)))]
18612 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18613 "{stosl|stosd}"
18614 [(set_attr "type" "str")
18615 (set_attr "memory" "store")
18616 (set_attr "mode" "SI")])
18617
18618 (define_insn "*strsethi_1"
18619 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18620 (match_operand:HI 2 "register_operand" "a"))
18621 (set (match_operand:SI 0 "register_operand" "=D")
18622 (plus:SI (match_dup 1)
18623 (const_int 2)))]
18624 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18625 "stosw"
18626 [(set_attr "type" "str")
18627 (set_attr "memory" "store")
18628 (set_attr "mode" "HI")])
18629
18630 (define_insn "*strsethi_rex_1"
18631 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18632 (match_operand:HI 2 "register_operand" "a"))
18633 (set (match_operand:DI 0 "register_operand" "=D")
18634 (plus:DI (match_dup 1)
18635 (const_int 2)))]
18636 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18637 "stosw"
18638 [(set_attr "type" "str")
18639 (set_attr "memory" "store")
18640 (set_attr "mode" "HI")])
18641
18642 (define_insn "*strsetqi_1"
18643 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18644 (match_operand:QI 2 "register_operand" "a"))
18645 (set (match_operand:SI 0 "register_operand" "=D")
18646 (plus:SI (match_dup 1)
18647 (const_int 1)))]
18648 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18649 "stosb"
18650 [(set_attr "type" "str")
18651 (set_attr "memory" "store")
18652 (set_attr "mode" "QI")])
18653
18654 (define_insn "*strsetqi_rex_1"
18655 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18656 (match_operand:QI 2 "register_operand" "a"))
18657 (set (match_operand:DI 0 "register_operand" "=D")
18658 (plus:DI (match_dup 1)
18659 (const_int 1)))]
18660 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18661 "stosb"
18662 [(set_attr "type" "str")
18663 (set_attr "memory" "store")
18664 (set_attr "mode" "QI")])
18665
18666 (define_expand "rep_stos"
18667 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18668 (set (match_operand 0 "register_operand" "")
18669 (match_operand 4 "" ""))
18670 (set (match_operand 2 "memory_operand" "") (const_int 0))
18671 (use (match_operand 3 "register_operand" ""))
18672 (use (match_dup 1))])]
18673 ""
18674 "")
18675
18676 (define_insn "*rep_stosdi_rex64"
18677 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18678 (set (match_operand:DI 0 "register_operand" "=D")
18679 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18680 (const_int 3))
18681 (match_operand:DI 3 "register_operand" "0")))
18682 (set (mem:BLK (match_dup 3))
18683 (const_int 0))
18684 (use (match_operand:DI 2 "register_operand" "a"))
18685 (use (match_dup 4))]
18686 "TARGET_64BIT"
18687 "{rep\;stosq|rep stosq}"
18688 [(set_attr "type" "str")
18689 (set_attr "prefix_rep" "1")
18690 (set_attr "memory" "store")
18691 (set_attr "mode" "DI")])
18692
18693 (define_insn "*rep_stossi"
18694 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18695 (set (match_operand:SI 0 "register_operand" "=D")
18696 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18697 (const_int 2))
18698 (match_operand:SI 3 "register_operand" "0")))
18699 (set (mem:BLK (match_dup 3))
18700 (const_int 0))
18701 (use (match_operand:SI 2 "register_operand" "a"))
18702 (use (match_dup 4))]
18703 "!TARGET_64BIT"
18704 "{rep\;stosl|rep stosd}"
18705 [(set_attr "type" "str")
18706 (set_attr "prefix_rep" "1")
18707 (set_attr "memory" "store")
18708 (set_attr "mode" "SI")])
18709
18710 (define_insn "*rep_stossi_rex64"
18711 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18712 (set (match_operand:DI 0 "register_operand" "=D")
18713 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18714 (const_int 2))
18715 (match_operand:DI 3 "register_operand" "0")))
18716 (set (mem:BLK (match_dup 3))
18717 (const_int 0))
18718 (use (match_operand:SI 2 "register_operand" "a"))
18719 (use (match_dup 4))]
18720 "TARGET_64BIT"
18721 "{rep\;stosl|rep stosd}"
18722 [(set_attr "type" "str")
18723 (set_attr "prefix_rep" "1")
18724 (set_attr "memory" "store")
18725 (set_attr "mode" "SI")])
18726
18727 (define_insn "*rep_stosqi"
18728 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18729 (set (match_operand:SI 0 "register_operand" "=D")
18730 (plus:SI (match_operand:SI 3 "register_operand" "0")
18731 (match_operand:SI 4 "register_operand" "1")))
18732 (set (mem:BLK (match_dup 3))
18733 (const_int 0))
18734 (use (match_operand:QI 2 "register_operand" "a"))
18735 (use (match_dup 4))]
18736 "!TARGET_64BIT"
18737 "{rep\;stosb|rep stosb}"
18738 [(set_attr "type" "str")
18739 (set_attr "prefix_rep" "1")
18740 (set_attr "memory" "store")
18741 (set_attr "mode" "QI")])
18742
18743 (define_insn "*rep_stosqi_rex64"
18744 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18745 (set (match_operand:DI 0 "register_operand" "=D")
18746 (plus:DI (match_operand:DI 3 "register_operand" "0")
18747 (match_operand:DI 4 "register_operand" "1")))
18748 (set (mem:BLK (match_dup 3))
18749 (const_int 0))
18750 (use (match_operand:QI 2 "register_operand" "a"))
18751 (use (match_dup 4))]
18752 "TARGET_64BIT"
18753 "{rep\;stosb|rep stosb}"
18754 [(set_attr "type" "str")
18755 (set_attr "prefix_rep" "1")
18756 (set_attr "memory" "store")
18757 (set_attr "mode" "QI")])
18758
18759 (define_expand "cmpstrnsi"
18760 [(set (match_operand:SI 0 "register_operand" "")
18761 (compare:SI (match_operand:BLK 1 "general_operand" "")
18762 (match_operand:BLK 2 "general_operand" "")))
18763 (use (match_operand 3 "general_operand" ""))
18764 (use (match_operand 4 "immediate_operand" ""))]
18765 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18766 {
18767 rtx addr1, addr2, out, outlow, count, countreg, align;
18768
18769 /* Can't use this if the user has appropriated esi or edi. */
18770 if (global_regs[4] || global_regs[5])
18771 FAIL;
18772
18773 out = operands[0];
18774 if (!REG_P (out))
18775 out = gen_reg_rtx (SImode);
18776
18777 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18778 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18779 if (addr1 != XEXP (operands[1], 0))
18780 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18781 if (addr2 != XEXP (operands[2], 0))
18782 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18783
18784 count = operands[3];
18785 countreg = ix86_zero_extend_to_Pmode (count);
18786
18787 /* %%% Iff we are testing strict equality, we can use known alignment
18788 to good advantage. This may be possible with combine, particularly
18789 once cc0 is dead. */
18790 align = operands[4];
18791
18792 if (CONST_INT_P (count))
18793 {
18794 if (INTVAL (count) == 0)
18795 {
18796 emit_move_insn (operands[0], const0_rtx);
18797 DONE;
18798 }
18799 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18800 operands[1], operands[2]));
18801 }
18802 else
18803 {
18804 if (TARGET_64BIT)
18805 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18806 else
18807 emit_insn (gen_cmpsi_1 (countreg, countreg));
18808 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18809 operands[1], operands[2]));
18810 }
18811
18812 outlow = gen_lowpart (QImode, out);
18813 emit_insn (gen_cmpintqi (outlow));
18814 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18815
18816 if (operands[0] != out)
18817 emit_move_insn (operands[0], out);
18818
18819 DONE;
18820 })
18821
18822 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18823
18824 (define_expand "cmpintqi"
18825 [(set (match_dup 1)
18826 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18827 (set (match_dup 2)
18828 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18829 (parallel [(set (match_operand:QI 0 "register_operand" "")
18830 (minus:QI (match_dup 1)
18831 (match_dup 2)))
18832 (clobber (reg:CC FLAGS_REG))])]
18833 ""
18834 "operands[1] = gen_reg_rtx (QImode);
18835 operands[2] = gen_reg_rtx (QImode);")
18836
18837 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18838 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18839
18840 (define_expand "cmpstrnqi_nz_1"
18841 [(parallel [(set (reg:CC FLAGS_REG)
18842 (compare:CC (match_operand 4 "memory_operand" "")
18843 (match_operand 5 "memory_operand" "")))
18844 (use (match_operand 2 "register_operand" ""))
18845 (use (match_operand:SI 3 "immediate_operand" ""))
18846 (clobber (match_operand 0 "register_operand" ""))
18847 (clobber (match_operand 1 "register_operand" ""))
18848 (clobber (match_dup 2))])]
18849 ""
18850 "")
18851
18852 (define_insn "*cmpstrnqi_nz_1"
18853 [(set (reg:CC FLAGS_REG)
18854 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18855 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18856 (use (match_operand:SI 6 "register_operand" "2"))
18857 (use (match_operand:SI 3 "immediate_operand" "i"))
18858 (clobber (match_operand:SI 0 "register_operand" "=S"))
18859 (clobber (match_operand:SI 1 "register_operand" "=D"))
18860 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18861 "!TARGET_64BIT"
18862 "repz{\;| }cmpsb"
18863 [(set_attr "type" "str")
18864 (set_attr "mode" "QI")
18865 (set_attr "prefix_rep" "1")])
18866
18867 (define_insn "*cmpstrnqi_nz_rex_1"
18868 [(set (reg:CC FLAGS_REG)
18869 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18870 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18871 (use (match_operand:DI 6 "register_operand" "2"))
18872 (use (match_operand:SI 3 "immediate_operand" "i"))
18873 (clobber (match_operand:DI 0 "register_operand" "=S"))
18874 (clobber (match_operand:DI 1 "register_operand" "=D"))
18875 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18876 "TARGET_64BIT"
18877 "repz{\;| }cmpsb"
18878 [(set_attr "type" "str")
18879 (set_attr "mode" "QI")
18880 (set_attr "prefix_rep" "1")])
18881
18882 ;; The same, but the count is not known to not be zero.
18883
18884 (define_expand "cmpstrnqi_1"
18885 [(parallel [(set (reg:CC FLAGS_REG)
18886 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18887 (const_int 0))
18888 (compare:CC (match_operand 4 "memory_operand" "")
18889 (match_operand 5 "memory_operand" ""))
18890 (const_int 0)))
18891 (use (match_operand:SI 3 "immediate_operand" ""))
18892 (use (reg:CC FLAGS_REG))
18893 (clobber (match_operand 0 "register_operand" ""))
18894 (clobber (match_operand 1 "register_operand" ""))
18895 (clobber (match_dup 2))])]
18896 ""
18897 "")
18898
18899 (define_insn "*cmpstrnqi_1"
18900 [(set (reg:CC FLAGS_REG)
18901 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18902 (const_int 0))
18903 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18904 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18905 (const_int 0)))
18906 (use (match_operand:SI 3 "immediate_operand" "i"))
18907 (use (reg:CC FLAGS_REG))
18908 (clobber (match_operand:SI 0 "register_operand" "=S"))
18909 (clobber (match_operand:SI 1 "register_operand" "=D"))
18910 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18911 "!TARGET_64BIT"
18912 "repz{\;| }cmpsb"
18913 [(set_attr "type" "str")
18914 (set_attr "mode" "QI")
18915 (set_attr "prefix_rep" "1")])
18916
18917 (define_insn "*cmpstrnqi_rex_1"
18918 [(set (reg:CC FLAGS_REG)
18919 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18920 (const_int 0))
18921 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18922 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18923 (const_int 0)))
18924 (use (match_operand:SI 3 "immediate_operand" "i"))
18925 (use (reg:CC FLAGS_REG))
18926 (clobber (match_operand:DI 0 "register_operand" "=S"))
18927 (clobber (match_operand:DI 1 "register_operand" "=D"))
18928 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18929 "TARGET_64BIT"
18930 "repz{\;| }cmpsb"
18931 [(set_attr "type" "str")
18932 (set_attr "mode" "QI")
18933 (set_attr "prefix_rep" "1")])
18934
18935 (define_expand "strlensi"
18936 [(set (match_operand:SI 0 "register_operand" "")
18937 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18938 (match_operand:QI 2 "immediate_operand" "")
18939 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18940 ""
18941 {
18942 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18943 DONE;
18944 else
18945 FAIL;
18946 })
18947
18948 (define_expand "strlendi"
18949 [(set (match_operand:DI 0 "register_operand" "")
18950 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18951 (match_operand:QI 2 "immediate_operand" "")
18952 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18953 ""
18954 {
18955 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18956 DONE;
18957 else
18958 FAIL;
18959 })
18960
18961 (define_expand "strlenqi_1"
18962 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18963 (clobber (match_operand 1 "register_operand" ""))
18964 (clobber (reg:CC FLAGS_REG))])]
18965 ""
18966 "")
18967
18968 (define_insn "*strlenqi_1"
18969 [(set (match_operand:SI 0 "register_operand" "=&c")
18970 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18971 (match_operand:QI 2 "register_operand" "a")
18972 (match_operand:SI 3 "immediate_operand" "i")
18973 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18974 (clobber (match_operand:SI 1 "register_operand" "=D"))
18975 (clobber (reg:CC FLAGS_REG))]
18976 "!TARGET_64BIT"
18977 "repnz{\;| }scasb"
18978 [(set_attr "type" "str")
18979 (set_attr "mode" "QI")
18980 (set_attr "prefix_rep" "1")])
18981
18982 (define_insn "*strlenqi_rex_1"
18983 [(set (match_operand:DI 0 "register_operand" "=&c")
18984 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18985 (match_operand:QI 2 "register_operand" "a")
18986 (match_operand:DI 3 "immediate_operand" "i")
18987 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18988 (clobber (match_operand:DI 1 "register_operand" "=D"))
18989 (clobber (reg:CC FLAGS_REG))]
18990 "TARGET_64BIT"
18991 "repnz{\;| }scasb"
18992 [(set_attr "type" "str")
18993 (set_attr "mode" "QI")
18994 (set_attr "prefix_rep" "1")])
18995
18996 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18997 ;; handled in combine, but it is not currently up to the task.
18998 ;; When used for their truth value, the cmpstrn* expanders generate
18999 ;; code like this:
19000 ;;
19001 ;; repz cmpsb
19002 ;; seta %al
19003 ;; setb %dl
19004 ;; cmpb %al, %dl
19005 ;; jcc label
19006 ;;
19007 ;; The intermediate three instructions are unnecessary.
19008
19009 ;; This one handles cmpstrn*_nz_1...
19010 (define_peephole2
19011 [(parallel[
19012 (set (reg:CC FLAGS_REG)
19013 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19014 (mem:BLK (match_operand 5 "register_operand" ""))))
19015 (use (match_operand 6 "register_operand" ""))
19016 (use (match_operand:SI 3 "immediate_operand" ""))
19017 (clobber (match_operand 0 "register_operand" ""))
19018 (clobber (match_operand 1 "register_operand" ""))
19019 (clobber (match_operand 2 "register_operand" ""))])
19020 (set (match_operand:QI 7 "register_operand" "")
19021 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19022 (set (match_operand:QI 8 "register_operand" "")
19023 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19024 (set (reg FLAGS_REG)
19025 (compare (match_dup 7) (match_dup 8)))
19026 ]
19027 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19028 [(parallel[
19029 (set (reg:CC FLAGS_REG)
19030 (compare:CC (mem:BLK (match_dup 4))
19031 (mem:BLK (match_dup 5))))
19032 (use (match_dup 6))
19033 (use (match_dup 3))
19034 (clobber (match_dup 0))
19035 (clobber (match_dup 1))
19036 (clobber (match_dup 2))])]
19037 "")
19038
19039 ;; ...and this one handles cmpstrn*_1.
19040 (define_peephole2
19041 [(parallel[
19042 (set (reg:CC FLAGS_REG)
19043 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19044 (const_int 0))
19045 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19046 (mem:BLK (match_operand 5 "register_operand" "")))
19047 (const_int 0)))
19048 (use (match_operand:SI 3 "immediate_operand" ""))
19049 (use (reg:CC FLAGS_REG))
19050 (clobber (match_operand 0 "register_operand" ""))
19051 (clobber (match_operand 1 "register_operand" ""))
19052 (clobber (match_operand 2 "register_operand" ""))])
19053 (set (match_operand:QI 7 "register_operand" "")
19054 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19055 (set (match_operand:QI 8 "register_operand" "")
19056 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19057 (set (reg FLAGS_REG)
19058 (compare (match_dup 7) (match_dup 8)))
19059 ]
19060 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19061 [(parallel[
19062 (set (reg:CC FLAGS_REG)
19063 (if_then_else:CC (ne (match_dup 6)
19064 (const_int 0))
19065 (compare:CC (mem:BLK (match_dup 4))
19066 (mem:BLK (match_dup 5)))
19067 (const_int 0)))
19068 (use (match_dup 3))
19069 (use (reg:CC FLAGS_REG))
19070 (clobber (match_dup 0))
19071 (clobber (match_dup 1))
19072 (clobber (match_dup 2))])]
19073 "")
19074
19075
19076 \f
19077 ;; Conditional move instructions.
19078
19079 (define_expand "movdicc"
19080 [(set (match_operand:DI 0 "register_operand" "")
19081 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19082 (match_operand:DI 2 "general_operand" "")
19083 (match_operand:DI 3 "general_operand" "")))]
19084 "TARGET_64BIT"
19085 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19086
19087 (define_insn "x86_movdicc_0_m1_rex64"
19088 [(set (match_operand:DI 0 "register_operand" "=r")
19089 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19090 (const_int -1)
19091 (const_int 0)))
19092 (clobber (reg:CC FLAGS_REG))]
19093 "TARGET_64BIT"
19094 "sbb{q}\t%0, %0"
19095 ; Since we don't have the proper number of operands for an alu insn,
19096 ; fill in all the blanks.
19097 [(set_attr "type" "alu")
19098 (set_attr "pent_pair" "pu")
19099 (set_attr "memory" "none")
19100 (set_attr "imm_disp" "false")
19101 (set_attr "mode" "DI")
19102 (set_attr "length_immediate" "0")])
19103
19104 (define_insn "*movdicc_c_rex64"
19105 [(set (match_operand:DI 0 "register_operand" "=r,r")
19106 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19107 [(reg FLAGS_REG) (const_int 0)])
19108 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19109 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19110 "TARGET_64BIT && TARGET_CMOVE
19111 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19112 "@
19113 cmov%O2%C1\t{%2, %0|%0, %2}
19114 cmov%O2%c1\t{%3, %0|%0, %3}"
19115 [(set_attr "type" "icmov")
19116 (set_attr "mode" "DI")])
19117
19118 (define_expand "movsicc"
19119 [(set (match_operand:SI 0 "register_operand" "")
19120 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19121 (match_operand:SI 2 "general_operand" "")
19122 (match_operand:SI 3 "general_operand" "")))]
19123 ""
19124 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19125
19126 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19127 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19128 ;; So just document what we're doing explicitly.
19129
19130 (define_insn "x86_movsicc_0_m1"
19131 [(set (match_operand:SI 0 "register_operand" "=r")
19132 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19133 (const_int -1)
19134 (const_int 0)))
19135 (clobber (reg:CC FLAGS_REG))]
19136 ""
19137 "sbb{l}\t%0, %0"
19138 ; Since we don't have the proper number of operands for an alu insn,
19139 ; fill in all the blanks.
19140 [(set_attr "type" "alu")
19141 (set_attr "pent_pair" "pu")
19142 (set_attr "memory" "none")
19143 (set_attr "imm_disp" "false")
19144 (set_attr "mode" "SI")
19145 (set_attr "length_immediate" "0")])
19146
19147 (define_insn "*movsicc_noc"
19148 [(set (match_operand:SI 0 "register_operand" "=r,r")
19149 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19150 [(reg FLAGS_REG) (const_int 0)])
19151 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19152 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19153 "TARGET_CMOVE
19154 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19155 "@
19156 cmov%O2%C1\t{%2, %0|%0, %2}
19157 cmov%O2%c1\t{%3, %0|%0, %3}"
19158 [(set_attr "type" "icmov")
19159 (set_attr "mode" "SI")])
19160
19161 (define_expand "movhicc"
19162 [(set (match_operand:HI 0 "register_operand" "")
19163 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19164 (match_operand:HI 2 "general_operand" "")
19165 (match_operand:HI 3 "general_operand" "")))]
19166 "TARGET_HIMODE_MATH"
19167 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19168
19169 (define_insn "*movhicc_noc"
19170 [(set (match_operand:HI 0 "register_operand" "=r,r")
19171 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19172 [(reg FLAGS_REG) (const_int 0)])
19173 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19174 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19175 "TARGET_CMOVE
19176 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19177 "@
19178 cmov%O2%C1\t{%2, %0|%0, %2}
19179 cmov%O2%c1\t{%3, %0|%0, %3}"
19180 [(set_attr "type" "icmov")
19181 (set_attr "mode" "HI")])
19182
19183 (define_expand "movqicc"
19184 [(set (match_operand:QI 0 "register_operand" "")
19185 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19186 (match_operand:QI 2 "general_operand" "")
19187 (match_operand:QI 3 "general_operand" "")))]
19188 "TARGET_QIMODE_MATH"
19189 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19190
19191 (define_insn_and_split "*movqicc_noc"
19192 [(set (match_operand:QI 0 "register_operand" "=r,r")
19193 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19194 [(match_operand 4 "flags_reg_operand" "")
19195 (const_int 0)])
19196 (match_operand:QI 2 "register_operand" "r,0")
19197 (match_operand:QI 3 "register_operand" "0,r")))]
19198 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19199 "#"
19200 "&& reload_completed"
19201 [(set (match_dup 0)
19202 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19203 (match_dup 2)
19204 (match_dup 3)))]
19205 "operands[0] = gen_lowpart (SImode, operands[0]);
19206 operands[2] = gen_lowpart (SImode, operands[2]);
19207 operands[3] = gen_lowpart (SImode, operands[3]);"
19208 [(set_attr "type" "icmov")
19209 (set_attr "mode" "SI")])
19210
19211 (define_expand "movsfcc"
19212 [(set (match_operand:SF 0 "register_operand" "")
19213 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19214 (match_operand:SF 2 "register_operand" "")
19215 (match_operand:SF 3 "register_operand" "")))]
19216 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19217 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19218
19219 (define_insn "*movsfcc_1_387"
19220 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19221 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19222 [(reg FLAGS_REG) (const_int 0)])
19223 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19224 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19225 "TARGET_80387 && TARGET_CMOVE
19226 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19227 "@
19228 fcmov%F1\t{%2, %0|%0, %2}
19229 fcmov%f1\t{%3, %0|%0, %3}
19230 cmov%O2%C1\t{%2, %0|%0, %2}
19231 cmov%O2%c1\t{%3, %0|%0, %3}"
19232 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19233 (set_attr "mode" "SF,SF,SI,SI")])
19234
19235 (define_expand "movdfcc"
19236 [(set (match_operand:DF 0 "register_operand" "")
19237 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19238 (match_operand:DF 2 "register_operand" "")
19239 (match_operand:DF 3 "register_operand" "")))]
19240 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19241 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19242
19243 (define_insn "*movdfcc_1"
19244 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19245 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19246 [(reg FLAGS_REG) (const_int 0)])
19247 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19248 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19249 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19250 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19251 "@
19252 fcmov%F1\t{%2, %0|%0, %2}
19253 fcmov%f1\t{%3, %0|%0, %3}
19254 #
19255 #"
19256 [(set_attr "type" "fcmov,fcmov,multi,multi")
19257 (set_attr "mode" "DF")])
19258
19259 (define_insn "*movdfcc_1_rex64"
19260 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19261 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19262 [(reg FLAGS_REG) (const_int 0)])
19263 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19264 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19265 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19266 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19267 "@
19268 fcmov%F1\t{%2, %0|%0, %2}
19269 fcmov%f1\t{%3, %0|%0, %3}
19270 cmov%O2%C1\t{%2, %0|%0, %2}
19271 cmov%O2%c1\t{%3, %0|%0, %3}"
19272 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19273 (set_attr "mode" "DF")])
19274
19275 (define_split
19276 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19277 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19278 [(match_operand 4 "flags_reg_operand" "")
19279 (const_int 0)])
19280 (match_operand:DF 2 "nonimmediate_operand" "")
19281 (match_operand:DF 3 "nonimmediate_operand" "")))]
19282 "!TARGET_64BIT && reload_completed"
19283 [(set (match_dup 2)
19284 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19285 (match_dup 5)
19286 (match_dup 7)))
19287 (set (match_dup 3)
19288 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19289 (match_dup 6)
19290 (match_dup 8)))]
19291 "split_di (operands+2, 1, operands+5, operands+6);
19292 split_di (operands+3, 1, operands+7, operands+8);
19293 split_di (operands, 1, operands+2, operands+3);")
19294
19295 (define_expand "movxfcc"
19296 [(set (match_operand:XF 0 "register_operand" "")
19297 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19298 (match_operand:XF 2 "register_operand" "")
19299 (match_operand:XF 3 "register_operand" "")))]
19300 "TARGET_80387 && TARGET_CMOVE"
19301 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19302
19303 (define_insn "*movxfcc_1"
19304 [(set (match_operand:XF 0 "register_operand" "=f,f")
19305 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19306 [(reg FLAGS_REG) (const_int 0)])
19307 (match_operand:XF 2 "register_operand" "f,0")
19308 (match_operand:XF 3 "register_operand" "0,f")))]
19309 "TARGET_80387 && TARGET_CMOVE"
19310 "@
19311 fcmov%F1\t{%2, %0|%0, %2}
19312 fcmov%f1\t{%3, %0|%0, %3}"
19313 [(set_attr "type" "fcmov")
19314 (set_attr "mode" "XF")])
19315
19316 ;; These versions of the min/max patterns are intentionally ignorant of
19317 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19318 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19319 ;; are undefined in this condition, we're certain this is correct.
19320
19321 (define_insn "sminsf3"
19322 [(set (match_operand:SF 0 "register_operand" "=x")
19323 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19324 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19325 "TARGET_SSE_MATH"
19326 "minss\t{%2, %0|%0, %2}"
19327 [(set_attr "type" "sseadd")
19328 (set_attr "mode" "SF")])
19329
19330 (define_insn "smaxsf3"
19331 [(set (match_operand:SF 0 "register_operand" "=x")
19332 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19333 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19334 "TARGET_SSE_MATH"
19335 "maxss\t{%2, %0|%0, %2}"
19336 [(set_attr "type" "sseadd")
19337 (set_attr "mode" "SF")])
19338
19339 (define_insn "smindf3"
19340 [(set (match_operand:DF 0 "register_operand" "=x")
19341 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19342 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19343 "TARGET_SSE2 && TARGET_SSE_MATH"
19344 "minsd\t{%2, %0|%0, %2}"
19345 [(set_attr "type" "sseadd")
19346 (set_attr "mode" "DF")])
19347
19348 (define_insn "smaxdf3"
19349 [(set (match_operand:DF 0 "register_operand" "=x")
19350 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19351 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19352 "TARGET_SSE2 && TARGET_SSE_MATH"
19353 "maxsd\t{%2, %0|%0, %2}"
19354 [(set_attr "type" "sseadd")
19355 (set_attr "mode" "DF")])
19356
19357 ;; These versions of the min/max patterns implement exactly the operations
19358 ;; min = (op1 < op2 ? op1 : op2)
19359 ;; max = (!(op1 < op2) ? op1 : op2)
19360 ;; Their operands are not commutative, and thus they may be used in the
19361 ;; presence of -0.0 and NaN.
19362
19363 (define_insn "*ieee_sminsf3"
19364 [(set (match_operand:SF 0 "register_operand" "=x")
19365 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19366 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19367 UNSPEC_IEEE_MIN))]
19368 "TARGET_SSE_MATH"
19369 "minss\t{%2, %0|%0, %2}"
19370 [(set_attr "type" "sseadd")
19371 (set_attr "mode" "SF")])
19372
19373 (define_insn "*ieee_smaxsf3"
19374 [(set (match_operand:SF 0 "register_operand" "=x")
19375 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19376 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19377 UNSPEC_IEEE_MAX))]
19378 "TARGET_SSE_MATH"
19379 "maxss\t{%2, %0|%0, %2}"
19380 [(set_attr "type" "sseadd")
19381 (set_attr "mode" "SF")])
19382
19383 (define_insn "*ieee_smindf3"
19384 [(set (match_operand:DF 0 "register_operand" "=x")
19385 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19386 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19387 UNSPEC_IEEE_MIN))]
19388 "TARGET_SSE2 && TARGET_SSE_MATH"
19389 "minsd\t{%2, %0|%0, %2}"
19390 [(set_attr "type" "sseadd")
19391 (set_attr "mode" "DF")])
19392
19393 (define_insn "*ieee_smaxdf3"
19394 [(set (match_operand:DF 0 "register_operand" "=x")
19395 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19396 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19397 UNSPEC_IEEE_MAX))]
19398 "TARGET_SSE2 && TARGET_SSE_MATH"
19399 "maxsd\t{%2, %0|%0, %2}"
19400 [(set_attr "type" "sseadd")
19401 (set_attr "mode" "DF")])
19402
19403 ;; Make two stack loads independent:
19404 ;; fld aa fld aa
19405 ;; fld %st(0) -> fld bb
19406 ;; fmul bb fmul %st(1), %st
19407 ;;
19408 ;; Actually we only match the last two instructions for simplicity.
19409 (define_peephole2
19410 [(set (match_operand 0 "fp_register_operand" "")
19411 (match_operand 1 "fp_register_operand" ""))
19412 (set (match_dup 0)
19413 (match_operator 2 "binary_fp_operator"
19414 [(match_dup 0)
19415 (match_operand 3 "memory_operand" "")]))]
19416 "REGNO (operands[0]) != REGNO (operands[1])"
19417 [(set (match_dup 0) (match_dup 3))
19418 (set (match_dup 0) (match_dup 4))]
19419
19420 ;; The % modifier is not operational anymore in peephole2's, so we have to
19421 ;; swap the operands manually in the case of addition and multiplication.
19422 "if (COMMUTATIVE_ARITH_P (operands[2]))
19423 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19424 operands[0], operands[1]);
19425 else
19426 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19427 operands[1], operands[0]);")
19428
19429 ;; Conditional addition patterns
19430 (define_expand "addqicc"
19431 [(match_operand:QI 0 "register_operand" "")
19432 (match_operand 1 "comparison_operator" "")
19433 (match_operand:QI 2 "register_operand" "")
19434 (match_operand:QI 3 "const_int_operand" "")]
19435 ""
19436 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19437
19438 (define_expand "addhicc"
19439 [(match_operand:HI 0 "register_operand" "")
19440 (match_operand 1 "comparison_operator" "")
19441 (match_operand:HI 2 "register_operand" "")
19442 (match_operand:HI 3 "const_int_operand" "")]
19443 ""
19444 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19445
19446 (define_expand "addsicc"
19447 [(match_operand:SI 0 "register_operand" "")
19448 (match_operand 1 "comparison_operator" "")
19449 (match_operand:SI 2 "register_operand" "")
19450 (match_operand:SI 3 "const_int_operand" "")]
19451 ""
19452 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19453
19454 (define_expand "adddicc"
19455 [(match_operand:DI 0 "register_operand" "")
19456 (match_operand 1 "comparison_operator" "")
19457 (match_operand:DI 2 "register_operand" "")
19458 (match_operand:DI 3 "const_int_operand" "")]
19459 "TARGET_64BIT"
19460 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19461
19462 \f
19463 ;; Misc patterns (?)
19464
19465 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19466 ;; Otherwise there will be nothing to keep
19467 ;;
19468 ;; [(set (reg ebp) (reg esp))]
19469 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19470 ;; (clobber (eflags)]
19471 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19472 ;;
19473 ;; in proper program order.
19474 (define_insn "pro_epilogue_adjust_stack_1"
19475 [(set (match_operand:SI 0 "register_operand" "=r,r")
19476 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19477 (match_operand:SI 2 "immediate_operand" "i,i")))
19478 (clobber (reg:CC FLAGS_REG))
19479 (clobber (mem:BLK (scratch)))]
19480 "!TARGET_64BIT"
19481 {
19482 switch (get_attr_type (insn))
19483 {
19484 case TYPE_IMOV:
19485 return "mov{l}\t{%1, %0|%0, %1}";
19486
19487 case TYPE_ALU:
19488 if (CONST_INT_P (operands[2])
19489 && (INTVAL (operands[2]) == 128
19490 || (INTVAL (operands[2]) < 0
19491 && INTVAL (operands[2]) != -128)))
19492 {
19493 operands[2] = GEN_INT (-INTVAL (operands[2]));
19494 return "sub{l}\t{%2, %0|%0, %2}";
19495 }
19496 return "add{l}\t{%2, %0|%0, %2}";
19497
19498 case TYPE_LEA:
19499 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19500 return "lea{l}\t{%a2, %0|%0, %a2}";
19501
19502 default:
19503 gcc_unreachable ();
19504 }
19505 }
19506 [(set (attr "type")
19507 (cond [(eq_attr "alternative" "0")
19508 (const_string "alu")
19509 (match_operand:SI 2 "const0_operand" "")
19510 (const_string "imov")
19511 ]
19512 (const_string "lea")))
19513 (set_attr "mode" "SI")])
19514
19515 (define_insn "pro_epilogue_adjust_stack_rex64"
19516 [(set (match_operand:DI 0 "register_operand" "=r,r")
19517 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19518 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19519 (clobber (reg:CC FLAGS_REG))
19520 (clobber (mem:BLK (scratch)))]
19521 "TARGET_64BIT"
19522 {
19523 switch (get_attr_type (insn))
19524 {
19525 case TYPE_IMOV:
19526 return "mov{q}\t{%1, %0|%0, %1}";
19527
19528 case TYPE_ALU:
19529 if (CONST_INT_P (operands[2])
19530 /* Avoid overflows. */
19531 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19532 && (INTVAL (operands[2]) == 128
19533 || (INTVAL (operands[2]) < 0
19534 && INTVAL (operands[2]) != -128)))
19535 {
19536 operands[2] = GEN_INT (-INTVAL (operands[2]));
19537 return "sub{q}\t{%2, %0|%0, %2}";
19538 }
19539 return "add{q}\t{%2, %0|%0, %2}";
19540
19541 case TYPE_LEA:
19542 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19543 return "lea{q}\t{%a2, %0|%0, %a2}";
19544
19545 default:
19546 gcc_unreachable ();
19547 }
19548 }
19549 [(set (attr "type")
19550 (cond [(eq_attr "alternative" "0")
19551 (const_string "alu")
19552 (match_operand:DI 2 "const0_operand" "")
19553 (const_string "imov")
19554 ]
19555 (const_string "lea")))
19556 (set_attr "mode" "DI")])
19557
19558 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19559 [(set (match_operand:DI 0 "register_operand" "=r,r")
19560 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19561 (match_operand:DI 3 "immediate_operand" "i,i")))
19562 (use (match_operand:DI 2 "register_operand" "r,r"))
19563 (clobber (reg:CC FLAGS_REG))
19564 (clobber (mem:BLK (scratch)))]
19565 "TARGET_64BIT"
19566 {
19567 switch (get_attr_type (insn))
19568 {
19569 case TYPE_ALU:
19570 return "add{q}\t{%2, %0|%0, %2}";
19571
19572 case TYPE_LEA:
19573 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19574 return "lea{q}\t{%a2, %0|%0, %a2}";
19575
19576 default:
19577 gcc_unreachable ();
19578 }
19579 }
19580 [(set_attr "type" "alu,lea")
19581 (set_attr "mode" "DI")])
19582
19583 (define_expand "allocate_stack_worker"
19584 [(match_operand:SI 0 "register_operand" "")]
19585 "TARGET_STACK_PROBE"
19586 {
19587 if (reload_completed)
19588 {
19589 if (TARGET_64BIT)
19590 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19591 else
19592 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19593 }
19594 else
19595 {
19596 if (TARGET_64BIT)
19597 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19598 else
19599 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19600 }
19601 DONE;
19602 })
19603
19604 (define_insn "allocate_stack_worker_1"
19605 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19606 UNSPECV_STACK_PROBE)
19607 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19608 (clobber (match_scratch:SI 1 "=0"))
19609 (clobber (reg:CC FLAGS_REG))]
19610 "!TARGET_64BIT && TARGET_STACK_PROBE"
19611 "call\t__alloca"
19612 [(set_attr "type" "multi")
19613 (set_attr "length" "5")])
19614
19615 (define_expand "allocate_stack_worker_postreload"
19616 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19617 UNSPECV_STACK_PROBE)
19618 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19619 (clobber (match_dup 0))
19620 (clobber (reg:CC FLAGS_REG))])]
19621 ""
19622 "")
19623
19624 (define_insn "allocate_stack_worker_rex64"
19625 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19626 UNSPECV_STACK_PROBE)
19627 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19628 (clobber (match_scratch:DI 1 "=0"))
19629 (clobber (reg:CC FLAGS_REG))]
19630 "TARGET_64BIT && TARGET_STACK_PROBE"
19631 "call\t__alloca"
19632 [(set_attr "type" "multi")
19633 (set_attr "length" "5")])
19634
19635 (define_expand "allocate_stack_worker_rex64_postreload"
19636 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19637 UNSPECV_STACK_PROBE)
19638 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19639 (clobber (match_dup 0))
19640 (clobber (reg:CC FLAGS_REG))])]
19641 ""
19642 "")
19643
19644 (define_expand "allocate_stack"
19645 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19646 (minus:SI (reg:SI SP_REG)
19647 (match_operand:SI 1 "general_operand" "")))
19648 (clobber (reg:CC FLAGS_REG))])
19649 (parallel [(set (reg:SI SP_REG)
19650 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19651 (clobber (reg:CC FLAGS_REG))])]
19652 "TARGET_STACK_PROBE"
19653 {
19654 #ifdef CHECK_STACK_LIMIT
19655 if (CONST_INT_P (operands[1])
19656 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19657 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19658 operands[1]));
19659 else
19660 #endif
19661 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19662 operands[1])));
19663
19664 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19665 DONE;
19666 })
19667
19668 (define_expand "builtin_setjmp_receiver"
19669 [(label_ref (match_operand 0 "" ""))]
19670 "!TARGET_64BIT && flag_pic"
19671 {
19672 if (TARGET_MACHO)
19673 {
19674 rtx xops[3];
19675 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19676 rtx label_rtx = gen_label_rtx ();
19677 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19678 xops[0] = xops[1] = picreg;
19679 xops[2] = gen_rtx_CONST (SImode,
19680 gen_rtx_MINUS (SImode,
19681 gen_rtx_LABEL_REF (SImode, label_rtx),
19682 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19683 ix86_expand_binary_operator (MINUS, SImode, xops);
19684 }
19685 else
19686 emit_insn (gen_set_got (pic_offset_table_rtx));
19687 DONE;
19688 })
19689 \f
19690 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19691
19692 (define_split
19693 [(set (match_operand 0 "register_operand" "")
19694 (match_operator 3 "promotable_binary_operator"
19695 [(match_operand 1 "register_operand" "")
19696 (match_operand 2 "aligned_operand" "")]))
19697 (clobber (reg:CC FLAGS_REG))]
19698 "! TARGET_PARTIAL_REG_STALL && reload_completed
19699 && ((GET_MODE (operands[0]) == HImode
19700 && ((!optimize_size && !TARGET_FAST_PREFIX)
19701 /* ??? next two lines just !satisfies_constraint_K (...) */
19702 || !CONST_INT_P (operands[2])
19703 || satisfies_constraint_K (operands[2])))
19704 || (GET_MODE (operands[0]) == QImode
19705 && (TARGET_PROMOTE_QImode || optimize_size)))"
19706 [(parallel [(set (match_dup 0)
19707 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19708 (clobber (reg:CC FLAGS_REG))])]
19709 "operands[0] = gen_lowpart (SImode, operands[0]);
19710 operands[1] = gen_lowpart (SImode, operands[1]);
19711 if (GET_CODE (operands[3]) != ASHIFT)
19712 operands[2] = gen_lowpart (SImode, operands[2]);
19713 PUT_MODE (operands[3], SImode);")
19714
19715 ; Promote the QImode tests, as i386 has encoding of the AND
19716 ; instruction with 32-bit sign-extended immediate and thus the
19717 ; instruction size is unchanged, except in the %eax case for
19718 ; which it is increased by one byte, hence the ! optimize_size.
19719 (define_split
19720 [(set (match_operand 0 "flags_reg_operand" "")
19721 (match_operator 2 "compare_operator"
19722 [(and (match_operand 3 "aligned_operand" "")
19723 (match_operand 4 "const_int_operand" ""))
19724 (const_int 0)]))
19725 (set (match_operand 1 "register_operand" "")
19726 (and (match_dup 3) (match_dup 4)))]
19727 "! TARGET_PARTIAL_REG_STALL && reload_completed
19728 /* Ensure that the operand will remain sign-extended immediate. */
19729 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19730 && ! optimize_size
19731 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19732 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19733 [(parallel [(set (match_dup 0)
19734 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19735 (const_int 0)]))
19736 (set (match_dup 1)
19737 (and:SI (match_dup 3) (match_dup 4)))])]
19738 {
19739 operands[4]
19740 = gen_int_mode (INTVAL (operands[4])
19741 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19742 operands[1] = gen_lowpart (SImode, operands[1]);
19743 operands[3] = gen_lowpart (SImode, operands[3]);
19744 })
19745
19746 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19747 ; the TEST instruction with 32-bit sign-extended immediate and thus
19748 ; the instruction size would at least double, which is not what we
19749 ; want even with ! optimize_size.
19750 (define_split
19751 [(set (match_operand 0 "flags_reg_operand" "")
19752 (match_operator 1 "compare_operator"
19753 [(and (match_operand:HI 2 "aligned_operand" "")
19754 (match_operand:HI 3 "const_int_operand" ""))
19755 (const_int 0)]))]
19756 "! TARGET_PARTIAL_REG_STALL && reload_completed
19757 /* Ensure that the operand will remain sign-extended immediate. */
19758 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19759 && ! TARGET_FAST_PREFIX
19760 && ! optimize_size"
19761 [(set (match_dup 0)
19762 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19763 (const_int 0)]))]
19764 {
19765 operands[3]
19766 = gen_int_mode (INTVAL (operands[3])
19767 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19768 operands[2] = gen_lowpart (SImode, operands[2]);
19769 })
19770
19771 (define_split
19772 [(set (match_operand 0 "register_operand" "")
19773 (neg (match_operand 1 "register_operand" "")))
19774 (clobber (reg:CC FLAGS_REG))]
19775 "! TARGET_PARTIAL_REG_STALL && reload_completed
19776 && (GET_MODE (operands[0]) == HImode
19777 || (GET_MODE (operands[0]) == QImode
19778 && (TARGET_PROMOTE_QImode || optimize_size)))"
19779 [(parallel [(set (match_dup 0)
19780 (neg:SI (match_dup 1)))
19781 (clobber (reg:CC FLAGS_REG))])]
19782 "operands[0] = gen_lowpart (SImode, operands[0]);
19783 operands[1] = gen_lowpart (SImode, operands[1]);")
19784
19785 (define_split
19786 [(set (match_operand 0 "register_operand" "")
19787 (not (match_operand 1 "register_operand" "")))]
19788 "! TARGET_PARTIAL_REG_STALL && reload_completed
19789 && (GET_MODE (operands[0]) == HImode
19790 || (GET_MODE (operands[0]) == QImode
19791 && (TARGET_PROMOTE_QImode || optimize_size)))"
19792 [(set (match_dup 0)
19793 (not:SI (match_dup 1)))]
19794 "operands[0] = gen_lowpart (SImode, operands[0]);
19795 operands[1] = gen_lowpart (SImode, operands[1]);")
19796
19797 (define_split
19798 [(set (match_operand 0 "register_operand" "")
19799 (if_then_else (match_operator 1 "comparison_operator"
19800 [(reg FLAGS_REG) (const_int 0)])
19801 (match_operand 2 "register_operand" "")
19802 (match_operand 3 "register_operand" "")))]
19803 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19804 && (GET_MODE (operands[0]) == HImode
19805 || (GET_MODE (operands[0]) == QImode
19806 && (TARGET_PROMOTE_QImode || optimize_size)))"
19807 [(set (match_dup 0)
19808 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19809 "operands[0] = gen_lowpart (SImode, operands[0]);
19810 operands[2] = gen_lowpart (SImode, operands[2]);
19811 operands[3] = gen_lowpart (SImode, operands[3]);")
19812
19813 \f
19814 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19815 ;; transform a complex memory operation into two memory to register operations.
19816
19817 ;; Don't push memory operands
19818 (define_peephole2
19819 [(set (match_operand:SI 0 "push_operand" "")
19820 (match_operand:SI 1 "memory_operand" ""))
19821 (match_scratch:SI 2 "r")]
19822 "!optimize_size && !TARGET_PUSH_MEMORY
19823 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19824 [(set (match_dup 2) (match_dup 1))
19825 (set (match_dup 0) (match_dup 2))]
19826 "")
19827
19828 (define_peephole2
19829 [(set (match_operand:DI 0 "push_operand" "")
19830 (match_operand:DI 1 "memory_operand" ""))
19831 (match_scratch:DI 2 "r")]
19832 "!optimize_size && !TARGET_PUSH_MEMORY
19833 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19834 [(set (match_dup 2) (match_dup 1))
19835 (set (match_dup 0) (match_dup 2))]
19836 "")
19837
19838 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19839 ;; SImode pushes.
19840 (define_peephole2
19841 [(set (match_operand:SF 0 "push_operand" "")
19842 (match_operand:SF 1 "memory_operand" ""))
19843 (match_scratch:SF 2 "r")]
19844 "!optimize_size && !TARGET_PUSH_MEMORY
19845 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19846 [(set (match_dup 2) (match_dup 1))
19847 (set (match_dup 0) (match_dup 2))]
19848 "")
19849
19850 (define_peephole2
19851 [(set (match_operand:HI 0 "push_operand" "")
19852 (match_operand:HI 1 "memory_operand" ""))
19853 (match_scratch:HI 2 "r")]
19854 "!optimize_size && !TARGET_PUSH_MEMORY
19855 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19856 [(set (match_dup 2) (match_dup 1))
19857 (set (match_dup 0) (match_dup 2))]
19858 "")
19859
19860 (define_peephole2
19861 [(set (match_operand:QI 0 "push_operand" "")
19862 (match_operand:QI 1 "memory_operand" ""))
19863 (match_scratch:QI 2 "q")]
19864 "!optimize_size && !TARGET_PUSH_MEMORY
19865 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19866 [(set (match_dup 2) (match_dup 1))
19867 (set (match_dup 0) (match_dup 2))]
19868 "")
19869
19870 ;; Don't move an immediate directly to memory when the instruction
19871 ;; gets too big.
19872 (define_peephole2
19873 [(match_scratch:SI 1 "r")
19874 (set (match_operand:SI 0 "memory_operand" "")
19875 (const_int 0))]
19876 "! optimize_size
19877 && ! TARGET_USE_MOV0
19878 && TARGET_SPLIT_LONG_MOVES
19879 && get_attr_length (insn) >= ix86_cost->large_insn
19880 && peep2_regno_dead_p (0, FLAGS_REG)"
19881 [(parallel [(set (match_dup 1) (const_int 0))
19882 (clobber (reg:CC FLAGS_REG))])
19883 (set (match_dup 0) (match_dup 1))]
19884 "")
19885
19886 (define_peephole2
19887 [(match_scratch:HI 1 "r")
19888 (set (match_operand:HI 0 "memory_operand" "")
19889 (const_int 0))]
19890 "! optimize_size
19891 && ! TARGET_USE_MOV0
19892 && TARGET_SPLIT_LONG_MOVES
19893 && get_attr_length (insn) >= ix86_cost->large_insn
19894 && peep2_regno_dead_p (0, FLAGS_REG)"
19895 [(parallel [(set (match_dup 2) (const_int 0))
19896 (clobber (reg:CC FLAGS_REG))])
19897 (set (match_dup 0) (match_dup 1))]
19898 "operands[2] = gen_lowpart (SImode, operands[1]);")
19899
19900 (define_peephole2
19901 [(match_scratch:QI 1 "q")
19902 (set (match_operand:QI 0 "memory_operand" "")
19903 (const_int 0))]
19904 "! optimize_size
19905 && ! TARGET_USE_MOV0
19906 && TARGET_SPLIT_LONG_MOVES
19907 && get_attr_length (insn) >= ix86_cost->large_insn
19908 && peep2_regno_dead_p (0, FLAGS_REG)"
19909 [(parallel [(set (match_dup 2) (const_int 0))
19910 (clobber (reg:CC FLAGS_REG))])
19911 (set (match_dup 0) (match_dup 1))]
19912 "operands[2] = gen_lowpart (SImode, operands[1]);")
19913
19914 (define_peephole2
19915 [(match_scratch:SI 2 "r")
19916 (set (match_operand:SI 0 "memory_operand" "")
19917 (match_operand:SI 1 "immediate_operand" ""))]
19918 "! optimize_size
19919 && get_attr_length (insn) >= ix86_cost->large_insn
19920 && TARGET_SPLIT_LONG_MOVES"
19921 [(set (match_dup 2) (match_dup 1))
19922 (set (match_dup 0) (match_dup 2))]
19923 "")
19924
19925 (define_peephole2
19926 [(match_scratch:HI 2 "r")
19927 (set (match_operand:HI 0 "memory_operand" "")
19928 (match_operand:HI 1 "immediate_operand" ""))]
19929 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19930 && TARGET_SPLIT_LONG_MOVES"
19931 [(set (match_dup 2) (match_dup 1))
19932 (set (match_dup 0) (match_dup 2))]
19933 "")
19934
19935 (define_peephole2
19936 [(match_scratch:QI 2 "q")
19937 (set (match_operand:QI 0 "memory_operand" "")
19938 (match_operand:QI 1 "immediate_operand" ""))]
19939 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19940 && TARGET_SPLIT_LONG_MOVES"
19941 [(set (match_dup 2) (match_dup 1))
19942 (set (match_dup 0) (match_dup 2))]
19943 "")
19944
19945 ;; Don't compare memory with zero, load and use a test instead.
19946 (define_peephole2
19947 [(set (match_operand 0 "flags_reg_operand" "")
19948 (match_operator 1 "compare_operator"
19949 [(match_operand:SI 2 "memory_operand" "")
19950 (const_int 0)]))
19951 (match_scratch:SI 3 "r")]
19952 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19953 [(set (match_dup 3) (match_dup 2))
19954 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19955 "")
19956
19957 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19958 ;; Don't split NOTs with a displacement operand, because resulting XOR
19959 ;; will not be pairable anyway.
19960 ;;
19961 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19962 ;; represented using a modRM byte. The XOR replacement is long decoded,
19963 ;; so this split helps here as well.
19964 ;;
19965 ;; Note: Can't do this as a regular split because we can't get proper
19966 ;; lifetime information then.
19967
19968 (define_peephole2
19969 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19970 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19971 "!optimize_size
19972 && peep2_regno_dead_p (0, FLAGS_REG)
19973 && ((TARGET_PENTIUM
19974 && (!MEM_P (operands[0])
19975 || !memory_displacement_operand (operands[0], SImode)))
19976 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19977 [(parallel [(set (match_dup 0)
19978 (xor:SI (match_dup 1) (const_int -1)))
19979 (clobber (reg:CC FLAGS_REG))])]
19980 "")
19981
19982 (define_peephole2
19983 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19984 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19985 "!optimize_size
19986 && peep2_regno_dead_p (0, FLAGS_REG)
19987 && ((TARGET_PENTIUM
19988 && (!MEM_P (operands[0])
19989 || !memory_displacement_operand (operands[0], HImode)))
19990 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19991 [(parallel [(set (match_dup 0)
19992 (xor:HI (match_dup 1) (const_int -1)))
19993 (clobber (reg:CC FLAGS_REG))])]
19994 "")
19995
19996 (define_peephole2
19997 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19998 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19999 "!optimize_size
20000 && peep2_regno_dead_p (0, FLAGS_REG)
20001 && ((TARGET_PENTIUM
20002 && (!MEM_P (operands[0])
20003 || !memory_displacement_operand (operands[0], QImode)))
20004 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20005 [(parallel [(set (match_dup 0)
20006 (xor:QI (match_dup 1) (const_int -1)))
20007 (clobber (reg:CC FLAGS_REG))])]
20008 "")
20009
20010 ;; Non pairable "test imm, reg" instructions can be translated to
20011 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20012 ;; byte opcode instead of two, have a short form for byte operands),
20013 ;; so do it for other CPUs as well. Given that the value was dead,
20014 ;; this should not create any new dependencies. Pass on the sub-word
20015 ;; versions if we're concerned about partial register stalls.
20016
20017 (define_peephole2
20018 [(set (match_operand 0 "flags_reg_operand" "")
20019 (match_operator 1 "compare_operator"
20020 [(and:SI (match_operand:SI 2 "register_operand" "")
20021 (match_operand:SI 3 "immediate_operand" ""))
20022 (const_int 0)]))]
20023 "ix86_match_ccmode (insn, CCNOmode)
20024 && (true_regnum (operands[2]) != 0
20025 || satisfies_constraint_K (operands[3]))
20026 && peep2_reg_dead_p (1, operands[2])"
20027 [(parallel
20028 [(set (match_dup 0)
20029 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20030 (const_int 0)]))
20031 (set (match_dup 2)
20032 (and:SI (match_dup 2) (match_dup 3)))])]
20033 "")
20034
20035 ;; We don't need to handle HImode case, because it will be promoted to SImode
20036 ;; on ! TARGET_PARTIAL_REG_STALL
20037
20038 (define_peephole2
20039 [(set (match_operand 0 "flags_reg_operand" "")
20040 (match_operator 1 "compare_operator"
20041 [(and:QI (match_operand:QI 2 "register_operand" "")
20042 (match_operand:QI 3 "immediate_operand" ""))
20043 (const_int 0)]))]
20044 "! TARGET_PARTIAL_REG_STALL
20045 && ix86_match_ccmode (insn, CCNOmode)
20046 && true_regnum (operands[2]) != 0
20047 && peep2_reg_dead_p (1, operands[2])"
20048 [(parallel
20049 [(set (match_dup 0)
20050 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20051 (const_int 0)]))
20052 (set (match_dup 2)
20053 (and:QI (match_dup 2) (match_dup 3)))])]
20054 "")
20055
20056 (define_peephole2
20057 [(set (match_operand 0 "flags_reg_operand" "")
20058 (match_operator 1 "compare_operator"
20059 [(and:SI
20060 (zero_extract:SI
20061 (match_operand 2 "ext_register_operand" "")
20062 (const_int 8)
20063 (const_int 8))
20064 (match_operand 3 "const_int_operand" ""))
20065 (const_int 0)]))]
20066 "! TARGET_PARTIAL_REG_STALL
20067 && ix86_match_ccmode (insn, CCNOmode)
20068 && true_regnum (operands[2]) != 0
20069 && peep2_reg_dead_p (1, operands[2])"
20070 [(parallel [(set (match_dup 0)
20071 (match_op_dup 1
20072 [(and:SI
20073 (zero_extract:SI
20074 (match_dup 2)
20075 (const_int 8)
20076 (const_int 8))
20077 (match_dup 3))
20078 (const_int 0)]))
20079 (set (zero_extract:SI (match_dup 2)
20080 (const_int 8)
20081 (const_int 8))
20082 (and:SI
20083 (zero_extract:SI
20084 (match_dup 2)
20085 (const_int 8)
20086 (const_int 8))
20087 (match_dup 3)))])]
20088 "")
20089
20090 ;; Don't do logical operations with memory inputs.
20091 (define_peephole2
20092 [(match_scratch:SI 2 "r")
20093 (parallel [(set (match_operand:SI 0 "register_operand" "")
20094 (match_operator:SI 3 "arith_or_logical_operator"
20095 [(match_dup 0)
20096 (match_operand:SI 1 "memory_operand" "")]))
20097 (clobber (reg:CC FLAGS_REG))])]
20098 "! optimize_size && ! TARGET_READ_MODIFY"
20099 [(set (match_dup 2) (match_dup 1))
20100 (parallel [(set (match_dup 0)
20101 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20102 (clobber (reg:CC FLAGS_REG))])]
20103 "")
20104
20105 (define_peephole2
20106 [(match_scratch:SI 2 "r")
20107 (parallel [(set (match_operand:SI 0 "register_operand" "")
20108 (match_operator:SI 3 "arith_or_logical_operator"
20109 [(match_operand:SI 1 "memory_operand" "")
20110 (match_dup 0)]))
20111 (clobber (reg:CC FLAGS_REG))])]
20112 "! optimize_size && ! TARGET_READ_MODIFY"
20113 [(set (match_dup 2) (match_dup 1))
20114 (parallel [(set (match_dup 0)
20115 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20116 (clobber (reg:CC FLAGS_REG))])]
20117 "")
20118
20119 ; Don't do logical operations with memory outputs
20120 ;
20121 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20122 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20123 ; the same decoder scheduling characteristics as the original.
20124
20125 (define_peephole2
20126 [(match_scratch:SI 2 "r")
20127 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20128 (match_operator:SI 3 "arith_or_logical_operator"
20129 [(match_dup 0)
20130 (match_operand:SI 1 "nonmemory_operand" "")]))
20131 (clobber (reg:CC FLAGS_REG))])]
20132 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20133 [(set (match_dup 2) (match_dup 0))
20134 (parallel [(set (match_dup 2)
20135 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20136 (clobber (reg:CC FLAGS_REG))])
20137 (set (match_dup 0) (match_dup 2))]
20138 "")
20139
20140 (define_peephole2
20141 [(match_scratch:SI 2 "r")
20142 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20143 (match_operator:SI 3 "arith_or_logical_operator"
20144 [(match_operand:SI 1 "nonmemory_operand" "")
20145 (match_dup 0)]))
20146 (clobber (reg:CC FLAGS_REG))])]
20147 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20148 [(set (match_dup 2) (match_dup 0))
20149 (parallel [(set (match_dup 2)
20150 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20151 (clobber (reg:CC FLAGS_REG))])
20152 (set (match_dup 0) (match_dup 2))]
20153 "")
20154
20155 ;; Attempt to always use XOR for zeroing registers.
20156 (define_peephole2
20157 [(set (match_operand 0 "register_operand" "")
20158 (match_operand 1 "const0_operand" ""))]
20159 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20160 && (! TARGET_USE_MOV0 || optimize_size)
20161 && GENERAL_REG_P (operands[0])
20162 && peep2_regno_dead_p (0, FLAGS_REG)"
20163 [(parallel [(set (match_dup 0) (const_int 0))
20164 (clobber (reg:CC FLAGS_REG))])]
20165 {
20166 operands[0] = gen_lowpart (word_mode, operands[0]);
20167 })
20168
20169 (define_peephole2
20170 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20171 (const_int 0))]
20172 "(GET_MODE (operands[0]) == QImode
20173 || GET_MODE (operands[0]) == HImode)
20174 && (! TARGET_USE_MOV0 || optimize_size)
20175 && peep2_regno_dead_p (0, FLAGS_REG)"
20176 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20177 (clobber (reg:CC FLAGS_REG))])])
20178
20179 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20180 (define_peephole2
20181 [(set (match_operand 0 "register_operand" "")
20182 (const_int -1))]
20183 "(GET_MODE (operands[0]) == HImode
20184 || GET_MODE (operands[0]) == SImode
20185 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20186 && (optimize_size || TARGET_PENTIUM)
20187 && peep2_regno_dead_p (0, FLAGS_REG)"
20188 [(parallel [(set (match_dup 0) (const_int -1))
20189 (clobber (reg:CC FLAGS_REG))])]
20190 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20191 operands[0]);")
20192
20193 ;; Attempt to convert simple leas to adds. These can be created by
20194 ;; move expanders.
20195 (define_peephole2
20196 [(set (match_operand:SI 0 "register_operand" "")
20197 (plus:SI (match_dup 0)
20198 (match_operand:SI 1 "nonmemory_operand" "")))]
20199 "peep2_regno_dead_p (0, FLAGS_REG)"
20200 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20201 (clobber (reg:CC FLAGS_REG))])]
20202 "")
20203
20204 (define_peephole2
20205 [(set (match_operand:SI 0 "register_operand" "")
20206 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20207 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20208 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20209 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20210 (clobber (reg:CC FLAGS_REG))])]
20211 "operands[2] = gen_lowpart (SImode, operands[2]);")
20212
20213 (define_peephole2
20214 [(set (match_operand:DI 0 "register_operand" "")
20215 (plus:DI (match_dup 0)
20216 (match_operand:DI 1 "x86_64_general_operand" "")))]
20217 "peep2_regno_dead_p (0, FLAGS_REG)"
20218 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20219 (clobber (reg:CC FLAGS_REG))])]
20220 "")
20221
20222 (define_peephole2
20223 [(set (match_operand:SI 0 "register_operand" "")
20224 (mult:SI (match_dup 0)
20225 (match_operand:SI 1 "const_int_operand" "")))]
20226 "exact_log2 (INTVAL (operands[1])) >= 0
20227 && peep2_regno_dead_p (0, FLAGS_REG)"
20228 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20229 (clobber (reg:CC FLAGS_REG))])]
20230 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20231
20232 (define_peephole2
20233 [(set (match_operand:DI 0 "register_operand" "")
20234 (mult:DI (match_dup 0)
20235 (match_operand:DI 1 "const_int_operand" "")))]
20236 "exact_log2 (INTVAL (operands[1])) >= 0
20237 && peep2_regno_dead_p (0, FLAGS_REG)"
20238 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20239 (clobber (reg:CC FLAGS_REG))])]
20240 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20241
20242 (define_peephole2
20243 [(set (match_operand:SI 0 "register_operand" "")
20244 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20245 (match_operand:DI 2 "const_int_operand" "")) 0))]
20246 "exact_log2 (INTVAL (operands[2])) >= 0
20247 && REGNO (operands[0]) == REGNO (operands[1])
20248 && peep2_regno_dead_p (0, FLAGS_REG)"
20249 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20250 (clobber (reg:CC FLAGS_REG))])]
20251 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20252
20253 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20254 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20255 ;; many CPUs it is also faster, since special hardware to avoid esp
20256 ;; dependencies is present.
20257
20258 ;; While some of these conversions may be done using splitters, we use peepholes
20259 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20260
20261 ;; Convert prologue esp subtractions to push.
20262 ;; We need register to push. In order to keep verify_flow_info happy we have
20263 ;; two choices
20264 ;; - use scratch and clobber it in order to avoid dependencies
20265 ;; - use already live register
20266 ;; We can't use the second way right now, since there is no reliable way how to
20267 ;; verify that given register is live. First choice will also most likely in
20268 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20269 ;; call clobbered registers are dead. We may want to use base pointer as an
20270 ;; alternative when no register is available later.
20271
20272 (define_peephole2
20273 [(match_scratch:SI 0 "r")
20274 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20275 (clobber (reg:CC FLAGS_REG))
20276 (clobber (mem:BLK (scratch)))])]
20277 "optimize_size || !TARGET_SUB_ESP_4"
20278 [(clobber (match_dup 0))
20279 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20280 (clobber (mem:BLK (scratch)))])])
20281
20282 (define_peephole2
20283 [(match_scratch:SI 0 "r")
20284 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20285 (clobber (reg:CC FLAGS_REG))
20286 (clobber (mem:BLK (scratch)))])]
20287 "optimize_size || !TARGET_SUB_ESP_8"
20288 [(clobber (match_dup 0))
20289 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20290 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20291 (clobber (mem:BLK (scratch)))])])
20292
20293 ;; Convert esp subtractions to push.
20294 (define_peephole2
20295 [(match_scratch:SI 0 "r")
20296 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20297 (clobber (reg:CC FLAGS_REG))])]
20298 "optimize_size || !TARGET_SUB_ESP_4"
20299 [(clobber (match_dup 0))
20300 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20301
20302 (define_peephole2
20303 [(match_scratch:SI 0 "r")
20304 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20305 (clobber (reg:CC FLAGS_REG))])]
20306 "optimize_size || !TARGET_SUB_ESP_8"
20307 [(clobber (match_dup 0))
20308 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20309 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20310
20311 ;; Convert epilogue deallocator to pop.
20312 (define_peephole2
20313 [(match_scratch:SI 0 "r")
20314 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20315 (clobber (reg:CC FLAGS_REG))
20316 (clobber (mem:BLK (scratch)))])]
20317 "optimize_size || !TARGET_ADD_ESP_4"
20318 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20319 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20320 (clobber (mem:BLK (scratch)))])]
20321 "")
20322
20323 ;; Two pops case is tricky, since pop causes dependency on destination register.
20324 ;; We use two registers if available.
20325 (define_peephole2
20326 [(match_scratch:SI 0 "r")
20327 (match_scratch:SI 1 "r")
20328 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20329 (clobber (reg:CC FLAGS_REG))
20330 (clobber (mem:BLK (scratch)))])]
20331 "optimize_size || !TARGET_ADD_ESP_8"
20332 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20333 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20334 (clobber (mem:BLK (scratch)))])
20335 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20336 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20337 "")
20338
20339 (define_peephole2
20340 [(match_scratch:SI 0 "r")
20341 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20342 (clobber (reg:CC FLAGS_REG))
20343 (clobber (mem:BLK (scratch)))])]
20344 "optimize_size"
20345 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20346 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20347 (clobber (mem:BLK (scratch)))])
20348 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20349 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20350 "")
20351
20352 ;; Convert esp additions to pop.
20353 (define_peephole2
20354 [(match_scratch:SI 0 "r")
20355 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20356 (clobber (reg:CC FLAGS_REG))])]
20357 ""
20358 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20359 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20360 "")
20361
20362 ;; Two pops case is tricky, since pop causes dependency on destination register.
20363 ;; We use two registers if available.
20364 (define_peephole2
20365 [(match_scratch:SI 0 "r")
20366 (match_scratch:SI 1 "r")
20367 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20368 (clobber (reg:CC FLAGS_REG))])]
20369 ""
20370 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20371 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20372 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20373 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20374 "")
20375
20376 (define_peephole2
20377 [(match_scratch:SI 0 "r")
20378 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20379 (clobber (reg:CC FLAGS_REG))])]
20380 "optimize_size"
20381 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20382 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20383 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20384 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20385 "")
20386 \f
20387 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20388 ;; required and register dies. Similarly for 128 to plus -128.
20389 (define_peephole2
20390 [(set (match_operand 0 "flags_reg_operand" "")
20391 (match_operator 1 "compare_operator"
20392 [(match_operand 2 "register_operand" "")
20393 (match_operand 3 "const_int_operand" "")]))]
20394 "(INTVAL (operands[3]) == -1
20395 || INTVAL (operands[3]) == 1
20396 || INTVAL (operands[3]) == 128)
20397 && ix86_match_ccmode (insn, CCGCmode)
20398 && peep2_reg_dead_p (1, operands[2])"
20399 [(parallel [(set (match_dup 0)
20400 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20401 (clobber (match_dup 2))])]
20402 "")
20403 \f
20404 (define_peephole2
20405 [(match_scratch:DI 0 "r")
20406 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20407 (clobber (reg:CC FLAGS_REG))
20408 (clobber (mem:BLK (scratch)))])]
20409 "optimize_size || !TARGET_SUB_ESP_4"
20410 [(clobber (match_dup 0))
20411 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20412 (clobber (mem:BLK (scratch)))])])
20413
20414 (define_peephole2
20415 [(match_scratch:DI 0 "r")
20416 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20417 (clobber (reg:CC FLAGS_REG))
20418 (clobber (mem:BLK (scratch)))])]
20419 "optimize_size || !TARGET_SUB_ESP_8"
20420 [(clobber (match_dup 0))
20421 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20422 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20423 (clobber (mem:BLK (scratch)))])])
20424
20425 ;; Convert esp subtractions to push.
20426 (define_peephole2
20427 [(match_scratch:DI 0 "r")
20428 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20429 (clobber (reg:CC FLAGS_REG))])]
20430 "optimize_size || !TARGET_SUB_ESP_4"
20431 [(clobber (match_dup 0))
20432 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20433
20434 (define_peephole2
20435 [(match_scratch:DI 0 "r")
20436 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20437 (clobber (reg:CC FLAGS_REG))])]
20438 "optimize_size || !TARGET_SUB_ESP_8"
20439 [(clobber (match_dup 0))
20440 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20441 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20442
20443 ;; Convert epilogue deallocator to pop.
20444 (define_peephole2
20445 [(match_scratch:DI 0 "r")
20446 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20447 (clobber (reg:CC FLAGS_REG))
20448 (clobber (mem:BLK (scratch)))])]
20449 "optimize_size || !TARGET_ADD_ESP_4"
20450 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20451 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20452 (clobber (mem:BLK (scratch)))])]
20453 "")
20454
20455 ;; Two pops case is tricky, since pop causes dependency on destination register.
20456 ;; We use two registers if available.
20457 (define_peephole2
20458 [(match_scratch:DI 0 "r")
20459 (match_scratch:DI 1 "r")
20460 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20461 (clobber (reg:CC FLAGS_REG))
20462 (clobber (mem:BLK (scratch)))])]
20463 "optimize_size || !TARGET_ADD_ESP_8"
20464 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20465 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20466 (clobber (mem:BLK (scratch)))])
20467 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20468 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20469 "")
20470
20471 (define_peephole2
20472 [(match_scratch:DI 0 "r")
20473 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20474 (clobber (reg:CC FLAGS_REG))
20475 (clobber (mem:BLK (scratch)))])]
20476 "optimize_size"
20477 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20478 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20479 (clobber (mem:BLK (scratch)))])
20480 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20481 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20482 "")
20483
20484 ;; Convert esp additions to pop.
20485 (define_peephole2
20486 [(match_scratch:DI 0 "r")
20487 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20488 (clobber (reg:CC FLAGS_REG))])]
20489 ""
20490 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20491 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20492 "")
20493
20494 ;; Two pops case is tricky, since pop causes dependency on destination register.
20495 ;; We use two registers if available.
20496 (define_peephole2
20497 [(match_scratch:DI 0 "r")
20498 (match_scratch:DI 1 "r")
20499 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20500 (clobber (reg:CC FLAGS_REG))])]
20501 ""
20502 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20503 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20504 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20505 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20506 "")
20507
20508 (define_peephole2
20509 [(match_scratch:DI 0 "r")
20510 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20511 (clobber (reg:CC FLAGS_REG))])]
20512 "optimize_size"
20513 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20514 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20515 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20516 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20517 "")
20518 \f
20519 ;; Convert imul by three, five and nine into lea
20520 (define_peephole2
20521 [(parallel
20522 [(set (match_operand:SI 0 "register_operand" "")
20523 (mult:SI (match_operand:SI 1 "register_operand" "")
20524 (match_operand:SI 2 "const_int_operand" "")))
20525 (clobber (reg:CC FLAGS_REG))])]
20526 "INTVAL (operands[2]) == 3
20527 || INTVAL (operands[2]) == 5
20528 || INTVAL (operands[2]) == 9"
20529 [(set (match_dup 0)
20530 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20531 (match_dup 1)))]
20532 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20533
20534 (define_peephole2
20535 [(parallel
20536 [(set (match_operand:SI 0 "register_operand" "")
20537 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20538 (match_operand:SI 2 "const_int_operand" "")))
20539 (clobber (reg:CC FLAGS_REG))])]
20540 "!optimize_size
20541 && (INTVAL (operands[2]) == 3
20542 || INTVAL (operands[2]) == 5
20543 || INTVAL (operands[2]) == 9)"
20544 [(set (match_dup 0) (match_dup 1))
20545 (set (match_dup 0)
20546 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20547 (match_dup 0)))]
20548 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20549
20550 (define_peephole2
20551 [(parallel
20552 [(set (match_operand:DI 0 "register_operand" "")
20553 (mult:DI (match_operand:DI 1 "register_operand" "")
20554 (match_operand:DI 2 "const_int_operand" "")))
20555 (clobber (reg:CC FLAGS_REG))])]
20556 "TARGET_64BIT
20557 && (INTVAL (operands[2]) == 3
20558 || INTVAL (operands[2]) == 5
20559 || INTVAL (operands[2]) == 9)"
20560 [(set (match_dup 0)
20561 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20562 (match_dup 1)))]
20563 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20564
20565 (define_peephole2
20566 [(parallel
20567 [(set (match_operand:DI 0 "register_operand" "")
20568 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20569 (match_operand:DI 2 "const_int_operand" "")))
20570 (clobber (reg:CC FLAGS_REG))])]
20571 "TARGET_64BIT
20572 && !optimize_size
20573 && (INTVAL (operands[2]) == 3
20574 || INTVAL (operands[2]) == 5
20575 || INTVAL (operands[2]) == 9)"
20576 [(set (match_dup 0) (match_dup 1))
20577 (set (match_dup 0)
20578 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20579 (match_dup 0)))]
20580 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20581
20582 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20583 ;; imul $32bit_imm, reg, reg is direct decoded.
20584 (define_peephole2
20585 [(match_scratch:DI 3 "r")
20586 (parallel [(set (match_operand:DI 0 "register_operand" "")
20587 (mult:DI (match_operand:DI 1 "memory_operand" "")
20588 (match_operand:DI 2 "immediate_operand" "")))
20589 (clobber (reg:CC FLAGS_REG))])]
20590 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20591 && !satisfies_constraint_K (operands[2])"
20592 [(set (match_dup 3) (match_dup 1))
20593 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20594 (clobber (reg:CC FLAGS_REG))])]
20595 "")
20596
20597 (define_peephole2
20598 [(match_scratch:SI 3 "r")
20599 (parallel [(set (match_operand:SI 0 "register_operand" "")
20600 (mult:SI (match_operand:SI 1 "memory_operand" "")
20601 (match_operand:SI 2 "immediate_operand" "")))
20602 (clobber (reg:CC FLAGS_REG))])]
20603 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20604 && !satisfies_constraint_K (operands[2])"
20605 [(set (match_dup 3) (match_dup 1))
20606 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20607 (clobber (reg:CC FLAGS_REG))])]
20608 "")
20609
20610 (define_peephole2
20611 [(match_scratch:SI 3 "r")
20612 (parallel [(set (match_operand:DI 0 "register_operand" "")
20613 (zero_extend:DI
20614 (mult:SI (match_operand:SI 1 "memory_operand" "")
20615 (match_operand:SI 2 "immediate_operand" ""))))
20616 (clobber (reg:CC FLAGS_REG))])]
20617 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20618 && !satisfies_constraint_K (operands[2])"
20619 [(set (match_dup 3) (match_dup 1))
20620 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20621 (clobber (reg:CC FLAGS_REG))])]
20622 "")
20623
20624 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20625 ;; Convert it into imul reg, reg
20626 ;; It would be better to force assembler to encode instruction using long
20627 ;; immediate, but there is apparently no way to do so.
20628 (define_peephole2
20629 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20630 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20631 (match_operand:DI 2 "const_int_operand" "")))
20632 (clobber (reg:CC FLAGS_REG))])
20633 (match_scratch:DI 3 "r")]
20634 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20635 && satisfies_constraint_K (operands[2])"
20636 [(set (match_dup 3) (match_dup 2))
20637 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20638 (clobber (reg:CC FLAGS_REG))])]
20639 {
20640 if (!rtx_equal_p (operands[0], operands[1]))
20641 emit_move_insn (operands[0], operands[1]);
20642 })
20643
20644 (define_peephole2
20645 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20646 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20647 (match_operand:SI 2 "const_int_operand" "")))
20648 (clobber (reg:CC FLAGS_REG))])
20649 (match_scratch:SI 3 "r")]
20650 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20651 && satisfies_constraint_K (operands[2])"
20652 [(set (match_dup 3) (match_dup 2))
20653 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20654 (clobber (reg:CC FLAGS_REG))])]
20655 {
20656 if (!rtx_equal_p (operands[0], operands[1]))
20657 emit_move_insn (operands[0], operands[1]);
20658 })
20659
20660 (define_peephole2
20661 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20662 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20663 (match_operand:HI 2 "immediate_operand" "")))
20664 (clobber (reg:CC FLAGS_REG))])
20665 (match_scratch:HI 3 "r")]
20666 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20667 [(set (match_dup 3) (match_dup 2))
20668 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20669 (clobber (reg:CC FLAGS_REG))])]
20670 {
20671 if (!rtx_equal_p (operands[0], operands[1]))
20672 emit_move_insn (operands[0], operands[1]);
20673 })
20674
20675 ;; After splitting up read-modify operations, array accesses with memory
20676 ;; operands might end up in form:
20677 ;; sall $2, %eax
20678 ;; movl 4(%esp), %edx
20679 ;; addl %edx, %eax
20680 ;; instead of pre-splitting:
20681 ;; sall $2, %eax
20682 ;; addl 4(%esp), %eax
20683 ;; Turn it into:
20684 ;; movl 4(%esp), %edx
20685 ;; leal (%edx,%eax,4), %eax
20686
20687 (define_peephole2
20688 [(parallel [(set (match_operand 0 "register_operand" "")
20689 (ashift (match_operand 1 "register_operand" "")
20690 (match_operand 2 "const_int_operand" "")))
20691 (clobber (reg:CC FLAGS_REG))])
20692 (set (match_operand 3 "register_operand")
20693 (match_operand 4 "x86_64_general_operand" ""))
20694 (parallel [(set (match_operand 5 "register_operand" "")
20695 (plus (match_operand 6 "register_operand" "")
20696 (match_operand 7 "register_operand" "")))
20697 (clobber (reg:CC FLAGS_REG))])]
20698 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20699 /* Validate MODE for lea. */
20700 && ((!TARGET_PARTIAL_REG_STALL
20701 && (GET_MODE (operands[0]) == QImode
20702 || GET_MODE (operands[0]) == HImode))
20703 || GET_MODE (operands[0]) == SImode
20704 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20705 /* We reorder load and the shift. */
20706 && !rtx_equal_p (operands[1], operands[3])
20707 && !reg_overlap_mentioned_p (operands[0], operands[4])
20708 /* Last PLUS must consist of operand 0 and 3. */
20709 && !rtx_equal_p (operands[0], operands[3])
20710 && (rtx_equal_p (operands[3], operands[6])
20711 || rtx_equal_p (operands[3], operands[7]))
20712 && (rtx_equal_p (operands[0], operands[6])
20713 || rtx_equal_p (operands[0], operands[7]))
20714 /* The intermediate operand 0 must die or be same as output. */
20715 && (rtx_equal_p (operands[0], operands[5])
20716 || peep2_reg_dead_p (3, operands[0]))"
20717 [(set (match_dup 3) (match_dup 4))
20718 (set (match_dup 0) (match_dup 1))]
20719 {
20720 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20721 int scale = 1 << INTVAL (operands[2]);
20722 rtx index = gen_lowpart (Pmode, operands[1]);
20723 rtx base = gen_lowpart (Pmode, operands[3]);
20724 rtx dest = gen_lowpart (mode, operands[5]);
20725
20726 operands[1] = gen_rtx_PLUS (Pmode, base,
20727 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20728 if (mode != Pmode)
20729 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20730 operands[0] = dest;
20731 })
20732 \f
20733 ;; Call-value patterns last so that the wildcard operand does not
20734 ;; disrupt insn-recog's switch tables.
20735
20736 (define_insn "*call_value_pop_0"
20737 [(set (match_operand 0 "" "")
20738 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20739 (match_operand:SI 2 "" "")))
20740 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20741 (match_operand:SI 3 "immediate_operand" "")))]
20742 "!TARGET_64BIT"
20743 {
20744 if (SIBLING_CALL_P (insn))
20745 return "jmp\t%P1";
20746 else
20747 return "call\t%P1";
20748 }
20749 [(set_attr "type" "callv")])
20750
20751 (define_insn "*call_value_pop_1"
20752 [(set (match_operand 0 "" "")
20753 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20754 (match_operand:SI 2 "" "")))
20755 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20756 (match_operand:SI 3 "immediate_operand" "i")))]
20757 "!TARGET_64BIT"
20758 {
20759 if (constant_call_address_operand (operands[1], Pmode))
20760 {
20761 if (SIBLING_CALL_P (insn))
20762 return "jmp\t%P1";
20763 else
20764 return "call\t%P1";
20765 }
20766 if (SIBLING_CALL_P (insn))
20767 return "jmp\t%A1";
20768 else
20769 return "call\t%A1";
20770 }
20771 [(set_attr "type" "callv")])
20772
20773 (define_insn "*call_value_0"
20774 [(set (match_operand 0 "" "")
20775 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20776 (match_operand:SI 2 "" "")))]
20777 "!TARGET_64BIT"
20778 {
20779 if (SIBLING_CALL_P (insn))
20780 return "jmp\t%P1";
20781 else
20782 return "call\t%P1";
20783 }
20784 [(set_attr "type" "callv")])
20785
20786 (define_insn "*call_value_0_rex64"
20787 [(set (match_operand 0 "" "")
20788 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20789 (match_operand:DI 2 "const_int_operand" "")))]
20790 "TARGET_64BIT"
20791 {
20792 if (SIBLING_CALL_P (insn))
20793 return "jmp\t%P1";
20794 else
20795 return "call\t%P1";
20796 }
20797 [(set_attr "type" "callv")])
20798
20799 (define_insn "*call_value_1"
20800 [(set (match_operand 0 "" "")
20801 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20802 (match_operand:SI 2 "" "")))]
20803 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20804 {
20805 if (constant_call_address_operand (operands[1], Pmode))
20806 return "call\t%P1";
20807 return "call\t%A1";
20808 }
20809 [(set_attr "type" "callv")])
20810
20811 (define_insn "*sibcall_value_1"
20812 [(set (match_operand 0 "" "")
20813 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20814 (match_operand:SI 2 "" "")))]
20815 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20816 {
20817 if (constant_call_address_operand (operands[1], Pmode))
20818 return "jmp\t%P1";
20819 return "jmp\t%A1";
20820 }
20821 [(set_attr "type" "callv")])
20822
20823 (define_insn "*call_value_1_rex64"
20824 [(set (match_operand 0 "" "")
20825 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20826 (match_operand:DI 2 "" "")))]
20827 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20828 {
20829 if (constant_call_address_operand (operands[1], Pmode))
20830 return "call\t%P1";
20831 return "call\t%A1";
20832 }
20833 [(set_attr "type" "callv")])
20834
20835 (define_insn "*sibcall_value_1_rex64"
20836 [(set (match_operand 0 "" "")
20837 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20838 (match_operand:DI 2 "" "")))]
20839 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20840 "jmp\t%P1"
20841 [(set_attr "type" "callv")])
20842
20843 (define_insn "*sibcall_value_1_rex64_v"
20844 [(set (match_operand 0 "" "")
20845 (call (mem:QI (reg:DI R11_REG))
20846 (match_operand:DI 1 "" "")))]
20847 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20848 "jmp\t*%%r11"
20849 [(set_attr "type" "callv")])
20850 \f
20851 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20852 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20853 ;; caught for use by garbage collectors and the like. Using an insn that
20854 ;; maps to SIGILL makes it more likely the program will rightfully die.
20855 ;; Keeping with tradition, "6" is in honor of #UD.
20856 (define_insn "trap"
20857 [(trap_if (const_int 1) (const_int 6))]
20858 ""
20859 { return ASM_SHORT "0x0b0f"; }
20860 [(set_attr "length" "2")])
20861
20862 (define_expand "sse_prologue_save"
20863 [(parallel [(set (match_operand:BLK 0 "" "")
20864 (unspec:BLK [(reg:DI 21)
20865 (reg:DI 22)
20866 (reg:DI 23)
20867 (reg:DI 24)
20868 (reg:DI 25)
20869 (reg:DI 26)
20870 (reg:DI 27)
20871 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20872 (use (match_operand:DI 1 "register_operand" ""))
20873 (use (match_operand:DI 2 "immediate_operand" ""))
20874 (use (label_ref:DI (match_operand 3 "" "")))])]
20875 "TARGET_64BIT"
20876 "")
20877
20878 (define_insn "*sse_prologue_save_insn"
20879 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20880 (match_operand:DI 4 "const_int_operand" "n")))
20881 (unspec:BLK [(reg:DI 21)
20882 (reg:DI 22)
20883 (reg:DI 23)
20884 (reg:DI 24)
20885 (reg:DI 25)
20886 (reg:DI 26)
20887 (reg:DI 27)
20888 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20889 (use (match_operand:DI 1 "register_operand" "r"))
20890 (use (match_operand:DI 2 "const_int_operand" "i"))
20891 (use (label_ref:DI (match_operand 3 "" "X")))]
20892 "TARGET_64BIT
20893 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20894 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20895 "*
20896 {
20897 int i;
20898 operands[0] = gen_rtx_MEM (Pmode,
20899 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20900 output_asm_insn (\"jmp\\t%A1\", operands);
20901 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20902 {
20903 operands[4] = adjust_address (operands[0], DImode, i*16);
20904 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20905 PUT_MODE (operands[4], TImode);
20906 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20907 output_asm_insn (\"rex\", operands);
20908 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20909 }
20910 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20911 CODE_LABEL_NUMBER (operands[3]));
20912 return \"\";
20913 }
20914 "
20915 [(set_attr "type" "other")
20916 (set_attr "length_immediate" "0")
20917 (set_attr "length_address" "0")
20918 (set_attr "length" "135")
20919 (set_attr "memory" "store")
20920 (set_attr "modrm" "0")
20921 (set_attr "mode" "DI")])
20922
20923 (define_expand "prefetch"
20924 [(prefetch (match_operand 0 "address_operand" "")
20925 (match_operand:SI 1 "const_int_operand" "")
20926 (match_operand:SI 2 "const_int_operand" ""))]
20927 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20928 {
20929 int rw = INTVAL (operands[1]);
20930 int locality = INTVAL (operands[2]);
20931
20932 gcc_assert (rw == 0 || rw == 1);
20933 gcc_assert (locality >= 0 && locality <= 3);
20934 gcc_assert (GET_MODE (operands[0]) == Pmode
20935 || GET_MODE (operands[0]) == VOIDmode);
20936
20937 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20938 supported by SSE counterpart or the SSE prefetch is not available
20939 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20940 of locality. */
20941 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20942 operands[2] = GEN_INT (3);
20943 else
20944 operands[1] = const0_rtx;
20945 })
20946
20947 (define_insn "*prefetch_sse"
20948 [(prefetch (match_operand:SI 0 "address_operand" "p")
20949 (const_int 0)
20950 (match_operand:SI 1 "const_int_operand" ""))]
20951 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20952 {
20953 static const char * const patterns[4] = {
20954 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20955 };
20956
20957 int locality = INTVAL (operands[1]);
20958 gcc_assert (locality >= 0 && locality <= 3);
20959
20960 return patterns[locality];
20961 }
20962 [(set_attr "type" "sse")
20963 (set_attr "memory" "none")])
20964
20965 (define_insn "*prefetch_sse_rex"
20966 [(prefetch (match_operand:DI 0 "address_operand" "p")
20967 (const_int 0)
20968 (match_operand:SI 1 "const_int_operand" ""))]
20969 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20970 {
20971 static const char * const patterns[4] = {
20972 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20973 };
20974
20975 int locality = INTVAL (operands[1]);
20976 gcc_assert (locality >= 0 && locality <= 3);
20977
20978 return patterns[locality];
20979 }
20980 [(set_attr "type" "sse")
20981 (set_attr "memory" "none")])
20982
20983 (define_insn "*prefetch_3dnow"
20984 [(prefetch (match_operand:SI 0 "address_operand" "p")
20985 (match_operand:SI 1 "const_int_operand" "n")
20986 (const_int 3))]
20987 "TARGET_3DNOW && !TARGET_64BIT"
20988 {
20989 if (INTVAL (operands[1]) == 0)
20990 return "prefetch\t%a0";
20991 else
20992 return "prefetchw\t%a0";
20993 }
20994 [(set_attr "type" "mmx")
20995 (set_attr "memory" "none")])
20996
20997 (define_insn "*prefetch_3dnow_rex"
20998 [(prefetch (match_operand:DI 0 "address_operand" "p")
20999 (match_operand:SI 1 "const_int_operand" "n")
21000 (const_int 3))]
21001 "TARGET_3DNOW && TARGET_64BIT"
21002 {
21003 if (INTVAL (operands[1]) == 0)
21004 return "prefetch\t%a0";
21005 else
21006 return "prefetchw\t%a0";
21007 }
21008 [(set_attr "type" "mmx")
21009 (set_attr "memory" "none")])
21010
21011 (define_expand "stack_protect_set"
21012 [(match_operand 0 "memory_operand" "")
21013 (match_operand 1 "memory_operand" "")]
21014 ""
21015 {
21016 #ifdef TARGET_THREAD_SSP_OFFSET
21017 if (TARGET_64BIT)
21018 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21019 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21020 else
21021 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21022 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21023 #else
21024 if (TARGET_64BIT)
21025 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21026 else
21027 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21028 #endif
21029 DONE;
21030 })
21031
21032 (define_insn "stack_protect_set_si"
21033 [(set (match_operand:SI 0 "memory_operand" "=m")
21034 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21035 (set (match_scratch:SI 2 "=&r") (const_int 0))
21036 (clobber (reg:CC FLAGS_REG))]
21037 ""
21038 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21039 [(set_attr "type" "multi")])
21040
21041 (define_insn "stack_protect_set_di"
21042 [(set (match_operand:DI 0 "memory_operand" "=m")
21043 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21044 (set (match_scratch:DI 2 "=&r") (const_int 0))
21045 (clobber (reg:CC FLAGS_REG))]
21046 "TARGET_64BIT"
21047 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21048 [(set_attr "type" "multi")])
21049
21050 (define_insn "stack_tls_protect_set_si"
21051 [(set (match_operand:SI 0 "memory_operand" "=m")
21052 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21053 (set (match_scratch:SI 2 "=&r") (const_int 0))
21054 (clobber (reg:CC FLAGS_REG))]
21055 ""
21056 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21057 [(set_attr "type" "multi")])
21058
21059 (define_insn "stack_tls_protect_set_di"
21060 [(set (match_operand:DI 0 "memory_operand" "=m")
21061 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21062 (set (match_scratch:DI 2 "=&r") (const_int 0))
21063 (clobber (reg:CC FLAGS_REG))]
21064 "TARGET_64BIT"
21065 {
21066 /* The kernel uses a different segment register for performance reasons; a
21067 system call would not have to trash the userspace segment register,
21068 which would be expensive */
21069 if (ix86_cmodel != CM_KERNEL)
21070 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21071 else
21072 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21073 }
21074 [(set_attr "type" "multi")])
21075
21076 (define_expand "stack_protect_test"
21077 [(match_operand 0 "memory_operand" "")
21078 (match_operand 1 "memory_operand" "")
21079 (match_operand 2 "" "")]
21080 ""
21081 {
21082 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21083 ix86_compare_op0 = operands[0];
21084 ix86_compare_op1 = operands[1];
21085 ix86_compare_emitted = flags;
21086
21087 #ifdef TARGET_THREAD_SSP_OFFSET
21088 if (TARGET_64BIT)
21089 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21090 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21091 else
21092 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21093 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21094 #else
21095 if (TARGET_64BIT)
21096 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21097 else
21098 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21099 #endif
21100 emit_jump_insn (gen_beq (operands[2]));
21101 DONE;
21102 })
21103
21104 (define_insn "stack_protect_test_si"
21105 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21106 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21107 (match_operand:SI 2 "memory_operand" "m")]
21108 UNSPEC_SP_TEST))
21109 (clobber (match_scratch:SI 3 "=&r"))]
21110 ""
21111 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21112 [(set_attr "type" "multi")])
21113
21114 (define_insn "stack_protect_test_di"
21115 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21116 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21117 (match_operand:DI 2 "memory_operand" "m")]
21118 UNSPEC_SP_TEST))
21119 (clobber (match_scratch:DI 3 "=&r"))]
21120 "TARGET_64BIT"
21121 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21122 [(set_attr "type" "multi")])
21123
21124 (define_insn "stack_tls_protect_test_si"
21125 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21126 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21127 (match_operand:SI 2 "const_int_operand" "i")]
21128 UNSPEC_SP_TLS_TEST))
21129 (clobber (match_scratch:SI 3 "=r"))]
21130 ""
21131 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21132 [(set_attr "type" "multi")])
21133
21134 (define_insn "stack_tls_protect_test_di"
21135 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21136 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21137 (match_operand:DI 2 "const_int_operand" "i")]
21138 UNSPEC_SP_TLS_TEST))
21139 (clobber (match_scratch:DI 3 "=r"))]
21140 "TARGET_64BIT"
21141 {
21142 /* The kernel uses a different segment register for performance reasons; a
21143 system call would not have to trash the userspace segment register,
21144 which would be expensive */
21145 if (ix86_cmodel != CM_KERNEL)
21146 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21147 else
21148 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21149 }
21150 [(set_attr "type" "multi")])
21151
21152 (include "mmx.md")
21153 (include "sse.md")
21154 (include "sync.md")