optabs.h (enum optab_index): Add new OTI_isinf.
[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
159 (define_constants
160 [(UNSPECV_BLOCKAGE 0)
161 (UNSPECV_STACK_PROBE 1)
162 (UNSPECV_EMMS 2)
163 (UNSPECV_LDMXCSR 3)
164 (UNSPECV_STMXCSR 4)
165 (UNSPECV_FEMMS 5)
166 (UNSPECV_CLFLUSH 6)
167 (UNSPECV_ALIGN 7)
168 (UNSPECV_MONITOR 8)
169 (UNSPECV_MWAIT 9)
170 (UNSPECV_CMPXCHG_1 10)
171 (UNSPECV_CMPXCHG_2 11)
172 (UNSPECV_XCHG 12)
173 (UNSPECV_LOCK 13)
174 ])
175
176 ;; Registers by name.
177 (define_constants
178 [(BP_REG 6)
179 (SP_REG 7)
180 (FLAGS_REG 17)
181 (FPSR_REG 18)
182 (FPCR_REG 19)
183 (R10_REG 39)
184 (R11_REG 40)
185 ])
186
187 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
188 ;; from i386.c.
189
190 ;; In C guard expressions, put expressions which may be compile-time
191 ;; constants first. This allows for better optimization. For
192 ;; example, write "TARGET_64BIT && reload_completed", not
193 ;; "reload_completed && TARGET_64BIT".
194
195 \f
196 ;; Processor type. This attribute must exactly match the processor_type
197 ;; enumeration in i386.h.
198 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
199 (const (symbol_ref "ix86_tune")))
200
201 ;; A basic instruction type. Refinements due to arguments to be
202 ;; provided in other attributes.
203 (define_attr "type"
204 "other,multi,
205 alu,alu1,negnot,imov,imovx,lea,
206 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
207 icmp,test,ibr,setcc,icmov,
208 push,pop,call,callv,leave,
209 str,
210 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
211 sselog,sselog1,sseiadd,sseishft,sseimul,
212 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
213 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
214 (const_string "other"))
215
216 ;; Main data type used by the insn
217 (define_attr "mode"
218 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
219 (const_string "unknown"))
220
221 ;; The CPU unit operations uses.
222 (define_attr "unit" "integer,i387,sse,mmx,unknown"
223 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
224 (const_string "i387")
225 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
226 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
227 (const_string "sse")
228 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
229 (const_string "mmx")
230 (eq_attr "type" "other")
231 (const_string "unknown")]
232 (const_string "integer")))
233
234 ;; The (bounding maximum) length of an instruction immediate.
235 (define_attr "length_immediate" ""
236 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave")
237 (const_int 0)
238 (eq_attr "unit" "i387,sse,mmx")
239 (const_int 0)
240 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
241 imul,icmp,push,pop")
242 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
243 (eq_attr "type" "imov,test")
244 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
245 (eq_attr "type" "call")
246 (if_then_else (match_operand 0 "constant_call_address_operand" "")
247 (const_int 4)
248 (const_int 0))
249 (eq_attr "type" "callv")
250 (if_then_else (match_operand 1 "constant_call_address_operand" "")
251 (const_int 4)
252 (const_int 0))
253 ;; We don't know the size before shorten_branches. Expect
254 ;; the instruction to fit for better scheduling.
255 (eq_attr "type" "ibr")
256 (const_int 1)
257 ]
258 (symbol_ref "/* Update immediate_length and other attributes! */
259 gcc_unreachable (),1")))
260
261 ;; The (bounding maximum) length of an instruction address.
262 (define_attr "length_address" ""
263 (cond [(eq_attr "type" "str,other,multi,fxch")
264 (const_int 0)
265 (and (eq_attr "type" "call")
266 (match_operand 0 "constant_call_address_operand" ""))
267 (const_int 0)
268 (and (eq_attr "type" "callv")
269 (match_operand 1 "constant_call_address_operand" ""))
270 (const_int 0)
271 ]
272 (symbol_ref "ix86_attr_length_address_default (insn)")))
273
274 ;; Set when length prefix is used.
275 (define_attr "prefix_data16" ""
276 (if_then_else (ior (eq_attr "mode" "HI")
277 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
278 (const_int 1)
279 (const_int 0)))
280
281 ;; Set when string REP prefix is used.
282 (define_attr "prefix_rep" ""
283 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
284 (const_int 1)
285 (const_int 0)))
286
287 ;; Set when 0f opcode prefix is used.
288 (define_attr "prefix_0f" ""
289 (if_then_else
290 (ior (eq_attr "type" "imovx,setcc,icmov")
291 (eq_attr "unit" "sse,mmx"))
292 (const_int 1)
293 (const_int 0)))
294
295 ;; Set when REX opcode prefix is used.
296 (define_attr "prefix_rex" ""
297 (cond [(and (eq_attr "mode" "DI")
298 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
299 (const_int 1)
300 (and (eq_attr "mode" "QI")
301 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
302 (const_int 0)))
303 (const_int 1)
304 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
305 (const_int 0))
306 (const_int 1)
307 ]
308 (const_int 0)))
309
310 ;; Set when modrm byte is used.
311 (define_attr "modrm" ""
312 (cond [(eq_attr "type" "str,leave")
313 (const_int 0)
314 (eq_attr "unit" "i387")
315 (const_int 0)
316 (and (eq_attr "type" "incdec")
317 (ior (match_operand:SI 1 "register_operand" "")
318 (match_operand:HI 1 "register_operand" "")))
319 (const_int 0)
320 (and (eq_attr "type" "push")
321 (not (match_operand 1 "memory_operand" "")))
322 (const_int 0)
323 (and (eq_attr "type" "pop")
324 (not (match_operand 0 "memory_operand" "")))
325 (const_int 0)
326 (and (eq_attr "type" "imov")
327 (ior (and (match_operand 0 "register_operand" "")
328 (match_operand 1 "immediate_operand" ""))
329 (ior (and (match_operand 0 "ax_reg_operand" "")
330 (match_operand 1 "memory_displacement_only_operand" ""))
331 (and (match_operand 0 "memory_displacement_only_operand" "")
332 (match_operand 1 "ax_reg_operand" "")))))
333 (const_int 0)
334 (and (eq_attr "type" "call")
335 (match_operand 0 "constant_call_address_operand" ""))
336 (const_int 0)
337 (and (eq_attr "type" "callv")
338 (match_operand 1 "constant_call_address_operand" ""))
339 (const_int 0)
340 ]
341 (const_int 1)))
342
343 ;; The (bounding maximum) length of an instruction in bytes.
344 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
345 ;; Later we may want to split them and compute proper length as for
346 ;; other insns.
347 (define_attr "length" ""
348 (cond [(eq_attr "type" "other,multi,fistp,frndint")
349 (const_int 16)
350 (eq_attr "type" "fcmp")
351 (const_int 4)
352 (eq_attr "unit" "i387")
353 (plus (const_int 2)
354 (plus (attr "prefix_data16")
355 (attr "length_address")))]
356 (plus (plus (attr "modrm")
357 (plus (attr "prefix_0f")
358 (plus (attr "prefix_rex")
359 (const_int 1))))
360 (plus (attr "prefix_rep")
361 (plus (attr "prefix_data16")
362 (plus (attr "length_immediate")
363 (attr "length_address")))))))
364
365 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
366 ;; `store' if there is a simple memory reference therein, or `unknown'
367 ;; if the instruction is complex.
368
369 (define_attr "memory" "none,load,store,both,unknown"
370 (cond [(eq_attr "type" "other,multi,str")
371 (const_string "unknown")
372 (eq_attr "type" "lea,fcmov,fpspc")
373 (const_string "none")
374 (eq_attr "type" "fistp,leave")
375 (const_string "both")
376 (eq_attr "type" "frndint")
377 (const_string "load")
378 (eq_attr "type" "push")
379 (if_then_else (match_operand 1 "memory_operand" "")
380 (const_string "both")
381 (const_string "store"))
382 (eq_attr "type" "pop")
383 (if_then_else (match_operand 0 "memory_operand" "")
384 (const_string "both")
385 (const_string "load"))
386 (eq_attr "type" "setcc")
387 (if_then_else (match_operand 0 "memory_operand" "")
388 (const_string "store")
389 (const_string "none"))
390 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
391 (if_then_else (ior (match_operand 0 "memory_operand" "")
392 (match_operand 1 "memory_operand" ""))
393 (const_string "load")
394 (const_string "none"))
395 (eq_attr "type" "ibr")
396 (if_then_else (match_operand 0 "memory_operand" "")
397 (const_string "load")
398 (const_string "none"))
399 (eq_attr "type" "call")
400 (if_then_else (match_operand 0 "constant_call_address_operand" "")
401 (const_string "none")
402 (const_string "load"))
403 (eq_attr "type" "callv")
404 (if_then_else (match_operand 1 "constant_call_address_operand" "")
405 (const_string "none")
406 (const_string "load"))
407 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
408 (match_operand 1 "memory_operand" ""))
409 (const_string "both")
410 (and (match_operand 0 "memory_operand" "")
411 (match_operand 1 "memory_operand" ""))
412 (const_string "both")
413 (match_operand 0 "memory_operand" "")
414 (const_string "store")
415 (match_operand 1 "memory_operand" "")
416 (const_string "load")
417 (and (eq_attr "type"
418 "!alu1,negnot,ishift1,
419 imov,imovx,icmp,test,
420 fmov,fcmp,fsgn,
421 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
422 mmx,mmxmov,mmxcmp,mmxcvt")
423 (match_operand 2 "memory_operand" ""))
424 (const_string "load")
425 (and (eq_attr "type" "icmov")
426 (match_operand 3 "memory_operand" ""))
427 (const_string "load")
428 ]
429 (const_string "none")))
430
431 ;; Indicates if an instruction has both an immediate and a displacement.
432
433 (define_attr "imm_disp" "false,true,unknown"
434 (cond [(eq_attr "type" "other,multi")
435 (const_string "unknown")
436 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
437 (and (match_operand 0 "memory_displacement_operand" "")
438 (match_operand 1 "immediate_operand" "")))
439 (const_string "true")
440 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
441 (and (match_operand 0 "memory_displacement_operand" "")
442 (match_operand 2 "immediate_operand" "")))
443 (const_string "true")
444 ]
445 (const_string "false")))
446
447 ;; Indicates if an FP operation has an integer source.
448
449 (define_attr "fp_int_src" "false,true"
450 (const_string "false"))
451
452 ;; Defines rounding mode of an FP operation.
453
454 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
455 (const_string "any"))
456
457 ;; Describe a user's asm statement.
458 (define_asm_attributes
459 [(set_attr "length" "128")
460 (set_attr "type" "multi")])
461
462 ;; All x87 floating point modes
463 (define_mode_macro X87MODEF [SF DF XF])
464
465 ;; x87 SFmode and DFMode floating point modes
466 (define_mode_macro X87MODEF12 [SF DF])
467
468 ;; All integer modes handled by x87 fisttp operator.
469 (define_mode_macro X87MODEI [HI SI DI])
470
471 ;; All integer modes handled by integer x87 operators.
472 (define_mode_macro X87MODEI12 [HI SI])
473
474 ;; All SSE floating point modes
475 (define_mode_macro SSEMODEF [SF DF])
476
477 ;; All integer modes handled by SSE cvtts?2si* operators.
478 (define_mode_macro SSEMODEI24 [SI DI])
479
480 ;; SSE asm suffix for floating point modes
481 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
482
483 \f
484 ;; Scheduling descriptions
485
486 (include "pentium.md")
487 (include "ppro.md")
488 (include "k6.md")
489 (include "athlon.md")
490 (include "geode.md")
491
492 \f
493 ;; Operand and operator predicates and constraints
494
495 (include "predicates.md")
496 (include "constraints.md")
497
498 \f
499 ;; Compare instructions.
500
501 ;; All compare insns have expanders that save the operands away without
502 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
503 ;; after the cmp) will actually emit the cmpM.
504
505 (define_expand "cmpti"
506 [(set (reg:CC FLAGS_REG)
507 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
508 (match_operand:TI 1 "x86_64_general_operand" "")))]
509 "TARGET_64BIT"
510 {
511 if (MEM_P (operands[0]) && MEM_P (operands[1]))
512 operands[0] = force_reg (TImode, operands[0]);
513 ix86_compare_op0 = operands[0];
514 ix86_compare_op1 = operands[1];
515 DONE;
516 })
517
518 (define_expand "cmpdi"
519 [(set (reg:CC FLAGS_REG)
520 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
521 (match_operand:DI 1 "x86_64_general_operand" "")))]
522 ""
523 {
524 if (MEM_P (operands[0]) && MEM_P (operands[1]))
525 operands[0] = force_reg (DImode, operands[0]);
526 ix86_compare_op0 = operands[0];
527 ix86_compare_op1 = operands[1];
528 DONE;
529 })
530
531 (define_expand "cmpsi"
532 [(set (reg:CC FLAGS_REG)
533 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
534 (match_operand:SI 1 "general_operand" "")))]
535 ""
536 {
537 if (MEM_P (operands[0]) && MEM_P (operands[1]))
538 operands[0] = force_reg (SImode, operands[0]);
539 ix86_compare_op0 = operands[0];
540 ix86_compare_op1 = operands[1];
541 DONE;
542 })
543
544 (define_expand "cmphi"
545 [(set (reg:CC FLAGS_REG)
546 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
547 (match_operand:HI 1 "general_operand" "")))]
548 ""
549 {
550 if (MEM_P (operands[0]) && MEM_P (operands[1]))
551 operands[0] = force_reg (HImode, operands[0]);
552 ix86_compare_op0 = operands[0];
553 ix86_compare_op1 = operands[1];
554 DONE;
555 })
556
557 (define_expand "cmpqi"
558 [(set (reg:CC FLAGS_REG)
559 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
560 (match_operand:QI 1 "general_operand" "")))]
561 "TARGET_QIMODE_MATH"
562 {
563 if (MEM_P (operands[0]) && MEM_P (operands[1]))
564 operands[0] = force_reg (QImode, operands[0]);
565 ix86_compare_op0 = operands[0];
566 ix86_compare_op1 = operands[1];
567 DONE;
568 })
569
570 (define_insn "cmpdi_ccno_1_rex64"
571 [(set (reg FLAGS_REG)
572 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
573 (match_operand:DI 1 "const0_operand" "n,n")))]
574 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
575 "@
576 test{q}\t{%0, %0|%0, %0}
577 cmp{q}\t{%1, %0|%0, %1}"
578 [(set_attr "type" "test,icmp")
579 (set_attr "length_immediate" "0,1")
580 (set_attr "mode" "DI")])
581
582 (define_insn "*cmpdi_minus_1_rex64"
583 [(set (reg FLAGS_REG)
584 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
585 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
586 (const_int 0)))]
587 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
588 "cmp{q}\t{%1, %0|%0, %1}"
589 [(set_attr "type" "icmp")
590 (set_attr "mode" "DI")])
591
592 (define_expand "cmpdi_1_rex64"
593 [(set (reg:CC FLAGS_REG)
594 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
595 (match_operand:DI 1 "general_operand" "")))]
596 "TARGET_64BIT"
597 "")
598
599 (define_insn "cmpdi_1_insn_rex64"
600 [(set (reg FLAGS_REG)
601 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
602 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
603 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
604 "cmp{q}\t{%1, %0|%0, %1}"
605 [(set_attr "type" "icmp")
606 (set_attr "mode" "DI")])
607
608
609 (define_insn "*cmpsi_ccno_1"
610 [(set (reg FLAGS_REG)
611 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
612 (match_operand:SI 1 "const0_operand" "n,n")))]
613 "ix86_match_ccmode (insn, CCNOmode)"
614 "@
615 test{l}\t{%0, %0|%0, %0}
616 cmp{l}\t{%1, %0|%0, %1}"
617 [(set_attr "type" "test,icmp")
618 (set_attr "length_immediate" "0,1")
619 (set_attr "mode" "SI")])
620
621 (define_insn "*cmpsi_minus_1"
622 [(set (reg FLAGS_REG)
623 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
624 (match_operand:SI 1 "general_operand" "ri,mr"))
625 (const_int 0)))]
626 "ix86_match_ccmode (insn, CCGOCmode)"
627 "cmp{l}\t{%1, %0|%0, %1}"
628 [(set_attr "type" "icmp")
629 (set_attr "mode" "SI")])
630
631 (define_expand "cmpsi_1"
632 [(set (reg:CC FLAGS_REG)
633 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
634 (match_operand:SI 1 "general_operand" "ri,mr")))]
635 ""
636 "")
637
638 (define_insn "*cmpsi_1_insn"
639 [(set (reg FLAGS_REG)
640 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
641 (match_operand:SI 1 "general_operand" "ri,mr")))]
642 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
643 && ix86_match_ccmode (insn, CCmode)"
644 "cmp{l}\t{%1, %0|%0, %1}"
645 [(set_attr "type" "icmp")
646 (set_attr "mode" "SI")])
647
648 (define_insn "*cmphi_ccno_1"
649 [(set (reg FLAGS_REG)
650 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
651 (match_operand:HI 1 "const0_operand" "n,n")))]
652 "ix86_match_ccmode (insn, CCNOmode)"
653 "@
654 test{w}\t{%0, %0|%0, %0}
655 cmp{w}\t{%1, %0|%0, %1}"
656 [(set_attr "type" "test,icmp")
657 (set_attr "length_immediate" "0,1")
658 (set_attr "mode" "HI")])
659
660 (define_insn "*cmphi_minus_1"
661 [(set (reg FLAGS_REG)
662 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
663 (match_operand:HI 1 "general_operand" "ri,mr"))
664 (const_int 0)))]
665 "ix86_match_ccmode (insn, CCGOCmode)"
666 "cmp{w}\t{%1, %0|%0, %1}"
667 [(set_attr "type" "icmp")
668 (set_attr "mode" "HI")])
669
670 (define_insn "*cmphi_1"
671 [(set (reg FLAGS_REG)
672 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
673 (match_operand:HI 1 "general_operand" "ri,mr")))]
674 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
675 && ix86_match_ccmode (insn, CCmode)"
676 "cmp{w}\t{%1, %0|%0, %1}"
677 [(set_attr "type" "icmp")
678 (set_attr "mode" "HI")])
679
680 (define_insn "*cmpqi_ccno_1"
681 [(set (reg FLAGS_REG)
682 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
683 (match_operand:QI 1 "const0_operand" "n,n")))]
684 "ix86_match_ccmode (insn, CCNOmode)"
685 "@
686 test{b}\t{%0, %0|%0, %0}
687 cmp{b}\t{$0, %0|%0, 0}"
688 [(set_attr "type" "test,icmp")
689 (set_attr "length_immediate" "0,1")
690 (set_attr "mode" "QI")])
691
692 (define_insn "*cmpqi_1"
693 [(set (reg FLAGS_REG)
694 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
695 (match_operand:QI 1 "general_operand" "qi,mq")))]
696 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
697 && ix86_match_ccmode (insn, CCmode)"
698 "cmp{b}\t{%1, %0|%0, %1}"
699 [(set_attr "type" "icmp")
700 (set_attr "mode" "QI")])
701
702 (define_insn "*cmpqi_minus_1"
703 [(set (reg FLAGS_REG)
704 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
705 (match_operand:QI 1 "general_operand" "qi,mq"))
706 (const_int 0)))]
707 "ix86_match_ccmode (insn, CCGOCmode)"
708 "cmp{b}\t{%1, %0|%0, %1}"
709 [(set_attr "type" "icmp")
710 (set_attr "mode" "QI")])
711
712 (define_insn "*cmpqi_ext_1"
713 [(set (reg FLAGS_REG)
714 (compare
715 (match_operand:QI 0 "general_operand" "Qm")
716 (subreg:QI
717 (zero_extract:SI
718 (match_operand 1 "ext_register_operand" "Q")
719 (const_int 8)
720 (const_int 8)) 0)))]
721 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
722 "cmp{b}\t{%h1, %0|%0, %h1}"
723 [(set_attr "type" "icmp")
724 (set_attr "mode" "QI")])
725
726 (define_insn "*cmpqi_ext_1_rex64"
727 [(set (reg FLAGS_REG)
728 (compare
729 (match_operand:QI 0 "register_operand" "Q")
730 (subreg:QI
731 (zero_extract:SI
732 (match_operand 1 "ext_register_operand" "Q")
733 (const_int 8)
734 (const_int 8)) 0)))]
735 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
736 "cmp{b}\t{%h1, %0|%0, %h1}"
737 [(set_attr "type" "icmp")
738 (set_attr "mode" "QI")])
739
740 (define_insn "*cmpqi_ext_2"
741 [(set (reg FLAGS_REG)
742 (compare
743 (subreg:QI
744 (zero_extract:SI
745 (match_operand 0 "ext_register_operand" "Q")
746 (const_int 8)
747 (const_int 8)) 0)
748 (match_operand:QI 1 "const0_operand" "n")))]
749 "ix86_match_ccmode (insn, CCNOmode)"
750 "test{b}\t%h0, %h0"
751 [(set_attr "type" "test")
752 (set_attr "length_immediate" "0")
753 (set_attr "mode" "QI")])
754
755 (define_expand "cmpqi_ext_3"
756 [(set (reg:CC FLAGS_REG)
757 (compare:CC
758 (subreg:QI
759 (zero_extract:SI
760 (match_operand 0 "ext_register_operand" "")
761 (const_int 8)
762 (const_int 8)) 0)
763 (match_operand:QI 1 "general_operand" "")))]
764 ""
765 "")
766
767 (define_insn "cmpqi_ext_3_insn"
768 [(set (reg FLAGS_REG)
769 (compare
770 (subreg:QI
771 (zero_extract:SI
772 (match_operand 0 "ext_register_operand" "Q")
773 (const_int 8)
774 (const_int 8)) 0)
775 (match_operand:QI 1 "general_operand" "Qmn")))]
776 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
777 "cmp{b}\t{%1, %h0|%h0, %1}"
778 [(set_attr "type" "icmp")
779 (set_attr "mode" "QI")])
780
781 (define_insn "cmpqi_ext_3_insn_rex64"
782 [(set (reg FLAGS_REG)
783 (compare
784 (subreg:QI
785 (zero_extract:SI
786 (match_operand 0 "ext_register_operand" "Q")
787 (const_int 8)
788 (const_int 8)) 0)
789 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
790 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
791 "cmp{b}\t{%1, %h0|%h0, %1}"
792 [(set_attr "type" "icmp")
793 (set_attr "mode" "QI")])
794
795 (define_insn "*cmpqi_ext_4"
796 [(set (reg FLAGS_REG)
797 (compare
798 (subreg:QI
799 (zero_extract:SI
800 (match_operand 0 "ext_register_operand" "Q")
801 (const_int 8)
802 (const_int 8)) 0)
803 (subreg:QI
804 (zero_extract:SI
805 (match_operand 1 "ext_register_operand" "Q")
806 (const_int 8)
807 (const_int 8)) 0)))]
808 "ix86_match_ccmode (insn, CCmode)"
809 "cmp{b}\t{%h1, %h0|%h0, %h1}"
810 [(set_attr "type" "icmp")
811 (set_attr "mode" "QI")])
812
813 ;; These implement float point compares.
814 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
815 ;; which would allow mix and match FP modes on the compares. Which is what
816 ;; the old patterns did, but with many more of them.
817
818 (define_expand "cmpxf"
819 [(set (reg:CC FLAGS_REG)
820 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
821 (match_operand:XF 1 "nonmemory_operand" "")))]
822 "TARGET_80387"
823 {
824 ix86_compare_op0 = operands[0];
825 ix86_compare_op1 = operands[1];
826 DONE;
827 })
828
829 (define_expand "cmpdf"
830 [(set (reg:CC FLAGS_REG)
831 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
832 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
833 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
834 {
835 ix86_compare_op0 = operands[0];
836 ix86_compare_op1 = operands[1];
837 DONE;
838 })
839
840 (define_expand "cmpsf"
841 [(set (reg:CC FLAGS_REG)
842 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
843 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
844 "TARGET_80387 || TARGET_SSE_MATH"
845 {
846 ix86_compare_op0 = operands[0];
847 ix86_compare_op1 = operands[1];
848 DONE;
849 })
850
851 ;; FP compares, step 1:
852 ;; Set the FP condition codes.
853 ;;
854 ;; CCFPmode compare with exceptions
855 ;; CCFPUmode compare with no exceptions
856
857 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
858 ;; used to manage the reg stack popping would not be preserved.
859
860 (define_insn "*cmpfp_0"
861 [(set (match_operand:HI 0 "register_operand" "=a")
862 (unspec:HI
863 [(compare:CCFP
864 (match_operand 1 "register_operand" "f")
865 (match_operand 2 "const0_operand" "X"))]
866 UNSPEC_FNSTSW))]
867 "TARGET_80387
868 && FLOAT_MODE_P (GET_MODE (operands[1]))
869 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
870 "* return output_fp_compare (insn, operands, 0, 0);"
871 [(set_attr "type" "multi")
872 (set_attr "unit" "i387")
873 (set (attr "mode")
874 (cond [(match_operand:SF 1 "" "")
875 (const_string "SF")
876 (match_operand:DF 1 "" "")
877 (const_string "DF")
878 ]
879 (const_string "XF")))])
880
881 (define_insn "*cmpfp_sf"
882 [(set (match_operand:HI 0 "register_operand" "=a")
883 (unspec:HI
884 [(compare:CCFP
885 (match_operand:SF 1 "register_operand" "f")
886 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
887 UNSPEC_FNSTSW))]
888 "TARGET_80387"
889 "* return output_fp_compare (insn, operands, 0, 0);"
890 [(set_attr "type" "multi")
891 (set_attr "unit" "i387")
892 (set_attr "mode" "SF")])
893
894 (define_insn "*cmpfp_df"
895 [(set (match_operand:HI 0 "register_operand" "=a")
896 (unspec:HI
897 [(compare:CCFP
898 (match_operand:DF 1 "register_operand" "f")
899 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
900 UNSPEC_FNSTSW))]
901 "TARGET_80387"
902 "* return output_fp_compare (insn, operands, 0, 0);"
903 [(set_attr "type" "multi")
904 (set_attr "unit" "i387")
905 (set_attr "mode" "DF")])
906
907 (define_insn "*cmpfp_xf"
908 [(set (match_operand:HI 0 "register_operand" "=a")
909 (unspec:HI
910 [(compare:CCFP
911 (match_operand:XF 1 "register_operand" "f")
912 (match_operand:XF 2 "register_operand" "f"))]
913 UNSPEC_FNSTSW))]
914 "TARGET_80387"
915 "* return output_fp_compare (insn, operands, 0, 0);"
916 [(set_attr "type" "multi")
917 (set_attr "unit" "i387")
918 (set_attr "mode" "XF")])
919
920 (define_insn "*cmpfp_u"
921 [(set (match_operand:HI 0 "register_operand" "=a")
922 (unspec:HI
923 [(compare:CCFPU
924 (match_operand 1 "register_operand" "f")
925 (match_operand 2 "register_operand" "f"))]
926 UNSPEC_FNSTSW))]
927 "TARGET_80387
928 && FLOAT_MODE_P (GET_MODE (operands[1]))
929 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
930 "* return output_fp_compare (insn, operands, 0, 1);"
931 [(set_attr "type" "multi")
932 (set_attr "unit" "i387")
933 (set (attr "mode")
934 (cond [(match_operand:SF 1 "" "")
935 (const_string "SF")
936 (match_operand:DF 1 "" "")
937 (const_string "DF")
938 ]
939 (const_string "XF")))])
940
941 (define_insn "*cmpfp_<mode>"
942 [(set (match_operand:HI 0 "register_operand" "=a")
943 (unspec:HI
944 [(compare:CCFP
945 (match_operand 1 "register_operand" "f")
946 (match_operator 3 "float_operator"
947 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
948 UNSPEC_FNSTSW))]
949 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
950 && FLOAT_MODE_P (GET_MODE (operands[1]))
951 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
952 "* return output_fp_compare (insn, operands, 0, 0);"
953 [(set_attr "type" "multi")
954 (set_attr "unit" "i387")
955 (set_attr "fp_int_src" "true")
956 (set_attr "mode" "<MODE>")])
957
958 ;; FP compares, step 2
959 ;; Move the fpsw to ax.
960
961 (define_insn "x86_fnstsw_1"
962 [(set (match_operand:HI 0 "register_operand" "=a")
963 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
964 "TARGET_80387"
965 "fnstsw\t%0"
966 [(set_attr "length" "2")
967 (set_attr "mode" "SI")
968 (set_attr "unit" "i387")])
969
970 ;; FP compares, step 3
971 ;; Get ax into flags, general case.
972
973 (define_insn "x86_sahf_1"
974 [(set (reg:CC FLAGS_REG)
975 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
976 "!TARGET_64BIT"
977 "sahf"
978 [(set_attr "length" "1")
979 (set_attr "athlon_decode" "vector")
980 (set_attr "mode" "SI")])
981
982 ;; Pentium Pro can do steps 1 through 3 in one go.
983
984 (define_insn "*cmpfp_i_mixed"
985 [(set (reg:CCFP FLAGS_REG)
986 (compare:CCFP (match_operand 0 "register_operand" "f,x")
987 (match_operand 1 "nonimmediate_operand" "f,xm")))]
988 "TARGET_MIX_SSE_I387
989 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991 "* return output_fp_compare (insn, operands, 1, 0);"
992 [(set_attr "type" "fcmp,ssecomi")
993 (set (attr "mode")
994 (if_then_else (match_operand:SF 1 "" "")
995 (const_string "SF")
996 (const_string "DF")))
997 (set_attr "athlon_decode" "vector")])
998
999 (define_insn "*cmpfp_i_sse"
1000 [(set (reg:CCFP FLAGS_REG)
1001 (compare:CCFP (match_operand 0 "register_operand" "x")
1002 (match_operand 1 "nonimmediate_operand" "xm")))]
1003 "TARGET_SSE_MATH
1004 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1005 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006 "* return output_fp_compare (insn, operands, 1, 0);"
1007 [(set_attr "type" "ssecomi")
1008 (set (attr "mode")
1009 (if_then_else (match_operand:SF 1 "" "")
1010 (const_string "SF")
1011 (const_string "DF")))
1012 (set_attr "athlon_decode" "vector")])
1013
1014 (define_insn "*cmpfp_i_i387"
1015 [(set (reg:CCFP FLAGS_REG)
1016 (compare:CCFP (match_operand 0 "register_operand" "f")
1017 (match_operand 1 "register_operand" "f")))]
1018 "TARGET_80387 && TARGET_CMOVE
1019 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1020 && FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022 "* return output_fp_compare (insn, operands, 1, 0);"
1023 [(set_attr "type" "fcmp")
1024 (set (attr "mode")
1025 (cond [(match_operand:SF 1 "" "")
1026 (const_string "SF")
1027 (match_operand:DF 1 "" "")
1028 (const_string "DF")
1029 ]
1030 (const_string "XF")))
1031 (set_attr "athlon_decode" "vector")])
1032
1033 (define_insn "*cmpfp_iu_mixed"
1034 [(set (reg:CCFPU FLAGS_REG)
1035 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1036 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1037 "TARGET_MIX_SSE_I387
1038 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040 "* return output_fp_compare (insn, operands, 1, 1);"
1041 [(set_attr "type" "fcmp,ssecomi")
1042 (set (attr "mode")
1043 (if_then_else (match_operand:SF 1 "" "")
1044 (const_string "SF")
1045 (const_string "DF")))
1046 (set_attr "athlon_decode" "vector")])
1047
1048 (define_insn "*cmpfp_iu_sse"
1049 [(set (reg:CCFPU FLAGS_REG)
1050 (compare:CCFPU (match_operand 0 "register_operand" "x")
1051 (match_operand 1 "nonimmediate_operand" "xm")))]
1052 "TARGET_SSE_MATH
1053 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1054 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055 "* return output_fp_compare (insn, operands, 1, 1);"
1056 [(set_attr "type" "ssecomi")
1057 (set (attr "mode")
1058 (if_then_else (match_operand:SF 1 "" "")
1059 (const_string "SF")
1060 (const_string "DF")))
1061 (set_attr "athlon_decode" "vector")])
1062
1063 (define_insn "*cmpfp_iu_387"
1064 [(set (reg:CCFPU FLAGS_REG)
1065 (compare:CCFPU (match_operand 0 "register_operand" "f")
1066 (match_operand 1 "register_operand" "f")))]
1067 "TARGET_80387 && TARGET_CMOVE
1068 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1069 && FLOAT_MODE_P (GET_MODE (operands[0]))
1070 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1071 "* return output_fp_compare (insn, operands, 1, 1);"
1072 [(set_attr "type" "fcmp")
1073 (set (attr "mode")
1074 (cond [(match_operand:SF 1 "" "")
1075 (const_string "SF")
1076 (match_operand:DF 1 "" "")
1077 (const_string "DF")
1078 ]
1079 (const_string "XF")))
1080 (set_attr "athlon_decode" "vector")])
1081 \f
1082 ;; Move instructions.
1083
1084 ;; General case of fullword move.
1085
1086 (define_expand "movsi"
1087 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1088 (match_operand:SI 1 "general_operand" ""))]
1089 ""
1090 "ix86_expand_move (SImode, operands); DONE;")
1091
1092 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1093 ;; general_operand.
1094 ;;
1095 ;; %%% We don't use a post-inc memory reference because x86 is not a
1096 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1097 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1098 ;; targets without our curiosities, and it is just as easy to represent
1099 ;; this differently.
1100
1101 (define_insn "*pushsi2"
1102 [(set (match_operand:SI 0 "push_operand" "=<")
1103 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1104 "!TARGET_64BIT"
1105 "push{l}\t%1"
1106 [(set_attr "type" "push")
1107 (set_attr "mode" "SI")])
1108
1109 ;; For 64BIT abi we always round up to 8 bytes.
1110 (define_insn "*pushsi2_rex64"
1111 [(set (match_operand:SI 0 "push_operand" "=X")
1112 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1113 "TARGET_64BIT"
1114 "push{q}\t%q1"
1115 [(set_attr "type" "push")
1116 (set_attr "mode" "SI")])
1117
1118 (define_insn "*pushsi2_prologue"
1119 [(set (match_operand:SI 0 "push_operand" "=<")
1120 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1121 (clobber (mem:BLK (scratch)))]
1122 "!TARGET_64BIT"
1123 "push{l}\t%1"
1124 [(set_attr "type" "push")
1125 (set_attr "mode" "SI")])
1126
1127 (define_insn "*popsi1_epilogue"
1128 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1129 (mem:SI (reg:SI SP_REG)))
1130 (set (reg:SI SP_REG)
1131 (plus:SI (reg:SI SP_REG) (const_int 4)))
1132 (clobber (mem:BLK (scratch)))]
1133 "!TARGET_64BIT"
1134 "pop{l}\t%0"
1135 [(set_attr "type" "pop")
1136 (set_attr "mode" "SI")])
1137
1138 (define_insn "popsi1"
1139 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1140 (mem:SI (reg:SI SP_REG)))
1141 (set (reg:SI SP_REG)
1142 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1143 "!TARGET_64BIT"
1144 "pop{l}\t%0"
1145 [(set_attr "type" "pop")
1146 (set_attr "mode" "SI")])
1147
1148 (define_insn "*movsi_xor"
1149 [(set (match_operand:SI 0 "register_operand" "=r")
1150 (match_operand:SI 1 "const0_operand" "i"))
1151 (clobber (reg:CC FLAGS_REG))]
1152 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1153 "xor{l}\t{%0, %0|%0, %0}"
1154 [(set_attr "type" "alu1")
1155 (set_attr "mode" "SI")
1156 (set_attr "length_immediate" "0")])
1157
1158 (define_insn "*movsi_or"
1159 [(set (match_operand:SI 0 "register_operand" "=r")
1160 (match_operand:SI 1 "immediate_operand" "i"))
1161 (clobber (reg:CC FLAGS_REG))]
1162 "reload_completed
1163 && operands[1] == constm1_rtx
1164 && (TARGET_PENTIUM || optimize_size)"
1165 {
1166 operands[1] = constm1_rtx;
1167 return "or{l}\t{%1, %0|%0, %1}";
1168 }
1169 [(set_attr "type" "alu1")
1170 (set_attr "mode" "SI")
1171 (set_attr "length_immediate" "1")])
1172
1173 (define_insn "*movsi_1"
1174 [(set (match_operand:SI 0 "nonimmediate_operand"
1175 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1176 (match_operand:SI 1 "general_operand"
1177 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1178 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1179 {
1180 switch (get_attr_type (insn))
1181 {
1182 case TYPE_SSELOG1:
1183 if (get_attr_mode (insn) == MODE_TI)
1184 return "pxor\t%0, %0";
1185 return "xorps\t%0, %0";
1186
1187 case TYPE_SSEMOV:
1188 switch (get_attr_mode (insn))
1189 {
1190 case MODE_TI:
1191 return "movdqa\t{%1, %0|%0, %1}";
1192 case MODE_V4SF:
1193 return "movaps\t{%1, %0|%0, %1}";
1194 case MODE_SI:
1195 return "movd\t{%1, %0|%0, %1}";
1196 case MODE_SF:
1197 return "movss\t{%1, %0|%0, %1}";
1198 default:
1199 gcc_unreachable ();
1200 }
1201
1202 case TYPE_MMXADD:
1203 return "pxor\t%0, %0";
1204
1205 case TYPE_MMXMOV:
1206 if (get_attr_mode (insn) == MODE_DI)
1207 return "movq\t{%1, %0|%0, %1}";
1208 return "movd\t{%1, %0|%0, %1}";
1209
1210 case TYPE_LEA:
1211 return "lea{l}\t{%1, %0|%0, %1}";
1212
1213 default:
1214 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1215 return "mov{l}\t{%1, %0|%0, %1}";
1216 }
1217 }
1218 [(set (attr "type")
1219 (cond [(eq_attr "alternative" "2")
1220 (const_string "mmxadd")
1221 (eq_attr "alternative" "3,4,5")
1222 (const_string "mmxmov")
1223 (eq_attr "alternative" "6")
1224 (const_string "sselog1")
1225 (eq_attr "alternative" "7,8,9,10,11")
1226 (const_string "ssemov")
1227 (match_operand:DI 1 "pic_32bit_operand" "")
1228 (const_string "lea")
1229 ]
1230 (const_string "imov")))
1231 (set (attr "mode")
1232 (cond [(eq_attr "alternative" "2,3")
1233 (const_string "DI")
1234 (eq_attr "alternative" "6,7")
1235 (if_then_else
1236 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1237 (const_string "V4SF")
1238 (const_string "TI"))
1239 (and (eq_attr "alternative" "8,9,10,11")
1240 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1241 (const_string "SF")
1242 ]
1243 (const_string "SI")))])
1244
1245 ;; Stores and loads of ax to arbitrary constant address.
1246 ;; We fake an second form of instruction to force reload to load address
1247 ;; into register when rax is not available
1248 (define_insn "*movabssi_1_rex64"
1249 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1250 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1251 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1252 "@
1253 movabs{l}\t{%1, %P0|%P0, %1}
1254 mov{l}\t{%1, %a0|%a0, %1}"
1255 [(set_attr "type" "imov")
1256 (set_attr "modrm" "0,*")
1257 (set_attr "length_address" "8,0")
1258 (set_attr "length_immediate" "0,*")
1259 (set_attr "memory" "store")
1260 (set_attr "mode" "SI")])
1261
1262 (define_insn "*movabssi_2_rex64"
1263 [(set (match_operand:SI 0 "register_operand" "=a,r")
1264 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1265 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1266 "@
1267 movabs{l}\t{%P1, %0|%0, %P1}
1268 mov{l}\t{%a1, %0|%0, %a1}"
1269 [(set_attr "type" "imov")
1270 (set_attr "modrm" "0,*")
1271 (set_attr "length_address" "8,0")
1272 (set_attr "length_immediate" "0")
1273 (set_attr "memory" "load")
1274 (set_attr "mode" "SI")])
1275
1276 (define_insn "*swapsi"
1277 [(set (match_operand:SI 0 "register_operand" "+r")
1278 (match_operand:SI 1 "register_operand" "+r"))
1279 (set (match_dup 1)
1280 (match_dup 0))]
1281 ""
1282 "xchg{l}\t%1, %0"
1283 [(set_attr "type" "imov")
1284 (set_attr "mode" "SI")
1285 (set_attr "pent_pair" "np")
1286 (set_attr "athlon_decode" "vector")])
1287
1288 (define_expand "movhi"
1289 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1290 (match_operand:HI 1 "general_operand" ""))]
1291 ""
1292 "ix86_expand_move (HImode, operands); DONE;")
1293
1294 (define_insn "*pushhi2"
1295 [(set (match_operand:HI 0 "push_operand" "=X")
1296 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1297 "!TARGET_64BIT"
1298 "push{l}\t%k1"
1299 [(set_attr "type" "push")
1300 (set_attr "mode" "SI")])
1301
1302 ;; For 64BIT abi we always round up to 8 bytes.
1303 (define_insn "*pushhi2_rex64"
1304 [(set (match_operand:HI 0 "push_operand" "=X")
1305 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1306 "TARGET_64BIT"
1307 "push{q}\t%q1"
1308 [(set_attr "type" "push")
1309 (set_attr "mode" "DI")])
1310
1311 (define_insn "*movhi_1"
1312 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1313 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1314 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1315 {
1316 switch (get_attr_type (insn))
1317 {
1318 case TYPE_IMOVX:
1319 /* movzwl is faster than movw on p2 due to partial word stalls,
1320 though not as fast as an aligned movl. */
1321 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1322 default:
1323 if (get_attr_mode (insn) == MODE_SI)
1324 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1325 else
1326 return "mov{w}\t{%1, %0|%0, %1}";
1327 }
1328 }
1329 [(set (attr "type")
1330 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1331 (const_string "imov")
1332 (and (eq_attr "alternative" "0")
1333 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1334 (const_int 0))
1335 (eq (symbol_ref "TARGET_HIMODE_MATH")
1336 (const_int 0))))
1337 (const_string "imov")
1338 (and (eq_attr "alternative" "1,2")
1339 (match_operand:HI 1 "aligned_operand" ""))
1340 (const_string "imov")
1341 (and (ne (symbol_ref "TARGET_MOVX")
1342 (const_int 0))
1343 (eq_attr "alternative" "0,2"))
1344 (const_string "imovx")
1345 ]
1346 (const_string "imov")))
1347 (set (attr "mode")
1348 (cond [(eq_attr "type" "imovx")
1349 (const_string "SI")
1350 (and (eq_attr "alternative" "1,2")
1351 (match_operand:HI 1 "aligned_operand" ""))
1352 (const_string "SI")
1353 (and (eq_attr "alternative" "0")
1354 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1355 (const_int 0))
1356 (eq (symbol_ref "TARGET_HIMODE_MATH")
1357 (const_int 0))))
1358 (const_string "SI")
1359 ]
1360 (const_string "HI")))])
1361
1362 ;; Stores and loads of ax to arbitrary constant address.
1363 ;; We fake an second form of instruction to force reload to load address
1364 ;; into register when rax is not available
1365 (define_insn "*movabshi_1_rex64"
1366 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1367 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1368 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1369 "@
1370 movabs{w}\t{%1, %P0|%P0, %1}
1371 mov{w}\t{%1, %a0|%a0, %1}"
1372 [(set_attr "type" "imov")
1373 (set_attr "modrm" "0,*")
1374 (set_attr "length_address" "8,0")
1375 (set_attr "length_immediate" "0,*")
1376 (set_attr "memory" "store")
1377 (set_attr "mode" "HI")])
1378
1379 (define_insn "*movabshi_2_rex64"
1380 [(set (match_operand:HI 0 "register_operand" "=a,r")
1381 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1382 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1383 "@
1384 movabs{w}\t{%P1, %0|%0, %P1}
1385 mov{w}\t{%a1, %0|%0, %a1}"
1386 [(set_attr "type" "imov")
1387 (set_attr "modrm" "0,*")
1388 (set_attr "length_address" "8,0")
1389 (set_attr "length_immediate" "0")
1390 (set_attr "memory" "load")
1391 (set_attr "mode" "HI")])
1392
1393 (define_insn "*swaphi_1"
1394 [(set (match_operand:HI 0 "register_operand" "+r")
1395 (match_operand:HI 1 "register_operand" "+r"))
1396 (set (match_dup 1)
1397 (match_dup 0))]
1398 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1399 "xchg{l}\t%k1, %k0"
1400 [(set_attr "type" "imov")
1401 (set_attr "mode" "SI")
1402 (set_attr "pent_pair" "np")
1403 (set_attr "athlon_decode" "vector")])
1404
1405 (define_insn "*swaphi_2"
1406 [(set (match_operand:HI 0 "register_operand" "+r")
1407 (match_operand:HI 1 "register_operand" "+r"))
1408 (set (match_dup 1)
1409 (match_dup 0))]
1410 "TARGET_PARTIAL_REG_STALL"
1411 "xchg{w}\t%1, %0"
1412 [(set_attr "type" "imov")
1413 (set_attr "mode" "HI")
1414 (set_attr "pent_pair" "np")
1415 (set_attr "athlon_decode" "vector")])
1416
1417 (define_expand "movstricthi"
1418 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1419 (match_operand:HI 1 "general_operand" ""))]
1420 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1421 {
1422 /* Don't generate memory->memory moves, go through a register */
1423 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1424 operands[1] = force_reg (HImode, operands[1]);
1425 })
1426
1427 (define_insn "*movstricthi_1"
1428 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1429 (match_operand:HI 1 "general_operand" "rn,m"))]
1430 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1431 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1432 "mov{w}\t{%1, %0|%0, %1}"
1433 [(set_attr "type" "imov")
1434 (set_attr "mode" "HI")])
1435
1436 (define_insn "*movstricthi_xor"
1437 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1438 (match_operand:HI 1 "const0_operand" "i"))
1439 (clobber (reg:CC FLAGS_REG))]
1440 "reload_completed
1441 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1442 "xor{w}\t{%0, %0|%0, %0}"
1443 [(set_attr "type" "alu1")
1444 (set_attr "mode" "HI")
1445 (set_attr "length_immediate" "0")])
1446
1447 (define_expand "movqi"
1448 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1449 (match_operand:QI 1 "general_operand" ""))]
1450 ""
1451 "ix86_expand_move (QImode, operands); DONE;")
1452
1453 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1454 ;; "push a byte". But actually we use pushl, which has the effect
1455 ;; of rounding the amount pushed up to a word.
1456
1457 (define_insn "*pushqi2"
1458 [(set (match_operand:QI 0 "push_operand" "=X")
1459 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1460 "!TARGET_64BIT"
1461 "push{l}\t%k1"
1462 [(set_attr "type" "push")
1463 (set_attr "mode" "SI")])
1464
1465 ;; For 64BIT abi we always round up to 8 bytes.
1466 (define_insn "*pushqi2_rex64"
1467 [(set (match_operand:QI 0 "push_operand" "=X")
1468 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1469 "TARGET_64BIT"
1470 "push{q}\t%q1"
1471 [(set_attr "type" "push")
1472 (set_attr "mode" "DI")])
1473
1474 ;; Situation is quite tricky about when to choose full sized (SImode) move
1475 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1476 ;; partial register dependency machines (such as AMD Athlon), where QImode
1477 ;; moves issue extra dependency and for partial register stalls machines
1478 ;; that don't use QImode patterns (and QImode move cause stall on the next
1479 ;; instruction).
1480 ;;
1481 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1482 ;; register stall machines with, where we use QImode instructions, since
1483 ;; partial register stall can be caused there. Then we use movzx.
1484 (define_insn "*movqi_1"
1485 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1486 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1487 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1488 {
1489 switch (get_attr_type (insn))
1490 {
1491 case TYPE_IMOVX:
1492 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1493 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1494 default:
1495 if (get_attr_mode (insn) == MODE_SI)
1496 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1497 else
1498 return "mov{b}\t{%1, %0|%0, %1}";
1499 }
1500 }
1501 [(set (attr "type")
1502 (cond [(and (eq_attr "alternative" "5")
1503 (not (match_operand:QI 1 "aligned_operand" "")))
1504 (const_string "imovx")
1505 (ne (symbol_ref "optimize_size") (const_int 0))
1506 (const_string "imov")
1507 (and (eq_attr "alternative" "3")
1508 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1509 (const_int 0))
1510 (eq (symbol_ref "TARGET_QIMODE_MATH")
1511 (const_int 0))))
1512 (const_string "imov")
1513 (eq_attr "alternative" "3,5")
1514 (const_string "imovx")
1515 (and (ne (symbol_ref "TARGET_MOVX")
1516 (const_int 0))
1517 (eq_attr "alternative" "2"))
1518 (const_string "imovx")
1519 ]
1520 (const_string "imov")))
1521 (set (attr "mode")
1522 (cond [(eq_attr "alternative" "3,4,5")
1523 (const_string "SI")
1524 (eq_attr "alternative" "6")
1525 (const_string "QI")
1526 (eq_attr "type" "imovx")
1527 (const_string "SI")
1528 (and (eq_attr "type" "imov")
1529 (and (eq_attr "alternative" "0,1")
1530 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1531 (const_int 0))
1532 (and (eq (symbol_ref "optimize_size")
1533 (const_int 0))
1534 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1535 (const_int 0))))))
1536 (const_string "SI")
1537 ;; Avoid partial register stalls when not using QImode arithmetic
1538 (and (eq_attr "type" "imov")
1539 (and (eq_attr "alternative" "0,1")
1540 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1541 (const_int 0))
1542 (eq (symbol_ref "TARGET_QIMODE_MATH")
1543 (const_int 0)))))
1544 (const_string "SI")
1545 ]
1546 (const_string "QI")))])
1547
1548 (define_expand "reload_outqi"
1549 [(parallel [(match_operand:QI 0 "" "=m")
1550 (match_operand:QI 1 "register_operand" "r")
1551 (match_operand:QI 2 "register_operand" "=&q")])]
1552 ""
1553 {
1554 rtx op0, op1, op2;
1555 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1556
1557 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1558 if (! q_regs_operand (op1, QImode))
1559 {
1560 emit_insn (gen_movqi (op2, op1));
1561 op1 = op2;
1562 }
1563 emit_insn (gen_movqi (op0, op1));
1564 DONE;
1565 })
1566
1567 (define_insn "*swapqi_1"
1568 [(set (match_operand:QI 0 "register_operand" "+r")
1569 (match_operand:QI 1 "register_operand" "+r"))
1570 (set (match_dup 1)
1571 (match_dup 0))]
1572 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1573 "xchg{l}\t%k1, %k0"
1574 [(set_attr "type" "imov")
1575 (set_attr "mode" "SI")
1576 (set_attr "pent_pair" "np")
1577 (set_attr "athlon_decode" "vector")])
1578
1579 (define_insn "*swapqi_2"
1580 [(set (match_operand:QI 0 "register_operand" "+q")
1581 (match_operand:QI 1 "register_operand" "+q"))
1582 (set (match_dup 1)
1583 (match_dup 0))]
1584 "TARGET_PARTIAL_REG_STALL"
1585 "xchg{b}\t%1, %0"
1586 [(set_attr "type" "imov")
1587 (set_attr "mode" "QI")
1588 (set_attr "pent_pair" "np")
1589 (set_attr "athlon_decode" "vector")])
1590
1591 (define_expand "movstrictqi"
1592 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1593 (match_operand:QI 1 "general_operand" ""))]
1594 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1595 {
1596 /* Don't generate memory->memory moves, go through a register. */
1597 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1598 operands[1] = force_reg (QImode, operands[1]);
1599 })
1600
1601 (define_insn "*movstrictqi_1"
1602 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1603 (match_operand:QI 1 "general_operand" "*qn,m"))]
1604 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1605 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1606 "mov{b}\t{%1, %0|%0, %1}"
1607 [(set_attr "type" "imov")
1608 (set_attr "mode" "QI")])
1609
1610 (define_insn "*movstrictqi_xor"
1611 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1612 (match_operand:QI 1 "const0_operand" "i"))
1613 (clobber (reg:CC FLAGS_REG))]
1614 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1615 "xor{b}\t{%0, %0|%0, %0}"
1616 [(set_attr "type" "alu1")
1617 (set_attr "mode" "QI")
1618 (set_attr "length_immediate" "0")])
1619
1620 (define_insn "*movsi_extv_1"
1621 [(set (match_operand:SI 0 "register_operand" "=R")
1622 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1623 (const_int 8)
1624 (const_int 8)))]
1625 ""
1626 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1627 [(set_attr "type" "imovx")
1628 (set_attr "mode" "SI")])
1629
1630 (define_insn "*movhi_extv_1"
1631 [(set (match_operand:HI 0 "register_operand" "=R")
1632 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1633 (const_int 8)
1634 (const_int 8)))]
1635 ""
1636 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1637 [(set_attr "type" "imovx")
1638 (set_attr "mode" "SI")])
1639
1640 (define_insn "*movqi_extv_1"
1641 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1642 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1643 (const_int 8)
1644 (const_int 8)))]
1645 "!TARGET_64BIT"
1646 {
1647 switch (get_attr_type (insn))
1648 {
1649 case TYPE_IMOVX:
1650 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1651 default:
1652 return "mov{b}\t{%h1, %0|%0, %h1}";
1653 }
1654 }
1655 [(set (attr "type")
1656 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1657 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1658 (ne (symbol_ref "TARGET_MOVX")
1659 (const_int 0))))
1660 (const_string "imovx")
1661 (const_string "imov")))
1662 (set (attr "mode")
1663 (if_then_else (eq_attr "type" "imovx")
1664 (const_string "SI")
1665 (const_string "QI")))])
1666
1667 (define_insn "*movqi_extv_1_rex64"
1668 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1669 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1670 (const_int 8)
1671 (const_int 8)))]
1672 "TARGET_64BIT"
1673 {
1674 switch (get_attr_type (insn))
1675 {
1676 case TYPE_IMOVX:
1677 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1678 default:
1679 return "mov{b}\t{%h1, %0|%0, %h1}";
1680 }
1681 }
1682 [(set (attr "type")
1683 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1684 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1685 (ne (symbol_ref "TARGET_MOVX")
1686 (const_int 0))))
1687 (const_string "imovx")
1688 (const_string "imov")))
1689 (set (attr "mode")
1690 (if_then_else (eq_attr "type" "imovx")
1691 (const_string "SI")
1692 (const_string "QI")))])
1693
1694 ;; Stores and loads of ax to arbitrary constant address.
1695 ;; We fake an second form of instruction to force reload to load address
1696 ;; into register when rax is not available
1697 (define_insn "*movabsqi_1_rex64"
1698 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1699 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1700 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1701 "@
1702 movabs{b}\t{%1, %P0|%P0, %1}
1703 mov{b}\t{%1, %a0|%a0, %1}"
1704 [(set_attr "type" "imov")
1705 (set_attr "modrm" "0,*")
1706 (set_attr "length_address" "8,0")
1707 (set_attr "length_immediate" "0,*")
1708 (set_attr "memory" "store")
1709 (set_attr "mode" "QI")])
1710
1711 (define_insn "*movabsqi_2_rex64"
1712 [(set (match_operand:QI 0 "register_operand" "=a,r")
1713 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1714 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1715 "@
1716 movabs{b}\t{%P1, %0|%0, %P1}
1717 mov{b}\t{%a1, %0|%0, %a1}"
1718 [(set_attr "type" "imov")
1719 (set_attr "modrm" "0,*")
1720 (set_attr "length_address" "8,0")
1721 (set_attr "length_immediate" "0")
1722 (set_attr "memory" "load")
1723 (set_attr "mode" "QI")])
1724
1725 (define_insn "*movdi_extzv_1"
1726 [(set (match_operand:DI 0 "register_operand" "=R")
1727 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1728 (const_int 8)
1729 (const_int 8)))]
1730 "TARGET_64BIT"
1731 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1732 [(set_attr "type" "imovx")
1733 (set_attr "mode" "DI")])
1734
1735 (define_insn "*movsi_extzv_1"
1736 [(set (match_operand:SI 0 "register_operand" "=R")
1737 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1738 (const_int 8)
1739 (const_int 8)))]
1740 ""
1741 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1742 [(set_attr "type" "imovx")
1743 (set_attr "mode" "SI")])
1744
1745 (define_insn "*movqi_extzv_2"
1746 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1747 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1748 (const_int 8)
1749 (const_int 8)) 0))]
1750 "!TARGET_64BIT"
1751 {
1752 switch (get_attr_type (insn))
1753 {
1754 case TYPE_IMOVX:
1755 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1756 default:
1757 return "mov{b}\t{%h1, %0|%0, %h1}";
1758 }
1759 }
1760 [(set (attr "type")
1761 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1762 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1763 (ne (symbol_ref "TARGET_MOVX")
1764 (const_int 0))))
1765 (const_string "imovx")
1766 (const_string "imov")))
1767 (set (attr "mode")
1768 (if_then_else (eq_attr "type" "imovx")
1769 (const_string "SI")
1770 (const_string "QI")))])
1771
1772 (define_insn "*movqi_extzv_2_rex64"
1773 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1774 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1775 (const_int 8)
1776 (const_int 8)) 0))]
1777 "TARGET_64BIT"
1778 {
1779 switch (get_attr_type (insn))
1780 {
1781 case TYPE_IMOVX:
1782 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1783 default:
1784 return "mov{b}\t{%h1, %0|%0, %h1}";
1785 }
1786 }
1787 [(set (attr "type")
1788 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1789 (ne (symbol_ref "TARGET_MOVX")
1790 (const_int 0)))
1791 (const_string "imovx")
1792 (const_string "imov")))
1793 (set (attr "mode")
1794 (if_then_else (eq_attr "type" "imovx")
1795 (const_string "SI")
1796 (const_string "QI")))])
1797
1798 (define_insn "movsi_insv_1"
1799 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1800 (const_int 8)
1801 (const_int 8))
1802 (match_operand:SI 1 "general_operand" "Qmn"))]
1803 "!TARGET_64BIT"
1804 "mov{b}\t{%b1, %h0|%h0, %b1}"
1805 [(set_attr "type" "imov")
1806 (set_attr "mode" "QI")])
1807
1808 (define_insn "*movsi_insv_1_rex64"
1809 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1810 (const_int 8)
1811 (const_int 8))
1812 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1813 "TARGET_64BIT"
1814 "mov{b}\t{%b1, %h0|%h0, %b1}"
1815 [(set_attr "type" "imov")
1816 (set_attr "mode" "QI")])
1817
1818 (define_insn "movdi_insv_1_rex64"
1819 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1820 (const_int 8)
1821 (const_int 8))
1822 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
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 "*movqi_insv_2"
1829 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1830 (const_int 8)
1831 (const_int 8))
1832 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1833 (const_int 8)))]
1834 ""
1835 "mov{b}\t{%h1, %h0|%h0, %h1}"
1836 [(set_attr "type" "imov")
1837 (set_attr "mode" "QI")])
1838
1839 (define_expand "movdi"
1840 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1841 (match_operand:DI 1 "general_operand" ""))]
1842 ""
1843 "ix86_expand_move (DImode, operands); DONE;")
1844
1845 (define_insn "*pushdi"
1846 [(set (match_operand:DI 0 "push_operand" "=<")
1847 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1848 "!TARGET_64BIT"
1849 "#")
1850
1851 (define_insn "*pushdi2_rex64"
1852 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1853 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1854 "TARGET_64BIT"
1855 "@
1856 push{q}\t%1
1857 #"
1858 [(set_attr "type" "push,multi")
1859 (set_attr "mode" "DI")])
1860
1861 ;; Convert impossible pushes of immediate to existing instructions.
1862 ;; First try to get scratch register and go through it. In case this
1863 ;; fails, push sign extended lower part first and then overwrite
1864 ;; upper part by 32bit move.
1865 (define_peephole2
1866 [(match_scratch:DI 2 "r")
1867 (set (match_operand:DI 0 "push_operand" "")
1868 (match_operand:DI 1 "immediate_operand" ""))]
1869 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1870 && !x86_64_immediate_operand (operands[1], DImode)"
1871 [(set (match_dup 2) (match_dup 1))
1872 (set (match_dup 0) (match_dup 2))]
1873 "")
1874
1875 ;; We need to define this as both peepholer and splitter for case
1876 ;; peephole2 pass is not run.
1877 ;; "&& 1" is needed to keep it from matching the previous pattern.
1878 (define_peephole2
1879 [(set (match_operand:DI 0 "push_operand" "")
1880 (match_operand:DI 1 "immediate_operand" ""))]
1881 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1882 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1883 [(set (match_dup 0) (match_dup 1))
1884 (set (match_dup 2) (match_dup 3))]
1885 "split_di (operands + 1, 1, operands + 2, operands + 3);
1886 operands[1] = gen_lowpart (DImode, operands[2]);
1887 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1888 GEN_INT (4)));
1889 ")
1890
1891 (define_split
1892 [(set (match_operand:DI 0 "push_operand" "")
1893 (match_operand:DI 1 "immediate_operand" ""))]
1894 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1895 ? flow2_completed : reload_completed)
1896 && !symbolic_operand (operands[1], DImode)
1897 && !x86_64_immediate_operand (operands[1], DImode)"
1898 [(set (match_dup 0) (match_dup 1))
1899 (set (match_dup 2) (match_dup 3))]
1900 "split_di (operands + 1, 1, operands + 2, operands + 3);
1901 operands[1] = gen_lowpart (DImode, operands[2]);
1902 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1903 GEN_INT (4)));
1904 ")
1905
1906 (define_insn "*pushdi2_prologue_rex64"
1907 [(set (match_operand:DI 0 "push_operand" "=<")
1908 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1909 (clobber (mem:BLK (scratch)))]
1910 "TARGET_64BIT"
1911 "push{q}\t%1"
1912 [(set_attr "type" "push")
1913 (set_attr "mode" "DI")])
1914
1915 (define_insn "*popdi1_epilogue_rex64"
1916 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1917 (mem:DI (reg:DI SP_REG)))
1918 (set (reg:DI SP_REG)
1919 (plus:DI (reg:DI SP_REG) (const_int 8)))
1920 (clobber (mem:BLK (scratch)))]
1921 "TARGET_64BIT"
1922 "pop{q}\t%0"
1923 [(set_attr "type" "pop")
1924 (set_attr "mode" "DI")])
1925
1926 (define_insn "popdi1"
1927 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1928 (mem:DI (reg:DI SP_REG)))
1929 (set (reg:DI SP_REG)
1930 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1931 "TARGET_64BIT"
1932 "pop{q}\t%0"
1933 [(set_attr "type" "pop")
1934 (set_attr "mode" "DI")])
1935
1936 (define_insn "*movdi_xor_rex64"
1937 [(set (match_operand:DI 0 "register_operand" "=r")
1938 (match_operand:DI 1 "const0_operand" "i"))
1939 (clobber (reg:CC FLAGS_REG))]
1940 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1941 && reload_completed"
1942 "xor{l}\t{%k0, %k0|%k0, %k0}"
1943 [(set_attr "type" "alu1")
1944 (set_attr "mode" "SI")
1945 (set_attr "length_immediate" "0")])
1946
1947 (define_insn "*movdi_or_rex64"
1948 [(set (match_operand:DI 0 "register_operand" "=r")
1949 (match_operand:DI 1 "const_int_operand" "i"))
1950 (clobber (reg:CC FLAGS_REG))]
1951 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1952 && reload_completed
1953 && operands[1] == constm1_rtx"
1954 {
1955 operands[1] = constm1_rtx;
1956 return "or{q}\t{%1, %0|%0, %1}";
1957 }
1958 [(set_attr "type" "alu1")
1959 (set_attr "mode" "DI")
1960 (set_attr "length_immediate" "1")])
1961
1962 (define_insn "*movdi_2"
1963 [(set (match_operand:DI 0 "nonimmediate_operand"
1964 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1965 (match_operand:DI 1 "general_operand"
1966 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1967 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1968 "@
1969 #
1970 #
1971 pxor\t%0, %0
1972 movq\t{%1, %0|%0, %1}
1973 movq\t{%1, %0|%0, %1}
1974 pxor\t%0, %0
1975 movq\t{%1, %0|%0, %1}
1976 movdqa\t{%1, %0|%0, %1}
1977 movq\t{%1, %0|%0, %1}
1978 xorps\t%0, %0
1979 movlps\t{%1, %0|%0, %1}
1980 movaps\t{%1, %0|%0, %1}
1981 movlps\t{%1, %0|%0, %1}"
1982 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1983 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1984
1985 (define_split
1986 [(set (match_operand:DI 0 "push_operand" "")
1987 (match_operand:DI 1 "general_operand" ""))]
1988 "!TARGET_64BIT && reload_completed
1989 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1990 [(const_int 0)]
1991 "ix86_split_long_move (operands); DONE;")
1992
1993 ;; %%% This multiword shite has got to go.
1994 (define_split
1995 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1996 (match_operand:DI 1 "general_operand" ""))]
1997 "!TARGET_64BIT && reload_completed
1998 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1999 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2000 [(const_int 0)]
2001 "ix86_split_long_move (operands); DONE;")
2002
2003 (define_insn "*movdi_1_rex64"
2004 [(set (match_operand:DI 0 "nonimmediate_operand"
2005 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2006 (match_operand:DI 1 "general_operand"
2007 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2008 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2009 {
2010 switch (get_attr_type (insn))
2011 {
2012 case TYPE_SSECVT:
2013 if (which_alternative == 13)
2014 return "movq2dq\t{%1, %0|%0, %1}";
2015 else
2016 return "movdq2q\t{%1, %0|%0, %1}";
2017 case TYPE_SSEMOV:
2018 if (get_attr_mode (insn) == MODE_TI)
2019 return "movdqa\t{%1, %0|%0, %1}";
2020 /* FALLTHRU */
2021 case TYPE_MMXMOV:
2022 /* Moves from and into integer register is done using movd opcode with
2023 REX prefix. */
2024 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2025 return "movd\t{%1, %0|%0, %1}";
2026 return "movq\t{%1, %0|%0, %1}";
2027 case TYPE_SSELOG1:
2028 case TYPE_MMXADD:
2029 return "pxor\t%0, %0";
2030 case TYPE_MULTI:
2031 return "#";
2032 case TYPE_LEA:
2033 return "lea{q}\t{%a1, %0|%0, %a1}";
2034 default:
2035 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2036 if (get_attr_mode (insn) == MODE_SI)
2037 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2038 else if (which_alternative == 2)
2039 return "movabs{q}\t{%1, %0|%0, %1}";
2040 else
2041 return "mov{q}\t{%1, %0|%0, %1}";
2042 }
2043 }
2044 [(set (attr "type")
2045 (cond [(eq_attr "alternative" "5")
2046 (const_string "mmxadd")
2047 (eq_attr "alternative" "6,7,8")
2048 (const_string "mmxmov")
2049 (eq_attr "alternative" "9")
2050 (const_string "sselog1")
2051 (eq_attr "alternative" "10,11,12")
2052 (const_string "ssemov")
2053 (eq_attr "alternative" "13,14")
2054 (const_string "ssecvt")
2055 (eq_attr "alternative" "4")
2056 (const_string "multi")
2057 (match_operand:DI 1 "pic_32bit_operand" "")
2058 (const_string "lea")
2059 ]
2060 (const_string "imov")))
2061 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2062 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2063 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2064
2065 ;; Stores and loads of ax to arbitrary constant address.
2066 ;; We fake an second form of instruction to force reload to load address
2067 ;; into register when rax is not available
2068 (define_insn "*movabsdi_1_rex64"
2069 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2070 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2071 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2072 "@
2073 movabs{q}\t{%1, %P0|%P0, %1}
2074 mov{q}\t{%1, %a0|%a0, %1}"
2075 [(set_attr "type" "imov")
2076 (set_attr "modrm" "0,*")
2077 (set_attr "length_address" "8,0")
2078 (set_attr "length_immediate" "0,*")
2079 (set_attr "memory" "store")
2080 (set_attr "mode" "DI")])
2081
2082 (define_insn "*movabsdi_2_rex64"
2083 [(set (match_operand:DI 0 "register_operand" "=a,r")
2084 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2085 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2086 "@
2087 movabs{q}\t{%P1, %0|%0, %P1}
2088 mov{q}\t{%a1, %0|%0, %a1}"
2089 [(set_attr "type" "imov")
2090 (set_attr "modrm" "0,*")
2091 (set_attr "length_address" "8,0")
2092 (set_attr "length_immediate" "0")
2093 (set_attr "memory" "load")
2094 (set_attr "mode" "DI")])
2095
2096 ;; Convert impossible stores of immediate to existing instructions.
2097 ;; First try to get scratch register and go through it. In case this
2098 ;; fails, move by 32bit parts.
2099 (define_peephole2
2100 [(match_scratch:DI 2 "r")
2101 (set (match_operand:DI 0 "memory_operand" "")
2102 (match_operand:DI 1 "immediate_operand" ""))]
2103 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2104 && !x86_64_immediate_operand (operands[1], DImode)"
2105 [(set (match_dup 2) (match_dup 1))
2106 (set (match_dup 0) (match_dup 2))]
2107 "")
2108
2109 ;; We need to define this as both peepholer and splitter for case
2110 ;; peephole2 pass is not run.
2111 ;; "&& 1" is needed to keep it from matching the previous pattern.
2112 (define_peephole2
2113 [(set (match_operand:DI 0 "memory_operand" "")
2114 (match_operand:DI 1 "immediate_operand" ""))]
2115 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2116 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2117 [(set (match_dup 2) (match_dup 3))
2118 (set (match_dup 4) (match_dup 5))]
2119 "split_di (operands, 2, operands + 2, operands + 4);")
2120
2121 (define_split
2122 [(set (match_operand:DI 0 "memory_operand" "")
2123 (match_operand:DI 1 "immediate_operand" ""))]
2124 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2125 ? flow2_completed : reload_completed)
2126 && !symbolic_operand (operands[1], DImode)
2127 && !x86_64_immediate_operand (operands[1], DImode)"
2128 [(set (match_dup 2) (match_dup 3))
2129 (set (match_dup 4) (match_dup 5))]
2130 "split_di (operands, 2, operands + 2, operands + 4);")
2131
2132 (define_insn "*swapdi_rex64"
2133 [(set (match_operand:DI 0 "register_operand" "+r")
2134 (match_operand:DI 1 "register_operand" "+r"))
2135 (set (match_dup 1)
2136 (match_dup 0))]
2137 "TARGET_64BIT"
2138 "xchg{q}\t%1, %0"
2139 [(set_attr "type" "imov")
2140 (set_attr "mode" "DI")
2141 (set_attr "pent_pair" "np")
2142 (set_attr "athlon_decode" "vector")])
2143
2144 (define_expand "movti"
2145 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2146 (match_operand:TI 1 "nonimmediate_operand" ""))]
2147 "TARGET_SSE || TARGET_64BIT"
2148 {
2149 if (TARGET_64BIT)
2150 ix86_expand_move (TImode, operands);
2151 else
2152 ix86_expand_vector_move (TImode, operands);
2153 DONE;
2154 })
2155
2156 (define_insn "*movti_internal"
2157 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2158 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2159 "TARGET_SSE && !TARGET_64BIT
2160 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2161 {
2162 switch (which_alternative)
2163 {
2164 case 0:
2165 if (get_attr_mode (insn) == MODE_V4SF)
2166 return "xorps\t%0, %0";
2167 else
2168 return "pxor\t%0, %0";
2169 case 1:
2170 case 2:
2171 if (get_attr_mode (insn) == MODE_V4SF)
2172 return "movaps\t{%1, %0|%0, %1}";
2173 else
2174 return "movdqa\t{%1, %0|%0, %1}";
2175 default:
2176 gcc_unreachable ();
2177 }
2178 }
2179 [(set_attr "type" "sselog1,ssemov,ssemov")
2180 (set (attr "mode")
2181 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2182 (ne (symbol_ref "optimize_size") (const_int 0)))
2183 (const_string "V4SF")
2184 (and (eq_attr "alternative" "2")
2185 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2186 (const_int 0)))
2187 (const_string "V4SF")]
2188 (const_string "TI")))])
2189
2190 (define_insn "*movti_rex64"
2191 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2192 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2193 "TARGET_64BIT
2194 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2195 {
2196 switch (which_alternative)
2197 {
2198 case 0:
2199 case 1:
2200 return "#";
2201 case 2:
2202 if (get_attr_mode (insn) == MODE_V4SF)
2203 return "xorps\t%0, %0";
2204 else
2205 return "pxor\t%0, %0";
2206 case 3:
2207 case 4:
2208 if (get_attr_mode (insn) == MODE_V4SF)
2209 return "movaps\t{%1, %0|%0, %1}";
2210 else
2211 return "movdqa\t{%1, %0|%0, %1}";
2212 default:
2213 gcc_unreachable ();
2214 }
2215 }
2216 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2217 (set (attr "mode")
2218 (cond [(eq_attr "alternative" "2,3")
2219 (if_then_else
2220 (ne (symbol_ref "optimize_size")
2221 (const_int 0))
2222 (const_string "V4SF")
2223 (const_string "TI"))
2224 (eq_attr "alternative" "4")
2225 (if_then_else
2226 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2227 (const_int 0))
2228 (ne (symbol_ref "optimize_size")
2229 (const_int 0)))
2230 (const_string "V4SF")
2231 (const_string "TI"))]
2232 (const_string "DI")))])
2233
2234 (define_split
2235 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2236 (match_operand:TI 1 "general_operand" ""))]
2237 "reload_completed && !SSE_REG_P (operands[0])
2238 && !SSE_REG_P (operands[1])"
2239 [(const_int 0)]
2240 "ix86_split_long_move (operands); DONE;")
2241
2242 (define_expand "movsf"
2243 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2244 (match_operand:SF 1 "general_operand" ""))]
2245 ""
2246 "ix86_expand_move (SFmode, operands); DONE;")
2247
2248 (define_insn "*pushsf"
2249 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2250 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2251 "!TARGET_64BIT"
2252 {
2253 /* Anything else should be already split before reg-stack. */
2254 gcc_assert (which_alternative == 1);
2255 return "push{l}\t%1";
2256 }
2257 [(set_attr "type" "multi,push,multi")
2258 (set_attr "unit" "i387,*,*")
2259 (set_attr "mode" "SF,SI,SF")])
2260
2261 (define_insn "*pushsf_rex64"
2262 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2263 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2264 "TARGET_64BIT"
2265 {
2266 /* Anything else should be already split before reg-stack. */
2267 gcc_assert (which_alternative == 1);
2268 return "push{q}\t%q1";
2269 }
2270 [(set_attr "type" "multi,push,multi")
2271 (set_attr "unit" "i387,*,*")
2272 (set_attr "mode" "SF,DI,SF")])
2273
2274 (define_split
2275 [(set (match_operand:SF 0 "push_operand" "")
2276 (match_operand:SF 1 "memory_operand" ""))]
2277 "reload_completed
2278 && MEM_P (operands[1])
2279 && constant_pool_reference_p (operands[1])"
2280 [(set (match_dup 0)
2281 (match_dup 1))]
2282 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2283
2284
2285 ;; %%% Kill this when call knows how to work this out.
2286 (define_split
2287 [(set (match_operand:SF 0 "push_operand" "")
2288 (match_operand:SF 1 "any_fp_register_operand" ""))]
2289 "!TARGET_64BIT"
2290 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2291 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2292
2293 (define_split
2294 [(set (match_operand:SF 0 "push_operand" "")
2295 (match_operand:SF 1 "any_fp_register_operand" ""))]
2296 "TARGET_64BIT"
2297 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2298 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2299
2300 (define_insn "*movsf_1"
2301 [(set (match_operand:SF 0 "nonimmediate_operand"
2302 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2303 (match_operand:SF 1 "general_operand"
2304 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2305 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2306 && (reload_in_progress || reload_completed
2307 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2308 || (!TARGET_SSE_MATH && optimize_size
2309 && standard_80387_constant_p (operands[1]))
2310 || GET_CODE (operands[1]) != CONST_DOUBLE
2311 || memory_operand (operands[0], SFmode))"
2312 {
2313 switch (which_alternative)
2314 {
2315 case 0:
2316 return output_387_reg_move (insn, operands);
2317
2318 case 1:
2319 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2320 return "fstp%z0\t%y0";
2321 else
2322 return "fst%z0\t%y0";
2323
2324 case 2:
2325 return standard_80387_constant_opcode (operands[1]);
2326
2327 case 3:
2328 case 4:
2329 return "mov{l}\t{%1, %0|%0, %1}";
2330 case 5:
2331 if (get_attr_mode (insn) == MODE_TI)
2332 return "pxor\t%0, %0";
2333 else
2334 return "xorps\t%0, %0";
2335 case 6:
2336 if (get_attr_mode (insn) == MODE_V4SF)
2337 return "movaps\t{%1, %0|%0, %1}";
2338 else
2339 return "movss\t{%1, %0|%0, %1}";
2340 case 7:
2341 case 8:
2342 return "movss\t{%1, %0|%0, %1}";
2343
2344 case 9:
2345 case 10:
2346 return "movd\t{%1, %0|%0, %1}";
2347
2348 case 11:
2349 return "movq\t{%1, %0|%0, %1}";
2350
2351 default:
2352 gcc_unreachable ();
2353 }
2354 }
2355 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2356 (set (attr "mode")
2357 (cond [(eq_attr "alternative" "3,4,9,10")
2358 (const_string "SI")
2359 (eq_attr "alternative" "5")
2360 (if_then_else
2361 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2362 (const_int 0))
2363 (ne (symbol_ref "TARGET_SSE2")
2364 (const_int 0)))
2365 (eq (symbol_ref "optimize_size")
2366 (const_int 0)))
2367 (const_string "TI")
2368 (const_string "V4SF"))
2369 /* For architectures resolving dependencies on
2370 whole SSE registers use APS move to break dependency
2371 chains, otherwise use short move to avoid extra work.
2372
2373 Do the same for architectures resolving dependencies on
2374 the parts. While in DF mode it is better to always handle
2375 just register parts, the SF mode is different due to lack
2376 of instructions to load just part of the register. It is
2377 better to maintain the whole registers in single format
2378 to avoid problems on using packed logical operations. */
2379 (eq_attr "alternative" "6")
2380 (if_then_else
2381 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2382 (const_int 0))
2383 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2384 (const_int 0)))
2385 (const_string "V4SF")
2386 (const_string "SF"))
2387 (eq_attr "alternative" "11")
2388 (const_string "DI")]
2389 (const_string "SF")))])
2390
2391 (define_insn "*swapsf"
2392 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2393 (match_operand:SF 1 "fp_register_operand" "+f"))
2394 (set (match_dup 1)
2395 (match_dup 0))]
2396 "reload_completed || TARGET_80387"
2397 {
2398 if (STACK_TOP_P (operands[0]))
2399 return "fxch\t%1";
2400 else
2401 return "fxch\t%0";
2402 }
2403 [(set_attr "type" "fxch")
2404 (set_attr "mode" "SF")])
2405
2406 (define_expand "movdf"
2407 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2408 (match_operand:DF 1 "general_operand" ""))]
2409 ""
2410 "ix86_expand_move (DFmode, operands); DONE;")
2411
2412 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2413 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2414 ;; On the average, pushdf using integers can be still shorter. Allow this
2415 ;; pattern for optimize_size too.
2416
2417 (define_insn "*pushdf_nointeger"
2418 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2419 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2420 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2421 {
2422 /* This insn should be already split before reg-stack. */
2423 gcc_unreachable ();
2424 }
2425 [(set_attr "type" "multi")
2426 (set_attr "unit" "i387,*,*,*")
2427 (set_attr "mode" "DF,SI,SI,DF")])
2428
2429 (define_insn "*pushdf_integer"
2430 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2431 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2432 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2433 {
2434 /* This insn should be already split before reg-stack. */
2435 gcc_unreachable ();
2436 }
2437 [(set_attr "type" "multi")
2438 (set_attr "unit" "i387,*,*")
2439 (set_attr "mode" "DF,SI,DF")])
2440
2441 ;; %%% Kill this when call knows how to work this out.
2442 (define_split
2443 [(set (match_operand:DF 0 "push_operand" "")
2444 (match_operand:DF 1 "any_fp_register_operand" ""))]
2445 "!TARGET_64BIT && reload_completed"
2446 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2447 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2448 "")
2449
2450 (define_split
2451 [(set (match_operand:DF 0 "push_operand" "")
2452 (match_operand:DF 1 "any_fp_register_operand" ""))]
2453 "TARGET_64BIT && reload_completed"
2454 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2455 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2456 "")
2457
2458 (define_split
2459 [(set (match_operand:DF 0 "push_operand" "")
2460 (match_operand:DF 1 "general_operand" ""))]
2461 "reload_completed"
2462 [(const_int 0)]
2463 "ix86_split_long_move (operands); DONE;")
2464
2465 ;; Moving is usually shorter when only FP registers are used. This separate
2466 ;; movdf pattern avoids the use of integer registers for FP operations
2467 ;; when optimizing for size.
2468
2469 (define_insn "*movdf_nointeger"
2470 [(set (match_operand:DF 0 "nonimmediate_operand"
2471 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2472 (match_operand:DF 1 "general_operand"
2473 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2474 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2475 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2476 && (reload_in_progress || reload_completed
2477 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2478 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2479 && standard_80387_constant_p (operands[1]))
2480 || GET_CODE (operands[1]) != CONST_DOUBLE
2481 || memory_operand (operands[0], DFmode))"
2482 {
2483 switch (which_alternative)
2484 {
2485 case 0:
2486 return output_387_reg_move (insn, operands);
2487
2488 case 1:
2489 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2490 return "fstp%z0\t%y0";
2491 else
2492 return "fst%z0\t%y0";
2493
2494 case 2:
2495 return standard_80387_constant_opcode (operands[1]);
2496
2497 case 3:
2498 case 4:
2499 return "#";
2500 case 5:
2501 switch (get_attr_mode (insn))
2502 {
2503 case MODE_V4SF:
2504 return "xorps\t%0, %0";
2505 case MODE_V2DF:
2506 return "xorpd\t%0, %0";
2507 case MODE_TI:
2508 return "pxor\t%0, %0";
2509 default:
2510 gcc_unreachable ();
2511 }
2512 case 6:
2513 case 7:
2514 case 8:
2515 switch (get_attr_mode (insn))
2516 {
2517 case MODE_V4SF:
2518 return "movaps\t{%1, %0|%0, %1}";
2519 case MODE_V2DF:
2520 return "movapd\t{%1, %0|%0, %1}";
2521 case MODE_TI:
2522 return "movdqa\t{%1, %0|%0, %1}";
2523 case MODE_DI:
2524 return "movq\t{%1, %0|%0, %1}";
2525 case MODE_DF:
2526 return "movsd\t{%1, %0|%0, %1}";
2527 case MODE_V1DF:
2528 return "movlpd\t{%1, %0|%0, %1}";
2529 case MODE_V2SF:
2530 return "movlps\t{%1, %0|%0, %1}";
2531 default:
2532 gcc_unreachable ();
2533 }
2534
2535 default:
2536 gcc_unreachable ();
2537 }
2538 }
2539 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2540 (set (attr "mode")
2541 (cond [(eq_attr "alternative" "0,1,2")
2542 (const_string "DF")
2543 (eq_attr "alternative" "3,4")
2544 (const_string "SI")
2545
2546 /* For SSE1, we have many fewer alternatives. */
2547 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2548 (cond [(eq_attr "alternative" "5,6")
2549 (const_string "V4SF")
2550 ]
2551 (const_string "V2SF"))
2552
2553 /* xorps is one byte shorter. */
2554 (eq_attr "alternative" "5")
2555 (cond [(ne (symbol_ref "optimize_size")
2556 (const_int 0))
2557 (const_string "V4SF")
2558 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2559 (const_int 0))
2560 (const_string "TI")
2561 ]
2562 (const_string "V2DF"))
2563
2564 /* For architectures resolving dependencies on
2565 whole SSE registers use APD move to break dependency
2566 chains, otherwise use short move to avoid extra work.
2567
2568 movaps encodes one byte shorter. */
2569 (eq_attr "alternative" "6")
2570 (cond
2571 [(ne (symbol_ref "optimize_size")
2572 (const_int 0))
2573 (const_string "V4SF")
2574 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2575 (const_int 0))
2576 (const_string "V2DF")
2577 ]
2578 (const_string "DF"))
2579 /* For architectures resolving dependencies on register
2580 parts we may avoid extra work to zero out upper part
2581 of register. */
2582 (eq_attr "alternative" "7")
2583 (if_then_else
2584 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2585 (const_int 0))
2586 (const_string "V1DF")
2587 (const_string "DF"))
2588 ]
2589 (const_string "DF")))])
2590
2591 (define_insn "*movdf_integer"
2592 [(set (match_operand:DF 0 "nonimmediate_operand"
2593 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2594 (match_operand:DF 1 "general_operand"
2595 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2596 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2597 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2598 && (reload_in_progress || reload_completed
2599 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2600 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2601 && standard_80387_constant_p (operands[1]))
2602 || GET_CODE (operands[1]) != CONST_DOUBLE
2603 || memory_operand (operands[0], DFmode))"
2604 {
2605 switch (which_alternative)
2606 {
2607 case 0:
2608 return output_387_reg_move (insn, operands);
2609
2610 case 1:
2611 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2612 return "fstp%z0\t%y0";
2613 else
2614 return "fst%z0\t%y0";
2615
2616 case 2:
2617 return standard_80387_constant_opcode (operands[1]);
2618
2619 case 3:
2620 case 4:
2621 return "#";
2622
2623 case 5:
2624 switch (get_attr_mode (insn))
2625 {
2626 case MODE_V4SF:
2627 return "xorps\t%0, %0";
2628 case MODE_V2DF:
2629 return "xorpd\t%0, %0";
2630 case MODE_TI:
2631 return "pxor\t%0, %0";
2632 default:
2633 gcc_unreachable ();
2634 }
2635 case 6:
2636 case 7:
2637 case 8:
2638 switch (get_attr_mode (insn))
2639 {
2640 case MODE_V4SF:
2641 return "movaps\t{%1, %0|%0, %1}";
2642 case MODE_V2DF:
2643 return "movapd\t{%1, %0|%0, %1}";
2644 case MODE_TI:
2645 return "movdqa\t{%1, %0|%0, %1}";
2646 case MODE_DI:
2647 return "movq\t{%1, %0|%0, %1}";
2648 case MODE_DF:
2649 return "movsd\t{%1, %0|%0, %1}";
2650 case MODE_V1DF:
2651 return "movlpd\t{%1, %0|%0, %1}";
2652 case MODE_V2SF:
2653 return "movlps\t{%1, %0|%0, %1}";
2654 default:
2655 gcc_unreachable ();
2656 }
2657
2658 default:
2659 gcc_unreachable();
2660 }
2661 }
2662 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2663 (set (attr "mode")
2664 (cond [(eq_attr "alternative" "0,1,2")
2665 (const_string "DF")
2666 (eq_attr "alternative" "3,4")
2667 (const_string "SI")
2668
2669 /* For SSE1, we have many fewer alternatives. */
2670 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2671 (cond [(eq_attr "alternative" "5,6")
2672 (const_string "V4SF")
2673 ]
2674 (const_string "V2SF"))
2675
2676 /* xorps is one byte shorter. */
2677 (eq_attr "alternative" "5")
2678 (cond [(ne (symbol_ref "optimize_size")
2679 (const_int 0))
2680 (const_string "V4SF")
2681 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2682 (const_int 0))
2683 (const_string "TI")
2684 ]
2685 (const_string "V2DF"))
2686
2687 /* For architectures resolving dependencies on
2688 whole SSE registers use APD move to break dependency
2689 chains, otherwise use short move to avoid extra work.
2690
2691 movaps encodes one byte shorter. */
2692 (eq_attr "alternative" "6")
2693 (cond
2694 [(ne (symbol_ref "optimize_size")
2695 (const_int 0))
2696 (const_string "V4SF")
2697 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2698 (const_int 0))
2699 (const_string "V2DF")
2700 ]
2701 (const_string "DF"))
2702 /* For architectures resolving dependencies on register
2703 parts we may avoid extra work to zero out upper part
2704 of register. */
2705 (eq_attr "alternative" "7")
2706 (if_then_else
2707 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2708 (const_int 0))
2709 (const_string "V1DF")
2710 (const_string "DF"))
2711 ]
2712 (const_string "DF")))])
2713
2714 (define_split
2715 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2716 (match_operand:DF 1 "general_operand" ""))]
2717 "reload_completed
2718 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2719 && ! (ANY_FP_REG_P (operands[0]) ||
2720 (GET_CODE (operands[0]) == SUBREG
2721 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2722 && ! (ANY_FP_REG_P (operands[1]) ||
2723 (GET_CODE (operands[1]) == SUBREG
2724 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2725 [(const_int 0)]
2726 "ix86_split_long_move (operands); DONE;")
2727
2728 (define_insn "*swapdf"
2729 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2730 (match_operand:DF 1 "fp_register_operand" "+f"))
2731 (set (match_dup 1)
2732 (match_dup 0))]
2733 "reload_completed || TARGET_80387"
2734 {
2735 if (STACK_TOP_P (operands[0]))
2736 return "fxch\t%1";
2737 else
2738 return "fxch\t%0";
2739 }
2740 [(set_attr "type" "fxch")
2741 (set_attr "mode" "DF")])
2742
2743 (define_expand "movxf"
2744 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2745 (match_operand:XF 1 "general_operand" ""))]
2746 ""
2747 "ix86_expand_move (XFmode, operands); DONE;")
2748
2749 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2750 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2751 ;; Pushing using integer instructions is longer except for constants
2752 ;; and direct memory references.
2753 ;; (assuming that any given constant is pushed only once, but this ought to be
2754 ;; handled elsewhere).
2755
2756 (define_insn "*pushxf_nointeger"
2757 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2758 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2759 "optimize_size"
2760 {
2761 /* This insn should be already split before reg-stack. */
2762 gcc_unreachable ();
2763 }
2764 [(set_attr "type" "multi")
2765 (set_attr "unit" "i387,*,*")
2766 (set_attr "mode" "XF,SI,SI")])
2767
2768 (define_insn "*pushxf_integer"
2769 [(set (match_operand:XF 0 "push_operand" "=<,<")
2770 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2771 "!optimize_size"
2772 {
2773 /* This insn should be already split before reg-stack. */
2774 gcc_unreachable ();
2775 }
2776 [(set_attr "type" "multi")
2777 (set_attr "unit" "i387,*")
2778 (set_attr "mode" "XF,SI")])
2779
2780 (define_split
2781 [(set (match_operand 0 "push_operand" "")
2782 (match_operand 1 "general_operand" ""))]
2783 "reload_completed
2784 && (GET_MODE (operands[0]) == XFmode
2785 || GET_MODE (operands[0]) == DFmode)
2786 && !ANY_FP_REG_P (operands[1])"
2787 [(const_int 0)]
2788 "ix86_split_long_move (operands); DONE;")
2789
2790 (define_split
2791 [(set (match_operand:XF 0 "push_operand" "")
2792 (match_operand:XF 1 "any_fp_register_operand" ""))]
2793 "!TARGET_64BIT"
2794 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2795 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2796 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2797
2798 (define_split
2799 [(set (match_operand:XF 0 "push_operand" "")
2800 (match_operand:XF 1 "any_fp_register_operand" ""))]
2801 "TARGET_64BIT"
2802 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2803 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2804 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2805
2806 ;; Do not use integer registers when optimizing for size
2807 (define_insn "*movxf_nointeger"
2808 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2809 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2810 "optimize_size
2811 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2812 && (reload_in_progress || reload_completed
2813 || (optimize_size && standard_80387_constant_p (operands[1]))
2814 || GET_CODE (operands[1]) != CONST_DOUBLE
2815 || memory_operand (operands[0], XFmode))"
2816 {
2817 switch (which_alternative)
2818 {
2819 case 0:
2820 return output_387_reg_move (insn, operands);
2821
2822 case 1:
2823 /* There is no non-popping store to memory for XFmode. So if
2824 we need one, follow the store with a load. */
2825 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2826 return "fstp%z0\t%y0\;fld%z0\t%y0";
2827 else
2828 return "fstp%z0\t%y0";
2829
2830 case 2:
2831 return standard_80387_constant_opcode (operands[1]);
2832
2833 case 3: case 4:
2834 return "#";
2835 default:
2836 gcc_unreachable ();
2837 }
2838 }
2839 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2840 (set_attr "mode" "XF,XF,XF,SI,SI")])
2841
2842 (define_insn "*movxf_integer"
2843 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2844 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2845 "!optimize_size
2846 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2847 && (reload_in_progress || reload_completed
2848 || (optimize_size && standard_80387_constant_p (operands[1]))
2849 || GET_CODE (operands[1]) != CONST_DOUBLE
2850 || memory_operand (operands[0], XFmode))"
2851 {
2852 switch (which_alternative)
2853 {
2854 case 0:
2855 return output_387_reg_move (insn, operands);
2856
2857 case 1:
2858 /* There is no non-popping store to memory for XFmode. So if
2859 we need one, follow the store with a load. */
2860 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2861 return "fstp%z0\t%y0\;fld%z0\t%y0";
2862 else
2863 return "fstp%z0\t%y0";
2864
2865 case 2:
2866 return standard_80387_constant_opcode (operands[1]);
2867
2868 case 3: case 4:
2869 return "#";
2870
2871 default:
2872 gcc_unreachable ();
2873 }
2874 }
2875 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2876 (set_attr "mode" "XF,XF,XF,SI,SI")])
2877
2878 (define_split
2879 [(set (match_operand 0 "nonimmediate_operand" "")
2880 (match_operand 1 "general_operand" ""))]
2881 "reload_completed
2882 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2883 && GET_MODE (operands[0]) == XFmode
2884 && ! (ANY_FP_REG_P (operands[0]) ||
2885 (GET_CODE (operands[0]) == SUBREG
2886 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2887 && ! (ANY_FP_REG_P (operands[1]) ||
2888 (GET_CODE (operands[1]) == SUBREG
2889 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2890 [(const_int 0)]
2891 "ix86_split_long_move (operands); DONE;")
2892
2893 (define_split
2894 [(set (match_operand 0 "register_operand" "")
2895 (match_operand 1 "memory_operand" ""))]
2896 "reload_completed
2897 && MEM_P (operands[1])
2898 && (GET_MODE (operands[0]) == XFmode
2899 || GET_MODE (operands[0]) == SFmode
2900 || GET_MODE (operands[0]) == DFmode)
2901 && constant_pool_reference_p (operands[1])"
2902 [(set (match_dup 0) (match_dup 1))]
2903 {
2904 rtx c = avoid_constant_pool_reference (operands[1]);
2905 rtx r = operands[0];
2906
2907 if (GET_CODE (r) == SUBREG)
2908 r = SUBREG_REG (r);
2909
2910 if (SSE_REG_P (r))
2911 {
2912 if (!standard_sse_constant_p (c))
2913 FAIL;
2914 }
2915 else if (FP_REG_P (r))
2916 {
2917 if (!standard_80387_constant_p (c))
2918 FAIL;
2919 }
2920 else if (MMX_REG_P (r))
2921 FAIL;
2922
2923 operands[1] = c;
2924 })
2925
2926 (define_split
2927 [(set (match_operand 0 "register_operand" "")
2928 (float_extend (match_operand 1 "memory_operand" "")))]
2929 "reload_completed
2930 && MEM_P (operands[1])
2931 && (GET_MODE (operands[0]) == XFmode
2932 || GET_MODE (operands[0]) == SFmode
2933 || GET_MODE (operands[0]) == DFmode)
2934 && constant_pool_reference_p (operands[1])"
2935 [(set (match_dup 0) (match_dup 1))]
2936 {
2937 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2938 rtx r = operands[0];
2939
2940 if (GET_CODE (r) == SUBREG)
2941 r = SUBREG_REG (r);
2942
2943 if (SSE_REG_P (r))
2944 {
2945 if (!standard_sse_constant_p (c))
2946 FAIL;
2947 }
2948 else if (FP_REG_P (r))
2949 {
2950 if (!standard_80387_constant_p (c))
2951 FAIL;
2952 }
2953 else if (MMX_REG_P (r))
2954 FAIL;
2955
2956 operands[1] = c;
2957 })
2958
2959 (define_insn "swapxf"
2960 [(set (match_operand:XF 0 "register_operand" "+f")
2961 (match_operand:XF 1 "register_operand" "+f"))
2962 (set (match_dup 1)
2963 (match_dup 0))]
2964 "TARGET_80387"
2965 {
2966 if (STACK_TOP_P (operands[0]))
2967 return "fxch\t%1";
2968 else
2969 return "fxch\t%0";
2970 }
2971 [(set_attr "type" "fxch")
2972 (set_attr "mode" "XF")])
2973
2974 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2975 (define_split
2976 [(set (match_operand:X87MODEF 0 "register_operand" "")
2977 (match_operand:X87MODEF 1 "immediate_operand" ""))]
2978 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2979 && (standard_80387_constant_p (operands[1]) == 8
2980 || standard_80387_constant_p (operands[1]) == 9)"
2981 [(set (match_dup 0)(match_dup 1))
2982 (set (match_dup 0)
2983 (neg:X87MODEF (match_dup 0)))]
2984 {
2985 REAL_VALUE_TYPE r;
2986
2987 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2988 if (real_isnegzero (&r))
2989 operands[1] = CONST0_RTX (<MODE>mode);
2990 else
2991 operands[1] = CONST1_RTX (<MODE>mode);
2992 })
2993
2994 (define_expand "movtf"
2995 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2996 (match_operand:TF 1 "nonimmediate_operand" ""))]
2997 "TARGET_64BIT"
2998 {
2999 ix86_expand_move (TFmode, operands);
3000 DONE;
3001 })
3002
3003 (define_insn "*movtf_internal"
3004 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3005 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3006 "TARGET_64BIT
3007 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3008 {
3009 switch (which_alternative)
3010 {
3011 case 0:
3012 case 1:
3013 return "#";
3014 case 2:
3015 if (get_attr_mode (insn) == MODE_V4SF)
3016 return "xorps\t%0, %0";
3017 else
3018 return "pxor\t%0, %0";
3019 case 3:
3020 case 4:
3021 if (get_attr_mode (insn) == MODE_V4SF)
3022 return "movaps\t{%1, %0|%0, %1}";
3023 else
3024 return "movdqa\t{%1, %0|%0, %1}";
3025 default:
3026 gcc_unreachable ();
3027 }
3028 }
3029 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3030 (set (attr "mode")
3031 (cond [(eq_attr "alternative" "2,3")
3032 (if_then_else
3033 (ne (symbol_ref "optimize_size")
3034 (const_int 0))
3035 (const_string "V4SF")
3036 (const_string "TI"))
3037 (eq_attr "alternative" "4")
3038 (if_then_else
3039 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3040 (const_int 0))
3041 (ne (symbol_ref "optimize_size")
3042 (const_int 0)))
3043 (const_string "V4SF")
3044 (const_string "TI"))]
3045 (const_string "DI")))])
3046
3047 (define_split
3048 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3049 (match_operand:TF 1 "general_operand" ""))]
3050 "reload_completed && !SSE_REG_P (operands[0])
3051 && !SSE_REG_P (operands[1])"
3052 [(const_int 0)]
3053 "ix86_split_long_move (operands); DONE;")
3054 \f
3055 ;; Zero extension instructions
3056
3057 (define_expand "zero_extendhisi2"
3058 [(set (match_operand:SI 0 "register_operand" "")
3059 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3060 ""
3061 {
3062 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3063 {
3064 operands[1] = force_reg (HImode, operands[1]);
3065 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3066 DONE;
3067 }
3068 })
3069
3070 (define_insn "zero_extendhisi2_and"
3071 [(set (match_operand:SI 0 "register_operand" "=r")
3072 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3073 (clobber (reg:CC FLAGS_REG))]
3074 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3075 "#"
3076 [(set_attr "type" "alu1")
3077 (set_attr "mode" "SI")])
3078
3079 (define_split
3080 [(set (match_operand:SI 0 "register_operand" "")
3081 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3082 (clobber (reg:CC FLAGS_REG))]
3083 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3084 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3085 (clobber (reg:CC FLAGS_REG))])]
3086 "")
3087
3088 (define_insn "*zero_extendhisi2_movzwl"
3089 [(set (match_operand:SI 0 "register_operand" "=r")
3090 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3091 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3092 "movz{wl|x}\t{%1, %0|%0, %1}"
3093 [(set_attr "type" "imovx")
3094 (set_attr "mode" "SI")])
3095
3096 (define_expand "zero_extendqihi2"
3097 [(parallel
3098 [(set (match_operand:HI 0 "register_operand" "")
3099 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3100 (clobber (reg:CC FLAGS_REG))])]
3101 ""
3102 "")
3103
3104 (define_insn "*zero_extendqihi2_and"
3105 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3106 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3107 (clobber (reg:CC FLAGS_REG))]
3108 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3109 "#"
3110 [(set_attr "type" "alu1")
3111 (set_attr "mode" "HI")])
3112
3113 (define_insn "*zero_extendqihi2_movzbw_and"
3114 [(set (match_operand:HI 0 "register_operand" "=r,r")
3115 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3116 (clobber (reg:CC FLAGS_REG))]
3117 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3118 "#"
3119 [(set_attr "type" "imovx,alu1")
3120 (set_attr "mode" "HI")])
3121
3122 ; zero extend to SImode here to avoid partial register stalls
3123 (define_insn "*zero_extendqihi2_movzbl"
3124 [(set (match_operand:HI 0 "register_operand" "=r")
3125 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3126 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3127 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3128 [(set_attr "type" "imovx")
3129 (set_attr "mode" "SI")])
3130
3131 ;; For the movzbw case strip only the clobber
3132 (define_split
3133 [(set (match_operand:HI 0 "register_operand" "")
3134 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3135 (clobber (reg:CC FLAGS_REG))]
3136 "reload_completed
3137 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3138 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3139 [(set (match_operand:HI 0 "register_operand" "")
3140 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3141
3142 ;; When source and destination does not overlap, clear destination
3143 ;; first and then do the movb
3144 (define_split
3145 [(set (match_operand:HI 0 "register_operand" "")
3146 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3147 (clobber (reg:CC FLAGS_REG))]
3148 "reload_completed
3149 && ANY_QI_REG_P (operands[0])
3150 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3151 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3152 [(set (match_dup 0) (const_int 0))
3153 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3154 "operands[2] = gen_lowpart (QImode, operands[0]);")
3155
3156 ;; Rest is handled by single and.
3157 (define_split
3158 [(set (match_operand:HI 0 "register_operand" "")
3159 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3160 (clobber (reg:CC FLAGS_REG))]
3161 "reload_completed
3162 && true_regnum (operands[0]) == true_regnum (operands[1])"
3163 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3164 (clobber (reg:CC FLAGS_REG))])]
3165 "")
3166
3167 (define_expand "zero_extendqisi2"
3168 [(parallel
3169 [(set (match_operand:SI 0 "register_operand" "")
3170 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3171 (clobber (reg:CC FLAGS_REG))])]
3172 ""
3173 "")
3174
3175 (define_insn "*zero_extendqisi2_and"
3176 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3177 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3178 (clobber (reg:CC FLAGS_REG))]
3179 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3180 "#"
3181 [(set_attr "type" "alu1")
3182 (set_attr "mode" "SI")])
3183
3184 (define_insn "*zero_extendqisi2_movzbw_and"
3185 [(set (match_operand:SI 0 "register_operand" "=r,r")
3186 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3187 (clobber (reg:CC FLAGS_REG))]
3188 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3189 "#"
3190 [(set_attr "type" "imovx,alu1")
3191 (set_attr "mode" "SI")])
3192
3193 (define_insn "*zero_extendqisi2_movzbw"
3194 [(set (match_operand:SI 0 "register_operand" "=r")
3195 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3196 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3197 "movz{bl|x}\t{%1, %0|%0, %1}"
3198 [(set_attr "type" "imovx")
3199 (set_attr "mode" "SI")])
3200
3201 ;; For the movzbl case strip only the clobber
3202 (define_split
3203 [(set (match_operand:SI 0 "register_operand" "")
3204 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3205 (clobber (reg:CC FLAGS_REG))]
3206 "reload_completed
3207 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3208 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3209 [(set (match_dup 0)
3210 (zero_extend:SI (match_dup 1)))])
3211
3212 ;; When source and destination does not overlap, clear destination
3213 ;; first and then do the movb
3214 (define_split
3215 [(set (match_operand:SI 0 "register_operand" "")
3216 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3217 (clobber (reg:CC FLAGS_REG))]
3218 "reload_completed
3219 && ANY_QI_REG_P (operands[0])
3220 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3221 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3222 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3223 [(set (match_dup 0) (const_int 0))
3224 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3225 "operands[2] = gen_lowpart (QImode, operands[0]);")
3226
3227 ;; Rest is handled by single and.
3228 (define_split
3229 [(set (match_operand:SI 0 "register_operand" "")
3230 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3231 (clobber (reg:CC FLAGS_REG))]
3232 "reload_completed
3233 && true_regnum (operands[0]) == true_regnum (operands[1])"
3234 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3235 (clobber (reg:CC FLAGS_REG))])]
3236 "")
3237
3238 ;; %%% Kill me once multi-word ops are sane.
3239 (define_expand "zero_extendsidi2"
3240 [(set (match_operand:DI 0 "register_operand" "=r")
3241 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3242 ""
3243 "if (!TARGET_64BIT)
3244 {
3245 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3246 DONE;
3247 }
3248 ")
3249
3250 (define_insn "zero_extendsidi2_32"
3251 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3252 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3253 (clobber (reg:CC FLAGS_REG))]
3254 "!TARGET_64BIT"
3255 "@
3256 #
3257 #
3258 #
3259 movd\t{%1, %0|%0, %1}
3260 movd\t{%1, %0|%0, %1}"
3261 [(set_attr "mode" "SI,SI,SI,DI,TI")
3262 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3263
3264 (define_insn "zero_extendsidi2_rex64"
3265 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3266 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3267 "TARGET_64BIT"
3268 "@
3269 mov\t{%k1, %k0|%k0, %k1}
3270 #
3271 movd\t{%1, %0|%0, %1}
3272 movd\t{%1, %0|%0, %1}"
3273 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3274 (set_attr "mode" "SI,DI,SI,SI")])
3275
3276 (define_split
3277 [(set (match_operand:DI 0 "memory_operand" "")
3278 (zero_extend:DI (match_dup 0)))]
3279 "TARGET_64BIT"
3280 [(set (match_dup 4) (const_int 0))]
3281 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3282
3283 (define_split
3284 [(set (match_operand:DI 0 "register_operand" "")
3285 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3286 (clobber (reg:CC FLAGS_REG))]
3287 "!TARGET_64BIT && reload_completed
3288 && true_regnum (operands[0]) == true_regnum (operands[1])"
3289 [(set (match_dup 4) (const_int 0))]
3290 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3291
3292 (define_split
3293 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3294 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3295 (clobber (reg:CC FLAGS_REG))]
3296 "!TARGET_64BIT && reload_completed
3297 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3298 [(set (match_dup 3) (match_dup 1))
3299 (set (match_dup 4) (const_int 0))]
3300 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3301
3302 (define_insn "zero_extendhidi2"
3303 [(set (match_operand:DI 0 "register_operand" "=r")
3304 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3305 "TARGET_64BIT"
3306 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3307 [(set_attr "type" "imovx")
3308 (set_attr "mode" "DI")])
3309
3310 (define_insn "zero_extendqidi2"
3311 [(set (match_operand:DI 0 "register_operand" "=r")
3312 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3313 "TARGET_64BIT"
3314 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3315 [(set_attr "type" "imovx")
3316 (set_attr "mode" "DI")])
3317 \f
3318 ;; Sign extension instructions
3319
3320 (define_expand "extendsidi2"
3321 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3322 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3323 (clobber (reg:CC FLAGS_REG))
3324 (clobber (match_scratch:SI 2 ""))])]
3325 ""
3326 {
3327 if (TARGET_64BIT)
3328 {
3329 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3330 DONE;
3331 }
3332 })
3333
3334 (define_insn "*extendsidi2_1"
3335 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3336 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3337 (clobber (reg:CC FLAGS_REG))
3338 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3339 "!TARGET_64BIT"
3340 "#")
3341
3342 (define_insn "extendsidi2_rex64"
3343 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3344 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3345 "TARGET_64BIT"
3346 "@
3347 {cltq|cdqe}
3348 movs{lq|x}\t{%1,%0|%0, %1}"
3349 [(set_attr "type" "imovx")
3350 (set_attr "mode" "DI")
3351 (set_attr "prefix_0f" "0")
3352 (set_attr "modrm" "0,1")])
3353
3354 (define_insn "extendhidi2"
3355 [(set (match_operand:DI 0 "register_operand" "=r")
3356 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3357 "TARGET_64BIT"
3358 "movs{wq|x}\t{%1,%0|%0, %1}"
3359 [(set_attr "type" "imovx")
3360 (set_attr "mode" "DI")])
3361
3362 (define_insn "extendqidi2"
3363 [(set (match_operand:DI 0 "register_operand" "=r")
3364 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3365 "TARGET_64BIT"
3366 "movs{bq|x}\t{%1,%0|%0, %1}"
3367 [(set_attr "type" "imovx")
3368 (set_attr "mode" "DI")])
3369
3370 ;; Extend to memory case when source register does die.
3371 (define_split
3372 [(set (match_operand:DI 0 "memory_operand" "")
3373 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3374 (clobber (reg:CC FLAGS_REG))
3375 (clobber (match_operand:SI 2 "register_operand" ""))]
3376 "(reload_completed
3377 && dead_or_set_p (insn, operands[1])
3378 && !reg_mentioned_p (operands[1], operands[0]))"
3379 [(set (match_dup 3) (match_dup 1))
3380 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3381 (clobber (reg:CC FLAGS_REG))])
3382 (set (match_dup 4) (match_dup 1))]
3383 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3384
3385 ;; Extend to memory case when source register does not die.
3386 (define_split
3387 [(set (match_operand:DI 0 "memory_operand" "")
3388 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3389 (clobber (reg:CC FLAGS_REG))
3390 (clobber (match_operand:SI 2 "register_operand" ""))]
3391 "reload_completed"
3392 [(const_int 0)]
3393 {
3394 split_di (&operands[0], 1, &operands[3], &operands[4]);
3395
3396 emit_move_insn (operands[3], operands[1]);
3397
3398 /* Generate a cltd if possible and doing so it profitable. */
3399 if (true_regnum (operands[1]) == 0
3400 && true_regnum (operands[2]) == 1
3401 && (optimize_size || TARGET_USE_CLTD))
3402 {
3403 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3404 }
3405 else
3406 {
3407 emit_move_insn (operands[2], operands[1]);
3408 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3409 }
3410 emit_move_insn (operands[4], operands[2]);
3411 DONE;
3412 })
3413
3414 ;; Extend to register case. Optimize case where source and destination
3415 ;; registers match and cases where we can use cltd.
3416 (define_split
3417 [(set (match_operand:DI 0 "register_operand" "")
3418 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3419 (clobber (reg:CC FLAGS_REG))
3420 (clobber (match_scratch:SI 2 ""))]
3421 "reload_completed"
3422 [(const_int 0)]
3423 {
3424 split_di (&operands[0], 1, &operands[3], &operands[4]);
3425
3426 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3427 emit_move_insn (operands[3], operands[1]);
3428
3429 /* Generate a cltd if possible and doing so it profitable. */
3430 if (true_regnum (operands[3]) == 0
3431 && (optimize_size || TARGET_USE_CLTD))
3432 {
3433 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3434 DONE;
3435 }
3436
3437 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3438 emit_move_insn (operands[4], operands[1]);
3439
3440 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3441 DONE;
3442 })
3443
3444 (define_insn "extendhisi2"
3445 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3446 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3447 ""
3448 {
3449 switch (get_attr_prefix_0f (insn))
3450 {
3451 case 0:
3452 return "{cwtl|cwde}";
3453 default:
3454 return "movs{wl|x}\t{%1,%0|%0, %1}";
3455 }
3456 }
3457 [(set_attr "type" "imovx")
3458 (set_attr "mode" "SI")
3459 (set (attr "prefix_0f")
3460 ;; movsx is short decodable while cwtl is vector decoded.
3461 (if_then_else (and (eq_attr "cpu" "!k6")
3462 (eq_attr "alternative" "0"))
3463 (const_string "0")
3464 (const_string "1")))
3465 (set (attr "modrm")
3466 (if_then_else (eq_attr "prefix_0f" "0")
3467 (const_string "0")
3468 (const_string "1")))])
3469
3470 (define_insn "*extendhisi2_zext"
3471 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3472 (zero_extend:DI
3473 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3474 "TARGET_64BIT"
3475 {
3476 switch (get_attr_prefix_0f (insn))
3477 {
3478 case 0:
3479 return "{cwtl|cwde}";
3480 default:
3481 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3482 }
3483 }
3484 [(set_attr "type" "imovx")
3485 (set_attr "mode" "SI")
3486 (set (attr "prefix_0f")
3487 ;; movsx is short decodable while cwtl is vector decoded.
3488 (if_then_else (and (eq_attr "cpu" "!k6")
3489 (eq_attr "alternative" "0"))
3490 (const_string "0")
3491 (const_string "1")))
3492 (set (attr "modrm")
3493 (if_then_else (eq_attr "prefix_0f" "0")
3494 (const_string "0")
3495 (const_string "1")))])
3496
3497 (define_insn "extendqihi2"
3498 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3499 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3500 ""
3501 {
3502 switch (get_attr_prefix_0f (insn))
3503 {
3504 case 0:
3505 return "{cbtw|cbw}";
3506 default:
3507 return "movs{bw|x}\t{%1,%0|%0, %1}";
3508 }
3509 }
3510 [(set_attr "type" "imovx")
3511 (set_attr "mode" "HI")
3512 (set (attr "prefix_0f")
3513 ;; movsx is short decodable while cwtl is vector decoded.
3514 (if_then_else (and (eq_attr "cpu" "!k6")
3515 (eq_attr "alternative" "0"))
3516 (const_string "0")
3517 (const_string "1")))
3518 (set (attr "modrm")
3519 (if_then_else (eq_attr "prefix_0f" "0")
3520 (const_string "0")
3521 (const_string "1")))])
3522
3523 (define_insn "extendqisi2"
3524 [(set (match_operand:SI 0 "register_operand" "=r")
3525 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3526 ""
3527 "movs{bl|x}\t{%1,%0|%0, %1}"
3528 [(set_attr "type" "imovx")
3529 (set_attr "mode" "SI")])
3530
3531 (define_insn "*extendqisi2_zext"
3532 [(set (match_operand:DI 0 "register_operand" "=r")
3533 (zero_extend:DI
3534 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3535 "TARGET_64BIT"
3536 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3537 [(set_attr "type" "imovx")
3538 (set_attr "mode" "SI")])
3539 \f
3540 ;; Conversions between float and double.
3541
3542 ;; These are all no-ops in the model used for the 80387. So just
3543 ;; emit moves.
3544
3545 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3546 (define_insn "*dummy_extendsfdf2"
3547 [(set (match_operand:DF 0 "push_operand" "=<")
3548 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3549 "0"
3550 "#")
3551
3552 (define_split
3553 [(set (match_operand:DF 0 "push_operand" "")
3554 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3555 "!TARGET_64BIT"
3556 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3557 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3558
3559 (define_split
3560 [(set (match_operand:DF 0 "push_operand" "")
3561 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3562 "TARGET_64BIT"
3563 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3564 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3565
3566 (define_insn "*dummy_extendsfxf2"
3567 [(set (match_operand:XF 0 "push_operand" "=<")
3568 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3569 "0"
3570 "#")
3571
3572 (define_split
3573 [(set (match_operand:XF 0 "push_operand" "")
3574 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3575 ""
3576 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3577 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3578 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3579
3580 (define_split
3581 [(set (match_operand:XF 0 "push_operand" "")
3582 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3583 "TARGET_64BIT"
3584 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3585 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3586 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3587
3588 (define_split
3589 [(set (match_operand:XF 0 "push_operand" "")
3590 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3591 ""
3592 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3593 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3594 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3595
3596 (define_split
3597 [(set (match_operand:XF 0 "push_operand" "")
3598 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3599 "TARGET_64BIT"
3600 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3601 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3602 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3603
3604 (define_expand "extendsfdf2"
3605 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3606 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3607 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3608 {
3609 /* ??? Needed for compress_float_constant since all fp constants
3610 are LEGITIMATE_CONSTANT_P. */
3611 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3612 {
3613 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3614 && standard_80387_constant_p (operands[1]) > 0)
3615 {
3616 operands[1] = simplify_const_unary_operation
3617 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3618 emit_move_insn_1 (operands[0], operands[1]);
3619 DONE;
3620 }
3621 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3622 }
3623 })
3624
3625 (define_insn "*extendsfdf2_mixed"
3626 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3627 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3628 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3629 {
3630 switch (which_alternative)
3631 {
3632 case 0:
3633 return output_387_reg_move (insn, operands);
3634
3635 case 1:
3636 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637 return "fstp%z0\t%y0";
3638 else
3639 return "fst%z0\t%y0";
3640
3641 case 2:
3642 return "cvtss2sd\t{%1, %0|%0, %1}";
3643
3644 default:
3645 gcc_unreachable ();
3646 }
3647 }
3648 [(set_attr "type" "fmov,fmov,ssecvt")
3649 (set_attr "mode" "SF,XF,DF")])
3650
3651 (define_insn "*extendsfdf2_sse"
3652 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3653 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3654 "TARGET_SSE2 && TARGET_SSE_MATH"
3655 "cvtss2sd\t{%1, %0|%0, %1}"
3656 [(set_attr "type" "ssecvt")
3657 (set_attr "mode" "DF")])
3658
3659 (define_insn "*extendsfdf2_i387"
3660 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3661 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3662 "TARGET_80387"
3663 {
3664 switch (which_alternative)
3665 {
3666 case 0:
3667 return output_387_reg_move (insn, operands);
3668
3669 case 1:
3670 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3671 return "fstp%z0\t%y0";
3672 else
3673 return "fst%z0\t%y0";
3674
3675 default:
3676 gcc_unreachable ();
3677 }
3678 }
3679 [(set_attr "type" "fmov")
3680 (set_attr "mode" "SF,XF")])
3681
3682 (define_expand "extendsfxf2"
3683 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3684 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3685 "TARGET_80387"
3686 {
3687 /* ??? Needed for compress_float_constant since all fp constants
3688 are LEGITIMATE_CONSTANT_P. */
3689 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3690 {
3691 if (standard_80387_constant_p (operands[1]) > 0)
3692 {
3693 operands[1] = simplify_const_unary_operation
3694 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3695 emit_move_insn_1 (operands[0], operands[1]);
3696 DONE;
3697 }
3698 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3699 }
3700 })
3701
3702 (define_insn "*extendsfxf2_i387"
3703 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3704 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3705 "TARGET_80387"
3706 {
3707 switch (which_alternative)
3708 {
3709 case 0:
3710 return output_387_reg_move (insn, operands);
3711
3712 case 1:
3713 /* There is no non-popping store to memory for XFmode. So if
3714 we need one, follow the store with a load. */
3715 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3716 return "fstp%z0\t%y0";
3717 else
3718 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3719
3720 default:
3721 gcc_unreachable ();
3722 }
3723 }
3724 [(set_attr "type" "fmov")
3725 (set_attr "mode" "SF,XF")])
3726
3727 (define_expand "extenddfxf2"
3728 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3729 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3730 "TARGET_80387"
3731 {
3732 /* ??? Needed for compress_float_constant since all fp constants
3733 are LEGITIMATE_CONSTANT_P. */
3734 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3735 {
3736 if (standard_80387_constant_p (operands[1]) > 0)
3737 {
3738 operands[1] = simplify_const_unary_operation
3739 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3740 emit_move_insn_1 (operands[0], operands[1]);
3741 DONE;
3742 }
3743 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3744 }
3745 })
3746
3747 (define_insn "*extenddfxf2_i387"
3748 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3749 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3750 "TARGET_80387"
3751 {
3752 switch (which_alternative)
3753 {
3754 case 0:
3755 return output_387_reg_move (insn, operands);
3756
3757 case 1:
3758 /* There is no non-popping store to memory for XFmode. So if
3759 we need one, follow the store with a load. */
3760 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3761 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3762 else
3763 return "fstp%z0\t%y0";
3764
3765 default:
3766 gcc_unreachable ();
3767 }
3768 }
3769 [(set_attr "type" "fmov")
3770 (set_attr "mode" "DF,XF")])
3771
3772 ;; %%% This seems bad bad news.
3773 ;; This cannot output into an f-reg because there is no way to be sure
3774 ;; of truncating in that case. Otherwise this is just like a simple move
3775 ;; insn. So we pretend we can output to a reg in order to get better
3776 ;; register preferencing, but we really use a stack slot.
3777
3778 ;; Conversion from DFmode to SFmode.
3779
3780 (define_expand "truncdfsf2"
3781 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3782 (float_truncate:SF
3783 (match_operand:DF 1 "nonimmediate_operand" "")))]
3784 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3785 {
3786 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3787 ;
3788 else if (flag_unsafe_math_optimizations)
3789 ;
3790 else
3791 {
3792 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3793 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3794 DONE;
3795 }
3796 })
3797
3798 (define_expand "truncdfsf2_with_temp"
3799 [(parallel [(set (match_operand:SF 0 "" "")
3800 (float_truncate:SF (match_operand:DF 1 "" "")))
3801 (clobber (match_operand:SF 2 "" ""))])]
3802 "")
3803
3804 (define_insn "*truncdfsf_fast_mixed"
3805 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3806 (float_truncate:SF
3807 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3808 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3809 {
3810 switch (which_alternative)
3811 {
3812 case 0:
3813 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3814 return "fstp%z0\t%y0";
3815 else
3816 return "fst%z0\t%y0";
3817 case 1:
3818 return output_387_reg_move (insn, operands);
3819 case 2:
3820 return "cvtsd2ss\t{%1, %0|%0, %1}";
3821 default:
3822 gcc_unreachable ();
3823 }
3824 }
3825 [(set_attr "type" "fmov,fmov,ssecvt")
3826 (set_attr "mode" "SF")])
3827
3828 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3829 ;; because nothing we do here is unsafe.
3830 (define_insn "*truncdfsf_fast_sse"
3831 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3832 (float_truncate:SF
3833 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3834 "TARGET_SSE2 && TARGET_SSE_MATH"
3835 "cvtsd2ss\t{%1, %0|%0, %1}"
3836 [(set_attr "type" "ssecvt")
3837 (set_attr "mode" "SF")])
3838
3839 (define_insn "*truncdfsf_fast_i387"
3840 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3841 (float_truncate:SF
3842 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3843 "TARGET_80387 && flag_unsafe_math_optimizations"
3844 "* return output_387_reg_move (insn, operands);"
3845 [(set_attr "type" "fmov")
3846 (set_attr "mode" "SF")])
3847
3848 (define_insn "*truncdfsf_mixed"
3849 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3850 (float_truncate:SF
3851 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3852 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3853 "TARGET_MIX_SSE_I387"
3854 {
3855 switch (which_alternative)
3856 {
3857 case 0:
3858 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3859 return "fstp%z0\t%y0";
3860 else
3861 return "fst%z0\t%y0";
3862 case 1:
3863 return "#";
3864 case 2:
3865 return "cvtsd2ss\t{%1, %0|%0, %1}";
3866 default:
3867 gcc_unreachable ();
3868 }
3869 }
3870 [(set_attr "type" "fmov,multi,ssecvt")
3871 (set_attr "unit" "*,i387,*")
3872 (set_attr "mode" "SF")])
3873
3874 (define_insn "*truncdfsf_i387"
3875 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3876 (float_truncate:SF
3877 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3878 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3879 "TARGET_80387"
3880 {
3881 switch (which_alternative)
3882 {
3883 case 0:
3884 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3885 return "fstp%z0\t%y0";
3886 else
3887 return "fst%z0\t%y0";
3888 case 1:
3889 return "#";
3890 default:
3891 gcc_unreachable ();
3892 }
3893 }
3894 [(set_attr "type" "fmov,multi")
3895 (set_attr "unit" "*,i387")
3896 (set_attr "mode" "SF")])
3897
3898 (define_insn "*truncdfsf2_i387_1"
3899 [(set (match_operand:SF 0 "memory_operand" "=m")
3900 (float_truncate:SF
3901 (match_operand:DF 1 "register_operand" "f")))]
3902 "TARGET_80387
3903 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3904 && !TARGET_MIX_SSE_I387"
3905 {
3906 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3907 return "fstp%z0\t%y0";
3908 else
3909 return "fst%z0\t%y0";
3910 }
3911 [(set_attr "type" "fmov")
3912 (set_attr "mode" "SF")])
3913
3914 (define_split
3915 [(set (match_operand:SF 0 "register_operand" "")
3916 (float_truncate:SF
3917 (match_operand:DF 1 "fp_register_operand" "")))
3918 (clobber (match_operand 2 "" ""))]
3919 "reload_completed"
3920 [(set (match_dup 2) (match_dup 1))
3921 (set (match_dup 0) (match_dup 2))]
3922 {
3923 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3924 })
3925
3926 ;; Conversion from XFmode to SFmode.
3927
3928 (define_expand "truncxfsf2"
3929 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3930 (float_truncate:SF
3931 (match_operand:XF 1 "register_operand" "")))
3932 (clobber (match_dup 2))])]
3933 "TARGET_80387"
3934 {
3935 if (flag_unsafe_math_optimizations)
3936 {
3937 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3938 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3939 if (reg != operands[0])
3940 emit_move_insn (operands[0], reg);
3941 DONE;
3942 }
3943 else
3944 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3945 })
3946
3947 (define_insn "*truncxfsf2_mixed"
3948 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3949 (float_truncate:SF
3950 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3951 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3952 "TARGET_80387"
3953 {
3954 gcc_assert (!which_alternative);
3955 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3956 return "fstp%z0\t%y0";
3957 else
3958 return "fst%z0\t%y0";
3959 }
3960 [(set_attr "type" "fmov,multi,multi,multi")
3961 (set_attr "unit" "*,i387,i387,i387")
3962 (set_attr "mode" "SF")])
3963
3964 (define_insn "truncxfsf2_i387_noop"
3965 [(set (match_operand:SF 0 "register_operand" "=f")
3966 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3967 "TARGET_80387 && flag_unsafe_math_optimizations"
3968 "* return output_387_reg_move (insn, operands);"
3969 [(set_attr "type" "fmov")
3970 (set_attr "mode" "SF")])
3971
3972 (define_insn "*truncxfsf2_i387"
3973 [(set (match_operand:SF 0 "memory_operand" "=m")
3974 (float_truncate:SF
3975 (match_operand:XF 1 "register_operand" "f")))]
3976 "TARGET_80387"
3977 {
3978 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3979 return "fstp%z0\t%y0";
3980 else
3981 return "fst%z0\t%y0";
3982 }
3983 [(set_attr "type" "fmov")
3984 (set_attr "mode" "SF")])
3985
3986 (define_split
3987 [(set (match_operand:SF 0 "register_operand" "")
3988 (float_truncate:SF
3989 (match_operand:XF 1 "register_operand" "")))
3990 (clobber (match_operand:SF 2 "memory_operand" ""))]
3991 "TARGET_80387 && reload_completed"
3992 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3993 (set (match_dup 0) (match_dup 2))]
3994 "")
3995
3996 (define_split
3997 [(set (match_operand:SF 0 "memory_operand" "")
3998 (float_truncate:SF
3999 (match_operand:XF 1 "register_operand" "")))
4000 (clobber (match_operand:SF 2 "memory_operand" ""))]
4001 "TARGET_80387"
4002 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4003 "")
4004
4005 ;; Conversion from XFmode to DFmode.
4006
4007 (define_expand "truncxfdf2"
4008 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4009 (float_truncate:DF
4010 (match_operand:XF 1 "register_operand" "")))
4011 (clobber (match_dup 2))])]
4012 "TARGET_80387"
4013 {
4014 if (flag_unsafe_math_optimizations)
4015 {
4016 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4017 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4018 if (reg != operands[0])
4019 emit_move_insn (operands[0], reg);
4020 DONE;
4021 }
4022 else
4023 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4024 })
4025
4026 (define_insn "*truncxfdf2_mixed"
4027 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4028 (float_truncate:DF
4029 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4030 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4031 "TARGET_80387"
4032 {
4033 gcc_assert (!which_alternative);
4034 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4035 return "fstp%z0\t%y0";
4036 else
4037 return "fst%z0\t%y0";
4038 }
4039 [(set_attr "type" "fmov,multi,multi,multi")
4040 (set_attr "unit" "*,i387,i387,i387")
4041 (set_attr "mode" "DF")])
4042
4043 (define_insn "truncxfdf2_i387_noop"
4044 [(set (match_operand:DF 0 "register_operand" "=f")
4045 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4046 "TARGET_80387 && flag_unsafe_math_optimizations"
4047 "* return output_387_reg_move (insn, operands);"
4048 [(set_attr "type" "fmov")
4049 (set_attr "mode" "DF")])
4050
4051 (define_insn "*truncxfdf2_i387"
4052 [(set (match_operand:DF 0 "memory_operand" "=m")
4053 (float_truncate:DF
4054 (match_operand:XF 1 "register_operand" "f")))]
4055 "TARGET_80387"
4056 {
4057 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4058 return "fstp%z0\t%y0";
4059 else
4060 return "fst%z0\t%y0";
4061 }
4062 [(set_attr "type" "fmov")
4063 (set_attr "mode" "DF")])
4064
4065 (define_split
4066 [(set (match_operand:DF 0 "register_operand" "")
4067 (float_truncate:DF
4068 (match_operand:XF 1 "register_operand" "")))
4069 (clobber (match_operand:DF 2 "memory_operand" ""))]
4070 "TARGET_80387 && reload_completed"
4071 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4072 (set (match_dup 0) (match_dup 2))]
4073 "")
4074
4075 (define_split
4076 [(set (match_operand:DF 0 "memory_operand" "")
4077 (float_truncate:DF
4078 (match_operand:XF 1 "register_operand" "")))
4079 (clobber (match_operand:DF 2 "memory_operand" ""))]
4080 "TARGET_80387"
4081 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4082 "")
4083 \f
4084 ;; Signed conversion to DImode.
4085
4086 (define_expand "fix_truncxfdi2"
4087 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4088 (fix:DI (match_operand:XF 1 "register_operand" "")))
4089 (clobber (reg:CC FLAGS_REG))])]
4090 "TARGET_80387"
4091 {
4092 if (TARGET_FISTTP)
4093 {
4094 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4095 DONE;
4096 }
4097 })
4098
4099 (define_expand "fix_trunc<mode>di2"
4100 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4101 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4102 (clobber (reg:CC FLAGS_REG))])]
4103 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4104 {
4105 if (TARGET_FISTTP
4106 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4107 {
4108 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4109 DONE;
4110 }
4111 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4112 {
4113 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4114 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4115 if (out != operands[0])
4116 emit_move_insn (operands[0], out);
4117 DONE;
4118 }
4119 })
4120
4121 ;; Signed conversion to SImode.
4122
4123 (define_expand "fix_truncxfsi2"
4124 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4125 (fix:SI (match_operand:XF 1 "register_operand" "")))
4126 (clobber (reg:CC FLAGS_REG))])]
4127 "TARGET_80387"
4128 {
4129 if (TARGET_FISTTP)
4130 {
4131 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4132 DONE;
4133 }
4134 })
4135
4136 (define_expand "fix_trunc<mode>si2"
4137 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4138 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4139 (clobber (reg:CC FLAGS_REG))])]
4140 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4141 {
4142 if (TARGET_FISTTP
4143 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4144 {
4145 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4146 DONE;
4147 }
4148 if (SSE_FLOAT_MODE_P (<MODE>mode))
4149 {
4150 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4151 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4152 if (out != operands[0])
4153 emit_move_insn (operands[0], out);
4154 DONE;
4155 }
4156 })
4157
4158 ;; Signed conversion to HImode.
4159
4160 (define_expand "fix_trunc<mode>hi2"
4161 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4162 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4163 (clobber (reg:CC FLAGS_REG))])]
4164 "TARGET_80387
4165 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4166 {
4167 if (TARGET_FISTTP)
4168 {
4169 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4170 DONE;
4171 }
4172 })
4173
4174 ;; When SSE is available, it is always faster to use it!
4175 (define_insn "fix_truncsfdi_sse"
4176 [(set (match_operand:DI 0 "register_operand" "=r,r")
4177 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4178 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4179 "cvttss2si{q}\t{%1, %0|%0, %1}"
4180 [(set_attr "type" "sseicvt")
4181 (set_attr "mode" "SF")
4182 (set_attr "athlon_decode" "double,vector")])
4183
4184 (define_insn "fix_truncdfdi_sse"
4185 [(set (match_operand:DI 0 "register_operand" "=r,r")
4186 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4187 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4188 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4189 [(set_attr "type" "sseicvt")
4190 (set_attr "mode" "DF")
4191 (set_attr "athlon_decode" "double,vector")])
4192
4193 (define_insn "fix_truncsfsi_sse"
4194 [(set (match_operand:SI 0 "register_operand" "=r,r")
4195 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4196 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4197 "cvttss2si\t{%1, %0|%0, %1}"
4198 [(set_attr "type" "sseicvt")
4199 (set_attr "mode" "DF")
4200 (set_attr "athlon_decode" "double,vector")])
4201
4202 (define_insn "fix_truncdfsi_sse"
4203 [(set (match_operand:SI 0 "register_operand" "=r,r")
4204 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4205 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4206 "cvttsd2si\t{%1, %0|%0, %1}"
4207 [(set_attr "type" "sseicvt")
4208 (set_attr "mode" "DF")
4209 (set_attr "athlon_decode" "double,vector")])
4210
4211 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4212 (define_peephole2
4213 [(set (match_operand:DF 0 "register_operand" "")
4214 (match_operand:DF 1 "memory_operand" ""))
4215 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4216 (fix:SSEMODEI24 (match_dup 0)))]
4217 "!TARGET_K8
4218 && peep2_reg_dead_p (2, operands[0])"
4219 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4220 "")
4221
4222 (define_peephole2
4223 [(set (match_operand:SF 0 "register_operand" "")
4224 (match_operand:SF 1 "memory_operand" ""))
4225 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4226 (fix:SSEMODEI24 (match_dup 0)))]
4227 "!TARGET_K8
4228 && peep2_reg_dead_p (2, operands[0])"
4229 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4230 "")
4231
4232 ;; Avoid vector decoded forms of the instruction.
4233 (define_peephole2
4234 [(match_scratch:DF 2 "Y")
4235 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4236 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4237 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4238 [(set (match_dup 2) (match_dup 1))
4239 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4240 "")
4241
4242 (define_peephole2
4243 [(match_scratch:SF 2 "x")
4244 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4245 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4246 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4247 [(set (match_dup 2) (match_dup 1))
4248 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4249 "")
4250
4251 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4252 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4253 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4254 "TARGET_FISTTP
4255 && FLOAT_MODE_P (GET_MODE (operands[1]))
4256 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4257 && (TARGET_64BIT || <MODE>mode != DImode))
4258 && TARGET_SSE_MATH)
4259 && !(reload_completed || reload_in_progress)"
4260 "#"
4261 "&& 1"
4262 [(const_int 0)]
4263 {
4264 if (memory_operand (operands[0], VOIDmode))
4265 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4266 else
4267 {
4268 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4269 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4270 operands[1],
4271 operands[2]));
4272 }
4273 DONE;
4274 }
4275 [(set_attr "type" "fisttp")
4276 (set_attr "mode" "<MODE>")])
4277
4278 (define_insn "fix_trunc<mode>_i387_fisttp"
4279 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4280 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4281 (clobber (match_scratch:XF 2 "=&1f"))]
4282 "TARGET_FISTTP
4283 && FLOAT_MODE_P (GET_MODE (operands[1]))
4284 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4285 && (TARGET_64BIT || <MODE>mode != DImode))
4286 && TARGET_SSE_MATH)"
4287 "* return output_fix_trunc (insn, operands, 1);"
4288 [(set_attr "type" "fisttp")
4289 (set_attr "mode" "<MODE>")])
4290
4291 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4292 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4293 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4294 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4295 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4296 "TARGET_FISTTP
4297 && FLOAT_MODE_P (GET_MODE (operands[1]))
4298 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4299 && (TARGET_64BIT || <MODE>mode != DImode))
4300 && TARGET_SSE_MATH)"
4301 "#"
4302 [(set_attr "type" "fisttp")
4303 (set_attr "mode" "<MODE>")])
4304
4305 (define_split
4306 [(set (match_operand:X87MODEI 0 "register_operand" "")
4307 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4308 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4309 (clobber (match_scratch 3 ""))]
4310 "reload_completed"
4311 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4312 (clobber (match_dup 3))])
4313 (set (match_dup 0) (match_dup 2))]
4314 "")
4315
4316 (define_split
4317 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4318 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4319 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4320 (clobber (match_scratch 3 ""))]
4321 "reload_completed"
4322 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4323 (clobber (match_dup 3))])]
4324 "")
4325
4326 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4327 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4328 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4329 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4330 ;; function in i386.c.
4331 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4332 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4333 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4334 (clobber (reg:CC FLAGS_REG))]
4335 "TARGET_80387 && !TARGET_FISTTP
4336 && FLOAT_MODE_P (GET_MODE (operands[1]))
4337 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4338 && (TARGET_64BIT || <MODE>mode != DImode))
4339 && !(reload_completed || reload_in_progress)"
4340 "#"
4341 "&& 1"
4342 [(const_int 0)]
4343 {
4344 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4345
4346 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4347 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4348 if (memory_operand (operands[0], VOIDmode))
4349 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4350 operands[2], operands[3]));
4351 else
4352 {
4353 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4354 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4355 operands[2], operands[3],
4356 operands[4]));
4357 }
4358 DONE;
4359 }
4360 [(set_attr "type" "fistp")
4361 (set_attr "i387_cw" "trunc")
4362 (set_attr "mode" "<MODE>")])
4363
4364 (define_insn "fix_truncdi_i387"
4365 [(set (match_operand:DI 0 "memory_operand" "=m")
4366 (fix:DI (match_operand 1 "register_operand" "f")))
4367 (use (match_operand:HI 2 "memory_operand" "m"))
4368 (use (match_operand:HI 3 "memory_operand" "m"))
4369 (clobber (match_scratch:XF 4 "=&1f"))]
4370 "TARGET_80387 && !TARGET_FISTTP
4371 && FLOAT_MODE_P (GET_MODE (operands[1]))
4372 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4373 "* return output_fix_trunc (insn, operands, 0);"
4374 [(set_attr "type" "fistp")
4375 (set_attr "i387_cw" "trunc")
4376 (set_attr "mode" "DI")])
4377
4378 (define_insn "fix_truncdi_i387_with_temp"
4379 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4380 (fix:DI (match_operand 1 "register_operand" "f,f")))
4381 (use (match_operand:HI 2 "memory_operand" "m,m"))
4382 (use (match_operand:HI 3 "memory_operand" "m,m"))
4383 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4384 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4385 "TARGET_80387 && !TARGET_FISTTP
4386 && FLOAT_MODE_P (GET_MODE (operands[1]))
4387 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4388 "#"
4389 [(set_attr "type" "fistp")
4390 (set_attr "i387_cw" "trunc")
4391 (set_attr "mode" "DI")])
4392
4393 (define_split
4394 [(set (match_operand:DI 0 "register_operand" "")
4395 (fix:DI (match_operand 1 "register_operand" "")))
4396 (use (match_operand:HI 2 "memory_operand" ""))
4397 (use (match_operand:HI 3 "memory_operand" ""))
4398 (clobber (match_operand:DI 4 "memory_operand" ""))
4399 (clobber (match_scratch 5 ""))]
4400 "reload_completed"
4401 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4402 (use (match_dup 2))
4403 (use (match_dup 3))
4404 (clobber (match_dup 5))])
4405 (set (match_dup 0) (match_dup 4))]
4406 "")
4407
4408 (define_split
4409 [(set (match_operand:DI 0 "memory_operand" "")
4410 (fix:DI (match_operand 1 "register_operand" "")))
4411 (use (match_operand:HI 2 "memory_operand" ""))
4412 (use (match_operand:HI 3 "memory_operand" ""))
4413 (clobber (match_operand:DI 4 "memory_operand" ""))
4414 (clobber (match_scratch 5 ""))]
4415 "reload_completed"
4416 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4417 (use (match_dup 2))
4418 (use (match_dup 3))
4419 (clobber (match_dup 5))])]
4420 "")
4421
4422 (define_insn "fix_trunc<mode>_i387"
4423 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4424 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4425 (use (match_operand:HI 2 "memory_operand" "m"))
4426 (use (match_operand:HI 3 "memory_operand" "m"))]
4427 "TARGET_80387 && !TARGET_FISTTP
4428 && FLOAT_MODE_P (GET_MODE (operands[1]))
4429 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4430 "* return output_fix_trunc (insn, operands, 0);"
4431 [(set_attr "type" "fistp")
4432 (set_attr "i387_cw" "trunc")
4433 (set_attr "mode" "<MODE>")])
4434
4435 (define_insn "fix_trunc<mode>_i387_with_temp"
4436 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4437 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4438 (use (match_operand:HI 2 "memory_operand" "m,m"))
4439 (use (match_operand:HI 3 "memory_operand" "m,m"))
4440 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4441 "TARGET_80387 && !TARGET_FISTTP
4442 && FLOAT_MODE_P (GET_MODE (operands[1]))
4443 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4444 "#"
4445 [(set_attr "type" "fistp")
4446 (set_attr "i387_cw" "trunc")
4447 (set_attr "mode" "<MODE>")])
4448
4449 (define_split
4450 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4451 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4452 (use (match_operand:HI 2 "memory_operand" ""))
4453 (use (match_operand:HI 3 "memory_operand" ""))
4454 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4455 "reload_completed"
4456 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4457 (use (match_dup 2))
4458 (use (match_dup 3))])
4459 (set (match_dup 0) (match_dup 4))]
4460 "")
4461
4462 (define_split
4463 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4464 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4465 (use (match_operand:HI 2 "memory_operand" ""))
4466 (use (match_operand:HI 3 "memory_operand" ""))
4467 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4468 "reload_completed"
4469 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4470 (use (match_dup 2))
4471 (use (match_dup 3))])]
4472 "")
4473
4474 (define_insn "x86_fnstcw_1"
4475 [(set (match_operand:HI 0 "memory_operand" "=m")
4476 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4477 "TARGET_80387"
4478 "fnstcw\t%0"
4479 [(set_attr "length" "2")
4480 (set_attr "mode" "HI")
4481 (set_attr "unit" "i387")])
4482
4483 (define_insn "x86_fldcw_1"
4484 [(set (reg:HI FPCR_REG)
4485 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4486 "TARGET_80387"
4487 "fldcw\t%0"
4488 [(set_attr "length" "2")
4489 (set_attr "mode" "HI")
4490 (set_attr "unit" "i387")
4491 (set_attr "athlon_decode" "vector")])
4492 \f
4493 ;; Conversion between fixed point and floating point.
4494
4495 ;; Even though we only accept memory inputs, the backend _really_
4496 ;; wants to be able to do this between registers.
4497
4498 (define_expand "floathisf2"
4499 [(set (match_operand:SF 0 "register_operand" "")
4500 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4501 "TARGET_80387 || TARGET_SSE_MATH"
4502 {
4503 if (TARGET_SSE_MATH)
4504 {
4505 emit_insn (gen_floatsisf2 (operands[0],
4506 convert_to_mode (SImode, operands[1], 0)));
4507 DONE;
4508 }
4509 })
4510
4511 (define_insn "*floathisf2_i387"
4512 [(set (match_operand:SF 0 "register_operand" "=f,f")
4513 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4514 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4515 "@
4516 fild%z1\t%1
4517 #"
4518 [(set_attr "type" "fmov,multi")
4519 (set_attr "mode" "SF")
4520 (set_attr "unit" "*,i387")
4521 (set_attr "fp_int_src" "true")])
4522
4523 (define_expand "floatsisf2"
4524 [(set (match_operand:SF 0 "register_operand" "")
4525 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4526 "TARGET_80387 || TARGET_SSE_MATH"
4527 "")
4528
4529 (define_insn "*floatsisf2_mixed"
4530 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4531 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4532 "TARGET_MIX_SSE_I387"
4533 "@
4534 fild%z1\t%1
4535 #
4536 cvtsi2ss\t{%1, %0|%0, %1}
4537 cvtsi2ss\t{%1, %0|%0, %1}"
4538 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4539 (set_attr "mode" "SF")
4540 (set_attr "unit" "*,i387,*,*")
4541 (set_attr "athlon_decode" "*,*,vector,double")
4542 (set_attr "fp_int_src" "true")])
4543
4544 (define_insn "*floatsisf2_sse"
4545 [(set (match_operand:SF 0 "register_operand" "=x,x")
4546 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4547 "TARGET_SSE_MATH"
4548 "cvtsi2ss\t{%1, %0|%0, %1}"
4549 [(set_attr "type" "sseicvt")
4550 (set_attr "mode" "SF")
4551 (set_attr "athlon_decode" "vector,double")
4552 (set_attr "fp_int_src" "true")])
4553
4554 (define_insn "*floatsisf2_i387"
4555 [(set (match_operand:SF 0 "register_operand" "=f,f")
4556 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4557 "TARGET_80387"
4558 "@
4559 fild%z1\t%1
4560 #"
4561 [(set_attr "type" "fmov,multi")
4562 (set_attr "mode" "SF")
4563 (set_attr "unit" "*,i387")
4564 (set_attr "fp_int_src" "true")])
4565
4566 (define_expand "floatdisf2"
4567 [(set (match_operand:SF 0 "register_operand" "")
4568 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4569 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4570 "")
4571
4572 (define_insn "*floatdisf2_mixed"
4573 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4574 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4575 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4576 "@
4577 fild%z1\t%1
4578 #
4579 cvtsi2ss{q}\t{%1, %0|%0, %1}
4580 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4581 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4582 (set_attr "mode" "SF")
4583 (set_attr "unit" "*,i387,*,*")
4584 (set_attr "athlon_decode" "*,*,vector,double")
4585 (set_attr "fp_int_src" "true")])
4586
4587 (define_insn "*floatdisf2_sse"
4588 [(set (match_operand:SF 0 "register_operand" "=x,x")
4589 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4590 "TARGET_64BIT && TARGET_SSE_MATH"
4591 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4592 [(set_attr "type" "sseicvt")
4593 (set_attr "mode" "SF")
4594 (set_attr "athlon_decode" "vector,double")
4595 (set_attr "fp_int_src" "true")])
4596
4597 (define_insn "*floatdisf2_i387"
4598 [(set (match_operand:SF 0 "register_operand" "=f,f")
4599 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4600 "TARGET_80387"
4601 "@
4602 fild%z1\t%1
4603 #"
4604 [(set_attr "type" "fmov,multi")
4605 (set_attr "mode" "SF")
4606 (set_attr "unit" "*,i387")
4607 (set_attr "fp_int_src" "true")])
4608
4609 (define_expand "floathidf2"
4610 [(set (match_operand:DF 0 "register_operand" "")
4611 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4612 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4613 {
4614 if (TARGET_SSE2 && TARGET_SSE_MATH)
4615 {
4616 emit_insn (gen_floatsidf2 (operands[0],
4617 convert_to_mode (SImode, operands[1], 0)));
4618 DONE;
4619 }
4620 })
4621
4622 (define_insn "*floathidf2_i387"
4623 [(set (match_operand:DF 0 "register_operand" "=f,f")
4624 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4625 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4626 "@
4627 fild%z1\t%1
4628 #"
4629 [(set_attr "type" "fmov,multi")
4630 (set_attr "mode" "DF")
4631 (set_attr "unit" "*,i387")
4632 (set_attr "fp_int_src" "true")])
4633
4634 (define_expand "floatsidf2"
4635 [(set (match_operand:DF 0 "register_operand" "")
4636 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4637 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4638 "")
4639
4640 (define_insn "*floatsidf2_mixed"
4641 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4642 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4643 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4644 "@
4645 fild%z1\t%1
4646 #
4647 cvtsi2sd\t{%1, %0|%0, %1}
4648 cvtsi2sd\t{%1, %0|%0, %1}"
4649 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4650 (set_attr "mode" "DF")
4651 (set_attr "unit" "*,i387,*,*")
4652 (set_attr "athlon_decode" "*,*,double,direct")
4653 (set_attr "fp_int_src" "true")])
4654
4655 (define_insn "*floatsidf2_sse"
4656 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4657 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4658 "TARGET_SSE2 && TARGET_SSE_MATH"
4659 "cvtsi2sd\t{%1, %0|%0, %1}"
4660 [(set_attr "type" "sseicvt")
4661 (set_attr "mode" "DF")
4662 (set_attr "athlon_decode" "double,direct")
4663 (set_attr "fp_int_src" "true")])
4664
4665 (define_insn "*floatsidf2_i387"
4666 [(set (match_operand:DF 0 "register_operand" "=f,f")
4667 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4668 "TARGET_80387"
4669 "@
4670 fild%z1\t%1
4671 #"
4672 [(set_attr "type" "fmov,multi")
4673 (set_attr "mode" "DF")
4674 (set_attr "unit" "*,i387")
4675 (set_attr "fp_int_src" "true")])
4676
4677 (define_expand "floatdidf2"
4678 [(set (match_operand:DF 0 "register_operand" "")
4679 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4680 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4681 "")
4682
4683 (define_insn "*floatdidf2_mixed"
4684 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4685 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4686 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4687 "@
4688 fild%z1\t%1
4689 #
4690 cvtsi2sd{q}\t{%1, %0|%0, %1}
4691 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4692 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4693 (set_attr "mode" "DF")
4694 (set_attr "unit" "*,i387,*,*")
4695 (set_attr "athlon_decode" "*,*,double,direct")
4696 (set_attr "fp_int_src" "true")])
4697
4698 (define_insn "*floatdidf2_sse"
4699 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4700 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4701 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4702 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4703 [(set_attr "type" "sseicvt")
4704 (set_attr "mode" "DF")
4705 (set_attr "athlon_decode" "double,direct")
4706 (set_attr "fp_int_src" "true")])
4707
4708 (define_insn "*floatdidf2_i387"
4709 [(set (match_operand:DF 0 "register_operand" "=f,f")
4710 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4711 "TARGET_80387"
4712 "@
4713 fild%z1\t%1
4714 #"
4715 [(set_attr "type" "fmov,multi")
4716 (set_attr "mode" "DF")
4717 (set_attr "unit" "*,i387")
4718 (set_attr "fp_int_src" "true")])
4719
4720 (define_insn "floathixf2"
4721 [(set (match_operand:XF 0 "register_operand" "=f,f")
4722 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4723 "TARGET_80387"
4724 "@
4725 fild%z1\t%1
4726 #"
4727 [(set_attr "type" "fmov,multi")
4728 (set_attr "mode" "XF")
4729 (set_attr "unit" "*,i387")
4730 (set_attr "fp_int_src" "true")])
4731
4732 (define_insn "floatsixf2"
4733 [(set (match_operand:XF 0 "register_operand" "=f,f")
4734 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4735 "TARGET_80387"
4736 "@
4737 fild%z1\t%1
4738 #"
4739 [(set_attr "type" "fmov,multi")
4740 (set_attr "mode" "XF")
4741 (set_attr "unit" "*,i387")
4742 (set_attr "fp_int_src" "true")])
4743
4744 (define_insn "floatdixf2"
4745 [(set (match_operand:XF 0 "register_operand" "=f,f")
4746 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4747 "TARGET_80387"
4748 "@
4749 fild%z1\t%1
4750 #"
4751 [(set_attr "type" "fmov,multi")
4752 (set_attr "mode" "XF")
4753 (set_attr "unit" "*,i387")
4754 (set_attr "fp_int_src" "true")])
4755
4756 ;; %%% Kill these when reload knows how to do it.
4757 (define_split
4758 [(set (match_operand 0 "fp_register_operand" "")
4759 (float (match_operand 1 "register_operand" "")))]
4760 "reload_completed
4761 && TARGET_80387
4762 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4763 [(const_int 0)]
4764 {
4765 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4766 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4767 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4768 ix86_free_from_memory (GET_MODE (operands[1]));
4769 DONE;
4770 })
4771
4772 (define_expand "floatunssisf2"
4773 [(use (match_operand:SF 0 "register_operand" ""))
4774 (use (match_operand:SI 1 "register_operand" ""))]
4775 "!TARGET_64BIT && TARGET_SSE_MATH"
4776 "x86_emit_floatuns (operands); DONE;")
4777
4778 (define_expand "floatunsdisf2"
4779 [(use (match_operand:SF 0 "register_operand" ""))
4780 (use (match_operand:DI 1 "register_operand" ""))]
4781 "TARGET_64BIT && TARGET_SSE_MATH"
4782 "x86_emit_floatuns (operands); DONE;")
4783
4784 (define_expand "floatunsdidf2"
4785 [(use (match_operand:DF 0 "register_operand" ""))
4786 (use (match_operand:DI 1 "register_operand" ""))]
4787 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4788 "x86_emit_floatuns (operands); DONE;")
4789 \f
4790 ;; SSE extract/set expanders
4791
4792 \f
4793 ;; Add instructions
4794
4795 ;; %%% splits for addditi3
4796
4797 (define_expand "addti3"
4798 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4799 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4800 (match_operand:TI 2 "x86_64_general_operand" "")))
4801 (clobber (reg:CC FLAGS_REG))]
4802 "TARGET_64BIT"
4803 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4804
4805 (define_insn "*addti3_1"
4806 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4807 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4808 (match_operand:TI 2 "general_operand" "roiF,riF")))
4809 (clobber (reg:CC FLAGS_REG))]
4810 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4811 "#")
4812
4813 (define_split
4814 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4815 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4816 (match_operand:TI 2 "general_operand" "")))
4817 (clobber (reg:CC FLAGS_REG))]
4818 "TARGET_64BIT && reload_completed"
4819 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4820 UNSPEC_ADD_CARRY))
4821 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4822 (parallel [(set (match_dup 3)
4823 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4824 (match_dup 4))
4825 (match_dup 5)))
4826 (clobber (reg:CC FLAGS_REG))])]
4827 "split_ti (operands+0, 1, operands+0, operands+3);
4828 split_ti (operands+1, 1, operands+1, operands+4);
4829 split_ti (operands+2, 1, operands+2, operands+5);")
4830
4831 ;; %%% splits for addsidi3
4832 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4833 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4834 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4835
4836 (define_expand "adddi3"
4837 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4838 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4839 (match_operand:DI 2 "x86_64_general_operand" "")))
4840 (clobber (reg:CC FLAGS_REG))]
4841 ""
4842 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4843
4844 (define_insn "*adddi3_1"
4845 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4846 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4847 (match_operand:DI 2 "general_operand" "roiF,riF")))
4848 (clobber (reg:CC FLAGS_REG))]
4849 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4850 "#")
4851
4852 (define_split
4853 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4854 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4855 (match_operand:DI 2 "general_operand" "")))
4856 (clobber (reg:CC FLAGS_REG))]
4857 "!TARGET_64BIT && reload_completed"
4858 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4859 UNSPEC_ADD_CARRY))
4860 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4861 (parallel [(set (match_dup 3)
4862 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4863 (match_dup 4))
4864 (match_dup 5)))
4865 (clobber (reg:CC FLAGS_REG))])]
4866 "split_di (operands+0, 1, operands+0, operands+3);
4867 split_di (operands+1, 1, operands+1, operands+4);
4868 split_di (operands+2, 1, operands+2, operands+5);")
4869
4870 (define_insn "adddi3_carry_rex64"
4871 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4872 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4873 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4874 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4875 (clobber (reg:CC FLAGS_REG))]
4876 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4877 "adc{q}\t{%2, %0|%0, %2}"
4878 [(set_attr "type" "alu")
4879 (set_attr "pent_pair" "pu")
4880 (set_attr "mode" "DI")])
4881
4882 (define_insn "*adddi3_cc_rex64"
4883 [(set (reg:CC FLAGS_REG)
4884 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4885 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4886 UNSPEC_ADD_CARRY))
4887 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4888 (plus:DI (match_dup 1) (match_dup 2)))]
4889 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4890 "add{q}\t{%2, %0|%0, %2}"
4891 [(set_attr "type" "alu")
4892 (set_attr "mode" "DI")])
4893
4894 (define_insn "addqi3_carry"
4895 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4896 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4897 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4898 (match_operand:QI 2 "general_operand" "qi,qm")))
4899 (clobber (reg:CC FLAGS_REG))]
4900 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4901 "adc{b}\t{%2, %0|%0, %2}"
4902 [(set_attr "type" "alu")
4903 (set_attr "pent_pair" "pu")
4904 (set_attr "mode" "QI")])
4905
4906 (define_insn "addhi3_carry"
4907 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4908 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4909 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4910 (match_operand:HI 2 "general_operand" "ri,rm")))
4911 (clobber (reg:CC FLAGS_REG))]
4912 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4913 "adc{w}\t{%2, %0|%0, %2}"
4914 [(set_attr "type" "alu")
4915 (set_attr "pent_pair" "pu")
4916 (set_attr "mode" "HI")])
4917
4918 (define_insn "addsi3_carry"
4919 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4920 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4921 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4922 (match_operand:SI 2 "general_operand" "ri,rm")))
4923 (clobber (reg:CC FLAGS_REG))]
4924 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4925 "adc{l}\t{%2, %0|%0, %2}"
4926 [(set_attr "type" "alu")
4927 (set_attr "pent_pair" "pu")
4928 (set_attr "mode" "SI")])
4929
4930 (define_insn "*addsi3_carry_zext"
4931 [(set (match_operand:DI 0 "register_operand" "=r")
4932 (zero_extend:DI
4933 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4934 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4935 (match_operand:SI 2 "general_operand" "rim"))))
4936 (clobber (reg:CC FLAGS_REG))]
4937 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4938 "adc{l}\t{%2, %k0|%k0, %2}"
4939 [(set_attr "type" "alu")
4940 (set_attr "pent_pair" "pu")
4941 (set_attr "mode" "SI")])
4942
4943 (define_insn "*addsi3_cc"
4944 [(set (reg:CC FLAGS_REG)
4945 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4946 (match_operand:SI 2 "general_operand" "ri,rm")]
4947 UNSPEC_ADD_CARRY))
4948 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4949 (plus:SI (match_dup 1) (match_dup 2)))]
4950 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4951 "add{l}\t{%2, %0|%0, %2}"
4952 [(set_attr "type" "alu")
4953 (set_attr "mode" "SI")])
4954
4955 (define_insn "addqi3_cc"
4956 [(set (reg:CC FLAGS_REG)
4957 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4958 (match_operand:QI 2 "general_operand" "qi,qm")]
4959 UNSPEC_ADD_CARRY))
4960 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4961 (plus:QI (match_dup 1) (match_dup 2)))]
4962 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4963 "add{b}\t{%2, %0|%0, %2}"
4964 [(set_attr "type" "alu")
4965 (set_attr "mode" "QI")])
4966
4967 (define_expand "addsi3"
4968 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4969 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4970 (match_operand:SI 2 "general_operand" "")))
4971 (clobber (reg:CC FLAGS_REG))])]
4972 ""
4973 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4974
4975 (define_insn "*lea_1"
4976 [(set (match_operand:SI 0 "register_operand" "=r")
4977 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4978 "!TARGET_64BIT"
4979 "lea{l}\t{%a1, %0|%0, %a1}"
4980 [(set_attr "type" "lea")
4981 (set_attr "mode" "SI")])
4982
4983 (define_insn "*lea_1_rex64"
4984 [(set (match_operand:SI 0 "register_operand" "=r")
4985 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4986 "TARGET_64BIT"
4987 "lea{l}\t{%a1, %0|%0, %a1}"
4988 [(set_attr "type" "lea")
4989 (set_attr "mode" "SI")])
4990
4991 (define_insn "*lea_1_zext"
4992 [(set (match_operand:DI 0 "register_operand" "=r")
4993 (zero_extend:DI
4994 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4995 "TARGET_64BIT"
4996 "lea{l}\t{%a1, %k0|%k0, %a1}"
4997 [(set_attr "type" "lea")
4998 (set_attr "mode" "SI")])
4999
5000 (define_insn "*lea_2_rex64"
5001 [(set (match_operand:DI 0 "register_operand" "=r")
5002 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5003 "TARGET_64BIT"
5004 "lea{q}\t{%a1, %0|%0, %a1}"
5005 [(set_attr "type" "lea")
5006 (set_attr "mode" "DI")])
5007
5008 ;; The lea patterns for non-Pmodes needs to be matched by several
5009 ;; insns converted to real lea by splitters.
5010
5011 (define_insn_and_split "*lea_general_1"
5012 [(set (match_operand 0 "register_operand" "=r")
5013 (plus (plus (match_operand 1 "index_register_operand" "l")
5014 (match_operand 2 "register_operand" "r"))
5015 (match_operand 3 "immediate_operand" "i")))]
5016 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5017 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5018 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5019 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5020 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5021 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5022 || GET_MODE (operands[3]) == VOIDmode)"
5023 "#"
5024 "&& reload_completed"
5025 [(const_int 0)]
5026 {
5027 rtx pat;
5028 operands[0] = gen_lowpart (SImode, operands[0]);
5029 operands[1] = gen_lowpart (Pmode, operands[1]);
5030 operands[2] = gen_lowpart (Pmode, operands[2]);
5031 operands[3] = gen_lowpart (Pmode, operands[3]);
5032 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5033 operands[3]);
5034 if (Pmode != SImode)
5035 pat = gen_rtx_SUBREG (SImode, pat, 0);
5036 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5037 DONE;
5038 }
5039 [(set_attr "type" "lea")
5040 (set_attr "mode" "SI")])
5041
5042 (define_insn_and_split "*lea_general_1_zext"
5043 [(set (match_operand:DI 0 "register_operand" "=r")
5044 (zero_extend:DI
5045 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5046 (match_operand:SI 2 "register_operand" "r"))
5047 (match_operand:SI 3 "immediate_operand" "i"))))]
5048 "TARGET_64BIT"
5049 "#"
5050 "&& reload_completed"
5051 [(set (match_dup 0)
5052 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5053 (match_dup 2))
5054 (match_dup 3)) 0)))]
5055 {
5056 operands[1] = gen_lowpart (Pmode, operands[1]);
5057 operands[2] = gen_lowpart (Pmode, operands[2]);
5058 operands[3] = gen_lowpart (Pmode, operands[3]);
5059 }
5060 [(set_attr "type" "lea")
5061 (set_attr "mode" "SI")])
5062
5063 (define_insn_and_split "*lea_general_2"
5064 [(set (match_operand 0 "register_operand" "=r")
5065 (plus (mult (match_operand 1 "index_register_operand" "l")
5066 (match_operand 2 "const248_operand" "i"))
5067 (match_operand 3 "nonmemory_operand" "ri")))]
5068 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5069 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5070 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5071 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5072 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5073 || GET_MODE (operands[3]) == VOIDmode)"
5074 "#"
5075 "&& reload_completed"
5076 [(const_int 0)]
5077 {
5078 rtx pat;
5079 operands[0] = gen_lowpart (SImode, operands[0]);
5080 operands[1] = gen_lowpart (Pmode, operands[1]);
5081 operands[3] = gen_lowpart (Pmode, operands[3]);
5082 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5083 operands[3]);
5084 if (Pmode != SImode)
5085 pat = gen_rtx_SUBREG (SImode, pat, 0);
5086 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5087 DONE;
5088 }
5089 [(set_attr "type" "lea")
5090 (set_attr "mode" "SI")])
5091
5092 (define_insn_and_split "*lea_general_2_zext"
5093 [(set (match_operand:DI 0 "register_operand" "=r")
5094 (zero_extend:DI
5095 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5096 (match_operand:SI 2 "const248_operand" "n"))
5097 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5098 "TARGET_64BIT"
5099 "#"
5100 "&& reload_completed"
5101 [(set (match_dup 0)
5102 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5103 (match_dup 2))
5104 (match_dup 3)) 0)))]
5105 {
5106 operands[1] = gen_lowpart (Pmode, operands[1]);
5107 operands[3] = gen_lowpart (Pmode, operands[3]);
5108 }
5109 [(set_attr "type" "lea")
5110 (set_attr "mode" "SI")])
5111
5112 (define_insn_and_split "*lea_general_3"
5113 [(set (match_operand 0 "register_operand" "=r")
5114 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5115 (match_operand 2 "const248_operand" "i"))
5116 (match_operand 3 "register_operand" "r"))
5117 (match_operand 4 "immediate_operand" "i")))]
5118 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5119 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5120 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5121 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5122 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5123 "#"
5124 "&& reload_completed"
5125 [(const_int 0)]
5126 {
5127 rtx pat;
5128 operands[0] = gen_lowpart (SImode, operands[0]);
5129 operands[1] = gen_lowpart (Pmode, operands[1]);
5130 operands[3] = gen_lowpart (Pmode, operands[3]);
5131 operands[4] = gen_lowpart (Pmode, operands[4]);
5132 pat = gen_rtx_PLUS (Pmode,
5133 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5134 operands[2]),
5135 operands[3]),
5136 operands[4]);
5137 if (Pmode != SImode)
5138 pat = gen_rtx_SUBREG (SImode, pat, 0);
5139 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5140 DONE;
5141 }
5142 [(set_attr "type" "lea")
5143 (set_attr "mode" "SI")])
5144
5145 (define_insn_and_split "*lea_general_3_zext"
5146 [(set (match_operand:DI 0 "register_operand" "=r")
5147 (zero_extend:DI
5148 (plus:SI (plus:SI (mult:SI
5149 (match_operand:SI 1 "index_register_operand" "l")
5150 (match_operand:SI 2 "const248_operand" "n"))
5151 (match_operand:SI 3 "register_operand" "r"))
5152 (match_operand:SI 4 "immediate_operand" "i"))))]
5153 "TARGET_64BIT"
5154 "#"
5155 "&& reload_completed"
5156 [(set (match_dup 0)
5157 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5158 (match_dup 2))
5159 (match_dup 3))
5160 (match_dup 4)) 0)))]
5161 {
5162 operands[1] = gen_lowpart (Pmode, operands[1]);
5163 operands[3] = gen_lowpart (Pmode, operands[3]);
5164 operands[4] = gen_lowpart (Pmode, operands[4]);
5165 }
5166 [(set_attr "type" "lea")
5167 (set_attr "mode" "SI")])
5168
5169 (define_insn "*adddi_1_rex64"
5170 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5171 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5172 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5173 (clobber (reg:CC FLAGS_REG))]
5174 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5175 {
5176 switch (get_attr_type (insn))
5177 {
5178 case TYPE_LEA:
5179 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5180 return "lea{q}\t{%a2, %0|%0, %a2}";
5181
5182 case TYPE_INCDEC:
5183 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5184 if (operands[2] == const1_rtx)
5185 return "inc{q}\t%0";
5186 else
5187 {
5188 gcc_assert (operands[2] == constm1_rtx);
5189 return "dec{q}\t%0";
5190 }
5191
5192 default:
5193 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5194
5195 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5196 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5197 if (CONST_INT_P (operands[2])
5198 /* Avoid overflows. */
5199 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5200 && (INTVAL (operands[2]) == 128
5201 || (INTVAL (operands[2]) < 0
5202 && INTVAL (operands[2]) != -128)))
5203 {
5204 operands[2] = GEN_INT (-INTVAL (operands[2]));
5205 return "sub{q}\t{%2, %0|%0, %2}";
5206 }
5207 return "add{q}\t{%2, %0|%0, %2}";
5208 }
5209 }
5210 [(set (attr "type")
5211 (cond [(eq_attr "alternative" "2")
5212 (const_string "lea")
5213 ; Current assemblers are broken and do not allow @GOTOFF in
5214 ; ought but a memory context.
5215 (match_operand:DI 2 "pic_symbolic_operand" "")
5216 (const_string "lea")
5217 (match_operand:DI 2 "incdec_operand" "")
5218 (const_string "incdec")
5219 ]
5220 (const_string "alu")))
5221 (set_attr "mode" "DI")])
5222
5223 ;; Convert lea to the lea pattern to avoid flags dependency.
5224 (define_split
5225 [(set (match_operand:DI 0 "register_operand" "")
5226 (plus:DI (match_operand:DI 1 "register_operand" "")
5227 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5228 (clobber (reg:CC FLAGS_REG))]
5229 "TARGET_64BIT && reload_completed
5230 && true_regnum (operands[0]) != true_regnum (operands[1])"
5231 [(set (match_dup 0)
5232 (plus:DI (match_dup 1)
5233 (match_dup 2)))]
5234 "")
5235
5236 (define_insn "*adddi_2_rex64"
5237 [(set (reg FLAGS_REG)
5238 (compare
5239 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5240 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5241 (const_int 0)))
5242 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5243 (plus:DI (match_dup 1) (match_dup 2)))]
5244 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5245 && ix86_binary_operator_ok (PLUS, DImode, operands)
5246 /* Current assemblers are broken and do not allow @GOTOFF in
5247 ought but a memory context. */
5248 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5249 {
5250 switch (get_attr_type (insn))
5251 {
5252 case TYPE_INCDEC:
5253 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5254 if (operands[2] == const1_rtx)
5255 return "inc{q}\t%0";
5256 else
5257 {
5258 gcc_assert (operands[2] == constm1_rtx);
5259 return "dec{q}\t%0";
5260 }
5261
5262 default:
5263 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5264 /* ???? We ought to handle there the 32bit case too
5265 - do we need new constraint? */
5266 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5267 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5268 if (CONST_INT_P (operands[2])
5269 /* Avoid overflows. */
5270 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5271 && (INTVAL (operands[2]) == 128
5272 || (INTVAL (operands[2]) < 0
5273 && INTVAL (operands[2]) != -128)))
5274 {
5275 operands[2] = GEN_INT (-INTVAL (operands[2]));
5276 return "sub{q}\t{%2, %0|%0, %2}";
5277 }
5278 return "add{q}\t{%2, %0|%0, %2}";
5279 }
5280 }
5281 [(set (attr "type")
5282 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5283 (const_string "incdec")
5284 (const_string "alu")))
5285 (set_attr "mode" "DI")])
5286
5287 (define_insn "*adddi_3_rex64"
5288 [(set (reg FLAGS_REG)
5289 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5290 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5291 (clobber (match_scratch:DI 0 "=r"))]
5292 "TARGET_64BIT
5293 && ix86_match_ccmode (insn, CCZmode)
5294 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5295 /* Current assemblers are broken and do not allow @GOTOFF in
5296 ought but a memory context. */
5297 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5298 {
5299 switch (get_attr_type (insn))
5300 {
5301 case TYPE_INCDEC:
5302 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5303 if (operands[2] == const1_rtx)
5304 return "inc{q}\t%0";
5305 else
5306 {
5307 gcc_assert (operands[2] == constm1_rtx);
5308 return "dec{q}\t%0";
5309 }
5310
5311 default:
5312 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5313 /* ???? We ought to handle there the 32bit case too
5314 - do we need new constraint? */
5315 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5316 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5317 if (CONST_INT_P (operands[2])
5318 /* Avoid overflows. */
5319 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5320 && (INTVAL (operands[2]) == 128
5321 || (INTVAL (operands[2]) < 0
5322 && INTVAL (operands[2]) != -128)))
5323 {
5324 operands[2] = GEN_INT (-INTVAL (operands[2]));
5325 return "sub{q}\t{%2, %0|%0, %2}";
5326 }
5327 return "add{q}\t{%2, %0|%0, %2}";
5328 }
5329 }
5330 [(set (attr "type")
5331 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5332 (const_string "incdec")
5333 (const_string "alu")))
5334 (set_attr "mode" "DI")])
5335
5336 ; For comparisons against 1, -1 and 128, we may generate better code
5337 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5338 ; is matched then. We can't accept general immediate, because for
5339 ; case of overflows, the result is messed up.
5340 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5341 ; when negated.
5342 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5343 ; only for comparisons not depending on it.
5344 (define_insn "*adddi_4_rex64"
5345 [(set (reg FLAGS_REG)
5346 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5347 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5348 (clobber (match_scratch:DI 0 "=rm"))]
5349 "TARGET_64BIT
5350 && ix86_match_ccmode (insn, CCGCmode)"
5351 {
5352 switch (get_attr_type (insn))
5353 {
5354 case TYPE_INCDEC:
5355 if (operands[2] == constm1_rtx)
5356 return "inc{q}\t%0";
5357 else
5358 {
5359 gcc_assert (operands[2] == const1_rtx);
5360 return "dec{q}\t%0";
5361 }
5362
5363 default:
5364 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5365 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5366 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5367 if ((INTVAL (operands[2]) == -128
5368 || (INTVAL (operands[2]) > 0
5369 && INTVAL (operands[2]) != 128))
5370 /* Avoid overflows. */
5371 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5372 return "sub{q}\t{%2, %0|%0, %2}";
5373 operands[2] = GEN_INT (-INTVAL (operands[2]));
5374 return "add{q}\t{%2, %0|%0, %2}";
5375 }
5376 }
5377 [(set (attr "type")
5378 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5379 (const_string "incdec")
5380 (const_string "alu")))
5381 (set_attr "mode" "DI")])
5382
5383 (define_insn "*adddi_5_rex64"
5384 [(set (reg FLAGS_REG)
5385 (compare
5386 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5387 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5388 (const_int 0)))
5389 (clobber (match_scratch:DI 0 "=r"))]
5390 "TARGET_64BIT
5391 && ix86_match_ccmode (insn, CCGOCmode)
5392 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5393 /* Current assemblers are broken and do not allow @GOTOFF in
5394 ought but a memory context. */
5395 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5396 {
5397 switch (get_attr_type (insn))
5398 {
5399 case TYPE_INCDEC:
5400 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5401 if (operands[2] == const1_rtx)
5402 return "inc{q}\t%0";
5403 else
5404 {
5405 gcc_assert (operands[2] == constm1_rtx);
5406 return "dec{q}\t%0";
5407 }
5408
5409 default:
5410 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5411 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5412 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5413 if (CONST_INT_P (operands[2])
5414 /* Avoid overflows. */
5415 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5416 && (INTVAL (operands[2]) == 128
5417 || (INTVAL (operands[2]) < 0
5418 && INTVAL (operands[2]) != -128)))
5419 {
5420 operands[2] = GEN_INT (-INTVAL (operands[2]));
5421 return "sub{q}\t{%2, %0|%0, %2}";
5422 }
5423 return "add{q}\t{%2, %0|%0, %2}";
5424 }
5425 }
5426 [(set (attr "type")
5427 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5428 (const_string "incdec")
5429 (const_string "alu")))
5430 (set_attr "mode" "DI")])
5431
5432
5433 (define_insn "*addsi_1"
5434 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5435 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5436 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5437 (clobber (reg:CC FLAGS_REG))]
5438 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5439 {
5440 switch (get_attr_type (insn))
5441 {
5442 case TYPE_LEA:
5443 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5444 return "lea{l}\t{%a2, %0|%0, %a2}";
5445
5446 case TYPE_INCDEC:
5447 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5448 if (operands[2] == const1_rtx)
5449 return "inc{l}\t%0";
5450 else
5451 {
5452 gcc_assert (operands[2] == constm1_rtx);
5453 return "dec{l}\t%0";
5454 }
5455
5456 default:
5457 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5458
5459 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5460 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5461 if (CONST_INT_P (operands[2])
5462 && (INTVAL (operands[2]) == 128
5463 || (INTVAL (operands[2]) < 0
5464 && INTVAL (operands[2]) != -128)))
5465 {
5466 operands[2] = GEN_INT (-INTVAL (operands[2]));
5467 return "sub{l}\t{%2, %0|%0, %2}";
5468 }
5469 return "add{l}\t{%2, %0|%0, %2}";
5470 }
5471 }
5472 [(set (attr "type")
5473 (cond [(eq_attr "alternative" "2")
5474 (const_string "lea")
5475 ; Current assemblers are broken and do not allow @GOTOFF in
5476 ; ought but a memory context.
5477 (match_operand:SI 2 "pic_symbolic_operand" "")
5478 (const_string "lea")
5479 (match_operand:SI 2 "incdec_operand" "")
5480 (const_string "incdec")
5481 ]
5482 (const_string "alu")))
5483 (set_attr "mode" "SI")])
5484
5485 ;; Convert lea to the lea pattern to avoid flags dependency.
5486 (define_split
5487 [(set (match_operand 0 "register_operand" "")
5488 (plus (match_operand 1 "register_operand" "")
5489 (match_operand 2 "nonmemory_operand" "")))
5490 (clobber (reg:CC FLAGS_REG))]
5491 "reload_completed
5492 && true_regnum (operands[0]) != true_regnum (operands[1])"
5493 [(const_int 0)]
5494 {
5495 rtx pat;
5496 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5497 may confuse gen_lowpart. */
5498 if (GET_MODE (operands[0]) != Pmode)
5499 {
5500 operands[1] = gen_lowpart (Pmode, operands[1]);
5501 operands[2] = gen_lowpart (Pmode, operands[2]);
5502 }
5503 operands[0] = gen_lowpart (SImode, operands[0]);
5504 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5505 if (Pmode != SImode)
5506 pat = gen_rtx_SUBREG (SImode, pat, 0);
5507 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5508 DONE;
5509 })
5510
5511 ;; It may seem that nonimmediate operand is proper one for operand 1.
5512 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5513 ;; we take care in ix86_binary_operator_ok to not allow two memory
5514 ;; operands so proper swapping will be done in reload. This allow
5515 ;; patterns constructed from addsi_1 to match.
5516 (define_insn "addsi_1_zext"
5517 [(set (match_operand:DI 0 "register_operand" "=r,r")
5518 (zero_extend:DI
5519 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5520 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5521 (clobber (reg:CC FLAGS_REG))]
5522 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5523 {
5524 switch (get_attr_type (insn))
5525 {
5526 case TYPE_LEA:
5527 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5528 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5529
5530 case TYPE_INCDEC:
5531 if (operands[2] == const1_rtx)
5532 return "inc{l}\t%k0";
5533 else
5534 {
5535 gcc_assert (operands[2] == constm1_rtx);
5536 return "dec{l}\t%k0";
5537 }
5538
5539 default:
5540 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5541 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5542 if (CONST_INT_P (operands[2])
5543 && (INTVAL (operands[2]) == 128
5544 || (INTVAL (operands[2]) < 0
5545 && INTVAL (operands[2]) != -128)))
5546 {
5547 operands[2] = GEN_INT (-INTVAL (operands[2]));
5548 return "sub{l}\t{%2, %k0|%k0, %2}";
5549 }
5550 return "add{l}\t{%2, %k0|%k0, %2}";
5551 }
5552 }
5553 [(set (attr "type")
5554 (cond [(eq_attr "alternative" "1")
5555 (const_string "lea")
5556 ; Current assemblers are broken and do not allow @GOTOFF in
5557 ; ought but a memory context.
5558 (match_operand:SI 2 "pic_symbolic_operand" "")
5559 (const_string "lea")
5560 (match_operand:SI 2 "incdec_operand" "")
5561 (const_string "incdec")
5562 ]
5563 (const_string "alu")))
5564 (set_attr "mode" "SI")])
5565
5566 ;; Convert lea to the lea pattern to avoid flags dependency.
5567 (define_split
5568 [(set (match_operand:DI 0 "register_operand" "")
5569 (zero_extend:DI
5570 (plus:SI (match_operand:SI 1 "register_operand" "")
5571 (match_operand:SI 2 "nonmemory_operand" ""))))
5572 (clobber (reg:CC FLAGS_REG))]
5573 "TARGET_64BIT && reload_completed
5574 && true_regnum (operands[0]) != true_regnum (operands[1])"
5575 [(set (match_dup 0)
5576 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5577 {
5578 operands[1] = gen_lowpart (Pmode, operands[1]);
5579 operands[2] = gen_lowpart (Pmode, operands[2]);
5580 })
5581
5582 (define_insn "*addsi_2"
5583 [(set (reg FLAGS_REG)
5584 (compare
5585 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5586 (match_operand:SI 2 "general_operand" "rmni,rni"))
5587 (const_int 0)))
5588 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5589 (plus:SI (match_dup 1) (match_dup 2)))]
5590 "ix86_match_ccmode (insn, CCGOCmode)
5591 && ix86_binary_operator_ok (PLUS, SImode, operands)
5592 /* Current assemblers are broken and do not allow @GOTOFF in
5593 ought but a memory context. */
5594 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5595 {
5596 switch (get_attr_type (insn))
5597 {
5598 case TYPE_INCDEC:
5599 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5600 if (operands[2] == const1_rtx)
5601 return "inc{l}\t%0";
5602 else
5603 {
5604 gcc_assert (operands[2] == constm1_rtx);
5605 return "dec{l}\t%0";
5606 }
5607
5608 default:
5609 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5610 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5611 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5612 if (CONST_INT_P (operands[2])
5613 && (INTVAL (operands[2]) == 128
5614 || (INTVAL (operands[2]) < 0
5615 && INTVAL (operands[2]) != -128)))
5616 {
5617 operands[2] = GEN_INT (-INTVAL (operands[2]));
5618 return "sub{l}\t{%2, %0|%0, %2}";
5619 }
5620 return "add{l}\t{%2, %0|%0, %2}";
5621 }
5622 }
5623 [(set (attr "type")
5624 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5625 (const_string "incdec")
5626 (const_string "alu")))
5627 (set_attr "mode" "SI")])
5628
5629 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5630 (define_insn "*addsi_2_zext"
5631 [(set (reg FLAGS_REG)
5632 (compare
5633 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5634 (match_operand:SI 2 "general_operand" "rmni"))
5635 (const_int 0)))
5636 (set (match_operand:DI 0 "register_operand" "=r")
5637 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5638 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5639 && ix86_binary_operator_ok (PLUS, SImode, operands)
5640 /* Current assemblers are broken and do not allow @GOTOFF in
5641 ought but a memory context. */
5642 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5643 {
5644 switch (get_attr_type (insn))
5645 {
5646 case TYPE_INCDEC:
5647 if (operands[2] == const1_rtx)
5648 return "inc{l}\t%k0";
5649 else
5650 {
5651 gcc_assert (operands[2] == constm1_rtx);
5652 return "dec{l}\t%k0";
5653 }
5654
5655 default:
5656 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5657 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5658 if (CONST_INT_P (operands[2])
5659 && (INTVAL (operands[2]) == 128
5660 || (INTVAL (operands[2]) < 0
5661 && INTVAL (operands[2]) != -128)))
5662 {
5663 operands[2] = GEN_INT (-INTVAL (operands[2]));
5664 return "sub{l}\t{%2, %k0|%k0, %2}";
5665 }
5666 return "add{l}\t{%2, %k0|%k0, %2}";
5667 }
5668 }
5669 [(set (attr "type")
5670 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5671 (const_string "incdec")
5672 (const_string "alu")))
5673 (set_attr "mode" "SI")])
5674
5675 (define_insn "*addsi_3"
5676 [(set (reg FLAGS_REG)
5677 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5678 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5679 (clobber (match_scratch:SI 0 "=r"))]
5680 "ix86_match_ccmode (insn, CCZmode)
5681 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5682 /* Current assemblers are broken and do not allow @GOTOFF in
5683 ought but a memory context. */
5684 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5685 {
5686 switch (get_attr_type (insn))
5687 {
5688 case TYPE_INCDEC:
5689 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5690 if (operands[2] == const1_rtx)
5691 return "inc{l}\t%0";
5692 else
5693 {
5694 gcc_assert (operands[2] == constm1_rtx);
5695 return "dec{l}\t%0";
5696 }
5697
5698 default:
5699 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5700 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5701 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5702 if (CONST_INT_P (operands[2])
5703 && (INTVAL (operands[2]) == 128
5704 || (INTVAL (operands[2]) < 0
5705 && INTVAL (operands[2]) != -128)))
5706 {
5707 operands[2] = GEN_INT (-INTVAL (operands[2]));
5708 return "sub{l}\t{%2, %0|%0, %2}";
5709 }
5710 return "add{l}\t{%2, %0|%0, %2}";
5711 }
5712 }
5713 [(set (attr "type")
5714 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5715 (const_string "incdec")
5716 (const_string "alu")))
5717 (set_attr "mode" "SI")])
5718
5719 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5720 (define_insn "*addsi_3_zext"
5721 [(set (reg FLAGS_REG)
5722 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5723 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5724 (set (match_operand:DI 0 "register_operand" "=r")
5725 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5726 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5727 && ix86_binary_operator_ok (PLUS, SImode, operands)
5728 /* Current assemblers are broken and do not allow @GOTOFF in
5729 ought but a memory context. */
5730 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5731 {
5732 switch (get_attr_type (insn))
5733 {
5734 case TYPE_INCDEC:
5735 if (operands[2] == const1_rtx)
5736 return "inc{l}\t%k0";
5737 else
5738 {
5739 gcc_assert (operands[2] == constm1_rtx);
5740 return "dec{l}\t%k0";
5741 }
5742
5743 default:
5744 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5745 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5746 if (CONST_INT_P (operands[2])
5747 && (INTVAL (operands[2]) == 128
5748 || (INTVAL (operands[2]) < 0
5749 && INTVAL (operands[2]) != -128)))
5750 {
5751 operands[2] = GEN_INT (-INTVAL (operands[2]));
5752 return "sub{l}\t{%2, %k0|%k0, %2}";
5753 }
5754 return "add{l}\t{%2, %k0|%k0, %2}";
5755 }
5756 }
5757 [(set (attr "type")
5758 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5759 (const_string "incdec")
5760 (const_string "alu")))
5761 (set_attr "mode" "SI")])
5762
5763 ; For comparisons against 1, -1 and 128, we may generate better code
5764 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5765 ; is matched then. We can't accept general immediate, because for
5766 ; case of overflows, the result is messed up.
5767 ; This pattern also don't hold of 0x80000000, since the value overflows
5768 ; when negated.
5769 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5770 ; only for comparisons not depending on it.
5771 (define_insn "*addsi_4"
5772 [(set (reg FLAGS_REG)
5773 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5774 (match_operand:SI 2 "const_int_operand" "n")))
5775 (clobber (match_scratch:SI 0 "=rm"))]
5776 "ix86_match_ccmode (insn, CCGCmode)
5777 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5778 {
5779 switch (get_attr_type (insn))
5780 {
5781 case TYPE_INCDEC:
5782 if (operands[2] == constm1_rtx)
5783 return "inc{l}\t%0";
5784 else
5785 {
5786 gcc_assert (operands[2] == const1_rtx);
5787 return "dec{l}\t%0";
5788 }
5789
5790 default:
5791 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5792 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5793 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5794 if ((INTVAL (operands[2]) == -128
5795 || (INTVAL (operands[2]) > 0
5796 && INTVAL (operands[2]) != 128)))
5797 return "sub{l}\t{%2, %0|%0, %2}";
5798 operands[2] = GEN_INT (-INTVAL (operands[2]));
5799 return "add{l}\t{%2, %0|%0, %2}";
5800 }
5801 }
5802 [(set (attr "type")
5803 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5804 (const_string "incdec")
5805 (const_string "alu")))
5806 (set_attr "mode" "SI")])
5807
5808 (define_insn "*addsi_5"
5809 [(set (reg FLAGS_REG)
5810 (compare
5811 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5812 (match_operand:SI 2 "general_operand" "rmni"))
5813 (const_int 0)))
5814 (clobber (match_scratch:SI 0 "=r"))]
5815 "ix86_match_ccmode (insn, CCGOCmode)
5816 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5817 /* Current assemblers are broken and do not allow @GOTOFF in
5818 ought but a memory context. */
5819 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5820 {
5821 switch (get_attr_type (insn))
5822 {
5823 case TYPE_INCDEC:
5824 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5825 if (operands[2] == const1_rtx)
5826 return "inc{l}\t%0";
5827 else
5828 {
5829 gcc_assert (operands[2] == constm1_rtx);
5830 return "dec{l}\t%0";
5831 }
5832
5833 default:
5834 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5835 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5836 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5837 if (CONST_INT_P (operands[2])
5838 && (INTVAL (operands[2]) == 128
5839 || (INTVAL (operands[2]) < 0
5840 && INTVAL (operands[2]) != -128)))
5841 {
5842 operands[2] = GEN_INT (-INTVAL (operands[2]));
5843 return "sub{l}\t{%2, %0|%0, %2}";
5844 }
5845 return "add{l}\t{%2, %0|%0, %2}";
5846 }
5847 }
5848 [(set (attr "type")
5849 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5850 (const_string "incdec")
5851 (const_string "alu")))
5852 (set_attr "mode" "SI")])
5853
5854 (define_expand "addhi3"
5855 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5856 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5857 (match_operand:HI 2 "general_operand" "")))
5858 (clobber (reg:CC FLAGS_REG))])]
5859 "TARGET_HIMODE_MATH"
5860 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5861
5862 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5863 ;; type optimizations enabled by define-splits. This is not important
5864 ;; for PII, and in fact harmful because of partial register stalls.
5865
5866 (define_insn "*addhi_1_lea"
5867 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5868 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5869 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5870 (clobber (reg:CC FLAGS_REG))]
5871 "!TARGET_PARTIAL_REG_STALL
5872 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5873 {
5874 switch (get_attr_type (insn))
5875 {
5876 case TYPE_LEA:
5877 return "#";
5878 case TYPE_INCDEC:
5879 if (operands[2] == const1_rtx)
5880 return "inc{w}\t%0";
5881 else
5882 {
5883 gcc_assert (operands[2] == constm1_rtx);
5884 return "dec{w}\t%0";
5885 }
5886
5887 default:
5888 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5889 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5890 if (CONST_INT_P (operands[2])
5891 && (INTVAL (operands[2]) == 128
5892 || (INTVAL (operands[2]) < 0
5893 && INTVAL (operands[2]) != -128)))
5894 {
5895 operands[2] = GEN_INT (-INTVAL (operands[2]));
5896 return "sub{w}\t{%2, %0|%0, %2}";
5897 }
5898 return "add{w}\t{%2, %0|%0, %2}";
5899 }
5900 }
5901 [(set (attr "type")
5902 (if_then_else (eq_attr "alternative" "2")
5903 (const_string "lea")
5904 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5905 (const_string "incdec")
5906 (const_string "alu"))))
5907 (set_attr "mode" "HI,HI,SI")])
5908
5909 (define_insn "*addhi_1"
5910 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5911 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5912 (match_operand:HI 2 "general_operand" "ri,rm")))
5913 (clobber (reg:CC FLAGS_REG))]
5914 "TARGET_PARTIAL_REG_STALL
5915 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5916 {
5917 switch (get_attr_type (insn))
5918 {
5919 case TYPE_INCDEC:
5920 if (operands[2] == const1_rtx)
5921 return "inc{w}\t%0";
5922 else
5923 {
5924 gcc_assert (operands[2] == constm1_rtx);
5925 return "dec{w}\t%0";
5926 }
5927
5928 default:
5929 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5930 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5931 if (CONST_INT_P (operands[2])
5932 && (INTVAL (operands[2]) == 128
5933 || (INTVAL (operands[2]) < 0
5934 && INTVAL (operands[2]) != -128)))
5935 {
5936 operands[2] = GEN_INT (-INTVAL (operands[2]));
5937 return "sub{w}\t{%2, %0|%0, %2}";
5938 }
5939 return "add{w}\t{%2, %0|%0, %2}";
5940 }
5941 }
5942 [(set (attr "type")
5943 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5944 (const_string "incdec")
5945 (const_string "alu")))
5946 (set_attr "mode" "HI")])
5947
5948 (define_insn "*addhi_2"
5949 [(set (reg FLAGS_REG)
5950 (compare
5951 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5952 (match_operand:HI 2 "general_operand" "rmni,rni"))
5953 (const_int 0)))
5954 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5955 (plus:HI (match_dup 1) (match_dup 2)))]
5956 "ix86_match_ccmode (insn, CCGOCmode)
5957 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5958 {
5959 switch (get_attr_type (insn))
5960 {
5961 case TYPE_INCDEC:
5962 if (operands[2] == const1_rtx)
5963 return "inc{w}\t%0";
5964 else
5965 {
5966 gcc_assert (operands[2] == constm1_rtx);
5967 return "dec{w}\t%0";
5968 }
5969
5970 default:
5971 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5972 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5973 if (CONST_INT_P (operands[2])
5974 && (INTVAL (operands[2]) == 128
5975 || (INTVAL (operands[2]) < 0
5976 && INTVAL (operands[2]) != -128)))
5977 {
5978 operands[2] = GEN_INT (-INTVAL (operands[2]));
5979 return "sub{w}\t{%2, %0|%0, %2}";
5980 }
5981 return "add{w}\t{%2, %0|%0, %2}";
5982 }
5983 }
5984 [(set (attr "type")
5985 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5986 (const_string "incdec")
5987 (const_string "alu")))
5988 (set_attr "mode" "HI")])
5989
5990 (define_insn "*addhi_3"
5991 [(set (reg FLAGS_REG)
5992 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5993 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5994 (clobber (match_scratch:HI 0 "=r"))]
5995 "ix86_match_ccmode (insn, CCZmode)
5996 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5997 {
5998 switch (get_attr_type (insn))
5999 {
6000 case TYPE_INCDEC:
6001 if (operands[2] == const1_rtx)
6002 return "inc{w}\t%0";
6003 else
6004 {
6005 gcc_assert (operands[2] == constm1_rtx);
6006 return "dec{w}\t%0";
6007 }
6008
6009 default:
6010 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6011 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6012 if (CONST_INT_P (operands[2])
6013 && (INTVAL (operands[2]) == 128
6014 || (INTVAL (operands[2]) < 0
6015 && INTVAL (operands[2]) != -128)))
6016 {
6017 operands[2] = GEN_INT (-INTVAL (operands[2]));
6018 return "sub{w}\t{%2, %0|%0, %2}";
6019 }
6020 return "add{w}\t{%2, %0|%0, %2}";
6021 }
6022 }
6023 [(set (attr "type")
6024 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6025 (const_string "incdec")
6026 (const_string "alu")))
6027 (set_attr "mode" "HI")])
6028
6029 ; See comments above addsi_4 for details.
6030 (define_insn "*addhi_4"
6031 [(set (reg FLAGS_REG)
6032 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6033 (match_operand:HI 2 "const_int_operand" "n")))
6034 (clobber (match_scratch:HI 0 "=rm"))]
6035 "ix86_match_ccmode (insn, CCGCmode)
6036 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6037 {
6038 switch (get_attr_type (insn))
6039 {
6040 case TYPE_INCDEC:
6041 if (operands[2] == constm1_rtx)
6042 return "inc{w}\t%0";
6043 else
6044 {
6045 gcc_assert (operands[2] == const1_rtx);
6046 return "dec{w}\t%0";
6047 }
6048
6049 default:
6050 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6051 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6052 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6053 if ((INTVAL (operands[2]) == -128
6054 || (INTVAL (operands[2]) > 0
6055 && INTVAL (operands[2]) != 128)))
6056 return "sub{w}\t{%2, %0|%0, %2}";
6057 operands[2] = GEN_INT (-INTVAL (operands[2]));
6058 return "add{w}\t{%2, %0|%0, %2}";
6059 }
6060 }
6061 [(set (attr "type")
6062 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6063 (const_string "incdec")
6064 (const_string "alu")))
6065 (set_attr "mode" "SI")])
6066
6067
6068 (define_insn "*addhi_5"
6069 [(set (reg FLAGS_REG)
6070 (compare
6071 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6072 (match_operand:HI 2 "general_operand" "rmni"))
6073 (const_int 0)))
6074 (clobber (match_scratch:HI 0 "=r"))]
6075 "ix86_match_ccmode (insn, CCGOCmode)
6076 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6077 {
6078 switch (get_attr_type (insn))
6079 {
6080 case TYPE_INCDEC:
6081 if (operands[2] == const1_rtx)
6082 return "inc{w}\t%0";
6083 else
6084 {
6085 gcc_assert (operands[2] == constm1_rtx);
6086 return "dec{w}\t%0";
6087 }
6088
6089 default:
6090 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6091 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6092 if (CONST_INT_P (operands[2])
6093 && (INTVAL (operands[2]) == 128
6094 || (INTVAL (operands[2]) < 0
6095 && INTVAL (operands[2]) != -128)))
6096 {
6097 operands[2] = GEN_INT (-INTVAL (operands[2]));
6098 return "sub{w}\t{%2, %0|%0, %2}";
6099 }
6100 return "add{w}\t{%2, %0|%0, %2}";
6101 }
6102 }
6103 [(set (attr "type")
6104 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6105 (const_string "incdec")
6106 (const_string "alu")))
6107 (set_attr "mode" "HI")])
6108
6109 (define_expand "addqi3"
6110 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6111 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6112 (match_operand:QI 2 "general_operand" "")))
6113 (clobber (reg:CC FLAGS_REG))])]
6114 "TARGET_QIMODE_MATH"
6115 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6116
6117 ;; %%% Potential partial reg stall on alternative 2. What to do?
6118 (define_insn "*addqi_1_lea"
6119 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6120 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6121 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6122 (clobber (reg:CC FLAGS_REG))]
6123 "!TARGET_PARTIAL_REG_STALL
6124 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6125 {
6126 int widen = (which_alternative == 2);
6127 switch (get_attr_type (insn))
6128 {
6129 case TYPE_LEA:
6130 return "#";
6131 case TYPE_INCDEC:
6132 if (operands[2] == const1_rtx)
6133 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6134 else
6135 {
6136 gcc_assert (operands[2] == constm1_rtx);
6137 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6138 }
6139
6140 default:
6141 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6143 if (CONST_INT_P (operands[2])
6144 && (INTVAL (operands[2]) == 128
6145 || (INTVAL (operands[2]) < 0
6146 && INTVAL (operands[2]) != -128)))
6147 {
6148 operands[2] = GEN_INT (-INTVAL (operands[2]));
6149 if (widen)
6150 return "sub{l}\t{%2, %k0|%k0, %2}";
6151 else
6152 return "sub{b}\t{%2, %0|%0, %2}";
6153 }
6154 if (widen)
6155 return "add{l}\t{%k2, %k0|%k0, %k2}";
6156 else
6157 return "add{b}\t{%2, %0|%0, %2}";
6158 }
6159 }
6160 [(set (attr "type")
6161 (if_then_else (eq_attr "alternative" "3")
6162 (const_string "lea")
6163 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6164 (const_string "incdec")
6165 (const_string "alu"))))
6166 (set_attr "mode" "QI,QI,SI,SI")])
6167
6168 (define_insn "*addqi_1"
6169 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6170 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6171 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6172 (clobber (reg:CC FLAGS_REG))]
6173 "TARGET_PARTIAL_REG_STALL
6174 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6175 {
6176 int widen = (which_alternative == 2);
6177 switch (get_attr_type (insn))
6178 {
6179 case TYPE_INCDEC:
6180 if (operands[2] == const1_rtx)
6181 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6182 else
6183 {
6184 gcc_assert (operands[2] == constm1_rtx);
6185 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6186 }
6187
6188 default:
6189 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6190 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6191 if (CONST_INT_P (operands[2])
6192 && (INTVAL (operands[2]) == 128
6193 || (INTVAL (operands[2]) < 0
6194 && INTVAL (operands[2]) != -128)))
6195 {
6196 operands[2] = GEN_INT (-INTVAL (operands[2]));
6197 if (widen)
6198 return "sub{l}\t{%2, %k0|%k0, %2}";
6199 else
6200 return "sub{b}\t{%2, %0|%0, %2}";
6201 }
6202 if (widen)
6203 return "add{l}\t{%k2, %k0|%k0, %k2}";
6204 else
6205 return "add{b}\t{%2, %0|%0, %2}";
6206 }
6207 }
6208 [(set (attr "type")
6209 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6210 (const_string "incdec")
6211 (const_string "alu")))
6212 (set_attr "mode" "QI,QI,SI")])
6213
6214 (define_insn "*addqi_1_slp"
6215 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6216 (plus:QI (match_dup 0)
6217 (match_operand:QI 1 "general_operand" "qn,qnm")))
6218 (clobber (reg:CC FLAGS_REG))]
6219 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6220 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6221 {
6222 switch (get_attr_type (insn))
6223 {
6224 case TYPE_INCDEC:
6225 if (operands[1] == const1_rtx)
6226 return "inc{b}\t%0";
6227 else
6228 {
6229 gcc_assert (operands[1] == constm1_rtx);
6230 return "dec{b}\t%0";
6231 }
6232
6233 default:
6234 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6235 if (CONST_INT_P (operands[1])
6236 && INTVAL (operands[1]) < 0)
6237 {
6238 operands[1] = GEN_INT (-INTVAL (operands[1]));
6239 return "sub{b}\t{%1, %0|%0, %1}";
6240 }
6241 return "add{b}\t{%1, %0|%0, %1}";
6242 }
6243 }
6244 [(set (attr "type")
6245 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6246 (const_string "incdec")
6247 (const_string "alu1")))
6248 (set (attr "memory")
6249 (if_then_else (match_operand 1 "memory_operand" "")
6250 (const_string "load")
6251 (const_string "none")))
6252 (set_attr "mode" "QI")])
6253
6254 (define_insn "*addqi_2"
6255 [(set (reg FLAGS_REG)
6256 (compare
6257 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6258 (match_operand:QI 2 "general_operand" "qmni,qni"))
6259 (const_int 0)))
6260 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6261 (plus:QI (match_dup 1) (match_dup 2)))]
6262 "ix86_match_ccmode (insn, CCGOCmode)
6263 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6264 {
6265 switch (get_attr_type (insn))
6266 {
6267 case TYPE_INCDEC:
6268 if (operands[2] == const1_rtx)
6269 return "inc{b}\t%0";
6270 else
6271 {
6272 gcc_assert (operands[2] == constm1_rtx
6273 || (CONST_INT_P (operands[2])
6274 && INTVAL (operands[2]) == 255));
6275 return "dec{b}\t%0";
6276 }
6277
6278 default:
6279 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6280 if (CONST_INT_P (operands[2])
6281 && INTVAL (operands[2]) < 0)
6282 {
6283 operands[2] = GEN_INT (-INTVAL (operands[2]));
6284 return "sub{b}\t{%2, %0|%0, %2}";
6285 }
6286 return "add{b}\t{%2, %0|%0, %2}";
6287 }
6288 }
6289 [(set (attr "type")
6290 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6291 (const_string "incdec")
6292 (const_string "alu")))
6293 (set_attr "mode" "QI")])
6294
6295 (define_insn "*addqi_3"
6296 [(set (reg FLAGS_REG)
6297 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6298 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6299 (clobber (match_scratch:QI 0 "=q"))]
6300 "ix86_match_ccmode (insn, CCZmode)
6301 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6302 {
6303 switch (get_attr_type (insn))
6304 {
6305 case TYPE_INCDEC:
6306 if (operands[2] == const1_rtx)
6307 return "inc{b}\t%0";
6308 else
6309 {
6310 gcc_assert (operands[2] == constm1_rtx
6311 || (CONST_INT_P (operands[2])
6312 && INTVAL (operands[2]) == 255));
6313 return "dec{b}\t%0";
6314 }
6315
6316 default:
6317 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6318 if (CONST_INT_P (operands[2])
6319 && INTVAL (operands[2]) < 0)
6320 {
6321 operands[2] = GEN_INT (-INTVAL (operands[2]));
6322 return "sub{b}\t{%2, %0|%0, %2}";
6323 }
6324 return "add{b}\t{%2, %0|%0, %2}";
6325 }
6326 }
6327 [(set (attr "type")
6328 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6329 (const_string "incdec")
6330 (const_string "alu")))
6331 (set_attr "mode" "QI")])
6332
6333 ; See comments above addsi_4 for details.
6334 (define_insn "*addqi_4"
6335 [(set (reg FLAGS_REG)
6336 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6337 (match_operand:QI 2 "const_int_operand" "n")))
6338 (clobber (match_scratch:QI 0 "=qm"))]
6339 "ix86_match_ccmode (insn, CCGCmode)
6340 && (INTVAL (operands[2]) & 0xff) != 0x80"
6341 {
6342 switch (get_attr_type (insn))
6343 {
6344 case TYPE_INCDEC:
6345 if (operands[2] == constm1_rtx
6346 || (CONST_INT_P (operands[2])
6347 && INTVAL (operands[2]) == 255))
6348 return "inc{b}\t%0";
6349 else
6350 {
6351 gcc_assert (operands[2] == const1_rtx);
6352 return "dec{b}\t%0";
6353 }
6354
6355 default:
6356 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6357 if (INTVAL (operands[2]) < 0)
6358 {
6359 operands[2] = GEN_INT (-INTVAL (operands[2]));
6360 return "add{b}\t{%2, %0|%0, %2}";
6361 }
6362 return "sub{b}\t{%2, %0|%0, %2}";
6363 }
6364 }
6365 [(set (attr "type")
6366 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6367 (const_string "incdec")
6368 (const_string "alu")))
6369 (set_attr "mode" "QI")])
6370
6371
6372 (define_insn "*addqi_5"
6373 [(set (reg FLAGS_REG)
6374 (compare
6375 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6376 (match_operand:QI 2 "general_operand" "qmni"))
6377 (const_int 0)))
6378 (clobber (match_scratch:QI 0 "=q"))]
6379 "ix86_match_ccmode (insn, CCGOCmode)
6380 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6381 {
6382 switch (get_attr_type (insn))
6383 {
6384 case TYPE_INCDEC:
6385 if (operands[2] == const1_rtx)
6386 return "inc{b}\t%0";
6387 else
6388 {
6389 gcc_assert (operands[2] == constm1_rtx
6390 || (CONST_INT_P (operands[2])
6391 && INTVAL (operands[2]) == 255));
6392 return "dec{b}\t%0";
6393 }
6394
6395 default:
6396 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6397 if (CONST_INT_P (operands[2])
6398 && INTVAL (operands[2]) < 0)
6399 {
6400 operands[2] = GEN_INT (-INTVAL (operands[2]));
6401 return "sub{b}\t{%2, %0|%0, %2}";
6402 }
6403 return "add{b}\t{%2, %0|%0, %2}";
6404 }
6405 }
6406 [(set (attr "type")
6407 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6408 (const_string "incdec")
6409 (const_string "alu")))
6410 (set_attr "mode" "QI")])
6411
6412
6413 (define_insn "addqi_ext_1"
6414 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6415 (const_int 8)
6416 (const_int 8))
6417 (plus:SI
6418 (zero_extract:SI
6419 (match_operand 1 "ext_register_operand" "0")
6420 (const_int 8)
6421 (const_int 8))
6422 (match_operand:QI 2 "general_operand" "Qmn")))
6423 (clobber (reg:CC FLAGS_REG))]
6424 "!TARGET_64BIT"
6425 {
6426 switch (get_attr_type (insn))
6427 {
6428 case TYPE_INCDEC:
6429 if (operands[2] == const1_rtx)
6430 return "inc{b}\t%h0";
6431 else
6432 {
6433 gcc_assert (operands[2] == constm1_rtx
6434 || (CONST_INT_P (operands[2])
6435 && INTVAL (operands[2]) == 255));
6436 return "dec{b}\t%h0";
6437 }
6438
6439 default:
6440 return "add{b}\t{%2, %h0|%h0, %2}";
6441 }
6442 }
6443 [(set (attr "type")
6444 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6445 (const_string "incdec")
6446 (const_string "alu")))
6447 (set_attr "mode" "QI")])
6448
6449 (define_insn "*addqi_ext_1_rex64"
6450 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6451 (const_int 8)
6452 (const_int 8))
6453 (plus:SI
6454 (zero_extract:SI
6455 (match_operand 1 "ext_register_operand" "0")
6456 (const_int 8)
6457 (const_int 8))
6458 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6459 (clobber (reg:CC FLAGS_REG))]
6460 "TARGET_64BIT"
6461 {
6462 switch (get_attr_type (insn))
6463 {
6464 case TYPE_INCDEC:
6465 if (operands[2] == const1_rtx)
6466 return "inc{b}\t%h0";
6467 else
6468 {
6469 gcc_assert (operands[2] == constm1_rtx
6470 || (CONST_INT_P (operands[2])
6471 && INTVAL (operands[2]) == 255));
6472 return "dec{b}\t%h0";
6473 }
6474
6475 default:
6476 return "add{b}\t{%2, %h0|%h0, %2}";
6477 }
6478 }
6479 [(set (attr "type")
6480 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6481 (const_string "incdec")
6482 (const_string "alu")))
6483 (set_attr "mode" "QI")])
6484
6485 (define_insn "*addqi_ext_2"
6486 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6487 (const_int 8)
6488 (const_int 8))
6489 (plus:SI
6490 (zero_extract:SI
6491 (match_operand 1 "ext_register_operand" "%0")
6492 (const_int 8)
6493 (const_int 8))
6494 (zero_extract:SI
6495 (match_operand 2 "ext_register_operand" "Q")
6496 (const_int 8)
6497 (const_int 8))))
6498 (clobber (reg:CC FLAGS_REG))]
6499 ""
6500 "add{b}\t{%h2, %h0|%h0, %h2}"
6501 [(set_attr "type" "alu")
6502 (set_attr "mode" "QI")])
6503
6504 ;; The patterns that match these are at the end of this file.
6505
6506 (define_expand "addxf3"
6507 [(set (match_operand:XF 0 "register_operand" "")
6508 (plus:XF (match_operand:XF 1 "register_operand" "")
6509 (match_operand:XF 2 "register_operand" "")))]
6510 "TARGET_80387"
6511 "")
6512
6513 (define_expand "adddf3"
6514 [(set (match_operand:DF 0 "register_operand" "")
6515 (plus:DF (match_operand:DF 1 "register_operand" "")
6516 (match_operand:DF 2 "nonimmediate_operand" "")))]
6517 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6518 "")
6519
6520 (define_expand "addsf3"
6521 [(set (match_operand:SF 0 "register_operand" "")
6522 (plus:SF (match_operand:SF 1 "register_operand" "")
6523 (match_operand:SF 2 "nonimmediate_operand" "")))]
6524 "TARGET_80387 || TARGET_SSE_MATH"
6525 "")
6526 \f
6527 ;; Subtract instructions
6528
6529 ;; %%% splits for subditi3
6530
6531 (define_expand "subti3"
6532 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6533 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6534 (match_operand:TI 2 "x86_64_general_operand" "")))
6535 (clobber (reg:CC FLAGS_REG))])]
6536 "TARGET_64BIT"
6537 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6538
6539 (define_insn "*subti3_1"
6540 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6541 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6542 (match_operand:TI 2 "general_operand" "roiF,riF")))
6543 (clobber (reg:CC FLAGS_REG))]
6544 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6545 "#")
6546
6547 (define_split
6548 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6549 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6550 (match_operand:TI 2 "general_operand" "")))
6551 (clobber (reg:CC FLAGS_REG))]
6552 "TARGET_64BIT && reload_completed"
6553 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6554 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6555 (parallel [(set (match_dup 3)
6556 (minus:DI (match_dup 4)
6557 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6558 (match_dup 5))))
6559 (clobber (reg:CC FLAGS_REG))])]
6560 "split_ti (operands+0, 1, operands+0, operands+3);
6561 split_ti (operands+1, 1, operands+1, operands+4);
6562 split_ti (operands+2, 1, operands+2, operands+5);")
6563
6564 ;; %%% splits for subsidi3
6565
6566 (define_expand "subdi3"
6567 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6568 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6569 (match_operand:DI 2 "x86_64_general_operand" "")))
6570 (clobber (reg:CC FLAGS_REG))])]
6571 ""
6572 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6573
6574 (define_insn "*subdi3_1"
6575 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6576 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6577 (match_operand:DI 2 "general_operand" "roiF,riF")))
6578 (clobber (reg:CC FLAGS_REG))]
6579 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6580 "#")
6581
6582 (define_split
6583 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6584 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6585 (match_operand:DI 2 "general_operand" "")))
6586 (clobber (reg:CC FLAGS_REG))]
6587 "!TARGET_64BIT && reload_completed"
6588 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6589 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6590 (parallel [(set (match_dup 3)
6591 (minus:SI (match_dup 4)
6592 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6593 (match_dup 5))))
6594 (clobber (reg:CC FLAGS_REG))])]
6595 "split_di (operands+0, 1, operands+0, operands+3);
6596 split_di (operands+1, 1, operands+1, operands+4);
6597 split_di (operands+2, 1, operands+2, operands+5);")
6598
6599 (define_insn "subdi3_carry_rex64"
6600 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6601 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6602 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6603 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6604 (clobber (reg:CC FLAGS_REG))]
6605 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6606 "sbb{q}\t{%2, %0|%0, %2}"
6607 [(set_attr "type" "alu")
6608 (set_attr "pent_pair" "pu")
6609 (set_attr "mode" "DI")])
6610
6611 (define_insn "*subdi_1_rex64"
6612 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6613 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6614 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6615 (clobber (reg:CC FLAGS_REG))]
6616 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6617 "sub{q}\t{%2, %0|%0, %2}"
6618 [(set_attr "type" "alu")
6619 (set_attr "mode" "DI")])
6620
6621 (define_insn "*subdi_2_rex64"
6622 [(set (reg FLAGS_REG)
6623 (compare
6624 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6625 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6626 (const_int 0)))
6627 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6628 (minus:DI (match_dup 1) (match_dup 2)))]
6629 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6630 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6631 "sub{q}\t{%2, %0|%0, %2}"
6632 [(set_attr "type" "alu")
6633 (set_attr "mode" "DI")])
6634
6635 (define_insn "*subdi_3_rex63"
6636 [(set (reg FLAGS_REG)
6637 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6638 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6639 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6640 (minus:DI (match_dup 1) (match_dup 2)))]
6641 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6642 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6643 "sub{q}\t{%2, %0|%0, %2}"
6644 [(set_attr "type" "alu")
6645 (set_attr "mode" "DI")])
6646
6647 (define_insn "subqi3_carry"
6648 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6649 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6650 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6651 (match_operand:QI 2 "general_operand" "qi,qm"))))
6652 (clobber (reg:CC FLAGS_REG))]
6653 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6654 "sbb{b}\t{%2, %0|%0, %2}"
6655 [(set_attr "type" "alu")
6656 (set_attr "pent_pair" "pu")
6657 (set_attr "mode" "QI")])
6658
6659 (define_insn "subhi3_carry"
6660 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6661 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6662 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6663 (match_operand:HI 2 "general_operand" "ri,rm"))))
6664 (clobber (reg:CC FLAGS_REG))]
6665 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6666 "sbb{w}\t{%2, %0|%0, %2}"
6667 [(set_attr "type" "alu")
6668 (set_attr "pent_pair" "pu")
6669 (set_attr "mode" "HI")])
6670
6671 (define_insn "subsi3_carry"
6672 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6673 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6674 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6675 (match_operand:SI 2 "general_operand" "ri,rm"))))
6676 (clobber (reg:CC FLAGS_REG))]
6677 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6678 "sbb{l}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "pent_pair" "pu")
6681 (set_attr "mode" "SI")])
6682
6683 (define_insn "subsi3_carry_zext"
6684 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6685 (zero_extend:DI
6686 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6687 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6688 (match_operand:SI 2 "general_operand" "ri,rm")))))
6689 (clobber (reg:CC FLAGS_REG))]
6690 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6691 "sbb{l}\t{%2, %k0|%k0, %2}"
6692 [(set_attr "type" "alu")
6693 (set_attr "pent_pair" "pu")
6694 (set_attr "mode" "SI")])
6695
6696 (define_expand "subsi3"
6697 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6698 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6699 (match_operand:SI 2 "general_operand" "")))
6700 (clobber (reg:CC FLAGS_REG))])]
6701 ""
6702 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6703
6704 (define_insn "*subsi_1"
6705 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6706 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6707 (match_operand:SI 2 "general_operand" "ri,rm")))
6708 (clobber (reg:CC FLAGS_REG))]
6709 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6710 "sub{l}\t{%2, %0|%0, %2}"
6711 [(set_attr "type" "alu")
6712 (set_attr "mode" "SI")])
6713
6714 (define_insn "*subsi_1_zext"
6715 [(set (match_operand:DI 0 "register_operand" "=r")
6716 (zero_extend:DI
6717 (minus:SI (match_operand:SI 1 "register_operand" "0")
6718 (match_operand:SI 2 "general_operand" "rim"))))
6719 (clobber (reg:CC FLAGS_REG))]
6720 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721 "sub{l}\t{%2, %k0|%k0, %2}"
6722 [(set_attr "type" "alu")
6723 (set_attr "mode" "SI")])
6724
6725 (define_insn "*subsi_2"
6726 [(set (reg FLAGS_REG)
6727 (compare
6728 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6729 (match_operand:SI 2 "general_operand" "ri,rm"))
6730 (const_int 0)))
6731 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6732 (minus:SI (match_dup 1) (match_dup 2)))]
6733 "ix86_match_ccmode (insn, CCGOCmode)
6734 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735 "sub{l}\t{%2, %0|%0, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "mode" "SI")])
6738
6739 (define_insn "*subsi_2_zext"
6740 [(set (reg FLAGS_REG)
6741 (compare
6742 (minus:SI (match_operand:SI 1 "register_operand" "0")
6743 (match_operand:SI 2 "general_operand" "rim"))
6744 (const_int 0)))
6745 (set (match_operand:DI 0 "register_operand" "=r")
6746 (zero_extend:DI
6747 (minus:SI (match_dup 1)
6748 (match_dup 2))))]
6749 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6750 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6751 "sub{l}\t{%2, %k0|%k0, %2}"
6752 [(set_attr "type" "alu")
6753 (set_attr "mode" "SI")])
6754
6755 (define_insn "*subsi_3"
6756 [(set (reg FLAGS_REG)
6757 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6758 (match_operand:SI 2 "general_operand" "ri,rm")))
6759 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6760 (minus:SI (match_dup 1) (match_dup 2)))]
6761 "ix86_match_ccmode (insn, CCmode)
6762 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6763 "sub{l}\t{%2, %0|%0, %2}"
6764 [(set_attr "type" "alu")
6765 (set_attr "mode" "SI")])
6766
6767 (define_insn "*subsi_3_zext"
6768 [(set (reg FLAGS_REG)
6769 (compare (match_operand:SI 1 "register_operand" "0")
6770 (match_operand:SI 2 "general_operand" "rim")))
6771 (set (match_operand:DI 0 "register_operand" "=r")
6772 (zero_extend:DI
6773 (minus:SI (match_dup 1)
6774 (match_dup 2))))]
6775 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6776 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6777 "sub{l}\t{%2, %1|%1, %2}"
6778 [(set_attr "type" "alu")
6779 (set_attr "mode" "DI")])
6780
6781 (define_expand "subhi3"
6782 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6783 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6784 (match_operand:HI 2 "general_operand" "")))
6785 (clobber (reg:CC FLAGS_REG))])]
6786 "TARGET_HIMODE_MATH"
6787 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6788
6789 (define_insn "*subhi_1"
6790 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6791 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6792 (match_operand:HI 2 "general_operand" "ri,rm")))
6793 (clobber (reg:CC FLAGS_REG))]
6794 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6795 "sub{w}\t{%2, %0|%0, %2}"
6796 [(set_attr "type" "alu")
6797 (set_attr "mode" "HI")])
6798
6799 (define_insn "*subhi_2"
6800 [(set (reg FLAGS_REG)
6801 (compare
6802 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6803 (match_operand:HI 2 "general_operand" "ri,rm"))
6804 (const_int 0)))
6805 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6806 (minus:HI (match_dup 1) (match_dup 2)))]
6807 "ix86_match_ccmode (insn, CCGOCmode)
6808 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6809 "sub{w}\t{%2, %0|%0, %2}"
6810 [(set_attr "type" "alu")
6811 (set_attr "mode" "HI")])
6812
6813 (define_insn "*subhi_3"
6814 [(set (reg FLAGS_REG)
6815 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6816 (match_operand:HI 2 "general_operand" "ri,rm")))
6817 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6818 (minus:HI (match_dup 1) (match_dup 2)))]
6819 "ix86_match_ccmode (insn, CCmode)
6820 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6821 "sub{w}\t{%2, %0|%0, %2}"
6822 [(set_attr "type" "alu")
6823 (set_attr "mode" "HI")])
6824
6825 (define_expand "subqi3"
6826 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6827 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6828 (match_operand:QI 2 "general_operand" "")))
6829 (clobber (reg:CC FLAGS_REG))])]
6830 "TARGET_QIMODE_MATH"
6831 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6832
6833 (define_insn "*subqi_1"
6834 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6835 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6836 (match_operand:QI 2 "general_operand" "qn,qmn")))
6837 (clobber (reg:CC FLAGS_REG))]
6838 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6839 "sub{b}\t{%2, %0|%0, %2}"
6840 [(set_attr "type" "alu")
6841 (set_attr "mode" "QI")])
6842
6843 (define_insn "*subqi_1_slp"
6844 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6845 (minus:QI (match_dup 0)
6846 (match_operand:QI 1 "general_operand" "qn,qmn")))
6847 (clobber (reg:CC FLAGS_REG))]
6848 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6849 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6850 "sub{b}\t{%1, %0|%0, %1}"
6851 [(set_attr "type" "alu1")
6852 (set_attr "mode" "QI")])
6853
6854 (define_insn "*subqi_2"
6855 [(set (reg FLAGS_REG)
6856 (compare
6857 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6858 (match_operand:QI 2 "general_operand" "qi,qm"))
6859 (const_int 0)))
6860 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6861 (minus:HI (match_dup 1) (match_dup 2)))]
6862 "ix86_match_ccmode (insn, CCGOCmode)
6863 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6864 "sub{b}\t{%2, %0|%0, %2}"
6865 [(set_attr "type" "alu")
6866 (set_attr "mode" "QI")])
6867
6868 (define_insn "*subqi_3"
6869 [(set (reg FLAGS_REG)
6870 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6871 (match_operand:QI 2 "general_operand" "qi,qm")))
6872 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6873 (minus:HI (match_dup 1) (match_dup 2)))]
6874 "ix86_match_ccmode (insn, CCmode)
6875 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6876 "sub{b}\t{%2, %0|%0, %2}"
6877 [(set_attr "type" "alu")
6878 (set_attr "mode" "QI")])
6879
6880 ;; The patterns that match these are at the end of this file.
6881
6882 (define_expand "subxf3"
6883 [(set (match_operand:XF 0 "register_operand" "")
6884 (minus:XF (match_operand:XF 1 "register_operand" "")
6885 (match_operand:XF 2 "register_operand" "")))]
6886 "TARGET_80387"
6887 "")
6888
6889 (define_expand "subdf3"
6890 [(set (match_operand:DF 0 "register_operand" "")
6891 (minus:DF (match_operand:DF 1 "register_operand" "")
6892 (match_operand:DF 2 "nonimmediate_operand" "")))]
6893 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6894 "")
6895
6896 (define_expand "subsf3"
6897 [(set (match_operand:SF 0 "register_operand" "")
6898 (minus:SF (match_operand:SF 1 "register_operand" "")
6899 (match_operand:SF 2 "nonimmediate_operand" "")))]
6900 "TARGET_80387 || TARGET_SSE_MATH"
6901 "")
6902 \f
6903 ;; Multiply instructions
6904
6905 (define_expand "muldi3"
6906 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6907 (mult:DI (match_operand:DI 1 "register_operand" "")
6908 (match_operand:DI 2 "x86_64_general_operand" "")))
6909 (clobber (reg:CC FLAGS_REG))])]
6910 "TARGET_64BIT"
6911 "")
6912
6913 (define_insn "*muldi3_1_rex64"
6914 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6915 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6916 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6917 (clobber (reg:CC FLAGS_REG))]
6918 "TARGET_64BIT
6919 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6920 "@
6921 imul{q}\t{%2, %1, %0|%0, %1, %2}
6922 imul{q}\t{%2, %1, %0|%0, %1, %2}
6923 imul{q}\t{%2, %0|%0, %2}"
6924 [(set_attr "type" "imul")
6925 (set_attr "prefix_0f" "0,0,1")
6926 (set (attr "athlon_decode")
6927 (cond [(eq_attr "cpu" "athlon")
6928 (const_string "vector")
6929 (eq_attr "alternative" "1")
6930 (const_string "vector")
6931 (and (eq_attr "alternative" "2")
6932 (match_operand 1 "memory_operand" ""))
6933 (const_string "vector")]
6934 (const_string "direct")))
6935 (set_attr "mode" "DI")])
6936
6937 (define_expand "mulsi3"
6938 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6939 (mult:SI (match_operand:SI 1 "register_operand" "")
6940 (match_operand:SI 2 "general_operand" "")))
6941 (clobber (reg:CC FLAGS_REG))])]
6942 ""
6943 "")
6944
6945 (define_insn "*mulsi3_1"
6946 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6947 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6948 (match_operand:SI 2 "general_operand" "K,i,mr")))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6951 "@
6952 imul{l}\t{%2, %1, %0|%0, %1, %2}
6953 imul{l}\t{%2, %1, %0|%0, %1, %2}
6954 imul{l}\t{%2, %0|%0, %2}"
6955 [(set_attr "type" "imul")
6956 (set_attr "prefix_0f" "0,0,1")
6957 (set (attr "athlon_decode")
6958 (cond [(eq_attr "cpu" "athlon")
6959 (const_string "vector")
6960 (eq_attr "alternative" "1")
6961 (const_string "vector")
6962 (and (eq_attr "alternative" "2")
6963 (match_operand 1 "memory_operand" ""))
6964 (const_string "vector")]
6965 (const_string "direct")))
6966 (set_attr "mode" "SI")])
6967
6968 (define_insn "*mulsi3_1_zext"
6969 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6970 (zero_extend:DI
6971 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6972 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6973 (clobber (reg:CC FLAGS_REG))]
6974 "TARGET_64BIT
6975 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6976 "@
6977 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6978 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6979 imul{l}\t{%2, %k0|%k0, %2}"
6980 [(set_attr "type" "imul")
6981 (set_attr "prefix_0f" "0,0,1")
6982 (set (attr "athlon_decode")
6983 (cond [(eq_attr "cpu" "athlon")
6984 (const_string "vector")
6985 (eq_attr "alternative" "1")
6986 (const_string "vector")
6987 (and (eq_attr "alternative" "2")
6988 (match_operand 1 "memory_operand" ""))
6989 (const_string "vector")]
6990 (const_string "direct")))
6991 (set_attr "mode" "SI")])
6992
6993 (define_expand "mulhi3"
6994 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6995 (mult:HI (match_operand:HI 1 "register_operand" "")
6996 (match_operand:HI 2 "general_operand" "")))
6997 (clobber (reg:CC FLAGS_REG))])]
6998 "TARGET_HIMODE_MATH"
6999 "")
7000
7001 (define_insn "*mulhi3_1"
7002 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7003 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7004 (match_operand:HI 2 "general_operand" "K,i,mr")))
7005 (clobber (reg:CC FLAGS_REG))]
7006 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7007 "@
7008 imul{w}\t{%2, %1, %0|%0, %1, %2}
7009 imul{w}\t{%2, %1, %0|%0, %1, %2}
7010 imul{w}\t{%2, %0|%0, %2}"
7011 [(set_attr "type" "imul")
7012 (set_attr "prefix_0f" "0,0,1")
7013 (set (attr "athlon_decode")
7014 (cond [(eq_attr "cpu" "athlon")
7015 (const_string "vector")
7016 (eq_attr "alternative" "1,2")
7017 (const_string "vector")]
7018 (const_string "direct")))
7019 (set_attr "mode" "HI")])
7020
7021 (define_expand "mulqi3"
7022 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7023 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7024 (match_operand:QI 2 "register_operand" "")))
7025 (clobber (reg:CC FLAGS_REG))])]
7026 "TARGET_QIMODE_MATH"
7027 "")
7028
7029 (define_insn "*mulqi3_1"
7030 [(set (match_operand:QI 0 "register_operand" "=a")
7031 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7032 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7033 (clobber (reg:CC FLAGS_REG))]
7034 "TARGET_QIMODE_MATH
7035 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7036 "mul{b}\t%2"
7037 [(set_attr "type" "imul")
7038 (set_attr "length_immediate" "0")
7039 (set (attr "athlon_decode")
7040 (if_then_else (eq_attr "cpu" "athlon")
7041 (const_string "vector")
7042 (const_string "direct")))
7043 (set_attr "mode" "QI")])
7044
7045 (define_expand "umulqihi3"
7046 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7047 (mult:HI (zero_extend:HI
7048 (match_operand:QI 1 "nonimmediate_operand" ""))
7049 (zero_extend:HI
7050 (match_operand:QI 2 "register_operand" ""))))
7051 (clobber (reg:CC FLAGS_REG))])]
7052 "TARGET_QIMODE_MATH"
7053 "")
7054
7055 (define_insn "*umulqihi3_1"
7056 [(set (match_operand:HI 0 "register_operand" "=a")
7057 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7058 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7059 (clobber (reg:CC FLAGS_REG))]
7060 "TARGET_QIMODE_MATH
7061 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7062 "mul{b}\t%2"
7063 [(set_attr "type" "imul")
7064 (set_attr "length_immediate" "0")
7065 (set (attr "athlon_decode")
7066 (if_then_else (eq_attr "cpu" "athlon")
7067 (const_string "vector")
7068 (const_string "direct")))
7069 (set_attr "mode" "QI")])
7070
7071 (define_expand "mulqihi3"
7072 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7073 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7074 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7075 (clobber (reg:CC FLAGS_REG))])]
7076 "TARGET_QIMODE_MATH"
7077 "")
7078
7079 (define_insn "*mulqihi3_insn"
7080 [(set (match_operand:HI 0 "register_operand" "=a")
7081 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7082 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7083 (clobber (reg:CC FLAGS_REG))]
7084 "TARGET_QIMODE_MATH
7085 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7086 "imul{b}\t%2"
7087 [(set_attr "type" "imul")
7088 (set_attr "length_immediate" "0")
7089 (set (attr "athlon_decode")
7090 (if_then_else (eq_attr "cpu" "athlon")
7091 (const_string "vector")
7092 (const_string "direct")))
7093 (set_attr "mode" "QI")])
7094
7095 (define_expand "umulditi3"
7096 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7097 (mult:TI (zero_extend:TI
7098 (match_operand:DI 1 "nonimmediate_operand" ""))
7099 (zero_extend:TI
7100 (match_operand:DI 2 "register_operand" ""))))
7101 (clobber (reg:CC FLAGS_REG))])]
7102 "TARGET_64BIT"
7103 "")
7104
7105 (define_insn "*umulditi3_insn"
7106 [(set (match_operand:TI 0 "register_operand" "=A")
7107 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7108 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7109 (clobber (reg:CC FLAGS_REG))]
7110 "TARGET_64BIT
7111 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7112 "mul{q}\t%2"
7113 [(set_attr "type" "imul")
7114 (set_attr "length_immediate" "0")
7115 (set (attr "athlon_decode")
7116 (if_then_else (eq_attr "cpu" "athlon")
7117 (const_string "vector")
7118 (const_string "double")))
7119 (set_attr "mode" "DI")])
7120
7121 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7122 (define_expand "umulsidi3"
7123 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7124 (mult:DI (zero_extend:DI
7125 (match_operand:SI 1 "nonimmediate_operand" ""))
7126 (zero_extend:DI
7127 (match_operand:SI 2 "register_operand" ""))))
7128 (clobber (reg:CC FLAGS_REG))])]
7129 "!TARGET_64BIT"
7130 "")
7131
7132 (define_insn "*umulsidi3_insn"
7133 [(set (match_operand:DI 0 "register_operand" "=A")
7134 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7135 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7136 (clobber (reg:CC FLAGS_REG))]
7137 "!TARGET_64BIT
7138 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7139 "mul{l}\t%2"
7140 [(set_attr "type" "imul")
7141 (set_attr "length_immediate" "0")
7142 (set (attr "athlon_decode")
7143 (if_then_else (eq_attr "cpu" "athlon")
7144 (const_string "vector")
7145 (const_string "double")))
7146 (set_attr "mode" "SI")])
7147
7148 (define_expand "mulditi3"
7149 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7150 (mult:TI (sign_extend:TI
7151 (match_operand:DI 1 "nonimmediate_operand" ""))
7152 (sign_extend:TI
7153 (match_operand:DI 2 "register_operand" ""))))
7154 (clobber (reg:CC FLAGS_REG))])]
7155 "TARGET_64BIT"
7156 "")
7157
7158 (define_insn "*mulditi3_insn"
7159 [(set (match_operand:TI 0 "register_operand" "=A")
7160 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7161 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7162 (clobber (reg:CC FLAGS_REG))]
7163 "TARGET_64BIT
7164 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7165 "imul{q}\t%2"
7166 [(set_attr "type" "imul")
7167 (set_attr "length_immediate" "0")
7168 (set (attr "athlon_decode")
7169 (if_then_else (eq_attr "cpu" "athlon")
7170 (const_string "vector")
7171 (const_string "double")))
7172 (set_attr "mode" "DI")])
7173
7174 (define_expand "mulsidi3"
7175 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7176 (mult:DI (sign_extend:DI
7177 (match_operand:SI 1 "nonimmediate_operand" ""))
7178 (sign_extend:DI
7179 (match_operand:SI 2 "register_operand" ""))))
7180 (clobber (reg:CC FLAGS_REG))])]
7181 "!TARGET_64BIT"
7182 "")
7183
7184 (define_insn "*mulsidi3_insn"
7185 [(set (match_operand:DI 0 "register_operand" "=A")
7186 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7187 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7188 (clobber (reg:CC FLAGS_REG))]
7189 "!TARGET_64BIT
7190 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7191 "imul{l}\t%2"
7192 [(set_attr "type" "imul")
7193 (set_attr "length_immediate" "0")
7194 (set (attr "athlon_decode")
7195 (if_then_else (eq_attr "cpu" "athlon")
7196 (const_string "vector")
7197 (const_string "double")))
7198 (set_attr "mode" "SI")])
7199
7200 (define_expand "umuldi3_highpart"
7201 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7202 (truncate:DI
7203 (lshiftrt:TI
7204 (mult:TI (zero_extend:TI
7205 (match_operand:DI 1 "nonimmediate_operand" ""))
7206 (zero_extend:TI
7207 (match_operand:DI 2 "register_operand" "")))
7208 (const_int 64))))
7209 (clobber (match_scratch:DI 3 ""))
7210 (clobber (reg:CC FLAGS_REG))])]
7211 "TARGET_64BIT"
7212 "")
7213
7214 (define_insn "*umuldi3_highpart_rex64"
7215 [(set (match_operand:DI 0 "register_operand" "=d")
7216 (truncate:DI
7217 (lshiftrt:TI
7218 (mult:TI (zero_extend:TI
7219 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7220 (zero_extend:TI
7221 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7222 (const_int 64))))
7223 (clobber (match_scratch:DI 3 "=1"))
7224 (clobber (reg:CC FLAGS_REG))]
7225 "TARGET_64BIT
7226 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7227 "mul{q}\t%2"
7228 [(set_attr "type" "imul")
7229 (set_attr "length_immediate" "0")
7230 (set (attr "athlon_decode")
7231 (if_then_else (eq_attr "cpu" "athlon")
7232 (const_string "vector")
7233 (const_string "double")))
7234 (set_attr "mode" "DI")])
7235
7236 (define_expand "umulsi3_highpart"
7237 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7238 (truncate:SI
7239 (lshiftrt:DI
7240 (mult:DI (zero_extend:DI
7241 (match_operand:SI 1 "nonimmediate_operand" ""))
7242 (zero_extend:DI
7243 (match_operand:SI 2 "register_operand" "")))
7244 (const_int 32))))
7245 (clobber (match_scratch:SI 3 ""))
7246 (clobber (reg:CC FLAGS_REG))])]
7247 ""
7248 "")
7249
7250 (define_insn "*umulsi3_highpart_insn"
7251 [(set (match_operand:SI 0 "register_operand" "=d")
7252 (truncate:SI
7253 (lshiftrt:DI
7254 (mult:DI (zero_extend:DI
7255 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7256 (zero_extend:DI
7257 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7258 (const_int 32))))
7259 (clobber (match_scratch:SI 3 "=1"))
7260 (clobber (reg:CC FLAGS_REG))]
7261 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7262 "mul{l}\t%2"
7263 [(set_attr "type" "imul")
7264 (set_attr "length_immediate" "0")
7265 (set (attr "athlon_decode")
7266 (if_then_else (eq_attr "cpu" "athlon")
7267 (const_string "vector")
7268 (const_string "double")))
7269 (set_attr "mode" "SI")])
7270
7271 (define_insn "*umulsi3_highpart_zext"
7272 [(set (match_operand:DI 0 "register_operand" "=d")
7273 (zero_extend:DI (truncate:SI
7274 (lshiftrt:DI
7275 (mult:DI (zero_extend:DI
7276 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7277 (zero_extend:DI
7278 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7279 (const_int 32)))))
7280 (clobber (match_scratch:SI 3 "=1"))
7281 (clobber (reg:CC FLAGS_REG))]
7282 "TARGET_64BIT
7283 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7284 "mul{l}\t%2"
7285 [(set_attr "type" "imul")
7286 (set_attr "length_immediate" "0")
7287 (set (attr "athlon_decode")
7288 (if_then_else (eq_attr "cpu" "athlon")
7289 (const_string "vector")
7290 (const_string "double")))
7291 (set_attr "mode" "SI")])
7292
7293 (define_expand "smuldi3_highpart"
7294 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7295 (truncate:DI
7296 (lshiftrt:TI
7297 (mult:TI (sign_extend:TI
7298 (match_operand:DI 1 "nonimmediate_operand" ""))
7299 (sign_extend:TI
7300 (match_operand:DI 2 "register_operand" "")))
7301 (const_int 64))))
7302 (clobber (match_scratch:DI 3 ""))
7303 (clobber (reg:CC FLAGS_REG))])]
7304 "TARGET_64BIT"
7305 "")
7306
7307 (define_insn "*smuldi3_highpart_rex64"
7308 [(set (match_operand:DI 0 "register_operand" "=d")
7309 (truncate:DI
7310 (lshiftrt:TI
7311 (mult:TI (sign_extend:TI
7312 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7313 (sign_extend:TI
7314 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7315 (const_int 64))))
7316 (clobber (match_scratch:DI 3 "=1"))
7317 (clobber (reg:CC FLAGS_REG))]
7318 "TARGET_64BIT
7319 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7320 "imul{q}\t%2"
7321 [(set_attr "type" "imul")
7322 (set (attr "athlon_decode")
7323 (if_then_else (eq_attr "cpu" "athlon")
7324 (const_string "vector")
7325 (const_string "double")))
7326 (set_attr "mode" "DI")])
7327
7328 (define_expand "smulsi3_highpart"
7329 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7330 (truncate:SI
7331 (lshiftrt:DI
7332 (mult:DI (sign_extend:DI
7333 (match_operand:SI 1 "nonimmediate_operand" ""))
7334 (sign_extend:DI
7335 (match_operand:SI 2 "register_operand" "")))
7336 (const_int 32))))
7337 (clobber (match_scratch:SI 3 ""))
7338 (clobber (reg:CC FLAGS_REG))])]
7339 ""
7340 "")
7341
7342 (define_insn "*smulsi3_highpart_insn"
7343 [(set (match_operand:SI 0 "register_operand" "=d")
7344 (truncate:SI
7345 (lshiftrt:DI
7346 (mult:DI (sign_extend:DI
7347 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7348 (sign_extend:DI
7349 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7350 (const_int 32))))
7351 (clobber (match_scratch:SI 3 "=1"))
7352 (clobber (reg:CC FLAGS_REG))]
7353 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7354 "imul{l}\t%2"
7355 [(set_attr "type" "imul")
7356 (set (attr "athlon_decode")
7357 (if_then_else (eq_attr "cpu" "athlon")
7358 (const_string "vector")
7359 (const_string "double")))
7360 (set_attr "mode" "SI")])
7361
7362 (define_insn "*smulsi3_highpart_zext"
7363 [(set (match_operand:DI 0 "register_operand" "=d")
7364 (zero_extend:DI (truncate:SI
7365 (lshiftrt:DI
7366 (mult:DI (sign_extend:DI
7367 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7368 (sign_extend:DI
7369 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7370 (const_int 32)))))
7371 (clobber (match_scratch:SI 3 "=1"))
7372 (clobber (reg:CC FLAGS_REG))]
7373 "TARGET_64BIT
7374 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7375 "imul{l}\t%2"
7376 [(set_attr "type" "imul")
7377 (set (attr "athlon_decode")
7378 (if_then_else (eq_attr "cpu" "athlon")
7379 (const_string "vector")
7380 (const_string "double")))
7381 (set_attr "mode" "SI")])
7382
7383 ;; The patterns that match these are at the end of this file.
7384
7385 (define_expand "mulxf3"
7386 [(set (match_operand:XF 0 "register_operand" "")
7387 (mult:XF (match_operand:XF 1 "register_operand" "")
7388 (match_operand:XF 2 "register_operand" "")))]
7389 "TARGET_80387"
7390 "")
7391
7392 (define_expand "muldf3"
7393 [(set (match_operand:DF 0 "register_operand" "")
7394 (mult:DF (match_operand:DF 1 "register_operand" "")
7395 (match_operand:DF 2 "nonimmediate_operand" "")))]
7396 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7397 "")
7398
7399 (define_expand "mulsf3"
7400 [(set (match_operand:SF 0 "register_operand" "")
7401 (mult:SF (match_operand:SF 1 "register_operand" "")
7402 (match_operand:SF 2 "nonimmediate_operand" "")))]
7403 "TARGET_80387 || TARGET_SSE_MATH"
7404 "")
7405 \f
7406 ;; Divide instructions
7407
7408 (define_insn "divqi3"
7409 [(set (match_operand:QI 0 "register_operand" "=a")
7410 (div:QI (match_operand:HI 1 "register_operand" "0")
7411 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7412 (clobber (reg:CC FLAGS_REG))]
7413 "TARGET_QIMODE_MATH"
7414 "idiv{b}\t%2"
7415 [(set_attr "type" "idiv")
7416 (set_attr "mode" "QI")])
7417
7418 (define_insn "udivqi3"
7419 [(set (match_operand:QI 0 "register_operand" "=a")
7420 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7421 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7422 (clobber (reg:CC FLAGS_REG))]
7423 "TARGET_QIMODE_MATH"
7424 "div{b}\t%2"
7425 [(set_attr "type" "idiv")
7426 (set_attr "mode" "QI")])
7427
7428 ;; The patterns that match these are at the end of this file.
7429
7430 (define_expand "divxf3"
7431 [(set (match_operand:XF 0 "register_operand" "")
7432 (div:XF (match_operand:XF 1 "register_operand" "")
7433 (match_operand:XF 2 "register_operand" "")))]
7434 "TARGET_80387"
7435 "")
7436
7437 (define_expand "divdf3"
7438 [(set (match_operand:DF 0 "register_operand" "")
7439 (div:DF (match_operand:DF 1 "register_operand" "")
7440 (match_operand:DF 2 "nonimmediate_operand" "")))]
7441 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7442 "")
7443
7444 (define_expand "divsf3"
7445 [(set (match_operand:SF 0 "register_operand" "")
7446 (div:SF (match_operand:SF 1 "register_operand" "")
7447 (match_operand:SF 2 "nonimmediate_operand" "")))]
7448 "TARGET_80387 || TARGET_SSE_MATH"
7449 "")
7450 \f
7451 ;; Remainder instructions.
7452
7453 (define_expand "divmoddi4"
7454 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7455 (div:DI (match_operand:DI 1 "register_operand" "")
7456 (match_operand:DI 2 "nonimmediate_operand" "")))
7457 (set (match_operand:DI 3 "register_operand" "")
7458 (mod:DI (match_dup 1) (match_dup 2)))
7459 (clobber (reg:CC FLAGS_REG))])]
7460 "TARGET_64BIT"
7461 "")
7462
7463 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7464 ;; Penalize eax case slightly because it results in worse scheduling
7465 ;; of code.
7466 (define_insn "*divmoddi4_nocltd_rex64"
7467 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7468 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7469 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7470 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7471 (mod:DI (match_dup 2) (match_dup 3)))
7472 (clobber (reg:CC FLAGS_REG))]
7473 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7474 "#"
7475 [(set_attr "type" "multi")])
7476
7477 (define_insn "*divmoddi4_cltd_rex64"
7478 [(set (match_operand:DI 0 "register_operand" "=a")
7479 (div:DI (match_operand:DI 2 "register_operand" "a")
7480 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7481 (set (match_operand:DI 1 "register_operand" "=&d")
7482 (mod:DI (match_dup 2) (match_dup 3)))
7483 (clobber (reg:CC FLAGS_REG))]
7484 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7485 "#"
7486 [(set_attr "type" "multi")])
7487
7488 (define_insn "*divmoddi_noext_rex64"
7489 [(set (match_operand:DI 0 "register_operand" "=a")
7490 (div:DI (match_operand:DI 1 "register_operand" "0")
7491 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7492 (set (match_operand:DI 3 "register_operand" "=d")
7493 (mod:DI (match_dup 1) (match_dup 2)))
7494 (use (match_operand:DI 4 "register_operand" "3"))
7495 (clobber (reg:CC FLAGS_REG))]
7496 "TARGET_64BIT"
7497 "idiv{q}\t%2"
7498 [(set_attr "type" "idiv")
7499 (set_attr "mode" "DI")])
7500
7501 (define_split
7502 [(set (match_operand:DI 0 "register_operand" "")
7503 (div:DI (match_operand:DI 1 "register_operand" "")
7504 (match_operand:DI 2 "nonimmediate_operand" "")))
7505 (set (match_operand:DI 3 "register_operand" "")
7506 (mod:DI (match_dup 1) (match_dup 2)))
7507 (clobber (reg:CC FLAGS_REG))]
7508 "TARGET_64BIT && reload_completed"
7509 [(parallel [(set (match_dup 3)
7510 (ashiftrt:DI (match_dup 4) (const_int 63)))
7511 (clobber (reg:CC FLAGS_REG))])
7512 (parallel [(set (match_dup 0)
7513 (div:DI (reg:DI 0) (match_dup 2)))
7514 (set (match_dup 3)
7515 (mod:DI (reg:DI 0) (match_dup 2)))
7516 (use (match_dup 3))
7517 (clobber (reg:CC FLAGS_REG))])]
7518 {
7519 /* Avoid use of cltd in favor of a mov+shift. */
7520 if (!TARGET_USE_CLTD && !optimize_size)
7521 {
7522 if (true_regnum (operands[1]))
7523 emit_move_insn (operands[0], operands[1]);
7524 else
7525 emit_move_insn (operands[3], operands[1]);
7526 operands[4] = operands[3];
7527 }
7528 else
7529 {
7530 gcc_assert (!true_regnum (operands[1]));
7531 operands[4] = operands[1];
7532 }
7533 })
7534
7535
7536 (define_expand "divmodsi4"
7537 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7538 (div:SI (match_operand:SI 1 "register_operand" "")
7539 (match_operand:SI 2 "nonimmediate_operand" "")))
7540 (set (match_operand:SI 3 "register_operand" "")
7541 (mod:SI (match_dup 1) (match_dup 2)))
7542 (clobber (reg:CC FLAGS_REG))])]
7543 ""
7544 "")
7545
7546 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7547 ;; Penalize eax case slightly because it results in worse scheduling
7548 ;; of code.
7549 (define_insn "*divmodsi4_nocltd"
7550 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7551 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7552 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7553 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7554 (mod:SI (match_dup 2) (match_dup 3)))
7555 (clobber (reg:CC FLAGS_REG))]
7556 "!optimize_size && !TARGET_USE_CLTD"
7557 "#"
7558 [(set_attr "type" "multi")])
7559
7560 (define_insn "*divmodsi4_cltd"
7561 [(set (match_operand:SI 0 "register_operand" "=a")
7562 (div:SI (match_operand:SI 2 "register_operand" "a")
7563 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7564 (set (match_operand:SI 1 "register_operand" "=&d")
7565 (mod:SI (match_dup 2) (match_dup 3)))
7566 (clobber (reg:CC FLAGS_REG))]
7567 "optimize_size || TARGET_USE_CLTD"
7568 "#"
7569 [(set_attr "type" "multi")])
7570
7571 (define_insn "*divmodsi_noext"
7572 [(set (match_operand:SI 0 "register_operand" "=a")
7573 (div:SI (match_operand:SI 1 "register_operand" "0")
7574 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7575 (set (match_operand:SI 3 "register_operand" "=d")
7576 (mod:SI (match_dup 1) (match_dup 2)))
7577 (use (match_operand:SI 4 "register_operand" "3"))
7578 (clobber (reg:CC FLAGS_REG))]
7579 ""
7580 "idiv{l}\t%2"
7581 [(set_attr "type" "idiv")
7582 (set_attr "mode" "SI")])
7583
7584 (define_split
7585 [(set (match_operand:SI 0 "register_operand" "")
7586 (div:SI (match_operand:SI 1 "register_operand" "")
7587 (match_operand:SI 2 "nonimmediate_operand" "")))
7588 (set (match_operand:SI 3 "register_operand" "")
7589 (mod:SI (match_dup 1) (match_dup 2)))
7590 (clobber (reg:CC FLAGS_REG))]
7591 "reload_completed"
7592 [(parallel [(set (match_dup 3)
7593 (ashiftrt:SI (match_dup 4) (const_int 31)))
7594 (clobber (reg:CC FLAGS_REG))])
7595 (parallel [(set (match_dup 0)
7596 (div:SI (reg:SI 0) (match_dup 2)))
7597 (set (match_dup 3)
7598 (mod:SI (reg:SI 0) (match_dup 2)))
7599 (use (match_dup 3))
7600 (clobber (reg:CC FLAGS_REG))])]
7601 {
7602 /* Avoid use of cltd in favor of a mov+shift. */
7603 if (!TARGET_USE_CLTD && !optimize_size)
7604 {
7605 if (true_regnum (operands[1]))
7606 emit_move_insn (operands[0], operands[1]);
7607 else
7608 emit_move_insn (operands[3], operands[1]);
7609 operands[4] = operands[3];
7610 }
7611 else
7612 {
7613 gcc_assert (!true_regnum (operands[1]));
7614 operands[4] = operands[1];
7615 }
7616 })
7617 ;; %%% Split me.
7618 (define_insn "divmodhi4"
7619 [(set (match_operand:HI 0 "register_operand" "=a")
7620 (div:HI (match_operand:HI 1 "register_operand" "0")
7621 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7622 (set (match_operand:HI 3 "register_operand" "=&d")
7623 (mod:HI (match_dup 1) (match_dup 2)))
7624 (clobber (reg:CC FLAGS_REG))]
7625 "TARGET_HIMODE_MATH"
7626 "cwtd\;idiv{w}\t%2"
7627 [(set_attr "type" "multi")
7628 (set_attr "length_immediate" "0")
7629 (set_attr "mode" "SI")])
7630
7631 (define_insn "udivmoddi4"
7632 [(set (match_operand:DI 0 "register_operand" "=a")
7633 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7634 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7635 (set (match_operand:DI 3 "register_operand" "=&d")
7636 (umod:DI (match_dup 1) (match_dup 2)))
7637 (clobber (reg:CC FLAGS_REG))]
7638 "TARGET_64BIT"
7639 "xor{q}\t%3, %3\;div{q}\t%2"
7640 [(set_attr "type" "multi")
7641 (set_attr "length_immediate" "0")
7642 (set_attr "mode" "DI")])
7643
7644 (define_insn "*udivmoddi4_noext"
7645 [(set (match_operand:DI 0 "register_operand" "=a")
7646 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7647 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7648 (set (match_operand:DI 3 "register_operand" "=d")
7649 (umod:DI (match_dup 1) (match_dup 2)))
7650 (use (match_dup 3))
7651 (clobber (reg:CC FLAGS_REG))]
7652 "TARGET_64BIT"
7653 "div{q}\t%2"
7654 [(set_attr "type" "idiv")
7655 (set_attr "mode" "DI")])
7656
7657 (define_split
7658 [(set (match_operand:DI 0 "register_operand" "")
7659 (udiv:DI (match_operand:DI 1 "register_operand" "")
7660 (match_operand:DI 2 "nonimmediate_operand" "")))
7661 (set (match_operand:DI 3 "register_operand" "")
7662 (umod:DI (match_dup 1) (match_dup 2)))
7663 (clobber (reg:CC FLAGS_REG))]
7664 "TARGET_64BIT && reload_completed"
7665 [(set (match_dup 3) (const_int 0))
7666 (parallel [(set (match_dup 0)
7667 (udiv:DI (match_dup 1) (match_dup 2)))
7668 (set (match_dup 3)
7669 (umod:DI (match_dup 1) (match_dup 2)))
7670 (use (match_dup 3))
7671 (clobber (reg:CC FLAGS_REG))])]
7672 "")
7673
7674 (define_insn "udivmodsi4"
7675 [(set (match_operand:SI 0 "register_operand" "=a")
7676 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7677 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7678 (set (match_operand:SI 3 "register_operand" "=&d")
7679 (umod:SI (match_dup 1) (match_dup 2)))
7680 (clobber (reg:CC FLAGS_REG))]
7681 ""
7682 "xor{l}\t%3, %3\;div{l}\t%2"
7683 [(set_attr "type" "multi")
7684 (set_attr "length_immediate" "0")
7685 (set_attr "mode" "SI")])
7686
7687 (define_insn "*udivmodsi4_noext"
7688 [(set (match_operand:SI 0 "register_operand" "=a")
7689 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7690 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7691 (set (match_operand:SI 3 "register_operand" "=d")
7692 (umod:SI (match_dup 1) (match_dup 2)))
7693 (use (match_dup 3))
7694 (clobber (reg:CC FLAGS_REG))]
7695 ""
7696 "div{l}\t%2"
7697 [(set_attr "type" "idiv")
7698 (set_attr "mode" "SI")])
7699
7700 (define_split
7701 [(set (match_operand:SI 0 "register_operand" "")
7702 (udiv:SI (match_operand:SI 1 "register_operand" "")
7703 (match_operand:SI 2 "nonimmediate_operand" "")))
7704 (set (match_operand:SI 3 "register_operand" "")
7705 (umod:SI (match_dup 1) (match_dup 2)))
7706 (clobber (reg:CC FLAGS_REG))]
7707 "reload_completed"
7708 [(set (match_dup 3) (const_int 0))
7709 (parallel [(set (match_dup 0)
7710 (udiv:SI (match_dup 1) (match_dup 2)))
7711 (set (match_dup 3)
7712 (umod:SI (match_dup 1) (match_dup 2)))
7713 (use (match_dup 3))
7714 (clobber (reg:CC FLAGS_REG))])]
7715 "")
7716
7717 (define_expand "udivmodhi4"
7718 [(set (match_dup 4) (const_int 0))
7719 (parallel [(set (match_operand:HI 0 "register_operand" "")
7720 (udiv:HI (match_operand:HI 1 "register_operand" "")
7721 (match_operand:HI 2 "nonimmediate_operand" "")))
7722 (set (match_operand:HI 3 "register_operand" "")
7723 (umod:HI (match_dup 1) (match_dup 2)))
7724 (use (match_dup 4))
7725 (clobber (reg:CC FLAGS_REG))])]
7726 "TARGET_HIMODE_MATH"
7727 "operands[4] = gen_reg_rtx (HImode);")
7728
7729 (define_insn "*udivmodhi_noext"
7730 [(set (match_operand:HI 0 "register_operand" "=a")
7731 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7732 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7733 (set (match_operand:HI 3 "register_operand" "=d")
7734 (umod:HI (match_dup 1) (match_dup 2)))
7735 (use (match_operand:HI 4 "register_operand" "3"))
7736 (clobber (reg:CC FLAGS_REG))]
7737 ""
7738 "div{w}\t%2"
7739 [(set_attr "type" "idiv")
7740 (set_attr "mode" "HI")])
7741
7742 ;; We cannot use div/idiv for double division, because it causes
7743 ;; "division by zero" on the overflow and that's not what we expect
7744 ;; from truncate. Because true (non truncating) double division is
7745 ;; never generated, we can't create this insn anyway.
7746 ;
7747 ;(define_insn ""
7748 ; [(set (match_operand:SI 0 "register_operand" "=a")
7749 ; (truncate:SI
7750 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7751 ; (zero_extend:DI
7752 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7753 ; (set (match_operand:SI 3 "register_operand" "=d")
7754 ; (truncate:SI
7755 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7756 ; (clobber (reg:CC FLAGS_REG))]
7757 ; ""
7758 ; "div{l}\t{%2, %0|%0, %2}"
7759 ; [(set_attr "type" "idiv")])
7760 \f
7761 ;;- Logical AND instructions
7762
7763 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7764 ;; Note that this excludes ah.
7765
7766 (define_insn "*testdi_1_rex64"
7767 [(set (reg FLAGS_REG)
7768 (compare
7769 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7770 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7771 (const_int 0)))]
7772 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7773 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7774 "@
7775 test{l}\t{%k1, %k0|%k0, %k1}
7776 test{l}\t{%k1, %k0|%k0, %k1}
7777 test{q}\t{%1, %0|%0, %1}
7778 test{q}\t{%1, %0|%0, %1}
7779 test{q}\t{%1, %0|%0, %1}"
7780 [(set_attr "type" "test")
7781 (set_attr "modrm" "0,1,0,1,1")
7782 (set_attr "mode" "SI,SI,DI,DI,DI")
7783 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7784
7785 (define_insn "testsi_1"
7786 [(set (reg FLAGS_REG)
7787 (compare
7788 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7789 (match_operand:SI 1 "general_operand" "in,in,rin"))
7790 (const_int 0)))]
7791 "ix86_match_ccmode (insn, CCNOmode)
7792 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7793 "test{l}\t{%1, %0|%0, %1}"
7794 [(set_attr "type" "test")
7795 (set_attr "modrm" "0,1,1")
7796 (set_attr "mode" "SI")
7797 (set_attr "pent_pair" "uv,np,uv")])
7798
7799 (define_expand "testsi_ccno_1"
7800 [(set (reg:CCNO FLAGS_REG)
7801 (compare:CCNO
7802 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7803 (match_operand:SI 1 "nonmemory_operand" ""))
7804 (const_int 0)))]
7805 ""
7806 "")
7807
7808 (define_insn "*testhi_1"
7809 [(set (reg FLAGS_REG)
7810 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7811 (match_operand:HI 1 "general_operand" "n,n,rn"))
7812 (const_int 0)))]
7813 "ix86_match_ccmode (insn, CCNOmode)
7814 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7815 "test{w}\t{%1, %0|%0, %1}"
7816 [(set_attr "type" "test")
7817 (set_attr "modrm" "0,1,1")
7818 (set_attr "mode" "HI")
7819 (set_attr "pent_pair" "uv,np,uv")])
7820
7821 (define_expand "testqi_ccz_1"
7822 [(set (reg:CCZ FLAGS_REG)
7823 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7824 (match_operand:QI 1 "nonmemory_operand" ""))
7825 (const_int 0)))]
7826 ""
7827 "")
7828
7829 (define_insn "*testqi_1_maybe_si"
7830 [(set (reg FLAGS_REG)
7831 (compare
7832 (and:QI
7833 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7834 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7835 (const_int 0)))]
7836 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7837 && ix86_match_ccmode (insn,
7838 CONST_INT_P (operands[1])
7839 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7840 {
7841 if (which_alternative == 3)
7842 {
7843 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7844 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7845 return "test{l}\t{%1, %k0|%k0, %1}";
7846 }
7847 return "test{b}\t{%1, %0|%0, %1}";
7848 }
7849 [(set_attr "type" "test")
7850 (set_attr "modrm" "0,1,1,1")
7851 (set_attr "mode" "QI,QI,QI,SI")
7852 (set_attr "pent_pair" "uv,np,uv,np")])
7853
7854 (define_insn "*testqi_1"
7855 [(set (reg FLAGS_REG)
7856 (compare
7857 (and:QI
7858 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7859 (match_operand:QI 1 "general_operand" "n,n,qn"))
7860 (const_int 0)))]
7861 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7862 && ix86_match_ccmode (insn, CCNOmode)"
7863 "test{b}\t{%1, %0|%0, %1}"
7864 [(set_attr "type" "test")
7865 (set_attr "modrm" "0,1,1")
7866 (set_attr "mode" "QI")
7867 (set_attr "pent_pair" "uv,np,uv")])
7868
7869 (define_expand "testqi_ext_ccno_0"
7870 [(set (reg:CCNO FLAGS_REG)
7871 (compare:CCNO
7872 (and:SI
7873 (zero_extract:SI
7874 (match_operand 0 "ext_register_operand" "")
7875 (const_int 8)
7876 (const_int 8))
7877 (match_operand 1 "const_int_operand" ""))
7878 (const_int 0)))]
7879 ""
7880 "")
7881
7882 (define_insn "*testqi_ext_0"
7883 [(set (reg FLAGS_REG)
7884 (compare
7885 (and:SI
7886 (zero_extract:SI
7887 (match_operand 0 "ext_register_operand" "Q")
7888 (const_int 8)
7889 (const_int 8))
7890 (match_operand 1 "const_int_operand" "n"))
7891 (const_int 0)))]
7892 "ix86_match_ccmode (insn, CCNOmode)"
7893 "test{b}\t{%1, %h0|%h0, %1}"
7894 [(set_attr "type" "test")
7895 (set_attr "mode" "QI")
7896 (set_attr "length_immediate" "1")
7897 (set_attr "pent_pair" "np")])
7898
7899 (define_insn "*testqi_ext_1"
7900 [(set (reg FLAGS_REG)
7901 (compare
7902 (and:SI
7903 (zero_extract:SI
7904 (match_operand 0 "ext_register_operand" "Q")
7905 (const_int 8)
7906 (const_int 8))
7907 (zero_extend:SI
7908 (match_operand:QI 1 "general_operand" "Qm")))
7909 (const_int 0)))]
7910 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7911 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7912 "test{b}\t{%1, %h0|%h0, %1}"
7913 [(set_attr "type" "test")
7914 (set_attr "mode" "QI")])
7915
7916 (define_insn "*testqi_ext_1_rex64"
7917 [(set (reg FLAGS_REG)
7918 (compare
7919 (and:SI
7920 (zero_extract:SI
7921 (match_operand 0 "ext_register_operand" "Q")
7922 (const_int 8)
7923 (const_int 8))
7924 (zero_extend:SI
7925 (match_operand:QI 1 "register_operand" "Q")))
7926 (const_int 0)))]
7927 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7928 "test{b}\t{%1, %h0|%h0, %1}"
7929 [(set_attr "type" "test")
7930 (set_attr "mode" "QI")])
7931
7932 (define_insn "*testqi_ext_2"
7933 [(set (reg FLAGS_REG)
7934 (compare
7935 (and:SI
7936 (zero_extract:SI
7937 (match_operand 0 "ext_register_operand" "Q")
7938 (const_int 8)
7939 (const_int 8))
7940 (zero_extract:SI
7941 (match_operand 1 "ext_register_operand" "Q")
7942 (const_int 8)
7943 (const_int 8)))
7944 (const_int 0)))]
7945 "ix86_match_ccmode (insn, CCNOmode)"
7946 "test{b}\t{%h1, %h0|%h0, %h1}"
7947 [(set_attr "type" "test")
7948 (set_attr "mode" "QI")])
7949
7950 ;; Combine likes to form bit extractions for some tests. Humor it.
7951 (define_insn "*testqi_ext_3"
7952 [(set (reg FLAGS_REG)
7953 (compare (zero_extract:SI
7954 (match_operand 0 "nonimmediate_operand" "rm")
7955 (match_operand:SI 1 "const_int_operand" "")
7956 (match_operand:SI 2 "const_int_operand" ""))
7957 (const_int 0)))]
7958 "ix86_match_ccmode (insn, CCNOmode)
7959 && INTVAL (operands[1]) > 0
7960 && INTVAL (operands[2]) >= 0
7961 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7962 && (GET_MODE (operands[0]) == SImode
7963 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7964 || GET_MODE (operands[0]) == HImode
7965 || GET_MODE (operands[0]) == QImode)"
7966 "#")
7967
7968 (define_insn "*testqi_ext_3_rex64"
7969 [(set (reg FLAGS_REG)
7970 (compare (zero_extract:DI
7971 (match_operand 0 "nonimmediate_operand" "rm")
7972 (match_operand:DI 1 "const_int_operand" "")
7973 (match_operand:DI 2 "const_int_operand" ""))
7974 (const_int 0)))]
7975 "TARGET_64BIT
7976 && ix86_match_ccmode (insn, CCNOmode)
7977 && INTVAL (operands[1]) > 0
7978 && INTVAL (operands[2]) >= 0
7979 /* Ensure that resulting mask is zero or sign extended operand. */
7980 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7981 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7982 && INTVAL (operands[1]) > 32))
7983 && (GET_MODE (operands[0]) == SImode
7984 || GET_MODE (operands[0]) == DImode
7985 || GET_MODE (operands[0]) == HImode
7986 || GET_MODE (operands[0]) == QImode)"
7987 "#")
7988
7989 (define_split
7990 [(set (match_operand 0 "flags_reg_operand" "")
7991 (match_operator 1 "compare_operator"
7992 [(zero_extract
7993 (match_operand 2 "nonimmediate_operand" "")
7994 (match_operand 3 "const_int_operand" "")
7995 (match_operand 4 "const_int_operand" ""))
7996 (const_int 0)]))]
7997 "ix86_match_ccmode (insn, CCNOmode)"
7998 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7999 {
8000 rtx val = operands[2];
8001 HOST_WIDE_INT len = INTVAL (operands[3]);
8002 HOST_WIDE_INT pos = INTVAL (operands[4]);
8003 HOST_WIDE_INT mask;
8004 enum machine_mode mode, submode;
8005
8006 mode = GET_MODE (val);
8007 if (MEM_P (val))
8008 {
8009 /* ??? Combine likes to put non-volatile mem extractions in QImode
8010 no matter the size of the test. So find a mode that works. */
8011 if (! MEM_VOLATILE_P (val))
8012 {
8013 mode = smallest_mode_for_size (pos + len, MODE_INT);
8014 val = adjust_address (val, mode, 0);
8015 }
8016 }
8017 else if (GET_CODE (val) == SUBREG
8018 && (submode = GET_MODE (SUBREG_REG (val)),
8019 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8020 && pos + len <= GET_MODE_BITSIZE (submode))
8021 {
8022 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8023 mode = submode;
8024 val = SUBREG_REG (val);
8025 }
8026 else if (mode == HImode && pos + len <= 8)
8027 {
8028 /* Small HImode tests can be converted to QImode. */
8029 mode = QImode;
8030 val = gen_lowpart (QImode, val);
8031 }
8032
8033 if (len == HOST_BITS_PER_WIDE_INT)
8034 mask = -1;
8035 else
8036 mask = ((HOST_WIDE_INT)1 << len) - 1;
8037 mask <<= pos;
8038
8039 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8040 })
8041
8042 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8043 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8044 ;; this is relatively important trick.
8045 ;; Do the conversion only post-reload to avoid limiting of the register class
8046 ;; to QI regs.
8047 (define_split
8048 [(set (match_operand 0 "flags_reg_operand" "")
8049 (match_operator 1 "compare_operator"
8050 [(and (match_operand 2 "register_operand" "")
8051 (match_operand 3 "const_int_operand" ""))
8052 (const_int 0)]))]
8053 "reload_completed
8054 && QI_REG_P (operands[2])
8055 && GET_MODE (operands[2]) != QImode
8056 && ((ix86_match_ccmode (insn, CCZmode)
8057 && !(INTVAL (operands[3]) & ~(255 << 8)))
8058 || (ix86_match_ccmode (insn, CCNOmode)
8059 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8060 [(set (match_dup 0)
8061 (match_op_dup 1
8062 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8063 (match_dup 3))
8064 (const_int 0)]))]
8065 "operands[2] = gen_lowpart (SImode, operands[2]);
8066 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8067
8068 (define_split
8069 [(set (match_operand 0 "flags_reg_operand" "")
8070 (match_operator 1 "compare_operator"
8071 [(and (match_operand 2 "nonimmediate_operand" "")
8072 (match_operand 3 "const_int_operand" ""))
8073 (const_int 0)]))]
8074 "reload_completed
8075 && GET_MODE (operands[2]) != QImode
8076 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8077 && ((ix86_match_ccmode (insn, CCZmode)
8078 && !(INTVAL (operands[3]) & ~255))
8079 || (ix86_match_ccmode (insn, CCNOmode)
8080 && !(INTVAL (operands[3]) & ~127)))"
8081 [(set (match_dup 0)
8082 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8083 (const_int 0)]))]
8084 "operands[2] = gen_lowpart (QImode, operands[2]);
8085 operands[3] = gen_lowpart (QImode, operands[3]);")
8086
8087
8088 ;; %%% This used to optimize known byte-wide and operations to memory,
8089 ;; and sometimes to QImode registers. If this is considered useful,
8090 ;; it should be done with splitters.
8091
8092 (define_expand "anddi3"
8093 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8094 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8095 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8096 (clobber (reg:CC FLAGS_REG))]
8097 "TARGET_64BIT"
8098 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8099
8100 (define_insn "*anddi_1_rex64"
8101 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8102 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8103 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8104 (clobber (reg:CC FLAGS_REG))]
8105 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8106 {
8107 switch (get_attr_type (insn))
8108 {
8109 case TYPE_IMOVX:
8110 {
8111 enum machine_mode mode;
8112
8113 gcc_assert (CONST_INT_P (operands[2]));
8114 if (INTVAL (operands[2]) == 0xff)
8115 mode = QImode;
8116 else
8117 {
8118 gcc_assert (INTVAL (operands[2]) == 0xffff);
8119 mode = HImode;
8120 }
8121
8122 operands[1] = gen_lowpart (mode, operands[1]);
8123 if (mode == QImode)
8124 return "movz{bq|x}\t{%1,%0|%0, %1}";
8125 else
8126 return "movz{wq|x}\t{%1,%0|%0, %1}";
8127 }
8128
8129 default:
8130 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8131 if (get_attr_mode (insn) == MODE_SI)
8132 return "and{l}\t{%k2, %k0|%k0, %k2}";
8133 else
8134 return "and{q}\t{%2, %0|%0, %2}";
8135 }
8136 }
8137 [(set_attr "type" "alu,alu,alu,imovx")
8138 (set_attr "length_immediate" "*,*,*,0")
8139 (set_attr "mode" "SI,DI,DI,DI")])
8140
8141 (define_insn "*anddi_2"
8142 [(set (reg FLAGS_REG)
8143 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8144 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8145 (const_int 0)))
8146 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8147 (and:DI (match_dup 1) (match_dup 2)))]
8148 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8149 && ix86_binary_operator_ok (AND, DImode, operands)"
8150 "@
8151 and{l}\t{%k2, %k0|%k0, %k2}
8152 and{q}\t{%2, %0|%0, %2}
8153 and{q}\t{%2, %0|%0, %2}"
8154 [(set_attr "type" "alu")
8155 (set_attr "mode" "SI,DI,DI")])
8156
8157 (define_expand "andsi3"
8158 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8159 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8160 (match_operand:SI 2 "general_operand" "")))
8161 (clobber (reg:CC FLAGS_REG))]
8162 ""
8163 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8164
8165 (define_insn "*andsi_1"
8166 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8167 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8168 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8169 (clobber (reg:CC FLAGS_REG))]
8170 "ix86_binary_operator_ok (AND, SImode, operands)"
8171 {
8172 switch (get_attr_type (insn))
8173 {
8174 case TYPE_IMOVX:
8175 {
8176 enum machine_mode mode;
8177
8178 gcc_assert (CONST_INT_P (operands[2]));
8179 if (INTVAL (operands[2]) == 0xff)
8180 mode = QImode;
8181 else
8182 {
8183 gcc_assert (INTVAL (operands[2]) == 0xffff);
8184 mode = HImode;
8185 }
8186
8187 operands[1] = gen_lowpart (mode, operands[1]);
8188 if (mode == QImode)
8189 return "movz{bl|x}\t{%1,%0|%0, %1}";
8190 else
8191 return "movz{wl|x}\t{%1,%0|%0, %1}";
8192 }
8193
8194 default:
8195 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8196 return "and{l}\t{%2, %0|%0, %2}";
8197 }
8198 }
8199 [(set_attr "type" "alu,alu,imovx")
8200 (set_attr "length_immediate" "*,*,0")
8201 (set_attr "mode" "SI")])
8202
8203 (define_split
8204 [(set (match_operand 0 "register_operand" "")
8205 (and (match_dup 0)
8206 (const_int -65536)))
8207 (clobber (reg:CC FLAGS_REG))]
8208 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8209 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8210 "operands[1] = gen_lowpart (HImode, operands[0]);")
8211
8212 (define_split
8213 [(set (match_operand 0 "ext_register_operand" "")
8214 (and (match_dup 0)
8215 (const_int -256)))
8216 (clobber (reg:CC FLAGS_REG))]
8217 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8218 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8219 "operands[1] = gen_lowpart (QImode, operands[0]);")
8220
8221 (define_split
8222 [(set (match_operand 0 "ext_register_operand" "")
8223 (and (match_dup 0)
8224 (const_int -65281)))
8225 (clobber (reg:CC FLAGS_REG))]
8226 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8227 [(parallel [(set (zero_extract:SI (match_dup 0)
8228 (const_int 8)
8229 (const_int 8))
8230 (xor:SI
8231 (zero_extract:SI (match_dup 0)
8232 (const_int 8)
8233 (const_int 8))
8234 (zero_extract:SI (match_dup 0)
8235 (const_int 8)
8236 (const_int 8))))
8237 (clobber (reg:CC FLAGS_REG))])]
8238 "operands[0] = gen_lowpart (SImode, operands[0]);")
8239
8240 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8241 (define_insn "*andsi_1_zext"
8242 [(set (match_operand:DI 0 "register_operand" "=r")
8243 (zero_extend:DI
8244 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8245 (match_operand:SI 2 "general_operand" "rim"))))
8246 (clobber (reg:CC FLAGS_REG))]
8247 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8248 "and{l}\t{%2, %k0|%k0, %2}"
8249 [(set_attr "type" "alu")
8250 (set_attr "mode" "SI")])
8251
8252 (define_insn "*andsi_2"
8253 [(set (reg FLAGS_REG)
8254 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8255 (match_operand:SI 2 "general_operand" "rim,ri"))
8256 (const_int 0)))
8257 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8258 (and:SI (match_dup 1) (match_dup 2)))]
8259 "ix86_match_ccmode (insn, CCNOmode)
8260 && ix86_binary_operator_ok (AND, SImode, operands)"
8261 "and{l}\t{%2, %0|%0, %2}"
8262 [(set_attr "type" "alu")
8263 (set_attr "mode" "SI")])
8264
8265 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8266 (define_insn "*andsi_2_zext"
8267 [(set (reg FLAGS_REG)
8268 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8269 (match_operand:SI 2 "general_operand" "rim"))
8270 (const_int 0)))
8271 (set (match_operand:DI 0 "register_operand" "=r")
8272 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8273 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8274 && ix86_binary_operator_ok (AND, SImode, operands)"
8275 "and{l}\t{%2, %k0|%k0, %2}"
8276 [(set_attr "type" "alu")
8277 (set_attr "mode" "SI")])
8278
8279 (define_expand "andhi3"
8280 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8281 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8282 (match_operand:HI 2 "general_operand" "")))
8283 (clobber (reg:CC FLAGS_REG))]
8284 "TARGET_HIMODE_MATH"
8285 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8286
8287 (define_insn "*andhi_1"
8288 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8289 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8290 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8291 (clobber (reg:CC FLAGS_REG))]
8292 "ix86_binary_operator_ok (AND, HImode, operands)"
8293 {
8294 switch (get_attr_type (insn))
8295 {
8296 case TYPE_IMOVX:
8297 gcc_assert (CONST_INT_P (operands[2]));
8298 gcc_assert (INTVAL (operands[2]) == 0xff);
8299 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8300
8301 default:
8302 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8303
8304 return "and{w}\t{%2, %0|%0, %2}";
8305 }
8306 }
8307 [(set_attr "type" "alu,alu,imovx")
8308 (set_attr "length_immediate" "*,*,0")
8309 (set_attr "mode" "HI,HI,SI")])
8310
8311 (define_insn "*andhi_2"
8312 [(set (reg FLAGS_REG)
8313 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8314 (match_operand:HI 2 "general_operand" "rim,ri"))
8315 (const_int 0)))
8316 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8317 (and:HI (match_dup 1) (match_dup 2)))]
8318 "ix86_match_ccmode (insn, CCNOmode)
8319 && ix86_binary_operator_ok (AND, HImode, operands)"
8320 "and{w}\t{%2, %0|%0, %2}"
8321 [(set_attr "type" "alu")
8322 (set_attr "mode" "HI")])
8323
8324 (define_expand "andqi3"
8325 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8326 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8327 (match_operand:QI 2 "general_operand" "")))
8328 (clobber (reg:CC FLAGS_REG))]
8329 "TARGET_QIMODE_MATH"
8330 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8331
8332 ;; %%% Potential partial reg stall on alternative 2. What to do?
8333 (define_insn "*andqi_1"
8334 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8335 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8336 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8337 (clobber (reg:CC FLAGS_REG))]
8338 "ix86_binary_operator_ok (AND, QImode, operands)"
8339 "@
8340 and{b}\t{%2, %0|%0, %2}
8341 and{b}\t{%2, %0|%0, %2}
8342 and{l}\t{%k2, %k0|%k0, %k2}"
8343 [(set_attr "type" "alu")
8344 (set_attr "mode" "QI,QI,SI")])
8345
8346 (define_insn "*andqi_1_slp"
8347 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8348 (and:QI (match_dup 0)
8349 (match_operand:QI 1 "general_operand" "qi,qmi")))
8350 (clobber (reg:CC FLAGS_REG))]
8351 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8352 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8353 "and{b}\t{%1, %0|%0, %1}"
8354 [(set_attr "type" "alu1")
8355 (set_attr "mode" "QI")])
8356
8357 (define_insn "*andqi_2_maybe_si"
8358 [(set (reg FLAGS_REG)
8359 (compare (and:QI
8360 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8361 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8362 (const_int 0)))
8363 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8364 (and:QI (match_dup 1) (match_dup 2)))]
8365 "ix86_binary_operator_ok (AND, QImode, operands)
8366 && ix86_match_ccmode (insn,
8367 CONST_INT_P (operands[2])
8368 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8369 {
8370 if (which_alternative == 2)
8371 {
8372 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8373 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8374 return "and{l}\t{%2, %k0|%k0, %2}";
8375 }
8376 return "and{b}\t{%2, %0|%0, %2}";
8377 }
8378 [(set_attr "type" "alu")
8379 (set_attr "mode" "QI,QI,SI")])
8380
8381 (define_insn "*andqi_2"
8382 [(set (reg FLAGS_REG)
8383 (compare (and:QI
8384 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8385 (match_operand:QI 2 "general_operand" "qim,qi"))
8386 (const_int 0)))
8387 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8388 (and:QI (match_dup 1) (match_dup 2)))]
8389 "ix86_match_ccmode (insn, CCNOmode)
8390 && ix86_binary_operator_ok (AND, QImode, operands)"
8391 "and{b}\t{%2, %0|%0, %2}"
8392 [(set_attr "type" "alu")
8393 (set_attr "mode" "QI")])
8394
8395 (define_insn "*andqi_2_slp"
8396 [(set (reg FLAGS_REG)
8397 (compare (and:QI
8398 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8399 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8400 (const_int 0)))
8401 (set (strict_low_part (match_dup 0))
8402 (and:QI (match_dup 0) (match_dup 1)))]
8403 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8404 && ix86_match_ccmode (insn, CCNOmode)
8405 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8406 "and{b}\t{%1, %0|%0, %1}"
8407 [(set_attr "type" "alu1")
8408 (set_attr "mode" "QI")])
8409
8410 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8411 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8412 ;; for a QImode operand, which of course failed.
8413
8414 (define_insn "andqi_ext_0"
8415 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8416 (const_int 8)
8417 (const_int 8))
8418 (and:SI
8419 (zero_extract:SI
8420 (match_operand 1 "ext_register_operand" "0")
8421 (const_int 8)
8422 (const_int 8))
8423 (match_operand 2 "const_int_operand" "n")))
8424 (clobber (reg:CC FLAGS_REG))]
8425 ""
8426 "and{b}\t{%2, %h0|%h0, %2}"
8427 [(set_attr "type" "alu")
8428 (set_attr "length_immediate" "1")
8429 (set_attr "mode" "QI")])
8430
8431 ;; Generated by peephole translating test to and. This shows up
8432 ;; often in fp comparisons.
8433
8434 (define_insn "*andqi_ext_0_cc"
8435 [(set (reg FLAGS_REG)
8436 (compare
8437 (and:SI
8438 (zero_extract:SI
8439 (match_operand 1 "ext_register_operand" "0")
8440 (const_int 8)
8441 (const_int 8))
8442 (match_operand 2 "const_int_operand" "n"))
8443 (const_int 0)))
8444 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8445 (const_int 8)
8446 (const_int 8))
8447 (and:SI
8448 (zero_extract:SI
8449 (match_dup 1)
8450 (const_int 8)
8451 (const_int 8))
8452 (match_dup 2)))]
8453 "ix86_match_ccmode (insn, CCNOmode)"
8454 "and{b}\t{%2, %h0|%h0, %2}"
8455 [(set_attr "type" "alu")
8456 (set_attr "length_immediate" "1")
8457 (set_attr "mode" "QI")])
8458
8459 (define_insn "*andqi_ext_1"
8460 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8461 (const_int 8)
8462 (const_int 8))
8463 (and:SI
8464 (zero_extract:SI
8465 (match_operand 1 "ext_register_operand" "0")
8466 (const_int 8)
8467 (const_int 8))
8468 (zero_extend:SI
8469 (match_operand:QI 2 "general_operand" "Qm"))))
8470 (clobber (reg:CC FLAGS_REG))]
8471 "!TARGET_64BIT"
8472 "and{b}\t{%2, %h0|%h0, %2}"
8473 [(set_attr "type" "alu")
8474 (set_attr "length_immediate" "0")
8475 (set_attr "mode" "QI")])
8476
8477 (define_insn "*andqi_ext_1_rex64"
8478 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8479 (const_int 8)
8480 (const_int 8))
8481 (and:SI
8482 (zero_extract:SI
8483 (match_operand 1 "ext_register_operand" "0")
8484 (const_int 8)
8485 (const_int 8))
8486 (zero_extend:SI
8487 (match_operand 2 "ext_register_operand" "Q"))))
8488 (clobber (reg:CC FLAGS_REG))]
8489 "TARGET_64BIT"
8490 "and{b}\t{%2, %h0|%h0, %2}"
8491 [(set_attr "type" "alu")
8492 (set_attr "length_immediate" "0")
8493 (set_attr "mode" "QI")])
8494
8495 (define_insn "*andqi_ext_2"
8496 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8497 (const_int 8)
8498 (const_int 8))
8499 (and:SI
8500 (zero_extract:SI
8501 (match_operand 1 "ext_register_operand" "%0")
8502 (const_int 8)
8503 (const_int 8))
8504 (zero_extract:SI
8505 (match_operand 2 "ext_register_operand" "Q")
8506 (const_int 8)
8507 (const_int 8))))
8508 (clobber (reg:CC FLAGS_REG))]
8509 ""
8510 "and{b}\t{%h2, %h0|%h0, %h2}"
8511 [(set_attr "type" "alu")
8512 (set_attr "length_immediate" "0")
8513 (set_attr "mode" "QI")])
8514
8515 ;; Convert wide AND instructions with immediate operand to shorter QImode
8516 ;; equivalents when possible.
8517 ;; Don't do the splitting with memory operands, since it introduces risk
8518 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8519 ;; for size, but that can (should?) be handled by generic code instead.
8520 (define_split
8521 [(set (match_operand 0 "register_operand" "")
8522 (and (match_operand 1 "register_operand" "")
8523 (match_operand 2 "const_int_operand" "")))
8524 (clobber (reg:CC FLAGS_REG))]
8525 "reload_completed
8526 && QI_REG_P (operands[0])
8527 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8528 && !(~INTVAL (operands[2]) & ~(255 << 8))
8529 && GET_MODE (operands[0]) != QImode"
8530 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8531 (and:SI (zero_extract:SI (match_dup 1)
8532 (const_int 8) (const_int 8))
8533 (match_dup 2)))
8534 (clobber (reg:CC FLAGS_REG))])]
8535 "operands[0] = gen_lowpart (SImode, operands[0]);
8536 operands[1] = gen_lowpart (SImode, operands[1]);
8537 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8538
8539 ;; Since AND can be encoded with sign extended immediate, this is only
8540 ;; profitable when 7th bit is not set.
8541 (define_split
8542 [(set (match_operand 0 "register_operand" "")
8543 (and (match_operand 1 "general_operand" "")
8544 (match_operand 2 "const_int_operand" "")))
8545 (clobber (reg:CC FLAGS_REG))]
8546 "reload_completed
8547 && ANY_QI_REG_P (operands[0])
8548 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8549 && !(~INTVAL (operands[2]) & ~255)
8550 && !(INTVAL (operands[2]) & 128)
8551 && GET_MODE (operands[0]) != QImode"
8552 [(parallel [(set (strict_low_part (match_dup 0))
8553 (and:QI (match_dup 1)
8554 (match_dup 2)))
8555 (clobber (reg:CC FLAGS_REG))])]
8556 "operands[0] = gen_lowpart (QImode, operands[0]);
8557 operands[1] = gen_lowpart (QImode, operands[1]);
8558 operands[2] = gen_lowpart (QImode, operands[2]);")
8559 \f
8560 ;; Logical inclusive OR instructions
8561
8562 ;; %%% This used to optimize known byte-wide and operations to memory.
8563 ;; If this is considered useful, it should be done with splitters.
8564
8565 (define_expand "iordi3"
8566 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8567 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8568 (match_operand:DI 2 "x86_64_general_operand" "")))
8569 (clobber (reg:CC FLAGS_REG))]
8570 "TARGET_64BIT"
8571 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8572
8573 (define_insn "*iordi_1_rex64"
8574 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8575 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8576 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8577 (clobber (reg:CC FLAGS_REG))]
8578 "TARGET_64BIT
8579 && ix86_binary_operator_ok (IOR, DImode, operands)"
8580 "or{q}\t{%2, %0|%0, %2}"
8581 [(set_attr "type" "alu")
8582 (set_attr "mode" "DI")])
8583
8584 (define_insn "*iordi_2_rex64"
8585 [(set (reg FLAGS_REG)
8586 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8587 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8588 (const_int 0)))
8589 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8590 (ior:DI (match_dup 1) (match_dup 2)))]
8591 "TARGET_64BIT
8592 && ix86_match_ccmode (insn, CCNOmode)
8593 && ix86_binary_operator_ok (IOR, DImode, operands)"
8594 "or{q}\t{%2, %0|%0, %2}"
8595 [(set_attr "type" "alu")
8596 (set_attr "mode" "DI")])
8597
8598 (define_insn "*iordi_3_rex64"
8599 [(set (reg FLAGS_REG)
8600 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8601 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8602 (const_int 0)))
8603 (clobber (match_scratch:DI 0 "=r"))]
8604 "TARGET_64BIT
8605 && ix86_match_ccmode (insn, CCNOmode)
8606 && ix86_binary_operator_ok (IOR, DImode, operands)"
8607 "or{q}\t{%2, %0|%0, %2}"
8608 [(set_attr "type" "alu")
8609 (set_attr "mode" "DI")])
8610
8611
8612 (define_expand "iorsi3"
8613 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8614 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8615 (match_operand:SI 2 "general_operand" "")))
8616 (clobber (reg:CC FLAGS_REG))]
8617 ""
8618 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8619
8620 (define_insn "*iorsi_1"
8621 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8622 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8623 (match_operand:SI 2 "general_operand" "ri,rmi")))
8624 (clobber (reg:CC FLAGS_REG))]
8625 "ix86_binary_operator_ok (IOR, SImode, operands)"
8626 "or{l}\t{%2, %0|%0, %2}"
8627 [(set_attr "type" "alu")
8628 (set_attr "mode" "SI")])
8629
8630 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8631 (define_insn "*iorsi_1_zext"
8632 [(set (match_operand:DI 0 "register_operand" "=rm")
8633 (zero_extend:DI
8634 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8635 (match_operand:SI 2 "general_operand" "rim"))))
8636 (clobber (reg:CC FLAGS_REG))]
8637 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8638 "or{l}\t{%2, %k0|%k0, %2}"
8639 [(set_attr "type" "alu")
8640 (set_attr "mode" "SI")])
8641
8642 (define_insn "*iorsi_1_zext_imm"
8643 [(set (match_operand:DI 0 "register_operand" "=rm")
8644 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8645 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8646 (clobber (reg:CC FLAGS_REG))]
8647 "TARGET_64BIT"
8648 "or{l}\t{%2, %k0|%k0, %2}"
8649 [(set_attr "type" "alu")
8650 (set_attr "mode" "SI")])
8651
8652 (define_insn "*iorsi_2"
8653 [(set (reg FLAGS_REG)
8654 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8655 (match_operand:SI 2 "general_operand" "rim,ri"))
8656 (const_int 0)))
8657 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8658 (ior:SI (match_dup 1) (match_dup 2)))]
8659 "ix86_match_ccmode (insn, CCNOmode)
8660 && ix86_binary_operator_ok (IOR, SImode, operands)"
8661 "or{l}\t{%2, %0|%0, %2}"
8662 [(set_attr "type" "alu")
8663 (set_attr "mode" "SI")])
8664
8665 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8666 ;; ??? Special case for immediate operand is missing - it is tricky.
8667 (define_insn "*iorsi_2_zext"
8668 [(set (reg FLAGS_REG)
8669 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8670 (match_operand:SI 2 "general_operand" "rim"))
8671 (const_int 0)))
8672 (set (match_operand:DI 0 "register_operand" "=r")
8673 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8674 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8675 && ix86_binary_operator_ok (IOR, SImode, operands)"
8676 "or{l}\t{%2, %k0|%k0, %2}"
8677 [(set_attr "type" "alu")
8678 (set_attr "mode" "SI")])
8679
8680 (define_insn "*iorsi_2_zext_imm"
8681 [(set (reg FLAGS_REG)
8682 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8683 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8684 (const_int 0)))
8685 (set (match_operand:DI 0 "register_operand" "=r")
8686 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8687 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8688 && ix86_binary_operator_ok (IOR, SImode, operands)"
8689 "or{l}\t{%2, %k0|%k0, %2}"
8690 [(set_attr "type" "alu")
8691 (set_attr "mode" "SI")])
8692
8693 (define_insn "*iorsi_3"
8694 [(set (reg FLAGS_REG)
8695 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8696 (match_operand:SI 2 "general_operand" "rim"))
8697 (const_int 0)))
8698 (clobber (match_scratch:SI 0 "=r"))]
8699 "ix86_match_ccmode (insn, CCNOmode)
8700 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8701 "or{l}\t{%2, %0|%0, %2}"
8702 [(set_attr "type" "alu")
8703 (set_attr "mode" "SI")])
8704
8705 (define_expand "iorhi3"
8706 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8707 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8708 (match_operand:HI 2 "general_operand" "")))
8709 (clobber (reg:CC FLAGS_REG))]
8710 "TARGET_HIMODE_MATH"
8711 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8712
8713 (define_insn "*iorhi_1"
8714 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8715 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8716 (match_operand:HI 2 "general_operand" "rmi,ri")))
8717 (clobber (reg:CC FLAGS_REG))]
8718 "ix86_binary_operator_ok (IOR, HImode, operands)"
8719 "or{w}\t{%2, %0|%0, %2}"
8720 [(set_attr "type" "alu")
8721 (set_attr "mode" "HI")])
8722
8723 (define_insn "*iorhi_2"
8724 [(set (reg FLAGS_REG)
8725 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8726 (match_operand:HI 2 "general_operand" "rim,ri"))
8727 (const_int 0)))
8728 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8729 (ior:HI (match_dup 1) (match_dup 2)))]
8730 "ix86_match_ccmode (insn, CCNOmode)
8731 && ix86_binary_operator_ok (IOR, HImode, operands)"
8732 "or{w}\t{%2, %0|%0, %2}"
8733 [(set_attr "type" "alu")
8734 (set_attr "mode" "HI")])
8735
8736 (define_insn "*iorhi_3"
8737 [(set (reg FLAGS_REG)
8738 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8739 (match_operand:HI 2 "general_operand" "rim"))
8740 (const_int 0)))
8741 (clobber (match_scratch:HI 0 "=r"))]
8742 "ix86_match_ccmode (insn, CCNOmode)
8743 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8744 "or{w}\t{%2, %0|%0, %2}"
8745 [(set_attr "type" "alu")
8746 (set_attr "mode" "HI")])
8747
8748 (define_expand "iorqi3"
8749 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8750 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8751 (match_operand:QI 2 "general_operand" "")))
8752 (clobber (reg:CC FLAGS_REG))]
8753 "TARGET_QIMODE_MATH"
8754 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8755
8756 ;; %%% Potential partial reg stall on alternative 2. What to do?
8757 (define_insn "*iorqi_1"
8758 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8759 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8760 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8761 (clobber (reg:CC FLAGS_REG))]
8762 "ix86_binary_operator_ok (IOR, QImode, operands)"
8763 "@
8764 or{b}\t{%2, %0|%0, %2}
8765 or{b}\t{%2, %0|%0, %2}
8766 or{l}\t{%k2, %k0|%k0, %k2}"
8767 [(set_attr "type" "alu")
8768 (set_attr "mode" "QI,QI,SI")])
8769
8770 (define_insn "*iorqi_1_slp"
8771 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8772 (ior:QI (match_dup 0)
8773 (match_operand:QI 1 "general_operand" "qmi,qi")))
8774 (clobber (reg:CC FLAGS_REG))]
8775 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8776 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8777 "or{b}\t{%1, %0|%0, %1}"
8778 [(set_attr "type" "alu1")
8779 (set_attr "mode" "QI")])
8780
8781 (define_insn "*iorqi_2"
8782 [(set (reg FLAGS_REG)
8783 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8784 (match_operand:QI 2 "general_operand" "qim,qi"))
8785 (const_int 0)))
8786 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8787 (ior:QI (match_dup 1) (match_dup 2)))]
8788 "ix86_match_ccmode (insn, CCNOmode)
8789 && ix86_binary_operator_ok (IOR, QImode, operands)"
8790 "or{b}\t{%2, %0|%0, %2}"
8791 [(set_attr "type" "alu")
8792 (set_attr "mode" "QI")])
8793
8794 (define_insn "*iorqi_2_slp"
8795 [(set (reg FLAGS_REG)
8796 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8797 (match_operand:QI 1 "general_operand" "qim,qi"))
8798 (const_int 0)))
8799 (set (strict_low_part (match_dup 0))
8800 (ior:QI (match_dup 0) (match_dup 1)))]
8801 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8802 && ix86_match_ccmode (insn, CCNOmode)
8803 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8804 "or{b}\t{%1, %0|%0, %1}"
8805 [(set_attr "type" "alu1")
8806 (set_attr "mode" "QI")])
8807
8808 (define_insn "*iorqi_3"
8809 [(set (reg FLAGS_REG)
8810 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8811 (match_operand:QI 2 "general_operand" "qim"))
8812 (const_int 0)))
8813 (clobber (match_scratch:QI 0 "=q"))]
8814 "ix86_match_ccmode (insn, CCNOmode)
8815 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8816 "or{b}\t{%2, %0|%0, %2}"
8817 [(set_attr "type" "alu")
8818 (set_attr "mode" "QI")])
8819
8820 (define_insn "iorqi_ext_0"
8821 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8822 (const_int 8)
8823 (const_int 8))
8824 (ior:SI
8825 (zero_extract:SI
8826 (match_operand 1 "ext_register_operand" "0")
8827 (const_int 8)
8828 (const_int 8))
8829 (match_operand 2 "const_int_operand" "n")))
8830 (clobber (reg:CC FLAGS_REG))]
8831 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8832 "or{b}\t{%2, %h0|%h0, %2}"
8833 [(set_attr "type" "alu")
8834 (set_attr "length_immediate" "1")
8835 (set_attr "mode" "QI")])
8836
8837 (define_insn "*iorqi_ext_1"
8838 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8839 (const_int 8)
8840 (const_int 8))
8841 (ior:SI
8842 (zero_extract:SI
8843 (match_operand 1 "ext_register_operand" "0")
8844 (const_int 8)
8845 (const_int 8))
8846 (zero_extend:SI
8847 (match_operand:QI 2 "general_operand" "Qm"))))
8848 (clobber (reg:CC FLAGS_REG))]
8849 "!TARGET_64BIT
8850 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8851 "or{b}\t{%2, %h0|%h0, %2}"
8852 [(set_attr "type" "alu")
8853 (set_attr "length_immediate" "0")
8854 (set_attr "mode" "QI")])
8855
8856 (define_insn "*iorqi_ext_1_rex64"
8857 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8858 (const_int 8)
8859 (const_int 8))
8860 (ior:SI
8861 (zero_extract:SI
8862 (match_operand 1 "ext_register_operand" "0")
8863 (const_int 8)
8864 (const_int 8))
8865 (zero_extend:SI
8866 (match_operand 2 "ext_register_operand" "Q"))))
8867 (clobber (reg:CC FLAGS_REG))]
8868 "TARGET_64BIT
8869 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8870 "or{b}\t{%2, %h0|%h0, %2}"
8871 [(set_attr "type" "alu")
8872 (set_attr "length_immediate" "0")
8873 (set_attr "mode" "QI")])
8874
8875 (define_insn "*iorqi_ext_2"
8876 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8877 (const_int 8)
8878 (const_int 8))
8879 (ior:SI
8880 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8881 (const_int 8)
8882 (const_int 8))
8883 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8884 (const_int 8)
8885 (const_int 8))))
8886 (clobber (reg:CC FLAGS_REG))]
8887 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8888 "ior{b}\t{%h2, %h0|%h0, %h2}"
8889 [(set_attr "type" "alu")
8890 (set_attr "length_immediate" "0")
8891 (set_attr "mode" "QI")])
8892
8893 (define_split
8894 [(set (match_operand 0 "register_operand" "")
8895 (ior (match_operand 1 "register_operand" "")
8896 (match_operand 2 "const_int_operand" "")))
8897 (clobber (reg:CC FLAGS_REG))]
8898 "reload_completed
8899 && QI_REG_P (operands[0])
8900 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8901 && !(INTVAL (operands[2]) & ~(255 << 8))
8902 && GET_MODE (operands[0]) != QImode"
8903 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8904 (ior:SI (zero_extract:SI (match_dup 1)
8905 (const_int 8) (const_int 8))
8906 (match_dup 2)))
8907 (clobber (reg:CC FLAGS_REG))])]
8908 "operands[0] = gen_lowpart (SImode, operands[0]);
8909 operands[1] = gen_lowpart (SImode, operands[1]);
8910 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8911
8912 ;; Since OR can be encoded with sign extended immediate, this is only
8913 ;; profitable when 7th bit is set.
8914 (define_split
8915 [(set (match_operand 0 "register_operand" "")
8916 (ior (match_operand 1 "general_operand" "")
8917 (match_operand 2 "const_int_operand" "")))
8918 (clobber (reg:CC FLAGS_REG))]
8919 "reload_completed
8920 && ANY_QI_REG_P (operands[0])
8921 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8922 && !(INTVAL (operands[2]) & ~255)
8923 && (INTVAL (operands[2]) & 128)
8924 && GET_MODE (operands[0]) != QImode"
8925 [(parallel [(set (strict_low_part (match_dup 0))
8926 (ior:QI (match_dup 1)
8927 (match_dup 2)))
8928 (clobber (reg:CC FLAGS_REG))])]
8929 "operands[0] = gen_lowpart (QImode, operands[0]);
8930 operands[1] = gen_lowpart (QImode, operands[1]);
8931 operands[2] = gen_lowpart (QImode, operands[2]);")
8932 \f
8933 ;; Logical XOR instructions
8934
8935 ;; %%% This used to optimize known byte-wide and operations to memory.
8936 ;; If this is considered useful, it should be done with splitters.
8937
8938 (define_expand "xordi3"
8939 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8940 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8941 (match_operand:DI 2 "x86_64_general_operand" "")))
8942 (clobber (reg:CC FLAGS_REG))]
8943 "TARGET_64BIT"
8944 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8945
8946 (define_insn "*xordi_1_rex64"
8947 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8948 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8949 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8950 (clobber (reg:CC FLAGS_REG))]
8951 "TARGET_64BIT
8952 && ix86_binary_operator_ok (XOR, DImode, operands)"
8953 "@
8954 xor{q}\t{%2, %0|%0, %2}
8955 xor{q}\t{%2, %0|%0, %2}"
8956 [(set_attr "type" "alu")
8957 (set_attr "mode" "DI,DI")])
8958
8959 (define_insn "*xordi_2_rex64"
8960 [(set (reg FLAGS_REG)
8961 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8962 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8963 (const_int 0)))
8964 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8965 (xor:DI (match_dup 1) (match_dup 2)))]
8966 "TARGET_64BIT
8967 && ix86_match_ccmode (insn, CCNOmode)
8968 && ix86_binary_operator_ok (XOR, DImode, operands)"
8969 "@
8970 xor{q}\t{%2, %0|%0, %2}
8971 xor{q}\t{%2, %0|%0, %2}"
8972 [(set_attr "type" "alu")
8973 (set_attr "mode" "DI,DI")])
8974
8975 (define_insn "*xordi_3_rex64"
8976 [(set (reg FLAGS_REG)
8977 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8978 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8979 (const_int 0)))
8980 (clobber (match_scratch:DI 0 "=r"))]
8981 "TARGET_64BIT
8982 && ix86_match_ccmode (insn, CCNOmode)
8983 && ix86_binary_operator_ok (XOR, DImode, operands)"
8984 "xor{q}\t{%2, %0|%0, %2}"
8985 [(set_attr "type" "alu")
8986 (set_attr "mode" "DI")])
8987
8988 (define_expand "xorsi3"
8989 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8990 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8991 (match_operand:SI 2 "general_operand" "")))
8992 (clobber (reg:CC FLAGS_REG))]
8993 ""
8994 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8995
8996 (define_insn "*xorsi_1"
8997 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8998 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8999 (match_operand:SI 2 "general_operand" "ri,rm")))
9000 (clobber (reg:CC FLAGS_REG))]
9001 "ix86_binary_operator_ok (XOR, SImode, operands)"
9002 "xor{l}\t{%2, %0|%0, %2}"
9003 [(set_attr "type" "alu")
9004 (set_attr "mode" "SI")])
9005
9006 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9007 ;; Add speccase for immediates
9008 (define_insn "*xorsi_1_zext"
9009 [(set (match_operand:DI 0 "register_operand" "=r")
9010 (zero_extend:DI
9011 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9012 (match_operand:SI 2 "general_operand" "rim"))))
9013 (clobber (reg:CC FLAGS_REG))]
9014 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9015 "xor{l}\t{%2, %k0|%k0, %2}"
9016 [(set_attr "type" "alu")
9017 (set_attr "mode" "SI")])
9018
9019 (define_insn "*xorsi_1_zext_imm"
9020 [(set (match_operand:DI 0 "register_operand" "=r")
9021 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9022 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9023 (clobber (reg:CC FLAGS_REG))]
9024 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9025 "xor{l}\t{%2, %k0|%k0, %2}"
9026 [(set_attr "type" "alu")
9027 (set_attr "mode" "SI")])
9028
9029 (define_insn "*xorsi_2"
9030 [(set (reg FLAGS_REG)
9031 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9032 (match_operand:SI 2 "general_operand" "rim,ri"))
9033 (const_int 0)))
9034 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9035 (xor:SI (match_dup 1) (match_dup 2)))]
9036 "ix86_match_ccmode (insn, CCNOmode)
9037 && ix86_binary_operator_ok (XOR, SImode, operands)"
9038 "xor{l}\t{%2, %0|%0, %2}"
9039 [(set_attr "type" "alu")
9040 (set_attr "mode" "SI")])
9041
9042 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9043 ;; ??? Special case for immediate operand is missing - it is tricky.
9044 (define_insn "*xorsi_2_zext"
9045 [(set (reg FLAGS_REG)
9046 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9047 (match_operand:SI 2 "general_operand" "rim"))
9048 (const_int 0)))
9049 (set (match_operand:DI 0 "register_operand" "=r")
9050 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9051 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9052 && ix86_binary_operator_ok (XOR, SImode, operands)"
9053 "xor{l}\t{%2, %k0|%k0, %2}"
9054 [(set_attr "type" "alu")
9055 (set_attr "mode" "SI")])
9056
9057 (define_insn "*xorsi_2_zext_imm"
9058 [(set (reg FLAGS_REG)
9059 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9060 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9061 (const_int 0)))
9062 (set (match_operand:DI 0 "register_operand" "=r")
9063 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9064 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9065 && ix86_binary_operator_ok (XOR, SImode, operands)"
9066 "xor{l}\t{%2, %k0|%k0, %2}"
9067 [(set_attr "type" "alu")
9068 (set_attr "mode" "SI")])
9069
9070 (define_insn "*xorsi_3"
9071 [(set (reg FLAGS_REG)
9072 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9073 (match_operand:SI 2 "general_operand" "rim"))
9074 (const_int 0)))
9075 (clobber (match_scratch:SI 0 "=r"))]
9076 "ix86_match_ccmode (insn, CCNOmode)
9077 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9078 "xor{l}\t{%2, %0|%0, %2}"
9079 [(set_attr "type" "alu")
9080 (set_attr "mode" "SI")])
9081
9082 (define_expand "xorhi3"
9083 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9084 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9085 (match_operand:HI 2 "general_operand" "")))
9086 (clobber (reg:CC FLAGS_REG))]
9087 "TARGET_HIMODE_MATH"
9088 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9089
9090 (define_insn "*xorhi_1"
9091 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9092 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9093 (match_operand:HI 2 "general_operand" "rmi,ri")))
9094 (clobber (reg:CC FLAGS_REG))]
9095 "ix86_binary_operator_ok (XOR, HImode, operands)"
9096 "xor{w}\t{%2, %0|%0, %2}"
9097 [(set_attr "type" "alu")
9098 (set_attr "mode" "HI")])
9099
9100 (define_insn "*xorhi_2"
9101 [(set (reg FLAGS_REG)
9102 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9103 (match_operand:HI 2 "general_operand" "rim,ri"))
9104 (const_int 0)))
9105 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9106 (xor:HI (match_dup 1) (match_dup 2)))]
9107 "ix86_match_ccmode (insn, CCNOmode)
9108 && ix86_binary_operator_ok (XOR, HImode, operands)"
9109 "xor{w}\t{%2, %0|%0, %2}"
9110 [(set_attr "type" "alu")
9111 (set_attr "mode" "HI")])
9112
9113 (define_insn "*xorhi_3"
9114 [(set (reg FLAGS_REG)
9115 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9116 (match_operand:HI 2 "general_operand" "rim"))
9117 (const_int 0)))
9118 (clobber (match_scratch:HI 0 "=r"))]
9119 "ix86_match_ccmode (insn, CCNOmode)
9120 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9121 "xor{w}\t{%2, %0|%0, %2}"
9122 [(set_attr "type" "alu")
9123 (set_attr "mode" "HI")])
9124
9125 (define_expand "xorqi3"
9126 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9127 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9128 (match_operand:QI 2 "general_operand" "")))
9129 (clobber (reg:CC FLAGS_REG))]
9130 "TARGET_QIMODE_MATH"
9131 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9132
9133 ;; %%% Potential partial reg stall on alternative 2. What to do?
9134 (define_insn "*xorqi_1"
9135 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9136 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9137 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9138 (clobber (reg:CC FLAGS_REG))]
9139 "ix86_binary_operator_ok (XOR, QImode, operands)"
9140 "@
9141 xor{b}\t{%2, %0|%0, %2}
9142 xor{b}\t{%2, %0|%0, %2}
9143 xor{l}\t{%k2, %k0|%k0, %k2}"
9144 [(set_attr "type" "alu")
9145 (set_attr "mode" "QI,QI,SI")])
9146
9147 (define_insn "*xorqi_1_slp"
9148 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9149 (xor:QI (match_dup 0)
9150 (match_operand:QI 1 "general_operand" "qi,qmi")))
9151 (clobber (reg:CC FLAGS_REG))]
9152 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9153 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9154 "xor{b}\t{%1, %0|%0, %1}"
9155 [(set_attr "type" "alu1")
9156 (set_attr "mode" "QI")])
9157
9158 (define_insn "xorqi_ext_0"
9159 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9160 (const_int 8)
9161 (const_int 8))
9162 (xor:SI
9163 (zero_extract:SI
9164 (match_operand 1 "ext_register_operand" "0")
9165 (const_int 8)
9166 (const_int 8))
9167 (match_operand 2 "const_int_operand" "n")))
9168 (clobber (reg:CC FLAGS_REG))]
9169 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9170 "xor{b}\t{%2, %h0|%h0, %2}"
9171 [(set_attr "type" "alu")
9172 (set_attr "length_immediate" "1")
9173 (set_attr "mode" "QI")])
9174
9175 (define_insn "*xorqi_ext_1"
9176 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9177 (const_int 8)
9178 (const_int 8))
9179 (xor:SI
9180 (zero_extract:SI
9181 (match_operand 1 "ext_register_operand" "0")
9182 (const_int 8)
9183 (const_int 8))
9184 (zero_extend:SI
9185 (match_operand:QI 2 "general_operand" "Qm"))))
9186 (clobber (reg:CC FLAGS_REG))]
9187 "!TARGET_64BIT
9188 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9189 "xor{b}\t{%2, %h0|%h0, %2}"
9190 [(set_attr "type" "alu")
9191 (set_attr "length_immediate" "0")
9192 (set_attr "mode" "QI")])
9193
9194 (define_insn "*xorqi_ext_1_rex64"
9195 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9196 (const_int 8)
9197 (const_int 8))
9198 (xor:SI
9199 (zero_extract:SI
9200 (match_operand 1 "ext_register_operand" "0")
9201 (const_int 8)
9202 (const_int 8))
9203 (zero_extend:SI
9204 (match_operand 2 "ext_register_operand" "Q"))))
9205 (clobber (reg:CC FLAGS_REG))]
9206 "TARGET_64BIT
9207 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9208 "xor{b}\t{%2, %h0|%h0, %2}"
9209 [(set_attr "type" "alu")
9210 (set_attr "length_immediate" "0")
9211 (set_attr "mode" "QI")])
9212
9213 (define_insn "*xorqi_ext_2"
9214 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9215 (const_int 8)
9216 (const_int 8))
9217 (xor:SI
9218 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9219 (const_int 8)
9220 (const_int 8))
9221 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9222 (const_int 8)
9223 (const_int 8))))
9224 (clobber (reg:CC FLAGS_REG))]
9225 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9226 "xor{b}\t{%h2, %h0|%h0, %h2}"
9227 [(set_attr "type" "alu")
9228 (set_attr "length_immediate" "0")
9229 (set_attr "mode" "QI")])
9230
9231 (define_insn "*xorqi_cc_1"
9232 [(set (reg FLAGS_REG)
9233 (compare
9234 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9235 (match_operand:QI 2 "general_operand" "qim,qi"))
9236 (const_int 0)))
9237 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9238 (xor:QI (match_dup 1) (match_dup 2)))]
9239 "ix86_match_ccmode (insn, CCNOmode)
9240 && ix86_binary_operator_ok (XOR, QImode, operands)"
9241 "xor{b}\t{%2, %0|%0, %2}"
9242 [(set_attr "type" "alu")
9243 (set_attr "mode" "QI")])
9244
9245 (define_insn "*xorqi_2_slp"
9246 [(set (reg FLAGS_REG)
9247 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9248 (match_operand:QI 1 "general_operand" "qim,qi"))
9249 (const_int 0)))
9250 (set (strict_low_part (match_dup 0))
9251 (xor:QI (match_dup 0) (match_dup 1)))]
9252 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9253 && ix86_match_ccmode (insn, CCNOmode)
9254 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9255 "xor{b}\t{%1, %0|%0, %1}"
9256 [(set_attr "type" "alu1")
9257 (set_attr "mode" "QI")])
9258
9259 (define_insn "*xorqi_cc_2"
9260 [(set (reg FLAGS_REG)
9261 (compare
9262 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9263 (match_operand:QI 2 "general_operand" "qim"))
9264 (const_int 0)))
9265 (clobber (match_scratch:QI 0 "=q"))]
9266 "ix86_match_ccmode (insn, CCNOmode)
9267 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9268 "xor{b}\t{%2, %0|%0, %2}"
9269 [(set_attr "type" "alu")
9270 (set_attr "mode" "QI")])
9271
9272 (define_insn "*xorqi_cc_ext_1"
9273 [(set (reg FLAGS_REG)
9274 (compare
9275 (xor:SI
9276 (zero_extract:SI
9277 (match_operand 1 "ext_register_operand" "0")
9278 (const_int 8)
9279 (const_int 8))
9280 (match_operand:QI 2 "general_operand" "qmn"))
9281 (const_int 0)))
9282 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9283 (const_int 8)
9284 (const_int 8))
9285 (xor:SI
9286 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9287 (match_dup 2)))]
9288 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9289 "xor{b}\t{%2, %h0|%h0, %2}"
9290 [(set_attr "type" "alu")
9291 (set_attr "mode" "QI")])
9292
9293 (define_insn "*xorqi_cc_ext_1_rex64"
9294 [(set (reg FLAGS_REG)
9295 (compare
9296 (xor:SI
9297 (zero_extract:SI
9298 (match_operand 1 "ext_register_operand" "0")
9299 (const_int 8)
9300 (const_int 8))
9301 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9302 (const_int 0)))
9303 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9304 (const_int 8)
9305 (const_int 8))
9306 (xor:SI
9307 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9308 (match_dup 2)))]
9309 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9310 "xor{b}\t{%2, %h0|%h0, %2}"
9311 [(set_attr "type" "alu")
9312 (set_attr "mode" "QI")])
9313
9314 (define_expand "xorqi_cc_ext_1"
9315 [(parallel [
9316 (set (reg:CCNO FLAGS_REG)
9317 (compare:CCNO
9318 (xor:SI
9319 (zero_extract:SI
9320 (match_operand 1 "ext_register_operand" "")
9321 (const_int 8)
9322 (const_int 8))
9323 (match_operand:QI 2 "general_operand" ""))
9324 (const_int 0)))
9325 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9326 (const_int 8)
9327 (const_int 8))
9328 (xor:SI
9329 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9330 (match_dup 2)))])]
9331 ""
9332 "")
9333
9334 (define_split
9335 [(set (match_operand 0 "register_operand" "")
9336 (xor (match_operand 1 "register_operand" "")
9337 (match_operand 2 "const_int_operand" "")))
9338 (clobber (reg:CC FLAGS_REG))]
9339 "reload_completed
9340 && QI_REG_P (operands[0])
9341 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9342 && !(INTVAL (operands[2]) & ~(255 << 8))
9343 && GET_MODE (operands[0]) != QImode"
9344 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9345 (xor:SI (zero_extract:SI (match_dup 1)
9346 (const_int 8) (const_int 8))
9347 (match_dup 2)))
9348 (clobber (reg:CC FLAGS_REG))])]
9349 "operands[0] = gen_lowpart (SImode, operands[0]);
9350 operands[1] = gen_lowpart (SImode, operands[1]);
9351 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9352
9353 ;; Since XOR can be encoded with sign extended immediate, this is only
9354 ;; profitable when 7th bit is set.
9355 (define_split
9356 [(set (match_operand 0 "register_operand" "")
9357 (xor (match_operand 1 "general_operand" "")
9358 (match_operand 2 "const_int_operand" "")))
9359 (clobber (reg:CC FLAGS_REG))]
9360 "reload_completed
9361 && ANY_QI_REG_P (operands[0])
9362 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9363 && !(INTVAL (operands[2]) & ~255)
9364 && (INTVAL (operands[2]) & 128)
9365 && GET_MODE (operands[0]) != QImode"
9366 [(parallel [(set (strict_low_part (match_dup 0))
9367 (xor:QI (match_dup 1)
9368 (match_dup 2)))
9369 (clobber (reg:CC FLAGS_REG))])]
9370 "operands[0] = gen_lowpart (QImode, operands[0]);
9371 operands[1] = gen_lowpart (QImode, operands[1]);
9372 operands[2] = gen_lowpart (QImode, operands[2]);")
9373 \f
9374 ;; Negation instructions
9375
9376 (define_expand "negti2"
9377 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9378 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9379 (clobber (reg:CC FLAGS_REG))])]
9380 "TARGET_64BIT"
9381 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9382
9383 (define_insn "*negti2_1"
9384 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9385 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9386 (clobber (reg:CC FLAGS_REG))]
9387 "TARGET_64BIT
9388 && ix86_unary_operator_ok (NEG, TImode, operands)"
9389 "#")
9390
9391 (define_split
9392 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9393 (neg:TI (match_operand:TI 1 "general_operand" "")))
9394 (clobber (reg:CC FLAGS_REG))]
9395 "TARGET_64BIT && reload_completed"
9396 [(parallel
9397 [(set (reg:CCZ FLAGS_REG)
9398 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9399 (set (match_dup 0) (neg:DI (match_dup 2)))])
9400 (parallel
9401 [(set (match_dup 1)
9402 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9403 (match_dup 3))
9404 (const_int 0)))
9405 (clobber (reg:CC FLAGS_REG))])
9406 (parallel
9407 [(set (match_dup 1)
9408 (neg:DI (match_dup 1)))
9409 (clobber (reg:CC FLAGS_REG))])]
9410 "split_ti (operands+1, 1, operands+2, operands+3);
9411 split_ti (operands+0, 1, operands+0, operands+1);")
9412
9413 (define_expand "negdi2"
9414 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9415 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9416 (clobber (reg:CC FLAGS_REG))])]
9417 ""
9418 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9419
9420 (define_insn "*negdi2_1"
9421 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9422 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9423 (clobber (reg:CC FLAGS_REG))]
9424 "!TARGET_64BIT
9425 && ix86_unary_operator_ok (NEG, DImode, operands)"
9426 "#")
9427
9428 (define_split
9429 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9430 (neg:DI (match_operand:DI 1 "general_operand" "")))
9431 (clobber (reg:CC FLAGS_REG))]
9432 "!TARGET_64BIT && reload_completed"
9433 [(parallel
9434 [(set (reg:CCZ FLAGS_REG)
9435 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9436 (set (match_dup 0) (neg:SI (match_dup 2)))])
9437 (parallel
9438 [(set (match_dup 1)
9439 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9440 (match_dup 3))
9441 (const_int 0)))
9442 (clobber (reg:CC FLAGS_REG))])
9443 (parallel
9444 [(set (match_dup 1)
9445 (neg:SI (match_dup 1)))
9446 (clobber (reg:CC FLAGS_REG))])]
9447 "split_di (operands+1, 1, operands+2, operands+3);
9448 split_di (operands+0, 1, operands+0, operands+1);")
9449
9450 (define_insn "*negdi2_1_rex64"
9451 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9452 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9453 (clobber (reg:CC FLAGS_REG))]
9454 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9455 "neg{q}\t%0"
9456 [(set_attr "type" "negnot")
9457 (set_attr "mode" "DI")])
9458
9459 ;; The problem with neg is that it does not perform (compare x 0),
9460 ;; it really performs (compare 0 x), which leaves us with the zero
9461 ;; flag being the only useful item.
9462
9463 (define_insn "*negdi2_cmpz_rex64"
9464 [(set (reg:CCZ FLAGS_REG)
9465 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9466 (const_int 0)))
9467 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9468 (neg:DI (match_dup 1)))]
9469 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9470 "neg{q}\t%0"
9471 [(set_attr "type" "negnot")
9472 (set_attr "mode" "DI")])
9473
9474
9475 (define_expand "negsi2"
9476 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9477 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9478 (clobber (reg:CC FLAGS_REG))])]
9479 ""
9480 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9481
9482 (define_insn "*negsi2_1"
9483 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9484 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9485 (clobber (reg:CC FLAGS_REG))]
9486 "ix86_unary_operator_ok (NEG, SImode, operands)"
9487 "neg{l}\t%0"
9488 [(set_attr "type" "negnot")
9489 (set_attr "mode" "SI")])
9490
9491 ;; Combine is quite creative about this pattern.
9492 (define_insn "*negsi2_1_zext"
9493 [(set (match_operand:DI 0 "register_operand" "=r")
9494 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9495 (const_int 32)))
9496 (const_int 32)))
9497 (clobber (reg:CC FLAGS_REG))]
9498 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9499 "neg{l}\t%k0"
9500 [(set_attr "type" "negnot")
9501 (set_attr "mode" "SI")])
9502
9503 ;; The problem with neg is that it does not perform (compare x 0),
9504 ;; it really performs (compare 0 x), which leaves us with the zero
9505 ;; flag being the only useful item.
9506
9507 (define_insn "*negsi2_cmpz"
9508 [(set (reg:CCZ FLAGS_REG)
9509 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9510 (const_int 0)))
9511 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9512 (neg:SI (match_dup 1)))]
9513 "ix86_unary_operator_ok (NEG, SImode, operands)"
9514 "neg{l}\t%0"
9515 [(set_attr "type" "negnot")
9516 (set_attr "mode" "SI")])
9517
9518 (define_insn "*negsi2_cmpz_zext"
9519 [(set (reg:CCZ FLAGS_REG)
9520 (compare:CCZ (lshiftrt:DI
9521 (neg:DI (ashift:DI
9522 (match_operand:DI 1 "register_operand" "0")
9523 (const_int 32)))
9524 (const_int 32))
9525 (const_int 0)))
9526 (set (match_operand:DI 0 "register_operand" "=r")
9527 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9528 (const_int 32)))
9529 (const_int 32)))]
9530 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9531 "neg{l}\t%k0"
9532 [(set_attr "type" "negnot")
9533 (set_attr "mode" "SI")])
9534
9535 (define_expand "neghi2"
9536 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9537 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9538 (clobber (reg:CC FLAGS_REG))])]
9539 "TARGET_HIMODE_MATH"
9540 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9541
9542 (define_insn "*neghi2_1"
9543 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9544 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9545 (clobber (reg:CC FLAGS_REG))]
9546 "ix86_unary_operator_ok (NEG, HImode, operands)"
9547 "neg{w}\t%0"
9548 [(set_attr "type" "negnot")
9549 (set_attr "mode" "HI")])
9550
9551 (define_insn "*neghi2_cmpz"
9552 [(set (reg:CCZ FLAGS_REG)
9553 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9554 (const_int 0)))
9555 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9556 (neg:HI (match_dup 1)))]
9557 "ix86_unary_operator_ok (NEG, HImode, operands)"
9558 "neg{w}\t%0"
9559 [(set_attr "type" "negnot")
9560 (set_attr "mode" "HI")])
9561
9562 (define_expand "negqi2"
9563 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9564 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9565 (clobber (reg:CC FLAGS_REG))])]
9566 "TARGET_QIMODE_MATH"
9567 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9568
9569 (define_insn "*negqi2_1"
9570 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9571 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9572 (clobber (reg:CC FLAGS_REG))]
9573 "ix86_unary_operator_ok (NEG, QImode, operands)"
9574 "neg{b}\t%0"
9575 [(set_attr "type" "negnot")
9576 (set_attr "mode" "QI")])
9577
9578 (define_insn "*negqi2_cmpz"
9579 [(set (reg:CCZ FLAGS_REG)
9580 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9581 (const_int 0)))
9582 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9583 (neg:QI (match_dup 1)))]
9584 "ix86_unary_operator_ok (NEG, QImode, operands)"
9585 "neg{b}\t%0"
9586 [(set_attr "type" "negnot")
9587 (set_attr "mode" "QI")])
9588
9589 ;; Changing of sign for FP values is doable using integer unit too.
9590
9591 (define_expand "negsf2"
9592 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9593 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9594 "TARGET_80387 || TARGET_SSE_MATH"
9595 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9596
9597 (define_expand "abssf2"
9598 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9599 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9600 "TARGET_80387 || TARGET_SSE_MATH"
9601 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9602
9603 (define_insn "*absnegsf2_mixed"
9604 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9605 (match_operator:SF 3 "absneg_operator"
9606 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9607 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9608 (clobber (reg:CC FLAGS_REG))]
9609 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9610 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9611 "#")
9612
9613 (define_insn "*absnegsf2_sse"
9614 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9615 (match_operator:SF 3 "absneg_operator"
9616 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9617 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9618 (clobber (reg:CC FLAGS_REG))]
9619 "TARGET_SSE_MATH
9620 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9621 "#")
9622
9623 (define_insn "*absnegsf2_i387"
9624 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9625 (match_operator:SF 3 "absneg_operator"
9626 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9627 (use (match_operand 2 "" ""))
9628 (clobber (reg:CC FLAGS_REG))]
9629 "TARGET_80387 && !TARGET_SSE_MATH
9630 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9631 "#")
9632
9633 (define_expand "copysignsf3"
9634 [(match_operand:SF 0 "register_operand" "")
9635 (match_operand:SF 1 "nonmemory_operand" "")
9636 (match_operand:SF 2 "register_operand" "")]
9637 "TARGET_SSE_MATH"
9638 {
9639 ix86_expand_copysign (operands);
9640 DONE;
9641 })
9642
9643 (define_insn_and_split "copysignsf3_const"
9644 [(set (match_operand:SF 0 "register_operand" "=x")
9645 (unspec:SF
9646 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9647 (match_operand:SF 2 "register_operand" "0")
9648 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9649 UNSPEC_COPYSIGN))]
9650 "TARGET_SSE_MATH"
9651 "#"
9652 "&& reload_completed"
9653 [(const_int 0)]
9654 {
9655 ix86_split_copysign_const (operands);
9656 DONE;
9657 })
9658
9659 (define_insn "copysignsf3_var"
9660 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9661 (unspec:SF
9662 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9663 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9664 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9665 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9666 UNSPEC_COPYSIGN))
9667 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9668 "TARGET_SSE_MATH"
9669 "#")
9670
9671 (define_split
9672 [(set (match_operand:SF 0 "register_operand" "")
9673 (unspec:SF
9674 [(match_operand:SF 2 "register_operand" "")
9675 (match_operand:SF 3 "register_operand" "")
9676 (match_operand:V4SF 4 "" "")
9677 (match_operand:V4SF 5 "" "")]
9678 UNSPEC_COPYSIGN))
9679 (clobber (match_scratch:V4SF 1 ""))]
9680 "TARGET_SSE_MATH && reload_completed"
9681 [(const_int 0)]
9682 {
9683 ix86_split_copysign_var (operands);
9684 DONE;
9685 })
9686
9687 (define_expand "negdf2"
9688 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9689 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9690 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9691 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9692
9693 (define_expand "absdf2"
9694 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9695 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9696 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9697 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9698
9699 (define_insn "*absnegdf2_mixed"
9700 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9701 (match_operator:DF 3 "absneg_operator"
9702 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9703 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9704 (clobber (reg:CC FLAGS_REG))]
9705 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9706 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9707 "#")
9708
9709 (define_insn "*absnegdf2_sse"
9710 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9711 (match_operator:DF 3 "absneg_operator"
9712 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9713 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9714 (clobber (reg:CC FLAGS_REG))]
9715 "TARGET_SSE2 && TARGET_SSE_MATH
9716 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9717 "#")
9718
9719 (define_insn "*absnegdf2_i387"
9720 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9721 (match_operator:DF 3 "absneg_operator"
9722 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9723 (use (match_operand 2 "" ""))
9724 (clobber (reg:CC FLAGS_REG))]
9725 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9726 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9727 "#")
9728
9729 (define_expand "copysigndf3"
9730 [(match_operand:DF 0 "register_operand" "")
9731 (match_operand:DF 1 "nonmemory_operand" "")
9732 (match_operand:DF 2 "register_operand" "")]
9733 "TARGET_SSE2 && TARGET_SSE_MATH"
9734 {
9735 ix86_expand_copysign (operands);
9736 DONE;
9737 })
9738
9739 (define_insn_and_split "copysigndf3_const"
9740 [(set (match_operand:DF 0 "register_operand" "=x")
9741 (unspec:DF
9742 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9743 (match_operand:DF 2 "register_operand" "0")
9744 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9745 UNSPEC_COPYSIGN))]
9746 "TARGET_SSE2 && TARGET_SSE_MATH"
9747 "#"
9748 "&& reload_completed"
9749 [(const_int 0)]
9750 {
9751 ix86_split_copysign_const (operands);
9752 DONE;
9753 })
9754
9755 (define_insn "copysigndf3_var"
9756 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9757 (unspec:DF
9758 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9759 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9760 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9761 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9762 UNSPEC_COPYSIGN))
9763 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9764 "TARGET_SSE2 && TARGET_SSE_MATH"
9765 "#")
9766
9767 (define_split
9768 [(set (match_operand:DF 0 "register_operand" "")
9769 (unspec:DF
9770 [(match_operand:DF 2 "register_operand" "")
9771 (match_operand:DF 3 "register_operand" "")
9772 (match_operand:V2DF 4 "" "")
9773 (match_operand:V2DF 5 "" "")]
9774 UNSPEC_COPYSIGN))
9775 (clobber (match_scratch:V2DF 1 ""))]
9776 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9777 [(const_int 0)]
9778 {
9779 ix86_split_copysign_var (operands);
9780 DONE;
9781 })
9782
9783 (define_expand "negxf2"
9784 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9785 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9786 "TARGET_80387"
9787 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9788
9789 (define_expand "absxf2"
9790 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9791 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9792 "TARGET_80387"
9793 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9794
9795 (define_insn "*absnegxf2_i387"
9796 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9797 (match_operator:XF 3 "absneg_operator"
9798 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9799 (use (match_operand 2 "" ""))
9800 (clobber (reg:CC FLAGS_REG))]
9801 "TARGET_80387
9802 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9803 "#")
9804
9805 ;; Splitters for fp abs and neg.
9806
9807 (define_split
9808 [(set (match_operand 0 "fp_register_operand" "")
9809 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9810 (use (match_operand 2 "" ""))
9811 (clobber (reg:CC FLAGS_REG))]
9812 "reload_completed"
9813 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9814
9815 (define_split
9816 [(set (match_operand 0 "register_operand" "")
9817 (match_operator 3 "absneg_operator"
9818 [(match_operand 1 "register_operand" "")]))
9819 (use (match_operand 2 "nonimmediate_operand" ""))
9820 (clobber (reg:CC FLAGS_REG))]
9821 "reload_completed && SSE_REG_P (operands[0])"
9822 [(set (match_dup 0) (match_dup 3))]
9823 {
9824 enum machine_mode mode = GET_MODE (operands[0]);
9825 enum machine_mode vmode = GET_MODE (operands[2]);
9826 rtx tmp;
9827
9828 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9829 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9830 if (operands_match_p (operands[0], operands[2]))
9831 {
9832 tmp = operands[1];
9833 operands[1] = operands[2];
9834 operands[2] = tmp;
9835 }
9836 if (GET_CODE (operands[3]) == ABS)
9837 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9838 else
9839 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9840 operands[3] = tmp;
9841 })
9842
9843 (define_split
9844 [(set (match_operand:SF 0 "register_operand" "")
9845 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9846 (use (match_operand:V4SF 2 "" ""))
9847 (clobber (reg:CC FLAGS_REG))]
9848 "reload_completed"
9849 [(parallel [(set (match_dup 0) (match_dup 1))
9850 (clobber (reg:CC FLAGS_REG))])]
9851 {
9852 rtx tmp;
9853 operands[0] = gen_lowpart (SImode, operands[0]);
9854 if (GET_CODE (operands[1]) == ABS)
9855 {
9856 tmp = gen_int_mode (0x7fffffff, SImode);
9857 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9858 }
9859 else
9860 {
9861 tmp = gen_int_mode (0x80000000, SImode);
9862 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9863 }
9864 operands[1] = tmp;
9865 })
9866
9867 (define_split
9868 [(set (match_operand:DF 0 "register_operand" "")
9869 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9870 (use (match_operand 2 "" ""))
9871 (clobber (reg:CC FLAGS_REG))]
9872 "reload_completed"
9873 [(parallel [(set (match_dup 0) (match_dup 1))
9874 (clobber (reg:CC FLAGS_REG))])]
9875 {
9876 rtx tmp;
9877 if (TARGET_64BIT)
9878 {
9879 tmp = gen_lowpart (DImode, operands[0]);
9880 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9881 operands[0] = tmp;
9882
9883 if (GET_CODE (operands[1]) == ABS)
9884 tmp = const0_rtx;
9885 else
9886 tmp = gen_rtx_NOT (DImode, tmp);
9887 }
9888 else
9889 {
9890 operands[0] = gen_highpart (SImode, operands[0]);
9891 if (GET_CODE (operands[1]) == ABS)
9892 {
9893 tmp = gen_int_mode (0x7fffffff, SImode);
9894 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9895 }
9896 else
9897 {
9898 tmp = gen_int_mode (0x80000000, SImode);
9899 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9900 }
9901 }
9902 operands[1] = tmp;
9903 })
9904
9905 (define_split
9906 [(set (match_operand:XF 0 "register_operand" "")
9907 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9908 (use (match_operand 2 "" ""))
9909 (clobber (reg:CC FLAGS_REG))]
9910 "reload_completed"
9911 [(parallel [(set (match_dup 0) (match_dup 1))
9912 (clobber (reg:CC FLAGS_REG))])]
9913 {
9914 rtx tmp;
9915 operands[0] = gen_rtx_REG (SImode,
9916 true_regnum (operands[0])
9917 + (TARGET_64BIT ? 1 : 2));
9918 if (GET_CODE (operands[1]) == ABS)
9919 {
9920 tmp = GEN_INT (0x7fff);
9921 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9922 }
9923 else
9924 {
9925 tmp = GEN_INT (0x8000);
9926 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9927 }
9928 operands[1] = tmp;
9929 })
9930
9931 (define_split
9932 [(set (match_operand 0 "memory_operand" "")
9933 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9934 (use (match_operand 2 "" ""))
9935 (clobber (reg:CC FLAGS_REG))]
9936 "reload_completed"
9937 [(parallel [(set (match_dup 0) (match_dup 1))
9938 (clobber (reg:CC FLAGS_REG))])]
9939 {
9940 enum machine_mode mode = GET_MODE (operands[0]);
9941 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9942 rtx tmp;
9943
9944 operands[0] = adjust_address (operands[0], QImode, size - 1);
9945 if (GET_CODE (operands[1]) == ABS)
9946 {
9947 tmp = gen_int_mode (0x7f, QImode);
9948 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9949 }
9950 else
9951 {
9952 tmp = gen_int_mode (0x80, QImode);
9953 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9954 }
9955 operands[1] = tmp;
9956 })
9957
9958 ;; Conditionalize these after reload. If they match before reload, we
9959 ;; lose the clobber and ability to use integer instructions.
9960
9961 (define_insn "*negsf2_1"
9962 [(set (match_operand:SF 0 "register_operand" "=f")
9963 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9964 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9965 "fchs"
9966 [(set_attr "type" "fsgn")
9967 (set_attr "mode" "SF")])
9968
9969 (define_insn "*negdf2_1"
9970 [(set (match_operand:DF 0 "register_operand" "=f")
9971 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9972 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9973 "fchs"
9974 [(set_attr "type" "fsgn")
9975 (set_attr "mode" "DF")])
9976
9977 (define_insn "*negxf2_1"
9978 [(set (match_operand:XF 0 "register_operand" "=f")
9979 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9980 "TARGET_80387"
9981 "fchs"
9982 [(set_attr "type" "fsgn")
9983 (set_attr "mode" "XF")])
9984
9985 (define_insn "*abssf2_1"
9986 [(set (match_operand:SF 0 "register_operand" "=f")
9987 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9988 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9989 "fabs"
9990 [(set_attr "type" "fsgn")
9991 (set_attr "mode" "SF")])
9992
9993 (define_insn "*absdf2_1"
9994 [(set (match_operand:DF 0 "register_operand" "=f")
9995 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9996 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9997 "fabs"
9998 [(set_attr "type" "fsgn")
9999 (set_attr "mode" "DF")])
10000
10001 (define_insn "*absxf2_1"
10002 [(set (match_operand:XF 0 "register_operand" "=f")
10003 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10004 "TARGET_80387"
10005 "fabs"
10006 [(set_attr "type" "fsgn")
10007 (set_attr "mode" "DF")])
10008
10009 (define_insn "*negextendsfdf2"
10010 [(set (match_operand:DF 0 "register_operand" "=f")
10011 (neg:DF (float_extend:DF
10012 (match_operand:SF 1 "register_operand" "0"))))]
10013 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10014 "fchs"
10015 [(set_attr "type" "fsgn")
10016 (set_attr "mode" "DF")])
10017
10018 (define_insn "*negextenddfxf2"
10019 [(set (match_operand:XF 0 "register_operand" "=f")
10020 (neg:XF (float_extend:XF
10021 (match_operand:DF 1 "register_operand" "0"))))]
10022 "TARGET_80387"
10023 "fchs"
10024 [(set_attr "type" "fsgn")
10025 (set_attr "mode" "XF")])
10026
10027 (define_insn "*negextendsfxf2"
10028 [(set (match_operand:XF 0 "register_operand" "=f")
10029 (neg:XF (float_extend:XF
10030 (match_operand:SF 1 "register_operand" "0"))))]
10031 "TARGET_80387"
10032 "fchs"
10033 [(set_attr "type" "fsgn")
10034 (set_attr "mode" "XF")])
10035
10036 (define_insn "*absextendsfdf2"
10037 [(set (match_operand:DF 0 "register_operand" "=f")
10038 (abs:DF (float_extend:DF
10039 (match_operand:SF 1 "register_operand" "0"))))]
10040 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10041 "fabs"
10042 [(set_attr "type" "fsgn")
10043 (set_attr "mode" "DF")])
10044
10045 (define_insn "*absextenddfxf2"
10046 [(set (match_operand:XF 0 "register_operand" "=f")
10047 (abs:XF (float_extend:XF
10048 (match_operand:DF 1 "register_operand" "0"))))]
10049 "TARGET_80387"
10050 "fabs"
10051 [(set_attr "type" "fsgn")
10052 (set_attr "mode" "XF")])
10053
10054 (define_insn "*absextendsfxf2"
10055 [(set (match_operand:XF 0 "register_operand" "=f")
10056 (abs:XF (float_extend:XF
10057 (match_operand:SF 1 "register_operand" "0"))))]
10058 "TARGET_80387"
10059 "fabs"
10060 [(set_attr "type" "fsgn")
10061 (set_attr "mode" "XF")])
10062 \f
10063 ;; One complement instructions
10064
10065 (define_expand "one_cmpldi2"
10066 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10067 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10068 "TARGET_64BIT"
10069 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10070
10071 (define_insn "*one_cmpldi2_1_rex64"
10072 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10073 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10074 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10075 "not{q}\t%0"
10076 [(set_attr "type" "negnot")
10077 (set_attr "mode" "DI")])
10078
10079 (define_insn "*one_cmpldi2_2_rex64"
10080 [(set (reg FLAGS_REG)
10081 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10082 (const_int 0)))
10083 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10084 (not:DI (match_dup 1)))]
10085 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10086 && ix86_unary_operator_ok (NOT, DImode, operands)"
10087 "#"
10088 [(set_attr "type" "alu1")
10089 (set_attr "mode" "DI")])
10090
10091 (define_split
10092 [(set (match_operand 0 "flags_reg_operand" "")
10093 (match_operator 2 "compare_operator"
10094 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10095 (const_int 0)]))
10096 (set (match_operand:DI 1 "nonimmediate_operand" "")
10097 (not:DI (match_dup 3)))]
10098 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10099 [(parallel [(set (match_dup 0)
10100 (match_op_dup 2
10101 [(xor:DI (match_dup 3) (const_int -1))
10102 (const_int 0)]))
10103 (set (match_dup 1)
10104 (xor:DI (match_dup 3) (const_int -1)))])]
10105 "")
10106
10107 (define_expand "one_cmplsi2"
10108 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10109 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10110 ""
10111 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10112
10113 (define_insn "*one_cmplsi2_1"
10114 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10115 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10116 "ix86_unary_operator_ok (NOT, SImode, operands)"
10117 "not{l}\t%0"
10118 [(set_attr "type" "negnot")
10119 (set_attr "mode" "SI")])
10120
10121 ;; ??? Currently never generated - xor is used instead.
10122 (define_insn "*one_cmplsi2_1_zext"
10123 [(set (match_operand:DI 0 "register_operand" "=r")
10124 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10125 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10126 "not{l}\t%k0"
10127 [(set_attr "type" "negnot")
10128 (set_attr "mode" "SI")])
10129
10130 (define_insn "*one_cmplsi2_2"
10131 [(set (reg FLAGS_REG)
10132 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10133 (const_int 0)))
10134 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10135 (not:SI (match_dup 1)))]
10136 "ix86_match_ccmode (insn, CCNOmode)
10137 && ix86_unary_operator_ok (NOT, SImode, operands)"
10138 "#"
10139 [(set_attr "type" "alu1")
10140 (set_attr "mode" "SI")])
10141
10142 (define_split
10143 [(set (match_operand 0 "flags_reg_operand" "")
10144 (match_operator 2 "compare_operator"
10145 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10146 (const_int 0)]))
10147 (set (match_operand:SI 1 "nonimmediate_operand" "")
10148 (not:SI (match_dup 3)))]
10149 "ix86_match_ccmode (insn, CCNOmode)"
10150 [(parallel [(set (match_dup 0)
10151 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10152 (const_int 0)]))
10153 (set (match_dup 1)
10154 (xor:SI (match_dup 3) (const_int -1)))])]
10155 "")
10156
10157 ;; ??? Currently never generated - xor is used instead.
10158 (define_insn "*one_cmplsi2_2_zext"
10159 [(set (reg FLAGS_REG)
10160 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10161 (const_int 0)))
10162 (set (match_operand:DI 0 "register_operand" "=r")
10163 (zero_extend:DI (not:SI (match_dup 1))))]
10164 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10165 && ix86_unary_operator_ok (NOT, SImode, operands)"
10166 "#"
10167 [(set_attr "type" "alu1")
10168 (set_attr "mode" "SI")])
10169
10170 (define_split
10171 [(set (match_operand 0 "flags_reg_operand" "")
10172 (match_operator 2 "compare_operator"
10173 [(not:SI (match_operand:SI 3 "register_operand" ""))
10174 (const_int 0)]))
10175 (set (match_operand:DI 1 "register_operand" "")
10176 (zero_extend:DI (not:SI (match_dup 3))))]
10177 "ix86_match_ccmode (insn, CCNOmode)"
10178 [(parallel [(set (match_dup 0)
10179 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10180 (const_int 0)]))
10181 (set (match_dup 1)
10182 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10183 "")
10184
10185 (define_expand "one_cmplhi2"
10186 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10187 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10188 "TARGET_HIMODE_MATH"
10189 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10190
10191 (define_insn "*one_cmplhi2_1"
10192 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10193 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10194 "ix86_unary_operator_ok (NOT, HImode, operands)"
10195 "not{w}\t%0"
10196 [(set_attr "type" "negnot")
10197 (set_attr "mode" "HI")])
10198
10199 (define_insn "*one_cmplhi2_2"
10200 [(set (reg FLAGS_REG)
10201 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10202 (const_int 0)))
10203 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10204 (not:HI (match_dup 1)))]
10205 "ix86_match_ccmode (insn, CCNOmode)
10206 && ix86_unary_operator_ok (NEG, HImode, operands)"
10207 "#"
10208 [(set_attr "type" "alu1")
10209 (set_attr "mode" "HI")])
10210
10211 (define_split
10212 [(set (match_operand 0 "flags_reg_operand" "")
10213 (match_operator 2 "compare_operator"
10214 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10215 (const_int 0)]))
10216 (set (match_operand:HI 1 "nonimmediate_operand" "")
10217 (not:HI (match_dup 3)))]
10218 "ix86_match_ccmode (insn, CCNOmode)"
10219 [(parallel [(set (match_dup 0)
10220 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10221 (const_int 0)]))
10222 (set (match_dup 1)
10223 (xor:HI (match_dup 3) (const_int -1)))])]
10224 "")
10225
10226 ;; %%% Potential partial reg stall on alternative 1. What to do?
10227 (define_expand "one_cmplqi2"
10228 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10229 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10230 "TARGET_QIMODE_MATH"
10231 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10232
10233 (define_insn "*one_cmplqi2_1"
10234 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10235 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10236 "ix86_unary_operator_ok (NOT, QImode, operands)"
10237 "@
10238 not{b}\t%0
10239 not{l}\t%k0"
10240 [(set_attr "type" "negnot")
10241 (set_attr "mode" "QI,SI")])
10242
10243 (define_insn "*one_cmplqi2_2"
10244 [(set (reg FLAGS_REG)
10245 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10246 (const_int 0)))
10247 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10248 (not:QI (match_dup 1)))]
10249 "ix86_match_ccmode (insn, CCNOmode)
10250 && ix86_unary_operator_ok (NOT, QImode, operands)"
10251 "#"
10252 [(set_attr "type" "alu1")
10253 (set_attr "mode" "QI")])
10254
10255 (define_split
10256 [(set (match_operand 0 "flags_reg_operand" "")
10257 (match_operator 2 "compare_operator"
10258 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10259 (const_int 0)]))
10260 (set (match_operand:QI 1 "nonimmediate_operand" "")
10261 (not:QI (match_dup 3)))]
10262 "ix86_match_ccmode (insn, CCNOmode)"
10263 [(parallel [(set (match_dup 0)
10264 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10265 (const_int 0)]))
10266 (set (match_dup 1)
10267 (xor:QI (match_dup 3) (const_int -1)))])]
10268 "")
10269 \f
10270 ;; Arithmetic shift instructions
10271
10272 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10273 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10274 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10275 ;; from the assembler input.
10276 ;;
10277 ;; This instruction shifts the target reg/mem as usual, but instead of
10278 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10279 ;; is a left shift double, bits are taken from the high order bits of
10280 ;; reg, else if the insn is a shift right double, bits are taken from the
10281 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10282 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10283 ;;
10284 ;; Since sh[lr]d does not change the `reg' operand, that is done
10285 ;; separately, making all shifts emit pairs of shift double and normal
10286 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10287 ;; support a 63 bit shift, each shift where the count is in a reg expands
10288 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10289 ;;
10290 ;; If the shift count is a constant, we need never emit more than one
10291 ;; shift pair, instead using moves and sign extension for counts greater
10292 ;; than 31.
10293
10294 (define_expand "ashlti3"
10295 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10296 (ashift:TI (match_operand:TI 1 "register_operand" "")
10297 (match_operand:QI 2 "nonmemory_operand" "")))
10298 (clobber (reg:CC FLAGS_REG))])]
10299 "TARGET_64BIT"
10300 {
10301 if (! immediate_operand (operands[2], QImode))
10302 {
10303 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10304 DONE;
10305 }
10306 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10307 DONE;
10308 })
10309
10310 (define_insn "ashlti3_1"
10311 [(set (match_operand:TI 0 "register_operand" "=r")
10312 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10313 (match_operand:QI 2 "register_operand" "c")))
10314 (clobber (match_scratch:DI 3 "=&r"))
10315 (clobber (reg:CC FLAGS_REG))]
10316 "TARGET_64BIT"
10317 "#"
10318 [(set_attr "type" "multi")])
10319
10320 (define_insn "*ashlti3_2"
10321 [(set (match_operand:TI 0 "register_operand" "=r")
10322 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10323 (match_operand:QI 2 "immediate_operand" "O")))
10324 (clobber (reg:CC FLAGS_REG))]
10325 "TARGET_64BIT"
10326 "#"
10327 [(set_attr "type" "multi")])
10328
10329 (define_split
10330 [(set (match_operand:TI 0 "register_operand" "")
10331 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10332 (match_operand:QI 2 "register_operand" "")))
10333 (clobber (match_scratch:DI 3 ""))
10334 (clobber (reg:CC FLAGS_REG))]
10335 "TARGET_64BIT && reload_completed"
10336 [(const_int 0)]
10337 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10338
10339 (define_split
10340 [(set (match_operand:TI 0 "register_operand" "")
10341 (ashift:TI (match_operand:TI 1 "register_operand" "")
10342 (match_operand:QI 2 "immediate_operand" "")))
10343 (clobber (reg:CC FLAGS_REG))]
10344 "TARGET_64BIT && reload_completed"
10345 [(const_int 0)]
10346 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10347
10348 (define_insn "x86_64_shld"
10349 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10350 (ior:DI (ashift:DI (match_dup 0)
10351 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10352 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10353 (minus:QI (const_int 64) (match_dup 2)))))
10354 (clobber (reg:CC FLAGS_REG))]
10355 "TARGET_64BIT"
10356 "@
10357 shld{q}\t{%2, %1, %0|%0, %1, %2}
10358 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10359 [(set_attr "type" "ishift")
10360 (set_attr "prefix_0f" "1")
10361 (set_attr "mode" "DI")
10362 (set_attr "athlon_decode" "vector")])
10363
10364 (define_expand "x86_64_shift_adj"
10365 [(set (reg:CCZ FLAGS_REG)
10366 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10367 (const_int 64))
10368 (const_int 0)))
10369 (set (match_operand:DI 0 "register_operand" "")
10370 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10371 (match_operand:DI 1 "register_operand" "")
10372 (match_dup 0)))
10373 (set (match_dup 1)
10374 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10375 (match_operand:DI 3 "register_operand" "r")
10376 (match_dup 1)))]
10377 "TARGET_64BIT"
10378 "")
10379
10380 (define_expand "ashldi3"
10381 [(set (match_operand:DI 0 "shiftdi_operand" "")
10382 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10383 (match_operand:QI 2 "nonmemory_operand" "")))]
10384 ""
10385 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10386
10387 (define_insn "*ashldi3_1_rex64"
10388 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10389 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10390 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10391 (clobber (reg:CC FLAGS_REG))]
10392 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10393 {
10394 switch (get_attr_type (insn))
10395 {
10396 case TYPE_ALU:
10397 gcc_assert (operands[2] == const1_rtx);
10398 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10399 return "add{q}\t{%0, %0|%0, %0}";
10400
10401 case TYPE_LEA:
10402 gcc_assert (CONST_INT_P (operands[2]));
10403 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10404 operands[1] = gen_rtx_MULT (DImode, operands[1],
10405 GEN_INT (1 << INTVAL (operands[2])));
10406 return "lea{q}\t{%a1, %0|%0, %a1}";
10407
10408 default:
10409 if (REG_P (operands[2]))
10410 return "sal{q}\t{%b2, %0|%0, %b2}";
10411 else if (operands[2] == const1_rtx
10412 && (TARGET_SHIFT1 || optimize_size))
10413 return "sal{q}\t%0";
10414 else
10415 return "sal{q}\t{%2, %0|%0, %2}";
10416 }
10417 }
10418 [(set (attr "type")
10419 (cond [(eq_attr "alternative" "1")
10420 (const_string "lea")
10421 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10422 (const_int 0))
10423 (match_operand 0 "register_operand" ""))
10424 (match_operand 2 "const1_operand" ""))
10425 (const_string "alu")
10426 ]
10427 (const_string "ishift")))
10428 (set_attr "mode" "DI")])
10429
10430 ;; Convert lea to the lea pattern to avoid flags dependency.
10431 (define_split
10432 [(set (match_operand:DI 0 "register_operand" "")
10433 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10434 (match_operand:QI 2 "immediate_operand" "")))
10435 (clobber (reg:CC FLAGS_REG))]
10436 "TARGET_64BIT && reload_completed
10437 && true_regnum (operands[0]) != true_regnum (operands[1])"
10438 [(set (match_dup 0)
10439 (mult:DI (match_dup 1)
10440 (match_dup 2)))]
10441 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10442
10443 ;; This pattern can't accept a variable shift count, since shifts by
10444 ;; zero don't affect the flags. We assume that shifts by constant
10445 ;; zero are optimized away.
10446 (define_insn "*ashldi3_cmp_rex64"
10447 [(set (reg FLAGS_REG)
10448 (compare
10449 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10450 (match_operand:QI 2 "immediate_operand" "e"))
10451 (const_int 0)))
10452 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10453 (ashift:DI (match_dup 1) (match_dup 2)))]
10454 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10455 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10456 && (optimize_size
10457 || !TARGET_PARTIAL_FLAG_REG_STALL
10458 || (operands[2] == const1_rtx
10459 && (TARGET_SHIFT1
10460 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10461 {
10462 switch (get_attr_type (insn))
10463 {
10464 case TYPE_ALU:
10465 gcc_assert (operands[2] == const1_rtx);
10466 return "add{q}\t{%0, %0|%0, %0}";
10467
10468 default:
10469 if (REG_P (operands[2]))
10470 return "sal{q}\t{%b2, %0|%0, %b2}";
10471 else if (operands[2] == const1_rtx
10472 && (TARGET_SHIFT1 || optimize_size))
10473 return "sal{q}\t%0";
10474 else
10475 return "sal{q}\t{%2, %0|%0, %2}";
10476 }
10477 }
10478 [(set (attr "type")
10479 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10480 (const_int 0))
10481 (match_operand 0 "register_operand" ""))
10482 (match_operand 2 "const1_operand" ""))
10483 (const_string "alu")
10484 ]
10485 (const_string "ishift")))
10486 (set_attr "mode" "DI")])
10487
10488 (define_insn "*ashldi3_cconly_rex64"
10489 [(set (reg FLAGS_REG)
10490 (compare
10491 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10492 (match_operand:QI 2 "immediate_operand" "e"))
10493 (const_int 0)))
10494 (clobber (match_scratch:DI 0 "=r"))]
10495 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10496 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10497 && (optimize_size
10498 || !TARGET_PARTIAL_FLAG_REG_STALL
10499 || (operands[2] == const1_rtx
10500 && (TARGET_SHIFT1
10501 || TARGET_DOUBLE_WITH_ADD)))"
10502 {
10503 switch (get_attr_type (insn))
10504 {
10505 case TYPE_ALU:
10506 gcc_assert (operands[2] == const1_rtx);
10507 return "add{q}\t{%0, %0|%0, %0}";
10508
10509 default:
10510 if (REG_P (operands[2]))
10511 return "sal{q}\t{%b2, %0|%0, %b2}";
10512 else if (operands[2] == const1_rtx
10513 && (TARGET_SHIFT1 || optimize_size))
10514 return "sal{q}\t%0";
10515 else
10516 return "sal{q}\t{%2, %0|%0, %2}";
10517 }
10518 }
10519 [(set (attr "type")
10520 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10521 (const_int 0))
10522 (match_operand 0 "register_operand" ""))
10523 (match_operand 2 "const1_operand" ""))
10524 (const_string "alu")
10525 ]
10526 (const_string "ishift")))
10527 (set_attr "mode" "DI")])
10528
10529 (define_insn "*ashldi3_1"
10530 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10531 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10532 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10533 (clobber (reg:CC FLAGS_REG))]
10534 "!TARGET_64BIT"
10535 "#"
10536 [(set_attr "type" "multi")])
10537
10538 ;; By default we don't ask for a scratch register, because when DImode
10539 ;; values are manipulated, registers are already at a premium. But if
10540 ;; we have one handy, we won't turn it away.
10541 (define_peephole2
10542 [(match_scratch:SI 3 "r")
10543 (parallel [(set (match_operand:DI 0 "register_operand" "")
10544 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10545 (match_operand:QI 2 "nonmemory_operand" "")))
10546 (clobber (reg:CC FLAGS_REG))])
10547 (match_dup 3)]
10548 "!TARGET_64BIT && TARGET_CMOVE"
10549 [(const_int 0)]
10550 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10551
10552 (define_split
10553 [(set (match_operand:DI 0 "register_operand" "")
10554 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10555 (match_operand:QI 2 "nonmemory_operand" "")))
10556 (clobber (reg:CC FLAGS_REG))]
10557 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10558 ? flow2_completed : reload_completed)"
10559 [(const_int 0)]
10560 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10561
10562 (define_insn "x86_shld_1"
10563 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10564 (ior:SI (ashift:SI (match_dup 0)
10565 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10566 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10567 (minus:QI (const_int 32) (match_dup 2)))))
10568 (clobber (reg:CC FLAGS_REG))]
10569 ""
10570 "@
10571 shld{l}\t{%2, %1, %0|%0, %1, %2}
10572 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10573 [(set_attr "type" "ishift")
10574 (set_attr "prefix_0f" "1")
10575 (set_attr "mode" "SI")
10576 (set_attr "pent_pair" "np")
10577 (set_attr "athlon_decode" "vector")])
10578
10579 (define_expand "x86_shift_adj_1"
10580 [(set (reg:CCZ FLAGS_REG)
10581 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10582 (const_int 32))
10583 (const_int 0)))
10584 (set (match_operand:SI 0 "register_operand" "")
10585 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10586 (match_operand:SI 1 "register_operand" "")
10587 (match_dup 0)))
10588 (set (match_dup 1)
10589 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10590 (match_operand:SI 3 "register_operand" "r")
10591 (match_dup 1)))]
10592 "TARGET_CMOVE"
10593 "")
10594
10595 (define_expand "x86_shift_adj_2"
10596 [(use (match_operand:SI 0 "register_operand" ""))
10597 (use (match_operand:SI 1 "register_operand" ""))
10598 (use (match_operand:QI 2 "register_operand" ""))]
10599 ""
10600 {
10601 rtx label = gen_label_rtx ();
10602 rtx tmp;
10603
10604 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10605
10606 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10607 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10608 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10609 gen_rtx_LABEL_REF (VOIDmode, label),
10610 pc_rtx);
10611 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10612 JUMP_LABEL (tmp) = label;
10613
10614 emit_move_insn (operands[0], operands[1]);
10615 ix86_expand_clear (operands[1]);
10616
10617 emit_label (label);
10618 LABEL_NUSES (label) = 1;
10619
10620 DONE;
10621 })
10622
10623 (define_expand "ashlsi3"
10624 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10625 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10626 (match_operand:QI 2 "nonmemory_operand" "")))
10627 (clobber (reg:CC FLAGS_REG))]
10628 ""
10629 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10630
10631 (define_insn "*ashlsi3_1"
10632 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10633 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10634 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10635 (clobber (reg:CC FLAGS_REG))]
10636 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10637 {
10638 switch (get_attr_type (insn))
10639 {
10640 case TYPE_ALU:
10641 gcc_assert (operands[2] == const1_rtx);
10642 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10643 return "add{l}\t{%0, %0|%0, %0}";
10644
10645 case TYPE_LEA:
10646 return "#";
10647
10648 default:
10649 if (REG_P (operands[2]))
10650 return "sal{l}\t{%b2, %0|%0, %b2}";
10651 else if (operands[2] == const1_rtx
10652 && (TARGET_SHIFT1 || optimize_size))
10653 return "sal{l}\t%0";
10654 else
10655 return "sal{l}\t{%2, %0|%0, %2}";
10656 }
10657 }
10658 [(set (attr "type")
10659 (cond [(eq_attr "alternative" "1")
10660 (const_string "lea")
10661 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10662 (const_int 0))
10663 (match_operand 0 "register_operand" ""))
10664 (match_operand 2 "const1_operand" ""))
10665 (const_string "alu")
10666 ]
10667 (const_string "ishift")))
10668 (set_attr "mode" "SI")])
10669
10670 ;; Convert lea to the lea pattern to avoid flags dependency.
10671 (define_split
10672 [(set (match_operand 0 "register_operand" "")
10673 (ashift (match_operand 1 "index_register_operand" "")
10674 (match_operand:QI 2 "const_int_operand" "")))
10675 (clobber (reg:CC FLAGS_REG))]
10676 "reload_completed
10677 && true_regnum (operands[0]) != true_regnum (operands[1])
10678 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10679 [(const_int 0)]
10680 {
10681 rtx pat;
10682 enum machine_mode mode = GET_MODE (operands[0]);
10683
10684 if (GET_MODE_SIZE (mode) < 4)
10685 operands[0] = gen_lowpart (SImode, operands[0]);
10686 if (mode != Pmode)
10687 operands[1] = gen_lowpart (Pmode, operands[1]);
10688 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10689
10690 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10691 if (Pmode != SImode)
10692 pat = gen_rtx_SUBREG (SImode, pat, 0);
10693 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10694 DONE;
10695 })
10696
10697 ;; Rare case of shifting RSP is handled by generating move and shift
10698 (define_split
10699 [(set (match_operand 0 "register_operand" "")
10700 (ashift (match_operand 1 "register_operand" "")
10701 (match_operand:QI 2 "const_int_operand" "")))
10702 (clobber (reg:CC FLAGS_REG))]
10703 "reload_completed
10704 && true_regnum (operands[0]) != true_regnum (operands[1])"
10705 [(const_int 0)]
10706 {
10707 rtx pat, clob;
10708 emit_move_insn (operands[0], operands[1]);
10709 pat = gen_rtx_SET (VOIDmode, operands[0],
10710 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10711 operands[0], operands[2]));
10712 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10713 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10714 DONE;
10715 })
10716
10717 (define_insn "*ashlsi3_1_zext"
10718 [(set (match_operand:DI 0 "register_operand" "=r,r")
10719 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10720 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10721 (clobber (reg:CC FLAGS_REG))]
10722 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10723 {
10724 switch (get_attr_type (insn))
10725 {
10726 case TYPE_ALU:
10727 gcc_assert (operands[2] == const1_rtx);
10728 return "add{l}\t{%k0, %k0|%k0, %k0}";
10729
10730 case TYPE_LEA:
10731 return "#";
10732
10733 default:
10734 if (REG_P (operands[2]))
10735 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10736 else if (operands[2] == const1_rtx
10737 && (TARGET_SHIFT1 || optimize_size))
10738 return "sal{l}\t%k0";
10739 else
10740 return "sal{l}\t{%2, %k0|%k0, %2}";
10741 }
10742 }
10743 [(set (attr "type")
10744 (cond [(eq_attr "alternative" "1")
10745 (const_string "lea")
10746 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10747 (const_int 0))
10748 (match_operand 2 "const1_operand" ""))
10749 (const_string "alu")
10750 ]
10751 (const_string "ishift")))
10752 (set_attr "mode" "SI")])
10753
10754 ;; Convert lea to the lea pattern to avoid flags dependency.
10755 (define_split
10756 [(set (match_operand:DI 0 "register_operand" "")
10757 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10758 (match_operand:QI 2 "const_int_operand" ""))))
10759 (clobber (reg:CC FLAGS_REG))]
10760 "TARGET_64BIT && reload_completed
10761 && true_regnum (operands[0]) != true_regnum (operands[1])"
10762 [(set (match_dup 0) (zero_extend:DI
10763 (subreg:SI (mult:SI (match_dup 1)
10764 (match_dup 2)) 0)))]
10765 {
10766 operands[1] = gen_lowpart (Pmode, operands[1]);
10767 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10768 })
10769
10770 ;; This pattern can't accept a variable shift count, since shifts by
10771 ;; zero don't affect the flags. We assume that shifts by constant
10772 ;; zero are optimized away.
10773 (define_insn "*ashlsi3_cmp"
10774 [(set (reg FLAGS_REG)
10775 (compare
10776 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10777 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10778 (const_int 0)))
10779 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10780 (ashift:SI (match_dup 1) (match_dup 2)))]
10781 "ix86_match_ccmode (insn, CCGOCmode)
10782 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10783 && (optimize_size
10784 || !TARGET_PARTIAL_FLAG_REG_STALL
10785 || (operands[2] == const1_rtx
10786 && (TARGET_SHIFT1
10787 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10788 {
10789 switch (get_attr_type (insn))
10790 {
10791 case TYPE_ALU:
10792 gcc_assert (operands[2] == const1_rtx);
10793 return "add{l}\t{%0, %0|%0, %0}";
10794
10795 default:
10796 if (REG_P (operands[2]))
10797 return "sal{l}\t{%b2, %0|%0, %b2}";
10798 else if (operands[2] == const1_rtx
10799 && (TARGET_SHIFT1 || optimize_size))
10800 return "sal{l}\t%0";
10801 else
10802 return "sal{l}\t{%2, %0|%0, %2}";
10803 }
10804 }
10805 [(set (attr "type")
10806 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10807 (const_int 0))
10808 (match_operand 0 "register_operand" ""))
10809 (match_operand 2 "const1_operand" ""))
10810 (const_string "alu")
10811 ]
10812 (const_string "ishift")))
10813 (set_attr "mode" "SI")])
10814
10815 (define_insn "*ashlsi3_cconly"
10816 [(set (reg FLAGS_REG)
10817 (compare
10818 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10819 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10820 (const_int 0)))
10821 (clobber (match_scratch:SI 0 "=r"))]
10822 "ix86_match_ccmode (insn, CCGOCmode)
10823 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10824 && (optimize_size
10825 || !TARGET_PARTIAL_FLAG_REG_STALL
10826 || (operands[2] == const1_rtx
10827 && (TARGET_SHIFT1
10828 || TARGET_DOUBLE_WITH_ADD)))"
10829 {
10830 switch (get_attr_type (insn))
10831 {
10832 case TYPE_ALU:
10833 gcc_assert (operands[2] == const1_rtx);
10834 return "add{l}\t{%0, %0|%0, %0}";
10835
10836 default:
10837 if (REG_P (operands[2]))
10838 return "sal{l}\t{%b2, %0|%0, %b2}";
10839 else if (operands[2] == const1_rtx
10840 && (TARGET_SHIFT1 || optimize_size))
10841 return "sal{l}\t%0";
10842 else
10843 return "sal{l}\t{%2, %0|%0, %2}";
10844 }
10845 }
10846 [(set (attr "type")
10847 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10848 (const_int 0))
10849 (match_operand 0 "register_operand" ""))
10850 (match_operand 2 "const1_operand" ""))
10851 (const_string "alu")
10852 ]
10853 (const_string "ishift")))
10854 (set_attr "mode" "SI")])
10855
10856 (define_insn "*ashlsi3_cmp_zext"
10857 [(set (reg FLAGS_REG)
10858 (compare
10859 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10860 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10861 (const_int 0)))
10862 (set (match_operand:DI 0 "register_operand" "=r")
10863 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10864 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10865 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10866 && (optimize_size
10867 || !TARGET_PARTIAL_FLAG_REG_STALL
10868 || (operands[2] == const1_rtx
10869 && (TARGET_SHIFT1
10870 || TARGET_DOUBLE_WITH_ADD)))"
10871 {
10872 switch (get_attr_type (insn))
10873 {
10874 case TYPE_ALU:
10875 gcc_assert (operands[2] == const1_rtx);
10876 return "add{l}\t{%k0, %k0|%k0, %k0}";
10877
10878 default:
10879 if (REG_P (operands[2]))
10880 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10881 else if (operands[2] == const1_rtx
10882 && (TARGET_SHIFT1 || optimize_size))
10883 return "sal{l}\t%k0";
10884 else
10885 return "sal{l}\t{%2, %k0|%k0, %2}";
10886 }
10887 }
10888 [(set (attr "type")
10889 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10890 (const_int 0))
10891 (match_operand 2 "const1_operand" ""))
10892 (const_string "alu")
10893 ]
10894 (const_string "ishift")))
10895 (set_attr "mode" "SI")])
10896
10897 (define_expand "ashlhi3"
10898 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10899 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10900 (match_operand:QI 2 "nonmemory_operand" "")))
10901 (clobber (reg:CC FLAGS_REG))]
10902 "TARGET_HIMODE_MATH"
10903 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10904
10905 (define_insn "*ashlhi3_1_lea"
10906 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10907 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10908 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10909 (clobber (reg:CC FLAGS_REG))]
10910 "!TARGET_PARTIAL_REG_STALL
10911 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10912 {
10913 switch (get_attr_type (insn))
10914 {
10915 case TYPE_LEA:
10916 return "#";
10917 case TYPE_ALU:
10918 gcc_assert (operands[2] == const1_rtx);
10919 return "add{w}\t{%0, %0|%0, %0}";
10920
10921 default:
10922 if (REG_P (operands[2]))
10923 return "sal{w}\t{%b2, %0|%0, %b2}";
10924 else if (operands[2] == const1_rtx
10925 && (TARGET_SHIFT1 || optimize_size))
10926 return "sal{w}\t%0";
10927 else
10928 return "sal{w}\t{%2, %0|%0, %2}";
10929 }
10930 }
10931 [(set (attr "type")
10932 (cond [(eq_attr "alternative" "1")
10933 (const_string "lea")
10934 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10935 (const_int 0))
10936 (match_operand 0 "register_operand" ""))
10937 (match_operand 2 "const1_operand" ""))
10938 (const_string "alu")
10939 ]
10940 (const_string "ishift")))
10941 (set_attr "mode" "HI,SI")])
10942
10943 (define_insn "*ashlhi3_1"
10944 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10945 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10946 (match_operand:QI 2 "nonmemory_operand" "cI")))
10947 (clobber (reg:CC FLAGS_REG))]
10948 "TARGET_PARTIAL_REG_STALL
10949 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10950 {
10951 switch (get_attr_type (insn))
10952 {
10953 case TYPE_ALU:
10954 gcc_assert (operands[2] == const1_rtx);
10955 return "add{w}\t{%0, %0|%0, %0}";
10956
10957 default:
10958 if (REG_P (operands[2]))
10959 return "sal{w}\t{%b2, %0|%0, %b2}";
10960 else if (operands[2] == const1_rtx
10961 && (TARGET_SHIFT1 || optimize_size))
10962 return "sal{w}\t%0";
10963 else
10964 return "sal{w}\t{%2, %0|%0, %2}";
10965 }
10966 }
10967 [(set (attr "type")
10968 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10969 (const_int 0))
10970 (match_operand 0 "register_operand" ""))
10971 (match_operand 2 "const1_operand" ""))
10972 (const_string "alu")
10973 ]
10974 (const_string "ishift")))
10975 (set_attr "mode" "HI")])
10976
10977 ;; This pattern can't accept a variable shift count, since shifts by
10978 ;; zero don't affect the flags. We assume that shifts by constant
10979 ;; zero are optimized away.
10980 (define_insn "*ashlhi3_cmp"
10981 [(set (reg FLAGS_REG)
10982 (compare
10983 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10984 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10985 (const_int 0)))
10986 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10987 (ashift:HI (match_dup 1) (match_dup 2)))]
10988 "ix86_match_ccmode (insn, CCGOCmode)
10989 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10990 && (optimize_size
10991 || !TARGET_PARTIAL_FLAG_REG_STALL
10992 || (operands[2] == const1_rtx
10993 && (TARGET_SHIFT1
10994 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10995 {
10996 switch (get_attr_type (insn))
10997 {
10998 case TYPE_ALU:
10999 gcc_assert (operands[2] == const1_rtx);
11000 return "add{w}\t{%0, %0|%0, %0}";
11001
11002 default:
11003 if (REG_P (operands[2]))
11004 return "sal{w}\t{%b2, %0|%0, %b2}";
11005 else if (operands[2] == const1_rtx
11006 && (TARGET_SHIFT1 || optimize_size))
11007 return "sal{w}\t%0";
11008 else
11009 return "sal{w}\t{%2, %0|%0, %2}";
11010 }
11011 }
11012 [(set (attr "type")
11013 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014 (const_int 0))
11015 (match_operand 0 "register_operand" ""))
11016 (match_operand 2 "const1_operand" ""))
11017 (const_string "alu")
11018 ]
11019 (const_string "ishift")))
11020 (set_attr "mode" "HI")])
11021
11022 (define_insn "*ashlhi3_cconly"
11023 [(set (reg FLAGS_REG)
11024 (compare
11025 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11026 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11027 (const_int 0)))
11028 (clobber (match_scratch:HI 0 "=r"))]
11029 "ix86_match_ccmode (insn, CCGOCmode)
11030 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11031 && (optimize_size
11032 || !TARGET_PARTIAL_FLAG_REG_STALL
11033 || (operands[2] == const1_rtx
11034 && (TARGET_SHIFT1
11035 || TARGET_DOUBLE_WITH_ADD)))"
11036 {
11037 switch (get_attr_type (insn))
11038 {
11039 case TYPE_ALU:
11040 gcc_assert (operands[2] == const1_rtx);
11041 return "add{w}\t{%0, %0|%0, %0}";
11042
11043 default:
11044 if (REG_P (operands[2]))
11045 return "sal{w}\t{%b2, %0|%0, %b2}";
11046 else if (operands[2] == const1_rtx
11047 && (TARGET_SHIFT1 || optimize_size))
11048 return "sal{w}\t%0";
11049 else
11050 return "sal{w}\t{%2, %0|%0, %2}";
11051 }
11052 }
11053 [(set (attr "type")
11054 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11055 (const_int 0))
11056 (match_operand 0 "register_operand" ""))
11057 (match_operand 2 "const1_operand" ""))
11058 (const_string "alu")
11059 ]
11060 (const_string "ishift")))
11061 (set_attr "mode" "HI")])
11062
11063 (define_expand "ashlqi3"
11064 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11065 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11066 (match_operand:QI 2 "nonmemory_operand" "")))
11067 (clobber (reg:CC FLAGS_REG))]
11068 "TARGET_QIMODE_MATH"
11069 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11070
11071 ;; %%% Potential partial reg stall on alternative 2. What to do?
11072
11073 (define_insn "*ashlqi3_1_lea"
11074 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11075 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11076 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11077 (clobber (reg:CC FLAGS_REG))]
11078 "!TARGET_PARTIAL_REG_STALL
11079 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11080 {
11081 switch (get_attr_type (insn))
11082 {
11083 case TYPE_LEA:
11084 return "#";
11085 case TYPE_ALU:
11086 gcc_assert (operands[2] == const1_rtx);
11087 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11088 return "add{l}\t{%k0, %k0|%k0, %k0}";
11089 else
11090 return "add{b}\t{%0, %0|%0, %0}";
11091
11092 default:
11093 if (REG_P (operands[2]))
11094 {
11095 if (get_attr_mode (insn) == MODE_SI)
11096 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11097 else
11098 return "sal{b}\t{%b2, %0|%0, %b2}";
11099 }
11100 else if (operands[2] == const1_rtx
11101 && (TARGET_SHIFT1 || optimize_size))
11102 {
11103 if (get_attr_mode (insn) == MODE_SI)
11104 return "sal{l}\t%0";
11105 else
11106 return "sal{b}\t%0";
11107 }
11108 else
11109 {
11110 if (get_attr_mode (insn) == MODE_SI)
11111 return "sal{l}\t{%2, %k0|%k0, %2}";
11112 else
11113 return "sal{b}\t{%2, %0|%0, %2}";
11114 }
11115 }
11116 }
11117 [(set (attr "type")
11118 (cond [(eq_attr "alternative" "2")
11119 (const_string "lea")
11120 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11121 (const_int 0))
11122 (match_operand 0 "register_operand" ""))
11123 (match_operand 2 "const1_operand" ""))
11124 (const_string "alu")
11125 ]
11126 (const_string "ishift")))
11127 (set_attr "mode" "QI,SI,SI")])
11128
11129 (define_insn "*ashlqi3_1"
11130 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11131 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11132 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11133 (clobber (reg:CC FLAGS_REG))]
11134 "TARGET_PARTIAL_REG_STALL
11135 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11136 {
11137 switch (get_attr_type (insn))
11138 {
11139 case TYPE_ALU:
11140 gcc_assert (operands[2] == const1_rtx);
11141 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11142 return "add{l}\t{%k0, %k0|%k0, %k0}";
11143 else
11144 return "add{b}\t{%0, %0|%0, %0}";
11145
11146 default:
11147 if (REG_P (operands[2]))
11148 {
11149 if (get_attr_mode (insn) == MODE_SI)
11150 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11151 else
11152 return "sal{b}\t{%b2, %0|%0, %b2}";
11153 }
11154 else if (operands[2] == const1_rtx
11155 && (TARGET_SHIFT1 || optimize_size))
11156 {
11157 if (get_attr_mode (insn) == MODE_SI)
11158 return "sal{l}\t%0";
11159 else
11160 return "sal{b}\t%0";
11161 }
11162 else
11163 {
11164 if (get_attr_mode (insn) == MODE_SI)
11165 return "sal{l}\t{%2, %k0|%k0, %2}";
11166 else
11167 return "sal{b}\t{%2, %0|%0, %2}";
11168 }
11169 }
11170 }
11171 [(set (attr "type")
11172 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11173 (const_int 0))
11174 (match_operand 0 "register_operand" ""))
11175 (match_operand 2 "const1_operand" ""))
11176 (const_string "alu")
11177 ]
11178 (const_string "ishift")))
11179 (set_attr "mode" "QI,SI")])
11180
11181 ;; This pattern can't accept a variable shift count, since shifts by
11182 ;; zero don't affect the flags. We assume that shifts by constant
11183 ;; zero are optimized away.
11184 (define_insn "*ashlqi3_cmp"
11185 [(set (reg FLAGS_REG)
11186 (compare
11187 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11188 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11189 (const_int 0)))
11190 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11191 (ashift:QI (match_dup 1) (match_dup 2)))]
11192 "ix86_match_ccmode (insn, CCGOCmode)
11193 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11194 && (optimize_size
11195 || !TARGET_PARTIAL_FLAG_REG_STALL
11196 || (operands[2] == const1_rtx
11197 && (TARGET_SHIFT1
11198 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11199 {
11200 switch (get_attr_type (insn))
11201 {
11202 case TYPE_ALU:
11203 gcc_assert (operands[2] == const1_rtx);
11204 return "add{b}\t{%0, %0|%0, %0}";
11205
11206 default:
11207 if (REG_P (operands[2]))
11208 return "sal{b}\t{%b2, %0|%0, %b2}";
11209 else if (operands[2] == const1_rtx
11210 && (TARGET_SHIFT1 || optimize_size))
11211 return "sal{b}\t%0";
11212 else
11213 return "sal{b}\t{%2, %0|%0, %2}";
11214 }
11215 }
11216 [(set (attr "type")
11217 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11218 (const_int 0))
11219 (match_operand 0 "register_operand" ""))
11220 (match_operand 2 "const1_operand" ""))
11221 (const_string "alu")
11222 ]
11223 (const_string "ishift")))
11224 (set_attr "mode" "QI")])
11225
11226 (define_insn "*ashlqi3_cconly"
11227 [(set (reg FLAGS_REG)
11228 (compare
11229 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11230 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11231 (const_int 0)))
11232 (clobber (match_scratch:QI 0 "=q"))]
11233 "ix86_match_ccmode (insn, CCGOCmode)
11234 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11235 && (optimize_size
11236 || !TARGET_PARTIAL_FLAG_REG_STALL
11237 || (operands[2] == const1_rtx
11238 && (TARGET_SHIFT1
11239 || TARGET_DOUBLE_WITH_ADD)))"
11240 {
11241 switch (get_attr_type (insn))
11242 {
11243 case TYPE_ALU:
11244 gcc_assert (operands[2] == const1_rtx);
11245 return "add{b}\t{%0, %0|%0, %0}";
11246
11247 default:
11248 if (REG_P (operands[2]))
11249 return "sal{b}\t{%b2, %0|%0, %b2}";
11250 else if (operands[2] == const1_rtx
11251 && (TARGET_SHIFT1 || optimize_size))
11252 return "sal{b}\t%0";
11253 else
11254 return "sal{b}\t{%2, %0|%0, %2}";
11255 }
11256 }
11257 [(set (attr "type")
11258 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11259 (const_int 0))
11260 (match_operand 0 "register_operand" ""))
11261 (match_operand 2 "const1_operand" ""))
11262 (const_string "alu")
11263 ]
11264 (const_string "ishift")))
11265 (set_attr "mode" "QI")])
11266
11267 ;; See comment above `ashldi3' about how this works.
11268
11269 (define_expand "ashrti3"
11270 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11271 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11272 (match_operand:QI 2 "nonmemory_operand" "")))
11273 (clobber (reg:CC FLAGS_REG))])]
11274 "TARGET_64BIT"
11275 {
11276 if (! immediate_operand (operands[2], QImode))
11277 {
11278 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11279 DONE;
11280 }
11281 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11282 DONE;
11283 })
11284
11285 (define_insn "ashrti3_1"
11286 [(set (match_operand:TI 0 "register_operand" "=r")
11287 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11288 (match_operand:QI 2 "register_operand" "c")))
11289 (clobber (match_scratch:DI 3 "=&r"))
11290 (clobber (reg:CC FLAGS_REG))]
11291 "TARGET_64BIT"
11292 "#"
11293 [(set_attr "type" "multi")])
11294
11295 (define_insn "*ashrti3_2"
11296 [(set (match_operand:TI 0 "register_operand" "=r")
11297 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11298 (match_operand:QI 2 "immediate_operand" "O")))
11299 (clobber (reg:CC FLAGS_REG))]
11300 "TARGET_64BIT"
11301 "#"
11302 [(set_attr "type" "multi")])
11303
11304 (define_split
11305 [(set (match_operand:TI 0 "register_operand" "")
11306 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11307 (match_operand:QI 2 "register_operand" "")))
11308 (clobber (match_scratch:DI 3 ""))
11309 (clobber (reg:CC FLAGS_REG))]
11310 "TARGET_64BIT && reload_completed"
11311 [(const_int 0)]
11312 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11313
11314 (define_split
11315 [(set (match_operand:TI 0 "register_operand" "")
11316 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11317 (match_operand:QI 2 "immediate_operand" "")))
11318 (clobber (reg:CC FLAGS_REG))]
11319 "TARGET_64BIT && reload_completed"
11320 [(const_int 0)]
11321 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11322
11323 (define_insn "x86_64_shrd"
11324 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11325 (ior:DI (ashiftrt:DI (match_dup 0)
11326 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11327 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11328 (minus:QI (const_int 64) (match_dup 2)))))
11329 (clobber (reg:CC FLAGS_REG))]
11330 "TARGET_64BIT"
11331 "@
11332 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11333 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11334 [(set_attr "type" "ishift")
11335 (set_attr "prefix_0f" "1")
11336 (set_attr "mode" "DI")
11337 (set_attr "athlon_decode" "vector")])
11338
11339 (define_expand "ashrdi3"
11340 [(set (match_operand:DI 0 "shiftdi_operand" "")
11341 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11342 (match_operand:QI 2 "nonmemory_operand" "")))]
11343 ""
11344 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11345
11346 (define_insn "*ashrdi3_63_rex64"
11347 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11348 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11349 (match_operand:DI 2 "const_int_operand" "i,i")))
11350 (clobber (reg:CC FLAGS_REG))]
11351 "TARGET_64BIT && INTVAL (operands[2]) == 63
11352 && (TARGET_USE_CLTD || optimize_size)
11353 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11354 "@
11355 {cqto|cqo}
11356 sar{q}\t{%2, %0|%0, %2}"
11357 [(set_attr "type" "imovx,ishift")
11358 (set_attr "prefix_0f" "0,*")
11359 (set_attr "length_immediate" "0,*")
11360 (set_attr "modrm" "0,1")
11361 (set_attr "mode" "DI")])
11362
11363 (define_insn "*ashrdi3_1_one_bit_rex64"
11364 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11365 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11366 (match_operand:QI 2 "const1_operand" "")))
11367 (clobber (reg:CC FLAGS_REG))]
11368 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11369 && (TARGET_SHIFT1 || optimize_size)"
11370 "sar{q}\t%0"
11371 [(set_attr "type" "ishift")
11372 (set (attr "length")
11373 (if_then_else (match_operand:DI 0 "register_operand" "")
11374 (const_string "2")
11375 (const_string "*")))])
11376
11377 (define_insn "*ashrdi3_1_rex64"
11378 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11379 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11380 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11381 (clobber (reg:CC FLAGS_REG))]
11382 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11383 "@
11384 sar{q}\t{%2, %0|%0, %2}
11385 sar{q}\t{%b2, %0|%0, %b2}"
11386 [(set_attr "type" "ishift")
11387 (set_attr "mode" "DI")])
11388
11389 ;; This pattern can't accept a variable shift count, since shifts by
11390 ;; zero don't affect the flags. We assume that shifts by constant
11391 ;; zero are optimized away.
11392 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11393 [(set (reg FLAGS_REG)
11394 (compare
11395 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11396 (match_operand:QI 2 "const1_operand" ""))
11397 (const_int 0)))
11398 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11399 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11400 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11401 && (TARGET_SHIFT1 || optimize_size)
11402 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11403 "sar{q}\t%0"
11404 [(set_attr "type" "ishift")
11405 (set (attr "length")
11406 (if_then_else (match_operand:DI 0 "register_operand" "")
11407 (const_string "2")
11408 (const_string "*")))])
11409
11410 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11411 [(set (reg FLAGS_REG)
11412 (compare
11413 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11414 (match_operand:QI 2 "const1_operand" ""))
11415 (const_int 0)))
11416 (clobber (match_scratch:DI 0 "=r"))]
11417 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11418 && (TARGET_SHIFT1 || optimize_size)
11419 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11420 "sar{q}\t%0"
11421 [(set_attr "type" "ishift")
11422 (set_attr "length" "2")])
11423
11424 ;; This pattern can't accept a variable shift count, since shifts by
11425 ;; zero don't affect the flags. We assume that shifts by constant
11426 ;; zero are optimized away.
11427 (define_insn "*ashrdi3_cmp_rex64"
11428 [(set (reg FLAGS_REG)
11429 (compare
11430 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11431 (match_operand:QI 2 "const_int_operand" "n"))
11432 (const_int 0)))
11433 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11434 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11435 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11436 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11437 && (optimize_size
11438 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11439 "sar{q}\t{%2, %0|%0, %2}"
11440 [(set_attr "type" "ishift")
11441 (set_attr "mode" "DI")])
11442
11443 (define_insn "*ashrdi3_cconly_rex64"
11444 [(set (reg FLAGS_REG)
11445 (compare
11446 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11447 (match_operand:QI 2 "const_int_operand" "n"))
11448 (const_int 0)))
11449 (clobber (match_scratch:DI 0 "=r"))]
11450 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11451 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11452 && (optimize_size
11453 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11454 "sar{q}\t{%2, %0|%0, %2}"
11455 [(set_attr "type" "ishift")
11456 (set_attr "mode" "DI")])
11457
11458 (define_insn "*ashrdi3_1"
11459 [(set (match_operand:DI 0 "register_operand" "=r")
11460 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11461 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11462 (clobber (reg:CC FLAGS_REG))]
11463 "!TARGET_64BIT"
11464 "#"
11465 [(set_attr "type" "multi")])
11466
11467 ;; By default we don't ask for a scratch register, because when DImode
11468 ;; values are manipulated, registers are already at a premium. But if
11469 ;; we have one handy, we won't turn it away.
11470 (define_peephole2
11471 [(match_scratch:SI 3 "r")
11472 (parallel [(set (match_operand:DI 0 "register_operand" "")
11473 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11474 (match_operand:QI 2 "nonmemory_operand" "")))
11475 (clobber (reg:CC FLAGS_REG))])
11476 (match_dup 3)]
11477 "!TARGET_64BIT && TARGET_CMOVE"
11478 [(const_int 0)]
11479 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11480
11481 (define_split
11482 [(set (match_operand:DI 0 "register_operand" "")
11483 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11484 (match_operand:QI 2 "nonmemory_operand" "")))
11485 (clobber (reg:CC FLAGS_REG))]
11486 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11487 ? flow2_completed : reload_completed)"
11488 [(const_int 0)]
11489 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11490
11491 (define_insn "x86_shrd_1"
11492 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11493 (ior:SI (ashiftrt:SI (match_dup 0)
11494 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11495 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11496 (minus:QI (const_int 32) (match_dup 2)))))
11497 (clobber (reg:CC FLAGS_REG))]
11498 ""
11499 "@
11500 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11501 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11502 [(set_attr "type" "ishift")
11503 (set_attr "prefix_0f" "1")
11504 (set_attr "pent_pair" "np")
11505 (set_attr "mode" "SI")])
11506
11507 (define_expand "x86_shift_adj_3"
11508 [(use (match_operand:SI 0 "register_operand" ""))
11509 (use (match_operand:SI 1 "register_operand" ""))
11510 (use (match_operand:QI 2 "register_operand" ""))]
11511 ""
11512 {
11513 rtx label = gen_label_rtx ();
11514 rtx tmp;
11515
11516 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11517
11518 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11519 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11520 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11521 gen_rtx_LABEL_REF (VOIDmode, label),
11522 pc_rtx);
11523 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11524 JUMP_LABEL (tmp) = label;
11525
11526 emit_move_insn (operands[0], operands[1]);
11527 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11528
11529 emit_label (label);
11530 LABEL_NUSES (label) = 1;
11531
11532 DONE;
11533 })
11534
11535 (define_insn "ashrsi3_31"
11536 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11537 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11538 (match_operand:SI 2 "const_int_operand" "i,i")))
11539 (clobber (reg:CC FLAGS_REG))]
11540 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11541 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11542 "@
11543 {cltd|cdq}
11544 sar{l}\t{%2, %0|%0, %2}"
11545 [(set_attr "type" "imovx,ishift")
11546 (set_attr "prefix_0f" "0,*")
11547 (set_attr "length_immediate" "0,*")
11548 (set_attr "modrm" "0,1")
11549 (set_attr "mode" "SI")])
11550
11551 (define_insn "*ashrsi3_31_zext"
11552 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11553 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11554 (match_operand:SI 2 "const_int_operand" "i,i"))))
11555 (clobber (reg:CC FLAGS_REG))]
11556 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11557 && INTVAL (operands[2]) == 31
11558 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11559 "@
11560 {cltd|cdq}
11561 sar{l}\t{%2, %k0|%k0, %2}"
11562 [(set_attr "type" "imovx,ishift")
11563 (set_attr "prefix_0f" "0,*")
11564 (set_attr "length_immediate" "0,*")
11565 (set_attr "modrm" "0,1")
11566 (set_attr "mode" "SI")])
11567
11568 (define_expand "ashrsi3"
11569 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11570 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11571 (match_operand:QI 2 "nonmemory_operand" "")))
11572 (clobber (reg:CC FLAGS_REG))]
11573 ""
11574 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11575
11576 (define_insn "*ashrsi3_1_one_bit"
11577 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11578 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11579 (match_operand:QI 2 "const1_operand" "")))
11580 (clobber (reg:CC FLAGS_REG))]
11581 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11582 && (TARGET_SHIFT1 || optimize_size)"
11583 "sar{l}\t%0"
11584 [(set_attr "type" "ishift")
11585 (set (attr "length")
11586 (if_then_else (match_operand:SI 0 "register_operand" "")
11587 (const_string "2")
11588 (const_string "*")))])
11589
11590 (define_insn "*ashrsi3_1_one_bit_zext"
11591 [(set (match_operand:DI 0 "register_operand" "=r")
11592 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11593 (match_operand:QI 2 "const1_operand" ""))))
11594 (clobber (reg:CC FLAGS_REG))]
11595 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11596 && (TARGET_SHIFT1 || optimize_size)"
11597 "sar{l}\t%k0"
11598 [(set_attr "type" "ishift")
11599 (set_attr "length" "2")])
11600
11601 (define_insn "*ashrsi3_1"
11602 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11603 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11604 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11605 (clobber (reg:CC FLAGS_REG))]
11606 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11607 "@
11608 sar{l}\t{%2, %0|%0, %2}
11609 sar{l}\t{%b2, %0|%0, %b2}"
11610 [(set_attr "type" "ishift")
11611 (set_attr "mode" "SI")])
11612
11613 (define_insn "*ashrsi3_1_zext"
11614 [(set (match_operand:DI 0 "register_operand" "=r,r")
11615 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11616 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11617 (clobber (reg:CC FLAGS_REG))]
11618 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11619 "@
11620 sar{l}\t{%2, %k0|%k0, %2}
11621 sar{l}\t{%b2, %k0|%k0, %b2}"
11622 [(set_attr "type" "ishift")
11623 (set_attr "mode" "SI")])
11624
11625 ;; This pattern can't accept a variable shift count, since shifts by
11626 ;; zero don't affect the flags. We assume that shifts by constant
11627 ;; zero are optimized away.
11628 (define_insn "*ashrsi3_one_bit_cmp"
11629 [(set (reg FLAGS_REG)
11630 (compare
11631 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11632 (match_operand:QI 2 "const1_operand" ""))
11633 (const_int 0)))
11634 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11635 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11636 "ix86_match_ccmode (insn, CCGOCmode)
11637 && (TARGET_SHIFT1 || optimize_size)
11638 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11639 "sar{l}\t%0"
11640 [(set_attr "type" "ishift")
11641 (set (attr "length")
11642 (if_then_else (match_operand:SI 0 "register_operand" "")
11643 (const_string "2")
11644 (const_string "*")))])
11645
11646 (define_insn "*ashrsi3_one_bit_cconly"
11647 [(set (reg FLAGS_REG)
11648 (compare
11649 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11650 (match_operand:QI 2 "const1_operand" ""))
11651 (const_int 0)))
11652 (clobber (match_scratch:SI 0 "=r"))]
11653 "ix86_match_ccmode (insn, CCGOCmode)
11654 && (TARGET_SHIFT1 || optimize_size)
11655 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11656 "sar{l}\t%0"
11657 [(set_attr "type" "ishift")
11658 (set_attr "length" "2")])
11659
11660 (define_insn "*ashrsi3_one_bit_cmp_zext"
11661 [(set (reg FLAGS_REG)
11662 (compare
11663 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11664 (match_operand:QI 2 "const1_operand" ""))
11665 (const_int 0)))
11666 (set (match_operand:DI 0 "register_operand" "=r")
11667 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11668 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11669 && (TARGET_SHIFT1 || optimize_size)
11670 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11671 "sar{l}\t%k0"
11672 [(set_attr "type" "ishift")
11673 (set_attr "length" "2")])
11674
11675 ;; This pattern can't accept a variable shift count, since shifts by
11676 ;; zero don't affect the flags. We assume that shifts by constant
11677 ;; zero are optimized away.
11678 (define_insn "*ashrsi3_cmp"
11679 [(set (reg FLAGS_REG)
11680 (compare
11681 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11682 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11683 (const_int 0)))
11684 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11685 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11686 "ix86_match_ccmode (insn, CCGOCmode)
11687 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11688 && (optimize_size
11689 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11690 "sar{l}\t{%2, %0|%0, %2}"
11691 [(set_attr "type" "ishift")
11692 (set_attr "mode" "SI")])
11693
11694 (define_insn "*ashrsi3_cconly"
11695 [(set (reg FLAGS_REG)
11696 (compare
11697 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11698 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11699 (const_int 0)))
11700 (clobber (match_scratch:SI 0 "=r"))]
11701 "ix86_match_ccmode (insn, CCGOCmode)
11702 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11703 && (optimize_size
11704 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11705 "sar{l}\t{%2, %0|%0, %2}"
11706 [(set_attr "type" "ishift")
11707 (set_attr "mode" "SI")])
11708
11709 (define_insn "*ashrsi3_cmp_zext"
11710 [(set (reg FLAGS_REG)
11711 (compare
11712 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11713 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11714 (const_int 0)))
11715 (set (match_operand:DI 0 "register_operand" "=r")
11716 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11717 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11718 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11719 && (optimize_size
11720 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11721 "sar{l}\t{%2, %k0|%k0, %2}"
11722 [(set_attr "type" "ishift")
11723 (set_attr "mode" "SI")])
11724
11725 (define_expand "ashrhi3"
11726 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11727 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11728 (match_operand:QI 2 "nonmemory_operand" "")))
11729 (clobber (reg:CC FLAGS_REG))]
11730 "TARGET_HIMODE_MATH"
11731 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11732
11733 (define_insn "*ashrhi3_1_one_bit"
11734 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11735 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11736 (match_operand:QI 2 "const1_operand" "")))
11737 (clobber (reg:CC FLAGS_REG))]
11738 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11739 && (TARGET_SHIFT1 || optimize_size)"
11740 "sar{w}\t%0"
11741 [(set_attr "type" "ishift")
11742 (set (attr "length")
11743 (if_then_else (match_operand 0 "register_operand" "")
11744 (const_string "2")
11745 (const_string "*")))])
11746
11747 (define_insn "*ashrhi3_1"
11748 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11749 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11750 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11751 (clobber (reg:CC FLAGS_REG))]
11752 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11753 "@
11754 sar{w}\t{%2, %0|%0, %2}
11755 sar{w}\t{%b2, %0|%0, %b2}"
11756 [(set_attr "type" "ishift")
11757 (set_attr "mode" "HI")])
11758
11759 ;; This pattern can't accept a variable shift count, since shifts by
11760 ;; zero don't affect the flags. We assume that shifts by constant
11761 ;; zero are optimized away.
11762 (define_insn "*ashrhi3_one_bit_cmp"
11763 [(set (reg FLAGS_REG)
11764 (compare
11765 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11766 (match_operand:QI 2 "const1_operand" ""))
11767 (const_int 0)))
11768 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11769 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11770 "ix86_match_ccmode (insn, CCGOCmode)
11771 && (TARGET_SHIFT1 || optimize_size)
11772 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11773 "sar{w}\t%0"
11774 [(set_attr "type" "ishift")
11775 (set (attr "length")
11776 (if_then_else (match_operand 0 "register_operand" "")
11777 (const_string "2")
11778 (const_string "*")))])
11779
11780 (define_insn "*ashrhi3_one_bit_cconly"
11781 [(set (reg FLAGS_REG)
11782 (compare
11783 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11784 (match_operand:QI 2 "const1_operand" ""))
11785 (const_int 0)))
11786 (clobber (match_scratch:HI 0 "=r"))]
11787 "ix86_match_ccmode (insn, CCGOCmode)
11788 && (TARGET_SHIFT1 || optimize_size)
11789 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11790 "sar{w}\t%0"
11791 [(set_attr "type" "ishift")
11792 (set_attr "length" "2")])
11793
11794 ;; This pattern can't accept a variable shift count, since shifts by
11795 ;; zero don't affect the flags. We assume that shifts by constant
11796 ;; zero are optimized away.
11797 (define_insn "*ashrhi3_cmp"
11798 [(set (reg FLAGS_REG)
11799 (compare
11800 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11801 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11802 (const_int 0)))
11803 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11804 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11805 "ix86_match_ccmode (insn, CCGOCmode)
11806 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11807 && (optimize_size
11808 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11809 "sar{w}\t{%2, %0|%0, %2}"
11810 [(set_attr "type" "ishift")
11811 (set_attr "mode" "HI")])
11812
11813 (define_insn "*ashrhi3_cconly"
11814 [(set (reg FLAGS_REG)
11815 (compare
11816 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11817 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11818 (const_int 0)))
11819 (clobber (match_scratch:HI 0 "=r"))]
11820 "ix86_match_ccmode (insn, CCGOCmode)
11821 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11822 && (optimize_size
11823 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11824 "sar{w}\t{%2, %0|%0, %2}"
11825 [(set_attr "type" "ishift")
11826 (set_attr "mode" "HI")])
11827
11828 (define_expand "ashrqi3"
11829 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11830 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11831 (match_operand:QI 2 "nonmemory_operand" "")))
11832 (clobber (reg:CC FLAGS_REG))]
11833 "TARGET_QIMODE_MATH"
11834 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11835
11836 (define_insn "*ashrqi3_1_one_bit"
11837 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11838 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11839 (match_operand:QI 2 "const1_operand" "")))
11840 (clobber (reg:CC FLAGS_REG))]
11841 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11842 && (TARGET_SHIFT1 || optimize_size)"
11843 "sar{b}\t%0"
11844 [(set_attr "type" "ishift")
11845 (set (attr "length")
11846 (if_then_else (match_operand 0 "register_operand" "")
11847 (const_string "2")
11848 (const_string "*")))])
11849
11850 (define_insn "*ashrqi3_1_one_bit_slp"
11851 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11852 (ashiftrt:QI (match_dup 0)
11853 (match_operand:QI 1 "const1_operand" "")))
11854 (clobber (reg:CC FLAGS_REG))]
11855 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11856 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11857 && (TARGET_SHIFT1 || optimize_size)"
11858 "sar{b}\t%0"
11859 [(set_attr "type" "ishift1")
11860 (set (attr "length")
11861 (if_then_else (match_operand 0 "register_operand" "")
11862 (const_string "2")
11863 (const_string "*")))])
11864
11865 (define_insn "*ashrqi3_1"
11866 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11867 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11868 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11869 (clobber (reg:CC FLAGS_REG))]
11870 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11871 "@
11872 sar{b}\t{%2, %0|%0, %2}
11873 sar{b}\t{%b2, %0|%0, %b2}"
11874 [(set_attr "type" "ishift")
11875 (set_attr "mode" "QI")])
11876
11877 (define_insn "*ashrqi3_1_slp"
11878 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11879 (ashiftrt:QI (match_dup 0)
11880 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11881 (clobber (reg:CC FLAGS_REG))]
11882 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11883 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11884 "@
11885 sar{b}\t{%1, %0|%0, %1}
11886 sar{b}\t{%b1, %0|%0, %b1}"
11887 [(set_attr "type" "ishift1")
11888 (set_attr "mode" "QI")])
11889
11890 ;; This pattern can't accept a variable shift count, since shifts by
11891 ;; zero don't affect the flags. We assume that shifts by constant
11892 ;; zero are optimized away.
11893 (define_insn "*ashrqi3_one_bit_cmp"
11894 [(set (reg FLAGS_REG)
11895 (compare
11896 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11897 (match_operand:QI 2 "const1_operand" "I"))
11898 (const_int 0)))
11899 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11900 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11901 "ix86_match_ccmode (insn, CCGOCmode)
11902 && (TARGET_SHIFT1 || optimize_size)
11903 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11904 "sar{b}\t%0"
11905 [(set_attr "type" "ishift")
11906 (set (attr "length")
11907 (if_then_else (match_operand 0 "register_operand" "")
11908 (const_string "2")
11909 (const_string "*")))])
11910
11911 (define_insn "*ashrqi3_one_bit_cconly"
11912 [(set (reg FLAGS_REG)
11913 (compare
11914 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11915 (match_operand:QI 2 "const1_operand" "I"))
11916 (const_int 0)))
11917 (clobber (match_scratch:QI 0 "=q"))]
11918 "ix86_match_ccmode (insn, CCGOCmode)
11919 && (TARGET_SHIFT1 || optimize_size)
11920 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11921 "sar{b}\t%0"
11922 [(set_attr "type" "ishift")
11923 (set_attr "length" "2")])
11924
11925 ;; This pattern can't accept a variable shift count, since shifts by
11926 ;; zero don't affect the flags. We assume that shifts by constant
11927 ;; zero are optimized away.
11928 (define_insn "*ashrqi3_cmp"
11929 [(set (reg FLAGS_REG)
11930 (compare
11931 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11932 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11933 (const_int 0)))
11934 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11935 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11936 "ix86_match_ccmode (insn, CCGOCmode)
11937 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11938 && (optimize_size
11939 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11940 "sar{b}\t{%2, %0|%0, %2}"
11941 [(set_attr "type" "ishift")
11942 (set_attr "mode" "QI")])
11943
11944 (define_insn "*ashrqi3_cconly"
11945 [(set (reg FLAGS_REG)
11946 (compare
11947 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11948 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11949 (const_int 0)))
11950 (clobber (match_scratch:QI 0 "=q"))]
11951 "ix86_match_ccmode (insn, CCGOCmode)
11952 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11953 && (optimize_size
11954 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11955 "sar{b}\t{%2, %0|%0, %2}"
11956 [(set_attr "type" "ishift")
11957 (set_attr "mode" "QI")])
11958
11959 \f
11960 ;; Logical shift instructions
11961
11962 ;; See comment above `ashldi3' about how this works.
11963
11964 (define_expand "lshrti3"
11965 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11966 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11967 (match_operand:QI 2 "nonmemory_operand" "")))
11968 (clobber (reg:CC FLAGS_REG))])]
11969 "TARGET_64BIT"
11970 {
11971 if (! immediate_operand (operands[2], QImode))
11972 {
11973 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11974 DONE;
11975 }
11976 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11977 DONE;
11978 })
11979
11980 (define_insn "lshrti3_1"
11981 [(set (match_operand:TI 0 "register_operand" "=r")
11982 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11983 (match_operand:QI 2 "register_operand" "c")))
11984 (clobber (match_scratch:DI 3 "=&r"))
11985 (clobber (reg:CC FLAGS_REG))]
11986 "TARGET_64BIT"
11987 "#"
11988 [(set_attr "type" "multi")])
11989
11990 (define_insn "*lshrti3_2"
11991 [(set (match_operand:TI 0 "register_operand" "=r")
11992 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11993 (match_operand:QI 2 "immediate_operand" "O")))
11994 (clobber (reg:CC FLAGS_REG))]
11995 "TARGET_64BIT"
11996 "#"
11997 [(set_attr "type" "multi")])
11998
11999 (define_split
12000 [(set (match_operand:TI 0 "register_operand" "")
12001 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12002 (match_operand:QI 2 "register_operand" "")))
12003 (clobber (match_scratch:DI 3 ""))
12004 (clobber (reg:CC FLAGS_REG))]
12005 "TARGET_64BIT && reload_completed"
12006 [(const_int 0)]
12007 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12008
12009 (define_split
12010 [(set (match_operand:TI 0 "register_operand" "")
12011 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12012 (match_operand:QI 2 "immediate_operand" "")))
12013 (clobber (reg:CC FLAGS_REG))]
12014 "TARGET_64BIT && reload_completed"
12015 [(const_int 0)]
12016 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12017
12018 (define_expand "lshrdi3"
12019 [(set (match_operand:DI 0 "shiftdi_operand" "")
12020 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12021 (match_operand:QI 2 "nonmemory_operand" "")))]
12022 ""
12023 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12024
12025 (define_insn "*lshrdi3_1_one_bit_rex64"
12026 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12027 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12028 (match_operand:QI 2 "const1_operand" "")))
12029 (clobber (reg:CC FLAGS_REG))]
12030 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12031 && (TARGET_SHIFT1 || optimize_size)"
12032 "shr{q}\t%0"
12033 [(set_attr "type" "ishift")
12034 (set (attr "length")
12035 (if_then_else (match_operand:DI 0 "register_operand" "")
12036 (const_string "2")
12037 (const_string "*")))])
12038
12039 (define_insn "*lshrdi3_1_rex64"
12040 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12041 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12042 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12043 (clobber (reg:CC FLAGS_REG))]
12044 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12045 "@
12046 shr{q}\t{%2, %0|%0, %2}
12047 shr{q}\t{%b2, %0|%0, %b2}"
12048 [(set_attr "type" "ishift")
12049 (set_attr "mode" "DI")])
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 "*lshrdi3_cmp_one_bit_rex64"
12055 [(set (reg FLAGS_REG)
12056 (compare
12057 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12058 (match_operand:QI 2 "const1_operand" ""))
12059 (const_int 0)))
12060 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12061 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12062 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12063 && (TARGET_SHIFT1 || optimize_size)
12064 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12065 "shr{q}\t%0"
12066 [(set_attr "type" "ishift")
12067 (set (attr "length")
12068 (if_then_else (match_operand:DI 0 "register_operand" "")
12069 (const_string "2")
12070 (const_string "*")))])
12071
12072 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12073 [(set (reg FLAGS_REG)
12074 (compare
12075 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12076 (match_operand:QI 2 "const1_operand" ""))
12077 (const_int 0)))
12078 (clobber (match_scratch:DI 0 "=r"))]
12079 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12080 && (TARGET_SHIFT1 || optimize_size)
12081 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12082 "shr{q}\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 "*lshrdi3_cmp_rex64"
12090 [(set (reg FLAGS_REG)
12091 (compare
12092 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12093 (match_operand:QI 2 "const_int_operand" "e"))
12094 (const_int 0)))
12095 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12096 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12097 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12098 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12099 && (optimize_size
12100 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12101 "shr{q}\t{%2, %0|%0, %2}"
12102 [(set_attr "type" "ishift")
12103 (set_attr "mode" "DI")])
12104
12105 (define_insn "*lshrdi3_cconly_rex64"
12106 [(set (reg FLAGS_REG)
12107 (compare
12108 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12109 (match_operand:QI 2 "const_int_operand" "e"))
12110 (const_int 0)))
12111 (clobber (match_scratch:DI 0 "=r"))]
12112 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12113 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12114 && (optimize_size
12115 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12116 "shr{q}\t{%2, %0|%0, %2}"
12117 [(set_attr "type" "ishift")
12118 (set_attr "mode" "DI")])
12119
12120 (define_insn "*lshrdi3_1"
12121 [(set (match_operand:DI 0 "register_operand" "=r")
12122 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12123 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12124 (clobber (reg:CC FLAGS_REG))]
12125 "!TARGET_64BIT"
12126 "#"
12127 [(set_attr "type" "multi")])
12128
12129 ;; By default we don't ask for a scratch register, because when DImode
12130 ;; values are manipulated, registers are already at a premium. But if
12131 ;; we have one handy, we won't turn it away.
12132 (define_peephole2
12133 [(match_scratch:SI 3 "r")
12134 (parallel [(set (match_operand:DI 0 "register_operand" "")
12135 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12136 (match_operand:QI 2 "nonmemory_operand" "")))
12137 (clobber (reg:CC FLAGS_REG))])
12138 (match_dup 3)]
12139 "!TARGET_64BIT && TARGET_CMOVE"
12140 [(const_int 0)]
12141 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12142
12143 (define_split
12144 [(set (match_operand:DI 0 "register_operand" "")
12145 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12146 (match_operand:QI 2 "nonmemory_operand" "")))
12147 (clobber (reg:CC FLAGS_REG))]
12148 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12149 ? flow2_completed : reload_completed)"
12150 [(const_int 0)]
12151 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12152
12153 (define_expand "lshrsi3"
12154 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12155 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12156 (match_operand:QI 2 "nonmemory_operand" "")))
12157 (clobber (reg:CC FLAGS_REG))]
12158 ""
12159 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12160
12161 (define_insn "*lshrsi3_1_one_bit"
12162 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12163 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12164 (match_operand:QI 2 "const1_operand" "")))
12165 (clobber (reg:CC FLAGS_REG))]
12166 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12167 && (TARGET_SHIFT1 || optimize_size)"
12168 "shr{l}\t%0"
12169 [(set_attr "type" "ishift")
12170 (set (attr "length")
12171 (if_then_else (match_operand:SI 0 "register_operand" "")
12172 (const_string "2")
12173 (const_string "*")))])
12174
12175 (define_insn "*lshrsi3_1_one_bit_zext"
12176 [(set (match_operand:DI 0 "register_operand" "=r")
12177 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12178 (match_operand:QI 2 "const1_operand" "")))
12179 (clobber (reg:CC FLAGS_REG))]
12180 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12181 && (TARGET_SHIFT1 || optimize_size)"
12182 "shr{l}\t%k0"
12183 [(set_attr "type" "ishift")
12184 (set_attr "length" "2")])
12185
12186 (define_insn "*lshrsi3_1"
12187 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12188 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12189 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12190 (clobber (reg:CC FLAGS_REG))]
12191 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12192 "@
12193 shr{l}\t{%2, %0|%0, %2}
12194 shr{l}\t{%b2, %0|%0, %b2}"
12195 [(set_attr "type" "ishift")
12196 (set_attr "mode" "SI")])
12197
12198 (define_insn "*lshrsi3_1_zext"
12199 [(set (match_operand:DI 0 "register_operand" "=r,r")
12200 (zero_extend:DI
12201 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12202 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12203 (clobber (reg:CC FLAGS_REG))]
12204 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12205 "@
12206 shr{l}\t{%2, %k0|%k0, %2}
12207 shr{l}\t{%b2, %k0|%k0, %b2}"
12208 [(set_attr "type" "ishift")
12209 (set_attr "mode" "SI")])
12210
12211 ;; This pattern can't accept a variable shift count, since shifts by
12212 ;; zero don't affect the flags. We assume that shifts by constant
12213 ;; zero are optimized away.
12214 (define_insn "*lshrsi3_one_bit_cmp"
12215 [(set (reg FLAGS_REG)
12216 (compare
12217 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12218 (match_operand:QI 2 "const1_operand" ""))
12219 (const_int 0)))
12220 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12221 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12222 "ix86_match_ccmode (insn, CCGOCmode)
12223 && (TARGET_SHIFT1 || optimize_size)
12224 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12225 "shr{l}\t%0"
12226 [(set_attr "type" "ishift")
12227 (set (attr "length")
12228 (if_then_else (match_operand:SI 0 "register_operand" "")
12229 (const_string "2")
12230 (const_string "*")))])
12231
12232 (define_insn "*lshrsi3_one_bit_cconly"
12233 [(set (reg FLAGS_REG)
12234 (compare
12235 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12236 (match_operand:QI 2 "const1_operand" ""))
12237 (const_int 0)))
12238 (clobber (match_scratch:SI 0 "=r"))]
12239 "ix86_match_ccmode (insn, CCGOCmode)
12240 && (TARGET_SHIFT1 || optimize_size)
12241 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12242 "shr{l}\t%0"
12243 [(set_attr "type" "ishift")
12244 (set_attr "length" "2")])
12245
12246 (define_insn "*lshrsi3_cmp_one_bit_zext"
12247 [(set (reg FLAGS_REG)
12248 (compare
12249 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12250 (match_operand:QI 2 "const1_operand" ""))
12251 (const_int 0)))
12252 (set (match_operand:DI 0 "register_operand" "=r")
12253 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12254 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12255 && (TARGET_SHIFT1 || optimize_size)
12256 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12257 "shr{l}\t%k0"
12258 [(set_attr "type" "ishift")
12259 (set_attr "length" "2")])
12260
12261 ;; This pattern can't accept a variable shift count, since shifts by
12262 ;; zero don't affect the flags. We assume that shifts by constant
12263 ;; zero are optimized away.
12264 (define_insn "*lshrsi3_cmp"
12265 [(set (reg FLAGS_REG)
12266 (compare
12267 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12268 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12269 (const_int 0)))
12270 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12271 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12272 "ix86_match_ccmode (insn, CCGOCmode)
12273 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12274 && (optimize_size
12275 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12276 "shr{l}\t{%2, %0|%0, %2}"
12277 [(set_attr "type" "ishift")
12278 (set_attr "mode" "SI")])
12279
12280 (define_insn "*lshrsi3_cconly"
12281 [(set (reg FLAGS_REG)
12282 (compare
12283 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12284 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12285 (const_int 0)))
12286 (clobber (match_scratch:SI 0 "=r"))]
12287 "ix86_match_ccmode (insn, CCGOCmode)
12288 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12289 && (optimize_size
12290 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12291 "shr{l}\t{%2, %0|%0, %2}"
12292 [(set_attr "type" "ishift")
12293 (set_attr "mode" "SI")])
12294
12295 (define_insn "*lshrsi3_cmp_zext"
12296 [(set (reg FLAGS_REG)
12297 (compare
12298 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12299 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12300 (const_int 0)))
12301 (set (match_operand:DI 0 "register_operand" "=r")
12302 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12303 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12304 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12305 && (optimize_size
12306 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12307 "shr{l}\t{%2, %k0|%k0, %2}"
12308 [(set_attr "type" "ishift")
12309 (set_attr "mode" "SI")])
12310
12311 (define_expand "lshrhi3"
12312 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12313 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12314 (match_operand:QI 2 "nonmemory_operand" "")))
12315 (clobber (reg:CC FLAGS_REG))]
12316 "TARGET_HIMODE_MATH"
12317 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12318
12319 (define_insn "*lshrhi3_1_one_bit"
12320 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12321 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12322 (match_operand:QI 2 "const1_operand" "")))
12323 (clobber (reg:CC FLAGS_REG))]
12324 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12325 && (TARGET_SHIFT1 || optimize_size)"
12326 "shr{w}\t%0"
12327 [(set_attr "type" "ishift")
12328 (set (attr "length")
12329 (if_then_else (match_operand 0 "register_operand" "")
12330 (const_string "2")
12331 (const_string "*")))])
12332
12333 (define_insn "*lshrhi3_1"
12334 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12335 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12336 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12337 (clobber (reg:CC FLAGS_REG))]
12338 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12339 "@
12340 shr{w}\t{%2, %0|%0, %2}
12341 shr{w}\t{%b2, %0|%0, %b2}"
12342 [(set_attr "type" "ishift")
12343 (set_attr "mode" "HI")])
12344
12345 ;; This pattern can't accept a variable shift count, since shifts by
12346 ;; zero don't affect the flags. We assume that shifts by constant
12347 ;; zero are optimized away.
12348 (define_insn "*lshrhi3_one_bit_cmp"
12349 [(set (reg FLAGS_REG)
12350 (compare
12351 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12352 (match_operand:QI 2 "const1_operand" ""))
12353 (const_int 0)))
12354 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12355 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12356 "ix86_match_ccmode (insn, CCGOCmode)
12357 && (TARGET_SHIFT1 || optimize_size)
12358 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12359 "shr{w}\t%0"
12360 [(set_attr "type" "ishift")
12361 (set (attr "length")
12362 (if_then_else (match_operand:SI 0 "register_operand" "")
12363 (const_string "2")
12364 (const_string "*")))])
12365
12366 (define_insn "*lshrhi3_one_bit_cconly"
12367 [(set (reg FLAGS_REG)
12368 (compare
12369 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12370 (match_operand:QI 2 "const1_operand" ""))
12371 (const_int 0)))
12372 (clobber (match_scratch:HI 0 "=r"))]
12373 "ix86_match_ccmode (insn, CCGOCmode)
12374 && (TARGET_SHIFT1 || optimize_size)
12375 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12376 "shr{w}\t%0"
12377 [(set_attr "type" "ishift")
12378 (set_attr "length" "2")])
12379
12380 ;; This pattern can't accept a variable shift count, since shifts by
12381 ;; zero don't affect the flags. We assume that shifts by constant
12382 ;; zero are optimized away.
12383 (define_insn "*lshrhi3_cmp"
12384 [(set (reg FLAGS_REG)
12385 (compare
12386 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12387 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12388 (const_int 0)))
12389 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12390 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12391 "ix86_match_ccmode (insn, CCGOCmode)
12392 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12393 && (optimize_size
12394 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12395 "shr{w}\t{%2, %0|%0, %2}"
12396 [(set_attr "type" "ishift")
12397 (set_attr "mode" "HI")])
12398
12399 (define_insn "*lshrhi3_cconly"
12400 [(set (reg FLAGS_REG)
12401 (compare
12402 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12403 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12404 (const_int 0)))
12405 (clobber (match_scratch:HI 0 "=r"))]
12406 "ix86_match_ccmode (insn, CCGOCmode)
12407 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12408 && (optimize_size
12409 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12410 "shr{w}\t{%2, %0|%0, %2}"
12411 [(set_attr "type" "ishift")
12412 (set_attr "mode" "HI")])
12413
12414 (define_expand "lshrqi3"
12415 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12416 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12417 (match_operand:QI 2 "nonmemory_operand" "")))
12418 (clobber (reg:CC FLAGS_REG))]
12419 "TARGET_QIMODE_MATH"
12420 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12421
12422 (define_insn "*lshrqi3_1_one_bit"
12423 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12424 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12425 (match_operand:QI 2 "const1_operand" "")))
12426 (clobber (reg:CC FLAGS_REG))]
12427 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12428 && (TARGET_SHIFT1 || optimize_size)"
12429 "shr{b}\t%0"
12430 [(set_attr "type" "ishift")
12431 (set (attr "length")
12432 (if_then_else (match_operand 0 "register_operand" "")
12433 (const_string "2")
12434 (const_string "*")))])
12435
12436 (define_insn "*lshrqi3_1_one_bit_slp"
12437 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12438 (lshiftrt:QI (match_dup 0)
12439 (match_operand:QI 1 "const1_operand" "")))
12440 (clobber (reg:CC FLAGS_REG))]
12441 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12442 && (TARGET_SHIFT1 || optimize_size)"
12443 "shr{b}\t%0"
12444 [(set_attr "type" "ishift1")
12445 (set (attr "length")
12446 (if_then_else (match_operand 0 "register_operand" "")
12447 (const_string "2")
12448 (const_string "*")))])
12449
12450 (define_insn "*lshrqi3_1"
12451 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12452 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12453 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12454 (clobber (reg:CC FLAGS_REG))]
12455 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12456 "@
12457 shr{b}\t{%2, %0|%0, %2}
12458 shr{b}\t{%b2, %0|%0, %b2}"
12459 [(set_attr "type" "ishift")
12460 (set_attr "mode" "QI")])
12461
12462 (define_insn "*lshrqi3_1_slp"
12463 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12464 (lshiftrt:QI (match_dup 0)
12465 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12466 (clobber (reg:CC FLAGS_REG))]
12467 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12468 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12469 "@
12470 shr{b}\t{%1, %0|%0, %1}
12471 shr{b}\t{%b1, %0|%0, %b1}"
12472 [(set_attr "type" "ishift1")
12473 (set_attr "mode" "QI")])
12474
12475 ;; This pattern can't accept a variable shift count, since shifts by
12476 ;; zero don't affect the flags. We assume that shifts by constant
12477 ;; zero are optimized away.
12478 (define_insn "*lshrqi2_one_bit_cmp"
12479 [(set (reg FLAGS_REG)
12480 (compare
12481 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12482 (match_operand:QI 2 "const1_operand" ""))
12483 (const_int 0)))
12484 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12485 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12486 "ix86_match_ccmode (insn, CCGOCmode)
12487 && (TARGET_SHIFT1 || optimize_size)
12488 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12489 "shr{b}\t%0"
12490 [(set_attr "type" "ishift")
12491 (set (attr "length")
12492 (if_then_else (match_operand:SI 0 "register_operand" "")
12493 (const_string "2")
12494 (const_string "*")))])
12495
12496 (define_insn "*lshrqi2_one_bit_cconly"
12497 [(set (reg FLAGS_REG)
12498 (compare
12499 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12500 (match_operand:QI 2 "const1_operand" ""))
12501 (const_int 0)))
12502 (clobber (match_scratch:QI 0 "=q"))]
12503 "ix86_match_ccmode (insn, CCGOCmode)
12504 && (TARGET_SHIFT1 || optimize_size)
12505 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12506 "shr{b}\t%0"
12507 [(set_attr "type" "ishift")
12508 (set_attr "length" "2")])
12509
12510 ;; This pattern can't accept a variable shift count, since shifts by
12511 ;; zero don't affect the flags. We assume that shifts by constant
12512 ;; zero are optimized away.
12513 (define_insn "*lshrqi2_cmp"
12514 [(set (reg FLAGS_REG)
12515 (compare
12516 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12517 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12518 (const_int 0)))
12519 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12520 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12521 "ix86_match_ccmode (insn, CCGOCmode)
12522 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12523 && (optimize_size
12524 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12525 "shr{b}\t{%2, %0|%0, %2}"
12526 [(set_attr "type" "ishift")
12527 (set_attr "mode" "QI")])
12528
12529 (define_insn "*lshrqi2_cconly"
12530 [(set (reg FLAGS_REG)
12531 (compare
12532 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12533 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12534 (const_int 0)))
12535 (clobber (match_scratch:QI 0 "=q"))]
12536 "ix86_match_ccmode (insn, CCGOCmode)
12537 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12538 && (optimize_size
12539 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12540 "shr{b}\t{%2, %0|%0, %2}"
12541 [(set_attr "type" "ishift")
12542 (set_attr "mode" "QI")])
12543 \f
12544 ;; Rotate instructions
12545
12546 (define_expand "rotldi3"
12547 [(set (match_operand:DI 0 "shiftdi_operand" "")
12548 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12549 (match_operand:QI 2 "nonmemory_operand" "")))
12550 (clobber (reg:CC FLAGS_REG))]
12551 ""
12552 {
12553 if (TARGET_64BIT)
12554 {
12555 ix86_expand_binary_operator (ROTATE, DImode, operands);
12556 DONE;
12557 }
12558 if (!const_1_to_31_operand (operands[2], VOIDmode))
12559 FAIL;
12560 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12561 DONE;
12562 })
12563
12564 ;; Implement rotation using two double-precision shift instructions
12565 ;; and a scratch register.
12566 (define_insn_and_split "ix86_rotldi3"
12567 [(set (match_operand:DI 0 "register_operand" "=r")
12568 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12569 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12570 (clobber (reg:CC FLAGS_REG))
12571 (clobber (match_scratch:SI 3 "=&r"))]
12572 "!TARGET_64BIT"
12573 ""
12574 "&& reload_completed"
12575 [(set (match_dup 3) (match_dup 4))
12576 (parallel
12577 [(set (match_dup 4)
12578 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12579 (lshiftrt:SI (match_dup 5)
12580 (minus:QI (const_int 32) (match_dup 2)))))
12581 (clobber (reg:CC FLAGS_REG))])
12582 (parallel
12583 [(set (match_dup 5)
12584 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12585 (lshiftrt:SI (match_dup 3)
12586 (minus:QI (const_int 32) (match_dup 2)))))
12587 (clobber (reg:CC FLAGS_REG))])]
12588 "split_di (operands, 1, operands + 4, operands + 5);")
12589
12590 (define_insn "*rotlsi3_1_one_bit_rex64"
12591 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12592 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12593 (match_operand:QI 2 "const1_operand" "")))
12594 (clobber (reg:CC FLAGS_REG))]
12595 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12596 && (TARGET_SHIFT1 || optimize_size)"
12597 "rol{q}\t%0"
12598 [(set_attr "type" "rotate")
12599 (set (attr "length")
12600 (if_then_else (match_operand:DI 0 "register_operand" "")
12601 (const_string "2")
12602 (const_string "*")))])
12603
12604 (define_insn "*rotldi3_1_rex64"
12605 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12606 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12607 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12608 (clobber (reg:CC FLAGS_REG))]
12609 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12610 "@
12611 rol{q}\t{%2, %0|%0, %2}
12612 rol{q}\t{%b2, %0|%0, %b2}"
12613 [(set_attr "type" "rotate")
12614 (set_attr "mode" "DI")])
12615
12616 (define_expand "rotlsi3"
12617 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12618 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12619 (match_operand:QI 2 "nonmemory_operand" "")))
12620 (clobber (reg:CC FLAGS_REG))]
12621 ""
12622 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12623
12624 (define_insn "*rotlsi3_1_one_bit"
12625 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12626 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12627 (match_operand:QI 2 "const1_operand" "")))
12628 (clobber (reg:CC FLAGS_REG))]
12629 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12630 && (TARGET_SHIFT1 || optimize_size)"
12631 "rol{l}\t%0"
12632 [(set_attr "type" "rotate")
12633 (set (attr "length")
12634 (if_then_else (match_operand:SI 0 "register_operand" "")
12635 (const_string "2")
12636 (const_string "*")))])
12637
12638 (define_insn "*rotlsi3_1_one_bit_zext"
12639 [(set (match_operand:DI 0 "register_operand" "=r")
12640 (zero_extend:DI
12641 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12642 (match_operand:QI 2 "const1_operand" ""))))
12643 (clobber (reg:CC FLAGS_REG))]
12644 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12645 && (TARGET_SHIFT1 || optimize_size)"
12646 "rol{l}\t%k0"
12647 [(set_attr "type" "rotate")
12648 (set_attr "length" "2")])
12649
12650 (define_insn "*rotlsi3_1"
12651 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12652 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12653 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12654 (clobber (reg:CC FLAGS_REG))]
12655 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12656 "@
12657 rol{l}\t{%2, %0|%0, %2}
12658 rol{l}\t{%b2, %0|%0, %b2}"
12659 [(set_attr "type" "rotate")
12660 (set_attr "mode" "SI")])
12661
12662 (define_insn "*rotlsi3_1_zext"
12663 [(set (match_operand:DI 0 "register_operand" "=r,r")
12664 (zero_extend:DI
12665 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12666 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12667 (clobber (reg:CC FLAGS_REG))]
12668 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12669 "@
12670 rol{l}\t{%2, %k0|%k0, %2}
12671 rol{l}\t{%b2, %k0|%k0, %b2}"
12672 [(set_attr "type" "rotate")
12673 (set_attr "mode" "SI")])
12674
12675 (define_expand "rotlhi3"
12676 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12677 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12678 (match_operand:QI 2 "nonmemory_operand" "")))
12679 (clobber (reg:CC FLAGS_REG))]
12680 "TARGET_HIMODE_MATH"
12681 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12682
12683 (define_insn "*rotlhi3_1_one_bit"
12684 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12685 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12686 (match_operand:QI 2 "const1_operand" "")))
12687 (clobber (reg:CC FLAGS_REG))]
12688 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12689 && (TARGET_SHIFT1 || optimize_size)"
12690 "rol{w}\t%0"
12691 [(set_attr "type" "rotate")
12692 (set (attr "length")
12693 (if_then_else (match_operand 0 "register_operand" "")
12694 (const_string "2")
12695 (const_string "*")))])
12696
12697 (define_insn "*rotlhi3_1"
12698 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12699 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12700 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12701 (clobber (reg:CC FLAGS_REG))]
12702 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12703 "@
12704 rol{w}\t{%2, %0|%0, %2}
12705 rol{w}\t{%b2, %0|%0, %b2}"
12706 [(set_attr "type" "rotate")
12707 (set_attr "mode" "HI")])
12708
12709 (define_expand "rotlqi3"
12710 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12711 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12712 (match_operand:QI 2 "nonmemory_operand" "")))
12713 (clobber (reg:CC FLAGS_REG))]
12714 "TARGET_QIMODE_MATH"
12715 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12716
12717 (define_insn "*rotlqi3_1_one_bit_slp"
12718 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12719 (rotate:QI (match_dup 0)
12720 (match_operand:QI 1 "const1_operand" "")))
12721 (clobber (reg:CC FLAGS_REG))]
12722 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12723 && (TARGET_SHIFT1 || optimize_size)"
12724 "rol{b}\t%0"
12725 [(set_attr "type" "rotate1")
12726 (set (attr "length")
12727 (if_then_else (match_operand 0 "register_operand" "")
12728 (const_string "2")
12729 (const_string "*")))])
12730
12731 (define_insn "*rotlqi3_1_one_bit"
12732 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12733 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12734 (match_operand:QI 2 "const1_operand" "")))
12735 (clobber (reg:CC FLAGS_REG))]
12736 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12737 && (TARGET_SHIFT1 || optimize_size)"
12738 "rol{b}\t%0"
12739 [(set_attr "type" "rotate")
12740 (set (attr "length")
12741 (if_then_else (match_operand 0 "register_operand" "")
12742 (const_string "2")
12743 (const_string "*")))])
12744
12745 (define_insn "*rotlqi3_1_slp"
12746 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12747 (rotate:QI (match_dup 0)
12748 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12749 (clobber (reg:CC FLAGS_REG))]
12750 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12751 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12752 "@
12753 rol{b}\t{%1, %0|%0, %1}
12754 rol{b}\t{%b1, %0|%0, %b1}"
12755 [(set_attr "type" "rotate1")
12756 (set_attr "mode" "QI")])
12757
12758 (define_insn "*rotlqi3_1"
12759 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12760 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12761 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12762 (clobber (reg:CC FLAGS_REG))]
12763 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12764 "@
12765 rol{b}\t{%2, %0|%0, %2}
12766 rol{b}\t{%b2, %0|%0, %b2}"
12767 [(set_attr "type" "rotate")
12768 (set_attr "mode" "QI")])
12769
12770 (define_expand "rotrdi3"
12771 [(set (match_operand:DI 0 "shiftdi_operand" "")
12772 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12773 (match_operand:QI 2 "nonmemory_operand" "")))
12774 (clobber (reg:CC FLAGS_REG))]
12775 ""
12776 {
12777 if (TARGET_64BIT)
12778 {
12779 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12780 DONE;
12781 }
12782 if (!const_1_to_31_operand (operands[2], VOIDmode))
12783 FAIL;
12784 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12785 DONE;
12786 })
12787
12788 ;; Implement rotation using two double-precision shift instructions
12789 ;; and a scratch register.
12790 (define_insn_and_split "ix86_rotrdi3"
12791 [(set (match_operand:DI 0 "register_operand" "=r")
12792 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12793 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12794 (clobber (reg:CC FLAGS_REG))
12795 (clobber (match_scratch:SI 3 "=&r"))]
12796 "!TARGET_64BIT"
12797 ""
12798 "&& reload_completed"
12799 [(set (match_dup 3) (match_dup 4))
12800 (parallel
12801 [(set (match_dup 4)
12802 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12803 (ashift:SI (match_dup 5)
12804 (minus:QI (const_int 32) (match_dup 2)))))
12805 (clobber (reg:CC FLAGS_REG))])
12806 (parallel
12807 [(set (match_dup 5)
12808 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12809 (ashift:SI (match_dup 3)
12810 (minus:QI (const_int 32) (match_dup 2)))))
12811 (clobber (reg:CC FLAGS_REG))])]
12812 "split_di (operands, 1, operands + 4, operands + 5);")
12813
12814 (define_insn "*rotrdi3_1_one_bit_rex64"
12815 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12816 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12817 (match_operand:QI 2 "const1_operand" "")))
12818 (clobber (reg:CC FLAGS_REG))]
12819 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12820 && (TARGET_SHIFT1 || optimize_size)"
12821 "ror{q}\t%0"
12822 [(set_attr "type" "rotate")
12823 (set (attr "length")
12824 (if_then_else (match_operand:DI 0 "register_operand" "")
12825 (const_string "2")
12826 (const_string "*")))])
12827
12828 (define_insn "*rotrdi3_1_rex64"
12829 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12830 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12831 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12832 (clobber (reg:CC FLAGS_REG))]
12833 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12834 "@
12835 ror{q}\t{%2, %0|%0, %2}
12836 ror{q}\t{%b2, %0|%0, %b2}"
12837 [(set_attr "type" "rotate")
12838 (set_attr "mode" "DI")])
12839
12840 (define_expand "rotrsi3"
12841 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12842 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12843 (match_operand:QI 2 "nonmemory_operand" "")))
12844 (clobber (reg:CC FLAGS_REG))]
12845 ""
12846 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12847
12848 (define_insn "*rotrsi3_1_one_bit"
12849 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12850 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12851 (match_operand:QI 2 "const1_operand" "")))
12852 (clobber (reg:CC FLAGS_REG))]
12853 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12854 && (TARGET_SHIFT1 || optimize_size)"
12855 "ror{l}\t%0"
12856 [(set_attr "type" "rotate")
12857 (set (attr "length")
12858 (if_then_else (match_operand:SI 0 "register_operand" "")
12859 (const_string "2")
12860 (const_string "*")))])
12861
12862 (define_insn "*rotrsi3_1_one_bit_zext"
12863 [(set (match_operand:DI 0 "register_operand" "=r")
12864 (zero_extend:DI
12865 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12866 (match_operand:QI 2 "const1_operand" ""))))
12867 (clobber (reg:CC FLAGS_REG))]
12868 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12869 && (TARGET_SHIFT1 || optimize_size)"
12870 "ror{l}\t%k0"
12871 [(set_attr "type" "rotate")
12872 (set (attr "length")
12873 (if_then_else (match_operand:SI 0 "register_operand" "")
12874 (const_string "2")
12875 (const_string "*")))])
12876
12877 (define_insn "*rotrsi3_1"
12878 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12879 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12880 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12881 (clobber (reg:CC FLAGS_REG))]
12882 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12883 "@
12884 ror{l}\t{%2, %0|%0, %2}
12885 ror{l}\t{%b2, %0|%0, %b2}"
12886 [(set_attr "type" "rotate")
12887 (set_attr "mode" "SI")])
12888
12889 (define_insn "*rotrsi3_1_zext"
12890 [(set (match_operand:DI 0 "register_operand" "=r,r")
12891 (zero_extend:DI
12892 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12893 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12894 (clobber (reg:CC FLAGS_REG))]
12895 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12896 "@
12897 ror{l}\t{%2, %k0|%k0, %2}
12898 ror{l}\t{%b2, %k0|%k0, %b2}"
12899 [(set_attr "type" "rotate")
12900 (set_attr "mode" "SI")])
12901
12902 (define_expand "rotrhi3"
12903 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12904 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12905 (match_operand:QI 2 "nonmemory_operand" "")))
12906 (clobber (reg:CC FLAGS_REG))]
12907 "TARGET_HIMODE_MATH"
12908 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12909
12910 (define_insn "*rotrhi3_one_bit"
12911 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12912 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12913 (match_operand:QI 2 "const1_operand" "")))
12914 (clobber (reg:CC FLAGS_REG))]
12915 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12916 && (TARGET_SHIFT1 || optimize_size)"
12917 "ror{w}\t%0"
12918 [(set_attr "type" "rotate")
12919 (set (attr "length")
12920 (if_then_else (match_operand 0 "register_operand" "")
12921 (const_string "2")
12922 (const_string "*")))])
12923
12924 (define_insn "*rotrhi3"
12925 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12926 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12927 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12928 (clobber (reg:CC FLAGS_REG))]
12929 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12930 "@
12931 ror{w}\t{%2, %0|%0, %2}
12932 ror{w}\t{%b2, %0|%0, %b2}"
12933 [(set_attr "type" "rotate")
12934 (set_attr "mode" "HI")])
12935
12936 (define_expand "rotrqi3"
12937 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12938 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12939 (match_operand:QI 2 "nonmemory_operand" "")))
12940 (clobber (reg:CC FLAGS_REG))]
12941 "TARGET_QIMODE_MATH"
12942 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12943
12944 (define_insn "*rotrqi3_1_one_bit"
12945 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12946 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12947 (match_operand:QI 2 "const1_operand" "")))
12948 (clobber (reg:CC FLAGS_REG))]
12949 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12950 && (TARGET_SHIFT1 || optimize_size)"
12951 "ror{b}\t%0"
12952 [(set_attr "type" "rotate")
12953 (set (attr "length")
12954 (if_then_else (match_operand 0 "register_operand" "")
12955 (const_string "2")
12956 (const_string "*")))])
12957
12958 (define_insn "*rotrqi3_1_one_bit_slp"
12959 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12960 (rotatert:QI (match_dup 0)
12961 (match_operand:QI 1 "const1_operand" "")))
12962 (clobber (reg:CC FLAGS_REG))]
12963 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12964 && (TARGET_SHIFT1 || optimize_size)"
12965 "ror{b}\t%0"
12966 [(set_attr "type" "rotate1")
12967 (set (attr "length")
12968 (if_then_else (match_operand 0 "register_operand" "")
12969 (const_string "2")
12970 (const_string "*")))])
12971
12972 (define_insn "*rotrqi3_1"
12973 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12974 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12975 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12976 (clobber (reg:CC FLAGS_REG))]
12977 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12978 "@
12979 ror{b}\t{%2, %0|%0, %2}
12980 ror{b}\t{%b2, %0|%0, %b2}"
12981 [(set_attr "type" "rotate")
12982 (set_attr "mode" "QI")])
12983
12984 (define_insn "*rotrqi3_1_slp"
12985 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12986 (rotatert:QI (match_dup 0)
12987 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12988 (clobber (reg:CC FLAGS_REG))]
12989 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12990 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12991 "@
12992 ror{b}\t{%1, %0|%0, %1}
12993 ror{b}\t{%b1, %0|%0, %b1}"
12994 [(set_attr "type" "rotate1")
12995 (set_attr "mode" "QI")])
12996 \f
12997 ;; Bit set / bit test instructions
12998
12999 (define_expand "extv"
13000 [(set (match_operand:SI 0 "register_operand" "")
13001 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13002 (match_operand:SI 2 "const8_operand" "")
13003 (match_operand:SI 3 "const8_operand" "")))]
13004 ""
13005 {
13006 /* Handle extractions from %ah et al. */
13007 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13008 FAIL;
13009
13010 /* From mips.md: extract_bit_field doesn't verify that our source
13011 matches the predicate, so check it again here. */
13012 if (! ext_register_operand (operands[1], VOIDmode))
13013 FAIL;
13014 })
13015
13016 (define_expand "extzv"
13017 [(set (match_operand:SI 0 "register_operand" "")
13018 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13019 (match_operand:SI 2 "const8_operand" "")
13020 (match_operand:SI 3 "const8_operand" "")))]
13021 ""
13022 {
13023 /* Handle extractions from %ah et al. */
13024 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13025 FAIL;
13026
13027 /* From mips.md: extract_bit_field doesn't verify that our source
13028 matches the predicate, so check it again here. */
13029 if (! ext_register_operand (operands[1], VOIDmode))
13030 FAIL;
13031 })
13032
13033 (define_expand "insv"
13034 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13035 (match_operand 1 "const8_operand" "")
13036 (match_operand 2 "const8_operand" ""))
13037 (match_operand 3 "register_operand" ""))]
13038 ""
13039 {
13040 /* Handle insertions to %ah et al. */
13041 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13042 FAIL;
13043
13044 /* From mips.md: insert_bit_field doesn't verify that our source
13045 matches the predicate, so check it again here. */
13046 if (! ext_register_operand (operands[0], VOIDmode))
13047 FAIL;
13048
13049 if (TARGET_64BIT)
13050 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13051 else
13052 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13053
13054 DONE;
13055 })
13056
13057 ;; %%% bts, btr, btc, bt.
13058 ;; In general these instructions are *slow* when applied to memory,
13059 ;; since they enforce atomic operation. When applied to registers,
13060 ;; it depends on the cpu implementation. They're never faster than
13061 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13062 ;; no point. But in 64-bit, we can't hold the relevant immediates
13063 ;; within the instruction itself, so operating on bits in the high
13064 ;; 32-bits of a register becomes easier.
13065 ;;
13066 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13067 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13068 ;; negdf respectively, so they can never be disabled entirely.
13069
13070 (define_insn "*btsq"
13071 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13072 (const_int 1)
13073 (match_operand:DI 1 "const_0_to_63_operand" ""))
13074 (const_int 1))
13075 (clobber (reg:CC FLAGS_REG))]
13076 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13077 "bts{q} %1,%0"
13078 [(set_attr "type" "alu1")])
13079
13080 (define_insn "*btrq"
13081 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13082 (const_int 1)
13083 (match_operand:DI 1 "const_0_to_63_operand" ""))
13084 (const_int 0))
13085 (clobber (reg:CC FLAGS_REG))]
13086 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13087 "btr{q} %1,%0"
13088 [(set_attr "type" "alu1")])
13089
13090 (define_insn "*btcq"
13091 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13092 (const_int 1)
13093 (match_operand:DI 1 "const_0_to_63_operand" ""))
13094 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13095 (clobber (reg:CC FLAGS_REG))]
13096 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13097 "btc{q} %1,%0"
13098 [(set_attr "type" "alu1")])
13099
13100 ;; Allow Nocona to avoid these instructions if a register is available.
13101
13102 (define_peephole2
13103 [(match_scratch:DI 2 "r")
13104 (parallel [(set (zero_extract:DI
13105 (match_operand:DI 0 "register_operand" "")
13106 (const_int 1)
13107 (match_operand:DI 1 "const_0_to_63_operand" ""))
13108 (const_int 1))
13109 (clobber (reg:CC FLAGS_REG))])]
13110 "TARGET_64BIT && !TARGET_USE_BT"
13111 [(const_int 0)]
13112 {
13113 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13114 rtx op1;
13115
13116 if (HOST_BITS_PER_WIDE_INT >= 64)
13117 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13118 else if (i < HOST_BITS_PER_WIDE_INT)
13119 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13120 else
13121 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13122
13123 op1 = immed_double_const (lo, hi, DImode);
13124 if (i >= 31)
13125 {
13126 emit_move_insn (operands[2], op1);
13127 op1 = operands[2];
13128 }
13129
13130 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13131 DONE;
13132 })
13133
13134 (define_peephole2
13135 [(match_scratch:DI 2 "r")
13136 (parallel [(set (zero_extract:DI
13137 (match_operand:DI 0 "register_operand" "")
13138 (const_int 1)
13139 (match_operand:DI 1 "const_0_to_63_operand" ""))
13140 (const_int 0))
13141 (clobber (reg:CC FLAGS_REG))])]
13142 "TARGET_64BIT && !TARGET_USE_BT"
13143 [(const_int 0)]
13144 {
13145 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13146 rtx op1;
13147
13148 if (HOST_BITS_PER_WIDE_INT >= 64)
13149 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13150 else if (i < HOST_BITS_PER_WIDE_INT)
13151 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13152 else
13153 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13154
13155 op1 = immed_double_const (~lo, ~hi, DImode);
13156 if (i >= 32)
13157 {
13158 emit_move_insn (operands[2], op1);
13159 op1 = operands[2];
13160 }
13161
13162 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13163 DONE;
13164 })
13165
13166 (define_peephole2
13167 [(match_scratch:DI 2 "r")
13168 (parallel [(set (zero_extract:DI
13169 (match_operand:DI 0 "register_operand" "")
13170 (const_int 1)
13171 (match_operand:DI 1 "const_0_to_63_operand" ""))
13172 (not:DI (zero_extract:DI
13173 (match_dup 0) (const_int 1) (match_dup 1))))
13174 (clobber (reg:CC FLAGS_REG))])]
13175 "TARGET_64BIT && !TARGET_USE_BT"
13176 [(const_int 0)]
13177 {
13178 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13179 rtx op1;
13180
13181 if (HOST_BITS_PER_WIDE_INT >= 64)
13182 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13183 else if (i < HOST_BITS_PER_WIDE_INT)
13184 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13185 else
13186 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13187
13188 op1 = immed_double_const (lo, hi, DImode);
13189 if (i >= 31)
13190 {
13191 emit_move_insn (operands[2], op1);
13192 op1 = operands[2];
13193 }
13194
13195 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13196 DONE;
13197 })
13198 \f
13199 ;; Store-flag instructions.
13200
13201 ;; For all sCOND expanders, also expand the compare or test insn that
13202 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13203
13204 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13205 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13206 ;; way, which can later delete the movzx if only QImode is needed.
13207
13208 (define_expand "seq"
13209 [(set (match_operand:QI 0 "register_operand" "")
13210 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13211 ""
13212 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13213
13214 (define_expand "sne"
13215 [(set (match_operand:QI 0 "register_operand" "")
13216 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13217 ""
13218 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13219
13220 (define_expand "sgt"
13221 [(set (match_operand:QI 0 "register_operand" "")
13222 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13223 ""
13224 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13225
13226 (define_expand "sgtu"
13227 [(set (match_operand:QI 0 "register_operand" "")
13228 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13229 ""
13230 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13231
13232 (define_expand "slt"
13233 [(set (match_operand:QI 0 "register_operand" "")
13234 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13235 ""
13236 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13237
13238 (define_expand "sltu"
13239 [(set (match_operand:QI 0 "register_operand" "")
13240 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13241 ""
13242 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13243
13244 (define_expand "sge"
13245 [(set (match_operand:QI 0 "register_operand" "")
13246 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13247 ""
13248 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13249
13250 (define_expand "sgeu"
13251 [(set (match_operand:QI 0 "register_operand" "")
13252 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13253 ""
13254 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13255
13256 (define_expand "sle"
13257 [(set (match_operand:QI 0 "register_operand" "")
13258 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13259 ""
13260 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13261
13262 (define_expand "sleu"
13263 [(set (match_operand:QI 0 "register_operand" "")
13264 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13265 ""
13266 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13267
13268 (define_expand "sunordered"
13269 [(set (match_operand:QI 0 "register_operand" "")
13270 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13271 "TARGET_80387 || TARGET_SSE"
13272 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13273
13274 (define_expand "sordered"
13275 [(set (match_operand:QI 0 "register_operand" "")
13276 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13277 "TARGET_80387"
13278 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13279
13280 (define_expand "suneq"
13281 [(set (match_operand:QI 0 "register_operand" "")
13282 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13283 "TARGET_80387 || TARGET_SSE"
13284 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13285
13286 (define_expand "sunge"
13287 [(set (match_operand:QI 0 "register_operand" "")
13288 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13289 "TARGET_80387 || TARGET_SSE"
13290 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13291
13292 (define_expand "sungt"
13293 [(set (match_operand:QI 0 "register_operand" "")
13294 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13295 "TARGET_80387 || TARGET_SSE"
13296 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13297
13298 (define_expand "sunle"
13299 [(set (match_operand:QI 0 "register_operand" "")
13300 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13301 "TARGET_80387 || TARGET_SSE"
13302 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13303
13304 (define_expand "sunlt"
13305 [(set (match_operand:QI 0 "register_operand" "")
13306 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13307 "TARGET_80387 || TARGET_SSE"
13308 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13309
13310 (define_expand "sltgt"
13311 [(set (match_operand:QI 0 "register_operand" "")
13312 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13313 "TARGET_80387 || TARGET_SSE"
13314 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13315
13316 (define_insn "*setcc_1"
13317 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13318 (match_operator:QI 1 "ix86_comparison_operator"
13319 [(reg FLAGS_REG) (const_int 0)]))]
13320 ""
13321 "set%C1\t%0"
13322 [(set_attr "type" "setcc")
13323 (set_attr "mode" "QI")])
13324
13325 (define_insn "*setcc_2"
13326 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13327 (match_operator:QI 1 "ix86_comparison_operator"
13328 [(reg FLAGS_REG) (const_int 0)]))]
13329 ""
13330 "set%C1\t%0"
13331 [(set_attr "type" "setcc")
13332 (set_attr "mode" "QI")])
13333
13334 ;; In general it is not safe to assume too much about CCmode registers,
13335 ;; so simplify-rtx stops when it sees a second one. Under certain
13336 ;; conditions this is safe on x86, so help combine not create
13337 ;;
13338 ;; seta %al
13339 ;; testb %al, %al
13340 ;; sete %al
13341
13342 (define_split
13343 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13344 (ne:QI (match_operator 1 "ix86_comparison_operator"
13345 [(reg FLAGS_REG) (const_int 0)])
13346 (const_int 0)))]
13347 ""
13348 [(set (match_dup 0) (match_dup 1))]
13349 {
13350 PUT_MODE (operands[1], QImode);
13351 })
13352
13353 (define_split
13354 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13355 (ne:QI (match_operator 1 "ix86_comparison_operator"
13356 [(reg FLAGS_REG) (const_int 0)])
13357 (const_int 0)))]
13358 ""
13359 [(set (match_dup 0) (match_dup 1))]
13360 {
13361 PUT_MODE (operands[1], QImode);
13362 })
13363
13364 (define_split
13365 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13366 (eq:QI (match_operator 1 "ix86_comparison_operator"
13367 [(reg FLAGS_REG) (const_int 0)])
13368 (const_int 0)))]
13369 ""
13370 [(set (match_dup 0) (match_dup 1))]
13371 {
13372 rtx new_op1 = copy_rtx (operands[1]);
13373 operands[1] = new_op1;
13374 PUT_MODE (new_op1, QImode);
13375 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13376 GET_MODE (XEXP (new_op1, 0))));
13377
13378 /* Make sure that (a) the CCmode we have for the flags is strong
13379 enough for the reversed compare or (b) we have a valid FP compare. */
13380 if (! ix86_comparison_operator (new_op1, VOIDmode))
13381 FAIL;
13382 })
13383
13384 (define_split
13385 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13386 (eq:QI (match_operator 1 "ix86_comparison_operator"
13387 [(reg FLAGS_REG) (const_int 0)])
13388 (const_int 0)))]
13389 ""
13390 [(set (match_dup 0) (match_dup 1))]
13391 {
13392 rtx new_op1 = copy_rtx (operands[1]);
13393 operands[1] = new_op1;
13394 PUT_MODE (new_op1, QImode);
13395 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13396 GET_MODE (XEXP (new_op1, 0))));
13397
13398 /* Make sure that (a) the CCmode we have for the flags is strong
13399 enough for the reversed compare or (b) we have a valid FP compare. */
13400 if (! ix86_comparison_operator (new_op1, VOIDmode))
13401 FAIL;
13402 })
13403
13404 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13405 ;; subsequent logical operations are used to imitate conditional moves.
13406 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13407 ;; it directly.
13408
13409 (define_insn "*sse_setccsf"
13410 [(set (match_operand:SF 0 "register_operand" "=x")
13411 (match_operator:SF 1 "sse_comparison_operator"
13412 [(match_operand:SF 2 "register_operand" "0")
13413 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13414 "TARGET_SSE"
13415 "cmp%D1ss\t{%3, %0|%0, %3}"
13416 [(set_attr "type" "ssecmp")
13417 (set_attr "mode" "SF")])
13418
13419 (define_insn "*sse_setccdf"
13420 [(set (match_operand:DF 0 "register_operand" "=Y")
13421 (match_operator:DF 1 "sse_comparison_operator"
13422 [(match_operand:DF 2 "register_operand" "0")
13423 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13424 "TARGET_SSE2"
13425 "cmp%D1sd\t{%3, %0|%0, %3}"
13426 [(set_attr "type" "ssecmp")
13427 (set_attr "mode" "DF")])
13428 \f
13429 ;; Basic conditional jump instructions.
13430 ;; We ignore the overflow flag for signed branch instructions.
13431
13432 ;; For all bCOND expanders, also expand the compare or test insn that
13433 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13434
13435 (define_expand "beq"
13436 [(set (pc)
13437 (if_then_else (match_dup 1)
13438 (label_ref (match_operand 0 "" ""))
13439 (pc)))]
13440 ""
13441 "ix86_expand_branch (EQ, operands[0]); DONE;")
13442
13443 (define_expand "bne"
13444 [(set (pc)
13445 (if_then_else (match_dup 1)
13446 (label_ref (match_operand 0 "" ""))
13447 (pc)))]
13448 ""
13449 "ix86_expand_branch (NE, operands[0]); DONE;")
13450
13451 (define_expand "bgt"
13452 [(set (pc)
13453 (if_then_else (match_dup 1)
13454 (label_ref (match_operand 0 "" ""))
13455 (pc)))]
13456 ""
13457 "ix86_expand_branch (GT, operands[0]); DONE;")
13458
13459 (define_expand "bgtu"
13460 [(set (pc)
13461 (if_then_else (match_dup 1)
13462 (label_ref (match_operand 0 "" ""))
13463 (pc)))]
13464 ""
13465 "ix86_expand_branch (GTU, operands[0]); DONE;")
13466
13467 (define_expand "blt"
13468 [(set (pc)
13469 (if_then_else (match_dup 1)
13470 (label_ref (match_operand 0 "" ""))
13471 (pc)))]
13472 ""
13473 "ix86_expand_branch (LT, operands[0]); DONE;")
13474
13475 (define_expand "bltu"
13476 [(set (pc)
13477 (if_then_else (match_dup 1)
13478 (label_ref (match_operand 0 "" ""))
13479 (pc)))]
13480 ""
13481 "ix86_expand_branch (LTU, operands[0]); DONE;")
13482
13483 (define_expand "bge"
13484 [(set (pc)
13485 (if_then_else (match_dup 1)
13486 (label_ref (match_operand 0 "" ""))
13487 (pc)))]
13488 ""
13489 "ix86_expand_branch (GE, operands[0]); DONE;")
13490
13491 (define_expand "bgeu"
13492 [(set (pc)
13493 (if_then_else (match_dup 1)
13494 (label_ref (match_operand 0 "" ""))
13495 (pc)))]
13496 ""
13497 "ix86_expand_branch (GEU, operands[0]); DONE;")
13498
13499 (define_expand "ble"
13500 [(set (pc)
13501 (if_then_else (match_dup 1)
13502 (label_ref (match_operand 0 "" ""))
13503 (pc)))]
13504 ""
13505 "ix86_expand_branch (LE, operands[0]); DONE;")
13506
13507 (define_expand "bleu"
13508 [(set (pc)
13509 (if_then_else (match_dup 1)
13510 (label_ref (match_operand 0 "" ""))
13511 (pc)))]
13512 ""
13513 "ix86_expand_branch (LEU, operands[0]); DONE;")
13514
13515 (define_expand "bunordered"
13516 [(set (pc)
13517 (if_then_else (match_dup 1)
13518 (label_ref (match_operand 0 "" ""))
13519 (pc)))]
13520 "TARGET_80387 || TARGET_SSE_MATH"
13521 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13522
13523 (define_expand "bordered"
13524 [(set (pc)
13525 (if_then_else (match_dup 1)
13526 (label_ref (match_operand 0 "" ""))
13527 (pc)))]
13528 "TARGET_80387 || TARGET_SSE_MATH"
13529 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13530
13531 (define_expand "buneq"
13532 [(set (pc)
13533 (if_then_else (match_dup 1)
13534 (label_ref (match_operand 0 "" ""))
13535 (pc)))]
13536 "TARGET_80387 || TARGET_SSE_MATH"
13537 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13538
13539 (define_expand "bunge"
13540 [(set (pc)
13541 (if_then_else (match_dup 1)
13542 (label_ref (match_operand 0 "" ""))
13543 (pc)))]
13544 "TARGET_80387 || TARGET_SSE_MATH"
13545 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13546
13547 (define_expand "bungt"
13548 [(set (pc)
13549 (if_then_else (match_dup 1)
13550 (label_ref (match_operand 0 "" ""))
13551 (pc)))]
13552 "TARGET_80387 || TARGET_SSE_MATH"
13553 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13554
13555 (define_expand "bunle"
13556 [(set (pc)
13557 (if_then_else (match_dup 1)
13558 (label_ref (match_operand 0 "" ""))
13559 (pc)))]
13560 "TARGET_80387 || TARGET_SSE_MATH"
13561 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13562
13563 (define_expand "bunlt"
13564 [(set (pc)
13565 (if_then_else (match_dup 1)
13566 (label_ref (match_operand 0 "" ""))
13567 (pc)))]
13568 "TARGET_80387 || TARGET_SSE_MATH"
13569 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13570
13571 (define_expand "bltgt"
13572 [(set (pc)
13573 (if_then_else (match_dup 1)
13574 (label_ref (match_operand 0 "" ""))
13575 (pc)))]
13576 "TARGET_80387 || TARGET_SSE_MATH"
13577 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13578
13579 (define_insn "*jcc_1"
13580 [(set (pc)
13581 (if_then_else (match_operator 1 "ix86_comparison_operator"
13582 [(reg FLAGS_REG) (const_int 0)])
13583 (label_ref (match_operand 0 "" ""))
13584 (pc)))]
13585 ""
13586 "%+j%C1\t%l0"
13587 [(set_attr "type" "ibr")
13588 (set_attr "modrm" "0")
13589 (set (attr "length")
13590 (if_then_else (and (ge (minus (match_dup 0) (pc))
13591 (const_int -126))
13592 (lt (minus (match_dup 0) (pc))
13593 (const_int 128)))
13594 (const_int 2)
13595 (const_int 6)))])
13596
13597 (define_insn "*jcc_2"
13598 [(set (pc)
13599 (if_then_else (match_operator 1 "ix86_comparison_operator"
13600 [(reg FLAGS_REG) (const_int 0)])
13601 (pc)
13602 (label_ref (match_operand 0 "" ""))))]
13603 ""
13604 "%+j%c1\t%l0"
13605 [(set_attr "type" "ibr")
13606 (set_attr "modrm" "0")
13607 (set (attr "length")
13608 (if_then_else (and (ge (minus (match_dup 0) (pc))
13609 (const_int -126))
13610 (lt (minus (match_dup 0) (pc))
13611 (const_int 128)))
13612 (const_int 2)
13613 (const_int 6)))])
13614
13615 ;; In general it is not safe to assume too much about CCmode registers,
13616 ;; so simplify-rtx stops when it sees a second one. Under certain
13617 ;; conditions this is safe on x86, so help combine not create
13618 ;;
13619 ;; seta %al
13620 ;; testb %al, %al
13621 ;; je Lfoo
13622
13623 (define_split
13624 [(set (pc)
13625 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13626 [(reg FLAGS_REG) (const_int 0)])
13627 (const_int 0))
13628 (label_ref (match_operand 1 "" ""))
13629 (pc)))]
13630 ""
13631 [(set (pc)
13632 (if_then_else (match_dup 0)
13633 (label_ref (match_dup 1))
13634 (pc)))]
13635 {
13636 PUT_MODE (operands[0], VOIDmode);
13637 })
13638
13639 (define_split
13640 [(set (pc)
13641 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13642 [(reg FLAGS_REG) (const_int 0)])
13643 (const_int 0))
13644 (label_ref (match_operand 1 "" ""))
13645 (pc)))]
13646 ""
13647 [(set (pc)
13648 (if_then_else (match_dup 0)
13649 (label_ref (match_dup 1))
13650 (pc)))]
13651 {
13652 rtx new_op0 = copy_rtx (operands[0]);
13653 operands[0] = new_op0;
13654 PUT_MODE (new_op0, VOIDmode);
13655 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13656 GET_MODE (XEXP (new_op0, 0))));
13657
13658 /* Make sure that (a) the CCmode we have for the flags is strong
13659 enough for the reversed compare or (b) we have a valid FP compare. */
13660 if (! ix86_comparison_operator (new_op0, VOIDmode))
13661 FAIL;
13662 })
13663
13664 ;; Define combination compare-and-branch fp compare instructions to use
13665 ;; during early optimization. Splitting the operation apart early makes
13666 ;; for bad code when we want to reverse the operation.
13667
13668 (define_insn "*fp_jcc_1_mixed"
13669 [(set (pc)
13670 (if_then_else (match_operator 0 "comparison_operator"
13671 [(match_operand 1 "register_operand" "f,x")
13672 (match_operand 2 "nonimmediate_operand" "f,xm")])
13673 (label_ref (match_operand 3 "" ""))
13674 (pc)))
13675 (clobber (reg:CCFP FPSR_REG))
13676 (clobber (reg:CCFP FLAGS_REG))]
13677 "TARGET_MIX_SSE_I387
13678 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13679 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13680 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13681 "#")
13682
13683 (define_insn "*fp_jcc_1_sse"
13684 [(set (pc)
13685 (if_then_else (match_operator 0 "comparison_operator"
13686 [(match_operand 1 "register_operand" "x")
13687 (match_operand 2 "nonimmediate_operand" "xm")])
13688 (label_ref (match_operand 3 "" ""))
13689 (pc)))
13690 (clobber (reg:CCFP FPSR_REG))
13691 (clobber (reg:CCFP FLAGS_REG))]
13692 "TARGET_SSE_MATH
13693 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13694 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13695 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13696 "#")
13697
13698 (define_insn "*fp_jcc_1_387"
13699 [(set (pc)
13700 (if_then_else (match_operator 0 "comparison_operator"
13701 [(match_operand 1 "register_operand" "f")
13702 (match_operand 2 "register_operand" "f")])
13703 (label_ref (match_operand 3 "" ""))
13704 (pc)))
13705 (clobber (reg:CCFP FPSR_REG))
13706 (clobber (reg:CCFP FLAGS_REG))]
13707 "TARGET_CMOVE && TARGET_80387
13708 && FLOAT_MODE_P (GET_MODE (operands[1]))
13709 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13710 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13711 "#")
13712
13713 (define_insn "*fp_jcc_2_mixed"
13714 [(set (pc)
13715 (if_then_else (match_operator 0 "comparison_operator"
13716 [(match_operand 1 "register_operand" "f,x")
13717 (match_operand 2 "nonimmediate_operand" "f,xm")])
13718 (pc)
13719 (label_ref (match_operand 3 "" ""))))
13720 (clobber (reg:CCFP FPSR_REG))
13721 (clobber (reg:CCFP FLAGS_REG))]
13722 "TARGET_MIX_SSE_I387
13723 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13724 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13725 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13726 "#")
13727
13728 (define_insn "*fp_jcc_2_sse"
13729 [(set (pc)
13730 (if_then_else (match_operator 0 "comparison_operator"
13731 [(match_operand 1 "register_operand" "x")
13732 (match_operand 2 "nonimmediate_operand" "xm")])
13733 (pc)
13734 (label_ref (match_operand 3 "" ""))))
13735 (clobber (reg:CCFP FPSR_REG))
13736 (clobber (reg:CCFP FLAGS_REG))]
13737 "TARGET_SSE_MATH
13738 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13739 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13740 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13741 "#")
13742
13743 (define_insn "*fp_jcc_2_387"
13744 [(set (pc)
13745 (if_then_else (match_operator 0 "comparison_operator"
13746 [(match_operand 1 "register_operand" "f")
13747 (match_operand 2 "register_operand" "f")])
13748 (pc)
13749 (label_ref (match_operand 3 "" ""))))
13750 (clobber (reg:CCFP FPSR_REG))
13751 (clobber (reg:CCFP FLAGS_REG))]
13752 "TARGET_CMOVE && TARGET_80387
13753 && FLOAT_MODE_P (GET_MODE (operands[1]))
13754 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13755 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13756 "#")
13757
13758 (define_insn "*fp_jcc_3_387"
13759 [(set (pc)
13760 (if_then_else (match_operator 0 "comparison_operator"
13761 [(match_operand 1 "register_operand" "f")
13762 (match_operand 2 "nonimmediate_operand" "fm")])
13763 (label_ref (match_operand 3 "" ""))
13764 (pc)))
13765 (clobber (reg:CCFP FPSR_REG))
13766 (clobber (reg:CCFP FLAGS_REG))
13767 (clobber (match_scratch:HI 4 "=a"))]
13768 "TARGET_80387
13769 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13770 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13772 && SELECT_CC_MODE (GET_CODE (operands[0]),
13773 operands[1], operands[2]) == CCFPmode
13774 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13775 "#")
13776
13777 (define_insn "*fp_jcc_4_387"
13778 [(set (pc)
13779 (if_then_else (match_operator 0 "comparison_operator"
13780 [(match_operand 1 "register_operand" "f")
13781 (match_operand 2 "nonimmediate_operand" "fm")])
13782 (pc)
13783 (label_ref (match_operand 3 "" ""))))
13784 (clobber (reg:CCFP FPSR_REG))
13785 (clobber (reg:CCFP FLAGS_REG))
13786 (clobber (match_scratch:HI 4 "=a"))]
13787 "TARGET_80387
13788 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13789 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13790 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13791 && SELECT_CC_MODE (GET_CODE (operands[0]),
13792 operands[1], operands[2]) == CCFPmode
13793 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13794 "#")
13795
13796 (define_insn "*fp_jcc_5_387"
13797 [(set (pc)
13798 (if_then_else (match_operator 0 "comparison_operator"
13799 [(match_operand 1 "register_operand" "f")
13800 (match_operand 2 "register_operand" "f")])
13801 (label_ref (match_operand 3 "" ""))
13802 (pc)))
13803 (clobber (reg:CCFP FPSR_REG))
13804 (clobber (reg:CCFP FLAGS_REG))
13805 (clobber (match_scratch:HI 4 "=a"))]
13806 "TARGET_80387
13807 && FLOAT_MODE_P (GET_MODE (operands[1]))
13808 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13809 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13810 "#")
13811
13812 (define_insn "*fp_jcc_6_387"
13813 [(set (pc)
13814 (if_then_else (match_operator 0 "comparison_operator"
13815 [(match_operand 1 "register_operand" "f")
13816 (match_operand 2 "register_operand" "f")])
13817 (pc)
13818 (label_ref (match_operand 3 "" ""))))
13819 (clobber (reg:CCFP FPSR_REG))
13820 (clobber (reg:CCFP FLAGS_REG))
13821 (clobber (match_scratch:HI 4 "=a"))]
13822 "TARGET_80387
13823 && FLOAT_MODE_P (GET_MODE (operands[1]))
13824 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13825 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13826 "#")
13827
13828 (define_insn "*fp_jcc_7_387"
13829 [(set (pc)
13830 (if_then_else (match_operator 0 "comparison_operator"
13831 [(match_operand 1 "register_operand" "f")
13832 (match_operand 2 "const0_operand" "X")])
13833 (label_ref (match_operand 3 "" ""))
13834 (pc)))
13835 (clobber (reg:CCFP FPSR_REG))
13836 (clobber (reg:CCFP FLAGS_REG))
13837 (clobber (match_scratch:HI 4 "=a"))]
13838 "TARGET_80387
13839 && FLOAT_MODE_P (GET_MODE (operands[1]))
13840 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13841 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13842 && SELECT_CC_MODE (GET_CODE (operands[0]),
13843 operands[1], operands[2]) == CCFPmode
13844 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13845 "#")
13846
13847 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13848 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13849 ;; with a precedence over other operators and is always put in the first
13850 ;; place. Swap condition and operands to match ficom instruction.
13851
13852 (define_insn "*fp_jcc_8<mode>_387"
13853 [(set (pc)
13854 (if_then_else (match_operator 0 "comparison_operator"
13855 [(match_operator 1 "float_operator"
13856 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13857 (match_operand 3 "register_operand" "f,f")])
13858 (label_ref (match_operand 4 "" ""))
13859 (pc)))
13860 (clobber (reg:CCFP FPSR_REG))
13861 (clobber (reg:CCFP FLAGS_REG))
13862 (clobber (match_scratch:HI 5 "=a,a"))]
13863 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13864 && FLOAT_MODE_P (GET_MODE (operands[3]))
13865 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13866 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13867 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13868 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13869 "#")
13870
13871 (define_split
13872 [(set (pc)
13873 (if_then_else (match_operator 0 "comparison_operator"
13874 [(match_operand 1 "register_operand" "")
13875 (match_operand 2 "nonimmediate_operand" "")])
13876 (match_operand 3 "" "")
13877 (match_operand 4 "" "")))
13878 (clobber (reg:CCFP FPSR_REG))
13879 (clobber (reg:CCFP FLAGS_REG))]
13880 "reload_completed"
13881 [(const_int 0)]
13882 {
13883 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13884 operands[3], operands[4], NULL_RTX, NULL_RTX);
13885 DONE;
13886 })
13887
13888 (define_split
13889 [(set (pc)
13890 (if_then_else (match_operator 0 "comparison_operator"
13891 [(match_operand 1 "register_operand" "")
13892 (match_operand 2 "general_operand" "")])
13893 (match_operand 3 "" "")
13894 (match_operand 4 "" "")))
13895 (clobber (reg:CCFP FPSR_REG))
13896 (clobber (reg:CCFP FLAGS_REG))
13897 (clobber (match_scratch:HI 5 "=a"))]
13898 "reload_completed"
13899 [(const_int 0)]
13900 {
13901 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13902 operands[3], operands[4], operands[5], NULL_RTX);
13903 DONE;
13904 })
13905
13906 (define_split
13907 [(set (pc)
13908 (if_then_else (match_operator 0 "comparison_operator"
13909 [(match_operator 1 "float_operator"
13910 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13911 (match_operand 3 "register_operand" "")])
13912 (match_operand 4 "" "")
13913 (match_operand 5 "" "")))
13914 (clobber (reg:CCFP FPSR_REG))
13915 (clobber (reg:CCFP FLAGS_REG))
13916 (clobber (match_scratch:HI 6 "=a"))]
13917 "reload_completed"
13918 [(const_int 0)]
13919 {
13920 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13921 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13922 operands[3], operands[7],
13923 operands[4], operands[5], operands[6], NULL_RTX);
13924 DONE;
13925 })
13926
13927 ;; %%% Kill this when reload knows how to do it.
13928 (define_split
13929 [(set (pc)
13930 (if_then_else (match_operator 0 "comparison_operator"
13931 [(match_operator 1 "float_operator"
13932 [(match_operand:X87MODEI12 2 "register_operand" "")])
13933 (match_operand 3 "register_operand" "")])
13934 (match_operand 4 "" "")
13935 (match_operand 5 "" "")))
13936 (clobber (reg:CCFP FPSR_REG))
13937 (clobber (reg:CCFP FLAGS_REG))
13938 (clobber (match_scratch:HI 6 "=a"))]
13939 "reload_completed"
13940 [(const_int 0)]
13941 {
13942 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13943 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13944 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13945 operands[3], operands[7],
13946 operands[4], operands[5], operands[6], operands[2]);
13947 DONE;
13948 })
13949 \f
13950 ;; Unconditional and other jump instructions
13951
13952 (define_insn "jump"
13953 [(set (pc)
13954 (label_ref (match_operand 0 "" "")))]
13955 ""
13956 "jmp\t%l0"
13957 [(set_attr "type" "ibr")
13958 (set (attr "length")
13959 (if_then_else (and (ge (minus (match_dup 0) (pc))
13960 (const_int -126))
13961 (lt (minus (match_dup 0) (pc))
13962 (const_int 128)))
13963 (const_int 2)
13964 (const_int 5)))
13965 (set_attr "modrm" "0")])
13966
13967 (define_expand "indirect_jump"
13968 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13969 ""
13970 "")
13971
13972 (define_insn "*indirect_jump"
13973 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13974 "!TARGET_64BIT"
13975 "jmp\t%A0"
13976 [(set_attr "type" "ibr")
13977 (set_attr "length_immediate" "0")])
13978
13979 (define_insn "*indirect_jump_rtx64"
13980 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13981 "TARGET_64BIT"
13982 "jmp\t%A0"
13983 [(set_attr "type" "ibr")
13984 (set_attr "length_immediate" "0")])
13985
13986 (define_expand "tablejump"
13987 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13988 (use (label_ref (match_operand 1 "" "")))])]
13989 ""
13990 {
13991 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13992 relative. Convert the relative address to an absolute address. */
13993 if (flag_pic)
13994 {
13995 rtx op0, op1;
13996 enum rtx_code code;
13997
13998 if (TARGET_64BIT)
13999 {
14000 code = PLUS;
14001 op0 = operands[0];
14002 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14003 }
14004 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14005 {
14006 code = PLUS;
14007 op0 = operands[0];
14008 op1 = pic_offset_table_rtx;
14009 }
14010 else
14011 {
14012 code = MINUS;
14013 op0 = pic_offset_table_rtx;
14014 op1 = operands[0];
14015 }
14016
14017 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14018 OPTAB_DIRECT);
14019 }
14020 })
14021
14022 (define_insn "*tablejump_1"
14023 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14024 (use (label_ref (match_operand 1 "" "")))]
14025 "!TARGET_64BIT"
14026 "jmp\t%A0"
14027 [(set_attr "type" "ibr")
14028 (set_attr "length_immediate" "0")])
14029
14030 (define_insn "*tablejump_1_rtx64"
14031 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14032 (use (label_ref (match_operand 1 "" "")))]
14033 "TARGET_64BIT"
14034 "jmp\t%A0"
14035 [(set_attr "type" "ibr")
14036 (set_attr "length_immediate" "0")])
14037 \f
14038 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14039
14040 (define_peephole2
14041 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14042 (set (match_operand:QI 1 "register_operand" "")
14043 (match_operator:QI 2 "ix86_comparison_operator"
14044 [(reg FLAGS_REG) (const_int 0)]))
14045 (set (match_operand 3 "q_regs_operand" "")
14046 (zero_extend (match_dup 1)))]
14047 "(peep2_reg_dead_p (3, operands[1])
14048 || operands_match_p (operands[1], operands[3]))
14049 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14050 [(set (match_dup 4) (match_dup 0))
14051 (set (strict_low_part (match_dup 5))
14052 (match_dup 2))]
14053 {
14054 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14055 operands[5] = gen_lowpart (QImode, operands[3]);
14056 ix86_expand_clear (operands[3]);
14057 })
14058
14059 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14060
14061 (define_peephole2
14062 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14063 (set (match_operand:QI 1 "register_operand" "")
14064 (match_operator:QI 2 "ix86_comparison_operator"
14065 [(reg FLAGS_REG) (const_int 0)]))
14066 (parallel [(set (match_operand 3 "q_regs_operand" "")
14067 (zero_extend (match_dup 1)))
14068 (clobber (reg:CC FLAGS_REG))])]
14069 "(peep2_reg_dead_p (3, operands[1])
14070 || operands_match_p (operands[1], operands[3]))
14071 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14072 [(set (match_dup 4) (match_dup 0))
14073 (set (strict_low_part (match_dup 5))
14074 (match_dup 2))]
14075 {
14076 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14077 operands[5] = gen_lowpart (QImode, operands[3]);
14078 ix86_expand_clear (operands[3]);
14079 })
14080 \f
14081 ;; Call instructions.
14082
14083 ;; The predicates normally associated with named expanders are not properly
14084 ;; checked for calls. This is a bug in the generic code, but it isn't that
14085 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14086
14087 ;; Call subroutine returning no value.
14088
14089 (define_expand "call_pop"
14090 [(parallel [(call (match_operand:QI 0 "" "")
14091 (match_operand:SI 1 "" ""))
14092 (set (reg:SI SP_REG)
14093 (plus:SI (reg:SI SP_REG)
14094 (match_operand:SI 3 "" "")))])]
14095 "!TARGET_64BIT"
14096 {
14097 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14098 DONE;
14099 })
14100
14101 (define_insn "*call_pop_0"
14102 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14103 (match_operand:SI 1 "" ""))
14104 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14105 (match_operand:SI 2 "immediate_operand" "")))]
14106 "!TARGET_64BIT"
14107 {
14108 if (SIBLING_CALL_P (insn))
14109 return "jmp\t%P0";
14110 else
14111 return "call\t%P0";
14112 }
14113 [(set_attr "type" "call")])
14114
14115 (define_insn "*call_pop_1"
14116 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14117 (match_operand:SI 1 "" ""))
14118 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14119 (match_operand:SI 2 "immediate_operand" "i")))]
14120 "!TARGET_64BIT"
14121 {
14122 if (constant_call_address_operand (operands[0], Pmode))
14123 {
14124 if (SIBLING_CALL_P (insn))
14125 return "jmp\t%P0";
14126 else
14127 return "call\t%P0";
14128 }
14129 if (SIBLING_CALL_P (insn))
14130 return "jmp\t%A0";
14131 else
14132 return "call\t%A0";
14133 }
14134 [(set_attr "type" "call")])
14135
14136 (define_expand "call"
14137 [(call (match_operand:QI 0 "" "")
14138 (match_operand 1 "" ""))
14139 (use (match_operand 2 "" ""))]
14140 ""
14141 {
14142 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14143 DONE;
14144 })
14145
14146 (define_expand "sibcall"
14147 [(call (match_operand:QI 0 "" "")
14148 (match_operand 1 "" ""))
14149 (use (match_operand 2 "" ""))]
14150 ""
14151 {
14152 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14153 DONE;
14154 })
14155
14156 (define_insn "*call_0"
14157 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14158 (match_operand 1 "" ""))]
14159 ""
14160 {
14161 if (SIBLING_CALL_P (insn))
14162 return "jmp\t%P0";
14163 else
14164 return "call\t%P0";
14165 }
14166 [(set_attr "type" "call")])
14167
14168 (define_insn "*call_1"
14169 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14170 (match_operand 1 "" ""))]
14171 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14172 {
14173 if (constant_call_address_operand (operands[0], Pmode))
14174 return "call\t%P0";
14175 return "call\t%A0";
14176 }
14177 [(set_attr "type" "call")])
14178
14179 (define_insn "*sibcall_1"
14180 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14181 (match_operand 1 "" ""))]
14182 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14183 {
14184 if (constant_call_address_operand (operands[0], Pmode))
14185 return "jmp\t%P0";
14186 return "jmp\t%A0";
14187 }
14188 [(set_attr "type" "call")])
14189
14190 (define_insn "*call_1_rex64"
14191 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14192 (match_operand 1 "" ""))]
14193 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14194 {
14195 if (constant_call_address_operand (operands[0], Pmode))
14196 return "call\t%P0";
14197 return "call\t%A0";
14198 }
14199 [(set_attr "type" "call")])
14200
14201 (define_insn "*sibcall_1_rex64"
14202 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14203 (match_operand 1 "" ""))]
14204 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14205 "jmp\t%P0"
14206 [(set_attr "type" "call")])
14207
14208 (define_insn "*sibcall_1_rex64_v"
14209 [(call (mem:QI (reg:DI R11_REG))
14210 (match_operand 0 "" ""))]
14211 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14212 "jmp\t*%%r11"
14213 [(set_attr "type" "call")])
14214
14215
14216 ;; Call subroutine, returning value in operand 0
14217
14218 (define_expand "call_value_pop"
14219 [(parallel [(set (match_operand 0 "" "")
14220 (call (match_operand:QI 1 "" "")
14221 (match_operand:SI 2 "" "")))
14222 (set (reg:SI SP_REG)
14223 (plus:SI (reg:SI SP_REG)
14224 (match_operand:SI 4 "" "")))])]
14225 "!TARGET_64BIT"
14226 {
14227 ix86_expand_call (operands[0], operands[1], operands[2],
14228 operands[3], operands[4], 0);
14229 DONE;
14230 })
14231
14232 (define_expand "call_value"
14233 [(set (match_operand 0 "" "")
14234 (call (match_operand:QI 1 "" "")
14235 (match_operand:SI 2 "" "")))
14236 (use (match_operand:SI 3 "" ""))]
14237 ;; Operand 2 not used on the i386.
14238 ""
14239 {
14240 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14241 DONE;
14242 })
14243
14244 (define_expand "sibcall_value"
14245 [(set (match_operand 0 "" "")
14246 (call (match_operand:QI 1 "" "")
14247 (match_operand:SI 2 "" "")))
14248 (use (match_operand:SI 3 "" ""))]
14249 ;; Operand 2 not used on the i386.
14250 ""
14251 {
14252 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14253 DONE;
14254 })
14255
14256 ;; Call subroutine returning any type.
14257
14258 (define_expand "untyped_call"
14259 [(parallel [(call (match_operand 0 "" "")
14260 (const_int 0))
14261 (match_operand 1 "" "")
14262 (match_operand 2 "" "")])]
14263 ""
14264 {
14265 int i;
14266
14267 /* In order to give reg-stack an easier job in validating two
14268 coprocessor registers as containing a possible return value,
14269 simply pretend the untyped call returns a complex long double
14270 value. */
14271
14272 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14273 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14274 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14275 NULL, 0);
14276
14277 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14278 {
14279 rtx set = XVECEXP (operands[2], 0, i);
14280 emit_move_insn (SET_DEST (set), SET_SRC (set));
14281 }
14282
14283 /* The optimizer does not know that the call sets the function value
14284 registers we stored in the result block. We avoid problems by
14285 claiming that all hard registers are used and clobbered at this
14286 point. */
14287 emit_insn (gen_blockage (const0_rtx));
14288
14289 DONE;
14290 })
14291 \f
14292 ;; Prologue and epilogue instructions
14293
14294 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14295 ;; all of memory. This blocks insns from being moved across this point.
14296
14297 (define_insn "blockage"
14298 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14299 ""
14300 ""
14301 [(set_attr "length" "0")])
14302
14303 ;; Insn emitted into the body of a function to return from a function.
14304 ;; This is only done if the function's epilogue is known to be simple.
14305 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14306
14307 (define_expand "return"
14308 [(return)]
14309 "ix86_can_use_return_insn_p ()"
14310 {
14311 if (current_function_pops_args)
14312 {
14313 rtx popc = GEN_INT (current_function_pops_args);
14314 emit_jump_insn (gen_return_pop_internal (popc));
14315 DONE;
14316 }
14317 })
14318
14319 (define_insn "return_internal"
14320 [(return)]
14321 "reload_completed"
14322 "ret"
14323 [(set_attr "length" "1")
14324 (set_attr "length_immediate" "0")
14325 (set_attr "modrm" "0")])
14326
14327 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14328 ;; instruction Athlon and K8 have.
14329
14330 (define_insn "return_internal_long"
14331 [(return)
14332 (unspec [(const_int 0)] UNSPEC_REP)]
14333 "reload_completed"
14334 "rep {;} ret"
14335 [(set_attr "length" "1")
14336 (set_attr "length_immediate" "0")
14337 (set_attr "prefix_rep" "1")
14338 (set_attr "modrm" "0")])
14339
14340 (define_insn "return_pop_internal"
14341 [(return)
14342 (use (match_operand:SI 0 "const_int_operand" ""))]
14343 "reload_completed"
14344 "ret\t%0"
14345 [(set_attr "length" "3")
14346 (set_attr "length_immediate" "2")
14347 (set_attr "modrm" "0")])
14348
14349 (define_insn "return_indirect_internal"
14350 [(return)
14351 (use (match_operand:SI 0 "register_operand" "r"))]
14352 "reload_completed"
14353 "jmp\t%A0"
14354 [(set_attr "type" "ibr")
14355 (set_attr "length_immediate" "0")])
14356
14357 (define_insn "nop"
14358 [(const_int 0)]
14359 ""
14360 "nop"
14361 [(set_attr "length" "1")
14362 (set_attr "length_immediate" "0")
14363 (set_attr "modrm" "0")])
14364
14365 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14366 ;; branch prediction penalty for the third jump in a 16-byte
14367 ;; block on K8.
14368
14369 (define_insn "align"
14370 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14371 ""
14372 {
14373 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14374 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14375 #else
14376 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14377 The align insn is used to avoid 3 jump instructions in the row to improve
14378 branch prediction and the benefits hardly outweigh the cost of extra 8
14379 nops on the average inserted by full alignment pseudo operation. */
14380 #endif
14381 return "";
14382 }
14383 [(set_attr "length" "16")])
14384
14385 (define_expand "prologue"
14386 [(const_int 1)]
14387 ""
14388 "ix86_expand_prologue (); DONE;")
14389
14390 (define_insn "set_got"
14391 [(set (match_operand:SI 0 "register_operand" "=r")
14392 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14393 (clobber (reg:CC FLAGS_REG))]
14394 "!TARGET_64BIT"
14395 { return output_set_got (operands[0], NULL_RTX); }
14396 [(set_attr "type" "multi")
14397 (set_attr "length" "12")])
14398
14399 (define_insn "set_got_labelled"
14400 [(set (match_operand:SI 0 "register_operand" "=r")
14401 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14402 UNSPEC_SET_GOT))
14403 (clobber (reg:CC FLAGS_REG))]
14404 "!TARGET_64BIT"
14405 { return output_set_got (operands[0], operands[1]); }
14406 [(set_attr "type" "multi")
14407 (set_attr "length" "12")])
14408
14409 (define_insn "set_got_rex64"
14410 [(set (match_operand:DI 0 "register_operand" "=r")
14411 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14412 "TARGET_64BIT"
14413 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14414 [(set_attr "type" "lea")
14415 (set_attr "length" "6")])
14416
14417 (define_expand "epilogue"
14418 [(const_int 1)]
14419 ""
14420 "ix86_expand_epilogue (1); DONE;")
14421
14422 (define_expand "sibcall_epilogue"
14423 [(const_int 1)]
14424 ""
14425 "ix86_expand_epilogue (0); DONE;")
14426
14427 (define_expand "eh_return"
14428 [(use (match_operand 0 "register_operand" ""))]
14429 ""
14430 {
14431 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14432
14433 /* Tricky bit: we write the address of the handler to which we will
14434 be returning into someone else's stack frame, one word below the
14435 stack address we wish to restore. */
14436 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14437 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14438 tmp = gen_rtx_MEM (Pmode, tmp);
14439 emit_move_insn (tmp, ra);
14440
14441 if (Pmode == SImode)
14442 emit_jump_insn (gen_eh_return_si (sa));
14443 else
14444 emit_jump_insn (gen_eh_return_di (sa));
14445 emit_barrier ();
14446 DONE;
14447 })
14448
14449 (define_insn_and_split "eh_return_si"
14450 [(set (pc)
14451 (unspec [(match_operand:SI 0 "register_operand" "c")]
14452 UNSPEC_EH_RETURN))]
14453 "!TARGET_64BIT"
14454 "#"
14455 "reload_completed"
14456 [(const_int 1)]
14457 "ix86_expand_epilogue (2); DONE;")
14458
14459 (define_insn_and_split "eh_return_di"
14460 [(set (pc)
14461 (unspec [(match_operand:DI 0 "register_operand" "c")]
14462 UNSPEC_EH_RETURN))]
14463 "TARGET_64BIT"
14464 "#"
14465 "reload_completed"
14466 [(const_int 1)]
14467 "ix86_expand_epilogue (2); DONE;")
14468
14469 (define_insn "leave"
14470 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14471 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14472 (clobber (mem:BLK (scratch)))]
14473 "!TARGET_64BIT"
14474 "leave"
14475 [(set_attr "type" "leave")])
14476
14477 (define_insn "leave_rex64"
14478 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14479 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14480 (clobber (mem:BLK (scratch)))]
14481 "TARGET_64BIT"
14482 "leave"
14483 [(set_attr "type" "leave")])
14484 \f
14485 (define_expand "ffssi2"
14486 [(parallel
14487 [(set (match_operand:SI 0 "register_operand" "")
14488 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14489 (clobber (match_scratch:SI 2 ""))
14490 (clobber (reg:CC FLAGS_REG))])]
14491 ""
14492 "")
14493
14494 (define_insn_and_split "*ffs_cmove"
14495 [(set (match_operand:SI 0 "register_operand" "=r")
14496 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14497 (clobber (match_scratch:SI 2 "=&r"))
14498 (clobber (reg:CC FLAGS_REG))]
14499 "TARGET_CMOVE"
14500 "#"
14501 "&& reload_completed"
14502 [(set (match_dup 2) (const_int -1))
14503 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14504 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14505 (set (match_dup 0) (if_then_else:SI
14506 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14507 (match_dup 2)
14508 (match_dup 0)))
14509 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14510 (clobber (reg:CC FLAGS_REG))])]
14511 "")
14512
14513 (define_insn_and_split "*ffs_no_cmove"
14514 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14515 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14516 (clobber (match_scratch:SI 2 "=&q"))
14517 (clobber (reg:CC FLAGS_REG))]
14518 ""
14519 "#"
14520 "reload_completed"
14521 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14522 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14523 (set (strict_low_part (match_dup 3))
14524 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14525 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14526 (clobber (reg:CC FLAGS_REG))])
14527 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14528 (clobber (reg:CC FLAGS_REG))])
14529 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14530 (clobber (reg:CC FLAGS_REG))])]
14531 {
14532 operands[3] = gen_lowpart (QImode, operands[2]);
14533 ix86_expand_clear (operands[2]);
14534 })
14535
14536 (define_insn "*ffssi_1"
14537 [(set (reg:CCZ FLAGS_REG)
14538 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14539 (const_int 0)))
14540 (set (match_operand:SI 0 "register_operand" "=r")
14541 (ctz:SI (match_dup 1)))]
14542 ""
14543 "bsf{l}\t{%1, %0|%0, %1}"
14544 [(set_attr "prefix_0f" "1")])
14545
14546 (define_expand "ffsdi2"
14547 [(parallel
14548 [(set (match_operand:DI 0 "register_operand" "")
14549 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14550 (clobber (match_scratch:DI 2 ""))
14551 (clobber (reg:CC FLAGS_REG))])]
14552 "TARGET_64BIT && TARGET_CMOVE"
14553 "")
14554
14555 (define_insn_and_split "*ffs_rex64"
14556 [(set (match_operand:DI 0 "register_operand" "=r")
14557 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14558 (clobber (match_scratch:DI 2 "=&r"))
14559 (clobber (reg:CC FLAGS_REG))]
14560 "TARGET_64BIT && TARGET_CMOVE"
14561 "#"
14562 "&& reload_completed"
14563 [(set (match_dup 2) (const_int -1))
14564 (parallel [(set (reg:CCZ FLAGS_REG)
14565 (compare:CCZ (match_dup 1) (const_int 0)))
14566 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14567 (set (match_dup 0) (if_then_else:DI
14568 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14569 (match_dup 2)
14570 (match_dup 0)))
14571 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14572 (clobber (reg:CC FLAGS_REG))])]
14573 "")
14574
14575 (define_insn "*ffsdi_1"
14576 [(set (reg:CCZ FLAGS_REG)
14577 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14578 (const_int 0)))
14579 (set (match_operand:DI 0 "register_operand" "=r")
14580 (ctz:DI (match_dup 1)))]
14581 "TARGET_64BIT"
14582 "bsf{q}\t{%1, %0|%0, %1}"
14583 [(set_attr "prefix_0f" "1")])
14584
14585 (define_insn "ctzsi2"
14586 [(set (match_operand:SI 0 "register_operand" "=r")
14587 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14588 (clobber (reg:CC FLAGS_REG))]
14589 ""
14590 "bsf{l}\t{%1, %0|%0, %1}"
14591 [(set_attr "prefix_0f" "1")])
14592
14593 (define_insn "ctzdi2"
14594 [(set (match_operand:DI 0 "register_operand" "=r")
14595 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14596 (clobber (reg:CC FLAGS_REG))]
14597 "TARGET_64BIT"
14598 "bsf{q}\t{%1, %0|%0, %1}"
14599 [(set_attr "prefix_0f" "1")])
14600
14601 (define_expand "clzsi2"
14602 [(parallel
14603 [(set (match_operand:SI 0 "register_operand" "")
14604 (minus:SI (const_int 31)
14605 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14606 (clobber (reg:CC FLAGS_REG))])
14607 (parallel
14608 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14609 (clobber (reg:CC FLAGS_REG))])]
14610 ""
14611 "")
14612
14613 (define_insn "*bsr"
14614 [(set (match_operand:SI 0 "register_operand" "=r")
14615 (minus:SI (const_int 31)
14616 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14617 (clobber (reg:CC FLAGS_REG))]
14618 ""
14619 "bsr{l}\t{%1, %0|%0, %1}"
14620 [(set_attr "prefix_0f" "1")])
14621
14622 (define_insn "bswapsi2"
14623 [(set (match_operand:SI 0 "register_operand" "=r")
14624 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14625 (clobber (reg:CC FLAGS_REG))]
14626 "TARGET_BSWAP"
14627 "bswap\t%k0"
14628 [(set_attr "prefix_0f" "1")
14629 (set_attr "length" "2")])
14630
14631 (define_insn "bswapdi2"
14632 [(set (match_operand:DI 0 "register_operand" "=r")
14633 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14634 (clobber (reg:CC FLAGS_REG))]
14635 "TARGET_64BIT && TARGET_BSWAP"
14636 "bswap\t%0"
14637 [(set_attr "prefix_0f" "1")
14638 (set_attr "length" "3")])
14639
14640 (define_expand "clzdi2"
14641 [(parallel
14642 [(set (match_operand:DI 0 "register_operand" "")
14643 (minus:DI (const_int 63)
14644 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14645 (clobber (reg:CC FLAGS_REG))])
14646 (parallel
14647 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14648 (clobber (reg:CC FLAGS_REG))])]
14649 "TARGET_64BIT"
14650 "")
14651
14652 (define_insn "*bsr_rex64"
14653 [(set (match_operand:DI 0 "register_operand" "=r")
14654 (minus:DI (const_int 63)
14655 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14656 (clobber (reg:CC FLAGS_REG))]
14657 "TARGET_64BIT"
14658 "bsr{q}\t{%1, %0|%0, %1}"
14659 [(set_attr "prefix_0f" "1")])
14660 \f
14661 ;; Thread-local storage patterns for ELF.
14662 ;;
14663 ;; Note that these code sequences must appear exactly as shown
14664 ;; in order to allow linker relaxation.
14665
14666 (define_insn "*tls_global_dynamic_32_gnu"
14667 [(set (match_operand:SI 0 "register_operand" "=a")
14668 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14669 (match_operand:SI 2 "tls_symbolic_operand" "")
14670 (match_operand:SI 3 "call_insn_operand" "")]
14671 UNSPEC_TLS_GD))
14672 (clobber (match_scratch:SI 4 "=d"))
14673 (clobber (match_scratch:SI 5 "=c"))
14674 (clobber (reg:CC FLAGS_REG))]
14675 "!TARGET_64BIT && TARGET_GNU_TLS"
14676 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14677 [(set_attr "type" "multi")
14678 (set_attr "length" "12")])
14679
14680 (define_insn "*tls_global_dynamic_32_sun"
14681 [(set (match_operand:SI 0 "register_operand" "=a")
14682 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14683 (match_operand:SI 2 "tls_symbolic_operand" "")
14684 (match_operand:SI 3 "call_insn_operand" "")]
14685 UNSPEC_TLS_GD))
14686 (clobber (match_scratch:SI 4 "=d"))
14687 (clobber (match_scratch:SI 5 "=c"))
14688 (clobber (reg:CC FLAGS_REG))]
14689 "!TARGET_64BIT && TARGET_SUN_TLS"
14690 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14691 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14692 [(set_attr "type" "multi")
14693 (set_attr "length" "14")])
14694
14695 (define_expand "tls_global_dynamic_32"
14696 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14697 (unspec:SI
14698 [(match_dup 2)
14699 (match_operand:SI 1 "tls_symbolic_operand" "")
14700 (match_dup 3)]
14701 UNSPEC_TLS_GD))
14702 (clobber (match_scratch:SI 4 ""))
14703 (clobber (match_scratch:SI 5 ""))
14704 (clobber (reg:CC FLAGS_REG))])]
14705 ""
14706 {
14707 if (flag_pic)
14708 operands[2] = pic_offset_table_rtx;
14709 else
14710 {
14711 operands[2] = gen_reg_rtx (Pmode);
14712 emit_insn (gen_set_got (operands[2]));
14713 }
14714 if (TARGET_GNU2_TLS)
14715 {
14716 emit_insn (gen_tls_dynamic_gnu2_32
14717 (operands[0], operands[1], operands[2]));
14718 DONE;
14719 }
14720 operands[3] = ix86_tls_get_addr ();
14721 })
14722
14723 (define_insn "*tls_global_dynamic_64"
14724 [(set (match_operand:DI 0 "register_operand" "=a")
14725 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14726 (match_operand:DI 3 "" "")))
14727 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14728 UNSPEC_TLS_GD)]
14729 "TARGET_64BIT"
14730 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14731 [(set_attr "type" "multi")
14732 (set_attr "length" "16")])
14733
14734 (define_expand "tls_global_dynamic_64"
14735 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14736 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14737 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14738 UNSPEC_TLS_GD)])]
14739 ""
14740 {
14741 if (TARGET_GNU2_TLS)
14742 {
14743 emit_insn (gen_tls_dynamic_gnu2_64
14744 (operands[0], operands[1]));
14745 DONE;
14746 }
14747 operands[2] = ix86_tls_get_addr ();
14748 })
14749
14750 (define_insn "*tls_local_dynamic_base_32_gnu"
14751 [(set (match_operand:SI 0 "register_operand" "=a")
14752 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14753 (match_operand:SI 2 "call_insn_operand" "")]
14754 UNSPEC_TLS_LD_BASE))
14755 (clobber (match_scratch:SI 3 "=d"))
14756 (clobber (match_scratch:SI 4 "=c"))
14757 (clobber (reg:CC FLAGS_REG))]
14758 "!TARGET_64BIT && TARGET_GNU_TLS"
14759 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14760 [(set_attr "type" "multi")
14761 (set_attr "length" "11")])
14762
14763 (define_insn "*tls_local_dynamic_base_32_sun"
14764 [(set (match_operand:SI 0 "register_operand" "=a")
14765 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14766 (match_operand:SI 2 "call_insn_operand" "")]
14767 UNSPEC_TLS_LD_BASE))
14768 (clobber (match_scratch:SI 3 "=d"))
14769 (clobber (match_scratch:SI 4 "=c"))
14770 (clobber (reg:CC FLAGS_REG))]
14771 "!TARGET_64BIT && TARGET_SUN_TLS"
14772 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14773 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14774 [(set_attr "type" "multi")
14775 (set_attr "length" "13")])
14776
14777 (define_expand "tls_local_dynamic_base_32"
14778 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14779 (unspec:SI [(match_dup 1) (match_dup 2)]
14780 UNSPEC_TLS_LD_BASE))
14781 (clobber (match_scratch:SI 3 ""))
14782 (clobber (match_scratch:SI 4 ""))
14783 (clobber (reg:CC FLAGS_REG))])]
14784 ""
14785 {
14786 if (flag_pic)
14787 operands[1] = pic_offset_table_rtx;
14788 else
14789 {
14790 operands[1] = gen_reg_rtx (Pmode);
14791 emit_insn (gen_set_got (operands[1]));
14792 }
14793 if (TARGET_GNU2_TLS)
14794 {
14795 emit_insn (gen_tls_dynamic_gnu2_32
14796 (operands[0], ix86_tls_module_base (), operands[1]));
14797 DONE;
14798 }
14799 operands[2] = ix86_tls_get_addr ();
14800 })
14801
14802 (define_insn "*tls_local_dynamic_base_64"
14803 [(set (match_operand:DI 0 "register_operand" "=a")
14804 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14805 (match_operand:DI 2 "" "")))
14806 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14807 "TARGET_64BIT"
14808 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14809 [(set_attr "type" "multi")
14810 (set_attr "length" "12")])
14811
14812 (define_expand "tls_local_dynamic_base_64"
14813 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14814 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14815 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14816 ""
14817 {
14818 if (TARGET_GNU2_TLS)
14819 {
14820 emit_insn (gen_tls_dynamic_gnu2_64
14821 (operands[0], ix86_tls_module_base ()));
14822 DONE;
14823 }
14824 operands[1] = ix86_tls_get_addr ();
14825 })
14826
14827 ;; Local dynamic of a single variable is a lose. Show combine how
14828 ;; to convert that back to global dynamic.
14829
14830 (define_insn_and_split "*tls_local_dynamic_32_once"
14831 [(set (match_operand:SI 0 "register_operand" "=a")
14832 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14833 (match_operand:SI 2 "call_insn_operand" "")]
14834 UNSPEC_TLS_LD_BASE)
14835 (const:SI (unspec:SI
14836 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14837 UNSPEC_DTPOFF))))
14838 (clobber (match_scratch:SI 4 "=d"))
14839 (clobber (match_scratch:SI 5 "=c"))
14840 (clobber (reg:CC FLAGS_REG))]
14841 ""
14842 "#"
14843 ""
14844 [(parallel [(set (match_dup 0)
14845 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14846 UNSPEC_TLS_GD))
14847 (clobber (match_dup 4))
14848 (clobber (match_dup 5))
14849 (clobber (reg:CC FLAGS_REG))])]
14850 "")
14851
14852 ;; Load and add the thread base pointer from %gs:0.
14853
14854 (define_insn "*load_tp_si"
14855 [(set (match_operand:SI 0 "register_operand" "=r")
14856 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14857 "!TARGET_64BIT"
14858 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14859 [(set_attr "type" "imov")
14860 (set_attr "modrm" "0")
14861 (set_attr "length" "7")
14862 (set_attr "memory" "load")
14863 (set_attr "imm_disp" "false")])
14864
14865 (define_insn "*add_tp_si"
14866 [(set (match_operand:SI 0 "register_operand" "=r")
14867 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14868 (match_operand:SI 1 "register_operand" "0")))
14869 (clobber (reg:CC FLAGS_REG))]
14870 "!TARGET_64BIT"
14871 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14872 [(set_attr "type" "alu")
14873 (set_attr "modrm" "0")
14874 (set_attr "length" "7")
14875 (set_attr "memory" "load")
14876 (set_attr "imm_disp" "false")])
14877
14878 (define_insn "*load_tp_di"
14879 [(set (match_operand:DI 0 "register_operand" "=r")
14880 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14881 "TARGET_64BIT"
14882 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14883 [(set_attr "type" "imov")
14884 (set_attr "modrm" "0")
14885 (set_attr "length" "7")
14886 (set_attr "memory" "load")
14887 (set_attr "imm_disp" "false")])
14888
14889 (define_insn "*add_tp_di"
14890 [(set (match_operand:DI 0 "register_operand" "=r")
14891 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14892 (match_operand:DI 1 "register_operand" "0")))
14893 (clobber (reg:CC FLAGS_REG))]
14894 "TARGET_64BIT"
14895 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14896 [(set_attr "type" "alu")
14897 (set_attr "modrm" "0")
14898 (set_attr "length" "7")
14899 (set_attr "memory" "load")
14900 (set_attr "imm_disp" "false")])
14901
14902 ;; GNU2 TLS patterns can be split.
14903
14904 (define_expand "tls_dynamic_gnu2_32"
14905 [(set (match_dup 3)
14906 (plus:SI (match_operand:SI 2 "register_operand" "")
14907 (const:SI
14908 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14909 UNSPEC_TLSDESC))))
14910 (parallel
14911 [(set (match_operand:SI 0 "register_operand" "")
14912 (unspec:SI [(match_dup 1) (match_dup 3)
14913 (match_dup 2) (reg:SI SP_REG)]
14914 UNSPEC_TLSDESC))
14915 (clobber (reg:CC FLAGS_REG))])]
14916 "!TARGET_64BIT && TARGET_GNU2_TLS"
14917 {
14918 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14919 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14920 })
14921
14922 (define_insn "*tls_dynamic_lea_32"
14923 [(set (match_operand:SI 0 "register_operand" "=r")
14924 (plus:SI (match_operand:SI 1 "register_operand" "b")
14925 (const:SI
14926 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14927 UNSPEC_TLSDESC))))]
14928 "!TARGET_64BIT && TARGET_GNU2_TLS"
14929 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14930 [(set_attr "type" "lea")
14931 (set_attr "mode" "SI")
14932 (set_attr "length" "6")
14933 (set_attr "length_address" "4")])
14934
14935 (define_insn "*tls_dynamic_call_32"
14936 [(set (match_operand:SI 0 "register_operand" "=a")
14937 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14938 (match_operand:SI 2 "register_operand" "0")
14939 ;; we have to make sure %ebx still points to the GOT
14940 (match_operand:SI 3 "register_operand" "b")
14941 (reg:SI SP_REG)]
14942 UNSPEC_TLSDESC))
14943 (clobber (reg:CC FLAGS_REG))]
14944 "!TARGET_64BIT && TARGET_GNU2_TLS"
14945 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14946 [(set_attr "type" "call")
14947 (set_attr "length" "2")
14948 (set_attr "length_address" "0")])
14949
14950 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14951 [(set (match_operand:SI 0 "register_operand" "=&a")
14952 (plus:SI
14953 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14954 (match_operand:SI 4 "" "")
14955 (match_operand:SI 2 "register_operand" "b")
14956 (reg:SI SP_REG)]
14957 UNSPEC_TLSDESC)
14958 (const:SI (unspec:SI
14959 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14960 UNSPEC_DTPOFF))))
14961 (clobber (reg:CC FLAGS_REG))]
14962 "!TARGET_64BIT && TARGET_GNU2_TLS"
14963 "#"
14964 ""
14965 [(set (match_dup 0) (match_dup 5))]
14966 {
14967 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14968 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14969 })
14970
14971 (define_expand "tls_dynamic_gnu2_64"
14972 [(set (match_dup 2)
14973 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14974 UNSPEC_TLSDESC))
14975 (parallel
14976 [(set (match_operand:DI 0 "register_operand" "")
14977 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14978 UNSPEC_TLSDESC))
14979 (clobber (reg:CC FLAGS_REG))])]
14980 "TARGET_64BIT && TARGET_GNU2_TLS"
14981 {
14982 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14983 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14984 })
14985
14986 (define_insn "*tls_dynamic_lea_64"
14987 [(set (match_operand:DI 0 "register_operand" "=r")
14988 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14989 UNSPEC_TLSDESC))]
14990 "TARGET_64BIT && TARGET_GNU2_TLS"
14991 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14992 [(set_attr "type" "lea")
14993 (set_attr "mode" "DI")
14994 (set_attr "length" "7")
14995 (set_attr "length_address" "4")])
14996
14997 (define_insn "*tls_dynamic_call_64"
14998 [(set (match_operand:DI 0 "register_operand" "=a")
14999 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15000 (match_operand:DI 2 "register_operand" "0")
15001 (reg:DI SP_REG)]
15002 UNSPEC_TLSDESC))
15003 (clobber (reg:CC FLAGS_REG))]
15004 "TARGET_64BIT && TARGET_GNU2_TLS"
15005 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15006 [(set_attr "type" "call")
15007 (set_attr "length" "2")
15008 (set_attr "length_address" "0")])
15009
15010 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15011 [(set (match_operand:DI 0 "register_operand" "=&a")
15012 (plus:DI
15013 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15014 (match_operand:DI 3 "" "")
15015 (reg:DI SP_REG)]
15016 UNSPEC_TLSDESC)
15017 (const:DI (unspec:DI
15018 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15019 UNSPEC_DTPOFF))))
15020 (clobber (reg:CC FLAGS_REG))]
15021 "TARGET_64BIT && TARGET_GNU2_TLS"
15022 "#"
15023 ""
15024 [(set (match_dup 0) (match_dup 4))]
15025 {
15026 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15027 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15028 })
15029
15030 ;;
15031 \f
15032 ;; These patterns match the binary 387 instructions for addM3, subM3,
15033 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15034 ;; SFmode. The first is the normal insn, the second the same insn but
15035 ;; with one operand a conversion, and the third the same insn but with
15036 ;; the other operand a conversion. The conversion may be SFmode or
15037 ;; SImode if the target mode DFmode, but only SImode if the target mode
15038 ;; is SFmode.
15039
15040 ;; Gcc is slightly more smart about handling normal two address instructions
15041 ;; so use special patterns for add and mull.
15042
15043 (define_insn "*fop_sf_comm_mixed"
15044 [(set (match_operand:SF 0 "register_operand" "=f,x")
15045 (match_operator:SF 3 "binary_fp_operator"
15046 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15047 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15048 "TARGET_MIX_SSE_I387
15049 && COMMUTATIVE_ARITH_P (operands[3])
15050 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15051 "* return output_387_binary_op (insn, operands);"
15052 [(set (attr "type")
15053 (if_then_else (eq_attr "alternative" "1")
15054 (if_then_else (match_operand:SF 3 "mult_operator" "")
15055 (const_string "ssemul")
15056 (const_string "sseadd"))
15057 (if_then_else (match_operand:SF 3 "mult_operator" "")
15058 (const_string "fmul")
15059 (const_string "fop"))))
15060 (set_attr "mode" "SF")])
15061
15062 (define_insn "*fop_sf_comm_sse"
15063 [(set (match_operand:SF 0 "register_operand" "=x")
15064 (match_operator:SF 3 "binary_fp_operator"
15065 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15066 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15067 "TARGET_SSE_MATH
15068 && COMMUTATIVE_ARITH_P (operands[3])
15069 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15070 "* return output_387_binary_op (insn, operands);"
15071 [(set (attr "type")
15072 (if_then_else (match_operand:SF 3 "mult_operator" "")
15073 (const_string "ssemul")
15074 (const_string "sseadd")))
15075 (set_attr "mode" "SF")])
15076
15077 (define_insn "*fop_sf_comm_i387"
15078 [(set (match_operand:SF 0 "register_operand" "=f")
15079 (match_operator:SF 3 "binary_fp_operator"
15080 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15081 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15082 "TARGET_80387
15083 && COMMUTATIVE_ARITH_P (operands[3])
15084 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15085 "* return output_387_binary_op (insn, operands);"
15086 [(set (attr "type")
15087 (if_then_else (match_operand:SF 3 "mult_operator" "")
15088 (const_string "fmul")
15089 (const_string "fop")))
15090 (set_attr "mode" "SF")])
15091
15092 (define_insn "*fop_sf_1_mixed"
15093 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15094 (match_operator:SF 3 "binary_fp_operator"
15095 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15096 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15097 "TARGET_MIX_SSE_I387
15098 && !COMMUTATIVE_ARITH_P (operands[3])
15099 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15100 "* return output_387_binary_op (insn, operands);"
15101 [(set (attr "type")
15102 (cond [(and (eq_attr "alternative" "2")
15103 (match_operand:SF 3 "mult_operator" ""))
15104 (const_string "ssemul")
15105 (and (eq_attr "alternative" "2")
15106 (match_operand:SF 3 "div_operator" ""))
15107 (const_string "ssediv")
15108 (eq_attr "alternative" "2")
15109 (const_string "sseadd")
15110 (match_operand:SF 3 "mult_operator" "")
15111 (const_string "fmul")
15112 (match_operand:SF 3 "div_operator" "")
15113 (const_string "fdiv")
15114 ]
15115 (const_string "fop")))
15116 (set_attr "mode" "SF")])
15117
15118 (define_insn "*fop_sf_1_sse"
15119 [(set (match_operand:SF 0 "register_operand" "=x")
15120 (match_operator:SF 3 "binary_fp_operator"
15121 [(match_operand:SF 1 "register_operand" "0")
15122 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15123 "TARGET_SSE_MATH
15124 && !COMMUTATIVE_ARITH_P (operands[3])"
15125 "* return output_387_binary_op (insn, operands);"
15126 [(set (attr "type")
15127 (cond [(match_operand:SF 3 "mult_operator" "")
15128 (const_string "ssemul")
15129 (match_operand:SF 3 "div_operator" "")
15130 (const_string "ssediv")
15131 ]
15132 (const_string "sseadd")))
15133 (set_attr "mode" "SF")])
15134
15135 ;; This pattern is not fully shadowed by the pattern above.
15136 (define_insn "*fop_sf_1_i387"
15137 [(set (match_operand:SF 0 "register_operand" "=f,f")
15138 (match_operator:SF 3 "binary_fp_operator"
15139 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15140 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15141 "TARGET_80387 && !TARGET_SSE_MATH
15142 && !COMMUTATIVE_ARITH_P (operands[3])
15143 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15144 "* return output_387_binary_op (insn, operands);"
15145 [(set (attr "type")
15146 (cond [(match_operand:SF 3 "mult_operator" "")
15147 (const_string "fmul")
15148 (match_operand:SF 3 "div_operator" "")
15149 (const_string "fdiv")
15150 ]
15151 (const_string "fop")))
15152 (set_attr "mode" "SF")])
15153
15154 ;; ??? Add SSE splitters for these!
15155 (define_insn "*fop_sf_2<mode>_i387"
15156 [(set (match_operand:SF 0 "register_operand" "=f,f")
15157 (match_operator:SF 3 "binary_fp_operator"
15158 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15159 (match_operand:SF 2 "register_operand" "0,0")]))]
15160 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15161 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15162 [(set (attr "type")
15163 (cond [(match_operand:SF 3 "mult_operator" "")
15164 (const_string "fmul")
15165 (match_operand:SF 3 "div_operator" "")
15166 (const_string "fdiv")
15167 ]
15168 (const_string "fop")))
15169 (set_attr "fp_int_src" "true")
15170 (set_attr "mode" "<MODE>")])
15171
15172 (define_insn "*fop_sf_3<mode>_i387"
15173 [(set (match_operand:SF 0 "register_operand" "=f,f")
15174 (match_operator:SF 3 "binary_fp_operator"
15175 [(match_operand:SF 1 "register_operand" "0,0")
15176 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15177 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15178 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15179 [(set (attr "type")
15180 (cond [(match_operand:SF 3 "mult_operator" "")
15181 (const_string "fmul")
15182 (match_operand:SF 3 "div_operator" "")
15183 (const_string "fdiv")
15184 ]
15185 (const_string "fop")))
15186 (set_attr "fp_int_src" "true")
15187 (set_attr "mode" "<MODE>")])
15188
15189 (define_insn "*fop_df_comm_mixed"
15190 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15191 (match_operator:DF 3 "binary_fp_operator"
15192 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15193 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15194 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15195 && COMMUTATIVE_ARITH_P (operands[3])
15196 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15197 "* return output_387_binary_op (insn, operands);"
15198 [(set (attr "type")
15199 (if_then_else (eq_attr "alternative" "1")
15200 (if_then_else (match_operand:DF 3 "mult_operator" "")
15201 (const_string "ssemul")
15202 (const_string "sseadd"))
15203 (if_then_else (match_operand:DF 3 "mult_operator" "")
15204 (const_string "fmul")
15205 (const_string "fop"))))
15206 (set_attr "mode" "DF")])
15207
15208 (define_insn "*fop_df_comm_sse"
15209 [(set (match_operand:DF 0 "register_operand" "=Y")
15210 (match_operator:DF 3 "binary_fp_operator"
15211 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15212 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15213 "TARGET_SSE2 && TARGET_SSE_MATH
15214 && COMMUTATIVE_ARITH_P (operands[3])
15215 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15216 "* return output_387_binary_op (insn, operands);"
15217 [(set (attr "type")
15218 (if_then_else (match_operand:DF 3 "mult_operator" "")
15219 (const_string "ssemul")
15220 (const_string "sseadd")))
15221 (set_attr "mode" "DF")])
15222
15223 (define_insn "*fop_df_comm_i387"
15224 [(set (match_operand:DF 0 "register_operand" "=f")
15225 (match_operator:DF 3 "binary_fp_operator"
15226 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15227 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15228 "TARGET_80387
15229 && COMMUTATIVE_ARITH_P (operands[3])
15230 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15231 "* return output_387_binary_op (insn, operands);"
15232 [(set (attr "type")
15233 (if_then_else (match_operand:DF 3 "mult_operator" "")
15234 (const_string "fmul")
15235 (const_string "fop")))
15236 (set_attr "mode" "DF")])
15237
15238 (define_insn "*fop_df_1_mixed"
15239 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15240 (match_operator:DF 3 "binary_fp_operator"
15241 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15242 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15243 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15244 && !COMMUTATIVE_ARITH_P (operands[3])
15245 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15246 "* return output_387_binary_op (insn, operands);"
15247 [(set (attr "type")
15248 (cond [(and (eq_attr "alternative" "2")
15249 (match_operand:DF 3 "mult_operator" ""))
15250 (const_string "ssemul")
15251 (and (eq_attr "alternative" "2")
15252 (match_operand:DF 3 "div_operator" ""))
15253 (const_string "ssediv")
15254 (eq_attr "alternative" "2")
15255 (const_string "sseadd")
15256 (match_operand:DF 3 "mult_operator" "")
15257 (const_string "fmul")
15258 (match_operand:DF 3 "div_operator" "")
15259 (const_string "fdiv")
15260 ]
15261 (const_string "fop")))
15262 (set_attr "mode" "DF")])
15263
15264 (define_insn "*fop_df_1_sse"
15265 [(set (match_operand:DF 0 "register_operand" "=Y")
15266 (match_operator:DF 3 "binary_fp_operator"
15267 [(match_operand:DF 1 "register_operand" "0")
15268 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15269 "TARGET_SSE2 && TARGET_SSE_MATH
15270 && !COMMUTATIVE_ARITH_P (operands[3])"
15271 "* return output_387_binary_op (insn, operands);"
15272 [(set_attr "mode" "DF")
15273 (set (attr "type")
15274 (cond [(match_operand:DF 3 "mult_operator" "")
15275 (const_string "ssemul")
15276 (match_operand:DF 3 "div_operator" "")
15277 (const_string "ssediv")
15278 ]
15279 (const_string "sseadd")))])
15280
15281 ;; This pattern is not fully shadowed by the pattern above.
15282 (define_insn "*fop_df_1_i387"
15283 [(set (match_operand:DF 0 "register_operand" "=f,f")
15284 (match_operator:DF 3 "binary_fp_operator"
15285 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15286 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15287 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15288 && !COMMUTATIVE_ARITH_P (operands[3])
15289 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15290 "* return output_387_binary_op (insn, operands);"
15291 [(set (attr "type")
15292 (cond [(match_operand:DF 3 "mult_operator" "")
15293 (const_string "fmul")
15294 (match_operand:DF 3 "div_operator" "")
15295 (const_string "fdiv")
15296 ]
15297 (const_string "fop")))
15298 (set_attr "mode" "DF")])
15299
15300 ;; ??? Add SSE splitters for these!
15301 (define_insn "*fop_df_2<mode>_i387"
15302 [(set (match_operand:DF 0 "register_operand" "=f,f")
15303 (match_operator:DF 3 "binary_fp_operator"
15304 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15305 (match_operand:DF 2 "register_operand" "0,0")]))]
15306 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15307 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15308 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15309 [(set (attr "type")
15310 (cond [(match_operand:DF 3 "mult_operator" "")
15311 (const_string "fmul")
15312 (match_operand:DF 3 "div_operator" "")
15313 (const_string "fdiv")
15314 ]
15315 (const_string "fop")))
15316 (set_attr "fp_int_src" "true")
15317 (set_attr "mode" "<MODE>")])
15318
15319 (define_insn "*fop_df_3<mode>_i387"
15320 [(set (match_operand:DF 0 "register_operand" "=f,f")
15321 (match_operator:DF 3 "binary_fp_operator"
15322 [(match_operand:DF 1 "register_operand" "0,0")
15323 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15324 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15325 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15326 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15327 [(set (attr "type")
15328 (cond [(match_operand:DF 3 "mult_operator" "")
15329 (const_string "fmul")
15330 (match_operand:DF 3 "div_operator" "")
15331 (const_string "fdiv")
15332 ]
15333 (const_string "fop")))
15334 (set_attr "fp_int_src" "true")
15335 (set_attr "mode" "<MODE>")])
15336
15337 (define_insn "*fop_df_4_i387"
15338 [(set (match_operand:DF 0 "register_operand" "=f,f")
15339 (match_operator:DF 3 "binary_fp_operator"
15340 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15341 (match_operand:DF 2 "register_operand" "0,f")]))]
15342 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15343 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15344 "* return output_387_binary_op (insn, operands);"
15345 [(set (attr "type")
15346 (cond [(match_operand:DF 3 "mult_operator" "")
15347 (const_string "fmul")
15348 (match_operand:DF 3 "div_operator" "")
15349 (const_string "fdiv")
15350 ]
15351 (const_string "fop")))
15352 (set_attr "mode" "SF")])
15353
15354 (define_insn "*fop_df_5_i387"
15355 [(set (match_operand:DF 0 "register_operand" "=f,f")
15356 (match_operator:DF 3 "binary_fp_operator"
15357 [(match_operand:DF 1 "register_operand" "0,f")
15358 (float_extend:DF
15359 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15360 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15361 "* return output_387_binary_op (insn, operands);"
15362 [(set (attr "type")
15363 (cond [(match_operand:DF 3 "mult_operator" "")
15364 (const_string "fmul")
15365 (match_operand:DF 3 "div_operator" "")
15366 (const_string "fdiv")
15367 ]
15368 (const_string "fop")))
15369 (set_attr "mode" "SF")])
15370
15371 (define_insn "*fop_df_6_i387"
15372 [(set (match_operand:DF 0 "register_operand" "=f,f")
15373 (match_operator:DF 3 "binary_fp_operator"
15374 [(float_extend:DF
15375 (match_operand:SF 1 "register_operand" "0,f"))
15376 (float_extend:DF
15377 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15378 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15379 "* return output_387_binary_op (insn, operands);"
15380 [(set (attr "type")
15381 (cond [(match_operand:DF 3 "mult_operator" "")
15382 (const_string "fmul")
15383 (match_operand:DF 3 "div_operator" "")
15384 (const_string "fdiv")
15385 ]
15386 (const_string "fop")))
15387 (set_attr "mode" "SF")])
15388
15389 (define_insn "*fop_xf_comm_i387"
15390 [(set (match_operand:XF 0 "register_operand" "=f")
15391 (match_operator:XF 3 "binary_fp_operator"
15392 [(match_operand:XF 1 "register_operand" "%0")
15393 (match_operand:XF 2 "register_operand" "f")]))]
15394 "TARGET_80387
15395 && COMMUTATIVE_ARITH_P (operands[3])"
15396 "* return output_387_binary_op (insn, operands);"
15397 [(set (attr "type")
15398 (if_then_else (match_operand:XF 3 "mult_operator" "")
15399 (const_string "fmul")
15400 (const_string "fop")))
15401 (set_attr "mode" "XF")])
15402
15403 (define_insn "*fop_xf_1_i387"
15404 [(set (match_operand:XF 0 "register_operand" "=f,f")
15405 (match_operator:XF 3 "binary_fp_operator"
15406 [(match_operand:XF 1 "register_operand" "0,f")
15407 (match_operand:XF 2 "register_operand" "f,0")]))]
15408 "TARGET_80387
15409 && !COMMUTATIVE_ARITH_P (operands[3])"
15410 "* return output_387_binary_op (insn, operands);"
15411 [(set (attr "type")
15412 (cond [(match_operand:XF 3 "mult_operator" "")
15413 (const_string "fmul")
15414 (match_operand:XF 3 "div_operator" "")
15415 (const_string "fdiv")
15416 ]
15417 (const_string "fop")))
15418 (set_attr "mode" "XF")])
15419
15420 (define_insn "*fop_xf_2<mode>_i387"
15421 [(set (match_operand:XF 0 "register_operand" "=f,f")
15422 (match_operator:XF 3 "binary_fp_operator"
15423 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15424 (match_operand:XF 2 "register_operand" "0,0")]))]
15425 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15426 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15427 [(set (attr "type")
15428 (cond [(match_operand:XF 3 "mult_operator" "")
15429 (const_string "fmul")
15430 (match_operand:XF 3 "div_operator" "")
15431 (const_string "fdiv")
15432 ]
15433 (const_string "fop")))
15434 (set_attr "fp_int_src" "true")
15435 (set_attr "mode" "<MODE>")])
15436
15437 (define_insn "*fop_xf_3<mode>_i387"
15438 [(set (match_operand:XF 0 "register_operand" "=f,f")
15439 (match_operator:XF 3 "binary_fp_operator"
15440 [(match_operand:XF 1 "register_operand" "0,0")
15441 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15442 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15443 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15444 [(set (attr "type")
15445 (cond [(match_operand:XF 3 "mult_operator" "")
15446 (const_string "fmul")
15447 (match_operand:XF 3 "div_operator" "")
15448 (const_string "fdiv")
15449 ]
15450 (const_string "fop")))
15451 (set_attr "fp_int_src" "true")
15452 (set_attr "mode" "<MODE>")])
15453
15454 (define_insn "*fop_xf_4_i387"
15455 [(set (match_operand:XF 0 "register_operand" "=f,f")
15456 (match_operator:XF 3 "binary_fp_operator"
15457 [(float_extend:XF
15458 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15459 (match_operand:XF 2 "register_operand" "0,f")]))]
15460 "TARGET_80387"
15461 "* return output_387_binary_op (insn, operands);"
15462 [(set (attr "type")
15463 (cond [(match_operand:XF 3 "mult_operator" "")
15464 (const_string "fmul")
15465 (match_operand:XF 3 "div_operator" "")
15466 (const_string "fdiv")
15467 ]
15468 (const_string "fop")))
15469 (set_attr "mode" "SF")])
15470
15471 (define_insn "*fop_xf_5_i387"
15472 [(set (match_operand:XF 0 "register_operand" "=f,f")
15473 (match_operator:XF 3 "binary_fp_operator"
15474 [(match_operand:XF 1 "register_operand" "0,f")
15475 (float_extend:XF
15476 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15477 "TARGET_80387"
15478 "* return output_387_binary_op (insn, operands);"
15479 [(set (attr "type")
15480 (cond [(match_operand:XF 3 "mult_operator" "")
15481 (const_string "fmul")
15482 (match_operand:XF 3 "div_operator" "")
15483 (const_string "fdiv")
15484 ]
15485 (const_string "fop")))
15486 (set_attr "mode" "SF")])
15487
15488 (define_insn "*fop_xf_6_i387"
15489 [(set (match_operand:XF 0 "register_operand" "=f,f")
15490 (match_operator:XF 3 "binary_fp_operator"
15491 [(float_extend:XF
15492 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15493 (float_extend:XF
15494 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15495 "TARGET_80387"
15496 "* return output_387_binary_op (insn, operands);"
15497 [(set (attr "type")
15498 (cond [(match_operand:XF 3 "mult_operator" "")
15499 (const_string "fmul")
15500 (match_operand:XF 3 "div_operator" "")
15501 (const_string "fdiv")
15502 ]
15503 (const_string "fop")))
15504 (set_attr "mode" "SF")])
15505
15506 (define_split
15507 [(set (match_operand 0 "register_operand" "")
15508 (match_operator 3 "binary_fp_operator"
15509 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15510 (match_operand 2 "register_operand" "")]))]
15511 "TARGET_80387 && reload_completed
15512 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15513 [(const_int 0)]
15514 {
15515 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15516 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15517 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15518 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15519 GET_MODE (operands[3]),
15520 operands[4],
15521 operands[2])));
15522 ix86_free_from_memory (GET_MODE (operands[1]));
15523 DONE;
15524 })
15525
15526 (define_split
15527 [(set (match_operand 0 "register_operand" "")
15528 (match_operator 3 "binary_fp_operator"
15529 [(match_operand 1 "register_operand" "")
15530 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15531 "TARGET_80387 && reload_completed
15532 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15533 [(const_int 0)]
15534 {
15535 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15536 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15537 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15538 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15539 GET_MODE (operands[3]),
15540 operands[1],
15541 operands[4])));
15542 ix86_free_from_memory (GET_MODE (operands[2]));
15543 DONE;
15544 })
15545 \f
15546 ;; FPU special functions.
15547
15548 ;; This pattern implements a no-op XFmode truncation for
15549 ;; all fancy i386 XFmode math functions.
15550
15551 (define_insn "truncxf<mode>2_i387_noop_unspec"
15552 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15553 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15554 UNSPEC_TRUNC_NOOP))]
15555 "TARGET_USE_FANCY_MATH_387"
15556 "* return output_387_reg_move (insn, operands);"
15557 [(set_attr "type" "fmov")
15558 (set_attr "mode" "<MODE>")])
15559
15560 (define_insn "sqrtxf2"
15561 [(set (match_operand:XF 0 "register_operand" "=f")
15562 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15563 "TARGET_USE_FANCY_MATH_387"
15564 "fsqrt"
15565 [(set_attr "type" "fpspc")
15566 (set_attr "mode" "XF")
15567 (set_attr "athlon_decode" "direct")])
15568
15569 (define_insn "sqrt_extend<mode>xf2_i387"
15570 [(set (match_operand:XF 0 "register_operand" "=f")
15571 (sqrt:XF
15572 (float_extend:XF
15573 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15574 "TARGET_USE_FANCY_MATH_387"
15575 "fsqrt"
15576 [(set_attr "type" "fpspc")
15577 (set_attr "mode" "XF")
15578 (set_attr "athlon_decode" "direct")])
15579
15580 (define_insn "*sqrt<mode>2_sse"
15581 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15582 (sqrt:SSEMODEF
15583 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15584 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15585 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15586 [(set_attr "type" "sse")
15587 (set_attr "mode" "<MODE>")
15588 (set_attr "athlon_decode" "*")])
15589
15590 (define_expand "sqrt<mode>2"
15591 [(set (match_operand:X87MODEF12 0 "register_operand" "")
15592 (sqrt:X87MODEF12
15593 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15594 "TARGET_USE_FANCY_MATH_387
15595 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15596 {
15597 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15598 {
15599 rtx op0 = gen_reg_rtx (XFmode);
15600 rtx op1 = force_reg (<MODE>mode, operands[1]);
15601
15602 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15603 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15604 DONE;
15605 }
15606 })
15607
15608 (define_insn "fpremxf4_i387"
15609 [(set (match_operand:XF 0 "register_operand" "=f")
15610 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15611 (match_operand:XF 3 "register_operand" "1")]
15612 UNSPEC_FPREM_F))
15613 (set (match_operand:XF 1 "register_operand" "=u")
15614 (unspec:XF [(match_dup 2) (match_dup 3)]
15615 UNSPEC_FPREM_U))
15616 (set (reg:CCFP FPSR_REG)
15617 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15618 "TARGET_USE_FANCY_MATH_387"
15619 "fprem"
15620 [(set_attr "type" "fpspc")
15621 (set_attr "mode" "XF")])
15622
15623 (define_expand "fmodxf3"
15624 [(use (match_operand:XF 0 "register_operand" ""))
15625 (use (match_operand:XF 1 "register_operand" ""))
15626 (use (match_operand:XF 2 "register_operand" ""))]
15627 "TARGET_USE_FANCY_MATH_387"
15628 {
15629 rtx label = gen_label_rtx ();
15630
15631 emit_label (label);
15632
15633 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15634 operands[1], operands[2]));
15635 ix86_emit_fp_unordered_jump (label);
15636
15637 emit_move_insn (operands[0], operands[1]);
15638 DONE;
15639 })
15640
15641 (define_expand "fmod<mode>3"
15642 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15643 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15644 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15645 "TARGET_USE_FANCY_MATH_387"
15646 {
15647 rtx label = gen_label_rtx ();
15648
15649 rtx op1 = gen_reg_rtx (XFmode);
15650 rtx op2 = gen_reg_rtx (XFmode);
15651
15652 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15653 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15654
15655 emit_label (label);
15656 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15657 ix86_emit_fp_unordered_jump (label);
15658
15659 /* Truncate the result properly for strict SSE math. */
15660 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15661 && !TARGET_MIX_SSE_I387)
15662 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15663 else
15664 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15665
15666 DONE;
15667 })
15668
15669 (define_insn "fprem1xf4_i387"
15670 [(set (match_operand:XF 0 "register_operand" "=f")
15671 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15672 (match_operand:XF 3 "register_operand" "1")]
15673 UNSPEC_FPREM1_F))
15674 (set (match_operand:XF 1 "register_operand" "=u")
15675 (unspec:XF [(match_dup 2) (match_dup 3)]
15676 UNSPEC_FPREM1_U))
15677 (set (reg:CCFP FPSR_REG)
15678 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15679 "TARGET_USE_FANCY_MATH_387"
15680 "fprem1"
15681 [(set_attr "type" "fpspc")
15682 (set_attr "mode" "XF")])
15683
15684 (define_expand "remainderxf3"
15685 [(use (match_operand:XF 0 "register_operand" ""))
15686 (use (match_operand:XF 1 "register_operand" ""))
15687 (use (match_operand:XF 2 "register_operand" ""))]
15688 "TARGET_USE_FANCY_MATH_387"
15689 {
15690 rtx label = gen_label_rtx ();
15691
15692 emit_label (label);
15693
15694 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15695 operands[1], operands[2]));
15696 ix86_emit_fp_unordered_jump (label);
15697
15698 emit_move_insn (operands[0], operands[1]);
15699 DONE;
15700 })
15701
15702 (define_expand "remainder<mode>3"
15703 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15704 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15705 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15706 "TARGET_USE_FANCY_MATH_387"
15707 {
15708 rtx label = gen_label_rtx ();
15709
15710 rtx op1 = gen_reg_rtx (XFmode);
15711 rtx op2 = gen_reg_rtx (XFmode);
15712
15713 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15714 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15715
15716 emit_label (label);
15717
15718 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15719 ix86_emit_fp_unordered_jump (label);
15720
15721 /* Truncate the result properly for strict SSE math. */
15722 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15723 && !TARGET_MIX_SSE_I387)
15724 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15725 else
15726 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15727
15728 DONE;
15729 })
15730
15731 (define_insn "*sinxf2_i387"
15732 [(set (match_operand:XF 0 "register_operand" "=f")
15733 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15734 "TARGET_USE_FANCY_MATH_387
15735 && flag_unsafe_math_optimizations"
15736 "fsin"
15737 [(set_attr "type" "fpspc")
15738 (set_attr "mode" "XF")])
15739
15740 (define_insn "*sin_extend<mode>xf2_i387"
15741 [(set (match_operand:XF 0 "register_operand" "=f")
15742 (unspec:XF [(float_extend:XF
15743 (match_operand:X87MODEF12 1 "register_operand" "0"))]
15744 UNSPEC_SIN))]
15745 "TARGET_USE_FANCY_MATH_387
15746 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15747 || TARGET_MIX_SSE_I387)
15748 && flag_unsafe_math_optimizations"
15749 "fsin"
15750 [(set_attr "type" "fpspc")
15751 (set_attr "mode" "XF")])
15752
15753 (define_insn "*cosxf2_i387"
15754 [(set (match_operand:XF 0 "register_operand" "=f")
15755 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15756 "TARGET_USE_FANCY_MATH_387
15757 && flag_unsafe_math_optimizations"
15758 "fcos"
15759 [(set_attr "type" "fpspc")
15760 (set_attr "mode" "XF")])
15761
15762 (define_insn "*cos_extend<mode>xf2_i387"
15763 [(set (match_operand:XF 0 "register_operand" "=f")
15764 (unspec:XF [(float_extend:XF
15765 (match_operand:X87MODEF12 1 "register_operand" "0"))]
15766 UNSPEC_COS))]
15767 "TARGET_USE_FANCY_MATH_387
15768 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15769 || TARGET_MIX_SSE_I387)
15770 && flag_unsafe_math_optimizations"
15771 "fcos"
15772 [(set_attr "type" "fpspc")
15773 (set_attr "mode" "XF")])
15774
15775 ;; When sincos pattern is defined, sin and cos builtin functions will be
15776 ;; expanded to sincos pattern with one of its outputs left unused.
15777 ;; CSE pass will figure out if two sincos patterns can be combined,
15778 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15779 ;; depending on the unused output.
15780
15781 (define_insn "sincosxf3"
15782 [(set (match_operand:XF 0 "register_operand" "=f")
15783 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15784 UNSPEC_SINCOS_COS))
15785 (set (match_operand:XF 1 "register_operand" "=u")
15786 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15787 "TARGET_USE_FANCY_MATH_387
15788 && flag_unsafe_math_optimizations"
15789 "fsincos"
15790 [(set_attr "type" "fpspc")
15791 (set_attr "mode" "XF")])
15792
15793 (define_split
15794 [(set (match_operand:XF 0 "register_operand" "")
15795 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15796 UNSPEC_SINCOS_COS))
15797 (set (match_operand:XF 1 "register_operand" "")
15798 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15799 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15800 && !reload_completed && !reload_in_progress"
15801 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15802 "")
15803
15804 (define_split
15805 [(set (match_operand:XF 0 "register_operand" "")
15806 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15807 UNSPEC_SINCOS_COS))
15808 (set (match_operand:XF 1 "register_operand" "")
15809 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15810 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15811 && !reload_completed && !reload_in_progress"
15812 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15813 "")
15814
15815 (define_insn "sincos_extend<mode>xf3_i387"
15816 [(set (match_operand:XF 0 "register_operand" "=f")
15817 (unspec:XF [(float_extend:XF
15818 (match_operand:X87MODEF12 2 "register_operand" "0"))]
15819 UNSPEC_SINCOS_COS))
15820 (set (match_operand:XF 1 "register_operand" "=u")
15821 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15822 "TARGET_USE_FANCY_MATH_387
15823 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15824 || TARGET_MIX_SSE_I387)
15825 && flag_unsafe_math_optimizations"
15826 "fsincos"
15827 [(set_attr "type" "fpspc")
15828 (set_attr "mode" "XF")])
15829
15830 (define_split
15831 [(set (match_operand:XF 0 "register_operand" "")
15832 (unspec:XF [(float_extend:XF
15833 (match_operand:X87MODEF12 2 "register_operand" ""))]
15834 UNSPEC_SINCOS_COS))
15835 (set (match_operand:XF 1 "register_operand" "")
15836 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15837 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15838 && !reload_completed && !reload_in_progress"
15839 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15840 "")
15841
15842 (define_split
15843 [(set (match_operand:XF 0 "register_operand" "")
15844 (unspec:XF [(float_extend:XF
15845 (match_operand:X87MODEF12 2 "register_operand" ""))]
15846 UNSPEC_SINCOS_COS))
15847 (set (match_operand:XF 1 "register_operand" "")
15848 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15849 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15850 && !reload_completed && !reload_in_progress"
15851 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15852 "")
15853
15854 (define_expand "sincos<mode>3"
15855 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15856 (use (match_operand:X87MODEF12 1 "register_operand" ""))
15857 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15858 "TARGET_USE_FANCY_MATH_387
15859 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15860 || TARGET_MIX_SSE_I387)
15861 && flag_unsafe_math_optimizations"
15862 {
15863 rtx op0 = gen_reg_rtx (XFmode);
15864 rtx op1 = gen_reg_rtx (XFmode);
15865
15866 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15867 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15868 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15869 DONE;
15870 })
15871
15872 (define_insn "fptanxf4_i387"
15873 [(set (match_operand:XF 0 "register_operand" "=f")
15874 (match_operand:XF 3 "const_double_operand" "F"))
15875 (set (match_operand:XF 1 "register_operand" "=u")
15876 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15877 UNSPEC_TAN))]
15878 "TARGET_USE_FANCY_MATH_387
15879 && flag_unsafe_math_optimizations
15880 && standard_80387_constant_p (operands[3]) == 2"
15881 "fptan"
15882 [(set_attr "type" "fpspc")
15883 (set_attr "mode" "XF")])
15884
15885 (define_insn "fptan_extend<mode>xf4_i387"
15886 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15887 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
15888 (set (match_operand:XF 1 "register_operand" "=u")
15889 (unspec:XF [(float_extend:XF
15890 (match_operand:X87MODEF12 2 "register_operand" "0"))]
15891 UNSPEC_TAN))]
15892 "TARGET_USE_FANCY_MATH_387
15893 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15894 || TARGET_MIX_SSE_I387)
15895 && flag_unsafe_math_optimizations
15896 && standard_80387_constant_p (operands[3]) == 2"
15897 "fptan"
15898 [(set_attr "type" "fpspc")
15899 (set_attr "mode" "XF")])
15900
15901 (define_expand "tanxf2"
15902 [(use (match_operand:XF 0 "register_operand" ""))
15903 (use (match_operand:XF 1 "register_operand" ""))]
15904 "TARGET_USE_FANCY_MATH_387
15905 && flag_unsafe_math_optimizations"
15906 {
15907 rtx one = gen_reg_rtx (XFmode);
15908 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15909
15910 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15911 DONE;
15912 })
15913
15914 (define_expand "tan<mode>2"
15915 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15916 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
15917 "TARGET_USE_FANCY_MATH_387
15918 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15919 || TARGET_MIX_SSE_I387)
15920 && flag_unsafe_math_optimizations"
15921 {
15922 rtx op0 = gen_reg_rtx (XFmode);
15923
15924 rtx one = gen_reg_rtx (<MODE>mode);
15925 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15926
15927 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15928 operands[1], op2));
15929 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15930 DONE;
15931 })
15932
15933 (define_insn "*fpatanxf3_i387"
15934 [(set (match_operand:XF 0 "register_operand" "=f")
15935 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15936 (match_operand:XF 2 "register_operand" "u")]
15937 UNSPEC_FPATAN))
15938 (clobber (match_scratch:XF 3 "=2"))]
15939 "TARGET_USE_FANCY_MATH_387
15940 && flag_unsafe_math_optimizations"
15941 "fpatan"
15942 [(set_attr "type" "fpspc")
15943 (set_attr "mode" "XF")])
15944
15945 (define_insn "fpatan_extend<mode>xf3_i387"
15946 [(set (match_operand:XF 0 "register_operand" "=f")
15947 (unspec:XF [(float_extend:XF
15948 (match_operand:X87MODEF12 1 "register_operand" "0"))
15949 (float_extend:XF
15950 (match_operand:X87MODEF12 2 "register_operand" "u"))]
15951 UNSPEC_FPATAN))
15952 (clobber (match_scratch:XF 3 "=2"))]
15953 "TARGET_USE_FANCY_MATH_387
15954 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15955 || TARGET_MIX_SSE_I387)
15956 && flag_unsafe_math_optimizations"
15957 "fpatan"
15958 [(set_attr "type" "fpspc")
15959 (set_attr "mode" "XF")])
15960
15961 (define_expand "atan2xf3"
15962 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15963 (unspec:XF [(match_operand:XF 2 "register_operand" "")
15964 (match_operand:XF 1 "register_operand" "")]
15965 UNSPEC_FPATAN))
15966 (clobber (match_scratch:XF 3 ""))])]
15967 "TARGET_USE_FANCY_MATH_387
15968 && flag_unsafe_math_optimizations"
15969 "")
15970
15971 (define_expand "atan2<mode>3"
15972 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15973 (use (match_operand:X87MODEF12 1 "register_operand" ""))
15974 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15975 "TARGET_USE_FANCY_MATH_387
15976 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15977 || TARGET_MIX_SSE_I387)
15978 && flag_unsafe_math_optimizations"
15979 {
15980 rtx op0 = gen_reg_rtx (XFmode);
15981
15982 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15983 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15984 DONE;
15985 })
15986
15987 (define_expand "atanxf2"
15988 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15989 (unspec:XF [(match_dup 2)
15990 (match_operand:XF 1 "register_operand" "")]
15991 UNSPEC_FPATAN))
15992 (clobber (match_scratch:XF 3 ""))])]
15993 "TARGET_USE_FANCY_MATH_387
15994 && flag_unsafe_math_optimizations"
15995 {
15996 operands[2] = gen_reg_rtx (XFmode);
15997 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15998 })
15999
16000 (define_expand "atan<mode>2"
16001 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16002 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16003 "TARGET_USE_FANCY_MATH_387
16004 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16005 || TARGET_MIX_SSE_I387)
16006 && flag_unsafe_math_optimizations"
16007 {
16008 rtx op0 = gen_reg_rtx (XFmode);
16009
16010 rtx op2 = gen_reg_rtx (<MODE>mode);
16011 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16012
16013 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16014 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16015 DONE;
16016 })
16017
16018 (define_expand "asinxf2"
16019 [(set (match_dup 2)
16020 (mult:XF (match_operand:XF 1 "register_operand" "")
16021 (match_dup 1)))
16022 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16023 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16024 (parallel [(set (match_operand:XF 0 "register_operand" "")
16025 (unspec:XF [(match_dup 5) (match_dup 1)]
16026 UNSPEC_FPATAN))
16027 (clobber (match_scratch:XF 6 ""))])]
16028 "TARGET_USE_FANCY_MATH_387
16029 && flag_unsafe_math_optimizations && !optimize_size"
16030 {
16031 int i;
16032
16033 for (i = 2; i < 6; i++)
16034 operands[i] = gen_reg_rtx (XFmode);
16035
16036 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16037 })
16038
16039 (define_expand "asin<mode>2"
16040 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16041 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16042 "TARGET_USE_FANCY_MATH_387
16043 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16044 || TARGET_MIX_SSE_I387)
16045 && flag_unsafe_math_optimizations && !optimize_size"
16046 {
16047 rtx op0 = gen_reg_rtx (XFmode);
16048 rtx op1 = gen_reg_rtx (XFmode);
16049
16050 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16051 emit_insn (gen_asinxf2 (op0, op1));
16052 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16053 DONE;
16054 })
16055
16056 (define_expand "acosxf2"
16057 [(set (match_dup 2)
16058 (mult:XF (match_operand:XF 1 "register_operand" "")
16059 (match_dup 1)))
16060 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16061 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16062 (parallel [(set (match_operand:XF 0 "register_operand" "")
16063 (unspec:XF [(match_dup 1) (match_dup 5)]
16064 UNSPEC_FPATAN))
16065 (clobber (match_scratch:XF 6 ""))])]
16066 "TARGET_USE_FANCY_MATH_387
16067 && flag_unsafe_math_optimizations && !optimize_size"
16068 {
16069 int i;
16070
16071 for (i = 2; i < 6; i++)
16072 operands[i] = gen_reg_rtx (XFmode);
16073
16074 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16075 })
16076
16077 (define_expand "acos<mode>2"
16078 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16079 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16080 "TARGET_USE_FANCY_MATH_387
16081 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16082 || TARGET_MIX_SSE_I387)
16083 && flag_unsafe_math_optimizations && !optimize_size"
16084 {
16085 rtx op0 = gen_reg_rtx (XFmode);
16086 rtx op1 = gen_reg_rtx (XFmode);
16087
16088 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16089 emit_insn (gen_acosxf2 (op0, op1));
16090 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16091 DONE;
16092 })
16093
16094 (define_insn "fyl2xxf3_i387"
16095 [(set (match_operand:XF 0 "register_operand" "=f")
16096 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16097 (match_operand:XF 2 "register_operand" "u")]
16098 UNSPEC_FYL2X))
16099 (clobber (match_scratch:XF 3 "=2"))]
16100 "TARGET_USE_FANCY_MATH_387
16101 && flag_unsafe_math_optimizations"
16102 "fyl2x"
16103 [(set_attr "type" "fpspc")
16104 (set_attr "mode" "XF")])
16105
16106 (define_insn "fyl2x_extend<mode>xf3_i387"
16107 [(set (match_operand:XF 0 "register_operand" "=f")
16108 (unspec:XF [(float_extend:XF
16109 (match_operand:X87MODEF12 1 "register_operand" "0"))
16110 (match_operand:XF 2 "register_operand" "u")]
16111 UNSPEC_FYL2X))
16112 (clobber (match_scratch:XF 3 "=2"))]
16113 "TARGET_USE_FANCY_MATH_387
16114 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16115 || TARGET_MIX_SSE_I387)
16116 && flag_unsafe_math_optimizations"
16117 "fyl2x"
16118 [(set_attr "type" "fpspc")
16119 (set_attr "mode" "XF")])
16120
16121 (define_expand "logxf2"
16122 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16123 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16124 (match_dup 2)] UNSPEC_FYL2X))
16125 (clobber (match_scratch:XF 3 ""))])]
16126 "TARGET_USE_FANCY_MATH_387
16127 && flag_unsafe_math_optimizations"
16128 {
16129 operands[2] = gen_reg_rtx (XFmode);
16130 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16131 })
16132
16133 (define_expand "log<mode>2"
16134 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16135 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16136 "TARGET_USE_FANCY_MATH_387
16137 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16138 || TARGET_MIX_SSE_I387)
16139 && flag_unsafe_math_optimizations"
16140 {
16141 rtx op0 = gen_reg_rtx (XFmode);
16142
16143 rtx op2 = gen_reg_rtx (XFmode);
16144 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16145
16146 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16147 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16148 DONE;
16149 })
16150
16151 (define_expand "log10xf2"
16152 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16153 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16154 (match_dup 2)] UNSPEC_FYL2X))
16155 (clobber (match_scratch:XF 3 ""))])]
16156 "TARGET_USE_FANCY_MATH_387
16157 && flag_unsafe_math_optimizations"
16158 {
16159 operands[2] = gen_reg_rtx (XFmode);
16160 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16161 })
16162
16163 (define_expand "log10<mode>2"
16164 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16165 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16166 "TARGET_USE_FANCY_MATH_387
16167 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16168 || TARGET_MIX_SSE_I387)
16169 && flag_unsafe_math_optimizations"
16170 {
16171 rtx op0 = gen_reg_rtx (XFmode);
16172
16173 rtx op2 = gen_reg_rtx (XFmode);
16174 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16175
16176 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16177 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16178 DONE;
16179 })
16180
16181 (define_expand "log2xf2"
16182 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16183 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16184 (match_dup 2)] UNSPEC_FYL2X))
16185 (clobber (match_scratch:XF 3 ""))])]
16186 "TARGET_USE_FANCY_MATH_387
16187 && flag_unsafe_math_optimizations"
16188 {
16189 operands[2] = gen_reg_rtx (XFmode);
16190 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16191 })
16192
16193 (define_expand "log2<mode>2"
16194 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16195 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16196 "TARGET_USE_FANCY_MATH_387
16197 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16198 || TARGET_MIX_SSE_I387)
16199 && flag_unsafe_math_optimizations"
16200 {
16201 rtx op0 = gen_reg_rtx (XFmode);
16202
16203 rtx op2 = gen_reg_rtx (XFmode);
16204 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16205
16206 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16207 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16208 DONE;
16209 })
16210
16211 (define_insn "fyl2xp1xf3_i387"
16212 [(set (match_operand:XF 0 "register_operand" "=f")
16213 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16214 (match_operand:XF 2 "register_operand" "u")]
16215 UNSPEC_FYL2XP1))
16216 (clobber (match_scratch:XF 3 "=2"))]
16217 "TARGET_USE_FANCY_MATH_387
16218 && flag_unsafe_math_optimizations"
16219 "fyl2xp1"
16220 [(set_attr "type" "fpspc")
16221 (set_attr "mode" "XF")])
16222
16223 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16224 [(set (match_operand:XF 0 "register_operand" "=f")
16225 (unspec:XF [(float_extend:XF
16226 (match_operand:X87MODEF12 1 "register_operand" "0"))
16227 (match_operand:XF 2 "register_operand" "u")]
16228 UNSPEC_FYL2XP1))
16229 (clobber (match_scratch:XF 3 "=2"))]
16230 "TARGET_USE_FANCY_MATH_387
16231 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16232 || TARGET_MIX_SSE_I387)
16233 && flag_unsafe_math_optimizations"
16234 "fyl2xp1"
16235 [(set_attr "type" "fpspc")
16236 (set_attr "mode" "XF")])
16237
16238 (define_expand "log1pxf2"
16239 [(use (match_operand:XF 0 "register_operand" ""))
16240 (use (match_operand:XF 1 "register_operand" ""))]
16241 "TARGET_USE_FANCY_MATH_387
16242 && flag_unsafe_math_optimizations && !optimize_size"
16243 {
16244 ix86_emit_i387_log1p (operands[0], operands[1]);
16245 DONE;
16246 })
16247
16248 (define_expand "log1p<mode>2"
16249 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16250 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16251 "TARGET_USE_FANCY_MATH_387
16252 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16253 || TARGET_MIX_SSE_I387)
16254 && flag_unsafe_math_optimizations && !optimize_size"
16255 {
16256 rtx op0 = gen_reg_rtx (XFmode);
16257
16258 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16259
16260 ix86_emit_i387_log1p (op0, operands[1]);
16261 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16262 DONE;
16263 })
16264
16265 (define_insn "fxtractxf3_i387"
16266 [(set (match_operand:XF 0 "register_operand" "=f")
16267 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16268 UNSPEC_XTRACT_FRACT))
16269 (set (match_operand:XF 1 "register_operand" "=u")
16270 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16271 "TARGET_USE_FANCY_MATH_387
16272 && flag_unsafe_math_optimizations"
16273 "fxtract"
16274 [(set_attr "type" "fpspc")
16275 (set_attr "mode" "XF")])
16276
16277 (define_insn "fxtract_extend<mode>xf3_i387"
16278 [(set (match_operand:XF 0 "register_operand" "=f")
16279 (unspec:XF [(float_extend:XF
16280 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16281 UNSPEC_XTRACT_FRACT))
16282 (set (match_operand:XF 1 "register_operand" "=u")
16283 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16284 "TARGET_USE_FANCY_MATH_387
16285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16286 || TARGET_MIX_SSE_I387)
16287 && flag_unsafe_math_optimizations"
16288 "fxtract"
16289 [(set_attr "type" "fpspc")
16290 (set_attr "mode" "XF")])
16291
16292 (define_expand "logbxf2"
16293 [(parallel [(set (match_dup 2)
16294 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16295 UNSPEC_XTRACT_FRACT))
16296 (set (match_operand:XF 0 "register_operand" "")
16297 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16298 "TARGET_USE_FANCY_MATH_387
16299 && flag_unsafe_math_optimizations"
16300 {
16301 operands[2] = gen_reg_rtx (XFmode);
16302 })
16303
16304 (define_expand "logb<mode>2"
16305 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16306 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16307 "TARGET_USE_FANCY_MATH_387
16308 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16309 || TARGET_MIX_SSE_I387)
16310 && flag_unsafe_math_optimizations"
16311 {
16312 rtx op0 = gen_reg_rtx (XFmode);
16313 rtx op1 = gen_reg_rtx (XFmode);
16314
16315 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16316 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16317 DONE;
16318 })
16319
16320 (define_expand "ilogbxf2"
16321 [(use (match_operand:SI 0 "register_operand" ""))
16322 (use (match_operand:XF 1 "register_operand" ""))]
16323 "TARGET_USE_FANCY_MATH_387
16324 && flag_unsafe_math_optimizations && !optimize_size"
16325 {
16326 rtx op0 = gen_reg_rtx (XFmode);
16327 rtx op1 = gen_reg_rtx (XFmode);
16328
16329 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16330 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16331 DONE;
16332 })
16333
16334 (define_expand "ilogb<mode>2"
16335 [(use (match_operand:SI 0 "register_operand" ""))
16336 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
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 && !optimize_size"
16341 {
16342 rtx op0 = gen_reg_rtx (XFmode);
16343 rtx op1 = gen_reg_rtx (XFmode);
16344
16345 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16346 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16347 DONE;
16348 })
16349
16350 (define_insn "*f2xm1xf2_i387"
16351 [(set (match_operand:XF 0 "register_operand" "=f")
16352 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16353 UNSPEC_F2XM1))]
16354 "TARGET_USE_FANCY_MATH_387
16355 && flag_unsafe_math_optimizations"
16356 "f2xm1"
16357 [(set_attr "type" "fpspc")
16358 (set_attr "mode" "XF")])
16359
16360 (define_insn "*fscalexf4_i387"
16361 [(set (match_operand:XF 0 "register_operand" "=f")
16362 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16363 (match_operand:XF 3 "register_operand" "1")]
16364 UNSPEC_FSCALE_FRACT))
16365 (set (match_operand:XF 1 "register_operand" "=u")
16366 (unspec:XF [(match_dup 2) (match_dup 3)]
16367 UNSPEC_FSCALE_EXP))]
16368 "TARGET_USE_FANCY_MATH_387
16369 && flag_unsafe_math_optimizations"
16370 "fscale"
16371 [(set_attr "type" "fpspc")
16372 (set_attr "mode" "XF")])
16373
16374 (define_expand "expNcorexf3"
16375 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16376 (match_operand:XF 2 "register_operand" "")))
16377 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16378 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16379 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16380 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16381 (parallel [(set (match_operand:XF 0 "register_operand" "")
16382 (unspec:XF [(match_dup 8) (match_dup 4)]
16383 UNSPEC_FSCALE_FRACT))
16384 (set (match_dup 9)
16385 (unspec:XF [(match_dup 8) (match_dup 4)]
16386 UNSPEC_FSCALE_EXP))])]
16387 "TARGET_USE_FANCY_MATH_387
16388 && flag_unsafe_math_optimizations && !optimize_size"
16389 {
16390 int i;
16391
16392 for (i = 3; i < 10; i++)
16393 operands[i] = gen_reg_rtx (XFmode);
16394
16395 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16396 })
16397
16398 (define_expand "expxf2"
16399 [(use (match_operand:XF 0 "register_operand" ""))
16400 (use (match_operand:XF 1 "register_operand" ""))]
16401 "TARGET_USE_FANCY_MATH_387
16402 && flag_unsafe_math_optimizations && !optimize_size"
16403 {
16404 rtx op2 = gen_reg_rtx (XFmode);
16405 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16406
16407 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16408 DONE;
16409 })
16410
16411 (define_expand "exp<mode>2"
16412 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16413 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
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 && !optimize_size"
16418 {
16419 rtx op0 = gen_reg_rtx (XFmode);
16420 rtx op1 = gen_reg_rtx (XFmode);
16421
16422 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16423 emit_insn (gen_expxf2 (op0, op1));
16424 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16425 DONE;
16426 })
16427
16428 (define_expand "exp10xf2"
16429 [(use (match_operand:XF 0 "register_operand" ""))
16430 (use (match_operand:XF 1 "register_operand" ""))]
16431 "TARGET_USE_FANCY_MATH_387
16432 && flag_unsafe_math_optimizations && !optimize_size"
16433 {
16434 rtx op2 = gen_reg_rtx (XFmode);
16435 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16436
16437 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16438 DONE;
16439 })
16440
16441 (define_expand "exp10<mode>2"
16442 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16443 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16444 "TARGET_USE_FANCY_MATH_387
16445 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16446 || TARGET_MIX_SSE_I387)
16447 && flag_unsafe_math_optimizations && !optimize_size"
16448 {
16449 rtx op0 = gen_reg_rtx (XFmode);
16450 rtx op1 = gen_reg_rtx (XFmode);
16451
16452 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16453 emit_insn (gen_exp10xf2 (op0, op1));
16454 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16455 DONE;
16456 })
16457
16458 (define_expand "exp2xf2"
16459 [(use (match_operand:XF 0 "register_operand" ""))
16460 (use (match_operand:XF 1 "register_operand" ""))]
16461 "TARGET_USE_FANCY_MATH_387
16462 && flag_unsafe_math_optimizations && !optimize_size"
16463 {
16464 rtx op2 = gen_reg_rtx (XFmode);
16465 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16466
16467 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16468 DONE;
16469 })
16470
16471 (define_expand "exp2<mode>2"
16472 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16473 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16474 "TARGET_USE_FANCY_MATH_387
16475 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16476 || TARGET_MIX_SSE_I387)
16477 && flag_unsafe_math_optimizations && !optimize_size"
16478 {
16479 rtx op0 = gen_reg_rtx (XFmode);
16480 rtx op1 = gen_reg_rtx (XFmode);
16481
16482 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16483 emit_insn (gen_exp2xf2 (op0, op1));
16484 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16485 DONE;
16486 })
16487
16488 (define_expand "expm1xf2"
16489 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16490 (match_dup 2)))
16491 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16492 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16493 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16494 (parallel [(set (match_dup 7)
16495 (unspec:XF [(match_dup 6) (match_dup 4)]
16496 UNSPEC_FSCALE_FRACT))
16497 (set (match_dup 8)
16498 (unspec:XF [(match_dup 6) (match_dup 4)]
16499 UNSPEC_FSCALE_EXP))])
16500 (parallel [(set (match_dup 10)
16501 (unspec:XF [(match_dup 9) (match_dup 8)]
16502 UNSPEC_FSCALE_FRACT))
16503 (set (match_dup 11)
16504 (unspec:XF [(match_dup 9) (match_dup 8)]
16505 UNSPEC_FSCALE_EXP))])
16506 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16507 (set (match_operand:XF 0 "register_operand" "")
16508 (plus:XF (match_dup 12) (match_dup 7)))]
16509 "TARGET_USE_FANCY_MATH_387
16510 && flag_unsafe_math_optimizations && !optimize_size"
16511 {
16512 int i;
16513
16514 for (i = 2; i < 13; i++)
16515 operands[i] = gen_reg_rtx (XFmode);
16516
16517 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16518 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16519 })
16520
16521 (define_expand "expm1<mode>2"
16522 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16523 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16524 "TARGET_USE_FANCY_MATH_387
16525 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16526 || TARGET_MIX_SSE_I387)
16527 && flag_unsafe_math_optimizations && !optimize_size"
16528 {
16529 rtx op0 = gen_reg_rtx (XFmode);
16530 rtx op1 = gen_reg_rtx (XFmode);
16531
16532 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16533 emit_insn (gen_expm1xf2 (op0, op1));
16534 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16535 DONE;
16536 })
16537
16538 (define_expand "ldexpxf3"
16539 [(set (match_dup 3)
16540 (float:XF (match_operand:SI 2 "register_operand" "")))
16541 (parallel [(set (match_operand:XF 0 " register_operand" "")
16542 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16543 (match_dup 3)]
16544 UNSPEC_FSCALE_FRACT))
16545 (set (match_dup 4)
16546 (unspec:XF [(match_dup 1) (match_dup 3)]
16547 UNSPEC_FSCALE_EXP))])]
16548 "TARGET_USE_FANCY_MATH_387
16549 && flag_unsafe_math_optimizations && !optimize_size"
16550 {
16551 operands[3] = gen_reg_rtx (XFmode);
16552 operands[4] = gen_reg_rtx (XFmode);
16553 })
16554
16555 (define_expand "ldexp<mode>3"
16556 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16557 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16558 (use (match_operand:SI 2 "register_operand" ""))]
16559 "TARGET_USE_FANCY_MATH_387
16560 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16561 || TARGET_MIX_SSE_I387)
16562 && flag_unsafe_math_optimizations && !optimize_size"
16563 {
16564 rtx op0 = gen_reg_rtx (XFmode);
16565 rtx op1 = gen_reg_rtx (XFmode);
16566
16567 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16568 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16569 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16570 DONE;
16571 })
16572 \f
16573
16574 (define_insn "frndintxf2"
16575 [(set (match_operand:XF 0 "register_operand" "=f")
16576 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16577 UNSPEC_FRNDINT))]
16578 "TARGET_USE_FANCY_MATH_387
16579 && flag_unsafe_math_optimizations"
16580 "frndint"
16581 [(set_attr "type" "fpspc")
16582 (set_attr "mode" "XF")])
16583
16584 (define_expand "rintdf2"
16585 [(use (match_operand:DF 0 "register_operand" ""))
16586 (use (match_operand:DF 1 "register_operand" ""))]
16587 "(TARGET_USE_FANCY_MATH_387
16588 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16589 && flag_unsafe_math_optimizations)
16590 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16591 && !flag_trapping_math
16592 && !optimize_size)"
16593 {
16594 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16595 && !flag_trapping_math
16596 && !optimize_size)
16597 ix86_expand_rint (operand0, operand1);
16598 else
16599 {
16600 rtx op0 = gen_reg_rtx (XFmode);
16601 rtx op1 = gen_reg_rtx (XFmode);
16602
16603 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16604 emit_insn (gen_frndintxf2 (op0, op1));
16605
16606 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16607 }
16608 DONE;
16609 })
16610
16611 (define_expand "rintsf2"
16612 [(use (match_operand:SF 0 "register_operand" ""))
16613 (use (match_operand:SF 1 "register_operand" ""))]
16614 "(TARGET_USE_FANCY_MATH_387
16615 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16616 && flag_unsafe_math_optimizations)
16617 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16618 && !flag_trapping_math
16619 && !optimize_size)"
16620 {
16621 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16622 && !flag_trapping_math
16623 && !optimize_size)
16624 ix86_expand_rint (operand0, operand1);
16625 else
16626 {
16627 rtx op0 = gen_reg_rtx (XFmode);
16628 rtx op1 = gen_reg_rtx (XFmode);
16629
16630 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16631 emit_insn (gen_frndintxf2 (op0, op1));
16632
16633 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16634 }
16635 DONE;
16636 })
16637
16638 (define_expand "rintxf2"
16639 [(use (match_operand:XF 0 "register_operand" ""))
16640 (use (match_operand:XF 1 "register_operand" ""))]
16641 "TARGET_USE_FANCY_MATH_387
16642 && flag_unsafe_math_optimizations && !optimize_size"
16643 {
16644 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16645 DONE;
16646 })
16647
16648 (define_expand "roundsf2"
16649 [(match_operand:SF 0 "register_operand" "")
16650 (match_operand:SF 1 "nonimmediate_operand" "")]
16651 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16652 && !flag_trapping_math && !flag_rounding_math
16653 && !optimize_size"
16654 {
16655 ix86_expand_round (operand0, operand1);
16656 DONE;
16657 })
16658
16659 (define_expand "rounddf2"
16660 [(match_operand:DF 0 "register_operand" "")
16661 (match_operand:DF 1 "nonimmediate_operand" "")]
16662 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16663 && !flag_trapping_math && !flag_rounding_math
16664 && !optimize_size"
16665 {
16666 if (TARGET_64BIT)
16667 ix86_expand_round (operand0, operand1);
16668 else
16669 ix86_expand_rounddf_32 (operand0, operand1);
16670 DONE;
16671 })
16672
16673 (define_insn_and_split "*fistdi2_1"
16674 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16675 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16676 UNSPEC_FIST))]
16677 "TARGET_USE_FANCY_MATH_387
16678 && !(reload_completed || reload_in_progress)"
16679 "#"
16680 "&& 1"
16681 [(const_int 0)]
16682 {
16683 if (memory_operand (operands[0], VOIDmode))
16684 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16685 else
16686 {
16687 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16688 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16689 operands[2]));
16690 }
16691 DONE;
16692 }
16693 [(set_attr "type" "fpspc")
16694 (set_attr "mode" "DI")])
16695
16696 (define_insn "fistdi2"
16697 [(set (match_operand:DI 0 "memory_operand" "=m")
16698 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16699 UNSPEC_FIST))
16700 (clobber (match_scratch:XF 2 "=&1f"))]
16701 "TARGET_USE_FANCY_MATH_387"
16702 "* return output_fix_trunc (insn, operands, 0);"
16703 [(set_attr "type" "fpspc")
16704 (set_attr "mode" "DI")])
16705
16706 (define_insn "fistdi2_with_temp"
16707 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16708 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16709 UNSPEC_FIST))
16710 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16711 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16712 "TARGET_USE_FANCY_MATH_387"
16713 "#"
16714 [(set_attr "type" "fpspc")
16715 (set_attr "mode" "DI")])
16716
16717 (define_split
16718 [(set (match_operand:DI 0 "register_operand" "")
16719 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16720 UNSPEC_FIST))
16721 (clobber (match_operand:DI 2 "memory_operand" ""))
16722 (clobber (match_scratch 3 ""))]
16723 "reload_completed"
16724 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16725 (clobber (match_dup 3))])
16726 (set (match_dup 0) (match_dup 2))]
16727 "")
16728
16729 (define_split
16730 [(set (match_operand:DI 0 "memory_operand" "")
16731 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16732 UNSPEC_FIST))
16733 (clobber (match_operand:DI 2 "memory_operand" ""))
16734 (clobber (match_scratch 3 ""))]
16735 "reload_completed"
16736 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16737 (clobber (match_dup 3))])]
16738 "")
16739
16740 (define_insn_and_split "*fist<mode>2_1"
16741 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16742 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16743 UNSPEC_FIST))]
16744 "TARGET_USE_FANCY_MATH_387
16745 && !(reload_completed || reload_in_progress)"
16746 "#"
16747 "&& 1"
16748 [(const_int 0)]
16749 {
16750 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16751 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16752 operands[2]));
16753 DONE;
16754 }
16755 [(set_attr "type" "fpspc")
16756 (set_attr "mode" "<MODE>")])
16757
16758 (define_insn "fist<mode>2"
16759 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16760 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16761 UNSPEC_FIST))]
16762 "TARGET_USE_FANCY_MATH_387"
16763 "* return output_fix_trunc (insn, operands, 0);"
16764 [(set_attr "type" "fpspc")
16765 (set_attr "mode" "<MODE>")])
16766
16767 (define_insn "fist<mode>2_with_temp"
16768 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16769 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16770 UNSPEC_FIST))
16771 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16772 "TARGET_USE_FANCY_MATH_387"
16773 "#"
16774 [(set_attr "type" "fpspc")
16775 (set_attr "mode" "<MODE>")])
16776
16777 (define_split
16778 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16779 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16780 UNSPEC_FIST))
16781 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16782 "reload_completed"
16783 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16784 UNSPEC_FIST))
16785 (set (match_dup 0) (match_dup 2))]
16786 "")
16787
16788 (define_split
16789 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16790 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16791 UNSPEC_FIST))
16792 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16793 "reload_completed"
16794 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16795 UNSPEC_FIST))]
16796 "")
16797
16798 (define_expand "lrintxf<mode>2"
16799 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16800 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16801 UNSPEC_FIST))]
16802 "TARGET_USE_FANCY_MATH_387"
16803 "")
16804
16805 (define_expand "lrint<mode>di2"
16806 [(set (match_operand:DI 0 "nonimmediate_operand" "")
16807 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
16808 UNSPEC_FIX_NOTRUNC))]
16809 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
16810 "")
16811
16812 (define_expand "lrint<mode>si2"
16813 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16814 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
16815 UNSPEC_FIX_NOTRUNC))]
16816 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16817 "")
16818
16819 (define_expand "lround<mode>di2"
16820 [(match_operand:DI 0 "nonimmediate_operand" "")
16821 (match_operand:SSEMODEF 1 "register_operand" "")]
16822 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
16823 && !flag_trapping_math && !flag_rounding_math
16824 && !optimize_size"
16825 {
16826 ix86_expand_lround (operand0, operand1);
16827 DONE;
16828 })
16829
16830 (define_expand "lround<mode>si2"
16831 [(match_operand:SI 0 "nonimmediate_operand" "")
16832 (match_operand:SSEMODEF 1 "register_operand" "")]
16833 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16834 && !flag_trapping_math && !flag_rounding_math
16835 && !optimize_size"
16836 {
16837 ix86_expand_lround (operand0, operand1);
16838 DONE;
16839 })
16840
16841 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16842 (define_insn_and_split "frndintxf2_floor"
16843 [(set (match_operand:XF 0 "register_operand" "=f")
16844 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16845 UNSPEC_FRNDINT_FLOOR))
16846 (clobber (reg:CC FLAGS_REG))]
16847 "TARGET_USE_FANCY_MATH_387
16848 && flag_unsafe_math_optimizations
16849 && !(reload_completed || reload_in_progress)"
16850 "#"
16851 "&& 1"
16852 [(const_int 0)]
16853 {
16854 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16855
16856 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16857 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16858
16859 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16860 operands[2], operands[3]));
16861 DONE;
16862 }
16863 [(set_attr "type" "frndint")
16864 (set_attr "i387_cw" "floor")
16865 (set_attr "mode" "XF")])
16866
16867 (define_insn "frndintxf2_floor_i387"
16868 [(set (match_operand:XF 0 "register_operand" "=f")
16869 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16870 UNSPEC_FRNDINT_FLOOR))
16871 (use (match_operand:HI 2 "memory_operand" "m"))
16872 (use (match_operand:HI 3 "memory_operand" "m"))]
16873 "TARGET_USE_FANCY_MATH_387
16874 && flag_unsafe_math_optimizations"
16875 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16876 [(set_attr "type" "frndint")
16877 (set_attr "i387_cw" "floor")
16878 (set_attr "mode" "XF")])
16879
16880 (define_expand "floorxf2"
16881 [(use (match_operand:XF 0 "register_operand" ""))
16882 (use (match_operand:XF 1 "register_operand" ""))]
16883 "TARGET_USE_FANCY_MATH_387
16884 && flag_unsafe_math_optimizations && !optimize_size"
16885 {
16886 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16887 DONE;
16888 })
16889
16890 (define_expand "floordf2"
16891 [(use (match_operand:DF 0 "register_operand" ""))
16892 (use (match_operand:DF 1 "register_operand" ""))]
16893 "((TARGET_USE_FANCY_MATH_387
16894 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16895 && flag_unsafe_math_optimizations)
16896 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16897 && !flag_trapping_math))
16898 && !optimize_size"
16899 {
16900 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16901 && !flag_trapping_math)
16902 {
16903 if (TARGET_64BIT)
16904 ix86_expand_floorceil (operand0, operand1, true);
16905 else
16906 ix86_expand_floorceildf_32 (operand0, operand1, true);
16907 }
16908 else
16909 {
16910 rtx op0 = gen_reg_rtx (XFmode);
16911 rtx op1 = gen_reg_rtx (XFmode);
16912
16913 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16914 emit_insn (gen_frndintxf2_floor (op0, op1));
16915
16916 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16917 }
16918 DONE;
16919 })
16920
16921 (define_expand "floorsf2"
16922 [(use (match_operand:SF 0 "register_operand" ""))
16923 (use (match_operand:SF 1 "register_operand" ""))]
16924 "((TARGET_USE_FANCY_MATH_387
16925 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16926 && flag_unsafe_math_optimizations)
16927 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16928 && !flag_trapping_math))
16929 && !optimize_size"
16930 {
16931 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16932 && !flag_trapping_math)
16933 ix86_expand_floorceil (operand0, operand1, true);
16934 else
16935 {
16936 rtx op0 = gen_reg_rtx (XFmode);
16937 rtx op1 = gen_reg_rtx (XFmode);
16938
16939 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16940 emit_insn (gen_frndintxf2_floor (op0, op1));
16941
16942 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16943 }
16944 DONE;
16945 })
16946
16947 (define_insn_and_split "*fist<mode>2_floor_1"
16948 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16949 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16950 UNSPEC_FIST_FLOOR))
16951 (clobber (reg:CC FLAGS_REG))]
16952 "TARGET_USE_FANCY_MATH_387
16953 && flag_unsafe_math_optimizations
16954 && !(reload_completed || reload_in_progress)"
16955 "#"
16956 "&& 1"
16957 [(const_int 0)]
16958 {
16959 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16960
16961 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16962 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16963 if (memory_operand (operands[0], VOIDmode))
16964 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16965 operands[2], operands[3]));
16966 else
16967 {
16968 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16969 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16970 operands[2], operands[3],
16971 operands[4]));
16972 }
16973 DONE;
16974 }
16975 [(set_attr "type" "fistp")
16976 (set_attr "i387_cw" "floor")
16977 (set_attr "mode" "<MODE>")])
16978
16979 (define_insn "fistdi2_floor"
16980 [(set (match_operand:DI 0 "memory_operand" "=m")
16981 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16982 UNSPEC_FIST_FLOOR))
16983 (use (match_operand:HI 2 "memory_operand" "m"))
16984 (use (match_operand:HI 3 "memory_operand" "m"))
16985 (clobber (match_scratch:XF 4 "=&1f"))]
16986 "TARGET_USE_FANCY_MATH_387
16987 && flag_unsafe_math_optimizations"
16988 "* return output_fix_trunc (insn, operands, 0);"
16989 [(set_attr "type" "fistp")
16990 (set_attr "i387_cw" "floor")
16991 (set_attr "mode" "DI")])
16992
16993 (define_insn "fistdi2_floor_with_temp"
16994 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16995 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16996 UNSPEC_FIST_FLOOR))
16997 (use (match_operand:HI 2 "memory_operand" "m,m"))
16998 (use (match_operand:HI 3 "memory_operand" "m,m"))
16999 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17000 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17001 "TARGET_USE_FANCY_MATH_387
17002 && flag_unsafe_math_optimizations"
17003 "#"
17004 [(set_attr "type" "fistp")
17005 (set_attr "i387_cw" "floor")
17006 (set_attr "mode" "DI")])
17007
17008 (define_split
17009 [(set (match_operand:DI 0 "register_operand" "")
17010 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17011 UNSPEC_FIST_FLOOR))
17012 (use (match_operand:HI 2 "memory_operand" ""))
17013 (use (match_operand:HI 3 "memory_operand" ""))
17014 (clobber (match_operand:DI 4 "memory_operand" ""))
17015 (clobber (match_scratch 5 ""))]
17016 "reload_completed"
17017 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17018 (use (match_dup 2))
17019 (use (match_dup 3))
17020 (clobber (match_dup 5))])
17021 (set (match_dup 0) (match_dup 4))]
17022 "")
17023
17024 (define_split
17025 [(set (match_operand:DI 0 "memory_operand" "")
17026 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17027 UNSPEC_FIST_FLOOR))
17028 (use (match_operand:HI 2 "memory_operand" ""))
17029 (use (match_operand:HI 3 "memory_operand" ""))
17030 (clobber (match_operand:DI 4 "memory_operand" ""))
17031 (clobber (match_scratch 5 ""))]
17032 "reload_completed"
17033 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17034 (use (match_dup 2))
17035 (use (match_dup 3))
17036 (clobber (match_dup 5))])]
17037 "")
17038
17039 (define_insn "fist<mode>2_floor"
17040 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17041 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17042 UNSPEC_FIST_FLOOR))
17043 (use (match_operand:HI 2 "memory_operand" "m"))
17044 (use (match_operand:HI 3 "memory_operand" "m"))]
17045 "TARGET_USE_FANCY_MATH_387
17046 && flag_unsafe_math_optimizations"
17047 "* return output_fix_trunc (insn, operands, 0);"
17048 [(set_attr "type" "fistp")
17049 (set_attr "i387_cw" "floor")
17050 (set_attr "mode" "<MODE>")])
17051
17052 (define_insn "fist<mode>2_floor_with_temp"
17053 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17054 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17055 UNSPEC_FIST_FLOOR))
17056 (use (match_operand:HI 2 "memory_operand" "m,m"))
17057 (use (match_operand:HI 3 "memory_operand" "m,m"))
17058 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17059 "TARGET_USE_FANCY_MATH_387
17060 && flag_unsafe_math_optimizations"
17061 "#"
17062 [(set_attr "type" "fistp")
17063 (set_attr "i387_cw" "floor")
17064 (set_attr "mode" "<MODE>")])
17065
17066 (define_split
17067 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17068 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17069 UNSPEC_FIST_FLOOR))
17070 (use (match_operand:HI 2 "memory_operand" ""))
17071 (use (match_operand:HI 3 "memory_operand" ""))
17072 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17073 "reload_completed"
17074 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17075 UNSPEC_FIST_FLOOR))
17076 (use (match_dup 2))
17077 (use (match_dup 3))])
17078 (set (match_dup 0) (match_dup 4))]
17079 "")
17080
17081 (define_split
17082 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17083 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17084 UNSPEC_FIST_FLOOR))
17085 (use (match_operand:HI 2 "memory_operand" ""))
17086 (use (match_operand:HI 3 "memory_operand" ""))
17087 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17088 "reload_completed"
17089 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17090 UNSPEC_FIST_FLOOR))
17091 (use (match_dup 2))
17092 (use (match_dup 3))])]
17093 "")
17094
17095 (define_expand "lfloorxf<mode>2"
17096 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17097 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17098 UNSPEC_FIST_FLOOR))
17099 (clobber (reg:CC FLAGS_REG))])]
17100 "TARGET_USE_FANCY_MATH_387
17101 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17102 && flag_unsafe_math_optimizations"
17103 "")
17104
17105 (define_expand "lfloor<mode>di2"
17106 [(match_operand:DI 0 "nonimmediate_operand" "")
17107 (match_operand:SSEMODEF 1 "register_operand" "")]
17108 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17109 && !flag_trapping_math
17110 && !optimize_size"
17111 {
17112 ix86_expand_lfloorceil (operand0, operand1, true);
17113 DONE;
17114 })
17115
17116 (define_expand "lfloor<mode>si2"
17117 [(match_operand:SI 0 "nonimmediate_operand" "")
17118 (match_operand:SSEMODEF 1 "register_operand" "")]
17119 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17120 && !flag_trapping_math
17121 && (!optimize_size || !TARGET_64BIT)"
17122 {
17123 ix86_expand_lfloorceil (operand0, operand1, true);
17124 DONE;
17125 })
17126
17127 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17128 (define_insn_and_split "frndintxf2_ceil"
17129 [(set (match_operand:XF 0 "register_operand" "=f")
17130 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17131 UNSPEC_FRNDINT_CEIL))
17132 (clobber (reg:CC FLAGS_REG))]
17133 "TARGET_USE_FANCY_MATH_387
17134 && flag_unsafe_math_optimizations
17135 && !(reload_completed || reload_in_progress)"
17136 "#"
17137 "&& 1"
17138 [(const_int 0)]
17139 {
17140 ix86_optimize_mode_switching[I387_CEIL] = 1;
17141
17142 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17143 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17144
17145 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17146 operands[2], operands[3]));
17147 DONE;
17148 }
17149 [(set_attr "type" "frndint")
17150 (set_attr "i387_cw" "ceil")
17151 (set_attr "mode" "XF")])
17152
17153 (define_insn "frndintxf2_ceil_i387"
17154 [(set (match_operand:XF 0 "register_operand" "=f")
17155 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17156 UNSPEC_FRNDINT_CEIL))
17157 (use (match_operand:HI 2 "memory_operand" "m"))
17158 (use (match_operand:HI 3 "memory_operand" "m"))]
17159 "TARGET_USE_FANCY_MATH_387
17160 && flag_unsafe_math_optimizations"
17161 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17162 [(set_attr "type" "frndint")
17163 (set_attr "i387_cw" "ceil")
17164 (set_attr "mode" "XF")])
17165
17166 (define_expand "ceilxf2"
17167 [(use (match_operand:XF 0 "register_operand" ""))
17168 (use (match_operand:XF 1 "register_operand" ""))]
17169 "TARGET_USE_FANCY_MATH_387
17170 && flag_unsafe_math_optimizations && !optimize_size"
17171 {
17172 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17173 DONE;
17174 })
17175
17176 (define_expand "ceildf2"
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 {
17189 if (TARGET_64BIT)
17190 ix86_expand_floorceil (operand0, operand1, false);
17191 else
17192 ix86_expand_floorceildf_32 (operand0, operand1, false);
17193 }
17194 else
17195 {
17196 rtx op0 = gen_reg_rtx (XFmode);
17197 rtx op1 = gen_reg_rtx (XFmode);
17198
17199 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17200 emit_insn (gen_frndintxf2_ceil (op0, op1));
17201
17202 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17203 }
17204 DONE;
17205 })
17206
17207 (define_expand "ceilsf2"
17208 [(use (match_operand:SF 0 "register_operand" ""))
17209 (use (match_operand:SF 1 "register_operand" ""))]
17210 "((TARGET_USE_FANCY_MATH_387
17211 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17212 && flag_unsafe_math_optimizations)
17213 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17214 && !flag_trapping_math))
17215 && !optimize_size"
17216 {
17217 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17218 && !flag_trapping_math)
17219 ix86_expand_floorceil (operand0, operand1, false);
17220 else
17221 {
17222 rtx op0 = gen_reg_rtx (XFmode);
17223 rtx op1 = gen_reg_rtx (XFmode);
17224
17225 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17226 emit_insn (gen_frndintxf2_ceil (op0, op1));
17227
17228 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17229 }
17230 DONE;
17231 })
17232
17233 (define_insn_and_split "*fist<mode>2_ceil_1"
17234 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17235 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17236 UNSPEC_FIST_CEIL))
17237 (clobber (reg:CC FLAGS_REG))]
17238 "TARGET_USE_FANCY_MATH_387
17239 && flag_unsafe_math_optimizations
17240 && !(reload_completed || reload_in_progress)"
17241 "#"
17242 "&& 1"
17243 [(const_int 0)]
17244 {
17245 ix86_optimize_mode_switching[I387_CEIL] = 1;
17246
17247 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17248 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17249 if (memory_operand (operands[0], VOIDmode))
17250 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17251 operands[2], operands[3]));
17252 else
17253 {
17254 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17255 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17256 operands[2], operands[3],
17257 operands[4]));
17258 }
17259 DONE;
17260 }
17261 [(set_attr "type" "fistp")
17262 (set_attr "i387_cw" "ceil")
17263 (set_attr "mode" "<MODE>")])
17264
17265 (define_insn "fistdi2_ceil"
17266 [(set (match_operand:DI 0 "memory_operand" "=m")
17267 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17268 UNSPEC_FIST_CEIL))
17269 (use (match_operand:HI 2 "memory_operand" "m"))
17270 (use (match_operand:HI 3 "memory_operand" "m"))
17271 (clobber (match_scratch:XF 4 "=&1f"))]
17272 "TARGET_USE_FANCY_MATH_387
17273 && flag_unsafe_math_optimizations"
17274 "* return output_fix_trunc (insn, operands, 0);"
17275 [(set_attr "type" "fistp")
17276 (set_attr "i387_cw" "ceil")
17277 (set_attr "mode" "DI")])
17278
17279 (define_insn "fistdi2_ceil_with_temp"
17280 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17281 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17282 UNSPEC_FIST_CEIL))
17283 (use (match_operand:HI 2 "memory_operand" "m,m"))
17284 (use (match_operand:HI 3 "memory_operand" "m,m"))
17285 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17286 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17287 "TARGET_USE_FANCY_MATH_387
17288 && flag_unsafe_math_optimizations"
17289 "#"
17290 [(set_attr "type" "fistp")
17291 (set_attr "i387_cw" "ceil")
17292 (set_attr "mode" "DI")])
17293
17294 (define_split
17295 [(set (match_operand:DI 0 "register_operand" "")
17296 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17297 UNSPEC_FIST_CEIL))
17298 (use (match_operand:HI 2 "memory_operand" ""))
17299 (use (match_operand:HI 3 "memory_operand" ""))
17300 (clobber (match_operand:DI 4 "memory_operand" ""))
17301 (clobber (match_scratch 5 ""))]
17302 "reload_completed"
17303 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17304 (use (match_dup 2))
17305 (use (match_dup 3))
17306 (clobber (match_dup 5))])
17307 (set (match_dup 0) (match_dup 4))]
17308 "")
17309
17310 (define_split
17311 [(set (match_operand:DI 0 "memory_operand" "")
17312 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17313 UNSPEC_FIST_CEIL))
17314 (use (match_operand:HI 2 "memory_operand" ""))
17315 (use (match_operand:HI 3 "memory_operand" ""))
17316 (clobber (match_operand:DI 4 "memory_operand" ""))
17317 (clobber (match_scratch 5 ""))]
17318 "reload_completed"
17319 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17320 (use (match_dup 2))
17321 (use (match_dup 3))
17322 (clobber (match_dup 5))])]
17323 "")
17324
17325 (define_insn "fist<mode>2_ceil"
17326 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17327 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17328 UNSPEC_FIST_CEIL))
17329 (use (match_operand:HI 2 "memory_operand" "m"))
17330 (use (match_operand:HI 3 "memory_operand" "m"))]
17331 "TARGET_USE_FANCY_MATH_387
17332 && flag_unsafe_math_optimizations"
17333 "* return output_fix_trunc (insn, operands, 0);"
17334 [(set_attr "type" "fistp")
17335 (set_attr "i387_cw" "ceil")
17336 (set_attr "mode" "<MODE>")])
17337
17338 (define_insn "fist<mode>2_ceil_with_temp"
17339 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17340 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17341 UNSPEC_FIST_CEIL))
17342 (use (match_operand:HI 2 "memory_operand" "m,m"))
17343 (use (match_operand:HI 3 "memory_operand" "m,m"))
17344 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17345 "TARGET_USE_FANCY_MATH_387
17346 && flag_unsafe_math_optimizations"
17347 "#"
17348 [(set_attr "type" "fistp")
17349 (set_attr "i387_cw" "ceil")
17350 (set_attr "mode" "<MODE>")])
17351
17352 (define_split
17353 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17354 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17355 UNSPEC_FIST_CEIL))
17356 (use (match_operand:HI 2 "memory_operand" ""))
17357 (use (match_operand:HI 3 "memory_operand" ""))
17358 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17359 "reload_completed"
17360 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17361 UNSPEC_FIST_CEIL))
17362 (use (match_dup 2))
17363 (use (match_dup 3))])
17364 (set (match_dup 0) (match_dup 4))]
17365 "")
17366
17367 (define_split
17368 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17369 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17370 UNSPEC_FIST_CEIL))
17371 (use (match_operand:HI 2 "memory_operand" ""))
17372 (use (match_operand:HI 3 "memory_operand" ""))
17373 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17374 "reload_completed"
17375 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17376 UNSPEC_FIST_CEIL))
17377 (use (match_dup 2))
17378 (use (match_dup 3))])]
17379 "")
17380
17381 (define_expand "lceilxf<mode>2"
17382 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17383 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17384 UNSPEC_FIST_CEIL))
17385 (clobber (reg:CC FLAGS_REG))])]
17386 "TARGET_USE_FANCY_MATH_387
17387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17388 && flag_unsafe_math_optimizations"
17389 "")
17390
17391 (define_expand "lceil<mode>di2"
17392 [(match_operand:DI 0 "nonimmediate_operand" "")
17393 (match_operand:SSEMODEF 1 "register_operand" "")]
17394 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17395 && !flag_trapping_math"
17396 {
17397 ix86_expand_lfloorceil (operand0, operand1, false);
17398 DONE;
17399 })
17400
17401 (define_expand "lceil<mode>si2"
17402 [(match_operand:SI 0 "nonimmediate_operand" "")
17403 (match_operand:SSEMODEF 1 "register_operand" "")]
17404 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17405 && !flag_trapping_math"
17406 {
17407 ix86_expand_lfloorceil (operand0, operand1, false);
17408 DONE;
17409 })
17410
17411 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17412 (define_insn_and_split "frndintxf2_trunc"
17413 [(set (match_operand:XF 0 "register_operand" "=f")
17414 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17415 UNSPEC_FRNDINT_TRUNC))
17416 (clobber (reg:CC FLAGS_REG))]
17417 "TARGET_USE_FANCY_MATH_387
17418 && flag_unsafe_math_optimizations
17419 && !(reload_completed || reload_in_progress)"
17420 "#"
17421 "&& 1"
17422 [(const_int 0)]
17423 {
17424 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17425
17426 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17427 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17428
17429 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17430 operands[2], operands[3]));
17431 DONE;
17432 }
17433 [(set_attr "type" "frndint")
17434 (set_attr "i387_cw" "trunc")
17435 (set_attr "mode" "XF")])
17436
17437 (define_insn "frndintxf2_trunc_i387"
17438 [(set (match_operand:XF 0 "register_operand" "=f")
17439 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17440 UNSPEC_FRNDINT_TRUNC))
17441 (use (match_operand:HI 2 "memory_operand" "m"))
17442 (use (match_operand:HI 3 "memory_operand" "m"))]
17443 "TARGET_USE_FANCY_MATH_387
17444 && flag_unsafe_math_optimizations"
17445 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17446 [(set_attr "type" "frndint")
17447 (set_attr "i387_cw" "trunc")
17448 (set_attr "mode" "XF")])
17449
17450 (define_expand "btruncxf2"
17451 [(use (match_operand:XF 0 "register_operand" ""))
17452 (use (match_operand:XF 1 "register_operand" ""))]
17453 "TARGET_USE_FANCY_MATH_387
17454 && flag_unsafe_math_optimizations && !optimize_size"
17455 {
17456 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17457 DONE;
17458 })
17459
17460 (define_expand "btruncdf2"
17461 [(use (match_operand:DF 0 "register_operand" ""))
17462 (use (match_operand:DF 1 "register_operand" ""))]
17463 "((TARGET_USE_FANCY_MATH_387
17464 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17465 && flag_unsafe_math_optimizations)
17466 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17467 && !flag_trapping_math))
17468 && !optimize_size"
17469 {
17470 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17471 && !flag_trapping_math)
17472 {
17473 if (TARGET_64BIT)
17474 ix86_expand_trunc (operand0, operand1);
17475 else
17476 ix86_expand_truncdf_32 (operand0, operand1);
17477 }
17478 else
17479 {
17480 rtx op0 = gen_reg_rtx (XFmode);
17481 rtx op1 = gen_reg_rtx (XFmode);
17482
17483 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17484 emit_insn (gen_frndintxf2_trunc (op0, op1));
17485
17486 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17487 }
17488 DONE;
17489 })
17490
17491 (define_expand "btruncsf2"
17492 [(use (match_operand:SF 0 "register_operand" ""))
17493 (use (match_operand:SF 1 "register_operand" ""))]
17494 "((TARGET_USE_FANCY_MATH_387
17495 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17496 && flag_unsafe_math_optimizations)
17497 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17498 && !flag_trapping_math))
17499 && !optimize_size"
17500 {
17501 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17502 && !flag_trapping_math)
17503 ix86_expand_trunc (operand0, operand1);
17504 else
17505 {
17506 rtx op0 = gen_reg_rtx (XFmode);
17507 rtx op1 = gen_reg_rtx (XFmode);
17508
17509 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17510 emit_insn (gen_frndintxf2_trunc (op0, op1));
17511
17512 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17513 }
17514 DONE;
17515 })
17516
17517 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17518 (define_insn_and_split "frndintxf2_mask_pm"
17519 [(set (match_operand:XF 0 "register_operand" "=f")
17520 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17521 UNSPEC_FRNDINT_MASK_PM))
17522 (clobber (reg:CC FLAGS_REG))]
17523 "TARGET_USE_FANCY_MATH_387
17524 && flag_unsafe_math_optimizations
17525 && !(reload_completed || reload_in_progress)"
17526 "#"
17527 "&& 1"
17528 [(const_int 0)]
17529 {
17530 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17531
17532 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17533 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17534
17535 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17536 operands[2], operands[3]));
17537 DONE;
17538 }
17539 [(set_attr "type" "frndint")
17540 (set_attr "i387_cw" "mask_pm")
17541 (set_attr "mode" "XF")])
17542
17543 (define_insn "frndintxf2_mask_pm_i387"
17544 [(set (match_operand:XF 0 "register_operand" "=f")
17545 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17546 UNSPEC_FRNDINT_MASK_PM))
17547 (use (match_operand:HI 2 "memory_operand" "m"))
17548 (use (match_operand:HI 3 "memory_operand" "m"))]
17549 "TARGET_USE_FANCY_MATH_387
17550 && flag_unsafe_math_optimizations"
17551 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17552 [(set_attr "type" "frndint")
17553 (set_attr "i387_cw" "mask_pm")
17554 (set_attr "mode" "XF")])
17555
17556 (define_expand "nearbyintxf2"
17557 [(use (match_operand:XF 0 "register_operand" ""))
17558 (use (match_operand:XF 1 "register_operand" ""))]
17559 "TARGET_USE_FANCY_MATH_387
17560 && flag_unsafe_math_optimizations"
17561 {
17562 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17563
17564 DONE;
17565 })
17566
17567 (define_expand "nearbyintdf2"
17568 [(use (match_operand:DF 0 "register_operand" ""))
17569 (use (match_operand:DF 1 "register_operand" ""))]
17570 "TARGET_USE_FANCY_MATH_387
17571 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17572 && flag_unsafe_math_optimizations"
17573 {
17574 rtx op0 = gen_reg_rtx (XFmode);
17575 rtx op1 = gen_reg_rtx (XFmode);
17576
17577 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17578 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17579
17580 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17581 DONE;
17582 })
17583
17584 (define_expand "nearbyintsf2"
17585 [(use (match_operand:SF 0 "register_operand" ""))
17586 (use (match_operand:SF 1 "register_operand" ""))]
17587 "TARGET_USE_FANCY_MATH_387
17588 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17589 && flag_unsafe_math_optimizations"
17590 {
17591 rtx op0 = gen_reg_rtx (XFmode);
17592 rtx op1 = gen_reg_rtx (XFmode);
17593
17594 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17595 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17596
17597 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17598 DONE;
17599 })
17600
17601 (define_insn "fxam<mode>2_i387"
17602 [(set (match_operand:HI 0 "register_operand" "=a")
17603 (unspec:HI
17604 [(match_operand:X87MODEF 1 "register_operand" "f")]
17605 UNSPEC_FXAM))]
17606 "TARGET_USE_FANCY_MATH_387"
17607 "fxam\n\tfnstsw\t%0"
17608 [(set_attr "type" "multi")
17609 (set_attr "unit" "i387")
17610 (set_attr "mode" "<MODE>")])
17611
17612 (define_expand "isinf<mode>2"
17613 [(use (match_operand:SI 0 "register_operand" ""))
17614 (use (match_operand:X87MODEF 1 "register_operand" ""))]
17615 "TARGET_USE_FANCY_MATH_387
17616 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17617 || TARGET_MIX_SSE_I387)"
17618 {
17619 rtx mask = GEN_INT (0x45);
17620 rtx val = GEN_INT (0x05);
17621
17622 rtx cond;
17623
17624 rtx scratch = gen_reg_rtx (HImode);
17625 rtx res = gen_reg_rtx (QImode);
17626
17627 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17628 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17629 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17630 cond = gen_rtx_fmt_ee (EQ, QImode,
17631 gen_rtx_REG (CCmode, FLAGS_REG),
17632 const0_rtx);
17633 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17634 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17635 DONE;
17636 })
17637
17638 \f
17639 ;; Block operation instructions
17640
17641 (define_expand "movmemsi"
17642 [(use (match_operand:BLK 0 "memory_operand" ""))
17643 (use (match_operand:BLK 1 "memory_operand" ""))
17644 (use (match_operand:SI 2 "nonmemory_operand" ""))
17645 (use (match_operand:SI 3 "const_int_operand" ""))
17646 (use (match_operand:SI 4 "const_int_operand" ""))
17647 (use (match_operand:SI 5 "const_int_operand" ""))]
17648 ""
17649 {
17650 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17651 operands[4], operands[5]))
17652 DONE;
17653 else
17654 FAIL;
17655 })
17656
17657 (define_expand "movmemdi"
17658 [(use (match_operand:BLK 0 "memory_operand" ""))
17659 (use (match_operand:BLK 1 "memory_operand" ""))
17660 (use (match_operand:DI 2 "nonmemory_operand" ""))
17661 (use (match_operand:DI 3 "const_int_operand" ""))
17662 (use (match_operand:SI 4 "const_int_operand" ""))
17663 (use (match_operand:SI 5 "const_int_operand" ""))]
17664 "TARGET_64BIT"
17665 {
17666 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17667 operands[4], operands[5]))
17668 DONE;
17669 else
17670 FAIL;
17671 })
17672
17673 ;; Most CPUs don't like single string operations
17674 ;; Handle this case here to simplify previous expander.
17675
17676 (define_expand "strmov"
17677 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17678 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17679 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17680 (clobber (reg:CC FLAGS_REG))])
17681 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17682 (clobber (reg:CC FLAGS_REG))])]
17683 ""
17684 {
17685 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17686
17687 /* If .md ever supports :P for Pmode, these can be directly
17688 in the pattern above. */
17689 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17690 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17691
17692 if (TARGET_SINGLE_STRINGOP || optimize_size)
17693 {
17694 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17695 operands[2], operands[3],
17696 operands[5], operands[6]));
17697 DONE;
17698 }
17699
17700 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17701 })
17702
17703 (define_expand "strmov_singleop"
17704 [(parallel [(set (match_operand 1 "memory_operand" "")
17705 (match_operand 3 "memory_operand" ""))
17706 (set (match_operand 0 "register_operand" "")
17707 (match_operand 4 "" ""))
17708 (set (match_operand 2 "register_operand" "")
17709 (match_operand 5 "" ""))])]
17710 "TARGET_SINGLE_STRINGOP || optimize_size"
17711 "")
17712
17713 (define_insn "*strmovdi_rex_1"
17714 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17715 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17716 (set (match_operand:DI 0 "register_operand" "=D")
17717 (plus:DI (match_dup 2)
17718 (const_int 8)))
17719 (set (match_operand:DI 1 "register_operand" "=S")
17720 (plus:DI (match_dup 3)
17721 (const_int 8)))]
17722 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17723 "movsq"
17724 [(set_attr "type" "str")
17725 (set_attr "mode" "DI")
17726 (set_attr "memory" "both")])
17727
17728 (define_insn "*strmovsi_1"
17729 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17730 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17731 (set (match_operand:SI 0 "register_operand" "=D")
17732 (plus:SI (match_dup 2)
17733 (const_int 4)))
17734 (set (match_operand:SI 1 "register_operand" "=S")
17735 (plus:SI (match_dup 3)
17736 (const_int 4)))]
17737 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17738 "{movsl|movsd}"
17739 [(set_attr "type" "str")
17740 (set_attr "mode" "SI")
17741 (set_attr "memory" "both")])
17742
17743 (define_insn "*strmovsi_rex_1"
17744 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17745 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17746 (set (match_operand:DI 0 "register_operand" "=D")
17747 (plus:DI (match_dup 2)
17748 (const_int 4)))
17749 (set (match_operand:DI 1 "register_operand" "=S")
17750 (plus:DI (match_dup 3)
17751 (const_int 4)))]
17752 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17753 "{movsl|movsd}"
17754 [(set_attr "type" "str")
17755 (set_attr "mode" "SI")
17756 (set_attr "memory" "both")])
17757
17758 (define_insn "*strmovhi_1"
17759 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17760 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17761 (set (match_operand:SI 0 "register_operand" "=D")
17762 (plus:SI (match_dup 2)
17763 (const_int 2)))
17764 (set (match_operand:SI 1 "register_operand" "=S")
17765 (plus:SI (match_dup 3)
17766 (const_int 2)))]
17767 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17768 "movsw"
17769 [(set_attr "type" "str")
17770 (set_attr "memory" "both")
17771 (set_attr "mode" "HI")])
17772
17773 (define_insn "*strmovhi_rex_1"
17774 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17775 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17776 (set (match_operand:DI 0 "register_operand" "=D")
17777 (plus:DI (match_dup 2)
17778 (const_int 2)))
17779 (set (match_operand:DI 1 "register_operand" "=S")
17780 (plus:DI (match_dup 3)
17781 (const_int 2)))]
17782 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17783 "movsw"
17784 [(set_attr "type" "str")
17785 (set_attr "memory" "both")
17786 (set_attr "mode" "HI")])
17787
17788 (define_insn "*strmovqi_1"
17789 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17790 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17791 (set (match_operand:SI 0 "register_operand" "=D")
17792 (plus:SI (match_dup 2)
17793 (const_int 1)))
17794 (set (match_operand:SI 1 "register_operand" "=S")
17795 (plus:SI (match_dup 3)
17796 (const_int 1)))]
17797 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17798 "movsb"
17799 [(set_attr "type" "str")
17800 (set_attr "memory" "both")
17801 (set_attr "mode" "QI")])
17802
17803 (define_insn "*strmovqi_rex_1"
17804 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17805 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17806 (set (match_operand:DI 0 "register_operand" "=D")
17807 (plus:DI (match_dup 2)
17808 (const_int 1)))
17809 (set (match_operand:DI 1 "register_operand" "=S")
17810 (plus:DI (match_dup 3)
17811 (const_int 1)))]
17812 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17813 "movsb"
17814 [(set_attr "type" "str")
17815 (set_attr "memory" "both")
17816 (set_attr "mode" "QI")])
17817
17818 (define_expand "rep_mov"
17819 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17820 (set (match_operand 0 "register_operand" "")
17821 (match_operand 5 "" ""))
17822 (set (match_operand 2 "register_operand" "")
17823 (match_operand 6 "" ""))
17824 (set (match_operand 1 "memory_operand" "")
17825 (match_operand 3 "memory_operand" ""))
17826 (use (match_dup 4))])]
17827 ""
17828 "")
17829
17830 (define_insn "*rep_movdi_rex64"
17831 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17832 (set (match_operand:DI 0 "register_operand" "=D")
17833 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17834 (const_int 3))
17835 (match_operand:DI 3 "register_operand" "0")))
17836 (set (match_operand:DI 1 "register_operand" "=S")
17837 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17838 (match_operand:DI 4 "register_operand" "1")))
17839 (set (mem:BLK (match_dup 3))
17840 (mem:BLK (match_dup 4)))
17841 (use (match_dup 5))]
17842 "TARGET_64BIT"
17843 "{rep\;movsq|rep movsq}"
17844 [(set_attr "type" "str")
17845 (set_attr "prefix_rep" "1")
17846 (set_attr "memory" "both")
17847 (set_attr "mode" "DI")])
17848
17849 (define_insn "*rep_movsi"
17850 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17851 (set (match_operand:SI 0 "register_operand" "=D")
17852 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17853 (const_int 2))
17854 (match_operand:SI 3 "register_operand" "0")))
17855 (set (match_operand:SI 1 "register_operand" "=S")
17856 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17857 (match_operand:SI 4 "register_operand" "1")))
17858 (set (mem:BLK (match_dup 3))
17859 (mem:BLK (match_dup 4)))
17860 (use (match_dup 5))]
17861 "!TARGET_64BIT"
17862 "{rep\;movsl|rep movsd}"
17863 [(set_attr "type" "str")
17864 (set_attr "prefix_rep" "1")
17865 (set_attr "memory" "both")
17866 (set_attr "mode" "SI")])
17867
17868 (define_insn "*rep_movsi_rex64"
17869 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17870 (set (match_operand:DI 0 "register_operand" "=D")
17871 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17872 (const_int 2))
17873 (match_operand:DI 3 "register_operand" "0")))
17874 (set (match_operand:DI 1 "register_operand" "=S")
17875 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17876 (match_operand:DI 4 "register_operand" "1")))
17877 (set (mem:BLK (match_dup 3))
17878 (mem:BLK (match_dup 4)))
17879 (use (match_dup 5))]
17880 "TARGET_64BIT"
17881 "{rep\;movsl|rep movsd}"
17882 [(set_attr "type" "str")
17883 (set_attr "prefix_rep" "1")
17884 (set_attr "memory" "both")
17885 (set_attr "mode" "SI")])
17886
17887 (define_insn "*rep_movqi"
17888 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17889 (set (match_operand:SI 0 "register_operand" "=D")
17890 (plus:SI (match_operand:SI 3 "register_operand" "0")
17891 (match_operand:SI 5 "register_operand" "2")))
17892 (set (match_operand:SI 1 "register_operand" "=S")
17893 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17894 (set (mem:BLK (match_dup 3))
17895 (mem:BLK (match_dup 4)))
17896 (use (match_dup 5))]
17897 "!TARGET_64BIT"
17898 "{rep\;movsb|rep movsb}"
17899 [(set_attr "type" "str")
17900 (set_attr "prefix_rep" "1")
17901 (set_attr "memory" "both")
17902 (set_attr "mode" "SI")])
17903
17904 (define_insn "*rep_movqi_rex64"
17905 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17906 (set (match_operand:DI 0 "register_operand" "=D")
17907 (plus:DI (match_operand:DI 3 "register_operand" "0")
17908 (match_operand:DI 5 "register_operand" "2")))
17909 (set (match_operand:DI 1 "register_operand" "=S")
17910 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17911 (set (mem:BLK (match_dup 3))
17912 (mem:BLK (match_dup 4)))
17913 (use (match_dup 5))]
17914 "TARGET_64BIT"
17915 "{rep\;movsb|rep movsb}"
17916 [(set_attr "type" "str")
17917 (set_attr "prefix_rep" "1")
17918 (set_attr "memory" "both")
17919 (set_attr "mode" "SI")])
17920
17921 (define_expand "setmemsi"
17922 [(use (match_operand:BLK 0 "memory_operand" ""))
17923 (use (match_operand:SI 1 "nonmemory_operand" ""))
17924 (use (match_operand 2 "const_int_operand" ""))
17925 (use (match_operand 3 "const_int_operand" ""))
17926 (use (match_operand:SI 4 "const_int_operand" ""))
17927 (use (match_operand:SI 5 "const_int_operand" ""))]
17928 ""
17929 {
17930 if (ix86_expand_setmem (operands[0], operands[1],
17931 operands[2], operands[3],
17932 operands[4], operands[5]))
17933 DONE;
17934 else
17935 FAIL;
17936 })
17937
17938 (define_expand "setmemdi"
17939 [(use (match_operand:BLK 0 "memory_operand" ""))
17940 (use (match_operand:DI 1 "nonmemory_operand" ""))
17941 (use (match_operand 2 "const_int_operand" ""))
17942 (use (match_operand 3 "const_int_operand" ""))
17943 (use (match_operand 4 "const_int_operand" ""))
17944 (use (match_operand 5 "const_int_operand" ""))]
17945 "TARGET_64BIT"
17946 {
17947 if (ix86_expand_setmem (operands[0], operands[1],
17948 operands[2], operands[3],
17949 operands[4], operands[5]))
17950 DONE;
17951 else
17952 FAIL;
17953 })
17954
17955 ;; Most CPUs don't like single string operations
17956 ;; Handle this case here to simplify previous expander.
17957
17958 (define_expand "strset"
17959 [(set (match_operand 1 "memory_operand" "")
17960 (match_operand 2 "register_operand" ""))
17961 (parallel [(set (match_operand 0 "register_operand" "")
17962 (match_dup 3))
17963 (clobber (reg:CC FLAGS_REG))])]
17964 ""
17965 {
17966 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17967 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17968
17969 /* If .md ever supports :P for Pmode, this can be directly
17970 in the pattern above. */
17971 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17972 GEN_INT (GET_MODE_SIZE (GET_MODE
17973 (operands[2]))));
17974 if (TARGET_SINGLE_STRINGOP || optimize_size)
17975 {
17976 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17977 operands[3]));
17978 DONE;
17979 }
17980 })
17981
17982 (define_expand "strset_singleop"
17983 [(parallel [(set (match_operand 1 "memory_operand" "")
17984 (match_operand 2 "register_operand" ""))
17985 (set (match_operand 0 "register_operand" "")
17986 (match_operand 3 "" ""))])]
17987 "TARGET_SINGLE_STRINGOP || optimize_size"
17988 "")
17989
17990 (define_insn "*strsetdi_rex_1"
17991 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17992 (match_operand:DI 2 "register_operand" "a"))
17993 (set (match_operand:DI 0 "register_operand" "=D")
17994 (plus:DI (match_dup 1)
17995 (const_int 8)))]
17996 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17997 "stosq"
17998 [(set_attr "type" "str")
17999 (set_attr "memory" "store")
18000 (set_attr "mode" "DI")])
18001
18002 (define_insn "*strsetsi_1"
18003 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18004 (match_operand:SI 2 "register_operand" "a"))
18005 (set (match_operand:SI 0 "register_operand" "=D")
18006 (plus:SI (match_dup 1)
18007 (const_int 4)))]
18008 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18009 "{stosl|stosd}"
18010 [(set_attr "type" "str")
18011 (set_attr "memory" "store")
18012 (set_attr "mode" "SI")])
18013
18014 (define_insn "*strsetsi_rex_1"
18015 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18016 (match_operand:SI 2 "register_operand" "a"))
18017 (set (match_operand:DI 0 "register_operand" "=D")
18018 (plus:DI (match_dup 1)
18019 (const_int 4)))]
18020 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18021 "{stosl|stosd}"
18022 [(set_attr "type" "str")
18023 (set_attr "memory" "store")
18024 (set_attr "mode" "SI")])
18025
18026 (define_insn "*strsethi_1"
18027 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18028 (match_operand:HI 2 "register_operand" "a"))
18029 (set (match_operand:SI 0 "register_operand" "=D")
18030 (plus:SI (match_dup 1)
18031 (const_int 2)))]
18032 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18033 "stosw"
18034 [(set_attr "type" "str")
18035 (set_attr "memory" "store")
18036 (set_attr "mode" "HI")])
18037
18038 (define_insn "*strsethi_rex_1"
18039 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18040 (match_operand:HI 2 "register_operand" "a"))
18041 (set (match_operand:DI 0 "register_operand" "=D")
18042 (plus:DI (match_dup 1)
18043 (const_int 2)))]
18044 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18045 "stosw"
18046 [(set_attr "type" "str")
18047 (set_attr "memory" "store")
18048 (set_attr "mode" "HI")])
18049
18050 (define_insn "*strsetqi_1"
18051 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18052 (match_operand:QI 2 "register_operand" "a"))
18053 (set (match_operand:SI 0 "register_operand" "=D")
18054 (plus:SI (match_dup 1)
18055 (const_int 1)))]
18056 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18057 "stosb"
18058 [(set_attr "type" "str")
18059 (set_attr "memory" "store")
18060 (set_attr "mode" "QI")])
18061
18062 (define_insn "*strsetqi_rex_1"
18063 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18064 (match_operand:QI 2 "register_operand" "a"))
18065 (set (match_operand:DI 0 "register_operand" "=D")
18066 (plus:DI (match_dup 1)
18067 (const_int 1)))]
18068 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18069 "stosb"
18070 [(set_attr "type" "str")
18071 (set_attr "memory" "store")
18072 (set_attr "mode" "QI")])
18073
18074 (define_expand "rep_stos"
18075 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18076 (set (match_operand 0 "register_operand" "")
18077 (match_operand 4 "" ""))
18078 (set (match_operand 2 "memory_operand" "") (const_int 0))
18079 (use (match_operand 3 "register_operand" ""))
18080 (use (match_dup 1))])]
18081 ""
18082 "")
18083
18084 (define_insn "*rep_stosdi_rex64"
18085 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18086 (set (match_operand:DI 0 "register_operand" "=D")
18087 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18088 (const_int 3))
18089 (match_operand:DI 3 "register_operand" "0")))
18090 (set (mem:BLK (match_dup 3))
18091 (const_int 0))
18092 (use (match_operand:DI 2 "register_operand" "a"))
18093 (use (match_dup 4))]
18094 "TARGET_64BIT"
18095 "{rep\;stosq|rep stosq}"
18096 [(set_attr "type" "str")
18097 (set_attr "prefix_rep" "1")
18098 (set_attr "memory" "store")
18099 (set_attr "mode" "DI")])
18100
18101 (define_insn "*rep_stossi"
18102 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18103 (set (match_operand:SI 0 "register_operand" "=D")
18104 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18105 (const_int 2))
18106 (match_operand:SI 3 "register_operand" "0")))
18107 (set (mem:BLK (match_dup 3))
18108 (const_int 0))
18109 (use (match_operand:SI 2 "register_operand" "a"))
18110 (use (match_dup 4))]
18111 "!TARGET_64BIT"
18112 "{rep\;stosl|rep stosd}"
18113 [(set_attr "type" "str")
18114 (set_attr "prefix_rep" "1")
18115 (set_attr "memory" "store")
18116 (set_attr "mode" "SI")])
18117
18118 (define_insn "*rep_stossi_rex64"
18119 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18120 (set (match_operand:DI 0 "register_operand" "=D")
18121 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18122 (const_int 2))
18123 (match_operand:DI 3 "register_operand" "0")))
18124 (set (mem:BLK (match_dup 3))
18125 (const_int 0))
18126 (use (match_operand:SI 2 "register_operand" "a"))
18127 (use (match_dup 4))]
18128 "TARGET_64BIT"
18129 "{rep\;stosl|rep stosd}"
18130 [(set_attr "type" "str")
18131 (set_attr "prefix_rep" "1")
18132 (set_attr "memory" "store")
18133 (set_attr "mode" "SI")])
18134
18135 (define_insn "*rep_stosqi"
18136 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18137 (set (match_operand:SI 0 "register_operand" "=D")
18138 (plus:SI (match_operand:SI 3 "register_operand" "0")
18139 (match_operand:SI 4 "register_operand" "1")))
18140 (set (mem:BLK (match_dup 3))
18141 (const_int 0))
18142 (use (match_operand:QI 2 "register_operand" "a"))
18143 (use (match_dup 4))]
18144 "!TARGET_64BIT"
18145 "{rep\;stosb|rep stosb}"
18146 [(set_attr "type" "str")
18147 (set_attr "prefix_rep" "1")
18148 (set_attr "memory" "store")
18149 (set_attr "mode" "QI")])
18150
18151 (define_insn "*rep_stosqi_rex64"
18152 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18153 (set (match_operand:DI 0 "register_operand" "=D")
18154 (plus:DI (match_operand:DI 3 "register_operand" "0")
18155 (match_operand:DI 4 "register_operand" "1")))
18156 (set (mem:BLK (match_dup 3))
18157 (const_int 0))
18158 (use (match_operand:QI 2 "register_operand" "a"))
18159 (use (match_dup 4))]
18160 "TARGET_64BIT"
18161 "{rep\;stosb|rep stosb}"
18162 [(set_attr "type" "str")
18163 (set_attr "prefix_rep" "1")
18164 (set_attr "memory" "store")
18165 (set_attr "mode" "QI")])
18166
18167 (define_expand "cmpstrnsi"
18168 [(set (match_operand:SI 0 "register_operand" "")
18169 (compare:SI (match_operand:BLK 1 "general_operand" "")
18170 (match_operand:BLK 2 "general_operand" "")))
18171 (use (match_operand 3 "general_operand" ""))
18172 (use (match_operand 4 "immediate_operand" ""))]
18173 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18174 {
18175 rtx addr1, addr2, out, outlow, count, countreg, align;
18176
18177 /* Can't use this if the user has appropriated esi or edi. */
18178 if (global_regs[4] || global_regs[5])
18179 FAIL;
18180
18181 out = operands[0];
18182 if (!REG_P (out))
18183 out = gen_reg_rtx (SImode);
18184
18185 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18186 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18187 if (addr1 != XEXP (operands[1], 0))
18188 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18189 if (addr2 != XEXP (operands[2], 0))
18190 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18191
18192 count = operands[3];
18193 countreg = ix86_zero_extend_to_Pmode (count);
18194
18195 /* %%% Iff we are testing strict equality, we can use known alignment
18196 to good advantage. This may be possible with combine, particularly
18197 once cc0 is dead. */
18198 align = operands[4];
18199
18200 if (CONST_INT_P (count))
18201 {
18202 if (INTVAL (count) == 0)
18203 {
18204 emit_move_insn (operands[0], const0_rtx);
18205 DONE;
18206 }
18207 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18208 operands[1], operands[2]));
18209 }
18210 else
18211 {
18212 if (TARGET_64BIT)
18213 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18214 else
18215 emit_insn (gen_cmpsi_1 (countreg, countreg));
18216 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18217 operands[1], operands[2]));
18218 }
18219
18220 outlow = gen_lowpart (QImode, out);
18221 emit_insn (gen_cmpintqi (outlow));
18222 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18223
18224 if (operands[0] != out)
18225 emit_move_insn (operands[0], out);
18226
18227 DONE;
18228 })
18229
18230 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18231
18232 (define_expand "cmpintqi"
18233 [(set (match_dup 1)
18234 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18235 (set (match_dup 2)
18236 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18237 (parallel [(set (match_operand:QI 0 "register_operand" "")
18238 (minus:QI (match_dup 1)
18239 (match_dup 2)))
18240 (clobber (reg:CC FLAGS_REG))])]
18241 ""
18242 "operands[1] = gen_reg_rtx (QImode);
18243 operands[2] = gen_reg_rtx (QImode);")
18244
18245 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18246 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18247
18248 (define_expand "cmpstrnqi_nz_1"
18249 [(parallel [(set (reg:CC FLAGS_REG)
18250 (compare:CC (match_operand 4 "memory_operand" "")
18251 (match_operand 5 "memory_operand" "")))
18252 (use (match_operand 2 "register_operand" ""))
18253 (use (match_operand:SI 3 "immediate_operand" ""))
18254 (clobber (match_operand 0 "register_operand" ""))
18255 (clobber (match_operand 1 "register_operand" ""))
18256 (clobber (match_dup 2))])]
18257 ""
18258 "")
18259
18260 (define_insn "*cmpstrnqi_nz_1"
18261 [(set (reg:CC FLAGS_REG)
18262 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18263 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18264 (use (match_operand:SI 6 "register_operand" "2"))
18265 (use (match_operand:SI 3 "immediate_operand" "i"))
18266 (clobber (match_operand:SI 0 "register_operand" "=S"))
18267 (clobber (match_operand:SI 1 "register_operand" "=D"))
18268 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18269 "!TARGET_64BIT"
18270 "repz{\;| }cmpsb"
18271 [(set_attr "type" "str")
18272 (set_attr "mode" "QI")
18273 (set_attr "prefix_rep" "1")])
18274
18275 (define_insn "*cmpstrnqi_nz_rex_1"
18276 [(set (reg:CC FLAGS_REG)
18277 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18278 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18279 (use (match_operand:DI 6 "register_operand" "2"))
18280 (use (match_operand:SI 3 "immediate_operand" "i"))
18281 (clobber (match_operand:DI 0 "register_operand" "=S"))
18282 (clobber (match_operand:DI 1 "register_operand" "=D"))
18283 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18284 "TARGET_64BIT"
18285 "repz{\;| }cmpsb"
18286 [(set_attr "type" "str")
18287 (set_attr "mode" "QI")
18288 (set_attr "prefix_rep" "1")])
18289
18290 ;; The same, but the count is not known to not be zero.
18291
18292 (define_expand "cmpstrnqi_1"
18293 [(parallel [(set (reg:CC FLAGS_REG)
18294 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18295 (const_int 0))
18296 (compare:CC (match_operand 4 "memory_operand" "")
18297 (match_operand 5 "memory_operand" ""))
18298 (const_int 0)))
18299 (use (match_operand:SI 3 "immediate_operand" ""))
18300 (use (reg:CC FLAGS_REG))
18301 (clobber (match_operand 0 "register_operand" ""))
18302 (clobber (match_operand 1 "register_operand" ""))
18303 (clobber (match_dup 2))])]
18304 ""
18305 "")
18306
18307 (define_insn "*cmpstrnqi_1"
18308 [(set (reg:CC FLAGS_REG)
18309 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18310 (const_int 0))
18311 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18312 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18313 (const_int 0)))
18314 (use (match_operand:SI 3 "immediate_operand" "i"))
18315 (use (reg:CC FLAGS_REG))
18316 (clobber (match_operand:SI 0 "register_operand" "=S"))
18317 (clobber (match_operand:SI 1 "register_operand" "=D"))
18318 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18319 "!TARGET_64BIT"
18320 "repz{\;| }cmpsb"
18321 [(set_attr "type" "str")
18322 (set_attr "mode" "QI")
18323 (set_attr "prefix_rep" "1")])
18324
18325 (define_insn "*cmpstrnqi_rex_1"
18326 [(set (reg:CC FLAGS_REG)
18327 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18328 (const_int 0))
18329 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18330 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18331 (const_int 0)))
18332 (use (match_operand:SI 3 "immediate_operand" "i"))
18333 (use (reg:CC FLAGS_REG))
18334 (clobber (match_operand:DI 0 "register_operand" "=S"))
18335 (clobber (match_operand:DI 1 "register_operand" "=D"))
18336 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18337 "TARGET_64BIT"
18338 "repz{\;| }cmpsb"
18339 [(set_attr "type" "str")
18340 (set_attr "mode" "QI")
18341 (set_attr "prefix_rep" "1")])
18342
18343 (define_expand "strlensi"
18344 [(set (match_operand:SI 0 "register_operand" "")
18345 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18346 (match_operand:QI 2 "immediate_operand" "")
18347 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18348 ""
18349 {
18350 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18351 DONE;
18352 else
18353 FAIL;
18354 })
18355
18356 (define_expand "strlendi"
18357 [(set (match_operand:DI 0 "register_operand" "")
18358 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18359 (match_operand:QI 2 "immediate_operand" "")
18360 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18361 ""
18362 {
18363 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18364 DONE;
18365 else
18366 FAIL;
18367 })
18368
18369 (define_expand "strlenqi_1"
18370 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18371 (clobber (match_operand 1 "register_operand" ""))
18372 (clobber (reg:CC FLAGS_REG))])]
18373 ""
18374 "")
18375
18376 (define_insn "*strlenqi_1"
18377 [(set (match_operand:SI 0 "register_operand" "=&c")
18378 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18379 (match_operand:QI 2 "register_operand" "a")
18380 (match_operand:SI 3 "immediate_operand" "i")
18381 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18382 (clobber (match_operand:SI 1 "register_operand" "=D"))
18383 (clobber (reg:CC FLAGS_REG))]
18384 "!TARGET_64BIT"
18385 "repnz{\;| }scasb"
18386 [(set_attr "type" "str")
18387 (set_attr "mode" "QI")
18388 (set_attr "prefix_rep" "1")])
18389
18390 (define_insn "*strlenqi_rex_1"
18391 [(set (match_operand:DI 0 "register_operand" "=&c")
18392 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18393 (match_operand:QI 2 "register_operand" "a")
18394 (match_operand:DI 3 "immediate_operand" "i")
18395 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18396 (clobber (match_operand:DI 1 "register_operand" "=D"))
18397 (clobber (reg:CC FLAGS_REG))]
18398 "TARGET_64BIT"
18399 "repnz{\;| }scasb"
18400 [(set_attr "type" "str")
18401 (set_attr "mode" "QI")
18402 (set_attr "prefix_rep" "1")])
18403
18404 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18405 ;; handled in combine, but it is not currently up to the task.
18406 ;; When used for their truth value, the cmpstrn* expanders generate
18407 ;; code like this:
18408 ;;
18409 ;; repz cmpsb
18410 ;; seta %al
18411 ;; setb %dl
18412 ;; cmpb %al, %dl
18413 ;; jcc label
18414 ;;
18415 ;; The intermediate three instructions are unnecessary.
18416
18417 ;; This one handles cmpstrn*_nz_1...
18418 (define_peephole2
18419 [(parallel[
18420 (set (reg:CC FLAGS_REG)
18421 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18422 (mem:BLK (match_operand 5 "register_operand" ""))))
18423 (use (match_operand 6 "register_operand" ""))
18424 (use (match_operand:SI 3 "immediate_operand" ""))
18425 (clobber (match_operand 0 "register_operand" ""))
18426 (clobber (match_operand 1 "register_operand" ""))
18427 (clobber (match_operand 2 "register_operand" ""))])
18428 (set (match_operand:QI 7 "register_operand" "")
18429 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18430 (set (match_operand:QI 8 "register_operand" "")
18431 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18432 (set (reg FLAGS_REG)
18433 (compare (match_dup 7) (match_dup 8)))
18434 ]
18435 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18436 [(parallel[
18437 (set (reg:CC FLAGS_REG)
18438 (compare:CC (mem:BLK (match_dup 4))
18439 (mem:BLK (match_dup 5))))
18440 (use (match_dup 6))
18441 (use (match_dup 3))
18442 (clobber (match_dup 0))
18443 (clobber (match_dup 1))
18444 (clobber (match_dup 2))])]
18445 "")
18446
18447 ;; ...and this one handles cmpstrn*_1.
18448 (define_peephole2
18449 [(parallel[
18450 (set (reg:CC FLAGS_REG)
18451 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18452 (const_int 0))
18453 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18454 (mem:BLK (match_operand 5 "register_operand" "")))
18455 (const_int 0)))
18456 (use (match_operand:SI 3 "immediate_operand" ""))
18457 (use (reg:CC FLAGS_REG))
18458 (clobber (match_operand 0 "register_operand" ""))
18459 (clobber (match_operand 1 "register_operand" ""))
18460 (clobber (match_operand 2 "register_operand" ""))])
18461 (set (match_operand:QI 7 "register_operand" "")
18462 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18463 (set (match_operand:QI 8 "register_operand" "")
18464 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18465 (set (reg FLAGS_REG)
18466 (compare (match_dup 7) (match_dup 8)))
18467 ]
18468 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18469 [(parallel[
18470 (set (reg:CC FLAGS_REG)
18471 (if_then_else:CC (ne (match_dup 6)
18472 (const_int 0))
18473 (compare:CC (mem:BLK (match_dup 4))
18474 (mem:BLK (match_dup 5)))
18475 (const_int 0)))
18476 (use (match_dup 3))
18477 (use (reg:CC FLAGS_REG))
18478 (clobber (match_dup 0))
18479 (clobber (match_dup 1))
18480 (clobber (match_dup 2))])]
18481 "")
18482
18483
18484 \f
18485 ;; Conditional move instructions.
18486
18487 (define_expand "movdicc"
18488 [(set (match_operand:DI 0 "register_operand" "")
18489 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18490 (match_operand:DI 2 "general_operand" "")
18491 (match_operand:DI 3 "general_operand" "")))]
18492 "TARGET_64BIT"
18493 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18494
18495 (define_insn "x86_movdicc_0_m1_rex64"
18496 [(set (match_operand:DI 0 "register_operand" "=r")
18497 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18498 (const_int -1)
18499 (const_int 0)))
18500 (clobber (reg:CC FLAGS_REG))]
18501 "TARGET_64BIT"
18502 "sbb{q}\t%0, %0"
18503 ; Since we don't have the proper number of operands for an alu insn,
18504 ; fill in all the blanks.
18505 [(set_attr "type" "alu")
18506 (set_attr "pent_pair" "pu")
18507 (set_attr "memory" "none")
18508 (set_attr "imm_disp" "false")
18509 (set_attr "mode" "DI")
18510 (set_attr "length_immediate" "0")])
18511
18512 (define_insn "*movdicc_c_rex64"
18513 [(set (match_operand:DI 0 "register_operand" "=r,r")
18514 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18515 [(reg FLAGS_REG) (const_int 0)])
18516 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18517 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18518 "TARGET_64BIT && TARGET_CMOVE
18519 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18520 "@
18521 cmov%O2%C1\t{%2, %0|%0, %2}
18522 cmov%O2%c1\t{%3, %0|%0, %3}"
18523 [(set_attr "type" "icmov")
18524 (set_attr "mode" "DI")])
18525
18526 (define_expand "movsicc"
18527 [(set (match_operand:SI 0 "register_operand" "")
18528 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18529 (match_operand:SI 2 "general_operand" "")
18530 (match_operand:SI 3 "general_operand" "")))]
18531 ""
18532 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18533
18534 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18535 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18536 ;; So just document what we're doing explicitly.
18537
18538 (define_insn "x86_movsicc_0_m1"
18539 [(set (match_operand:SI 0 "register_operand" "=r")
18540 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18541 (const_int -1)
18542 (const_int 0)))
18543 (clobber (reg:CC FLAGS_REG))]
18544 ""
18545 "sbb{l}\t%0, %0"
18546 ; Since we don't have the proper number of operands for an alu insn,
18547 ; fill in all the blanks.
18548 [(set_attr "type" "alu")
18549 (set_attr "pent_pair" "pu")
18550 (set_attr "memory" "none")
18551 (set_attr "imm_disp" "false")
18552 (set_attr "mode" "SI")
18553 (set_attr "length_immediate" "0")])
18554
18555 (define_insn "*movsicc_noc"
18556 [(set (match_operand:SI 0 "register_operand" "=r,r")
18557 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18558 [(reg FLAGS_REG) (const_int 0)])
18559 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18560 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18561 "TARGET_CMOVE
18562 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18563 "@
18564 cmov%O2%C1\t{%2, %0|%0, %2}
18565 cmov%O2%c1\t{%3, %0|%0, %3}"
18566 [(set_attr "type" "icmov")
18567 (set_attr "mode" "SI")])
18568
18569 (define_expand "movhicc"
18570 [(set (match_operand:HI 0 "register_operand" "")
18571 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18572 (match_operand:HI 2 "general_operand" "")
18573 (match_operand:HI 3 "general_operand" "")))]
18574 "TARGET_HIMODE_MATH"
18575 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18576
18577 (define_insn "*movhicc_noc"
18578 [(set (match_operand:HI 0 "register_operand" "=r,r")
18579 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18580 [(reg FLAGS_REG) (const_int 0)])
18581 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18582 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18583 "TARGET_CMOVE
18584 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18585 "@
18586 cmov%O2%C1\t{%2, %0|%0, %2}
18587 cmov%O2%c1\t{%3, %0|%0, %3}"
18588 [(set_attr "type" "icmov")
18589 (set_attr "mode" "HI")])
18590
18591 (define_expand "movqicc"
18592 [(set (match_operand:QI 0 "register_operand" "")
18593 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18594 (match_operand:QI 2 "general_operand" "")
18595 (match_operand:QI 3 "general_operand" "")))]
18596 "TARGET_QIMODE_MATH"
18597 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18598
18599 (define_insn_and_split "*movqicc_noc"
18600 [(set (match_operand:QI 0 "register_operand" "=r,r")
18601 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18602 [(match_operand 4 "flags_reg_operand" "")
18603 (const_int 0)])
18604 (match_operand:QI 2 "register_operand" "r,0")
18605 (match_operand:QI 3 "register_operand" "0,r")))]
18606 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18607 "#"
18608 "&& reload_completed"
18609 [(set (match_dup 0)
18610 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18611 (match_dup 2)
18612 (match_dup 3)))]
18613 "operands[0] = gen_lowpart (SImode, operands[0]);
18614 operands[2] = gen_lowpart (SImode, operands[2]);
18615 operands[3] = gen_lowpart (SImode, operands[3]);"
18616 [(set_attr "type" "icmov")
18617 (set_attr "mode" "SI")])
18618
18619 (define_expand "movsfcc"
18620 [(set (match_operand:SF 0 "register_operand" "")
18621 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18622 (match_operand:SF 2 "register_operand" "")
18623 (match_operand:SF 3 "register_operand" "")))]
18624 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18625 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18626
18627 (define_insn "*movsfcc_1_387"
18628 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18629 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18630 [(reg FLAGS_REG) (const_int 0)])
18631 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18632 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18633 "TARGET_80387 && TARGET_CMOVE
18634 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18635 "@
18636 fcmov%F1\t{%2, %0|%0, %2}
18637 fcmov%f1\t{%3, %0|%0, %3}
18638 cmov%O2%C1\t{%2, %0|%0, %2}
18639 cmov%O2%c1\t{%3, %0|%0, %3}"
18640 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18641 (set_attr "mode" "SF,SF,SI,SI")])
18642
18643 (define_expand "movdfcc"
18644 [(set (match_operand:DF 0 "register_operand" "")
18645 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18646 (match_operand:DF 2 "register_operand" "")
18647 (match_operand:DF 3 "register_operand" "")))]
18648 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18649 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18650
18651 (define_insn "*movdfcc_1"
18652 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18653 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18654 [(reg FLAGS_REG) (const_int 0)])
18655 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18656 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18657 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18658 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18659 "@
18660 fcmov%F1\t{%2, %0|%0, %2}
18661 fcmov%f1\t{%3, %0|%0, %3}
18662 #
18663 #"
18664 [(set_attr "type" "fcmov,fcmov,multi,multi")
18665 (set_attr "mode" "DF")])
18666
18667 (define_insn "*movdfcc_1_rex64"
18668 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18669 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18670 [(reg FLAGS_REG) (const_int 0)])
18671 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18672 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18673 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18674 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18675 "@
18676 fcmov%F1\t{%2, %0|%0, %2}
18677 fcmov%f1\t{%3, %0|%0, %3}
18678 cmov%O2%C1\t{%2, %0|%0, %2}
18679 cmov%O2%c1\t{%3, %0|%0, %3}"
18680 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18681 (set_attr "mode" "DF")])
18682
18683 (define_split
18684 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18685 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18686 [(match_operand 4 "flags_reg_operand" "")
18687 (const_int 0)])
18688 (match_operand:DF 2 "nonimmediate_operand" "")
18689 (match_operand:DF 3 "nonimmediate_operand" "")))]
18690 "!TARGET_64BIT && reload_completed"
18691 [(set (match_dup 2)
18692 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18693 (match_dup 5)
18694 (match_dup 7)))
18695 (set (match_dup 3)
18696 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18697 (match_dup 6)
18698 (match_dup 8)))]
18699 "split_di (operands+2, 1, operands+5, operands+6);
18700 split_di (operands+3, 1, operands+7, operands+8);
18701 split_di (operands, 1, operands+2, operands+3);")
18702
18703 (define_expand "movxfcc"
18704 [(set (match_operand:XF 0 "register_operand" "")
18705 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18706 (match_operand:XF 2 "register_operand" "")
18707 (match_operand:XF 3 "register_operand" "")))]
18708 "TARGET_80387 && TARGET_CMOVE"
18709 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18710
18711 (define_insn "*movxfcc_1"
18712 [(set (match_operand:XF 0 "register_operand" "=f,f")
18713 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18714 [(reg FLAGS_REG) (const_int 0)])
18715 (match_operand:XF 2 "register_operand" "f,0")
18716 (match_operand:XF 3 "register_operand" "0,f")))]
18717 "TARGET_80387 && TARGET_CMOVE"
18718 "@
18719 fcmov%F1\t{%2, %0|%0, %2}
18720 fcmov%f1\t{%3, %0|%0, %3}"
18721 [(set_attr "type" "fcmov")
18722 (set_attr "mode" "XF")])
18723
18724 ;; These versions of the min/max patterns are intentionally ignorant of
18725 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18726 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18727 ;; are undefined in this condition, we're certain this is correct.
18728
18729 (define_insn "sminsf3"
18730 [(set (match_operand:SF 0 "register_operand" "=x")
18731 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18732 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18733 "TARGET_SSE_MATH"
18734 "minss\t{%2, %0|%0, %2}"
18735 [(set_attr "type" "sseadd")
18736 (set_attr "mode" "SF")])
18737
18738 (define_insn "smaxsf3"
18739 [(set (match_operand:SF 0 "register_operand" "=x")
18740 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18741 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18742 "TARGET_SSE_MATH"
18743 "maxss\t{%2, %0|%0, %2}"
18744 [(set_attr "type" "sseadd")
18745 (set_attr "mode" "SF")])
18746
18747 (define_insn "smindf3"
18748 [(set (match_operand:DF 0 "register_operand" "=x")
18749 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18750 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18751 "TARGET_SSE2 && TARGET_SSE_MATH"
18752 "minsd\t{%2, %0|%0, %2}"
18753 [(set_attr "type" "sseadd")
18754 (set_attr "mode" "DF")])
18755
18756 (define_insn "smaxdf3"
18757 [(set (match_operand:DF 0 "register_operand" "=x")
18758 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18759 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18760 "TARGET_SSE2 && TARGET_SSE_MATH"
18761 "maxsd\t{%2, %0|%0, %2}"
18762 [(set_attr "type" "sseadd")
18763 (set_attr "mode" "DF")])
18764
18765 ;; These versions of the min/max patterns implement exactly the operations
18766 ;; min = (op1 < op2 ? op1 : op2)
18767 ;; max = (!(op1 < op2) ? op1 : op2)
18768 ;; Their operands are not commutative, and thus they may be used in the
18769 ;; presence of -0.0 and NaN.
18770
18771 (define_insn "*ieee_sminsf3"
18772 [(set (match_operand:SF 0 "register_operand" "=x")
18773 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18774 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18775 UNSPEC_IEEE_MIN))]
18776 "TARGET_SSE_MATH"
18777 "minss\t{%2, %0|%0, %2}"
18778 [(set_attr "type" "sseadd")
18779 (set_attr "mode" "SF")])
18780
18781 (define_insn "*ieee_smaxsf3"
18782 [(set (match_operand:SF 0 "register_operand" "=x")
18783 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18784 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18785 UNSPEC_IEEE_MAX))]
18786 "TARGET_SSE_MATH"
18787 "maxss\t{%2, %0|%0, %2}"
18788 [(set_attr "type" "sseadd")
18789 (set_attr "mode" "SF")])
18790
18791 (define_insn "*ieee_smindf3"
18792 [(set (match_operand:DF 0 "register_operand" "=x")
18793 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18794 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18795 UNSPEC_IEEE_MIN))]
18796 "TARGET_SSE2 && TARGET_SSE_MATH"
18797 "minsd\t{%2, %0|%0, %2}"
18798 [(set_attr "type" "sseadd")
18799 (set_attr "mode" "DF")])
18800
18801 (define_insn "*ieee_smaxdf3"
18802 [(set (match_operand:DF 0 "register_operand" "=x")
18803 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18804 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18805 UNSPEC_IEEE_MAX))]
18806 "TARGET_SSE2 && TARGET_SSE_MATH"
18807 "maxsd\t{%2, %0|%0, %2}"
18808 [(set_attr "type" "sseadd")
18809 (set_attr "mode" "DF")])
18810
18811 ;; Make two stack loads independent:
18812 ;; fld aa fld aa
18813 ;; fld %st(0) -> fld bb
18814 ;; fmul bb fmul %st(1), %st
18815 ;;
18816 ;; Actually we only match the last two instructions for simplicity.
18817 (define_peephole2
18818 [(set (match_operand 0 "fp_register_operand" "")
18819 (match_operand 1 "fp_register_operand" ""))
18820 (set (match_dup 0)
18821 (match_operator 2 "binary_fp_operator"
18822 [(match_dup 0)
18823 (match_operand 3 "memory_operand" "")]))]
18824 "REGNO (operands[0]) != REGNO (operands[1])"
18825 [(set (match_dup 0) (match_dup 3))
18826 (set (match_dup 0) (match_dup 4))]
18827
18828 ;; The % modifier is not operational anymore in peephole2's, so we have to
18829 ;; swap the operands manually in the case of addition and multiplication.
18830 "if (COMMUTATIVE_ARITH_P (operands[2]))
18831 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18832 operands[0], operands[1]);
18833 else
18834 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18835 operands[1], operands[0]);")
18836
18837 ;; Conditional addition patterns
18838 (define_expand "addqicc"
18839 [(match_operand:QI 0 "register_operand" "")
18840 (match_operand 1 "comparison_operator" "")
18841 (match_operand:QI 2 "register_operand" "")
18842 (match_operand:QI 3 "const_int_operand" "")]
18843 ""
18844 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18845
18846 (define_expand "addhicc"
18847 [(match_operand:HI 0 "register_operand" "")
18848 (match_operand 1 "comparison_operator" "")
18849 (match_operand:HI 2 "register_operand" "")
18850 (match_operand:HI 3 "const_int_operand" "")]
18851 ""
18852 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18853
18854 (define_expand "addsicc"
18855 [(match_operand:SI 0 "register_operand" "")
18856 (match_operand 1 "comparison_operator" "")
18857 (match_operand:SI 2 "register_operand" "")
18858 (match_operand:SI 3 "const_int_operand" "")]
18859 ""
18860 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18861
18862 (define_expand "adddicc"
18863 [(match_operand:DI 0 "register_operand" "")
18864 (match_operand 1 "comparison_operator" "")
18865 (match_operand:DI 2 "register_operand" "")
18866 (match_operand:DI 3 "const_int_operand" "")]
18867 "TARGET_64BIT"
18868 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18869
18870 \f
18871 ;; Misc patterns (?)
18872
18873 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18874 ;; Otherwise there will be nothing to keep
18875 ;;
18876 ;; [(set (reg ebp) (reg esp))]
18877 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18878 ;; (clobber (eflags)]
18879 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18880 ;;
18881 ;; in proper program order.
18882 (define_insn "pro_epilogue_adjust_stack_1"
18883 [(set (match_operand:SI 0 "register_operand" "=r,r")
18884 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18885 (match_operand:SI 2 "immediate_operand" "i,i")))
18886 (clobber (reg:CC FLAGS_REG))
18887 (clobber (mem:BLK (scratch)))]
18888 "!TARGET_64BIT"
18889 {
18890 switch (get_attr_type (insn))
18891 {
18892 case TYPE_IMOV:
18893 return "mov{l}\t{%1, %0|%0, %1}";
18894
18895 case TYPE_ALU:
18896 if (CONST_INT_P (operands[2])
18897 && (INTVAL (operands[2]) == 128
18898 || (INTVAL (operands[2]) < 0
18899 && INTVAL (operands[2]) != -128)))
18900 {
18901 operands[2] = GEN_INT (-INTVAL (operands[2]));
18902 return "sub{l}\t{%2, %0|%0, %2}";
18903 }
18904 return "add{l}\t{%2, %0|%0, %2}";
18905
18906 case TYPE_LEA:
18907 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18908 return "lea{l}\t{%a2, %0|%0, %a2}";
18909
18910 default:
18911 gcc_unreachable ();
18912 }
18913 }
18914 [(set (attr "type")
18915 (cond [(eq_attr "alternative" "0")
18916 (const_string "alu")
18917 (match_operand:SI 2 "const0_operand" "")
18918 (const_string "imov")
18919 ]
18920 (const_string "lea")))
18921 (set_attr "mode" "SI")])
18922
18923 (define_insn "pro_epilogue_adjust_stack_rex64"
18924 [(set (match_operand:DI 0 "register_operand" "=r,r")
18925 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18926 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18927 (clobber (reg:CC FLAGS_REG))
18928 (clobber (mem:BLK (scratch)))]
18929 "TARGET_64BIT"
18930 {
18931 switch (get_attr_type (insn))
18932 {
18933 case TYPE_IMOV:
18934 return "mov{q}\t{%1, %0|%0, %1}";
18935
18936 case TYPE_ALU:
18937 if (CONST_INT_P (operands[2])
18938 /* Avoid overflows. */
18939 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18940 && (INTVAL (operands[2]) == 128
18941 || (INTVAL (operands[2]) < 0
18942 && INTVAL (operands[2]) != -128)))
18943 {
18944 operands[2] = GEN_INT (-INTVAL (operands[2]));
18945 return "sub{q}\t{%2, %0|%0, %2}";
18946 }
18947 return "add{q}\t{%2, %0|%0, %2}";
18948
18949 case TYPE_LEA:
18950 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18951 return "lea{q}\t{%a2, %0|%0, %a2}";
18952
18953 default:
18954 gcc_unreachable ();
18955 }
18956 }
18957 [(set (attr "type")
18958 (cond [(eq_attr "alternative" "0")
18959 (const_string "alu")
18960 (match_operand:DI 2 "const0_operand" "")
18961 (const_string "imov")
18962 ]
18963 (const_string "lea")))
18964 (set_attr "mode" "DI")])
18965
18966 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18967 [(set (match_operand:DI 0 "register_operand" "=r,r")
18968 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18969 (match_operand:DI 3 "immediate_operand" "i,i")))
18970 (use (match_operand:DI 2 "register_operand" "r,r"))
18971 (clobber (reg:CC FLAGS_REG))
18972 (clobber (mem:BLK (scratch)))]
18973 "TARGET_64BIT"
18974 {
18975 switch (get_attr_type (insn))
18976 {
18977 case TYPE_ALU:
18978 return "add{q}\t{%2, %0|%0, %2}";
18979
18980 case TYPE_LEA:
18981 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18982 return "lea{q}\t{%a2, %0|%0, %a2}";
18983
18984 default:
18985 gcc_unreachable ();
18986 }
18987 }
18988 [(set_attr "type" "alu,lea")
18989 (set_attr "mode" "DI")])
18990
18991 (define_expand "allocate_stack_worker"
18992 [(match_operand:SI 0 "register_operand" "")]
18993 "TARGET_STACK_PROBE"
18994 {
18995 if (reload_completed)
18996 {
18997 if (TARGET_64BIT)
18998 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18999 else
19000 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19001 }
19002 else
19003 {
19004 if (TARGET_64BIT)
19005 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19006 else
19007 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19008 }
19009 DONE;
19010 })
19011
19012 (define_insn "allocate_stack_worker_1"
19013 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19014 UNSPECV_STACK_PROBE)
19015 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19016 (clobber (match_scratch:SI 1 "=0"))
19017 (clobber (reg:CC FLAGS_REG))]
19018 "!TARGET_64BIT && TARGET_STACK_PROBE"
19019 "call\t__alloca"
19020 [(set_attr "type" "multi")
19021 (set_attr "length" "5")])
19022
19023 (define_expand "allocate_stack_worker_postreload"
19024 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19025 UNSPECV_STACK_PROBE)
19026 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19027 (clobber (match_dup 0))
19028 (clobber (reg:CC FLAGS_REG))])]
19029 ""
19030 "")
19031
19032 (define_insn "allocate_stack_worker_rex64"
19033 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19034 UNSPECV_STACK_PROBE)
19035 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19036 (clobber (match_scratch:DI 1 "=0"))
19037 (clobber (reg:CC FLAGS_REG))]
19038 "TARGET_64BIT && TARGET_STACK_PROBE"
19039 "call\t__alloca"
19040 [(set_attr "type" "multi")
19041 (set_attr "length" "5")])
19042
19043 (define_expand "allocate_stack_worker_rex64_postreload"
19044 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19045 UNSPECV_STACK_PROBE)
19046 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19047 (clobber (match_dup 0))
19048 (clobber (reg:CC FLAGS_REG))])]
19049 ""
19050 "")
19051
19052 (define_expand "allocate_stack"
19053 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19054 (minus:SI (reg:SI SP_REG)
19055 (match_operand:SI 1 "general_operand" "")))
19056 (clobber (reg:CC FLAGS_REG))])
19057 (parallel [(set (reg:SI SP_REG)
19058 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19059 (clobber (reg:CC FLAGS_REG))])]
19060 "TARGET_STACK_PROBE"
19061 {
19062 #ifdef CHECK_STACK_LIMIT
19063 if (CONST_INT_P (operands[1])
19064 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19065 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19066 operands[1]));
19067 else
19068 #endif
19069 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19070 operands[1])));
19071
19072 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19073 DONE;
19074 })
19075
19076 (define_expand "builtin_setjmp_receiver"
19077 [(label_ref (match_operand 0 "" ""))]
19078 "!TARGET_64BIT && flag_pic"
19079 {
19080 if (TARGET_MACHO)
19081 {
19082 rtx xops[3];
19083 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19084 rtx label_rtx = gen_label_rtx ();
19085 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19086 xops[0] = xops[1] = picreg;
19087 xops[2] = gen_rtx_CONST (SImode,
19088 gen_rtx_MINUS (SImode,
19089 gen_rtx_LABEL_REF (SImode, label_rtx),
19090 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19091 ix86_expand_binary_operator (MINUS, SImode, xops);
19092 }
19093 else
19094 emit_insn (gen_set_got (pic_offset_table_rtx));
19095 DONE;
19096 })
19097 \f
19098 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19099
19100 (define_split
19101 [(set (match_operand 0 "register_operand" "")
19102 (match_operator 3 "promotable_binary_operator"
19103 [(match_operand 1 "register_operand" "")
19104 (match_operand 2 "aligned_operand" "")]))
19105 (clobber (reg:CC FLAGS_REG))]
19106 "! TARGET_PARTIAL_REG_STALL && reload_completed
19107 && ((GET_MODE (operands[0]) == HImode
19108 && ((!optimize_size && !TARGET_FAST_PREFIX)
19109 /* ??? next two lines just !satisfies_constraint_K (...) */
19110 || !CONST_INT_P (operands[2])
19111 || satisfies_constraint_K (operands[2])))
19112 || (GET_MODE (operands[0]) == QImode
19113 && (TARGET_PROMOTE_QImode || optimize_size)))"
19114 [(parallel [(set (match_dup 0)
19115 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19116 (clobber (reg:CC FLAGS_REG))])]
19117 "operands[0] = gen_lowpart (SImode, operands[0]);
19118 operands[1] = gen_lowpart (SImode, operands[1]);
19119 if (GET_CODE (operands[3]) != ASHIFT)
19120 operands[2] = gen_lowpart (SImode, operands[2]);
19121 PUT_MODE (operands[3], SImode);")
19122
19123 ; Promote the QImode tests, as i386 has encoding of the AND
19124 ; instruction with 32-bit sign-extended immediate and thus the
19125 ; instruction size is unchanged, except in the %eax case for
19126 ; which it is increased by one byte, hence the ! optimize_size.
19127 (define_split
19128 [(set (match_operand 0 "flags_reg_operand" "")
19129 (match_operator 2 "compare_operator"
19130 [(and (match_operand 3 "aligned_operand" "")
19131 (match_operand 4 "const_int_operand" ""))
19132 (const_int 0)]))
19133 (set (match_operand 1 "register_operand" "")
19134 (and (match_dup 3) (match_dup 4)))]
19135 "! TARGET_PARTIAL_REG_STALL && reload_completed
19136 /* Ensure that the operand will remain sign-extended immediate. */
19137 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19138 && ! optimize_size
19139 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19140 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19141 [(parallel [(set (match_dup 0)
19142 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19143 (const_int 0)]))
19144 (set (match_dup 1)
19145 (and:SI (match_dup 3) (match_dup 4)))])]
19146 {
19147 operands[4]
19148 = gen_int_mode (INTVAL (operands[4])
19149 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19150 operands[1] = gen_lowpart (SImode, operands[1]);
19151 operands[3] = gen_lowpart (SImode, operands[3]);
19152 })
19153
19154 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19155 ; the TEST instruction with 32-bit sign-extended immediate and thus
19156 ; the instruction size would at least double, which is not what we
19157 ; want even with ! optimize_size.
19158 (define_split
19159 [(set (match_operand 0 "flags_reg_operand" "")
19160 (match_operator 1 "compare_operator"
19161 [(and (match_operand:HI 2 "aligned_operand" "")
19162 (match_operand:HI 3 "const_int_operand" ""))
19163 (const_int 0)]))]
19164 "! TARGET_PARTIAL_REG_STALL && reload_completed
19165 /* Ensure that the operand will remain sign-extended immediate. */
19166 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19167 && ! TARGET_FAST_PREFIX
19168 && ! optimize_size"
19169 [(set (match_dup 0)
19170 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19171 (const_int 0)]))]
19172 {
19173 operands[3]
19174 = gen_int_mode (INTVAL (operands[3])
19175 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19176 operands[2] = gen_lowpart (SImode, operands[2]);
19177 })
19178
19179 (define_split
19180 [(set (match_operand 0 "register_operand" "")
19181 (neg (match_operand 1 "register_operand" "")))
19182 (clobber (reg:CC FLAGS_REG))]
19183 "! TARGET_PARTIAL_REG_STALL && reload_completed
19184 && (GET_MODE (operands[0]) == HImode
19185 || (GET_MODE (operands[0]) == QImode
19186 && (TARGET_PROMOTE_QImode || optimize_size)))"
19187 [(parallel [(set (match_dup 0)
19188 (neg:SI (match_dup 1)))
19189 (clobber (reg:CC FLAGS_REG))])]
19190 "operands[0] = gen_lowpart (SImode, operands[0]);
19191 operands[1] = gen_lowpart (SImode, operands[1]);")
19192
19193 (define_split
19194 [(set (match_operand 0 "register_operand" "")
19195 (not (match_operand 1 "register_operand" "")))]
19196 "! TARGET_PARTIAL_REG_STALL && reload_completed
19197 && (GET_MODE (operands[0]) == HImode
19198 || (GET_MODE (operands[0]) == QImode
19199 && (TARGET_PROMOTE_QImode || optimize_size)))"
19200 [(set (match_dup 0)
19201 (not:SI (match_dup 1)))]
19202 "operands[0] = gen_lowpart (SImode, operands[0]);
19203 operands[1] = gen_lowpart (SImode, operands[1]);")
19204
19205 (define_split
19206 [(set (match_operand 0 "register_operand" "")
19207 (if_then_else (match_operator 1 "comparison_operator"
19208 [(reg FLAGS_REG) (const_int 0)])
19209 (match_operand 2 "register_operand" "")
19210 (match_operand 3 "register_operand" "")))]
19211 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19212 && (GET_MODE (operands[0]) == HImode
19213 || (GET_MODE (operands[0]) == QImode
19214 && (TARGET_PROMOTE_QImode || optimize_size)))"
19215 [(set (match_dup 0)
19216 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19217 "operands[0] = gen_lowpart (SImode, operands[0]);
19218 operands[2] = gen_lowpart (SImode, operands[2]);
19219 operands[3] = gen_lowpart (SImode, operands[3]);")
19220
19221 \f
19222 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19223 ;; transform a complex memory operation into two memory to register operations.
19224
19225 ;; Don't push memory operands
19226 (define_peephole2
19227 [(set (match_operand:SI 0 "push_operand" "")
19228 (match_operand:SI 1 "memory_operand" ""))
19229 (match_scratch:SI 2 "r")]
19230 "!optimize_size && !TARGET_PUSH_MEMORY
19231 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19232 [(set (match_dup 2) (match_dup 1))
19233 (set (match_dup 0) (match_dup 2))]
19234 "")
19235
19236 (define_peephole2
19237 [(set (match_operand:DI 0 "push_operand" "")
19238 (match_operand:DI 1 "memory_operand" ""))
19239 (match_scratch:DI 2 "r")]
19240 "!optimize_size && !TARGET_PUSH_MEMORY
19241 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19242 [(set (match_dup 2) (match_dup 1))
19243 (set (match_dup 0) (match_dup 2))]
19244 "")
19245
19246 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19247 ;; SImode pushes.
19248 (define_peephole2
19249 [(set (match_operand:SF 0 "push_operand" "")
19250 (match_operand:SF 1 "memory_operand" ""))
19251 (match_scratch:SF 2 "r")]
19252 "!optimize_size && !TARGET_PUSH_MEMORY
19253 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19254 [(set (match_dup 2) (match_dup 1))
19255 (set (match_dup 0) (match_dup 2))]
19256 "")
19257
19258 (define_peephole2
19259 [(set (match_operand:HI 0 "push_operand" "")
19260 (match_operand:HI 1 "memory_operand" ""))
19261 (match_scratch:HI 2 "r")]
19262 "!optimize_size && !TARGET_PUSH_MEMORY
19263 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19264 [(set (match_dup 2) (match_dup 1))
19265 (set (match_dup 0) (match_dup 2))]
19266 "")
19267
19268 (define_peephole2
19269 [(set (match_operand:QI 0 "push_operand" "")
19270 (match_operand:QI 1 "memory_operand" ""))
19271 (match_scratch:QI 2 "q")]
19272 "!optimize_size && !TARGET_PUSH_MEMORY
19273 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19274 [(set (match_dup 2) (match_dup 1))
19275 (set (match_dup 0) (match_dup 2))]
19276 "")
19277
19278 ;; Don't move an immediate directly to memory when the instruction
19279 ;; gets too big.
19280 (define_peephole2
19281 [(match_scratch:SI 1 "r")
19282 (set (match_operand:SI 0 "memory_operand" "")
19283 (const_int 0))]
19284 "! optimize_size
19285 && ! TARGET_USE_MOV0
19286 && TARGET_SPLIT_LONG_MOVES
19287 && get_attr_length (insn) >= ix86_cost->large_insn
19288 && peep2_regno_dead_p (0, FLAGS_REG)"
19289 [(parallel [(set (match_dup 1) (const_int 0))
19290 (clobber (reg:CC FLAGS_REG))])
19291 (set (match_dup 0) (match_dup 1))]
19292 "")
19293
19294 (define_peephole2
19295 [(match_scratch:HI 1 "r")
19296 (set (match_operand:HI 0 "memory_operand" "")
19297 (const_int 0))]
19298 "! optimize_size
19299 && ! TARGET_USE_MOV0
19300 && TARGET_SPLIT_LONG_MOVES
19301 && get_attr_length (insn) >= ix86_cost->large_insn
19302 && peep2_regno_dead_p (0, FLAGS_REG)"
19303 [(parallel [(set (match_dup 2) (const_int 0))
19304 (clobber (reg:CC FLAGS_REG))])
19305 (set (match_dup 0) (match_dup 1))]
19306 "operands[2] = gen_lowpart (SImode, operands[1]);")
19307
19308 (define_peephole2
19309 [(match_scratch:QI 1 "q")
19310 (set (match_operand:QI 0 "memory_operand" "")
19311 (const_int 0))]
19312 "! optimize_size
19313 && ! TARGET_USE_MOV0
19314 && TARGET_SPLIT_LONG_MOVES
19315 && get_attr_length (insn) >= ix86_cost->large_insn
19316 && peep2_regno_dead_p (0, FLAGS_REG)"
19317 [(parallel [(set (match_dup 2) (const_int 0))
19318 (clobber (reg:CC FLAGS_REG))])
19319 (set (match_dup 0) (match_dup 1))]
19320 "operands[2] = gen_lowpart (SImode, operands[1]);")
19321
19322 (define_peephole2
19323 [(match_scratch:SI 2 "r")
19324 (set (match_operand:SI 0 "memory_operand" "")
19325 (match_operand:SI 1 "immediate_operand" ""))]
19326 "! optimize_size
19327 && get_attr_length (insn) >= ix86_cost->large_insn
19328 && TARGET_SPLIT_LONG_MOVES"
19329 [(set (match_dup 2) (match_dup 1))
19330 (set (match_dup 0) (match_dup 2))]
19331 "")
19332
19333 (define_peephole2
19334 [(match_scratch:HI 2 "r")
19335 (set (match_operand:HI 0 "memory_operand" "")
19336 (match_operand:HI 1 "immediate_operand" ""))]
19337 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19338 && TARGET_SPLIT_LONG_MOVES"
19339 [(set (match_dup 2) (match_dup 1))
19340 (set (match_dup 0) (match_dup 2))]
19341 "")
19342
19343 (define_peephole2
19344 [(match_scratch:QI 2 "q")
19345 (set (match_operand:QI 0 "memory_operand" "")
19346 (match_operand:QI 1 "immediate_operand" ""))]
19347 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19348 && TARGET_SPLIT_LONG_MOVES"
19349 [(set (match_dup 2) (match_dup 1))
19350 (set (match_dup 0) (match_dup 2))]
19351 "")
19352
19353 ;; Don't compare memory with zero, load and use a test instead.
19354 (define_peephole2
19355 [(set (match_operand 0 "flags_reg_operand" "")
19356 (match_operator 1 "compare_operator"
19357 [(match_operand:SI 2 "memory_operand" "")
19358 (const_int 0)]))
19359 (match_scratch:SI 3 "r")]
19360 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19361 [(set (match_dup 3) (match_dup 2))
19362 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19363 "")
19364
19365 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19366 ;; Don't split NOTs with a displacement operand, because resulting XOR
19367 ;; will not be pairable anyway.
19368 ;;
19369 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19370 ;; represented using a modRM byte. The XOR replacement is long decoded,
19371 ;; so this split helps here as well.
19372 ;;
19373 ;; Note: Can't do this as a regular split because we can't get proper
19374 ;; lifetime information then.
19375
19376 (define_peephole2
19377 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19378 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19379 "!optimize_size
19380 && peep2_regno_dead_p (0, FLAGS_REG)
19381 && ((TARGET_PENTIUM
19382 && (!MEM_P (operands[0])
19383 || !memory_displacement_operand (operands[0], SImode)))
19384 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19385 [(parallel [(set (match_dup 0)
19386 (xor:SI (match_dup 1) (const_int -1)))
19387 (clobber (reg:CC FLAGS_REG))])]
19388 "")
19389
19390 (define_peephole2
19391 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19392 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19393 "!optimize_size
19394 && peep2_regno_dead_p (0, FLAGS_REG)
19395 && ((TARGET_PENTIUM
19396 && (!MEM_P (operands[0])
19397 || !memory_displacement_operand (operands[0], HImode)))
19398 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19399 [(parallel [(set (match_dup 0)
19400 (xor:HI (match_dup 1) (const_int -1)))
19401 (clobber (reg:CC FLAGS_REG))])]
19402 "")
19403
19404 (define_peephole2
19405 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19406 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19407 "!optimize_size
19408 && peep2_regno_dead_p (0, FLAGS_REG)
19409 && ((TARGET_PENTIUM
19410 && (!MEM_P (operands[0])
19411 || !memory_displacement_operand (operands[0], QImode)))
19412 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19413 [(parallel [(set (match_dup 0)
19414 (xor:QI (match_dup 1) (const_int -1)))
19415 (clobber (reg:CC FLAGS_REG))])]
19416 "")
19417
19418 ;; Non pairable "test imm, reg" instructions can be translated to
19419 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19420 ;; byte opcode instead of two, have a short form for byte operands),
19421 ;; so do it for other CPUs as well. Given that the value was dead,
19422 ;; this should not create any new dependencies. Pass on the sub-word
19423 ;; versions if we're concerned about partial register stalls.
19424
19425 (define_peephole2
19426 [(set (match_operand 0 "flags_reg_operand" "")
19427 (match_operator 1 "compare_operator"
19428 [(and:SI (match_operand:SI 2 "register_operand" "")
19429 (match_operand:SI 3 "immediate_operand" ""))
19430 (const_int 0)]))]
19431 "ix86_match_ccmode (insn, CCNOmode)
19432 && (true_regnum (operands[2]) != 0
19433 || satisfies_constraint_K (operands[3]))
19434 && peep2_reg_dead_p (1, operands[2])"
19435 [(parallel
19436 [(set (match_dup 0)
19437 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19438 (const_int 0)]))
19439 (set (match_dup 2)
19440 (and:SI (match_dup 2) (match_dup 3)))])]
19441 "")
19442
19443 ;; We don't need to handle HImode case, because it will be promoted to SImode
19444 ;; on ! TARGET_PARTIAL_REG_STALL
19445
19446 (define_peephole2
19447 [(set (match_operand 0 "flags_reg_operand" "")
19448 (match_operator 1 "compare_operator"
19449 [(and:QI (match_operand:QI 2 "register_operand" "")
19450 (match_operand:QI 3 "immediate_operand" ""))
19451 (const_int 0)]))]
19452 "! TARGET_PARTIAL_REG_STALL
19453 && ix86_match_ccmode (insn, CCNOmode)
19454 && true_regnum (operands[2]) != 0
19455 && peep2_reg_dead_p (1, operands[2])"
19456 [(parallel
19457 [(set (match_dup 0)
19458 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19459 (const_int 0)]))
19460 (set (match_dup 2)
19461 (and:QI (match_dup 2) (match_dup 3)))])]
19462 "")
19463
19464 (define_peephole2
19465 [(set (match_operand 0 "flags_reg_operand" "")
19466 (match_operator 1 "compare_operator"
19467 [(and:SI
19468 (zero_extract:SI
19469 (match_operand 2 "ext_register_operand" "")
19470 (const_int 8)
19471 (const_int 8))
19472 (match_operand 3 "const_int_operand" ""))
19473 (const_int 0)]))]
19474 "! TARGET_PARTIAL_REG_STALL
19475 && ix86_match_ccmode (insn, CCNOmode)
19476 && true_regnum (operands[2]) != 0
19477 && peep2_reg_dead_p (1, operands[2])"
19478 [(parallel [(set (match_dup 0)
19479 (match_op_dup 1
19480 [(and:SI
19481 (zero_extract:SI
19482 (match_dup 2)
19483 (const_int 8)
19484 (const_int 8))
19485 (match_dup 3))
19486 (const_int 0)]))
19487 (set (zero_extract:SI (match_dup 2)
19488 (const_int 8)
19489 (const_int 8))
19490 (and:SI
19491 (zero_extract:SI
19492 (match_dup 2)
19493 (const_int 8)
19494 (const_int 8))
19495 (match_dup 3)))])]
19496 "")
19497
19498 ;; Don't do logical operations with memory inputs.
19499 (define_peephole2
19500 [(match_scratch:SI 2 "r")
19501 (parallel [(set (match_operand:SI 0 "register_operand" "")
19502 (match_operator:SI 3 "arith_or_logical_operator"
19503 [(match_dup 0)
19504 (match_operand:SI 1 "memory_operand" "")]))
19505 (clobber (reg:CC FLAGS_REG))])]
19506 "! optimize_size && ! TARGET_READ_MODIFY"
19507 [(set (match_dup 2) (match_dup 1))
19508 (parallel [(set (match_dup 0)
19509 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19510 (clobber (reg:CC FLAGS_REG))])]
19511 "")
19512
19513 (define_peephole2
19514 [(match_scratch:SI 2 "r")
19515 (parallel [(set (match_operand:SI 0 "register_operand" "")
19516 (match_operator:SI 3 "arith_or_logical_operator"
19517 [(match_operand:SI 1 "memory_operand" "")
19518 (match_dup 0)]))
19519 (clobber (reg:CC FLAGS_REG))])]
19520 "! optimize_size && ! TARGET_READ_MODIFY"
19521 [(set (match_dup 2) (match_dup 1))
19522 (parallel [(set (match_dup 0)
19523 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19524 (clobber (reg:CC FLAGS_REG))])]
19525 "")
19526
19527 ; Don't do logical operations with memory outputs
19528 ;
19529 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19530 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19531 ; the same decoder scheduling characteristics as the original.
19532
19533 (define_peephole2
19534 [(match_scratch:SI 2 "r")
19535 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19536 (match_operator:SI 3 "arith_or_logical_operator"
19537 [(match_dup 0)
19538 (match_operand:SI 1 "nonmemory_operand" "")]))
19539 (clobber (reg:CC FLAGS_REG))])]
19540 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19541 [(set (match_dup 2) (match_dup 0))
19542 (parallel [(set (match_dup 2)
19543 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19544 (clobber (reg:CC FLAGS_REG))])
19545 (set (match_dup 0) (match_dup 2))]
19546 "")
19547
19548 (define_peephole2
19549 [(match_scratch:SI 2 "r")
19550 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19551 (match_operator:SI 3 "arith_or_logical_operator"
19552 [(match_operand:SI 1 "nonmemory_operand" "")
19553 (match_dup 0)]))
19554 (clobber (reg:CC FLAGS_REG))])]
19555 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19556 [(set (match_dup 2) (match_dup 0))
19557 (parallel [(set (match_dup 2)
19558 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19559 (clobber (reg:CC FLAGS_REG))])
19560 (set (match_dup 0) (match_dup 2))]
19561 "")
19562
19563 ;; Attempt to always use XOR for zeroing registers.
19564 (define_peephole2
19565 [(set (match_operand 0 "register_operand" "")
19566 (match_operand 1 "const0_operand" ""))]
19567 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19568 && (! TARGET_USE_MOV0 || optimize_size)
19569 && GENERAL_REG_P (operands[0])
19570 && peep2_regno_dead_p (0, FLAGS_REG)"
19571 [(parallel [(set (match_dup 0) (const_int 0))
19572 (clobber (reg:CC FLAGS_REG))])]
19573 {
19574 operands[0] = gen_lowpart (word_mode, operands[0]);
19575 })
19576
19577 (define_peephole2
19578 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19579 (const_int 0))]
19580 "(GET_MODE (operands[0]) == QImode
19581 || GET_MODE (operands[0]) == HImode)
19582 && (! TARGET_USE_MOV0 || optimize_size)
19583 && peep2_regno_dead_p (0, FLAGS_REG)"
19584 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19585 (clobber (reg:CC FLAGS_REG))])])
19586
19587 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19588 (define_peephole2
19589 [(set (match_operand 0 "register_operand" "")
19590 (const_int -1))]
19591 "(GET_MODE (operands[0]) == HImode
19592 || GET_MODE (operands[0]) == SImode
19593 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19594 && (optimize_size || TARGET_PENTIUM)
19595 && peep2_regno_dead_p (0, FLAGS_REG)"
19596 [(parallel [(set (match_dup 0) (const_int -1))
19597 (clobber (reg:CC FLAGS_REG))])]
19598 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19599 operands[0]);")
19600
19601 ;; Attempt to convert simple leas to adds. These can be created by
19602 ;; move expanders.
19603 (define_peephole2
19604 [(set (match_operand:SI 0 "register_operand" "")
19605 (plus:SI (match_dup 0)
19606 (match_operand:SI 1 "nonmemory_operand" "")))]
19607 "peep2_regno_dead_p (0, FLAGS_REG)"
19608 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19609 (clobber (reg:CC FLAGS_REG))])]
19610 "")
19611
19612 (define_peephole2
19613 [(set (match_operand:SI 0 "register_operand" "")
19614 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19615 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19616 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19617 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19618 (clobber (reg:CC FLAGS_REG))])]
19619 "operands[2] = gen_lowpart (SImode, operands[2]);")
19620
19621 (define_peephole2
19622 [(set (match_operand:DI 0 "register_operand" "")
19623 (plus:DI (match_dup 0)
19624 (match_operand:DI 1 "x86_64_general_operand" "")))]
19625 "peep2_regno_dead_p (0, FLAGS_REG)"
19626 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19627 (clobber (reg:CC FLAGS_REG))])]
19628 "")
19629
19630 (define_peephole2
19631 [(set (match_operand:SI 0 "register_operand" "")
19632 (mult:SI (match_dup 0)
19633 (match_operand:SI 1 "const_int_operand" "")))]
19634 "exact_log2 (INTVAL (operands[1])) >= 0
19635 && peep2_regno_dead_p (0, FLAGS_REG)"
19636 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19637 (clobber (reg:CC FLAGS_REG))])]
19638 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19639
19640 (define_peephole2
19641 [(set (match_operand:DI 0 "register_operand" "")
19642 (mult:DI (match_dup 0)
19643 (match_operand:DI 1 "const_int_operand" "")))]
19644 "exact_log2 (INTVAL (operands[1])) >= 0
19645 && peep2_regno_dead_p (0, FLAGS_REG)"
19646 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19647 (clobber (reg:CC FLAGS_REG))])]
19648 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19649
19650 (define_peephole2
19651 [(set (match_operand:SI 0 "register_operand" "")
19652 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19653 (match_operand:DI 2 "const_int_operand" "")) 0))]
19654 "exact_log2 (INTVAL (operands[2])) >= 0
19655 && REGNO (operands[0]) == REGNO (operands[1])
19656 && peep2_regno_dead_p (0, FLAGS_REG)"
19657 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19658 (clobber (reg:CC FLAGS_REG))])]
19659 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19660
19661 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19662 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19663 ;; many CPUs it is also faster, since special hardware to avoid esp
19664 ;; dependencies is present.
19665
19666 ;; While some of these conversions may be done using splitters, we use peepholes
19667 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19668
19669 ;; Convert prologue esp subtractions to push.
19670 ;; We need register to push. In order to keep verify_flow_info happy we have
19671 ;; two choices
19672 ;; - use scratch and clobber it in order to avoid dependencies
19673 ;; - use already live register
19674 ;; We can't use the second way right now, since there is no reliable way how to
19675 ;; verify that given register is live. First choice will also most likely in
19676 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19677 ;; call clobbered registers are dead. We may want to use base pointer as an
19678 ;; alternative when no register is available later.
19679
19680 (define_peephole2
19681 [(match_scratch:SI 0 "r")
19682 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19683 (clobber (reg:CC FLAGS_REG))
19684 (clobber (mem:BLK (scratch)))])]
19685 "optimize_size || !TARGET_SUB_ESP_4"
19686 [(clobber (match_dup 0))
19687 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19688 (clobber (mem:BLK (scratch)))])])
19689
19690 (define_peephole2
19691 [(match_scratch:SI 0 "r")
19692 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19693 (clobber (reg:CC FLAGS_REG))
19694 (clobber (mem:BLK (scratch)))])]
19695 "optimize_size || !TARGET_SUB_ESP_8"
19696 [(clobber (match_dup 0))
19697 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19698 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19699 (clobber (mem:BLK (scratch)))])])
19700
19701 ;; Convert esp subtractions to push.
19702 (define_peephole2
19703 [(match_scratch:SI 0 "r")
19704 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19705 (clobber (reg:CC FLAGS_REG))])]
19706 "optimize_size || !TARGET_SUB_ESP_4"
19707 [(clobber (match_dup 0))
19708 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19709
19710 (define_peephole2
19711 [(match_scratch:SI 0 "r")
19712 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19713 (clobber (reg:CC FLAGS_REG))])]
19714 "optimize_size || !TARGET_SUB_ESP_8"
19715 [(clobber (match_dup 0))
19716 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19717 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19718
19719 ;; Convert epilogue deallocator to pop.
19720 (define_peephole2
19721 [(match_scratch:SI 0 "r")
19722 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19723 (clobber (reg:CC FLAGS_REG))
19724 (clobber (mem:BLK (scratch)))])]
19725 "optimize_size || !TARGET_ADD_ESP_4"
19726 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19727 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19728 (clobber (mem:BLK (scratch)))])]
19729 "")
19730
19731 ;; Two pops case is tricky, since pop causes dependency on destination register.
19732 ;; We use two registers if available.
19733 (define_peephole2
19734 [(match_scratch:SI 0 "r")
19735 (match_scratch:SI 1 "r")
19736 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19737 (clobber (reg:CC FLAGS_REG))
19738 (clobber (mem:BLK (scratch)))])]
19739 "optimize_size || !TARGET_ADD_ESP_8"
19740 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19741 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19742 (clobber (mem:BLK (scratch)))])
19743 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19744 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19745 "")
19746
19747 (define_peephole2
19748 [(match_scratch:SI 0 "r")
19749 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19750 (clobber (reg:CC FLAGS_REG))
19751 (clobber (mem:BLK (scratch)))])]
19752 "optimize_size"
19753 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19754 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19755 (clobber (mem:BLK (scratch)))])
19756 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19757 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19758 "")
19759
19760 ;; Convert esp additions to pop.
19761 (define_peephole2
19762 [(match_scratch:SI 0 "r")
19763 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19764 (clobber (reg:CC FLAGS_REG))])]
19765 ""
19766 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19767 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19768 "")
19769
19770 ;; Two pops case is tricky, since pop causes dependency on destination register.
19771 ;; We use two registers if available.
19772 (define_peephole2
19773 [(match_scratch:SI 0 "r")
19774 (match_scratch:SI 1 "r")
19775 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19776 (clobber (reg:CC FLAGS_REG))])]
19777 ""
19778 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19779 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19780 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19781 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19782 "")
19783
19784 (define_peephole2
19785 [(match_scratch:SI 0 "r")
19786 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19787 (clobber (reg:CC FLAGS_REG))])]
19788 "optimize_size"
19789 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19790 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19791 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19792 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19793 "")
19794 \f
19795 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19796 ;; required and register dies. Similarly for 128 to plus -128.
19797 (define_peephole2
19798 [(set (match_operand 0 "flags_reg_operand" "")
19799 (match_operator 1 "compare_operator"
19800 [(match_operand 2 "register_operand" "")
19801 (match_operand 3 "const_int_operand" "")]))]
19802 "(INTVAL (operands[3]) == -1
19803 || INTVAL (operands[3]) == 1
19804 || INTVAL (operands[3]) == 128)
19805 && ix86_match_ccmode (insn, CCGCmode)
19806 && peep2_reg_dead_p (1, operands[2])"
19807 [(parallel [(set (match_dup 0)
19808 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19809 (clobber (match_dup 2))])]
19810 "")
19811 \f
19812 (define_peephole2
19813 [(match_scratch:DI 0 "r")
19814 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19815 (clobber (reg:CC FLAGS_REG))
19816 (clobber (mem:BLK (scratch)))])]
19817 "optimize_size || !TARGET_SUB_ESP_4"
19818 [(clobber (match_dup 0))
19819 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19820 (clobber (mem:BLK (scratch)))])])
19821
19822 (define_peephole2
19823 [(match_scratch:DI 0 "r")
19824 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19825 (clobber (reg:CC FLAGS_REG))
19826 (clobber (mem:BLK (scratch)))])]
19827 "optimize_size || !TARGET_SUB_ESP_8"
19828 [(clobber (match_dup 0))
19829 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19830 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19831 (clobber (mem:BLK (scratch)))])])
19832
19833 ;; Convert esp subtractions to push.
19834 (define_peephole2
19835 [(match_scratch:DI 0 "r")
19836 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19837 (clobber (reg:CC FLAGS_REG))])]
19838 "optimize_size || !TARGET_SUB_ESP_4"
19839 [(clobber (match_dup 0))
19840 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19841
19842 (define_peephole2
19843 [(match_scratch:DI 0 "r")
19844 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19845 (clobber (reg:CC FLAGS_REG))])]
19846 "optimize_size || !TARGET_SUB_ESP_8"
19847 [(clobber (match_dup 0))
19848 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19849 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19850
19851 ;; Convert epilogue deallocator to pop.
19852 (define_peephole2
19853 [(match_scratch:DI 0 "r")
19854 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19855 (clobber (reg:CC FLAGS_REG))
19856 (clobber (mem:BLK (scratch)))])]
19857 "optimize_size || !TARGET_ADD_ESP_4"
19858 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19859 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19860 (clobber (mem:BLK (scratch)))])]
19861 "")
19862
19863 ;; Two pops case is tricky, since pop causes dependency on destination register.
19864 ;; We use two registers if available.
19865 (define_peephole2
19866 [(match_scratch:DI 0 "r")
19867 (match_scratch:DI 1 "r")
19868 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19869 (clobber (reg:CC FLAGS_REG))
19870 (clobber (mem:BLK (scratch)))])]
19871 "optimize_size || !TARGET_ADD_ESP_8"
19872 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19873 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19874 (clobber (mem:BLK (scratch)))])
19875 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19876 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19877 "")
19878
19879 (define_peephole2
19880 [(match_scratch:DI 0 "r")
19881 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19882 (clobber (reg:CC FLAGS_REG))
19883 (clobber (mem:BLK (scratch)))])]
19884 "optimize_size"
19885 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19886 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19887 (clobber (mem:BLK (scratch)))])
19888 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19889 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19890 "")
19891
19892 ;; Convert esp additions to pop.
19893 (define_peephole2
19894 [(match_scratch:DI 0 "r")
19895 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19896 (clobber (reg:CC FLAGS_REG))])]
19897 ""
19898 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19899 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19900 "")
19901
19902 ;; Two pops case is tricky, since pop causes dependency on destination register.
19903 ;; We use two registers if available.
19904 (define_peephole2
19905 [(match_scratch:DI 0 "r")
19906 (match_scratch:DI 1 "r")
19907 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19908 (clobber (reg:CC FLAGS_REG))])]
19909 ""
19910 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19911 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19912 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19913 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19914 "")
19915
19916 (define_peephole2
19917 [(match_scratch:DI 0 "r")
19918 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19919 (clobber (reg:CC FLAGS_REG))])]
19920 "optimize_size"
19921 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19922 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19923 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19924 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19925 "")
19926 \f
19927 ;; Convert imul by three, five and nine into lea
19928 (define_peephole2
19929 [(parallel
19930 [(set (match_operand:SI 0 "register_operand" "")
19931 (mult:SI (match_operand:SI 1 "register_operand" "")
19932 (match_operand:SI 2 "const_int_operand" "")))
19933 (clobber (reg:CC FLAGS_REG))])]
19934 "INTVAL (operands[2]) == 3
19935 || INTVAL (operands[2]) == 5
19936 || INTVAL (operands[2]) == 9"
19937 [(set (match_dup 0)
19938 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19939 (match_dup 1)))]
19940 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19941
19942 (define_peephole2
19943 [(parallel
19944 [(set (match_operand:SI 0 "register_operand" "")
19945 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19946 (match_operand:SI 2 "const_int_operand" "")))
19947 (clobber (reg:CC FLAGS_REG))])]
19948 "!optimize_size
19949 && (INTVAL (operands[2]) == 3
19950 || INTVAL (operands[2]) == 5
19951 || INTVAL (operands[2]) == 9)"
19952 [(set (match_dup 0) (match_dup 1))
19953 (set (match_dup 0)
19954 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19955 (match_dup 0)))]
19956 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19957
19958 (define_peephole2
19959 [(parallel
19960 [(set (match_operand:DI 0 "register_operand" "")
19961 (mult:DI (match_operand:DI 1 "register_operand" "")
19962 (match_operand:DI 2 "const_int_operand" "")))
19963 (clobber (reg:CC FLAGS_REG))])]
19964 "TARGET_64BIT
19965 && (INTVAL (operands[2]) == 3
19966 || INTVAL (operands[2]) == 5
19967 || INTVAL (operands[2]) == 9)"
19968 [(set (match_dup 0)
19969 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19970 (match_dup 1)))]
19971 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19972
19973 (define_peephole2
19974 [(parallel
19975 [(set (match_operand:DI 0 "register_operand" "")
19976 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19977 (match_operand:DI 2 "const_int_operand" "")))
19978 (clobber (reg:CC FLAGS_REG))])]
19979 "TARGET_64BIT
19980 && !optimize_size
19981 && (INTVAL (operands[2]) == 3
19982 || INTVAL (operands[2]) == 5
19983 || INTVAL (operands[2]) == 9)"
19984 [(set (match_dup 0) (match_dup 1))
19985 (set (match_dup 0)
19986 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19987 (match_dup 0)))]
19988 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19989
19990 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19991 ;; imul $32bit_imm, reg, reg is direct decoded.
19992 (define_peephole2
19993 [(match_scratch:DI 3 "r")
19994 (parallel [(set (match_operand:DI 0 "register_operand" "")
19995 (mult:DI (match_operand:DI 1 "memory_operand" "")
19996 (match_operand:DI 2 "immediate_operand" "")))
19997 (clobber (reg:CC FLAGS_REG))])]
19998 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19999 && !satisfies_constraint_K (operands[2])"
20000 [(set (match_dup 3) (match_dup 1))
20001 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20002 (clobber (reg:CC FLAGS_REG))])]
20003 "")
20004
20005 (define_peephole2
20006 [(match_scratch:SI 3 "r")
20007 (parallel [(set (match_operand:SI 0 "register_operand" "")
20008 (mult:SI (match_operand:SI 1 "memory_operand" "")
20009 (match_operand:SI 2 "immediate_operand" "")))
20010 (clobber (reg:CC FLAGS_REG))])]
20011 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20012 && !satisfies_constraint_K (operands[2])"
20013 [(set (match_dup 3) (match_dup 1))
20014 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20015 (clobber (reg:CC FLAGS_REG))])]
20016 "")
20017
20018 (define_peephole2
20019 [(match_scratch:SI 3 "r")
20020 (parallel [(set (match_operand:DI 0 "register_operand" "")
20021 (zero_extend:DI
20022 (mult:SI (match_operand:SI 1 "memory_operand" "")
20023 (match_operand:SI 2 "immediate_operand" ""))))
20024 (clobber (reg:CC FLAGS_REG))])]
20025 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20026 && !satisfies_constraint_K (operands[2])"
20027 [(set (match_dup 3) (match_dup 1))
20028 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20029 (clobber (reg:CC FLAGS_REG))])]
20030 "")
20031
20032 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20033 ;; Convert it into imul reg, reg
20034 ;; It would be better to force assembler to encode instruction using long
20035 ;; immediate, but there is apparently no way to do so.
20036 (define_peephole2
20037 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20038 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20039 (match_operand:DI 2 "const_int_operand" "")))
20040 (clobber (reg:CC FLAGS_REG))])
20041 (match_scratch:DI 3 "r")]
20042 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20043 && satisfies_constraint_K (operands[2])"
20044 [(set (match_dup 3) (match_dup 2))
20045 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20046 (clobber (reg:CC FLAGS_REG))])]
20047 {
20048 if (!rtx_equal_p (operands[0], operands[1]))
20049 emit_move_insn (operands[0], operands[1]);
20050 })
20051
20052 (define_peephole2
20053 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20054 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20055 (match_operand:SI 2 "const_int_operand" "")))
20056 (clobber (reg:CC FLAGS_REG))])
20057 (match_scratch:SI 3 "r")]
20058 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20059 && satisfies_constraint_K (operands[2])"
20060 [(set (match_dup 3) (match_dup 2))
20061 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20062 (clobber (reg:CC FLAGS_REG))])]
20063 {
20064 if (!rtx_equal_p (operands[0], operands[1]))
20065 emit_move_insn (operands[0], operands[1]);
20066 })
20067
20068 (define_peephole2
20069 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20070 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20071 (match_operand:HI 2 "immediate_operand" "")))
20072 (clobber (reg:CC FLAGS_REG))])
20073 (match_scratch:HI 3 "r")]
20074 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20075 [(set (match_dup 3) (match_dup 2))
20076 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20077 (clobber (reg:CC FLAGS_REG))])]
20078 {
20079 if (!rtx_equal_p (operands[0], operands[1]))
20080 emit_move_insn (operands[0], operands[1]);
20081 })
20082
20083 ;; After splitting up read-modify operations, array accesses with memory
20084 ;; operands might end up in form:
20085 ;; sall $2, %eax
20086 ;; movl 4(%esp), %edx
20087 ;; addl %edx, %eax
20088 ;; instead of pre-splitting:
20089 ;; sall $2, %eax
20090 ;; addl 4(%esp), %eax
20091 ;; Turn it into:
20092 ;; movl 4(%esp), %edx
20093 ;; leal (%edx,%eax,4), %eax
20094
20095 (define_peephole2
20096 [(parallel [(set (match_operand 0 "register_operand" "")
20097 (ashift (match_operand 1 "register_operand" "")
20098 (match_operand 2 "const_int_operand" "")))
20099 (clobber (reg:CC FLAGS_REG))])
20100 (set (match_operand 3 "register_operand")
20101 (match_operand 4 "x86_64_general_operand" ""))
20102 (parallel [(set (match_operand 5 "register_operand" "")
20103 (plus (match_operand 6 "register_operand" "")
20104 (match_operand 7 "register_operand" "")))
20105 (clobber (reg:CC FLAGS_REG))])]
20106 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20107 /* Validate MODE for lea. */
20108 && ((!TARGET_PARTIAL_REG_STALL
20109 && (GET_MODE (operands[0]) == QImode
20110 || GET_MODE (operands[0]) == HImode))
20111 || GET_MODE (operands[0]) == SImode
20112 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20113 /* We reorder load and the shift. */
20114 && !rtx_equal_p (operands[1], operands[3])
20115 && !reg_overlap_mentioned_p (operands[0], operands[4])
20116 /* Last PLUS must consist of operand 0 and 3. */
20117 && !rtx_equal_p (operands[0], operands[3])
20118 && (rtx_equal_p (operands[3], operands[6])
20119 || rtx_equal_p (operands[3], operands[7]))
20120 && (rtx_equal_p (operands[0], operands[6])
20121 || rtx_equal_p (operands[0], operands[7]))
20122 /* The intermediate operand 0 must die or be same as output. */
20123 && (rtx_equal_p (operands[0], operands[5])
20124 || peep2_reg_dead_p (3, operands[0]))"
20125 [(set (match_dup 3) (match_dup 4))
20126 (set (match_dup 0) (match_dup 1))]
20127 {
20128 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20129 int scale = 1 << INTVAL (operands[2]);
20130 rtx index = gen_lowpart (Pmode, operands[1]);
20131 rtx base = gen_lowpart (Pmode, operands[3]);
20132 rtx dest = gen_lowpart (mode, operands[5]);
20133
20134 operands[1] = gen_rtx_PLUS (Pmode, base,
20135 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20136 if (mode != Pmode)
20137 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20138 operands[0] = dest;
20139 })
20140 \f
20141 ;; Call-value patterns last so that the wildcard operand does not
20142 ;; disrupt insn-recog's switch tables.
20143
20144 (define_insn "*call_value_pop_0"
20145 [(set (match_operand 0 "" "")
20146 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20147 (match_operand:SI 2 "" "")))
20148 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20149 (match_operand:SI 3 "immediate_operand" "")))]
20150 "!TARGET_64BIT"
20151 {
20152 if (SIBLING_CALL_P (insn))
20153 return "jmp\t%P1";
20154 else
20155 return "call\t%P1";
20156 }
20157 [(set_attr "type" "callv")])
20158
20159 (define_insn "*call_value_pop_1"
20160 [(set (match_operand 0 "" "")
20161 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20162 (match_operand:SI 2 "" "")))
20163 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20164 (match_operand:SI 3 "immediate_operand" "i")))]
20165 "!TARGET_64BIT"
20166 {
20167 if (constant_call_address_operand (operands[1], Pmode))
20168 {
20169 if (SIBLING_CALL_P (insn))
20170 return "jmp\t%P1";
20171 else
20172 return "call\t%P1";
20173 }
20174 if (SIBLING_CALL_P (insn))
20175 return "jmp\t%A1";
20176 else
20177 return "call\t%A1";
20178 }
20179 [(set_attr "type" "callv")])
20180
20181 (define_insn "*call_value_0"
20182 [(set (match_operand 0 "" "")
20183 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20184 (match_operand:SI 2 "" "")))]
20185 "!TARGET_64BIT"
20186 {
20187 if (SIBLING_CALL_P (insn))
20188 return "jmp\t%P1";
20189 else
20190 return "call\t%P1";
20191 }
20192 [(set_attr "type" "callv")])
20193
20194 (define_insn "*call_value_0_rex64"
20195 [(set (match_operand 0 "" "")
20196 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20197 (match_operand:DI 2 "const_int_operand" "")))]
20198 "TARGET_64BIT"
20199 {
20200 if (SIBLING_CALL_P (insn))
20201 return "jmp\t%P1";
20202 else
20203 return "call\t%P1";
20204 }
20205 [(set_attr "type" "callv")])
20206
20207 (define_insn "*call_value_1"
20208 [(set (match_operand 0 "" "")
20209 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20210 (match_operand:SI 2 "" "")))]
20211 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20212 {
20213 if (constant_call_address_operand (operands[1], Pmode))
20214 return "call\t%P1";
20215 return "call\t%A1";
20216 }
20217 [(set_attr "type" "callv")])
20218
20219 (define_insn "*sibcall_value_1"
20220 [(set (match_operand 0 "" "")
20221 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20222 (match_operand:SI 2 "" "")))]
20223 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20224 {
20225 if (constant_call_address_operand (operands[1], Pmode))
20226 return "jmp\t%P1";
20227 return "jmp\t%A1";
20228 }
20229 [(set_attr "type" "callv")])
20230
20231 (define_insn "*call_value_1_rex64"
20232 [(set (match_operand 0 "" "")
20233 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20234 (match_operand:DI 2 "" "")))]
20235 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20236 {
20237 if (constant_call_address_operand (operands[1], Pmode))
20238 return "call\t%P1";
20239 return "call\t%A1";
20240 }
20241 [(set_attr "type" "callv")])
20242
20243 (define_insn "*sibcall_value_1_rex64"
20244 [(set (match_operand 0 "" "")
20245 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20246 (match_operand:DI 2 "" "")))]
20247 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20248 "jmp\t%P1"
20249 [(set_attr "type" "callv")])
20250
20251 (define_insn "*sibcall_value_1_rex64_v"
20252 [(set (match_operand 0 "" "")
20253 (call (mem:QI (reg:DI R11_REG))
20254 (match_operand:DI 1 "" "")))]
20255 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20256 "jmp\t*%%r11"
20257 [(set_attr "type" "callv")])
20258 \f
20259 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20260 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20261 ;; caught for use by garbage collectors and the like. Using an insn that
20262 ;; maps to SIGILL makes it more likely the program will rightfully die.
20263 ;; Keeping with tradition, "6" is in honor of #UD.
20264 (define_insn "trap"
20265 [(trap_if (const_int 1) (const_int 6))]
20266 ""
20267 { return ASM_SHORT "0x0b0f"; }
20268 [(set_attr "length" "2")])
20269
20270 (define_expand "sse_prologue_save"
20271 [(parallel [(set (match_operand:BLK 0 "" "")
20272 (unspec:BLK [(reg:DI 21)
20273 (reg:DI 22)
20274 (reg:DI 23)
20275 (reg:DI 24)
20276 (reg:DI 25)
20277 (reg:DI 26)
20278 (reg:DI 27)
20279 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20280 (use (match_operand:DI 1 "register_operand" ""))
20281 (use (match_operand:DI 2 "immediate_operand" ""))
20282 (use (label_ref:DI (match_operand 3 "" "")))])]
20283 "TARGET_64BIT"
20284 "")
20285
20286 (define_insn "*sse_prologue_save_insn"
20287 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20288 (match_operand:DI 4 "const_int_operand" "n")))
20289 (unspec:BLK [(reg:DI 21)
20290 (reg:DI 22)
20291 (reg:DI 23)
20292 (reg:DI 24)
20293 (reg:DI 25)
20294 (reg:DI 26)
20295 (reg:DI 27)
20296 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20297 (use (match_operand:DI 1 "register_operand" "r"))
20298 (use (match_operand:DI 2 "const_int_operand" "i"))
20299 (use (label_ref:DI (match_operand 3 "" "X")))]
20300 "TARGET_64BIT
20301 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20302 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20303 "*
20304 {
20305 int i;
20306 operands[0] = gen_rtx_MEM (Pmode,
20307 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20308 output_asm_insn (\"jmp\\t%A1\", operands);
20309 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20310 {
20311 operands[4] = adjust_address (operands[0], DImode, i*16);
20312 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20313 PUT_MODE (operands[4], TImode);
20314 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20315 output_asm_insn (\"rex\", operands);
20316 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20317 }
20318 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20319 CODE_LABEL_NUMBER (operands[3]));
20320 return \"\";
20321 }
20322 "
20323 [(set_attr "type" "other")
20324 (set_attr "length_immediate" "0")
20325 (set_attr "length_address" "0")
20326 (set_attr "length" "135")
20327 (set_attr "memory" "store")
20328 (set_attr "modrm" "0")
20329 (set_attr "mode" "DI")])
20330
20331 (define_expand "prefetch"
20332 [(prefetch (match_operand 0 "address_operand" "")
20333 (match_operand:SI 1 "const_int_operand" "")
20334 (match_operand:SI 2 "const_int_operand" ""))]
20335 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20336 {
20337 int rw = INTVAL (operands[1]);
20338 int locality = INTVAL (operands[2]);
20339
20340 gcc_assert (rw == 0 || rw == 1);
20341 gcc_assert (locality >= 0 && locality <= 3);
20342 gcc_assert (GET_MODE (operands[0]) == Pmode
20343 || GET_MODE (operands[0]) == VOIDmode);
20344
20345 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20346 supported by SSE counterpart or the SSE prefetch is not available
20347 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20348 of locality. */
20349 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20350 operands[2] = GEN_INT (3);
20351 else
20352 operands[1] = const0_rtx;
20353 })
20354
20355 (define_insn "*prefetch_sse"
20356 [(prefetch (match_operand:SI 0 "address_operand" "p")
20357 (const_int 0)
20358 (match_operand:SI 1 "const_int_operand" ""))]
20359 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20360 {
20361 static const char * const patterns[4] = {
20362 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20363 };
20364
20365 int locality = INTVAL (operands[1]);
20366 gcc_assert (locality >= 0 && locality <= 3);
20367
20368 return patterns[locality];
20369 }
20370 [(set_attr "type" "sse")
20371 (set_attr "memory" "none")])
20372
20373 (define_insn "*prefetch_sse_rex"
20374 [(prefetch (match_operand:DI 0 "address_operand" "p")
20375 (const_int 0)
20376 (match_operand:SI 1 "const_int_operand" ""))]
20377 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20378 {
20379 static const char * const patterns[4] = {
20380 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20381 };
20382
20383 int locality = INTVAL (operands[1]);
20384 gcc_assert (locality >= 0 && locality <= 3);
20385
20386 return patterns[locality];
20387 }
20388 [(set_attr "type" "sse")
20389 (set_attr "memory" "none")])
20390
20391 (define_insn "*prefetch_3dnow"
20392 [(prefetch (match_operand:SI 0 "address_operand" "p")
20393 (match_operand:SI 1 "const_int_operand" "n")
20394 (const_int 3))]
20395 "TARGET_3DNOW && !TARGET_64BIT"
20396 {
20397 if (INTVAL (operands[1]) == 0)
20398 return "prefetch\t%a0";
20399 else
20400 return "prefetchw\t%a0";
20401 }
20402 [(set_attr "type" "mmx")
20403 (set_attr "memory" "none")])
20404
20405 (define_insn "*prefetch_3dnow_rex"
20406 [(prefetch (match_operand:DI 0 "address_operand" "p")
20407 (match_operand:SI 1 "const_int_operand" "n")
20408 (const_int 3))]
20409 "TARGET_3DNOW && TARGET_64BIT"
20410 {
20411 if (INTVAL (operands[1]) == 0)
20412 return "prefetch\t%a0";
20413 else
20414 return "prefetchw\t%a0";
20415 }
20416 [(set_attr "type" "mmx")
20417 (set_attr "memory" "none")])
20418
20419 (define_expand "stack_protect_set"
20420 [(match_operand 0 "memory_operand" "")
20421 (match_operand 1 "memory_operand" "")]
20422 ""
20423 {
20424 #ifdef TARGET_THREAD_SSP_OFFSET
20425 if (TARGET_64BIT)
20426 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20427 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20428 else
20429 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20430 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20431 #else
20432 if (TARGET_64BIT)
20433 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20434 else
20435 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20436 #endif
20437 DONE;
20438 })
20439
20440 (define_insn "stack_protect_set_si"
20441 [(set (match_operand:SI 0 "memory_operand" "=m")
20442 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20443 (set (match_scratch:SI 2 "=&r") (const_int 0))
20444 (clobber (reg:CC FLAGS_REG))]
20445 ""
20446 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20447 [(set_attr "type" "multi")])
20448
20449 (define_insn "stack_protect_set_di"
20450 [(set (match_operand:DI 0 "memory_operand" "=m")
20451 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20452 (set (match_scratch:DI 2 "=&r") (const_int 0))
20453 (clobber (reg:CC FLAGS_REG))]
20454 "TARGET_64BIT"
20455 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20456 [(set_attr "type" "multi")])
20457
20458 (define_insn "stack_tls_protect_set_si"
20459 [(set (match_operand:SI 0 "memory_operand" "=m")
20460 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20461 (set (match_scratch:SI 2 "=&r") (const_int 0))
20462 (clobber (reg:CC FLAGS_REG))]
20463 ""
20464 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20465 [(set_attr "type" "multi")])
20466
20467 (define_insn "stack_tls_protect_set_di"
20468 [(set (match_operand:DI 0 "memory_operand" "=m")
20469 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20470 (set (match_scratch:DI 2 "=&r") (const_int 0))
20471 (clobber (reg:CC FLAGS_REG))]
20472 "TARGET_64BIT"
20473 {
20474 /* The kernel uses a different segment register for performance reasons; a
20475 system call would not have to trash the userspace segment register,
20476 which would be expensive */
20477 if (ix86_cmodel != CM_KERNEL)
20478 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20479 else
20480 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20481 }
20482 [(set_attr "type" "multi")])
20483
20484 (define_expand "stack_protect_test"
20485 [(match_operand 0 "memory_operand" "")
20486 (match_operand 1 "memory_operand" "")
20487 (match_operand 2 "" "")]
20488 ""
20489 {
20490 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20491 ix86_compare_op0 = operands[0];
20492 ix86_compare_op1 = operands[1];
20493 ix86_compare_emitted = flags;
20494
20495 #ifdef TARGET_THREAD_SSP_OFFSET
20496 if (TARGET_64BIT)
20497 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20498 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20499 else
20500 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20501 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20502 #else
20503 if (TARGET_64BIT)
20504 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20505 else
20506 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20507 #endif
20508 emit_jump_insn (gen_beq (operands[2]));
20509 DONE;
20510 })
20511
20512 (define_insn "stack_protect_test_si"
20513 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20514 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20515 (match_operand:SI 2 "memory_operand" "m")]
20516 UNSPEC_SP_TEST))
20517 (clobber (match_scratch:SI 3 "=&r"))]
20518 ""
20519 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20520 [(set_attr "type" "multi")])
20521
20522 (define_insn "stack_protect_test_di"
20523 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20524 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20525 (match_operand:DI 2 "memory_operand" "m")]
20526 UNSPEC_SP_TEST))
20527 (clobber (match_scratch:DI 3 "=&r"))]
20528 "TARGET_64BIT"
20529 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20530 [(set_attr "type" "multi")])
20531
20532 (define_insn "stack_tls_protect_test_si"
20533 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20534 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20535 (match_operand:SI 2 "const_int_operand" "i")]
20536 UNSPEC_SP_TLS_TEST))
20537 (clobber (match_scratch:SI 3 "=r"))]
20538 ""
20539 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20540 [(set_attr "type" "multi")])
20541
20542 (define_insn "stack_tls_protect_test_di"
20543 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20544 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20545 (match_operand:DI 2 "const_int_operand" "i")]
20546 UNSPEC_SP_TLS_TEST))
20547 (clobber (match_scratch:DI 3 "=r"))]
20548 "TARGET_64BIT"
20549 {
20550 /* The kernel uses a different segment register for performance reasons; a
20551 system call would not have to trash the userspace segment register,
20552 which would be expensive */
20553 if (ix86_cmodel != CM_KERNEL)
20554 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20555 else
20556 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20557 }
20558 [(set_attr "type" "multi")])
20559
20560 (include "mmx.md")
20561 (include "sse.md")
20562 (include "sync.md")