invoke.texi (generic): Document (i686) Update.
[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
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
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 30)
91 (UNSPEC_MASKMOV 31)
92 (UNSPEC_MOVMSK 32)
93 (UNSPEC_MOVNT 33)
94 (UNSPEC_MOVU 34)
95 (UNSPEC_RCP 35)
96 (UNSPEC_RSQRT 36)
97 (UNSPEC_SFENCE 37)
98 (UNSPEC_NOP 38) ; prevents combiner cleverness
99 (UNSPEC_PFRCP 39)
100 (UNSPEC_PFRCPIT1 40)
101 (UNSPEC_PFRCPIT2 41)
102 (UNSPEC_PFRSQRT 42)
103 (UNSPEC_PFRSQIT1 43)
104 (UNSPEC_MFENCE 44)
105 (UNSPEC_LFENCE 45)
106 (UNSPEC_PSADBW 46)
107 (UNSPEC_LDQQU 47)
108
109 ; Generic math support
110 (UNSPEC_COPYSIGN 50)
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
113
114 ; x87 Floating point
115 (UNSPEC_SIN 60)
116 (UNSPEC_COS 61)
117 (UNSPEC_FPATAN 62)
118 (UNSPEC_FYL2X 63)
119 (UNSPEC_FYL2XP1 64)
120 (UNSPEC_FRNDINT 65)
121 (UNSPEC_FIST 66)
122 (UNSPEC_F2XM1 67)
123
124 ; x87 Rounding
125 (UNSPEC_FRNDINT_FLOOR 70)
126 (UNSPEC_FRNDINT_CEIL 71)
127 (UNSPEC_FRNDINT_TRUNC 72)
128 (UNSPEC_FRNDINT_MASK_PM 73)
129 (UNSPEC_FIST_FLOOR 74)
130 (UNSPEC_FIST_CEIL 75)
131
132 ; x87 Double output FP
133 (UNSPEC_SINCOS_COS 80)
134 (UNSPEC_SINCOS_SIN 81)
135 (UNSPEC_TAN_ONE 82)
136 (UNSPEC_TAN_TAN 83)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
141 (UNSPEC_FPREM_F 88)
142 (UNSPEC_FPREM_U 89)
143 (UNSPEC_FPREM1_F 90)
144 (UNSPEC_FPREM1_U 91)
145
146 ; SSP patterns
147 (UNSPEC_SP_SET 100)
148 (UNSPEC_SP_TEST 101)
149 (UNSPEC_SP_TLS_SET 102)
150 (UNSPEC_SP_TLS_TEST 103)
151 ])
152
153 (define_constants
154 [(UNSPECV_BLOCKAGE 0)
155 (UNSPECV_STACK_PROBE 1)
156 (UNSPECV_EMMS 2)
157 (UNSPECV_LDMXCSR 3)
158 (UNSPECV_STMXCSR 4)
159 (UNSPECV_FEMMS 5)
160 (UNSPECV_CLFLUSH 6)
161 (UNSPECV_ALIGN 7)
162 (UNSPECV_MONITOR 8)
163 (UNSPECV_MWAIT 9)
164 (UNSPECV_CMPXCHG_1 10)
165 (UNSPECV_CMPXCHG_2 11)
166 (UNSPECV_XCHG 12)
167 (UNSPECV_LOCK 13)
168 ])
169
170 ;; Registers by name.
171 (define_constants
172 [(BP_REG 6)
173 (SP_REG 7)
174 (FLAGS_REG 17)
175 (FPSR_REG 18)
176 (DIRFLAG_REG 19)
177 ])
178
179 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
180 ;; from i386.c.
181
182 ;; In C guard expressions, put expressions which may be compile-time
183 ;; constants first. This allows for better optimization. For
184 ;; example, write "TARGET_64BIT && reload_completed", not
185 ;; "reload_completed && TARGET_64BIT".
186
187 \f
188 ;; Processor type. This attribute must exactly match the processor_type
189 ;; enumeration in i386.h.
190 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64"
191 (const (symbol_ref "ix86_tune")))
192
193 ;; A basic instruction type. Refinements due to arguments to be
194 ;; provided in other attributes.
195 (define_attr "type"
196 "other,multi,
197 alu,alu1,negnot,imov,imovx,lea,
198 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
199 icmp,test,ibr,setcc,icmov,
200 push,pop,call,callv,leave,
201 str,cld,
202 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
203 sselog,sselog1,sseiadd,sseishft,sseimul,
204 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
205 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
206 (const_string "other"))
207
208 ;; Main data type used by the insn
209 (define_attr "mode"
210 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
211 (const_string "unknown"))
212
213 ;; The CPU unit operations uses.
214 (define_attr "unit" "integer,i387,sse,mmx,unknown"
215 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
216 (const_string "i387")
217 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
218 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
219 (const_string "sse")
220 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
221 (const_string "mmx")
222 (eq_attr "type" "other")
223 (const_string "unknown")]
224 (const_string "integer")))
225
226 ;; The (bounding maximum) length of an instruction immediate.
227 (define_attr "length_immediate" ""
228 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
229 (const_int 0)
230 (eq_attr "unit" "i387,sse,mmx")
231 (const_int 0)
232 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
233 imul,icmp,push,pop")
234 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
235 (eq_attr "type" "imov,test")
236 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
237 (eq_attr "type" "call")
238 (if_then_else (match_operand 0 "constant_call_address_operand" "")
239 (const_int 4)
240 (const_int 0))
241 (eq_attr "type" "callv")
242 (if_then_else (match_operand 1 "constant_call_address_operand" "")
243 (const_int 4)
244 (const_int 0))
245 ;; We don't know the size before shorten_branches. Expect
246 ;; the instruction to fit for better scheduling.
247 (eq_attr "type" "ibr")
248 (const_int 1)
249 ]
250 (symbol_ref "/* Update immediate_length and other attributes! */
251 gcc_unreachable (),1")))
252
253 ;; The (bounding maximum) length of an instruction address.
254 (define_attr "length_address" ""
255 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
256 (const_int 0)
257 (and (eq_attr "type" "call")
258 (match_operand 0 "constant_call_address_operand" ""))
259 (const_int 0)
260 (and (eq_attr "type" "callv")
261 (match_operand 1 "constant_call_address_operand" ""))
262 (const_int 0)
263 ]
264 (symbol_ref "ix86_attr_length_address_default (insn)")))
265
266 ;; Set when length prefix is used.
267 (define_attr "prefix_data16" ""
268 (if_then_else (ior (eq_attr "mode" "HI")
269 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
270 (const_int 1)
271 (const_int 0)))
272
273 ;; Set when string REP prefix is used.
274 (define_attr "prefix_rep" ""
275 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
276 (const_int 1)
277 (const_int 0)))
278
279 ;; Set when 0f opcode prefix is used.
280 (define_attr "prefix_0f" ""
281 (if_then_else
282 (ior (eq_attr "type" "imovx,setcc,icmov")
283 (eq_attr "unit" "sse,mmx"))
284 (const_int 1)
285 (const_int 0)))
286
287 ;; Set when REX opcode prefix is used.
288 (define_attr "prefix_rex" ""
289 (cond [(and (eq_attr "mode" "DI")
290 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
291 (const_int 1)
292 (and (eq_attr "mode" "QI")
293 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
294 (const_int 0)))
295 (const_int 1)
296 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
297 (const_int 0))
298 (const_int 1)
299 ]
300 (const_int 0)))
301
302 ;; Set when modrm byte is used.
303 (define_attr "modrm" ""
304 (cond [(eq_attr "type" "str,cld,leave")
305 (const_int 0)
306 (eq_attr "unit" "i387")
307 (const_int 0)
308 (and (eq_attr "type" "incdec")
309 (ior (match_operand:SI 1 "register_operand" "")
310 (match_operand:HI 1 "register_operand" "")))
311 (const_int 0)
312 (and (eq_attr "type" "push")
313 (not (match_operand 1 "memory_operand" "")))
314 (const_int 0)
315 (and (eq_attr "type" "pop")
316 (not (match_operand 0 "memory_operand" "")))
317 (const_int 0)
318 (and (eq_attr "type" "imov")
319 (ior (and (match_operand 0 "register_operand" "")
320 (match_operand 1 "immediate_operand" ""))
321 (ior (and (match_operand 0 "ax_reg_operand" "")
322 (match_operand 1 "memory_displacement_only_operand" ""))
323 (and (match_operand 0 "memory_displacement_only_operand" "")
324 (match_operand 1 "ax_reg_operand" "")))))
325 (const_int 0)
326 (and (eq_attr "type" "call")
327 (match_operand 0 "constant_call_address_operand" ""))
328 (const_int 0)
329 (and (eq_attr "type" "callv")
330 (match_operand 1 "constant_call_address_operand" ""))
331 (const_int 0)
332 ]
333 (const_int 1)))
334
335 ;; The (bounding maximum) length of an instruction in bytes.
336 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
337 ;; Later we may want to split them and compute proper length as for
338 ;; other insns.
339 (define_attr "length" ""
340 (cond [(eq_attr "type" "other,multi,fistp,frndint")
341 (const_int 16)
342 (eq_attr "type" "fcmp")
343 (const_int 4)
344 (eq_attr "unit" "i387")
345 (plus (const_int 2)
346 (plus (attr "prefix_data16")
347 (attr "length_address")))]
348 (plus (plus (attr "modrm")
349 (plus (attr "prefix_0f")
350 (plus (attr "prefix_rex")
351 (const_int 1))))
352 (plus (attr "prefix_rep")
353 (plus (attr "prefix_data16")
354 (plus (attr "length_immediate")
355 (attr "length_address")))))))
356
357 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
358 ;; `store' if there is a simple memory reference therein, or `unknown'
359 ;; if the instruction is complex.
360
361 (define_attr "memory" "none,load,store,both,unknown"
362 (cond [(eq_attr "type" "other,multi,str")
363 (const_string "unknown")
364 (eq_attr "type" "lea,fcmov,fpspc,cld")
365 (const_string "none")
366 (eq_attr "type" "fistp,leave")
367 (const_string "both")
368 (eq_attr "type" "frndint")
369 (const_string "load")
370 (eq_attr "type" "push")
371 (if_then_else (match_operand 1 "memory_operand" "")
372 (const_string "both")
373 (const_string "store"))
374 (eq_attr "type" "pop")
375 (if_then_else (match_operand 0 "memory_operand" "")
376 (const_string "both")
377 (const_string "load"))
378 (eq_attr "type" "setcc")
379 (if_then_else (match_operand 0 "memory_operand" "")
380 (const_string "store")
381 (const_string "none"))
382 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
383 (if_then_else (ior (match_operand 0 "memory_operand" "")
384 (match_operand 1 "memory_operand" ""))
385 (const_string "load")
386 (const_string "none"))
387 (eq_attr "type" "ibr")
388 (if_then_else (match_operand 0 "memory_operand" "")
389 (const_string "load")
390 (const_string "none"))
391 (eq_attr "type" "call")
392 (if_then_else (match_operand 0 "constant_call_address_operand" "")
393 (const_string "none")
394 (const_string "load"))
395 (eq_attr "type" "callv")
396 (if_then_else (match_operand 1 "constant_call_address_operand" "")
397 (const_string "none")
398 (const_string "load"))
399 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
400 (match_operand 1 "memory_operand" ""))
401 (const_string "both")
402 (and (match_operand 0 "memory_operand" "")
403 (match_operand 1 "memory_operand" ""))
404 (const_string "both")
405 (match_operand 0 "memory_operand" "")
406 (const_string "store")
407 (match_operand 1 "memory_operand" "")
408 (const_string "load")
409 (and (eq_attr "type"
410 "!alu1,negnot,ishift1,
411 imov,imovx,icmp,test,
412 fmov,fcmp,fsgn,
413 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
414 mmx,mmxmov,mmxcmp,mmxcvt")
415 (match_operand 2 "memory_operand" ""))
416 (const_string "load")
417 (and (eq_attr "type" "icmov")
418 (match_operand 3 "memory_operand" ""))
419 (const_string "load")
420 ]
421 (const_string "none")))
422
423 ;; Indicates if an instruction has both an immediate and a displacement.
424
425 (define_attr "imm_disp" "false,true,unknown"
426 (cond [(eq_attr "type" "other,multi")
427 (const_string "unknown")
428 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
429 (and (match_operand 0 "memory_displacement_operand" "")
430 (match_operand 1 "immediate_operand" "")))
431 (const_string "true")
432 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
433 (and (match_operand 0 "memory_displacement_operand" "")
434 (match_operand 2 "immediate_operand" "")))
435 (const_string "true")
436 ]
437 (const_string "false")))
438
439 ;; Indicates if an FP operation has an integer source.
440
441 (define_attr "fp_int_src" "false,true"
442 (const_string "false"))
443
444 ;; Defines rounding mode of an FP operation.
445
446 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
447 (const_string "any"))
448
449 ;; Describe a user's asm statement.
450 (define_asm_attributes
451 [(set_attr "length" "128")
452 (set_attr "type" "multi")])
453
454 ;; All x87 floating point modes
455 (define_mode_macro X87MODEF [SF DF XF])
456
457 ;; All integer modes handled by x87 fisttp operator.
458 (define_mode_macro X87MODEI [HI SI DI])
459
460 ;; All integer modes handled by integer x87 operators.
461 (define_mode_macro X87MODEI12 [HI SI])
462
463 ;; All SSE floating point modes
464 (define_mode_macro SSEMODEF [SF DF])
465
466 ;; All integer modes handled by SSE cvtts?2si* operators.
467 (define_mode_macro SSEMODEI24 [SI DI])
468
469 \f
470 ;; Scheduling descriptions
471
472 (include "pentium.md")
473 (include "ppro.md")
474 (include "k6.md")
475 (include "athlon.md")
476
477 \f
478 ;; Operand and operator predicates
479
480 (include "predicates.md")
481
482 \f
483 ;; Compare instructions.
484
485 ;; All compare insns have expanders that save the operands away without
486 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
487 ;; after the cmp) will actually emit the cmpM.
488
489 (define_expand "cmpti"
490 [(set (reg:CC FLAGS_REG)
491 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
492 (match_operand:TI 1 "x86_64_general_operand" "")))]
493 "TARGET_64BIT"
494 {
495 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
496 operands[0] = force_reg (TImode, operands[0]);
497 ix86_compare_op0 = operands[0];
498 ix86_compare_op1 = operands[1];
499 DONE;
500 })
501
502 (define_expand "cmpdi"
503 [(set (reg:CC FLAGS_REG)
504 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
505 (match_operand:DI 1 "x86_64_general_operand" "")))]
506 ""
507 {
508 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
509 operands[0] = force_reg (DImode, operands[0]);
510 ix86_compare_op0 = operands[0];
511 ix86_compare_op1 = operands[1];
512 DONE;
513 })
514
515 (define_expand "cmpsi"
516 [(set (reg:CC FLAGS_REG)
517 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
518 (match_operand:SI 1 "general_operand" "")))]
519 ""
520 {
521 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
522 operands[0] = force_reg (SImode, operands[0]);
523 ix86_compare_op0 = operands[0];
524 ix86_compare_op1 = operands[1];
525 DONE;
526 })
527
528 (define_expand "cmphi"
529 [(set (reg:CC FLAGS_REG)
530 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
531 (match_operand:HI 1 "general_operand" "")))]
532 ""
533 {
534 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
535 operands[0] = force_reg (HImode, operands[0]);
536 ix86_compare_op0 = operands[0];
537 ix86_compare_op1 = operands[1];
538 DONE;
539 })
540
541 (define_expand "cmpqi"
542 [(set (reg:CC FLAGS_REG)
543 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
544 (match_operand:QI 1 "general_operand" "")))]
545 "TARGET_QIMODE_MATH"
546 {
547 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
548 operands[0] = force_reg (QImode, operands[0]);
549 ix86_compare_op0 = operands[0];
550 ix86_compare_op1 = operands[1];
551 DONE;
552 })
553
554 (define_insn "cmpdi_ccno_1_rex64"
555 [(set (reg FLAGS_REG)
556 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
557 (match_operand:DI 1 "const0_operand" "n,n")))]
558 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
559 "@
560 test{q}\t{%0, %0|%0, %0}
561 cmp{q}\t{%1, %0|%0, %1}"
562 [(set_attr "type" "test,icmp")
563 (set_attr "length_immediate" "0,1")
564 (set_attr "mode" "DI")])
565
566 (define_insn "*cmpdi_minus_1_rex64"
567 [(set (reg FLAGS_REG)
568 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
569 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
570 (const_int 0)))]
571 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
572 "cmp{q}\t{%1, %0|%0, %1}"
573 [(set_attr "type" "icmp")
574 (set_attr "mode" "DI")])
575
576 (define_expand "cmpdi_1_rex64"
577 [(set (reg:CC FLAGS_REG)
578 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
579 (match_operand:DI 1 "general_operand" "")))]
580 "TARGET_64BIT"
581 "")
582
583 (define_insn "cmpdi_1_insn_rex64"
584 [(set (reg FLAGS_REG)
585 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
586 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
587 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
588 "cmp{q}\t{%1, %0|%0, %1}"
589 [(set_attr "type" "icmp")
590 (set_attr "mode" "DI")])
591
592
593 (define_insn "*cmpsi_ccno_1"
594 [(set (reg FLAGS_REG)
595 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
596 (match_operand:SI 1 "const0_operand" "n,n")))]
597 "ix86_match_ccmode (insn, CCNOmode)"
598 "@
599 test{l}\t{%0, %0|%0, %0}
600 cmp{l}\t{%1, %0|%0, %1}"
601 [(set_attr "type" "test,icmp")
602 (set_attr "length_immediate" "0,1")
603 (set_attr "mode" "SI")])
604
605 (define_insn "*cmpsi_minus_1"
606 [(set (reg FLAGS_REG)
607 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
608 (match_operand:SI 1 "general_operand" "ri,mr"))
609 (const_int 0)))]
610 "ix86_match_ccmode (insn, CCGOCmode)"
611 "cmp{l}\t{%1, %0|%0, %1}"
612 [(set_attr "type" "icmp")
613 (set_attr "mode" "SI")])
614
615 (define_expand "cmpsi_1"
616 [(set (reg:CC FLAGS_REG)
617 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
618 (match_operand:SI 1 "general_operand" "ri,mr")))]
619 ""
620 "")
621
622 (define_insn "*cmpsi_1_insn"
623 [(set (reg FLAGS_REG)
624 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625 (match_operand:SI 1 "general_operand" "ri,mr")))]
626 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
627 && ix86_match_ccmode (insn, CCmode)"
628 "cmp{l}\t{%1, %0|%0, %1}"
629 [(set_attr "type" "icmp")
630 (set_attr "mode" "SI")])
631
632 (define_insn "*cmphi_ccno_1"
633 [(set (reg FLAGS_REG)
634 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
635 (match_operand:HI 1 "const0_operand" "n,n")))]
636 "ix86_match_ccmode (insn, CCNOmode)"
637 "@
638 test{w}\t{%0, %0|%0, %0}
639 cmp{w}\t{%1, %0|%0, %1}"
640 [(set_attr "type" "test,icmp")
641 (set_attr "length_immediate" "0,1")
642 (set_attr "mode" "HI")])
643
644 (define_insn "*cmphi_minus_1"
645 [(set (reg FLAGS_REG)
646 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
647 (match_operand:HI 1 "general_operand" "ri,mr"))
648 (const_int 0)))]
649 "ix86_match_ccmode (insn, CCGOCmode)"
650 "cmp{w}\t{%1, %0|%0, %1}"
651 [(set_attr "type" "icmp")
652 (set_attr "mode" "HI")])
653
654 (define_insn "*cmphi_1"
655 [(set (reg FLAGS_REG)
656 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
657 (match_operand:HI 1 "general_operand" "ri,mr")))]
658 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
659 && ix86_match_ccmode (insn, CCmode)"
660 "cmp{w}\t{%1, %0|%0, %1}"
661 [(set_attr "type" "icmp")
662 (set_attr "mode" "HI")])
663
664 (define_insn "*cmpqi_ccno_1"
665 [(set (reg FLAGS_REG)
666 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
667 (match_operand:QI 1 "const0_operand" "n,n")))]
668 "ix86_match_ccmode (insn, CCNOmode)"
669 "@
670 test{b}\t{%0, %0|%0, %0}
671 cmp{b}\t{$0, %0|%0, 0}"
672 [(set_attr "type" "test,icmp")
673 (set_attr "length_immediate" "0,1")
674 (set_attr "mode" "QI")])
675
676 (define_insn "*cmpqi_1"
677 [(set (reg FLAGS_REG)
678 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
679 (match_operand:QI 1 "general_operand" "qi,mq")))]
680 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
681 && ix86_match_ccmode (insn, CCmode)"
682 "cmp{b}\t{%1, %0|%0, %1}"
683 [(set_attr "type" "icmp")
684 (set_attr "mode" "QI")])
685
686 (define_insn "*cmpqi_minus_1"
687 [(set (reg FLAGS_REG)
688 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
689 (match_operand:QI 1 "general_operand" "qi,mq"))
690 (const_int 0)))]
691 "ix86_match_ccmode (insn, CCGOCmode)"
692 "cmp{b}\t{%1, %0|%0, %1}"
693 [(set_attr "type" "icmp")
694 (set_attr "mode" "QI")])
695
696 (define_insn "*cmpqi_ext_1"
697 [(set (reg FLAGS_REG)
698 (compare
699 (match_operand:QI 0 "general_operand" "Qm")
700 (subreg:QI
701 (zero_extract:SI
702 (match_operand 1 "ext_register_operand" "Q")
703 (const_int 8)
704 (const_int 8)) 0)))]
705 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
706 "cmp{b}\t{%h1, %0|%0, %h1}"
707 [(set_attr "type" "icmp")
708 (set_attr "mode" "QI")])
709
710 (define_insn "*cmpqi_ext_1_rex64"
711 [(set (reg FLAGS_REG)
712 (compare
713 (match_operand:QI 0 "register_operand" "Q")
714 (subreg:QI
715 (zero_extract:SI
716 (match_operand 1 "ext_register_operand" "Q")
717 (const_int 8)
718 (const_int 8)) 0)))]
719 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720 "cmp{b}\t{%h1, %0|%0, %h1}"
721 [(set_attr "type" "icmp")
722 (set_attr "mode" "QI")])
723
724 (define_insn "*cmpqi_ext_2"
725 [(set (reg FLAGS_REG)
726 (compare
727 (subreg:QI
728 (zero_extract:SI
729 (match_operand 0 "ext_register_operand" "Q")
730 (const_int 8)
731 (const_int 8)) 0)
732 (match_operand:QI 1 "const0_operand" "n")))]
733 "ix86_match_ccmode (insn, CCNOmode)"
734 "test{b}\t%h0, %h0"
735 [(set_attr "type" "test")
736 (set_attr "length_immediate" "0")
737 (set_attr "mode" "QI")])
738
739 (define_expand "cmpqi_ext_3"
740 [(set (reg:CC FLAGS_REG)
741 (compare:CC
742 (subreg:QI
743 (zero_extract:SI
744 (match_operand 0 "ext_register_operand" "")
745 (const_int 8)
746 (const_int 8)) 0)
747 (match_operand:QI 1 "general_operand" "")))]
748 ""
749 "")
750
751 (define_insn "cmpqi_ext_3_insn"
752 [(set (reg FLAGS_REG)
753 (compare
754 (subreg:QI
755 (zero_extract:SI
756 (match_operand 0 "ext_register_operand" "Q")
757 (const_int 8)
758 (const_int 8)) 0)
759 (match_operand:QI 1 "general_operand" "Qmn")))]
760 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
761 "cmp{b}\t{%1, %h0|%h0, %1}"
762 [(set_attr "type" "icmp")
763 (set_attr "mode" "QI")])
764
765 (define_insn "cmpqi_ext_3_insn_rex64"
766 [(set (reg FLAGS_REG)
767 (compare
768 (subreg:QI
769 (zero_extract:SI
770 (match_operand 0 "ext_register_operand" "Q")
771 (const_int 8)
772 (const_int 8)) 0)
773 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
774 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
775 "cmp{b}\t{%1, %h0|%h0, %1}"
776 [(set_attr "type" "icmp")
777 (set_attr "mode" "QI")])
778
779 (define_insn "*cmpqi_ext_4"
780 [(set (reg FLAGS_REG)
781 (compare
782 (subreg:QI
783 (zero_extract:SI
784 (match_operand 0 "ext_register_operand" "Q")
785 (const_int 8)
786 (const_int 8)) 0)
787 (subreg:QI
788 (zero_extract:SI
789 (match_operand 1 "ext_register_operand" "Q")
790 (const_int 8)
791 (const_int 8)) 0)))]
792 "ix86_match_ccmode (insn, CCmode)"
793 "cmp{b}\t{%h1, %h0|%h0, %h1}"
794 [(set_attr "type" "icmp")
795 (set_attr "mode" "QI")])
796
797 ;; These implement float point compares.
798 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
799 ;; which would allow mix and match FP modes on the compares. Which is what
800 ;; the old patterns did, but with many more of them.
801
802 (define_expand "cmpxf"
803 [(set (reg:CC FLAGS_REG)
804 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
805 (match_operand:XF 1 "nonmemory_operand" "")))]
806 "TARGET_80387"
807 {
808 ix86_compare_op0 = operands[0];
809 ix86_compare_op1 = operands[1];
810 DONE;
811 })
812
813 (define_expand "cmpdf"
814 [(set (reg:CC FLAGS_REG)
815 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
816 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
817 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
818 {
819 ix86_compare_op0 = operands[0];
820 ix86_compare_op1 = operands[1];
821 DONE;
822 })
823
824 (define_expand "cmpsf"
825 [(set (reg:CC FLAGS_REG)
826 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
827 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
828 "TARGET_80387 || TARGET_SSE_MATH"
829 {
830 ix86_compare_op0 = operands[0];
831 ix86_compare_op1 = operands[1];
832 DONE;
833 })
834
835 ;; FP compares, step 1:
836 ;; Set the FP condition codes.
837 ;;
838 ;; CCFPmode compare with exceptions
839 ;; CCFPUmode compare with no exceptions
840
841 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
842 ;; used to manage the reg stack popping would not be preserved.
843
844 (define_insn "*cmpfp_0"
845 [(set (match_operand:HI 0 "register_operand" "=a")
846 (unspec:HI
847 [(compare:CCFP
848 (match_operand 1 "register_operand" "f")
849 (match_operand 2 "const0_operand" "X"))]
850 UNSPEC_FNSTSW))]
851 "TARGET_80387
852 && FLOAT_MODE_P (GET_MODE (operands[1]))
853 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
854 "* return output_fp_compare (insn, operands, 0, 0);"
855 [(set_attr "type" "multi")
856 (set_attr "unit" "i387")
857 (set (attr "mode")
858 (cond [(match_operand:SF 1 "" "")
859 (const_string "SF")
860 (match_operand:DF 1 "" "")
861 (const_string "DF")
862 ]
863 (const_string "XF")))])
864
865 (define_insn "*cmpfp_sf"
866 [(set (match_operand:HI 0 "register_operand" "=a")
867 (unspec:HI
868 [(compare:CCFP
869 (match_operand:SF 1 "register_operand" "f")
870 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
871 UNSPEC_FNSTSW))]
872 "TARGET_80387"
873 "* return output_fp_compare (insn, operands, 0, 0);"
874 [(set_attr "type" "multi")
875 (set_attr "unit" "i387")
876 (set_attr "mode" "SF")])
877
878 (define_insn "*cmpfp_df"
879 [(set (match_operand:HI 0 "register_operand" "=a")
880 (unspec:HI
881 [(compare:CCFP
882 (match_operand:DF 1 "register_operand" "f")
883 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
884 UNSPEC_FNSTSW))]
885 "TARGET_80387"
886 "* return output_fp_compare (insn, operands, 0, 0);"
887 [(set_attr "type" "multi")
888 (set_attr "unit" "i387")
889 (set_attr "mode" "DF")])
890
891 (define_insn "*cmpfp_xf"
892 [(set (match_operand:HI 0 "register_operand" "=a")
893 (unspec:HI
894 [(compare:CCFP
895 (match_operand:XF 1 "register_operand" "f")
896 (match_operand:XF 2 "register_operand" "f"))]
897 UNSPEC_FNSTSW))]
898 "TARGET_80387"
899 "* return output_fp_compare (insn, operands, 0, 0);"
900 [(set_attr "type" "multi")
901 (set_attr "unit" "i387")
902 (set_attr "mode" "XF")])
903
904 (define_insn "*cmpfp_u"
905 [(set (match_operand:HI 0 "register_operand" "=a")
906 (unspec:HI
907 [(compare:CCFPU
908 (match_operand 1 "register_operand" "f")
909 (match_operand 2 "register_operand" "f"))]
910 UNSPEC_FNSTSW))]
911 "TARGET_80387
912 && FLOAT_MODE_P (GET_MODE (operands[1]))
913 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
914 "* return output_fp_compare (insn, operands, 0, 1);"
915 [(set_attr "type" "multi")
916 (set_attr "unit" "i387")
917 (set (attr "mode")
918 (cond [(match_operand:SF 1 "" "")
919 (const_string "SF")
920 (match_operand:DF 1 "" "")
921 (const_string "DF")
922 ]
923 (const_string "XF")))])
924
925 (define_insn "*cmpfp_<mode>"
926 [(set (match_operand:HI 0 "register_operand" "=a")
927 (unspec:HI
928 [(compare:CCFP
929 (match_operand 1 "register_operand" "f")
930 (match_operator 3 "float_operator"
931 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
932 UNSPEC_FNSTSW))]
933 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
934 && FLOAT_MODE_P (GET_MODE (operands[1]))
935 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
936 "* return output_fp_compare (insn, operands, 0, 0);"
937 [(set_attr "type" "multi")
938 (set_attr "unit" "i387")
939 (set_attr "fp_int_src" "true")
940 (set_attr "mode" "<MODE>")])
941
942 ;; FP compares, step 2
943 ;; Move the fpsw to ax.
944
945 (define_insn "x86_fnstsw_1"
946 [(set (match_operand:HI 0 "register_operand" "=a")
947 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
948 "TARGET_80387"
949 "fnstsw\t%0"
950 [(set_attr "length" "2")
951 (set_attr "mode" "SI")
952 (set_attr "unit" "i387")])
953
954 ;; FP compares, step 3
955 ;; Get ax into flags, general case.
956
957 (define_insn "x86_sahf_1"
958 [(set (reg:CC FLAGS_REG)
959 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
960 "!TARGET_64BIT"
961 "sahf"
962 [(set_attr "length" "1")
963 (set_attr "athlon_decode" "vector")
964 (set_attr "mode" "SI")])
965
966 ;; Pentium Pro can do steps 1 through 3 in one go.
967
968 (define_insn "*cmpfp_i_mixed"
969 [(set (reg:CCFP FLAGS_REG)
970 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
971 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
972 "TARGET_MIX_SSE_I387
973 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
974 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
975 "* return output_fp_compare (insn, operands, 1, 0);"
976 [(set_attr "type" "fcmp,ssecomi")
977 (set (attr "mode")
978 (if_then_else (match_operand:SF 1 "" "")
979 (const_string "SF")
980 (const_string "DF")))
981 (set_attr "athlon_decode" "vector")])
982
983 (define_insn "*cmpfp_i_sse"
984 [(set (reg:CCFP FLAGS_REG)
985 (compare:CCFP (match_operand 0 "register_operand" "x")
986 (match_operand 1 "nonimmediate_operand" "xm")))]
987 "TARGET_SSE_MATH
988 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
990 "* return output_fp_compare (insn, operands, 1, 0);"
991 [(set_attr "type" "ssecomi")
992 (set (attr "mode")
993 (if_then_else (match_operand:SF 1 "" "")
994 (const_string "SF")
995 (const_string "DF")))
996 (set_attr "athlon_decode" "vector")])
997
998 (define_insn "*cmpfp_i_i387"
999 [(set (reg:CCFP FLAGS_REG)
1000 (compare:CCFP (match_operand 0 "register_operand" "f")
1001 (match_operand 1 "register_operand" "f")))]
1002 "TARGET_80387 && TARGET_CMOVE
1003 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1004 && FLOAT_MODE_P (GET_MODE (operands[0]))
1005 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006 "* return output_fp_compare (insn, operands, 1, 0);"
1007 [(set_attr "type" "fcmp")
1008 (set (attr "mode")
1009 (cond [(match_operand:SF 1 "" "")
1010 (const_string "SF")
1011 (match_operand:DF 1 "" "")
1012 (const_string "DF")
1013 ]
1014 (const_string "XF")))
1015 (set_attr "athlon_decode" "vector")])
1016
1017 (define_insn "*cmpfp_iu_mixed"
1018 [(set (reg:CCFPU FLAGS_REG)
1019 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1020 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1021 "TARGET_MIX_SSE_I387
1022 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1023 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1024 "* return output_fp_compare (insn, operands, 1, 1);"
1025 [(set_attr "type" "fcmp,ssecomi")
1026 (set (attr "mode")
1027 (if_then_else (match_operand:SF 1 "" "")
1028 (const_string "SF")
1029 (const_string "DF")))
1030 (set_attr "athlon_decode" "vector")])
1031
1032 (define_insn "*cmpfp_iu_sse"
1033 [(set (reg:CCFPU FLAGS_REG)
1034 (compare:CCFPU (match_operand 0 "register_operand" "x")
1035 (match_operand 1 "nonimmediate_operand" "xm")))]
1036 "TARGET_SSE_MATH
1037 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039 "* return output_fp_compare (insn, operands, 1, 1);"
1040 [(set_attr "type" "ssecomi")
1041 (set (attr "mode")
1042 (if_then_else (match_operand:SF 1 "" "")
1043 (const_string "SF")
1044 (const_string "DF")))
1045 (set_attr "athlon_decode" "vector")])
1046
1047 (define_insn "*cmpfp_iu_387"
1048 [(set (reg:CCFPU FLAGS_REG)
1049 (compare:CCFPU (match_operand 0 "register_operand" "f")
1050 (match_operand 1 "register_operand" "f")))]
1051 "TARGET_80387 && TARGET_CMOVE
1052 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1053 && 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" "fcmp")
1057 (set (attr "mode")
1058 (cond [(match_operand:SF 1 "" "")
1059 (const_string "SF")
1060 (match_operand:DF 1 "" "")
1061 (const_string "DF")
1062 ]
1063 (const_string "XF")))
1064 (set_attr "athlon_decode" "vector")])
1065 \f
1066 ;; Move instructions.
1067
1068 ;; General case of fullword move.
1069
1070 (define_expand "movsi"
1071 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1072 (match_operand:SI 1 "general_operand" ""))]
1073 ""
1074 "ix86_expand_move (SImode, operands); DONE;")
1075
1076 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1077 ;; general_operand.
1078 ;;
1079 ;; %%% We don't use a post-inc memory reference because x86 is not a
1080 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1081 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1082 ;; targets without our curiosities, and it is just as easy to represent
1083 ;; this differently.
1084
1085 (define_insn "*pushsi2"
1086 [(set (match_operand:SI 0 "push_operand" "=<")
1087 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1088 "!TARGET_64BIT"
1089 "push{l}\t%1"
1090 [(set_attr "type" "push")
1091 (set_attr "mode" "SI")])
1092
1093 ;; For 64BIT abi we always round up to 8 bytes.
1094 (define_insn "*pushsi2_rex64"
1095 [(set (match_operand:SI 0 "push_operand" "=X")
1096 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1097 "TARGET_64BIT"
1098 "push{q}\t%q1"
1099 [(set_attr "type" "push")
1100 (set_attr "mode" "SI")])
1101
1102 (define_insn "*pushsi2_prologue"
1103 [(set (match_operand:SI 0 "push_operand" "=<")
1104 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1105 (clobber (mem:BLK (scratch)))]
1106 "!TARGET_64BIT"
1107 "push{l}\t%1"
1108 [(set_attr "type" "push")
1109 (set_attr "mode" "SI")])
1110
1111 (define_insn "*popsi1_epilogue"
1112 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1113 (mem:SI (reg:SI SP_REG)))
1114 (set (reg:SI SP_REG)
1115 (plus:SI (reg:SI SP_REG) (const_int 4)))
1116 (clobber (mem:BLK (scratch)))]
1117 "!TARGET_64BIT"
1118 "pop{l}\t%0"
1119 [(set_attr "type" "pop")
1120 (set_attr "mode" "SI")])
1121
1122 (define_insn "popsi1"
1123 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1124 (mem:SI (reg:SI SP_REG)))
1125 (set (reg:SI SP_REG)
1126 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1127 "!TARGET_64BIT"
1128 "pop{l}\t%0"
1129 [(set_attr "type" "pop")
1130 (set_attr "mode" "SI")])
1131
1132 (define_insn "*movsi_xor"
1133 [(set (match_operand:SI 0 "register_operand" "=r")
1134 (match_operand:SI 1 "const0_operand" "i"))
1135 (clobber (reg:CC FLAGS_REG))]
1136 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1137 "xor{l}\t{%0, %0|%0, %0}"
1138 [(set_attr "type" "alu1")
1139 (set_attr "mode" "SI")
1140 (set_attr "length_immediate" "0")])
1141
1142 (define_insn "*movsi_or"
1143 [(set (match_operand:SI 0 "register_operand" "=r")
1144 (match_operand:SI 1 "immediate_operand" "i"))
1145 (clobber (reg:CC FLAGS_REG))]
1146 "reload_completed
1147 && operands[1] == constm1_rtx
1148 && (TARGET_PENTIUM || optimize_size)"
1149 {
1150 operands[1] = constm1_rtx;
1151 return "or{l}\t{%1, %0|%0, %1}";
1152 }
1153 [(set_attr "type" "alu1")
1154 (set_attr "mode" "SI")
1155 (set_attr "length_immediate" "1")])
1156
1157 (define_insn "*movsi_1"
1158 [(set (match_operand:SI 0 "nonimmediate_operand"
1159 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1160 (match_operand:SI 1 "general_operand"
1161 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1162 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1163 {
1164 switch (get_attr_type (insn))
1165 {
1166 case TYPE_SSELOG1:
1167 if (get_attr_mode (insn) == MODE_TI)
1168 return "pxor\t%0, %0";
1169 return "xorps\t%0, %0";
1170
1171 case TYPE_SSEMOV:
1172 switch (get_attr_mode (insn))
1173 {
1174 case MODE_TI:
1175 return "movdqa\t{%1, %0|%0, %1}";
1176 case MODE_V4SF:
1177 return "movaps\t{%1, %0|%0, %1}";
1178 case MODE_SI:
1179 return "movd\t{%1, %0|%0, %1}";
1180 case MODE_SF:
1181 return "movss\t{%1, %0|%0, %1}";
1182 default:
1183 gcc_unreachable ();
1184 }
1185
1186 case TYPE_MMXADD:
1187 return "pxor\t%0, %0";
1188
1189 case TYPE_MMXMOV:
1190 if (get_attr_mode (insn) == MODE_DI)
1191 return "movq\t{%1, %0|%0, %1}";
1192 return "movd\t{%1, %0|%0, %1}";
1193
1194 case TYPE_LEA:
1195 return "lea{l}\t{%1, %0|%0, %1}";
1196
1197 default:
1198 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1199 return "mov{l}\t{%1, %0|%0, %1}";
1200 }
1201 }
1202 [(set (attr "type")
1203 (cond [(eq_attr "alternative" "2")
1204 (const_string "mmxadd")
1205 (eq_attr "alternative" "3,4,5")
1206 (const_string "mmxmov")
1207 (eq_attr "alternative" "6")
1208 (const_string "sselog1")
1209 (eq_attr "alternative" "7,8,9,10,11")
1210 (const_string "ssemov")
1211 (match_operand:DI 1 "pic_32bit_operand" "")
1212 (const_string "lea")
1213 ]
1214 (const_string "imov")))
1215 (set (attr "mode")
1216 (cond [(eq_attr "alternative" "2,3")
1217 (const_string "DI")
1218 (eq_attr "alternative" "6,7")
1219 (if_then_else
1220 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1221 (const_string "V4SF")
1222 (const_string "TI"))
1223 (and (eq_attr "alternative" "8,9,10,11")
1224 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1225 (const_string "SF")
1226 ]
1227 (const_string "SI")))])
1228
1229 ;; Stores and loads of ax to arbitrary constant address.
1230 ;; We fake an second form of instruction to force reload to load address
1231 ;; into register when rax is not available
1232 (define_insn "*movabssi_1_rex64"
1233 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1234 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1235 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1236 "@
1237 movabs{l}\t{%1, %P0|%P0, %1}
1238 mov{l}\t{%1, %a0|%a0, %1}"
1239 [(set_attr "type" "imov")
1240 (set_attr "modrm" "0,*")
1241 (set_attr "length_address" "8,0")
1242 (set_attr "length_immediate" "0,*")
1243 (set_attr "memory" "store")
1244 (set_attr "mode" "SI")])
1245
1246 (define_insn "*movabssi_2_rex64"
1247 [(set (match_operand:SI 0 "register_operand" "=a,r")
1248 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1249 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1250 "@
1251 movabs{l}\t{%P1, %0|%0, %P1}
1252 mov{l}\t{%a1, %0|%0, %a1}"
1253 [(set_attr "type" "imov")
1254 (set_attr "modrm" "0,*")
1255 (set_attr "length_address" "8,0")
1256 (set_attr "length_immediate" "0")
1257 (set_attr "memory" "load")
1258 (set_attr "mode" "SI")])
1259
1260 (define_insn "*swapsi"
1261 [(set (match_operand:SI 0 "register_operand" "+r")
1262 (match_operand:SI 1 "register_operand" "+r"))
1263 (set (match_dup 1)
1264 (match_dup 0))]
1265 ""
1266 "xchg{l}\t%1, %0"
1267 [(set_attr "type" "imov")
1268 (set_attr "mode" "SI")
1269 (set_attr "pent_pair" "np")
1270 (set_attr "athlon_decode" "vector")])
1271
1272 (define_expand "movhi"
1273 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1274 (match_operand:HI 1 "general_operand" ""))]
1275 ""
1276 "ix86_expand_move (HImode, operands); DONE;")
1277
1278 (define_insn "*pushhi2"
1279 [(set (match_operand:HI 0 "push_operand" "=X")
1280 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1281 "!TARGET_64BIT"
1282 "push{l}\t%k1"
1283 [(set_attr "type" "push")
1284 (set_attr "mode" "SI")])
1285
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288 [(set (match_operand:HI 0 "push_operand" "=X")
1289 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290 "TARGET_64BIT"
1291 "push{q}\t%q1"
1292 [(set_attr "type" "push")
1293 (set_attr "mode" "DI")])
1294
1295 (define_insn "*movhi_1"
1296 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1299 {
1300 switch (get_attr_type (insn))
1301 {
1302 case TYPE_IMOVX:
1303 /* movzwl is faster than movw on p2 due to partial word stalls,
1304 though not as fast as an aligned movl. */
1305 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1306 default:
1307 if (get_attr_mode (insn) == MODE_SI)
1308 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1309 else
1310 return "mov{w}\t{%1, %0|%0, %1}";
1311 }
1312 }
1313 [(set (attr "type")
1314 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315 (const_string "imov")
1316 (and (eq_attr "alternative" "0")
1317 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318 (const_int 0))
1319 (eq (symbol_ref "TARGET_HIMODE_MATH")
1320 (const_int 0))))
1321 (const_string "imov")
1322 (and (eq_attr "alternative" "1,2")
1323 (match_operand:HI 1 "aligned_operand" ""))
1324 (const_string "imov")
1325 (and (ne (symbol_ref "TARGET_MOVX")
1326 (const_int 0))
1327 (eq_attr "alternative" "0,2"))
1328 (const_string "imovx")
1329 ]
1330 (const_string "imov")))
1331 (set (attr "mode")
1332 (cond [(eq_attr "type" "imovx")
1333 (const_string "SI")
1334 (and (eq_attr "alternative" "1,2")
1335 (match_operand:HI 1 "aligned_operand" ""))
1336 (const_string "SI")
1337 (and (eq_attr "alternative" "0")
1338 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1339 (const_int 0))
1340 (eq (symbol_ref "TARGET_HIMODE_MATH")
1341 (const_int 0))))
1342 (const_string "SI")
1343 ]
1344 (const_string "HI")))])
1345
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1353 "@
1354 movabs{w}\t{%1, %P0|%P0, %1}
1355 mov{w}\t{%1, %a0|%a0, %1}"
1356 [(set_attr "type" "imov")
1357 (set_attr "modrm" "0,*")
1358 (set_attr "length_address" "8,0")
1359 (set_attr "length_immediate" "0,*")
1360 (set_attr "memory" "store")
1361 (set_attr "mode" "HI")])
1362
1363 (define_insn "*movabshi_2_rex64"
1364 [(set (match_operand:HI 0 "register_operand" "=a,r")
1365 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1367 "@
1368 movabs{w}\t{%P1, %0|%0, %P1}
1369 mov{w}\t{%a1, %0|%0, %a1}"
1370 [(set_attr "type" "imov")
1371 (set_attr "modrm" "0,*")
1372 (set_attr "length_address" "8,0")
1373 (set_attr "length_immediate" "0")
1374 (set_attr "memory" "load")
1375 (set_attr "mode" "HI")])
1376
1377 (define_insn "*swaphi_1"
1378 [(set (match_operand:HI 0 "register_operand" "+r")
1379 (match_operand:HI 1 "register_operand" "+r"))
1380 (set (match_dup 1)
1381 (match_dup 0))]
1382 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1383 "xchg{l}\t%k1, %k0"
1384 [(set_attr "type" "imov")
1385 (set_attr "mode" "SI")
1386 (set_attr "pent_pair" "np")
1387 (set_attr "athlon_decode" "vector")])
1388
1389 (define_insn "*swaphi_2"
1390 [(set (match_operand:HI 0 "register_operand" "+r")
1391 (match_operand:HI 1 "register_operand" "+r"))
1392 (set (match_dup 1)
1393 (match_dup 0))]
1394 "TARGET_PARTIAL_REG_STALL"
1395 "xchg{w}\t%1, %0"
1396 [(set_attr "type" "imov")
1397 (set_attr "mode" "HI")
1398 (set_attr "pent_pair" "np")
1399 (set_attr "athlon_decode" "vector")])
1400
1401 (define_expand "movstricthi"
1402 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403 (match_operand:HI 1 "general_operand" ""))]
1404 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1405 {
1406 /* Don't generate memory->memory moves, go through a register */
1407 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408 operands[1] = force_reg (HImode, operands[1]);
1409 })
1410
1411 (define_insn "*movstricthi_1"
1412 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413 (match_operand:HI 1 "general_operand" "rn,m"))]
1414 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416 "mov{w}\t{%1, %0|%0, %1}"
1417 [(set_attr "type" "imov")
1418 (set_attr "mode" "HI")])
1419
1420 (define_insn "*movstricthi_xor"
1421 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422 (match_operand:HI 1 "const0_operand" "i"))
1423 (clobber (reg:CC FLAGS_REG))]
1424 "reload_completed
1425 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426 "xor{w}\t{%0, %0|%0, %0}"
1427 [(set_attr "type" "alu1")
1428 (set_attr "mode" "HI")
1429 (set_attr "length_immediate" "0")])
1430
1431 (define_expand "movqi"
1432 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433 (match_operand:QI 1 "general_operand" ""))]
1434 ""
1435 "ix86_expand_move (QImode, operands); DONE;")
1436
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte". But actually we use pushl, which has the effect
1439 ;; of rounding the amount pushed up to a word.
1440
1441 (define_insn "*pushqi2"
1442 [(set (match_operand:QI 0 "push_operand" "=X")
1443 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1444 "!TARGET_64BIT"
1445 "push{l}\t%k1"
1446 [(set_attr "type" "push")
1447 (set_attr "mode" "SI")])
1448
1449 ;; For 64BIT abi we always round up to 8 bytes.
1450 (define_insn "*pushqi2_rex64"
1451 [(set (match_operand:QI 0 "push_operand" "=X")
1452 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1453 "TARGET_64BIT"
1454 "push{q}\t%q1"
1455 [(set_attr "type" "push")
1456 (set_attr "mode" "DI")])
1457
1458 ;; Situation is quite tricky about when to choose full sized (SImode) move
1459 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1460 ;; partial register dependency machines (such as AMD Athlon), where QImode
1461 ;; moves issue extra dependency and for partial register stalls machines
1462 ;; that don't use QImode patterns (and QImode move cause stall on the next
1463 ;; instruction).
1464 ;;
1465 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1466 ;; register stall machines with, where we use QImode instructions, since
1467 ;; partial register stall can be caused there. Then we use movzx.
1468 (define_insn "*movqi_1"
1469 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1470 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1471 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1472 {
1473 switch (get_attr_type (insn))
1474 {
1475 case TYPE_IMOVX:
1476 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1477 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1478 default:
1479 if (get_attr_mode (insn) == MODE_SI)
1480 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1481 else
1482 return "mov{b}\t{%1, %0|%0, %1}";
1483 }
1484 }
1485 [(set (attr "type")
1486 (cond [(and (eq_attr "alternative" "5")
1487 (not (match_operand:QI 1 "aligned_operand" "")))
1488 (const_string "imovx")
1489 (ne (symbol_ref "optimize_size") (const_int 0))
1490 (const_string "imov")
1491 (and (eq_attr "alternative" "3")
1492 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1493 (const_int 0))
1494 (eq (symbol_ref "TARGET_QIMODE_MATH")
1495 (const_int 0))))
1496 (const_string "imov")
1497 (eq_attr "alternative" "3,5")
1498 (const_string "imovx")
1499 (and (ne (symbol_ref "TARGET_MOVX")
1500 (const_int 0))
1501 (eq_attr "alternative" "2"))
1502 (const_string "imovx")
1503 ]
1504 (const_string "imov")))
1505 (set (attr "mode")
1506 (cond [(eq_attr "alternative" "3,4,5")
1507 (const_string "SI")
1508 (eq_attr "alternative" "6")
1509 (const_string "QI")
1510 (eq_attr "type" "imovx")
1511 (const_string "SI")
1512 (and (eq_attr "type" "imov")
1513 (and (eq_attr "alternative" "0,1")
1514 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1515 (const_int 0))
1516 (and (eq (symbol_ref "optimize_size")
1517 (const_int 0))
1518 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1519 (const_int 0))))))
1520 (const_string "SI")
1521 ;; Avoid partial register stalls when not using QImode arithmetic
1522 (and (eq_attr "type" "imov")
1523 (and (eq_attr "alternative" "0,1")
1524 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1525 (const_int 0))
1526 (eq (symbol_ref "TARGET_QIMODE_MATH")
1527 (const_int 0)))))
1528 (const_string "SI")
1529 ]
1530 (const_string "QI")))])
1531
1532 (define_expand "reload_outqi"
1533 [(parallel [(match_operand:QI 0 "" "=m")
1534 (match_operand:QI 1 "register_operand" "r")
1535 (match_operand:QI 2 "register_operand" "=&q")])]
1536 ""
1537 {
1538 rtx op0, op1, op2;
1539 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1540
1541 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1542 if (! q_regs_operand (op1, QImode))
1543 {
1544 emit_insn (gen_movqi (op2, op1));
1545 op1 = op2;
1546 }
1547 emit_insn (gen_movqi (op0, op1));
1548 DONE;
1549 })
1550
1551 (define_insn "*swapqi_1"
1552 [(set (match_operand:QI 0 "register_operand" "+r")
1553 (match_operand:QI 1 "register_operand" "+r"))
1554 (set (match_dup 1)
1555 (match_dup 0))]
1556 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1557 "xchg{l}\t%k1, %k0"
1558 [(set_attr "type" "imov")
1559 (set_attr "mode" "SI")
1560 (set_attr "pent_pair" "np")
1561 (set_attr "athlon_decode" "vector")])
1562
1563 (define_insn "*swapqi_2"
1564 [(set (match_operand:QI 0 "register_operand" "+q")
1565 (match_operand:QI 1 "register_operand" "+q"))
1566 (set (match_dup 1)
1567 (match_dup 0))]
1568 "TARGET_PARTIAL_REG_STALL"
1569 "xchg{b}\t%1, %0"
1570 [(set_attr "type" "imov")
1571 (set_attr "mode" "QI")
1572 (set_attr "pent_pair" "np")
1573 (set_attr "athlon_decode" "vector")])
1574
1575 (define_expand "movstrictqi"
1576 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1577 (match_operand:QI 1 "general_operand" ""))]
1578 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1579 {
1580 /* Don't generate memory->memory moves, go through a register. */
1581 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1582 operands[1] = force_reg (QImode, operands[1]);
1583 })
1584
1585 (define_insn "*movstrictqi_1"
1586 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1587 (match_operand:QI 1 "general_operand" "*qn,m"))]
1588 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1589 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1590 "mov{b}\t{%1, %0|%0, %1}"
1591 [(set_attr "type" "imov")
1592 (set_attr "mode" "QI")])
1593
1594 (define_insn "*movstrictqi_xor"
1595 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1596 (match_operand:QI 1 "const0_operand" "i"))
1597 (clobber (reg:CC FLAGS_REG))]
1598 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1599 "xor{b}\t{%0, %0|%0, %0}"
1600 [(set_attr "type" "alu1")
1601 (set_attr "mode" "QI")
1602 (set_attr "length_immediate" "0")])
1603
1604 (define_insn "*movsi_extv_1"
1605 [(set (match_operand:SI 0 "register_operand" "=R")
1606 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1607 (const_int 8)
1608 (const_int 8)))]
1609 ""
1610 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1611 [(set_attr "type" "imovx")
1612 (set_attr "mode" "SI")])
1613
1614 (define_insn "*movhi_extv_1"
1615 [(set (match_operand:HI 0 "register_operand" "=R")
1616 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1617 (const_int 8)
1618 (const_int 8)))]
1619 ""
1620 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1621 [(set_attr "type" "imovx")
1622 (set_attr "mode" "SI")])
1623
1624 (define_insn "*movqi_extv_1"
1625 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1626 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1627 (const_int 8)
1628 (const_int 8)))]
1629 "!TARGET_64BIT"
1630 {
1631 switch (get_attr_type (insn))
1632 {
1633 case TYPE_IMOVX:
1634 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1635 default:
1636 return "mov{b}\t{%h1, %0|%0, %h1}";
1637 }
1638 }
1639 [(set (attr "type")
1640 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1641 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1642 (ne (symbol_ref "TARGET_MOVX")
1643 (const_int 0))))
1644 (const_string "imovx")
1645 (const_string "imov")))
1646 (set (attr "mode")
1647 (if_then_else (eq_attr "type" "imovx")
1648 (const_string "SI")
1649 (const_string "QI")))])
1650
1651 (define_insn "*movqi_extv_1_rex64"
1652 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1653 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1654 (const_int 8)
1655 (const_int 8)))]
1656 "TARGET_64BIT"
1657 {
1658 switch (get_attr_type (insn))
1659 {
1660 case TYPE_IMOVX:
1661 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1662 default:
1663 return "mov{b}\t{%h1, %0|%0, %h1}";
1664 }
1665 }
1666 [(set (attr "type")
1667 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1668 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1669 (ne (symbol_ref "TARGET_MOVX")
1670 (const_int 0))))
1671 (const_string "imovx")
1672 (const_string "imov")))
1673 (set (attr "mode")
1674 (if_then_else (eq_attr "type" "imovx")
1675 (const_string "SI")
1676 (const_string "QI")))])
1677
1678 ;; Stores and loads of ax to arbitrary constant address.
1679 ;; We fake an second form of instruction to force reload to load address
1680 ;; into register when rax is not available
1681 (define_insn "*movabsqi_1_rex64"
1682 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1683 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1684 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1685 "@
1686 movabs{b}\t{%1, %P0|%P0, %1}
1687 mov{b}\t{%1, %a0|%a0, %1}"
1688 [(set_attr "type" "imov")
1689 (set_attr "modrm" "0,*")
1690 (set_attr "length_address" "8,0")
1691 (set_attr "length_immediate" "0,*")
1692 (set_attr "memory" "store")
1693 (set_attr "mode" "QI")])
1694
1695 (define_insn "*movabsqi_2_rex64"
1696 [(set (match_operand:QI 0 "register_operand" "=a,r")
1697 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1698 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1699 "@
1700 movabs{b}\t{%P1, %0|%0, %P1}
1701 mov{b}\t{%a1, %0|%0, %a1}"
1702 [(set_attr "type" "imov")
1703 (set_attr "modrm" "0,*")
1704 (set_attr "length_address" "8,0")
1705 (set_attr "length_immediate" "0")
1706 (set_attr "memory" "load")
1707 (set_attr "mode" "QI")])
1708
1709 (define_insn "*movdi_extzv_1"
1710 [(set (match_operand:DI 0 "register_operand" "=R")
1711 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1712 (const_int 8)
1713 (const_int 8)))]
1714 "TARGET_64BIT"
1715 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1716 [(set_attr "type" "imovx")
1717 (set_attr "mode" "DI")])
1718
1719 (define_insn "*movsi_extzv_1"
1720 [(set (match_operand:SI 0 "register_operand" "=R")
1721 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1722 (const_int 8)
1723 (const_int 8)))]
1724 ""
1725 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1726 [(set_attr "type" "imovx")
1727 (set_attr "mode" "SI")])
1728
1729 (define_insn "*movqi_extzv_2"
1730 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1731 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1732 (const_int 8)
1733 (const_int 8)) 0))]
1734 "!TARGET_64BIT"
1735 {
1736 switch (get_attr_type (insn))
1737 {
1738 case TYPE_IMOVX:
1739 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1740 default:
1741 return "mov{b}\t{%h1, %0|%0, %h1}";
1742 }
1743 }
1744 [(set (attr "type")
1745 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1746 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1747 (ne (symbol_ref "TARGET_MOVX")
1748 (const_int 0))))
1749 (const_string "imovx")
1750 (const_string "imov")))
1751 (set (attr "mode")
1752 (if_then_else (eq_attr "type" "imovx")
1753 (const_string "SI")
1754 (const_string "QI")))])
1755
1756 (define_insn "*movqi_extzv_2_rex64"
1757 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1758 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1759 (const_int 8)
1760 (const_int 8)) 0))]
1761 "TARGET_64BIT"
1762 {
1763 switch (get_attr_type (insn))
1764 {
1765 case TYPE_IMOVX:
1766 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1767 default:
1768 return "mov{b}\t{%h1, %0|%0, %h1}";
1769 }
1770 }
1771 [(set (attr "type")
1772 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1773 (ne (symbol_ref "TARGET_MOVX")
1774 (const_int 0)))
1775 (const_string "imovx")
1776 (const_string "imov")))
1777 (set (attr "mode")
1778 (if_then_else (eq_attr "type" "imovx")
1779 (const_string "SI")
1780 (const_string "QI")))])
1781
1782 (define_insn "movsi_insv_1"
1783 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1784 (const_int 8)
1785 (const_int 8))
1786 (match_operand:SI 1 "general_operand" "Qmn"))]
1787 "!TARGET_64BIT"
1788 "mov{b}\t{%b1, %h0|%h0, %b1}"
1789 [(set_attr "type" "imov")
1790 (set_attr "mode" "QI")])
1791
1792 (define_insn "movdi_insv_1_rex64"
1793 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1794 (const_int 8)
1795 (const_int 8))
1796 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1797 "TARGET_64BIT"
1798 "mov{b}\t{%b1, %h0|%h0, %b1}"
1799 [(set_attr "type" "imov")
1800 (set_attr "mode" "QI")])
1801
1802 (define_insn "*movqi_insv_2"
1803 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1804 (const_int 8)
1805 (const_int 8))
1806 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1807 (const_int 8)))]
1808 ""
1809 "mov{b}\t{%h1, %h0|%h0, %h1}"
1810 [(set_attr "type" "imov")
1811 (set_attr "mode" "QI")])
1812
1813 (define_expand "movdi"
1814 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1815 (match_operand:DI 1 "general_operand" ""))]
1816 ""
1817 "ix86_expand_move (DImode, operands); DONE;")
1818
1819 (define_insn "*pushdi"
1820 [(set (match_operand:DI 0 "push_operand" "=<")
1821 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1822 "!TARGET_64BIT"
1823 "#")
1824
1825 (define_insn "*pushdi2_rex64"
1826 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1827 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1828 "TARGET_64BIT"
1829 "@
1830 push{q}\t%1
1831 #"
1832 [(set_attr "type" "push,multi")
1833 (set_attr "mode" "DI")])
1834
1835 ;; Convert impossible pushes of immediate to existing instructions.
1836 ;; First try to get scratch register and go through it. In case this
1837 ;; fails, push sign extended lower part first and then overwrite
1838 ;; upper part by 32bit move.
1839 (define_peephole2
1840 [(match_scratch:DI 2 "r")
1841 (set (match_operand:DI 0 "push_operand" "")
1842 (match_operand:DI 1 "immediate_operand" ""))]
1843 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1844 && !x86_64_immediate_operand (operands[1], DImode)"
1845 [(set (match_dup 2) (match_dup 1))
1846 (set (match_dup 0) (match_dup 2))]
1847 "")
1848
1849 ;; We need to define this as both peepholer and splitter for case
1850 ;; peephole2 pass is not run.
1851 ;; "&& 1" is needed to keep it from matching the previous pattern.
1852 (define_peephole2
1853 [(set (match_operand:DI 0 "push_operand" "")
1854 (match_operand:DI 1 "immediate_operand" ""))]
1855 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1856 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1857 [(set (match_dup 0) (match_dup 1))
1858 (set (match_dup 2) (match_dup 3))]
1859 "split_di (operands + 1, 1, operands + 2, operands + 3);
1860 operands[1] = gen_lowpart (DImode, operands[2]);
1861 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1862 GEN_INT (4)));
1863 ")
1864
1865 (define_split
1866 [(set (match_operand:DI 0 "push_operand" "")
1867 (match_operand:DI 1 "immediate_operand" ""))]
1868 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1869 ? flow2_completed : reload_completed)
1870 && !symbolic_operand (operands[1], DImode)
1871 && !x86_64_immediate_operand (operands[1], DImode)"
1872 [(set (match_dup 0) (match_dup 1))
1873 (set (match_dup 2) (match_dup 3))]
1874 "split_di (operands + 1, 1, operands + 2, operands + 3);
1875 operands[1] = gen_lowpart (DImode, operands[2]);
1876 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1877 GEN_INT (4)));
1878 ")
1879
1880 (define_insn "*pushdi2_prologue_rex64"
1881 [(set (match_operand:DI 0 "push_operand" "=<")
1882 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1883 (clobber (mem:BLK (scratch)))]
1884 "TARGET_64BIT"
1885 "push{q}\t%1"
1886 [(set_attr "type" "push")
1887 (set_attr "mode" "DI")])
1888
1889 (define_insn "*popdi1_epilogue_rex64"
1890 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1891 (mem:DI (reg:DI SP_REG)))
1892 (set (reg:DI SP_REG)
1893 (plus:DI (reg:DI SP_REG) (const_int 8)))
1894 (clobber (mem:BLK (scratch)))]
1895 "TARGET_64BIT"
1896 "pop{q}\t%0"
1897 [(set_attr "type" "pop")
1898 (set_attr "mode" "DI")])
1899
1900 (define_insn "popdi1"
1901 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1902 (mem:DI (reg:DI SP_REG)))
1903 (set (reg:DI SP_REG)
1904 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1905 "TARGET_64BIT"
1906 "pop{q}\t%0"
1907 [(set_attr "type" "pop")
1908 (set_attr "mode" "DI")])
1909
1910 (define_insn "*movdi_xor_rex64"
1911 [(set (match_operand:DI 0 "register_operand" "=r")
1912 (match_operand:DI 1 "const0_operand" "i"))
1913 (clobber (reg:CC FLAGS_REG))]
1914 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1915 && reload_completed"
1916 "xor{l}\t{%k0, %k0|%k0, %k0}"
1917 [(set_attr "type" "alu1")
1918 (set_attr "mode" "SI")
1919 (set_attr "length_immediate" "0")])
1920
1921 (define_insn "*movdi_or_rex64"
1922 [(set (match_operand:DI 0 "register_operand" "=r")
1923 (match_operand:DI 1 "const_int_operand" "i"))
1924 (clobber (reg:CC FLAGS_REG))]
1925 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1926 && reload_completed
1927 && operands[1] == constm1_rtx"
1928 {
1929 operands[1] = constm1_rtx;
1930 return "or{q}\t{%1, %0|%0, %1}";
1931 }
1932 [(set_attr "type" "alu1")
1933 (set_attr "mode" "DI")
1934 (set_attr "length_immediate" "1")])
1935
1936 (define_insn "*movdi_2"
1937 [(set (match_operand:DI 0 "nonimmediate_operand"
1938 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1939 (match_operand:DI 1 "general_operand"
1940 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1941 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1942 "@
1943 #
1944 #
1945 pxor\t%0, %0
1946 movq\t{%1, %0|%0, %1}
1947 movq\t{%1, %0|%0, %1}
1948 pxor\t%0, %0
1949 movq\t{%1, %0|%0, %1}
1950 movdqa\t{%1, %0|%0, %1}
1951 movq\t{%1, %0|%0, %1}
1952 xorps\t%0, %0
1953 movlps\t{%1, %0|%0, %1}
1954 movaps\t{%1, %0|%0, %1}
1955 movlps\t{%1, %0|%0, %1}"
1956 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1957 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1958
1959 (define_split
1960 [(set (match_operand:DI 0 "push_operand" "")
1961 (match_operand:DI 1 "general_operand" ""))]
1962 "!TARGET_64BIT && reload_completed
1963 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1964 [(const_int 0)]
1965 "ix86_split_long_move (operands); DONE;")
1966
1967 ;; %%% This multiword shite has got to go.
1968 (define_split
1969 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1970 (match_operand:DI 1 "general_operand" ""))]
1971 "!TARGET_64BIT && reload_completed
1972 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1973 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1974 [(const_int 0)]
1975 "ix86_split_long_move (operands); DONE;")
1976
1977 (define_insn "*movdi_1_rex64"
1978 [(set (match_operand:DI 0 "nonimmediate_operand"
1979 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1980 (match_operand:DI 1 "general_operand"
1981 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1982 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1983 {
1984 switch (get_attr_type (insn))
1985 {
1986 case TYPE_SSECVT:
1987 if (which_alternative == 13)
1988 return "movq2dq\t{%1, %0|%0, %1}";
1989 else
1990 return "movdq2q\t{%1, %0|%0, %1}";
1991 case TYPE_SSEMOV:
1992 if (get_attr_mode (insn) == MODE_TI)
1993 return "movdqa\t{%1, %0|%0, %1}";
1994 /* FALLTHRU */
1995 case TYPE_MMXMOV:
1996 /* Moves from and into integer register is done using movd opcode with
1997 REX prefix. */
1998 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1999 return "movd\t{%1, %0|%0, %1}";
2000 return "movq\t{%1, %0|%0, %1}";
2001 case TYPE_SSELOG1:
2002 case TYPE_MMXADD:
2003 return "pxor\t%0, %0";
2004 case TYPE_MULTI:
2005 return "#";
2006 case TYPE_LEA:
2007 return "lea{q}\t{%a1, %0|%0, %a1}";
2008 default:
2009 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2010 if (get_attr_mode (insn) == MODE_SI)
2011 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2012 else if (which_alternative == 2)
2013 return "movabs{q}\t{%1, %0|%0, %1}";
2014 else
2015 return "mov{q}\t{%1, %0|%0, %1}";
2016 }
2017 }
2018 [(set (attr "type")
2019 (cond [(eq_attr "alternative" "5")
2020 (const_string "mmxadd")
2021 (eq_attr "alternative" "6,7,8")
2022 (const_string "mmxmov")
2023 (eq_attr "alternative" "9")
2024 (const_string "sselog1")
2025 (eq_attr "alternative" "10,11,12")
2026 (const_string "ssemov")
2027 (eq_attr "alternative" "13,14")
2028 (const_string "ssecvt")
2029 (eq_attr "alternative" "4")
2030 (const_string "multi")
2031 (match_operand:DI 1 "pic_32bit_operand" "")
2032 (const_string "lea")
2033 ]
2034 (const_string "imov")))
2035 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2036 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2037 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2038
2039 ;; Stores and loads of ax to arbitrary constant address.
2040 ;; We fake an second form of instruction to force reload to load address
2041 ;; into register when rax is not available
2042 (define_insn "*movabsdi_1_rex64"
2043 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2044 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2045 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2046 "@
2047 movabs{q}\t{%1, %P0|%P0, %1}
2048 mov{q}\t{%1, %a0|%a0, %1}"
2049 [(set_attr "type" "imov")
2050 (set_attr "modrm" "0,*")
2051 (set_attr "length_address" "8,0")
2052 (set_attr "length_immediate" "0,*")
2053 (set_attr "memory" "store")
2054 (set_attr "mode" "DI")])
2055
2056 (define_insn "*movabsdi_2_rex64"
2057 [(set (match_operand:DI 0 "register_operand" "=a,r")
2058 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2059 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2060 "@
2061 movabs{q}\t{%P1, %0|%0, %P1}
2062 mov{q}\t{%a1, %0|%0, %a1}"
2063 [(set_attr "type" "imov")
2064 (set_attr "modrm" "0,*")
2065 (set_attr "length_address" "8,0")
2066 (set_attr "length_immediate" "0")
2067 (set_attr "memory" "load")
2068 (set_attr "mode" "DI")])
2069
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it. In case this
2072 ;; fails, move by 32bit parts.
2073 (define_peephole2
2074 [(match_scratch:DI 2 "r")
2075 (set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 1))
2080 (set (match_dup 0) (match_dup 2))]
2081 "")
2082
2083 ;; We need to define this as both peepholer and splitter for case
2084 ;; peephole2 pass is not run.
2085 ;; "&& 1" is needed to keep it from matching the previous pattern.
2086 (define_peephole2
2087 [(set (match_operand:DI 0 "memory_operand" "")
2088 (match_operand:DI 1 "immediate_operand" ""))]
2089 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2090 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2091 [(set (match_dup 2) (match_dup 3))
2092 (set (match_dup 4) (match_dup 5))]
2093 "split_di (operands, 2, operands + 2, operands + 4);")
2094
2095 (define_split
2096 [(set (match_operand:DI 0 "memory_operand" "")
2097 (match_operand:DI 1 "immediate_operand" ""))]
2098 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2099 ? flow2_completed : reload_completed)
2100 && !symbolic_operand (operands[1], DImode)
2101 && !x86_64_immediate_operand (operands[1], DImode)"
2102 [(set (match_dup 2) (match_dup 3))
2103 (set (match_dup 4) (match_dup 5))]
2104 "split_di (operands, 2, operands + 2, operands + 4);")
2105
2106 (define_insn "*swapdi_rex64"
2107 [(set (match_operand:DI 0 "register_operand" "+r")
2108 (match_operand:DI 1 "register_operand" "+r"))
2109 (set (match_dup 1)
2110 (match_dup 0))]
2111 "TARGET_64BIT"
2112 "xchg{q}\t%1, %0"
2113 [(set_attr "type" "imov")
2114 (set_attr "mode" "DI")
2115 (set_attr "pent_pair" "np")
2116 (set_attr "athlon_decode" "vector")])
2117
2118 (define_expand "movti"
2119 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2120 (match_operand:TI 1 "nonimmediate_operand" ""))]
2121 "TARGET_SSE || TARGET_64BIT"
2122 {
2123 if (TARGET_64BIT)
2124 ix86_expand_move (TImode, operands);
2125 else
2126 ix86_expand_vector_move (TImode, operands);
2127 DONE;
2128 })
2129
2130 (define_insn "*movti_internal"
2131 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2132 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2133 "TARGET_SSE && !TARGET_64BIT
2134 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2135 {
2136 switch (which_alternative)
2137 {
2138 case 0:
2139 if (get_attr_mode (insn) == MODE_V4SF)
2140 return "xorps\t%0, %0";
2141 else
2142 return "pxor\t%0, %0";
2143 case 1:
2144 case 2:
2145 if (get_attr_mode (insn) == MODE_V4SF)
2146 return "movaps\t{%1, %0|%0, %1}";
2147 else
2148 return "movdqa\t{%1, %0|%0, %1}";
2149 default:
2150 gcc_unreachable ();
2151 }
2152 }
2153 [(set_attr "type" "sselog1,ssemov,ssemov")
2154 (set (attr "mode")
2155 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2156 (ne (symbol_ref "optimize_size") (const_int 0)))
2157 (const_string "V4SF")
2158 (and (eq_attr "alternative" "2")
2159 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2160 (const_int 0)))
2161 (const_string "V4SF")]
2162 (const_string "TI")))])
2163
2164 (define_insn "*movti_rex64"
2165 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2166 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2167 "TARGET_64BIT
2168 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2169 {
2170 switch (which_alternative)
2171 {
2172 case 0:
2173 case 1:
2174 return "#";
2175 case 2:
2176 if (get_attr_mode (insn) == MODE_V4SF)
2177 return "xorps\t%0, %0";
2178 else
2179 return "pxor\t%0, %0";
2180 case 3:
2181 case 4:
2182 if (get_attr_mode (insn) == MODE_V4SF)
2183 return "movaps\t{%1, %0|%0, %1}";
2184 else
2185 return "movdqa\t{%1, %0|%0, %1}";
2186 default:
2187 gcc_unreachable ();
2188 }
2189 }
2190 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2191 (set (attr "mode")
2192 (cond [(eq_attr "alternative" "2,3")
2193 (if_then_else
2194 (ne (symbol_ref "optimize_size")
2195 (const_int 0))
2196 (const_string "V4SF")
2197 (const_string "TI"))
2198 (eq_attr "alternative" "4")
2199 (if_then_else
2200 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2201 (const_int 0))
2202 (ne (symbol_ref "optimize_size")
2203 (const_int 0)))
2204 (const_string "V4SF")
2205 (const_string "TI"))]
2206 (const_string "DI")))])
2207
2208 (define_split
2209 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2210 (match_operand:TI 1 "general_operand" ""))]
2211 "reload_completed && !SSE_REG_P (operands[0])
2212 && !SSE_REG_P (operands[1])"
2213 [(const_int 0)]
2214 "ix86_split_long_move (operands); DONE;")
2215
2216 (define_expand "movsf"
2217 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2218 (match_operand:SF 1 "general_operand" ""))]
2219 ""
2220 "ix86_expand_move (SFmode, operands); DONE;")
2221
2222 (define_insn "*pushsf"
2223 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2224 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2225 "!TARGET_64BIT"
2226 {
2227 /* Anything else should be already split before reg-stack. */
2228 gcc_assert (which_alternative == 1);
2229 return "push{l}\t%1";
2230 }
2231 [(set_attr "type" "multi,push,multi")
2232 (set_attr "unit" "i387,*,*")
2233 (set_attr "mode" "SF,SI,SF")])
2234
2235 (define_insn "*pushsf_rex64"
2236 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2237 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2238 "TARGET_64BIT"
2239 {
2240 /* Anything else should be already split before reg-stack. */
2241 gcc_assert (which_alternative == 1);
2242 return "push{q}\t%q1";
2243 }
2244 [(set_attr "type" "multi,push,multi")
2245 (set_attr "unit" "i387,*,*")
2246 (set_attr "mode" "SF,DI,SF")])
2247
2248 (define_split
2249 [(set (match_operand:SF 0 "push_operand" "")
2250 (match_operand:SF 1 "memory_operand" ""))]
2251 "reload_completed
2252 && GET_CODE (operands[1]) == MEM
2253 && constant_pool_reference_p (operands[1])"
2254 [(set (match_dup 0)
2255 (match_dup 1))]
2256 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2257
2258
2259 ;; %%% Kill this when call knows how to work this out.
2260 (define_split
2261 [(set (match_operand:SF 0 "push_operand" "")
2262 (match_operand:SF 1 "any_fp_register_operand" ""))]
2263 "!TARGET_64BIT"
2264 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2265 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2266
2267 (define_split
2268 [(set (match_operand:SF 0 "push_operand" "")
2269 (match_operand:SF 1 "any_fp_register_operand" ""))]
2270 "TARGET_64BIT"
2271 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2272 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2273
2274 (define_insn "*movsf_1"
2275 [(set (match_operand:SF 0 "nonimmediate_operand"
2276 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2277 (match_operand:SF 1 "general_operand"
2278 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2279 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2280 && (reload_in_progress || reload_completed
2281 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2282 || GET_CODE (operands[1]) != CONST_DOUBLE
2283 || memory_operand (operands[0], SFmode))"
2284 {
2285 switch (which_alternative)
2286 {
2287 case 0:
2288 return output_387_reg_move (insn, operands);
2289
2290 case 1:
2291 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2292 return "fstp%z0\t%y0";
2293 else
2294 return "fst%z0\t%y0";
2295
2296 case 2:
2297 return standard_80387_constant_opcode (operands[1]);
2298
2299 case 3:
2300 case 4:
2301 return "mov{l}\t{%1, %0|%0, %1}";
2302 case 5:
2303 if (get_attr_mode (insn) == MODE_TI)
2304 return "pxor\t%0, %0";
2305 else
2306 return "xorps\t%0, %0";
2307 case 6:
2308 if (get_attr_mode (insn) == MODE_V4SF)
2309 return "movaps\t{%1, %0|%0, %1}";
2310 else
2311 return "movss\t{%1, %0|%0, %1}";
2312 case 7:
2313 case 8:
2314 return "movss\t{%1, %0|%0, %1}";
2315
2316 case 9:
2317 case 10:
2318 return "movd\t{%1, %0|%0, %1}";
2319
2320 case 11:
2321 return "movq\t{%1, %0|%0, %1}";
2322
2323 default:
2324 gcc_unreachable ();
2325 }
2326 }
2327 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2328 (set (attr "mode")
2329 (cond [(eq_attr "alternative" "3,4,9,10")
2330 (const_string "SI")
2331 (eq_attr "alternative" "5")
2332 (if_then_else
2333 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2334 (const_int 0))
2335 (ne (symbol_ref "TARGET_SSE2")
2336 (const_int 0)))
2337 (eq (symbol_ref "optimize_size")
2338 (const_int 0)))
2339 (const_string "TI")
2340 (const_string "V4SF"))
2341 /* For architectures resolving dependencies on
2342 whole SSE registers use APS move to break dependency
2343 chains, otherwise use short move to avoid extra work.
2344
2345 Do the same for architectures resolving dependencies on
2346 the parts. While in DF mode it is better to always handle
2347 just register parts, the SF mode is different due to lack
2348 of instructions to load just part of the register. It is
2349 better to maintain the whole registers in single format
2350 to avoid problems on using packed logical operations. */
2351 (eq_attr "alternative" "6")
2352 (if_then_else
2353 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2354 (const_int 0))
2355 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2356 (const_int 0)))
2357 (const_string "V4SF")
2358 (const_string "SF"))
2359 (eq_attr "alternative" "11")
2360 (const_string "DI")]
2361 (const_string "SF")))])
2362
2363 (define_insn "*swapsf"
2364 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2365 (match_operand:SF 1 "fp_register_operand" "+f"))
2366 (set (match_dup 1)
2367 (match_dup 0))]
2368 "reload_completed || TARGET_80387"
2369 {
2370 if (STACK_TOP_P (operands[0]))
2371 return "fxch\t%1";
2372 else
2373 return "fxch\t%0";
2374 }
2375 [(set_attr "type" "fxch")
2376 (set_attr "mode" "SF")])
2377
2378 (define_expand "movdf"
2379 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2380 (match_operand:DF 1 "general_operand" ""))]
2381 ""
2382 "ix86_expand_move (DFmode, operands); DONE;")
2383
2384 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2385 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2386 ;; On the average, pushdf using integers can be still shorter. Allow this
2387 ;; pattern for optimize_size too.
2388
2389 (define_insn "*pushdf_nointeger"
2390 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2391 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2392 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2393 {
2394 /* This insn should be already split before reg-stack. */
2395 gcc_unreachable ();
2396 }
2397 [(set_attr "type" "multi")
2398 (set_attr "unit" "i387,*,*,*")
2399 (set_attr "mode" "DF,SI,SI,DF")])
2400
2401 (define_insn "*pushdf_integer"
2402 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2403 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2404 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2405 {
2406 /* This insn should be already split before reg-stack. */
2407 gcc_unreachable ();
2408 }
2409 [(set_attr "type" "multi")
2410 (set_attr "unit" "i387,*,*")
2411 (set_attr "mode" "DF,SI,DF")])
2412
2413 ;; %%% Kill this when call knows how to work this out.
2414 (define_split
2415 [(set (match_operand:DF 0 "push_operand" "")
2416 (match_operand:DF 1 "any_fp_register_operand" ""))]
2417 "!TARGET_64BIT && reload_completed"
2418 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2419 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2420 "")
2421
2422 (define_split
2423 [(set (match_operand:DF 0 "push_operand" "")
2424 (match_operand:DF 1 "any_fp_register_operand" ""))]
2425 "TARGET_64BIT && reload_completed"
2426 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2427 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2428 "")
2429
2430 (define_split
2431 [(set (match_operand:DF 0 "push_operand" "")
2432 (match_operand:DF 1 "general_operand" ""))]
2433 "reload_completed"
2434 [(const_int 0)]
2435 "ix86_split_long_move (operands); DONE;")
2436
2437 ;; Moving is usually shorter when only FP registers are used. This separate
2438 ;; movdf pattern avoids the use of integer registers for FP operations
2439 ;; when optimizing for size.
2440
2441 (define_insn "*movdf_nointeger"
2442 [(set (match_operand:DF 0 "nonimmediate_operand"
2443 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2444 (match_operand:DF 1 "general_operand"
2445 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2446 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2447 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2448 && (reload_in_progress || reload_completed
2449 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2450 || GET_CODE (operands[1]) != CONST_DOUBLE
2451 || memory_operand (operands[0], DFmode))"
2452 {
2453 switch (which_alternative)
2454 {
2455 case 0:
2456 return output_387_reg_move (insn, operands);
2457
2458 case 1:
2459 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2460 return "fstp%z0\t%y0";
2461 else
2462 return "fst%z0\t%y0";
2463
2464 case 2:
2465 return standard_80387_constant_opcode (operands[1]);
2466
2467 case 3:
2468 case 4:
2469 return "#";
2470 case 5:
2471 switch (get_attr_mode (insn))
2472 {
2473 case MODE_V4SF:
2474 return "xorps\t%0, %0";
2475 case MODE_V2DF:
2476 return "xorpd\t%0, %0";
2477 case MODE_TI:
2478 return "pxor\t%0, %0";
2479 default:
2480 gcc_unreachable ();
2481 }
2482 case 6:
2483 case 7:
2484 case 8:
2485 switch (get_attr_mode (insn))
2486 {
2487 case MODE_V4SF:
2488 return "movaps\t{%1, %0|%0, %1}";
2489 case MODE_V2DF:
2490 return "movapd\t{%1, %0|%0, %1}";
2491 case MODE_TI:
2492 return "movdqa\t{%1, %0|%0, %1}";
2493 case MODE_DI:
2494 return "movq\t{%1, %0|%0, %1}";
2495 case MODE_DF:
2496 return "movsd\t{%1, %0|%0, %1}";
2497 case MODE_V1DF:
2498 return "movlpd\t{%1, %0|%0, %1}";
2499 case MODE_V2SF:
2500 return "movlps\t{%1, %0|%0, %1}";
2501 default:
2502 gcc_unreachable ();
2503 }
2504
2505 default:
2506 gcc_unreachable ();
2507 }
2508 }
2509 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2510 (set (attr "mode")
2511 (cond [(eq_attr "alternative" "0,1,2")
2512 (const_string "DF")
2513 (eq_attr "alternative" "3,4")
2514 (const_string "SI")
2515
2516 /* For SSE1, we have many fewer alternatives. */
2517 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518 (cond [(eq_attr "alternative" "5,6")
2519 (const_string "V4SF")
2520 ]
2521 (const_string "V2SF"))
2522
2523 /* xorps is one byte shorter. */
2524 (eq_attr "alternative" "5")
2525 (cond [(ne (symbol_ref "optimize_size")
2526 (const_int 0))
2527 (const_string "V4SF")
2528 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2529 (const_int 0))
2530 (const_string "TI")
2531 ]
2532 (const_string "V2DF"))
2533
2534 /* For architectures resolving dependencies on
2535 whole SSE registers use APD move to break dependency
2536 chains, otherwise use short move to avoid extra work.
2537
2538 movaps encodes one byte shorter. */
2539 (eq_attr "alternative" "6")
2540 (cond
2541 [(ne (symbol_ref "optimize_size")
2542 (const_int 0))
2543 (const_string "V4SF")
2544 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2545 (const_int 0))
2546 (const_string "V2DF")
2547 ]
2548 (const_string "DF"))
2549 /* For architectures resolving dependencies on register
2550 parts we may avoid extra work to zero out upper part
2551 of register. */
2552 (eq_attr "alternative" "7")
2553 (if_then_else
2554 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2555 (const_int 0))
2556 (const_string "V1DF")
2557 (const_string "DF"))
2558 ]
2559 (const_string "DF")))])
2560
2561 (define_insn "*movdf_integer"
2562 [(set (match_operand:DF 0 "nonimmediate_operand"
2563 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2564 (match_operand:DF 1 "general_operand"
2565 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2566 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2567 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2568 && (reload_in_progress || reload_completed
2569 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2570 || GET_CODE (operands[1]) != CONST_DOUBLE
2571 || memory_operand (operands[0], DFmode))"
2572 {
2573 switch (which_alternative)
2574 {
2575 case 0:
2576 return output_387_reg_move (insn, operands);
2577
2578 case 1:
2579 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2580 return "fstp%z0\t%y0";
2581 else
2582 return "fst%z0\t%y0";
2583
2584 case 2:
2585 return standard_80387_constant_opcode (operands[1]);
2586
2587 case 3:
2588 case 4:
2589 return "#";
2590
2591 case 5:
2592 switch (get_attr_mode (insn))
2593 {
2594 case MODE_V4SF:
2595 return "xorps\t%0, %0";
2596 case MODE_V2DF:
2597 return "xorpd\t%0, %0";
2598 case MODE_TI:
2599 return "pxor\t%0, %0";
2600 default:
2601 gcc_unreachable ();
2602 }
2603 case 6:
2604 case 7:
2605 case 8:
2606 switch (get_attr_mode (insn))
2607 {
2608 case MODE_V4SF:
2609 return "movaps\t{%1, %0|%0, %1}";
2610 case MODE_V2DF:
2611 return "movapd\t{%1, %0|%0, %1}";
2612 case MODE_TI:
2613 return "movdqa\t{%1, %0|%0, %1}";
2614 case MODE_DI:
2615 return "movq\t{%1, %0|%0, %1}";
2616 case MODE_DF:
2617 return "movsd\t{%1, %0|%0, %1}";
2618 case MODE_V1DF:
2619 return "movlpd\t{%1, %0|%0, %1}";
2620 case MODE_V2SF:
2621 return "movlps\t{%1, %0|%0, %1}";
2622 default:
2623 gcc_unreachable ();
2624 }
2625
2626 default:
2627 gcc_unreachable();
2628 }
2629 }
2630 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2631 (set (attr "mode")
2632 (cond [(eq_attr "alternative" "0,1,2")
2633 (const_string "DF")
2634 (eq_attr "alternative" "3,4")
2635 (const_string "SI")
2636
2637 /* For SSE1, we have many fewer alternatives. */
2638 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2639 (cond [(eq_attr "alternative" "5,6")
2640 (const_string "V4SF")
2641 ]
2642 (const_string "V2SF"))
2643
2644 /* xorps is one byte shorter. */
2645 (eq_attr "alternative" "5")
2646 (cond [(ne (symbol_ref "optimize_size")
2647 (const_int 0))
2648 (const_string "V4SF")
2649 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2650 (const_int 0))
2651 (const_string "TI")
2652 ]
2653 (const_string "V2DF"))
2654
2655 /* For architectures resolving dependencies on
2656 whole SSE registers use APD move to break dependency
2657 chains, otherwise use short move to avoid extra work.
2658
2659 movaps encodes one byte shorter. */
2660 (eq_attr "alternative" "6")
2661 (cond
2662 [(ne (symbol_ref "optimize_size")
2663 (const_int 0))
2664 (const_string "V4SF")
2665 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2666 (const_int 0))
2667 (const_string "V2DF")
2668 ]
2669 (const_string "DF"))
2670 /* For architectures resolving dependencies on register
2671 parts we may avoid extra work to zero out upper part
2672 of register. */
2673 (eq_attr "alternative" "7")
2674 (if_then_else
2675 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2676 (const_int 0))
2677 (const_string "V1DF")
2678 (const_string "DF"))
2679 ]
2680 (const_string "DF")))])
2681
2682 (define_split
2683 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2684 (match_operand:DF 1 "general_operand" ""))]
2685 "reload_completed
2686 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2687 && ! (ANY_FP_REG_P (operands[0]) ||
2688 (GET_CODE (operands[0]) == SUBREG
2689 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2690 && ! (ANY_FP_REG_P (operands[1]) ||
2691 (GET_CODE (operands[1]) == SUBREG
2692 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2693 [(const_int 0)]
2694 "ix86_split_long_move (operands); DONE;")
2695
2696 (define_insn "*swapdf"
2697 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2698 (match_operand:DF 1 "fp_register_operand" "+f"))
2699 (set (match_dup 1)
2700 (match_dup 0))]
2701 "reload_completed || TARGET_80387"
2702 {
2703 if (STACK_TOP_P (operands[0]))
2704 return "fxch\t%1";
2705 else
2706 return "fxch\t%0";
2707 }
2708 [(set_attr "type" "fxch")
2709 (set_attr "mode" "DF")])
2710
2711 (define_expand "movxf"
2712 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2713 (match_operand:XF 1 "general_operand" ""))]
2714 ""
2715 "ix86_expand_move (XFmode, operands); DONE;")
2716
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2719 ;; Pushing using integer instructions is longer except for constants
2720 ;; and direct memory references.
2721 ;; (assuming that any given constant is pushed only once, but this ought to be
2722 ;; handled elsewhere).
2723
2724 (define_insn "*pushxf_nointeger"
2725 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2726 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2727 "optimize_size"
2728 {
2729 /* This insn should be already split before reg-stack. */
2730 gcc_unreachable ();
2731 }
2732 [(set_attr "type" "multi")
2733 (set_attr "unit" "i387,*,*")
2734 (set_attr "mode" "XF,SI,SI")])
2735
2736 (define_insn "*pushxf_integer"
2737 [(set (match_operand:XF 0 "push_operand" "=<,<")
2738 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2739 "!optimize_size"
2740 {
2741 /* This insn should be already split before reg-stack. */
2742 gcc_unreachable ();
2743 }
2744 [(set_attr "type" "multi")
2745 (set_attr "unit" "i387,*")
2746 (set_attr "mode" "XF,SI")])
2747
2748 (define_split
2749 [(set (match_operand 0 "push_operand" "")
2750 (match_operand 1 "general_operand" ""))]
2751 "reload_completed
2752 && (GET_MODE (operands[0]) == XFmode
2753 || GET_MODE (operands[0]) == DFmode)
2754 && !ANY_FP_REG_P (operands[1])"
2755 [(const_int 0)]
2756 "ix86_split_long_move (operands); DONE;")
2757
2758 (define_split
2759 [(set (match_operand:XF 0 "push_operand" "")
2760 (match_operand:XF 1 "any_fp_register_operand" ""))]
2761 "!TARGET_64BIT"
2762 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2765
2766 (define_split
2767 [(set (match_operand:XF 0 "push_operand" "")
2768 (match_operand:XF 1 "any_fp_register_operand" ""))]
2769 "TARGET_64BIT"
2770 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773
2774 ;; Do not use integer registers when optimizing for size
2775 (define_insn "*movxf_nointeger"
2776 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2778 "optimize_size
2779 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780 && (reload_in_progress || reload_completed
2781 || GET_CODE (operands[1]) != CONST_DOUBLE
2782 || memory_operand (operands[0], XFmode))"
2783 {
2784 switch (which_alternative)
2785 {
2786 case 0:
2787 return output_387_reg_move (insn, operands);
2788
2789 case 1:
2790 /* There is no non-popping store to memory for XFmode. So if
2791 we need one, follow the store with a load. */
2792 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793 return "fstp%z0\t%y0\;fld%z0\t%y0";
2794 else
2795 return "fstp%z0\t%y0";
2796
2797 case 2:
2798 return standard_80387_constant_opcode (operands[1]);
2799
2800 case 3: case 4:
2801 return "#";
2802 default:
2803 gcc_unreachable ();
2804 }
2805 }
2806 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2807 (set_attr "mode" "XF,XF,XF,SI,SI")])
2808
2809 (define_insn "*movxf_integer"
2810 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2811 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2812 "!optimize_size
2813 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2814 && (reload_in_progress || reload_completed
2815 || GET_CODE (operands[1]) != CONST_DOUBLE
2816 || memory_operand (operands[0], XFmode))"
2817 {
2818 switch (which_alternative)
2819 {
2820 case 0:
2821 return output_387_reg_move (insn, operands);
2822
2823 case 1:
2824 /* There is no non-popping store to memory for XFmode. So if
2825 we need one, follow the store with a load. */
2826 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2827 return "fstp%z0\t%y0\;fld%z0\t%y0";
2828 else
2829 return "fstp%z0\t%y0";
2830
2831 case 2:
2832 return standard_80387_constant_opcode (operands[1]);
2833
2834 case 3: case 4:
2835 return "#";
2836
2837 default:
2838 gcc_unreachable ();
2839 }
2840 }
2841 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2842 (set_attr "mode" "XF,XF,XF,SI,SI")])
2843
2844 (define_split
2845 [(set (match_operand 0 "nonimmediate_operand" "")
2846 (match_operand 1 "general_operand" ""))]
2847 "reload_completed
2848 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2849 && GET_MODE (operands[0]) == XFmode
2850 && ! (ANY_FP_REG_P (operands[0]) ||
2851 (GET_CODE (operands[0]) == SUBREG
2852 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2853 && ! (ANY_FP_REG_P (operands[1]) ||
2854 (GET_CODE (operands[1]) == SUBREG
2855 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2856 [(const_int 0)]
2857 "ix86_split_long_move (operands); DONE;")
2858
2859 (define_split
2860 [(set (match_operand 0 "register_operand" "")
2861 (match_operand 1 "memory_operand" ""))]
2862 "reload_completed
2863 && GET_CODE (operands[1]) == MEM
2864 && (GET_MODE (operands[0]) == XFmode
2865 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2866 && constant_pool_reference_p (operands[1])"
2867 [(set (match_dup 0) (match_dup 1))]
2868 {
2869 rtx c = avoid_constant_pool_reference (operands[1]);
2870 rtx r = operands[0];
2871
2872 if (GET_CODE (r) == SUBREG)
2873 r = SUBREG_REG (r);
2874
2875 if (SSE_REG_P (r))
2876 {
2877 if (!standard_sse_constant_p (c))
2878 FAIL;
2879 }
2880 else if (FP_REG_P (r))
2881 {
2882 if (!standard_80387_constant_p (c))
2883 FAIL;
2884 }
2885 else if (MMX_REG_P (r))
2886 FAIL;
2887
2888 operands[1] = c;
2889 })
2890
2891 (define_insn "swapxf"
2892 [(set (match_operand:XF 0 "register_operand" "+f")
2893 (match_operand:XF 1 "register_operand" "+f"))
2894 (set (match_dup 1)
2895 (match_dup 0))]
2896 "TARGET_80387"
2897 {
2898 if (STACK_TOP_P (operands[0]))
2899 return "fxch\t%1";
2900 else
2901 return "fxch\t%0";
2902 }
2903 [(set_attr "type" "fxch")
2904 (set_attr "mode" "XF")])
2905
2906 (define_expand "movtf"
2907 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2908 (match_operand:TF 1 "nonimmediate_operand" ""))]
2909 "TARGET_64BIT"
2910 {
2911 ix86_expand_move (TFmode, operands);
2912 DONE;
2913 })
2914
2915 (define_insn "*movtf_internal"
2916 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2917 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2918 "TARGET_64BIT
2919 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2920 {
2921 switch (which_alternative)
2922 {
2923 case 0:
2924 case 1:
2925 return "#";
2926 case 2:
2927 if (get_attr_mode (insn) == MODE_V4SF)
2928 return "xorps\t%0, %0";
2929 else
2930 return "pxor\t%0, %0";
2931 case 3:
2932 case 4:
2933 if (get_attr_mode (insn) == MODE_V4SF)
2934 return "movaps\t{%1, %0|%0, %1}";
2935 else
2936 return "movdqa\t{%1, %0|%0, %1}";
2937 default:
2938 gcc_unreachable ();
2939 }
2940 }
2941 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2942 (set (attr "mode")
2943 (cond [(eq_attr "alternative" "2,3")
2944 (if_then_else
2945 (ne (symbol_ref "optimize_size")
2946 (const_int 0))
2947 (const_string "V4SF")
2948 (const_string "TI"))
2949 (eq_attr "alternative" "4")
2950 (if_then_else
2951 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2952 (const_int 0))
2953 (ne (symbol_ref "optimize_size")
2954 (const_int 0)))
2955 (const_string "V4SF")
2956 (const_string "TI"))]
2957 (const_string "DI")))])
2958
2959 (define_split
2960 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2961 (match_operand:TF 1 "general_operand" ""))]
2962 "reload_completed && !SSE_REG_P (operands[0])
2963 && !SSE_REG_P (operands[1])"
2964 [(const_int 0)]
2965 "ix86_split_long_move (operands); DONE;")
2966 \f
2967 ;; Zero extension instructions
2968
2969 (define_expand "zero_extendhisi2"
2970 [(set (match_operand:SI 0 "register_operand" "")
2971 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2972 ""
2973 {
2974 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2975 {
2976 operands[1] = force_reg (HImode, operands[1]);
2977 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2978 DONE;
2979 }
2980 })
2981
2982 (define_insn "zero_extendhisi2_and"
2983 [(set (match_operand:SI 0 "register_operand" "=r")
2984 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2985 (clobber (reg:CC FLAGS_REG))]
2986 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2987 "#"
2988 [(set_attr "type" "alu1")
2989 (set_attr "mode" "SI")])
2990
2991 (define_split
2992 [(set (match_operand:SI 0 "register_operand" "")
2993 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2994 (clobber (reg:CC FLAGS_REG))]
2995 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2996 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2997 (clobber (reg:CC FLAGS_REG))])]
2998 "")
2999
3000 (define_insn "*zero_extendhisi2_movzwl"
3001 [(set (match_operand:SI 0 "register_operand" "=r")
3002 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3003 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3004 "movz{wl|x}\t{%1, %0|%0, %1}"
3005 [(set_attr "type" "imovx")
3006 (set_attr "mode" "SI")])
3007
3008 (define_expand "zero_extendqihi2"
3009 [(parallel
3010 [(set (match_operand:HI 0 "register_operand" "")
3011 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3012 (clobber (reg:CC FLAGS_REG))])]
3013 ""
3014 "")
3015
3016 (define_insn "*zero_extendqihi2_and"
3017 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3018 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3019 (clobber (reg:CC FLAGS_REG))]
3020 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3021 "#"
3022 [(set_attr "type" "alu1")
3023 (set_attr "mode" "HI")])
3024
3025 (define_insn "*zero_extendqihi2_movzbw_and"
3026 [(set (match_operand:HI 0 "register_operand" "=r,r")
3027 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3028 (clobber (reg:CC FLAGS_REG))]
3029 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3030 "#"
3031 [(set_attr "type" "imovx,alu1")
3032 (set_attr "mode" "HI")])
3033
3034 ; zero extend to SImode here to avoid partial register stalls
3035 (define_insn "*zero_extendqihi2_movzbl"
3036 [(set (match_operand:HI 0 "register_operand" "=r")
3037 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3038 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3039 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3040 [(set_attr "type" "imovx")
3041 (set_attr "mode" "SI")])
3042
3043 ;; For the movzbw case strip only the clobber
3044 (define_split
3045 [(set (match_operand:HI 0 "register_operand" "")
3046 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3047 (clobber (reg:CC FLAGS_REG))]
3048 "reload_completed
3049 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3050 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3051 [(set (match_operand:HI 0 "register_operand" "")
3052 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3053
3054 ;; When source and destination does not overlap, clear destination
3055 ;; first and then do the movb
3056 (define_split
3057 [(set (match_operand:HI 0 "register_operand" "")
3058 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3059 (clobber (reg:CC FLAGS_REG))]
3060 "reload_completed
3061 && ANY_QI_REG_P (operands[0])
3062 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3063 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3064 [(set (match_dup 0) (const_int 0))
3065 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3066 "operands[2] = gen_lowpart (QImode, operands[0]);")
3067
3068 ;; Rest is handled by single and.
3069 (define_split
3070 [(set (match_operand:HI 0 "register_operand" "")
3071 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3072 (clobber (reg:CC FLAGS_REG))]
3073 "reload_completed
3074 && true_regnum (operands[0]) == true_regnum (operands[1])"
3075 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3076 (clobber (reg:CC FLAGS_REG))])]
3077 "")
3078
3079 (define_expand "zero_extendqisi2"
3080 [(parallel
3081 [(set (match_operand:SI 0 "register_operand" "")
3082 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3083 (clobber (reg:CC FLAGS_REG))])]
3084 ""
3085 "")
3086
3087 (define_insn "*zero_extendqisi2_and"
3088 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3089 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3090 (clobber (reg:CC FLAGS_REG))]
3091 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3092 "#"
3093 [(set_attr "type" "alu1")
3094 (set_attr "mode" "SI")])
3095
3096 (define_insn "*zero_extendqisi2_movzbw_and"
3097 [(set (match_operand:SI 0 "register_operand" "=r,r")
3098 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3099 (clobber (reg:CC FLAGS_REG))]
3100 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3101 "#"
3102 [(set_attr "type" "imovx,alu1")
3103 (set_attr "mode" "SI")])
3104
3105 (define_insn "*zero_extendqisi2_movzbw"
3106 [(set (match_operand:SI 0 "register_operand" "=r")
3107 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3108 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3109 "movz{bl|x}\t{%1, %0|%0, %1}"
3110 [(set_attr "type" "imovx")
3111 (set_attr "mode" "SI")])
3112
3113 ;; For the movzbl case strip only the clobber
3114 (define_split
3115 [(set (match_operand:SI 0 "register_operand" "")
3116 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3117 (clobber (reg:CC FLAGS_REG))]
3118 "reload_completed
3119 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3120 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3121 [(set (match_dup 0)
3122 (zero_extend:SI (match_dup 1)))])
3123
3124 ;; When source and destination does not overlap, clear destination
3125 ;; first and then do the movb
3126 (define_split
3127 [(set (match_operand:SI 0 "register_operand" "")
3128 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3129 (clobber (reg:CC FLAGS_REG))]
3130 "reload_completed
3131 && ANY_QI_REG_P (operands[0])
3132 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3133 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3134 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3135 [(set (match_dup 0) (const_int 0))
3136 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3137 "operands[2] = gen_lowpart (QImode, operands[0]);")
3138
3139 ;; Rest is handled by single and.
3140 (define_split
3141 [(set (match_operand:SI 0 "register_operand" "")
3142 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3143 (clobber (reg:CC FLAGS_REG))]
3144 "reload_completed
3145 && true_regnum (operands[0]) == true_regnum (operands[1])"
3146 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3147 (clobber (reg:CC FLAGS_REG))])]
3148 "")
3149
3150 ;; %%% Kill me once multi-word ops are sane.
3151 (define_expand "zero_extendsidi2"
3152 [(set (match_operand:DI 0 "register_operand" "=r")
3153 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3154 ""
3155 "if (!TARGET_64BIT)
3156 {
3157 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3158 DONE;
3159 }
3160 ")
3161
3162 (define_insn "zero_extendsidi2_32"
3163 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3164 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3165 (clobber (reg:CC FLAGS_REG))]
3166 "!TARGET_64BIT"
3167 "@
3168 #
3169 #
3170 #
3171 movd\t{%1, %0|%0, %1}
3172 movd\t{%1, %0|%0, %1}"
3173 [(set_attr "mode" "SI,SI,SI,DI,TI")
3174 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3175
3176 (define_insn "zero_extendsidi2_rex64"
3177 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3178 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3179 "TARGET_64BIT"
3180 "@
3181 mov\t{%k1, %k0|%k0, %k1}
3182 #
3183 movd\t{%1, %0|%0, %1}
3184 movd\t{%1, %0|%0, %1}"
3185 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3186 (set_attr "mode" "SI,DI,SI,SI")])
3187
3188 (define_split
3189 [(set (match_operand:DI 0 "memory_operand" "")
3190 (zero_extend:DI (match_dup 0)))]
3191 "TARGET_64BIT"
3192 [(set (match_dup 4) (const_int 0))]
3193 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3194
3195 (define_split
3196 [(set (match_operand:DI 0 "register_operand" "")
3197 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3198 (clobber (reg:CC FLAGS_REG))]
3199 "!TARGET_64BIT && reload_completed
3200 && true_regnum (operands[0]) == true_regnum (operands[1])"
3201 [(set (match_dup 4) (const_int 0))]
3202 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3203
3204 (define_split
3205 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3206 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3207 (clobber (reg:CC FLAGS_REG))]
3208 "!TARGET_64BIT && reload_completed
3209 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3210 [(set (match_dup 3) (match_dup 1))
3211 (set (match_dup 4) (const_int 0))]
3212 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3213
3214 (define_insn "zero_extendhidi2"
3215 [(set (match_operand:DI 0 "register_operand" "=r")
3216 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3217 "TARGET_64BIT"
3218 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3219 [(set_attr "type" "imovx")
3220 (set_attr "mode" "DI")])
3221
3222 (define_insn "zero_extendqidi2"
3223 [(set (match_operand:DI 0 "register_operand" "=r")
3224 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3225 "TARGET_64BIT"
3226 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3227 [(set_attr "type" "imovx")
3228 (set_attr "mode" "DI")])
3229 \f
3230 ;; Sign extension instructions
3231
3232 (define_expand "extendsidi2"
3233 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3234 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3235 (clobber (reg:CC FLAGS_REG))
3236 (clobber (match_scratch:SI 2 ""))])]
3237 ""
3238 {
3239 if (TARGET_64BIT)
3240 {
3241 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3242 DONE;
3243 }
3244 })
3245
3246 (define_insn "*extendsidi2_1"
3247 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3248 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3249 (clobber (reg:CC FLAGS_REG))
3250 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3251 "!TARGET_64BIT"
3252 "#")
3253
3254 (define_insn "extendsidi2_rex64"
3255 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3256 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3257 "TARGET_64BIT"
3258 "@
3259 {cltq|cdqe}
3260 movs{lq|x}\t{%1,%0|%0, %1}"
3261 [(set_attr "type" "imovx")
3262 (set_attr "mode" "DI")
3263 (set_attr "prefix_0f" "0")
3264 (set_attr "modrm" "0,1")])
3265
3266 (define_insn "extendhidi2"
3267 [(set (match_operand:DI 0 "register_operand" "=r")
3268 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3269 "TARGET_64BIT"
3270 "movs{wq|x}\t{%1,%0|%0, %1}"
3271 [(set_attr "type" "imovx")
3272 (set_attr "mode" "DI")])
3273
3274 (define_insn "extendqidi2"
3275 [(set (match_operand:DI 0 "register_operand" "=r")
3276 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3277 "TARGET_64BIT"
3278 "movs{bq|x}\t{%1,%0|%0, %1}"
3279 [(set_attr "type" "imovx")
3280 (set_attr "mode" "DI")])
3281
3282 ;; Extend to memory case when source register does die.
3283 (define_split
3284 [(set (match_operand:DI 0 "memory_operand" "")
3285 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3286 (clobber (reg:CC FLAGS_REG))
3287 (clobber (match_operand:SI 2 "register_operand" ""))]
3288 "(reload_completed
3289 && dead_or_set_p (insn, operands[1])
3290 && !reg_mentioned_p (operands[1], operands[0]))"
3291 [(set (match_dup 3) (match_dup 1))
3292 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3293 (clobber (reg:CC FLAGS_REG))])
3294 (set (match_dup 4) (match_dup 1))]
3295 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3296
3297 ;; Extend to memory case when source register does not die.
3298 (define_split
3299 [(set (match_operand:DI 0 "memory_operand" "")
3300 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3301 (clobber (reg:CC FLAGS_REG))
3302 (clobber (match_operand:SI 2 "register_operand" ""))]
3303 "reload_completed"
3304 [(const_int 0)]
3305 {
3306 split_di (&operands[0], 1, &operands[3], &operands[4]);
3307
3308 emit_move_insn (operands[3], operands[1]);
3309
3310 /* Generate a cltd if possible and doing so it profitable. */
3311 if (true_regnum (operands[1]) == 0
3312 && true_regnum (operands[2]) == 1
3313 && (optimize_size || TARGET_USE_CLTD))
3314 {
3315 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3316 }
3317 else
3318 {
3319 emit_move_insn (operands[2], operands[1]);
3320 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3321 }
3322 emit_move_insn (operands[4], operands[2]);
3323 DONE;
3324 })
3325
3326 ;; Extend to register case. Optimize case where source and destination
3327 ;; registers match and cases where we can use cltd.
3328 (define_split
3329 [(set (match_operand:DI 0 "register_operand" "")
3330 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3331 (clobber (reg:CC FLAGS_REG))
3332 (clobber (match_scratch:SI 2 ""))]
3333 "reload_completed"
3334 [(const_int 0)]
3335 {
3336 split_di (&operands[0], 1, &operands[3], &operands[4]);
3337
3338 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3339 emit_move_insn (operands[3], operands[1]);
3340
3341 /* Generate a cltd if possible and doing so it profitable. */
3342 if (true_regnum (operands[3]) == 0
3343 && (optimize_size || TARGET_USE_CLTD))
3344 {
3345 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3346 DONE;
3347 }
3348
3349 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3350 emit_move_insn (operands[4], operands[1]);
3351
3352 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3353 DONE;
3354 })
3355
3356 (define_insn "extendhisi2"
3357 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3358 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3359 ""
3360 {
3361 switch (get_attr_prefix_0f (insn))
3362 {
3363 case 0:
3364 return "{cwtl|cwde}";
3365 default:
3366 return "movs{wl|x}\t{%1,%0|%0, %1}";
3367 }
3368 }
3369 [(set_attr "type" "imovx")
3370 (set_attr "mode" "SI")
3371 (set (attr "prefix_0f")
3372 ;; movsx is short decodable while cwtl is vector decoded.
3373 (if_then_else (and (eq_attr "cpu" "!k6")
3374 (eq_attr "alternative" "0"))
3375 (const_string "0")
3376 (const_string "1")))
3377 (set (attr "modrm")
3378 (if_then_else (eq_attr "prefix_0f" "0")
3379 (const_string "0")
3380 (const_string "1")))])
3381
3382 (define_insn "*extendhisi2_zext"
3383 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3384 (zero_extend:DI
3385 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3386 "TARGET_64BIT"
3387 {
3388 switch (get_attr_prefix_0f (insn))
3389 {
3390 case 0:
3391 return "{cwtl|cwde}";
3392 default:
3393 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3394 }
3395 }
3396 [(set_attr "type" "imovx")
3397 (set_attr "mode" "SI")
3398 (set (attr "prefix_0f")
3399 ;; movsx is short decodable while cwtl is vector decoded.
3400 (if_then_else (and (eq_attr "cpu" "!k6")
3401 (eq_attr "alternative" "0"))
3402 (const_string "0")
3403 (const_string "1")))
3404 (set (attr "modrm")
3405 (if_then_else (eq_attr "prefix_0f" "0")
3406 (const_string "0")
3407 (const_string "1")))])
3408
3409 (define_insn "extendqihi2"
3410 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3411 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3412 ""
3413 {
3414 switch (get_attr_prefix_0f (insn))
3415 {
3416 case 0:
3417 return "{cbtw|cbw}";
3418 default:
3419 return "movs{bw|x}\t{%1,%0|%0, %1}";
3420 }
3421 }
3422 [(set_attr "type" "imovx")
3423 (set_attr "mode" "HI")
3424 (set (attr "prefix_0f")
3425 ;; movsx is short decodable while cwtl is vector decoded.
3426 (if_then_else (and (eq_attr "cpu" "!k6")
3427 (eq_attr "alternative" "0"))
3428 (const_string "0")
3429 (const_string "1")))
3430 (set (attr "modrm")
3431 (if_then_else (eq_attr "prefix_0f" "0")
3432 (const_string "0")
3433 (const_string "1")))])
3434
3435 (define_insn "extendqisi2"
3436 [(set (match_operand:SI 0 "register_operand" "=r")
3437 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3438 ""
3439 "movs{bl|x}\t{%1,%0|%0, %1}"
3440 [(set_attr "type" "imovx")
3441 (set_attr "mode" "SI")])
3442
3443 (define_insn "*extendqisi2_zext"
3444 [(set (match_operand:DI 0 "register_operand" "=r")
3445 (zero_extend:DI
3446 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3447 "TARGET_64BIT"
3448 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3449 [(set_attr "type" "imovx")
3450 (set_attr "mode" "SI")])
3451 \f
3452 ;; Conversions between float and double.
3453
3454 ;; These are all no-ops in the model used for the 80387. So just
3455 ;; emit moves.
3456
3457 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3458 (define_insn "*dummy_extendsfdf2"
3459 [(set (match_operand:DF 0 "push_operand" "=<")
3460 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3461 "0"
3462 "#")
3463
3464 (define_split
3465 [(set (match_operand:DF 0 "push_operand" "")
3466 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3467 "!TARGET_64BIT"
3468 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3469 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3470
3471 (define_split
3472 [(set (match_operand:DF 0 "push_operand" "")
3473 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3474 "TARGET_64BIT"
3475 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3476 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3477
3478 (define_insn "*dummy_extendsfxf2"
3479 [(set (match_operand:XF 0 "push_operand" "=<")
3480 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3481 "0"
3482 "#")
3483
3484 (define_split
3485 [(set (match_operand:XF 0 "push_operand" "")
3486 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3487 ""
3488 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3489 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3490 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3491
3492 (define_split
3493 [(set (match_operand:XF 0 "push_operand" "")
3494 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3495 "TARGET_64BIT"
3496 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3497 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3498 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3499
3500 (define_split
3501 [(set (match_operand:XF 0 "push_operand" "")
3502 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3503 ""
3504 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3505 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3506 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3507
3508 (define_split
3509 [(set (match_operand:XF 0 "push_operand" "")
3510 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3511 "TARGET_64BIT"
3512 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3513 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3514 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3515
3516 (define_expand "extendsfdf2"
3517 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3518 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3519 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3520 {
3521 /* ??? Needed for compress_float_constant since all fp constants
3522 are LEGITIMATE_CONSTANT_P. */
3523 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3524 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3525 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3526 operands[1] = force_reg (SFmode, operands[1]);
3527 })
3528
3529 (define_insn "*extendsfdf2_mixed"
3530 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3531 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3532 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3533 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3534 {
3535 switch (which_alternative)
3536 {
3537 case 0:
3538 return output_387_reg_move (insn, operands);
3539
3540 case 1:
3541 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3542 return "fstp%z0\t%y0";
3543 else
3544 return "fst%z0\t%y0";
3545
3546 case 2:
3547 return "cvtss2sd\t{%1, %0|%0, %1}";
3548
3549 default:
3550 gcc_unreachable ();
3551 }
3552 }
3553 [(set_attr "type" "fmov,fmov,ssecvt")
3554 (set_attr "mode" "SF,XF,DF")])
3555
3556 (define_insn "*extendsfdf2_sse"
3557 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3558 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3559 "TARGET_SSE2 && TARGET_SSE_MATH
3560 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3561 "cvtss2sd\t{%1, %0|%0, %1}"
3562 [(set_attr "type" "ssecvt")
3563 (set_attr "mode" "DF")])
3564
3565 (define_insn "*extendsfdf2_i387"
3566 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3567 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3568 "TARGET_80387
3569 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3570 {
3571 switch (which_alternative)
3572 {
3573 case 0:
3574 return output_387_reg_move (insn, operands);
3575
3576 case 1:
3577 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3578 return "fstp%z0\t%y0";
3579 else
3580 return "fst%z0\t%y0";
3581
3582 default:
3583 gcc_unreachable ();
3584 }
3585 }
3586 [(set_attr "type" "fmov")
3587 (set_attr "mode" "SF,XF")])
3588
3589 (define_expand "extendsfxf2"
3590 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3591 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3592 "TARGET_80387"
3593 {
3594 /* ??? Needed for compress_float_constant since all fp constants
3595 are LEGITIMATE_CONSTANT_P. */
3596 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3597 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3598 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3599 operands[1] = force_reg (SFmode, operands[1]);
3600 })
3601
3602 (define_insn "*extendsfxf2_i387"
3603 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3604 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3605 "TARGET_80387
3606 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3607 {
3608 switch (which_alternative)
3609 {
3610 case 0:
3611 return output_387_reg_move (insn, operands);
3612
3613 case 1:
3614 /* There is no non-popping store to memory for XFmode. So if
3615 we need one, follow the store with a load. */
3616 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3617 return "fstp%z0\t%y0";
3618 else
3619 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3620
3621 default:
3622 gcc_unreachable ();
3623 }
3624 }
3625 [(set_attr "type" "fmov")
3626 (set_attr "mode" "SF,XF")])
3627
3628 (define_expand "extenddfxf2"
3629 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3630 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3631 "TARGET_80387"
3632 {
3633 /* ??? Needed for compress_float_constant since all fp constants
3634 are LEGITIMATE_CONSTANT_P. */
3635 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3636 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3637 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3638 operands[1] = force_reg (DFmode, operands[1]);
3639 })
3640
3641 (define_insn "*extenddfxf2_i387"
3642 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3643 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3644 "TARGET_80387
3645 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3646 {
3647 switch (which_alternative)
3648 {
3649 case 0:
3650 return output_387_reg_move (insn, operands);
3651
3652 case 1:
3653 /* There is no non-popping store to memory for XFmode. So if
3654 we need one, follow the store with a load. */
3655 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3656 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3657 else
3658 return "fstp%z0\t%y0";
3659
3660 default:
3661 gcc_unreachable ();
3662 }
3663 }
3664 [(set_attr "type" "fmov")
3665 (set_attr "mode" "DF,XF")])
3666
3667 ;; %%% This seems bad bad news.
3668 ;; This cannot output into an f-reg because there is no way to be sure
3669 ;; of truncating in that case. Otherwise this is just like a simple move
3670 ;; insn. So we pretend we can output to a reg in order to get better
3671 ;; register preferencing, but we really use a stack slot.
3672
3673 ;; Conversion from DFmode to SFmode.
3674
3675 (define_expand "truncdfsf2"
3676 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3677 (float_truncate:SF
3678 (match_operand:DF 1 "nonimmediate_operand" "")))]
3679 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3680 {
3681 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3682 operands[1] = force_reg (DFmode, operands[1]);
3683
3684 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3685 ;
3686 else if (flag_unsafe_math_optimizations)
3687 ;
3688 else
3689 {
3690 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3691 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3692 DONE;
3693 }
3694 })
3695
3696 (define_expand "truncdfsf2_with_temp"
3697 [(parallel [(set (match_operand:SF 0 "" "")
3698 (float_truncate:SF (match_operand:DF 1 "" "")))
3699 (clobber (match_operand:SF 2 "" ""))])]
3700 "")
3701
3702 (define_insn "*truncdfsf_fast_mixed"
3703 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3704 (float_truncate:SF
3705 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3706 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3707 {
3708 switch (which_alternative)
3709 {
3710 case 0:
3711 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712 return "fstp%z0\t%y0";
3713 else
3714 return "fst%z0\t%y0";
3715 case 1:
3716 return output_387_reg_move (insn, operands);
3717 case 2:
3718 return "cvtsd2ss\t{%1, %0|%0, %1}";
3719 default:
3720 gcc_unreachable ();
3721 }
3722 }
3723 [(set_attr "type" "fmov,fmov,ssecvt")
3724 (set_attr "mode" "SF")])
3725
3726 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3727 ;; because nothing we do here is unsafe.
3728 (define_insn "*truncdfsf_fast_sse"
3729 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3730 (float_truncate:SF
3731 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3732 "TARGET_SSE2 && TARGET_SSE_MATH"
3733 "cvtsd2ss\t{%1, %0|%0, %1}"
3734 [(set_attr "type" "ssecvt")
3735 (set_attr "mode" "SF")])
3736
3737 (define_insn "*truncdfsf_fast_i387"
3738 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3739 (float_truncate:SF
3740 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3741 "TARGET_80387 && flag_unsafe_math_optimizations"
3742 "* return output_387_reg_move (insn, operands);"
3743 [(set_attr "type" "fmov")
3744 (set_attr "mode" "SF")])
3745
3746 (define_insn "*truncdfsf_mixed"
3747 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3748 (float_truncate:SF
3749 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3750 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3751 "TARGET_MIX_SSE_I387"
3752 {
3753 switch (which_alternative)
3754 {
3755 case 0:
3756 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3757 return "fstp%z0\t%y0";
3758 else
3759 return "fst%z0\t%y0";
3760 case 1:
3761 return "#";
3762 case 2:
3763 return "cvtsd2ss\t{%1, %0|%0, %1}";
3764 default:
3765 gcc_unreachable ();
3766 }
3767 }
3768 [(set_attr "type" "fmov,multi,ssecvt")
3769 (set_attr "unit" "*,i387,*")
3770 (set_attr "mode" "SF")])
3771
3772 (define_insn "*truncdfsf_i387"
3773 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3774 (float_truncate:SF
3775 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3776 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3777 "TARGET_80387"
3778 {
3779 switch (which_alternative)
3780 {
3781 case 0:
3782 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3783 return "fstp%z0\t%y0";
3784 else
3785 return "fst%z0\t%y0";
3786 case 1:
3787 return "#";
3788 default:
3789 gcc_unreachable ();
3790 }
3791 }
3792 [(set_attr "type" "fmov,multi")
3793 (set_attr "unit" "*,i387")
3794 (set_attr "mode" "SF")])
3795
3796 (define_insn "*truncdfsf2_i387_1"
3797 [(set (match_operand:SF 0 "memory_operand" "=m")
3798 (float_truncate:SF
3799 (match_operand:DF 1 "register_operand" "f")))]
3800 "TARGET_80387
3801 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3802 && !TARGET_MIX_SSE_I387"
3803 {
3804 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3805 return "fstp%z0\t%y0";
3806 else
3807 return "fst%z0\t%y0";
3808 }
3809 [(set_attr "type" "fmov")
3810 (set_attr "mode" "SF")])
3811
3812 (define_split
3813 [(set (match_operand:SF 0 "register_operand" "")
3814 (float_truncate:SF
3815 (match_operand:DF 1 "fp_register_operand" "")))
3816 (clobber (match_operand 2 "" ""))]
3817 "reload_completed"
3818 [(set (match_dup 2) (match_dup 1))
3819 (set (match_dup 0) (match_dup 2))]
3820 {
3821 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3822 })
3823
3824 ;; Conversion from XFmode to SFmode.
3825
3826 (define_expand "truncxfsf2"
3827 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3828 (float_truncate:SF
3829 (match_operand:XF 1 "register_operand" "")))
3830 (clobber (match_dup 2))])]
3831 "TARGET_80387"
3832 {
3833 if (flag_unsafe_math_optimizations)
3834 {
3835 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3836 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3837 if (reg != operands[0])
3838 emit_move_insn (operands[0], reg);
3839 DONE;
3840 }
3841 else
3842 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3843 })
3844
3845 (define_insn "*truncxfsf2_mixed"
3846 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3847 (float_truncate:SF
3848 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3849 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3850 "TARGET_MIX_SSE_I387"
3851 {
3852 gcc_assert (!which_alternative);
3853 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3854 return "fstp%z0\t%y0";
3855 else
3856 return "fst%z0\t%y0";
3857 }
3858 [(set_attr "type" "fmov,multi,multi,multi")
3859 (set_attr "unit" "*,i387,i387,i387")
3860 (set_attr "mode" "SF")])
3861
3862 (define_insn "truncxfsf2_i387_noop"
3863 [(set (match_operand:SF 0 "register_operand" "=f")
3864 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3865 "TARGET_80387 && flag_unsafe_math_optimizations"
3866 {
3867 return output_387_reg_move (insn, operands);
3868 }
3869 [(set_attr "type" "fmov")
3870 (set_attr "mode" "SF")])
3871
3872 (define_insn "*truncxfsf2_i387"
3873 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3874 (float_truncate:SF
3875 (match_operand:XF 1 "register_operand" "f,f,f")))
3876 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3877 "TARGET_80387"
3878 {
3879 gcc_assert (!which_alternative);
3880 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3881 return "fstp%z0\t%y0";
3882 else
3883 return "fst%z0\t%y0";
3884 }
3885 [(set_attr "type" "fmov,multi,multi")
3886 (set_attr "unit" "*,i387,i387")
3887 (set_attr "mode" "SF")])
3888
3889 (define_insn "*truncxfsf2_i387_1"
3890 [(set (match_operand:SF 0 "memory_operand" "=m")
3891 (float_truncate:SF
3892 (match_operand:XF 1 "register_operand" "f")))]
3893 "TARGET_80387"
3894 {
3895 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3896 return "fstp%z0\t%y0";
3897 else
3898 return "fst%z0\t%y0";
3899 }
3900 [(set_attr "type" "fmov")
3901 (set_attr "mode" "SF")])
3902
3903 (define_split
3904 [(set (match_operand:SF 0 "register_operand" "")
3905 (float_truncate:SF
3906 (match_operand:XF 1 "register_operand" "")))
3907 (clobber (match_operand:SF 2 "memory_operand" ""))]
3908 "TARGET_80387 && reload_completed"
3909 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3910 (set (match_dup 0) (match_dup 2))]
3911 "")
3912
3913 (define_split
3914 [(set (match_operand:SF 0 "memory_operand" "")
3915 (float_truncate:SF
3916 (match_operand:XF 1 "register_operand" "")))
3917 (clobber (match_operand:SF 2 "memory_operand" ""))]
3918 "TARGET_80387"
3919 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3920 "")
3921
3922 ;; Conversion from XFmode to DFmode.
3923
3924 (define_expand "truncxfdf2"
3925 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3926 (float_truncate:DF
3927 (match_operand:XF 1 "register_operand" "")))
3928 (clobber (match_dup 2))])]
3929 "TARGET_80387"
3930 {
3931 if (flag_unsafe_math_optimizations)
3932 {
3933 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3934 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3935 if (reg != operands[0])
3936 emit_move_insn (operands[0], reg);
3937 DONE;
3938 }
3939 else
3940 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3941 })
3942
3943 (define_insn "*truncxfdf2_mixed"
3944 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3945 (float_truncate:DF
3946 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3947 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3948 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3949 {
3950 gcc_assert (!which_alternative);
3951 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3952 return "fstp%z0\t%y0";
3953 else
3954 return "fst%z0\t%y0";
3955 }
3956 [(set_attr "type" "fmov,multi,multi,multi")
3957 (set_attr "unit" "*,i387,i387,i387")
3958 (set_attr "mode" "DF")])
3959
3960 (define_insn "truncxfdf2_i387_noop"
3961 [(set (match_operand:DF 0 "register_operand" "=f")
3962 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3963 "TARGET_80387 && flag_unsafe_math_optimizations"
3964 {
3965 return output_387_reg_move (insn, operands);
3966 }
3967 [(set_attr "type" "fmov")
3968 (set_attr "mode" "DF")])
3969
3970 (define_insn "*truncxfdf2_i387"
3971 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3972 (float_truncate:DF
3973 (match_operand:XF 1 "register_operand" "f,f,f")))
3974 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3975 "TARGET_80387"
3976 {
3977 gcc_assert (!which_alternative);
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,multi,multi")
3984 (set_attr "unit" "*,i387,i387")
3985 (set_attr "mode" "DF")])
3986
3987 (define_insn "*truncxfdf2_i387_1"
3988 [(set (match_operand:DF 0 "memory_operand" "=m")
3989 (float_truncate:DF
3990 (match_operand:XF 1 "register_operand" "f")))]
3991 "TARGET_80387"
3992 {
3993 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3994 return "fstp%z0\t%y0";
3995 else
3996 return "fst%z0\t%y0";
3997 }
3998 [(set_attr "type" "fmov")
3999 (set_attr "mode" "DF")])
4000
4001 (define_split
4002 [(set (match_operand:DF 0 "register_operand" "")
4003 (float_truncate:DF
4004 (match_operand:XF 1 "register_operand" "")))
4005 (clobber (match_operand:DF 2 "memory_operand" ""))]
4006 "TARGET_80387 && reload_completed"
4007 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4008 (set (match_dup 0) (match_dup 2))]
4009 "")
4010
4011 (define_split
4012 [(set (match_operand:DF 0 "memory_operand" "")
4013 (float_truncate:DF
4014 (match_operand:XF 1 "register_operand" "")))
4015 (clobber (match_operand:DF 2 "memory_operand" ""))]
4016 "TARGET_80387"
4017 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4018 "")
4019 \f
4020 ;; Signed conversion to DImode.
4021
4022 (define_expand "fix_truncxfdi2"
4023 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4024 (fix:DI (match_operand:XF 1 "register_operand" "")))
4025 (clobber (reg:CC FLAGS_REG))])]
4026 "TARGET_80387"
4027 {
4028 if (TARGET_FISTTP)
4029 {
4030 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4031 DONE;
4032 }
4033 })
4034
4035 (define_expand "fix_trunc<mode>di2"
4036 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4037 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4038 (clobber (reg:CC FLAGS_REG))])]
4039 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4040 {
4041 if (TARGET_FISTTP
4042 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4043 {
4044 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4045 DONE;
4046 }
4047 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4048 {
4049 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4050 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4051 if (out != operands[0])
4052 emit_move_insn (operands[0], out);
4053 DONE;
4054 }
4055 })
4056
4057 ;; Signed conversion to SImode.
4058
4059 (define_expand "fix_truncxfsi2"
4060 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4061 (fix:SI (match_operand:XF 1 "register_operand" "")))
4062 (clobber (reg:CC FLAGS_REG))])]
4063 "TARGET_80387"
4064 {
4065 if (TARGET_FISTTP)
4066 {
4067 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4068 DONE;
4069 }
4070 })
4071
4072 (define_expand "fix_trunc<mode>si2"
4073 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4074 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4075 (clobber (reg:CC FLAGS_REG))])]
4076 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4077 {
4078 if (TARGET_FISTTP
4079 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4080 {
4081 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4082 DONE;
4083 }
4084 if (SSE_FLOAT_MODE_P (<MODE>mode))
4085 {
4086 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4087 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4088 if (out != operands[0])
4089 emit_move_insn (operands[0], out);
4090 DONE;
4091 }
4092 })
4093
4094 ;; Signed conversion to HImode.
4095
4096 (define_expand "fix_trunc<mode>hi2"
4097 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4098 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4099 (clobber (reg:CC FLAGS_REG))])]
4100 "TARGET_80387
4101 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4102 {
4103 if (TARGET_FISTTP)
4104 {
4105 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4106 DONE;
4107 }
4108 })
4109
4110 ;; When SSE is available, it is always faster to use it!
4111 (define_insn "fix_truncsfdi_sse"
4112 [(set (match_operand:DI 0 "register_operand" "=r,r")
4113 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4114 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4115 "cvttss2si{q}\t{%1, %0|%0, %1}"
4116 [(set_attr "type" "sseicvt")
4117 (set_attr "mode" "SF")
4118 (set_attr "athlon_decode" "double,vector")])
4119
4120 (define_insn "fix_truncdfdi_sse"
4121 [(set (match_operand:DI 0 "register_operand" "=r,r")
4122 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4123 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4124 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4125 [(set_attr "type" "sseicvt")
4126 (set_attr "mode" "DF")
4127 (set_attr "athlon_decode" "double,vector")])
4128
4129 (define_insn "fix_truncsfsi_sse"
4130 [(set (match_operand:SI 0 "register_operand" "=r,r")
4131 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4132 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4133 "cvttss2si\t{%1, %0|%0, %1}"
4134 [(set_attr "type" "sseicvt")
4135 (set_attr "mode" "DF")
4136 (set_attr "athlon_decode" "double,vector")])
4137
4138 (define_insn "fix_truncdfsi_sse"
4139 [(set (match_operand:SI 0 "register_operand" "=r,r")
4140 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4141 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4142 "cvttsd2si\t{%1, %0|%0, %1}"
4143 [(set_attr "type" "sseicvt")
4144 (set_attr "mode" "DF")
4145 (set_attr "athlon_decode" "double,vector")])
4146
4147 ;; Avoid vector decoded forms of the instruction.
4148 (define_peephole2
4149 [(match_scratch:DF 2 "Y")
4150 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4151 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4152 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4153 [(set (match_dup 2) (match_dup 1))
4154 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4155 "")
4156
4157 (define_peephole2
4158 [(match_scratch:SF 2 "x")
4159 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4160 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4161 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4162 [(set (match_dup 2) (match_dup 1))
4163 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4164 "")
4165
4166 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4167 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4168 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4169 "TARGET_FISTTP
4170 && FLOAT_MODE_P (GET_MODE (operands[1]))
4171 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4172 && (TARGET_64BIT || <MODE>mode != DImode))
4173 && TARGET_SSE_MATH)
4174 && !(reload_completed || reload_in_progress)"
4175 "#"
4176 "&& 1"
4177 [(const_int 0)]
4178 {
4179 if (memory_operand (operands[0], VOIDmode))
4180 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4181 else
4182 {
4183 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4184 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4185 operands[1],
4186 operands[2]));
4187 }
4188 DONE;
4189 }
4190 [(set_attr "type" "fisttp")
4191 (set_attr "mode" "<MODE>")])
4192
4193 (define_insn "fix_trunc<mode>_i387_fisttp"
4194 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4195 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4196 (clobber (match_scratch:XF 2 "=&1f"))]
4197 "TARGET_FISTTP
4198 && FLOAT_MODE_P (GET_MODE (operands[1]))
4199 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4200 && (TARGET_64BIT || <MODE>mode != DImode))
4201 && TARGET_SSE_MATH)"
4202 "* return output_fix_trunc (insn, operands, 1);"
4203 [(set_attr "type" "fisttp")
4204 (set_attr "mode" "<MODE>")])
4205
4206 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4207 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4208 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4209 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4210 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4211 "TARGET_FISTTP
4212 && FLOAT_MODE_P (GET_MODE (operands[1]))
4213 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4214 && (TARGET_64BIT || <MODE>mode != DImode))
4215 && TARGET_SSE_MATH)"
4216 "#"
4217 [(set_attr "type" "fisttp")
4218 (set_attr "mode" "<MODE>")])
4219
4220 (define_split
4221 [(set (match_operand:X87MODEI 0 "register_operand" "")
4222 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4223 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4224 (clobber (match_scratch 3 ""))]
4225 "reload_completed"
4226 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4227 (clobber (match_dup 3))])
4228 (set (match_dup 0) (match_dup 2))]
4229 "")
4230
4231 (define_split
4232 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4233 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4234 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4235 (clobber (match_scratch 3 ""))]
4236 "reload_completed"
4237 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4238 (clobber (match_dup 3))])]
4239 "")
4240
4241 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4242 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4243 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4244 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4245 ;; function in i386.c.
4246 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4247 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4248 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4249 (clobber (reg:CC FLAGS_REG))]
4250 "TARGET_80387 && !TARGET_FISTTP
4251 && FLOAT_MODE_P (GET_MODE (operands[1]))
4252 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4253 && (TARGET_64BIT || <MODE>mode != DImode))
4254 && !(reload_completed || reload_in_progress)"
4255 "#"
4256 "&& 1"
4257 [(const_int 0)]
4258 {
4259 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4260
4261 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4262 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4263 if (memory_operand (operands[0], VOIDmode))
4264 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4265 operands[2], operands[3]));
4266 else
4267 {
4268 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4269 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4270 operands[2], operands[3],
4271 operands[4]));
4272 }
4273 DONE;
4274 }
4275 [(set_attr "type" "fistp")
4276 (set_attr "i387_cw" "trunc")
4277 (set_attr "mode" "<MODE>")])
4278
4279 (define_insn "fix_truncdi_i387"
4280 [(set (match_operand:DI 0 "memory_operand" "=m")
4281 (fix:DI (match_operand 1 "register_operand" "f")))
4282 (use (match_operand:HI 2 "memory_operand" "m"))
4283 (use (match_operand:HI 3 "memory_operand" "m"))
4284 (clobber (match_scratch:XF 4 "=&1f"))]
4285 "TARGET_80387 && !TARGET_FISTTP
4286 && FLOAT_MODE_P (GET_MODE (operands[1]))
4287 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4288 "* return output_fix_trunc (insn, operands, 0);"
4289 [(set_attr "type" "fistp")
4290 (set_attr "i387_cw" "trunc")
4291 (set_attr "mode" "DI")])
4292
4293 (define_insn "fix_truncdi_i387_with_temp"
4294 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4295 (fix:DI (match_operand 1 "register_operand" "f,f")))
4296 (use (match_operand:HI 2 "memory_operand" "m,m"))
4297 (use (match_operand:HI 3 "memory_operand" "m,m"))
4298 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4299 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4300 "TARGET_80387 && !TARGET_FISTTP
4301 && FLOAT_MODE_P (GET_MODE (operands[1]))
4302 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4303 "#"
4304 [(set_attr "type" "fistp")
4305 (set_attr "i387_cw" "trunc")
4306 (set_attr "mode" "DI")])
4307
4308 (define_split
4309 [(set (match_operand:DI 0 "register_operand" "")
4310 (fix:DI (match_operand 1 "register_operand" "")))
4311 (use (match_operand:HI 2 "memory_operand" ""))
4312 (use (match_operand:HI 3 "memory_operand" ""))
4313 (clobber (match_operand:DI 4 "memory_operand" ""))
4314 (clobber (match_scratch 5 ""))]
4315 "reload_completed"
4316 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4317 (use (match_dup 2))
4318 (use (match_dup 3))
4319 (clobber (match_dup 5))])
4320 (set (match_dup 0) (match_dup 4))]
4321 "")
4322
4323 (define_split
4324 [(set (match_operand:DI 0 "memory_operand" "")
4325 (fix:DI (match_operand 1 "register_operand" "")))
4326 (use (match_operand:HI 2 "memory_operand" ""))
4327 (use (match_operand:HI 3 "memory_operand" ""))
4328 (clobber (match_operand:DI 4 "memory_operand" ""))
4329 (clobber (match_scratch 5 ""))]
4330 "reload_completed"
4331 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4332 (use (match_dup 2))
4333 (use (match_dup 3))
4334 (clobber (match_dup 5))])]
4335 "")
4336
4337 (define_insn "fix_trunc<mode>_i387"
4338 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4339 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4340 (use (match_operand:HI 2 "memory_operand" "m"))
4341 (use (match_operand:HI 3 "memory_operand" "m"))]
4342 "TARGET_80387 && !TARGET_FISTTP
4343 && FLOAT_MODE_P (GET_MODE (operands[1]))
4344 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4345 "* return output_fix_trunc (insn, operands, 0);"
4346 [(set_attr "type" "fistp")
4347 (set_attr "i387_cw" "trunc")
4348 (set_attr "mode" "<MODE>")])
4349
4350 (define_insn "fix_trunc<mode>_i387_with_temp"
4351 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4352 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4353 (use (match_operand:HI 2 "memory_operand" "m,m"))
4354 (use (match_operand:HI 3 "memory_operand" "m,m"))
4355 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4356 "TARGET_80387 && !TARGET_FISTTP
4357 && FLOAT_MODE_P (GET_MODE (operands[1]))
4358 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4359 "#"
4360 [(set_attr "type" "fistp")
4361 (set_attr "i387_cw" "trunc")
4362 (set_attr "mode" "<MODE>")])
4363
4364 (define_split
4365 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4366 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4367 (use (match_operand:HI 2 "memory_operand" ""))
4368 (use (match_operand:HI 3 "memory_operand" ""))
4369 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4370 "reload_completed"
4371 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4372 (use (match_dup 2))
4373 (use (match_dup 3))])
4374 (set (match_dup 0) (match_dup 4))]
4375 "")
4376
4377 (define_split
4378 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4379 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4380 (use (match_operand:HI 2 "memory_operand" ""))
4381 (use (match_operand:HI 3 "memory_operand" ""))
4382 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4383 "reload_completed"
4384 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4385 (use (match_dup 2))
4386 (use (match_dup 3))])]
4387 "")
4388
4389 (define_insn "x86_fnstcw_1"
4390 [(set (match_operand:HI 0 "memory_operand" "=m")
4391 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4392 "TARGET_80387"
4393 "fnstcw\t%0"
4394 [(set_attr "length" "2")
4395 (set_attr "mode" "HI")
4396 (set_attr "unit" "i387")])
4397
4398 (define_insn "x86_fldcw_1"
4399 [(set (reg:HI FPSR_REG)
4400 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4401 "TARGET_80387"
4402 "fldcw\t%0"
4403 [(set_attr "length" "2")
4404 (set_attr "mode" "HI")
4405 (set_attr "unit" "i387")
4406 (set_attr "athlon_decode" "vector")])
4407 \f
4408 ;; Conversion between fixed point and floating point.
4409
4410 ;; Even though we only accept memory inputs, the backend _really_
4411 ;; wants to be able to do this between registers.
4412
4413 (define_expand "floathisf2"
4414 [(set (match_operand:SF 0 "register_operand" "")
4415 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4416 "TARGET_80387 || TARGET_SSE_MATH"
4417 {
4418 if (TARGET_SSE_MATH)
4419 {
4420 emit_insn (gen_floatsisf2 (operands[0],
4421 convert_to_mode (SImode, operands[1], 0)));
4422 DONE;
4423 }
4424 })
4425
4426 (define_insn "*floathisf2_i387"
4427 [(set (match_operand:SF 0 "register_operand" "=f,f")
4428 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4429 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4430 "@
4431 fild%z1\t%1
4432 #"
4433 [(set_attr "type" "fmov,multi")
4434 (set_attr "mode" "SF")
4435 (set_attr "unit" "*,i387")
4436 (set_attr "fp_int_src" "true")])
4437
4438 (define_expand "floatsisf2"
4439 [(set (match_operand:SF 0 "register_operand" "")
4440 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4441 "TARGET_80387 || TARGET_SSE_MATH"
4442 "")
4443
4444 (define_insn "*floatsisf2_mixed"
4445 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4446 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4447 "TARGET_MIX_SSE_I387"
4448 "@
4449 fild%z1\t%1
4450 #
4451 cvtsi2ss\t{%1, %0|%0, %1}
4452 cvtsi2ss\t{%1, %0|%0, %1}"
4453 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4454 (set_attr "mode" "SF")
4455 (set_attr "unit" "*,i387,*,*")
4456 (set_attr "athlon_decode" "*,*,vector,double")
4457 (set_attr "fp_int_src" "true")])
4458
4459 (define_insn "*floatsisf2_sse"
4460 [(set (match_operand:SF 0 "register_operand" "=x,x")
4461 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4462 "TARGET_SSE_MATH"
4463 "cvtsi2ss\t{%1, %0|%0, %1}"
4464 [(set_attr "type" "sseicvt")
4465 (set_attr "mode" "SF")
4466 (set_attr "athlon_decode" "vector,double")
4467 (set_attr "fp_int_src" "true")])
4468
4469 (define_insn "*floatsisf2_i387"
4470 [(set (match_operand:SF 0 "register_operand" "=f,f")
4471 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4472 "TARGET_80387"
4473 "@
4474 fild%z1\t%1
4475 #"
4476 [(set_attr "type" "fmov,multi")
4477 (set_attr "mode" "SF")
4478 (set_attr "unit" "*,i387")
4479 (set_attr "fp_int_src" "true")])
4480
4481 (define_expand "floatdisf2"
4482 [(set (match_operand:SF 0 "register_operand" "")
4483 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4484 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4485 "")
4486
4487 (define_insn "*floatdisf2_mixed"
4488 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4489 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4490 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4491 "@
4492 fild%z1\t%1
4493 #
4494 cvtsi2ss{q}\t{%1, %0|%0, %1}
4495 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4496 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4497 (set_attr "mode" "SF")
4498 (set_attr "unit" "*,i387,*,*")
4499 (set_attr "athlon_decode" "*,*,vector,double")
4500 (set_attr "fp_int_src" "true")])
4501
4502 (define_insn "*floatdisf2_sse"
4503 [(set (match_operand:SF 0 "register_operand" "=x,x")
4504 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4505 "TARGET_64BIT && TARGET_SSE_MATH"
4506 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4507 [(set_attr "type" "sseicvt")
4508 (set_attr "mode" "SF")
4509 (set_attr "athlon_decode" "vector,double")
4510 (set_attr "fp_int_src" "true")])
4511
4512 (define_insn "*floatdisf2_i387"
4513 [(set (match_operand:SF 0 "register_operand" "=f,f")
4514 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4515 "TARGET_80387"
4516 "@
4517 fild%z1\t%1
4518 #"
4519 [(set_attr "type" "fmov,multi")
4520 (set_attr "mode" "SF")
4521 (set_attr "unit" "*,i387")
4522 (set_attr "fp_int_src" "true")])
4523
4524 (define_expand "floathidf2"
4525 [(set (match_operand:DF 0 "register_operand" "")
4526 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4527 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4528 {
4529 if (TARGET_SSE2 && TARGET_SSE_MATH)
4530 {
4531 emit_insn (gen_floatsidf2 (operands[0],
4532 convert_to_mode (SImode, operands[1], 0)));
4533 DONE;
4534 }
4535 })
4536
4537 (define_insn "*floathidf2_i387"
4538 [(set (match_operand:DF 0 "register_operand" "=f,f")
4539 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4540 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4541 "@
4542 fild%z1\t%1
4543 #"
4544 [(set_attr "type" "fmov,multi")
4545 (set_attr "mode" "DF")
4546 (set_attr "unit" "*,i387")
4547 (set_attr "fp_int_src" "true")])
4548
4549 (define_expand "floatsidf2"
4550 [(set (match_operand:DF 0 "register_operand" "")
4551 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4552 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4553 "")
4554
4555 (define_insn "*floatsidf2_mixed"
4556 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4557 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4558 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4559 "@
4560 fild%z1\t%1
4561 #
4562 cvtsi2sd\t{%1, %0|%0, %1}
4563 cvtsi2sd\t{%1, %0|%0, %1}"
4564 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4565 (set_attr "mode" "DF")
4566 (set_attr "unit" "*,i387,*,*")
4567 (set_attr "athlon_decode" "*,*,double,direct")
4568 (set_attr "fp_int_src" "true")])
4569
4570 (define_insn "*floatsidf2_sse"
4571 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4572 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4573 "TARGET_SSE2 && TARGET_SSE_MATH"
4574 "cvtsi2sd\t{%1, %0|%0, %1}"
4575 [(set_attr "type" "sseicvt")
4576 (set_attr "mode" "DF")
4577 (set_attr "athlon_decode" "double,direct")
4578 (set_attr "fp_int_src" "true")])
4579
4580 (define_insn "*floatsidf2_i387"
4581 [(set (match_operand:DF 0 "register_operand" "=f,f")
4582 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4583 "TARGET_80387"
4584 "@
4585 fild%z1\t%1
4586 #"
4587 [(set_attr "type" "fmov,multi")
4588 (set_attr "mode" "DF")
4589 (set_attr "unit" "*,i387")
4590 (set_attr "fp_int_src" "true")])
4591
4592 (define_expand "floatdidf2"
4593 [(set (match_operand:DF 0 "register_operand" "")
4594 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4595 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4596 "")
4597
4598 (define_insn "*floatdidf2_mixed"
4599 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4600 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4601 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4602 "@
4603 fild%z1\t%1
4604 #
4605 cvtsi2sd{q}\t{%1, %0|%0, %1}
4606 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4607 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4608 (set_attr "mode" "DF")
4609 (set_attr "unit" "*,i387,*,*")
4610 (set_attr "athlon_decode" "*,*,double,direct")
4611 (set_attr "fp_int_src" "true")])
4612
4613 (define_insn "*floatdidf2_sse"
4614 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4615 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4616 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4617 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4618 [(set_attr "type" "sseicvt")
4619 (set_attr "mode" "DF")
4620 (set_attr "athlon_decode" "double,direct")
4621 (set_attr "fp_int_src" "true")])
4622
4623 (define_insn "*floatdidf2_i387"
4624 [(set (match_operand:DF 0 "register_operand" "=f,f")
4625 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4626 "TARGET_80387"
4627 "@
4628 fild%z1\t%1
4629 #"
4630 [(set_attr "type" "fmov,multi")
4631 (set_attr "mode" "DF")
4632 (set_attr "unit" "*,i387")
4633 (set_attr "fp_int_src" "true")])
4634
4635 (define_insn "floathixf2"
4636 [(set (match_operand:XF 0 "register_operand" "=f,f")
4637 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4638 "TARGET_80387"
4639 "@
4640 fild%z1\t%1
4641 #"
4642 [(set_attr "type" "fmov,multi")
4643 (set_attr "mode" "XF")
4644 (set_attr "unit" "*,i387")
4645 (set_attr "fp_int_src" "true")])
4646
4647 (define_insn "floatsixf2"
4648 [(set (match_operand:XF 0 "register_operand" "=f,f")
4649 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4650 "TARGET_80387"
4651 "@
4652 fild%z1\t%1
4653 #"
4654 [(set_attr "type" "fmov,multi")
4655 (set_attr "mode" "XF")
4656 (set_attr "unit" "*,i387")
4657 (set_attr "fp_int_src" "true")])
4658
4659 (define_insn "floatdixf2"
4660 [(set (match_operand:XF 0 "register_operand" "=f,f")
4661 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4662 "TARGET_80387"
4663 "@
4664 fild%z1\t%1
4665 #"
4666 [(set_attr "type" "fmov,multi")
4667 (set_attr "mode" "XF")
4668 (set_attr "unit" "*,i387")
4669 (set_attr "fp_int_src" "true")])
4670
4671 ;; %%% Kill these when reload knows how to do it.
4672 (define_split
4673 [(set (match_operand 0 "fp_register_operand" "")
4674 (float (match_operand 1 "register_operand" "")))]
4675 "reload_completed
4676 && TARGET_80387
4677 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4678 [(const_int 0)]
4679 {
4680 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4681 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4682 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4683 ix86_free_from_memory (GET_MODE (operands[1]));
4684 DONE;
4685 })
4686
4687 (define_expand "floatunssisf2"
4688 [(use (match_operand:SF 0 "register_operand" ""))
4689 (use (match_operand:SI 1 "register_operand" ""))]
4690 "!TARGET_64BIT && TARGET_SSE_MATH"
4691 "x86_emit_floatuns (operands); DONE;")
4692
4693 (define_expand "floatunsdisf2"
4694 [(use (match_operand:SF 0 "register_operand" ""))
4695 (use (match_operand:DI 1 "register_operand" ""))]
4696 "TARGET_64BIT && TARGET_SSE_MATH"
4697 "x86_emit_floatuns (operands); DONE;")
4698
4699 (define_expand "floatunsdidf2"
4700 [(use (match_operand:DF 0 "register_operand" ""))
4701 (use (match_operand:DI 1 "register_operand" ""))]
4702 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4703 "x86_emit_floatuns (operands); DONE;")
4704 \f
4705 ;; SSE extract/set expanders
4706
4707 \f
4708 ;; Add instructions
4709
4710 ;; %%% splits for addditi3
4711
4712 (define_expand "addti3"
4713 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4714 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4715 (match_operand:TI 2 "x86_64_general_operand" "")))
4716 (clobber (reg:CC FLAGS_REG))]
4717 "TARGET_64BIT"
4718 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4719
4720 (define_insn "*addti3_1"
4721 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4722 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4723 (match_operand:TI 2 "general_operand" "roiF,riF")))
4724 (clobber (reg:CC FLAGS_REG))]
4725 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4726 "#")
4727
4728 (define_split
4729 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4730 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4731 (match_operand:TI 2 "general_operand" "")))
4732 (clobber (reg:CC FLAGS_REG))]
4733 "TARGET_64BIT && reload_completed"
4734 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4735 UNSPEC_ADD_CARRY))
4736 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4737 (parallel [(set (match_dup 3)
4738 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4739 (match_dup 4))
4740 (match_dup 5)))
4741 (clobber (reg:CC FLAGS_REG))])]
4742 "split_ti (operands+0, 1, operands+0, operands+3);
4743 split_ti (operands+1, 1, operands+1, operands+4);
4744 split_ti (operands+2, 1, operands+2, operands+5);")
4745
4746 ;; %%% splits for addsidi3
4747 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4748 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4749 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4750
4751 (define_expand "adddi3"
4752 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4753 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4754 (match_operand:DI 2 "x86_64_general_operand" "")))
4755 (clobber (reg:CC FLAGS_REG))]
4756 ""
4757 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4758
4759 (define_insn "*adddi3_1"
4760 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4761 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4762 (match_operand:DI 2 "general_operand" "roiF,riF")))
4763 (clobber (reg:CC FLAGS_REG))]
4764 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4765 "#")
4766
4767 (define_split
4768 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4769 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4770 (match_operand:DI 2 "general_operand" "")))
4771 (clobber (reg:CC FLAGS_REG))]
4772 "!TARGET_64BIT && reload_completed"
4773 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4774 UNSPEC_ADD_CARRY))
4775 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4776 (parallel [(set (match_dup 3)
4777 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4778 (match_dup 4))
4779 (match_dup 5)))
4780 (clobber (reg:CC FLAGS_REG))])]
4781 "split_di (operands+0, 1, operands+0, operands+3);
4782 split_di (operands+1, 1, operands+1, operands+4);
4783 split_di (operands+2, 1, operands+2, operands+5);")
4784
4785 (define_insn "adddi3_carry_rex64"
4786 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4787 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4788 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4789 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4790 (clobber (reg:CC FLAGS_REG))]
4791 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4792 "adc{q}\t{%2, %0|%0, %2}"
4793 [(set_attr "type" "alu")
4794 (set_attr "pent_pair" "pu")
4795 (set_attr "mode" "DI")])
4796
4797 (define_insn "*adddi3_cc_rex64"
4798 [(set (reg:CC FLAGS_REG)
4799 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4800 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4801 UNSPEC_ADD_CARRY))
4802 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4803 (plus:DI (match_dup 1) (match_dup 2)))]
4804 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4805 "add{q}\t{%2, %0|%0, %2}"
4806 [(set_attr "type" "alu")
4807 (set_attr "mode" "DI")])
4808
4809 (define_insn "addqi3_carry"
4810 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4811 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4812 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4813 (match_operand:QI 2 "general_operand" "qi,qm")))
4814 (clobber (reg:CC FLAGS_REG))]
4815 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4816 "adc{b}\t{%2, %0|%0, %2}"
4817 [(set_attr "type" "alu")
4818 (set_attr "pent_pair" "pu")
4819 (set_attr "mode" "QI")])
4820
4821 (define_insn "addhi3_carry"
4822 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4823 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4824 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4825 (match_operand:HI 2 "general_operand" "ri,rm")))
4826 (clobber (reg:CC FLAGS_REG))]
4827 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4828 "adc{w}\t{%2, %0|%0, %2}"
4829 [(set_attr "type" "alu")
4830 (set_attr "pent_pair" "pu")
4831 (set_attr "mode" "HI")])
4832
4833 (define_insn "addsi3_carry"
4834 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4835 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4836 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4837 (match_operand:SI 2 "general_operand" "ri,rm")))
4838 (clobber (reg:CC FLAGS_REG))]
4839 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4840 "adc{l}\t{%2, %0|%0, %2}"
4841 [(set_attr "type" "alu")
4842 (set_attr "pent_pair" "pu")
4843 (set_attr "mode" "SI")])
4844
4845 (define_insn "*addsi3_carry_zext"
4846 [(set (match_operand:DI 0 "register_operand" "=r")
4847 (zero_extend:DI
4848 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4849 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4850 (match_operand:SI 2 "general_operand" "rim"))))
4851 (clobber (reg:CC FLAGS_REG))]
4852 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4853 "adc{l}\t{%2, %k0|%k0, %2}"
4854 [(set_attr "type" "alu")
4855 (set_attr "pent_pair" "pu")
4856 (set_attr "mode" "SI")])
4857
4858 (define_insn "*addsi3_cc"
4859 [(set (reg:CC FLAGS_REG)
4860 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4861 (match_operand:SI 2 "general_operand" "ri,rm")]
4862 UNSPEC_ADD_CARRY))
4863 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4864 (plus:SI (match_dup 1) (match_dup 2)))]
4865 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4866 "add{l}\t{%2, %0|%0, %2}"
4867 [(set_attr "type" "alu")
4868 (set_attr "mode" "SI")])
4869
4870 (define_insn "addqi3_cc"
4871 [(set (reg:CC FLAGS_REG)
4872 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4873 (match_operand:QI 2 "general_operand" "qi,qm")]
4874 UNSPEC_ADD_CARRY))
4875 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4876 (plus:QI (match_dup 1) (match_dup 2)))]
4877 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4878 "add{b}\t{%2, %0|%0, %2}"
4879 [(set_attr "type" "alu")
4880 (set_attr "mode" "QI")])
4881
4882 (define_expand "addsi3"
4883 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4884 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4885 (match_operand:SI 2 "general_operand" "")))
4886 (clobber (reg:CC FLAGS_REG))])]
4887 ""
4888 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4889
4890 (define_insn "*lea_1"
4891 [(set (match_operand:SI 0 "register_operand" "=r")
4892 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4893 "!TARGET_64BIT"
4894 "lea{l}\t{%a1, %0|%0, %a1}"
4895 [(set_attr "type" "lea")
4896 (set_attr "mode" "SI")])
4897
4898 (define_insn "*lea_1_rex64"
4899 [(set (match_operand:SI 0 "register_operand" "=r")
4900 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4901 "TARGET_64BIT"
4902 "lea{l}\t{%a1, %0|%0, %a1}"
4903 [(set_attr "type" "lea")
4904 (set_attr "mode" "SI")])
4905
4906 (define_insn "*lea_1_zext"
4907 [(set (match_operand:DI 0 "register_operand" "=r")
4908 (zero_extend:DI
4909 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4910 "TARGET_64BIT"
4911 "lea{l}\t{%a1, %k0|%k0, %a1}"
4912 [(set_attr "type" "lea")
4913 (set_attr "mode" "SI")])
4914
4915 (define_insn "*lea_2_rex64"
4916 [(set (match_operand:DI 0 "register_operand" "=r")
4917 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4918 "TARGET_64BIT"
4919 "lea{q}\t{%a1, %0|%0, %a1}"
4920 [(set_attr "type" "lea")
4921 (set_attr "mode" "DI")])
4922
4923 ;; The lea patterns for non-Pmodes needs to be matched by several
4924 ;; insns converted to real lea by splitters.
4925
4926 (define_insn_and_split "*lea_general_1"
4927 [(set (match_operand 0 "register_operand" "=r")
4928 (plus (plus (match_operand 1 "index_register_operand" "l")
4929 (match_operand 2 "register_operand" "r"))
4930 (match_operand 3 "immediate_operand" "i")))]
4931 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4932 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4933 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4934 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4935 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4936 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4937 || GET_MODE (operands[3]) == VOIDmode)"
4938 "#"
4939 "&& reload_completed"
4940 [(const_int 0)]
4941 {
4942 rtx pat;
4943 operands[0] = gen_lowpart (SImode, operands[0]);
4944 operands[1] = gen_lowpart (Pmode, operands[1]);
4945 operands[2] = gen_lowpart (Pmode, operands[2]);
4946 operands[3] = gen_lowpart (Pmode, operands[3]);
4947 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4948 operands[3]);
4949 if (Pmode != SImode)
4950 pat = gen_rtx_SUBREG (SImode, pat, 0);
4951 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4952 DONE;
4953 }
4954 [(set_attr "type" "lea")
4955 (set_attr "mode" "SI")])
4956
4957 (define_insn_and_split "*lea_general_1_zext"
4958 [(set (match_operand:DI 0 "register_operand" "=r")
4959 (zero_extend:DI
4960 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4961 (match_operand:SI 2 "register_operand" "r"))
4962 (match_operand:SI 3 "immediate_operand" "i"))))]
4963 "TARGET_64BIT"
4964 "#"
4965 "&& reload_completed"
4966 [(set (match_dup 0)
4967 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4968 (match_dup 2))
4969 (match_dup 3)) 0)))]
4970 {
4971 operands[1] = gen_lowpart (Pmode, operands[1]);
4972 operands[2] = gen_lowpart (Pmode, operands[2]);
4973 operands[3] = gen_lowpart (Pmode, operands[3]);
4974 }
4975 [(set_attr "type" "lea")
4976 (set_attr "mode" "SI")])
4977
4978 (define_insn_and_split "*lea_general_2"
4979 [(set (match_operand 0 "register_operand" "=r")
4980 (plus (mult (match_operand 1 "index_register_operand" "l")
4981 (match_operand 2 "const248_operand" "i"))
4982 (match_operand 3 "nonmemory_operand" "ri")))]
4983 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4984 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4985 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4986 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4987 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4988 || GET_MODE (operands[3]) == VOIDmode)"
4989 "#"
4990 "&& reload_completed"
4991 [(const_int 0)]
4992 {
4993 rtx pat;
4994 operands[0] = gen_lowpart (SImode, operands[0]);
4995 operands[1] = gen_lowpart (Pmode, operands[1]);
4996 operands[3] = gen_lowpart (Pmode, operands[3]);
4997 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4998 operands[3]);
4999 if (Pmode != SImode)
5000 pat = gen_rtx_SUBREG (SImode, pat, 0);
5001 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5002 DONE;
5003 }
5004 [(set_attr "type" "lea")
5005 (set_attr "mode" "SI")])
5006
5007 (define_insn_and_split "*lea_general_2_zext"
5008 [(set (match_operand:DI 0 "register_operand" "=r")
5009 (zero_extend:DI
5010 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5011 (match_operand:SI 2 "const248_operand" "n"))
5012 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5013 "TARGET_64BIT"
5014 "#"
5015 "&& reload_completed"
5016 [(set (match_dup 0)
5017 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5018 (match_dup 2))
5019 (match_dup 3)) 0)))]
5020 {
5021 operands[1] = gen_lowpart (Pmode, operands[1]);
5022 operands[3] = gen_lowpart (Pmode, operands[3]);
5023 }
5024 [(set_attr "type" "lea")
5025 (set_attr "mode" "SI")])
5026
5027 (define_insn_and_split "*lea_general_3"
5028 [(set (match_operand 0 "register_operand" "=r")
5029 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5030 (match_operand 2 "const248_operand" "i"))
5031 (match_operand 3 "register_operand" "r"))
5032 (match_operand 4 "immediate_operand" "i")))]
5033 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5034 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5035 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5036 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5037 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5038 "#"
5039 "&& reload_completed"
5040 [(const_int 0)]
5041 {
5042 rtx pat;
5043 operands[0] = gen_lowpart (SImode, operands[0]);
5044 operands[1] = gen_lowpart (Pmode, operands[1]);
5045 operands[3] = gen_lowpart (Pmode, operands[3]);
5046 operands[4] = gen_lowpart (Pmode, operands[4]);
5047 pat = gen_rtx_PLUS (Pmode,
5048 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5049 operands[2]),
5050 operands[3]),
5051 operands[4]);
5052 if (Pmode != SImode)
5053 pat = gen_rtx_SUBREG (SImode, pat, 0);
5054 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5055 DONE;
5056 }
5057 [(set_attr "type" "lea")
5058 (set_attr "mode" "SI")])
5059
5060 (define_insn_and_split "*lea_general_3_zext"
5061 [(set (match_operand:DI 0 "register_operand" "=r")
5062 (zero_extend:DI
5063 (plus:SI (plus:SI (mult:SI
5064 (match_operand:SI 1 "index_register_operand" "l")
5065 (match_operand:SI 2 "const248_operand" "n"))
5066 (match_operand:SI 3 "register_operand" "r"))
5067 (match_operand:SI 4 "immediate_operand" "i"))))]
5068 "TARGET_64BIT"
5069 "#"
5070 "&& reload_completed"
5071 [(set (match_dup 0)
5072 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5073 (match_dup 2))
5074 (match_dup 3))
5075 (match_dup 4)) 0)))]
5076 {
5077 operands[1] = gen_lowpart (Pmode, operands[1]);
5078 operands[3] = gen_lowpart (Pmode, operands[3]);
5079 operands[4] = gen_lowpart (Pmode, operands[4]);
5080 }
5081 [(set_attr "type" "lea")
5082 (set_attr "mode" "SI")])
5083
5084 (define_insn "*adddi_1_rex64"
5085 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5086 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5087 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5088 (clobber (reg:CC FLAGS_REG))]
5089 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5090 {
5091 switch (get_attr_type (insn))
5092 {
5093 case TYPE_LEA:
5094 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5095 return "lea{q}\t{%a2, %0|%0, %a2}";
5096
5097 case TYPE_INCDEC:
5098 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5099 if (operands[2] == const1_rtx)
5100 return "inc{q}\t%0";
5101 else
5102 {
5103 gcc_assert (operands[2] == constm1_rtx);
5104 return "dec{q}\t%0";
5105 }
5106
5107 default:
5108 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5109
5110 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5111 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5112 if (GET_CODE (operands[2]) == CONST_INT
5113 /* Avoid overflows. */
5114 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5115 && (INTVAL (operands[2]) == 128
5116 || (INTVAL (operands[2]) < 0
5117 && INTVAL (operands[2]) != -128)))
5118 {
5119 operands[2] = GEN_INT (-INTVAL (operands[2]));
5120 return "sub{q}\t{%2, %0|%0, %2}";
5121 }
5122 return "add{q}\t{%2, %0|%0, %2}";
5123 }
5124 }
5125 [(set (attr "type")
5126 (cond [(eq_attr "alternative" "2")
5127 (const_string "lea")
5128 ; Current assemblers are broken and do not allow @GOTOFF in
5129 ; ought but a memory context.
5130 (match_operand:DI 2 "pic_symbolic_operand" "")
5131 (const_string "lea")
5132 (match_operand:DI 2 "incdec_operand" "")
5133 (const_string "incdec")
5134 ]
5135 (const_string "alu")))
5136 (set_attr "mode" "DI")])
5137
5138 ;; Convert lea to the lea pattern to avoid flags dependency.
5139 (define_split
5140 [(set (match_operand:DI 0 "register_operand" "")
5141 (plus:DI (match_operand:DI 1 "register_operand" "")
5142 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5143 (clobber (reg:CC FLAGS_REG))]
5144 "TARGET_64BIT && reload_completed
5145 && true_regnum (operands[0]) != true_regnum (operands[1])"
5146 [(set (match_dup 0)
5147 (plus:DI (match_dup 1)
5148 (match_dup 2)))]
5149 "")
5150
5151 (define_insn "*adddi_2_rex64"
5152 [(set (reg FLAGS_REG)
5153 (compare
5154 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5155 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5156 (const_int 0)))
5157 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5158 (plus:DI (match_dup 1) (match_dup 2)))]
5159 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5160 && ix86_binary_operator_ok (PLUS, DImode, operands)
5161 /* Current assemblers are broken and do not allow @GOTOFF in
5162 ought but a memory context. */
5163 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5164 {
5165 switch (get_attr_type (insn))
5166 {
5167 case TYPE_INCDEC:
5168 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5169 if (operands[2] == const1_rtx)
5170 return "inc{q}\t%0";
5171 else
5172 {
5173 gcc_assert (operands[2] == constm1_rtx);
5174 return "dec{q}\t%0";
5175 }
5176
5177 default:
5178 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5179 /* ???? We ought to handle there the 32bit case too
5180 - do we need new constraint? */
5181 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5182 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5183 if (GET_CODE (operands[2]) == CONST_INT
5184 /* Avoid overflows. */
5185 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5186 && (INTVAL (operands[2]) == 128
5187 || (INTVAL (operands[2]) < 0
5188 && INTVAL (operands[2]) != -128)))
5189 {
5190 operands[2] = GEN_INT (-INTVAL (operands[2]));
5191 return "sub{q}\t{%2, %0|%0, %2}";
5192 }
5193 return "add{q}\t{%2, %0|%0, %2}";
5194 }
5195 }
5196 [(set (attr "type")
5197 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5198 (const_string "incdec")
5199 (const_string "alu")))
5200 (set_attr "mode" "DI")])
5201
5202 (define_insn "*adddi_3_rex64"
5203 [(set (reg FLAGS_REG)
5204 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5205 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5206 (clobber (match_scratch:DI 0 "=r"))]
5207 "TARGET_64BIT
5208 && ix86_match_ccmode (insn, CCZmode)
5209 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5210 /* Current assemblers are broken and do not allow @GOTOFF in
5211 ought but a memory context. */
5212 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5213 {
5214 switch (get_attr_type (insn))
5215 {
5216 case TYPE_INCDEC:
5217 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5218 if (operands[2] == const1_rtx)
5219 return "inc{q}\t%0";
5220 else
5221 {
5222 gcc_assert (operands[2] == constm1_rtx);
5223 return "dec{q}\t%0";
5224 }
5225
5226 default:
5227 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5228 /* ???? We ought to handle there the 32bit case too
5229 - do we need new constraint? */
5230 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5231 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5232 if (GET_CODE (operands[2]) == CONST_INT
5233 /* Avoid overflows. */
5234 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5235 && (INTVAL (operands[2]) == 128
5236 || (INTVAL (operands[2]) < 0
5237 && INTVAL (operands[2]) != -128)))
5238 {
5239 operands[2] = GEN_INT (-INTVAL (operands[2]));
5240 return "sub{q}\t{%2, %0|%0, %2}";
5241 }
5242 return "add{q}\t{%2, %0|%0, %2}";
5243 }
5244 }
5245 [(set (attr "type")
5246 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5247 (const_string "incdec")
5248 (const_string "alu")))
5249 (set_attr "mode" "DI")])
5250
5251 ; For comparisons against 1, -1 and 128, we may generate better code
5252 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5253 ; is matched then. We can't accept general immediate, because for
5254 ; case of overflows, the result is messed up.
5255 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5256 ; when negated.
5257 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5258 ; only for comparisons not depending on it.
5259 (define_insn "*adddi_4_rex64"
5260 [(set (reg FLAGS_REG)
5261 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5262 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5263 (clobber (match_scratch:DI 0 "=rm"))]
5264 "TARGET_64BIT
5265 && ix86_match_ccmode (insn, CCGCmode)"
5266 {
5267 switch (get_attr_type (insn))
5268 {
5269 case TYPE_INCDEC:
5270 if (operands[2] == constm1_rtx)
5271 return "inc{q}\t%0";
5272 else
5273 {
5274 gcc_assert (operands[2] == const1_rtx);
5275 return "dec{q}\t%0";
5276 }
5277
5278 default:
5279 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5280 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5281 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5282 if ((INTVAL (operands[2]) == -128
5283 || (INTVAL (operands[2]) > 0
5284 && INTVAL (operands[2]) != 128))
5285 /* Avoid overflows. */
5286 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5287 return "sub{q}\t{%2, %0|%0, %2}";
5288 operands[2] = GEN_INT (-INTVAL (operands[2]));
5289 return "add{q}\t{%2, %0|%0, %2}";
5290 }
5291 }
5292 [(set (attr "type")
5293 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5294 (const_string "incdec")
5295 (const_string "alu")))
5296 (set_attr "mode" "DI")])
5297
5298 (define_insn "*adddi_5_rex64"
5299 [(set (reg FLAGS_REG)
5300 (compare
5301 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5302 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5303 (const_int 0)))
5304 (clobber (match_scratch:DI 0 "=r"))]
5305 "TARGET_64BIT
5306 && ix86_match_ccmode (insn, CCGOCmode)
5307 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5308 /* Current assemblers are broken and do not allow @GOTOFF in
5309 ought but a memory context. */
5310 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5311 {
5312 switch (get_attr_type (insn))
5313 {
5314 case TYPE_INCDEC:
5315 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5316 if (operands[2] == const1_rtx)
5317 return "inc{q}\t%0";
5318 else
5319 {
5320 gcc_assert (operands[2] == constm1_rtx);
5321 return "dec{q}\t%0";
5322 }
5323
5324 default:
5325 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5326 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5327 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5328 if (GET_CODE (operands[2]) == CONST_INT
5329 /* Avoid overflows. */
5330 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5331 && (INTVAL (operands[2]) == 128
5332 || (INTVAL (operands[2]) < 0
5333 && INTVAL (operands[2]) != -128)))
5334 {
5335 operands[2] = GEN_INT (-INTVAL (operands[2]));
5336 return "sub{q}\t{%2, %0|%0, %2}";
5337 }
5338 return "add{q}\t{%2, %0|%0, %2}";
5339 }
5340 }
5341 [(set (attr "type")
5342 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5343 (const_string "incdec")
5344 (const_string "alu")))
5345 (set_attr "mode" "DI")])
5346
5347
5348 (define_insn "*addsi_1"
5349 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5350 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5351 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5352 (clobber (reg:CC FLAGS_REG))]
5353 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5354 {
5355 switch (get_attr_type (insn))
5356 {
5357 case TYPE_LEA:
5358 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5359 return "lea{l}\t{%a2, %0|%0, %a2}";
5360
5361 case TYPE_INCDEC:
5362 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5363 if (operands[2] == const1_rtx)
5364 return "inc{l}\t%0";
5365 else
5366 {
5367 gcc_assert (operands[2] == constm1_rtx);
5368 return "dec{l}\t%0";
5369 }
5370
5371 default:
5372 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5373
5374 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5375 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5376 if (GET_CODE (operands[2]) == CONST_INT
5377 && (INTVAL (operands[2]) == 128
5378 || (INTVAL (operands[2]) < 0
5379 && INTVAL (operands[2]) != -128)))
5380 {
5381 operands[2] = GEN_INT (-INTVAL (operands[2]));
5382 return "sub{l}\t{%2, %0|%0, %2}";
5383 }
5384 return "add{l}\t{%2, %0|%0, %2}";
5385 }
5386 }
5387 [(set (attr "type")
5388 (cond [(eq_attr "alternative" "2")
5389 (const_string "lea")
5390 ; Current assemblers are broken and do not allow @GOTOFF in
5391 ; ought but a memory context.
5392 (match_operand:SI 2 "pic_symbolic_operand" "")
5393 (const_string "lea")
5394 (match_operand:SI 2 "incdec_operand" "")
5395 (const_string "incdec")
5396 ]
5397 (const_string "alu")))
5398 (set_attr "mode" "SI")])
5399
5400 ;; Convert lea to the lea pattern to avoid flags dependency.
5401 (define_split
5402 [(set (match_operand 0 "register_operand" "")
5403 (plus (match_operand 1 "register_operand" "")
5404 (match_operand 2 "nonmemory_operand" "")))
5405 (clobber (reg:CC FLAGS_REG))]
5406 "reload_completed
5407 && true_regnum (operands[0]) != true_regnum (operands[1])"
5408 [(const_int 0)]
5409 {
5410 rtx pat;
5411 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5412 may confuse gen_lowpart. */
5413 if (GET_MODE (operands[0]) != Pmode)
5414 {
5415 operands[1] = gen_lowpart (Pmode, operands[1]);
5416 operands[2] = gen_lowpart (Pmode, operands[2]);
5417 }
5418 operands[0] = gen_lowpart (SImode, operands[0]);
5419 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5420 if (Pmode != SImode)
5421 pat = gen_rtx_SUBREG (SImode, pat, 0);
5422 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5423 DONE;
5424 })
5425
5426 ;; It may seem that nonimmediate operand is proper one for operand 1.
5427 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5428 ;; we take care in ix86_binary_operator_ok to not allow two memory
5429 ;; operands so proper swapping will be done in reload. This allow
5430 ;; patterns constructed from addsi_1 to match.
5431 (define_insn "addsi_1_zext"
5432 [(set (match_operand:DI 0 "register_operand" "=r,r")
5433 (zero_extend:DI
5434 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5435 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5436 (clobber (reg:CC FLAGS_REG))]
5437 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5438 {
5439 switch (get_attr_type (insn))
5440 {
5441 case TYPE_LEA:
5442 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5443 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5444
5445 case TYPE_INCDEC:
5446 if (operands[2] == const1_rtx)
5447 return "inc{l}\t%k0";
5448 else
5449 {
5450 gcc_assert (operands[2] == constm1_rtx);
5451 return "dec{l}\t%k0";
5452 }
5453
5454 default:
5455 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5456 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5457 if (GET_CODE (operands[2]) == CONST_INT
5458 && (INTVAL (operands[2]) == 128
5459 || (INTVAL (operands[2]) < 0
5460 && INTVAL (operands[2]) != -128)))
5461 {
5462 operands[2] = GEN_INT (-INTVAL (operands[2]));
5463 return "sub{l}\t{%2, %k0|%k0, %2}";
5464 }
5465 return "add{l}\t{%2, %k0|%k0, %2}";
5466 }
5467 }
5468 [(set (attr "type")
5469 (cond [(eq_attr "alternative" "1")
5470 (const_string "lea")
5471 ; Current assemblers are broken and do not allow @GOTOFF in
5472 ; ought but a memory context.
5473 (match_operand:SI 2 "pic_symbolic_operand" "")
5474 (const_string "lea")
5475 (match_operand:SI 2 "incdec_operand" "")
5476 (const_string "incdec")
5477 ]
5478 (const_string "alu")))
5479 (set_attr "mode" "SI")])
5480
5481 ;; Convert lea to the lea pattern to avoid flags dependency.
5482 (define_split
5483 [(set (match_operand:DI 0 "register_operand" "")
5484 (zero_extend:DI
5485 (plus:SI (match_operand:SI 1 "register_operand" "")
5486 (match_operand:SI 2 "nonmemory_operand" ""))))
5487 (clobber (reg:CC FLAGS_REG))]
5488 "TARGET_64BIT && reload_completed
5489 && true_regnum (operands[0]) != true_regnum (operands[1])"
5490 [(set (match_dup 0)
5491 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5492 {
5493 operands[1] = gen_lowpart (Pmode, operands[1]);
5494 operands[2] = gen_lowpart (Pmode, operands[2]);
5495 })
5496
5497 (define_insn "*addsi_2"
5498 [(set (reg FLAGS_REG)
5499 (compare
5500 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5501 (match_operand:SI 2 "general_operand" "rmni,rni"))
5502 (const_int 0)))
5503 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5504 (plus:SI (match_dup 1) (match_dup 2)))]
5505 "ix86_match_ccmode (insn, CCGOCmode)
5506 && ix86_binary_operator_ok (PLUS, SImode, operands)
5507 /* Current assemblers are broken and do not allow @GOTOFF in
5508 ought but a memory context. */
5509 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5510 {
5511 switch (get_attr_type (insn))
5512 {
5513 case TYPE_INCDEC:
5514 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515 if (operands[2] == const1_rtx)
5516 return "inc{l}\t%0";
5517 else
5518 {
5519 gcc_assert (operands[2] == constm1_rtx);
5520 return "dec{l}\t%0";
5521 }
5522
5523 default:
5524 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5525 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5526 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5527 if (GET_CODE (operands[2]) == CONST_INT
5528 && (INTVAL (operands[2]) == 128
5529 || (INTVAL (operands[2]) < 0
5530 && INTVAL (operands[2]) != -128)))
5531 {
5532 operands[2] = GEN_INT (-INTVAL (operands[2]));
5533 return "sub{l}\t{%2, %0|%0, %2}";
5534 }
5535 return "add{l}\t{%2, %0|%0, %2}";
5536 }
5537 }
5538 [(set (attr "type")
5539 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5540 (const_string "incdec")
5541 (const_string "alu")))
5542 (set_attr "mode" "SI")])
5543
5544 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5545 (define_insn "*addsi_2_zext"
5546 [(set (reg FLAGS_REG)
5547 (compare
5548 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5549 (match_operand:SI 2 "general_operand" "rmni"))
5550 (const_int 0)))
5551 (set (match_operand:DI 0 "register_operand" "=r")
5552 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5553 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5554 && ix86_binary_operator_ok (PLUS, SImode, operands)
5555 /* Current assemblers are broken and do not allow @GOTOFF in
5556 ought but a memory context. */
5557 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5558 {
5559 switch (get_attr_type (insn))
5560 {
5561 case TYPE_INCDEC:
5562 if (operands[2] == const1_rtx)
5563 return "inc{l}\t%k0";
5564 else
5565 {
5566 gcc_assert (operands[2] == constm1_rtx);
5567 return "dec{l}\t%k0";
5568 }
5569
5570 default:
5571 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5572 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5573 if (GET_CODE (operands[2]) == CONST_INT
5574 && (INTVAL (operands[2]) == 128
5575 || (INTVAL (operands[2]) < 0
5576 && INTVAL (operands[2]) != -128)))
5577 {
5578 operands[2] = GEN_INT (-INTVAL (operands[2]));
5579 return "sub{l}\t{%2, %k0|%k0, %2}";
5580 }
5581 return "add{l}\t{%2, %k0|%k0, %2}";
5582 }
5583 }
5584 [(set (attr "type")
5585 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5586 (const_string "incdec")
5587 (const_string "alu")))
5588 (set_attr "mode" "SI")])
5589
5590 (define_insn "*addsi_3"
5591 [(set (reg FLAGS_REG)
5592 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5593 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5594 (clobber (match_scratch:SI 0 "=r"))]
5595 "ix86_match_ccmode (insn, CCZmode)
5596 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5597 /* Current assemblers are broken and do not allow @GOTOFF in
5598 ought but a memory context. */
5599 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5600 {
5601 switch (get_attr_type (insn))
5602 {
5603 case TYPE_INCDEC:
5604 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5605 if (operands[2] == const1_rtx)
5606 return "inc{l}\t%0";
5607 else
5608 {
5609 gcc_assert (operands[2] == constm1_rtx);
5610 return "dec{l}\t%0";
5611 }
5612
5613 default:
5614 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5615 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5616 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5617 if (GET_CODE (operands[2]) == CONST_INT
5618 && (INTVAL (operands[2]) == 128
5619 || (INTVAL (operands[2]) < 0
5620 && INTVAL (operands[2]) != -128)))
5621 {
5622 operands[2] = GEN_INT (-INTVAL (operands[2]));
5623 return "sub{l}\t{%2, %0|%0, %2}";
5624 }
5625 return "add{l}\t{%2, %0|%0, %2}";
5626 }
5627 }
5628 [(set (attr "type")
5629 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5630 (const_string "incdec")
5631 (const_string "alu")))
5632 (set_attr "mode" "SI")])
5633
5634 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5635 (define_insn "*addsi_3_zext"
5636 [(set (reg FLAGS_REG)
5637 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5638 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5639 (set (match_operand:DI 0 "register_operand" "=r")
5640 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5641 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5642 && ix86_binary_operator_ok (PLUS, SImode, operands)
5643 /* Current assemblers are broken and do not allow @GOTOFF in
5644 ought but a memory context. */
5645 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5646 {
5647 switch (get_attr_type (insn))
5648 {
5649 case TYPE_INCDEC:
5650 if (operands[2] == const1_rtx)
5651 return "inc{l}\t%k0";
5652 else
5653 {
5654 gcc_assert (operands[2] == constm1_rtx);
5655 return "dec{l}\t%k0";
5656 }
5657
5658 default:
5659 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5660 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5661 if (GET_CODE (operands[2]) == CONST_INT
5662 && (INTVAL (operands[2]) == 128
5663 || (INTVAL (operands[2]) < 0
5664 && INTVAL (operands[2]) != -128)))
5665 {
5666 operands[2] = GEN_INT (-INTVAL (operands[2]));
5667 return "sub{l}\t{%2, %k0|%k0, %2}";
5668 }
5669 return "add{l}\t{%2, %k0|%k0, %2}";
5670 }
5671 }
5672 [(set (attr "type")
5673 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674 (const_string "incdec")
5675 (const_string "alu")))
5676 (set_attr "mode" "SI")])
5677
5678 ; For comparisons against 1, -1 and 128, we may generate better code
5679 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5680 ; is matched then. We can't accept general immediate, because for
5681 ; case of overflows, the result is messed up.
5682 ; This pattern also don't hold of 0x80000000, since the value overflows
5683 ; when negated.
5684 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5685 ; only for comparisons not depending on it.
5686 (define_insn "*addsi_4"
5687 [(set (reg FLAGS_REG)
5688 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5689 (match_operand:SI 2 "const_int_operand" "n")))
5690 (clobber (match_scratch:SI 0 "=rm"))]
5691 "ix86_match_ccmode (insn, CCGCmode)
5692 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5693 {
5694 switch (get_attr_type (insn))
5695 {
5696 case TYPE_INCDEC:
5697 if (operands[2] == constm1_rtx)
5698 return "inc{l}\t%0";
5699 else
5700 {
5701 gcc_assert (operands[2] == const1_rtx);
5702 return "dec{l}\t%0";
5703 }
5704
5705 default:
5706 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5707 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5708 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5709 if ((INTVAL (operands[2]) == -128
5710 || (INTVAL (operands[2]) > 0
5711 && INTVAL (operands[2]) != 128)))
5712 return "sub{l}\t{%2, %0|%0, %2}";
5713 operands[2] = GEN_INT (-INTVAL (operands[2]));
5714 return "add{l}\t{%2, %0|%0, %2}";
5715 }
5716 }
5717 [(set (attr "type")
5718 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5719 (const_string "incdec")
5720 (const_string "alu")))
5721 (set_attr "mode" "SI")])
5722
5723 (define_insn "*addsi_5"
5724 [(set (reg FLAGS_REG)
5725 (compare
5726 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5727 (match_operand:SI 2 "general_operand" "rmni"))
5728 (const_int 0)))
5729 (clobber (match_scratch:SI 0 "=r"))]
5730 "ix86_match_ccmode (insn, CCGOCmode)
5731 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5732 /* Current assemblers are broken and do not allow @GOTOFF in
5733 ought but a memory context. */
5734 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5735 {
5736 switch (get_attr_type (insn))
5737 {
5738 case TYPE_INCDEC:
5739 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5740 if (operands[2] == const1_rtx)
5741 return "inc{l}\t%0";
5742 else
5743 {
5744 gcc_assert (operands[2] == constm1_rtx);
5745 return "dec{l}\t%0";
5746 }
5747
5748 default:
5749 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5750 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5751 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5752 if (GET_CODE (operands[2]) == CONST_INT
5753 && (INTVAL (operands[2]) == 128
5754 || (INTVAL (operands[2]) < 0
5755 && INTVAL (operands[2]) != -128)))
5756 {
5757 operands[2] = GEN_INT (-INTVAL (operands[2]));
5758 return "sub{l}\t{%2, %0|%0, %2}";
5759 }
5760 return "add{l}\t{%2, %0|%0, %2}";
5761 }
5762 }
5763 [(set (attr "type")
5764 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5765 (const_string "incdec")
5766 (const_string "alu")))
5767 (set_attr "mode" "SI")])
5768
5769 (define_expand "addhi3"
5770 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5771 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5772 (match_operand:HI 2 "general_operand" "")))
5773 (clobber (reg:CC FLAGS_REG))])]
5774 "TARGET_HIMODE_MATH"
5775 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5776
5777 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5778 ;; type optimizations enabled by define-splits. This is not important
5779 ;; for PII, and in fact harmful because of partial register stalls.
5780
5781 (define_insn "*addhi_1_lea"
5782 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5783 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5784 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5785 (clobber (reg:CC FLAGS_REG))]
5786 "!TARGET_PARTIAL_REG_STALL
5787 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5788 {
5789 switch (get_attr_type (insn))
5790 {
5791 case TYPE_LEA:
5792 return "#";
5793 case TYPE_INCDEC:
5794 if (operands[2] == const1_rtx)
5795 return "inc{w}\t%0";
5796 else
5797 {
5798 gcc_assert (operands[2] == constm1_rtx);
5799 return "dec{w}\t%0";
5800 }
5801
5802 default:
5803 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5804 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5805 if (GET_CODE (operands[2]) == CONST_INT
5806 && (INTVAL (operands[2]) == 128
5807 || (INTVAL (operands[2]) < 0
5808 && INTVAL (operands[2]) != -128)))
5809 {
5810 operands[2] = GEN_INT (-INTVAL (operands[2]));
5811 return "sub{w}\t{%2, %0|%0, %2}";
5812 }
5813 return "add{w}\t{%2, %0|%0, %2}";
5814 }
5815 }
5816 [(set (attr "type")
5817 (if_then_else (eq_attr "alternative" "2")
5818 (const_string "lea")
5819 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5820 (const_string "incdec")
5821 (const_string "alu"))))
5822 (set_attr "mode" "HI,HI,SI")])
5823
5824 (define_insn "*addhi_1"
5825 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5826 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5827 (match_operand:HI 2 "general_operand" "ri,rm")))
5828 (clobber (reg:CC FLAGS_REG))]
5829 "TARGET_PARTIAL_REG_STALL
5830 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5831 {
5832 switch (get_attr_type (insn))
5833 {
5834 case TYPE_INCDEC:
5835 if (operands[2] == const1_rtx)
5836 return "inc{w}\t%0";
5837 else
5838 {
5839 gcc_assert (operands[2] == constm1_rtx);
5840 return "dec{w}\t%0";
5841 }
5842
5843 default:
5844 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5845 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5846 if (GET_CODE (operands[2]) == CONST_INT
5847 && (INTVAL (operands[2]) == 128
5848 || (INTVAL (operands[2]) < 0
5849 && INTVAL (operands[2]) != -128)))
5850 {
5851 operands[2] = GEN_INT (-INTVAL (operands[2]));
5852 return "sub{w}\t{%2, %0|%0, %2}";
5853 }
5854 return "add{w}\t{%2, %0|%0, %2}";
5855 }
5856 }
5857 [(set (attr "type")
5858 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5859 (const_string "incdec")
5860 (const_string "alu")))
5861 (set_attr "mode" "HI")])
5862
5863 (define_insn "*addhi_2"
5864 [(set (reg FLAGS_REG)
5865 (compare
5866 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5867 (match_operand:HI 2 "general_operand" "rmni,rni"))
5868 (const_int 0)))
5869 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5870 (plus:HI (match_dup 1) (match_dup 2)))]
5871 "ix86_match_ccmode (insn, CCGOCmode)
5872 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5873 {
5874 switch (get_attr_type (insn))
5875 {
5876 case TYPE_INCDEC:
5877 if (operands[2] == const1_rtx)
5878 return "inc{w}\t%0";
5879 else
5880 {
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{w}\t%0";
5883 }
5884
5885 default:
5886 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5887 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5888 if (GET_CODE (operands[2]) == CONST_INT
5889 && (INTVAL (operands[2]) == 128
5890 || (INTVAL (operands[2]) < 0
5891 && INTVAL (operands[2]) != -128)))
5892 {
5893 operands[2] = GEN_INT (-INTVAL (operands[2]));
5894 return "sub{w}\t{%2, %0|%0, %2}";
5895 }
5896 return "add{w}\t{%2, %0|%0, %2}";
5897 }
5898 }
5899 [(set (attr "type")
5900 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set_attr "mode" "HI")])
5904
5905 (define_insn "*addhi_3"
5906 [(set (reg FLAGS_REG)
5907 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5908 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5909 (clobber (match_scratch:HI 0 "=r"))]
5910 "ix86_match_ccmode (insn, CCZmode)
5911 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5912 {
5913 switch (get_attr_type (insn))
5914 {
5915 case TYPE_INCDEC:
5916 if (operands[2] == const1_rtx)
5917 return "inc{w}\t%0";
5918 else
5919 {
5920 gcc_assert (operands[2] == constm1_rtx);
5921 return "dec{w}\t%0";
5922 }
5923
5924 default:
5925 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5926 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5927 if (GET_CODE (operands[2]) == CONST_INT
5928 && (INTVAL (operands[2]) == 128
5929 || (INTVAL (operands[2]) < 0
5930 && INTVAL (operands[2]) != -128)))
5931 {
5932 operands[2] = GEN_INT (-INTVAL (operands[2]));
5933 return "sub{w}\t{%2, %0|%0, %2}";
5934 }
5935 return "add{w}\t{%2, %0|%0, %2}";
5936 }
5937 }
5938 [(set (attr "type")
5939 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5940 (const_string "incdec")
5941 (const_string "alu")))
5942 (set_attr "mode" "HI")])
5943
5944 ; See comments above addsi_4 for details.
5945 (define_insn "*addhi_4"
5946 [(set (reg FLAGS_REG)
5947 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5948 (match_operand:HI 2 "const_int_operand" "n")))
5949 (clobber (match_scratch:HI 0 "=rm"))]
5950 "ix86_match_ccmode (insn, CCGCmode)
5951 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5952 {
5953 switch (get_attr_type (insn))
5954 {
5955 case TYPE_INCDEC:
5956 if (operands[2] == constm1_rtx)
5957 return "inc{w}\t%0";
5958 else
5959 {
5960 gcc_assert (operands[2] == const1_rtx);
5961 return "dec{w}\t%0";
5962 }
5963
5964 default:
5965 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5966 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5967 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5968 if ((INTVAL (operands[2]) == -128
5969 || (INTVAL (operands[2]) > 0
5970 && INTVAL (operands[2]) != 128)))
5971 return "sub{w}\t{%2, %0|%0, %2}";
5972 operands[2] = GEN_INT (-INTVAL (operands[2]));
5973 return "add{w}\t{%2, %0|%0, %2}";
5974 }
5975 }
5976 [(set (attr "type")
5977 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5978 (const_string "incdec")
5979 (const_string "alu")))
5980 (set_attr "mode" "SI")])
5981
5982
5983 (define_insn "*addhi_5"
5984 [(set (reg FLAGS_REG)
5985 (compare
5986 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5987 (match_operand:HI 2 "general_operand" "rmni"))
5988 (const_int 0)))
5989 (clobber (match_scratch:HI 0 "=r"))]
5990 "ix86_match_ccmode (insn, CCGOCmode)
5991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5992 {
5993 switch (get_attr_type (insn))
5994 {
5995 case TYPE_INCDEC:
5996 if (operands[2] == const1_rtx)
5997 return "inc{w}\t%0";
5998 else
5999 {
6000 gcc_assert (operands[2] == constm1_rtx);
6001 return "dec{w}\t%0";
6002 }
6003
6004 default:
6005 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6007 if (GET_CODE (operands[2]) == CONST_INT
6008 && (INTVAL (operands[2]) == 128
6009 || (INTVAL (operands[2]) < 0
6010 && INTVAL (operands[2]) != -128)))
6011 {
6012 operands[2] = GEN_INT (-INTVAL (operands[2]));
6013 return "sub{w}\t{%2, %0|%0, %2}";
6014 }
6015 return "add{w}\t{%2, %0|%0, %2}";
6016 }
6017 }
6018 [(set (attr "type")
6019 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6020 (const_string "incdec")
6021 (const_string "alu")))
6022 (set_attr "mode" "HI")])
6023
6024 (define_expand "addqi3"
6025 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6026 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6027 (match_operand:QI 2 "general_operand" "")))
6028 (clobber (reg:CC FLAGS_REG))])]
6029 "TARGET_QIMODE_MATH"
6030 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6031
6032 ;; %%% Potential partial reg stall on alternative 2. What to do?
6033 (define_insn "*addqi_1_lea"
6034 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6035 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6036 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6037 (clobber (reg:CC FLAGS_REG))]
6038 "!TARGET_PARTIAL_REG_STALL
6039 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6040 {
6041 int widen = (which_alternative == 2);
6042 switch (get_attr_type (insn))
6043 {
6044 case TYPE_LEA:
6045 return "#";
6046 case TYPE_INCDEC:
6047 if (operands[2] == const1_rtx)
6048 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6049 else
6050 {
6051 gcc_assert (operands[2] == constm1_rtx);
6052 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6053 }
6054
6055 default:
6056 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6057 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6058 if (GET_CODE (operands[2]) == CONST_INT
6059 && (INTVAL (operands[2]) == 128
6060 || (INTVAL (operands[2]) < 0
6061 && INTVAL (operands[2]) != -128)))
6062 {
6063 operands[2] = GEN_INT (-INTVAL (operands[2]));
6064 if (widen)
6065 return "sub{l}\t{%2, %k0|%k0, %2}";
6066 else
6067 return "sub{b}\t{%2, %0|%0, %2}";
6068 }
6069 if (widen)
6070 return "add{l}\t{%k2, %k0|%k0, %k2}";
6071 else
6072 return "add{b}\t{%2, %0|%0, %2}";
6073 }
6074 }
6075 [(set (attr "type")
6076 (if_then_else (eq_attr "alternative" "3")
6077 (const_string "lea")
6078 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6079 (const_string "incdec")
6080 (const_string "alu"))))
6081 (set_attr "mode" "QI,QI,SI,SI")])
6082
6083 (define_insn "*addqi_1"
6084 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6085 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6086 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6087 (clobber (reg:CC FLAGS_REG))]
6088 "TARGET_PARTIAL_REG_STALL
6089 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6090 {
6091 int widen = (which_alternative == 2);
6092 switch (get_attr_type (insn))
6093 {
6094 case TYPE_INCDEC:
6095 if (operands[2] == const1_rtx)
6096 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6097 else
6098 {
6099 gcc_assert (operands[2] == constm1_rtx);
6100 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6101 }
6102
6103 default:
6104 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6105 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6106 if (GET_CODE (operands[2]) == CONST_INT
6107 && (INTVAL (operands[2]) == 128
6108 || (INTVAL (operands[2]) < 0
6109 && INTVAL (operands[2]) != -128)))
6110 {
6111 operands[2] = GEN_INT (-INTVAL (operands[2]));
6112 if (widen)
6113 return "sub{l}\t{%2, %k0|%k0, %2}";
6114 else
6115 return "sub{b}\t{%2, %0|%0, %2}";
6116 }
6117 if (widen)
6118 return "add{l}\t{%k2, %k0|%k0, %k2}";
6119 else
6120 return "add{b}\t{%2, %0|%0, %2}";
6121 }
6122 }
6123 [(set (attr "type")
6124 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6125 (const_string "incdec")
6126 (const_string "alu")))
6127 (set_attr "mode" "QI,QI,SI")])
6128
6129 (define_insn "*addqi_1_slp"
6130 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6131 (plus:QI (match_dup 0)
6132 (match_operand:QI 1 "general_operand" "qn,qnm")))
6133 (clobber (reg:CC FLAGS_REG))]
6134 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6135 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6136 {
6137 switch (get_attr_type (insn))
6138 {
6139 case TYPE_INCDEC:
6140 if (operands[1] == const1_rtx)
6141 return "inc{b}\t%0";
6142 else
6143 {
6144 gcc_assert (operands[1] == constm1_rtx);
6145 return "dec{b}\t%0";
6146 }
6147
6148 default:
6149 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6150 if (GET_CODE (operands[1]) == CONST_INT
6151 && INTVAL (operands[1]) < 0)
6152 {
6153 operands[1] = GEN_INT (-INTVAL (operands[1]));
6154 return "sub{b}\t{%1, %0|%0, %1}";
6155 }
6156 return "add{b}\t{%1, %0|%0, %1}";
6157 }
6158 }
6159 [(set (attr "type")
6160 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6161 (const_string "incdec")
6162 (const_string "alu1")))
6163 (set (attr "memory")
6164 (if_then_else (match_operand 1 "memory_operand" "")
6165 (const_string "load")
6166 (const_string "none")))
6167 (set_attr "mode" "QI")])
6168
6169 (define_insn "*addqi_2"
6170 [(set (reg FLAGS_REG)
6171 (compare
6172 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6173 (match_operand:QI 2 "general_operand" "qmni,qni"))
6174 (const_int 0)))
6175 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6176 (plus:QI (match_dup 1) (match_dup 2)))]
6177 "ix86_match_ccmode (insn, CCGOCmode)
6178 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6179 {
6180 switch (get_attr_type (insn))
6181 {
6182 case TYPE_INCDEC:
6183 if (operands[2] == const1_rtx)
6184 return "inc{b}\t%0";
6185 else
6186 {
6187 gcc_assert (operands[2] == constm1_rtx
6188 || (GET_CODE (operands[2]) == CONST_INT
6189 && INTVAL (operands[2]) == 255));
6190 return "dec{b}\t%0";
6191 }
6192
6193 default:
6194 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6195 if (GET_CODE (operands[2]) == CONST_INT
6196 && INTVAL (operands[2]) < 0)
6197 {
6198 operands[2] = GEN_INT (-INTVAL (operands[2]));
6199 return "sub{b}\t{%2, %0|%0, %2}";
6200 }
6201 return "add{b}\t{%2, %0|%0, %2}";
6202 }
6203 }
6204 [(set (attr "type")
6205 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6206 (const_string "incdec")
6207 (const_string "alu")))
6208 (set_attr "mode" "QI")])
6209
6210 (define_insn "*addqi_3"
6211 [(set (reg FLAGS_REG)
6212 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6213 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6214 (clobber (match_scratch:QI 0 "=q"))]
6215 "ix86_match_ccmode (insn, CCZmode)
6216 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6217 {
6218 switch (get_attr_type (insn))
6219 {
6220 case TYPE_INCDEC:
6221 if (operands[2] == const1_rtx)
6222 return "inc{b}\t%0";
6223 else
6224 {
6225 gcc_assert (operands[2] == constm1_rtx
6226 || (GET_CODE (operands[2]) == CONST_INT
6227 && INTVAL (operands[2]) == 255));
6228 return "dec{b}\t%0";
6229 }
6230
6231 default:
6232 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6233 if (GET_CODE (operands[2]) == CONST_INT
6234 && INTVAL (operands[2]) < 0)
6235 {
6236 operands[2] = GEN_INT (-INTVAL (operands[2]));
6237 return "sub{b}\t{%2, %0|%0, %2}";
6238 }
6239 return "add{b}\t{%2, %0|%0, %2}";
6240 }
6241 }
6242 [(set (attr "type")
6243 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6244 (const_string "incdec")
6245 (const_string "alu")))
6246 (set_attr "mode" "QI")])
6247
6248 ; See comments above addsi_4 for details.
6249 (define_insn "*addqi_4"
6250 [(set (reg FLAGS_REG)
6251 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6252 (match_operand:QI 2 "const_int_operand" "n")))
6253 (clobber (match_scratch:QI 0 "=qm"))]
6254 "ix86_match_ccmode (insn, CCGCmode)
6255 && (INTVAL (operands[2]) & 0xff) != 0x80"
6256 {
6257 switch (get_attr_type (insn))
6258 {
6259 case TYPE_INCDEC:
6260 if (operands[2] == constm1_rtx
6261 || (GET_CODE (operands[2]) == CONST_INT
6262 && INTVAL (operands[2]) == 255))
6263 return "inc{b}\t%0";
6264 else
6265 {
6266 gcc_assert (operands[2] == const1_rtx);
6267 return "dec{b}\t%0";
6268 }
6269
6270 default:
6271 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6272 if (INTVAL (operands[2]) < 0)
6273 {
6274 operands[2] = GEN_INT (-INTVAL (operands[2]));
6275 return "add{b}\t{%2, %0|%0, %2}";
6276 }
6277 return "sub{b}\t{%2, %0|%0, %2}";
6278 }
6279 }
6280 [(set (attr "type")
6281 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6282 (const_string "incdec")
6283 (const_string "alu")))
6284 (set_attr "mode" "QI")])
6285
6286
6287 (define_insn "*addqi_5"
6288 [(set (reg FLAGS_REG)
6289 (compare
6290 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6291 (match_operand:QI 2 "general_operand" "qmni"))
6292 (const_int 0)))
6293 (clobber (match_scratch:QI 0 "=q"))]
6294 "ix86_match_ccmode (insn, CCGOCmode)
6295 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6296 {
6297 switch (get_attr_type (insn))
6298 {
6299 case TYPE_INCDEC:
6300 if (operands[2] == const1_rtx)
6301 return "inc{b}\t%0";
6302 else
6303 {
6304 gcc_assert (operands[2] == constm1_rtx
6305 || (GET_CODE (operands[2]) == CONST_INT
6306 && INTVAL (operands[2]) == 255));
6307 return "dec{b}\t%0";
6308 }
6309
6310 default:
6311 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6312 if (GET_CODE (operands[2]) == CONST_INT
6313 && INTVAL (operands[2]) < 0)
6314 {
6315 operands[2] = GEN_INT (-INTVAL (operands[2]));
6316 return "sub{b}\t{%2, %0|%0, %2}";
6317 }
6318 return "add{b}\t{%2, %0|%0, %2}";
6319 }
6320 }
6321 [(set (attr "type")
6322 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6323 (const_string "incdec")
6324 (const_string "alu")))
6325 (set_attr "mode" "QI")])
6326
6327
6328 (define_insn "addqi_ext_1"
6329 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6330 (const_int 8)
6331 (const_int 8))
6332 (plus:SI
6333 (zero_extract:SI
6334 (match_operand 1 "ext_register_operand" "0")
6335 (const_int 8)
6336 (const_int 8))
6337 (match_operand:QI 2 "general_operand" "Qmn")))
6338 (clobber (reg:CC FLAGS_REG))]
6339 "!TARGET_64BIT"
6340 {
6341 switch (get_attr_type (insn))
6342 {
6343 case TYPE_INCDEC:
6344 if (operands[2] == const1_rtx)
6345 return "inc{b}\t%h0";
6346 else
6347 {
6348 gcc_assert (operands[2] == constm1_rtx
6349 || (GET_CODE (operands[2]) == CONST_INT
6350 && INTVAL (operands[2]) == 255));
6351 return "dec{b}\t%h0";
6352 }
6353
6354 default:
6355 return "add{b}\t{%2, %h0|%h0, %2}";
6356 }
6357 }
6358 [(set (attr "type")
6359 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6360 (const_string "incdec")
6361 (const_string "alu")))
6362 (set_attr "mode" "QI")])
6363
6364 (define_insn "*addqi_ext_1_rex64"
6365 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6366 (const_int 8)
6367 (const_int 8))
6368 (plus:SI
6369 (zero_extract:SI
6370 (match_operand 1 "ext_register_operand" "0")
6371 (const_int 8)
6372 (const_int 8))
6373 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6374 (clobber (reg:CC FLAGS_REG))]
6375 "TARGET_64BIT"
6376 {
6377 switch (get_attr_type (insn))
6378 {
6379 case TYPE_INCDEC:
6380 if (operands[2] == const1_rtx)
6381 return "inc{b}\t%h0";
6382 else
6383 {
6384 gcc_assert (operands[2] == constm1_rtx
6385 || (GET_CODE (operands[2]) == CONST_INT
6386 && INTVAL (operands[2]) == 255));
6387 return "dec{b}\t%h0";
6388 }
6389
6390 default:
6391 return "add{b}\t{%2, %h0|%h0, %2}";
6392 }
6393 }
6394 [(set (attr "type")
6395 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6396 (const_string "incdec")
6397 (const_string "alu")))
6398 (set_attr "mode" "QI")])
6399
6400 (define_insn "*addqi_ext_2"
6401 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6402 (const_int 8)
6403 (const_int 8))
6404 (plus:SI
6405 (zero_extract:SI
6406 (match_operand 1 "ext_register_operand" "%0")
6407 (const_int 8)
6408 (const_int 8))
6409 (zero_extract:SI
6410 (match_operand 2 "ext_register_operand" "Q")
6411 (const_int 8)
6412 (const_int 8))))
6413 (clobber (reg:CC FLAGS_REG))]
6414 ""
6415 "add{b}\t{%h2, %h0|%h0, %h2}"
6416 [(set_attr "type" "alu")
6417 (set_attr "mode" "QI")])
6418
6419 ;; The patterns that match these are at the end of this file.
6420
6421 (define_expand "addxf3"
6422 [(set (match_operand:XF 0 "register_operand" "")
6423 (plus:XF (match_operand:XF 1 "register_operand" "")
6424 (match_operand:XF 2 "register_operand" "")))]
6425 "TARGET_80387"
6426 "")
6427
6428 (define_expand "adddf3"
6429 [(set (match_operand:DF 0 "register_operand" "")
6430 (plus:DF (match_operand:DF 1 "register_operand" "")
6431 (match_operand:DF 2 "nonimmediate_operand" "")))]
6432 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6433 "")
6434
6435 (define_expand "addsf3"
6436 [(set (match_operand:SF 0 "register_operand" "")
6437 (plus:SF (match_operand:SF 1 "register_operand" "")
6438 (match_operand:SF 2 "nonimmediate_operand" "")))]
6439 "TARGET_80387 || TARGET_SSE_MATH"
6440 "")
6441 \f
6442 ;; Subtract instructions
6443
6444 ;; %%% splits for subditi3
6445
6446 (define_expand "subti3"
6447 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6448 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6449 (match_operand:TI 2 "x86_64_general_operand" "")))
6450 (clobber (reg:CC FLAGS_REG))])]
6451 "TARGET_64BIT"
6452 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6453
6454 (define_insn "*subti3_1"
6455 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6456 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6457 (match_operand:TI 2 "general_operand" "roiF,riF")))
6458 (clobber (reg:CC FLAGS_REG))]
6459 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6460 "#")
6461
6462 (define_split
6463 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6464 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6465 (match_operand:TI 2 "general_operand" "")))
6466 (clobber (reg:CC FLAGS_REG))]
6467 "TARGET_64BIT && reload_completed"
6468 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6469 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6470 (parallel [(set (match_dup 3)
6471 (minus:DI (match_dup 4)
6472 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6473 (match_dup 5))))
6474 (clobber (reg:CC FLAGS_REG))])]
6475 "split_ti (operands+0, 1, operands+0, operands+3);
6476 split_ti (operands+1, 1, operands+1, operands+4);
6477 split_ti (operands+2, 1, operands+2, operands+5);")
6478
6479 ;; %%% splits for subsidi3
6480
6481 (define_expand "subdi3"
6482 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6483 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6484 (match_operand:DI 2 "x86_64_general_operand" "")))
6485 (clobber (reg:CC FLAGS_REG))])]
6486 ""
6487 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6488
6489 (define_insn "*subdi3_1"
6490 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6491 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6492 (match_operand:DI 2 "general_operand" "roiF,riF")))
6493 (clobber (reg:CC FLAGS_REG))]
6494 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6495 "#")
6496
6497 (define_split
6498 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6499 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6500 (match_operand:DI 2 "general_operand" "")))
6501 (clobber (reg:CC FLAGS_REG))]
6502 "!TARGET_64BIT && reload_completed"
6503 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6504 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6505 (parallel [(set (match_dup 3)
6506 (minus:SI (match_dup 4)
6507 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6508 (match_dup 5))))
6509 (clobber (reg:CC FLAGS_REG))])]
6510 "split_di (operands+0, 1, operands+0, operands+3);
6511 split_di (operands+1, 1, operands+1, operands+4);
6512 split_di (operands+2, 1, operands+2, operands+5);")
6513
6514 (define_insn "subdi3_carry_rex64"
6515 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6516 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6517 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6518 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6519 (clobber (reg:CC FLAGS_REG))]
6520 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6521 "sbb{q}\t{%2, %0|%0, %2}"
6522 [(set_attr "type" "alu")
6523 (set_attr "pent_pair" "pu")
6524 (set_attr "mode" "DI")])
6525
6526 (define_insn "*subdi_1_rex64"
6527 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6528 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6529 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6530 (clobber (reg:CC FLAGS_REG))]
6531 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6532 "sub{q}\t{%2, %0|%0, %2}"
6533 [(set_attr "type" "alu")
6534 (set_attr "mode" "DI")])
6535
6536 (define_insn "*subdi_2_rex64"
6537 [(set (reg FLAGS_REG)
6538 (compare
6539 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6540 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6541 (const_int 0)))
6542 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6543 (minus:DI (match_dup 1) (match_dup 2)))]
6544 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6545 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6546 "sub{q}\t{%2, %0|%0, %2}"
6547 [(set_attr "type" "alu")
6548 (set_attr "mode" "DI")])
6549
6550 (define_insn "*subdi_3_rex63"
6551 [(set (reg FLAGS_REG)
6552 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6553 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6554 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6555 (minus:DI (match_dup 1) (match_dup 2)))]
6556 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6557 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6558 "sub{q}\t{%2, %0|%0, %2}"
6559 [(set_attr "type" "alu")
6560 (set_attr "mode" "DI")])
6561
6562 (define_insn "subqi3_carry"
6563 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6564 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6565 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6566 (match_operand:QI 2 "general_operand" "qi,qm"))))
6567 (clobber (reg:CC FLAGS_REG))]
6568 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6569 "sbb{b}\t{%2, %0|%0, %2}"
6570 [(set_attr "type" "alu")
6571 (set_attr "pent_pair" "pu")
6572 (set_attr "mode" "QI")])
6573
6574 (define_insn "subhi3_carry"
6575 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6576 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6577 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6578 (match_operand:HI 2 "general_operand" "ri,rm"))))
6579 (clobber (reg:CC FLAGS_REG))]
6580 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6581 "sbb{w}\t{%2, %0|%0, %2}"
6582 [(set_attr "type" "alu")
6583 (set_attr "pent_pair" "pu")
6584 (set_attr "mode" "HI")])
6585
6586 (define_insn "subsi3_carry"
6587 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6588 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6589 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6590 (match_operand:SI 2 "general_operand" "ri,rm"))))
6591 (clobber (reg:CC FLAGS_REG))]
6592 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6593 "sbb{l}\t{%2, %0|%0, %2}"
6594 [(set_attr "type" "alu")
6595 (set_attr "pent_pair" "pu")
6596 (set_attr "mode" "SI")])
6597
6598 (define_insn "subsi3_carry_zext"
6599 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6600 (zero_extend:DI
6601 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6602 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6603 (match_operand:SI 2 "general_operand" "ri,rm")))))
6604 (clobber (reg:CC FLAGS_REG))]
6605 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6606 "sbb{l}\t{%2, %k0|%k0, %2}"
6607 [(set_attr "type" "alu")
6608 (set_attr "pent_pair" "pu")
6609 (set_attr "mode" "SI")])
6610
6611 (define_expand "subsi3"
6612 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6613 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6614 (match_operand:SI 2 "general_operand" "")))
6615 (clobber (reg:CC FLAGS_REG))])]
6616 ""
6617 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6618
6619 (define_insn "*subsi_1"
6620 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6621 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6622 (match_operand:SI 2 "general_operand" "ri,rm")))
6623 (clobber (reg:CC FLAGS_REG))]
6624 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6625 "sub{l}\t{%2, %0|%0, %2}"
6626 [(set_attr "type" "alu")
6627 (set_attr "mode" "SI")])
6628
6629 (define_insn "*subsi_1_zext"
6630 [(set (match_operand:DI 0 "register_operand" "=r")
6631 (zero_extend:DI
6632 (minus:SI (match_operand:SI 1 "register_operand" "0")
6633 (match_operand:SI 2 "general_operand" "rim"))))
6634 (clobber (reg:CC FLAGS_REG))]
6635 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6636 "sub{l}\t{%2, %k0|%k0, %2}"
6637 [(set_attr "type" "alu")
6638 (set_attr "mode" "SI")])
6639
6640 (define_insn "*subsi_2"
6641 [(set (reg FLAGS_REG)
6642 (compare
6643 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6644 (match_operand:SI 2 "general_operand" "ri,rm"))
6645 (const_int 0)))
6646 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6647 (minus:SI (match_dup 1) (match_dup 2)))]
6648 "ix86_match_ccmode (insn, CCGOCmode)
6649 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650 "sub{l}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "mode" "SI")])
6653
6654 (define_insn "*subsi_2_zext"
6655 [(set (reg FLAGS_REG)
6656 (compare
6657 (minus:SI (match_operand:SI 1 "register_operand" "0")
6658 (match_operand:SI 2 "general_operand" "rim"))
6659 (const_int 0)))
6660 (set (match_operand:DI 0 "register_operand" "=r")
6661 (zero_extend:DI
6662 (minus:SI (match_dup 1)
6663 (match_dup 2))))]
6664 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6666 "sub{l}\t{%2, %k0|%k0, %2}"
6667 [(set_attr "type" "alu")
6668 (set_attr "mode" "SI")])
6669
6670 (define_insn "*subsi_3"
6671 [(set (reg FLAGS_REG)
6672 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673 (match_operand:SI 2 "general_operand" "ri,rm")))
6674 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6675 (minus:SI (match_dup 1) (match_dup 2)))]
6676 "ix86_match_ccmode (insn, CCmode)
6677 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6678 "sub{l}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "mode" "SI")])
6681
6682 (define_insn "*subsi_3_zext"
6683 [(set (reg FLAGS_REG)
6684 (compare (match_operand:SI 1 "register_operand" "0")
6685 (match_operand:SI 2 "general_operand" "rim")))
6686 (set (match_operand:DI 0 "register_operand" "=r")
6687 (zero_extend:DI
6688 (minus:SI (match_dup 1)
6689 (match_dup 2))))]
6690 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6691 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6692 "sub{q}\t{%2, %0|%0, %2}"
6693 [(set_attr "type" "alu")
6694 (set_attr "mode" "DI")])
6695
6696 (define_expand "subhi3"
6697 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6698 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6699 (match_operand:HI 2 "general_operand" "")))
6700 (clobber (reg:CC FLAGS_REG))])]
6701 "TARGET_HIMODE_MATH"
6702 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6703
6704 (define_insn "*subhi_1"
6705 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6706 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6707 (match_operand:HI 2 "general_operand" "ri,rm")))
6708 (clobber (reg:CC FLAGS_REG))]
6709 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6710 "sub{w}\t{%2, %0|%0, %2}"
6711 [(set_attr "type" "alu")
6712 (set_attr "mode" "HI")])
6713
6714 (define_insn "*subhi_2"
6715 [(set (reg FLAGS_REG)
6716 (compare
6717 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6718 (match_operand:HI 2 "general_operand" "ri,rm"))
6719 (const_int 0)))
6720 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6721 (minus:HI (match_dup 1) (match_dup 2)))]
6722 "ix86_match_ccmode (insn, CCGOCmode)
6723 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6724 "sub{w}\t{%2, %0|%0, %2}"
6725 [(set_attr "type" "alu")
6726 (set_attr "mode" "HI")])
6727
6728 (define_insn "*subhi_3"
6729 [(set (reg FLAGS_REG)
6730 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6731 (match_operand:HI 2 "general_operand" "ri,rm")))
6732 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6733 (minus:HI (match_dup 1) (match_dup 2)))]
6734 "ix86_match_ccmode (insn, CCmode)
6735 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6736 "sub{w}\t{%2, %0|%0, %2}"
6737 [(set_attr "type" "alu")
6738 (set_attr "mode" "HI")])
6739
6740 (define_expand "subqi3"
6741 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6742 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6743 (match_operand:QI 2 "general_operand" "")))
6744 (clobber (reg:CC FLAGS_REG))])]
6745 "TARGET_QIMODE_MATH"
6746 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6747
6748 (define_insn "*subqi_1"
6749 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6750 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6751 (match_operand:QI 2 "general_operand" "qn,qmn")))
6752 (clobber (reg:CC FLAGS_REG))]
6753 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6754 "sub{b}\t{%2, %0|%0, %2}"
6755 [(set_attr "type" "alu")
6756 (set_attr "mode" "QI")])
6757
6758 (define_insn "*subqi_1_slp"
6759 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6760 (minus:QI (match_dup 0)
6761 (match_operand:QI 1 "general_operand" "qn,qmn")))
6762 (clobber (reg:CC FLAGS_REG))]
6763 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6764 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6765 "sub{b}\t{%1, %0|%0, %1}"
6766 [(set_attr "type" "alu1")
6767 (set_attr "mode" "QI")])
6768
6769 (define_insn "*subqi_2"
6770 [(set (reg FLAGS_REG)
6771 (compare
6772 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6773 (match_operand:QI 2 "general_operand" "qi,qm"))
6774 (const_int 0)))
6775 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6776 (minus:HI (match_dup 1) (match_dup 2)))]
6777 "ix86_match_ccmode (insn, CCGOCmode)
6778 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6779 "sub{b}\t{%2, %0|%0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "QI")])
6782
6783 (define_insn "*subqi_3"
6784 [(set (reg FLAGS_REG)
6785 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6786 (match_operand:QI 2 "general_operand" "qi,qm")))
6787 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6788 (minus:HI (match_dup 1) (match_dup 2)))]
6789 "ix86_match_ccmode (insn, CCmode)
6790 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6791 "sub{b}\t{%2, %0|%0, %2}"
6792 [(set_attr "type" "alu")
6793 (set_attr "mode" "QI")])
6794
6795 ;; The patterns that match these are at the end of this file.
6796
6797 (define_expand "subxf3"
6798 [(set (match_operand:XF 0 "register_operand" "")
6799 (minus:XF (match_operand:XF 1 "register_operand" "")
6800 (match_operand:XF 2 "register_operand" "")))]
6801 "TARGET_80387"
6802 "")
6803
6804 (define_expand "subdf3"
6805 [(set (match_operand:DF 0 "register_operand" "")
6806 (minus:DF (match_operand:DF 1 "register_operand" "")
6807 (match_operand:DF 2 "nonimmediate_operand" "")))]
6808 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6809 "")
6810
6811 (define_expand "subsf3"
6812 [(set (match_operand:SF 0 "register_operand" "")
6813 (minus:SF (match_operand:SF 1 "register_operand" "")
6814 (match_operand:SF 2 "nonimmediate_operand" "")))]
6815 "TARGET_80387 || TARGET_SSE_MATH"
6816 "")
6817 \f
6818 ;; Multiply instructions
6819
6820 (define_expand "muldi3"
6821 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6822 (mult:DI (match_operand:DI 1 "register_operand" "")
6823 (match_operand:DI 2 "x86_64_general_operand" "")))
6824 (clobber (reg:CC FLAGS_REG))])]
6825 "TARGET_64BIT"
6826 "")
6827
6828 (define_insn "*muldi3_1_rex64"
6829 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6830 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6831 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6832 (clobber (reg:CC FLAGS_REG))]
6833 "TARGET_64BIT
6834 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6835 "@
6836 imul{q}\t{%2, %1, %0|%0, %1, %2}
6837 imul{q}\t{%2, %1, %0|%0, %1, %2}
6838 imul{q}\t{%2, %0|%0, %2}"
6839 [(set_attr "type" "imul")
6840 (set_attr "prefix_0f" "0,0,1")
6841 (set (attr "athlon_decode")
6842 (cond [(eq_attr "cpu" "athlon")
6843 (const_string "vector")
6844 (eq_attr "alternative" "1")
6845 (const_string "vector")
6846 (and (eq_attr "alternative" "2")
6847 (match_operand 1 "memory_operand" ""))
6848 (const_string "vector")]
6849 (const_string "direct")))
6850 (set_attr "mode" "DI")])
6851
6852 (define_expand "mulsi3"
6853 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6854 (mult:SI (match_operand:SI 1 "register_operand" "")
6855 (match_operand:SI 2 "general_operand" "")))
6856 (clobber (reg:CC FLAGS_REG))])]
6857 ""
6858 "")
6859
6860 (define_insn "*mulsi3_1"
6861 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6862 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6863 (match_operand:SI 2 "general_operand" "K,i,mr")))
6864 (clobber (reg:CC FLAGS_REG))]
6865 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6866 "@
6867 imul{l}\t{%2, %1, %0|%0, %1, %2}
6868 imul{l}\t{%2, %1, %0|%0, %1, %2}
6869 imul{l}\t{%2, %0|%0, %2}"
6870 [(set_attr "type" "imul")
6871 (set_attr "prefix_0f" "0,0,1")
6872 (set (attr "athlon_decode")
6873 (cond [(eq_attr "cpu" "athlon")
6874 (const_string "vector")
6875 (eq_attr "alternative" "1")
6876 (const_string "vector")
6877 (and (eq_attr "alternative" "2")
6878 (match_operand 1 "memory_operand" ""))
6879 (const_string "vector")]
6880 (const_string "direct")))
6881 (set_attr "mode" "SI")])
6882
6883 (define_insn "*mulsi3_1_zext"
6884 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6885 (zero_extend:DI
6886 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6887 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6888 (clobber (reg:CC FLAGS_REG))]
6889 "TARGET_64BIT
6890 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6891 "@
6892 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6893 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6894 imul{l}\t{%2, %k0|%k0, %2}"
6895 [(set_attr "type" "imul")
6896 (set_attr "prefix_0f" "0,0,1")
6897 (set (attr "athlon_decode")
6898 (cond [(eq_attr "cpu" "athlon")
6899 (const_string "vector")
6900 (eq_attr "alternative" "1")
6901 (const_string "vector")
6902 (and (eq_attr "alternative" "2")
6903 (match_operand 1 "memory_operand" ""))
6904 (const_string "vector")]
6905 (const_string "direct")))
6906 (set_attr "mode" "SI")])
6907
6908 (define_expand "mulhi3"
6909 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6910 (mult:HI (match_operand:HI 1 "register_operand" "")
6911 (match_operand:HI 2 "general_operand" "")))
6912 (clobber (reg:CC FLAGS_REG))])]
6913 "TARGET_HIMODE_MATH"
6914 "")
6915
6916 (define_insn "*mulhi3_1"
6917 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6918 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6919 (match_operand:HI 2 "general_operand" "K,i,mr")))
6920 (clobber (reg:CC FLAGS_REG))]
6921 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6922 "@
6923 imul{w}\t{%2, %1, %0|%0, %1, %2}
6924 imul{w}\t{%2, %1, %0|%0, %1, %2}
6925 imul{w}\t{%2, %0|%0, %2}"
6926 [(set_attr "type" "imul")
6927 (set_attr "prefix_0f" "0,0,1")
6928 (set (attr "athlon_decode")
6929 (cond [(eq_attr "cpu" "athlon")
6930 (const_string "vector")
6931 (eq_attr "alternative" "1,2")
6932 (const_string "vector")]
6933 (const_string "direct")))
6934 (set_attr "mode" "HI")])
6935
6936 (define_expand "mulqi3"
6937 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6938 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6939 (match_operand:QI 2 "register_operand" "")))
6940 (clobber (reg:CC FLAGS_REG))])]
6941 "TARGET_QIMODE_MATH"
6942 "")
6943
6944 (define_insn "*mulqi3_1"
6945 [(set (match_operand:QI 0 "register_operand" "=a")
6946 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6947 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6948 (clobber (reg:CC FLAGS_REG))]
6949 "TARGET_QIMODE_MATH
6950 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6951 "mul{b}\t%2"
6952 [(set_attr "type" "imul")
6953 (set_attr "length_immediate" "0")
6954 (set (attr "athlon_decode")
6955 (if_then_else (eq_attr "cpu" "athlon")
6956 (const_string "vector")
6957 (const_string "direct")))
6958 (set_attr "mode" "QI")])
6959
6960 (define_expand "umulqihi3"
6961 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6962 (mult:HI (zero_extend:HI
6963 (match_operand:QI 1 "nonimmediate_operand" ""))
6964 (zero_extend:HI
6965 (match_operand:QI 2 "register_operand" ""))))
6966 (clobber (reg:CC FLAGS_REG))])]
6967 "TARGET_QIMODE_MATH"
6968 "")
6969
6970 (define_insn "*umulqihi3_1"
6971 [(set (match_operand:HI 0 "register_operand" "=a")
6972 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6973 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6974 (clobber (reg:CC FLAGS_REG))]
6975 "TARGET_QIMODE_MATH
6976 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6977 "mul{b}\t%2"
6978 [(set_attr "type" "imul")
6979 (set_attr "length_immediate" "0")
6980 (set (attr "athlon_decode")
6981 (if_then_else (eq_attr "cpu" "athlon")
6982 (const_string "vector")
6983 (const_string "direct")))
6984 (set_attr "mode" "QI")])
6985
6986 (define_expand "mulqihi3"
6987 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6988 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6989 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6990 (clobber (reg:CC FLAGS_REG))])]
6991 "TARGET_QIMODE_MATH"
6992 "")
6993
6994 (define_insn "*mulqihi3_insn"
6995 [(set (match_operand:HI 0 "register_operand" "=a")
6996 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6997 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6998 (clobber (reg:CC FLAGS_REG))]
6999 "TARGET_QIMODE_MATH
7000 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7001 "imul{b}\t%2"
7002 [(set_attr "type" "imul")
7003 (set_attr "length_immediate" "0")
7004 (set (attr "athlon_decode")
7005 (if_then_else (eq_attr "cpu" "athlon")
7006 (const_string "vector")
7007 (const_string "direct")))
7008 (set_attr "mode" "QI")])
7009
7010 (define_expand "umulditi3"
7011 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7012 (mult:TI (zero_extend:TI
7013 (match_operand:DI 1 "nonimmediate_operand" ""))
7014 (zero_extend:TI
7015 (match_operand:DI 2 "register_operand" ""))))
7016 (clobber (reg:CC FLAGS_REG))])]
7017 "TARGET_64BIT"
7018 "")
7019
7020 (define_insn "*umulditi3_insn"
7021 [(set (match_operand:TI 0 "register_operand" "=A")
7022 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7023 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7024 (clobber (reg:CC FLAGS_REG))]
7025 "TARGET_64BIT
7026 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7027 "mul{q}\t%2"
7028 [(set_attr "type" "imul")
7029 (set_attr "length_immediate" "0")
7030 (set (attr "athlon_decode")
7031 (if_then_else (eq_attr "cpu" "athlon")
7032 (const_string "vector")
7033 (const_string "double")))
7034 (set_attr "mode" "DI")])
7035
7036 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7037 (define_expand "umulsidi3"
7038 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7039 (mult:DI (zero_extend:DI
7040 (match_operand:SI 1 "nonimmediate_operand" ""))
7041 (zero_extend:DI
7042 (match_operand:SI 2 "register_operand" ""))))
7043 (clobber (reg:CC FLAGS_REG))])]
7044 "!TARGET_64BIT"
7045 "")
7046
7047 (define_insn "*umulsidi3_insn"
7048 [(set (match_operand:DI 0 "register_operand" "=A")
7049 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7050 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7051 (clobber (reg:CC FLAGS_REG))]
7052 "!TARGET_64BIT
7053 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7054 "mul{l}\t%2"
7055 [(set_attr "type" "imul")
7056 (set_attr "length_immediate" "0")
7057 (set (attr "athlon_decode")
7058 (if_then_else (eq_attr "cpu" "athlon")
7059 (const_string "vector")
7060 (const_string "double")))
7061 (set_attr "mode" "SI")])
7062
7063 (define_expand "mulditi3"
7064 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7065 (mult:TI (sign_extend:TI
7066 (match_operand:DI 1 "nonimmediate_operand" ""))
7067 (sign_extend:TI
7068 (match_operand:DI 2 "register_operand" ""))))
7069 (clobber (reg:CC FLAGS_REG))])]
7070 "TARGET_64BIT"
7071 "")
7072
7073 (define_insn "*mulditi3_insn"
7074 [(set (match_operand:TI 0 "register_operand" "=A")
7075 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7076 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7077 (clobber (reg:CC FLAGS_REG))]
7078 "TARGET_64BIT
7079 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7080 "imul{q}\t%2"
7081 [(set_attr "type" "imul")
7082 (set_attr "length_immediate" "0")
7083 (set (attr "athlon_decode")
7084 (if_then_else (eq_attr "cpu" "athlon")
7085 (const_string "vector")
7086 (const_string "double")))
7087 (set_attr "mode" "DI")])
7088
7089 (define_expand "mulsidi3"
7090 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7091 (mult:DI (sign_extend:DI
7092 (match_operand:SI 1 "nonimmediate_operand" ""))
7093 (sign_extend:DI
7094 (match_operand:SI 2 "register_operand" ""))))
7095 (clobber (reg:CC FLAGS_REG))])]
7096 "!TARGET_64BIT"
7097 "")
7098
7099 (define_insn "*mulsidi3_insn"
7100 [(set (match_operand:DI 0 "register_operand" "=A")
7101 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7102 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7103 (clobber (reg:CC FLAGS_REG))]
7104 "!TARGET_64BIT
7105 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7106 "imul{l}\t%2"
7107 [(set_attr "type" "imul")
7108 (set_attr "length_immediate" "0")
7109 (set (attr "athlon_decode")
7110 (if_then_else (eq_attr "cpu" "athlon")
7111 (const_string "vector")
7112 (const_string "double")))
7113 (set_attr "mode" "SI")])
7114
7115 (define_expand "umuldi3_highpart"
7116 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7117 (truncate:DI
7118 (lshiftrt:TI
7119 (mult:TI (zero_extend:TI
7120 (match_operand:DI 1 "nonimmediate_operand" ""))
7121 (zero_extend:TI
7122 (match_operand:DI 2 "register_operand" "")))
7123 (const_int 64))))
7124 (clobber (match_scratch:DI 3 ""))
7125 (clobber (reg:CC FLAGS_REG))])]
7126 "TARGET_64BIT"
7127 "")
7128
7129 (define_insn "*umuldi3_highpart_rex64"
7130 [(set (match_operand:DI 0 "register_operand" "=d")
7131 (truncate:DI
7132 (lshiftrt:TI
7133 (mult:TI (zero_extend:TI
7134 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7135 (zero_extend:TI
7136 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7137 (const_int 64))))
7138 (clobber (match_scratch:DI 3 "=1"))
7139 (clobber (reg:CC FLAGS_REG))]
7140 "TARGET_64BIT
7141 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7142 "mul{q}\t%2"
7143 [(set_attr "type" "imul")
7144 (set_attr "length_immediate" "0")
7145 (set (attr "athlon_decode")
7146 (if_then_else (eq_attr "cpu" "athlon")
7147 (const_string "vector")
7148 (const_string "double")))
7149 (set_attr "mode" "DI")])
7150
7151 (define_expand "umulsi3_highpart"
7152 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7153 (truncate:SI
7154 (lshiftrt:DI
7155 (mult:DI (zero_extend:DI
7156 (match_operand:SI 1 "nonimmediate_operand" ""))
7157 (zero_extend:DI
7158 (match_operand:SI 2 "register_operand" "")))
7159 (const_int 32))))
7160 (clobber (match_scratch:SI 3 ""))
7161 (clobber (reg:CC FLAGS_REG))])]
7162 ""
7163 "")
7164
7165 (define_insn "*umulsi3_highpart_insn"
7166 [(set (match_operand:SI 0 "register_operand" "=d")
7167 (truncate:SI
7168 (lshiftrt:DI
7169 (mult:DI (zero_extend:DI
7170 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7171 (zero_extend:DI
7172 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7173 (const_int 32))))
7174 (clobber (match_scratch:SI 3 "=1"))
7175 (clobber (reg:CC FLAGS_REG))]
7176 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7177 "mul{l}\t%2"
7178 [(set_attr "type" "imul")
7179 (set_attr "length_immediate" "0")
7180 (set (attr "athlon_decode")
7181 (if_then_else (eq_attr "cpu" "athlon")
7182 (const_string "vector")
7183 (const_string "double")))
7184 (set_attr "mode" "SI")])
7185
7186 (define_insn "*umulsi3_highpart_zext"
7187 [(set (match_operand:DI 0 "register_operand" "=d")
7188 (zero_extend:DI (truncate:SI
7189 (lshiftrt:DI
7190 (mult:DI (zero_extend:DI
7191 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7192 (zero_extend:DI
7193 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7194 (const_int 32)))))
7195 (clobber (match_scratch:SI 3 "=1"))
7196 (clobber (reg:CC FLAGS_REG))]
7197 "TARGET_64BIT
7198 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7199 "mul{l}\t%2"
7200 [(set_attr "type" "imul")
7201 (set_attr "length_immediate" "0")
7202 (set (attr "athlon_decode")
7203 (if_then_else (eq_attr "cpu" "athlon")
7204 (const_string "vector")
7205 (const_string "double")))
7206 (set_attr "mode" "SI")])
7207
7208 (define_expand "smuldi3_highpart"
7209 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7210 (truncate:DI
7211 (lshiftrt:TI
7212 (mult:TI (sign_extend:TI
7213 (match_operand:DI 1 "nonimmediate_operand" ""))
7214 (sign_extend:TI
7215 (match_operand:DI 2 "register_operand" "")))
7216 (const_int 64))))
7217 (clobber (match_scratch:DI 3 ""))
7218 (clobber (reg:CC FLAGS_REG))])]
7219 "TARGET_64BIT"
7220 "")
7221
7222 (define_insn "*smuldi3_highpart_rex64"
7223 [(set (match_operand:DI 0 "register_operand" "=d")
7224 (truncate:DI
7225 (lshiftrt:TI
7226 (mult:TI (sign_extend:TI
7227 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7228 (sign_extend:TI
7229 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7230 (const_int 64))))
7231 (clobber (match_scratch:DI 3 "=1"))
7232 (clobber (reg:CC FLAGS_REG))]
7233 "TARGET_64BIT
7234 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7235 "imul{q}\t%2"
7236 [(set_attr "type" "imul")
7237 (set (attr "athlon_decode")
7238 (if_then_else (eq_attr "cpu" "athlon")
7239 (const_string "vector")
7240 (const_string "double")))
7241 (set_attr "mode" "DI")])
7242
7243 (define_expand "smulsi3_highpart"
7244 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7245 (truncate:SI
7246 (lshiftrt:DI
7247 (mult:DI (sign_extend:DI
7248 (match_operand:SI 1 "nonimmediate_operand" ""))
7249 (sign_extend:DI
7250 (match_operand:SI 2 "register_operand" "")))
7251 (const_int 32))))
7252 (clobber (match_scratch:SI 3 ""))
7253 (clobber (reg:CC FLAGS_REG))])]
7254 ""
7255 "")
7256
7257 (define_insn "*smulsi3_highpart_insn"
7258 [(set (match_operand:SI 0 "register_operand" "=d")
7259 (truncate:SI
7260 (lshiftrt:DI
7261 (mult:DI (sign_extend:DI
7262 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7263 (sign_extend:DI
7264 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7265 (const_int 32))))
7266 (clobber (match_scratch:SI 3 "=1"))
7267 (clobber (reg:CC FLAGS_REG))]
7268 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7269 "imul{l}\t%2"
7270 [(set_attr "type" "imul")
7271 (set (attr "athlon_decode")
7272 (if_then_else (eq_attr "cpu" "athlon")
7273 (const_string "vector")
7274 (const_string "double")))
7275 (set_attr "mode" "SI")])
7276
7277 (define_insn "*smulsi3_highpart_zext"
7278 [(set (match_operand:DI 0 "register_operand" "=d")
7279 (zero_extend:DI (truncate:SI
7280 (lshiftrt:DI
7281 (mult:DI (sign_extend:DI
7282 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7283 (sign_extend:DI
7284 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7285 (const_int 32)))))
7286 (clobber (match_scratch:SI 3 "=1"))
7287 (clobber (reg:CC FLAGS_REG))]
7288 "TARGET_64BIT
7289 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7290 "imul{l}\t%2"
7291 [(set_attr "type" "imul")
7292 (set (attr "athlon_decode")
7293 (if_then_else (eq_attr "cpu" "athlon")
7294 (const_string "vector")
7295 (const_string "double")))
7296 (set_attr "mode" "SI")])
7297
7298 ;; The patterns that match these are at the end of this file.
7299
7300 (define_expand "mulxf3"
7301 [(set (match_operand:XF 0 "register_operand" "")
7302 (mult:XF (match_operand:XF 1 "register_operand" "")
7303 (match_operand:XF 2 "register_operand" "")))]
7304 "TARGET_80387"
7305 "")
7306
7307 (define_expand "muldf3"
7308 [(set (match_operand:DF 0 "register_operand" "")
7309 (mult:DF (match_operand:DF 1 "register_operand" "")
7310 (match_operand:DF 2 "nonimmediate_operand" "")))]
7311 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7312 "")
7313
7314 (define_expand "mulsf3"
7315 [(set (match_operand:SF 0 "register_operand" "")
7316 (mult:SF (match_operand:SF 1 "register_operand" "")
7317 (match_operand:SF 2 "nonimmediate_operand" "")))]
7318 "TARGET_80387 || TARGET_SSE_MATH"
7319 "")
7320 \f
7321 ;; Divide instructions
7322
7323 (define_insn "divqi3"
7324 [(set (match_operand:QI 0 "register_operand" "=a")
7325 (div:QI (match_operand:HI 1 "register_operand" "0")
7326 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7327 (clobber (reg:CC FLAGS_REG))]
7328 "TARGET_QIMODE_MATH"
7329 "idiv{b}\t%2"
7330 [(set_attr "type" "idiv")
7331 (set_attr "mode" "QI")])
7332
7333 (define_insn "udivqi3"
7334 [(set (match_operand:QI 0 "register_operand" "=a")
7335 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7336 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7337 (clobber (reg:CC FLAGS_REG))]
7338 "TARGET_QIMODE_MATH"
7339 "div{b}\t%2"
7340 [(set_attr "type" "idiv")
7341 (set_attr "mode" "QI")])
7342
7343 ;; The patterns that match these are at the end of this file.
7344
7345 (define_expand "divxf3"
7346 [(set (match_operand:XF 0 "register_operand" "")
7347 (div:XF (match_operand:XF 1 "register_operand" "")
7348 (match_operand:XF 2 "register_operand" "")))]
7349 "TARGET_80387"
7350 "")
7351
7352 (define_expand "divdf3"
7353 [(set (match_operand:DF 0 "register_operand" "")
7354 (div:DF (match_operand:DF 1 "register_operand" "")
7355 (match_operand:DF 2 "nonimmediate_operand" "")))]
7356 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7357 "")
7358
7359 (define_expand "divsf3"
7360 [(set (match_operand:SF 0 "register_operand" "")
7361 (div:SF (match_operand:SF 1 "register_operand" "")
7362 (match_operand:SF 2 "nonimmediate_operand" "")))]
7363 "TARGET_80387 || TARGET_SSE_MATH"
7364 "")
7365 \f
7366 ;; Remainder instructions.
7367
7368 (define_expand "divmoddi4"
7369 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7370 (div:DI (match_operand:DI 1 "register_operand" "")
7371 (match_operand:DI 2 "nonimmediate_operand" "")))
7372 (set (match_operand:DI 3 "register_operand" "")
7373 (mod:DI (match_dup 1) (match_dup 2)))
7374 (clobber (reg:CC FLAGS_REG))])]
7375 "TARGET_64BIT"
7376 "")
7377
7378 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7379 ;; Penalize eax case slightly because it results in worse scheduling
7380 ;; of code.
7381 (define_insn "*divmoddi4_nocltd_rex64"
7382 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7383 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7384 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7385 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7386 (mod:DI (match_dup 2) (match_dup 3)))
7387 (clobber (reg:CC FLAGS_REG))]
7388 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7389 "#"
7390 [(set_attr "type" "multi")])
7391
7392 (define_insn "*divmoddi4_cltd_rex64"
7393 [(set (match_operand:DI 0 "register_operand" "=a")
7394 (div:DI (match_operand:DI 2 "register_operand" "a")
7395 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7396 (set (match_operand:DI 1 "register_operand" "=&d")
7397 (mod:DI (match_dup 2) (match_dup 3)))
7398 (clobber (reg:CC FLAGS_REG))]
7399 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7400 "#"
7401 [(set_attr "type" "multi")])
7402
7403 (define_insn "*divmoddi_noext_rex64"
7404 [(set (match_operand:DI 0 "register_operand" "=a")
7405 (div:DI (match_operand:DI 1 "register_operand" "0")
7406 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7407 (set (match_operand:DI 3 "register_operand" "=d")
7408 (mod:DI (match_dup 1) (match_dup 2)))
7409 (use (match_operand:DI 4 "register_operand" "3"))
7410 (clobber (reg:CC FLAGS_REG))]
7411 "TARGET_64BIT"
7412 "idiv{q}\t%2"
7413 [(set_attr "type" "idiv")
7414 (set_attr "mode" "DI")])
7415
7416 (define_split
7417 [(set (match_operand:DI 0 "register_operand" "")
7418 (div:DI (match_operand:DI 1 "register_operand" "")
7419 (match_operand:DI 2 "nonimmediate_operand" "")))
7420 (set (match_operand:DI 3 "register_operand" "")
7421 (mod:DI (match_dup 1) (match_dup 2)))
7422 (clobber (reg:CC FLAGS_REG))]
7423 "TARGET_64BIT && reload_completed"
7424 [(parallel [(set (match_dup 3)
7425 (ashiftrt:DI (match_dup 4) (const_int 63)))
7426 (clobber (reg:CC FLAGS_REG))])
7427 (parallel [(set (match_dup 0)
7428 (div:DI (reg:DI 0) (match_dup 2)))
7429 (set (match_dup 3)
7430 (mod:DI (reg:DI 0) (match_dup 2)))
7431 (use (match_dup 3))
7432 (clobber (reg:CC FLAGS_REG))])]
7433 {
7434 /* Avoid use of cltd in favor of a mov+shift. */
7435 if (!TARGET_USE_CLTD && !optimize_size)
7436 {
7437 if (true_regnum (operands[1]))
7438 emit_move_insn (operands[0], operands[1]);
7439 else
7440 emit_move_insn (operands[3], operands[1]);
7441 operands[4] = operands[3];
7442 }
7443 else
7444 {
7445 gcc_assert (!true_regnum (operands[1]));
7446 operands[4] = operands[1];
7447 }
7448 })
7449
7450
7451 (define_expand "divmodsi4"
7452 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7453 (div:SI (match_operand:SI 1 "register_operand" "")
7454 (match_operand:SI 2 "nonimmediate_operand" "")))
7455 (set (match_operand:SI 3 "register_operand" "")
7456 (mod:SI (match_dup 1) (match_dup 2)))
7457 (clobber (reg:CC FLAGS_REG))])]
7458 ""
7459 "")
7460
7461 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7462 ;; Penalize eax case slightly because it results in worse scheduling
7463 ;; of code.
7464 (define_insn "*divmodsi4_nocltd"
7465 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7466 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7467 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7468 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7469 (mod:SI (match_dup 2) (match_dup 3)))
7470 (clobber (reg:CC FLAGS_REG))]
7471 "!optimize_size && !TARGET_USE_CLTD"
7472 "#"
7473 [(set_attr "type" "multi")])
7474
7475 (define_insn "*divmodsi4_cltd"
7476 [(set (match_operand:SI 0 "register_operand" "=a")
7477 (div:SI (match_operand:SI 2 "register_operand" "a")
7478 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7479 (set (match_operand:SI 1 "register_operand" "=&d")
7480 (mod:SI (match_dup 2) (match_dup 3)))
7481 (clobber (reg:CC FLAGS_REG))]
7482 "optimize_size || TARGET_USE_CLTD"
7483 "#"
7484 [(set_attr "type" "multi")])
7485
7486 (define_insn "*divmodsi_noext"
7487 [(set (match_operand:SI 0 "register_operand" "=a")
7488 (div:SI (match_operand:SI 1 "register_operand" "0")
7489 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7490 (set (match_operand:SI 3 "register_operand" "=d")
7491 (mod:SI (match_dup 1) (match_dup 2)))
7492 (use (match_operand:SI 4 "register_operand" "3"))
7493 (clobber (reg:CC FLAGS_REG))]
7494 ""
7495 "idiv{l}\t%2"
7496 [(set_attr "type" "idiv")
7497 (set_attr "mode" "SI")])
7498
7499 (define_split
7500 [(set (match_operand:SI 0 "register_operand" "")
7501 (div:SI (match_operand:SI 1 "register_operand" "")
7502 (match_operand:SI 2 "nonimmediate_operand" "")))
7503 (set (match_operand:SI 3 "register_operand" "")
7504 (mod:SI (match_dup 1) (match_dup 2)))
7505 (clobber (reg:CC FLAGS_REG))]
7506 "reload_completed"
7507 [(parallel [(set (match_dup 3)
7508 (ashiftrt:SI (match_dup 4) (const_int 31)))
7509 (clobber (reg:CC FLAGS_REG))])
7510 (parallel [(set (match_dup 0)
7511 (div:SI (reg:SI 0) (match_dup 2)))
7512 (set (match_dup 3)
7513 (mod:SI (reg:SI 0) (match_dup 2)))
7514 (use (match_dup 3))
7515 (clobber (reg:CC FLAGS_REG))])]
7516 {
7517 /* Avoid use of cltd in favor of a mov+shift. */
7518 if (!TARGET_USE_CLTD && !optimize_size)
7519 {
7520 if (true_regnum (operands[1]))
7521 emit_move_insn (operands[0], operands[1]);
7522 else
7523 emit_move_insn (operands[3], operands[1]);
7524 operands[4] = operands[3];
7525 }
7526 else
7527 {
7528 gcc_assert (!true_regnum (operands[1]));
7529 operands[4] = operands[1];
7530 }
7531 })
7532 ;; %%% Split me.
7533 (define_insn "divmodhi4"
7534 [(set (match_operand:HI 0 "register_operand" "=a")
7535 (div:HI (match_operand:HI 1 "register_operand" "0")
7536 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7537 (set (match_operand:HI 3 "register_operand" "=&d")
7538 (mod:HI (match_dup 1) (match_dup 2)))
7539 (clobber (reg:CC FLAGS_REG))]
7540 "TARGET_HIMODE_MATH"
7541 "cwtd\;idiv{w}\t%2"
7542 [(set_attr "type" "multi")
7543 (set_attr "length_immediate" "0")
7544 (set_attr "mode" "SI")])
7545
7546 (define_insn "udivmoddi4"
7547 [(set (match_operand:DI 0 "register_operand" "=a")
7548 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7549 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7550 (set (match_operand:DI 3 "register_operand" "=&d")
7551 (umod:DI (match_dup 1) (match_dup 2)))
7552 (clobber (reg:CC FLAGS_REG))]
7553 "TARGET_64BIT"
7554 "xor{q}\t%3, %3\;div{q}\t%2"
7555 [(set_attr "type" "multi")
7556 (set_attr "length_immediate" "0")
7557 (set_attr "mode" "DI")])
7558
7559 (define_insn "*udivmoddi4_noext"
7560 [(set (match_operand:DI 0 "register_operand" "=a")
7561 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7562 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7563 (set (match_operand:DI 3 "register_operand" "=d")
7564 (umod:DI (match_dup 1) (match_dup 2)))
7565 (use (match_dup 3))
7566 (clobber (reg:CC FLAGS_REG))]
7567 "TARGET_64BIT"
7568 "div{q}\t%2"
7569 [(set_attr "type" "idiv")
7570 (set_attr "mode" "DI")])
7571
7572 (define_split
7573 [(set (match_operand:DI 0 "register_operand" "")
7574 (udiv:DI (match_operand:DI 1 "register_operand" "")
7575 (match_operand:DI 2 "nonimmediate_operand" "")))
7576 (set (match_operand:DI 3 "register_operand" "")
7577 (umod:DI (match_dup 1) (match_dup 2)))
7578 (clobber (reg:CC FLAGS_REG))]
7579 "TARGET_64BIT && reload_completed"
7580 [(set (match_dup 3) (const_int 0))
7581 (parallel [(set (match_dup 0)
7582 (udiv:DI (match_dup 1) (match_dup 2)))
7583 (set (match_dup 3)
7584 (umod:DI (match_dup 1) (match_dup 2)))
7585 (use (match_dup 3))
7586 (clobber (reg:CC FLAGS_REG))])]
7587 "")
7588
7589 (define_insn "udivmodsi4"
7590 [(set (match_operand:SI 0 "register_operand" "=a")
7591 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7592 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7593 (set (match_operand:SI 3 "register_operand" "=&d")
7594 (umod:SI (match_dup 1) (match_dup 2)))
7595 (clobber (reg:CC FLAGS_REG))]
7596 ""
7597 "xor{l}\t%3, %3\;div{l}\t%2"
7598 [(set_attr "type" "multi")
7599 (set_attr "length_immediate" "0")
7600 (set_attr "mode" "SI")])
7601
7602 (define_insn "*udivmodsi4_noext"
7603 [(set (match_operand:SI 0 "register_operand" "=a")
7604 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7605 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7606 (set (match_operand:SI 3 "register_operand" "=d")
7607 (umod:SI (match_dup 1) (match_dup 2)))
7608 (use (match_dup 3))
7609 (clobber (reg:CC FLAGS_REG))]
7610 ""
7611 "div{l}\t%2"
7612 [(set_attr "type" "idiv")
7613 (set_attr "mode" "SI")])
7614
7615 (define_split
7616 [(set (match_operand:SI 0 "register_operand" "")
7617 (udiv:SI (match_operand:SI 1 "register_operand" "")
7618 (match_operand:SI 2 "nonimmediate_operand" "")))
7619 (set (match_operand:SI 3 "register_operand" "")
7620 (umod:SI (match_dup 1) (match_dup 2)))
7621 (clobber (reg:CC FLAGS_REG))]
7622 "reload_completed"
7623 [(set (match_dup 3) (const_int 0))
7624 (parallel [(set (match_dup 0)
7625 (udiv:SI (match_dup 1) (match_dup 2)))
7626 (set (match_dup 3)
7627 (umod:SI (match_dup 1) (match_dup 2)))
7628 (use (match_dup 3))
7629 (clobber (reg:CC FLAGS_REG))])]
7630 "")
7631
7632 (define_expand "udivmodhi4"
7633 [(set (match_dup 4) (const_int 0))
7634 (parallel [(set (match_operand:HI 0 "register_operand" "")
7635 (udiv:HI (match_operand:HI 1 "register_operand" "")
7636 (match_operand:HI 2 "nonimmediate_operand" "")))
7637 (set (match_operand:HI 3 "register_operand" "")
7638 (umod:HI (match_dup 1) (match_dup 2)))
7639 (use (match_dup 4))
7640 (clobber (reg:CC FLAGS_REG))])]
7641 "TARGET_HIMODE_MATH"
7642 "operands[4] = gen_reg_rtx (HImode);")
7643
7644 (define_insn "*udivmodhi_noext"
7645 [(set (match_operand:HI 0 "register_operand" "=a")
7646 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7647 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7648 (set (match_operand:HI 3 "register_operand" "=d")
7649 (umod:HI (match_dup 1) (match_dup 2)))
7650 (use (match_operand:HI 4 "register_operand" "3"))
7651 (clobber (reg:CC FLAGS_REG))]
7652 ""
7653 "div{w}\t%2"
7654 [(set_attr "type" "idiv")
7655 (set_attr "mode" "HI")])
7656
7657 ;; We cannot use div/idiv for double division, because it causes
7658 ;; "division by zero" on the overflow and that's not what we expect
7659 ;; from truncate. Because true (non truncating) double division is
7660 ;; never generated, we can't create this insn anyway.
7661 ;
7662 ;(define_insn ""
7663 ; [(set (match_operand:SI 0 "register_operand" "=a")
7664 ; (truncate:SI
7665 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7666 ; (zero_extend:DI
7667 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7668 ; (set (match_operand:SI 3 "register_operand" "=d")
7669 ; (truncate:SI
7670 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7671 ; (clobber (reg:CC FLAGS_REG))]
7672 ; ""
7673 ; "div{l}\t{%2, %0|%0, %2}"
7674 ; [(set_attr "type" "idiv")])
7675 \f
7676 ;;- Logical AND instructions
7677
7678 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7679 ;; Note that this excludes ah.
7680
7681 (define_insn "*testdi_1_rex64"
7682 [(set (reg FLAGS_REG)
7683 (compare
7684 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7685 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7686 (const_int 0)))]
7687 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7688 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7689 "@
7690 test{l}\t{%k1, %k0|%k0, %k1}
7691 test{l}\t{%k1, %k0|%k0, %k1}
7692 test{q}\t{%1, %0|%0, %1}
7693 test{q}\t{%1, %0|%0, %1}
7694 test{q}\t{%1, %0|%0, %1}"
7695 [(set_attr "type" "test")
7696 (set_attr "modrm" "0,1,0,1,1")
7697 (set_attr "mode" "SI,SI,DI,DI,DI")
7698 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7699
7700 (define_insn "testsi_1"
7701 [(set (reg FLAGS_REG)
7702 (compare
7703 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7704 (match_operand:SI 1 "general_operand" "in,in,rin"))
7705 (const_int 0)))]
7706 "ix86_match_ccmode (insn, CCNOmode)
7707 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7708 "test{l}\t{%1, %0|%0, %1}"
7709 [(set_attr "type" "test")
7710 (set_attr "modrm" "0,1,1")
7711 (set_attr "mode" "SI")
7712 (set_attr "pent_pair" "uv,np,uv")])
7713
7714 (define_expand "testsi_ccno_1"
7715 [(set (reg:CCNO FLAGS_REG)
7716 (compare:CCNO
7717 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7718 (match_operand:SI 1 "nonmemory_operand" ""))
7719 (const_int 0)))]
7720 ""
7721 "")
7722
7723 (define_insn "*testhi_1"
7724 [(set (reg FLAGS_REG)
7725 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7726 (match_operand:HI 1 "general_operand" "n,n,rn"))
7727 (const_int 0)))]
7728 "ix86_match_ccmode (insn, CCNOmode)
7729 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7730 "test{w}\t{%1, %0|%0, %1}"
7731 [(set_attr "type" "test")
7732 (set_attr "modrm" "0,1,1")
7733 (set_attr "mode" "HI")
7734 (set_attr "pent_pair" "uv,np,uv")])
7735
7736 (define_expand "testqi_ccz_1"
7737 [(set (reg:CCZ FLAGS_REG)
7738 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7739 (match_operand:QI 1 "nonmemory_operand" ""))
7740 (const_int 0)))]
7741 ""
7742 "")
7743
7744 (define_insn "*testqi_1_maybe_si"
7745 [(set (reg FLAGS_REG)
7746 (compare
7747 (and:QI
7748 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7749 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7750 (const_int 0)))]
7751 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7752 && ix86_match_ccmode (insn,
7753 GET_CODE (operands[1]) == CONST_INT
7754 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7755 {
7756 if (which_alternative == 3)
7757 {
7758 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7759 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7760 return "test{l}\t{%1, %k0|%k0, %1}";
7761 }
7762 return "test{b}\t{%1, %0|%0, %1}";
7763 }
7764 [(set_attr "type" "test")
7765 (set_attr "modrm" "0,1,1,1")
7766 (set_attr "mode" "QI,QI,QI,SI")
7767 (set_attr "pent_pair" "uv,np,uv,np")])
7768
7769 (define_insn "*testqi_1"
7770 [(set (reg FLAGS_REG)
7771 (compare
7772 (and:QI
7773 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7774 (match_operand:QI 1 "general_operand" "n,n,qn"))
7775 (const_int 0)))]
7776 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7777 && ix86_match_ccmode (insn, CCNOmode)"
7778 "test{b}\t{%1, %0|%0, %1}"
7779 [(set_attr "type" "test")
7780 (set_attr "modrm" "0,1,1")
7781 (set_attr "mode" "QI")
7782 (set_attr "pent_pair" "uv,np,uv")])
7783
7784 (define_expand "testqi_ext_ccno_0"
7785 [(set (reg:CCNO FLAGS_REG)
7786 (compare:CCNO
7787 (and:SI
7788 (zero_extract:SI
7789 (match_operand 0 "ext_register_operand" "")
7790 (const_int 8)
7791 (const_int 8))
7792 (match_operand 1 "const_int_operand" ""))
7793 (const_int 0)))]
7794 ""
7795 "")
7796
7797 (define_insn "*testqi_ext_0"
7798 [(set (reg FLAGS_REG)
7799 (compare
7800 (and:SI
7801 (zero_extract:SI
7802 (match_operand 0 "ext_register_operand" "Q")
7803 (const_int 8)
7804 (const_int 8))
7805 (match_operand 1 "const_int_operand" "n"))
7806 (const_int 0)))]
7807 "ix86_match_ccmode (insn, CCNOmode)"
7808 "test{b}\t{%1, %h0|%h0, %1}"
7809 [(set_attr "type" "test")
7810 (set_attr "mode" "QI")
7811 (set_attr "length_immediate" "1")
7812 (set_attr "pent_pair" "np")])
7813
7814 (define_insn "*testqi_ext_1"
7815 [(set (reg FLAGS_REG)
7816 (compare
7817 (and:SI
7818 (zero_extract:SI
7819 (match_operand 0 "ext_register_operand" "Q")
7820 (const_int 8)
7821 (const_int 8))
7822 (zero_extend:SI
7823 (match_operand:QI 1 "general_operand" "Qm")))
7824 (const_int 0)))]
7825 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7826 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7827 "test{b}\t{%1, %h0|%h0, %1}"
7828 [(set_attr "type" "test")
7829 (set_attr "mode" "QI")])
7830
7831 (define_insn "*testqi_ext_1_rex64"
7832 [(set (reg FLAGS_REG)
7833 (compare
7834 (and:SI
7835 (zero_extract:SI
7836 (match_operand 0 "ext_register_operand" "Q")
7837 (const_int 8)
7838 (const_int 8))
7839 (zero_extend:SI
7840 (match_operand:QI 1 "register_operand" "Q")))
7841 (const_int 0)))]
7842 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7843 "test{b}\t{%1, %h0|%h0, %1}"
7844 [(set_attr "type" "test")
7845 (set_attr "mode" "QI")])
7846
7847 (define_insn "*testqi_ext_2"
7848 [(set (reg FLAGS_REG)
7849 (compare
7850 (and:SI
7851 (zero_extract:SI
7852 (match_operand 0 "ext_register_operand" "Q")
7853 (const_int 8)
7854 (const_int 8))
7855 (zero_extract:SI
7856 (match_operand 1 "ext_register_operand" "Q")
7857 (const_int 8)
7858 (const_int 8)))
7859 (const_int 0)))]
7860 "ix86_match_ccmode (insn, CCNOmode)"
7861 "test{b}\t{%h1, %h0|%h0, %h1}"
7862 [(set_attr "type" "test")
7863 (set_attr "mode" "QI")])
7864
7865 ;; Combine likes to form bit extractions for some tests. Humor it.
7866 (define_insn "*testqi_ext_3"
7867 [(set (reg FLAGS_REG)
7868 (compare (zero_extract:SI
7869 (match_operand 0 "nonimmediate_operand" "rm")
7870 (match_operand:SI 1 "const_int_operand" "")
7871 (match_operand:SI 2 "const_int_operand" ""))
7872 (const_int 0)))]
7873 "ix86_match_ccmode (insn, CCNOmode)
7874 && INTVAL (operands[1]) > 0
7875 && INTVAL (operands[2]) >= 0
7876 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7877 && (GET_MODE (operands[0]) == SImode
7878 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7879 || GET_MODE (operands[0]) == HImode
7880 || GET_MODE (operands[0]) == QImode)"
7881 "#")
7882
7883 (define_insn "*testqi_ext_3_rex64"
7884 [(set (reg FLAGS_REG)
7885 (compare (zero_extract:DI
7886 (match_operand 0 "nonimmediate_operand" "rm")
7887 (match_operand:DI 1 "const_int_operand" "")
7888 (match_operand:DI 2 "const_int_operand" ""))
7889 (const_int 0)))]
7890 "TARGET_64BIT
7891 && ix86_match_ccmode (insn, CCNOmode)
7892 && INTVAL (operands[1]) > 0
7893 && INTVAL (operands[2]) >= 0
7894 /* Ensure that resulting mask is zero or sign extended operand. */
7895 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7896 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7897 && INTVAL (operands[1]) > 32))
7898 && (GET_MODE (operands[0]) == SImode
7899 || GET_MODE (operands[0]) == DImode
7900 || GET_MODE (operands[0]) == HImode
7901 || GET_MODE (operands[0]) == QImode)"
7902 "#")
7903
7904 (define_split
7905 [(set (match_operand 0 "flags_reg_operand" "")
7906 (match_operator 1 "compare_operator"
7907 [(zero_extract
7908 (match_operand 2 "nonimmediate_operand" "")
7909 (match_operand 3 "const_int_operand" "")
7910 (match_operand 4 "const_int_operand" ""))
7911 (const_int 0)]))]
7912 "ix86_match_ccmode (insn, CCNOmode)"
7913 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7914 {
7915 rtx val = operands[2];
7916 HOST_WIDE_INT len = INTVAL (operands[3]);
7917 HOST_WIDE_INT pos = INTVAL (operands[4]);
7918 HOST_WIDE_INT mask;
7919 enum machine_mode mode, submode;
7920
7921 mode = GET_MODE (val);
7922 if (GET_CODE (val) == MEM)
7923 {
7924 /* ??? Combine likes to put non-volatile mem extractions in QImode
7925 no matter the size of the test. So find a mode that works. */
7926 if (! MEM_VOLATILE_P (val))
7927 {
7928 mode = smallest_mode_for_size (pos + len, MODE_INT);
7929 val = adjust_address (val, mode, 0);
7930 }
7931 }
7932 else if (GET_CODE (val) == SUBREG
7933 && (submode = GET_MODE (SUBREG_REG (val)),
7934 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7935 && pos + len <= GET_MODE_BITSIZE (submode))
7936 {
7937 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7938 mode = submode;
7939 val = SUBREG_REG (val);
7940 }
7941 else if (mode == HImode && pos + len <= 8)
7942 {
7943 /* Small HImode tests can be converted to QImode. */
7944 mode = QImode;
7945 val = gen_lowpart (QImode, val);
7946 }
7947
7948 if (len == HOST_BITS_PER_WIDE_INT)
7949 mask = -1;
7950 else
7951 mask = ((HOST_WIDE_INT)1 << len) - 1;
7952 mask <<= pos;
7953
7954 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7955 })
7956
7957 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7958 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7959 ;; this is relatively important trick.
7960 ;; Do the conversion only post-reload to avoid limiting of the register class
7961 ;; to QI regs.
7962 (define_split
7963 [(set (match_operand 0 "flags_reg_operand" "")
7964 (match_operator 1 "compare_operator"
7965 [(and (match_operand 2 "register_operand" "")
7966 (match_operand 3 "const_int_operand" ""))
7967 (const_int 0)]))]
7968 "reload_completed
7969 && QI_REG_P (operands[2])
7970 && GET_MODE (operands[2]) != QImode
7971 && ((ix86_match_ccmode (insn, CCZmode)
7972 && !(INTVAL (operands[3]) & ~(255 << 8)))
7973 || (ix86_match_ccmode (insn, CCNOmode)
7974 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7975 [(set (match_dup 0)
7976 (match_op_dup 1
7977 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7978 (match_dup 3))
7979 (const_int 0)]))]
7980 "operands[2] = gen_lowpart (SImode, operands[2]);
7981 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7982
7983 (define_split
7984 [(set (match_operand 0 "flags_reg_operand" "")
7985 (match_operator 1 "compare_operator"
7986 [(and (match_operand 2 "nonimmediate_operand" "")
7987 (match_operand 3 "const_int_operand" ""))
7988 (const_int 0)]))]
7989 "reload_completed
7990 && GET_MODE (operands[2]) != QImode
7991 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7992 && ((ix86_match_ccmode (insn, CCZmode)
7993 && !(INTVAL (operands[3]) & ~255))
7994 || (ix86_match_ccmode (insn, CCNOmode)
7995 && !(INTVAL (operands[3]) & ~127)))"
7996 [(set (match_dup 0)
7997 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7998 (const_int 0)]))]
7999 "operands[2] = gen_lowpart (QImode, operands[2]);
8000 operands[3] = gen_lowpart (QImode, operands[3]);")
8001
8002
8003 ;; %%% This used to optimize known byte-wide and operations to memory,
8004 ;; and sometimes to QImode registers. If this is considered useful,
8005 ;; it should be done with splitters.
8006
8007 (define_expand "anddi3"
8008 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8009 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8010 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8011 (clobber (reg:CC FLAGS_REG))]
8012 "TARGET_64BIT"
8013 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8014
8015 (define_insn "*anddi_1_rex64"
8016 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8017 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8018 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8019 (clobber (reg:CC FLAGS_REG))]
8020 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8021 {
8022 switch (get_attr_type (insn))
8023 {
8024 case TYPE_IMOVX:
8025 {
8026 enum machine_mode mode;
8027
8028 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8029 if (INTVAL (operands[2]) == 0xff)
8030 mode = QImode;
8031 else
8032 {
8033 gcc_assert (INTVAL (operands[2]) == 0xffff);
8034 mode = HImode;
8035 }
8036
8037 operands[1] = gen_lowpart (mode, operands[1]);
8038 if (mode == QImode)
8039 return "movz{bq|x}\t{%1,%0|%0, %1}";
8040 else
8041 return "movz{wq|x}\t{%1,%0|%0, %1}";
8042 }
8043
8044 default:
8045 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8046 if (get_attr_mode (insn) == MODE_SI)
8047 return "and{l}\t{%k2, %k0|%k0, %k2}";
8048 else
8049 return "and{q}\t{%2, %0|%0, %2}";
8050 }
8051 }
8052 [(set_attr "type" "alu,alu,alu,imovx")
8053 (set_attr "length_immediate" "*,*,*,0")
8054 (set_attr "mode" "SI,DI,DI,DI")])
8055
8056 (define_insn "*anddi_2"
8057 [(set (reg FLAGS_REG)
8058 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8059 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8060 (const_int 0)))
8061 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8062 (and:DI (match_dup 1) (match_dup 2)))]
8063 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8064 && ix86_binary_operator_ok (AND, DImode, operands)"
8065 "@
8066 and{l}\t{%k2, %k0|%k0, %k2}
8067 and{q}\t{%2, %0|%0, %2}
8068 and{q}\t{%2, %0|%0, %2}"
8069 [(set_attr "type" "alu")
8070 (set_attr "mode" "SI,DI,DI")])
8071
8072 (define_expand "andsi3"
8073 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8074 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8075 (match_operand:SI 2 "general_operand" "")))
8076 (clobber (reg:CC FLAGS_REG))]
8077 ""
8078 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8079
8080 (define_insn "*andsi_1"
8081 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8082 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8083 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8084 (clobber (reg:CC FLAGS_REG))]
8085 "ix86_binary_operator_ok (AND, SImode, operands)"
8086 {
8087 switch (get_attr_type (insn))
8088 {
8089 case TYPE_IMOVX:
8090 {
8091 enum machine_mode mode;
8092
8093 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8094 if (INTVAL (operands[2]) == 0xff)
8095 mode = QImode;
8096 else
8097 {
8098 gcc_assert (INTVAL (operands[2]) == 0xffff);
8099 mode = HImode;
8100 }
8101
8102 operands[1] = gen_lowpart (mode, operands[1]);
8103 if (mode == QImode)
8104 return "movz{bl|x}\t{%1,%0|%0, %1}";
8105 else
8106 return "movz{wl|x}\t{%1,%0|%0, %1}";
8107 }
8108
8109 default:
8110 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8111 return "and{l}\t{%2, %0|%0, %2}";
8112 }
8113 }
8114 [(set_attr "type" "alu,alu,imovx")
8115 (set_attr "length_immediate" "*,*,0")
8116 (set_attr "mode" "SI")])
8117
8118 (define_split
8119 [(set (match_operand 0 "register_operand" "")
8120 (and (match_dup 0)
8121 (const_int -65536)))
8122 (clobber (reg:CC FLAGS_REG))]
8123 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8124 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8125 "operands[1] = gen_lowpart (HImode, operands[0]);")
8126
8127 (define_split
8128 [(set (match_operand 0 "ext_register_operand" "")
8129 (and (match_dup 0)
8130 (const_int -256)))
8131 (clobber (reg:CC FLAGS_REG))]
8132 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8133 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8134 "operands[1] = gen_lowpart (QImode, operands[0]);")
8135
8136 (define_split
8137 [(set (match_operand 0 "ext_register_operand" "")
8138 (and (match_dup 0)
8139 (const_int -65281)))
8140 (clobber (reg:CC FLAGS_REG))]
8141 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8142 [(parallel [(set (zero_extract:SI (match_dup 0)
8143 (const_int 8)
8144 (const_int 8))
8145 (xor:SI
8146 (zero_extract:SI (match_dup 0)
8147 (const_int 8)
8148 (const_int 8))
8149 (zero_extract:SI (match_dup 0)
8150 (const_int 8)
8151 (const_int 8))))
8152 (clobber (reg:CC FLAGS_REG))])]
8153 "operands[0] = gen_lowpart (SImode, operands[0]);")
8154
8155 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8156 (define_insn "*andsi_1_zext"
8157 [(set (match_operand:DI 0 "register_operand" "=r")
8158 (zero_extend:DI
8159 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8160 (match_operand:SI 2 "general_operand" "rim"))))
8161 (clobber (reg:CC FLAGS_REG))]
8162 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8163 "and{l}\t{%2, %k0|%k0, %2}"
8164 [(set_attr "type" "alu")
8165 (set_attr "mode" "SI")])
8166
8167 (define_insn "*andsi_2"
8168 [(set (reg FLAGS_REG)
8169 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8170 (match_operand:SI 2 "general_operand" "rim,ri"))
8171 (const_int 0)))
8172 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8173 (and:SI (match_dup 1) (match_dup 2)))]
8174 "ix86_match_ccmode (insn, CCNOmode)
8175 && ix86_binary_operator_ok (AND, SImode, operands)"
8176 "and{l}\t{%2, %0|%0, %2}"
8177 [(set_attr "type" "alu")
8178 (set_attr "mode" "SI")])
8179
8180 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8181 (define_insn "*andsi_2_zext"
8182 [(set (reg FLAGS_REG)
8183 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8184 (match_operand:SI 2 "general_operand" "rim"))
8185 (const_int 0)))
8186 (set (match_operand:DI 0 "register_operand" "=r")
8187 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8188 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8189 && ix86_binary_operator_ok (AND, SImode, operands)"
8190 "and{l}\t{%2, %k0|%k0, %2}"
8191 [(set_attr "type" "alu")
8192 (set_attr "mode" "SI")])
8193
8194 (define_expand "andhi3"
8195 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8196 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8197 (match_operand:HI 2 "general_operand" "")))
8198 (clobber (reg:CC FLAGS_REG))]
8199 "TARGET_HIMODE_MATH"
8200 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8201
8202 (define_insn "*andhi_1"
8203 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8204 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8205 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8206 (clobber (reg:CC FLAGS_REG))]
8207 "ix86_binary_operator_ok (AND, HImode, operands)"
8208 {
8209 switch (get_attr_type (insn))
8210 {
8211 case TYPE_IMOVX:
8212 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8213 gcc_assert (INTVAL (operands[2]) == 0xff);
8214 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8215
8216 default:
8217 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8218
8219 return "and{w}\t{%2, %0|%0, %2}";
8220 }
8221 }
8222 [(set_attr "type" "alu,alu,imovx")
8223 (set_attr "length_immediate" "*,*,0")
8224 (set_attr "mode" "HI,HI,SI")])
8225
8226 (define_insn "*andhi_2"
8227 [(set (reg FLAGS_REG)
8228 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8229 (match_operand:HI 2 "general_operand" "rim,ri"))
8230 (const_int 0)))
8231 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8232 (and:HI (match_dup 1) (match_dup 2)))]
8233 "ix86_match_ccmode (insn, CCNOmode)
8234 && ix86_binary_operator_ok (AND, HImode, operands)"
8235 "and{w}\t{%2, %0|%0, %2}"
8236 [(set_attr "type" "alu")
8237 (set_attr "mode" "HI")])
8238
8239 (define_expand "andqi3"
8240 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8241 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8242 (match_operand:QI 2 "general_operand" "")))
8243 (clobber (reg:CC FLAGS_REG))]
8244 "TARGET_QIMODE_MATH"
8245 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8246
8247 ;; %%% Potential partial reg stall on alternative 2. What to do?
8248 (define_insn "*andqi_1"
8249 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8250 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8251 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8252 (clobber (reg:CC FLAGS_REG))]
8253 "ix86_binary_operator_ok (AND, QImode, operands)"
8254 "@
8255 and{b}\t{%2, %0|%0, %2}
8256 and{b}\t{%2, %0|%0, %2}
8257 and{l}\t{%k2, %k0|%k0, %k2}"
8258 [(set_attr "type" "alu")
8259 (set_attr "mode" "QI,QI,SI")])
8260
8261 (define_insn "*andqi_1_slp"
8262 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8263 (and:QI (match_dup 0)
8264 (match_operand:QI 1 "general_operand" "qi,qmi")))
8265 (clobber (reg:CC FLAGS_REG))]
8266 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8267 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8268 "and{b}\t{%1, %0|%0, %1}"
8269 [(set_attr "type" "alu1")
8270 (set_attr "mode" "QI")])
8271
8272 (define_insn "*andqi_2_maybe_si"
8273 [(set (reg FLAGS_REG)
8274 (compare (and:QI
8275 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8276 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8277 (const_int 0)))
8278 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8279 (and:QI (match_dup 1) (match_dup 2)))]
8280 "ix86_binary_operator_ok (AND, QImode, operands)
8281 && ix86_match_ccmode (insn,
8282 GET_CODE (operands[2]) == CONST_INT
8283 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8284 {
8285 if (which_alternative == 2)
8286 {
8287 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8288 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8289 return "and{l}\t{%2, %k0|%k0, %2}";
8290 }
8291 return "and{b}\t{%2, %0|%0, %2}";
8292 }
8293 [(set_attr "type" "alu")
8294 (set_attr "mode" "QI,QI,SI")])
8295
8296 (define_insn "*andqi_2"
8297 [(set (reg FLAGS_REG)
8298 (compare (and:QI
8299 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8300 (match_operand:QI 2 "general_operand" "qim,qi"))
8301 (const_int 0)))
8302 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8303 (and:QI (match_dup 1) (match_dup 2)))]
8304 "ix86_match_ccmode (insn, CCNOmode)
8305 && ix86_binary_operator_ok (AND, QImode, operands)"
8306 "and{b}\t{%2, %0|%0, %2}"
8307 [(set_attr "type" "alu")
8308 (set_attr "mode" "QI")])
8309
8310 (define_insn "*andqi_2_slp"
8311 [(set (reg FLAGS_REG)
8312 (compare (and:QI
8313 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8314 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8315 (const_int 0)))
8316 (set (strict_low_part (match_dup 0))
8317 (and:QI (match_dup 0) (match_dup 1)))]
8318 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8319 && ix86_match_ccmode (insn, CCNOmode)
8320 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8321 "and{b}\t{%1, %0|%0, %1}"
8322 [(set_attr "type" "alu1")
8323 (set_attr "mode" "QI")])
8324
8325 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8326 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8327 ;; for a QImode operand, which of course failed.
8328
8329 (define_insn "andqi_ext_0"
8330 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8331 (const_int 8)
8332 (const_int 8))
8333 (and:SI
8334 (zero_extract:SI
8335 (match_operand 1 "ext_register_operand" "0")
8336 (const_int 8)
8337 (const_int 8))
8338 (match_operand 2 "const_int_operand" "n")))
8339 (clobber (reg:CC FLAGS_REG))]
8340 ""
8341 "and{b}\t{%2, %h0|%h0, %2}"
8342 [(set_attr "type" "alu")
8343 (set_attr "length_immediate" "1")
8344 (set_attr "mode" "QI")])
8345
8346 ;; Generated by peephole translating test to and. This shows up
8347 ;; often in fp comparisons.
8348
8349 (define_insn "*andqi_ext_0_cc"
8350 [(set (reg FLAGS_REG)
8351 (compare
8352 (and:SI
8353 (zero_extract:SI
8354 (match_operand 1 "ext_register_operand" "0")
8355 (const_int 8)
8356 (const_int 8))
8357 (match_operand 2 "const_int_operand" "n"))
8358 (const_int 0)))
8359 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8360 (const_int 8)
8361 (const_int 8))
8362 (and:SI
8363 (zero_extract:SI
8364 (match_dup 1)
8365 (const_int 8)
8366 (const_int 8))
8367 (match_dup 2)))]
8368 "ix86_match_ccmode (insn, CCNOmode)"
8369 "and{b}\t{%2, %h0|%h0, %2}"
8370 [(set_attr "type" "alu")
8371 (set_attr "length_immediate" "1")
8372 (set_attr "mode" "QI")])
8373
8374 (define_insn "*andqi_ext_1"
8375 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8376 (const_int 8)
8377 (const_int 8))
8378 (and:SI
8379 (zero_extract:SI
8380 (match_operand 1 "ext_register_operand" "0")
8381 (const_int 8)
8382 (const_int 8))
8383 (zero_extend:SI
8384 (match_operand:QI 2 "general_operand" "Qm"))))
8385 (clobber (reg:CC FLAGS_REG))]
8386 "!TARGET_64BIT"
8387 "and{b}\t{%2, %h0|%h0, %2}"
8388 [(set_attr "type" "alu")
8389 (set_attr "length_immediate" "0")
8390 (set_attr "mode" "QI")])
8391
8392 (define_insn "*andqi_ext_1_rex64"
8393 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8394 (const_int 8)
8395 (const_int 8))
8396 (and:SI
8397 (zero_extract:SI
8398 (match_operand 1 "ext_register_operand" "0")
8399 (const_int 8)
8400 (const_int 8))
8401 (zero_extend:SI
8402 (match_operand 2 "ext_register_operand" "Q"))))
8403 (clobber (reg:CC FLAGS_REG))]
8404 "TARGET_64BIT"
8405 "and{b}\t{%2, %h0|%h0, %2}"
8406 [(set_attr "type" "alu")
8407 (set_attr "length_immediate" "0")
8408 (set_attr "mode" "QI")])
8409
8410 (define_insn "*andqi_ext_2"
8411 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8412 (const_int 8)
8413 (const_int 8))
8414 (and:SI
8415 (zero_extract:SI
8416 (match_operand 1 "ext_register_operand" "%0")
8417 (const_int 8)
8418 (const_int 8))
8419 (zero_extract:SI
8420 (match_operand 2 "ext_register_operand" "Q")
8421 (const_int 8)
8422 (const_int 8))))
8423 (clobber (reg:CC FLAGS_REG))]
8424 ""
8425 "and{b}\t{%h2, %h0|%h0, %h2}"
8426 [(set_attr "type" "alu")
8427 (set_attr "length_immediate" "0")
8428 (set_attr "mode" "QI")])
8429
8430 ;; Convert wide AND instructions with immediate operand to shorter QImode
8431 ;; equivalents when possible.
8432 ;; Don't do the splitting with memory operands, since it introduces risk
8433 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8434 ;; for size, but that can (should?) be handled by generic code instead.
8435 (define_split
8436 [(set (match_operand 0 "register_operand" "")
8437 (and (match_operand 1 "register_operand" "")
8438 (match_operand 2 "const_int_operand" "")))
8439 (clobber (reg:CC FLAGS_REG))]
8440 "reload_completed
8441 && QI_REG_P (operands[0])
8442 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8443 && !(~INTVAL (operands[2]) & ~(255 << 8))
8444 && GET_MODE (operands[0]) != QImode"
8445 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8446 (and:SI (zero_extract:SI (match_dup 1)
8447 (const_int 8) (const_int 8))
8448 (match_dup 2)))
8449 (clobber (reg:CC FLAGS_REG))])]
8450 "operands[0] = gen_lowpart (SImode, operands[0]);
8451 operands[1] = gen_lowpart (SImode, operands[1]);
8452 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8453
8454 ;; Since AND can be encoded with sign extended immediate, this is only
8455 ;; profitable when 7th bit is not set.
8456 (define_split
8457 [(set (match_operand 0 "register_operand" "")
8458 (and (match_operand 1 "general_operand" "")
8459 (match_operand 2 "const_int_operand" "")))
8460 (clobber (reg:CC FLAGS_REG))]
8461 "reload_completed
8462 && ANY_QI_REG_P (operands[0])
8463 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8464 && !(~INTVAL (operands[2]) & ~255)
8465 && !(INTVAL (operands[2]) & 128)
8466 && GET_MODE (operands[0]) != QImode"
8467 [(parallel [(set (strict_low_part (match_dup 0))
8468 (and:QI (match_dup 1)
8469 (match_dup 2)))
8470 (clobber (reg:CC FLAGS_REG))])]
8471 "operands[0] = gen_lowpart (QImode, operands[0]);
8472 operands[1] = gen_lowpart (QImode, operands[1]);
8473 operands[2] = gen_lowpart (QImode, operands[2]);")
8474 \f
8475 ;; Logical inclusive OR instructions
8476
8477 ;; %%% This used to optimize known byte-wide and operations to memory.
8478 ;; If this is considered useful, it should be done with splitters.
8479
8480 (define_expand "iordi3"
8481 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8482 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8483 (match_operand:DI 2 "x86_64_general_operand" "")))
8484 (clobber (reg:CC FLAGS_REG))]
8485 "TARGET_64BIT"
8486 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8487
8488 (define_insn "*iordi_1_rex64"
8489 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8490 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8491 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8492 (clobber (reg:CC FLAGS_REG))]
8493 "TARGET_64BIT
8494 && ix86_binary_operator_ok (IOR, DImode, operands)"
8495 "or{q}\t{%2, %0|%0, %2}"
8496 [(set_attr "type" "alu")
8497 (set_attr "mode" "DI")])
8498
8499 (define_insn "*iordi_2_rex64"
8500 [(set (reg FLAGS_REG)
8501 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8502 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8503 (const_int 0)))
8504 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8505 (ior:DI (match_dup 1) (match_dup 2)))]
8506 "TARGET_64BIT
8507 && ix86_match_ccmode (insn, CCNOmode)
8508 && ix86_binary_operator_ok (IOR, DImode, operands)"
8509 "or{q}\t{%2, %0|%0, %2}"
8510 [(set_attr "type" "alu")
8511 (set_attr "mode" "DI")])
8512
8513 (define_insn "*iordi_3_rex64"
8514 [(set (reg FLAGS_REG)
8515 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8516 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8517 (const_int 0)))
8518 (clobber (match_scratch:DI 0 "=r"))]
8519 "TARGET_64BIT
8520 && ix86_match_ccmode (insn, CCNOmode)
8521 && ix86_binary_operator_ok (IOR, DImode, operands)"
8522 "or{q}\t{%2, %0|%0, %2}"
8523 [(set_attr "type" "alu")
8524 (set_attr "mode" "DI")])
8525
8526
8527 (define_expand "iorsi3"
8528 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8529 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8530 (match_operand:SI 2 "general_operand" "")))
8531 (clobber (reg:CC FLAGS_REG))]
8532 ""
8533 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8534
8535 (define_insn "*iorsi_1"
8536 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8537 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8538 (match_operand:SI 2 "general_operand" "ri,rmi")))
8539 (clobber (reg:CC FLAGS_REG))]
8540 "ix86_binary_operator_ok (IOR, SImode, operands)"
8541 "or{l}\t{%2, %0|%0, %2}"
8542 [(set_attr "type" "alu")
8543 (set_attr "mode" "SI")])
8544
8545 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8546 (define_insn "*iorsi_1_zext"
8547 [(set (match_operand:DI 0 "register_operand" "=rm")
8548 (zero_extend:DI
8549 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8550 (match_operand:SI 2 "general_operand" "rim"))))
8551 (clobber (reg:CC FLAGS_REG))]
8552 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8553 "or{l}\t{%2, %k0|%k0, %2}"
8554 [(set_attr "type" "alu")
8555 (set_attr "mode" "SI")])
8556
8557 (define_insn "*iorsi_1_zext_imm"
8558 [(set (match_operand:DI 0 "register_operand" "=rm")
8559 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8560 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8561 (clobber (reg:CC FLAGS_REG))]
8562 "TARGET_64BIT"
8563 "or{l}\t{%2, %k0|%k0, %2}"
8564 [(set_attr "type" "alu")
8565 (set_attr "mode" "SI")])
8566
8567 (define_insn "*iorsi_2"
8568 [(set (reg FLAGS_REG)
8569 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8570 (match_operand:SI 2 "general_operand" "rim,ri"))
8571 (const_int 0)))
8572 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8573 (ior:SI (match_dup 1) (match_dup 2)))]
8574 "ix86_match_ccmode (insn, CCNOmode)
8575 && ix86_binary_operator_ok (IOR, SImode, operands)"
8576 "or{l}\t{%2, %0|%0, %2}"
8577 [(set_attr "type" "alu")
8578 (set_attr "mode" "SI")])
8579
8580 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8581 ;; ??? Special case for immediate operand is missing - it is tricky.
8582 (define_insn "*iorsi_2_zext"
8583 [(set (reg FLAGS_REG)
8584 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8585 (match_operand:SI 2 "general_operand" "rim"))
8586 (const_int 0)))
8587 (set (match_operand:DI 0 "register_operand" "=r")
8588 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8589 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8590 && ix86_binary_operator_ok (IOR, SImode, operands)"
8591 "or{l}\t{%2, %k0|%k0, %2}"
8592 [(set_attr "type" "alu")
8593 (set_attr "mode" "SI")])
8594
8595 (define_insn "*iorsi_2_zext_imm"
8596 [(set (reg FLAGS_REG)
8597 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8598 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8599 (const_int 0)))
8600 (set (match_operand:DI 0 "register_operand" "=r")
8601 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8602 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8603 && ix86_binary_operator_ok (IOR, SImode, operands)"
8604 "or{l}\t{%2, %k0|%k0, %2}"
8605 [(set_attr "type" "alu")
8606 (set_attr "mode" "SI")])
8607
8608 (define_insn "*iorsi_3"
8609 [(set (reg FLAGS_REG)
8610 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8611 (match_operand:SI 2 "general_operand" "rim"))
8612 (const_int 0)))
8613 (clobber (match_scratch:SI 0 "=r"))]
8614 "ix86_match_ccmode (insn, CCNOmode)
8615 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8616 "or{l}\t{%2, %0|%0, %2}"
8617 [(set_attr "type" "alu")
8618 (set_attr "mode" "SI")])
8619
8620 (define_expand "iorhi3"
8621 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8622 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8623 (match_operand:HI 2 "general_operand" "")))
8624 (clobber (reg:CC FLAGS_REG))]
8625 "TARGET_HIMODE_MATH"
8626 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8627
8628 (define_insn "*iorhi_1"
8629 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8630 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8631 (match_operand:HI 2 "general_operand" "rmi,ri")))
8632 (clobber (reg:CC FLAGS_REG))]
8633 "ix86_binary_operator_ok (IOR, HImode, operands)"
8634 "or{w}\t{%2, %0|%0, %2}"
8635 [(set_attr "type" "alu")
8636 (set_attr "mode" "HI")])
8637
8638 (define_insn "*iorhi_2"
8639 [(set (reg FLAGS_REG)
8640 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8641 (match_operand:HI 2 "general_operand" "rim,ri"))
8642 (const_int 0)))
8643 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8644 (ior:HI (match_dup 1) (match_dup 2)))]
8645 "ix86_match_ccmode (insn, CCNOmode)
8646 && ix86_binary_operator_ok (IOR, HImode, operands)"
8647 "or{w}\t{%2, %0|%0, %2}"
8648 [(set_attr "type" "alu")
8649 (set_attr "mode" "HI")])
8650
8651 (define_insn "*iorhi_3"
8652 [(set (reg FLAGS_REG)
8653 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8654 (match_operand:HI 2 "general_operand" "rim"))
8655 (const_int 0)))
8656 (clobber (match_scratch:HI 0 "=r"))]
8657 "ix86_match_ccmode (insn, CCNOmode)
8658 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8659 "or{w}\t{%2, %0|%0, %2}"
8660 [(set_attr "type" "alu")
8661 (set_attr "mode" "HI")])
8662
8663 (define_expand "iorqi3"
8664 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8665 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8666 (match_operand:QI 2 "general_operand" "")))
8667 (clobber (reg:CC FLAGS_REG))]
8668 "TARGET_QIMODE_MATH"
8669 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8670
8671 ;; %%% Potential partial reg stall on alternative 2. What to do?
8672 (define_insn "*iorqi_1"
8673 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8674 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8675 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8676 (clobber (reg:CC FLAGS_REG))]
8677 "ix86_binary_operator_ok (IOR, QImode, operands)"
8678 "@
8679 or{b}\t{%2, %0|%0, %2}
8680 or{b}\t{%2, %0|%0, %2}
8681 or{l}\t{%k2, %k0|%k0, %k2}"
8682 [(set_attr "type" "alu")
8683 (set_attr "mode" "QI,QI,SI")])
8684
8685 (define_insn "*iorqi_1_slp"
8686 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8687 (ior:QI (match_dup 0)
8688 (match_operand:QI 1 "general_operand" "qmi,qi")))
8689 (clobber (reg:CC FLAGS_REG))]
8690 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8691 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8692 "or{b}\t{%1, %0|%0, %1}"
8693 [(set_attr "type" "alu1")
8694 (set_attr "mode" "QI")])
8695
8696 (define_insn "*iorqi_2"
8697 [(set (reg FLAGS_REG)
8698 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8699 (match_operand:QI 2 "general_operand" "qim,qi"))
8700 (const_int 0)))
8701 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8702 (ior:QI (match_dup 1) (match_dup 2)))]
8703 "ix86_match_ccmode (insn, CCNOmode)
8704 && ix86_binary_operator_ok (IOR, QImode, operands)"
8705 "or{b}\t{%2, %0|%0, %2}"
8706 [(set_attr "type" "alu")
8707 (set_attr "mode" "QI")])
8708
8709 (define_insn "*iorqi_2_slp"
8710 [(set (reg FLAGS_REG)
8711 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8712 (match_operand:QI 1 "general_operand" "qim,qi"))
8713 (const_int 0)))
8714 (set (strict_low_part (match_dup 0))
8715 (ior:QI (match_dup 0) (match_dup 1)))]
8716 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8717 && ix86_match_ccmode (insn, CCNOmode)
8718 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8719 "or{b}\t{%1, %0|%0, %1}"
8720 [(set_attr "type" "alu1")
8721 (set_attr "mode" "QI")])
8722
8723 (define_insn "*iorqi_3"
8724 [(set (reg FLAGS_REG)
8725 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8726 (match_operand:QI 2 "general_operand" "qim"))
8727 (const_int 0)))
8728 (clobber (match_scratch:QI 0 "=q"))]
8729 "ix86_match_ccmode (insn, CCNOmode)
8730 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8731 "or{b}\t{%2, %0|%0, %2}"
8732 [(set_attr "type" "alu")
8733 (set_attr "mode" "QI")])
8734
8735 (define_insn "iorqi_ext_0"
8736 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8737 (const_int 8)
8738 (const_int 8))
8739 (ior:SI
8740 (zero_extract:SI
8741 (match_operand 1 "ext_register_operand" "0")
8742 (const_int 8)
8743 (const_int 8))
8744 (match_operand 2 "const_int_operand" "n")))
8745 (clobber (reg:CC FLAGS_REG))]
8746 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8747 "or{b}\t{%2, %h0|%h0, %2}"
8748 [(set_attr "type" "alu")
8749 (set_attr "length_immediate" "1")
8750 (set_attr "mode" "QI")])
8751
8752 (define_insn "*iorqi_ext_1"
8753 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8754 (const_int 8)
8755 (const_int 8))
8756 (ior:SI
8757 (zero_extract:SI
8758 (match_operand 1 "ext_register_operand" "0")
8759 (const_int 8)
8760 (const_int 8))
8761 (zero_extend:SI
8762 (match_operand:QI 2 "general_operand" "Qm"))))
8763 (clobber (reg:CC FLAGS_REG))]
8764 "!TARGET_64BIT
8765 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8766 "or{b}\t{%2, %h0|%h0, %2}"
8767 [(set_attr "type" "alu")
8768 (set_attr "length_immediate" "0")
8769 (set_attr "mode" "QI")])
8770
8771 (define_insn "*iorqi_ext_1_rex64"
8772 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8773 (const_int 8)
8774 (const_int 8))
8775 (ior:SI
8776 (zero_extract:SI
8777 (match_operand 1 "ext_register_operand" "0")
8778 (const_int 8)
8779 (const_int 8))
8780 (zero_extend:SI
8781 (match_operand 2 "ext_register_operand" "Q"))))
8782 (clobber (reg:CC FLAGS_REG))]
8783 "TARGET_64BIT
8784 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8785 "or{b}\t{%2, %h0|%h0, %2}"
8786 [(set_attr "type" "alu")
8787 (set_attr "length_immediate" "0")
8788 (set_attr "mode" "QI")])
8789
8790 (define_insn "*iorqi_ext_2"
8791 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8792 (const_int 8)
8793 (const_int 8))
8794 (ior:SI
8795 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8796 (const_int 8)
8797 (const_int 8))
8798 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8799 (const_int 8)
8800 (const_int 8))))
8801 (clobber (reg:CC FLAGS_REG))]
8802 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8803 "ior{b}\t{%h2, %h0|%h0, %h2}"
8804 [(set_attr "type" "alu")
8805 (set_attr "length_immediate" "0")
8806 (set_attr "mode" "QI")])
8807
8808 (define_split
8809 [(set (match_operand 0 "register_operand" "")
8810 (ior (match_operand 1 "register_operand" "")
8811 (match_operand 2 "const_int_operand" "")))
8812 (clobber (reg:CC FLAGS_REG))]
8813 "reload_completed
8814 && QI_REG_P (operands[0])
8815 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8816 && !(INTVAL (operands[2]) & ~(255 << 8))
8817 && GET_MODE (operands[0]) != QImode"
8818 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8819 (ior:SI (zero_extract:SI (match_dup 1)
8820 (const_int 8) (const_int 8))
8821 (match_dup 2)))
8822 (clobber (reg:CC FLAGS_REG))])]
8823 "operands[0] = gen_lowpart (SImode, operands[0]);
8824 operands[1] = gen_lowpart (SImode, operands[1]);
8825 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8826
8827 ;; Since OR can be encoded with sign extended immediate, this is only
8828 ;; profitable when 7th bit is set.
8829 (define_split
8830 [(set (match_operand 0 "register_operand" "")
8831 (ior (match_operand 1 "general_operand" "")
8832 (match_operand 2 "const_int_operand" "")))
8833 (clobber (reg:CC FLAGS_REG))]
8834 "reload_completed
8835 && ANY_QI_REG_P (operands[0])
8836 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8837 && !(INTVAL (operands[2]) & ~255)
8838 && (INTVAL (operands[2]) & 128)
8839 && GET_MODE (operands[0]) != QImode"
8840 [(parallel [(set (strict_low_part (match_dup 0))
8841 (ior:QI (match_dup 1)
8842 (match_dup 2)))
8843 (clobber (reg:CC FLAGS_REG))])]
8844 "operands[0] = gen_lowpart (QImode, operands[0]);
8845 operands[1] = gen_lowpart (QImode, operands[1]);
8846 operands[2] = gen_lowpart (QImode, operands[2]);")
8847 \f
8848 ;; Logical XOR instructions
8849
8850 ;; %%% This used to optimize known byte-wide and operations to memory.
8851 ;; If this is considered useful, it should be done with splitters.
8852
8853 (define_expand "xordi3"
8854 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8855 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8856 (match_operand:DI 2 "x86_64_general_operand" "")))
8857 (clobber (reg:CC FLAGS_REG))]
8858 "TARGET_64BIT"
8859 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8860
8861 (define_insn "*xordi_1_rex64"
8862 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8863 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8864 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8865 (clobber (reg:CC FLAGS_REG))]
8866 "TARGET_64BIT
8867 && ix86_binary_operator_ok (XOR, DImode, operands)"
8868 "@
8869 xor{q}\t{%2, %0|%0, %2}
8870 xor{q}\t{%2, %0|%0, %2}"
8871 [(set_attr "type" "alu")
8872 (set_attr "mode" "DI,DI")])
8873
8874 (define_insn "*xordi_2_rex64"
8875 [(set (reg FLAGS_REG)
8876 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8877 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8878 (const_int 0)))
8879 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8880 (xor:DI (match_dup 1) (match_dup 2)))]
8881 "TARGET_64BIT
8882 && ix86_match_ccmode (insn, CCNOmode)
8883 && ix86_binary_operator_ok (XOR, DImode, operands)"
8884 "@
8885 xor{q}\t{%2, %0|%0, %2}
8886 xor{q}\t{%2, %0|%0, %2}"
8887 [(set_attr "type" "alu")
8888 (set_attr "mode" "DI,DI")])
8889
8890 (define_insn "*xordi_3_rex64"
8891 [(set (reg FLAGS_REG)
8892 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8893 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8894 (const_int 0)))
8895 (clobber (match_scratch:DI 0 "=r"))]
8896 "TARGET_64BIT
8897 && ix86_match_ccmode (insn, CCNOmode)
8898 && ix86_binary_operator_ok (XOR, DImode, operands)"
8899 "xor{q}\t{%2, %0|%0, %2}"
8900 [(set_attr "type" "alu")
8901 (set_attr "mode" "DI")])
8902
8903 (define_expand "xorsi3"
8904 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8905 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8906 (match_operand:SI 2 "general_operand" "")))
8907 (clobber (reg:CC FLAGS_REG))]
8908 ""
8909 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8910
8911 (define_insn "*xorsi_1"
8912 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8913 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8914 (match_operand:SI 2 "general_operand" "ri,rm")))
8915 (clobber (reg:CC FLAGS_REG))]
8916 "ix86_binary_operator_ok (XOR, SImode, operands)"
8917 "xor{l}\t{%2, %0|%0, %2}"
8918 [(set_attr "type" "alu")
8919 (set_attr "mode" "SI")])
8920
8921 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8922 ;; Add speccase for immediates
8923 (define_insn "*xorsi_1_zext"
8924 [(set (match_operand:DI 0 "register_operand" "=r")
8925 (zero_extend:DI
8926 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8927 (match_operand:SI 2 "general_operand" "rim"))))
8928 (clobber (reg:CC FLAGS_REG))]
8929 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8930 "xor{l}\t{%2, %k0|%k0, %2}"
8931 [(set_attr "type" "alu")
8932 (set_attr "mode" "SI")])
8933
8934 (define_insn "*xorsi_1_zext_imm"
8935 [(set (match_operand:DI 0 "register_operand" "=r")
8936 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8937 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8938 (clobber (reg:CC FLAGS_REG))]
8939 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8940 "xor{l}\t{%2, %k0|%k0, %2}"
8941 [(set_attr "type" "alu")
8942 (set_attr "mode" "SI")])
8943
8944 (define_insn "*xorsi_2"
8945 [(set (reg FLAGS_REG)
8946 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8947 (match_operand:SI 2 "general_operand" "rim,ri"))
8948 (const_int 0)))
8949 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8950 (xor:SI (match_dup 1) (match_dup 2)))]
8951 "ix86_match_ccmode (insn, CCNOmode)
8952 && ix86_binary_operator_ok (XOR, SImode, operands)"
8953 "xor{l}\t{%2, %0|%0, %2}"
8954 [(set_attr "type" "alu")
8955 (set_attr "mode" "SI")])
8956
8957 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8958 ;; ??? Special case for immediate operand is missing - it is tricky.
8959 (define_insn "*xorsi_2_zext"
8960 [(set (reg FLAGS_REG)
8961 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8962 (match_operand:SI 2 "general_operand" "rim"))
8963 (const_int 0)))
8964 (set (match_operand:DI 0 "register_operand" "=r")
8965 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8966 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8967 && ix86_binary_operator_ok (XOR, SImode, operands)"
8968 "xor{l}\t{%2, %k0|%k0, %2}"
8969 [(set_attr "type" "alu")
8970 (set_attr "mode" "SI")])
8971
8972 (define_insn "*xorsi_2_zext_imm"
8973 [(set (reg FLAGS_REG)
8974 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8975 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8976 (const_int 0)))
8977 (set (match_operand:DI 0 "register_operand" "=r")
8978 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8979 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8980 && ix86_binary_operator_ok (XOR, SImode, operands)"
8981 "xor{l}\t{%2, %k0|%k0, %2}"
8982 [(set_attr "type" "alu")
8983 (set_attr "mode" "SI")])
8984
8985 (define_insn "*xorsi_3"
8986 [(set (reg FLAGS_REG)
8987 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8988 (match_operand:SI 2 "general_operand" "rim"))
8989 (const_int 0)))
8990 (clobber (match_scratch:SI 0 "=r"))]
8991 "ix86_match_ccmode (insn, CCNOmode)
8992 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8993 "xor{l}\t{%2, %0|%0, %2}"
8994 [(set_attr "type" "alu")
8995 (set_attr "mode" "SI")])
8996
8997 (define_expand "xorhi3"
8998 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8999 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9000 (match_operand:HI 2 "general_operand" "")))
9001 (clobber (reg:CC FLAGS_REG))]
9002 "TARGET_HIMODE_MATH"
9003 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9004
9005 (define_insn "*xorhi_1"
9006 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9007 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9008 (match_operand:HI 2 "general_operand" "rmi,ri")))
9009 (clobber (reg:CC FLAGS_REG))]
9010 "ix86_binary_operator_ok (XOR, HImode, operands)"
9011 "xor{w}\t{%2, %0|%0, %2}"
9012 [(set_attr "type" "alu")
9013 (set_attr "mode" "HI")])
9014
9015 (define_insn "*xorhi_2"
9016 [(set (reg FLAGS_REG)
9017 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9018 (match_operand:HI 2 "general_operand" "rim,ri"))
9019 (const_int 0)))
9020 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9021 (xor:HI (match_dup 1) (match_dup 2)))]
9022 "ix86_match_ccmode (insn, CCNOmode)
9023 && ix86_binary_operator_ok (XOR, HImode, operands)"
9024 "xor{w}\t{%2, %0|%0, %2}"
9025 [(set_attr "type" "alu")
9026 (set_attr "mode" "HI")])
9027
9028 (define_insn "*xorhi_3"
9029 [(set (reg FLAGS_REG)
9030 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9031 (match_operand:HI 2 "general_operand" "rim"))
9032 (const_int 0)))
9033 (clobber (match_scratch:HI 0 "=r"))]
9034 "ix86_match_ccmode (insn, CCNOmode)
9035 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9036 "xor{w}\t{%2, %0|%0, %2}"
9037 [(set_attr "type" "alu")
9038 (set_attr "mode" "HI")])
9039
9040 (define_expand "xorqi3"
9041 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9042 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9043 (match_operand:QI 2 "general_operand" "")))
9044 (clobber (reg:CC FLAGS_REG))]
9045 "TARGET_QIMODE_MATH"
9046 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9047
9048 ;; %%% Potential partial reg stall on alternative 2. What to do?
9049 (define_insn "*xorqi_1"
9050 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9051 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9052 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9053 (clobber (reg:CC FLAGS_REG))]
9054 "ix86_binary_operator_ok (XOR, QImode, operands)"
9055 "@
9056 xor{b}\t{%2, %0|%0, %2}
9057 xor{b}\t{%2, %0|%0, %2}
9058 xor{l}\t{%k2, %k0|%k0, %k2}"
9059 [(set_attr "type" "alu")
9060 (set_attr "mode" "QI,QI,SI")])
9061
9062 (define_insn "*xorqi_1_slp"
9063 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9064 (xor:QI (match_dup 0)
9065 (match_operand:QI 1 "general_operand" "qi,qmi")))
9066 (clobber (reg:CC FLAGS_REG))]
9067 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9068 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9069 "xor{b}\t{%1, %0|%0, %1}"
9070 [(set_attr "type" "alu1")
9071 (set_attr "mode" "QI")])
9072
9073 (define_insn "xorqi_ext_0"
9074 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9075 (const_int 8)
9076 (const_int 8))
9077 (xor:SI
9078 (zero_extract:SI
9079 (match_operand 1 "ext_register_operand" "0")
9080 (const_int 8)
9081 (const_int 8))
9082 (match_operand 2 "const_int_operand" "n")))
9083 (clobber (reg:CC FLAGS_REG))]
9084 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9085 "xor{b}\t{%2, %h0|%h0, %2}"
9086 [(set_attr "type" "alu")
9087 (set_attr "length_immediate" "1")
9088 (set_attr "mode" "QI")])
9089
9090 (define_insn "*xorqi_ext_1"
9091 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9092 (const_int 8)
9093 (const_int 8))
9094 (xor:SI
9095 (zero_extract:SI
9096 (match_operand 1 "ext_register_operand" "0")
9097 (const_int 8)
9098 (const_int 8))
9099 (zero_extend:SI
9100 (match_operand:QI 2 "general_operand" "Qm"))))
9101 (clobber (reg:CC FLAGS_REG))]
9102 "!TARGET_64BIT
9103 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9104 "xor{b}\t{%2, %h0|%h0, %2}"
9105 [(set_attr "type" "alu")
9106 (set_attr "length_immediate" "0")
9107 (set_attr "mode" "QI")])
9108
9109 (define_insn "*xorqi_ext_1_rex64"
9110 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9111 (const_int 8)
9112 (const_int 8))
9113 (xor:SI
9114 (zero_extract:SI
9115 (match_operand 1 "ext_register_operand" "0")
9116 (const_int 8)
9117 (const_int 8))
9118 (zero_extend:SI
9119 (match_operand 2 "ext_register_operand" "Q"))))
9120 (clobber (reg:CC FLAGS_REG))]
9121 "TARGET_64BIT
9122 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9123 "xor{b}\t{%2, %h0|%h0, %2}"
9124 [(set_attr "type" "alu")
9125 (set_attr "length_immediate" "0")
9126 (set_attr "mode" "QI")])
9127
9128 (define_insn "*xorqi_ext_2"
9129 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9130 (const_int 8)
9131 (const_int 8))
9132 (xor:SI
9133 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9134 (const_int 8)
9135 (const_int 8))
9136 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9137 (const_int 8)
9138 (const_int 8))))
9139 (clobber (reg:CC FLAGS_REG))]
9140 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9141 "xor{b}\t{%h2, %h0|%h0, %h2}"
9142 [(set_attr "type" "alu")
9143 (set_attr "length_immediate" "0")
9144 (set_attr "mode" "QI")])
9145
9146 (define_insn "*xorqi_cc_1"
9147 [(set (reg FLAGS_REG)
9148 (compare
9149 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9150 (match_operand:QI 2 "general_operand" "qim,qi"))
9151 (const_int 0)))
9152 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9153 (xor:QI (match_dup 1) (match_dup 2)))]
9154 "ix86_match_ccmode (insn, CCNOmode)
9155 && ix86_binary_operator_ok (XOR, QImode, operands)"
9156 "xor{b}\t{%2, %0|%0, %2}"
9157 [(set_attr "type" "alu")
9158 (set_attr "mode" "QI")])
9159
9160 (define_insn "*xorqi_2_slp"
9161 [(set (reg FLAGS_REG)
9162 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9163 (match_operand:QI 1 "general_operand" "qim,qi"))
9164 (const_int 0)))
9165 (set (strict_low_part (match_dup 0))
9166 (xor:QI (match_dup 0) (match_dup 1)))]
9167 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9168 && ix86_match_ccmode (insn, CCNOmode)
9169 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9170 "xor{b}\t{%1, %0|%0, %1}"
9171 [(set_attr "type" "alu1")
9172 (set_attr "mode" "QI")])
9173
9174 (define_insn "*xorqi_cc_2"
9175 [(set (reg FLAGS_REG)
9176 (compare
9177 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9178 (match_operand:QI 2 "general_operand" "qim"))
9179 (const_int 0)))
9180 (clobber (match_scratch:QI 0 "=q"))]
9181 "ix86_match_ccmode (insn, CCNOmode)
9182 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9183 "xor{b}\t{%2, %0|%0, %2}"
9184 [(set_attr "type" "alu")
9185 (set_attr "mode" "QI")])
9186
9187 (define_insn "*xorqi_cc_ext_1"
9188 [(set (reg FLAGS_REG)
9189 (compare
9190 (xor:SI
9191 (zero_extract:SI
9192 (match_operand 1 "ext_register_operand" "0")
9193 (const_int 8)
9194 (const_int 8))
9195 (match_operand:QI 2 "general_operand" "qmn"))
9196 (const_int 0)))
9197 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9198 (const_int 8)
9199 (const_int 8))
9200 (xor:SI
9201 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9202 (match_dup 2)))]
9203 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9204 "xor{b}\t{%2, %h0|%h0, %2}"
9205 [(set_attr "type" "alu")
9206 (set_attr "mode" "QI")])
9207
9208 (define_insn "*xorqi_cc_ext_1_rex64"
9209 [(set (reg FLAGS_REG)
9210 (compare
9211 (xor:SI
9212 (zero_extract:SI
9213 (match_operand 1 "ext_register_operand" "0")
9214 (const_int 8)
9215 (const_int 8))
9216 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9217 (const_int 0)))
9218 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9219 (const_int 8)
9220 (const_int 8))
9221 (xor:SI
9222 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9223 (match_dup 2)))]
9224 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9225 "xor{b}\t{%2, %h0|%h0, %2}"
9226 [(set_attr "type" "alu")
9227 (set_attr "mode" "QI")])
9228
9229 (define_expand "xorqi_cc_ext_1"
9230 [(parallel [
9231 (set (reg:CCNO FLAGS_REG)
9232 (compare:CCNO
9233 (xor:SI
9234 (zero_extract:SI
9235 (match_operand 1 "ext_register_operand" "")
9236 (const_int 8)
9237 (const_int 8))
9238 (match_operand:QI 2 "general_operand" ""))
9239 (const_int 0)))
9240 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9241 (const_int 8)
9242 (const_int 8))
9243 (xor:SI
9244 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9245 (match_dup 2)))])]
9246 ""
9247 "")
9248
9249 (define_split
9250 [(set (match_operand 0 "register_operand" "")
9251 (xor (match_operand 1 "register_operand" "")
9252 (match_operand 2 "const_int_operand" "")))
9253 (clobber (reg:CC FLAGS_REG))]
9254 "reload_completed
9255 && QI_REG_P (operands[0])
9256 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9257 && !(INTVAL (operands[2]) & ~(255 << 8))
9258 && GET_MODE (operands[0]) != QImode"
9259 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9260 (xor:SI (zero_extract:SI (match_dup 1)
9261 (const_int 8) (const_int 8))
9262 (match_dup 2)))
9263 (clobber (reg:CC FLAGS_REG))])]
9264 "operands[0] = gen_lowpart (SImode, operands[0]);
9265 operands[1] = gen_lowpart (SImode, operands[1]);
9266 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9267
9268 ;; Since XOR can be encoded with sign extended immediate, this is only
9269 ;; profitable when 7th bit is set.
9270 (define_split
9271 [(set (match_operand 0 "register_operand" "")
9272 (xor (match_operand 1 "general_operand" "")
9273 (match_operand 2 "const_int_operand" "")))
9274 (clobber (reg:CC FLAGS_REG))]
9275 "reload_completed
9276 && ANY_QI_REG_P (operands[0])
9277 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9278 && !(INTVAL (operands[2]) & ~255)
9279 && (INTVAL (operands[2]) & 128)
9280 && GET_MODE (operands[0]) != QImode"
9281 [(parallel [(set (strict_low_part (match_dup 0))
9282 (xor:QI (match_dup 1)
9283 (match_dup 2)))
9284 (clobber (reg:CC FLAGS_REG))])]
9285 "operands[0] = gen_lowpart (QImode, operands[0]);
9286 operands[1] = gen_lowpart (QImode, operands[1]);
9287 operands[2] = gen_lowpart (QImode, operands[2]);")
9288 \f
9289 ;; Negation instructions
9290
9291 (define_expand "negti2"
9292 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9293 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9294 (clobber (reg:CC FLAGS_REG))])]
9295 "TARGET_64BIT"
9296 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9297
9298 (define_insn "*negti2_1"
9299 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9300 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9301 (clobber (reg:CC FLAGS_REG))]
9302 "TARGET_64BIT
9303 && ix86_unary_operator_ok (NEG, TImode, operands)"
9304 "#")
9305
9306 (define_split
9307 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9308 (neg:TI (match_operand:TI 1 "general_operand" "")))
9309 (clobber (reg:CC FLAGS_REG))]
9310 "TARGET_64BIT && reload_completed"
9311 [(parallel
9312 [(set (reg:CCZ FLAGS_REG)
9313 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9314 (set (match_dup 0) (neg:DI (match_dup 2)))])
9315 (parallel
9316 [(set (match_dup 1)
9317 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9318 (match_dup 3))
9319 (const_int 0)))
9320 (clobber (reg:CC FLAGS_REG))])
9321 (parallel
9322 [(set (match_dup 1)
9323 (neg:DI (match_dup 1)))
9324 (clobber (reg:CC FLAGS_REG))])]
9325 "split_ti (operands+1, 1, operands+2, operands+3);
9326 split_ti (operands+0, 1, operands+0, operands+1);")
9327
9328 (define_expand "negdi2"
9329 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9330 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9331 (clobber (reg:CC FLAGS_REG))])]
9332 ""
9333 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9334
9335 (define_insn "*negdi2_1"
9336 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9337 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9338 (clobber (reg:CC FLAGS_REG))]
9339 "!TARGET_64BIT
9340 && ix86_unary_operator_ok (NEG, DImode, operands)"
9341 "#")
9342
9343 (define_split
9344 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9345 (neg:DI (match_operand:DI 1 "general_operand" "")))
9346 (clobber (reg:CC FLAGS_REG))]
9347 "!TARGET_64BIT && reload_completed"
9348 [(parallel
9349 [(set (reg:CCZ FLAGS_REG)
9350 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9351 (set (match_dup 0) (neg:SI (match_dup 2)))])
9352 (parallel
9353 [(set (match_dup 1)
9354 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9355 (match_dup 3))
9356 (const_int 0)))
9357 (clobber (reg:CC FLAGS_REG))])
9358 (parallel
9359 [(set (match_dup 1)
9360 (neg:SI (match_dup 1)))
9361 (clobber (reg:CC FLAGS_REG))])]
9362 "split_di (operands+1, 1, operands+2, operands+3);
9363 split_di (operands+0, 1, operands+0, operands+1);")
9364
9365 (define_insn "*negdi2_1_rex64"
9366 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9367 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9368 (clobber (reg:CC FLAGS_REG))]
9369 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9370 "neg{q}\t%0"
9371 [(set_attr "type" "negnot")
9372 (set_attr "mode" "DI")])
9373
9374 ;; The problem with neg is that it does not perform (compare x 0),
9375 ;; it really performs (compare 0 x), which leaves us with the zero
9376 ;; flag being the only useful item.
9377
9378 (define_insn "*negdi2_cmpz_rex64"
9379 [(set (reg:CCZ FLAGS_REG)
9380 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9381 (const_int 0)))
9382 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9383 (neg:DI (match_dup 1)))]
9384 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9385 "neg{q}\t%0"
9386 [(set_attr "type" "negnot")
9387 (set_attr "mode" "DI")])
9388
9389
9390 (define_expand "negsi2"
9391 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9392 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9393 (clobber (reg:CC FLAGS_REG))])]
9394 ""
9395 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9396
9397 (define_insn "*negsi2_1"
9398 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9399 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9400 (clobber (reg:CC FLAGS_REG))]
9401 "ix86_unary_operator_ok (NEG, SImode, operands)"
9402 "neg{l}\t%0"
9403 [(set_attr "type" "negnot")
9404 (set_attr "mode" "SI")])
9405
9406 ;; Combine is quite creative about this pattern.
9407 (define_insn "*negsi2_1_zext"
9408 [(set (match_operand:DI 0 "register_operand" "=r")
9409 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9410 (const_int 32)))
9411 (const_int 32)))
9412 (clobber (reg:CC FLAGS_REG))]
9413 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9414 "neg{l}\t%k0"
9415 [(set_attr "type" "negnot")
9416 (set_attr "mode" "SI")])
9417
9418 ;; The problem with neg is that it does not perform (compare x 0),
9419 ;; it really performs (compare 0 x), which leaves us with the zero
9420 ;; flag being the only useful item.
9421
9422 (define_insn "*negsi2_cmpz"
9423 [(set (reg:CCZ FLAGS_REG)
9424 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9425 (const_int 0)))
9426 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9427 (neg:SI (match_dup 1)))]
9428 "ix86_unary_operator_ok (NEG, SImode, operands)"
9429 "neg{l}\t%0"
9430 [(set_attr "type" "negnot")
9431 (set_attr "mode" "SI")])
9432
9433 (define_insn "*negsi2_cmpz_zext"
9434 [(set (reg:CCZ FLAGS_REG)
9435 (compare:CCZ (lshiftrt:DI
9436 (neg:DI (ashift:DI
9437 (match_operand:DI 1 "register_operand" "0")
9438 (const_int 32)))
9439 (const_int 32))
9440 (const_int 0)))
9441 (set (match_operand:DI 0 "register_operand" "=r")
9442 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9443 (const_int 32)))
9444 (const_int 32)))]
9445 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9446 "neg{l}\t%k0"
9447 [(set_attr "type" "negnot")
9448 (set_attr "mode" "SI")])
9449
9450 (define_expand "neghi2"
9451 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9452 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9453 (clobber (reg:CC FLAGS_REG))])]
9454 "TARGET_HIMODE_MATH"
9455 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9456
9457 (define_insn "*neghi2_1"
9458 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9459 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9460 (clobber (reg:CC FLAGS_REG))]
9461 "ix86_unary_operator_ok (NEG, HImode, operands)"
9462 "neg{w}\t%0"
9463 [(set_attr "type" "negnot")
9464 (set_attr "mode" "HI")])
9465
9466 (define_insn "*neghi2_cmpz"
9467 [(set (reg:CCZ FLAGS_REG)
9468 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9469 (const_int 0)))
9470 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9471 (neg:HI (match_dup 1)))]
9472 "ix86_unary_operator_ok (NEG, HImode, operands)"
9473 "neg{w}\t%0"
9474 [(set_attr "type" "negnot")
9475 (set_attr "mode" "HI")])
9476
9477 (define_expand "negqi2"
9478 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9479 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9480 (clobber (reg:CC FLAGS_REG))])]
9481 "TARGET_QIMODE_MATH"
9482 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9483
9484 (define_insn "*negqi2_1"
9485 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9486 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9487 (clobber (reg:CC FLAGS_REG))]
9488 "ix86_unary_operator_ok (NEG, QImode, operands)"
9489 "neg{b}\t%0"
9490 [(set_attr "type" "negnot")
9491 (set_attr "mode" "QI")])
9492
9493 (define_insn "*negqi2_cmpz"
9494 [(set (reg:CCZ FLAGS_REG)
9495 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9496 (const_int 0)))
9497 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9498 (neg:QI (match_dup 1)))]
9499 "ix86_unary_operator_ok (NEG, QImode, operands)"
9500 "neg{b}\t%0"
9501 [(set_attr "type" "negnot")
9502 (set_attr "mode" "QI")])
9503
9504 ;; Changing of sign for FP values is doable using integer unit too.
9505
9506 (define_expand "negsf2"
9507 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9508 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9509 "TARGET_80387 || TARGET_SSE_MATH"
9510 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9511
9512 (define_expand "abssf2"
9513 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9514 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9515 "TARGET_80387 || TARGET_SSE_MATH"
9516 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9517
9518 (define_insn "*absnegsf2_mixed"
9519 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#f,x#f,f#x,rm")
9520 (match_operator:SF 3 "absneg_operator"
9521 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#f,0 ,0")]))
9522 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9523 (clobber (reg:CC FLAGS_REG))]
9524 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9525 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9526 "#")
9527
9528 (define_insn "*absnegsf2_sse"
9529 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9530 (match_operator:SF 3 "absneg_operator"
9531 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9532 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9533 (clobber (reg:CC FLAGS_REG))]
9534 "TARGET_SSE_MATH
9535 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9536 "#")
9537
9538 (define_insn "*absnegsf2_i387"
9539 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9540 (match_operator:SF 3 "absneg_operator"
9541 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9542 (use (match_operand 2 "" ""))
9543 (clobber (reg:CC FLAGS_REG))]
9544 "TARGET_80387 && !TARGET_SSE_MATH
9545 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9546 "#")
9547
9548 (define_expand "copysignsf3"
9549 [(match_operand:SF 0 "register_operand" "")
9550 (match_operand:SF 1 "nonmemory_operand" "")
9551 (match_operand:SF 2 "register_operand" "")]
9552 "TARGET_SSE_MATH"
9553 {
9554 ix86_expand_copysign (operands);
9555 DONE;
9556 })
9557
9558 (define_insn_and_split "copysignsf3_const"
9559 [(set (match_operand:SF 0 "register_operand" "=x")
9560 (unspec:SF
9561 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9562 (match_operand:SF 2 "register_operand" "0")
9563 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9564 UNSPEC_COPYSIGN))]
9565 "TARGET_SSE_MATH"
9566 "#"
9567 "&& reload_completed"
9568 [(const_int 0)]
9569 {
9570 ix86_split_copysign_const (operands);
9571 DONE;
9572 })
9573
9574 (define_insn "copysignsf3_var"
9575 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9576 (unspec:SF
9577 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9578 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9579 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9580 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9581 UNSPEC_COPYSIGN))
9582 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9583 "TARGET_SSE_MATH"
9584 "#")
9585
9586 (define_split
9587 [(set (match_operand:SF 0 "register_operand" "")
9588 (unspec:SF
9589 [(match_operand:SF 2 "register_operand" "")
9590 (match_operand:SF 3 "register_operand" "")
9591 (match_operand:V4SF 4 "" "")
9592 (match_operand:V4SF 5 "" "")]
9593 UNSPEC_COPYSIGN))
9594 (clobber (match_scratch:V4SF 1 ""))]
9595 "TARGET_SSE_MATH && reload_completed"
9596 [(const_int 0)]
9597 {
9598 ix86_split_copysign_var (operands);
9599 DONE;
9600 })
9601
9602 (define_expand "negdf2"
9603 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9604 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9605 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9606 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9607
9608 (define_expand "absdf2"
9609 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9610 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9611 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9612 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9613
9614 (define_insn "*absnegdf2_mixed"
9615 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,f#Y,rm")
9616 (match_operator:DF 3 "absneg_operator"
9617 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#f,0 ,0")]))
9618 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9619 (clobber (reg:CC FLAGS_REG))]
9620 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9621 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9622 "#")
9623
9624 (define_insn "*absnegdf2_sse"
9625 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9626 (match_operator:DF 3 "absneg_operator"
9627 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9628 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X"))
9629 (clobber (reg:CC FLAGS_REG))]
9630 "TARGET_SSE2 && TARGET_SSE_MATH
9631 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9632 "#")
9633
9634 (define_insn "*absnegdf2_i387"
9635 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9636 (match_operator:DF 3 "absneg_operator"
9637 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9638 (use (match_operand 2 "" ""))
9639 (clobber (reg:CC FLAGS_REG))]
9640 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9641 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9642 "#")
9643
9644 (define_expand "copysigndf3"
9645 [(match_operand:DF 0 "register_operand" "")
9646 (match_operand:DF 1 "nonmemory_operand" "")
9647 (match_operand:DF 2 "register_operand" "")]
9648 "TARGET_SSE2 && TARGET_SSE_MATH"
9649 {
9650 ix86_expand_copysign (operands);
9651 DONE;
9652 })
9653
9654 (define_insn_and_split "copysigndf3_const"
9655 [(set (match_operand:DF 0 "register_operand" "=x")
9656 (unspec:DF
9657 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9658 (match_operand:DF 2 "register_operand" "0")
9659 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9660 UNSPEC_COPYSIGN))]
9661 "TARGET_SSE2 && TARGET_SSE_MATH"
9662 "#"
9663 "&& reload_completed"
9664 [(const_int 0)]
9665 {
9666 ix86_split_copysign_const (operands);
9667 DONE;
9668 })
9669
9670 (define_insn "copysigndf3_var"
9671 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9672 (unspec:DF
9673 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9674 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9675 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9676 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9677 UNSPEC_COPYSIGN))
9678 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9679 "TARGET_SSE2 && TARGET_SSE_MATH"
9680 "#")
9681
9682 (define_split
9683 [(set (match_operand:DF 0 "register_operand" "")
9684 (unspec:DF
9685 [(match_operand:DF 2 "register_operand" "")
9686 (match_operand:DF 3 "register_operand" "")
9687 (match_operand:V2DF 4 "" "")
9688 (match_operand:V2DF 5 "" "")]
9689 UNSPEC_COPYSIGN))
9690 (clobber (match_scratch:V2DF 1 ""))]
9691 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9692 [(const_int 0)]
9693 {
9694 ix86_split_copysign_var (operands);
9695 DONE;
9696 })
9697
9698 (define_expand "negxf2"
9699 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9700 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9701 "TARGET_80387"
9702 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9703
9704 (define_expand "absxf2"
9705 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9706 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9707 "TARGET_80387"
9708 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9709
9710 (define_insn "*absnegxf2_i387"
9711 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9712 (match_operator:XF 3 "absneg_operator"
9713 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9714 (use (match_operand 2 "" ""))
9715 (clobber (reg:CC FLAGS_REG))]
9716 "TARGET_80387
9717 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9718 "#")
9719
9720 ;; Splitters for fp abs and neg.
9721
9722 (define_split
9723 [(set (match_operand 0 "fp_register_operand" "")
9724 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9725 (use (match_operand 2 "" ""))
9726 (clobber (reg:CC FLAGS_REG))]
9727 "reload_completed"
9728 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9729
9730 (define_split
9731 [(set (match_operand 0 "register_operand" "")
9732 (match_operator 3 "absneg_operator"
9733 [(match_operand 1 "register_operand" "")]))
9734 (use (match_operand 2 "nonimmediate_operand" ""))
9735 (clobber (reg:CC FLAGS_REG))]
9736 "reload_completed && SSE_REG_P (operands[0])"
9737 [(set (match_dup 0) (match_dup 3))]
9738 {
9739 enum machine_mode mode = GET_MODE (operands[0]);
9740 enum machine_mode vmode = GET_MODE (operands[2]);
9741 rtx tmp;
9742
9743 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9744 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9745 if (operands_match_p (operands[0], operands[2]))
9746 {
9747 tmp = operands[1];
9748 operands[1] = operands[2];
9749 operands[2] = tmp;
9750 }
9751 if (GET_CODE (operands[3]) == ABS)
9752 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9753 else
9754 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9755 operands[3] = tmp;
9756 })
9757
9758 (define_split
9759 [(set (match_operand:SF 0 "register_operand" "")
9760 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9761 (use (match_operand:V4SF 2 "" ""))
9762 (clobber (reg:CC FLAGS_REG))]
9763 "reload_completed"
9764 [(parallel [(set (match_dup 0) (match_dup 1))
9765 (clobber (reg:CC FLAGS_REG))])]
9766 {
9767 rtx tmp;
9768 operands[0] = gen_lowpart (SImode, operands[0]);
9769 if (GET_CODE (operands[1]) == ABS)
9770 {
9771 tmp = gen_int_mode (0x7fffffff, SImode);
9772 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9773 }
9774 else
9775 {
9776 tmp = gen_int_mode (0x80000000, SImode);
9777 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9778 }
9779 operands[1] = tmp;
9780 })
9781
9782 (define_split
9783 [(set (match_operand:DF 0 "register_operand" "")
9784 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9785 (use (match_operand 2 "" ""))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "reload_completed"
9788 [(parallel [(set (match_dup 0) (match_dup 1))
9789 (clobber (reg:CC FLAGS_REG))])]
9790 {
9791 rtx tmp;
9792 if (TARGET_64BIT)
9793 {
9794 tmp = gen_lowpart (DImode, operands[0]);
9795 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9796 operands[0] = tmp;
9797
9798 if (GET_CODE (operands[1]) == ABS)
9799 tmp = const0_rtx;
9800 else
9801 tmp = gen_rtx_NOT (DImode, tmp);
9802 }
9803 else
9804 {
9805 operands[0] = gen_highpart (SImode, operands[0]);
9806 if (GET_CODE (operands[1]) == ABS)
9807 {
9808 tmp = gen_int_mode (0x7fffffff, SImode);
9809 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9810 }
9811 else
9812 {
9813 tmp = gen_int_mode (0x80000000, SImode);
9814 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9815 }
9816 }
9817 operands[1] = tmp;
9818 })
9819
9820 (define_split
9821 [(set (match_operand:XF 0 "register_operand" "")
9822 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9823 (use (match_operand 2 "" ""))
9824 (clobber (reg:CC FLAGS_REG))]
9825 "reload_completed"
9826 [(parallel [(set (match_dup 0) (match_dup 1))
9827 (clobber (reg:CC FLAGS_REG))])]
9828 {
9829 rtx tmp;
9830 operands[0] = gen_rtx_REG (SImode,
9831 true_regnum (operands[0])
9832 + (TARGET_64BIT ? 1 : 2));
9833 if (GET_CODE (operands[1]) == ABS)
9834 {
9835 tmp = GEN_INT (0x7fff);
9836 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9837 }
9838 else
9839 {
9840 tmp = GEN_INT (0x8000);
9841 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9842 }
9843 operands[1] = tmp;
9844 })
9845
9846 (define_split
9847 [(set (match_operand 0 "memory_operand" "")
9848 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9849 (use (match_operand 2 "" ""))
9850 (clobber (reg:CC FLAGS_REG))]
9851 "reload_completed"
9852 [(parallel [(set (match_dup 0) (match_dup 1))
9853 (clobber (reg:CC FLAGS_REG))])]
9854 {
9855 enum machine_mode mode = GET_MODE (operands[0]);
9856 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9857 rtx tmp;
9858
9859 operands[0] = adjust_address (operands[0], QImode, size - 1);
9860 if (GET_CODE (operands[1]) == ABS)
9861 {
9862 tmp = gen_int_mode (0x7f, QImode);
9863 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9864 }
9865 else
9866 {
9867 tmp = gen_int_mode (0x80, QImode);
9868 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9869 }
9870 operands[1] = tmp;
9871 })
9872
9873 ;; Conditionalize these after reload. If they match before reload, we
9874 ;; lose the clobber and ability to use integer instructions.
9875
9876 (define_insn "*negsf2_1"
9877 [(set (match_operand:SF 0 "register_operand" "=f")
9878 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9879 "TARGET_80387 && reload_completed"
9880 "fchs"
9881 [(set_attr "type" "fsgn")
9882 (set_attr "mode" "SF")])
9883
9884 (define_insn "*negdf2_1"
9885 [(set (match_operand:DF 0 "register_operand" "=f")
9886 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9887 "TARGET_80387 && reload_completed"
9888 "fchs"
9889 [(set_attr "type" "fsgn")
9890 (set_attr "mode" "DF")])
9891
9892 (define_insn "*negxf2_1"
9893 [(set (match_operand:XF 0 "register_operand" "=f")
9894 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9895 "TARGET_80387 && reload_completed"
9896 "fchs"
9897 [(set_attr "type" "fsgn")
9898 (set_attr "mode" "XF")])
9899
9900 (define_insn "*abssf2_1"
9901 [(set (match_operand:SF 0 "register_operand" "=f")
9902 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9903 "TARGET_80387 && reload_completed"
9904 "fabs"
9905 [(set_attr "type" "fsgn")
9906 (set_attr "mode" "SF")])
9907
9908 (define_insn "*absdf2_1"
9909 [(set (match_operand:DF 0 "register_operand" "=f")
9910 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9911 "TARGET_80387 && reload_completed"
9912 "fabs"
9913 [(set_attr "type" "fsgn")
9914 (set_attr "mode" "DF")])
9915
9916 (define_insn "*absxf2_1"
9917 [(set (match_operand:XF 0 "register_operand" "=f")
9918 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9919 "TARGET_80387 && reload_completed"
9920 "fabs"
9921 [(set_attr "type" "fsgn")
9922 (set_attr "mode" "DF")])
9923
9924 (define_insn "*negextendsfdf2"
9925 [(set (match_operand:DF 0 "register_operand" "=f")
9926 (neg:DF (float_extend:DF
9927 (match_operand:SF 1 "register_operand" "0"))))]
9928 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9929 "fchs"
9930 [(set_attr "type" "fsgn")
9931 (set_attr "mode" "DF")])
9932
9933 (define_insn "*negextenddfxf2"
9934 [(set (match_operand:XF 0 "register_operand" "=f")
9935 (neg:XF (float_extend:XF
9936 (match_operand:DF 1 "register_operand" "0"))))]
9937 "TARGET_80387"
9938 "fchs"
9939 [(set_attr "type" "fsgn")
9940 (set_attr "mode" "XF")])
9941
9942 (define_insn "*negextendsfxf2"
9943 [(set (match_operand:XF 0 "register_operand" "=f")
9944 (neg:XF (float_extend:XF
9945 (match_operand:SF 1 "register_operand" "0"))))]
9946 "TARGET_80387"
9947 "fchs"
9948 [(set_attr "type" "fsgn")
9949 (set_attr "mode" "XF")])
9950
9951 (define_insn "*absextendsfdf2"
9952 [(set (match_operand:DF 0 "register_operand" "=f")
9953 (abs:DF (float_extend:DF
9954 (match_operand:SF 1 "register_operand" "0"))))]
9955 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9956 "fabs"
9957 [(set_attr "type" "fsgn")
9958 (set_attr "mode" "DF")])
9959
9960 (define_insn "*absextenddfxf2"
9961 [(set (match_operand:XF 0 "register_operand" "=f")
9962 (abs:XF (float_extend:XF
9963 (match_operand:DF 1 "register_operand" "0"))))]
9964 "TARGET_80387"
9965 "fabs"
9966 [(set_attr "type" "fsgn")
9967 (set_attr "mode" "XF")])
9968
9969 (define_insn "*absextendsfxf2"
9970 [(set (match_operand:XF 0 "register_operand" "=f")
9971 (abs:XF (float_extend:XF
9972 (match_operand:SF 1 "register_operand" "0"))))]
9973 "TARGET_80387"
9974 "fabs"
9975 [(set_attr "type" "fsgn")
9976 (set_attr "mode" "XF")])
9977 \f
9978 ;; One complement instructions
9979
9980 (define_expand "one_cmpldi2"
9981 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9982 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9983 "TARGET_64BIT"
9984 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9985
9986 (define_insn "*one_cmpldi2_1_rex64"
9987 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9988 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9989 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9990 "not{q}\t%0"
9991 [(set_attr "type" "negnot")
9992 (set_attr "mode" "DI")])
9993
9994 (define_insn "*one_cmpldi2_2_rex64"
9995 [(set (reg FLAGS_REG)
9996 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9997 (const_int 0)))
9998 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9999 (not:DI (match_dup 1)))]
10000 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10001 && ix86_unary_operator_ok (NOT, DImode, operands)"
10002 "#"
10003 [(set_attr "type" "alu1")
10004 (set_attr "mode" "DI")])
10005
10006 (define_split
10007 [(set (match_operand 0 "flags_reg_operand" "")
10008 (match_operator 2 "compare_operator"
10009 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10010 (const_int 0)]))
10011 (set (match_operand:DI 1 "nonimmediate_operand" "")
10012 (not:DI (match_dup 3)))]
10013 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10014 [(parallel [(set (match_dup 0)
10015 (match_op_dup 2
10016 [(xor:DI (match_dup 3) (const_int -1))
10017 (const_int 0)]))
10018 (set (match_dup 1)
10019 (xor:DI (match_dup 3) (const_int -1)))])]
10020 "")
10021
10022 (define_expand "one_cmplsi2"
10023 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10024 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10025 ""
10026 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10027
10028 (define_insn "*one_cmplsi2_1"
10029 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10030 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10031 "ix86_unary_operator_ok (NOT, SImode, operands)"
10032 "not{l}\t%0"
10033 [(set_attr "type" "negnot")
10034 (set_attr "mode" "SI")])
10035
10036 ;; ??? Currently never generated - xor is used instead.
10037 (define_insn "*one_cmplsi2_1_zext"
10038 [(set (match_operand:DI 0 "register_operand" "=r")
10039 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10040 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10041 "not{l}\t%k0"
10042 [(set_attr "type" "negnot")
10043 (set_attr "mode" "SI")])
10044
10045 (define_insn "*one_cmplsi2_2"
10046 [(set (reg FLAGS_REG)
10047 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10048 (const_int 0)))
10049 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10050 (not:SI (match_dup 1)))]
10051 "ix86_match_ccmode (insn, CCNOmode)
10052 && ix86_unary_operator_ok (NOT, SImode, operands)"
10053 "#"
10054 [(set_attr "type" "alu1")
10055 (set_attr "mode" "SI")])
10056
10057 (define_split
10058 [(set (match_operand 0 "flags_reg_operand" "")
10059 (match_operator 2 "compare_operator"
10060 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10061 (const_int 0)]))
10062 (set (match_operand:SI 1 "nonimmediate_operand" "")
10063 (not:SI (match_dup 3)))]
10064 "ix86_match_ccmode (insn, CCNOmode)"
10065 [(parallel [(set (match_dup 0)
10066 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10067 (const_int 0)]))
10068 (set (match_dup 1)
10069 (xor:SI (match_dup 3) (const_int -1)))])]
10070 "")
10071
10072 ;; ??? Currently never generated - xor is used instead.
10073 (define_insn "*one_cmplsi2_2_zext"
10074 [(set (reg FLAGS_REG)
10075 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10076 (const_int 0)))
10077 (set (match_operand:DI 0 "register_operand" "=r")
10078 (zero_extend:DI (not:SI (match_dup 1))))]
10079 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10080 && ix86_unary_operator_ok (NOT, SImode, operands)"
10081 "#"
10082 [(set_attr "type" "alu1")
10083 (set_attr "mode" "SI")])
10084
10085 (define_split
10086 [(set (match_operand 0 "flags_reg_operand" "")
10087 (match_operator 2 "compare_operator"
10088 [(not:SI (match_operand:SI 3 "register_operand" ""))
10089 (const_int 0)]))
10090 (set (match_operand:DI 1 "register_operand" "")
10091 (zero_extend:DI (not:SI (match_dup 3))))]
10092 "ix86_match_ccmode (insn, CCNOmode)"
10093 [(parallel [(set (match_dup 0)
10094 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10095 (const_int 0)]))
10096 (set (match_dup 1)
10097 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10098 "")
10099
10100 (define_expand "one_cmplhi2"
10101 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10102 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10103 "TARGET_HIMODE_MATH"
10104 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10105
10106 (define_insn "*one_cmplhi2_1"
10107 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10108 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10109 "ix86_unary_operator_ok (NOT, HImode, operands)"
10110 "not{w}\t%0"
10111 [(set_attr "type" "negnot")
10112 (set_attr "mode" "HI")])
10113
10114 (define_insn "*one_cmplhi2_2"
10115 [(set (reg FLAGS_REG)
10116 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10117 (const_int 0)))
10118 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10119 (not:HI (match_dup 1)))]
10120 "ix86_match_ccmode (insn, CCNOmode)
10121 && ix86_unary_operator_ok (NEG, HImode, operands)"
10122 "#"
10123 [(set_attr "type" "alu1")
10124 (set_attr "mode" "HI")])
10125
10126 (define_split
10127 [(set (match_operand 0 "flags_reg_operand" "")
10128 (match_operator 2 "compare_operator"
10129 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10130 (const_int 0)]))
10131 (set (match_operand:HI 1 "nonimmediate_operand" "")
10132 (not:HI (match_dup 3)))]
10133 "ix86_match_ccmode (insn, CCNOmode)"
10134 [(parallel [(set (match_dup 0)
10135 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10136 (const_int 0)]))
10137 (set (match_dup 1)
10138 (xor:HI (match_dup 3) (const_int -1)))])]
10139 "")
10140
10141 ;; %%% Potential partial reg stall on alternative 1. What to do?
10142 (define_expand "one_cmplqi2"
10143 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10144 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10145 "TARGET_QIMODE_MATH"
10146 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10147
10148 (define_insn "*one_cmplqi2_1"
10149 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10150 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10151 "ix86_unary_operator_ok (NOT, QImode, operands)"
10152 "@
10153 not{b}\t%0
10154 not{l}\t%k0"
10155 [(set_attr "type" "negnot")
10156 (set_attr "mode" "QI,SI")])
10157
10158 (define_insn "*one_cmplqi2_2"
10159 [(set (reg FLAGS_REG)
10160 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10161 (const_int 0)))
10162 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10163 (not:QI (match_dup 1)))]
10164 "ix86_match_ccmode (insn, CCNOmode)
10165 && ix86_unary_operator_ok (NOT, QImode, operands)"
10166 "#"
10167 [(set_attr "type" "alu1")
10168 (set_attr "mode" "QI")])
10169
10170 (define_split
10171 [(set (match_operand 0 "flags_reg_operand" "")
10172 (match_operator 2 "compare_operator"
10173 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10174 (const_int 0)]))
10175 (set (match_operand:QI 1 "nonimmediate_operand" "")
10176 (not:QI (match_dup 3)))]
10177 "ix86_match_ccmode (insn, CCNOmode)"
10178 [(parallel [(set (match_dup 0)
10179 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10180 (const_int 0)]))
10181 (set (match_dup 1)
10182 (xor:QI (match_dup 3) (const_int -1)))])]
10183 "")
10184 \f
10185 ;; Arithmetic shift instructions
10186
10187 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10188 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10189 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10190 ;; from the assembler input.
10191 ;;
10192 ;; This instruction shifts the target reg/mem as usual, but instead of
10193 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10194 ;; is a left shift double, bits are taken from the high order bits of
10195 ;; reg, else if the insn is a shift right double, bits are taken from the
10196 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10197 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10198 ;;
10199 ;; Since sh[lr]d does not change the `reg' operand, that is done
10200 ;; separately, making all shifts emit pairs of shift double and normal
10201 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10202 ;; support a 63 bit shift, each shift where the count is in a reg expands
10203 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10204 ;;
10205 ;; If the shift count is a constant, we need never emit more than one
10206 ;; shift pair, instead using moves and sign extension for counts greater
10207 ;; than 31.
10208
10209 (define_expand "ashlti3"
10210 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10211 (ashift:TI (match_operand:TI 1 "register_operand" "")
10212 (match_operand:QI 2 "nonmemory_operand" "")))
10213 (clobber (reg:CC FLAGS_REG))])]
10214 "TARGET_64BIT"
10215 {
10216 if (! immediate_operand (operands[2], QImode))
10217 {
10218 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10219 DONE;
10220 }
10221 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10222 DONE;
10223 })
10224
10225 (define_insn "ashlti3_1"
10226 [(set (match_operand:TI 0 "register_operand" "=r")
10227 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10228 (match_operand:QI 2 "register_operand" "c")))
10229 (clobber (match_scratch:DI 3 "=&r"))
10230 (clobber (reg:CC FLAGS_REG))]
10231 "TARGET_64BIT"
10232 "#"
10233 [(set_attr "type" "multi")])
10234
10235 (define_insn "*ashlti3_2"
10236 [(set (match_operand:TI 0 "register_operand" "=r")
10237 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10238 (match_operand:QI 2 "immediate_operand" "O")))
10239 (clobber (reg:CC FLAGS_REG))]
10240 "TARGET_64BIT"
10241 "#"
10242 [(set_attr "type" "multi")])
10243
10244 (define_split
10245 [(set (match_operand:TI 0 "register_operand" "")
10246 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10247 (match_operand:QI 2 "register_operand" "")))
10248 (clobber (match_scratch:DI 3 ""))
10249 (clobber (reg:CC FLAGS_REG))]
10250 "TARGET_64BIT && reload_completed"
10251 [(const_int 0)]
10252 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10253
10254 (define_split
10255 [(set (match_operand:TI 0 "register_operand" "")
10256 (ashift:TI (match_operand:TI 1 "register_operand" "")
10257 (match_operand:QI 2 "immediate_operand" "")))
10258 (clobber (reg:CC FLAGS_REG))]
10259 "TARGET_64BIT && reload_completed"
10260 [(const_int 0)]
10261 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10262
10263 (define_insn "x86_64_shld"
10264 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10265 (ior:DI (ashift:DI (match_dup 0)
10266 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10267 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10268 (minus:QI (const_int 64) (match_dup 2)))))
10269 (clobber (reg:CC FLAGS_REG))]
10270 "TARGET_64BIT"
10271 "@
10272 shld{q}\t{%2, %1, %0|%0, %1, %2}
10273 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10274 [(set_attr "type" "ishift")
10275 (set_attr "prefix_0f" "1")
10276 (set_attr "mode" "DI")
10277 (set_attr "athlon_decode" "vector")])
10278
10279 (define_expand "x86_64_shift_adj"
10280 [(set (reg:CCZ FLAGS_REG)
10281 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10282 (const_int 64))
10283 (const_int 0)))
10284 (set (match_operand:DI 0 "register_operand" "")
10285 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10286 (match_operand:DI 1 "register_operand" "")
10287 (match_dup 0)))
10288 (set (match_dup 1)
10289 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10290 (match_operand:DI 3 "register_operand" "r")
10291 (match_dup 1)))]
10292 "TARGET_64BIT"
10293 "")
10294
10295 (define_expand "ashldi3"
10296 [(set (match_operand:DI 0 "shiftdi_operand" "")
10297 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10298 (match_operand:QI 2 "nonmemory_operand" "")))]
10299 ""
10300 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10301
10302 (define_insn "*ashldi3_1_rex64"
10303 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10304 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10305 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10306 (clobber (reg:CC FLAGS_REG))]
10307 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10308 {
10309 switch (get_attr_type (insn))
10310 {
10311 case TYPE_ALU:
10312 gcc_assert (operands[2] == const1_rtx);
10313 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10314 return "add{q}\t{%0, %0|%0, %0}";
10315
10316 case TYPE_LEA:
10317 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10318 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10319 operands[1] = gen_rtx_MULT (DImode, operands[1],
10320 GEN_INT (1 << INTVAL (operands[2])));
10321 return "lea{q}\t{%a1, %0|%0, %a1}";
10322
10323 default:
10324 if (REG_P (operands[2]))
10325 return "sal{q}\t{%b2, %0|%0, %b2}";
10326 else if (operands[2] == const1_rtx
10327 && (TARGET_SHIFT1 || optimize_size))
10328 return "sal{q}\t%0";
10329 else
10330 return "sal{q}\t{%2, %0|%0, %2}";
10331 }
10332 }
10333 [(set (attr "type")
10334 (cond [(eq_attr "alternative" "1")
10335 (const_string "lea")
10336 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10337 (const_int 0))
10338 (match_operand 0 "register_operand" ""))
10339 (match_operand 2 "const1_operand" ""))
10340 (const_string "alu")
10341 ]
10342 (const_string "ishift")))
10343 (set_attr "mode" "DI")])
10344
10345 ;; Convert lea to the lea pattern to avoid flags dependency.
10346 (define_split
10347 [(set (match_operand:DI 0 "register_operand" "")
10348 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10349 (match_operand:QI 2 "immediate_operand" "")))
10350 (clobber (reg:CC FLAGS_REG))]
10351 "TARGET_64BIT && reload_completed
10352 && true_regnum (operands[0]) != true_regnum (operands[1])"
10353 [(set (match_dup 0)
10354 (mult:DI (match_dup 1)
10355 (match_dup 2)))]
10356 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10357
10358 ;; This pattern can't accept a variable shift count, since shifts by
10359 ;; zero don't affect the flags. We assume that shifts by constant
10360 ;; zero are optimized away.
10361 (define_insn "*ashldi3_cmp_rex64"
10362 [(set (reg FLAGS_REG)
10363 (compare
10364 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10365 (match_operand:QI 2 "immediate_operand" "e"))
10366 (const_int 0)))
10367 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10368 (ashift:DI (match_dup 1) (match_dup 2)))]
10369 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10370 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10371 {
10372 switch (get_attr_type (insn))
10373 {
10374 case TYPE_ALU:
10375 gcc_assert (operands[2] == const1_rtx);
10376 return "add{q}\t{%0, %0|%0, %0}";
10377
10378 default:
10379 if (REG_P (operands[2]))
10380 return "sal{q}\t{%b2, %0|%0, %b2}";
10381 else if (operands[2] == const1_rtx
10382 && (TARGET_SHIFT1 || optimize_size))
10383 return "sal{q}\t%0";
10384 else
10385 return "sal{q}\t{%2, %0|%0, %2}";
10386 }
10387 }
10388 [(set (attr "type")
10389 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10390 (const_int 0))
10391 (match_operand 0 "register_operand" ""))
10392 (match_operand 2 "const1_operand" ""))
10393 (const_string "alu")
10394 ]
10395 (const_string "ishift")))
10396 (set_attr "mode" "DI")])
10397
10398 (define_insn "*ashldi3_1"
10399 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10400 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10401 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10402 (clobber (reg:CC FLAGS_REG))]
10403 "!TARGET_64BIT"
10404 "#"
10405 [(set_attr "type" "multi")])
10406
10407 ;; By default we don't ask for a scratch register, because when DImode
10408 ;; values are manipulated, registers are already at a premium. But if
10409 ;; we have one handy, we won't turn it away.
10410 (define_peephole2
10411 [(match_scratch:SI 3 "r")
10412 (parallel [(set (match_operand:DI 0 "register_operand" "")
10413 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10414 (match_operand:QI 2 "nonmemory_operand" "")))
10415 (clobber (reg:CC FLAGS_REG))])
10416 (match_dup 3)]
10417 "!TARGET_64BIT && TARGET_CMOVE"
10418 [(const_int 0)]
10419 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10420
10421 (define_split
10422 [(set (match_operand:DI 0 "register_operand" "")
10423 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10424 (match_operand:QI 2 "nonmemory_operand" "")))
10425 (clobber (reg:CC FLAGS_REG))]
10426 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10427 ? flow2_completed : reload_completed)"
10428 [(const_int 0)]
10429 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10430
10431 (define_insn "x86_shld_1"
10432 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10433 (ior:SI (ashift:SI (match_dup 0)
10434 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10435 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10436 (minus:QI (const_int 32) (match_dup 2)))))
10437 (clobber (reg:CC FLAGS_REG))]
10438 ""
10439 "@
10440 shld{l}\t{%2, %1, %0|%0, %1, %2}
10441 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10442 [(set_attr "type" "ishift")
10443 (set_attr "prefix_0f" "1")
10444 (set_attr "mode" "SI")
10445 (set_attr "pent_pair" "np")
10446 (set_attr "athlon_decode" "vector")])
10447
10448 (define_expand "x86_shift_adj_1"
10449 [(set (reg:CCZ FLAGS_REG)
10450 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10451 (const_int 32))
10452 (const_int 0)))
10453 (set (match_operand:SI 0 "register_operand" "")
10454 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10455 (match_operand:SI 1 "register_operand" "")
10456 (match_dup 0)))
10457 (set (match_dup 1)
10458 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10459 (match_operand:SI 3 "register_operand" "r")
10460 (match_dup 1)))]
10461 "TARGET_CMOVE"
10462 "")
10463
10464 (define_expand "x86_shift_adj_2"
10465 [(use (match_operand:SI 0 "register_operand" ""))
10466 (use (match_operand:SI 1 "register_operand" ""))
10467 (use (match_operand:QI 2 "register_operand" ""))]
10468 ""
10469 {
10470 rtx label = gen_label_rtx ();
10471 rtx tmp;
10472
10473 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10474
10475 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10476 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10477 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10478 gen_rtx_LABEL_REF (VOIDmode, label),
10479 pc_rtx);
10480 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10481 JUMP_LABEL (tmp) = label;
10482
10483 emit_move_insn (operands[0], operands[1]);
10484 ix86_expand_clear (operands[1]);
10485
10486 emit_label (label);
10487 LABEL_NUSES (label) = 1;
10488
10489 DONE;
10490 })
10491
10492 (define_expand "ashlsi3"
10493 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10494 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10495 (match_operand:QI 2 "nonmemory_operand" "")))
10496 (clobber (reg:CC FLAGS_REG))]
10497 ""
10498 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10499
10500 (define_insn "*ashlsi3_1"
10501 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10502 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10503 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10504 (clobber (reg:CC FLAGS_REG))]
10505 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10506 {
10507 switch (get_attr_type (insn))
10508 {
10509 case TYPE_ALU:
10510 gcc_assert (operands[2] == const1_rtx);
10511 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10512 return "add{l}\t{%0, %0|%0, %0}";
10513
10514 case TYPE_LEA:
10515 return "#";
10516
10517 default:
10518 if (REG_P (operands[2]))
10519 return "sal{l}\t{%b2, %0|%0, %b2}";
10520 else if (operands[2] == const1_rtx
10521 && (TARGET_SHIFT1 || optimize_size))
10522 return "sal{l}\t%0";
10523 else
10524 return "sal{l}\t{%2, %0|%0, %2}";
10525 }
10526 }
10527 [(set (attr "type")
10528 (cond [(eq_attr "alternative" "1")
10529 (const_string "lea")
10530 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10531 (const_int 0))
10532 (match_operand 0 "register_operand" ""))
10533 (match_operand 2 "const1_operand" ""))
10534 (const_string "alu")
10535 ]
10536 (const_string "ishift")))
10537 (set_attr "mode" "SI")])
10538
10539 ;; Convert lea to the lea pattern to avoid flags dependency.
10540 (define_split
10541 [(set (match_operand 0 "register_operand" "")
10542 (ashift (match_operand 1 "index_register_operand" "")
10543 (match_operand:QI 2 "const_int_operand" "")))
10544 (clobber (reg:CC FLAGS_REG))]
10545 "reload_completed
10546 && true_regnum (operands[0]) != true_regnum (operands[1])
10547 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10548 [(const_int 0)]
10549 {
10550 rtx pat;
10551 enum machine_mode mode = GET_MODE (operands[0]);
10552
10553 if (GET_MODE_SIZE (mode) < 4)
10554 operands[0] = gen_lowpart (SImode, operands[0]);
10555 if (mode != Pmode)
10556 operands[1] = gen_lowpart (Pmode, operands[1]);
10557 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10558
10559 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10560 if (Pmode != SImode)
10561 pat = gen_rtx_SUBREG (SImode, pat, 0);
10562 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10563 DONE;
10564 })
10565
10566 ;; Rare case of shifting RSP is handled by generating move and shift
10567 (define_split
10568 [(set (match_operand 0 "register_operand" "")
10569 (ashift (match_operand 1 "register_operand" "")
10570 (match_operand:QI 2 "const_int_operand" "")))
10571 (clobber (reg:CC FLAGS_REG))]
10572 "reload_completed
10573 && true_regnum (operands[0]) != true_regnum (operands[1])"
10574 [(const_int 0)]
10575 {
10576 rtx pat, clob;
10577 emit_move_insn (operands[0], operands[1]);
10578 pat = gen_rtx_SET (VOIDmode, operands[0],
10579 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10580 operands[0], operands[2]));
10581 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10582 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10583 DONE;
10584 })
10585
10586 (define_insn "*ashlsi3_1_zext"
10587 [(set (match_operand:DI 0 "register_operand" "=r,r")
10588 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10589 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10590 (clobber (reg:CC FLAGS_REG))]
10591 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10592 {
10593 switch (get_attr_type (insn))
10594 {
10595 case TYPE_ALU:
10596 gcc_assert (operands[2] == const1_rtx);
10597 return "add{l}\t{%k0, %k0|%k0, %k0}";
10598
10599 case TYPE_LEA:
10600 return "#";
10601
10602 default:
10603 if (REG_P (operands[2]))
10604 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10605 else if (operands[2] == const1_rtx
10606 && (TARGET_SHIFT1 || optimize_size))
10607 return "sal{l}\t%k0";
10608 else
10609 return "sal{l}\t{%2, %k0|%k0, %2}";
10610 }
10611 }
10612 [(set (attr "type")
10613 (cond [(eq_attr "alternative" "1")
10614 (const_string "lea")
10615 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10616 (const_int 0))
10617 (match_operand 2 "const1_operand" ""))
10618 (const_string "alu")
10619 ]
10620 (const_string "ishift")))
10621 (set_attr "mode" "SI")])
10622
10623 ;; Convert lea to the lea pattern to avoid flags dependency.
10624 (define_split
10625 [(set (match_operand:DI 0 "register_operand" "")
10626 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10627 (match_operand:QI 2 "const_int_operand" ""))))
10628 (clobber (reg:CC FLAGS_REG))]
10629 "TARGET_64BIT && reload_completed
10630 && true_regnum (operands[0]) != true_regnum (operands[1])"
10631 [(set (match_dup 0) (zero_extend:DI
10632 (subreg:SI (mult:SI (match_dup 1)
10633 (match_dup 2)) 0)))]
10634 {
10635 operands[1] = gen_lowpart (Pmode, operands[1]);
10636 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10637 })
10638
10639 ;; This pattern can't accept a variable shift count, since shifts by
10640 ;; zero don't affect the flags. We assume that shifts by constant
10641 ;; zero are optimized away.
10642 (define_insn "*ashlsi3_cmp"
10643 [(set (reg FLAGS_REG)
10644 (compare
10645 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10646 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10647 (const_int 0)))
10648 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10649 (ashift:SI (match_dup 1) (match_dup 2)))]
10650 "ix86_match_ccmode (insn, CCGOCmode)
10651 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10652 {
10653 switch (get_attr_type (insn))
10654 {
10655 case TYPE_ALU:
10656 gcc_assert (operands[2] == const1_rtx);
10657 return "add{l}\t{%0, %0|%0, %0}";
10658
10659 default:
10660 if (REG_P (operands[2]))
10661 return "sal{l}\t{%b2, %0|%0, %b2}";
10662 else if (operands[2] == const1_rtx
10663 && (TARGET_SHIFT1 || optimize_size))
10664 return "sal{l}\t%0";
10665 else
10666 return "sal{l}\t{%2, %0|%0, %2}";
10667 }
10668 }
10669 [(set (attr "type")
10670 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10671 (const_int 0))
10672 (match_operand 0 "register_operand" ""))
10673 (match_operand 2 "const1_operand" ""))
10674 (const_string "alu")
10675 ]
10676 (const_string "ishift")))
10677 (set_attr "mode" "SI")])
10678
10679 (define_insn "*ashlsi3_cmp_zext"
10680 [(set (reg FLAGS_REG)
10681 (compare
10682 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10683 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10684 (const_int 0)))
10685 (set (match_operand:DI 0 "register_operand" "=r")
10686 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10687 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10688 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10689 {
10690 switch (get_attr_type (insn))
10691 {
10692 case TYPE_ALU:
10693 gcc_assert (operands[2] == const1_rtx);
10694 return "add{l}\t{%k0, %k0|%k0, %k0}";
10695
10696 default:
10697 if (REG_P (operands[2]))
10698 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10699 else if (operands[2] == const1_rtx
10700 && (TARGET_SHIFT1 || optimize_size))
10701 return "sal{l}\t%k0";
10702 else
10703 return "sal{l}\t{%2, %k0|%k0, %2}";
10704 }
10705 }
10706 [(set (attr "type")
10707 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10708 (const_int 0))
10709 (match_operand 2 "const1_operand" ""))
10710 (const_string "alu")
10711 ]
10712 (const_string "ishift")))
10713 (set_attr "mode" "SI")])
10714
10715 (define_expand "ashlhi3"
10716 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10717 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10718 (match_operand:QI 2 "nonmemory_operand" "")))
10719 (clobber (reg:CC FLAGS_REG))]
10720 "TARGET_HIMODE_MATH"
10721 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10722
10723 (define_insn "*ashlhi3_1_lea"
10724 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10725 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10726 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10727 (clobber (reg:CC FLAGS_REG))]
10728 "!TARGET_PARTIAL_REG_STALL
10729 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10730 {
10731 switch (get_attr_type (insn))
10732 {
10733 case TYPE_LEA:
10734 return "#";
10735 case TYPE_ALU:
10736 gcc_assert (operands[2] == const1_rtx);
10737 return "add{w}\t{%0, %0|%0, %0}";
10738
10739 default:
10740 if (REG_P (operands[2]))
10741 return "sal{w}\t{%b2, %0|%0, %b2}";
10742 else if (operands[2] == const1_rtx
10743 && (TARGET_SHIFT1 || optimize_size))
10744 return "sal{w}\t%0";
10745 else
10746 return "sal{w}\t{%2, %0|%0, %2}";
10747 }
10748 }
10749 [(set (attr "type")
10750 (cond [(eq_attr "alternative" "1")
10751 (const_string "lea")
10752 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10753 (const_int 0))
10754 (match_operand 0 "register_operand" ""))
10755 (match_operand 2 "const1_operand" ""))
10756 (const_string "alu")
10757 ]
10758 (const_string "ishift")))
10759 (set_attr "mode" "HI,SI")])
10760
10761 (define_insn "*ashlhi3_1"
10762 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10763 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10764 (match_operand:QI 2 "nonmemory_operand" "cI")))
10765 (clobber (reg:CC FLAGS_REG))]
10766 "TARGET_PARTIAL_REG_STALL
10767 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10768 {
10769 switch (get_attr_type (insn))
10770 {
10771 case TYPE_ALU:
10772 gcc_assert (operands[2] == const1_rtx);
10773 return "add{w}\t{%0, %0|%0, %0}";
10774
10775 default:
10776 if (REG_P (operands[2]))
10777 return "sal{w}\t{%b2, %0|%0, %b2}";
10778 else if (operands[2] == const1_rtx
10779 && (TARGET_SHIFT1 || optimize_size))
10780 return "sal{w}\t%0";
10781 else
10782 return "sal{w}\t{%2, %0|%0, %2}";
10783 }
10784 }
10785 [(set (attr "type")
10786 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10787 (const_int 0))
10788 (match_operand 0 "register_operand" ""))
10789 (match_operand 2 "const1_operand" ""))
10790 (const_string "alu")
10791 ]
10792 (const_string "ishift")))
10793 (set_attr "mode" "HI")])
10794
10795 ;; This pattern can't accept a variable shift count, since shifts by
10796 ;; zero don't affect the flags. We assume that shifts by constant
10797 ;; zero are optimized away.
10798 (define_insn "*ashlhi3_cmp"
10799 [(set (reg FLAGS_REG)
10800 (compare
10801 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10802 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10803 (const_int 0)))
10804 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10805 (ashift:HI (match_dup 1) (match_dup 2)))]
10806 "ix86_match_ccmode (insn, CCGOCmode)
10807 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10808 {
10809 switch (get_attr_type (insn))
10810 {
10811 case TYPE_ALU:
10812 gcc_assert (operands[2] == const1_rtx);
10813 return "add{w}\t{%0, %0|%0, %0}";
10814
10815 default:
10816 if (REG_P (operands[2]))
10817 return "sal{w}\t{%b2, %0|%0, %b2}";
10818 else if (operands[2] == const1_rtx
10819 && (TARGET_SHIFT1 || optimize_size))
10820 return "sal{w}\t%0";
10821 else
10822 return "sal{w}\t{%2, %0|%0, %2}";
10823 }
10824 }
10825 [(set (attr "type")
10826 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10827 (const_int 0))
10828 (match_operand 0 "register_operand" ""))
10829 (match_operand 2 "const1_operand" ""))
10830 (const_string "alu")
10831 ]
10832 (const_string "ishift")))
10833 (set_attr "mode" "HI")])
10834
10835 (define_expand "ashlqi3"
10836 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10837 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10838 (match_operand:QI 2 "nonmemory_operand" "")))
10839 (clobber (reg:CC FLAGS_REG))]
10840 "TARGET_QIMODE_MATH"
10841 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10842
10843 ;; %%% Potential partial reg stall on alternative 2. What to do?
10844
10845 (define_insn "*ashlqi3_1_lea"
10846 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10847 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10848 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10849 (clobber (reg:CC FLAGS_REG))]
10850 "!TARGET_PARTIAL_REG_STALL
10851 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10852 {
10853 switch (get_attr_type (insn))
10854 {
10855 case TYPE_LEA:
10856 return "#";
10857 case TYPE_ALU:
10858 gcc_assert (operands[2] == const1_rtx);
10859 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10860 return "add{l}\t{%k0, %k0|%k0, %k0}";
10861 else
10862 return "add{b}\t{%0, %0|%0, %0}";
10863
10864 default:
10865 if (REG_P (operands[2]))
10866 {
10867 if (get_attr_mode (insn) == MODE_SI)
10868 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10869 else
10870 return "sal{b}\t{%b2, %0|%0, %b2}";
10871 }
10872 else if (operands[2] == const1_rtx
10873 && (TARGET_SHIFT1 || optimize_size))
10874 {
10875 if (get_attr_mode (insn) == MODE_SI)
10876 return "sal{l}\t%0";
10877 else
10878 return "sal{b}\t%0";
10879 }
10880 else
10881 {
10882 if (get_attr_mode (insn) == MODE_SI)
10883 return "sal{l}\t{%2, %k0|%k0, %2}";
10884 else
10885 return "sal{b}\t{%2, %0|%0, %2}";
10886 }
10887 }
10888 }
10889 [(set (attr "type")
10890 (cond [(eq_attr "alternative" "2")
10891 (const_string "lea")
10892 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10893 (const_int 0))
10894 (match_operand 0 "register_operand" ""))
10895 (match_operand 2 "const1_operand" ""))
10896 (const_string "alu")
10897 ]
10898 (const_string "ishift")))
10899 (set_attr "mode" "QI,SI,SI")])
10900
10901 (define_insn "*ashlqi3_1"
10902 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10903 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10904 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10905 (clobber (reg:CC FLAGS_REG))]
10906 "TARGET_PARTIAL_REG_STALL
10907 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10908 {
10909 switch (get_attr_type (insn))
10910 {
10911 case TYPE_ALU:
10912 gcc_assert (operands[2] == const1_rtx);
10913 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10914 return "add{l}\t{%k0, %k0|%k0, %k0}";
10915 else
10916 return "add{b}\t{%0, %0|%0, %0}";
10917
10918 default:
10919 if (REG_P (operands[2]))
10920 {
10921 if (get_attr_mode (insn) == MODE_SI)
10922 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10923 else
10924 return "sal{b}\t{%b2, %0|%0, %b2}";
10925 }
10926 else if (operands[2] == const1_rtx
10927 && (TARGET_SHIFT1 || optimize_size))
10928 {
10929 if (get_attr_mode (insn) == MODE_SI)
10930 return "sal{l}\t%0";
10931 else
10932 return "sal{b}\t%0";
10933 }
10934 else
10935 {
10936 if (get_attr_mode (insn) == MODE_SI)
10937 return "sal{l}\t{%2, %k0|%k0, %2}";
10938 else
10939 return "sal{b}\t{%2, %0|%0, %2}";
10940 }
10941 }
10942 }
10943 [(set (attr "type")
10944 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10945 (const_int 0))
10946 (match_operand 0 "register_operand" ""))
10947 (match_operand 2 "const1_operand" ""))
10948 (const_string "alu")
10949 ]
10950 (const_string "ishift")))
10951 (set_attr "mode" "QI,SI")])
10952
10953 ;; This pattern can't accept a variable shift count, since shifts by
10954 ;; zero don't affect the flags. We assume that shifts by constant
10955 ;; zero are optimized away.
10956 (define_insn "*ashlqi3_cmp"
10957 [(set (reg FLAGS_REG)
10958 (compare
10959 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10960 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10961 (const_int 0)))
10962 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10963 (ashift:QI (match_dup 1) (match_dup 2)))]
10964 "ix86_match_ccmode (insn, CCGOCmode)
10965 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10966 {
10967 switch (get_attr_type (insn))
10968 {
10969 case TYPE_ALU:
10970 gcc_assert (operands[2] == const1_rtx);
10971 return "add{b}\t{%0, %0|%0, %0}";
10972
10973 default:
10974 if (REG_P (operands[2]))
10975 return "sal{b}\t{%b2, %0|%0, %b2}";
10976 else if (operands[2] == const1_rtx
10977 && (TARGET_SHIFT1 || optimize_size))
10978 return "sal{b}\t%0";
10979 else
10980 return "sal{b}\t{%2, %0|%0, %2}";
10981 }
10982 }
10983 [(set (attr "type")
10984 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10985 (const_int 0))
10986 (match_operand 0 "register_operand" ""))
10987 (match_operand 2 "const1_operand" ""))
10988 (const_string "alu")
10989 ]
10990 (const_string "ishift")))
10991 (set_attr "mode" "QI")])
10992
10993 ;; See comment above `ashldi3' about how this works.
10994
10995 (define_expand "ashrti3"
10996 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10997 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10998 (match_operand:QI 2 "nonmemory_operand" "")))
10999 (clobber (reg:CC FLAGS_REG))])]
11000 "TARGET_64BIT"
11001 {
11002 if (! immediate_operand (operands[2], QImode))
11003 {
11004 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11005 DONE;
11006 }
11007 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11008 DONE;
11009 })
11010
11011 (define_insn "ashrti3_1"
11012 [(set (match_operand:TI 0 "register_operand" "=r")
11013 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11014 (match_operand:QI 2 "register_operand" "c")))
11015 (clobber (match_scratch:DI 3 "=&r"))
11016 (clobber (reg:CC FLAGS_REG))]
11017 "TARGET_64BIT"
11018 "#"
11019 [(set_attr "type" "multi")])
11020
11021 (define_insn "*ashrti3_2"
11022 [(set (match_operand:TI 0 "register_operand" "=r")
11023 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11024 (match_operand:QI 2 "immediate_operand" "O")))
11025 (clobber (reg:CC FLAGS_REG))]
11026 "TARGET_64BIT"
11027 "#"
11028 [(set_attr "type" "multi")])
11029
11030 (define_split
11031 [(set (match_operand:TI 0 "register_operand" "")
11032 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11033 (match_operand:QI 2 "register_operand" "")))
11034 (clobber (match_scratch:DI 3 ""))
11035 (clobber (reg:CC FLAGS_REG))]
11036 "TARGET_64BIT && reload_completed"
11037 [(const_int 0)]
11038 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11039
11040 (define_split
11041 [(set (match_operand:TI 0 "register_operand" "")
11042 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11043 (match_operand:QI 2 "immediate_operand" "")))
11044 (clobber (reg:CC FLAGS_REG))]
11045 "TARGET_64BIT && reload_completed"
11046 [(const_int 0)]
11047 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11048
11049 (define_insn "x86_64_shrd"
11050 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11051 (ior:DI (ashiftrt:DI (match_dup 0)
11052 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11053 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11054 (minus:QI (const_int 64) (match_dup 2)))))
11055 (clobber (reg:CC FLAGS_REG))]
11056 "TARGET_64BIT"
11057 "@
11058 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11059 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11060 [(set_attr "type" "ishift")
11061 (set_attr "prefix_0f" "1")
11062 (set_attr "mode" "DI")
11063 (set_attr "athlon_decode" "vector")])
11064
11065 (define_expand "ashrdi3"
11066 [(set (match_operand:DI 0 "shiftdi_operand" "")
11067 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11068 (match_operand:QI 2 "nonmemory_operand" "")))]
11069 ""
11070 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11071
11072 (define_insn "*ashrdi3_63_rex64"
11073 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11074 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11075 (match_operand:DI 2 "const_int_operand" "i,i")))
11076 (clobber (reg:CC FLAGS_REG))]
11077 "TARGET_64BIT && INTVAL (operands[2]) == 63
11078 && (TARGET_USE_CLTD || optimize_size)
11079 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11080 "@
11081 {cqto|cqo}
11082 sar{q}\t{%2, %0|%0, %2}"
11083 [(set_attr "type" "imovx,ishift")
11084 (set_attr "prefix_0f" "0,*")
11085 (set_attr "length_immediate" "0,*")
11086 (set_attr "modrm" "0,1")
11087 (set_attr "mode" "DI")])
11088
11089 (define_insn "*ashrdi3_1_one_bit_rex64"
11090 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11091 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11092 (match_operand:QI 2 "const1_operand" "")))
11093 (clobber (reg:CC FLAGS_REG))]
11094 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11095 && (TARGET_SHIFT1 || optimize_size)"
11096 "sar{q}\t%0"
11097 [(set_attr "type" "ishift")
11098 (set (attr "length")
11099 (if_then_else (match_operand:DI 0 "register_operand" "")
11100 (const_string "2")
11101 (const_string "*")))])
11102
11103 (define_insn "*ashrdi3_1_rex64"
11104 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11105 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11106 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11107 (clobber (reg:CC FLAGS_REG))]
11108 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11109 "@
11110 sar{q}\t{%2, %0|%0, %2}
11111 sar{q}\t{%b2, %0|%0, %b2}"
11112 [(set_attr "type" "ishift")
11113 (set_attr "mode" "DI")])
11114
11115 ;; This pattern can't accept a variable shift count, since shifts by
11116 ;; zero don't affect the flags. We assume that shifts by constant
11117 ;; zero are optimized away.
11118 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11119 [(set (reg FLAGS_REG)
11120 (compare
11121 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11122 (match_operand:QI 2 "const1_operand" ""))
11123 (const_int 0)))
11124 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11125 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11126 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11127 && (TARGET_SHIFT1 || optimize_size)
11128 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11129 "sar{q}\t%0"
11130 [(set_attr "type" "ishift")
11131 (set (attr "length")
11132 (if_then_else (match_operand:DI 0 "register_operand" "")
11133 (const_string "2")
11134 (const_string "*")))])
11135
11136 ;; This pattern can't accept a variable shift count, since shifts by
11137 ;; zero don't affect the flags. We assume that shifts by constant
11138 ;; zero are optimized away.
11139 (define_insn "*ashrdi3_cmp_rex64"
11140 [(set (reg FLAGS_REG)
11141 (compare
11142 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11143 (match_operand:QI 2 "const_int_operand" "n"))
11144 (const_int 0)))
11145 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11146 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11147 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11148 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11149 "sar{q}\t{%2, %0|%0, %2}"
11150 [(set_attr "type" "ishift")
11151 (set_attr "mode" "DI")])
11152
11153 (define_insn "*ashrdi3_1"
11154 [(set (match_operand:DI 0 "register_operand" "=r")
11155 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11156 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11157 (clobber (reg:CC FLAGS_REG))]
11158 "!TARGET_64BIT"
11159 "#"
11160 [(set_attr "type" "multi")])
11161
11162 ;; By default we don't ask for a scratch register, because when DImode
11163 ;; values are manipulated, registers are already at a premium. But if
11164 ;; we have one handy, we won't turn it away.
11165 (define_peephole2
11166 [(match_scratch:SI 3 "r")
11167 (parallel [(set (match_operand:DI 0 "register_operand" "")
11168 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11169 (match_operand:QI 2 "nonmemory_operand" "")))
11170 (clobber (reg:CC FLAGS_REG))])
11171 (match_dup 3)]
11172 "!TARGET_64BIT && TARGET_CMOVE"
11173 [(const_int 0)]
11174 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11175
11176 (define_split
11177 [(set (match_operand:DI 0 "register_operand" "")
11178 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11179 (match_operand:QI 2 "nonmemory_operand" "")))
11180 (clobber (reg:CC FLAGS_REG))]
11181 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11182 ? flow2_completed : reload_completed)"
11183 [(const_int 0)]
11184 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11185
11186 (define_insn "x86_shrd_1"
11187 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11188 (ior:SI (ashiftrt:SI (match_dup 0)
11189 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11190 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11191 (minus:QI (const_int 32) (match_dup 2)))))
11192 (clobber (reg:CC FLAGS_REG))]
11193 ""
11194 "@
11195 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11196 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11197 [(set_attr "type" "ishift")
11198 (set_attr "prefix_0f" "1")
11199 (set_attr "pent_pair" "np")
11200 (set_attr "mode" "SI")])
11201
11202 (define_expand "x86_shift_adj_3"
11203 [(use (match_operand:SI 0 "register_operand" ""))
11204 (use (match_operand:SI 1 "register_operand" ""))
11205 (use (match_operand:QI 2 "register_operand" ""))]
11206 ""
11207 {
11208 rtx label = gen_label_rtx ();
11209 rtx tmp;
11210
11211 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11212
11213 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11214 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11215 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11216 gen_rtx_LABEL_REF (VOIDmode, label),
11217 pc_rtx);
11218 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11219 JUMP_LABEL (tmp) = label;
11220
11221 emit_move_insn (operands[0], operands[1]);
11222 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11223
11224 emit_label (label);
11225 LABEL_NUSES (label) = 1;
11226
11227 DONE;
11228 })
11229
11230 (define_insn "ashrsi3_31"
11231 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11232 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11233 (match_operand:SI 2 "const_int_operand" "i,i")))
11234 (clobber (reg:CC FLAGS_REG))]
11235 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11236 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11237 "@
11238 {cltd|cdq}
11239 sar{l}\t{%2, %0|%0, %2}"
11240 [(set_attr "type" "imovx,ishift")
11241 (set_attr "prefix_0f" "0,*")
11242 (set_attr "length_immediate" "0,*")
11243 (set_attr "modrm" "0,1")
11244 (set_attr "mode" "SI")])
11245
11246 (define_insn "*ashrsi3_31_zext"
11247 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11248 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11249 (match_operand:SI 2 "const_int_operand" "i,i"))))
11250 (clobber (reg:CC FLAGS_REG))]
11251 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11252 && INTVAL (operands[2]) == 31
11253 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11254 "@
11255 {cltd|cdq}
11256 sar{l}\t{%2, %k0|%k0, %2}"
11257 [(set_attr "type" "imovx,ishift")
11258 (set_attr "prefix_0f" "0,*")
11259 (set_attr "length_immediate" "0,*")
11260 (set_attr "modrm" "0,1")
11261 (set_attr "mode" "SI")])
11262
11263 (define_expand "ashrsi3"
11264 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11265 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11266 (match_operand:QI 2 "nonmemory_operand" "")))
11267 (clobber (reg:CC FLAGS_REG))]
11268 ""
11269 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11270
11271 (define_insn "*ashrsi3_1_one_bit"
11272 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11273 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11274 (match_operand:QI 2 "const1_operand" "")))
11275 (clobber (reg:CC FLAGS_REG))]
11276 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11277 && (TARGET_SHIFT1 || optimize_size)"
11278 "sar{l}\t%0"
11279 [(set_attr "type" "ishift")
11280 (set (attr "length")
11281 (if_then_else (match_operand:SI 0 "register_operand" "")
11282 (const_string "2")
11283 (const_string "*")))])
11284
11285 (define_insn "*ashrsi3_1_one_bit_zext"
11286 [(set (match_operand:DI 0 "register_operand" "=r")
11287 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11288 (match_operand:QI 2 "const1_operand" ""))))
11289 (clobber (reg:CC FLAGS_REG))]
11290 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11291 && (TARGET_SHIFT1 || optimize_size)"
11292 "sar{l}\t%k0"
11293 [(set_attr "type" "ishift")
11294 (set_attr "length" "2")])
11295
11296 (define_insn "*ashrsi3_1"
11297 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11298 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11299 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11300 (clobber (reg:CC FLAGS_REG))]
11301 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11302 "@
11303 sar{l}\t{%2, %0|%0, %2}
11304 sar{l}\t{%b2, %0|%0, %b2}"
11305 [(set_attr "type" "ishift")
11306 (set_attr "mode" "SI")])
11307
11308 (define_insn "*ashrsi3_1_zext"
11309 [(set (match_operand:DI 0 "register_operand" "=r,r")
11310 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11311 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11312 (clobber (reg:CC FLAGS_REG))]
11313 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11314 "@
11315 sar{l}\t{%2, %k0|%k0, %2}
11316 sar{l}\t{%b2, %k0|%k0, %b2}"
11317 [(set_attr "type" "ishift")
11318 (set_attr "mode" "SI")])
11319
11320 ;; This pattern can't accept a variable shift count, since shifts by
11321 ;; zero don't affect the flags. We assume that shifts by constant
11322 ;; zero are optimized away.
11323 (define_insn "*ashrsi3_one_bit_cmp"
11324 [(set (reg FLAGS_REG)
11325 (compare
11326 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11327 (match_operand:QI 2 "const1_operand" ""))
11328 (const_int 0)))
11329 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11330 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11331 "ix86_match_ccmode (insn, CCGOCmode)
11332 && (TARGET_SHIFT1 || optimize_size)
11333 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11334 "sar{l}\t%0"
11335 [(set_attr "type" "ishift")
11336 (set (attr "length")
11337 (if_then_else (match_operand:SI 0 "register_operand" "")
11338 (const_string "2")
11339 (const_string "*")))])
11340
11341 (define_insn "*ashrsi3_one_bit_cmp_zext"
11342 [(set (reg FLAGS_REG)
11343 (compare
11344 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11345 (match_operand:QI 2 "const1_operand" ""))
11346 (const_int 0)))
11347 (set (match_operand:DI 0 "register_operand" "=r")
11348 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11349 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11350 && (TARGET_SHIFT1 || optimize_size)
11351 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11352 "sar{l}\t%k0"
11353 [(set_attr "type" "ishift")
11354 (set_attr "length" "2")])
11355
11356 ;; This pattern can't accept a variable shift count, since shifts by
11357 ;; zero don't affect the flags. We assume that shifts by constant
11358 ;; zero are optimized away.
11359 (define_insn "*ashrsi3_cmp"
11360 [(set (reg FLAGS_REG)
11361 (compare
11362 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11363 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11364 (const_int 0)))
11365 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11366 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11367 "ix86_match_ccmode (insn, CCGOCmode)
11368 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11369 "sar{l}\t{%2, %0|%0, %2}"
11370 [(set_attr "type" "ishift")
11371 (set_attr "mode" "SI")])
11372
11373 (define_insn "*ashrsi3_cmp_zext"
11374 [(set (reg FLAGS_REG)
11375 (compare
11376 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11377 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11378 (const_int 0)))
11379 (set (match_operand:DI 0 "register_operand" "=r")
11380 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11381 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11382 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11383 "sar{l}\t{%2, %k0|%k0, %2}"
11384 [(set_attr "type" "ishift")
11385 (set_attr "mode" "SI")])
11386
11387 (define_expand "ashrhi3"
11388 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11389 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11390 (match_operand:QI 2 "nonmemory_operand" "")))
11391 (clobber (reg:CC FLAGS_REG))]
11392 "TARGET_HIMODE_MATH"
11393 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11394
11395 (define_insn "*ashrhi3_1_one_bit"
11396 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11397 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11398 (match_operand:QI 2 "const1_operand" "")))
11399 (clobber (reg:CC FLAGS_REG))]
11400 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11401 && (TARGET_SHIFT1 || optimize_size)"
11402 "sar{w}\t%0"
11403 [(set_attr "type" "ishift")
11404 (set (attr "length")
11405 (if_then_else (match_operand 0 "register_operand" "")
11406 (const_string "2")
11407 (const_string "*")))])
11408
11409 (define_insn "*ashrhi3_1"
11410 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11411 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11412 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11413 (clobber (reg:CC FLAGS_REG))]
11414 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11415 "@
11416 sar{w}\t{%2, %0|%0, %2}
11417 sar{w}\t{%b2, %0|%0, %b2}"
11418 [(set_attr "type" "ishift")
11419 (set_attr "mode" "HI")])
11420
11421 ;; This pattern can't accept a variable shift count, since shifts by
11422 ;; zero don't affect the flags. We assume that shifts by constant
11423 ;; zero are optimized away.
11424 (define_insn "*ashrhi3_one_bit_cmp"
11425 [(set (reg FLAGS_REG)
11426 (compare
11427 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11428 (match_operand:QI 2 "const1_operand" ""))
11429 (const_int 0)))
11430 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11431 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11432 "ix86_match_ccmode (insn, CCGOCmode)
11433 && (TARGET_SHIFT1 || optimize_size)
11434 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11435 "sar{w}\t%0"
11436 [(set_attr "type" "ishift")
11437 (set (attr "length")
11438 (if_then_else (match_operand 0 "register_operand" "")
11439 (const_string "2")
11440 (const_string "*")))])
11441
11442 ;; This pattern can't accept a variable shift count, since shifts by
11443 ;; zero don't affect the flags. We assume that shifts by constant
11444 ;; zero are optimized away.
11445 (define_insn "*ashrhi3_cmp"
11446 [(set (reg FLAGS_REG)
11447 (compare
11448 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11449 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11450 (const_int 0)))
11451 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11452 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11453 "ix86_match_ccmode (insn, CCGOCmode)
11454 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11455 "sar{w}\t{%2, %0|%0, %2}"
11456 [(set_attr "type" "ishift")
11457 (set_attr "mode" "HI")])
11458
11459 (define_expand "ashrqi3"
11460 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11461 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11462 (match_operand:QI 2 "nonmemory_operand" "")))
11463 (clobber (reg:CC FLAGS_REG))]
11464 "TARGET_QIMODE_MATH"
11465 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11466
11467 (define_insn "*ashrqi3_1_one_bit"
11468 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11469 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11470 (match_operand:QI 2 "const1_operand" "")))
11471 (clobber (reg:CC FLAGS_REG))]
11472 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11473 && (TARGET_SHIFT1 || optimize_size)"
11474 "sar{b}\t%0"
11475 [(set_attr "type" "ishift")
11476 (set (attr "length")
11477 (if_then_else (match_operand 0 "register_operand" "")
11478 (const_string "2")
11479 (const_string "*")))])
11480
11481 (define_insn "*ashrqi3_1_one_bit_slp"
11482 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11483 (ashiftrt:QI (match_dup 0)
11484 (match_operand:QI 1 "const1_operand" "")))
11485 (clobber (reg:CC FLAGS_REG))]
11486 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11487 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11488 && (TARGET_SHIFT1 || optimize_size)"
11489 "sar{b}\t%0"
11490 [(set_attr "type" "ishift1")
11491 (set (attr "length")
11492 (if_then_else (match_operand 0 "register_operand" "")
11493 (const_string "2")
11494 (const_string "*")))])
11495
11496 (define_insn "*ashrqi3_1"
11497 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11498 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11499 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11500 (clobber (reg:CC FLAGS_REG))]
11501 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11502 "@
11503 sar{b}\t{%2, %0|%0, %2}
11504 sar{b}\t{%b2, %0|%0, %b2}"
11505 [(set_attr "type" "ishift")
11506 (set_attr "mode" "QI")])
11507
11508 (define_insn "*ashrqi3_1_slp"
11509 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11510 (ashiftrt:QI (match_dup 0)
11511 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11512 (clobber (reg:CC FLAGS_REG))]
11513 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11514 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11515 "@
11516 sar{b}\t{%1, %0|%0, %1}
11517 sar{b}\t{%b1, %0|%0, %b1}"
11518 [(set_attr "type" "ishift1")
11519 (set_attr "mode" "QI")])
11520
11521 ;; This pattern can't accept a variable shift count, since shifts by
11522 ;; zero don't affect the flags. We assume that shifts by constant
11523 ;; zero are optimized away.
11524 (define_insn "*ashrqi3_one_bit_cmp"
11525 [(set (reg FLAGS_REG)
11526 (compare
11527 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11528 (match_operand:QI 2 "const1_operand" "I"))
11529 (const_int 0)))
11530 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11531 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11532 "ix86_match_ccmode (insn, CCGOCmode)
11533 && (TARGET_SHIFT1 || optimize_size)
11534 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11535 "sar{b}\t%0"
11536 [(set_attr "type" "ishift")
11537 (set (attr "length")
11538 (if_then_else (match_operand 0 "register_operand" "")
11539 (const_string "2")
11540 (const_string "*")))])
11541
11542 ;; This pattern can't accept a variable shift count, since shifts by
11543 ;; zero don't affect the flags. We assume that shifts by constant
11544 ;; zero are optimized away.
11545 (define_insn "*ashrqi3_cmp"
11546 [(set (reg FLAGS_REG)
11547 (compare
11548 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11549 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11550 (const_int 0)))
11551 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11552 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11553 "ix86_match_ccmode (insn, CCGOCmode)
11554 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11555 "sar{b}\t{%2, %0|%0, %2}"
11556 [(set_attr "type" "ishift")
11557 (set_attr "mode" "QI")])
11558 \f
11559 ;; Logical shift instructions
11560
11561 ;; See comment above `ashldi3' about how this works.
11562
11563 (define_expand "lshrti3"
11564 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11565 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11566 (match_operand:QI 2 "nonmemory_operand" "")))
11567 (clobber (reg:CC FLAGS_REG))])]
11568 "TARGET_64BIT"
11569 {
11570 if (! immediate_operand (operands[2], QImode))
11571 {
11572 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11573 DONE;
11574 }
11575 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11576 DONE;
11577 })
11578
11579 (define_insn "lshrti3_1"
11580 [(set (match_operand:TI 0 "register_operand" "=r")
11581 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11582 (match_operand:QI 2 "register_operand" "c")))
11583 (clobber (match_scratch:DI 3 "=&r"))
11584 (clobber (reg:CC FLAGS_REG))]
11585 "TARGET_64BIT"
11586 "#"
11587 [(set_attr "type" "multi")])
11588
11589 (define_insn "*lshrti3_2"
11590 [(set (match_operand:TI 0 "register_operand" "=r")
11591 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11592 (match_operand:QI 2 "immediate_operand" "O")))
11593 (clobber (reg:CC FLAGS_REG))]
11594 "TARGET_64BIT"
11595 "#"
11596 [(set_attr "type" "multi")])
11597
11598 (define_split
11599 [(set (match_operand:TI 0 "register_operand" "")
11600 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11601 (match_operand:QI 2 "register_operand" "")))
11602 (clobber (match_scratch:DI 3 ""))
11603 (clobber (reg:CC FLAGS_REG))]
11604 "TARGET_64BIT && reload_completed"
11605 [(const_int 0)]
11606 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11607
11608 (define_split
11609 [(set (match_operand:TI 0 "register_operand" "")
11610 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11611 (match_operand:QI 2 "immediate_operand" "")))
11612 (clobber (reg:CC FLAGS_REG))]
11613 "TARGET_64BIT && reload_completed"
11614 [(const_int 0)]
11615 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11616
11617 (define_expand "lshrdi3"
11618 [(set (match_operand:DI 0 "shiftdi_operand" "")
11619 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11620 (match_operand:QI 2 "nonmemory_operand" "")))]
11621 ""
11622 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11623
11624 (define_insn "*lshrdi3_1_one_bit_rex64"
11625 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11626 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11627 (match_operand:QI 2 "const1_operand" "")))
11628 (clobber (reg:CC FLAGS_REG))]
11629 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11630 && (TARGET_SHIFT1 || optimize_size)"
11631 "shr{q}\t%0"
11632 [(set_attr "type" "ishift")
11633 (set (attr "length")
11634 (if_then_else (match_operand:DI 0 "register_operand" "")
11635 (const_string "2")
11636 (const_string "*")))])
11637
11638 (define_insn "*lshrdi3_1_rex64"
11639 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11640 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11641 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11642 (clobber (reg:CC FLAGS_REG))]
11643 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11644 "@
11645 shr{q}\t{%2, %0|%0, %2}
11646 shr{q}\t{%b2, %0|%0, %b2}"
11647 [(set_attr "type" "ishift")
11648 (set_attr "mode" "DI")])
11649
11650 ;; This pattern can't accept a variable shift count, since shifts by
11651 ;; zero don't affect the flags. We assume that shifts by constant
11652 ;; zero are optimized away.
11653 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11654 [(set (reg FLAGS_REG)
11655 (compare
11656 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11657 (match_operand:QI 2 "const1_operand" ""))
11658 (const_int 0)))
11659 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11660 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11661 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11662 && (TARGET_SHIFT1 || optimize_size)
11663 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11664 "shr{q}\t%0"
11665 [(set_attr "type" "ishift")
11666 (set (attr "length")
11667 (if_then_else (match_operand:DI 0 "register_operand" "")
11668 (const_string "2")
11669 (const_string "*")))])
11670
11671 ;; This pattern can't accept a variable shift count, since shifts by
11672 ;; zero don't affect the flags. We assume that shifts by constant
11673 ;; zero are optimized away.
11674 (define_insn "*lshrdi3_cmp_rex64"
11675 [(set (reg FLAGS_REG)
11676 (compare
11677 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11678 (match_operand:QI 2 "const_int_operand" "e"))
11679 (const_int 0)))
11680 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11681 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11682 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11683 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11684 "shr{q}\t{%2, %0|%0, %2}"
11685 [(set_attr "type" "ishift")
11686 (set_attr "mode" "DI")])
11687
11688 (define_insn "*lshrdi3_1"
11689 [(set (match_operand:DI 0 "register_operand" "=r")
11690 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11691 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11692 (clobber (reg:CC FLAGS_REG))]
11693 "!TARGET_64BIT"
11694 "#"
11695 [(set_attr "type" "multi")])
11696
11697 ;; By default we don't ask for a scratch register, because when DImode
11698 ;; values are manipulated, registers are already at a premium. But if
11699 ;; we have one handy, we won't turn it away.
11700 (define_peephole2
11701 [(match_scratch:SI 3 "r")
11702 (parallel [(set (match_operand:DI 0 "register_operand" "")
11703 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11704 (match_operand:QI 2 "nonmemory_operand" "")))
11705 (clobber (reg:CC FLAGS_REG))])
11706 (match_dup 3)]
11707 "!TARGET_64BIT && TARGET_CMOVE"
11708 [(const_int 0)]
11709 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11710
11711 (define_split
11712 [(set (match_operand:DI 0 "register_operand" "")
11713 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11714 (match_operand:QI 2 "nonmemory_operand" "")))
11715 (clobber (reg:CC FLAGS_REG))]
11716 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11717 ? flow2_completed : reload_completed)"
11718 [(const_int 0)]
11719 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11720
11721 (define_expand "lshrsi3"
11722 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11723 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11724 (match_operand:QI 2 "nonmemory_operand" "")))
11725 (clobber (reg:CC FLAGS_REG))]
11726 ""
11727 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11728
11729 (define_insn "*lshrsi3_1_one_bit"
11730 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11731 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11732 (match_operand:QI 2 "const1_operand" "")))
11733 (clobber (reg:CC FLAGS_REG))]
11734 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11735 && (TARGET_SHIFT1 || optimize_size)"
11736 "shr{l}\t%0"
11737 [(set_attr "type" "ishift")
11738 (set (attr "length")
11739 (if_then_else (match_operand:SI 0 "register_operand" "")
11740 (const_string "2")
11741 (const_string "*")))])
11742
11743 (define_insn "*lshrsi3_1_one_bit_zext"
11744 [(set (match_operand:DI 0 "register_operand" "=r")
11745 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11746 (match_operand:QI 2 "const1_operand" "")))
11747 (clobber (reg:CC FLAGS_REG))]
11748 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11749 && (TARGET_SHIFT1 || optimize_size)"
11750 "shr{l}\t%k0"
11751 [(set_attr "type" "ishift")
11752 (set_attr "length" "2")])
11753
11754 (define_insn "*lshrsi3_1"
11755 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11756 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11757 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11758 (clobber (reg:CC FLAGS_REG))]
11759 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11760 "@
11761 shr{l}\t{%2, %0|%0, %2}
11762 shr{l}\t{%b2, %0|%0, %b2}"
11763 [(set_attr "type" "ishift")
11764 (set_attr "mode" "SI")])
11765
11766 (define_insn "*lshrsi3_1_zext"
11767 [(set (match_operand:DI 0 "register_operand" "=r,r")
11768 (zero_extend:DI
11769 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11770 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11771 (clobber (reg:CC FLAGS_REG))]
11772 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11773 "@
11774 shr{l}\t{%2, %k0|%k0, %2}
11775 shr{l}\t{%b2, %k0|%k0, %b2}"
11776 [(set_attr "type" "ishift")
11777 (set_attr "mode" "SI")])
11778
11779 ;; This pattern can't accept a variable shift count, since shifts by
11780 ;; zero don't affect the flags. We assume that shifts by constant
11781 ;; zero are optimized away.
11782 (define_insn "*lshrsi3_one_bit_cmp"
11783 [(set (reg FLAGS_REG)
11784 (compare
11785 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11786 (match_operand:QI 2 "const1_operand" ""))
11787 (const_int 0)))
11788 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11789 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11790 "ix86_match_ccmode (insn, CCGOCmode)
11791 && (TARGET_SHIFT1 || optimize_size)
11792 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11793 "shr{l}\t%0"
11794 [(set_attr "type" "ishift")
11795 (set (attr "length")
11796 (if_then_else (match_operand:SI 0 "register_operand" "")
11797 (const_string "2")
11798 (const_string "*")))])
11799
11800 (define_insn "*lshrsi3_cmp_one_bit_zext"
11801 [(set (reg FLAGS_REG)
11802 (compare
11803 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11804 (match_operand:QI 2 "const1_operand" ""))
11805 (const_int 0)))
11806 (set (match_operand:DI 0 "register_operand" "=r")
11807 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11808 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11809 && (TARGET_SHIFT1 || optimize_size)
11810 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11811 "shr{l}\t%k0"
11812 [(set_attr "type" "ishift")
11813 (set_attr "length" "2")])
11814
11815 ;; This pattern can't accept a variable shift count, since shifts by
11816 ;; zero don't affect the flags. We assume that shifts by constant
11817 ;; zero are optimized away.
11818 (define_insn "*lshrsi3_cmp"
11819 [(set (reg FLAGS_REG)
11820 (compare
11821 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11822 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11823 (const_int 0)))
11824 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11825 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11826 "ix86_match_ccmode (insn, CCGOCmode)
11827 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11828 "shr{l}\t{%2, %0|%0, %2}"
11829 [(set_attr "type" "ishift")
11830 (set_attr "mode" "SI")])
11831
11832 (define_insn "*lshrsi3_cmp_zext"
11833 [(set (reg FLAGS_REG)
11834 (compare
11835 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11836 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11837 (const_int 0)))
11838 (set (match_operand:DI 0 "register_operand" "=r")
11839 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11840 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11841 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11842 "shr{l}\t{%2, %k0|%k0, %2}"
11843 [(set_attr "type" "ishift")
11844 (set_attr "mode" "SI")])
11845
11846 (define_expand "lshrhi3"
11847 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11848 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11849 (match_operand:QI 2 "nonmemory_operand" "")))
11850 (clobber (reg:CC FLAGS_REG))]
11851 "TARGET_HIMODE_MATH"
11852 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11853
11854 (define_insn "*lshrhi3_1_one_bit"
11855 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11856 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11857 (match_operand:QI 2 "const1_operand" "")))
11858 (clobber (reg:CC FLAGS_REG))]
11859 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11860 && (TARGET_SHIFT1 || optimize_size)"
11861 "shr{w}\t%0"
11862 [(set_attr "type" "ishift")
11863 (set (attr "length")
11864 (if_then_else (match_operand 0 "register_operand" "")
11865 (const_string "2")
11866 (const_string "*")))])
11867
11868 (define_insn "*lshrhi3_1"
11869 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11870 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11871 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11872 (clobber (reg:CC FLAGS_REG))]
11873 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11874 "@
11875 shr{w}\t{%2, %0|%0, %2}
11876 shr{w}\t{%b2, %0|%0, %b2}"
11877 [(set_attr "type" "ishift")
11878 (set_attr "mode" "HI")])
11879
11880 ;; This pattern can't accept a variable shift count, since shifts by
11881 ;; zero don't affect the flags. We assume that shifts by constant
11882 ;; zero are optimized away.
11883 (define_insn "*lshrhi3_one_bit_cmp"
11884 [(set (reg FLAGS_REG)
11885 (compare
11886 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11887 (match_operand:QI 2 "const1_operand" ""))
11888 (const_int 0)))
11889 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11890 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11891 "ix86_match_ccmode (insn, CCGOCmode)
11892 && (TARGET_SHIFT1 || optimize_size)
11893 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11894 "shr{w}\t%0"
11895 [(set_attr "type" "ishift")
11896 (set (attr "length")
11897 (if_then_else (match_operand:SI 0 "register_operand" "")
11898 (const_string "2")
11899 (const_string "*")))])
11900
11901 ;; This pattern can't accept a variable shift count, since shifts by
11902 ;; zero don't affect the flags. We assume that shifts by constant
11903 ;; zero are optimized away.
11904 (define_insn "*lshrhi3_cmp"
11905 [(set (reg FLAGS_REG)
11906 (compare
11907 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11908 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11909 (const_int 0)))
11910 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11911 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11912 "ix86_match_ccmode (insn, CCGOCmode)
11913 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11914 "shr{w}\t{%2, %0|%0, %2}"
11915 [(set_attr "type" "ishift")
11916 (set_attr "mode" "HI")])
11917
11918 (define_expand "lshrqi3"
11919 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11920 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11921 (match_operand:QI 2 "nonmemory_operand" "")))
11922 (clobber (reg:CC FLAGS_REG))]
11923 "TARGET_QIMODE_MATH"
11924 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11925
11926 (define_insn "*lshrqi3_1_one_bit"
11927 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11928 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11929 (match_operand:QI 2 "const1_operand" "")))
11930 (clobber (reg:CC FLAGS_REG))]
11931 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11932 && (TARGET_SHIFT1 || optimize_size)"
11933 "shr{b}\t%0"
11934 [(set_attr "type" "ishift")
11935 (set (attr "length")
11936 (if_then_else (match_operand 0 "register_operand" "")
11937 (const_string "2")
11938 (const_string "*")))])
11939
11940 (define_insn "*lshrqi3_1_one_bit_slp"
11941 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11942 (lshiftrt:QI (match_dup 0)
11943 (match_operand:QI 1 "const1_operand" "")))
11944 (clobber (reg:CC FLAGS_REG))]
11945 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11946 && (TARGET_SHIFT1 || optimize_size)"
11947 "shr{b}\t%0"
11948 [(set_attr "type" "ishift1")
11949 (set (attr "length")
11950 (if_then_else (match_operand 0 "register_operand" "")
11951 (const_string "2")
11952 (const_string "*")))])
11953
11954 (define_insn "*lshrqi3_1"
11955 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11956 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11957 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11958 (clobber (reg:CC FLAGS_REG))]
11959 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11960 "@
11961 shr{b}\t{%2, %0|%0, %2}
11962 shr{b}\t{%b2, %0|%0, %b2}"
11963 [(set_attr "type" "ishift")
11964 (set_attr "mode" "QI")])
11965
11966 (define_insn "*lshrqi3_1_slp"
11967 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11968 (lshiftrt:QI (match_dup 0)
11969 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11970 (clobber (reg:CC FLAGS_REG))]
11971 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11972 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11973 "@
11974 shr{b}\t{%1, %0|%0, %1}
11975 shr{b}\t{%b1, %0|%0, %b1}"
11976 [(set_attr "type" "ishift1")
11977 (set_attr "mode" "QI")])
11978
11979 ;; This pattern can't accept a variable shift count, since shifts by
11980 ;; zero don't affect the flags. We assume that shifts by constant
11981 ;; zero are optimized away.
11982 (define_insn "*lshrqi2_one_bit_cmp"
11983 [(set (reg FLAGS_REG)
11984 (compare
11985 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11986 (match_operand:QI 2 "const1_operand" ""))
11987 (const_int 0)))
11988 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11989 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11990 "ix86_match_ccmode (insn, CCGOCmode)
11991 && (TARGET_SHIFT1 || optimize_size)
11992 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11993 "shr{b}\t%0"
11994 [(set_attr "type" "ishift")
11995 (set (attr "length")
11996 (if_then_else (match_operand:SI 0 "register_operand" "")
11997 (const_string "2")
11998 (const_string "*")))])
11999
12000 ;; This pattern can't accept a variable shift count, since shifts by
12001 ;; zero don't affect the flags. We assume that shifts by constant
12002 ;; zero are optimized away.
12003 (define_insn "*lshrqi2_cmp"
12004 [(set (reg FLAGS_REG)
12005 (compare
12006 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12007 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12008 (const_int 0)))
12009 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12010 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12011 "ix86_match_ccmode (insn, CCGOCmode)
12012 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12013 "shr{b}\t{%2, %0|%0, %2}"
12014 [(set_attr "type" "ishift")
12015 (set_attr "mode" "QI")])
12016 \f
12017 ;; Rotate instructions
12018
12019 (define_expand "rotldi3"
12020 [(set (match_operand:DI 0 "shiftdi_operand" "")
12021 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12022 (match_operand:QI 2 "nonmemory_operand" "")))
12023 (clobber (reg:CC FLAGS_REG))]
12024 ""
12025 {
12026 if (TARGET_64BIT)
12027 {
12028 ix86_expand_binary_operator (ROTATE, DImode, operands);
12029 DONE;
12030 }
12031 if (!const_1_to_31_operand (operands[2], VOIDmode))
12032 FAIL;
12033 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12034 DONE;
12035 })
12036
12037 ;; Implement rotation using two double-precision shift instructions
12038 ;; and a scratch register.
12039 (define_insn_and_split "ix86_rotldi3"
12040 [(set (match_operand:DI 0 "register_operand" "=r")
12041 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12042 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12043 (clobber (reg:CC FLAGS_REG))
12044 (clobber (match_scratch:SI 3 "=&r"))]
12045 "!TARGET_64BIT"
12046 ""
12047 "&& reload_completed"
12048 [(set (match_dup 3) (match_dup 4))
12049 (parallel
12050 [(set (match_dup 4)
12051 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12052 (lshiftrt:SI (match_dup 5)
12053 (minus:QI (const_int 32) (match_dup 2)))))
12054 (clobber (reg:CC FLAGS_REG))])
12055 (parallel
12056 [(set (match_dup 5)
12057 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12058 (lshiftrt:SI (match_dup 3)
12059 (minus:QI (const_int 32) (match_dup 2)))))
12060 (clobber (reg:CC FLAGS_REG))])]
12061 "split_di (operands, 1, operands + 4, operands + 5);")
12062
12063 (define_insn "*rotlsi3_1_one_bit_rex64"
12064 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12065 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12066 (match_operand:QI 2 "const1_operand" "")))
12067 (clobber (reg:CC FLAGS_REG))]
12068 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12069 && (TARGET_SHIFT1 || optimize_size)"
12070 "rol{q}\t%0"
12071 [(set_attr "type" "rotate")
12072 (set (attr "length")
12073 (if_then_else (match_operand:DI 0 "register_operand" "")
12074 (const_string "2")
12075 (const_string "*")))])
12076
12077 (define_insn "*rotldi3_1_rex64"
12078 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12079 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12080 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12081 (clobber (reg:CC FLAGS_REG))]
12082 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12083 "@
12084 rol{q}\t{%2, %0|%0, %2}
12085 rol{q}\t{%b2, %0|%0, %b2}"
12086 [(set_attr "type" "rotate")
12087 (set_attr "mode" "DI")])
12088
12089 (define_expand "rotlsi3"
12090 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12091 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12092 (match_operand:QI 2 "nonmemory_operand" "")))
12093 (clobber (reg:CC FLAGS_REG))]
12094 ""
12095 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12096
12097 (define_insn "*rotlsi3_1_one_bit"
12098 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12099 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12100 (match_operand:QI 2 "const1_operand" "")))
12101 (clobber (reg:CC FLAGS_REG))]
12102 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12103 && (TARGET_SHIFT1 || optimize_size)"
12104 "rol{l}\t%0"
12105 [(set_attr "type" "rotate")
12106 (set (attr "length")
12107 (if_then_else (match_operand:SI 0 "register_operand" "")
12108 (const_string "2")
12109 (const_string "*")))])
12110
12111 (define_insn "*rotlsi3_1_one_bit_zext"
12112 [(set (match_operand:DI 0 "register_operand" "=r")
12113 (zero_extend:DI
12114 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12115 (match_operand:QI 2 "const1_operand" ""))))
12116 (clobber (reg:CC FLAGS_REG))]
12117 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12118 && (TARGET_SHIFT1 || optimize_size)"
12119 "rol{l}\t%k0"
12120 [(set_attr "type" "rotate")
12121 (set_attr "length" "2")])
12122
12123 (define_insn "*rotlsi3_1"
12124 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12125 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12126 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12127 (clobber (reg:CC FLAGS_REG))]
12128 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12129 "@
12130 rol{l}\t{%2, %0|%0, %2}
12131 rol{l}\t{%b2, %0|%0, %b2}"
12132 [(set_attr "type" "rotate")
12133 (set_attr "mode" "SI")])
12134
12135 (define_insn "*rotlsi3_1_zext"
12136 [(set (match_operand:DI 0 "register_operand" "=r,r")
12137 (zero_extend:DI
12138 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12139 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12140 (clobber (reg:CC FLAGS_REG))]
12141 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12142 "@
12143 rol{l}\t{%2, %k0|%k0, %2}
12144 rol{l}\t{%b2, %k0|%k0, %b2}"
12145 [(set_attr "type" "rotate")
12146 (set_attr "mode" "SI")])
12147
12148 (define_expand "rotlhi3"
12149 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12150 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12151 (match_operand:QI 2 "nonmemory_operand" "")))
12152 (clobber (reg:CC FLAGS_REG))]
12153 "TARGET_HIMODE_MATH"
12154 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12155
12156 (define_insn "*rotlhi3_1_one_bit"
12157 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12158 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12159 (match_operand:QI 2 "const1_operand" "")))
12160 (clobber (reg:CC FLAGS_REG))]
12161 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12162 && (TARGET_SHIFT1 || optimize_size)"
12163 "rol{w}\t%0"
12164 [(set_attr "type" "rotate")
12165 (set (attr "length")
12166 (if_then_else (match_operand 0 "register_operand" "")
12167 (const_string "2")
12168 (const_string "*")))])
12169
12170 (define_insn "*rotlhi3_1"
12171 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12172 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12173 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12174 (clobber (reg:CC FLAGS_REG))]
12175 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12176 "@
12177 rol{w}\t{%2, %0|%0, %2}
12178 rol{w}\t{%b2, %0|%0, %b2}"
12179 [(set_attr "type" "rotate")
12180 (set_attr "mode" "HI")])
12181
12182 (define_expand "rotlqi3"
12183 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12184 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12185 (match_operand:QI 2 "nonmemory_operand" "")))
12186 (clobber (reg:CC FLAGS_REG))]
12187 "TARGET_QIMODE_MATH"
12188 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12189
12190 (define_insn "*rotlqi3_1_one_bit_slp"
12191 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12192 (rotate:QI (match_dup 0)
12193 (match_operand:QI 1 "const1_operand" "")))
12194 (clobber (reg:CC FLAGS_REG))]
12195 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12196 && (TARGET_SHIFT1 || optimize_size)"
12197 "rol{b}\t%0"
12198 [(set_attr "type" "rotate1")
12199 (set (attr "length")
12200 (if_then_else (match_operand 0 "register_operand" "")
12201 (const_string "2")
12202 (const_string "*")))])
12203
12204 (define_insn "*rotlqi3_1_one_bit"
12205 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12206 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12207 (match_operand:QI 2 "const1_operand" "")))
12208 (clobber (reg:CC FLAGS_REG))]
12209 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12210 && (TARGET_SHIFT1 || optimize_size)"
12211 "rol{b}\t%0"
12212 [(set_attr "type" "rotate")
12213 (set (attr "length")
12214 (if_then_else (match_operand 0 "register_operand" "")
12215 (const_string "2")
12216 (const_string "*")))])
12217
12218 (define_insn "*rotlqi3_1_slp"
12219 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12220 (rotate:QI (match_dup 0)
12221 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12222 (clobber (reg:CC FLAGS_REG))]
12223 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12224 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12225 "@
12226 rol{b}\t{%1, %0|%0, %1}
12227 rol{b}\t{%b1, %0|%0, %b1}"
12228 [(set_attr "type" "rotate1")
12229 (set_attr "mode" "QI")])
12230
12231 (define_insn "*rotlqi3_1"
12232 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12233 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12234 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12235 (clobber (reg:CC FLAGS_REG))]
12236 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12237 "@
12238 rol{b}\t{%2, %0|%0, %2}
12239 rol{b}\t{%b2, %0|%0, %b2}"
12240 [(set_attr "type" "rotate")
12241 (set_attr "mode" "QI")])
12242
12243 (define_expand "rotrdi3"
12244 [(set (match_operand:DI 0 "shiftdi_operand" "")
12245 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12246 (match_operand:QI 2 "nonmemory_operand" "")))
12247 (clobber (reg:CC FLAGS_REG))]
12248 ""
12249 {
12250 if (TARGET_64BIT)
12251 {
12252 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12253 DONE;
12254 }
12255 if (!const_1_to_31_operand (operands[2], VOIDmode))
12256 FAIL;
12257 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12258 DONE;
12259 })
12260
12261 ;; Implement rotation using two double-precision shift instructions
12262 ;; and a scratch register.
12263 (define_insn_and_split "ix86_rotrdi3"
12264 [(set (match_operand:DI 0 "register_operand" "=r")
12265 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12266 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12267 (clobber (reg:CC FLAGS_REG))
12268 (clobber (match_scratch:SI 3 "=&r"))]
12269 "!TARGET_64BIT"
12270 ""
12271 "&& reload_completed"
12272 [(set (match_dup 3) (match_dup 4))
12273 (parallel
12274 [(set (match_dup 4)
12275 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12276 (ashift:SI (match_dup 5)
12277 (minus:QI (const_int 32) (match_dup 2)))))
12278 (clobber (reg:CC FLAGS_REG))])
12279 (parallel
12280 [(set (match_dup 5)
12281 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12282 (ashift:SI (match_dup 3)
12283 (minus:QI (const_int 32) (match_dup 2)))))
12284 (clobber (reg:CC FLAGS_REG))])]
12285 "split_di (operands, 1, operands + 4, operands + 5);")
12286
12287 (define_insn "*rotrdi3_1_one_bit_rex64"
12288 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12289 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12290 (match_operand:QI 2 "const1_operand" "")))
12291 (clobber (reg:CC FLAGS_REG))]
12292 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12293 && (TARGET_SHIFT1 || optimize_size)"
12294 "ror{q}\t%0"
12295 [(set_attr "type" "rotate")
12296 (set (attr "length")
12297 (if_then_else (match_operand:DI 0 "register_operand" "")
12298 (const_string "2")
12299 (const_string "*")))])
12300
12301 (define_insn "*rotrdi3_1_rex64"
12302 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12303 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12304 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12305 (clobber (reg:CC FLAGS_REG))]
12306 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12307 "@
12308 ror{q}\t{%2, %0|%0, %2}
12309 ror{q}\t{%b2, %0|%0, %b2}"
12310 [(set_attr "type" "rotate")
12311 (set_attr "mode" "DI")])
12312
12313 (define_expand "rotrsi3"
12314 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12315 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12316 (match_operand:QI 2 "nonmemory_operand" "")))
12317 (clobber (reg:CC FLAGS_REG))]
12318 ""
12319 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12320
12321 (define_insn "*rotrsi3_1_one_bit"
12322 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12323 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12324 (match_operand:QI 2 "const1_operand" "")))
12325 (clobber (reg:CC FLAGS_REG))]
12326 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12327 && (TARGET_SHIFT1 || optimize_size)"
12328 "ror{l}\t%0"
12329 [(set_attr "type" "rotate")
12330 (set (attr "length")
12331 (if_then_else (match_operand:SI 0 "register_operand" "")
12332 (const_string "2")
12333 (const_string "*")))])
12334
12335 (define_insn "*rotrsi3_1_one_bit_zext"
12336 [(set (match_operand:DI 0 "register_operand" "=r")
12337 (zero_extend:DI
12338 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12339 (match_operand:QI 2 "const1_operand" ""))))
12340 (clobber (reg:CC FLAGS_REG))]
12341 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12342 && (TARGET_SHIFT1 || optimize_size)"
12343 "ror{l}\t%k0"
12344 [(set_attr "type" "rotate")
12345 (set (attr "length")
12346 (if_then_else (match_operand:SI 0 "register_operand" "")
12347 (const_string "2")
12348 (const_string "*")))])
12349
12350 (define_insn "*rotrsi3_1"
12351 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12352 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12353 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12354 (clobber (reg:CC FLAGS_REG))]
12355 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12356 "@
12357 ror{l}\t{%2, %0|%0, %2}
12358 ror{l}\t{%b2, %0|%0, %b2}"
12359 [(set_attr "type" "rotate")
12360 (set_attr "mode" "SI")])
12361
12362 (define_insn "*rotrsi3_1_zext"
12363 [(set (match_operand:DI 0 "register_operand" "=r,r")
12364 (zero_extend:DI
12365 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12366 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12367 (clobber (reg:CC FLAGS_REG))]
12368 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12369 "@
12370 ror{l}\t{%2, %k0|%k0, %2}
12371 ror{l}\t{%b2, %k0|%k0, %b2}"
12372 [(set_attr "type" "rotate")
12373 (set_attr "mode" "SI")])
12374
12375 (define_expand "rotrhi3"
12376 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12377 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12378 (match_operand:QI 2 "nonmemory_operand" "")))
12379 (clobber (reg:CC FLAGS_REG))]
12380 "TARGET_HIMODE_MATH"
12381 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12382
12383 (define_insn "*rotrhi3_one_bit"
12384 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12385 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12386 (match_operand:QI 2 "const1_operand" "")))
12387 (clobber (reg:CC FLAGS_REG))]
12388 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12389 && (TARGET_SHIFT1 || optimize_size)"
12390 "ror{w}\t%0"
12391 [(set_attr "type" "rotate")
12392 (set (attr "length")
12393 (if_then_else (match_operand 0 "register_operand" "")
12394 (const_string "2")
12395 (const_string "*")))])
12396
12397 (define_insn "*rotrhi3"
12398 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12399 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12400 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12401 (clobber (reg:CC FLAGS_REG))]
12402 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12403 "@
12404 ror{w}\t{%2, %0|%0, %2}
12405 ror{w}\t{%b2, %0|%0, %b2}"
12406 [(set_attr "type" "rotate")
12407 (set_attr "mode" "HI")])
12408
12409 (define_expand "rotrqi3"
12410 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12411 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12412 (match_operand:QI 2 "nonmemory_operand" "")))
12413 (clobber (reg:CC FLAGS_REG))]
12414 "TARGET_QIMODE_MATH"
12415 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12416
12417 (define_insn "*rotrqi3_1_one_bit"
12418 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12419 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12420 (match_operand:QI 2 "const1_operand" "")))
12421 (clobber (reg:CC FLAGS_REG))]
12422 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12423 && (TARGET_SHIFT1 || optimize_size)"
12424 "ror{b}\t%0"
12425 [(set_attr "type" "rotate")
12426 (set (attr "length")
12427 (if_then_else (match_operand 0 "register_operand" "")
12428 (const_string "2")
12429 (const_string "*")))])
12430
12431 (define_insn "*rotrqi3_1_one_bit_slp"
12432 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12433 (rotatert:QI (match_dup 0)
12434 (match_operand:QI 1 "const1_operand" "")))
12435 (clobber (reg:CC FLAGS_REG))]
12436 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12437 && (TARGET_SHIFT1 || optimize_size)"
12438 "ror{b}\t%0"
12439 [(set_attr "type" "rotate1")
12440 (set (attr "length")
12441 (if_then_else (match_operand 0 "register_operand" "")
12442 (const_string "2")
12443 (const_string "*")))])
12444
12445 (define_insn "*rotrqi3_1"
12446 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12447 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12448 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12449 (clobber (reg:CC FLAGS_REG))]
12450 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12451 "@
12452 ror{b}\t{%2, %0|%0, %2}
12453 ror{b}\t{%b2, %0|%0, %b2}"
12454 [(set_attr "type" "rotate")
12455 (set_attr "mode" "QI")])
12456
12457 (define_insn "*rotrqi3_1_slp"
12458 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12459 (rotatert:QI (match_dup 0)
12460 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12461 (clobber (reg:CC FLAGS_REG))]
12462 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12463 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12464 "@
12465 ror{b}\t{%1, %0|%0, %1}
12466 ror{b}\t{%b1, %0|%0, %b1}"
12467 [(set_attr "type" "rotate1")
12468 (set_attr "mode" "QI")])
12469 \f
12470 ;; Bit set / bit test instructions
12471
12472 (define_expand "extv"
12473 [(set (match_operand:SI 0 "register_operand" "")
12474 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12475 (match_operand:SI 2 "immediate_operand" "")
12476 (match_operand:SI 3 "immediate_operand" "")))]
12477 ""
12478 {
12479 /* Handle extractions from %ah et al. */
12480 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12481 FAIL;
12482
12483 /* From mips.md: extract_bit_field doesn't verify that our source
12484 matches the predicate, so check it again here. */
12485 if (! ext_register_operand (operands[1], VOIDmode))
12486 FAIL;
12487 })
12488
12489 (define_expand "extzv"
12490 [(set (match_operand:SI 0 "register_operand" "")
12491 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12492 (match_operand:SI 2 "immediate_operand" "")
12493 (match_operand:SI 3 "immediate_operand" "")))]
12494 ""
12495 {
12496 /* Handle extractions from %ah et al. */
12497 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12498 FAIL;
12499
12500 /* From mips.md: extract_bit_field doesn't verify that our source
12501 matches the predicate, so check it again here. */
12502 if (! ext_register_operand (operands[1], VOIDmode))
12503 FAIL;
12504 })
12505
12506 (define_expand "insv"
12507 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12508 (match_operand 1 "immediate_operand" "")
12509 (match_operand 2 "immediate_operand" ""))
12510 (match_operand 3 "register_operand" ""))]
12511 ""
12512 {
12513 /* Handle extractions from %ah et al. */
12514 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12515 FAIL;
12516
12517 /* From mips.md: insert_bit_field doesn't verify that our source
12518 matches the predicate, so check it again here. */
12519 if (! ext_register_operand (operands[0], VOIDmode))
12520 FAIL;
12521
12522 if (TARGET_64BIT)
12523 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12524 else
12525 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12526
12527 DONE;
12528 })
12529
12530 ;; %%% bts, btr, btc, bt.
12531 ;; In general these instructions are *slow* when applied to memory,
12532 ;; since they enforce atomic operation. When applied to registers,
12533 ;; it depends on the cpu implementation. They're never faster than
12534 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12535 ;; no point. But in 64-bit, we can't hold the relevant immediates
12536 ;; within the instruction itself, so operating on bits in the high
12537 ;; 32-bits of a register becomes easier.
12538 ;;
12539 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12540 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12541 ;; negdf respectively, so they can never be disabled entirely.
12542
12543 (define_insn "*btsq"
12544 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12545 (const_int 1)
12546 (match_operand:DI 1 "const_0_to_63_operand" ""))
12547 (const_int 1))
12548 (clobber (reg:CC FLAGS_REG))]
12549 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12550 "bts{q} %1,%0"
12551 [(set_attr "type" "alu1")])
12552
12553 (define_insn "*btrq"
12554 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12555 (const_int 1)
12556 (match_operand:DI 1 "const_0_to_63_operand" ""))
12557 (const_int 0))
12558 (clobber (reg:CC FLAGS_REG))]
12559 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12560 "btr{q} %1,%0"
12561 [(set_attr "type" "alu1")])
12562
12563 (define_insn "*btcq"
12564 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12565 (const_int 1)
12566 (match_operand:DI 1 "const_0_to_63_operand" ""))
12567 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12568 (clobber (reg:CC FLAGS_REG))]
12569 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12570 "btc{q} %1,%0"
12571 [(set_attr "type" "alu1")])
12572
12573 ;; Allow Nocona to avoid these instructions if a register is available.
12574
12575 (define_peephole2
12576 [(match_scratch:DI 2 "r")
12577 (parallel [(set (zero_extract:DI
12578 (match_operand:DI 0 "register_operand" "")
12579 (const_int 1)
12580 (match_operand:DI 1 "const_0_to_63_operand" ""))
12581 (const_int 1))
12582 (clobber (reg:CC FLAGS_REG))])]
12583 "TARGET_64BIT && !TARGET_USE_BT"
12584 [(const_int 0)]
12585 {
12586 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12587 rtx op1;
12588
12589 if (HOST_BITS_PER_WIDE_INT >= 64)
12590 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12591 else if (i < HOST_BITS_PER_WIDE_INT)
12592 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12593 else
12594 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12595
12596 op1 = immed_double_const (lo, hi, DImode);
12597 if (i >= 31)
12598 {
12599 emit_move_insn (operands[2], op1);
12600 op1 = operands[2];
12601 }
12602
12603 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12604 DONE;
12605 })
12606
12607 (define_peephole2
12608 [(match_scratch:DI 2 "r")
12609 (parallel [(set (zero_extract:DI
12610 (match_operand:DI 0 "register_operand" "")
12611 (const_int 1)
12612 (match_operand:DI 1 "const_0_to_63_operand" ""))
12613 (const_int 0))
12614 (clobber (reg:CC FLAGS_REG))])]
12615 "TARGET_64BIT && !TARGET_USE_BT"
12616 [(const_int 0)]
12617 {
12618 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12619 rtx op1;
12620
12621 if (HOST_BITS_PER_WIDE_INT >= 64)
12622 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12623 else if (i < HOST_BITS_PER_WIDE_INT)
12624 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12625 else
12626 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12627
12628 op1 = immed_double_const (~lo, ~hi, DImode);
12629 if (i >= 32)
12630 {
12631 emit_move_insn (operands[2], op1);
12632 op1 = operands[2];
12633 }
12634
12635 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12636 DONE;
12637 })
12638
12639 (define_peephole2
12640 [(match_scratch:DI 2 "r")
12641 (parallel [(set (zero_extract:DI
12642 (match_operand:DI 0 "register_operand" "")
12643 (const_int 1)
12644 (match_operand:DI 1 "const_0_to_63_operand" ""))
12645 (not:DI (zero_extract:DI
12646 (match_dup 0) (const_int 1) (match_dup 1))))
12647 (clobber (reg:CC FLAGS_REG))])]
12648 "TARGET_64BIT && !TARGET_USE_BT"
12649 [(const_int 0)]
12650 {
12651 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12652 rtx op1;
12653
12654 if (HOST_BITS_PER_WIDE_INT >= 64)
12655 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12656 else if (i < HOST_BITS_PER_WIDE_INT)
12657 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12658 else
12659 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12660
12661 op1 = immed_double_const (lo, hi, DImode);
12662 if (i >= 31)
12663 {
12664 emit_move_insn (operands[2], op1);
12665 op1 = operands[2];
12666 }
12667
12668 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12669 DONE;
12670 })
12671 \f
12672 ;; Store-flag instructions.
12673
12674 ;; For all sCOND expanders, also expand the compare or test insn that
12675 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12676
12677 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12678 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12679 ;; way, which can later delete the movzx if only QImode is needed.
12680
12681 (define_expand "seq"
12682 [(set (match_operand:QI 0 "register_operand" "")
12683 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12684 ""
12685 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12686
12687 (define_expand "sne"
12688 [(set (match_operand:QI 0 "register_operand" "")
12689 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12690 ""
12691 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12692
12693 (define_expand "sgt"
12694 [(set (match_operand:QI 0 "register_operand" "")
12695 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12696 ""
12697 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12698
12699 (define_expand "sgtu"
12700 [(set (match_operand:QI 0 "register_operand" "")
12701 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12702 ""
12703 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12704
12705 (define_expand "slt"
12706 [(set (match_operand:QI 0 "register_operand" "")
12707 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12708 ""
12709 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12710
12711 (define_expand "sltu"
12712 [(set (match_operand:QI 0 "register_operand" "")
12713 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12714 ""
12715 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12716
12717 (define_expand "sge"
12718 [(set (match_operand:QI 0 "register_operand" "")
12719 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12720 ""
12721 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12722
12723 (define_expand "sgeu"
12724 [(set (match_operand:QI 0 "register_operand" "")
12725 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12726 ""
12727 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12728
12729 (define_expand "sle"
12730 [(set (match_operand:QI 0 "register_operand" "")
12731 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12732 ""
12733 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12734
12735 (define_expand "sleu"
12736 [(set (match_operand:QI 0 "register_operand" "")
12737 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12738 ""
12739 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12740
12741 (define_expand "sunordered"
12742 [(set (match_operand:QI 0 "register_operand" "")
12743 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12744 "TARGET_80387 || TARGET_SSE"
12745 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12746
12747 (define_expand "sordered"
12748 [(set (match_operand:QI 0 "register_operand" "")
12749 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12750 "TARGET_80387"
12751 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12752
12753 (define_expand "suneq"
12754 [(set (match_operand:QI 0 "register_operand" "")
12755 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756 "TARGET_80387 || TARGET_SSE"
12757 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12758
12759 (define_expand "sunge"
12760 [(set (match_operand:QI 0 "register_operand" "")
12761 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762 "TARGET_80387 || TARGET_SSE"
12763 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12764
12765 (define_expand "sungt"
12766 [(set (match_operand:QI 0 "register_operand" "")
12767 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12768 "TARGET_80387 || TARGET_SSE"
12769 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12770
12771 (define_expand "sunle"
12772 [(set (match_operand:QI 0 "register_operand" "")
12773 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12774 "TARGET_80387 || TARGET_SSE"
12775 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12776
12777 (define_expand "sunlt"
12778 [(set (match_operand:QI 0 "register_operand" "")
12779 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12780 "TARGET_80387 || TARGET_SSE"
12781 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12782
12783 (define_expand "sltgt"
12784 [(set (match_operand:QI 0 "register_operand" "")
12785 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12786 "TARGET_80387 || TARGET_SSE"
12787 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12788
12789 (define_insn "*setcc_1"
12790 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12791 (match_operator:QI 1 "ix86_comparison_operator"
12792 [(reg FLAGS_REG) (const_int 0)]))]
12793 ""
12794 "set%C1\t%0"
12795 [(set_attr "type" "setcc")
12796 (set_attr "mode" "QI")])
12797
12798 (define_insn "*setcc_2"
12799 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12800 (match_operator:QI 1 "ix86_comparison_operator"
12801 [(reg FLAGS_REG) (const_int 0)]))]
12802 ""
12803 "set%C1\t%0"
12804 [(set_attr "type" "setcc")
12805 (set_attr "mode" "QI")])
12806
12807 ;; In general it is not safe to assume too much about CCmode registers,
12808 ;; so simplify-rtx stops when it sees a second one. Under certain
12809 ;; conditions this is safe on x86, so help combine not create
12810 ;;
12811 ;; seta %al
12812 ;; testb %al, %al
12813 ;; sete %al
12814
12815 (define_split
12816 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12817 (ne:QI (match_operator 1 "ix86_comparison_operator"
12818 [(reg FLAGS_REG) (const_int 0)])
12819 (const_int 0)))]
12820 ""
12821 [(set (match_dup 0) (match_dup 1))]
12822 {
12823 PUT_MODE (operands[1], QImode);
12824 })
12825
12826 (define_split
12827 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12828 (ne:QI (match_operator 1 "ix86_comparison_operator"
12829 [(reg FLAGS_REG) (const_int 0)])
12830 (const_int 0)))]
12831 ""
12832 [(set (match_dup 0) (match_dup 1))]
12833 {
12834 PUT_MODE (operands[1], QImode);
12835 })
12836
12837 (define_split
12838 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12839 (eq:QI (match_operator 1 "ix86_comparison_operator"
12840 [(reg FLAGS_REG) (const_int 0)])
12841 (const_int 0)))]
12842 ""
12843 [(set (match_dup 0) (match_dup 1))]
12844 {
12845 rtx new_op1 = copy_rtx (operands[1]);
12846 operands[1] = new_op1;
12847 PUT_MODE (new_op1, QImode);
12848 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12849 GET_MODE (XEXP (new_op1, 0))));
12850
12851 /* Make sure that (a) the CCmode we have for the flags is strong
12852 enough for the reversed compare or (b) we have a valid FP compare. */
12853 if (! ix86_comparison_operator (new_op1, VOIDmode))
12854 FAIL;
12855 })
12856
12857 (define_split
12858 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12859 (eq:QI (match_operator 1 "ix86_comparison_operator"
12860 [(reg FLAGS_REG) (const_int 0)])
12861 (const_int 0)))]
12862 ""
12863 [(set (match_dup 0) (match_dup 1))]
12864 {
12865 rtx new_op1 = copy_rtx (operands[1]);
12866 operands[1] = new_op1;
12867 PUT_MODE (new_op1, QImode);
12868 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12869 GET_MODE (XEXP (new_op1, 0))));
12870
12871 /* Make sure that (a) the CCmode we have for the flags is strong
12872 enough for the reversed compare or (b) we have a valid FP compare. */
12873 if (! ix86_comparison_operator (new_op1, VOIDmode))
12874 FAIL;
12875 })
12876
12877 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12878 ;; subsequent logical operations are used to imitate conditional moves.
12879 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12880 ;; it directly.
12881
12882 (define_insn "*sse_setccsf"
12883 [(set (match_operand:SF 0 "register_operand" "=x")
12884 (match_operator:SF 1 "sse_comparison_operator"
12885 [(match_operand:SF 2 "register_operand" "0")
12886 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12887 "TARGET_SSE"
12888 "cmp%D1ss\t{%3, %0|%0, %3}"
12889 [(set_attr "type" "ssecmp")
12890 (set_attr "mode" "SF")])
12891
12892 (define_insn "*sse_setccdf"
12893 [(set (match_operand:DF 0 "register_operand" "=Y")
12894 (match_operator:DF 1 "sse_comparison_operator"
12895 [(match_operand:DF 2 "register_operand" "0")
12896 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12897 "TARGET_SSE2"
12898 "cmp%D1sd\t{%3, %0|%0, %3}"
12899 [(set_attr "type" "ssecmp")
12900 (set_attr "mode" "DF")])
12901 \f
12902 ;; Basic conditional jump instructions.
12903 ;; We ignore the overflow flag for signed branch instructions.
12904
12905 ;; For all bCOND expanders, also expand the compare or test insn that
12906 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12907
12908 (define_expand "beq"
12909 [(set (pc)
12910 (if_then_else (match_dup 1)
12911 (label_ref (match_operand 0 "" ""))
12912 (pc)))]
12913 ""
12914 "ix86_expand_branch (EQ, operands[0]); DONE;")
12915
12916 (define_expand "bne"
12917 [(set (pc)
12918 (if_then_else (match_dup 1)
12919 (label_ref (match_operand 0 "" ""))
12920 (pc)))]
12921 ""
12922 "ix86_expand_branch (NE, operands[0]); DONE;")
12923
12924 (define_expand "bgt"
12925 [(set (pc)
12926 (if_then_else (match_dup 1)
12927 (label_ref (match_operand 0 "" ""))
12928 (pc)))]
12929 ""
12930 "ix86_expand_branch (GT, operands[0]); DONE;")
12931
12932 (define_expand "bgtu"
12933 [(set (pc)
12934 (if_then_else (match_dup 1)
12935 (label_ref (match_operand 0 "" ""))
12936 (pc)))]
12937 ""
12938 "ix86_expand_branch (GTU, operands[0]); DONE;")
12939
12940 (define_expand "blt"
12941 [(set (pc)
12942 (if_then_else (match_dup 1)
12943 (label_ref (match_operand 0 "" ""))
12944 (pc)))]
12945 ""
12946 "ix86_expand_branch (LT, operands[0]); DONE;")
12947
12948 (define_expand "bltu"
12949 [(set (pc)
12950 (if_then_else (match_dup 1)
12951 (label_ref (match_operand 0 "" ""))
12952 (pc)))]
12953 ""
12954 "ix86_expand_branch (LTU, operands[0]); DONE;")
12955
12956 (define_expand "bge"
12957 [(set (pc)
12958 (if_then_else (match_dup 1)
12959 (label_ref (match_operand 0 "" ""))
12960 (pc)))]
12961 ""
12962 "ix86_expand_branch (GE, operands[0]); DONE;")
12963
12964 (define_expand "bgeu"
12965 [(set (pc)
12966 (if_then_else (match_dup 1)
12967 (label_ref (match_operand 0 "" ""))
12968 (pc)))]
12969 ""
12970 "ix86_expand_branch (GEU, operands[0]); DONE;")
12971
12972 (define_expand "ble"
12973 [(set (pc)
12974 (if_then_else (match_dup 1)
12975 (label_ref (match_operand 0 "" ""))
12976 (pc)))]
12977 ""
12978 "ix86_expand_branch (LE, operands[0]); DONE;")
12979
12980 (define_expand "bleu"
12981 [(set (pc)
12982 (if_then_else (match_dup 1)
12983 (label_ref (match_operand 0 "" ""))
12984 (pc)))]
12985 ""
12986 "ix86_expand_branch (LEU, operands[0]); DONE;")
12987
12988 (define_expand "bunordered"
12989 [(set (pc)
12990 (if_then_else (match_dup 1)
12991 (label_ref (match_operand 0 "" ""))
12992 (pc)))]
12993 "TARGET_80387 || TARGET_SSE_MATH"
12994 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12995
12996 (define_expand "bordered"
12997 [(set (pc)
12998 (if_then_else (match_dup 1)
12999 (label_ref (match_operand 0 "" ""))
13000 (pc)))]
13001 "TARGET_80387 || TARGET_SSE_MATH"
13002 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13003
13004 (define_expand "buneq"
13005 [(set (pc)
13006 (if_then_else (match_dup 1)
13007 (label_ref (match_operand 0 "" ""))
13008 (pc)))]
13009 "TARGET_80387 || TARGET_SSE_MATH"
13010 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13011
13012 (define_expand "bunge"
13013 [(set (pc)
13014 (if_then_else (match_dup 1)
13015 (label_ref (match_operand 0 "" ""))
13016 (pc)))]
13017 "TARGET_80387 || TARGET_SSE_MATH"
13018 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13019
13020 (define_expand "bungt"
13021 [(set (pc)
13022 (if_then_else (match_dup 1)
13023 (label_ref (match_operand 0 "" ""))
13024 (pc)))]
13025 "TARGET_80387 || TARGET_SSE_MATH"
13026 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13027
13028 (define_expand "bunle"
13029 [(set (pc)
13030 (if_then_else (match_dup 1)
13031 (label_ref (match_operand 0 "" ""))
13032 (pc)))]
13033 "TARGET_80387 || TARGET_SSE_MATH"
13034 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13035
13036 (define_expand "bunlt"
13037 [(set (pc)
13038 (if_then_else (match_dup 1)
13039 (label_ref (match_operand 0 "" ""))
13040 (pc)))]
13041 "TARGET_80387 || TARGET_SSE_MATH"
13042 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13043
13044 (define_expand "bltgt"
13045 [(set (pc)
13046 (if_then_else (match_dup 1)
13047 (label_ref (match_operand 0 "" ""))
13048 (pc)))]
13049 "TARGET_80387 || TARGET_SSE_MATH"
13050 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13051
13052 (define_insn "*jcc_1"
13053 [(set (pc)
13054 (if_then_else (match_operator 1 "ix86_comparison_operator"
13055 [(reg FLAGS_REG) (const_int 0)])
13056 (label_ref (match_operand 0 "" ""))
13057 (pc)))]
13058 ""
13059 "%+j%C1\t%l0"
13060 [(set_attr "type" "ibr")
13061 (set_attr "modrm" "0")
13062 (set (attr "length")
13063 (if_then_else (and (ge (minus (match_dup 0) (pc))
13064 (const_int -126))
13065 (lt (minus (match_dup 0) (pc))
13066 (const_int 128)))
13067 (const_int 2)
13068 (const_int 6)))])
13069
13070 (define_insn "*jcc_2"
13071 [(set (pc)
13072 (if_then_else (match_operator 1 "ix86_comparison_operator"
13073 [(reg FLAGS_REG) (const_int 0)])
13074 (pc)
13075 (label_ref (match_operand 0 "" ""))))]
13076 ""
13077 "%+j%c1\t%l0"
13078 [(set_attr "type" "ibr")
13079 (set_attr "modrm" "0")
13080 (set (attr "length")
13081 (if_then_else (and (ge (minus (match_dup 0) (pc))
13082 (const_int -126))
13083 (lt (minus (match_dup 0) (pc))
13084 (const_int 128)))
13085 (const_int 2)
13086 (const_int 6)))])
13087
13088 ;; In general it is not safe to assume too much about CCmode registers,
13089 ;; so simplify-rtx stops when it sees a second one. Under certain
13090 ;; conditions this is safe on x86, so help combine not create
13091 ;;
13092 ;; seta %al
13093 ;; testb %al, %al
13094 ;; je Lfoo
13095
13096 (define_split
13097 [(set (pc)
13098 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13099 [(reg FLAGS_REG) (const_int 0)])
13100 (const_int 0))
13101 (label_ref (match_operand 1 "" ""))
13102 (pc)))]
13103 ""
13104 [(set (pc)
13105 (if_then_else (match_dup 0)
13106 (label_ref (match_dup 1))
13107 (pc)))]
13108 {
13109 PUT_MODE (operands[0], VOIDmode);
13110 })
13111
13112 (define_split
13113 [(set (pc)
13114 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13115 [(reg FLAGS_REG) (const_int 0)])
13116 (const_int 0))
13117 (label_ref (match_operand 1 "" ""))
13118 (pc)))]
13119 ""
13120 [(set (pc)
13121 (if_then_else (match_dup 0)
13122 (label_ref (match_dup 1))
13123 (pc)))]
13124 {
13125 rtx new_op0 = copy_rtx (operands[0]);
13126 operands[0] = new_op0;
13127 PUT_MODE (new_op0, VOIDmode);
13128 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13129 GET_MODE (XEXP (new_op0, 0))));
13130
13131 /* Make sure that (a) the CCmode we have for the flags is strong
13132 enough for the reversed compare or (b) we have a valid FP compare. */
13133 if (! ix86_comparison_operator (new_op0, VOIDmode))
13134 FAIL;
13135 })
13136
13137 ;; Define combination compare-and-branch fp compare instructions to use
13138 ;; during early optimization. Splitting the operation apart early makes
13139 ;; for bad code when we want to reverse the operation.
13140
13141 (define_insn "*fp_jcc_1_mixed"
13142 [(set (pc)
13143 (if_then_else (match_operator 0 "comparison_operator"
13144 [(match_operand 1 "register_operand" "f#x,x#f")
13145 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13146 (label_ref (match_operand 3 "" ""))
13147 (pc)))
13148 (clobber (reg:CCFP FPSR_REG))
13149 (clobber (reg:CCFP FLAGS_REG))]
13150 "TARGET_MIX_SSE_I387
13151 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13152 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13153 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13154 "#")
13155
13156 (define_insn "*fp_jcc_1_sse"
13157 [(set (pc)
13158 (if_then_else (match_operator 0 "comparison_operator"
13159 [(match_operand 1 "register_operand" "x")
13160 (match_operand 2 "nonimmediate_operand" "xm")])
13161 (label_ref (match_operand 3 "" ""))
13162 (pc)))
13163 (clobber (reg:CCFP FPSR_REG))
13164 (clobber (reg:CCFP FLAGS_REG))]
13165 "TARGET_SSE_MATH
13166 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13167 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13168 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13169 "#")
13170
13171 (define_insn "*fp_jcc_1_387"
13172 [(set (pc)
13173 (if_then_else (match_operator 0 "comparison_operator"
13174 [(match_operand 1 "register_operand" "f")
13175 (match_operand 2 "register_operand" "f")])
13176 (label_ref (match_operand 3 "" ""))
13177 (pc)))
13178 (clobber (reg:CCFP FPSR_REG))
13179 (clobber (reg:CCFP FLAGS_REG))]
13180 "TARGET_CMOVE && TARGET_80387
13181 && FLOAT_MODE_P (GET_MODE (operands[1]))
13182 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13183 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13184 "#")
13185
13186 (define_insn "*fp_jcc_2_mixed"
13187 [(set (pc)
13188 (if_then_else (match_operator 0 "comparison_operator"
13189 [(match_operand 1 "register_operand" "f#x,x#f")
13190 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13191 (pc)
13192 (label_ref (match_operand 3 "" ""))))
13193 (clobber (reg:CCFP FPSR_REG))
13194 (clobber (reg:CCFP FLAGS_REG))]
13195 "TARGET_MIX_SSE_I387
13196 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13197 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13198 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13199 "#")
13200
13201 (define_insn "*fp_jcc_2_sse"
13202 [(set (pc)
13203 (if_then_else (match_operator 0 "comparison_operator"
13204 [(match_operand 1 "register_operand" "x")
13205 (match_operand 2 "nonimmediate_operand" "xm")])
13206 (pc)
13207 (label_ref (match_operand 3 "" ""))))
13208 (clobber (reg:CCFP FPSR_REG))
13209 (clobber (reg:CCFP FLAGS_REG))]
13210 "TARGET_SSE_MATH
13211 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13212 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13213 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13214 "#")
13215
13216 (define_insn "*fp_jcc_2_387"
13217 [(set (pc)
13218 (if_then_else (match_operator 0 "comparison_operator"
13219 [(match_operand 1 "register_operand" "f")
13220 (match_operand 2 "register_operand" "f")])
13221 (pc)
13222 (label_ref (match_operand 3 "" ""))))
13223 (clobber (reg:CCFP FPSR_REG))
13224 (clobber (reg:CCFP FLAGS_REG))]
13225 "TARGET_CMOVE && TARGET_80387
13226 && FLOAT_MODE_P (GET_MODE (operands[1]))
13227 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13228 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13229 "#")
13230
13231 (define_insn "*fp_jcc_3_387"
13232 [(set (pc)
13233 (if_then_else (match_operator 0 "comparison_operator"
13234 [(match_operand 1 "register_operand" "f")
13235 (match_operand 2 "nonimmediate_operand" "fm")])
13236 (label_ref (match_operand 3 "" ""))
13237 (pc)))
13238 (clobber (reg:CCFP FPSR_REG))
13239 (clobber (reg:CCFP FLAGS_REG))
13240 (clobber (match_scratch:HI 4 "=a"))]
13241 "TARGET_80387
13242 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13243 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13244 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13245 && SELECT_CC_MODE (GET_CODE (operands[0]),
13246 operands[1], operands[2]) == CCFPmode
13247 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13248 "#")
13249
13250 (define_insn "*fp_jcc_4_387"
13251 [(set (pc)
13252 (if_then_else (match_operator 0 "comparison_operator"
13253 [(match_operand 1 "register_operand" "f")
13254 (match_operand 2 "nonimmediate_operand" "fm")])
13255 (pc)
13256 (label_ref (match_operand 3 "" ""))))
13257 (clobber (reg:CCFP FPSR_REG))
13258 (clobber (reg:CCFP FLAGS_REG))
13259 (clobber (match_scratch:HI 4 "=a"))]
13260 "TARGET_80387
13261 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13262 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13263 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13264 && SELECT_CC_MODE (GET_CODE (operands[0]),
13265 operands[1], operands[2]) == CCFPmode
13266 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13267 "#")
13268
13269 (define_insn "*fp_jcc_5_387"
13270 [(set (pc)
13271 (if_then_else (match_operator 0 "comparison_operator"
13272 [(match_operand 1 "register_operand" "f")
13273 (match_operand 2 "register_operand" "f")])
13274 (label_ref (match_operand 3 "" ""))
13275 (pc)))
13276 (clobber (reg:CCFP FPSR_REG))
13277 (clobber (reg:CCFP FLAGS_REG))
13278 (clobber (match_scratch:HI 4 "=a"))]
13279 "TARGET_80387
13280 && FLOAT_MODE_P (GET_MODE (operands[1]))
13281 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13282 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13283 "#")
13284
13285 (define_insn "*fp_jcc_6_387"
13286 [(set (pc)
13287 (if_then_else (match_operator 0 "comparison_operator"
13288 [(match_operand 1 "register_operand" "f")
13289 (match_operand 2 "register_operand" "f")])
13290 (pc)
13291 (label_ref (match_operand 3 "" ""))))
13292 (clobber (reg:CCFP FPSR_REG))
13293 (clobber (reg:CCFP FLAGS_REG))
13294 (clobber (match_scratch:HI 4 "=a"))]
13295 "TARGET_80387
13296 && FLOAT_MODE_P (GET_MODE (operands[1]))
13297 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13298 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13299 "#")
13300
13301 (define_insn "*fp_jcc_7_387"
13302 [(set (pc)
13303 (if_then_else (match_operator 0 "comparison_operator"
13304 [(match_operand 1 "register_operand" "f")
13305 (match_operand 2 "const0_operand" "X")])
13306 (label_ref (match_operand 3 "" ""))
13307 (pc)))
13308 (clobber (reg:CCFP FPSR_REG))
13309 (clobber (reg:CCFP FLAGS_REG))
13310 (clobber (match_scratch:HI 4 "=a"))]
13311 "TARGET_80387
13312 && FLOAT_MODE_P (GET_MODE (operands[1]))
13313 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13314 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13315 && SELECT_CC_MODE (GET_CODE (operands[0]),
13316 operands[1], operands[2]) == CCFPmode
13317 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13318 "#")
13319
13320 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13321 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13322 ;; with a precedence over other operators and is always put in the first
13323 ;; place. Swap condition and operands to match ficom instruction.
13324
13325 (define_insn "*fp_jcc_8<mode>_387"
13326 [(set (pc)
13327 (if_then_else (match_operator 0 "comparison_operator"
13328 [(match_operator 1 "float_operator"
13329 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13330 (match_operand 3 "register_operand" "f,f")])
13331 (label_ref (match_operand 4 "" ""))
13332 (pc)))
13333 (clobber (reg:CCFP FPSR_REG))
13334 (clobber (reg:CCFP FLAGS_REG))
13335 (clobber (match_scratch:HI 5 "=a,a"))]
13336 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13337 && FLOAT_MODE_P (GET_MODE (operands[3]))
13338 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13339 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13340 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13341 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13342 "#")
13343
13344 (define_split
13345 [(set (pc)
13346 (if_then_else (match_operator 0 "comparison_operator"
13347 [(match_operand 1 "register_operand" "")
13348 (match_operand 2 "nonimmediate_operand" "")])
13349 (match_operand 3 "" "")
13350 (match_operand 4 "" "")))
13351 (clobber (reg:CCFP FPSR_REG))
13352 (clobber (reg:CCFP FLAGS_REG))]
13353 "reload_completed"
13354 [(const_int 0)]
13355 {
13356 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13357 operands[3], operands[4], NULL_RTX, NULL_RTX);
13358 DONE;
13359 })
13360
13361 (define_split
13362 [(set (pc)
13363 (if_then_else (match_operator 0 "comparison_operator"
13364 [(match_operand 1 "register_operand" "")
13365 (match_operand 2 "general_operand" "")])
13366 (match_operand 3 "" "")
13367 (match_operand 4 "" "")))
13368 (clobber (reg:CCFP FPSR_REG))
13369 (clobber (reg:CCFP FLAGS_REG))
13370 (clobber (match_scratch:HI 5 "=a"))]
13371 "reload_completed"
13372 [(const_int 0)]
13373 {
13374 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13375 operands[3], operands[4], operands[5], NULL_RTX);
13376 DONE;
13377 })
13378
13379 (define_split
13380 [(set (pc)
13381 (if_then_else (match_operator 0 "comparison_operator"
13382 [(match_operator 1 "float_operator"
13383 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13384 (match_operand 3 "register_operand" "")])
13385 (match_operand 4 "" "")
13386 (match_operand 5 "" "")))
13387 (clobber (reg:CCFP FPSR_REG))
13388 (clobber (reg:CCFP FLAGS_REG))
13389 (clobber (match_scratch:HI 6 "=a"))]
13390 "reload_completed"
13391 [(const_int 0)]
13392 {
13393 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13394 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13395 operands[3], operands[7],
13396 operands[4], operands[5], operands[6], NULL_RTX);
13397 DONE;
13398 })
13399
13400 ;; %%% Kill this when reload knows how to do it.
13401 (define_split
13402 [(set (pc)
13403 (if_then_else (match_operator 0 "comparison_operator"
13404 [(match_operator 1 "float_operator"
13405 [(match_operand:X87MODEI12 2 "register_operand" "")])
13406 (match_operand 3 "register_operand" "")])
13407 (match_operand 4 "" "")
13408 (match_operand 5 "" "")))
13409 (clobber (reg:CCFP FPSR_REG))
13410 (clobber (reg:CCFP FLAGS_REG))
13411 (clobber (match_scratch:HI 6 "=a"))]
13412 "reload_completed"
13413 [(const_int 0)]
13414 {
13415 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13416 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13417 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13418 operands[3], operands[7],
13419 operands[4], operands[5], operands[6], operands[2]);
13420 DONE;
13421 })
13422 \f
13423 ;; Unconditional and other jump instructions
13424
13425 (define_insn "jump"
13426 [(set (pc)
13427 (label_ref (match_operand 0 "" "")))]
13428 ""
13429 "jmp\t%l0"
13430 [(set_attr "type" "ibr")
13431 (set (attr "length")
13432 (if_then_else (and (ge (minus (match_dup 0) (pc))
13433 (const_int -126))
13434 (lt (minus (match_dup 0) (pc))
13435 (const_int 128)))
13436 (const_int 2)
13437 (const_int 5)))
13438 (set_attr "modrm" "0")])
13439
13440 (define_expand "indirect_jump"
13441 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13442 ""
13443 "")
13444
13445 (define_insn "*indirect_jump"
13446 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13447 "!TARGET_64BIT"
13448 "jmp\t%A0"
13449 [(set_attr "type" "ibr")
13450 (set_attr "length_immediate" "0")])
13451
13452 (define_insn "*indirect_jump_rtx64"
13453 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13454 "TARGET_64BIT"
13455 "jmp\t%A0"
13456 [(set_attr "type" "ibr")
13457 (set_attr "length_immediate" "0")])
13458
13459 (define_expand "tablejump"
13460 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13461 (use (label_ref (match_operand 1 "" "")))])]
13462 ""
13463 {
13464 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13465 relative. Convert the relative address to an absolute address. */
13466 if (flag_pic)
13467 {
13468 rtx op0, op1;
13469 enum rtx_code code;
13470
13471 if (TARGET_64BIT)
13472 {
13473 code = PLUS;
13474 op0 = operands[0];
13475 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13476 }
13477 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13478 {
13479 code = PLUS;
13480 op0 = operands[0];
13481 op1 = pic_offset_table_rtx;
13482 }
13483 else
13484 {
13485 code = MINUS;
13486 op0 = pic_offset_table_rtx;
13487 op1 = operands[0];
13488 }
13489
13490 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13491 OPTAB_DIRECT);
13492 }
13493 })
13494
13495 (define_insn "*tablejump_1"
13496 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13497 (use (label_ref (match_operand 1 "" "")))]
13498 "!TARGET_64BIT"
13499 "jmp\t%A0"
13500 [(set_attr "type" "ibr")
13501 (set_attr "length_immediate" "0")])
13502
13503 (define_insn "*tablejump_1_rtx64"
13504 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13505 (use (label_ref (match_operand 1 "" "")))]
13506 "TARGET_64BIT"
13507 "jmp\t%A0"
13508 [(set_attr "type" "ibr")
13509 (set_attr "length_immediate" "0")])
13510 \f
13511 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13512
13513 (define_peephole2
13514 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13515 (set (match_operand:QI 1 "register_operand" "")
13516 (match_operator:QI 2 "ix86_comparison_operator"
13517 [(reg FLAGS_REG) (const_int 0)]))
13518 (set (match_operand 3 "q_regs_operand" "")
13519 (zero_extend (match_dup 1)))]
13520 "(peep2_reg_dead_p (3, operands[1])
13521 || operands_match_p (operands[1], operands[3]))
13522 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13523 [(set (match_dup 4) (match_dup 0))
13524 (set (strict_low_part (match_dup 5))
13525 (match_dup 2))]
13526 {
13527 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13528 operands[5] = gen_lowpart (QImode, operands[3]);
13529 ix86_expand_clear (operands[3]);
13530 })
13531
13532 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13533
13534 (define_peephole2
13535 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13536 (set (match_operand:QI 1 "register_operand" "")
13537 (match_operator:QI 2 "ix86_comparison_operator"
13538 [(reg FLAGS_REG) (const_int 0)]))
13539 (parallel [(set (match_operand 3 "q_regs_operand" "")
13540 (zero_extend (match_dup 1)))
13541 (clobber (reg:CC FLAGS_REG))])]
13542 "(peep2_reg_dead_p (3, operands[1])
13543 || operands_match_p (operands[1], operands[3]))
13544 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13545 [(set (match_dup 4) (match_dup 0))
13546 (set (strict_low_part (match_dup 5))
13547 (match_dup 2))]
13548 {
13549 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13550 operands[5] = gen_lowpart (QImode, operands[3]);
13551 ix86_expand_clear (operands[3]);
13552 })
13553 \f
13554 ;; Call instructions.
13555
13556 ;; The predicates normally associated with named expanders are not properly
13557 ;; checked for calls. This is a bug in the generic code, but it isn't that
13558 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13559
13560 ;; Call subroutine returning no value.
13561
13562 (define_expand "call_pop"
13563 [(parallel [(call (match_operand:QI 0 "" "")
13564 (match_operand:SI 1 "" ""))
13565 (set (reg:SI SP_REG)
13566 (plus:SI (reg:SI SP_REG)
13567 (match_operand:SI 3 "" "")))])]
13568 "!TARGET_64BIT"
13569 {
13570 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13571 DONE;
13572 })
13573
13574 (define_insn "*call_pop_0"
13575 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13576 (match_operand:SI 1 "" ""))
13577 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13578 (match_operand:SI 2 "immediate_operand" "")))]
13579 "!TARGET_64BIT"
13580 {
13581 if (SIBLING_CALL_P (insn))
13582 return "jmp\t%P0";
13583 else
13584 return "call\t%P0";
13585 }
13586 [(set_attr "type" "call")])
13587
13588 (define_insn "*call_pop_1"
13589 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13590 (match_operand:SI 1 "" ""))
13591 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13592 (match_operand:SI 2 "immediate_operand" "i")))]
13593 "!TARGET_64BIT"
13594 {
13595 if (constant_call_address_operand (operands[0], Pmode))
13596 {
13597 if (SIBLING_CALL_P (insn))
13598 return "jmp\t%P0";
13599 else
13600 return "call\t%P0";
13601 }
13602 if (SIBLING_CALL_P (insn))
13603 return "jmp\t%A0";
13604 else
13605 return "call\t%A0";
13606 }
13607 [(set_attr "type" "call")])
13608
13609 (define_expand "call"
13610 [(call (match_operand:QI 0 "" "")
13611 (match_operand 1 "" ""))
13612 (use (match_operand 2 "" ""))]
13613 ""
13614 {
13615 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13616 DONE;
13617 })
13618
13619 (define_expand "sibcall"
13620 [(call (match_operand:QI 0 "" "")
13621 (match_operand 1 "" ""))
13622 (use (match_operand 2 "" ""))]
13623 ""
13624 {
13625 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13626 DONE;
13627 })
13628
13629 (define_insn "*call_0"
13630 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13631 (match_operand 1 "" ""))]
13632 ""
13633 {
13634 if (SIBLING_CALL_P (insn))
13635 return "jmp\t%P0";
13636 else
13637 return "call\t%P0";
13638 }
13639 [(set_attr "type" "call")])
13640
13641 (define_insn "*call_1"
13642 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13643 (match_operand 1 "" ""))]
13644 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13645 {
13646 if (constant_call_address_operand (operands[0], Pmode))
13647 return "call\t%P0";
13648 return "call\t%A0";
13649 }
13650 [(set_attr "type" "call")])
13651
13652 (define_insn "*sibcall_1"
13653 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13654 (match_operand 1 "" ""))]
13655 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13656 {
13657 if (constant_call_address_operand (operands[0], Pmode))
13658 return "jmp\t%P0";
13659 return "jmp\t%A0";
13660 }
13661 [(set_attr "type" "call")])
13662
13663 (define_insn "*call_1_rex64"
13664 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13665 (match_operand 1 "" ""))]
13666 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13667 {
13668 if (constant_call_address_operand (operands[0], Pmode))
13669 return "call\t%P0";
13670 return "call\t%A0";
13671 }
13672 [(set_attr "type" "call")])
13673
13674 (define_insn "*sibcall_1_rex64"
13675 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13676 (match_operand 1 "" ""))]
13677 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13678 "jmp\t%P0"
13679 [(set_attr "type" "call")])
13680
13681 (define_insn "*sibcall_1_rex64_v"
13682 [(call (mem:QI (reg:DI 40))
13683 (match_operand 0 "" ""))]
13684 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13685 "jmp\t*%%r11"
13686 [(set_attr "type" "call")])
13687
13688
13689 ;; Call subroutine, returning value in operand 0
13690
13691 (define_expand "call_value_pop"
13692 [(parallel [(set (match_operand 0 "" "")
13693 (call (match_operand:QI 1 "" "")
13694 (match_operand:SI 2 "" "")))
13695 (set (reg:SI SP_REG)
13696 (plus:SI (reg:SI SP_REG)
13697 (match_operand:SI 4 "" "")))])]
13698 "!TARGET_64BIT"
13699 {
13700 ix86_expand_call (operands[0], operands[1], operands[2],
13701 operands[3], operands[4], 0);
13702 DONE;
13703 })
13704
13705 (define_expand "call_value"
13706 [(set (match_operand 0 "" "")
13707 (call (match_operand:QI 1 "" "")
13708 (match_operand:SI 2 "" "")))
13709 (use (match_operand:SI 3 "" ""))]
13710 ;; Operand 2 not used on the i386.
13711 ""
13712 {
13713 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13714 DONE;
13715 })
13716
13717 (define_expand "sibcall_value"
13718 [(set (match_operand 0 "" "")
13719 (call (match_operand:QI 1 "" "")
13720 (match_operand:SI 2 "" "")))
13721 (use (match_operand:SI 3 "" ""))]
13722 ;; Operand 2 not used on the i386.
13723 ""
13724 {
13725 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13726 DONE;
13727 })
13728
13729 ;; Call subroutine returning any type.
13730
13731 (define_expand "untyped_call"
13732 [(parallel [(call (match_operand 0 "" "")
13733 (const_int 0))
13734 (match_operand 1 "" "")
13735 (match_operand 2 "" "")])]
13736 ""
13737 {
13738 int i;
13739
13740 /* In order to give reg-stack an easier job in validating two
13741 coprocessor registers as containing a possible return value,
13742 simply pretend the untyped call returns a complex long double
13743 value. */
13744
13745 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13746 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13747 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13748 NULL, 0);
13749
13750 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13751 {
13752 rtx set = XVECEXP (operands[2], 0, i);
13753 emit_move_insn (SET_DEST (set), SET_SRC (set));
13754 }
13755
13756 /* The optimizer does not know that the call sets the function value
13757 registers we stored in the result block. We avoid problems by
13758 claiming that all hard registers are used and clobbered at this
13759 point. */
13760 emit_insn (gen_blockage (const0_rtx));
13761
13762 DONE;
13763 })
13764 \f
13765 ;; Prologue and epilogue instructions
13766
13767 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13768 ;; all of memory. This blocks insns from being moved across this point.
13769
13770 (define_insn "blockage"
13771 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13772 ""
13773 ""
13774 [(set_attr "length" "0")])
13775
13776 ;; Insn emitted into the body of a function to return from a function.
13777 ;; This is only done if the function's epilogue is known to be simple.
13778 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13779
13780 (define_expand "return"
13781 [(return)]
13782 "ix86_can_use_return_insn_p ()"
13783 {
13784 if (current_function_pops_args)
13785 {
13786 rtx popc = GEN_INT (current_function_pops_args);
13787 emit_jump_insn (gen_return_pop_internal (popc));
13788 DONE;
13789 }
13790 })
13791
13792 (define_insn "return_internal"
13793 [(return)]
13794 "reload_completed"
13795 "ret"
13796 [(set_attr "length" "1")
13797 (set_attr "length_immediate" "0")
13798 (set_attr "modrm" "0")])
13799
13800 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13801 ;; instruction Athlon and K8 have.
13802
13803 (define_insn "return_internal_long"
13804 [(return)
13805 (unspec [(const_int 0)] UNSPEC_REP)]
13806 "reload_completed"
13807 "rep {;} ret"
13808 [(set_attr "length" "1")
13809 (set_attr "length_immediate" "0")
13810 (set_attr "prefix_rep" "1")
13811 (set_attr "modrm" "0")])
13812
13813 (define_insn "return_pop_internal"
13814 [(return)
13815 (use (match_operand:SI 0 "const_int_operand" ""))]
13816 "reload_completed"
13817 "ret\t%0"
13818 [(set_attr "length" "3")
13819 (set_attr "length_immediate" "2")
13820 (set_attr "modrm" "0")])
13821
13822 (define_insn "return_indirect_internal"
13823 [(return)
13824 (use (match_operand:SI 0 "register_operand" "r"))]
13825 "reload_completed"
13826 "jmp\t%A0"
13827 [(set_attr "type" "ibr")
13828 (set_attr "length_immediate" "0")])
13829
13830 (define_insn "nop"
13831 [(const_int 0)]
13832 ""
13833 "nop"
13834 [(set_attr "length" "1")
13835 (set_attr "length_immediate" "0")
13836 (set_attr "modrm" "0")])
13837
13838 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13839 ;; branch prediction penalty for the third jump in a 16-byte
13840 ;; block on K8.
13841
13842 (define_insn "align"
13843 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13844 ""
13845 {
13846 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13847 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13848 #else
13849 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13850 The align insn is used to avoid 3 jump instructions in the row to improve
13851 branch prediction and the benefits hardly outweight the cost of extra 8
13852 nops on the average inserted by full alignment pseudo operation. */
13853 #endif
13854 return "";
13855 }
13856 [(set_attr "length" "16")])
13857
13858 (define_expand "prologue"
13859 [(const_int 1)]
13860 ""
13861 "ix86_expand_prologue (); DONE;")
13862
13863 (define_insn "set_got"
13864 [(set (match_operand:SI 0 "register_operand" "=r")
13865 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13866 (clobber (reg:CC FLAGS_REG))]
13867 "!TARGET_64BIT"
13868 { return output_set_got (operands[0], NULL_RTX); }
13869 [(set_attr "type" "multi")
13870 (set_attr "length" "12")])
13871
13872 (define_insn "set_got_labelled"
13873 [(set (match_operand:SI 0 "register_operand" "=r")
13874 (unspec:SI [(label_ref (match_operand 1 "" ""))]
13875 UNSPEC_SET_GOT))
13876 (clobber (reg:CC FLAGS_REG))]
13877 "!TARGET_64BIT"
13878 { return output_set_got (operands[0], operands[1]); }
13879 [(set_attr "type" "multi")
13880 (set_attr "length" "12")])
13881
13882 (define_insn "set_got_rex64"
13883 [(set (match_operand:DI 0 "register_operand" "=r")
13884 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13885 "TARGET_64BIT"
13886 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13887 [(set_attr "type" "lea")
13888 (set_attr "length" "6")])
13889
13890 (define_expand "epilogue"
13891 [(const_int 1)]
13892 ""
13893 "ix86_expand_epilogue (1); DONE;")
13894
13895 (define_expand "sibcall_epilogue"
13896 [(const_int 1)]
13897 ""
13898 "ix86_expand_epilogue (0); DONE;")
13899
13900 (define_expand "eh_return"
13901 [(use (match_operand 0 "register_operand" ""))]
13902 ""
13903 {
13904 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13905
13906 /* Tricky bit: we write the address of the handler to which we will
13907 be returning into someone else's stack frame, one word below the
13908 stack address we wish to restore. */
13909 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13910 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13911 tmp = gen_rtx_MEM (Pmode, tmp);
13912 emit_move_insn (tmp, ra);
13913
13914 if (Pmode == SImode)
13915 emit_jump_insn (gen_eh_return_si (sa));
13916 else
13917 emit_jump_insn (gen_eh_return_di (sa));
13918 emit_barrier ();
13919 DONE;
13920 })
13921
13922 (define_insn_and_split "eh_return_si"
13923 [(set (pc)
13924 (unspec [(match_operand:SI 0 "register_operand" "c")]
13925 UNSPEC_EH_RETURN))]
13926 "!TARGET_64BIT"
13927 "#"
13928 "reload_completed"
13929 [(const_int 1)]
13930 "ix86_expand_epilogue (2); DONE;")
13931
13932 (define_insn_and_split "eh_return_di"
13933 [(set (pc)
13934 (unspec [(match_operand:DI 0 "register_operand" "c")]
13935 UNSPEC_EH_RETURN))]
13936 "TARGET_64BIT"
13937 "#"
13938 "reload_completed"
13939 [(const_int 1)]
13940 "ix86_expand_epilogue (2); DONE;")
13941
13942 (define_insn "leave"
13943 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13944 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13945 (clobber (mem:BLK (scratch)))]
13946 "!TARGET_64BIT"
13947 "leave"
13948 [(set_attr "type" "leave")])
13949
13950 (define_insn "leave_rex64"
13951 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13952 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13953 (clobber (mem:BLK (scratch)))]
13954 "TARGET_64BIT"
13955 "leave"
13956 [(set_attr "type" "leave")])
13957 \f
13958 (define_expand "ffssi2"
13959 [(parallel
13960 [(set (match_operand:SI 0 "register_operand" "")
13961 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13962 (clobber (match_scratch:SI 2 ""))
13963 (clobber (reg:CC FLAGS_REG))])]
13964 ""
13965 "")
13966
13967 (define_insn_and_split "*ffs_cmove"
13968 [(set (match_operand:SI 0 "register_operand" "=r")
13969 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13970 (clobber (match_scratch:SI 2 "=&r"))
13971 (clobber (reg:CC FLAGS_REG))]
13972 "TARGET_CMOVE"
13973 "#"
13974 "&& reload_completed"
13975 [(set (match_dup 2) (const_int -1))
13976 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13977 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13978 (set (match_dup 0) (if_then_else:SI
13979 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13980 (match_dup 2)
13981 (match_dup 0)))
13982 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13983 (clobber (reg:CC FLAGS_REG))])]
13984 "")
13985
13986 (define_insn_and_split "*ffs_no_cmove"
13987 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13988 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13989 (clobber (match_scratch:SI 2 "=&q"))
13990 (clobber (reg:CC FLAGS_REG))]
13991 ""
13992 "#"
13993 "reload_completed"
13994 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13995 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13996 (set (strict_low_part (match_dup 3))
13997 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13998 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13999 (clobber (reg:CC FLAGS_REG))])
14000 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14001 (clobber (reg:CC FLAGS_REG))])
14002 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14003 (clobber (reg:CC FLAGS_REG))])]
14004 {
14005 operands[3] = gen_lowpart (QImode, operands[2]);
14006 ix86_expand_clear (operands[2]);
14007 })
14008
14009 (define_insn "*ffssi_1"
14010 [(set (reg:CCZ FLAGS_REG)
14011 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14012 (const_int 0)))
14013 (set (match_operand:SI 0 "register_operand" "=r")
14014 (ctz:SI (match_dup 1)))]
14015 ""
14016 "bsf{l}\t{%1, %0|%0, %1}"
14017 [(set_attr "prefix_0f" "1")])
14018
14019 (define_expand "ffsdi2"
14020 [(parallel
14021 [(set (match_operand:DI 0 "register_operand" "")
14022 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14023 (clobber (match_scratch:DI 2 ""))
14024 (clobber (reg:CC FLAGS_REG))])]
14025 "TARGET_64BIT && TARGET_CMOVE"
14026 "")
14027
14028 (define_insn_and_split "*ffs_rex64"
14029 [(set (match_operand:DI 0 "register_operand" "=r")
14030 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14031 (clobber (match_scratch:DI 2 "=&r"))
14032 (clobber (reg:CC FLAGS_REG))]
14033 "TARGET_64BIT && TARGET_CMOVE"
14034 "#"
14035 "&& reload_completed"
14036 [(set (match_dup 2) (const_int -1))
14037 (parallel [(set (reg:CCZ FLAGS_REG)
14038 (compare:CCZ (match_dup 1) (const_int 0)))
14039 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14040 (set (match_dup 0) (if_then_else:DI
14041 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14042 (match_dup 2)
14043 (match_dup 0)))
14044 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14045 (clobber (reg:CC FLAGS_REG))])]
14046 "")
14047
14048 (define_insn "*ffsdi_1"
14049 [(set (reg:CCZ FLAGS_REG)
14050 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14051 (const_int 0)))
14052 (set (match_operand:DI 0 "register_operand" "=r")
14053 (ctz:DI (match_dup 1)))]
14054 "TARGET_64BIT"
14055 "bsf{q}\t{%1, %0|%0, %1}"
14056 [(set_attr "prefix_0f" "1")])
14057
14058 (define_insn "ctzsi2"
14059 [(set (match_operand:SI 0 "register_operand" "=r")
14060 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14061 (clobber (reg:CC FLAGS_REG))]
14062 ""
14063 "bsf{l}\t{%1, %0|%0, %1}"
14064 [(set_attr "prefix_0f" "1")])
14065
14066 (define_insn "ctzdi2"
14067 [(set (match_operand:DI 0 "register_operand" "=r")
14068 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14069 (clobber (reg:CC FLAGS_REG))]
14070 "TARGET_64BIT"
14071 "bsf{q}\t{%1, %0|%0, %1}"
14072 [(set_attr "prefix_0f" "1")])
14073
14074 (define_expand "clzsi2"
14075 [(parallel
14076 [(set (match_operand:SI 0 "register_operand" "")
14077 (minus:SI (const_int 31)
14078 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14079 (clobber (reg:CC FLAGS_REG))])
14080 (parallel
14081 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14082 (clobber (reg:CC FLAGS_REG))])]
14083 ""
14084 "")
14085
14086 (define_insn "*bsr"
14087 [(set (match_operand:SI 0 "register_operand" "=r")
14088 (minus:SI (const_int 31)
14089 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14090 (clobber (reg:CC FLAGS_REG))]
14091 ""
14092 "bsr{l}\t{%1, %0|%0, %1}"
14093 [(set_attr "prefix_0f" "1")])
14094
14095 (define_expand "clzdi2"
14096 [(parallel
14097 [(set (match_operand:DI 0 "register_operand" "")
14098 (minus:DI (const_int 63)
14099 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14100 (clobber (reg:CC FLAGS_REG))])
14101 (parallel
14102 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14103 (clobber (reg:CC FLAGS_REG))])]
14104 "TARGET_64BIT"
14105 "")
14106
14107 (define_insn "*bsr_rex64"
14108 [(set (match_operand:DI 0 "register_operand" "=r")
14109 (minus:DI (const_int 63)
14110 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14111 (clobber (reg:CC FLAGS_REG))]
14112 "TARGET_64BIT"
14113 "bsr{q}\t{%1, %0|%0, %1}"
14114 [(set_attr "prefix_0f" "1")])
14115 \f
14116 ;; Thread-local storage patterns for ELF.
14117 ;;
14118 ;; Note that these code sequences must appear exactly as shown
14119 ;; in order to allow linker relaxation.
14120
14121 (define_insn "*tls_global_dynamic_32_gnu"
14122 [(set (match_operand:SI 0 "register_operand" "=a")
14123 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14124 (match_operand:SI 2 "tls_symbolic_operand" "")
14125 (match_operand:SI 3 "call_insn_operand" "")]
14126 UNSPEC_TLS_GD))
14127 (clobber (match_scratch:SI 4 "=d"))
14128 (clobber (match_scratch:SI 5 "=c"))
14129 (clobber (reg:CC FLAGS_REG))]
14130 "!TARGET_64BIT && TARGET_GNU_TLS"
14131 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14132 [(set_attr "type" "multi")
14133 (set_attr "length" "12")])
14134
14135 (define_insn "*tls_global_dynamic_32_sun"
14136 [(set (match_operand:SI 0 "register_operand" "=a")
14137 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14138 (match_operand:SI 2 "tls_symbolic_operand" "")
14139 (match_operand:SI 3 "call_insn_operand" "")]
14140 UNSPEC_TLS_GD))
14141 (clobber (match_scratch:SI 4 "=d"))
14142 (clobber (match_scratch:SI 5 "=c"))
14143 (clobber (reg:CC FLAGS_REG))]
14144 "!TARGET_64BIT && TARGET_SUN_TLS"
14145 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14146 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14147 [(set_attr "type" "multi")
14148 (set_attr "length" "14")])
14149
14150 (define_expand "tls_global_dynamic_32"
14151 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14152 (unspec:SI
14153 [(match_dup 2)
14154 (match_operand:SI 1 "tls_symbolic_operand" "")
14155 (match_dup 3)]
14156 UNSPEC_TLS_GD))
14157 (clobber (match_scratch:SI 4 ""))
14158 (clobber (match_scratch:SI 5 ""))
14159 (clobber (reg:CC FLAGS_REG))])]
14160 ""
14161 {
14162 if (flag_pic)
14163 operands[2] = pic_offset_table_rtx;
14164 else
14165 {
14166 operands[2] = gen_reg_rtx (Pmode);
14167 emit_insn (gen_set_got (operands[2]));
14168 }
14169 if (TARGET_GNU2_TLS)
14170 {
14171 emit_insn (gen_tls_dynamic_gnu2_32
14172 (operands[0], operands[1], operands[2]));
14173 DONE;
14174 }
14175 operands[3] = ix86_tls_get_addr ();
14176 })
14177
14178 (define_insn "*tls_global_dynamic_64"
14179 [(set (match_operand:DI 0 "register_operand" "=a")
14180 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14181 (match_operand:DI 3 "" "")))
14182 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14183 UNSPEC_TLS_GD)]
14184 "TARGET_64BIT"
14185 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14186 [(set_attr "type" "multi")
14187 (set_attr "length" "16")])
14188
14189 (define_expand "tls_global_dynamic_64"
14190 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14191 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14192 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14193 UNSPEC_TLS_GD)])]
14194 ""
14195 {
14196 if (TARGET_GNU2_TLS)
14197 {
14198 emit_insn (gen_tls_dynamic_gnu2_64
14199 (operands[0], operands[1]));
14200 DONE;
14201 }
14202 operands[2] = ix86_tls_get_addr ();
14203 })
14204
14205 (define_insn "*tls_local_dynamic_base_32_gnu"
14206 [(set (match_operand:SI 0 "register_operand" "=a")
14207 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14208 (match_operand:SI 2 "call_insn_operand" "")]
14209 UNSPEC_TLS_LD_BASE))
14210 (clobber (match_scratch:SI 3 "=d"))
14211 (clobber (match_scratch:SI 4 "=c"))
14212 (clobber (reg:CC FLAGS_REG))]
14213 "!TARGET_64BIT && TARGET_GNU_TLS"
14214 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14215 [(set_attr "type" "multi")
14216 (set_attr "length" "11")])
14217
14218 (define_insn "*tls_local_dynamic_base_32_sun"
14219 [(set (match_operand:SI 0 "register_operand" "=a")
14220 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14221 (match_operand:SI 2 "call_insn_operand" "")]
14222 UNSPEC_TLS_LD_BASE))
14223 (clobber (match_scratch:SI 3 "=d"))
14224 (clobber (match_scratch:SI 4 "=c"))
14225 (clobber (reg:CC FLAGS_REG))]
14226 "!TARGET_64BIT && TARGET_SUN_TLS"
14227 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14228 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14229 [(set_attr "type" "multi")
14230 (set_attr "length" "13")])
14231
14232 (define_expand "tls_local_dynamic_base_32"
14233 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14234 (unspec:SI [(match_dup 1) (match_dup 2)]
14235 UNSPEC_TLS_LD_BASE))
14236 (clobber (match_scratch:SI 3 ""))
14237 (clobber (match_scratch:SI 4 ""))
14238 (clobber (reg:CC FLAGS_REG))])]
14239 ""
14240 {
14241 if (flag_pic)
14242 operands[1] = pic_offset_table_rtx;
14243 else
14244 {
14245 operands[1] = gen_reg_rtx (Pmode);
14246 emit_insn (gen_set_got (operands[1]));
14247 }
14248 if (TARGET_GNU2_TLS)
14249 {
14250 emit_insn (gen_tls_dynamic_gnu2_32
14251 (operands[0], ix86_tls_module_base (), operands[1]));
14252 DONE;
14253 }
14254 operands[2] = ix86_tls_get_addr ();
14255 })
14256
14257 (define_insn "*tls_local_dynamic_base_64"
14258 [(set (match_operand:DI 0 "register_operand" "=a")
14259 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14260 (match_operand:DI 2 "" "")))
14261 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14262 "TARGET_64BIT"
14263 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14264 [(set_attr "type" "multi")
14265 (set_attr "length" "12")])
14266
14267 (define_expand "tls_local_dynamic_base_64"
14268 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14269 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14270 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14271 ""
14272 {
14273 if (TARGET_GNU2_TLS)
14274 {
14275 emit_insn (gen_tls_dynamic_gnu2_64
14276 (operands[0], ix86_tls_module_base ()));
14277 DONE;
14278 }
14279 operands[1] = ix86_tls_get_addr ();
14280 })
14281
14282 ;; Local dynamic of a single variable is a lose. Show combine how
14283 ;; to convert that back to global dynamic.
14284
14285 (define_insn_and_split "*tls_local_dynamic_32_once"
14286 [(set (match_operand:SI 0 "register_operand" "=a")
14287 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14288 (match_operand:SI 2 "call_insn_operand" "")]
14289 UNSPEC_TLS_LD_BASE)
14290 (const:SI (unspec:SI
14291 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14292 UNSPEC_DTPOFF))))
14293 (clobber (match_scratch:SI 4 "=d"))
14294 (clobber (match_scratch:SI 5 "=c"))
14295 (clobber (reg:CC FLAGS_REG))]
14296 ""
14297 "#"
14298 ""
14299 [(parallel [(set (match_dup 0)
14300 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14301 UNSPEC_TLS_GD))
14302 (clobber (match_dup 4))
14303 (clobber (match_dup 5))
14304 (clobber (reg:CC FLAGS_REG))])]
14305 "")
14306
14307 ;; Load and add the thread base pointer from %gs:0.
14308
14309 (define_insn "*load_tp_si"
14310 [(set (match_operand:SI 0 "register_operand" "=r")
14311 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14312 "!TARGET_64BIT"
14313 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14314 [(set_attr "type" "imov")
14315 (set_attr "modrm" "0")
14316 (set_attr "length" "7")
14317 (set_attr "memory" "load")
14318 (set_attr "imm_disp" "false")])
14319
14320 (define_insn "*add_tp_si"
14321 [(set (match_operand:SI 0 "register_operand" "=r")
14322 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14323 (match_operand:SI 1 "register_operand" "0")))
14324 (clobber (reg:CC FLAGS_REG))]
14325 "!TARGET_64BIT"
14326 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14327 [(set_attr "type" "alu")
14328 (set_attr "modrm" "0")
14329 (set_attr "length" "7")
14330 (set_attr "memory" "load")
14331 (set_attr "imm_disp" "false")])
14332
14333 (define_insn "*load_tp_di"
14334 [(set (match_operand:DI 0 "register_operand" "=r")
14335 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14336 "TARGET_64BIT"
14337 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14338 [(set_attr "type" "imov")
14339 (set_attr "modrm" "0")
14340 (set_attr "length" "7")
14341 (set_attr "memory" "load")
14342 (set_attr "imm_disp" "false")])
14343
14344 (define_insn "*add_tp_di"
14345 [(set (match_operand:DI 0 "register_operand" "=r")
14346 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14347 (match_operand:DI 1 "register_operand" "0")))
14348 (clobber (reg:CC FLAGS_REG))]
14349 "TARGET_64BIT"
14350 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14351 [(set_attr "type" "alu")
14352 (set_attr "modrm" "0")
14353 (set_attr "length" "7")
14354 (set_attr "memory" "load")
14355 (set_attr "imm_disp" "false")])
14356
14357 ;; GNU2 TLS patterns can be split.
14358
14359 (define_expand "tls_dynamic_gnu2_32"
14360 [(set (match_dup 3)
14361 (plus:SI (match_operand:SI 2 "register_operand" "")
14362 (const:SI
14363 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14364 UNSPEC_TLSDESC))))
14365 (parallel
14366 [(set (match_operand:SI 0 "register_operand" "")
14367 (unspec:SI [(match_dup 1) (match_dup 3)
14368 (match_dup 2) (reg:SI SP_REG)]
14369 UNSPEC_TLSDESC))
14370 (clobber (reg:CC FLAGS_REG))])]
14371 "!TARGET_64BIT && TARGET_GNU2_TLS"
14372 {
14373 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14374 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14375 })
14376
14377 (define_insn "*tls_dynamic_lea_32"
14378 [(set (match_operand:SI 0 "register_operand" "=r")
14379 (plus:SI (match_operand:SI 1 "register_operand" "b")
14380 (const:SI
14381 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14382 UNSPEC_TLSDESC))))]
14383 "!TARGET_64BIT && TARGET_GNU2_TLS"
14384 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14385 [(set_attr "type" "lea")
14386 (set_attr "mode" "SI")
14387 (set_attr "length" "6")
14388 (set_attr "length_address" "4")])
14389
14390 (define_insn "*tls_dynamic_call_32"
14391 [(set (match_operand:SI 0 "register_operand" "=a")
14392 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14393 (match_operand:SI 2 "register_operand" "0")
14394 ;; we have to make sure %ebx still points to the GOT
14395 (match_operand:SI 3 "register_operand" "b")
14396 (reg:SI SP_REG)]
14397 UNSPEC_TLSDESC))
14398 (clobber (reg:CC FLAGS_REG))]
14399 "!TARGET_64BIT && TARGET_GNU2_TLS"
14400 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14401 [(set_attr "type" "call")
14402 (set_attr "length" "2")
14403 (set_attr "length_address" "0")])
14404
14405 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14406 [(set (match_operand:SI 0 "register_operand" "=&a")
14407 (plus:SI
14408 (plus:SI (match_operand:SI 3 "tp_or_register_operand" "ir")
14409 (unspec:SI [(match_operand:SI 4 "tls_modbase_operand" "")
14410 (match_operand:SI 5 "" "")
14411 (match_operand:SI 2 "register_operand" "b")
14412 (reg:SI SP_REG)]
14413 UNSPEC_TLSDESC))
14414 (const:SI (unspec:SI
14415 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14416 UNSPEC_DTPOFF))))
14417 (clobber (reg:CC FLAGS_REG))]
14418 "!TARGET_64BIT && TARGET_GNU2_TLS"
14419 "#"
14420 ""
14421 [(parallel
14422 [(set (match_dup 0)
14423 (plus:SI (match_dup 3)
14424 (match_dup 5)))
14425 (clobber (reg:CC FLAGS_REG))])]
14426 {
14427 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14428 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14429 })
14430
14431 (define_expand "tls_dynamic_gnu2_64"
14432 [(set (match_dup 2)
14433 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14434 UNSPEC_TLSDESC))
14435 (parallel
14436 [(set (match_operand:DI 0 "register_operand" "")
14437 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14438 UNSPEC_TLSDESC))
14439 (clobber (reg:CC FLAGS_REG))])]
14440 "TARGET_64BIT && TARGET_GNU2_TLS"
14441 {
14442 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14443 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14444 })
14445
14446 (define_insn "*tls_dynamic_lea_64"
14447 [(set (match_operand:DI 0 "register_operand" "=r")
14448 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14449 UNSPEC_TLSDESC))]
14450 "TARGET_64BIT && TARGET_GNU2_TLS"
14451 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14452 [(set_attr "type" "lea")
14453 (set_attr "mode" "DI")
14454 (set_attr "length" "7")
14455 (set_attr "length_address" "4")])
14456
14457 (define_insn "*tls_dynamic_call_64"
14458 [(set (match_operand:DI 0 "register_operand" "=a")
14459 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14460 (match_operand:DI 2 "register_operand" "0")
14461 (reg:DI SP_REG)]
14462 UNSPEC_TLSDESC))
14463 (clobber (reg:CC FLAGS_REG))]
14464 "TARGET_64BIT && TARGET_GNU2_TLS"
14465 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14466 [(set_attr "type" "call")
14467 (set_attr "length" "2")
14468 (set_attr "length_address" "0")])
14469
14470 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14471 [(set (match_operand:DI 0 "register_operand" "=&a")
14472 (plus:DI
14473 (plus:DI (match_operand:DI 2 "tp_or_register_operand" "ir")
14474 (unspec:DI [(match_operand:DI 3 "tls_modbase_operand" "")
14475 (match_operand:DI 4 "" "")
14476 (reg:DI SP_REG)]
14477 UNSPEC_TLSDESC))
14478 (const:DI (unspec:DI
14479 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14480 UNSPEC_DTPOFF))))
14481 (clobber (reg:CC FLAGS_REG))]
14482 "TARGET_64BIT && TARGET_GNU2_TLS"
14483 "#"
14484 ""
14485 [(parallel
14486 [(set (match_dup 0)
14487 (plus:DI (match_dup 2)
14488 (match_dup 4)))
14489 (clobber (reg:CC FLAGS_REG))])]
14490 {
14491 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14492 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14493 })
14494
14495 ;;
14496 \f
14497 ;; These patterns match the binary 387 instructions for addM3, subM3,
14498 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14499 ;; SFmode. The first is the normal insn, the second the same insn but
14500 ;; with one operand a conversion, and the third the same insn but with
14501 ;; the other operand a conversion. The conversion may be SFmode or
14502 ;; SImode if the target mode DFmode, but only SImode if the target mode
14503 ;; is SFmode.
14504
14505 ;; Gcc is slightly more smart about handling normal two address instructions
14506 ;; so use special patterns for add and mull.
14507
14508 (define_insn "*fop_sf_comm_mixed"
14509 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14510 (match_operator:SF 3 "binary_fp_operator"
14511 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14512 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14513 "TARGET_MIX_SSE_I387
14514 && COMMUTATIVE_ARITH_P (operands[3])
14515 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14516 "* return output_387_binary_op (insn, operands);"
14517 [(set (attr "type")
14518 (if_then_else (eq_attr "alternative" "1")
14519 (if_then_else (match_operand:SF 3 "mult_operator" "")
14520 (const_string "ssemul")
14521 (const_string "sseadd"))
14522 (if_then_else (match_operand:SF 3 "mult_operator" "")
14523 (const_string "fmul")
14524 (const_string "fop"))))
14525 (set_attr "mode" "SF")])
14526
14527 (define_insn "*fop_sf_comm_sse"
14528 [(set (match_operand:SF 0 "register_operand" "=x")
14529 (match_operator:SF 3 "binary_fp_operator"
14530 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14531 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14532 "TARGET_SSE_MATH
14533 && COMMUTATIVE_ARITH_P (operands[3])
14534 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14535 "* return output_387_binary_op (insn, operands);"
14536 [(set (attr "type")
14537 (if_then_else (match_operand:SF 3 "mult_operator" "")
14538 (const_string "ssemul")
14539 (const_string "sseadd")))
14540 (set_attr "mode" "SF")])
14541
14542 (define_insn "*fop_sf_comm_i387"
14543 [(set (match_operand:SF 0 "register_operand" "=f")
14544 (match_operator:SF 3 "binary_fp_operator"
14545 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14546 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14547 "TARGET_80387
14548 && COMMUTATIVE_ARITH_P (operands[3])
14549 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14550 "* return output_387_binary_op (insn, operands);"
14551 [(set (attr "type")
14552 (if_then_else (match_operand:SF 3 "mult_operator" "")
14553 (const_string "fmul")
14554 (const_string "fop")))
14555 (set_attr "mode" "SF")])
14556
14557 (define_insn "*fop_sf_1_mixed"
14558 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14559 (match_operator:SF 3 "binary_fp_operator"
14560 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14561 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14562 "TARGET_MIX_SSE_I387
14563 && !COMMUTATIVE_ARITH_P (operands[3])
14564 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14565 "* return output_387_binary_op (insn, operands);"
14566 [(set (attr "type")
14567 (cond [(and (eq_attr "alternative" "2")
14568 (match_operand:SF 3 "mult_operator" ""))
14569 (const_string "ssemul")
14570 (and (eq_attr "alternative" "2")
14571 (match_operand:SF 3 "div_operator" ""))
14572 (const_string "ssediv")
14573 (eq_attr "alternative" "2")
14574 (const_string "sseadd")
14575 (match_operand:SF 3 "mult_operator" "")
14576 (const_string "fmul")
14577 (match_operand:SF 3 "div_operator" "")
14578 (const_string "fdiv")
14579 ]
14580 (const_string "fop")))
14581 (set_attr "mode" "SF")])
14582
14583 (define_insn "*fop_sf_1_sse"
14584 [(set (match_operand:SF 0 "register_operand" "=x")
14585 (match_operator:SF 3 "binary_fp_operator"
14586 [(match_operand:SF 1 "register_operand" "0")
14587 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14588 "TARGET_SSE_MATH
14589 && !COMMUTATIVE_ARITH_P (operands[3])"
14590 "* return output_387_binary_op (insn, operands);"
14591 [(set (attr "type")
14592 (cond [(match_operand:SF 3 "mult_operator" "")
14593 (const_string "ssemul")
14594 (match_operand:SF 3 "div_operator" "")
14595 (const_string "ssediv")
14596 ]
14597 (const_string "sseadd")))
14598 (set_attr "mode" "SF")])
14599
14600 ;; This pattern is not fully shadowed by the pattern above.
14601 (define_insn "*fop_sf_1_i387"
14602 [(set (match_operand:SF 0 "register_operand" "=f,f")
14603 (match_operator:SF 3 "binary_fp_operator"
14604 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14605 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14606 "TARGET_80387 && !TARGET_SSE_MATH
14607 && !COMMUTATIVE_ARITH_P (operands[3])
14608 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14609 "* return output_387_binary_op (insn, operands);"
14610 [(set (attr "type")
14611 (cond [(match_operand:SF 3 "mult_operator" "")
14612 (const_string "fmul")
14613 (match_operand:SF 3 "div_operator" "")
14614 (const_string "fdiv")
14615 ]
14616 (const_string "fop")))
14617 (set_attr "mode" "SF")])
14618
14619 ;; ??? Add SSE splitters for these!
14620 (define_insn "*fop_sf_2<mode>_i387"
14621 [(set (match_operand:SF 0 "register_operand" "=f,f")
14622 (match_operator:SF 3 "binary_fp_operator"
14623 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14624 (match_operand:SF 2 "register_operand" "0,0")]))]
14625 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14626 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14627 [(set (attr "type")
14628 (cond [(match_operand:SF 3 "mult_operator" "")
14629 (const_string "fmul")
14630 (match_operand:SF 3 "div_operator" "")
14631 (const_string "fdiv")
14632 ]
14633 (const_string "fop")))
14634 (set_attr "fp_int_src" "true")
14635 (set_attr "mode" "<MODE>")])
14636
14637 (define_insn "*fop_sf_3<mode>_i387"
14638 [(set (match_operand:SF 0 "register_operand" "=f,f")
14639 (match_operator:SF 3 "binary_fp_operator"
14640 [(match_operand:SF 1 "register_operand" "0,0")
14641 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14642 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14643 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14644 [(set (attr "type")
14645 (cond [(match_operand:SF 3 "mult_operator" "")
14646 (const_string "fmul")
14647 (match_operand:SF 3 "div_operator" "")
14648 (const_string "fdiv")
14649 ]
14650 (const_string "fop")))
14651 (set_attr "fp_int_src" "true")
14652 (set_attr "mode" "<MODE>")])
14653
14654 (define_insn "*fop_df_comm_mixed"
14655 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14656 (match_operator:DF 3 "binary_fp_operator"
14657 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14658 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14659 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14660 && COMMUTATIVE_ARITH_P (operands[3])
14661 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14662 "* return output_387_binary_op (insn, operands);"
14663 [(set (attr "type")
14664 (if_then_else (eq_attr "alternative" "1")
14665 (if_then_else (match_operand:SF 3 "mult_operator" "")
14666 (const_string "ssemul")
14667 (const_string "sseadd"))
14668 (if_then_else (match_operand:SF 3 "mult_operator" "")
14669 (const_string "fmul")
14670 (const_string "fop"))))
14671 (set_attr "mode" "DF")])
14672
14673 (define_insn "*fop_df_comm_sse"
14674 [(set (match_operand:DF 0 "register_operand" "=Y")
14675 (match_operator:DF 3 "binary_fp_operator"
14676 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14677 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14678 "TARGET_SSE2 && TARGET_SSE_MATH
14679 && COMMUTATIVE_ARITH_P (operands[3])
14680 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14681 "* return output_387_binary_op (insn, operands);"
14682 [(set (attr "type")
14683 (if_then_else (match_operand:SF 3 "mult_operator" "")
14684 (const_string "ssemul")
14685 (const_string "sseadd")))
14686 (set_attr "mode" "DF")])
14687
14688 (define_insn "*fop_df_comm_i387"
14689 [(set (match_operand:DF 0 "register_operand" "=f")
14690 (match_operator:DF 3 "binary_fp_operator"
14691 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14692 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14693 "TARGET_80387
14694 && COMMUTATIVE_ARITH_P (operands[3])
14695 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14696 "* return output_387_binary_op (insn, operands);"
14697 [(set (attr "type")
14698 (if_then_else (match_operand:SF 3 "mult_operator" "")
14699 (const_string "fmul")
14700 (const_string "fop")))
14701 (set_attr "mode" "DF")])
14702
14703 (define_insn "*fop_df_1_mixed"
14704 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14705 (match_operator:DF 3 "binary_fp_operator"
14706 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14707 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14708 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14709 && !COMMUTATIVE_ARITH_P (operands[3])
14710 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14711 "* return output_387_binary_op (insn, operands);"
14712 [(set (attr "type")
14713 (cond [(and (eq_attr "alternative" "2")
14714 (match_operand:SF 3 "mult_operator" ""))
14715 (const_string "ssemul")
14716 (and (eq_attr "alternative" "2")
14717 (match_operand:SF 3 "div_operator" ""))
14718 (const_string "ssediv")
14719 (eq_attr "alternative" "2")
14720 (const_string "sseadd")
14721 (match_operand:DF 3 "mult_operator" "")
14722 (const_string "fmul")
14723 (match_operand:DF 3 "div_operator" "")
14724 (const_string "fdiv")
14725 ]
14726 (const_string "fop")))
14727 (set_attr "mode" "DF")])
14728
14729 (define_insn "*fop_df_1_sse"
14730 [(set (match_operand:DF 0 "register_operand" "=Y")
14731 (match_operator:DF 3 "binary_fp_operator"
14732 [(match_operand:DF 1 "register_operand" "0")
14733 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14734 "TARGET_SSE2 && TARGET_SSE_MATH
14735 && !COMMUTATIVE_ARITH_P (operands[3])"
14736 "* return output_387_binary_op (insn, operands);"
14737 [(set_attr "mode" "DF")
14738 (set (attr "type")
14739 (cond [(match_operand:SF 3 "mult_operator" "")
14740 (const_string "ssemul")
14741 (match_operand:SF 3 "div_operator" "")
14742 (const_string "ssediv")
14743 ]
14744 (const_string "sseadd")))])
14745
14746 ;; This pattern is not fully shadowed by the pattern above.
14747 (define_insn "*fop_df_1_i387"
14748 [(set (match_operand:DF 0 "register_operand" "=f,f")
14749 (match_operator:DF 3 "binary_fp_operator"
14750 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14751 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14752 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14753 && !COMMUTATIVE_ARITH_P (operands[3])
14754 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14755 "* return output_387_binary_op (insn, operands);"
14756 [(set (attr "type")
14757 (cond [(match_operand:DF 3 "mult_operator" "")
14758 (const_string "fmul")
14759 (match_operand:DF 3 "div_operator" "")
14760 (const_string "fdiv")
14761 ]
14762 (const_string "fop")))
14763 (set_attr "mode" "DF")])
14764
14765 ;; ??? Add SSE splitters for these!
14766 (define_insn "*fop_df_2<mode>_i387"
14767 [(set (match_operand:DF 0 "register_operand" "=f,f")
14768 (match_operator:DF 3 "binary_fp_operator"
14769 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14770 (match_operand:DF 2 "register_operand" "0,0")]))]
14771 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14772 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14773 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14774 [(set (attr "type")
14775 (cond [(match_operand:DF 3 "mult_operator" "")
14776 (const_string "fmul")
14777 (match_operand:DF 3 "div_operator" "")
14778 (const_string "fdiv")
14779 ]
14780 (const_string "fop")))
14781 (set_attr "fp_int_src" "true")
14782 (set_attr "mode" "<MODE>")])
14783
14784 (define_insn "*fop_df_3<mode>_i387"
14785 [(set (match_operand:DF 0 "register_operand" "=f,f")
14786 (match_operator:DF 3 "binary_fp_operator"
14787 [(match_operand:DF 1 "register_operand" "0,0")
14788 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14789 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14790 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14791 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14792 [(set (attr "type")
14793 (cond [(match_operand:DF 3 "mult_operator" "")
14794 (const_string "fmul")
14795 (match_operand:DF 3 "div_operator" "")
14796 (const_string "fdiv")
14797 ]
14798 (const_string "fop")))
14799 (set_attr "fp_int_src" "true")
14800 (set_attr "mode" "<MODE>")])
14801
14802 (define_insn "*fop_df_4_i387"
14803 [(set (match_operand:DF 0 "register_operand" "=f,f")
14804 (match_operator:DF 3 "binary_fp_operator"
14805 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14806 (match_operand:DF 2 "register_operand" "0,f")]))]
14807 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14808 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14809 "* return output_387_binary_op (insn, operands);"
14810 [(set (attr "type")
14811 (cond [(match_operand:DF 3 "mult_operator" "")
14812 (const_string "fmul")
14813 (match_operand:DF 3 "div_operator" "")
14814 (const_string "fdiv")
14815 ]
14816 (const_string "fop")))
14817 (set_attr "mode" "SF")])
14818
14819 (define_insn "*fop_df_5_i387"
14820 [(set (match_operand:DF 0 "register_operand" "=f,f")
14821 (match_operator:DF 3 "binary_fp_operator"
14822 [(match_operand:DF 1 "register_operand" "0,f")
14823 (float_extend:DF
14824 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14825 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14826 "* return output_387_binary_op (insn, operands);"
14827 [(set (attr "type")
14828 (cond [(match_operand:DF 3 "mult_operator" "")
14829 (const_string "fmul")
14830 (match_operand:DF 3 "div_operator" "")
14831 (const_string "fdiv")
14832 ]
14833 (const_string "fop")))
14834 (set_attr "mode" "SF")])
14835
14836 (define_insn "*fop_df_6_i387"
14837 [(set (match_operand:DF 0 "register_operand" "=f,f")
14838 (match_operator:DF 3 "binary_fp_operator"
14839 [(float_extend:DF
14840 (match_operand:SF 1 "register_operand" "0,f"))
14841 (float_extend:DF
14842 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14843 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14844 "* return output_387_binary_op (insn, operands);"
14845 [(set (attr "type")
14846 (cond [(match_operand:DF 3 "mult_operator" "")
14847 (const_string "fmul")
14848 (match_operand:DF 3 "div_operator" "")
14849 (const_string "fdiv")
14850 ]
14851 (const_string "fop")))
14852 (set_attr "mode" "SF")])
14853
14854 (define_insn "*fop_xf_comm_i387"
14855 [(set (match_operand:XF 0 "register_operand" "=f")
14856 (match_operator:XF 3 "binary_fp_operator"
14857 [(match_operand:XF 1 "register_operand" "%0")
14858 (match_operand:XF 2 "register_operand" "f")]))]
14859 "TARGET_80387
14860 && COMMUTATIVE_ARITH_P (operands[3])"
14861 "* return output_387_binary_op (insn, operands);"
14862 [(set (attr "type")
14863 (if_then_else (match_operand:XF 3 "mult_operator" "")
14864 (const_string "fmul")
14865 (const_string "fop")))
14866 (set_attr "mode" "XF")])
14867
14868 (define_insn "*fop_xf_1_i387"
14869 [(set (match_operand:XF 0 "register_operand" "=f,f")
14870 (match_operator:XF 3 "binary_fp_operator"
14871 [(match_operand:XF 1 "register_operand" "0,f")
14872 (match_operand:XF 2 "register_operand" "f,0")]))]
14873 "TARGET_80387
14874 && !COMMUTATIVE_ARITH_P (operands[3])"
14875 "* return output_387_binary_op (insn, operands);"
14876 [(set (attr "type")
14877 (cond [(match_operand:XF 3 "mult_operator" "")
14878 (const_string "fmul")
14879 (match_operand:XF 3 "div_operator" "")
14880 (const_string "fdiv")
14881 ]
14882 (const_string "fop")))
14883 (set_attr "mode" "XF")])
14884
14885 (define_insn "*fop_xf_2<mode>_i387"
14886 [(set (match_operand:XF 0 "register_operand" "=f,f")
14887 (match_operator:XF 3 "binary_fp_operator"
14888 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14889 (match_operand:XF 2 "register_operand" "0,0")]))]
14890 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14891 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14892 [(set (attr "type")
14893 (cond [(match_operand:XF 3 "mult_operator" "")
14894 (const_string "fmul")
14895 (match_operand:XF 3 "div_operator" "")
14896 (const_string "fdiv")
14897 ]
14898 (const_string "fop")))
14899 (set_attr "fp_int_src" "true")
14900 (set_attr "mode" "<MODE>")])
14901
14902 (define_insn "*fop_xf_3<mode>_i387"
14903 [(set (match_operand:XF 0 "register_operand" "=f,f")
14904 (match_operator:XF 3 "binary_fp_operator"
14905 [(match_operand:XF 1 "register_operand" "0,0")
14906 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14907 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14908 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14909 [(set (attr "type")
14910 (cond [(match_operand:XF 3 "mult_operator" "")
14911 (const_string "fmul")
14912 (match_operand:XF 3 "div_operator" "")
14913 (const_string "fdiv")
14914 ]
14915 (const_string "fop")))
14916 (set_attr "fp_int_src" "true")
14917 (set_attr "mode" "<MODE>")])
14918
14919 (define_insn "*fop_xf_4_i387"
14920 [(set (match_operand:XF 0 "register_operand" "=f,f")
14921 (match_operator:XF 3 "binary_fp_operator"
14922 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14923 (match_operand:XF 2 "register_operand" "0,f")]))]
14924 "TARGET_80387"
14925 "* return output_387_binary_op (insn, operands);"
14926 [(set (attr "type")
14927 (cond [(match_operand:XF 3 "mult_operator" "")
14928 (const_string "fmul")
14929 (match_operand:XF 3 "div_operator" "")
14930 (const_string "fdiv")
14931 ]
14932 (const_string "fop")))
14933 (set_attr "mode" "SF")])
14934
14935 (define_insn "*fop_xf_5_i387"
14936 [(set (match_operand:XF 0 "register_operand" "=f,f")
14937 (match_operator:XF 3 "binary_fp_operator"
14938 [(match_operand:XF 1 "register_operand" "0,f")
14939 (float_extend:XF
14940 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14941 "TARGET_80387"
14942 "* return output_387_binary_op (insn, operands);"
14943 [(set (attr "type")
14944 (cond [(match_operand:XF 3 "mult_operator" "")
14945 (const_string "fmul")
14946 (match_operand:XF 3 "div_operator" "")
14947 (const_string "fdiv")
14948 ]
14949 (const_string "fop")))
14950 (set_attr "mode" "SF")])
14951
14952 (define_insn "*fop_xf_6_i387"
14953 [(set (match_operand:XF 0 "register_operand" "=f,f")
14954 (match_operator:XF 3 "binary_fp_operator"
14955 [(float_extend:XF
14956 (match_operand 1 "register_operand" "0,f"))
14957 (float_extend:XF
14958 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14959 "TARGET_80387"
14960 "* return output_387_binary_op (insn, operands);"
14961 [(set (attr "type")
14962 (cond [(match_operand:XF 3 "mult_operator" "")
14963 (const_string "fmul")
14964 (match_operand:XF 3 "div_operator" "")
14965 (const_string "fdiv")
14966 ]
14967 (const_string "fop")))
14968 (set_attr "mode" "SF")])
14969
14970 (define_split
14971 [(set (match_operand 0 "register_operand" "")
14972 (match_operator 3 "binary_fp_operator"
14973 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14974 (match_operand 2 "register_operand" "")]))]
14975 "TARGET_80387 && reload_completed
14976 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14977 [(const_int 0)]
14978 {
14979 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14980 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14981 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14982 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14983 GET_MODE (operands[3]),
14984 operands[4],
14985 operands[2])));
14986 ix86_free_from_memory (GET_MODE (operands[1]));
14987 DONE;
14988 })
14989
14990 (define_split
14991 [(set (match_operand 0 "register_operand" "")
14992 (match_operator 3 "binary_fp_operator"
14993 [(match_operand 1 "register_operand" "")
14994 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14995 "TARGET_80387 && reload_completed
14996 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14997 [(const_int 0)]
14998 {
14999 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15000 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15001 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15002 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15003 GET_MODE (operands[3]),
15004 operands[1],
15005 operands[4])));
15006 ix86_free_from_memory (GET_MODE (operands[2]));
15007 DONE;
15008 })
15009 \f
15010 ;; FPU special functions.
15011
15012 (define_expand "sqrtsf2"
15013 [(set (match_operand:SF 0 "register_operand" "")
15014 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15015 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15016 {
15017 if (!TARGET_SSE_MATH)
15018 operands[1] = force_reg (SFmode, operands[1]);
15019 })
15020
15021 (define_insn "*sqrtsf2_mixed"
15022 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15023 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15024 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15025 "@
15026 fsqrt
15027 sqrtss\t{%1, %0|%0, %1}"
15028 [(set_attr "type" "fpspc,sse")
15029 (set_attr "mode" "SF,SF")
15030 (set_attr "athlon_decode" "direct,*")])
15031
15032 (define_insn "*sqrtsf2_sse"
15033 [(set (match_operand:SF 0 "register_operand" "=x")
15034 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15035 "TARGET_SSE_MATH"
15036 "sqrtss\t{%1, %0|%0, %1}"
15037 [(set_attr "type" "sse")
15038 (set_attr "mode" "SF")
15039 (set_attr "athlon_decode" "*")])
15040
15041 (define_insn "*sqrtsf2_i387"
15042 [(set (match_operand:SF 0 "register_operand" "=f")
15043 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15044 "TARGET_USE_FANCY_MATH_387"
15045 "fsqrt"
15046 [(set_attr "type" "fpspc")
15047 (set_attr "mode" "SF")
15048 (set_attr "athlon_decode" "direct")])
15049
15050 (define_expand "sqrtdf2"
15051 [(set (match_operand:DF 0 "register_operand" "")
15052 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15053 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15054 {
15055 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15056 operands[1] = force_reg (DFmode, operands[1]);
15057 })
15058
15059 (define_insn "*sqrtdf2_mixed"
15060 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15061 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15062 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15063 "@
15064 fsqrt
15065 sqrtsd\t{%1, %0|%0, %1}"
15066 [(set_attr "type" "fpspc,sse")
15067 (set_attr "mode" "DF,DF")
15068 (set_attr "athlon_decode" "direct,*")])
15069
15070 (define_insn "*sqrtdf2_sse"
15071 [(set (match_operand:DF 0 "register_operand" "=Y")
15072 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15073 "TARGET_SSE2 && TARGET_SSE_MATH"
15074 "sqrtsd\t{%1, %0|%0, %1}"
15075 [(set_attr "type" "sse")
15076 (set_attr "mode" "DF")
15077 (set_attr "athlon_decode" "*")])
15078
15079 (define_insn "*sqrtdf2_i387"
15080 [(set (match_operand:DF 0 "register_operand" "=f")
15081 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15082 "TARGET_USE_FANCY_MATH_387"
15083 "fsqrt"
15084 [(set_attr "type" "fpspc")
15085 (set_attr "mode" "DF")
15086 (set_attr "athlon_decode" "direct")])
15087
15088 (define_insn "*sqrtextendsfdf2_i387"
15089 [(set (match_operand:DF 0 "register_operand" "=f")
15090 (sqrt:DF (float_extend:DF
15091 (match_operand:SF 1 "register_operand" "0"))))]
15092 "TARGET_USE_FANCY_MATH_387
15093 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15094 "fsqrt"
15095 [(set_attr "type" "fpspc")
15096 (set_attr "mode" "DF")
15097 (set_attr "athlon_decode" "direct")])
15098
15099 (define_insn "sqrtxf2"
15100 [(set (match_operand:XF 0 "register_operand" "=f")
15101 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15102 "TARGET_USE_FANCY_MATH_387
15103 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15104 "fsqrt"
15105 [(set_attr "type" "fpspc")
15106 (set_attr "mode" "XF")
15107 (set_attr "athlon_decode" "direct")])
15108
15109 (define_insn "*sqrtextendsfxf2_i387"
15110 [(set (match_operand:XF 0 "register_operand" "=f")
15111 (sqrt:XF (float_extend:XF
15112 (match_operand:SF 1 "register_operand" "0"))))]
15113 "TARGET_USE_FANCY_MATH_387"
15114 "fsqrt"
15115 [(set_attr "type" "fpspc")
15116 (set_attr "mode" "XF")
15117 (set_attr "athlon_decode" "direct")])
15118
15119 (define_insn "*sqrtextenddfxf2_i387"
15120 [(set (match_operand:XF 0 "register_operand" "=f")
15121 (sqrt:XF (float_extend:XF
15122 (match_operand:DF 1 "register_operand" "0"))))]
15123 "TARGET_USE_FANCY_MATH_387"
15124 "fsqrt"
15125 [(set_attr "type" "fpspc")
15126 (set_attr "mode" "XF")
15127 (set_attr "athlon_decode" "direct")])
15128
15129 (define_insn "fpremxf4"
15130 [(set (match_operand:XF 0 "register_operand" "=f")
15131 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15132 (match_operand:XF 3 "register_operand" "1")]
15133 UNSPEC_FPREM_F))
15134 (set (match_operand:XF 1 "register_operand" "=u")
15135 (unspec:XF [(match_dup 2) (match_dup 3)]
15136 UNSPEC_FPREM_U))
15137 (set (reg:CCFP FPSR_REG)
15138 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15139 "TARGET_USE_FANCY_MATH_387
15140 && flag_unsafe_math_optimizations"
15141 "fprem"
15142 [(set_attr "type" "fpspc")
15143 (set_attr "mode" "XF")])
15144
15145 (define_expand "fmodsf3"
15146 [(use (match_operand:SF 0 "register_operand" ""))
15147 (use (match_operand:SF 1 "register_operand" ""))
15148 (use (match_operand:SF 2 "register_operand" ""))]
15149 "TARGET_USE_FANCY_MATH_387
15150 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15151 && flag_unsafe_math_optimizations"
15152 {
15153 rtx label = gen_label_rtx ();
15154
15155 rtx op1 = gen_reg_rtx (XFmode);
15156 rtx op2 = gen_reg_rtx (XFmode);
15157
15158 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15159 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15160
15161 emit_label (label);
15162
15163 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15164 ix86_emit_fp_unordered_jump (label);
15165
15166 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15167 DONE;
15168 })
15169
15170 (define_expand "fmoddf3"
15171 [(use (match_operand:DF 0 "register_operand" ""))
15172 (use (match_operand:DF 1 "register_operand" ""))
15173 (use (match_operand:DF 2 "register_operand" ""))]
15174 "TARGET_USE_FANCY_MATH_387
15175 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15176 && flag_unsafe_math_optimizations"
15177 {
15178 rtx label = gen_label_rtx ();
15179
15180 rtx op1 = gen_reg_rtx (XFmode);
15181 rtx op2 = gen_reg_rtx (XFmode);
15182
15183 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15184 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15185
15186 emit_label (label);
15187
15188 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15189 ix86_emit_fp_unordered_jump (label);
15190
15191 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15192 DONE;
15193 })
15194
15195 (define_expand "fmodxf3"
15196 [(use (match_operand:XF 0 "register_operand" ""))
15197 (use (match_operand:XF 1 "register_operand" ""))
15198 (use (match_operand:XF 2 "register_operand" ""))]
15199 "TARGET_USE_FANCY_MATH_387
15200 && flag_unsafe_math_optimizations"
15201 {
15202 rtx label = gen_label_rtx ();
15203
15204 emit_label (label);
15205
15206 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15207 operands[1], operands[2]));
15208 ix86_emit_fp_unordered_jump (label);
15209
15210 emit_move_insn (operands[0], operands[1]);
15211 DONE;
15212 })
15213
15214 (define_insn "fprem1xf4"
15215 [(set (match_operand:XF 0 "register_operand" "=f")
15216 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15217 (match_operand:XF 3 "register_operand" "1")]
15218 UNSPEC_FPREM1_F))
15219 (set (match_operand:XF 1 "register_operand" "=u")
15220 (unspec:XF [(match_dup 2) (match_dup 3)]
15221 UNSPEC_FPREM1_U))
15222 (set (reg:CCFP FPSR_REG)
15223 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15224 "TARGET_USE_FANCY_MATH_387
15225 && flag_unsafe_math_optimizations"
15226 "fprem1"
15227 [(set_attr "type" "fpspc")
15228 (set_attr "mode" "XF")])
15229
15230 (define_expand "dremsf3"
15231 [(use (match_operand:SF 0 "register_operand" ""))
15232 (use (match_operand:SF 1 "register_operand" ""))
15233 (use (match_operand:SF 2 "register_operand" ""))]
15234 "TARGET_USE_FANCY_MATH_387
15235 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15236 && flag_unsafe_math_optimizations"
15237 {
15238 rtx label = gen_label_rtx ();
15239
15240 rtx op1 = gen_reg_rtx (XFmode);
15241 rtx op2 = gen_reg_rtx (XFmode);
15242
15243 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15244 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15245
15246 emit_label (label);
15247
15248 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15249 ix86_emit_fp_unordered_jump (label);
15250
15251 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15252 DONE;
15253 })
15254
15255 (define_expand "dremdf3"
15256 [(use (match_operand:DF 0 "register_operand" ""))
15257 (use (match_operand:DF 1 "register_operand" ""))
15258 (use (match_operand:DF 2 "register_operand" ""))]
15259 "TARGET_USE_FANCY_MATH_387
15260 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15261 && flag_unsafe_math_optimizations"
15262 {
15263 rtx label = gen_label_rtx ();
15264
15265 rtx op1 = gen_reg_rtx (XFmode);
15266 rtx op2 = gen_reg_rtx (XFmode);
15267
15268 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15269 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15270
15271 emit_label (label);
15272
15273 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15274 ix86_emit_fp_unordered_jump (label);
15275
15276 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15277 DONE;
15278 })
15279
15280 (define_expand "dremxf3"
15281 [(use (match_operand:XF 0 "register_operand" ""))
15282 (use (match_operand:XF 1 "register_operand" ""))
15283 (use (match_operand:XF 2 "register_operand" ""))]
15284 "TARGET_USE_FANCY_MATH_387
15285 && flag_unsafe_math_optimizations"
15286 {
15287 rtx label = gen_label_rtx ();
15288
15289 emit_label (label);
15290
15291 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15292 operands[1], operands[2]));
15293 ix86_emit_fp_unordered_jump (label);
15294
15295 emit_move_insn (operands[0], operands[1]);
15296 DONE;
15297 })
15298
15299 (define_insn "*sindf2"
15300 [(set (match_operand:DF 0 "register_operand" "=f")
15301 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15302 "TARGET_USE_FANCY_MATH_387
15303 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15304 && flag_unsafe_math_optimizations"
15305 "fsin"
15306 [(set_attr "type" "fpspc")
15307 (set_attr "mode" "DF")])
15308
15309 (define_insn "*sinsf2"
15310 [(set (match_operand:SF 0 "register_operand" "=f")
15311 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15312 "TARGET_USE_FANCY_MATH_387
15313 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15314 && flag_unsafe_math_optimizations"
15315 "fsin"
15316 [(set_attr "type" "fpspc")
15317 (set_attr "mode" "SF")])
15318
15319 (define_insn "*sinextendsfdf2"
15320 [(set (match_operand:DF 0 "register_operand" "=f")
15321 (unspec:DF [(float_extend:DF
15322 (match_operand:SF 1 "register_operand" "0"))]
15323 UNSPEC_SIN))]
15324 "TARGET_USE_FANCY_MATH_387
15325 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15326 && flag_unsafe_math_optimizations"
15327 "fsin"
15328 [(set_attr "type" "fpspc")
15329 (set_attr "mode" "DF")])
15330
15331 (define_insn "*sinxf2"
15332 [(set (match_operand:XF 0 "register_operand" "=f")
15333 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15334 "TARGET_USE_FANCY_MATH_387
15335 && flag_unsafe_math_optimizations"
15336 "fsin"
15337 [(set_attr "type" "fpspc")
15338 (set_attr "mode" "XF")])
15339
15340 (define_insn "*cosdf2"
15341 [(set (match_operand:DF 0 "register_operand" "=f")
15342 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15343 "TARGET_USE_FANCY_MATH_387
15344 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15345 && flag_unsafe_math_optimizations"
15346 "fcos"
15347 [(set_attr "type" "fpspc")
15348 (set_attr "mode" "DF")])
15349
15350 (define_insn "*cossf2"
15351 [(set (match_operand:SF 0 "register_operand" "=f")
15352 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15353 "TARGET_USE_FANCY_MATH_387
15354 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15355 && flag_unsafe_math_optimizations"
15356 "fcos"
15357 [(set_attr "type" "fpspc")
15358 (set_attr "mode" "SF")])
15359
15360 (define_insn "*cosextendsfdf2"
15361 [(set (match_operand:DF 0 "register_operand" "=f")
15362 (unspec:DF [(float_extend:DF
15363 (match_operand:SF 1 "register_operand" "0"))]
15364 UNSPEC_COS))]
15365 "TARGET_USE_FANCY_MATH_387
15366 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15367 && flag_unsafe_math_optimizations"
15368 "fcos"
15369 [(set_attr "type" "fpspc")
15370 (set_attr "mode" "DF")])
15371
15372 (define_insn "*cosxf2"
15373 [(set (match_operand:XF 0 "register_operand" "=f")
15374 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15375 "TARGET_USE_FANCY_MATH_387
15376 && flag_unsafe_math_optimizations"
15377 "fcos"
15378 [(set_attr "type" "fpspc")
15379 (set_attr "mode" "XF")])
15380
15381 ;; With sincos pattern defined, sin and cos builtin function will be
15382 ;; expanded to sincos pattern with one of its outputs left unused.
15383 ;; Cse pass will detected, if two sincos patterns can be combined,
15384 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15385 ;; depending on the unused output.
15386
15387 (define_insn "sincosdf3"
15388 [(set (match_operand:DF 0 "register_operand" "=f")
15389 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15390 UNSPEC_SINCOS_COS))
15391 (set (match_operand:DF 1 "register_operand" "=u")
15392 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15393 "TARGET_USE_FANCY_MATH_387
15394 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15395 && flag_unsafe_math_optimizations"
15396 "fsincos"
15397 [(set_attr "type" "fpspc")
15398 (set_attr "mode" "DF")])
15399
15400 (define_split
15401 [(set (match_operand:DF 0 "register_operand" "")
15402 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15403 UNSPEC_SINCOS_COS))
15404 (set (match_operand:DF 1 "register_operand" "")
15405 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15406 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15407 && !reload_completed && !reload_in_progress"
15408 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15409 "")
15410
15411 (define_split
15412 [(set (match_operand:DF 0 "register_operand" "")
15413 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15414 UNSPEC_SINCOS_COS))
15415 (set (match_operand:DF 1 "register_operand" "")
15416 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15417 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15418 && !reload_completed && !reload_in_progress"
15419 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15420 "")
15421
15422 (define_insn "sincossf3"
15423 [(set (match_operand:SF 0 "register_operand" "=f")
15424 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15425 UNSPEC_SINCOS_COS))
15426 (set (match_operand:SF 1 "register_operand" "=u")
15427 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15428 "TARGET_USE_FANCY_MATH_387
15429 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15430 && flag_unsafe_math_optimizations"
15431 "fsincos"
15432 [(set_attr "type" "fpspc")
15433 (set_attr "mode" "SF")])
15434
15435 (define_split
15436 [(set (match_operand:SF 0 "register_operand" "")
15437 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15438 UNSPEC_SINCOS_COS))
15439 (set (match_operand:SF 1 "register_operand" "")
15440 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15441 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15442 && !reload_completed && !reload_in_progress"
15443 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15444 "")
15445
15446 (define_split
15447 [(set (match_operand:SF 0 "register_operand" "")
15448 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15449 UNSPEC_SINCOS_COS))
15450 (set (match_operand:SF 1 "register_operand" "")
15451 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15452 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15453 && !reload_completed && !reload_in_progress"
15454 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15455 "")
15456
15457 (define_insn "*sincosextendsfdf3"
15458 [(set (match_operand:DF 0 "register_operand" "=f")
15459 (unspec:DF [(float_extend:DF
15460 (match_operand:SF 2 "register_operand" "0"))]
15461 UNSPEC_SINCOS_COS))
15462 (set (match_operand:DF 1 "register_operand" "=u")
15463 (unspec:DF [(float_extend:DF
15464 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15465 "TARGET_USE_FANCY_MATH_387
15466 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15467 && flag_unsafe_math_optimizations"
15468 "fsincos"
15469 [(set_attr "type" "fpspc")
15470 (set_attr "mode" "DF")])
15471
15472 (define_split
15473 [(set (match_operand:DF 0 "register_operand" "")
15474 (unspec:DF [(float_extend:DF
15475 (match_operand:SF 2 "register_operand" ""))]
15476 UNSPEC_SINCOS_COS))
15477 (set (match_operand:DF 1 "register_operand" "")
15478 (unspec:DF [(float_extend:DF
15479 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15480 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15481 && !reload_completed && !reload_in_progress"
15482 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15483 (match_dup 2))] UNSPEC_SIN))]
15484 "")
15485
15486 (define_split
15487 [(set (match_operand:DF 0 "register_operand" "")
15488 (unspec:DF [(float_extend:DF
15489 (match_operand:SF 2 "register_operand" ""))]
15490 UNSPEC_SINCOS_COS))
15491 (set (match_operand:DF 1 "register_operand" "")
15492 (unspec:DF [(float_extend:DF
15493 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15494 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15495 && !reload_completed && !reload_in_progress"
15496 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15497 (match_dup 2))] UNSPEC_COS))]
15498 "")
15499
15500 (define_insn "sincosxf3"
15501 [(set (match_operand:XF 0 "register_operand" "=f")
15502 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15503 UNSPEC_SINCOS_COS))
15504 (set (match_operand:XF 1 "register_operand" "=u")
15505 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15506 "TARGET_USE_FANCY_MATH_387
15507 && flag_unsafe_math_optimizations"
15508 "fsincos"
15509 [(set_attr "type" "fpspc")
15510 (set_attr "mode" "XF")])
15511
15512 (define_split
15513 [(set (match_operand:XF 0 "register_operand" "")
15514 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15515 UNSPEC_SINCOS_COS))
15516 (set (match_operand:XF 1 "register_operand" "")
15517 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15518 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15519 && !reload_completed && !reload_in_progress"
15520 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15521 "")
15522
15523 (define_split
15524 [(set (match_operand:XF 0 "register_operand" "")
15525 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15526 UNSPEC_SINCOS_COS))
15527 (set (match_operand:XF 1 "register_operand" "")
15528 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15529 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15530 && !reload_completed && !reload_in_progress"
15531 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15532 "")
15533
15534 (define_insn "*tandf3_1"
15535 [(set (match_operand:DF 0 "register_operand" "=f")
15536 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15537 UNSPEC_TAN_ONE))
15538 (set (match_operand:DF 1 "register_operand" "=u")
15539 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15540 "TARGET_USE_FANCY_MATH_387
15541 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15542 && flag_unsafe_math_optimizations"
15543 "fptan"
15544 [(set_attr "type" "fpspc")
15545 (set_attr "mode" "DF")])
15546
15547 ;; optimize sequence: fptan
15548 ;; fstp %st(0)
15549 ;; fld1
15550 ;; into fptan insn.
15551
15552 (define_peephole2
15553 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15554 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15555 UNSPEC_TAN_ONE))
15556 (set (match_operand:DF 1 "register_operand" "")
15557 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15558 (set (match_dup 0)
15559 (match_operand:DF 3 "immediate_operand" ""))]
15560 "standard_80387_constant_p (operands[3]) == 2"
15561 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15562 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15563 "")
15564
15565 (define_expand "tandf2"
15566 [(parallel [(set (match_dup 2)
15567 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15568 UNSPEC_TAN_ONE))
15569 (set (match_operand:DF 0 "register_operand" "")
15570 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15571 "TARGET_USE_FANCY_MATH_387
15572 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15573 && flag_unsafe_math_optimizations"
15574 {
15575 operands[2] = gen_reg_rtx (DFmode);
15576 })
15577
15578 (define_insn "*tansf3_1"
15579 [(set (match_operand:SF 0 "register_operand" "=f")
15580 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15581 UNSPEC_TAN_ONE))
15582 (set (match_operand:SF 1 "register_operand" "=u")
15583 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15584 "TARGET_USE_FANCY_MATH_387
15585 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15586 && flag_unsafe_math_optimizations"
15587 "fptan"
15588 [(set_attr "type" "fpspc")
15589 (set_attr "mode" "SF")])
15590
15591 ;; optimize sequence: fptan
15592 ;; fstp %st(0)
15593 ;; fld1
15594 ;; into fptan insn.
15595
15596 (define_peephole2
15597 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15598 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15599 UNSPEC_TAN_ONE))
15600 (set (match_operand:SF 1 "register_operand" "")
15601 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15602 (set (match_dup 0)
15603 (match_operand:SF 3 "immediate_operand" ""))]
15604 "standard_80387_constant_p (operands[3]) == 2"
15605 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15606 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15607 "")
15608
15609 (define_expand "tansf2"
15610 [(parallel [(set (match_dup 2)
15611 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15612 UNSPEC_TAN_ONE))
15613 (set (match_operand:SF 0 "register_operand" "")
15614 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15615 "TARGET_USE_FANCY_MATH_387
15616 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15617 && flag_unsafe_math_optimizations"
15618 {
15619 operands[2] = gen_reg_rtx (SFmode);
15620 })
15621
15622 (define_insn "*tanxf3_1"
15623 [(set (match_operand:XF 0 "register_operand" "=f")
15624 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15625 UNSPEC_TAN_ONE))
15626 (set (match_operand:XF 1 "register_operand" "=u")
15627 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15628 "TARGET_USE_FANCY_MATH_387
15629 && flag_unsafe_math_optimizations"
15630 "fptan"
15631 [(set_attr "type" "fpspc")
15632 (set_attr "mode" "XF")])
15633
15634 ;; optimize sequence: fptan
15635 ;; fstp %st(0)
15636 ;; fld1
15637 ;; into fptan insn.
15638
15639 (define_peephole2
15640 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15641 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15642 UNSPEC_TAN_ONE))
15643 (set (match_operand:XF 1 "register_operand" "")
15644 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15645 (set (match_dup 0)
15646 (match_operand:XF 3 "immediate_operand" ""))]
15647 "standard_80387_constant_p (operands[3]) == 2"
15648 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15649 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15650 "")
15651
15652 (define_expand "tanxf2"
15653 [(parallel [(set (match_dup 2)
15654 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15655 UNSPEC_TAN_ONE))
15656 (set (match_operand:XF 0 "register_operand" "")
15657 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15658 "TARGET_USE_FANCY_MATH_387
15659 && flag_unsafe_math_optimizations"
15660 {
15661 operands[2] = gen_reg_rtx (XFmode);
15662 })
15663
15664 (define_insn "atan2df3_1"
15665 [(set (match_operand:DF 0 "register_operand" "=f")
15666 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15667 (match_operand:DF 1 "register_operand" "u")]
15668 UNSPEC_FPATAN))
15669 (clobber (match_scratch:DF 3 "=1"))]
15670 "TARGET_USE_FANCY_MATH_387
15671 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15672 && flag_unsafe_math_optimizations"
15673 "fpatan"
15674 [(set_attr "type" "fpspc")
15675 (set_attr "mode" "DF")])
15676
15677 (define_expand "atan2df3"
15678 [(use (match_operand:DF 0 "register_operand" ""))
15679 (use (match_operand:DF 2 "register_operand" ""))
15680 (use (match_operand:DF 1 "register_operand" ""))]
15681 "TARGET_USE_FANCY_MATH_387
15682 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15683 && flag_unsafe_math_optimizations"
15684 {
15685 rtx copy = gen_reg_rtx (DFmode);
15686 emit_move_insn (copy, operands[1]);
15687 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15688 DONE;
15689 })
15690
15691 (define_expand "atandf2"
15692 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15693 (unspec:DF [(match_dup 2)
15694 (match_operand:DF 1 "register_operand" "")]
15695 UNSPEC_FPATAN))
15696 (clobber (match_scratch:DF 3 ""))])]
15697 "TARGET_USE_FANCY_MATH_387
15698 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15699 && flag_unsafe_math_optimizations"
15700 {
15701 operands[2] = gen_reg_rtx (DFmode);
15702 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15703 })
15704
15705 (define_insn "atan2sf3_1"
15706 [(set (match_operand:SF 0 "register_operand" "=f")
15707 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15708 (match_operand:SF 1 "register_operand" "u")]
15709 UNSPEC_FPATAN))
15710 (clobber (match_scratch:SF 3 "=1"))]
15711 "TARGET_USE_FANCY_MATH_387
15712 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15713 && flag_unsafe_math_optimizations"
15714 "fpatan"
15715 [(set_attr "type" "fpspc")
15716 (set_attr "mode" "SF")])
15717
15718 (define_expand "atan2sf3"
15719 [(use (match_operand:SF 0 "register_operand" ""))
15720 (use (match_operand:SF 2 "register_operand" ""))
15721 (use (match_operand:SF 1 "register_operand" ""))]
15722 "TARGET_USE_FANCY_MATH_387
15723 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15724 && flag_unsafe_math_optimizations"
15725 {
15726 rtx copy = gen_reg_rtx (SFmode);
15727 emit_move_insn (copy, operands[1]);
15728 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15729 DONE;
15730 })
15731
15732 (define_expand "atansf2"
15733 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15734 (unspec:SF [(match_dup 2)
15735 (match_operand:SF 1 "register_operand" "")]
15736 UNSPEC_FPATAN))
15737 (clobber (match_scratch:SF 3 ""))])]
15738 "TARGET_USE_FANCY_MATH_387
15739 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15740 && flag_unsafe_math_optimizations"
15741 {
15742 operands[2] = gen_reg_rtx (SFmode);
15743 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15744 })
15745
15746 (define_insn "atan2xf3_1"
15747 [(set (match_operand:XF 0 "register_operand" "=f")
15748 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15749 (match_operand:XF 1 "register_operand" "u")]
15750 UNSPEC_FPATAN))
15751 (clobber (match_scratch:XF 3 "=1"))]
15752 "TARGET_USE_FANCY_MATH_387
15753 && flag_unsafe_math_optimizations"
15754 "fpatan"
15755 [(set_attr "type" "fpspc")
15756 (set_attr "mode" "XF")])
15757
15758 (define_expand "atan2xf3"
15759 [(use (match_operand:XF 0 "register_operand" ""))
15760 (use (match_operand:XF 2 "register_operand" ""))
15761 (use (match_operand:XF 1 "register_operand" ""))]
15762 "TARGET_USE_FANCY_MATH_387
15763 && flag_unsafe_math_optimizations"
15764 {
15765 rtx copy = gen_reg_rtx (XFmode);
15766 emit_move_insn (copy, operands[1]);
15767 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15768 DONE;
15769 })
15770
15771 (define_expand "atanxf2"
15772 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15773 (unspec:XF [(match_dup 2)
15774 (match_operand:XF 1 "register_operand" "")]
15775 UNSPEC_FPATAN))
15776 (clobber (match_scratch:XF 3 ""))])]
15777 "TARGET_USE_FANCY_MATH_387
15778 && flag_unsafe_math_optimizations"
15779 {
15780 operands[2] = gen_reg_rtx (XFmode);
15781 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15782 })
15783
15784 (define_expand "asindf2"
15785 [(set (match_dup 2)
15786 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15787 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15788 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15789 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15790 (parallel [(set (match_dup 7)
15791 (unspec:XF [(match_dup 6) (match_dup 2)]
15792 UNSPEC_FPATAN))
15793 (clobber (match_scratch:XF 8 ""))])
15794 (set (match_operand:DF 0 "register_operand" "")
15795 (float_truncate:DF (match_dup 7)))]
15796 "TARGET_USE_FANCY_MATH_387
15797 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15798 && flag_unsafe_math_optimizations"
15799 {
15800 int i;
15801
15802 for (i=2; i<8; i++)
15803 operands[i] = gen_reg_rtx (XFmode);
15804
15805 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15806 })
15807
15808 (define_expand "asinsf2"
15809 [(set (match_dup 2)
15810 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15811 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15812 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15813 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15814 (parallel [(set (match_dup 7)
15815 (unspec:XF [(match_dup 6) (match_dup 2)]
15816 UNSPEC_FPATAN))
15817 (clobber (match_scratch:XF 8 ""))])
15818 (set (match_operand:SF 0 "register_operand" "")
15819 (float_truncate:SF (match_dup 7)))]
15820 "TARGET_USE_FANCY_MATH_387
15821 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15822 && flag_unsafe_math_optimizations"
15823 {
15824 int i;
15825
15826 for (i=2; i<8; i++)
15827 operands[i] = gen_reg_rtx (XFmode);
15828
15829 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15830 })
15831
15832 (define_expand "asinxf2"
15833 [(set (match_dup 2)
15834 (mult:XF (match_operand:XF 1 "register_operand" "")
15835 (match_dup 1)))
15836 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15837 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15838 (parallel [(set (match_operand:XF 0 "register_operand" "")
15839 (unspec:XF [(match_dup 5) (match_dup 1)]
15840 UNSPEC_FPATAN))
15841 (clobber (match_scratch:XF 6 ""))])]
15842 "TARGET_USE_FANCY_MATH_387
15843 && flag_unsafe_math_optimizations"
15844 {
15845 int i;
15846
15847 for (i=2; i<6; i++)
15848 operands[i] = gen_reg_rtx (XFmode);
15849
15850 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15851 })
15852
15853 (define_expand "acosdf2"
15854 [(set (match_dup 2)
15855 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15856 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15857 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15858 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15859 (parallel [(set (match_dup 7)
15860 (unspec:XF [(match_dup 2) (match_dup 6)]
15861 UNSPEC_FPATAN))
15862 (clobber (match_scratch:XF 8 ""))])
15863 (set (match_operand:DF 0 "register_operand" "")
15864 (float_truncate:DF (match_dup 7)))]
15865 "TARGET_USE_FANCY_MATH_387
15866 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15867 && flag_unsafe_math_optimizations"
15868 {
15869 int i;
15870
15871 for (i=2; i<8; i++)
15872 operands[i] = gen_reg_rtx (XFmode);
15873
15874 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15875 })
15876
15877 (define_expand "acossf2"
15878 [(set (match_dup 2)
15879 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15880 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15881 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15882 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15883 (parallel [(set (match_dup 7)
15884 (unspec:XF [(match_dup 2) (match_dup 6)]
15885 UNSPEC_FPATAN))
15886 (clobber (match_scratch:XF 8 ""))])
15887 (set (match_operand:SF 0 "register_operand" "")
15888 (float_truncate:SF (match_dup 7)))]
15889 "TARGET_USE_FANCY_MATH_387
15890 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15891 && flag_unsafe_math_optimizations"
15892 {
15893 int i;
15894
15895 for (i=2; i<8; i++)
15896 operands[i] = gen_reg_rtx (XFmode);
15897
15898 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15899 })
15900
15901 (define_expand "acosxf2"
15902 [(set (match_dup 2)
15903 (mult:XF (match_operand:XF 1 "register_operand" "")
15904 (match_dup 1)))
15905 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15906 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15907 (parallel [(set (match_operand:XF 0 "register_operand" "")
15908 (unspec:XF [(match_dup 1) (match_dup 5)]
15909 UNSPEC_FPATAN))
15910 (clobber (match_scratch:XF 6 ""))])]
15911 "TARGET_USE_FANCY_MATH_387
15912 && flag_unsafe_math_optimizations"
15913 {
15914 int i;
15915
15916 for (i=2; i<6; i++)
15917 operands[i] = gen_reg_rtx (XFmode);
15918
15919 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15920 })
15921
15922 (define_insn "fyl2x_xf3"
15923 [(set (match_operand:XF 0 "register_operand" "=f")
15924 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15925 (match_operand:XF 1 "register_operand" "u")]
15926 UNSPEC_FYL2X))
15927 (clobber (match_scratch:XF 3 "=1"))]
15928 "TARGET_USE_FANCY_MATH_387
15929 && flag_unsafe_math_optimizations"
15930 "fyl2x"
15931 [(set_attr "type" "fpspc")
15932 (set_attr "mode" "XF")])
15933
15934 (define_expand "logsf2"
15935 [(set (match_dup 2)
15936 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15937 (parallel [(set (match_dup 4)
15938 (unspec:XF [(match_dup 2)
15939 (match_dup 3)] UNSPEC_FYL2X))
15940 (clobber (match_scratch:XF 5 ""))])
15941 (set (match_operand:SF 0 "register_operand" "")
15942 (float_truncate:SF (match_dup 4)))]
15943 "TARGET_USE_FANCY_MATH_387
15944 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15945 && flag_unsafe_math_optimizations"
15946 {
15947 rtx temp;
15948
15949 operands[2] = gen_reg_rtx (XFmode);
15950 operands[3] = gen_reg_rtx (XFmode);
15951 operands[4] = gen_reg_rtx (XFmode);
15952
15953 temp = standard_80387_constant_rtx (4); /* fldln2 */
15954 emit_move_insn (operands[3], temp);
15955 })
15956
15957 (define_expand "logdf2"
15958 [(set (match_dup 2)
15959 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15960 (parallel [(set (match_dup 4)
15961 (unspec:XF [(match_dup 2)
15962 (match_dup 3)] UNSPEC_FYL2X))
15963 (clobber (match_scratch:XF 5 ""))])
15964 (set (match_operand:DF 0 "register_operand" "")
15965 (float_truncate:DF (match_dup 4)))]
15966 "TARGET_USE_FANCY_MATH_387
15967 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15968 && flag_unsafe_math_optimizations"
15969 {
15970 rtx temp;
15971
15972 operands[2] = gen_reg_rtx (XFmode);
15973 operands[3] = gen_reg_rtx (XFmode);
15974 operands[4] = gen_reg_rtx (XFmode);
15975
15976 temp = standard_80387_constant_rtx (4); /* fldln2 */
15977 emit_move_insn (operands[3], temp);
15978 })
15979
15980 (define_expand "logxf2"
15981 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15982 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15983 (match_dup 2)] UNSPEC_FYL2X))
15984 (clobber (match_scratch:XF 3 ""))])]
15985 "TARGET_USE_FANCY_MATH_387
15986 && flag_unsafe_math_optimizations"
15987 {
15988 rtx temp;
15989
15990 operands[2] = gen_reg_rtx (XFmode);
15991 temp = standard_80387_constant_rtx (4); /* fldln2 */
15992 emit_move_insn (operands[2], temp);
15993 })
15994
15995 (define_expand "log10sf2"
15996 [(set (match_dup 2)
15997 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15998 (parallel [(set (match_dup 4)
15999 (unspec:XF [(match_dup 2)
16000 (match_dup 3)] UNSPEC_FYL2X))
16001 (clobber (match_scratch:XF 5 ""))])
16002 (set (match_operand:SF 0 "register_operand" "")
16003 (float_truncate:SF (match_dup 4)))]
16004 "TARGET_USE_FANCY_MATH_387
16005 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16006 && flag_unsafe_math_optimizations"
16007 {
16008 rtx temp;
16009
16010 operands[2] = gen_reg_rtx (XFmode);
16011 operands[3] = gen_reg_rtx (XFmode);
16012 operands[4] = gen_reg_rtx (XFmode);
16013
16014 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16015 emit_move_insn (operands[3], temp);
16016 })
16017
16018 (define_expand "log10df2"
16019 [(set (match_dup 2)
16020 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16021 (parallel [(set (match_dup 4)
16022 (unspec:XF [(match_dup 2)
16023 (match_dup 3)] UNSPEC_FYL2X))
16024 (clobber (match_scratch:XF 5 ""))])
16025 (set (match_operand:DF 0 "register_operand" "")
16026 (float_truncate:DF (match_dup 4)))]
16027 "TARGET_USE_FANCY_MATH_387
16028 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16029 && flag_unsafe_math_optimizations"
16030 {
16031 rtx temp;
16032
16033 operands[2] = gen_reg_rtx (XFmode);
16034 operands[3] = gen_reg_rtx (XFmode);
16035 operands[4] = gen_reg_rtx (XFmode);
16036
16037 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16038 emit_move_insn (operands[3], temp);
16039 })
16040
16041 (define_expand "log10xf2"
16042 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16043 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16044 (match_dup 2)] UNSPEC_FYL2X))
16045 (clobber (match_scratch:XF 3 ""))])]
16046 "TARGET_USE_FANCY_MATH_387
16047 && flag_unsafe_math_optimizations"
16048 {
16049 rtx temp;
16050
16051 operands[2] = gen_reg_rtx (XFmode);
16052 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16053 emit_move_insn (operands[2], temp);
16054 })
16055
16056 (define_expand "log2sf2"
16057 [(set (match_dup 2)
16058 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16059 (parallel [(set (match_dup 4)
16060 (unspec:XF [(match_dup 2)
16061 (match_dup 3)] UNSPEC_FYL2X))
16062 (clobber (match_scratch:XF 5 ""))])
16063 (set (match_operand:SF 0 "register_operand" "")
16064 (float_truncate:SF (match_dup 4)))]
16065 "TARGET_USE_FANCY_MATH_387
16066 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16067 && flag_unsafe_math_optimizations"
16068 {
16069 operands[2] = gen_reg_rtx (XFmode);
16070 operands[3] = gen_reg_rtx (XFmode);
16071 operands[4] = gen_reg_rtx (XFmode);
16072
16073 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16074 })
16075
16076 (define_expand "log2df2"
16077 [(set (match_dup 2)
16078 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16079 (parallel [(set (match_dup 4)
16080 (unspec:XF [(match_dup 2)
16081 (match_dup 3)] UNSPEC_FYL2X))
16082 (clobber (match_scratch:XF 5 ""))])
16083 (set (match_operand:DF 0 "register_operand" "")
16084 (float_truncate:DF (match_dup 4)))]
16085 "TARGET_USE_FANCY_MATH_387
16086 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16087 && flag_unsafe_math_optimizations"
16088 {
16089 operands[2] = gen_reg_rtx (XFmode);
16090 operands[3] = gen_reg_rtx (XFmode);
16091 operands[4] = gen_reg_rtx (XFmode);
16092
16093 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16094 })
16095
16096 (define_expand "log2xf2"
16097 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16098 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16099 (match_dup 2)] UNSPEC_FYL2X))
16100 (clobber (match_scratch:XF 3 ""))])]
16101 "TARGET_USE_FANCY_MATH_387
16102 && flag_unsafe_math_optimizations"
16103 {
16104 operands[2] = gen_reg_rtx (XFmode);
16105 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16106 })
16107
16108 (define_insn "fyl2xp1_xf3"
16109 [(set (match_operand:XF 0 "register_operand" "=f")
16110 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16111 (match_operand:XF 1 "register_operand" "u")]
16112 UNSPEC_FYL2XP1))
16113 (clobber (match_scratch:XF 3 "=1"))]
16114 "TARGET_USE_FANCY_MATH_387
16115 && flag_unsafe_math_optimizations"
16116 "fyl2xp1"
16117 [(set_attr "type" "fpspc")
16118 (set_attr "mode" "XF")])
16119
16120 (define_expand "log1psf2"
16121 [(use (match_operand:SF 0 "register_operand" ""))
16122 (use (match_operand:SF 1 "register_operand" ""))]
16123 "TARGET_USE_FANCY_MATH_387
16124 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16125 && flag_unsafe_math_optimizations"
16126 {
16127 rtx op0 = gen_reg_rtx (XFmode);
16128 rtx op1 = gen_reg_rtx (XFmode);
16129
16130 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16131 ix86_emit_i387_log1p (op0, op1);
16132 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16133 DONE;
16134 })
16135
16136 (define_expand "log1pdf2"
16137 [(use (match_operand:DF 0 "register_operand" ""))
16138 (use (match_operand:DF 1 "register_operand" ""))]
16139 "TARGET_USE_FANCY_MATH_387
16140 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16141 && flag_unsafe_math_optimizations"
16142 {
16143 rtx op0 = gen_reg_rtx (XFmode);
16144 rtx op1 = gen_reg_rtx (XFmode);
16145
16146 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16147 ix86_emit_i387_log1p (op0, op1);
16148 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16149 DONE;
16150 })
16151
16152 (define_expand "log1pxf2"
16153 [(use (match_operand:XF 0 "register_operand" ""))
16154 (use (match_operand:XF 1 "register_operand" ""))]
16155 "TARGET_USE_FANCY_MATH_387
16156 && flag_unsafe_math_optimizations"
16157 {
16158 ix86_emit_i387_log1p (operands[0], operands[1]);
16159 DONE;
16160 })
16161
16162 (define_insn "*fxtractxf3"
16163 [(set (match_operand:XF 0 "register_operand" "=f")
16164 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16165 UNSPEC_XTRACT_FRACT))
16166 (set (match_operand:XF 1 "register_operand" "=u")
16167 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16168 "TARGET_USE_FANCY_MATH_387
16169 && flag_unsafe_math_optimizations"
16170 "fxtract"
16171 [(set_attr "type" "fpspc")
16172 (set_attr "mode" "XF")])
16173
16174 (define_expand "logbsf2"
16175 [(set (match_dup 2)
16176 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16177 (parallel [(set (match_dup 3)
16178 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16179 (set (match_dup 4)
16180 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16181 (set (match_operand:SF 0 "register_operand" "")
16182 (float_truncate:SF (match_dup 4)))]
16183 "TARGET_USE_FANCY_MATH_387
16184 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16185 && flag_unsafe_math_optimizations"
16186 {
16187 operands[2] = gen_reg_rtx (XFmode);
16188 operands[3] = gen_reg_rtx (XFmode);
16189 operands[4] = gen_reg_rtx (XFmode);
16190 })
16191
16192 (define_expand "logbdf2"
16193 [(set (match_dup 2)
16194 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16195 (parallel [(set (match_dup 3)
16196 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16197 (set (match_dup 4)
16198 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16199 (set (match_operand:DF 0 "register_operand" "")
16200 (float_truncate:DF (match_dup 4)))]
16201 "TARGET_USE_FANCY_MATH_387
16202 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16203 && flag_unsafe_math_optimizations"
16204 {
16205 operands[2] = gen_reg_rtx (XFmode);
16206 operands[3] = gen_reg_rtx (XFmode);
16207 operands[4] = gen_reg_rtx (XFmode);
16208 })
16209
16210 (define_expand "logbxf2"
16211 [(parallel [(set (match_dup 2)
16212 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16213 UNSPEC_XTRACT_FRACT))
16214 (set (match_operand:XF 0 "register_operand" "")
16215 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16216 "TARGET_USE_FANCY_MATH_387
16217 && flag_unsafe_math_optimizations"
16218 {
16219 operands[2] = gen_reg_rtx (XFmode);
16220 })
16221
16222 (define_expand "ilogbsi2"
16223 [(parallel [(set (match_dup 2)
16224 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16225 UNSPEC_XTRACT_FRACT))
16226 (set (match_operand:XF 3 "register_operand" "")
16227 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16228 (parallel [(set (match_operand:SI 0 "register_operand" "")
16229 (fix:SI (match_dup 3)))
16230 (clobber (reg:CC FLAGS_REG))])]
16231 "TARGET_USE_FANCY_MATH_387
16232 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16233 && flag_unsafe_math_optimizations"
16234 {
16235 operands[2] = gen_reg_rtx (XFmode);
16236 operands[3] = gen_reg_rtx (XFmode);
16237 })
16238
16239 (define_insn "*f2xm1xf2"
16240 [(set (match_operand:XF 0 "register_operand" "=f")
16241 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16242 UNSPEC_F2XM1))]
16243 "TARGET_USE_FANCY_MATH_387
16244 && flag_unsafe_math_optimizations"
16245 "f2xm1"
16246 [(set_attr "type" "fpspc")
16247 (set_attr "mode" "XF")])
16248
16249 (define_insn "*fscalexf4"
16250 [(set (match_operand:XF 0 "register_operand" "=f")
16251 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16252 (match_operand:XF 3 "register_operand" "1")]
16253 UNSPEC_FSCALE_FRACT))
16254 (set (match_operand:XF 1 "register_operand" "=u")
16255 (unspec:XF [(match_dup 2) (match_dup 3)]
16256 UNSPEC_FSCALE_EXP))]
16257 "TARGET_USE_FANCY_MATH_387
16258 && flag_unsafe_math_optimizations"
16259 "fscale"
16260 [(set_attr "type" "fpspc")
16261 (set_attr "mode" "XF")])
16262
16263 (define_expand "expsf2"
16264 [(set (match_dup 2)
16265 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16266 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16267 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16268 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16269 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16270 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16271 (parallel [(set (match_dup 10)
16272 (unspec:XF [(match_dup 9) (match_dup 5)]
16273 UNSPEC_FSCALE_FRACT))
16274 (set (match_dup 11)
16275 (unspec:XF [(match_dup 9) (match_dup 5)]
16276 UNSPEC_FSCALE_EXP))])
16277 (set (match_operand:SF 0 "register_operand" "")
16278 (float_truncate:SF (match_dup 10)))]
16279 "TARGET_USE_FANCY_MATH_387
16280 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16281 && flag_unsafe_math_optimizations"
16282 {
16283 rtx temp;
16284 int i;
16285
16286 for (i=2; i<12; i++)
16287 operands[i] = gen_reg_rtx (XFmode);
16288 temp = standard_80387_constant_rtx (5); /* fldl2e */
16289 emit_move_insn (operands[3], temp);
16290 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16291 })
16292
16293 (define_expand "expdf2"
16294 [(set (match_dup 2)
16295 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16296 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16297 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16298 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16299 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16300 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16301 (parallel [(set (match_dup 10)
16302 (unspec:XF [(match_dup 9) (match_dup 5)]
16303 UNSPEC_FSCALE_FRACT))
16304 (set (match_dup 11)
16305 (unspec:XF [(match_dup 9) (match_dup 5)]
16306 UNSPEC_FSCALE_EXP))])
16307 (set (match_operand:DF 0 "register_operand" "")
16308 (float_truncate:DF (match_dup 10)))]
16309 "TARGET_USE_FANCY_MATH_387
16310 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16311 && flag_unsafe_math_optimizations"
16312 {
16313 rtx temp;
16314 int i;
16315
16316 for (i=2; i<12; i++)
16317 operands[i] = gen_reg_rtx (XFmode);
16318 temp = standard_80387_constant_rtx (5); /* fldl2e */
16319 emit_move_insn (operands[3], temp);
16320 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16321 })
16322
16323 (define_expand "expxf2"
16324 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16325 (match_dup 2)))
16326 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16327 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16328 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16329 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16330 (parallel [(set (match_operand:XF 0 "register_operand" "")
16331 (unspec:XF [(match_dup 8) (match_dup 4)]
16332 UNSPEC_FSCALE_FRACT))
16333 (set (match_dup 9)
16334 (unspec:XF [(match_dup 8) (match_dup 4)]
16335 UNSPEC_FSCALE_EXP))])]
16336 "TARGET_USE_FANCY_MATH_387
16337 && flag_unsafe_math_optimizations"
16338 {
16339 rtx temp;
16340 int i;
16341
16342 for (i=2; i<10; i++)
16343 operands[i] = gen_reg_rtx (XFmode);
16344 temp = standard_80387_constant_rtx (5); /* fldl2e */
16345 emit_move_insn (operands[2], temp);
16346 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16347 })
16348
16349 (define_expand "exp10sf2"
16350 [(set (match_dup 2)
16351 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16352 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16353 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16354 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16355 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16356 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16357 (parallel [(set (match_dup 10)
16358 (unspec:XF [(match_dup 9) (match_dup 5)]
16359 UNSPEC_FSCALE_FRACT))
16360 (set (match_dup 11)
16361 (unspec:XF [(match_dup 9) (match_dup 5)]
16362 UNSPEC_FSCALE_EXP))])
16363 (set (match_operand:SF 0 "register_operand" "")
16364 (float_truncate:SF (match_dup 10)))]
16365 "TARGET_USE_FANCY_MATH_387
16366 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16367 && flag_unsafe_math_optimizations"
16368 {
16369 rtx temp;
16370 int i;
16371
16372 for (i=2; i<12; i++)
16373 operands[i] = gen_reg_rtx (XFmode);
16374 temp = standard_80387_constant_rtx (6); /* fldl2t */
16375 emit_move_insn (operands[3], temp);
16376 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16377 })
16378
16379 (define_expand "exp10df2"
16380 [(set (match_dup 2)
16381 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16382 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16383 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16384 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16385 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16386 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16387 (parallel [(set (match_dup 10)
16388 (unspec:XF [(match_dup 9) (match_dup 5)]
16389 UNSPEC_FSCALE_FRACT))
16390 (set (match_dup 11)
16391 (unspec:XF [(match_dup 9) (match_dup 5)]
16392 UNSPEC_FSCALE_EXP))])
16393 (set (match_operand:DF 0 "register_operand" "")
16394 (float_truncate:DF (match_dup 10)))]
16395 "TARGET_USE_FANCY_MATH_387
16396 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16397 && flag_unsafe_math_optimizations"
16398 {
16399 rtx temp;
16400 int i;
16401
16402 for (i=2; i<12; i++)
16403 operands[i] = gen_reg_rtx (XFmode);
16404 temp = standard_80387_constant_rtx (6); /* fldl2t */
16405 emit_move_insn (operands[3], temp);
16406 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16407 })
16408
16409 (define_expand "exp10xf2"
16410 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16411 (match_dup 2)))
16412 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16413 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16414 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16415 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16416 (parallel [(set (match_operand:XF 0 "register_operand" "")
16417 (unspec:XF [(match_dup 8) (match_dup 4)]
16418 UNSPEC_FSCALE_FRACT))
16419 (set (match_dup 9)
16420 (unspec:XF [(match_dup 8) (match_dup 4)]
16421 UNSPEC_FSCALE_EXP))])]
16422 "TARGET_USE_FANCY_MATH_387
16423 && flag_unsafe_math_optimizations"
16424 {
16425 rtx temp;
16426 int i;
16427
16428 for (i=2; i<10; i++)
16429 operands[i] = gen_reg_rtx (XFmode);
16430 temp = standard_80387_constant_rtx (6); /* fldl2t */
16431 emit_move_insn (operands[2], temp);
16432 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16433 })
16434
16435 (define_expand "exp2sf2"
16436 [(set (match_dup 2)
16437 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16438 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16439 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16440 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16441 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16442 (parallel [(set (match_dup 8)
16443 (unspec:XF [(match_dup 7) (match_dup 3)]
16444 UNSPEC_FSCALE_FRACT))
16445 (set (match_dup 9)
16446 (unspec:XF [(match_dup 7) (match_dup 3)]
16447 UNSPEC_FSCALE_EXP))])
16448 (set (match_operand:SF 0 "register_operand" "")
16449 (float_truncate:SF (match_dup 8)))]
16450 "TARGET_USE_FANCY_MATH_387
16451 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16452 && flag_unsafe_math_optimizations"
16453 {
16454 int i;
16455
16456 for (i=2; i<10; i++)
16457 operands[i] = gen_reg_rtx (XFmode);
16458 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16459 })
16460
16461 (define_expand "exp2df2"
16462 [(set (match_dup 2)
16463 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16464 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16465 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16466 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16467 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16468 (parallel [(set (match_dup 8)
16469 (unspec:XF [(match_dup 7) (match_dup 3)]
16470 UNSPEC_FSCALE_FRACT))
16471 (set (match_dup 9)
16472 (unspec:XF [(match_dup 7) (match_dup 3)]
16473 UNSPEC_FSCALE_EXP))])
16474 (set (match_operand:DF 0 "register_operand" "")
16475 (float_truncate:DF (match_dup 8)))]
16476 "TARGET_USE_FANCY_MATH_387
16477 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16478 && flag_unsafe_math_optimizations"
16479 {
16480 int i;
16481
16482 for (i=2; i<10; i++)
16483 operands[i] = gen_reg_rtx (XFmode);
16484 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16485 })
16486
16487 (define_expand "exp2xf2"
16488 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16489 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16490 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16491 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16492 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16493 (parallel [(set (match_operand:XF 0 "register_operand" "")
16494 (unspec:XF [(match_dup 7) (match_dup 3)]
16495 UNSPEC_FSCALE_FRACT))
16496 (set (match_dup 8)
16497 (unspec:XF [(match_dup 7) (match_dup 3)]
16498 UNSPEC_FSCALE_EXP))])]
16499 "TARGET_USE_FANCY_MATH_387
16500 && flag_unsafe_math_optimizations"
16501 {
16502 int i;
16503
16504 for (i=2; i<9; i++)
16505 operands[i] = gen_reg_rtx (XFmode);
16506 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16507 })
16508
16509 (define_expand "expm1df2"
16510 [(set (match_dup 2)
16511 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16512 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16513 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16514 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16515 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16516 (parallel [(set (match_dup 8)
16517 (unspec:XF [(match_dup 7) (match_dup 5)]
16518 UNSPEC_FSCALE_FRACT))
16519 (set (match_dup 9)
16520 (unspec:XF [(match_dup 7) (match_dup 5)]
16521 UNSPEC_FSCALE_EXP))])
16522 (parallel [(set (match_dup 11)
16523 (unspec:XF [(match_dup 10) (match_dup 9)]
16524 UNSPEC_FSCALE_FRACT))
16525 (set (match_dup 12)
16526 (unspec:XF [(match_dup 10) (match_dup 9)]
16527 UNSPEC_FSCALE_EXP))])
16528 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16529 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16530 (set (match_operand:DF 0 "register_operand" "")
16531 (float_truncate:DF (match_dup 14)))]
16532 "TARGET_USE_FANCY_MATH_387
16533 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16534 && flag_unsafe_math_optimizations"
16535 {
16536 rtx temp;
16537 int i;
16538
16539 for (i=2; i<15; i++)
16540 operands[i] = gen_reg_rtx (XFmode);
16541 temp = standard_80387_constant_rtx (5); /* fldl2e */
16542 emit_move_insn (operands[3], temp);
16543 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16544 })
16545
16546 (define_expand "expm1sf2"
16547 [(set (match_dup 2)
16548 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16549 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16550 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16551 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16552 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16553 (parallel [(set (match_dup 8)
16554 (unspec:XF [(match_dup 7) (match_dup 5)]
16555 UNSPEC_FSCALE_FRACT))
16556 (set (match_dup 9)
16557 (unspec:XF [(match_dup 7) (match_dup 5)]
16558 UNSPEC_FSCALE_EXP))])
16559 (parallel [(set (match_dup 11)
16560 (unspec:XF [(match_dup 10) (match_dup 9)]
16561 UNSPEC_FSCALE_FRACT))
16562 (set (match_dup 12)
16563 (unspec:XF [(match_dup 10) (match_dup 9)]
16564 UNSPEC_FSCALE_EXP))])
16565 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16566 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16567 (set (match_operand:SF 0 "register_operand" "")
16568 (float_truncate:SF (match_dup 14)))]
16569 "TARGET_USE_FANCY_MATH_387
16570 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16571 && flag_unsafe_math_optimizations"
16572 {
16573 rtx temp;
16574 int i;
16575
16576 for (i=2; i<15; i++)
16577 operands[i] = gen_reg_rtx (XFmode);
16578 temp = standard_80387_constant_rtx (5); /* fldl2e */
16579 emit_move_insn (operands[3], temp);
16580 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16581 })
16582
16583 (define_expand "expm1xf2"
16584 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16585 (match_dup 2)))
16586 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16587 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16588 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16589 (parallel [(set (match_dup 7)
16590 (unspec:XF [(match_dup 6) (match_dup 4)]
16591 UNSPEC_FSCALE_FRACT))
16592 (set (match_dup 8)
16593 (unspec:XF [(match_dup 6) (match_dup 4)]
16594 UNSPEC_FSCALE_EXP))])
16595 (parallel [(set (match_dup 10)
16596 (unspec:XF [(match_dup 9) (match_dup 8)]
16597 UNSPEC_FSCALE_FRACT))
16598 (set (match_dup 11)
16599 (unspec:XF [(match_dup 9) (match_dup 8)]
16600 UNSPEC_FSCALE_EXP))])
16601 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16602 (set (match_operand:XF 0 "register_operand" "")
16603 (plus:XF (match_dup 12) (match_dup 7)))]
16604 "TARGET_USE_FANCY_MATH_387
16605 && flag_unsafe_math_optimizations"
16606 {
16607 rtx temp;
16608 int i;
16609
16610 for (i=2; i<13; i++)
16611 operands[i] = gen_reg_rtx (XFmode);
16612 temp = standard_80387_constant_rtx (5); /* fldl2e */
16613 emit_move_insn (operands[2], temp);
16614 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16615 })
16616
16617 (define_expand "ldexpdf3"
16618 [(set (match_dup 3)
16619 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16620 (set (match_dup 4)
16621 (float:XF (match_operand:SI 2 "register_operand" "")))
16622 (parallel [(set (match_dup 5)
16623 (unspec:XF [(match_dup 3) (match_dup 4)]
16624 UNSPEC_FSCALE_FRACT))
16625 (set (match_dup 6)
16626 (unspec:XF [(match_dup 3) (match_dup 4)]
16627 UNSPEC_FSCALE_EXP))])
16628 (set (match_operand:DF 0 "register_operand" "")
16629 (float_truncate:DF (match_dup 5)))]
16630 "TARGET_USE_FANCY_MATH_387
16631 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16632 && flag_unsafe_math_optimizations"
16633 {
16634 int i;
16635
16636 for (i=3; i<7; i++)
16637 operands[i] = gen_reg_rtx (XFmode);
16638 })
16639
16640 (define_expand "ldexpsf3"
16641 [(set (match_dup 3)
16642 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16643 (set (match_dup 4)
16644 (float:XF (match_operand:SI 2 "register_operand" "")))
16645 (parallel [(set (match_dup 5)
16646 (unspec:XF [(match_dup 3) (match_dup 4)]
16647 UNSPEC_FSCALE_FRACT))
16648 (set (match_dup 6)
16649 (unspec:XF [(match_dup 3) (match_dup 4)]
16650 UNSPEC_FSCALE_EXP))])
16651 (set (match_operand:SF 0 "register_operand" "")
16652 (float_truncate:SF (match_dup 5)))]
16653 "TARGET_USE_FANCY_MATH_387
16654 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16655 && flag_unsafe_math_optimizations"
16656 {
16657 int i;
16658
16659 for (i=3; i<7; i++)
16660 operands[i] = gen_reg_rtx (XFmode);
16661 })
16662
16663 (define_expand "ldexpxf3"
16664 [(set (match_dup 3)
16665 (float:XF (match_operand:SI 2 "register_operand" "")))
16666 (parallel [(set (match_operand:XF 0 " register_operand" "")
16667 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16668 (match_dup 3)]
16669 UNSPEC_FSCALE_FRACT))
16670 (set (match_dup 4)
16671 (unspec:XF [(match_dup 1) (match_dup 3)]
16672 UNSPEC_FSCALE_EXP))])]
16673 "TARGET_USE_FANCY_MATH_387
16674 && flag_unsafe_math_optimizations"
16675 {
16676 int i;
16677
16678 for (i=3; i<5; i++)
16679 operands[i] = gen_reg_rtx (XFmode);
16680 })
16681 \f
16682
16683 (define_insn "frndintxf2"
16684 [(set (match_operand:XF 0 "register_operand" "=f")
16685 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16686 UNSPEC_FRNDINT))]
16687 "TARGET_USE_FANCY_MATH_387
16688 && flag_unsafe_math_optimizations"
16689 "frndint"
16690 [(set_attr "type" "fpspc")
16691 (set_attr "mode" "XF")])
16692
16693 (define_expand "rintdf2"
16694 [(use (match_operand:DF 0 "register_operand" ""))
16695 (use (match_operand:DF 1 "register_operand" ""))]
16696 "TARGET_USE_FANCY_MATH_387
16697 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16698 && flag_unsafe_math_optimizations"
16699 {
16700 rtx op0 = gen_reg_rtx (XFmode);
16701 rtx op1 = gen_reg_rtx (XFmode);
16702
16703 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16704 emit_insn (gen_frndintxf2 (op0, op1));
16705
16706 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16707 DONE;
16708 })
16709
16710 (define_expand "rintsf2"
16711 [(use (match_operand:SF 0 "register_operand" ""))
16712 (use (match_operand:SF 1 "register_operand" ""))]
16713 "TARGET_USE_FANCY_MATH_387
16714 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16715 && flag_unsafe_math_optimizations"
16716 {
16717 rtx op0 = gen_reg_rtx (XFmode);
16718 rtx op1 = gen_reg_rtx (XFmode);
16719
16720 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16721 emit_insn (gen_frndintxf2 (op0, op1));
16722
16723 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16724 DONE;
16725 })
16726
16727 (define_expand "rintxf2"
16728 [(use (match_operand:XF 0 "register_operand" ""))
16729 (use (match_operand:XF 1 "register_operand" ""))]
16730 "TARGET_USE_FANCY_MATH_387
16731 && flag_unsafe_math_optimizations"
16732 {
16733 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16734 DONE;
16735 })
16736
16737 (define_insn_and_split "*fistdi2_1"
16738 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16739 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16740 UNSPEC_FIST))]
16741 "TARGET_USE_FANCY_MATH_387
16742 && flag_unsafe_math_optimizations
16743 && !(reload_completed || reload_in_progress)"
16744 "#"
16745 "&& 1"
16746 [(const_int 0)]
16747 {
16748 if (memory_operand (operands[0], VOIDmode))
16749 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16750 else
16751 {
16752 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16753 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16754 operands[2]));
16755 }
16756 DONE;
16757 }
16758 [(set_attr "type" "fpspc")
16759 (set_attr "mode" "DI")])
16760
16761 (define_insn "fistdi2"
16762 [(set (match_operand:DI 0 "memory_operand" "=m")
16763 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16764 UNSPEC_FIST))
16765 (clobber (match_scratch:XF 2 "=&1f"))]
16766 "TARGET_USE_FANCY_MATH_387
16767 && flag_unsafe_math_optimizations"
16768 "* return output_fix_trunc (insn, operands, 0);"
16769 [(set_attr "type" "fpspc")
16770 (set_attr "mode" "DI")])
16771
16772 (define_insn "fistdi2_with_temp"
16773 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16774 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16775 UNSPEC_FIST))
16776 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16777 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16778 "TARGET_USE_FANCY_MATH_387
16779 && flag_unsafe_math_optimizations"
16780 "#"
16781 [(set_attr "type" "fpspc")
16782 (set_attr "mode" "DI")])
16783
16784 (define_split
16785 [(set (match_operand:DI 0 "register_operand" "")
16786 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16787 UNSPEC_FIST))
16788 (clobber (match_operand:DI 2 "memory_operand" ""))
16789 (clobber (match_scratch 3 ""))]
16790 "reload_completed"
16791 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16792 (clobber (match_dup 3))])
16793 (set (match_dup 0) (match_dup 2))]
16794 "")
16795
16796 (define_split
16797 [(set (match_operand:DI 0 "memory_operand" "")
16798 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16799 UNSPEC_FIST))
16800 (clobber (match_operand:DI 2 "memory_operand" ""))
16801 (clobber (match_scratch 3 ""))]
16802 "reload_completed"
16803 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16804 (clobber (match_dup 3))])]
16805 "")
16806
16807 (define_insn_and_split "*fist<mode>2_1"
16808 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16809 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16810 UNSPEC_FIST))]
16811 "TARGET_USE_FANCY_MATH_387
16812 && flag_unsafe_math_optimizations
16813 && !(reload_completed || reload_in_progress)"
16814 "#"
16815 "&& 1"
16816 [(const_int 0)]
16817 {
16818 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16819 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16820 operands[2]));
16821 DONE;
16822 }
16823 [(set_attr "type" "fpspc")
16824 (set_attr "mode" "<MODE>")])
16825
16826 (define_insn "fist<mode>2"
16827 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16828 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16829 UNSPEC_FIST))]
16830 "TARGET_USE_FANCY_MATH_387
16831 && flag_unsafe_math_optimizations"
16832 "* return output_fix_trunc (insn, operands, 0);"
16833 [(set_attr "type" "fpspc")
16834 (set_attr "mode" "<MODE>")])
16835
16836 (define_insn "fist<mode>2_with_temp"
16837 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16838 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16839 UNSPEC_FIST))
16840 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16841 "TARGET_USE_FANCY_MATH_387
16842 && flag_unsafe_math_optimizations"
16843 "#"
16844 [(set_attr "type" "fpspc")
16845 (set_attr "mode" "<MODE>")])
16846
16847 (define_split
16848 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16849 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16850 UNSPEC_FIST))
16851 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16852 "reload_completed"
16853 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16854 UNSPEC_FIST))
16855 (set (match_dup 0) (match_dup 2))]
16856 "")
16857
16858 (define_split
16859 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16860 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16861 UNSPEC_FIST))
16862 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16863 "reload_completed"
16864 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16865 UNSPEC_FIST))]
16866 "")
16867
16868 (define_expand "lrint<mode>2"
16869 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16870 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16871 UNSPEC_FIST))]
16872 "TARGET_USE_FANCY_MATH_387
16873 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16874 && flag_unsafe_math_optimizations"
16875 "")
16876
16877 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16878 (define_insn_and_split "frndintxf2_floor"
16879 [(set (match_operand:XF 0 "register_operand" "=f")
16880 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16881 UNSPEC_FRNDINT_FLOOR))
16882 (clobber (reg:CC FLAGS_REG))]
16883 "TARGET_USE_FANCY_MATH_387
16884 && flag_unsafe_math_optimizations
16885 && !(reload_completed || reload_in_progress)"
16886 "#"
16887 "&& 1"
16888 [(const_int 0)]
16889 {
16890 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16891
16892 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16893 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16894
16895 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16896 operands[2], operands[3]));
16897 DONE;
16898 }
16899 [(set_attr "type" "frndint")
16900 (set_attr "i387_cw" "floor")
16901 (set_attr "mode" "XF")])
16902
16903 (define_insn "frndintxf2_floor_i387"
16904 [(set (match_operand:XF 0 "register_operand" "=f")
16905 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16906 UNSPEC_FRNDINT_FLOOR))
16907 (use (match_operand:HI 2 "memory_operand" "m"))
16908 (use (match_operand:HI 3 "memory_operand" "m"))]
16909 "TARGET_USE_FANCY_MATH_387
16910 && flag_unsafe_math_optimizations"
16911 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16912 [(set_attr "type" "frndint")
16913 (set_attr "i387_cw" "floor")
16914 (set_attr "mode" "XF")])
16915
16916 (define_expand "floorxf2"
16917 [(use (match_operand:XF 0 "register_operand" ""))
16918 (use (match_operand:XF 1 "register_operand" ""))]
16919 "TARGET_USE_FANCY_MATH_387
16920 && flag_unsafe_math_optimizations"
16921 {
16922 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16923 DONE;
16924 })
16925
16926 (define_expand "floordf2"
16927 [(use (match_operand:DF 0 "register_operand" ""))
16928 (use (match_operand:DF 1 "register_operand" ""))]
16929 "TARGET_USE_FANCY_MATH_387
16930 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16931 && flag_unsafe_math_optimizations"
16932 {
16933 rtx op0 = gen_reg_rtx (XFmode);
16934 rtx op1 = gen_reg_rtx (XFmode);
16935
16936 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16937 emit_insn (gen_frndintxf2_floor (op0, op1));
16938
16939 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16940 DONE;
16941 })
16942
16943 (define_expand "floorsf2"
16944 [(use (match_operand:SF 0 "register_operand" ""))
16945 (use (match_operand:SF 1 "register_operand" ""))]
16946 "TARGET_USE_FANCY_MATH_387
16947 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16948 && flag_unsafe_math_optimizations"
16949 {
16950 rtx op0 = gen_reg_rtx (XFmode);
16951 rtx op1 = gen_reg_rtx (XFmode);
16952
16953 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16954 emit_insn (gen_frndintxf2_floor (op0, op1));
16955
16956 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16957 DONE;
16958 })
16959
16960 (define_insn_and_split "*fist<mode>2_floor_1"
16961 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16962 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16963 UNSPEC_FIST_FLOOR))
16964 (clobber (reg:CC FLAGS_REG))]
16965 "TARGET_USE_FANCY_MATH_387
16966 && flag_unsafe_math_optimizations
16967 && !(reload_completed || reload_in_progress)"
16968 "#"
16969 "&& 1"
16970 [(const_int 0)]
16971 {
16972 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16973
16974 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16975 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16976 if (memory_operand (operands[0], VOIDmode))
16977 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16978 operands[2], operands[3]));
16979 else
16980 {
16981 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16982 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16983 operands[2], operands[3],
16984 operands[4]));
16985 }
16986 DONE;
16987 }
16988 [(set_attr "type" "fistp")
16989 (set_attr "i387_cw" "floor")
16990 (set_attr "mode" "<MODE>")])
16991
16992 (define_insn "fistdi2_floor"
16993 [(set (match_operand:DI 0 "memory_operand" "=m")
16994 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16995 UNSPEC_FIST_FLOOR))
16996 (use (match_operand:HI 2 "memory_operand" "m"))
16997 (use (match_operand:HI 3 "memory_operand" "m"))
16998 (clobber (match_scratch:XF 4 "=&1f"))]
16999 "TARGET_USE_FANCY_MATH_387
17000 && flag_unsafe_math_optimizations"
17001 "* return output_fix_trunc (insn, operands, 0);"
17002 [(set_attr "type" "fistp")
17003 (set_attr "i387_cw" "floor")
17004 (set_attr "mode" "DI")])
17005
17006 (define_insn "fistdi2_floor_with_temp"
17007 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17008 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17009 UNSPEC_FIST_FLOOR))
17010 (use (match_operand:HI 2 "memory_operand" "m,m"))
17011 (use (match_operand:HI 3 "memory_operand" "m,m"))
17012 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17013 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17014 "TARGET_USE_FANCY_MATH_387
17015 && flag_unsafe_math_optimizations"
17016 "#"
17017 [(set_attr "type" "fistp")
17018 (set_attr "i387_cw" "floor")
17019 (set_attr "mode" "DI")])
17020
17021 (define_split
17022 [(set (match_operand:DI 0 "register_operand" "")
17023 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17024 UNSPEC_FIST_FLOOR))
17025 (use (match_operand:HI 2 "memory_operand" ""))
17026 (use (match_operand:HI 3 "memory_operand" ""))
17027 (clobber (match_operand:DI 4 "memory_operand" ""))
17028 (clobber (match_scratch 5 ""))]
17029 "reload_completed"
17030 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17031 (use (match_dup 2))
17032 (use (match_dup 3))
17033 (clobber (match_dup 5))])
17034 (set (match_dup 0) (match_dup 4))]
17035 "")
17036
17037 (define_split
17038 [(set (match_operand:DI 0 "memory_operand" "")
17039 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17040 UNSPEC_FIST_FLOOR))
17041 (use (match_operand:HI 2 "memory_operand" ""))
17042 (use (match_operand:HI 3 "memory_operand" ""))
17043 (clobber (match_operand:DI 4 "memory_operand" ""))
17044 (clobber (match_scratch 5 ""))]
17045 "reload_completed"
17046 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17047 (use (match_dup 2))
17048 (use (match_dup 3))
17049 (clobber (match_dup 5))])]
17050 "")
17051
17052 (define_insn "fist<mode>2_floor"
17053 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17054 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17055 UNSPEC_FIST_FLOOR))
17056 (use (match_operand:HI 2 "memory_operand" "m"))
17057 (use (match_operand:HI 3 "memory_operand" "m"))]
17058 "TARGET_USE_FANCY_MATH_387
17059 && flag_unsafe_math_optimizations"
17060 "* return output_fix_trunc (insn, operands, 0);"
17061 [(set_attr "type" "fistp")
17062 (set_attr "i387_cw" "floor")
17063 (set_attr "mode" "<MODE>")])
17064
17065 (define_insn "fist<mode>2_floor_with_temp"
17066 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17067 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17068 UNSPEC_FIST_FLOOR))
17069 (use (match_operand:HI 2 "memory_operand" "m,m"))
17070 (use (match_operand:HI 3 "memory_operand" "m,m"))
17071 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17072 "TARGET_USE_FANCY_MATH_387
17073 && flag_unsafe_math_optimizations"
17074 "#"
17075 [(set_attr "type" "fistp")
17076 (set_attr "i387_cw" "floor")
17077 (set_attr "mode" "<MODE>")])
17078
17079 (define_split
17080 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17081 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17082 UNSPEC_FIST_FLOOR))
17083 (use (match_operand:HI 2 "memory_operand" ""))
17084 (use (match_operand:HI 3 "memory_operand" ""))
17085 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17086 "reload_completed"
17087 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17088 UNSPEC_FIST_FLOOR))
17089 (use (match_dup 2))
17090 (use (match_dup 3))])
17091 (set (match_dup 0) (match_dup 4))]
17092 "")
17093
17094 (define_split
17095 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17096 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17097 UNSPEC_FIST_FLOOR))
17098 (use (match_operand:HI 2 "memory_operand" ""))
17099 (use (match_operand:HI 3 "memory_operand" ""))
17100 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17101 "reload_completed"
17102 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17103 UNSPEC_FIST_FLOOR))
17104 (use (match_dup 2))
17105 (use (match_dup 3))])]
17106 "")
17107
17108 (define_expand "lfloor<mode>2"
17109 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17110 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17111 UNSPEC_FIST_FLOOR))
17112 (clobber (reg:CC FLAGS_REG))])]
17113 "TARGET_USE_FANCY_MATH_387
17114 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17115 && flag_unsafe_math_optimizations"
17116 "")
17117
17118 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17119 (define_insn_and_split "frndintxf2_ceil"
17120 [(set (match_operand:XF 0 "register_operand" "=f")
17121 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17122 UNSPEC_FRNDINT_CEIL))
17123 (clobber (reg:CC FLAGS_REG))]
17124 "TARGET_USE_FANCY_MATH_387
17125 && flag_unsafe_math_optimizations
17126 && !(reload_completed || reload_in_progress)"
17127 "#"
17128 "&& 1"
17129 [(const_int 0)]
17130 {
17131 ix86_optimize_mode_switching[I387_CEIL] = 1;
17132
17133 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17134 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17135
17136 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17137 operands[2], operands[3]));
17138 DONE;
17139 }
17140 [(set_attr "type" "frndint")
17141 (set_attr "i387_cw" "ceil")
17142 (set_attr "mode" "XF")])
17143
17144 (define_insn "frndintxf2_ceil_i387"
17145 [(set (match_operand:XF 0 "register_operand" "=f")
17146 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17147 UNSPEC_FRNDINT_CEIL))
17148 (use (match_operand:HI 2 "memory_operand" "m"))
17149 (use (match_operand:HI 3 "memory_operand" "m"))]
17150 "TARGET_USE_FANCY_MATH_387
17151 && flag_unsafe_math_optimizations"
17152 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17153 [(set_attr "type" "frndint")
17154 (set_attr "i387_cw" "ceil")
17155 (set_attr "mode" "XF")])
17156
17157 (define_expand "ceilxf2"
17158 [(use (match_operand:XF 0 "register_operand" ""))
17159 (use (match_operand:XF 1 "register_operand" ""))]
17160 "TARGET_USE_FANCY_MATH_387
17161 && flag_unsafe_math_optimizations"
17162 {
17163 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17164 DONE;
17165 })
17166
17167 (define_expand "ceildf2"
17168 [(use (match_operand:DF 0 "register_operand" ""))
17169 (use (match_operand:DF 1 "register_operand" ""))]
17170 "TARGET_USE_FANCY_MATH_387
17171 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17172 && flag_unsafe_math_optimizations"
17173 {
17174 rtx op0 = gen_reg_rtx (XFmode);
17175 rtx op1 = gen_reg_rtx (XFmode);
17176
17177 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17178 emit_insn (gen_frndintxf2_ceil (op0, op1));
17179
17180 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17181 DONE;
17182 })
17183
17184 (define_expand "ceilsf2"
17185 [(use (match_operand:SF 0 "register_operand" ""))
17186 (use (match_operand:SF 1 "register_operand" ""))]
17187 "TARGET_USE_FANCY_MATH_387
17188 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17189 && flag_unsafe_math_optimizations"
17190 {
17191 rtx op0 = gen_reg_rtx (XFmode);
17192 rtx op1 = gen_reg_rtx (XFmode);
17193
17194 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17195 emit_insn (gen_frndintxf2_ceil (op0, op1));
17196
17197 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17198 DONE;
17199 })
17200
17201 (define_insn_and_split "*fist<mode>2_ceil_1"
17202 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17203 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17204 UNSPEC_FIST_CEIL))
17205 (clobber (reg:CC FLAGS_REG))]
17206 "TARGET_USE_FANCY_MATH_387
17207 && flag_unsafe_math_optimizations
17208 && !(reload_completed || reload_in_progress)"
17209 "#"
17210 "&& 1"
17211 [(const_int 0)]
17212 {
17213 ix86_optimize_mode_switching[I387_CEIL] = 1;
17214
17215 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17216 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17217 if (memory_operand (operands[0], VOIDmode))
17218 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17219 operands[2], operands[3]));
17220 else
17221 {
17222 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17223 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17224 operands[2], operands[3],
17225 operands[4]));
17226 }
17227 DONE;
17228 }
17229 [(set_attr "type" "fistp")
17230 (set_attr "i387_cw" "ceil")
17231 (set_attr "mode" "<MODE>")])
17232
17233 (define_insn "fistdi2_ceil"
17234 [(set (match_operand:DI 0 "memory_operand" "=m")
17235 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17236 UNSPEC_FIST_CEIL))
17237 (use (match_operand:HI 2 "memory_operand" "m"))
17238 (use (match_operand:HI 3 "memory_operand" "m"))
17239 (clobber (match_scratch:XF 4 "=&1f"))]
17240 "TARGET_USE_FANCY_MATH_387
17241 && flag_unsafe_math_optimizations"
17242 "* return output_fix_trunc (insn, operands, 0);"
17243 [(set_attr "type" "fistp")
17244 (set_attr "i387_cw" "ceil")
17245 (set_attr "mode" "DI")])
17246
17247 (define_insn "fistdi2_ceil_with_temp"
17248 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17249 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17250 UNSPEC_FIST_CEIL))
17251 (use (match_operand:HI 2 "memory_operand" "m,m"))
17252 (use (match_operand:HI 3 "memory_operand" "m,m"))
17253 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17254 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17255 "TARGET_USE_FANCY_MATH_387
17256 && flag_unsafe_math_optimizations"
17257 "#"
17258 [(set_attr "type" "fistp")
17259 (set_attr "i387_cw" "ceil")
17260 (set_attr "mode" "DI")])
17261
17262 (define_split
17263 [(set (match_operand:DI 0 "register_operand" "")
17264 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17265 UNSPEC_FIST_CEIL))
17266 (use (match_operand:HI 2 "memory_operand" ""))
17267 (use (match_operand:HI 3 "memory_operand" ""))
17268 (clobber (match_operand:DI 4 "memory_operand" ""))
17269 (clobber (match_scratch 5 ""))]
17270 "reload_completed"
17271 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17272 (use (match_dup 2))
17273 (use (match_dup 3))
17274 (clobber (match_dup 5))])
17275 (set (match_dup 0) (match_dup 4))]
17276 "")
17277
17278 (define_split
17279 [(set (match_operand:DI 0 "memory_operand" "")
17280 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17281 UNSPEC_FIST_CEIL))
17282 (use (match_operand:HI 2 "memory_operand" ""))
17283 (use (match_operand:HI 3 "memory_operand" ""))
17284 (clobber (match_operand:DI 4 "memory_operand" ""))
17285 (clobber (match_scratch 5 ""))]
17286 "reload_completed"
17287 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17288 (use (match_dup 2))
17289 (use (match_dup 3))
17290 (clobber (match_dup 5))])]
17291 "")
17292
17293 (define_insn "fist<mode>2_ceil"
17294 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17295 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17296 UNSPEC_FIST_CEIL))
17297 (use (match_operand:HI 2 "memory_operand" "m"))
17298 (use (match_operand:HI 3 "memory_operand" "m"))]
17299 "TARGET_USE_FANCY_MATH_387
17300 && flag_unsafe_math_optimizations"
17301 "* return output_fix_trunc (insn, operands, 0);"
17302 [(set_attr "type" "fistp")
17303 (set_attr "i387_cw" "ceil")
17304 (set_attr "mode" "<MODE>")])
17305
17306 (define_insn "fist<mode>2_ceil_with_temp"
17307 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17308 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17309 UNSPEC_FIST_CEIL))
17310 (use (match_operand:HI 2 "memory_operand" "m,m"))
17311 (use (match_operand:HI 3 "memory_operand" "m,m"))
17312 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17313 "TARGET_USE_FANCY_MATH_387
17314 && flag_unsafe_math_optimizations"
17315 "#"
17316 [(set_attr "type" "fistp")
17317 (set_attr "i387_cw" "ceil")
17318 (set_attr "mode" "<MODE>")])
17319
17320 (define_split
17321 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17322 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17323 UNSPEC_FIST_CEIL))
17324 (use (match_operand:HI 2 "memory_operand" ""))
17325 (use (match_operand:HI 3 "memory_operand" ""))
17326 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17327 "reload_completed"
17328 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17329 UNSPEC_FIST_CEIL))
17330 (use (match_dup 2))
17331 (use (match_dup 3))])
17332 (set (match_dup 0) (match_dup 4))]
17333 "")
17334
17335 (define_split
17336 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17337 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17338 UNSPEC_FIST_CEIL))
17339 (use (match_operand:HI 2 "memory_operand" ""))
17340 (use (match_operand:HI 3 "memory_operand" ""))
17341 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17342 "reload_completed"
17343 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17344 UNSPEC_FIST_CEIL))
17345 (use (match_dup 2))
17346 (use (match_dup 3))])]
17347 "")
17348
17349 (define_expand "lceil<mode>2"
17350 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17351 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17352 UNSPEC_FIST_CEIL))
17353 (clobber (reg:CC FLAGS_REG))])]
17354 "TARGET_USE_FANCY_MATH_387
17355 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17356 && flag_unsafe_math_optimizations"
17357 "")
17358
17359 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17360 (define_insn_and_split "frndintxf2_trunc"
17361 [(set (match_operand:XF 0 "register_operand" "=f")
17362 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17363 UNSPEC_FRNDINT_TRUNC))
17364 (clobber (reg:CC FLAGS_REG))]
17365 "TARGET_USE_FANCY_MATH_387
17366 && flag_unsafe_math_optimizations
17367 && !(reload_completed || reload_in_progress)"
17368 "#"
17369 "&& 1"
17370 [(const_int 0)]
17371 {
17372 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17373
17374 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17375 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17376
17377 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17378 operands[2], operands[3]));
17379 DONE;
17380 }
17381 [(set_attr "type" "frndint")
17382 (set_attr "i387_cw" "trunc")
17383 (set_attr "mode" "XF")])
17384
17385 (define_insn "frndintxf2_trunc_i387"
17386 [(set (match_operand:XF 0 "register_operand" "=f")
17387 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17388 UNSPEC_FRNDINT_TRUNC))
17389 (use (match_operand:HI 2 "memory_operand" "m"))
17390 (use (match_operand:HI 3 "memory_operand" "m"))]
17391 "TARGET_USE_FANCY_MATH_387
17392 && flag_unsafe_math_optimizations"
17393 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17394 [(set_attr "type" "frndint")
17395 (set_attr "i387_cw" "trunc")
17396 (set_attr "mode" "XF")])
17397
17398 (define_expand "btruncxf2"
17399 [(use (match_operand:XF 0 "register_operand" ""))
17400 (use (match_operand:XF 1 "register_operand" ""))]
17401 "TARGET_USE_FANCY_MATH_387
17402 && flag_unsafe_math_optimizations"
17403 {
17404 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17405 DONE;
17406 })
17407
17408 (define_expand "btruncdf2"
17409 [(use (match_operand:DF 0 "register_operand" ""))
17410 (use (match_operand:DF 1 "register_operand" ""))]
17411 "TARGET_USE_FANCY_MATH_387
17412 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17413 && flag_unsafe_math_optimizations"
17414 {
17415 rtx op0 = gen_reg_rtx (XFmode);
17416 rtx op1 = gen_reg_rtx (XFmode);
17417
17418 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17419 emit_insn (gen_frndintxf2_trunc (op0, op1));
17420
17421 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17422 DONE;
17423 })
17424
17425 (define_expand "btruncsf2"
17426 [(use (match_operand:SF 0 "register_operand" ""))
17427 (use (match_operand:SF 1 "register_operand" ""))]
17428 "TARGET_USE_FANCY_MATH_387
17429 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17430 && flag_unsafe_math_optimizations"
17431 {
17432 rtx op0 = gen_reg_rtx (XFmode);
17433 rtx op1 = gen_reg_rtx (XFmode);
17434
17435 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17436 emit_insn (gen_frndintxf2_trunc (op0, op1));
17437
17438 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17439 DONE;
17440 })
17441
17442 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17443 (define_insn_and_split "frndintxf2_mask_pm"
17444 [(set (match_operand:XF 0 "register_operand" "=f")
17445 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17446 UNSPEC_FRNDINT_MASK_PM))
17447 (clobber (reg:CC FLAGS_REG))]
17448 "TARGET_USE_FANCY_MATH_387
17449 && flag_unsafe_math_optimizations
17450 && !(reload_completed || reload_in_progress)"
17451 "#"
17452 "&& 1"
17453 [(const_int 0)]
17454 {
17455 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17456
17457 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17458 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17459
17460 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17461 operands[2], operands[3]));
17462 DONE;
17463 }
17464 [(set_attr "type" "frndint")
17465 (set_attr "i387_cw" "mask_pm")
17466 (set_attr "mode" "XF")])
17467
17468 (define_insn "frndintxf2_mask_pm_i387"
17469 [(set (match_operand:XF 0 "register_operand" "=f")
17470 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17471 UNSPEC_FRNDINT_MASK_PM))
17472 (use (match_operand:HI 2 "memory_operand" "m"))
17473 (use (match_operand:HI 3 "memory_operand" "m"))]
17474 "TARGET_USE_FANCY_MATH_387
17475 && flag_unsafe_math_optimizations"
17476 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17477 [(set_attr "type" "frndint")
17478 (set_attr "i387_cw" "mask_pm")
17479 (set_attr "mode" "XF")])
17480
17481 (define_expand "nearbyintxf2"
17482 [(use (match_operand:XF 0 "register_operand" ""))
17483 (use (match_operand:XF 1 "register_operand" ""))]
17484 "TARGET_USE_FANCY_MATH_387
17485 && flag_unsafe_math_optimizations"
17486 {
17487 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17488
17489 DONE;
17490 })
17491
17492 (define_expand "nearbyintdf2"
17493 [(use (match_operand:DF 0 "register_operand" ""))
17494 (use (match_operand:DF 1 "register_operand" ""))]
17495 "TARGET_USE_FANCY_MATH_387
17496 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17497 && flag_unsafe_math_optimizations"
17498 {
17499 rtx op0 = gen_reg_rtx (XFmode);
17500 rtx op1 = gen_reg_rtx (XFmode);
17501
17502 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17503 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17504
17505 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17506 DONE;
17507 })
17508
17509 (define_expand "nearbyintsf2"
17510 [(use (match_operand:SF 0 "register_operand" ""))
17511 (use (match_operand:SF 1 "register_operand" ""))]
17512 "TARGET_USE_FANCY_MATH_387
17513 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17514 && flag_unsafe_math_optimizations"
17515 {
17516 rtx op0 = gen_reg_rtx (XFmode);
17517 rtx op1 = gen_reg_rtx (XFmode);
17518
17519 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17520 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17521
17522 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17523 DONE;
17524 })
17525
17526 \f
17527 ;; Block operation instructions
17528
17529 (define_insn "cld"
17530 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17531 ""
17532 "cld"
17533 [(set_attr "type" "cld")])
17534
17535 (define_expand "movmemsi"
17536 [(use (match_operand:BLK 0 "memory_operand" ""))
17537 (use (match_operand:BLK 1 "memory_operand" ""))
17538 (use (match_operand:SI 2 "nonmemory_operand" ""))
17539 (use (match_operand:SI 3 "const_int_operand" ""))]
17540 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17541 {
17542 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17543 DONE;
17544 else
17545 FAIL;
17546 })
17547
17548 (define_expand "movmemdi"
17549 [(use (match_operand:BLK 0 "memory_operand" ""))
17550 (use (match_operand:BLK 1 "memory_operand" ""))
17551 (use (match_operand:DI 2 "nonmemory_operand" ""))
17552 (use (match_operand:DI 3 "const_int_operand" ""))]
17553 "TARGET_64BIT"
17554 {
17555 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17556 DONE;
17557 else
17558 FAIL;
17559 })
17560
17561 ;; Most CPUs don't like single string operations
17562 ;; Handle this case here to simplify previous expander.
17563
17564 (define_expand "strmov"
17565 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17566 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17567 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17568 (clobber (reg:CC FLAGS_REG))])
17569 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17570 (clobber (reg:CC FLAGS_REG))])]
17571 ""
17572 {
17573 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17574
17575 /* If .md ever supports :P for Pmode, these can be directly
17576 in the pattern above. */
17577 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17578 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17579
17580 if (TARGET_SINGLE_STRINGOP || optimize_size)
17581 {
17582 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17583 operands[2], operands[3],
17584 operands[5], operands[6]));
17585 DONE;
17586 }
17587
17588 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17589 })
17590
17591 (define_expand "strmov_singleop"
17592 [(parallel [(set (match_operand 1 "memory_operand" "")
17593 (match_operand 3 "memory_operand" ""))
17594 (set (match_operand 0 "register_operand" "")
17595 (match_operand 4 "" ""))
17596 (set (match_operand 2 "register_operand" "")
17597 (match_operand 5 "" ""))
17598 (use (reg:SI DIRFLAG_REG))])]
17599 "TARGET_SINGLE_STRINGOP || optimize_size"
17600 "")
17601
17602 (define_insn "*strmovdi_rex_1"
17603 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17604 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17605 (set (match_operand:DI 0 "register_operand" "=D")
17606 (plus:DI (match_dup 2)
17607 (const_int 8)))
17608 (set (match_operand:DI 1 "register_operand" "=S")
17609 (plus:DI (match_dup 3)
17610 (const_int 8)))
17611 (use (reg:SI DIRFLAG_REG))]
17612 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17613 "movsq"
17614 [(set_attr "type" "str")
17615 (set_attr "mode" "DI")
17616 (set_attr "memory" "both")])
17617
17618 (define_insn "*strmovsi_1"
17619 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17620 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17621 (set (match_operand:SI 0 "register_operand" "=D")
17622 (plus:SI (match_dup 2)
17623 (const_int 4)))
17624 (set (match_operand:SI 1 "register_operand" "=S")
17625 (plus:SI (match_dup 3)
17626 (const_int 4)))
17627 (use (reg:SI DIRFLAG_REG))]
17628 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17629 "{movsl|movsd}"
17630 [(set_attr "type" "str")
17631 (set_attr "mode" "SI")
17632 (set_attr "memory" "both")])
17633
17634 (define_insn "*strmovsi_rex_1"
17635 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17636 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17637 (set (match_operand:DI 0 "register_operand" "=D")
17638 (plus:DI (match_dup 2)
17639 (const_int 4)))
17640 (set (match_operand:DI 1 "register_operand" "=S")
17641 (plus:DI (match_dup 3)
17642 (const_int 4)))
17643 (use (reg:SI DIRFLAG_REG))]
17644 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17645 "{movsl|movsd}"
17646 [(set_attr "type" "str")
17647 (set_attr "mode" "SI")
17648 (set_attr "memory" "both")])
17649
17650 (define_insn "*strmovhi_1"
17651 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17652 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17653 (set (match_operand:SI 0 "register_operand" "=D")
17654 (plus:SI (match_dup 2)
17655 (const_int 2)))
17656 (set (match_operand:SI 1 "register_operand" "=S")
17657 (plus:SI (match_dup 3)
17658 (const_int 2)))
17659 (use (reg:SI DIRFLAG_REG))]
17660 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17661 "movsw"
17662 [(set_attr "type" "str")
17663 (set_attr "memory" "both")
17664 (set_attr "mode" "HI")])
17665
17666 (define_insn "*strmovhi_rex_1"
17667 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17668 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17669 (set (match_operand:DI 0 "register_operand" "=D")
17670 (plus:DI (match_dup 2)
17671 (const_int 2)))
17672 (set (match_operand:DI 1 "register_operand" "=S")
17673 (plus:DI (match_dup 3)
17674 (const_int 2)))
17675 (use (reg:SI DIRFLAG_REG))]
17676 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17677 "movsw"
17678 [(set_attr "type" "str")
17679 (set_attr "memory" "both")
17680 (set_attr "mode" "HI")])
17681
17682 (define_insn "*strmovqi_1"
17683 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17684 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17685 (set (match_operand:SI 0 "register_operand" "=D")
17686 (plus:SI (match_dup 2)
17687 (const_int 1)))
17688 (set (match_operand:SI 1 "register_operand" "=S")
17689 (plus:SI (match_dup 3)
17690 (const_int 1)))
17691 (use (reg:SI DIRFLAG_REG))]
17692 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17693 "movsb"
17694 [(set_attr "type" "str")
17695 (set_attr "memory" "both")
17696 (set_attr "mode" "QI")])
17697
17698 (define_insn "*strmovqi_rex_1"
17699 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17700 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17701 (set (match_operand:DI 0 "register_operand" "=D")
17702 (plus:DI (match_dup 2)
17703 (const_int 1)))
17704 (set (match_operand:DI 1 "register_operand" "=S")
17705 (plus:DI (match_dup 3)
17706 (const_int 1)))
17707 (use (reg:SI DIRFLAG_REG))]
17708 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17709 "movsb"
17710 [(set_attr "type" "str")
17711 (set_attr "memory" "both")
17712 (set_attr "mode" "QI")])
17713
17714 (define_expand "rep_mov"
17715 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17716 (set (match_operand 0 "register_operand" "")
17717 (match_operand 5 "" ""))
17718 (set (match_operand 2 "register_operand" "")
17719 (match_operand 6 "" ""))
17720 (set (match_operand 1 "memory_operand" "")
17721 (match_operand 3 "memory_operand" ""))
17722 (use (match_dup 4))
17723 (use (reg:SI DIRFLAG_REG))])]
17724 ""
17725 "")
17726
17727 (define_insn "*rep_movdi_rex64"
17728 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17729 (set (match_operand:DI 0 "register_operand" "=D")
17730 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17731 (const_int 3))
17732 (match_operand:DI 3 "register_operand" "0")))
17733 (set (match_operand:DI 1 "register_operand" "=S")
17734 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17735 (match_operand:DI 4 "register_operand" "1")))
17736 (set (mem:BLK (match_dup 3))
17737 (mem:BLK (match_dup 4)))
17738 (use (match_dup 5))
17739 (use (reg:SI DIRFLAG_REG))]
17740 "TARGET_64BIT"
17741 "{rep\;movsq|rep movsq}"
17742 [(set_attr "type" "str")
17743 (set_attr "prefix_rep" "1")
17744 (set_attr "memory" "both")
17745 (set_attr "mode" "DI")])
17746
17747 (define_insn "*rep_movsi"
17748 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17749 (set (match_operand:SI 0 "register_operand" "=D")
17750 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17751 (const_int 2))
17752 (match_operand:SI 3 "register_operand" "0")))
17753 (set (match_operand:SI 1 "register_operand" "=S")
17754 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17755 (match_operand:SI 4 "register_operand" "1")))
17756 (set (mem:BLK (match_dup 3))
17757 (mem:BLK (match_dup 4)))
17758 (use (match_dup 5))
17759 (use (reg:SI DIRFLAG_REG))]
17760 "!TARGET_64BIT"
17761 "{rep\;movsl|rep movsd}"
17762 [(set_attr "type" "str")
17763 (set_attr "prefix_rep" "1")
17764 (set_attr "memory" "both")
17765 (set_attr "mode" "SI")])
17766
17767 (define_insn "*rep_movsi_rex64"
17768 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17769 (set (match_operand:DI 0 "register_operand" "=D")
17770 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17771 (const_int 2))
17772 (match_operand:DI 3 "register_operand" "0")))
17773 (set (match_operand:DI 1 "register_operand" "=S")
17774 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17775 (match_operand:DI 4 "register_operand" "1")))
17776 (set (mem:BLK (match_dup 3))
17777 (mem:BLK (match_dup 4)))
17778 (use (match_dup 5))
17779 (use (reg:SI DIRFLAG_REG))]
17780 "TARGET_64BIT"
17781 "{rep\;movsl|rep movsd}"
17782 [(set_attr "type" "str")
17783 (set_attr "prefix_rep" "1")
17784 (set_attr "memory" "both")
17785 (set_attr "mode" "SI")])
17786
17787 (define_insn "*rep_movqi"
17788 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17789 (set (match_operand:SI 0 "register_operand" "=D")
17790 (plus:SI (match_operand:SI 3 "register_operand" "0")
17791 (match_operand:SI 5 "register_operand" "2")))
17792 (set (match_operand:SI 1 "register_operand" "=S")
17793 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17794 (set (mem:BLK (match_dup 3))
17795 (mem:BLK (match_dup 4)))
17796 (use (match_dup 5))
17797 (use (reg:SI DIRFLAG_REG))]
17798 "!TARGET_64BIT"
17799 "{rep\;movsb|rep movsb}"
17800 [(set_attr "type" "str")
17801 (set_attr "prefix_rep" "1")
17802 (set_attr "memory" "both")
17803 (set_attr "mode" "SI")])
17804
17805 (define_insn "*rep_movqi_rex64"
17806 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17807 (set (match_operand:DI 0 "register_operand" "=D")
17808 (plus:DI (match_operand:DI 3 "register_operand" "0")
17809 (match_operand:DI 5 "register_operand" "2")))
17810 (set (match_operand:DI 1 "register_operand" "=S")
17811 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17812 (set (mem:BLK (match_dup 3))
17813 (mem:BLK (match_dup 4)))
17814 (use (match_dup 5))
17815 (use (reg:SI DIRFLAG_REG))]
17816 "TARGET_64BIT"
17817 "{rep\;movsb|rep movsb}"
17818 [(set_attr "type" "str")
17819 (set_attr "prefix_rep" "1")
17820 (set_attr "memory" "both")
17821 (set_attr "mode" "SI")])
17822
17823 (define_expand "setmemsi"
17824 [(use (match_operand:BLK 0 "memory_operand" ""))
17825 (use (match_operand:SI 1 "nonmemory_operand" ""))
17826 (use (match_operand 2 "const_int_operand" ""))
17827 (use (match_operand 3 "const_int_operand" ""))]
17828 ""
17829 {
17830 /* If value to set is not zero, use the library routine. */
17831 if (operands[2] != const0_rtx)
17832 FAIL;
17833
17834 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17835 DONE;
17836 else
17837 FAIL;
17838 })
17839
17840 (define_expand "setmemdi"
17841 [(use (match_operand:BLK 0 "memory_operand" ""))
17842 (use (match_operand:DI 1 "nonmemory_operand" ""))
17843 (use (match_operand 2 "const_int_operand" ""))
17844 (use (match_operand 3 "const_int_operand" ""))]
17845 "TARGET_64BIT"
17846 {
17847 /* If value to set is not zero, use the library routine. */
17848 if (operands[2] != const0_rtx)
17849 FAIL;
17850
17851 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17852 DONE;
17853 else
17854 FAIL;
17855 })
17856
17857 ;; Most CPUs don't like single string operations
17858 ;; Handle this case here to simplify previous expander.
17859
17860 (define_expand "strset"
17861 [(set (match_operand 1 "memory_operand" "")
17862 (match_operand 2 "register_operand" ""))
17863 (parallel [(set (match_operand 0 "register_operand" "")
17864 (match_dup 3))
17865 (clobber (reg:CC FLAGS_REG))])]
17866 ""
17867 {
17868 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17869 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17870
17871 /* If .md ever supports :P for Pmode, this can be directly
17872 in the pattern above. */
17873 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17874 GEN_INT (GET_MODE_SIZE (GET_MODE
17875 (operands[2]))));
17876 if (TARGET_SINGLE_STRINGOP || optimize_size)
17877 {
17878 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17879 operands[3]));
17880 DONE;
17881 }
17882 })
17883
17884 (define_expand "strset_singleop"
17885 [(parallel [(set (match_operand 1 "memory_operand" "")
17886 (match_operand 2 "register_operand" ""))
17887 (set (match_operand 0 "register_operand" "")
17888 (match_operand 3 "" ""))
17889 (use (reg:SI DIRFLAG_REG))])]
17890 "TARGET_SINGLE_STRINGOP || optimize_size"
17891 "")
17892
17893 (define_insn "*strsetdi_rex_1"
17894 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17895 (match_operand:DI 2 "register_operand" "a"))
17896 (set (match_operand:DI 0 "register_operand" "=D")
17897 (plus:DI (match_dup 1)
17898 (const_int 8)))
17899 (use (reg:SI DIRFLAG_REG))]
17900 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17901 "stosq"
17902 [(set_attr "type" "str")
17903 (set_attr "memory" "store")
17904 (set_attr "mode" "DI")])
17905
17906 (define_insn "*strsetsi_1"
17907 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17908 (match_operand:SI 2 "register_operand" "a"))
17909 (set (match_operand:SI 0 "register_operand" "=D")
17910 (plus:SI (match_dup 1)
17911 (const_int 4)))
17912 (use (reg:SI DIRFLAG_REG))]
17913 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17914 "{stosl|stosd}"
17915 [(set_attr "type" "str")
17916 (set_attr "memory" "store")
17917 (set_attr "mode" "SI")])
17918
17919 (define_insn "*strsetsi_rex_1"
17920 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17921 (match_operand:SI 2 "register_operand" "a"))
17922 (set (match_operand:DI 0 "register_operand" "=D")
17923 (plus:DI (match_dup 1)
17924 (const_int 4)))
17925 (use (reg:SI DIRFLAG_REG))]
17926 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17927 "{stosl|stosd}"
17928 [(set_attr "type" "str")
17929 (set_attr "memory" "store")
17930 (set_attr "mode" "SI")])
17931
17932 (define_insn "*strsethi_1"
17933 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17934 (match_operand:HI 2 "register_operand" "a"))
17935 (set (match_operand:SI 0 "register_operand" "=D")
17936 (plus:SI (match_dup 1)
17937 (const_int 2)))
17938 (use (reg:SI DIRFLAG_REG))]
17939 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17940 "stosw"
17941 [(set_attr "type" "str")
17942 (set_attr "memory" "store")
17943 (set_attr "mode" "HI")])
17944
17945 (define_insn "*strsethi_rex_1"
17946 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17947 (match_operand:HI 2 "register_operand" "a"))
17948 (set (match_operand:DI 0 "register_operand" "=D")
17949 (plus:DI (match_dup 1)
17950 (const_int 2)))
17951 (use (reg:SI DIRFLAG_REG))]
17952 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17953 "stosw"
17954 [(set_attr "type" "str")
17955 (set_attr "memory" "store")
17956 (set_attr "mode" "HI")])
17957
17958 (define_insn "*strsetqi_1"
17959 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17960 (match_operand:QI 2 "register_operand" "a"))
17961 (set (match_operand:SI 0 "register_operand" "=D")
17962 (plus:SI (match_dup 1)
17963 (const_int 1)))
17964 (use (reg:SI DIRFLAG_REG))]
17965 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17966 "stosb"
17967 [(set_attr "type" "str")
17968 (set_attr "memory" "store")
17969 (set_attr "mode" "QI")])
17970
17971 (define_insn "*strsetqi_rex_1"
17972 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17973 (match_operand:QI 2 "register_operand" "a"))
17974 (set (match_operand:DI 0 "register_operand" "=D")
17975 (plus:DI (match_dup 1)
17976 (const_int 1)))
17977 (use (reg:SI DIRFLAG_REG))]
17978 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17979 "stosb"
17980 [(set_attr "type" "str")
17981 (set_attr "memory" "store")
17982 (set_attr "mode" "QI")])
17983
17984 (define_expand "rep_stos"
17985 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17986 (set (match_operand 0 "register_operand" "")
17987 (match_operand 4 "" ""))
17988 (set (match_operand 2 "memory_operand" "") (const_int 0))
17989 (use (match_operand 3 "register_operand" ""))
17990 (use (match_dup 1))
17991 (use (reg:SI DIRFLAG_REG))])]
17992 ""
17993 "")
17994
17995 (define_insn "*rep_stosdi_rex64"
17996 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17997 (set (match_operand:DI 0 "register_operand" "=D")
17998 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17999 (const_int 3))
18000 (match_operand:DI 3 "register_operand" "0")))
18001 (set (mem:BLK (match_dup 3))
18002 (const_int 0))
18003 (use (match_operand:DI 2 "register_operand" "a"))
18004 (use (match_dup 4))
18005 (use (reg:SI DIRFLAG_REG))]
18006 "TARGET_64BIT"
18007 "{rep\;stosq|rep stosq}"
18008 [(set_attr "type" "str")
18009 (set_attr "prefix_rep" "1")
18010 (set_attr "memory" "store")
18011 (set_attr "mode" "DI")])
18012
18013 (define_insn "*rep_stossi"
18014 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18015 (set (match_operand:SI 0 "register_operand" "=D")
18016 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18017 (const_int 2))
18018 (match_operand:SI 3 "register_operand" "0")))
18019 (set (mem:BLK (match_dup 3))
18020 (const_int 0))
18021 (use (match_operand:SI 2 "register_operand" "a"))
18022 (use (match_dup 4))
18023 (use (reg:SI DIRFLAG_REG))]
18024 "!TARGET_64BIT"
18025 "{rep\;stosl|rep stosd}"
18026 [(set_attr "type" "str")
18027 (set_attr "prefix_rep" "1")
18028 (set_attr "memory" "store")
18029 (set_attr "mode" "SI")])
18030
18031 (define_insn "*rep_stossi_rex64"
18032 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18033 (set (match_operand:DI 0 "register_operand" "=D")
18034 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18035 (const_int 2))
18036 (match_operand:DI 3 "register_operand" "0")))
18037 (set (mem:BLK (match_dup 3))
18038 (const_int 0))
18039 (use (match_operand:SI 2 "register_operand" "a"))
18040 (use (match_dup 4))
18041 (use (reg:SI DIRFLAG_REG))]
18042 "TARGET_64BIT"
18043 "{rep\;stosl|rep stosd}"
18044 [(set_attr "type" "str")
18045 (set_attr "prefix_rep" "1")
18046 (set_attr "memory" "store")
18047 (set_attr "mode" "SI")])
18048
18049 (define_insn "*rep_stosqi"
18050 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18051 (set (match_operand:SI 0 "register_operand" "=D")
18052 (plus:SI (match_operand:SI 3 "register_operand" "0")
18053 (match_operand:SI 4 "register_operand" "1")))
18054 (set (mem:BLK (match_dup 3))
18055 (const_int 0))
18056 (use (match_operand:QI 2 "register_operand" "a"))
18057 (use (match_dup 4))
18058 (use (reg:SI DIRFLAG_REG))]
18059 "!TARGET_64BIT"
18060 "{rep\;stosb|rep stosb}"
18061 [(set_attr "type" "str")
18062 (set_attr "prefix_rep" "1")
18063 (set_attr "memory" "store")
18064 (set_attr "mode" "QI")])
18065
18066 (define_insn "*rep_stosqi_rex64"
18067 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18068 (set (match_operand:DI 0 "register_operand" "=D")
18069 (plus:DI (match_operand:DI 3 "register_operand" "0")
18070 (match_operand:DI 4 "register_operand" "1")))
18071 (set (mem:BLK (match_dup 3))
18072 (const_int 0))
18073 (use (match_operand:QI 2 "register_operand" "a"))
18074 (use (match_dup 4))
18075 (use (reg:SI DIRFLAG_REG))]
18076 "TARGET_64BIT"
18077 "{rep\;stosb|rep stosb}"
18078 [(set_attr "type" "str")
18079 (set_attr "prefix_rep" "1")
18080 (set_attr "memory" "store")
18081 (set_attr "mode" "QI")])
18082
18083 (define_expand "cmpstrnsi"
18084 [(set (match_operand:SI 0 "register_operand" "")
18085 (compare:SI (match_operand:BLK 1 "general_operand" "")
18086 (match_operand:BLK 2 "general_operand" "")))
18087 (use (match_operand 3 "general_operand" ""))
18088 (use (match_operand 4 "immediate_operand" ""))]
18089 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18090 {
18091 rtx addr1, addr2, out, outlow, count, countreg, align;
18092
18093 /* Can't use this if the user has appropriated esi or edi. */
18094 if (global_regs[4] || global_regs[5])
18095 FAIL;
18096
18097 out = operands[0];
18098 if (GET_CODE (out) != REG)
18099 out = gen_reg_rtx (SImode);
18100
18101 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18102 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18103 if (addr1 != XEXP (operands[1], 0))
18104 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18105 if (addr2 != XEXP (operands[2], 0))
18106 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18107
18108 count = operands[3];
18109 countreg = ix86_zero_extend_to_Pmode (count);
18110
18111 /* %%% Iff we are testing strict equality, we can use known alignment
18112 to good advantage. This may be possible with combine, particularly
18113 once cc0 is dead. */
18114 align = operands[4];
18115
18116 emit_insn (gen_cld ());
18117 if (GET_CODE (count) == CONST_INT)
18118 {
18119 if (INTVAL (count) == 0)
18120 {
18121 emit_move_insn (operands[0], const0_rtx);
18122 DONE;
18123 }
18124 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18125 operands[1], operands[2]));
18126 }
18127 else
18128 {
18129 if (TARGET_64BIT)
18130 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18131 else
18132 emit_insn (gen_cmpsi_1 (countreg, countreg));
18133 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18134 operands[1], operands[2]));
18135 }
18136
18137 outlow = gen_lowpart (QImode, out);
18138 emit_insn (gen_cmpintqi (outlow));
18139 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18140
18141 if (operands[0] != out)
18142 emit_move_insn (operands[0], out);
18143
18144 DONE;
18145 })
18146
18147 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18148
18149 (define_expand "cmpintqi"
18150 [(set (match_dup 1)
18151 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18152 (set (match_dup 2)
18153 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18154 (parallel [(set (match_operand:QI 0 "register_operand" "")
18155 (minus:QI (match_dup 1)
18156 (match_dup 2)))
18157 (clobber (reg:CC FLAGS_REG))])]
18158 ""
18159 "operands[1] = gen_reg_rtx (QImode);
18160 operands[2] = gen_reg_rtx (QImode);")
18161
18162 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18163 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18164
18165 (define_expand "cmpstrnqi_nz_1"
18166 [(parallel [(set (reg:CC FLAGS_REG)
18167 (compare:CC (match_operand 4 "memory_operand" "")
18168 (match_operand 5 "memory_operand" "")))
18169 (use (match_operand 2 "register_operand" ""))
18170 (use (match_operand:SI 3 "immediate_operand" ""))
18171 (use (reg:SI DIRFLAG_REG))
18172 (clobber (match_operand 0 "register_operand" ""))
18173 (clobber (match_operand 1 "register_operand" ""))
18174 (clobber (match_dup 2))])]
18175 ""
18176 "")
18177
18178 (define_insn "*cmpstrnqi_nz_1"
18179 [(set (reg:CC FLAGS_REG)
18180 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18181 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18182 (use (match_operand:SI 6 "register_operand" "2"))
18183 (use (match_operand:SI 3 "immediate_operand" "i"))
18184 (use (reg:SI DIRFLAG_REG))
18185 (clobber (match_operand:SI 0 "register_operand" "=S"))
18186 (clobber (match_operand:SI 1 "register_operand" "=D"))
18187 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18188 "!TARGET_64BIT"
18189 "repz{\;| }cmpsb"
18190 [(set_attr "type" "str")
18191 (set_attr "mode" "QI")
18192 (set_attr "prefix_rep" "1")])
18193
18194 (define_insn "*cmpstrnqi_nz_rex_1"
18195 [(set (reg:CC FLAGS_REG)
18196 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18197 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18198 (use (match_operand:DI 6 "register_operand" "2"))
18199 (use (match_operand:SI 3 "immediate_operand" "i"))
18200 (use (reg:SI DIRFLAG_REG))
18201 (clobber (match_operand:DI 0 "register_operand" "=S"))
18202 (clobber (match_operand:DI 1 "register_operand" "=D"))
18203 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18204 "TARGET_64BIT"
18205 "repz{\;| }cmpsb"
18206 [(set_attr "type" "str")
18207 (set_attr "mode" "QI")
18208 (set_attr "prefix_rep" "1")])
18209
18210 ;; The same, but the count is not known to not be zero.
18211
18212 (define_expand "cmpstrnqi_1"
18213 [(parallel [(set (reg:CC FLAGS_REG)
18214 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18215 (const_int 0))
18216 (compare:CC (match_operand 4 "memory_operand" "")
18217 (match_operand 5 "memory_operand" ""))
18218 (const_int 0)))
18219 (use (match_operand:SI 3 "immediate_operand" ""))
18220 (use (reg:CC FLAGS_REG))
18221 (use (reg:SI DIRFLAG_REG))
18222 (clobber (match_operand 0 "register_operand" ""))
18223 (clobber (match_operand 1 "register_operand" ""))
18224 (clobber (match_dup 2))])]
18225 ""
18226 "")
18227
18228 (define_insn "*cmpstrnqi_1"
18229 [(set (reg:CC FLAGS_REG)
18230 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18231 (const_int 0))
18232 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18233 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18234 (const_int 0)))
18235 (use (match_operand:SI 3 "immediate_operand" "i"))
18236 (use (reg:CC FLAGS_REG))
18237 (use (reg:SI DIRFLAG_REG))
18238 (clobber (match_operand:SI 0 "register_operand" "=S"))
18239 (clobber (match_operand:SI 1 "register_operand" "=D"))
18240 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18241 "!TARGET_64BIT"
18242 "repz{\;| }cmpsb"
18243 [(set_attr "type" "str")
18244 (set_attr "mode" "QI")
18245 (set_attr "prefix_rep" "1")])
18246
18247 (define_insn "*cmpstrnqi_rex_1"
18248 [(set (reg:CC FLAGS_REG)
18249 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18250 (const_int 0))
18251 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18252 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18253 (const_int 0)))
18254 (use (match_operand:SI 3 "immediate_operand" "i"))
18255 (use (reg:CC FLAGS_REG))
18256 (use (reg:SI DIRFLAG_REG))
18257 (clobber (match_operand:DI 0 "register_operand" "=S"))
18258 (clobber (match_operand:DI 1 "register_operand" "=D"))
18259 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18260 "TARGET_64BIT"
18261 "repz{\;| }cmpsb"
18262 [(set_attr "type" "str")
18263 (set_attr "mode" "QI")
18264 (set_attr "prefix_rep" "1")])
18265
18266 (define_expand "strlensi"
18267 [(set (match_operand:SI 0 "register_operand" "")
18268 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18269 (match_operand:QI 2 "immediate_operand" "")
18270 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18271 ""
18272 {
18273 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18274 DONE;
18275 else
18276 FAIL;
18277 })
18278
18279 (define_expand "strlendi"
18280 [(set (match_operand:DI 0 "register_operand" "")
18281 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18282 (match_operand:QI 2 "immediate_operand" "")
18283 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18284 ""
18285 {
18286 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18287 DONE;
18288 else
18289 FAIL;
18290 })
18291
18292 (define_expand "strlenqi_1"
18293 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18294 (use (reg:SI DIRFLAG_REG))
18295 (clobber (match_operand 1 "register_operand" ""))
18296 (clobber (reg:CC FLAGS_REG))])]
18297 ""
18298 "")
18299
18300 (define_insn "*strlenqi_1"
18301 [(set (match_operand:SI 0 "register_operand" "=&c")
18302 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18303 (match_operand:QI 2 "register_operand" "a")
18304 (match_operand:SI 3 "immediate_operand" "i")
18305 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18306 (use (reg:SI DIRFLAG_REG))
18307 (clobber (match_operand:SI 1 "register_operand" "=D"))
18308 (clobber (reg:CC FLAGS_REG))]
18309 "!TARGET_64BIT"
18310 "repnz{\;| }scasb"
18311 [(set_attr "type" "str")
18312 (set_attr "mode" "QI")
18313 (set_attr "prefix_rep" "1")])
18314
18315 (define_insn "*strlenqi_rex_1"
18316 [(set (match_operand:DI 0 "register_operand" "=&c")
18317 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18318 (match_operand:QI 2 "register_operand" "a")
18319 (match_operand:DI 3 "immediate_operand" "i")
18320 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18321 (use (reg:SI DIRFLAG_REG))
18322 (clobber (match_operand:DI 1 "register_operand" "=D"))
18323 (clobber (reg:CC FLAGS_REG))]
18324 "TARGET_64BIT"
18325 "repnz{\;| }scasb"
18326 [(set_attr "type" "str")
18327 (set_attr "mode" "QI")
18328 (set_attr "prefix_rep" "1")])
18329
18330 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18331 ;; handled in combine, but it is not currently up to the task.
18332 ;; When used for their truth value, the cmpstrn* expanders generate
18333 ;; code like this:
18334 ;;
18335 ;; repz cmpsb
18336 ;; seta %al
18337 ;; setb %dl
18338 ;; cmpb %al, %dl
18339 ;; jcc label
18340 ;;
18341 ;; The intermediate three instructions are unnecessary.
18342
18343 ;; This one handles cmpstrn*_nz_1...
18344 (define_peephole2
18345 [(parallel[
18346 (set (reg:CC FLAGS_REG)
18347 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18348 (mem:BLK (match_operand 5 "register_operand" ""))))
18349 (use (match_operand 6 "register_operand" ""))
18350 (use (match_operand:SI 3 "immediate_operand" ""))
18351 (use (reg:SI DIRFLAG_REG))
18352 (clobber (match_operand 0 "register_operand" ""))
18353 (clobber (match_operand 1 "register_operand" ""))
18354 (clobber (match_operand 2 "register_operand" ""))])
18355 (set (match_operand:QI 7 "register_operand" "")
18356 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18357 (set (match_operand:QI 8 "register_operand" "")
18358 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18359 (set (reg FLAGS_REG)
18360 (compare (match_dup 7) (match_dup 8)))
18361 ]
18362 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18363 [(parallel[
18364 (set (reg:CC FLAGS_REG)
18365 (compare:CC (mem:BLK (match_dup 4))
18366 (mem:BLK (match_dup 5))))
18367 (use (match_dup 6))
18368 (use (match_dup 3))
18369 (use (reg:SI DIRFLAG_REG))
18370 (clobber (match_dup 0))
18371 (clobber (match_dup 1))
18372 (clobber (match_dup 2))])]
18373 "")
18374
18375 ;; ...and this one handles cmpstrn*_1.
18376 (define_peephole2
18377 [(parallel[
18378 (set (reg:CC FLAGS_REG)
18379 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18380 (const_int 0))
18381 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18382 (mem:BLK (match_operand 5 "register_operand" "")))
18383 (const_int 0)))
18384 (use (match_operand:SI 3 "immediate_operand" ""))
18385 (use (reg:CC FLAGS_REG))
18386 (use (reg:SI DIRFLAG_REG))
18387 (clobber (match_operand 0 "register_operand" ""))
18388 (clobber (match_operand 1 "register_operand" ""))
18389 (clobber (match_operand 2 "register_operand" ""))])
18390 (set (match_operand:QI 7 "register_operand" "")
18391 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18392 (set (match_operand:QI 8 "register_operand" "")
18393 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18394 (set (reg FLAGS_REG)
18395 (compare (match_dup 7) (match_dup 8)))
18396 ]
18397 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18398 [(parallel[
18399 (set (reg:CC FLAGS_REG)
18400 (if_then_else:CC (ne (match_dup 6)
18401 (const_int 0))
18402 (compare:CC (mem:BLK (match_dup 4))
18403 (mem:BLK (match_dup 5)))
18404 (const_int 0)))
18405 (use (match_dup 3))
18406 (use (reg:CC FLAGS_REG))
18407 (use (reg:SI DIRFLAG_REG))
18408 (clobber (match_dup 0))
18409 (clobber (match_dup 1))
18410 (clobber (match_dup 2))])]
18411 "")
18412
18413
18414 \f
18415 ;; Conditional move instructions.
18416
18417 (define_expand "movdicc"
18418 [(set (match_operand:DI 0 "register_operand" "")
18419 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18420 (match_operand:DI 2 "general_operand" "")
18421 (match_operand:DI 3 "general_operand" "")))]
18422 "TARGET_64BIT"
18423 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18424
18425 (define_insn "x86_movdicc_0_m1_rex64"
18426 [(set (match_operand:DI 0 "register_operand" "=r")
18427 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18428 (const_int -1)
18429 (const_int 0)))
18430 (clobber (reg:CC FLAGS_REG))]
18431 "TARGET_64BIT"
18432 "sbb{q}\t%0, %0"
18433 ; Since we don't have the proper number of operands for an alu insn,
18434 ; fill in all the blanks.
18435 [(set_attr "type" "alu")
18436 (set_attr "pent_pair" "pu")
18437 (set_attr "memory" "none")
18438 (set_attr "imm_disp" "false")
18439 (set_attr "mode" "DI")
18440 (set_attr "length_immediate" "0")])
18441
18442 (define_insn "*movdicc_c_rex64"
18443 [(set (match_operand:DI 0 "register_operand" "=r,r")
18444 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18445 [(reg FLAGS_REG) (const_int 0)])
18446 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18447 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18448 "TARGET_64BIT && TARGET_CMOVE
18449 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18450 "@
18451 cmov%O2%C1\t{%2, %0|%0, %2}
18452 cmov%O2%c1\t{%3, %0|%0, %3}"
18453 [(set_attr "type" "icmov")
18454 (set_attr "mode" "DI")])
18455
18456 (define_expand "movsicc"
18457 [(set (match_operand:SI 0 "register_operand" "")
18458 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18459 (match_operand:SI 2 "general_operand" "")
18460 (match_operand:SI 3 "general_operand" "")))]
18461 ""
18462 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18463
18464 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18465 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18466 ;; So just document what we're doing explicitly.
18467
18468 (define_insn "x86_movsicc_0_m1"
18469 [(set (match_operand:SI 0 "register_operand" "=r")
18470 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18471 (const_int -1)
18472 (const_int 0)))
18473 (clobber (reg:CC FLAGS_REG))]
18474 ""
18475 "sbb{l}\t%0, %0"
18476 ; Since we don't have the proper number of operands for an alu insn,
18477 ; fill in all the blanks.
18478 [(set_attr "type" "alu")
18479 (set_attr "pent_pair" "pu")
18480 (set_attr "memory" "none")
18481 (set_attr "imm_disp" "false")
18482 (set_attr "mode" "SI")
18483 (set_attr "length_immediate" "0")])
18484
18485 (define_insn "*movsicc_noc"
18486 [(set (match_operand:SI 0 "register_operand" "=r,r")
18487 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18488 [(reg FLAGS_REG) (const_int 0)])
18489 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18490 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18491 "TARGET_CMOVE
18492 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18493 "@
18494 cmov%O2%C1\t{%2, %0|%0, %2}
18495 cmov%O2%c1\t{%3, %0|%0, %3}"
18496 [(set_attr "type" "icmov")
18497 (set_attr "mode" "SI")])
18498
18499 (define_expand "movhicc"
18500 [(set (match_operand:HI 0 "register_operand" "")
18501 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18502 (match_operand:HI 2 "general_operand" "")
18503 (match_operand:HI 3 "general_operand" "")))]
18504 "TARGET_HIMODE_MATH"
18505 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18506
18507 (define_insn "*movhicc_noc"
18508 [(set (match_operand:HI 0 "register_operand" "=r,r")
18509 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18510 [(reg FLAGS_REG) (const_int 0)])
18511 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18512 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18513 "TARGET_CMOVE
18514 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18515 "@
18516 cmov%O2%C1\t{%2, %0|%0, %2}
18517 cmov%O2%c1\t{%3, %0|%0, %3}"
18518 [(set_attr "type" "icmov")
18519 (set_attr "mode" "HI")])
18520
18521 (define_expand "movqicc"
18522 [(set (match_operand:QI 0 "register_operand" "")
18523 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18524 (match_operand:QI 2 "general_operand" "")
18525 (match_operand:QI 3 "general_operand" "")))]
18526 "TARGET_QIMODE_MATH"
18527 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18528
18529 (define_insn_and_split "*movqicc_noc"
18530 [(set (match_operand:QI 0 "register_operand" "=r,r")
18531 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18532 [(match_operand 4 "flags_reg_operand" "")
18533 (const_int 0)])
18534 (match_operand:QI 2 "register_operand" "r,0")
18535 (match_operand:QI 3 "register_operand" "0,r")))]
18536 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18537 "#"
18538 "&& reload_completed"
18539 [(set (match_dup 0)
18540 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18541 (match_dup 2)
18542 (match_dup 3)))]
18543 "operands[0] = gen_lowpart (SImode, operands[0]);
18544 operands[2] = gen_lowpart (SImode, operands[2]);
18545 operands[3] = gen_lowpart (SImode, operands[3]);"
18546 [(set_attr "type" "icmov")
18547 (set_attr "mode" "SI")])
18548
18549 (define_expand "movsfcc"
18550 [(set (match_operand:SF 0 "register_operand" "")
18551 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18552 (match_operand:SF 2 "register_operand" "")
18553 (match_operand:SF 3 "register_operand" "")))]
18554 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18555 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18556
18557 (define_insn "*movsfcc_1_387"
18558 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18559 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18560 [(reg FLAGS_REG) (const_int 0)])
18561 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18562 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18563 "TARGET_80387 && TARGET_CMOVE
18564 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18565 "@
18566 fcmov%F1\t{%2, %0|%0, %2}
18567 fcmov%f1\t{%3, %0|%0, %3}
18568 cmov%O2%C1\t{%2, %0|%0, %2}
18569 cmov%O2%c1\t{%3, %0|%0, %3}"
18570 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18571 (set_attr "mode" "SF,SF,SI,SI")])
18572
18573 (define_expand "movdfcc"
18574 [(set (match_operand:DF 0 "register_operand" "")
18575 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18576 (match_operand:DF 2 "register_operand" "")
18577 (match_operand:DF 3 "register_operand" "")))]
18578 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18579 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18580
18581 (define_insn "*movdfcc_1"
18582 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18583 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18584 [(reg FLAGS_REG) (const_int 0)])
18585 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18586 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18587 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18588 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18589 "@
18590 fcmov%F1\t{%2, %0|%0, %2}
18591 fcmov%f1\t{%3, %0|%0, %3}
18592 #
18593 #"
18594 [(set_attr "type" "fcmov,fcmov,multi,multi")
18595 (set_attr "mode" "DF")])
18596
18597 (define_insn "*movdfcc_1_rex64"
18598 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18599 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18600 [(reg FLAGS_REG) (const_int 0)])
18601 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18602 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18603 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18604 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18605 "@
18606 fcmov%F1\t{%2, %0|%0, %2}
18607 fcmov%f1\t{%3, %0|%0, %3}
18608 cmov%O2%C1\t{%2, %0|%0, %2}
18609 cmov%O2%c1\t{%3, %0|%0, %3}"
18610 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18611 (set_attr "mode" "DF")])
18612
18613 (define_split
18614 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18615 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18616 [(match_operand 4 "flags_reg_operand" "")
18617 (const_int 0)])
18618 (match_operand:DF 2 "nonimmediate_operand" "")
18619 (match_operand:DF 3 "nonimmediate_operand" "")))]
18620 "!TARGET_64BIT && reload_completed"
18621 [(set (match_dup 2)
18622 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18623 (match_dup 5)
18624 (match_dup 7)))
18625 (set (match_dup 3)
18626 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18627 (match_dup 6)
18628 (match_dup 8)))]
18629 "split_di (operands+2, 1, operands+5, operands+6);
18630 split_di (operands+3, 1, operands+7, operands+8);
18631 split_di (operands, 1, operands+2, operands+3);")
18632
18633 (define_expand "movxfcc"
18634 [(set (match_operand:XF 0 "register_operand" "")
18635 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18636 (match_operand:XF 2 "register_operand" "")
18637 (match_operand:XF 3 "register_operand" "")))]
18638 "TARGET_80387 && TARGET_CMOVE"
18639 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18640
18641 (define_insn "*movxfcc_1"
18642 [(set (match_operand:XF 0 "register_operand" "=f,f")
18643 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18644 [(reg FLAGS_REG) (const_int 0)])
18645 (match_operand:XF 2 "register_operand" "f,0")
18646 (match_operand:XF 3 "register_operand" "0,f")))]
18647 "TARGET_80387 && TARGET_CMOVE"
18648 "@
18649 fcmov%F1\t{%2, %0|%0, %2}
18650 fcmov%f1\t{%3, %0|%0, %3}"
18651 [(set_attr "type" "fcmov")
18652 (set_attr "mode" "XF")])
18653
18654 ;; These versions of the min/max patterns are intentionally ignorant of
18655 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18656 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18657 ;; are undefined in this condition, we're certain this is correct.
18658
18659 (define_insn "sminsf3"
18660 [(set (match_operand:SF 0 "register_operand" "=x")
18661 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18662 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18663 "TARGET_SSE_MATH"
18664 "minss\t{%2, %0|%0, %2}"
18665 [(set_attr "type" "sseadd")
18666 (set_attr "mode" "SF")])
18667
18668 (define_insn "smaxsf3"
18669 [(set (match_operand:SF 0 "register_operand" "=x")
18670 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18671 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18672 "TARGET_SSE_MATH"
18673 "maxss\t{%2, %0|%0, %2}"
18674 [(set_attr "type" "sseadd")
18675 (set_attr "mode" "SF")])
18676
18677 (define_insn "smindf3"
18678 [(set (match_operand:DF 0 "register_operand" "=x")
18679 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18680 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18681 "TARGET_SSE2 && TARGET_SSE_MATH"
18682 "minsd\t{%2, %0|%0, %2}"
18683 [(set_attr "type" "sseadd")
18684 (set_attr "mode" "DF")])
18685
18686 (define_insn "smaxdf3"
18687 [(set (match_operand:DF 0 "register_operand" "=x")
18688 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18689 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18690 "TARGET_SSE2 && TARGET_SSE_MATH"
18691 "maxsd\t{%2, %0|%0, %2}"
18692 [(set_attr "type" "sseadd")
18693 (set_attr "mode" "DF")])
18694
18695 ;; These versions of the min/max patterns implement exactly the operations
18696 ;; min = (op1 < op2 ? op1 : op2)
18697 ;; max = (!(op1 < op2) ? op1 : op2)
18698 ;; Their operands are not commutative, and thus they may be used in the
18699 ;; presence of -0.0 and NaN.
18700
18701 (define_insn "*ieee_sminsf3"
18702 [(set (match_operand:SF 0 "register_operand" "=x")
18703 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18704 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18705 UNSPEC_IEEE_MIN))]
18706 "TARGET_SSE_MATH"
18707 "minss\t{%2, %0|%0, %2}"
18708 [(set_attr "type" "sseadd")
18709 (set_attr "mode" "SF")])
18710
18711 (define_insn "*ieee_smaxsf3"
18712 [(set (match_operand:SF 0 "register_operand" "=x")
18713 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18714 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18715 UNSPEC_IEEE_MAX))]
18716 "TARGET_SSE_MATH"
18717 "maxss\t{%2, %0|%0, %2}"
18718 [(set_attr "type" "sseadd")
18719 (set_attr "mode" "SF")])
18720
18721 (define_insn "*ieee_smindf3"
18722 [(set (match_operand:DF 0 "register_operand" "=x")
18723 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18724 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18725 UNSPEC_IEEE_MIN))]
18726 "TARGET_SSE2 && TARGET_SSE_MATH"
18727 "minsd\t{%2, %0|%0, %2}"
18728 [(set_attr "type" "sseadd")
18729 (set_attr "mode" "DF")])
18730
18731 (define_insn "*ieee_smaxdf3"
18732 [(set (match_operand:DF 0 "register_operand" "=x")
18733 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18734 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18735 UNSPEC_IEEE_MAX))]
18736 "TARGET_SSE2 && TARGET_SSE_MATH"
18737 "maxsd\t{%2, %0|%0, %2}"
18738 [(set_attr "type" "sseadd")
18739 (set_attr "mode" "DF")])
18740
18741 ;; Conditional addition patterns
18742 (define_expand "addqicc"
18743 [(match_operand:QI 0 "register_operand" "")
18744 (match_operand 1 "comparison_operator" "")
18745 (match_operand:QI 2 "register_operand" "")
18746 (match_operand:QI 3 "const_int_operand" "")]
18747 ""
18748 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18749
18750 (define_expand "addhicc"
18751 [(match_operand:HI 0 "register_operand" "")
18752 (match_operand 1 "comparison_operator" "")
18753 (match_operand:HI 2 "register_operand" "")
18754 (match_operand:HI 3 "const_int_operand" "")]
18755 ""
18756 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18757
18758 (define_expand "addsicc"
18759 [(match_operand:SI 0 "register_operand" "")
18760 (match_operand 1 "comparison_operator" "")
18761 (match_operand:SI 2 "register_operand" "")
18762 (match_operand:SI 3 "const_int_operand" "")]
18763 ""
18764 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18765
18766 (define_expand "adddicc"
18767 [(match_operand:DI 0 "register_operand" "")
18768 (match_operand 1 "comparison_operator" "")
18769 (match_operand:DI 2 "register_operand" "")
18770 (match_operand:DI 3 "const_int_operand" "")]
18771 "TARGET_64BIT"
18772 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18773
18774 \f
18775 ;; Misc patterns (?)
18776
18777 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18778 ;; Otherwise there will be nothing to keep
18779 ;;
18780 ;; [(set (reg ebp) (reg esp))]
18781 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18782 ;; (clobber (eflags)]
18783 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18784 ;;
18785 ;; in proper program order.
18786 (define_insn "pro_epilogue_adjust_stack_1"
18787 [(set (match_operand:SI 0 "register_operand" "=r,r")
18788 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18789 (match_operand:SI 2 "immediate_operand" "i,i")))
18790 (clobber (reg:CC FLAGS_REG))
18791 (clobber (mem:BLK (scratch)))]
18792 "!TARGET_64BIT"
18793 {
18794 switch (get_attr_type (insn))
18795 {
18796 case TYPE_IMOV:
18797 return "mov{l}\t{%1, %0|%0, %1}";
18798
18799 case TYPE_ALU:
18800 if (GET_CODE (operands[2]) == CONST_INT
18801 && (INTVAL (operands[2]) == 128
18802 || (INTVAL (operands[2]) < 0
18803 && INTVAL (operands[2]) != -128)))
18804 {
18805 operands[2] = GEN_INT (-INTVAL (operands[2]));
18806 return "sub{l}\t{%2, %0|%0, %2}";
18807 }
18808 return "add{l}\t{%2, %0|%0, %2}";
18809
18810 case TYPE_LEA:
18811 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18812 return "lea{l}\t{%a2, %0|%0, %a2}";
18813
18814 default:
18815 gcc_unreachable ();
18816 }
18817 }
18818 [(set (attr "type")
18819 (cond [(eq_attr "alternative" "0")
18820 (const_string "alu")
18821 (match_operand:SI 2 "const0_operand" "")
18822 (const_string "imov")
18823 ]
18824 (const_string "lea")))
18825 (set_attr "mode" "SI")])
18826
18827 (define_insn "pro_epilogue_adjust_stack_rex64"
18828 [(set (match_operand:DI 0 "register_operand" "=r,r")
18829 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18830 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18831 (clobber (reg:CC FLAGS_REG))
18832 (clobber (mem:BLK (scratch)))]
18833 "TARGET_64BIT"
18834 {
18835 switch (get_attr_type (insn))
18836 {
18837 case TYPE_IMOV:
18838 return "mov{q}\t{%1, %0|%0, %1}";
18839
18840 case TYPE_ALU:
18841 if (GET_CODE (operands[2]) == CONST_INT
18842 /* Avoid overflows. */
18843 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18844 && (INTVAL (operands[2]) == 128
18845 || (INTVAL (operands[2]) < 0
18846 && INTVAL (operands[2]) != -128)))
18847 {
18848 operands[2] = GEN_INT (-INTVAL (operands[2]));
18849 return "sub{q}\t{%2, %0|%0, %2}";
18850 }
18851 return "add{q}\t{%2, %0|%0, %2}";
18852
18853 case TYPE_LEA:
18854 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18855 return "lea{q}\t{%a2, %0|%0, %a2}";
18856
18857 default:
18858 gcc_unreachable ();
18859 }
18860 }
18861 [(set (attr "type")
18862 (cond [(eq_attr "alternative" "0")
18863 (const_string "alu")
18864 (match_operand:DI 2 "const0_operand" "")
18865 (const_string "imov")
18866 ]
18867 (const_string "lea")))
18868 (set_attr "mode" "DI")])
18869
18870 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18871 [(set (match_operand:DI 0 "register_operand" "=r,r")
18872 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18873 (match_operand:DI 3 "immediate_operand" "i,i")))
18874 (use (match_operand:DI 2 "register_operand" "r,r"))
18875 (clobber (reg:CC FLAGS_REG))
18876 (clobber (mem:BLK (scratch)))]
18877 "TARGET_64BIT"
18878 {
18879 switch (get_attr_type (insn))
18880 {
18881 case TYPE_ALU:
18882 return "add{q}\t{%2, %0|%0, %2}";
18883
18884 case TYPE_LEA:
18885 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18886 return "lea{q}\t{%a2, %0|%0, %a2}";
18887
18888 default:
18889 gcc_unreachable ();
18890 }
18891 }
18892 [(set_attr "type" "alu,lea")
18893 (set_attr "mode" "DI")])
18894
18895 (define_expand "allocate_stack_worker"
18896 [(match_operand:SI 0 "register_operand" "")]
18897 "TARGET_STACK_PROBE"
18898 {
18899 if (reload_completed)
18900 {
18901 if (TARGET_64BIT)
18902 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18903 else
18904 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18905 }
18906 else
18907 {
18908 if (TARGET_64BIT)
18909 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18910 else
18911 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18912 }
18913 DONE;
18914 })
18915
18916 (define_insn "allocate_stack_worker_1"
18917 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18918 UNSPECV_STACK_PROBE)
18919 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18920 (clobber (match_scratch:SI 1 "=0"))
18921 (clobber (reg:CC FLAGS_REG))]
18922 "!TARGET_64BIT && TARGET_STACK_PROBE"
18923 "call\t__alloca"
18924 [(set_attr "type" "multi")
18925 (set_attr "length" "5")])
18926
18927 (define_expand "allocate_stack_worker_postreload"
18928 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18929 UNSPECV_STACK_PROBE)
18930 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18931 (clobber (match_dup 0))
18932 (clobber (reg:CC FLAGS_REG))])]
18933 ""
18934 "")
18935
18936 (define_insn "allocate_stack_worker_rex64"
18937 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18938 UNSPECV_STACK_PROBE)
18939 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18940 (clobber (match_scratch:DI 1 "=0"))
18941 (clobber (reg:CC FLAGS_REG))]
18942 "TARGET_64BIT && TARGET_STACK_PROBE"
18943 "call\t__alloca"
18944 [(set_attr "type" "multi")
18945 (set_attr "length" "5")])
18946
18947 (define_expand "allocate_stack_worker_rex64_postreload"
18948 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18949 UNSPECV_STACK_PROBE)
18950 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18951 (clobber (match_dup 0))
18952 (clobber (reg:CC FLAGS_REG))])]
18953 ""
18954 "")
18955
18956 (define_expand "allocate_stack"
18957 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18958 (minus:SI (reg:SI SP_REG)
18959 (match_operand:SI 1 "general_operand" "")))
18960 (clobber (reg:CC FLAGS_REG))])
18961 (parallel [(set (reg:SI SP_REG)
18962 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18963 (clobber (reg:CC FLAGS_REG))])]
18964 "TARGET_STACK_PROBE"
18965 {
18966 #ifdef CHECK_STACK_LIMIT
18967 if (GET_CODE (operands[1]) == CONST_INT
18968 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18969 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18970 operands[1]));
18971 else
18972 #endif
18973 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18974 operands[1])));
18975
18976 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18977 DONE;
18978 })
18979
18980 (define_expand "builtin_setjmp_receiver"
18981 [(label_ref (match_operand 0 "" ""))]
18982 "!TARGET_64BIT && flag_pic"
18983 {
18984 if (TARGET_MACHO)
18985 {
18986 rtx xops[3];
18987 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18988 rtx label_rtx = gen_label_rtx ();
18989 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18990 emit_label (label_rtx);
18991 xops[0] = xops[1] = picreg;
18992 xops[2] = gen_rtx_CONST (SImode,
18993 gen_rtx_MINUS (SImode,
18994 gen_rtx_LABEL_REF (SImode, label_rtx),
18995 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
18996 ix86_expand_binary_operator (MINUS, SImode, xops);
18997 }
18998 else
18999 emit_insn (gen_set_got (pic_offset_table_rtx));
19000 DONE;
19001 })
19002 \f
19003 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19004
19005 (define_split
19006 [(set (match_operand 0 "register_operand" "")
19007 (match_operator 3 "promotable_binary_operator"
19008 [(match_operand 1 "register_operand" "")
19009 (match_operand 2 "aligned_operand" "")]))
19010 (clobber (reg:CC FLAGS_REG))]
19011 "! TARGET_PARTIAL_REG_STALL && reload_completed
19012 && ((GET_MODE (operands[0]) == HImode
19013 && ((!optimize_size && !TARGET_FAST_PREFIX)
19014 || GET_CODE (operands[2]) != CONST_INT
19015 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
19016 || (GET_MODE (operands[0]) == QImode
19017 && (TARGET_PROMOTE_QImode || optimize_size)))"
19018 [(parallel [(set (match_dup 0)
19019 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19020 (clobber (reg:CC FLAGS_REG))])]
19021 "operands[0] = gen_lowpart (SImode, operands[0]);
19022 operands[1] = gen_lowpart (SImode, operands[1]);
19023 if (GET_CODE (operands[3]) != ASHIFT)
19024 operands[2] = gen_lowpart (SImode, operands[2]);
19025 PUT_MODE (operands[3], SImode);")
19026
19027 ; Promote the QImode tests, as i386 has encoding of the AND
19028 ; instruction with 32-bit sign-extended immediate and thus the
19029 ; instruction size is unchanged, except in the %eax case for
19030 ; which it is increased by one byte, hence the ! optimize_size.
19031 (define_split
19032 [(set (match_operand 0 "flags_reg_operand" "")
19033 (match_operator 2 "compare_operator"
19034 [(and (match_operand 3 "aligned_operand" "")
19035 (match_operand 4 "const_int_operand" ""))
19036 (const_int 0)]))
19037 (set (match_operand 1 "register_operand" "")
19038 (and (match_dup 3) (match_dup 4)))]
19039 "! TARGET_PARTIAL_REG_STALL && reload_completed
19040 /* Ensure that the operand will remain sign-extended immediate. */
19041 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19042 && ! optimize_size
19043 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19044 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19045 [(parallel [(set (match_dup 0)
19046 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19047 (const_int 0)]))
19048 (set (match_dup 1)
19049 (and:SI (match_dup 3) (match_dup 4)))])]
19050 {
19051 operands[4]
19052 = gen_int_mode (INTVAL (operands[4])
19053 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19054 operands[1] = gen_lowpart (SImode, operands[1]);
19055 operands[3] = gen_lowpart (SImode, operands[3]);
19056 })
19057
19058 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19059 ; the TEST instruction with 32-bit sign-extended immediate and thus
19060 ; the instruction size would at least double, which is not what we
19061 ; want even with ! optimize_size.
19062 (define_split
19063 [(set (match_operand 0 "flags_reg_operand" "")
19064 (match_operator 1 "compare_operator"
19065 [(and (match_operand:HI 2 "aligned_operand" "")
19066 (match_operand:HI 3 "const_int_operand" ""))
19067 (const_int 0)]))]
19068 "! TARGET_PARTIAL_REG_STALL && reload_completed
19069 /* Ensure that the operand will remain sign-extended immediate. */
19070 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19071 && ! TARGET_FAST_PREFIX
19072 && ! optimize_size"
19073 [(set (match_dup 0)
19074 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19075 (const_int 0)]))]
19076 {
19077 operands[3]
19078 = gen_int_mode (INTVAL (operands[3])
19079 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19080 operands[2] = gen_lowpart (SImode, operands[2]);
19081 })
19082
19083 (define_split
19084 [(set (match_operand 0 "register_operand" "")
19085 (neg (match_operand 1 "register_operand" "")))
19086 (clobber (reg:CC FLAGS_REG))]
19087 "! TARGET_PARTIAL_REG_STALL && reload_completed
19088 && (GET_MODE (operands[0]) == HImode
19089 || (GET_MODE (operands[0]) == QImode
19090 && (TARGET_PROMOTE_QImode || optimize_size)))"
19091 [(parallel [(set (match_dup 0)
19092 (neg:SI (match_dup 1)))
19093 (clobber (reg:CC FLAGS_REG))])]
19094 "operands[0] = gen_lowpart (SImode, operands[0]);
19095 operands[1] = gen_lowpart (SImode, operands[1]);")
19096
19097 (define_split
19098 [(set (match_operand 0 "register_operand" "")
19099 (not (match_operand 1 "register_operand" "")))]
19100 "! TARGET_PARTIAL_REG_STALL && reload_completed
19101 && (GET_MODE (operands[0]) == HImode
19102 || (GET_MODE (operands[0]) == QImode
19103 && (TARGET_PROMOTE_QImode || optimize_size)))"
19104 [(set (match_dup 0)
19105 (not:SI (match_dup 1)))]
19106 "operands[0] = gen_lowpart (SImode, operands[0]);
19107 operands[1] = gen_lowpart (SImode, operands[1]);")
19108
19109 (define_split
19110 [(set (match_operand 0 "register_operand" "")
19111 (if_then_else (match_operator 1 "comparison_operator"
19112 [(reg FLAGS_REG) (const_int 0)])
19113 (match_operand 2 "register_operand" "")
19114 (match_operand 3 "register_operand" "")))]
19115 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19116 && (GET_MODE (operands[0]) == HImode
19117 || (GET_MODE (operands[0]) == QImode
19118 && (TARGET_PROMOTE_QImode || optimize_size)))"
19119 [(set (match_dup 0)
19120 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19121 "operands[0] = gen_lowpart (SImode, operands[0]);
19122 operands[2] = gen_lowpart (SImode, operands[2]);
19123 operands[3] = gen_lowpart (SImode, operands[3]);")
19124
19125 \f
19126 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19127 ;; transform a complex memory operation into two memory to register operations.
19128
19129 ;; Don't push memory operands
19130 (define_peephole2
19131 [(set (match_operand:SI 0 "push_operand" "")
19132 (match_operand:SI 1 "memory_operand" ""))
19133 (match_scratch:SI 2 "r")]
19134 "!optimize_size && !TARGET_PUSH_MEMORY
19135 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19136 [(set (match_dup 2) (match_dup 1))
19137 (set (match_dup 0) (match_dup 2))]
19138 "")
19139
19140 (define_peephole2
19141 [(set (match_operand:DI 0 "push_operand" "")
19142 (match_operand:DI 1 "memory_operand" ""))
19143 (match_scratch:DI 2 "r")]
19144 "!optimize_size && !TARGET_PUSH_MEMORY
19145 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19146 [(set (match_dup 2) (match_dup 1))
19147 (set (match_dup 0) (match_dup 2))]
19148 "")
19149
19150 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19151 ;; SImode pushes.
19152 (define_peephole2
19153 [(set (match_operand:SF 0 "push_operand" "")
19154 (match_operand:SF 1 "memory_operand" ""))
19155 (match_scratch:SF 2 "r")]
19156 "!optimize_size && !TARGET_PUSH_MEMORY
19157 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19158 [(set (match_dup 2) (match_dup 1))
19159 (set (match_dup 0) (match_dup 2))]
19160 "")
19161
19162 (define_peephole2
19163 [(set (match_operand:HI 0 "push_operand" "")
19164 (match_operand:HI 1 "memory_operand" ""))
19165 (match_scratch:HI 2 "r")]
19166 "!optimize_size && !TARGET_PUSH_MEMORY
19167 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19168 [(set (match_dup 2) (match_dup 1))
19169 (set (match_dup 0) (match_dup 2))]
19170 "")
19171
19172 (define_peephole2
19173 [(set (match_operand:QI 0 "push_operand" "")
19174 (match_operand:QI 1 "memory_operand" ""))
19175 (match_scratch:QI 2 "q")]
19176 "!optimize_size && !TARGET_PUSH_MEMORY
19177 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19178 [(set (match_dup 2) (match_dup 1))
19179 (set (match_dup 0) (match_dup 2))]
19180 "")
19181
19182 ;; Don't move an immediate directly to memory when the instruction
19183 ;; gets too big.
19184 (define_peephole2
19185 [(match_scratch:SI 1 "r")
19186 (set (match_operand:SI 0 "memory_operand" "")
19187 (const_int 0))]
19188 "! optimize_size
19189 && ! TARGET_USE_MOV0
19190 && TARGET_SPLIT_LONG_MOVES
19191 && get_attr_length (insn) >= ix86_cost->large_insn
19192 && peep2_regno_dead_p (0, FLAGS_REG)"
19193 [(parallel [(set (match_dup 1) (const_int 0))
19194 (clobber (reg:CC FLAGS_REG))])
19195 (set (match_dup 0) (match_dup 1))]
19196 "")
19197
19198 (define_peephole2
19199 [(match_scratch:HI 1 "r")
19200 (set (match_operand:HI 0 "memory_operand" "")
19201 (const_int 0))]
19202 "! optimize_size
19203 && ! TARGET_USE_MOV0
19204 && TARGET_SPLIT_LONG_MOVES
19205 && get_attr_length (insn) >= ix86_cost->large_insn
19206 && peep2_regno_dead_p (0, FLAGS_REG)"
19207 [(parallel [(set (match_dup 2) (const_int 0))
19208 (clobber (reg:CC FLAGS_REG))])
19209 (set (match_dup 0) (match_dup 1))]
19210 "operands[2] = gen_lowpart (SImode, operands[1]);")
19211
19212 (define_peephole2
19213 [(match_scratch:QI 1 "q")
19214 (set (match_operand:QI 0 "memory_operand" "")
19215 (const_int 0))]
19216 "! optimize_size
19217 && ! TARGET_USE_MOV0
19218 && TARGET_SPLIT_LONG_MOVES
19219 && get_attr_length (insn) >= ix86_cost->large_insn
19220 && peep2_regno_dead_p (0, FLAGS_REG)"
19221 [(parallel [(set (match_dup 2) (const_int 0))
19222 (clobber (reg:CC FLAGS_REG))])
19223 (set (match_dup 0) (match_dup 1))]
19224 "operands[2] = gen_lowpart (SImode, operands[1]);")
19225
19226 (define_peephole2
19227 [(match_scratch:SI 2 "r")
19228 (set (match_operand:SI 0 "memory_operand" "")
19229 (match_operand:SI 1 "immediate_operand" ""))]
19230 "! optimize_size
19231 && get_attr_length (insn) >= ix86_cost->large_insn
19232 && TARGET_SPLIT_LONG_MOVES"
19233 [(set (match_dup 2) (match_dup 1))
19234 (set (match_dup 0) (match_dup 2))]
19235 "")
19236
19237 (define_peephole2
19238 [(match_scratch:HI 2 "r")
19239 (set (match_operand:HI 0 "memory_operand" "")
19240 (match_operand:HI 1 "immediate_operand" ""))]
19241 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19242 && TARGET_SPLIT_LONG_MOVES"
19243 [(set (match_dup 2) (match_dup 1))
19244 (set (match_dup 0) (match_dup 2))]
19245 "")
19246
19247 (define_peephole2
19248 [(match_scratch:QI 2 "q")
19249 (set (match_operand:QI 0 "memory_operand" "")
19250 (match_operand:QI 1 "immediate_operand" ""))]
19251 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19252 && TARGET_SPLIT_LONG_MOVES"
19253 [(set (match_dup 2) (match_dup 1))
19254 (set (match_dup 0) (match_dup 2))]
19255 "")
19256
19257 ;; Don't compare memory with zero, load and use a test instead.
19258 (define_peephole2
19259 [(set (match_operand 0 "flags_reg_operand" "")
19260 (match_operator 1 "compare_operator"
19261 [(match_operand:SI 2 "memory_operand" "")
19262 (const_int 0)]))
19263 (match_scratch:SI 3 "r")]
19264 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19265 [(set (match_dup 3) (match_dup 2))
19266 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19267 "")
19268
19269 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19270 ;; Don't split NOTs with a displacement operand, because resulting XOR
19271 ;; will not be pairable anyway.
19272 ;;
19273 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19274 ;; represented using a modRM byte. The XOR replacement is long decoded,
19275 ;; so this split helps here as well.
19276 ;;
19277 ;; Note: Can't do this as a regular split because we can't get proper
19278 ;; lifetime information then.
19279
19280 (define_peephole2
19281 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19282 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19283 "!optimize_size
19284 && peep2_regno_dead_p (0, FLAGS_REG)
19285 && ((TARGET_PENTIUM
19286 && (GET_CODE (operands[0]) != MEM
19287 || !memory_displacement_operand (operands[0], SImode)))
19288 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19289 [(parallel [(set (match_dup 0)
19290 (xor:SI (match_dup 1) (const_int -1)))
19291 (clobber (reg:CC FLAGS_REG))])]
19292 "")
19293
19294 (define_peephole2
19295 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19296 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19297 "!optimize_size
19298 && peep2_regno_dead_p (0, FLAGS_REG)
19299 && ((TARGET_PENTIUM
19300 && (GET_CODE (operands[0]) != MEM
19301 || !memory_displacement_operand (operands[0], HImode)))
19302 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19303 [(parallel [(set (match_dup 0)
19304 (xor:HI (match_dup 1) (const_int -1)))
19305 (clobber (reg:CC FLAGS_REG))])]
19306 "")
19307
19308 (define_peephole2
19309 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19310 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19311 "!optimize_size
19312 && peep2_regno_dead_p (0, FLAGS_REG)
19313 && ((TARGET_PENTIUM
19314 && (GET_CODE (operands[0]) != MEM
19315 || !memory_displacement_operand (operands[0], QImode)))
19316 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19317 [(parallel [(set (match_dup 0)
19318 (xor:QI (match_dup 1) (const_int -1)))
19319 (clobber (reg:CC FLAGS_REG))])]
19320 "")
19321
19322 ;; Non pairable "test imm, reg" instructions can be translated to
19323 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19324 ;; byte opcode instead of two, have a short form for byte operands),
19325 ;; so do it for other CPUs as well. Given that the value was dead,
19326 ;; this should not create any new dependencies. Pass on the sub-word
19327 ;; versions if we're concerned about partial register stalls.
19328
19329 (define_peephole2
19330 [(set (match_operand 0 "flags_reg_operand" "")
19331 (match_operator 1 "compare_operator"
19332 [(and:SI (match_operand:SI 2 "register_operand" "")
19333 (match_operand:SI 3 "immediate_operand" ""))
19334 (const_int 0)]))]
19335 "ix86_match_ccmode (insn, CCNOmode)
19336 && (true_regnum (operands[2]) != 0
19337 || (GET_CODE (operands[3]) == CONST_INT
19338 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19339 && peep2_reg_dead_p (1, operands[2])"
19340 [(parallel
19341 [(set (match_dup 0)
19342 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19343 (const_int 0)]))
19344 (set (match_dup 2)
19345 (and:SI (match_dup 2) (match_dup 3)))])]
19346 "")
19347
19348 ;; We don't need to handle HImode case, because it will be promoted to SImode
19349 ;; on ! TARGET_PARTIAL_REG_STALL
19350
19351 (define_peephole2
19352 [(set (match_operand 0 "flags_reg_operand" "")
19353 (match_operator 1 "compare_operator"
19354 [(and:QI (match_operand:QI 2 "register_operand" "")
19355 (match_operand:QI 3 "immediate_operand" ""))
19356 (const_int 0)]))]
19357 "! TARGET_PARTIAL_REG_STALL
19358 && ix86_match_ccmode (insn, CCNOmode)
19359 && true_regnum (operands[2]) != 0
19360 && peep2_reg_dead_p (1, operands[2])"
19361 [(parallel
19362 [(set (match_dup 0)
19363 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19364 (const_int 0)]))
19365 (set (match_dup 2)
19366 (and:QI (match_dup 2) (match_dup 3)))])]
19367 "")
19368
19369 (define_peephole2
19370 [(set (match_operand 0 "flags_reg_operand" "")
19371 (match_operator 1 "compare_operator"
19372 [(and:SI
19373 (zero_extract:SI
19374 (match_operand 2 "ext_register_operand" "")
19375 (const_int 8)
19376 (const_int 8))
19377 (match_operand 3 "const_int_operand" ""))
19378 (const_int 0)]))]
19379 "! TARGET_PARTIAL_REG_STALL
19380 && ix86_match_ccmode (insn, CCNOmode)
19381 && true_regnum (operands[2]) != 0
19382 && peep2_reg_dead_p (1, operands[2])"
19383 [(parallel [(set (match_dup 0)
19384 (match_op_dup 1
19385 [(and:SI
19386 (zero_extract:SI
19387 (match_dup 2)
19388 (const_int 8)
19389 (const_int 8))
19390 (match_dup 3))
19391 (const_int 0)]))
19392 (set (zero_extract:SI (match_dup 2)
19393 (const_int 8)
19394 (const_int 8))
19395 (and:SI
19396 (zero_extract:SI
19397 (match_dup 2)
19398 (const_int 8)
19399 (const_int 8))
19400 (match_dup 3)))])]
19401 "")
19402
19403 ;; Don't do logical operations with memory inputs.
19404 (define_peephole2
19405 [(match_scratch:SI 2 "r")
19406 (parallel [(set (match_operand:SI 0 "register_operand" "")
19407 (match_operator:SI 3 "arith_or_logical_operator"
19408 [(match_dup 0)
19409 (match_operand:SI 1 "memory_operand" "")]))
19410 (clobber (reg:CC FLAGS_REG))])]
19411 "! optimize_size && ! TARGET_READ_MODIFY"
19412 [(set (match_dup 2) (match_dup 1))
19413 (parallel [(set (match_dup 0)
19414 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19415 (clobber (reg:CC FLAGS_REG))])]
19416 "")
19417
19418 (define_peephole2
19419 [(match_scratch:SI 2 "r")
19420 (parallel [(set (match_operand:SI 0 "register_operand" "")
19421 (match_operator:SI 3 "arith_or_logical_operator"
19422 [(match_operand:SI 1 "memory_operand" "")
19423 (match_dup 0)]))
19424 (clobber (reg:CC FLAGS_REG))])]
19425 "! optimize_size && ! TARGET_READ_MODIFY"
19426 [(set (match_dup 2) (match_dup 1))
19427 (parallel [(set (match_dup 0)
19428 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19429 (clobber (reg:CC FLAGS_REG))])]
19430 "")
19431
19432 ; Don't do logical operations with memory outputs
19433 ;
19434 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19435 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19436 ; the same decoder scheduling characteristics as the original.
19437
19438 (define_peephole2
19439 [(match_scratch:SI 2 "r")
19440 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19441 (match_operator:SI 3 "arith_or_logical_operator"
19442 [(match_dup 0)
19443 (match_operand:SI 1 "nonmemory_operand" "")]))
19444 (clobber (reg:CC FLAGS_REG))])]
19445 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19446 [(set (match_dup 2) (match_dup 0))
19447 (parallel [(set (match_dup 2)
19448 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19449 (clobber (reg:CC FLAGS_REG))])
19450 (set (match_dup 0) (match_dup 2))]
19451 "")
19452
19453 (define_peephole2
19454 [(match_scratch:SI 2 "r")
19455 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19456 (match_operator:SI 3 "arith_or_logical_operator"
19457 [(match_operand:SI 1 "nonmemory_operand" "")
19458 (match_dup 0)]))
19459 (clobber (reg:CC FLAGS_REG))])]
19460 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19461 [(set (match_dup 2) (match_dup 0))
19462 (parallel [(set (match_dup 2)
19463 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19464 (clobber (reg:CC FLAGS_REG))])
19465 (set (match_dup 0) (match_dup 2))]
19466 "")
19467
19468 ;; Attempt to always use XOR for zeroing registers.
19469 (define_peephole2
19470 [(set (match_operand 0 "register_operand" "")
19471 (match_operand 1 "const0_operand" ""))]
19472 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19473 && (! TARGET_USE_MOV0 || optimize_size)
19474 && GENERAL_REG_P (operands[0])
19475 && peep2_regno_dead_p (0, FLAGS_REG)"
19476 [(parallel [(set (match_dup 0) (const_int 0))
19477 (clobber (reg:CC FLAGS_REG))])]
19478 {
19479 operands[0] = gen_lowpart (word_mode, operands[0]);
19480 })
19481
19482 (define_peephole2
19483 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19484 (const_int 0))]
19485 "(GET_MODE (operands[0]) == QImode
19486 || GET_MODE (operands[0]) == HImode)
19487 && (! TARGET_USE_MOV0 || optimize_size)
19488 && peep2_regno_dead_p (0, FLAGS_REG)"
19489 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19490 (clobber (reg:CC FLAGS_REG))])])
19491
19492 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19493 (define_peephole2
19494 [(set (match_operand 0 "register_operand" "")
19495 (const_int -1))]
19496 "(GET_MODE (operands[0]) == HImode
19497 || GET_MODE (operands[0]) == SImode
19498 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19499 && (optimize_size || TARGET_PENTIUM)
19500 && peep2_regno_dead_p (0, FLAGS_REG)"
19501 [(parallel [(set (match_dup 0) (const_int -1))
19502 (clobber (reg:CC FLAGS_REG))])]
19503 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19504 operands[0]);")
19505
19506 ;; Attempt to convert simple leas to adds. These can be created by
19507 ;; move expanders.
19508 (define_peephole2
19509 [(set (match_operand:SI 0 "register_operand" "")
19510 (plus:SI (match_dup 0)
19511 (match_operand:SI 1 "nonmemory_operand" "")))]
19512 "peep2_regno_dead_p (0, FLAGS_REG)"
19513 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19514 (clobber (reg:CC FLAGS_REG))])]
19515 "")
19516
19517 (define_peephole2
19518 [(set (match_operand:SI 0 "register_operand" "")
19519 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19520 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19521 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19522 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19523 (clobber (reg:CC FLAGS_REG))])]
19524 "operands[2] = gen_lowpart (SImode, operands[2]);")
19525
19526 (define_peephole2
19527 [(set (match_operand:DI 0 "register_operand" "")
19528 (plus:DI (match_dup 0)
19529 (match_operand:DI 1 "x86_64_general_operand" "")))]
19530 "peep2_regno_dead_p (0, FLAGS_REG)"
19531 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19532 (clobber (reg:CC FLAGS_REG))])]
19533 "")
19534
19535 (define_peephole2
19536 [(set (match_operand:SI 0 "register_operand" "")
19537 (mult:SI (match_dup 0)
19538 (match_operand:SI 1 "const_int_operand" "")))]
19539 "exact_log2 (INTVAL (operands[1])) >= 0
19540 && peep2_regno_dead_p (0, FLAGS_REG)"
19541 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19542 (clobber (reg:CC FLAGS_REG))])]
19543 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19544
19545 (define_peephole2
19546 [(set (match_operand:DI 0 "register_operand" "")
19547 (mult:DI (match_dup 0)
19548 (match_operand:DI 1 "const_int_operand" "")))]
19549 "exact_log2 (INTVAL (operands[1])) >= 0
19550 && peep2_regno_dead_p (0, FLAGS_REG)"
19551 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19552 (clobber (reg:CC FLAGS_REG))])]
19553 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19554
19555 (define_peephole2
19556 [(set (match_operand:SI 0 "register_operand" "")
19557 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19558 (match_operand:DI 2 "const_int_operand" "")) 0))]
19559 "exact_log2 (INTVAL (operands[2])) >= 0
19560 && REGNO (operands[0]) == REGNO (operands[1])
19561 && peep2_regno_dead_p (0, FLAGS_REG)"
19562 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19563 (clobber (reg:CC FLAGS_REG))])]
19564 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19565
19566 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19567 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19568 ;; many CPUs it is also faster, since special hardware to avoid esp
19569 ;; dependencies is present.
19570
19571 ;; While some of these conversions may be done using splitters, we use peepholes
19572 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19573
19574 ;; Convert prologue esp subtractions to push.
19575 ;; We need register to push. In order to keep verify_flow_info happy we have
19576 ;; two choices
19577 ;; - use scratch and clobber it in order to avoid dependencies
19578 ;; - use already live register
19579 ;; We can't use the second way right now, since there is no reliable way how to
19580 ;; verify that given register is live. First choice will also most likely in
19581 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19582 ;; call clobbered registers are dead. We may want to use base pointer as an
19583 ;; alternative when no register is available later.
19584
19585 (define_peephole2
19586 [(match_scratch:SI 0 "r")
19587 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19588 (clobber (reg:CC FLAGS_REG))
19589 (clobber (mem:BLK (scratch)))])]
19590 "optimize_size || !TARGET_SUB_ESP_4"
19591 [(clobber (match_dup 0))
19592 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19593 (clobber (mem:BLK (scratch)))])])
19594
19595 (define_peephole2
19596 [(match_scratch:SI 0 "r")
19597 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19598 (clobber (reg:CC FLAGS_REG))
19599 (clobber (mem:BLK (scratch)))])]
19600 "optimize_size || !TARGET_SUB_ESP_8"
19601 [(clobber (match_dup 0))
19602 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19603 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19604 (clobber (mem:BLK (scratch)))])])
19605
19606 ;; Convert esp subtractions to push.
19607 (define_peephole2
19608 [(match_scratch:SI 0 "r")
19609 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19610 (clobber (reg:CC FLAGS_REG))])]
19611 "optimize_size || !TARGET_SUB_ESP_4"
19612 [(clobber (match_dup 0))
19613 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19614
19615 (define_peephole2
19616 [(match_scratch:SI 0 "r")
19617 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19618 (clobber (reg:CC FLAGS_REG))])]
19619 "optimize_size || !TARGET_SUB_ESP_8"
19620 [(clobber (match_dup 0))
19621 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19622 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19623
19624 ;; Convert epilogue deallocator to pop.
19625 (define_peephole2
19626 [(match_scratch:SI 0 "r")
19627 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19628 (clobber (reg:CC FLAGS_REG))
19629 (clobber (mem:BLK (scratch)))])]
19630 "optimize_size || !TARGET_ADD_ESP_4"
19631 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19632 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19633 (clobber (mem:BLK (scratch)))])]
19634 "")
19635
19636 ;; Two pops case is tricky, since pop causes dependency on destination register.
19637 ;; We use two registers if available.
19638 (define_peephole2
19639 [(match_scratch:SI 0 "r")
19640 (match_scratch:SI 1 "r")
19641 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19642 (clobber (reg:CC FLAGS_REG))
19643 (clobber (mem:BLK (scratch)))])]
19644 "optimize_size || !TARGET_ADD_ESP_8"
19645 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19646 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19647 (clobber (mem:BLK (scratch)))])
19648 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19649 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19650 "")
19651
19652 (define_peephole2
19653 [(match_scratch:SI 0 "r")
19654 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19655 (clobber (reg:CC FLAGS_REG))
19656 (clobber (mem:BLK (scratch)))])]
19657 "optimize_size"
19658 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19659 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19660 (clobber (mem:BLK (scratch)))])
19661 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19662 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19663 "")
19664
19665 ;; Convert esp additions to pop.
19666 (define_peephole2
19667 [(match_scratch:SI 0 "r")
19668 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19669 (clobber (reg:CC FLAGS_REG))])]
19670 ""
19671 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19672 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19673 "")
19674
19675 ;; Two pops case is tricky, since pop causes dependency on destination register.
19676 ;; We use two registers if available.
19677 (define_peephole2
19678 [(match_scratch:SI 0 "r")
19679 (match_scratch:SI 1 "r")
19680 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19681 (clobber (reg:CC FLAGS_REG))])]
19682 ""
19683 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19684 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19685 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19686 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19687 "")
19688
19689 (define_peephole2
19690 [(match_scratch:SI 0 "r")
19691 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19692 (clobber (reg:CC FLAGS_REG))])]
19693 "optimize_size"
19694 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19695 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19696 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19697 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19698 "")
19699 \f
19700 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19701 ;; required and register dies. Similarly for 128 to plus -128.
19702 (define_peephole2
19703 [(set (match_operand 0 "flags_reg_operand" "")
19704 (match_operator 1 "compare_operator"
19705 [(match_operand 2 "register_operand" "")
19706 (match_operand 3 "const_int_operand" "")]))]
19707 "(INTVAL (operands[3]) == -1
19708 || INTVAL (operands[3]) == 1
19709 || INTVAL (operands[3]) == 128)
19710 && ix86_match_ccmode (insn, CCGCmode)
19711 && peep2_reg_dead_p (1, operands[2])"
19712 [(parallel [(set (match_dup 0)
19713 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19714 (clobber (match_dup 2))])]
19715 "")
19716 \f
19717 (define_peephole2
19718 [(match_scratch:DI 0 "r")
19719 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19720 (clobber (reg:CC FLAGS_REG))
19721 (clobber (mem:BLK (scratch)))])]
19722 "optimize_size || !TARGET_SUB_ESP_4"
19723 [(clobber (match_dup 0))
19724 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19725 (clobber (mem:BLK (scratch)))])])
19726
19727 (define_peephole2
19728 [(match_scratch:DI 0 "r")
19729 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19730 (clobber (reg:CC FLAGS_REG))
19731 (clobber (mem:BLK (scratch)))])]
19732 "optimize_size || !TARGET_SUB_ESP_8"
19733 [(clobber (match_dup 0))
19734 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19735 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19736 (clobber (mem:BLK (scratch)))])])
19737
19738 ;; Convert esp subtractions to push.
19739 (define_peephole2
19740 [(match_scratch:DI 0 "r")
19741 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19742 (clobber (reg:CC FLAGS_REG))])]
19743 "optimize_size || !TARGET_SUB_ESP_4"
19744 [(clobber (match_dup 0))
19745 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19746
19747 (define_peephole2
19748 [(match_scratch:DI 0 "r")
19749 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19750 (clobber (reg:CC FLAGS_REG))])]
19751 "optimize_size || !TARGET_SUB_ESP_8"
19752 [(clobber (match_dup 0))
19753 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19754 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19755
19756 ;; Convert epilogue deallocator to pop.
19757 (define_peephole2
19758 [(match_scratch:DI 0 "r")
19759 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19760 (clobber (reg:CC FLAGS_REG))
19761 (clobber (mem:BLK (scratch)))])]
19762 "optimize_size || !TARGET_ADD_ESP_4"
19763 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19764 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19765 (clobber (mem:BLK (scratch)))])]
19766 "")
19767
19768 ;; Two pops case is tricky, since pop causes dependency on destination register.
19769 ;; We use two registers if available.
19770 (define_peephole2
19771 [(match_scratch:DI 0 "r")
19772 (match_scratch:DI 1 "r")
19773 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19774 (clobber (reg:CC FLAGS_REG))
19775 (clobber (mem:BLK (scratch)))])]
19776 "optimize_size || !TARGET_ADD_ESP_8"
19777 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19778 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19779 (clobber (mem:BLK (scratch)))])
19780 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19781 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19782 "")
19783
19784 (define_peephole2
19785 [(match_scratch:DI 0 "r")
19786 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19787 (clobber (reg:CC FLAGS_REG))
19788 (clobber (mem:BLK (scratch)))])]
19789 "optimize_size"
19790 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19791 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19792 (clobber (mem:BLK (scratch)))])
19793 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19794 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19795 "")
19796
19797 ;; Convert esp additions to pop.
19798 (define_peephole2
19799 [(match_scratch:DI 0 "r")
19800 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19801 (clobber (reg:CC FLAGS_REG))])]
19802 ""
19803 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19804 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19805 "")
19806
19807 ;; Two pops case is tricky, since pop causes dependency on destination register.
19808 ;; We use two registers if available.
19809 (define_peephole2
19810 [(match_scratch:DI 0 "r")
19811 (match_scratch:DI 1 "r")
19812 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19813 (clobber (reg:CC FLAGS_REG))])]
19814 ""
19815 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19816 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19817 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19818 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19819 "")
19820
19821 (define_peephole2
19822 [(match_scratch:DI 0 "r")
19823 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19824 (clobber (reg:CC FLAGS_REG))])]
19825 "optimize_size"
19826 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19827 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19828 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19829 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19830 "")
19831 \f
19832 ;; Convert imul by three, five and nine into lea
19833 (define_peephole2
19834 [(parallel
19835 [(set (match_operand:SI 0 "register_operand" "")
19836 (mult:SI (match_operand:SI 1 "register_operand" "")
19837 (match_operand:SI 2 "const_int_operand" "")))
19838 (clobber (reg:CC FLAGS_REG))])]
19839 "INTVAL (operands[2]) == 3
19840 || INTVAL (operands[2]) == 5
19841 || INTVAL (operands[2]) == 9"
19842 [(set (match_dup 0)
19843 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19844 (match_dup 1)))]
19845 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19846
19847 (define_peephole2
19848 [(parallel
19849 [(set (match_operand:SI 0 "register_operand" "")
19850 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19851 (match_operand:SI 2 "const_int_operand" "")))
19852 (clobber (reg:CC FLAGS_REG))])]
19853 "!optimize_size
19854 && (INTVAL (operands[2]) == 3
19855 || INTVAL (operands[2]) == 5
19856 || INTVAL (operands[2]) == 9)"
19857 [(set (match_dup 0) (match_dup 1))
19858 (set (match_dup 0)
19859 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19860 (match_dup 0)))]
19861 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19862
19863 (define_peephole2
19864 [(parallel
19865 [(set (match_operand:DI 0 "register_operand" "")
19866 (mult:DI (match_operand:DI 1 "register_operand" "")
19867 (match_operand:DI 2 "const_int_operand" "")))
19868 (clobber (reg:CC FLAGS_REG))])]
19869 "TARGET_64BIT
19870 && (INTVAL (operands[2]) == 3
19871 || INTVAL (operands[2]) == 5
19872 || INTVAL (operands[2]) == 9)"
19873 [(set (match_dup 0)
19874 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19875 (match_dup 1)))]
19876 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19877
19878 (define_peephole2
19879 [(parallel
19880 [(set (match_operand:DI 0 "register_operand" "")
19881 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19882 (match_operand:DI 2 "const_int_operand" "")))
19883 (clobber (reg:CC FLAGS_REG))])]
19884 "TARGET_64BIT
19885 && !optimize_size
19886 && (INTVAL (operands[2]) == 3
19887 || INTVAL (operands[2]) == 5
19888 || INTVAL (operands[2]) == 9)"
19889 [(set (match_dup 0) (match_dup 1))
19890 (set (match_dup 0)
19891 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19892 (match_dup 0)))]
19893 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19894
19895 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19896 ;; imul $32bit_imm, reg, reg is direct decoded.
19897 (define_peephole2
19898 [(match_scratch:DI 3 "r")
19899 (parallel [(set (match_operand:DI 0 "register_operand" "")
19900 (mult:DI (match_operand:DI 1 "memory_operand" "")
19901 (match_operand:DI 2 "immediate_operand" "")))
19902 (clobber (reg:CC FLAGS_REG))])]
19903 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19904 && (GET_CODE (operands[2]) != CONST_INT
19905 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19906 [(set (match_dup 3) (match_dup 1))
19907 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19908 (clobber (reg:CC FLAGS_REG))])]
19909 "")
19910
19911 (define_peephole2
19912 [(match_scratch:SI 3 "r")
19913 (parallel [(set (match_operand:SI 0 "register_operand" "")
19914 (mult:SI (match_operand:SI 1 "memory_operand" "")
19915 (match_operand:SI 2 "immediate_operand" "")))
19916 (clobber (reg:CC FLAGS_REG))])]
19917 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19918 && (GET_CODE (operands[2]) != CONST_INT
19919 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19920 [(set (match_dup 3) (match_dup 1))
19921 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19922 (clobber (reg:CC FLAGS_REG))])]
19923 "")
19924
19925 (define_peephole2
19926 [(match_scratch:SI 3 "r")
19927 (parallel [(set (match_operand:DI 0 "register_operand" "")
19928 (zero_extend:DI
19929 (mult:SI (match_operand:SI 1 "memory_operand" "")
19930 (match_operand:SI 2 "immediate_operand" ""))))
19931 (clobber (reg:CC FLAGS_REG))])]
19932 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19933 && (GET_CODE (operands[2]) != CONST_INT
19934 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19935 [(set (match_dup 3) (match_dup 1))
19936 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19937 (clobber (reg:CC FLAGS_REG))])]
19938 "")
19939
19940 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19941 ;; Convert it into imul reg, reg
19942 ;; It would be better to force assembler to encode instruction using long
19943 ;; immediate, but there is apparently no way to do so.
19944 (define_peephole2
19945 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19946 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19947 (match_operand:DI 2 "const_int_operand" "")))
19948 (clobber (reg:CC FLAGS_REG))])
19949 (match_scratch:DI 3 "r")]
19950 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19951 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19952 [(set (match_dup 3) (match_dup 2))
19953 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19954 (clobber (reg:CC FLAGS_REG))])]
19955 {
19956 if (!rtx_equal_p (operands[0], operands[1]))
19957 emit_move_insn (operands[0], operands[1]);
19958 })
19959
19960 (define_peephole2
19961 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19962 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19963 (match_operand:SI 2 "const_int_operand" "")))
19964 (clobber (reg:CC FLAGS_REG))])
19965 (match_scratch:SI 3 "r")]
19966 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19967 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19968 [(set (match_dup 3) (match_dup 2))
19969 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19970 (clobber (reg:CC FLAGS_REG))])]
19971 {
19972 if (!rtx_equal_p (operands[0], operands[1]))
19973 emit_move_insn (operands[0], operands[1]);
19974 })
19975
19976 (define_peephole2
19977 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19978 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19979 (match_operand:HI 2 "immediate_operand" "")))
19980 (clobber (reg:CC FLAGS_REG))])
19981 (match_scratch:HI 3 "r")]
19982 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
19983 [(set (match_dup 3) (match_dup 2))
19984 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19985 (clobber (reg:CC FLAGS_REG))])]
19986 {
19987 if (!rtx_equal_p (operands[0], operands[1]))
19988 emit_move_insn (operands[0], operands[1]);
19989 })
19990
19991 ;; After splitting up read-modify operations, array accesses with memory
19992 ;; operands might end up in form:
19993 ;; sall $2, %eax
19994 ;; movl 4(%esp), %edx
19995 ;; addl %edx, %eax
19996 ;; instead of pre-splitting:
19997 ;; sall $2, %eax
19998 ;; addl 4(%esp), %eax
19999 ;; Turn it into:
20000 ;; movl 4(%esp), %edx
20001 ;; leal (%edx,%eax,4), %eax
20002
20003 (define_peephole2
20004 [(parallel [(set (match_operand 0 "register_operand" "")
20005 (ashift (match_operand 1 "register_operand" "")
20006 (match_operand 2 "const_int_operand" "")))
20007 (clobber (reg:CC FLAGS_REG))])
20008 (set (match_operand 3 "register_operand")
20009 (match_operand 4 "x86_64_general_operand" ""))
20010 (parallel [(set (match_operand 5 "register_operand" "")
20011 (plus (match_operand 6 "register_operand" "")
20012 (match_operand 7 "register_operand" "")))
20013 (clobber (reg:CC FLAGS_REG))])]
20014 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20015 /* Validate MODE for lea. */
20016 && ((!TARGET_PARTIAL_REG_STALL
20017 && (GET_MODE (operands[0]) == QImode
20018 || GET_MODE (operands[0]) == HImode))
20019 || GET_MODE (operands[0]) == SImode
20020 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20021 /* We reorder load and the shift. */
20022 && !rtx_equal_p (operands[1], operands[3])
20023 && !reg_overlap_mentioned_p (operands[0], operands[4])
20024 /* Last PLUS must consist of operand 0 and 3. */
20025 && !rtx_equal_p (operands[0], operands[3])
20026 && (rtx_equal_p (operands[3], operands[6])
20027 || rtx_equal_p (operands[3], operands[7]))
20028 && (rtx_equal_p (operands[0], operands[6])
20029 || rtx_equal_p (operands[0], operands[7]))
20030 /* The intermediate operand 0 must die or be same as output. */
20031 && (rtx_equal_p (operands[0], operands[5])
20032 || peep2_reg_dead_p (3, operands[0]))"
20033 [(set (match_dup 3) (match_dup 4))
20034 (set (match_dup 0) (match_dup 1))]
20035 {
20036 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20037 int scale = 1 << INTVAL (operands[2]);
20038 rtx index = gen_lowpart (Pmode, operands[1]);
20039 rtx base = gen_lowpart (Pmode, operands[3]);
20040 rtx dest = gen_lowpart (mode, operands[5]);
20041
20042 operands[1] = gen_rtx_PLUS (Pmode, base,
20043 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20044 if (mode != Pmode)
20045 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20046 operands[0] = dest;
20047 })
20048 \f
20049 ;; Call-value patterns last so that the wildcard operand does not
20050 ;; disrupt insn-recog's switch tables.
20051
20052 (define_insn "*call_value_pop_0"
20053 [(set (match_operand 0 "" "")
20054 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20055 (match_operand:SI 2 "" "")))
20056 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20057 (match_operand:SI 3 "immediate_operand" "")))]
20058 "!TARGET_64BIT"
20059 {
20060 if (SIBLING_CALL_P (insn))
20061 return "jmp\t%P1";
20062 else
20063 return "call\t%P1";
20064 }
20065 [(set_attr "type" "callv")])
20066
20067 (define_insn "*call_value_pop_1"
20068 [(set (match_operand 0 "" "")
20069 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20070 (match_operand:SI 2 "" "")))
20071 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20072 (match_operand:SI 3 "immediate_operand" "i")))]
20073 "!TARGET_64BIT"
20074 {
20075 if (constant_call_address_operand (operands[1], Pmode))
20076 {
20077 if (SIBLING_CALL_P (insn))
20078 return "jmp\t%P1";
20079 else
20080 return "call\t%P1";
20081 }
20082 if (SIBLING_CALL_P (insn))
20083 return "jmp\t%A1";
20084 else
20085 return "call\t%A1";
20086 }
20087 [(set_attr "type" "callv")])
20088
20089 (define_insn "*call_value_0"
20090 [(set (match_operand 0 "" "")
20091 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20092 (match_operand:SI 2 "" "")))]
20093 "!TARGET_64BIT"
20094 {
20095 if (SIBLING_CALL_P (insn))
20096 return "jmp\t%P1";
20097 else
20098 return "call\t%P1";
20099 }
20100 [(set_attr "type" "callv")])
20101
20102 (define_insn "*call_value_0_rex64"
20103 [(set (match_operand 0 "" "")
20104 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20105 (match_operand:DI 2 "const_int_operand" "")))]
20106 "TARGET_64BIT"
20107 {
20108 if (SIBLING_CALL_P (insn))
20109 return "jmp\t%P1";
20110 else
20111 return "call\t%P1";
20112 }
20113 [(set_attr "type" "callv")])
20114
20115 (define_insn "*call_value_1"
20116 [(set (match_operand 0 "" "")
20117 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20118 (match_operand:SI 2 "" "")))]
20119 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20120 {
20121 if (constant_call_address_operand (operands[1], Pmode))
20122 return "call\t%P1";
20123 return "call\t%A1";
20124 }
20125 [(set_attr "type" "callv")])
20126
20127 (define_insn "*sibcall_value_1"
20128 [(set (match_operand 0 "" "")
20129 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20130 (match_operand:SI 2 "" "")))]
20131 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20132 {
20133 if (constant_call_address_operand (operands[1], Pmode))
20134 return "jmp\t%P1";
20135 return "jmp\t%A1";
20136 }
20137 [(set_attr "type" "callv")])
20138
20139 (define_insn "*call_value_1_rex64"
20140 [(set (match_operand 0 "" "")
20141 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20142 (match_operand:DI 2 "" "")))]
20143 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20144 {
20145 if (constant_call_address_operand (operands[1], Pmode))
20146 return "call\t%P1";
20147 return "call\t%A1";
20148 }
20149 [(set_attr "type" "callv")])
20150
20151 (define_insn "*sibcall_value_1_rex64"
20152 [(set (match_operand 0 "" "")
20153 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20154 (match_operand:DI 2 "" "")))]
20155 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20156 "jmp\t%P1"
20157 [(set_attr "type" "callv")])
20158
20159 (define_insn "*sibcall_value_1_rex64_v"
20160 [(set (match_operand 0 "" "")
20161 (call (mem:QI (reg:DI 40))
20162 (match_operand:DI 1 "" "")))]
20163 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20164 "jmp\t*%%r11"
20165 [(set_attr "type" "callv")])
20166 \f
20167 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20168 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20169 ;; caught for use by garbage collectors and the like. Using an insn that
20170 ;; maps to SIGILL makes it more likely the program will rightfully die.
20171 ;; Keeping with tradition, "6" is in honor of #UD.
20172 (define_insn "trap"
20173 [(trap_if (const_int 1) (const_int 6))]
20174 ""
20175 ".word\t0x0b0f"
20176 [(set_attr "length" "2")])
20177
20178 (define_expand "sse_prologue_save"
20179 [(parallel [(set (match_operand:BLK 0 "" "")
20180 (unspec:BLK [(reg:DI 21)
20181 (reg:DI 22)
20182 (reg:DI 23)
20183 (reg:DI 24)
20184 (reg:DI 25)
20185 (reg:DI 26)
20186 (reg:DI 27)
20187 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20188 (use (match_operand:DI 1 "register_operand" ""))
20189 (use (match_operand:DI 2 "immediate_operand" ""))
20190 (use (label_ref:DI (match_operand 3 "" "")))])]
20191 "TARGET_64BIT"
20192 "")
20193
20194 (define_insn "*sse_prologue_save_insn"
20195 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20196 (match_operand:DI 4 "const_int_operand" "n")))
20197 (unspec:BLK [(reg:DI 21)
20198 (reg:DI 22)
20199 (reg:DI 23)
20200 (reg:DI 24)
20201 (reg:DI 25)
20202 (reg:DI 26)
20203 (reg:DI 27)
20204 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20205 (use (match_operand:DI 1 "register_operand" "r"))
20206 (use (match_operand:DI 2 "const_int_operand" "i"))
20207 (use (label_ref:DI (match_operand 3 "" "X")))]
20208 "TARGET_64BIT
20209 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20210 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20211 "*
20212 {
20213 int i;
20214 operands[0] = gen_rtx_MEM (Pmode,
20215 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20216 output_asm_insn (\"jmp\\t%A1\", operands);
20217 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20218 {
20219 operands[4] = adjust_address (operands[0], DImode, i*16);
20220 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20221 PUT_MODE (operands[4], TImode);
20222 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20223 output_asm_insn (\"rex\", operands);
20224 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20225 }
20226 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20227 CODE_LABEL_NUMBER (operands[3]));
20228 RET;
20229 }
20230 "
20231 [(set_attr "type" "other")
20232 (set_attr "length_immediate" "0")
20233 (set_attr "length_address" "0")
20234 (set_attr "length" "135")
20235 (set_attr "memory" "store")
20236 (set_attr "modrm" "0")
20237 (set_attr "mode" "DI")])
20238
20239 (define_expand "prefetch"
20240 [(prefetch (match_operand 0 "address_operand" "")
20241 (match_operand:SI 1 "const_int_operand" "")
20242 (match_operand:SI 2 "const_int_operand" ""))]
20243 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20244 {
20245 int rw = INTVAL (operands[1]);
20246 int locality = INTVAL (operands[2]);
20247
20248 gcc_assert (rw == 0 || rw == 1);
20249 gcc_assert (locality >= 0 && locality <= 3);
20250 gcc_assert (GET_MODE (operands[0]) == Pmode
20251 || GET_MODE (operands[0]) == VOIDmode);
20252
20253 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20254 supported by SSE counterpart or the SSE prefetch is not available
20255 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20256 of locality. */
20257 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20258 operands[2] = GEN_INT (3);
20259 else
20260 operands[1] = const0_rtx;
20261 })
20262
20263 (define_insn "*prefetch_sse"
20264 [(prefetch (match_operand:SI 0 "address_operand" "p")
20265 (const_int 0)
20266 (match_operand:SI 1 "const_int_operand" ""))]
20267 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20268 {
20269 static const char * const patterns[4] = {
20270 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20271 };
20272
20273 int locality = INTVAL (operands[1]);
20274 gcc_assert (locality >= 0 && locality <= 3);
20275
20276 return patterns[locality];
20277 }
20278 [(set_attr "type" "sse")
20279 (set_attr "memory" "none")])
20280
20281 (define_insn "*prefetch_sse_rex"
20282 [(prefetch (match_operand:DI 0 "address_operand" "p")
20283 (const_int 0)
20284 (match_operand:SI 1 "const_int_operand" ""))]
20285 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20286 {
20287 static const char * const patterns[4] = {
20288 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20289 };
20290
20291 int locality = INTVAL (operands[1]);
20292 gcc_assert (locality >= 0 && locality <= 3);
20293
20294 return patterns[locality];
20295 }
20296 [(set_attr "type" "sse")
20297 (set_attr "memory" "none")])
20298
20299 (define_insn "*prefetch_3dnow"
20300 [(prefetch (match_operand:SI 0 "address_operand" "p")
20301 (match_operand:SI 1 "const_int_operand" "n")
20302 (const_int 3))]
20303 "TARGET_3DNOW && !TARGET_64BIT"
20304 {
20305 if (INTVAL (operands[1]) == 0)
20306 return "prefetch\t%a0";
20307 else
20308 return "prefetchw\t%a0";
20309 }
20310 [(set_attr "type" "mmx")
20311 (set_attr "memory" "none")])
20312
20313 (define_insn "*prefetch_3dnow_rex"
20314 [(prefetch (match_operand:DI 0 "address_operand" "p")
20315 (match_operand:SI 1 "const_int_operand" "n")
20316 (const_int 3))]
20317 "TARGET_3DNOW && TARGET_64BIT"
20318 {
20319 if (INTVAL (operands[1]) == 0)
20320 return "prefetch\t%a0";
20321 else
20322 return "prefetchw\t%a0";
20323 }
20324 [(set_attr "type" "mmx")
20325 (set_attr "memory" "none")])
20326
20327 (define_expand "stack_protect_set"
20328 [(match_operand 0 "memory_operand" "")
20329 (match_operand 1 "memory_operand" "")]
20330 ""
20331 {
20332 #ifdef TARGET_THREAD_SSP_OFFSET
20333 if (TARGET_64BIT)
20334 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20335 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20336 else
20337 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20338 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20339 #else
20340 if (TARGET_64BIT)
20341 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20342 else
20343 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20344 #endif
20345 DONE;
20346 })
20347
20348 (define_insn "stack_protect_set_si"
20349 [(set (match_operand:SI 0 "memory_operand" "=m")
20350 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20351 (set (match_scratch:SI 2 "=&r") (const_int 0))
20352 (clobber (reg:CC FLAGS_REG))]
20353 ""
20354 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20355 [(set_attr "type" "multi")])
20356
20357 (define_insn "stack_protect_set_di"
20358 [(set (match_operand:DI 0 "memory_operand" "=m")
20359 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20360 (set (match_scratch:DI 2 "=&r") (const_int 0))
20361 (clobber (reg:CC FLAGS_REG))]
20362 "TARGET_64BIT"
20363 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20364 [(set_attr "type" "multi")])
20365
20366 (define_insn "stack_tls_protect_set_si"
20367 [(set (match_operand:SI 0 "memory_operand" "=m")
20368 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20369 (set (match_scratch:SI 2 "=&r") (const_int 0))
20370 (clobber (reg:CC FLAGS_REG))]
20371 ""
20372 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20373 [(set_attr "type" "multi")])
20374
20375 (define_insn "stack_tls_protect_set_di"
20376 [(set (match_operand:DI 0 "memory_operand" "=m")
20377 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20378 (set (match_scratch:DI 2 "=&r") (const_int 0))
20379 (clobber (reg:CC FLAGS_REG))]
20380 "TARGET_64BIT"
20381 "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20382 [(set_attr "type" "multi")])
20383
20384 (define_expand "stack_protect_test"
20385 [(match_operand 0 "memory_operand" "")
20386 (match_operand 1 "memory_operand" "")
20387 (match_operand 2 "" "")]
20388 ""
20389 {
20390 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20391 ix86_compare_op0 = operands[0];
20392 ix86_compare_op1 = operands[1];
20393 ix86_compare_emitted = flags;
20394
20395 #ifdef TARGET_THREAD_SSP_OFFSET
20396 if (TARGET_64BIT)
20397 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20398 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20399 else
20400 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20401 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20402 #else
20403 if (TARGET_64BIT)
20404 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20405 else
20406 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20407 #endif
20408 emit_jump_insn (gen_beq (operands[2]));
20409 DONE;
20410 })
20411
20412 (define_insn "stack_protect_test_si"
20413 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20414 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20415 (match_operand:SI 2 "memory_operand" "m")]
20416 UNSPEC_SP_TEST))
20417 (clobber (match_scratch:SI 3 "=&r"))]
20418 ""
20419 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20420 [(set_attr "type" "multi")])
20421
20422 (define_insn "stack_protect_test_di"
20423 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20424 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20425 (match_operand:DI 2 "memory_operand" "m")]
20426 UNSPEC_SP_TEST))
20427 (clobber (match_scratch:DI 3 "=&r"))]
20428 "TARGET_64BIT"
20429 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20430 [(set_attr "type" "multi")])
20431
20432 (define_insn "stack_tls_protect_test_si"
20433 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20434 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20435 (match_operand:SI 2 "const_int_operand" "i")]
20436 UNSPEC_SP_TLS_TEST))
20437 (clobber (match_scratch:SI 3 "=r"))]
20438 ""
20439 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20440 [(set_attr "type" "multi")])
20441
20442 (define_insn "stack_tls_protect_test_di"
20443 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20444 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20445 (match_operand:DI 2 "const_int_operand" "i")]
20446 UNSPEC_SP_TLS_TEST))
20447 (clobber (match_scratch:DI 3 "=r"))]
20448 "TARGET_64BIT"
20449 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20450 [(set_attr "type" "multi")])
20451
20452 (include "sse.md")
20453 (include "mmx.md")
20454 (include "sync.md")