i386.md (movdi_extzv_1): New.
[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
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
70 ; TLS support
71 (UNSPEC_TP 15)
72 (UNSPEC_TLS_GD 16)
73 (UNSPEC_TLS_LD_BASE 17)
74
75 ; Other random patterns
76 (UNSPEC_SCAS 20)
77 (UNSPEC_FNSTSW 21)
78 (UNSPEC_SAHF 22)
79 (UNSPEC_FSTCW 23)
80 (UNSPEC_ADD_CARRY 24)
81 (UNSPEC_FLDCW 25)
82 (UNSPEC_REP 26)
83 (UNSPEC_EH_RETURN 27)
84
85 ; For SSE/MMX support:
86 (UNSPEC_FIX_NOTRUNC 30)
87 (UNSPEC_MASKMOV 31)
88 (UNSPEC_MOVMSK 32)
89 (UNSPEC_MOVNT 33)
90 (UNSPEC_MOVU 34)
91 (UNSPEC_RCP 35)
92 (UNSPEC_RSQRT 36)
93 (UNSPEC_SFENCE 37)
94 (UNSPEC_NOP 38) ; prevents combiner cleverness
95 (UNSPEC_PFRCP 39)
96 (UNSPEC_PFRCPIT1 40)
97 (UNSPEC_PFRCPIT2 41)
98 (UNSPEC_PFRSQRT 42)
99 (UNSPEC_PFRSQIT1 43)
100 (UNSPEC_MFENCE 44)
101 (UNSPEC_LFENCE 45)
102 (UNSPEC_PSADBW 46)
103 (UNSPEC_LDQQU 47)
104
105 ; Generic math support
106 (UNSPEC_COPYSIGN 50)
107 (UNSPEC_IEEE_MIN 51) ; not commutative
108 (UNSPEC_IEEE_MAX 52) ; not commutative
109
110 ; x87 Floating point
111 (UNSPEC_SIN 60)
112 (UNSPEC_COS 61)
113 (UNSPEC_FPATAN 62)
114 (UNSPEC_FYL2X 63)
115 (UNSPEC_FYL2XP1 64)
116 (UNSPEC_FRNDINT 65)
117 (UNSPEC_FIST 66)
118 (UNSPEC_F2XM1 67)
119
120 ; x87 Rounding
121 (UNSPEC_FRNDINT_FLOOR 70)
122 (UNSPEC_FRNDINT_CEIL 71)
123 (UNSPEC_FRNDINT_TRUNC 72)
124 (UNSPEC_FRNDINT_MASK_PM 73)
125 (UNSPEC_FIST_FLOOR 74)
126 (UNSPEC_FIST_CEIL 75)
127
128 ; x87 Double output FP
129 (UNSPEC_SINCOS_COS 80)
130 (UNSPEC_SINCOS_SIN 81)
131 (UNSPEC_TAN_ONE 82)
132 (UNSPEC_TAN_TAN 83)
133 (UNSPEC_XTRACT_FRACT 84)
134 (UNSPEC_XTRACT_EXP 85)
135 (UNSPEC_FSCALE_FRACT 86)
136 (UNSPEC_FSCALE_EXP 87)
137 (UNSPEC_FPREM_F 88)
138 (UNSPEC_FPREM_U 89)
139 (UNSPEC_FPREM1_F 90)
140 (UNSPEC_FPREM1_U 91)
141
142 ; SSP patterns
143 (UNSPEC_SP_SET 100)
144 (UNSPEC_SP_TEST 101)
145 (UNSPEC_SP_TLS_SET 102)
146 (UNSPEC_SP_TLS_TEST 103)
147 ])
148
149 (define_constants
150 [(UNSPECV_BLOCKAGE 0)
151 (UNSPECV_STACK_PROBE 1)
152 (UNSPECV_EMMS 2)
153 (UNSPECV_LDMXCSR 3)
154 (UNSPECV_STMXCSR 4)
155 (UNSPECV_FEMMS 5)
156 (UNSPECV_CLFLUSH 6)
157 (UNSPECV_ALIGN 7)
158 (UNSPECV_MONITOR 8)
159 (UNSPECV_MWAIT 9)
160 (UNSPECV_CMPXCHG_1 10)
161 (UNSPECV_CMPXCHG_2 11)
162 (UNSPECV_XCHG 12)
163 (UNSPECV_LOCK 13)
164 ])
165
166 ;; Registers by name.
167 (define_constants
168 [(BP_REG 6)
169 (SP_REG 7)
170 (FLAGS_REG 17)
171 (FPSR_REG 18)
172 (DIRFLAG_REG 19)
173 ])
174
175 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
176 ;; from i386.c.
177
178 ;; In C guard expressions, put expressions which may be compile-time
179 ;; constants first. This allows for better optimization. For
180 ;; example, write "TARGET_64BIT && reload_completed", not
181 ;; "reload_completed && TARGET_64BIT".
182
183 \f
184 ;; Processor type. This attribute must exactly match the processor_type
185 ;; enumeration in i386.h.
186 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
187 (const (symbol_ref "ix86_tune")))
188
189 ;; A basic instruction type. Refinements due to arguments to be
190 ;; provided in other attributes.
191 (define_attr "type"
192 "other,multi,
193 alu,alu1,negnot,imov,imovx,lea,
194 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
195 icmp,test,ibr,setcc,icmov,
196 push,pop,call,callv,leave,
197 str,cld,
198 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
199 sselog,sselog1,sseiadd,sseishft,sseimul,
200 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
201 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
202 (const_string "other"))
203
204 ;; Main data type used by the insn
205 (define_attr "mode"
206 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
207 (const_string "unknown"))
208
209 ;; The CPU unit operations uses.
210 (define_attr "unit" "integer,i387,sse,mmx,unknown"
211 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
212 (const_string "i387")
213 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
214 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
215 (const_string "sse")
216 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
217 (const_string "mmx")
218 (eq_attr "type" "other")
219 (const_string "unknown")]
220 (const_string "integer")))
221
222 ;; The (bounding maximum) length of an instruction immediate.
223 (define_attr "length_immediate" ""
224 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
225 (const_int 0)
226 (eq_attr "unit" "i387,sse,mmx")
227 (const_int 0)
228 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
229 imul,icmp,push,pop")
230 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
231 (eq_attr "type" "imov,test")
232 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
233 (eq_attr "type" "call")
234 (if_then_else (match_operand 0 "constant_call_address_operand" "")
235 (const_int 4)
236 (const_int 0))
237 (eq_attr "type" "callv")
238 (if_then_else (match_operand 1 "constant_call_address_operand" "")
239 (const_int 4)
240 (const_int 0))
241 ;; We don't know the size before shorten_branches. Expect
242 ;; the instruction to fit for better scheduling.
243 (eq_attr "type" "ibr")
244 (const_int 1)
245 ]
246 (symbol_ref "/* Update immediate_length and other attributes! */
247 gcc_unreachable (),1")))
248
249 ;; The (bounding maximum) length of an instruction address.
250 (define_attr "length_address" ""
251 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
252 (const_int 0)
253 (and (eq_attr "type" "call")
254 (match_operand 0 "constant_call_address_operand" ""))
255 (const_int 0)
256 (and (eq_attr "type" "callv")
257 (match_operand 1 "constant_call_address_operand" ""))
258 (const_int 0)
259 ]
260 (symbol_ref "ix86_attr_length_address_default (insn)")))
261
262 ;; Set when length prefix is used.
263 (define_attr "prefix_data16" ""
264 (if_then_else (ior (eq_attr "mode" "HI")
265 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
266 (const_int 1)
267 (const_int 0)))
268
269 ;; Set when string REP prefix is used.
270 (define_attr "prefix_rep" ""
271 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
272 (const_int 1)
273 (const_int 0)))
274
275 ;; Set when 0f opcode prefix is used.
276 (define_attr "prefix_0f" ""
277 (if_then_else
278 (ior (eq_attr "type" "imovx,setcc,icmov")
279 (eq_attr "unit" "sse,mmx"))
280 (const_int 1)
281 (const_int 0)))
282
283 ;; Set when REX opcode prefix is used.
284 (define_attr "prefix_rex" ""
285 (cond [(and (eq_attr "mode" "DI")
286 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
287 (const_int 1)
288 (and (eq_attr "mode" "QI")
289 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
290 (const_int 0)))
291 (const_int 1)
292 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
293 (const_int 0))
294 (const_int 1)
295 ]
296 (const_int 0)))
297
298 ;; Set when modrm byte is used.
299 (define_attr "modrm" ""
300 (cond [(eq_attr "type" "str,cld,leave")
301 (const_int 0)
302 (eq_attr "unit" "i387")
303 (const_int 0)
304 (and (eq_attr "type" "incdec")
305 (ior (match_operand:SI 1 "register_operand" "")
306 (match_operand:HI 1 "register_operand" "")))
307 (const_int 0)
308 (and (eq_attr "type" "push")
309 (not (match_operand 1 "memory_operand" "")))
310 (const_int 0)
311 (and (eq_attr "type" "pop")
312 (not (match_operand 0 "memory_operand" "")))
313 (const_int 0)
314 (and (eq_attr "type" "imov")
315 (and (match_operand 0 "register_operand" "")
316 (match_operand 1 "immediate_operand" "")))
317 (const_int 0)
318 (and (eq_attr "type" "call")
319 (match_operand 0 "constant_call_address_operand" ""))
320 (const_int 0)
321 (and (eq_attr "type" "callv")
322 (match_operand 1 "constant_call_address_operand" ""))
323 (const_int 0)
324 ]
325 (const_int 1)))
326
327 ;; The (bounding maximum) length of an instruction in bytes.
328 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
329 ;; Later we may want to split them and compute proper length as for
330 ;; other insns.
331 (define_attr "length" ""
332 (cond [(eq_attr "type" "other,multi,fistp,frndint")
333 (const_int 16)
334 (eq_attr "type" "fcmp")
335 (const_int 4)
336 (eq_attr "unit" "i387")
337 (plus (const_int 2)
338 (plus (attr "prefix_data16")
339 (attr "length_address")))]
340 (plus (plus (attr "modrm")
341 (plus (attr "prefix_0f")
342 (plus (attr "prefix_rex")
343 (const_int 1))))
344 (plus (attr "prefix_rep")
345 (plus (attr "prefix_data16")
346 (plus (attr "length_immediate")
347 (attr "length_address")))))))
348
349 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
350 ;; `store' if there is a simple memory reference therein, or `unknown'
351 ;; if the instruction is complex.
352
353 (define_attr "memory" "none,load,store,both,unknown"
354 (cond [(eq_attr "type" "other,multi,str")
355 (const_string "unknown")
356 (eq_attr "type" "lea,fcmov,fpspc,cld")
357 (const_string "none")
358 (eq_attr "type" "fistp,leave")
359 (const_string "both")
360 (eq_attr "type" "frndint")
361 (const_string "load")
362 (eq_attr "type" "push")
363 (if_then_else (match_operand 1 "memory_operand" "")
364 (const_string "both")
365 (const_string "store"))
366 (eq_attr "type" "pop")
367 (if_then_else (match_operand 0 "memory_operand" "")
368 (const_string "both")
369 (const_string "load"))
370 (eq_attr "type" "setcc")
371 (if_then_else (match_operand 0 "memory_operand" "")
372 (const_string "store")
373 (const_string "none"))
374 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
375 (if_then_else (ior (match_operand 0 "memory_operand" "")
376 (match_operand 1 "memory_operand" ""))
377 (const_string "load")
378 (const_string "none"))
379 (eq_attr "type" "ibr")
380 (if_then_else (match_operand 0 "memory_operand" "")
381 (const_string "load")
382 (const_string "none"))
383 (eq_attr "type" "call")
384 (if_then_else (match_operand 0 "constant_call_address_operand" "")
385 (const_string "none")
386 (const_string "load"))
387 (eq_attr "type" "callv")
388 (if_then_else (match_operand 1 "constant_call_address_operand" "")
389 (const_string "none")
390 (const_string "load"))
391 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
392 (match_operand 1 "memory_operand" ""))
393 (const_string "both")
394 (and (match_operand 0 "memory_operand" "")
395 (match_operand 1 "memory_operand" ""))
396 (const_string "both")
397 (match_operand 0 "memory_operand" "")
398 (const_string "store")
399 (match_operand 1 "memory_operand" "")
400 (const_string "load")
401 (and (eq_attr "type"
402 "!alu1,negnot,ishift1,
403 imov,imovx,icmp,test,
404 fmov,fcmp,fsgn,
405 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
406 mmx,mmxmov,mmxcmp,mmxcvt")
407 (match_operand 2 "memory_operand" ""))
408 (const_string "load")
409 (and (eq_attr "type" "icmov")
410 (match_operand 3 "memory_operand" ""))
411 (const_string "load")
412 ]
413 (const_string "none")))
414
415 ;; Indicates if an instruction has both an immediate and a displacement.
416
417 (define_attr "imm_disp" "false,true,unknown"
418 (cond [(eq_attr "type" "other,multi")
419 (const_string "unknown")
420 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
421 (and (match_operand 0 "memory_displacement_operand" "")
422 (match_operand 1 "immediate_operand" "")))
423 (const_string "true")
424 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
425 (and (match_operand 0 "memory_displacement_operand" "")
426 (match_operand 2 "immediate_operand" "")))
427 (const_string "true")
428 ]
429 (const_string "false")))
430
431 ;; Indicates if an FP operation has an integer source.
432
433 (define_attr "fp_int_src" "false,true"
434 (const_string "false"))
435
436 ;; Defines rounding mode of an FP operation.
437
438 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
439 (const_string "any"))
440
441 ;; Describe a user's asm statement.
442 (define_asm_attributes
443 [(set_attr "length" "128")
444 (set_attr "type" "multi")])
445
446 ;; All x87 floating point modes
447 (define_mode_macro X87MODEF [SF DF XF])
448
449 ;; All integer modes handled by x87 fisttp operator.
450 (define_mode_macro X87MODEI [HI SI DI])
451
452 ;; All integer modes handled by integer x87 operators.
453 (define_mode_macro X87MODEI12 [HI SI])
454
455 ;; All SSE floating point modes
456 (define_mode_macro SSEMODEF [SF DF])
457
458 ;; All integer modes handled by SSE cvtts?2si* operators.
459 (define_mode_macro SSEMODEI24 [SI DI])
460
461 \f
462 ;; Scheduling descriptions
463
464 (include "pentium.md")
465 (include "ppro.md")
466 (include "k6.md")
467 (include "athlon.md")
468
469 \f
470 ;; Operand and operator predicates
471
472 (include "predicates.md")
473
474 \f
475 ;; Compare instructions.
476
477 ;; All compare insns have expanders that save the operands away without
478 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
479 ;; after the cmp) will actually emit the cmpM.
480
481 (define_expand "cmpdi"
482 [(set (reg:CC FLAGS_REG)
483 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
484 (match_operand:DI 1 "x86_64_general_operand" "")))]
485 ""
486 {
487 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
488 operands[0] = force_reg (DImode, operands[0]);
489 ix86_compare_op0 = operands[0];
490 ix86_compare_op1 = operands[1];
491 DONE;
492 })
493
494 (define_expand "cmpsi"
495 [(set (reg:CC FLAGS_REG)
496 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
497 (match_operand:SI 1 "general_operand" "")))]
498 ""
499 {
500 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
501 operands[0] = force_reg (SImode, operands[0]);
502 ix86_compare_op0 = operands[0];
503 ix86_compare_op1 = operands[1];
504 DONE;
505 })
506
507 (define_expand "cmphi"
508 [(set (reg:CC FLAGS_REG)
509 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
510 (match_operand:HI 1 "general_operand" "")))]
511 ""
512 {
513 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
514 operands[0] = force_reg (HImode, operands[0]);
515 ix86_compare_op0 = operands[0];
516 ix86_compare_op1 = operands[1];
517 DONE;
518 })
519
520 (define_expand "cmpqi"
521 [(set (reg:CC FLAGS_REG)
522 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
523 (match_operand:QI 1 "general_operand" "")))]
524 "TARGET_QIMODE_MATH"
525 {
526 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
527 operands[0] = force_reg (QImode, operands[0]);
528 ix86_compare_op0 = operands[0];
529 ix86_compare_op1 = operands[1];
530 DONE;
531 })
532
533 (define_insn "cmpdi_ccno_1_rex64"
534 [(set (reg FLAGS_REG)
535 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
536 (match_operand:DI 1 "const0_operand" "n,n")))]
537 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
538 "@
539 test{q}\t{%0, %0|%0, %0}
540 cmp{q}\t{%1, %0|%0, %1}"
541 [(set_attr "type" "test,icmp")
542 (set_attr "length_immediate" "0,1")
543 (set_attr "mode" "DI")])
544
545 (define_insn "*cmpdi_minus_1_rex64"
546 [(set (reg FLAGS_REG)
547 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
548 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
549 (const_int 0)))]
550 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
551 "cmp{q}\t{%1, %0|%0, %1}"
552 [(set_attr "type" "icmp")
553 (set_attr "mode" "DI")])
554
555 (define_expand "cmpdi_1_rex64"
556 [(set (reg:CC FLAGS_REG)
557 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
558 (match_operand:DI 1 "general_operand" "")))]
559 "TARGET_64BIT"
560 "")
561
562 (define_insn "cmpdi_1_insn_rex64"
563 [(set (reg FLAGS_REG)
564 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
565 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
566 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
567 "cmp{q}\t{%1, %0|%0, %1}"
568 [(set_attr "type" "icmp")
569 (set_attr "mode" "DI")])
570
571
572 (define_insn "*cmpsi_ccno_1"
573 [(set (reg FLAGS_REG)
574 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
575 (match_operand:SI 1 "const0_operand" "n,n")))]
576 "ix86_match_ccmode (insn, CCNOmode)"
577 "@
578 test{l}\t{%0, %0|%0, %0}
579 cmp{l}\t{%1, %0|%0, %1}"
580 [(set_attr "type" "test,icmp")
581 (set_attr "length_immediate" "0,1")
582 (set_attr "mode" "SI")])
583
584 (define_insn "*cmpsi_minus_1"
585 [(set (reg FLAGS_REG)
586 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
587 (match_operand:SI 1 "general_operand" "ri,mr"))
588 (const_int 0)))]
589 "ix86_match_ccmode (insn, CCGOCmode)"
590 "cmp{l}\t{%1, %0|%0, %1}"
591 [(set_attr "type" "icmp")
592 (set_attr "mode" "SI")])
593
594 (define_expand "cmpsi_1"
595 [(set (reg:CC FLAGS_REG)
596 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
597 (match_operand:SI 1 "general_operand" "ri,mr")))]
598 ""
599 "")
600
601 (define_insn "*cmpsi_1_insn"
602 [(set (reg FLAGS_REG)
603 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
604 (match_operand:SI 1 "general_operand" "ri,mr")))]
605 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
606 && ix86_match_ccmode (insn, CCmode)"
607 "cmp{l}\t{%1, %0|%0, %1}"
608 [(set_attr "type" "icmp")
609 (set_attr "mode" "SI")])
610
611 (define_insn "*cmphi_ccno_1"
612 [(set (reg FLAGS_REG)
613 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
614 (match_operand:HI 1 "const0_operand" "n,n")))]
615 "ix86_match_ccmode (insn, CCNOmode)"
616 "@
617 test{w}\t{%0, %0|%0, %0}
618 cmp{w}\t{%1, %0|%0, %1}"
619 [(set_attr "type" "test,icmp")
620 (set_attr "length_immediate" "0,1")
621 (set_attr "mode" "HI")])
622
623 (define_insn "*cmphi_minus_1"
624 [(set (reg FLAGS_REG)
625 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
626 (match_operand:HI 1 "general_operand" "ri,mr"))
627 (const_int 0)))]
628 "ix86_match_ccmode (insn, CCGOCmode)"
629 "cmp{w}\t{%1, %0|%0, %1}"
630 [(set_attr "type" "icmp")
631 (set_attr "mode" "HI")])
632
633 (define_insn "*cmphi_1"
634 [(set (reg FLAGS_REG)
635 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
636 (match_operand:HI 1 "general_operand" "ri,mr")))]
637 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
638 && ix86_match_ccmode (insn, CCmode)"
639 "cmp{w}\t{%1, %0|%0, %1}"
640 [(set_attr "type" "icmp")
641 (set_attr "mode" "HI")])
642
643 (define_insn "*cmpqi_ccno_1"
644 [(set (reg FLAGS_REG)
645 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
646 (match_operand:QI 1 "const0_operand" "n,n")))]
647 "ix86_match_ccmode (insn, CCNOmode)"
648 "@
649 test{b}\t{%0, %0|%0, %0}
650 cmp{b}\t{$0, %0|%0, 0}"
651 [(set_attr "type" "test,icmp")
652 (set_attr "length_immediate" "0,1")
653 (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_1"
656 [(set (reg FLAGS_REG)
657 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
658 (match_operand:QI 1 "general_operand" "qi,mq")))]
659 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
660 && ix86_match_ccmode (insn, CCmode)"
661 "cmp{b}\t{%1, %0|%0, %1}"
662 [(set_attr "type" "icmp")
663 (set_attr "mode" "QI")])
664
665 (define_insn "*cmpqi_minus_1"
666 [(set (reg FLAGS_REG)
667 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
668 (match_operand:QI 1 "general_operand" "qi,mq"))
669 (const_int 0)))]
670 "ix86_match_ccmode (insn, CCGOCmode)"
671 "cmp{b}\t{%1, %0|%0, %1}"
672 [(set_attr "type" "icmp")
673 (set_attr "mode" "QI")])
674
675 (define_insn "*cmpqi_ext_1"
676 [(set (reg FLAGS_REG)
677 (compare
678 (match_operand:QI 0 "general_operand" "Qm")
679 (subreg:QI
680 (zero_extract:SI
681 (match_operand 1 "ext_register_operand" "Q")
682 (const_int 8)
683 (const_int 8)) 0)))]
684 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
685 "cmp{b}\t{%h1, %0|%0, %h1}"
686 [(set_attr "type" "icmp")
687 (set_attr "mode" "QI")])
688
689 (define_insn "*cmpqi_ext_1_rex64"
690 [(set (reg FLAGS_REG)
691 (compare
692 (match_operand:QI 0 "register_operand" "Q")
693 (subreg:QI
694 (zero_extract:SI
695 (match_operand 1 "ext_register_operand" "Q")
696 (const_int 8)
697 (const_int 8)) 0)))]
698 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
699 "cmp{b}\t{%h1, %0|%0, %h1}"
700 [(set_attr "type" "icmp")
701 (set_attr "mode" "QI")])
702
703 (define_insn "*cmpqi_ext_2"
704 [(set (reg FLAGS_REG)
705 (compare
706 (subreg:QI
707 (zero_extract:SI
708 (match_operand 0 "ext_register_operand" "Q")
709 (const_int 8)
710 (const_int 8)) 0)
711 (match_operand:QI 1 "const0_operand" "n")))]
712 "ix86_match_ccmode (insn, CCNOmode)"
713 "test{b}\t%h0, %h0"
714 [(set_attr "type" "test")
715 (set_attr "length_immediate" "0")
716 (set_attr "mode" "QI")])
717
718 (define_expand "cmpqi_ext_3"
719 [(set (reg:CC FLAGS_REG)
720 (compare:CC
721 (subreg:QI
722 (zero_extract:SI
723 (match_operand 0 "ext_register_operand" "")
724 (const_int 8)
725 (const_int 8)) 0)
726 (match_operand:QI 1 "general_operand" "")))]
727 ""
728 "")
729
730 (define_insn "cmpqi_ext_3_insn"
731 [(set (reg FLAGS_REG)
732 (compare
733 (subreg:QI
734 (zero_extract:SI
735 (match_operand 0 "ext_register_operand" "Q")
736 (const_int 8)
737 (const_int 8)) 0)
738 (match_operand:QI 1 "general_operand" "Qmn")))]
739 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
740 "cmp{b}\t{%1, %h0|%h0, %1}"
741 [(set_attr "type" "icmp")
742 (set_attr "mode" "QI")])
743
744 (define_insn "cmpqi_ext_3_insn_rex64"
745 [(set (reg FLAGS_REG)
746 (compare
747 (subreg:QI
748 (zero_extract:SI
749 (match_operand 0 "ext_register_operand" "Q")
750 (const_int 8)
751 (const_int 8)) 0)
752 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
753 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
754 "cmp{b}\t{%1, %h0|%h0, %1}"
755 [(set_attr "type" "icmp")
756 (set_attr "mode" "QI")])
757
758 (define_insn "*cmpqi_ext_4"
759 [(set (reg FLAGS_REG)
760 (compare
761 (subreg:QI
762 (zero_extract:SI
763 (match_operand 0 "ext_register_operand" "Q")
764 (const_int 8)
765 (const_int 8)) 0)
766 (subreg:QI
767 (zero_extract:SI
768 (match_operand 1 "ext_register_operand" "Q")
769 (const_int 8)
770 (const_int 8)) 0)))]
771 "ix86_match_ccmode (insn, CCmode)"
772 "cmp{b}\t{%h1, %h0|%h0, %h1}"
773 [(set_attr "type" "icmp")
774 (set_attr "mode" "QI")])
775
776 ;; These implement float point compares.
777 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
778 ;; which would allow mix and match FP modes on the compares. Which is what
779 ;; the old patterns did, but with many more of them.
780
781 (define_expand "cmpxf"
782 [(set (reg:CC FLAGS_REG)
783 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
784 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
785 "TARGET_80387"
786 {
787 ix86_compare_op0 = operands[0];
788 ix86_compare_op1 = operands[1];
789 DONE;
790 })
791
792 (define_expand "cmpdf"
793 [(set (reg:CC FLAGS_REG)
794 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
795 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
796 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
797 {
798 ix86_compare_op0 = operands[0];
799 ix86_compare_op1 = operands[1];
800 DONE;
801 })
802
803 (define_expand "cmpsf"
804 [(set (reg:CC FLAGS_REG)
805 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
806 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
807 "TARGET_80387 || TARGET_SSE_MATH"
808 {
809 ix86_compare_op0 = operands[0];
810 ix86_compare_op1 = operands[1];
811 DONE;
812 })
813
814 ;; FP compares, step 1:
815 ;; Set the FP condition codes.
816 ;;
817 ;; CCFPmode compare with exceptions
818 ;; CCFPUmode compare with no exceptions
819
820 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
821 ;; used to manage the reg stack popping would not be preserved.
822
823 (define_insn "*cmpfp_0"
824 [(set (match_operand:HI 0 "register_operand" "=a")
825 (unspec:HI
826 [(compare:CCFP
827 (match_operand 1 "register_operand" "f")
828 (match_operand 2 "const0_operand" "X"))]
829 UNSPEC_FNSTSW))]
830 "TARGET_80387
831 && FLOAT_MODE_P (GET_MODE (operands[1]))
832 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
833 "* return output_fp_compare (insn, operands, 0, 0);"
834 [(set_attr "type" "multi")
835 (set_attr "unit" "i387")
836 (set (attr "mode")
837 (cond [(match_operand:SF 1 "" "")
838 (const_string "SF")
839 (match_operand:DF 1 "" "")
840 (const_string "DF")
841 ]
842 (const_string "XF")))])
843
844 (define_insn "*cmpfp_sf"
845 [(set (match_operand:HI 0 "register_operand" "=a")
846 (unspec:HI
847 [(compare:CCFP
848 (match_operand:SF 1 "register_operand" "f")
849 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
850 UNSPEC_FNSTSW))]
851 "TARGET_80387"
852 "* return output_fp_compare (insn, operands, 0, 0);"
853 [(set_attr "type" "multi")
854 (set_attr "unit" "i387")
855 (set_attr "mode" "SF")])
856
857 (define_insn "*cmpfp_df"
858 [(set (match_operand:HI 0 "register_operand" "=a")
859 (unspec:HI
860 [(compare:CCFP
861 (match_operand:DF 1 "register_operand" "f")
862 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
863 UNSPEC_FNSTSW))]
864 "TARGET_80387"
865 "* return output_fp_compare (insn, operands, 0, 0);"
866 [(set_attr "type" "multi")
867 (set_attr "unit" "i387")
868 (set_attr "mode" "DF")])
869
870 (define_insn "*cmpfp_xf"
871 [(set (match_operand:HI 0 "register_operand" "=a")
872 (unspec:HI
873 [(compare:CCFP
874 (match_operand:XF 1 "register_operand" "f")
875 (match_operand:XF 2 "register_operand" "f"))]
876 UNSPEC_FNSTSW))]
877 "TARGET_80387"
878 "* return output_fp_compare (insn, operands, 0, 0);"
879 [(set_attr "type" "multi")
880 (set_attr "unit" "i387")
881 (set_attr "mode" "XF")])
882
883 (define_insn "*cmpfp_u"
884 [(set (match_operand:HI 0 "register_operand" "=a")
885 (unspec:HI
886 [(compare:CCFPU
887 (match_operand 1 "register_operand" "f")
888 (match_operand 2 "register_operand" "f"))]
889 UNSPEC_FNSTSW))]
890 "TARGET_80387
891 && FLOAT_MODE_P (GET_MODE (operands[1]))
892 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
893 "* return output_fp_compare (insn, operands, 0, 1);"
894 [(set_attr "type" "multi")
895 (set_attr "unit" "i387")
896 (set (attr "mode")
897 (cond [(match_operand:SF 1 "" "")
898 (const_string "SF")
899 (match_operand:DF 1 "" "")
900 (const_string "DF")
901 ]
902 (const_string "XF")))])
903
904 (define_insn "*cmpfp_<mode>"
905 [(set (match_operand:HI 0 "register_operand" "=a")
906 (unspec:HI
907 [(compare:CCFP
908 (match_operand 1 "register_operand" "f")
909 (match_operator 3 "float_operator"
910 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
911 UNSPEC_FNSTSW))]
912 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
913 && FLOAT_MODE_P (GET_MODE (operands[1]))
914 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
915 "* return output_fp_compare (insn, operands, 0, 0);"
916 [(set_attr "type" "multi")
917 (set_attr "unit" "i387")
918 (set_attr "fp_int_src" "true")
919 (set_attr "mode" "<MODE>")])
920
921 ;; FP compares, step 2
922 ;; Move the fpsw to ax.
923
924 (define_insn "x86_fnstsw_1"
925 [(set (match_operand:HI 0 "register_operand" "=a")
926 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
927 "TARGET_80387"
928 "fnstsw\t%0"
929 [(set_attr "length" "2")
930 (set_attr "mode" "SI")
931 (set_attr "unit" "i387")])
932
933 ;; FP compares, step 3
934 ;; Get ax into flags, general case.
935
936 (define_insn "x86_sahf_1"
937 [(set (reg:CC FLAGS_REG)
938 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
939 "!TARGET_64BIT"
940 "sahf"
941 [(set_attr "length" "1")
942 (set_attr "athlon_decode" "vector")
943 (set_attr "mode" "SI")])
944
945 ;; Pentium Pro can do steps 1 through 3 in one go.
946
947 (define_insn "*cmpfp_i_mixed"
948 [(set (reg:CCFP FLAGS_REG)
949 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
950 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
951 "TARGET_MIX_SSE_I387
952 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
953 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
954 "* return output_fp_compare (insn, operands, 1, 0);"
955 [(set_attr "type" "fcmp,ssecomi")
956 (set (attr "mode")
957 (if_then_else (match_operand:SF 1 "" "")
958 (const_string "SF")
959 (const_string "DF")))
960 (set_attr "athlon_decode" "vector")])
961
962 (define_insn "*cmpfp_i_sse"
963 [(set (reg:CCFP FLAGS_REG)
964 (compare:CCFP (match_operand 0 "register_operand" "x")
965 (match_operand 1 "nonimmediate_operand" "xm")))]
966 "TARGET_SSE_MATH
967 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
968 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
969 "* return output_fp_compare (insn, operands, 1, 0);"
970 [(set_attr "type" "ssecomi")
971 (set (attr "mode")
972 (if_then_else (match_operand:SF 1 "" "")
973 (const_string "SF")
974 (const_string "DF")))
975 (set_attr "athlon_decode" "vector")])
976
977 (define_insn "*cmpfp_i_i387"
978 [(set (reg:CCFP FLAGS_REG)
979 (compare:CCFP (match_operand 0 "register_operand" "f")
980 (match_operand 1 "register_operand" "f")))]
981 "TARGET_80387 && TARGET_CMOVE
982 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
983 && FLOAT_MODE_P (GET_MODE (operands[0]))
984 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
985 "* return output_fp_compare (insn, operands, 1, 0);"
986 [(set_attr "type" "fcmp")
987 (set (attr "mode")
988 (cond [(match_operand:SF 1 "" "")
989 (const_string "SF")
990 (match_operand:DF 1 "" "")
991 (const_string "DF")
992 ]
993 (const_string "XF")))
994 (set_attr "athlon_decode" "vector")])
995
996 (define_insn "*cmpfp_iu_mixed"
997 [(set (reg:CCFPU FLAGS_REG)
998 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
999 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1000 "TARGET_MIX_SSE_I387
1001 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1002 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1003 "* return output_fp_compare (insn, operands, 1, 1);"
1004 [(set_attr "type" "fcmp,ssecomi")
1005 (set (attr "mode")
1006 (if_then_else (match_operand:SF 1 "" "")
1007 (const_string "SF")
1008 (const_string "DF")))
1009 (set_attr "athlon_decode" "vector")])
1010
1011 (define_insn "*cmpfp_iu_sse"
1012 [(set (reg:CCFPU FLAGS_REG)
1013 (compare:CCFPU (match_operand 0 "register_operand" "x")
1014 (match_operand 1 "nonimmediate_operand" "xm")))]
1015 "TARGET_SSE_MATH
1016 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1017 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1018 "* return output_fp_compare (insn, operands, 1, 1);"
1019 [(set_attr "type" "ssecomi")
1020 (set (attr "mode")
1021 (if_then_else (match_operand:SF 1 "" "")
1022 (const_string "SF")
1023 (const_string "DF")))
1024 (set_attr "athlon_decode" "vector")])
1025
1026 (define_insn "*cmpfp_iu_387"
1027 [(set (reg:CCFPU FLAGS_REG)
1028 (compare:CCFPU (match_operand 0 "register_operand" "f")
1029 (match_operand 1 "register_operand" "f")))]
1030 "TARGET_80387 && TARGET_CMOVE
1031 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1032 && FLOAT_MODE_P (GET_MODE (operands[0]))
1033 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1034 "* return output_fp_compare (insn, operands, 1, 1);"
1035 [(set_attr "type" "fcmp")
1036 (set (attr "mode")
1037 (cond [(match_operand:SF 1 "" "")
1038 (const_string "SF")
1039 (match_operand:DF 1 "" "")
1040 (const_string "DF")
1041 ]
1042 (const_string "XF")))
1043 (set_attr "athlon_decode" "vector")])
1044 \f
1045 ;; Move instructions.
1046
1047 ;; General case of fullword move.
1048
1049 (define_expand "movsi"
1050 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1051 (match_operand:SI 1 "general_operand" ""))]
1052 ""
1053 "ix86_expand_move (SImode, operands); DONE;")
1054
1055 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1056 ;; general_operand.
1057 ;;
1058 ;; %%% We don't use a post-inc memory reference because x86 is not a
1059 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1060 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1061 ;; targets without our curiosities, and it is just as easy to represent
1062 ;; this differently.
1063
1064 (define_insn "*pushsi2"
1065 [(set (match_operand:SI 0 "push_operand" "=<")
1066 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1067 "!TARGET_64BIT"
1068 "push{l}\t%1"
1069 [(set_attr "type" "push")
1070 (set_attr "mode" "SI")])
1071
1072 ;; For 64BIT abi we always round up to 8 bytes.
1073 (define_insn "*pushsi2_rex64"
1074 [(set (match_operand:SI 0 "push_operand" "=X")
1075 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1076 "TARGET_64BIT"
1077 "push{q}\t%q1"
1078 [(set_attr "type" "push")
1079 (set_attr "mode" "SI")])
1080
1081 (define_insn "*pushsi2_prologue"
1082 [(set (match_operand:SI 0 "push_operand" "=<")
1083 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1084 (clobber (mem:BLK (scratch)))]
1085 "!TARGET_64BIT"
1086 "push{l}\t%1"
1087 [(set_attr "type" "push")
1088 (set_attr "mode" "SI")])
1089
1090 (define_insn "*popsi1_epilogue"
1091 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1092 (mem:SI (reg:SI SP_REG)))
1093 (set (reg:SI SP_REG)
1094 (plus:SI (reg:SI SP_REG) (const_int 4)))
1095 (clobber (mem:BLK (scratch)))]
1096 "!TARGET_64BIT"
1097 "pop{l}\t%0"
1098 [(set_attr "type" "pop")
1099 (set_attr "mode" "SI")])
1100
1101 (define_insn "popsi1"
1102 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1103 (mem:SI (reg:SI SP_REG)))
1104 (set (reg:SI SP_REG)
1105 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1106 "!TARGET_64BIT"
1107 "pop{l}\t%0"
1108 [(set_attr "type" "pop")
1109 (set_attr "mode" "SI")])
1110
1111 (define_insn "*movsi_xor"
1112 [(set (match_operand:SI 0 "register_operand" "=r")
1113 (match_operand:SI 1 "const0_operand" "i"))
1114 (clobber (reg:CC FLAGS_REG))]
1115 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1116 "xor{l}\t{%0, %0|%0, %0}"
1117 [(set_attr "type" "alu1")
1118 (set_attr "mode" "SI")
1119 (set_attr "length_immediate" "0")])
1120
1121 (define_insn "*movsi_or"
1122 [(set (match_operand:SI 0 "register_operand" "=r")
1123 (match_operand:SI 1 "immediate_operand" "i"))
1124 (clobber (reg:CC FLAGS_REG))]
1125 "reload_completed
1126 && operands[1] == constm1_rtx
1127 && (TARGET_PENTIUM || optimize_size)"
1128 {
1129 operands[1] = constm1_rtx;
1130 return "or{l}\t{%1, %0|%0, %1}";
1131 }
1132 [(set_attr "type" "alu1")
1133 (set_attr "mode" "SI")
1134 (set_attr "length_immediate" "1")])
1135
1136 (define_insn "*movsi_1"
1137 [(set (match_operand:SI 0 "nonimmediate_operand"
1138 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1139 (match_operand:SI 1 "general_operand"
1140 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1141 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1142 {
1143 switch (get_attr_type (insn))
1144 {
1145 case TYPE_SSELOG1:
1146 if (get_attr_mode (insn) == MODE_TI)
1147 return "pxor\t%0, %0";
1148 return "xorps\t%0, %0";
1149
1150 case TYPE_SSEMOV:
1151 switch (get_attr_mode (insn))
1152 {
1153 case MODE_TI:
1154 return "movdqa\t{%1, %0|%0, %1}";
1155 case MODE_V4SF:
1156 return "movaps\t{%1, %0|%0, %1}";
1157 case MODE_SI:
1158 return "movd\t{%1, %0|%0, %1}";
1159 case MODE_SF:
1160 return "movss\t{%1, %0|%0, %1}";
1161 default:
1162 gcc_unreachable ();
1163 }
1164
1165 case TYPE_MMXADD:
1166 return "pxor\t%0, %0";
1167
1168 case TYPE_MMXMOV:
1169 if (get_attr_mode (insn) == MODE_DI)
1170 return "movq\t{%1, %0|%0, %1}";
1171 return "movd\t{%1, %0|%0, %1}";
1172
1173 case TYPE_LEA:
1174 return "lea{l}\t{%1, %0|%0, %1}";
1175
1176 default:
1177 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1178 return "mov{l}\t{%1, %0|%0, %1}";
1179 }
1180 }
1181 [(set (attr "type")
1182 (cond [(eq_attr "alternative" "2")
1183 (const_string "mmx")
1184 (eq_attr "alternative" "3,4,5")
1185 (const_string "mmxmov")
1186 (eq_attr "alternative" "6")
1187 (const_string "sselog1")
1188 (eq_attr "alternative" "7,8,9,10,11")
1189 (const_string "ssemov")
1190 (and (ne (symbol_ref "flag_pic") (const_int 0))
1191 (match_operand:SI 1 "symbolic_operand" ""))
1192 (const_string "lea")
1193 ]
1194 (const_string "imov")))
1195 (set (attr "mode")
1196 (cond [(eq_attr "alternative" "2,3")
1197 (const_string "DI")
1198 (eq_attr "alternative" "6,7")
1199 (if_then_else
1200 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1201 (const_string "V4SF")
1202 (const_string "TI"))
1203 (and (eq_attr "alternative" "8,9,10,11")
1204 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1205 (const_string "SF")
1206 ]
1207 (const_string "SI")))])
1208
1209 ;; Stores and loads of ax to arbitrary constant address.
1210 ;; We fake an second form of instruction to force reload to load address
1211 ;; into register when rax is not available
1212 (define_insn "*movabssi_1_rex64"
1213 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1214 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1215 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1216 "@
1217 movabs{l}\t{%1, %P0|%P0, %1}
1218 mov{l}\t{%1, %a0|%a0, %1}"
1219 [(set_attr "type" "imov")
1220 (set_attr "modrm" "0,*")
1221 (set_attr "length_address" "8,0")
1222 (set_attr "length_immediate" "0,*")
1223 (set_attr "memory" "store")
1224 (set_attr "mode" "SI")])
1225
1226 (define_insn "*movabssi_2_rex64"
1227 [(set (match_operand:SI 0 "register_operand" "=a,r")
1228 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1229 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1230 "@
1231 movabs{l}\t{%P1, %0|%0, %P1}
1232 mov{l}\t{%a1, %0|%0, %a1}"
1233 [(set_attr "type" "imov")
1234 (set_attr "modrm" "0,*")
1235 (set_attr "length_address" "8,0")
1236 (set_attr "length_immediate" "0")
1237 (set_attr "memory" "load")
1238 (set_attr "mode" "SI")])
1239
1240 (define_insn "*swapsi"
1241 [(set (match_operand:SI 0 "register_operand" "+r")
1242 (match_operand:SI 1 "register_operand" "+r"))
1243 (set (match_dup 1)
1244 (match_dup 0))]
1245 ""
1246 "xchg{l}\t%1, %0"
1247 [(set_attr "type" "imov")
1248 (set_attr "mode" "SI")
1249 (set_attr "pent_pair" "np")
1250 (set_attr "athlon_decode" "vector")])
1251
1252 (define_expand "movhi"
1253 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1254 (match_operand:HI 1 "general_operand" ""))]
1255 ""
1256 "ix86_expand_move (HImode, operands); DONE;")
1257
1258 (define_insn "*pushhi2"
1259 [(set (match_operand:HI 0 "push_operand" "=<,<")
1260 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1261 "!TARGET_64BIT"
1262 "@
1263 push{w}\t{|WORD PTR }%1
1264 push{w}\t%1"
1265 [(set_attr "type" "push")
1266 (set_attr "mode" "HI")])
1267
1268 ;; For 64BIT abi we always round up to 8 bytes.
1269 (define_insn "*pushhi2_rex64"
1270 [(set (match_operand:HI 0 "push_operand" "=X")
1271 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1272 "TARGET_64BIT"
1273 "push{q}\t%q1"
1274 [(set_attr "type" "push")
1275 (set_attr "mode" "QI")])
1276
1277 (define_insn "*movhi_1"
1278 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1279 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1280 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1281 {
1282 switch (get_attr_type (insn))
1283 {
1284 case TYPE_IMOVX:
1285 /* movzwl is faster than movw on p2 due to partial word stalls,
1286 though not as fast as an aligned movl. */
1287 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1288 default:
1289 if (get_attr_mode (insn) == MODE_SI)
1290 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1291 else
1292 return "mov{w}\t{%1, %0|%0, %1}";
1293 }
1294 }
1295 [(set (attr "type")
1296 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1297 (const_string "imov")
1298 (and (eq_attr "alternative" "0")
1299 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1300 (const_int 0))
1301 (eq (symbol_ref "TARGET_HIMODE_MATH")
1302 (const_int 0))))
1303 (const_string "imov")
1304 (and (eq_attr "alternative" "1,2")
1305 (match_operand:HI 1 "aligned_operand" ""))
1306 (const_string "imov")
1307 (and (ne (symbol_ref "TARGET_MOVX")
1308 (const_int 0))
1309 (eq_attr "alternative" "0,2"))
1310 (const_string "imovx")
1311 ]
1312 (const_string "imov")))
1313 (set (attr "mode")
1314 (cond [(eq_attr "type" "imovx")
1315 (const_string "SI")
1316 (and (eq_attr "alternative" "1,2")
1317 (match_operand:HI 1 "aligned_operand" ""))
1318 (const_string "SI")
1319 (and (eq_attr "alternative" "0")
1320 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1321 (const_int 0))
1322 (eq (symbol_ref "TARGET_HIMODE_MATH")
1323 (const_int 0))))
1324 (const_string "SI")
1325 ]
1326 (const_string "HI")))])
1327
1328 ;; Stores and loads of ax to arbitrary constant address.
1329 ;; We fake an second form of instruction to force reload to load address
1330 ;; into register when rax is not available
1331 (define_insn "*movabshi_1_rex64"
1332 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1333 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1334 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1335 "@
1336 movabs{w}\t{%1, %P0|%P0, %1}
1337 mov{w}\t{%1, %a0|%a0, %1}"
1338 [(set_attr "type" "imov")
1339 (set_attr "modrm" "0,*")
1340 (set_attr "length_address" "8,0")
1341 (set_attr "length_immediate" "0,*")
1342 (set_attr "memory" "store")
1343 (set_attr "mode" "HI")])
1344
1345 (define_insn "*movabshi_2_rex64"
1346 [(set (match_operand:HI 0 "register_operand" "=a,r")
1347 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1348 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1349 "@
1350 movabs{w}\t{%P1, %0|%0, %P1}
1351 mov{w}\t{%a1, %0|%0, %a1}"
1352 [(set_attr "type" "imov")
1353 (set_attr "modrm" "0,*")
1354 (set_attr "length_address" "8,0")
1355 (set_attr "length_immediate" "0")
1356 (set_attr "memory" "load")
1357 (set_attr "mode" "HI")])
1358
1359 (define_insn "*swaphi_1"
1360 [(set (match_operand:HI 0 "register_operand" "+r")
1361 (match_operand:HI 1 "register_operand" "+r"))
1362 (set (match_dup 1)
1363 (match_dup 0))]
1364 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1365 "xchg{l}\t%k1, %k0"
1366 [(set_attr "type" "imov")
1367 (set_attr "mode" "SI")
1368 (set_attr "pent_pair" "np")
1369 (set_attr "athlon_decode" "vector")])
1370
1371 (define_insn "*swaphi_2"
1372 [(set (match_operand:HI 0 "register_operand" "+r")
1373 (match_operand:HI 1 "register_operand" "+r"))
1374 (set (match_dup 1)
1375 (match_dup 0))]
1376 "TARGET_PARTIAL_REG_STALL"
1377 "xchg{w}\t%1, %0"
1378 [(set_attr "type" "imov")
1379 (set_attr "mode" "HI")
1380 (set_attr "pent_pair" "np")
1381 (set_attr "athlon_decode" "vector")])
1382
1383 (define_expand "movstricthi"
1384 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1385 (match_operand:HI 1 "general_operand" ""))]
1386 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1387 {
1388 /* Don't generate memory->memory moves, go through a register */
1389 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1390 operands[1] = force_reg (HImode, operands[1]);
1391 })
1392
1393 (define_insn "*movstricthi_1"
1394 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1395 (match_operand:HI 1 "general_operand" "rn,m"))]
1396 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1397 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1398 "mov{w}\t{%1, %0|%0, %1}"
1399 [(set_attr "type" "imov")
1400 (set_attr "mode" "HI")])
1401
1402 (define_insn "*movstricthi_xor"
1403 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1404 (match_operand:HI 1 "const0_operand" "i"))
1405 (clobber (reg:CC FLAGS_REG))]
1406 "reload_completed
1407 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1408 "xor{w}\t{%0, %0|%0, %0}"
1409 [(set_attr "type" "alu1")
1410 (set_attr "mode" "HI")
1411 (set_attr "length_immediate" "0")])
1412
1413 (define_expand "movqi"
1414 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1415 (match_operand:QI 1 "general_operand" ""))]
1416 ""
1417 "ix86_expand_move (QImode, operands); DONE;")
1418
1419 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1420 ;; "push a byte". But actually we use pushw, which has the effect
1421 ;; of rounding the amount pushed up to a halfword.
1422
1423 (define_insn "*pushqi2"
1424 [(set (match_operand:QI 0 "push_operand" "=X,X")
1425 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1426 "!TARGET_64BIT"
1427 "@
1428 push{w}\t{|word ptr }%1
1429 push{w}\t%w1"
1430 [(set_attr "type" "push")
1431 (set_attr "mode" "HI")])
1432
1433 ;; For 64BIT abi we always round up to 8 bytes.
1434 (define_insn "*pushqi2_rex64"
1435 [(set (match_operand:QI 0 "push_operand" "=X")
1436 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1437 "TARGET_64BIT"
1438 "push{q}\t%q1"
1439 [(set_attr "type" "push")
1440 (set_attr "mode" "QI")])
1441
1442 ;; Situation is quite tricky about when to choose full sized (SImode) move
1443 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1444 ;; partial register dependency machines (such as AMD Athlon), where QImode
1445 ;; moves issue extra dependency and for partial register stalls machines
1446 ;; that don't use QImode patterns (and QImode move cause stall on the next
1447 ;; instruction).
1448 ;;
1449 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1450 ;; register stall machines with, where we use QImode instructions, since
1451 ;; partial register stall can be caused there. Then we use movzx.
1452 (define_insn "*movqi_1"
1453 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1454 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,m ,qn"))]
1455 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1456 {
1457 switch (get_attr_type (insn))
1458 {
1459 case TYPE_IMOVX:
1460 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1461 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1462 default:
1463 if (get_attr_mode (insn) == MODE_SI)
1464 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1465 else
1466 return "mov{b}\t{%1, %0|%0, %1}";
1467 }
1468 }
1469 [(set (attr "type")
1470 (cond [(eq_attr "alternative" "5")
1471 (const_string "imovx")
1472 (ne (symbol_ref "optimize_size") (const_int 0))
1473 (const_string "imov")
1474 (and (eq_attr "alternative" "3")
1475 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1476 (const_int 0))
1477 (eq (symbol_ref "TARGET_QIMODE_MATH")
1478 (const_int 0))))
1479 (const_string "imov")
1480 (eq_attr "alternative" "3")
1481 (const_string "imovx")
1482 (and (ne (symbol_ref "TARGET_MOVX")
1483 (const_int 0))
1484 (eq_attr "alternative" "2"))
1485 (const_string "imovx")
1486 ]
1487 (const_string "imov")))
1488 (set (attr "mode")
1489 (cond [(eq_attr "alternative" "3,4,5")
1490 (const_string "SI")
1491 (eq_attr "alternative" "6")
1492 (const_string "QI")
1493 (eq_attr "type" "imovx")
1494 (const_string "SI")
1495 (and (eq_attr "type" "imov")
1496 (and (eq_attr "alternative" "0,1")
1497 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1498 (const_int 0))))
1499 (const_string "SI")
1500 ;; Avoid partial register stalls when not using QImode arithmetic
1501 (and (eq_attr "type" "imov")
1502 (and (eq_attr "alternative" "0,1")
1503 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1504 (const_int 0))
1505 (eq (symbol_ref "TARGET_QIMODE_MATH")
1506 (const_int 0)))))
1507 (const_string "SI")
1508 ]
1509 (const_string "QI")))])
1510
1511 (define_expand "reload_outqi"
1512 [(parallel [(match_operand:QI 0 "" "=m")
1513 (match_operand:QI 1 "register_operand" "r")
1514 (match_operand:QI 2 "register_operand" "=&q")])]
1515 ""
1516 {
1517 rtx op0, op1, op2;
1518 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1519
1520 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1521 if (! q_regs_operand (op1, QImode))
1522 {
1523 emit_insn (gen_movqi (op2, op1));
1524 op1 = op2;
1525 }
1526 emit_insn (gen_movqi (op0, op1));
1527 DONE;
1528 })
1529
1530 (define_insn "*swapqi_1"
1531 [(set (match_operand:QI 0 "register_operand" "+r")
1532 (match_operand:QI 1 "register_operand" "+r"))
1533 (set (match_dup 1)
1534 (match_dup 0))]
1535 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1536 "xchg{l}\t%k1, %k0"
1537 [(set_attr "type" "imov")
1538 (set_attr "mode" "SI")
1539 (set_attr "pent_pair" "np")
1540 (set_attr "athlon_decode" "vector")])
1541
1542 (define_insn "*swapqi_2"
1543 [(set (match_operand:QI 0 "register_operand" "+q")
1544 (match_operand:QI 1 "register_operand" "+q"))
1545 (set (match_dup 1)
1546 (match_dup 0))]
1547 "TARGET_PARTIAL_REG_STALL"
1548 "xchg{b}\t%1, %0"
1549 [(set_attr "type" "imov")
1550 (set_attr "mode" "QI")
1551 (set_attr "pent_pair" "np")
1552 (set_attr "athlon_decode" "vector")])
1553
1554 (define_expand "movstrictqi"
1555 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1556 (match_operand:QI 1 "general_operand" ""))]
1557 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1558 {
1559 /* Don't generate memory->memory moves, go through a register. */
1560 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1561 operands[1] = force_reg (QImode, operands[1]);
1562 })
1563
1564 (define_insn "*movstrictqi_1"
1565 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1566 (match_operand:QI 1 "general_operand" "*qn,m"))]
1567 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1568 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1569 "mov{b}\t{%1, %0|%0, %1}"
1570 [(set_attr "type" "imov")
1571 (set_attr "mode" "QI")])
1572
1573 (define_insn "*movstrictqi_xor"
1574 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1575 (match_operand:QI 1 "const0_operand" "i"))
1576 (clobber (reg:CC FLAGS_REG))]
1577 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1578 "xor{b}\t{%0, %0|%0, %0}"
1579 [(set_attr "type" "alu1")
1580 (set_attr "mode" "QI")
1581 (set_attr "length_immediate" "0")])
1582
1583 (define_insn "*movsi_extv_1"
1584 [(set (match_operand:SI 0 "register_operand" "=R")
1585 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1586 (const_int 8)
1587 (const_int 8)))]
1588 ""
1589 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1590 [(set_attr "type" "imovx")
1591 (set_attr "mode" "SI")])
1592
1593 (define_insn "*movhi_extv_1"
1594 [(set (match_operand:HI 0 "register_operand" "=R")
1595 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1596 (const_int 8)
1597 (const_int 8)))]
1598 ""
1599 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1600 [(set_attr "type" "imovx")
1601 (set_attr "mode" "SI")])
1602
1603 (define_insn "*movqi_extv_1"
1604 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1605 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1606 (const_int 8)
1607 (const_int 8)))]
1608 "!TARGET_64BIT"
1609 {
1610 switch (get_attr_type (insn))
1611 {
1612 case TYPE_IMOVX:
1613 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1614 default:
1615 return "mov{b}\t{%h1, %0|%0, %h1}";
1616 }
1617 }
1618 [(set (attr "type")
1619 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1620 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1621 (ne (symbol_ref "TARGET_MOVX")
1622 (const_int 0))))
1623 (const_string "imovx")
1624 (const_string "imov")))
1625 (set (attr "mode")
1626 (if_then_else (eq_attr "type" "imovx")
1627 (const_string "SI")
1628 (const_string "QI")))])
1629
1630 (define_insn "*movqi_extv_1_rex64"
1631 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1632 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1633 (const_int 8)
1634 (const_int 8)))]
1635 "TARGET_64BIT"
1636 {
1637 switch (get_attr_type (insn))
1638 {
1639 case TYPE_IMOVX:
1640 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1641 default:
1642 return "mov{b}\t{%h1, %0|%0, %h1}";
1643 }
1644 }
1645 [(set (attr "type")
1646 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1647 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1648 (ne (symbol_ref "TARGET_MOVX")
1649 (const_int 0))))
1650 (const_string "imovx")
1651 (const_string "imov")))
1652 (set (attr "mode")
1653 (if_then_else (eq_attr "type" "imovx")
1654 (const_string "SI")
1655 (const_string "QI")))])
1656
1657 ;; Stores and loads of ax to arbitrary constant address.
1658 ;; We fake an second form of instruction to force reload to load address
1659 ;; into register when rax is not available
1660 (define_insn "*movabsqi_1_rex64"
1661 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1662 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1663 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1664 "@
1665 movabs{b}\t{%1, %P0|%P0, %1}
1666 mov{b}\t{%1, %a0|%a0, %1}"
1667 [(set_attr "type" "imov")
1668 (set_attr "modrm" "0,*")
1669 (set_attr "length_address" "8,0")
1670 (set_attr "length_immediate" "0,*")
1671 (set_attr "memory" "store")
1672 (set_attr "mode" "QI")])
1673
1674 (define_insn "*movabsqi_2_rex64"
1675 [(set (match_operand:QI 0 "register_operand" "=a,r")
1676 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1677 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1678 "@
1679 movabs{b}\t{%P1, %0|%0, %P1}
1680 mov{b}\t{%a1, %0|%0, %a1}"
1681 [(set_attr "type" "imov")
1682 (set_attr "modrm" "0,*")
1683 (set_attr "length_address" "8,0")
1684 (set_attr "length_immediate" "0")
1685 (set_attr "memory" "load")
1686 (set_attr "mode" "QI")])
1687
1688 (define_insn "*movdi_extzv_1"
1689 [(set (match_operand:DI 0 "register_operand" "=R")
1690 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1691 (const_int 8)
1692 (const_int 8)))]
1693 "TARGET_64BIT"
1694 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1695 [(set_attr "type" "imovx")
1696 (set_attr "mode" "DI")])
1697
1698 (define_insn "*movsi_extzv_1"
1699 [(set (match_operand:SI 0 "register_operand" "=R")
1700 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1701 (const_int 8)
1702 (const_int 8)))]
1703 ""
1704 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1705 [(set_attr "type" "imovx")
1706 (set_attr "mode" "SI")])
1707
1708 (define_insn "*movqi_extzv_2"
1709 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1710 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1711 (const_int 8)
1712 (const_int 8)) 0))]
1713 "!TARGET_64BIT"
1714 {
1715 switch (get_attr_type (insn))
1716 {
1717 case TYPE_IMOVX:
1718 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1719 default:
1720 return "mov{b}\t{%h1, %0|%0, %h1}";
1721 }
1722 }
1723 [(set (attr "type")
1724 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1725 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1726 (ne (symbol_ref "TARGET_MOVX")
1727 (const_int 0))))
1728 (const_string "imovx")
1729 (const_string "imov")))
1730 (set (attr "mode")
1731 (if_then_else (eq_attr "type" "imovx")
1732 (const_string "SI")
1733 (const_string "QI")))])
1734
1735 (define_insn "*movqi_extzv_2_rex64"
1736 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1737 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1738 (const_int 8)
1739 (const_int 8)) 0))]
1740 "TARGET_64BIT"
1741 {
1742 switch (get_attr_type (insn))
1743 {
1744 case TYPE_IMOVX:
1745 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1746 default:
1747 return "mov{b}\t{%h1, %0|%0, %h1}";
1748 }
1749 }
1750 [(set (attr "type")
1751 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1752 (ne (symbol_ref "TARGET_MOVX")
1753 (const_int 0)))
1754 (const_string "imovx")
1755 (const_string "imov")))
1756 (set (attr "mode")
1757 (if_then_else (eq_attr "type" "imovx")
1758 (const_string "SI")
1759 (const_string "QI")))])
1760
1761 (define_insn "movsi_insv_1"
1762 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1763 (const_int 8)
1764 (const_int 8))
1765 (match_operand:SI 1 "general_operand" "Qmn"))]
1766 "!TARGET_64BIT"
1767 "mov{b}\t{%b1, %h0|%h0, %b1}"
1768 [(set_attr "type" "imov")
1769 (set_attr "mode" "QI")])
1770
1771 (define_insn "movdi_insv_1_rex64"
1772 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1773 (const_int 8)
1774 (const_int 8))
1775 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1776 "TARGET_64BIT"
1777 "mov{b}\t{%b1, %h0|%h0, %b1}"
1778 [(set_attr "type" "imov")
1779 (set_attr "mode" "QI")])
1780
1781 (define_insn "*movqi_insv_2"
1782 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1783 (const_int 8)
1784 (const_int 8))
1785 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1786 (const_int 8)))]
1787 ""
1788 "mov{b}\t{%h1, %h0|%h0, %h1}"
1789 [(set_attr "type" "imov")
1790 (set_attr "mode" "QI")])
1791
1792 (define_expand "movdi"
1793 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1794 (match_operand:DI 1 "general_operand" ""))]
1795 ""
1796 "ix86_expand_move (DImode, operands); DONE;")
1797
1798 (define_insn "*pushdi"
1799 [(set (match_operand:DI 0 "push_operand" "=<")
1800 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1801 "!TARGET_64BIT"
1802 "#")
1803
1804 (define_insn "*pushdi2_rex64"
1805 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1806 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1807 "TARGET_64BIT"
1808 "@
1809 push{q}\t%1
1810 #"
1811 [(set_attr "type" "push,multi")
1812 (set_attr "mode" "DI")])
1813
1814 ;; Convert impossible pushes of immediate to existing instructions.
1815 ;; First try to get scratch register and go through it. In case this
1816 ;; fails, push sign extended lower part first and then overwrite
1817 ;; upper part by 32bit move.
1818 (define_peephole2
1819 [(match_scratch:DI 2 "r")
1820 (set (match_operand:DI 0 "push_operand" "")
1821 (match_operand:DI 1 "immediate_operand" ""))]
1822 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1823 && !x86_64_immediate_operand (operands[1], DImode)"
1824 [(set (match_dup 2) (match_dup 1))
1825 (set (match_dup 0) (match_dup 2))]
1826 "")
1827
1828 ;; We need to define this as both peepholer and splitter for case
1829 ;; peephole2 pass is not run.
1830 ;; "&& 1" is needed to keep it from matching the previous pattern.
1831 (define_peephole2
1832 [(set (match_operand:DI 0 "push_operand" "")
1833 (match_operand:DI 1 "immediate_operand" ""))]
1834 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1835 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1836 [(set (match_dup 0) (match_dup 1))
1837 (set (match_dup 2) (match_dup 3))]
1838 "split_di (operands + 1, 1, operands + 2, operands + 3);
1839 operands[1] = gen_lowpart (DImode, operands[2]);
1840 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1841 GEN_INT (4)));
1842 ")
1843
1844 (define_split
1845 [(set (match_operand:DI 0 "push_operand" "")
1846 (match_operand:DI 1 "immediate_operand" ""))]
1847 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1848 && !symbolic_operand (operands[1], DImode)
1849 && !x86_64_immediate_operand (operands[1], DImode)"
1850 [(set (match_dup 0) (match_dup 1))
1851 (set (match_dup 2) (match_dup 3))]
1852 "split_di (operands + 1, 1, operands + 2, operands + 3);
1853 operands[1] = gen_lowpart (DImode, operands[2]);
1854 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1855 GEN_INT (4)));
1856 ")
1857
1858 (define_insn "*pushdi2_prologue_rex64"
1859 [(set (match_operand:DI 0 "push_operand" "=<")
1860 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1861 (clobber (mem:BLK (scratch)))]
1862 "TARGET_64BIT"
1863 "push{q}\t%1"
1864 [(set_attr "type" "push")
1865 (set_attr "mode" "DI")])
1866
1867 (define_insn "*popdi1_epilogue_rex64"
1868 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1869 (mem:DI (reg:DI SP_REG)))
1870 (set (reg:DI SP_REG)
1871 (plus:DI (reg:DI SP_REG) (const_int 8)))
1872 (clobber (mem:BLK (scratch)))]
1873 "TARGET_64BIT"
1874 "pop{q}\t%0"
1875 [(set_attr "type" "pop")
1876 (set_attr "mode" "DI")])
1877
1878 (define_insn "popdi1"
1879 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1880 (mem:DI (reg:DI SP_REG)))
1881 (set (reg:DI SP_REG)
1882 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1883 "TARGET_64BIT"
1884 "pop{q}\t%0"
1885 [(set_attr "type" "pop")
1886 (set_attr "mode" "DI")])
1887
1888 (define_insn "*movdi_xor_rex64"
1889 [(set (match_operand:DI 0 "register_operand" "=r")
1890 (match_operand:DI 1 "const0_operand" "i"))
1891 (clobber (reg:CC FLAGS_REG))]
1892 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1893 && reload_completed"
1894 "xor{l}\t{%k0, %k0|%k0, %k0}"
1895 [(set_attr "type" "alu1")
1896 (set_attr "mode" "SI")
1897 (set_attr "length_immediate" "0")])
1898
1899 (define_insn "*movdi_or_rex64"
1900 [(set (match_operand:DI 0 "register_operand" "=r")
1901 (match_operand:DI 1 "const_int_operand" "i"))
1902 (clobber (reg:CC FLAGS_REG))]
1903 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1904 && reload_completed
1905 && operands[1] == constm1_rtx"
1906 {
1907 operands[1] = constm1_rtx;
1908 return "or{q}\t{%1, %0|%0, %1}";
1909 }
1910 [(set_attr "type" "alu1")
1911 (set_attr "mode" "DI")
1912 (set_attr "length_immediate" "1")])
1913
1914 (define_insn "*movdi_2"
1915 [(set (match_operand:DI 0 "nonimmediate_operand"
1916 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1917 (match_operand:DI 1 "general_operand"
1918 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1919 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1920 "@
1921 #
1922 #
1923 pxor\t%0, %0
1924 movq\t{%1, %0|%0, %1}
1925 movq\t{%1, %0|%0, %1}
1926 pxor\t%0, %0
1927 movq\t{%1, %0|%0, %1}
1928 movdqa\t{%1, %0|%0, %1}
1929 movq\t{%1, %0|%0, %1}
1930 xorps\t%0, %0
1931 movlps\t{%1, %0|%0, %1}
1932 movaps\t{%1, %0|%0, %1}
1933 movlps\t{%1, %0|%0, %1}"
1934 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1935 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1936
1937 (define_split
1938 [(set (match_operand:DI 0 "push_operand" "")
1939 (match_operand:DI 1 "general_operand" ""))]
1940 "!TARGET_64BIT && reload_completed
1941 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1942 [(const_int 0)]
1943 "ix86_split_long_move (operands); DONE;")
1944
1945 ;; %%% This multiword shite has got to go.
1946 (define_split
1947 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1948 (match_operand:DI 1 "general_operand" ""))]
1949 "!TARGET_64BIT && reload_completed
1950 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1951 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1952 [(const_int 0)]
1953 "ix86_split_long_move (operands); DONE;")
1954
1955 (define_insn "*movdi_1_rex64"
1956 [(set (match_operand:DI 0 "nonimmediate_operand"
1957 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1958 (match_operand:DI 1 "general_operand"
1959 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1960 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1961 {
1962 switch (get_attr_type (insn))
1963 {
1964 case TYPE_SSECVT:
1965 if (which_alternative == 13)
1966 return "movq2dq\t{%1, %0|%0, %1}";
1967 else
1968 return "movdq2q\t{%1, %0|%0, %1}";
1969 case TYPE_SSEMOV:
1970 if (get_attr_mode (insn) == MODE_TI)
1971 return "movdqa\t{%1, %0|%0, %1}";
1972 /* FALLTHRU */
1973 case TYPE_MMXMOV:
1974 /* Moves from and into integer register is done using movd opcode with
1975 REX prefix. */
1976 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1977 return "movd\t{%1, %0|%0, %1}";
1978 return "movq\t{%1, %0|%0, %1}";
1979 case TYPE_SSELOG1:
1980 case TYPE_MMXADD:
1981 return "pxor\t%0, %0";
1982 case TYPE_MULTI:
1983 return "#";
1984 case TYPE_LEA:
1985 return "lea{q}\t{%a1, %0|%0, %a1}";
1986 default:
1987 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1988 if (get_attr_mode (insn) == MODE_SI)
1989 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1990 else if (which_alternative == 2)
1991 return "movabs{q}\t{%1, %0|%0, %1}";
1992 else
1993 return "mov{q}\t{%1, %0|%0, %1}";
1994 }
1995 }
1996 [(set (attr "type")
1997 (cond [(eq_attr "alternative" "5")
1998 (const_string "mmx")
1999 (eq_attr "alternative" "6,7,8")
2000 (const_string "mmxmov")
2001 (eq_attr "alternative" "9")
2002 (const_string "sselog1")
2003 (eq_attr "alternative" "10,11,12")
2004 (const_string "ssemov")
2005 (eq_attr "alternative" "13,14")
2006 (const_string "ssecvt")
2007 (eq_attr "alternative" "4")
2008 (const_string "multi")
2009 (and (ne (symbol_ref "flag_pic") (const_int 0))
2010 (match_operand:DI 1 "symbolic_operand" ""))
2011 (const_string "lea")
2012 ]
2013 (const_string "imov")))
2014 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2015 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2016 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2017
2018 ;; Stores and loads of ax to arbitrary constant address.
2019 ;; We fake an second form of instruction to force reload to load address
2020 ;; into register when rax is not available
2021 (define_insn "*movabsdi_1_rex64"
2022 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2023 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2024 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2025 "@
2026 movabs{q}\t{%1, %P0|%P0, %1}
2027 mov{q}\t{%1, %a0|%a0, %1}"
2028 [(set_attr "type" "imov")
2029 (set_attr "modrm" "0,*")
2030 (set_attr "length_address" "8,0")
2031 (set_attr "length_immediate" "0,*")
2032 (set_attr "memory" "store")
2033 (set_attr "mode" "DI")])
2034
2035 (define_insn "*movabsdi_2_rex64"
2036 [(set (match_operand:DI 0 "register_operand" "=a,r")
2037 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2038 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2039 "@
2040 movabs{q}\t{%P1, %0|%0, %P1}
2041 mov{q}\t{%a1, %0|%0, %a1}"
2042 [(set_attr "type" "imov")
2043 (set_attr "modrm" "0,*")
2044 (set_attr "length_address" "8,0")
2045 (set_attr "length_immediate" "0")
2046 (set_attr "memory" "load")
2047 (set_attr "mode" "DI")])
2048
2049 ;; Convert impossible stores of immediate to existing instructions.
2050 ;; First try to get scratch register and go through it. In case this
2051 ;; fails, move by 32bit parts.
2052 (define_peephole2
2053 [(match_scratch:DI 2 "r")
2054 (set (match_operand:DI 0 "memory_operand" "")
2055 (match_operand:DI 1 "immediate_operand" ""))]
2056 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2057 && !x86_64_immediate_operand (operands[1], DImode)"
2058 [(set (match_dup 2) (match_dup 1))
2059 (set (match_dup 0) (match_dup 2))]
2060 "")
2061
2062 ;; We need to define this as both peepholer and splitter for case
2063 ;; peephole2 pass is not run.
2064 ;; "&& 1" is needed to keep it from matching the previous pattern.
2065 (define_peephole2
2066 [(set (match_operand:DI 0 "memory_operand" "")
2067 (match_operand:DI 1 "immediate_operand" ""))]
2068 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2069 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2070 [(set (match_dup 2) (match_dup 3))
2071 (set (match_dup 4) (match_dup 5))]
2072 "split_di (operands, 2, operands + 2, operands + 4);")
2073
2074 (define_split
2075 [(set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2078 && !symbolic_operand (operands[1], DImode)
2079 && !x86_64_immediate_operand (operands[1], DImode)"
2080 [(set (match_dup 2) (match_dup 3))
2081 (set (match_dup 4) (match_dup 5))]
2082 "split_di (operands, 2, operands + 2, operands + 4);")
2083
2084 (define_insn "*swapdi_rex64"
2085 [(set (match_operand:DI 0 "register_operand" "+r")
2086 (match_operand:DI 1 "register_operand" "+r"))
2087 (set (match_dup 1)
2088 (match_dup 0))]
2089 "TARGET_64BIT"
2090 "xchg{q}\t%1, %0"
2091 [(set_attr "type" "imov")
2092 (set_attr "mode" "DI")
2093 (set_attr "pent_pair" "np")
2094 (set_attr "athlon_decode" "vector")])
2095
2096 (define_expand "movti"
2097 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2098 (match_operand:TI 1 "nonimmediate_operand" ""))]
2099 "TARGET_SSE || TARGET_64BIT"
2100 {
2101 if (TARGET_64BIT)
2102 ix86_expand_move (TImode, operands);
2103 else
2104 ix86_expand_vector_move (TImode, operands);
2105 DONE;
2106 })
2107
2108 (define_insn "*movti_internal"
2109 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2110 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2111 "TARGET_SSE && !TARGET_64BIT
2112 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2113 {
2114 switch (which_alternative)
2115 {
2116 case 0:
2117 if (get_attr_mode (insn) == MODE_V4SF)
2118 return "xorps\t%0, %0";
2119 else
2120 return "pxor\t%0, %0";
2121 case 1:
2122 case 2:
2123 if (get_attr_mode (insn) == MODE_V4SF)
2124 return "movaps\t{%1, %0|%0, %1}";
2125 else
2126 return "movdqa\t{%1, %0|%0, %1}";
2127 default:
2128 gcc_unreachable ();
2129 }
2130 }
2131 [(set_attr "type" "ssemov,ssemov,ssemov")
2132 (set (attr "mode")
2133 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2134 (const_string "V4SF")
2135
2136 (eq_attr "alternative" "0,1")
2137 (if_then_else
2138 (ne (symbol_ref "optimize_size")
2139 (const_int 0))
2140 (const_string "V4SF")
2141 (const_string "TI"))
2142 (eq_attr "alternative" "2")
2143 (if_then_else
2144 (ne (symbol_ref "optimize_size")
2145 (const_int 0))
2146 (const_string "V4SF")
2147 (const_string "TI"))]
2148 (const_string "TI")))])
2149
2150 (define_insn "*movti_rex64"
2151 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2152 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2153 "TARGET_64BIT
2154 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2155 {
2156 switch (which_alternative)
2157 {
2158 case 0:
2159 case 1:
2160 return "#";
2161 case 2:
2162 if (get_attr_mode (insn) == MODE_V4SF)
2163 return "xorps\t%0, %0";
2164 else
2165 return "pxor\t%0, %0";
2166 case 3:
2167 case 4:
2168 if (get_attr_mode (insn) == MODE_V4SF)
2169 return "movaps\t{%1, %0|%0, %1}";
2170 else
2171 return "movdqa\t{%1, %0|%0, %1}";
2172 default:
2173 gcc_unreachable ();
2174 }
2175 }
2176 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2177 (set (attr "mode")
2178 (cond [(eq_attr "alternative" "2,3")
2179 (if_then_else
2180 (ne (symbol_ref "optimize_size")
2181 (const_int 0))
2182 (const_string "V4SF")
2183 (const_string "TI"))
2184 (eq_attr "alternative" "4")
2185 (if_then_else
2186 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2187 (const_int 0))
2188 (ne (symbol_ref "optimize_size")
2189 (const_int 0)))
2190 (const_string "V4SF")
2191 (const_string "TI"))]
2192 (const_string "DI")))])
2193
2194 (define_split
2195 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2196 (match_operand:TI 1 "general_operand" ""))]
2197 "reload_completed && !SSE_REG_P (operands[0])
2198 && !SSE_REG_P (operands[1])"
2199 [(const_int 0)]
2200 "ix86_split_long_move (operands); DONE;")
2201
2202 (define_expand "movsf"
2203 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2204 (match_operand:SF 1 "general_operand" ""))]
2205 ""
2206 "ix86_expand_move (SFmode, operands); DONE;")
2207
2208 (define_insn "*pushsf"
2209 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2210 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2211 "!TARGET_64BIT"
2212 {
2213 /* Anything else should be already split before reg-stack. */
2214 gcc_assert (which_alternative == 1);
2215 return "push{l}\t%1";
2216 }
2217 [(set_attr "type" "multi,push,multi")
2218 (set_attr "unit" "i387,*,*")
2219 (set_attr "mode" "SF,SI,SF")])
2220
2221 (define_insn "*pushsf_rex64"
2222 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2223 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2224 "TARGET_64BIT"
2225 {
2226 /* Anything else should be already split before reg-stack. */
2227 gcc_assert (which_alternative == 1);
2228 return "push{q}\t%q1";
2229 }
2230 [(set_attr "type" "multi,push,multi")
2231 (set_attr "unit" "i387,*,*")
2232 (set_attr "mode" "SF,DI,SF")])
2233
2234 (define_split
2235 [(set (match_operand:SF 0 "push_operand" "")
2236 (match_operand:SF 1 "memory_operand" ""))]
2237 "reload_completed
2238 && GET_CODE (operands[1]) == MEM
2239 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2240 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2241 [(set (match_dup 0)
2242 (match_dup 1))]
2243 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2244
2245
2246 ;; %%% Kill this when call knows how to work this out.
2247 (define_split
2248 [(set (match_operand:SF 0 "push_operand" "")
2249 (match_operand:SF 1 "any_fp_register_operand" ""))]
2250 "!TARGET_64BIT"
2251 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2252 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2253
2254 (define_split
2255 [(set (match_operand:SF 0 "push_operand" "")
2256 (match_operand:SF 1 "any_fp_register_operand" ""))]
2257 "TARGET_64BIT"
2258 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2259 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2260
2261 (define_insn "*movsf_1"
2262 [(set (match_operand:SF 0 "nonimmediate_operand"
2263 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2264 (match_operand:SF 1 "general_operand"
2265 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2266 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2267 && (reload_in_progress || reload_completed
2268 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2269 || GET_CODE (operands[1]) != CONST_DOUBLE
2270 || memory_operand (operands[0], SFmode))"
2271 {
2272 switch (which_alternative)
2273 {
2274 case 0:
2275 return output_387_reg_move (insn, operands);
2276
2277 case 1:
2278 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2279 return "fstp%z0\t%y0";
2280 else
2281 return "fst%z0\t%y0";
2282
2283 case 2:
2284 return standard_80387_constant_opcode (operands[1]);
2285
2286 case 3:
2287 case 4:
2288 return "mov{l}\t{%1, %0|%0, %1}";
2289 case 5:
2290 if (get_attr_mode (insn) == MODE_TI)
2291 return "pxor\t%0, %0";
2292 else
2293 return "xorps\t%0, %0";
2294 case 6:
2295 if (get_attr_mode (insn) == MODE_V4SF)
2296 return "movaps\t{%1, %0|%0, %1}";
2297 else
2298 return "movss\t{%1, %0|%0, %1}";
2299 case 7:
2300 case 8:
2301 return "movss\t{%1, %0|%0, %1}";
2302
2303 case 9:
2304 case 10:
2305 return "movd\t{%1, %0|%0, %1}";
2306
2307 case 11:
2308 return "movq\t{%1, %0|%0, %1}";
2309
2310 default:
2311 gcc_unreachable ();
2312 }
2313 }
2314 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2315 (set (attr "mode")
2316 (cond [(eq_attr "alternative" "3,4,9,10")
2317 (const_string "SI")
2318 (eq_attr "alternative" "5")
2319 (if_then_else
2320 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2321 (const_int 0))
2322 (ne (symbol_ref "TARGET_SSE2")
2323 (const_int 0)))
2324 (eq (symbol_ref "optimize_size")
2325 (const_int 0)))
2326 (const_string "TI")
2327 (const_string "V4SF"))
2328 /* For architectures resolving dependencies on
2329 whole SSE registers use APS move to break dependency
2330 chains, otherwise use short move to avoid extra work.
2331
2332 Do the same for architectures resolving dependencies on
2333 the parts. While in DF mode it is better to always handle
2334 just register parts, the SF mode is different due to lack
2335 of instructions to load just part of the register. It is
2336 better to maintain the whole registers in single format
2337 to avoid problems on using packed logical operations. */
2338 (eq_attr "alternative" "6")
2339 (if_then_else
2340 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2341 (const_int 0))
2342 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2343 (const_int 0)))
2344 (const_string "V4SF")
2345 (const_string "SF"))
2346 (eq_attr "alternative" "11")
2347 (const_string "DI")]
2348 (const_string "SF")))])
2349
2350 (define_insn "*swapsf"
2351 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2352 (match_operand:SF 1 "fp_register_operand" "+f"))
2353 (set (match_dup 1)
2354 (match_dup 0))]
2355 "reload_completed || TARGET_80387"
2356 {
2357 if (STACK_TOP_P (operands[0]))
2358 return "fxch\t%1";
2359 else
2360 return "fxch\t%0";
2361 }
2362 [(set_attr "type" "fxch")
2363 (set_attr "mode" "SF")])
2364
2365 (define_expand "movdf"
2366 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2367 (match_operand:DF 1 "general_operand" ""))]
2368 ""
2369 "ix86_expand_move (DFmode, operands); DONE;")
2370
2371 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2372 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2373 ;; On the average, pushdf using integers can be still shorter. Allow this
2374 ;; pattern for optimize_size too.
2375
2376 (define_insn "*pushdf_nointeger"
2377 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2378 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2379 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2380 {
2381 /* This insn should be already split before reg-stack. */
2382 gcc_unreachable ();
2383 }
2384 [(set_attr "type" "multi")
2385 (set_attr "unit" "i387,*,*,*")
2386 (set_attr "mode" "DF,SI,SI,DF")])
2387
2388 (define_insn "*pushdf_integer"
2389 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2390 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2391 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2392 {
2393 /* This insn should be already split before reg-stack. */
2394 gcc_unreachable ();
2395 }
2396 [(set_attr "type" "multi")
2397 (set_attr "unit" "i387,*,*")
2398 (set_attr "mode" "DF,SI,DF")])
2399
2400 ;; %%% Kill this when call knows how to work this out.
2401 (define_split
2402 [(set (match_operand:DF 0 "push_operand" "")
2403 (match_operand:DF 1 "any_fp_register_operand" ""))]
2404 "!TARGET_64BIT && reload_completed"
2405 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2406 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2407 "")
2408
2409 (define_split
2410 [(set (match_operand:DF 0 "push_operand" "")
2411 (match_operand:DF 1 "any_fp_register_operand" ""))]
2412 "TARGET_64BIT && reload_completed"
2413 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2414 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2415 "")
2416
2417 (define_split
2418 [(set (match_operand:DF 0 "push_operand" "")
2419 (match_operand:DF 1 "general_operand" ""))]
2420 "reload_completed"
2421 [(const_int 0)]
2422 "ix86_split_long_move (operands); DONE;")
2423
2424 ;; Moving is usually shorter when only FP registers are used. This separate
2425 ;; movdf pattern avoids the use of integer registers for FP operations
2426 ;; when optimizing for size.
2427
2428 (define_insn "*movdf_nointeger"
2429 [(set (match_operand:DF 0 "nonimmediate_operand"
2430 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2431 (match_operand:DF 1 "general_operand"
2432 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2433 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2434 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2435 && (reload_in_progress || reload_completed
2436 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2437 || GET_CODE (operands[1]) != CONST_DOUBLE
2438 || memory_operand (operands[0], DFmode))"
2439 {
2440 switch (which_alternative)
2441 {
2442 case 0:
2443 return output_387_reg_move (insn, operands);
2444
2445 case 1:
2446 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2447 return "fstp%z0\t%y0";
2448 else
2449 return "fst%z0\t%y0";
2450
2451 case 2:
2452 return standard_80387_constant_opcode (operands[1]);
2453
2454 case 3:
2455 case 4:
2456 return "#";
2457 case 5:
2458 switch (get_attr_mode (insn))
2459 {
2460 case MODE_V4SF:
2461 return "xorps\t%0, %0";
2462 case MODE_V2DF:
2463 return "xorpd\t%0, %0";
2464 case MODE_TI:
2465 return "pxor\t%0, %0";
2466 default:
2467 gcc_unreachable ();
2468 }
2469 case 6:
2470 case 7:
2471 case 8:
2472 switch (get_attr_mode (insn))
2473 {
2474 case MODE_V4SF:
2475 return "movaps\t{%1, %0|%0, %1}";
2476 case MODE_V2DF:
2477 return "movapd\t{%1, %0|%0, %1}";
2478 case MODE_TI:
2479 return "movdqa\t{%1, %0|%0, %1}";
2480 case MODE_DI:
2481 return "movq\t{%1, %0|%0, %1}";
2482 case MODE_DF:
2483 return "movsd\t{%1, %0|%0, %1}";
2484 case MODE_V1DF:
2485 return "movlpd\t{%1, %0|%0, %1}";
2486 case MODE_V2SF:
2487 return "movlps\t{%1, %0|%0, %1}";
2488 default:
2489 gcc_unreachable ();
2490 }
2491
2492 default:
2493 gcc_unreachable ();
2494 }
2495 }
2496 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2497 (set (attr "mode")
2498 (cond [(eq_attr "alternative" "0,1,2")
2499 (const_string "DF")
2500 (eq_attr "alternative" "3,4")
2501 (const_string "SI")
2502
2503 /* For SSE1, we have many fewer alternatives. */
2504 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2505 (cond [(eq_attr "alternative" "5,6")
2506 (const_string "V4SF")
2507 ]
2508 (const_string "V2SF"))
2509
2510 /* xorps is one byte shorter. */
2511 (eq_attr "alternative" "5")
2512 (cond [(ne (symbol_ref "optimize_size")
2513 (const_int 0))
2514 (const_string "V4SF")
2515 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2516 (const_int 0))
2517 (const_string "TI")
2518 ]
2519 (const_string "V2DF"))
2520
2521 /* For architectures resolving dependencies on
2522 whole SSE registers use APD move to break dependency
2523 chains, otherwise use short move to avoid extra work.
2524
2525 movaps encodes one byte shorter. */
2526 (eq_attr "alternative" "6")
2527 (cond
2528 [(ne (symbol_ref "optimize_size")
2529 (const_int 0))
2530 (const_string "V4SF")
2531 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2532 (const_int 0))
2533 (const_string "V2DF")
2534 ]
2535 (const_string "DF"))
2536 /* For architectures resolving dependencies on register
2537 parts we may avoid extra work to zero out upper part
2538 of register. */
2539 (eq_attr "alternative" "7")
2540 (if_then_else
2541 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2542 (const_int 0))
2543 (const_string "V1DF")
2544 (const_string "DF"))
2545 ]
2546 (const_string "DF")))])
2547
2548 (define_insn "*movdf_integer"
2549 [(set (match_operand:DF 0 "nonimmediate_operand"
2550 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2551 (match_operand:DF 1 "general_operand"
2552 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2553 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2554 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2555 && (reload_in_progress || reload_completed
2556 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2557 || GET_CODE (operands[1]) != CONST_DOUBLE
2558 || memory_operand (operands[0], DFmode))"
2559 {
2560 switch (which_alternative)
2561 {
2562 case 0:
2563 return output_387_reg_move (insn, operands);
2564
2565 case 1:
2566 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2567 return "fstp%z0\t%y0";
2568 else
2569 return "fst%z0\t%y0";
2570
2571 case 2:
2572 return standard_80387_constant_opcode (operands[1]);
2573
2574 case 3:
2575 case 4:
2576 return "#";
2577
2578 case 5:
2579 switch (get_attr_mode (insn))
2580 {
2581 case MODE_V4SF:
2582 return "xorps\t%0, %0";
2583 case MODE_V2DF:
2584 return "xorpd\t%0, %0";
2585 case MODE_TI:
2586 return "pxor\t%0, %0";
2587 default:
2588 gcc_unreachable ();
2589 }
2590 case 6:
2591 case 7:
2592 case 8:
2593 switch (get_attr_mode (insn))
2594 {
2595 case MODE_V4SF:
2596 return "movaps\t{%1, %0|%0, %1}";
2597 case MODE_V2DF:
2598 return "movapd\t{%1, %0|%0, %1}";
2599 case MODE_TI:
2600 return "movdqa\t{%1, %0|%0, %1}";
2601 case MODE_DI:
2602 return "movq\t{%1, %0|%0, %1}";
2603 case MODE_DF:
2604 return "movsd\t{%1, %0|%0, %1}";
2605 case MODE_V1DF:
2606 return "movlpd\t{%1, %0|%0, %1}";
2607 case MODE_V2SF:
2608 return "movlps\t{%1, %0|%0, %1}";
2609 default:
2610 gcc_unreachable ();
2611 }
2612
2613 default:
2614 gcc_unreachable();
2615 }
2616 }
2617 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2618 (set (attr "mode")
2619 (cond [(eq_attr "alternative" "0,1,2")
2620 (const_string "DF")
2621 (eq_attr "alternative" "3,4")
2622 (const_string "SI")
2623
2624 /* For SSE1, we have many fewer alternatives. */
2625 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2626 (cond [(eq_attr "alternative" "5,6")
2627 (const_string "V4SF")
2628 ]
2629 (const_string "V2SF"))
2630
2631 /* xorps is one byte shorter. */
2632 (eq_attr "alternative" "5")
2633 (cond [(ne (symbol_ref "optimize_size")
2634 (const_int 0))
2635 (const_string "V4SF")
2636 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2637 (const_int 0))
2638 (const_string "TI")
2639 ]
2640 (const_string "V2DF"))
2641
2642 /* For architectures resolving dependencies on
2643 whole SSE registers use APD move to break dependency
2644 chains, otherwise use short move to avoid extra work.
2645
2646 movaps encodes one byte shorter. */
2647 (eq_attr "alternative" "6")
2648 (cond
2649 [(ne (symbol_ref "optimize_size")
2650 (const_int 0))
2651 (const_string "V4SF")
2652 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2653 (const_int 0))
2654 (const_string "V2DF")
2655 ]
2656 (const_string "DF"))
2657 /* For architectures resolving dependencies on register
2658 parts we may avoid extra work to zero out upper part
2659 of register. */
2660 (eq_attr "alternative" "7")
2661 (if_then_else
2662 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2663 (const_int 0))
2664 (const_string "V1DF")
2665 (const_string "DF"))
2666 ]
2667 (const_string "DF")))])
2668
2669 (define_split
2670 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2671 (match_operand:DF 1 "general_operand" ""))]
2672 "reload_completed
2673 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2674 && ! (ANY_FP_REG_P (operands[0]) ||
2675 (GET_CODE (operands[0]) == SUBREG
2676 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2677 && ! (ANY_FP_REG_P (operands[1]) ||
2678 (GET_CODE (operands[1]) == SUBREG
2679 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2680 [(const_int 0)]
2681 "ix86_split_long_move (operands); DONE;")
2682
2683 (define_insn "*swapdf"
2684 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2685 (match_operand:DF 1 "fp_register_operand" "+f"))
2686 (set (match_dup 1)
2687 (match_dup 0))]
2688 "reload_completed || TARGET_80387"
2689 {
2690 if (STACK_TOP_P (operands[0]))
2691 return "fxch\t%1";
2692 else
2693 return "fxch\t%0";
2694 }
2695 [(set_attr "type" "fxch")
2696 (set_attr "mode" "DF")])
2697
2698 (define_expand "movxf"
2699 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2700 (match_operand:XF 1 "general_operand" ""))]
2701 ""
2702 "ix86_expand_move (XFmode, operands); DONE;")
2703
2704 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2705 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2706 ;; Pushing using integer instructions is longer except for constants
2707 ;; and direct memory references.
2708 ;; (assuming that any given constant is pushed only once, but this ought to be
2709 ;; handled elsewhere).
2710
2711 (define_insn "*pushxf_nointeger"
2712 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2713 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2714 "optimize_size"
2715 {
2716 /* This insn should be already split before reg-stack. */
2717 gcc_unreachable ();
2718 }
2719 [(set_attr "type" "multi")
2720 (set_attr "unit" "i387,*,*")
2721 (set_attr "mode" "XF,SI,SI")])
2722
2723 (define_insn "*pushxf_integer"
2724 [(set (match_operand:XF 0 "push_operand" "=<,<")
2725 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2726 "!optimize_size"
2727 {
2728 /* This insn should be already split before reg-stack. */
2729 gcc_unreachable ();
2730 }
2731 [(set_attr "type" "multi")
2732 (set_attr "unit" "i387,*")
2733 (set_attr "mode" "XF,SI")])
2734
2735 (define_split
2736 [(set (match_operand 0 "push_operand" "")
2737 (match_operand 1 "general_operand" ""))]
2738 "reload_completed
2739 && (GET_MODE (operands[0]) == XFmode
2740 || GET_MODE (operands[0]) == DFmode)
2741 && !ANY_FP_REG_P (operands[1])"
2742 [(const_int 0)]
2743 "ix86_split_long_move (operands); DONE;")
2744
2745 (define_split
2746 [(set (match_operand:XF 0 "push_operand" "")
2747 (match_operand:XF 1 "any_fp_register_operand" ""))]
2748 "!TARGET_64BIT"
2749 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2750 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2751 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2752
2753 (define_split
2754 [(set (match_operand:XF 0 "push_operand" "")
2755 (match_operand:XF 1 "any_fp_register_operand" ""))]
2756 "TARGET_64BIT"
2757 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2758 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2759 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2760
2761 ;; Do not use integer registers when optimizing for size
2762 (define_insn "*movxf_nointeger"
2763 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2764 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2765 "optimize_size
2766 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2767 && (reload_in_progress || reload_completed
2768 || GET_CODE (operands[1]) != CONST_DOUBLE
2769 || memory_operand (operands[0], XFmode))"
2770 {
2771 switch (which_alternative)
2772 {
2773 case 0:
2774 return output_387_reg_move (insn, operands);
2775
2776 case 1:
2777 /* There is no non-popping store to memory for XFmode. So if
2778 we need one, follow the store with a load. */
2779 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2780 return "fstp%z0\t%y0\;fld%z0\t%y0";
2781 else
2782 return "fstp%z0\t%y0";
2783
2784 case 2:
2785 return standard_80387_constant_opcode (operands[1]);
2786
2787 case 3: case 4:
2788 return "#";
2789 default:
2790 gcc_unreachable ();
2791 }
2792 }
2793 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2794 (set_attr "mode" "XF,XF,XF,SI,SI")])
2795
2796 (define_insn "*movxf_integer"
2797 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2798 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2799 "!optimize_size
2800 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2801 && (reload_in_progress || reload_completed
2802 || GET_CODE (operands[1]) != CONST_DOUBLE
2803 || memory_operand (operands[0], XFmode))"
2804 {
2805 switch (which_alternative)
2806 {
2807 case 0:
2808 return output_387_reg_move (insn, operands);
2809
2810 case 1:
2811 /* There is no non-popping store to memory for XFmode. So if
2812 we need one, follow the store with a load. */
2813 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2814 return "fstp%z0\t%y0\;fld%z0\t%y0";
2815 else
2816 return "fstp%z0\t%y0";
2817
2818 case 2:
2819 return standard_80387_constant_opcode (operands[1]);
2820
2821 case 3: case 4:
2822 return "#";
2823
2824 default:
2825 gcc_unreachable ();
2826 }
2827 }
2828 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2829 (set_attr "mode" "XF,XF,XF,SI,SI")])
2830
2831 (define_split
2832 [(set (match_operand 0 "nonimmediate_operand" "")
2833 (match_operand 1 "general_operand" ""))]
2834 "reload_completed
2835 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2836 && GET_MODE (operands[0]) == XFmode
2837 && ! (ANY_FP_REG_P (operands[0]) ||
2838 (GET_CODE (operands[0]) == SUBREG
2839 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2840 && ! (ANY_FP_REG_P (operands[1]) ||
2841 (GET_CODE (operands[1]) == SUBREG
2842 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2843 [(const_int 0)]
2844 "ix86_split_long_move (operands); DONE;")
2845
2846 (define_split
2847 [(set (match_operand 0 "register_operand" "")
2848 (match_operand 1 "memory_operand" ""))]
2849 "reload_completed
2850 && GET_CODE (operands[1]) == MEM
2851 && (GET_MODE (operands[0]) == XFmode
2852 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2853 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2854 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2855 [(set (match_dup 0) (match_dup 1))]
2856 {
2857 rtx c = get_pool_constant (XEXP (operands[1], 0));
2858 rtx r = operands[0];
2859
2860 if (GET_CODE (r) == SUBREG)
2861 r = SUBREG_REG (r);
2862
2863 if (SSE_REG_P (r))
2864 {
2865 if (!standard_sse_constant_p (c))
2866 FAIL;
2867 }
2868 else if (FP_REG_P (r))
2869 {
2870 if (!standard_80387_constant_p (c))
2871 FAIL;
2872 }
2873 else if (MMX_REG_P (r))
2874 FAIL;
2875
2876 operands[1] = c;
2877 })
2878
2879 (define_insn "swapxf"
2880 [(set (match_operand:XF 0 "register_operand" "+f")
2881 (match_operand:XF 1 "register_operand" "+f"))
2882 (set (match_dup 1)
2883 (match_dup 0))]
2884 "TARGET_80387"
2885 {
2886 if (STACK_TOP_P (operands[0]))
2887 return "fxch\t%1";
2888 else
2889 return "fxch\t%0";
2890 }
2891 [(set_attr "type" "fxch")
2892 (set_attr "mode" "XF")])
2893
2894 (define_expand "movtf"
2895 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2896 (match_operand:TF 1 "nonimmediate_operand" ""))]
2897 "TARGET_64BIT"
2898 {
2899 ix86_expand_move (TFmode, operands);
2900 DONE;
2901 })
2902
2903 (define_insn "*movtf_internal"
2904 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2905 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2906 "TARGET_64BIT
2907 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2908 {
2909 switch (which_alternative)
2910 {
2911 case 0:
2912 case 1:
2913 return "#";
2914 case 2:
2915 if (get_attr_mode (insn) == MODE_V4SF)
2916 return "xorps\t%0, %0";
2917 else
2918 return "pxor\t%0, %0";
2919 case 3:
2920 case 4:
2921 if (get_attr_mode (insn) == MODE_V4SF)
2922 return "movaps\t{%1, %0|%0, %1}";
2923 else
2924 return "movdqa\t{%1, %0|%0, %1}";
2925 default:
2926 gcc_unreachable ();
2927 }
2928 }
2929 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2930 (set (attr "mode")
2931 (cond [(eq_attr "alternative" "2,3")
2932 (if_then_else
2933 (ne (symbol_ref "optimize_size")
2934 (const_int 0))
2935 (const_string "V4SF")
2936 (const_string "TI"))
2937 (eq_attr "alternative" "4")
2938 (if_then_else
2939 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2940 (const_int 0))
2941 (ne (symbol_ref "optimize_size")
2942 (const_int 0)))
2943 (const_string "V4SF")
2944 (const_string "TI"))]
2945 (const_string "DI")))])
2946
2947 (define_split
2948 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2949 (match_operand:TF 1 "general_operand" ""))]
2950 "reload_completed && !SSE_REG_P (operands[0])
2951 && !SSE_REG_P (operands[1])"
2952 [(const_int 0)]
2953 "ix86_split_long_move (operands); DONE;")
2954 \f
2955 ;; Zero extension instructions
2956
2957 (define_expand "zero_extendhisi2"
2958 [(set (match_operand:SI 0 "register_operand" "")
2959 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2960 ""
2961 {
2962 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2963 {
2964 operands[1] = force_reg (HImode, operands[1]);
2965 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2966 DONE;
2967 }
2968 })
2969
2970 (define_insn "zero_extendhisi2_and"
2971 [(set (match_operand:SI 0 "register_operand" "=r")
2972 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2973 (clobber (reg:CC FLAGS_REG))]
2974 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2975 "#"
2976 [(set_attr "type" "alu1")
2977 (set_attr "mode" "SI")])
2978
2979 (define_split
2980 [(set (match_operand:SI 0 "register_operand" "")
2981 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2982 (clobber (reg:CC FLAGS_REG))]
2983 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2984 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2985 (clobber (reg:CC FLAGS_REG))])]
2986 "")
2987
2988 (define_insn "*zero_extendhisi2_movzwl"
2989 [(set (match_operand:SI 0 "register_operand" "=r")
2990 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2991 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2992 "movz{wl|x}\t{%1, %0|%0, %1}"
2993 [(set_attr "type" "imovx")
2994 (set_attr "mode" "SI")])
2995
2996 (define_expand "zero_extendqihi2"
2997 [(parallel
2998 [(set (match_operand:HI 0 "register_operand" "")
2999 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3000 (clobber (reg:CC FLAGS_REG))])]
3001 ""
3002 "")
3003
3004 (define_insn "*zero_extendqihi2_and"
3005 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3006 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3007 (clobber (reg:CC FLAGS_REG))]
3008 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3009 "#"
3010 [(set_attr "type" "alu1")
3011 (set_attr "mode" "HI")])
3012
3013 (define_insn "*zero_extendqihi2_movzbw_and"
3014 [(set (match_operand:HI 0 "register_operand" "=r,r")
3015 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3016 (clobber (reg:CC FLAGS_REG))]
3017 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3018 "#"
3019 [(set_attr "type" "imovx,alu1")
3020 (set_attr "mode" "HI")])
3021
3022 (define_insn "*zero_extendqihi2_movzbw"
3023 [(set (match_operand:HI 0 "register_operand" "=r")
3024 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3025 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3026 "movz{bw|x}\t{%1, %0|%0, %1}"
3027 [(set_attr "type" "imovx")
3028 (set_attr "mode" "HI")])
3029
3030 ;; For the movzbw case strip only the clobber
3031 (define_split
3032 [(set (match_operand:HI 0 "register_operand" "")
3033 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3034 (clobber (reg:CC FLAGS_REG))]
3035 "reload_completed
3036 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3037 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3038 [(set (match_operand:HI 0 "register_operand" "")
3039 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3040
3041 ;; When source and destination does not overlap, clear destination
3042 ;; first and then do the movb
3043 (define_split
3044 [(set (match_operand:HI 0 "register_operand" "")
3045 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3046 (clobber (reg:CC FLAGS_REG))]
3047 "reload_completed
3048 && ANY_QI_REG_P (operands[0])
3049 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3050 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3051 [(set (match_dup 0) (const_int 0))
3052 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3053 "operands[2] = gen_lowpart (QImode, operands[0]);")
3054
3055 ;; Rest is handled by single and.
3056 (define_split
3057 [(set (match_operand:HI 0 "register_operand" "")
3058 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3059 (clobber (reg:CC FLAGS_REG))]
3060 "reload_completed
3061 && true_regnum (operands[0]) == true_regnum (operands[1])"
3062 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3063 (clobber (reg:CC FLAGS_REG))])]
3064 "")
3065
3066 (define_expand "zero_extendqisi2"
3067 [(parallel
3068 [(set (match_operand:SI 0 "register_operand" "")
3069 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3070 (clobber (reg:CC FLAGS_REG))])]
3071 ""
3072 "")
3073
3074 (define_insn "*zero_extendqisi2_and"
3075 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3076 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3077 (clobber (reg:CC FLAGS_REG))]
3078 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3079 "#"
3080 [(set_attr "type" "alu1")
3081 (set_attr "mode" "SI")])
3082
3083 (define_insn "*zero_extendqisi2_movzbw_and"
3084 [(set (match_operand:SI 0 "register_operand" "=r,r")
3085 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3086 (clobber (reg:CC FLAGS_REG))]
3087 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3088 "#"
3089 [(set_attr "type" "imovx,alu1")
3090 (set_attr "mode" "SI")])
3091
3092 (define_insn "*zero_extendqisi2_movzbw"
3093 [(set (match_operand:SI 0 "register_operand" "=r")
3094 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3095 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3096 "movz{bl|x}\t{%1, %0|%0, %1}"
3097 [(set_attr "type" "imovx")
3098 (set_attr "mode" "SI")])
3099
3100 ;; For the movzbl case strip only the clobber
3101 (define_split
3102 [(set (match_operand:SI 0 "register_operand" "")
3103 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3104 (clobber (reg:CC FLAGS_REG))]
3105 "reload_completed
3106 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3107 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3108 [(set (match_dup 0)
3109 (zero_extend:SI (match_dup 1)))])
3110
3111 ;; When source and destination does not overlap, clear destination
3112 ;; first and then do the movb
3113 (define_split
3114 [(set (match_operand:SI 0 "register_operand" "")
3115 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3116 (clobber (reg:CC FLAGS_REG))]
3117 "reload_completed
3118 && ANY_QI_REG_P (operands[0])
3119 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3120 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3121 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3122 [(set (match_dup 0) (const_int 0))
3123 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3124 "operands[2] = gen_lowpart (QImode, operands[0]);")
3125
3126 ;; Rest is handled by single and.
3127 (define_split
3128 [(set (match_operand:SI 0 "register_operand" "")
3129 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3130 (clobber (reg:CC FLAGS_REG))]
3131 "reload_completed
3132 && true_regnum (operands[0]) == true_regnum (operands[1])"
3133 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3134 (clobber (reg:CC FLAGS_REG))])]
3135 "")
3136
3137 ;; %%% Kill me once multi-word ops are sane.
3138 (define_expand "zero_extendsidi2"
3139 [(set (match_operand:DI 0 "register_operand" "=r")
3140 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3141 ""
3142 "if (!TARGET_64BIT)
3143 {
3144 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3145 DONE;
3146 }
3147 ")
3148
3149 (define_insn "zero_extendsidi2_32"
3150 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3151 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3152 (clobber (reg:CC FLAGS_REG))]
3153 "!TARGET_64BIT"
3154 "@
3155 #
3156 #
3157 #
3158 movd\t{%1, %0|%0, %1}
3159 movd\t{%1, %0|%0, %1}"
3160 [(set_attr "mode" "SI,SI,SI,DI,TI")
3161 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3162
3163 (define_insn "zero_extendsidi2_rex64"
3164 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3165 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3166 "TARGET_64BIT"
3167 "@
3168 mov\t{%k1, %k0|%k0, %k1}
3169 #
3170 movd\t{%1, %0|%0, %1}
3171 movd\t{%1, %0|%0, %1}"
3172 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3173 (set_attr "mode" "SI,DI,SI,SI")])
3174
3175 (define_split
3176 [(set (match_operand:DI 0 "memory_operand" "")
3177 (zero_extend:DI (match_dup 0)))]
3178 "TARGET_64BIT"
3179 [(set (match_dup 4) (const_int 0))]
3180 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3181
3182 (define_split
3183 [(set (match_operand:DI 0 "register_operand" "")
3184 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3185 (clobber (reg:CC FLAGS_REG))]
3186 "!TARGET_64BIT && reload_completed
3187 && true_regnum (operands[0]) == true_regnum (operands[1])"
3188 [(set (match_dup 4) (const_int 0))]
3189 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3190
3191 (define_split
3192 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3193 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3194 (clobber (reg:CC FLAGS_REG))]
3195 "!TARGET_64BIT && reload_completed
3196 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3197 [(set (match_dup 3) (match_dup 1))
3198 (set (match_dup 4) (const_int 0))]
3199 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3200
3201 (define_insn "zero_extendhidi2"
3202 [(set (match_operand:DI 0 "register_operand" "=r")
3203 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3204 "TARGET_64BIT"
3205 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3206 [(set_attr "type" "imovx")
3207 (set_attr "mode" "DI")])
3208
3209 (define_insn "zero_extendqidi2"
3210 [(set (match_operand:DI 0 "register_operand" "=r")
3211 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3212 "TARGET_64BIT"
3213 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3214 [(set_attr "type" "imovx")
3215 (set_attr "mode" "DI")])
3216 \f
3217 ;; Sign extension instructions
3218
3219 (define_expand "extendsidi2"
3220 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3221 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3222 (clobber (reg:CC FLAGS_REG))
3223 (clobber (match_scratch:SI 2 ""))])]
3224 ""
3225 {
3226 if (TARGET_64BIT)
3227 {
3228 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3229 DONE;
3230 }
3231 })
3232
3233 (define_insn "*extendsidi2_1"
3234 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3235 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3236 (clobber (reg:CC FLAGS_REG))
3237 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3238 "!TARGET_64BIT"
3239 "#")
3240
3241 (define_insn "extendsidi2_rex64"
3242 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3243 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3244 "TARGET_64BIT"
3245 "@
3246 {cltq|cdqe}
3247 movs{lq|x}\t{%1,%0|%0, %1}"
3248 [(set_attr "type" "imovx")
3249 (set_attr "mode" "DI")
3250 (set_attr "prefix_0f" "0")
3251 (set_attr "modrm" "0,1")])
3252
3253 (define_insn "extendhidi2"
3254 [(set (match_operand:DI 0 "register_operand" "=r")
3255 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3256 "TARGET_64BIT"
3257 "movs{wq|x}\t{%1,%0|%0, %1}"
3258 [(set_attr "type" "imovx")
3259 (set_attr "mode" "DI")])
3260
3261 (define_insn "extendqidi2"
3262 [(set (match_operand:DI 0 "register_operand" "=r")
3263 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3264 "TARGET_64BIT"
3265 "movs{bq|x}\t{%1,%0|%0, %1}"
3266 [(set_attr "type" "imovx")
3267 (set_attr "mode" "DI")])
3268
3269 ;; Extend to memory case when source register does die.
3270 (define_split
3271 [(set (match_operand:DI 0 "memory_operand" "")
3272 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3273 (clobber (reg:CC FLAGS_REG))
3274 (clobber (match_operand:SI 2 "register_operand" ""))]
3275 "(reload_completed
3276 && dead_or_set_p (insn, operands[1])
3277 && !reg_mentioned_p (operands[1], operands[0]))"
3278 [(set (match_dup 3) (match_dup 1))
3279 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3280 (clobber (reg:CC FLAGS_REG))])
3281 (set (match_dup 4) (match_dup 1))]
3282 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3283
3284 ;; Extend to memory case when source register does not die.
3285 (define_split
3286 [(set (match_operand:DI 0 "memory_operand" "")
3287 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3288 (clobber (reg:CC FLAGS_REG))
3289 (clobber (match_operand:SI 2 "register_operand" ""))]
3290 "reload_completed"
3291 [(const_int 0)]
3292 {
3293 split_di (&operands[0], 1, &operands[3], &operands[4]);
3294
3295 emit_move_insn (operands[3], operands[1]);
3296
3297 /* Generate a cltd if possible and doing so it profitable. */
3298 if (true_regnum (operands[1]) == 0
3299 && true_regnum (operands[2]) == 1
3300 && (optimize_size || TARGET_USE_CLTD))
3301 {
3302 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3303 }
3304 else
3305 {
3306 emit_move_insn (operands[2], operands[1]);
3307 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3308 }
3309 emit_move_insn (operands[4], operands[2]);
3310 DONE;
3311 })
3312
3313 ;; Extend to register case. Optimize case where source and destination
3314 ;; registers match and cases where we can use cltd.
3315 (define_split
3316 [(set (match_operand:DI 0 "register_operand" "")
3317 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3318 (clobber (reg:CC FLAGS_REG))
3319 (clobber (match_scratch:SI 2 ""))]
3320 "reload_completed"
3321 [(const_int 0)]
3322 {
3323 split_di (&operands[0], 1, &operands[3], &operands[4]);
3324
3325 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3326 emit_move_insn (operands[3], operands[1]);
3327
3328 /* Generate a cltd if possible and doing so it profitable. */
3329 if (true_regnum (operands[3]) == 0
3330 && (optimize_size || TARGET_USE_CLTD))
3331 {
3332 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3333 DONE;
3334 }
3335
3336 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3337 emit_move_insn (operands[4], operands[1]);
3338
3339 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3340 DONE;
3341 })
3342
3343 (define_insn "extendhisi2"
3344 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3345 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3346 ""
3347 {
3348 switch (get_attr_prefix_0f (insn))
3349 {
3350 case 0:
3351 return "{cwtl|cwde}";
3352 default:
3353 return "movs{wl|x}\t{%1,%0|%0, %1}";
3354 }
3355 }
3356 [(set_attr "type" "imovx")
3357 (set_attr "mode" "SI")
3358 (set (attr "prefix_0f")
3359 ;; movsx is short decodable while cwtl is vector decoded.
3360 (if_then_else (and (eq_attr "cpu" "!k6")
3361 (eq_attr "alternative" "0"))
3362 (const_string "0")
3363 (const_string "1")))
3364 (set (attr "modrm")
3365 (if_then_else (eq_attr "prefix_0f" "0")
3366 (const_string "0")
3367 (const_string "1")))])
3368
3369 (define_insn "*extendhisi2_zext"
3370 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3371 (zero_extend:DI
3372 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3373 "TARGET_64BIT"
3374 {
3375 switch (get_attr_prefix_0f (insn))
3376 {
3377 case 0:
3378 return "{cwtl|cwde}";
3379 default:
3380 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3381 }
3382 }
3383 [(set_attr "type" "imovx")
3384 (set_attr "mode" "SI")
3385 (set (attr "prefix_0f")
3386 ;; movsx is short decodable while cwtl is vector decoded.
3387 (if_then_else (and (eq_attr "cpu" "!k6")
3388 (eq_attr "alternative" "0"))
3389 (const_string "0")
3390 (const_string "1")))
3391 (set (attr "modrm")
3392 (if_then_else (eq_attr "prefix_0f" "0")
3393 (const_string "0")
3394 (const_string "1")))])
3395
3396 (define_insn "extendqihi2"
3397 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3398 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3399 ""
3400 {
3401 switch (get_attr_prefix_0f (insn))
3402 {
3403 case 0:
3404 return "{cbtw|cbw}";
3405 default:
3406 return "movs{bw|x}\t{%1,%0|%0, %1}";
3407 }
3408 }
3409 [(set_attr "type" "imovx")
3410 (set_attr "mode" "HI")
3411 (set (attr "prefix_0f")
3412 ;; movsx is short decodable while cwtl is vector decoded.
3413 (if_then_else (and (eq_attr "cpu" "!k6")
3414 (eq_attr "alternative" "0"))
3415 (const_string "0")
3416 (const_string "1")))
3417 (set (attr "modrm")
3418 (if_then_else (eq_attr "prefix_0f" "0")
3419 (const_string "0")
3420 (const_string "1")))])
3421
3422 (define_insn "extendqisi2"
3423 [(set (match_operand:SI 0 "register_operand" "=r")
3424 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3425 ""
3426 "movs{bl|x}\t{%1,%0|%0, %1}"
3427 [(set_attr "type" "imovx")
3428 (set_attr "mode" "SI")])
3429
3430 (define_insn "*extendqisi2_zext"
3431 [(set (match_operand:DI 0 "register_operand" "=r")
3432 (zero_extend:DI
3433 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3434 "TARGET_64BIT"
3435 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3436 [(set_attr "type" "imovx")
3437 (set_attr "mode" "SI")])
3438 \f
3439 ;; Conversions between float and double.
3440
3441 ;; These are all no-ops in the model used for the 80387. So just
3442 ;; emit moves.
3443
3444 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3445 (define_insn "*dummy_extendsfdf2"
3446 [(set (match_operand:DF 0 "push_operand" "=<")
3447 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3448 "0"
3449 "#")
3450
3451 (define_split
3452 [(set (match_operand:DF 0 "push_operand" "")
3453 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3454 "!TARGET_64BIT"
3455 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3456 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3457
3458 (define_split
3459 [(set (match_operand:DF 0 "push_operand" "")
3460 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3461 "TARGET_64BIT"
3462 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3463 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3464
3465 (define_insn "*dummy_extendsfxf2"
3466 [(set (match_operand:XF 0 "push_operand" "=<")
3467 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3468 "0"
3469 "#")
3470
3471 (define_split
3472 [(set (match_operand:XF 0 "push_operand" "")
3473 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3474 ""
3475 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3476 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3477 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3478
3479 (define_split
3480 [(set (match_operand:XF 0 "push_operand" "")
3481 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3482 "TARGET_64BIT"
3483 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3484 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3485 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3486
3487 (define_split
3488 [(set (match_operand:XF 0 "push_operand" "")
3489 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3490 ""
3491 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3492 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3493 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3494
3495 (define_split
3496 [(set (match_operand:XF 0 "push_operand" "")
3497 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3498 "TARGET_64BIT"
3499 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3500 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3501 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3502
3503 (define_expand "extendsfdf2"
3504 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3505 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3506 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3507 {
3508 /* ??? Needed for compress_float_constant since all fp constants
3509 are LEGITIMATE_CONSTANT_P. */
3510 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3511 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3512 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3513 operands[1] = force_reg (SFmode, operands[1]);
3514 })
3515
3516 (define_insn "*extendsfdf2_mixed"
3517 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3518 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3519 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3520 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3521 {
3522 switch (which_alternative)
3523 {
3524 case 0:
3525 return output_387_reg_move (insn, operands);
3526
3527 case 1:
3528 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3529 return "fstp%z0\t%y0";
3530 else
3531 return "fst%z0\t%y0";
3532
3533 case 2:
3534 return "cvtss2sd\t{%1, %0|%0, %1}";
3535
3536 default:
3537 gcc_unreachable ();
3538 }
3539 }
3540 [(set_attr "type" "fmov,fmov,ssecvt")
3541 (set_attr "mode" "SF,XF,DF")])
3542
3543 (define_insn "*extendsfdf2_sse"
3544 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3545 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3546 "TARGET_SSE2 && TARGET_SSE_MATH
3547 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3548 "cvtss2sd\t{%1, %0|%0, %1}"
3549 [(set_attr "type" "ssecvt")
3550 (set_attr "mode" "DF")])
3551
3552 (define_insn "*extendsfdf2_i387"
3553 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3554 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3555 "TARGET_80387
3556 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3557 {
3558 switch (which_alternative)
3559 {
3560 case 0:
3561 return output_387_reg_move (insn, operands);
3562
3563 case 1:
3564 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3565 return "fstp%z0\t%y0";
3566 else
3567 return "fst%z0\t%y0";
3568
3569 default:
3570 gcc_unreachable ();
3571 }
3572 }
3573 [(set_attr "type" "fmov")
3574 (set_attr "mode" "SF,XF")])
3575
3576 (define_expand "extendsfxf2"
3577 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3578 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3579 "TARGET_80387"
3580 {
3581 /* ??? Needed for compress_float_constant since all fp constants
3582 are LEGITIMATE_CONSTANT_P. */
3583 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3584 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3585 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3586 operands[1] = force_reg (SFmode, operands[1]);
3587 })
3588
3589 (define_insn "*extendsfxf2_i387"
3590 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3591 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3592 "TARGET_80387
3593 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3594 {
3595 switch (which_alternative)
3596 {
3597 case 0:
3598 return output_387_reg_move (insn, operands);
3599
3600 case 1:
3601 /* There is no non-popping store to memory for XFmode. So if
3602 we need one, follow the store with a load. */
3603 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3604 return "fstp%z0\t%y0";
3605 else
3606 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3607
3608 default:
3609 gcc_unreachable ();
3610 }
3611 }
3612 [(set_attr "type" "fmov")
3613 (set_attr "mode" "SF,XF")])
3614
3615 (define_expand "extenddfxf2"
3616 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3617 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3618 "TARGET_80387"
3619 {
3620 /* ??? Needed for compress_float_constant since all fp constants
3621 are LEGITIMATE_CONSTANT_P. */
3622 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3623 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3624 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3625 operands[1] = force_reg (DFmode, operands[1]);
3626 })
3627
3628 (define_insn "*extenddfxf2_i387"
3629 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3630 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3631 "TARGET_80387
3632 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3633 {
3634 switch (which_alternative)
3635 {
3636 case 0:
3637 return output_387_reg_move (insn, operands);
3638
3639 case 1:
3640 /* There is no non-popping store to memory for XFmode. So if
3641 we need one, follow the store with a load. */
3642 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3643 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3644 else
3645 return "fstp%z0\t%y0";
3646
3647 default:
3648 gcc_unreachable ();
3649 }
3650 }
3651 [(set_attr "type" "fmov")
3652 (set_attr "mode" "DF,XF")])
3653
3654 ;; %%% This seems bad bad news.
3655 ;; This cannot output into an f-reg because there is no way to be sure
3656 ;; of truncating in that case. Otherwise this is just like a simple move
3657 ;; insn. So we pretend we can output to a reg in order to get better
3658 ;; register preferencing, but we really use a stack slot.
3659
3660 ;; Conversion from DFmode to SFmode.
3661
3662 (define_expand "truncdfsf2"
3663 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3664 (float_truncate:SF
3665 (match_operand:DF 1 "nonimmediate_operand" "")))]
3666 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3667 {
3668 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3669 operands[1] = force_reg (DFmode, operands[1]);
3670
3671 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3672 ;
3673 else if (flag_unsafe_math_optimizations)
3674 ;
3675 else
3676 {
3677 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3678 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3679 DONE;
3680 }
3681 })
3682
3683 (define_expand "truncdfsf2_with_temp"
3684 [(parallel [(set (match_operand:SF 0 "" "")
3685 (float_truncate:SF (match_operand:DF 1 "" "")))
3686 (clobber (match_operand:SF 2 "" ""))])]
3687 "")
3688
3689 (define_insn "*truncdfsf_fast_mixed"
3690 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3691 (float_truncate:SF
3692 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3693 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3694 {
3695 switch (which_alternative)
3696 {
3697 case 0:
3698 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3699 return "fstp%z0\t%y0";
3700 else
3701 return "fst%z0\t%y0";
3702 case 1:
3703 return output_387_reg_move (insn, operands);
3704 case 2:
3705 return "cvtsd2ss\t{%1, %0|%0, %1}";
3706 default:
3707 gcc_unreachable ();
3708 }
3709 }
3710 [(set_attr "type" "fmov,fmov,ssecvt")
3711 (set_attr "mode" "SF")])
3712
3713 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3714 ;; because nothing we do here is unsafe.
3715 (define_insn "*truncdfsf_fast_sse"
3716 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3717 (float_truncate:SF
3718 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3719 "TARGET_SSE2 && TARGET_SSE_MATH"
3720 "cvtsd2ss\t{%1, %0|%0, %1}"
3721 [(set_attr "type" "ssecvt")
3722 (set_attr "mode" "SF")])
3723
3724 (define_insn "*truncdfsf_fast_i387"
3725 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3726 (float_truncate:SF
3727 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3728 "TARGET_80387 && flag_unsafe_math_optimizations"
3729 "* return output_387_reg_move (insn, operands);"
3730 [(set_attr "type" "fmov")
3731 (set_attr "mode" "SF")])
3732
3733 (define_insn "*truncdfsf_mixed"
3734 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3735 (float_truncate:SF
3736 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3737 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3738 "TARGET_MIX_SSE_I387"
3739 {
3740 switch (which_alternative)
3741 {
3742 case 0:
3743 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3744 return "fstp%z0\t%y0";
3745 else
3746 return "fst%z0\t%y0";
3747 case 1:
3748 return "#";
3749 case 2:
3750 return "cvtsd2ss\t{%1, %0|%0, %1}";
3751 default:
3752 gcc_unreachable ();
3753 }
3754 }
3755 [(set_attr "type" "fmov,multi,ssecvt")
3756 (set_attr "unit" "*,i387,*")
3757 (set_attr "mode" "SF")])
3758
3759 (define_insn "*truncdfsf_i387"
3760 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3761 (float_truncate:SF
3762 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3763 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3764 "TARGET_80387"
3765 {
3766 switch (which_alternative)
3767 {
3768 case 0:
3769 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3770 return "fstp%z0\t%y0";
3771 else
3772 return "fst%z0\t%y0";
3773 case 1:
3774 return "#";
3775 default:
3776 gcc_unreachable ();
3777 }
3778 }
3779 [(set_attr "type" "fmov,multi")
3780 (set_attr "unit" "*,i387")
3781 (set_attr "mode" "SF")])
3782
3783 (define_insn "*truncdfsf2_i387_1"
3784 [(set (match_operand:SF 0 "memory_operand" "=m")
3785 (float_truncate:SF
3786 (match_operand:DF 1 "register_operand" "f")))]
3787 "TARGET_80387
3788 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3789 && !TARGET_MIX_SSE_I387"
3790 {
3791 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3792 return "fstp%z0\t%y0";
3793 else
3794 return "fst%z0\t%y0";
3795 }
3796 [(set_attr "type" "fmov")
3797 (set_attr "mode" "SF")])
3798
3799 (define_split
3800 [(set (match_operand:SF 0 "register_operand" "")
3801 (float_truncate:SF
3802 (match_operand:DF 1 "fp_register_operand" "")))
3803 (clobber (match_operand 2 "" ""))]
3804 "reload_completed"
3805 [(set (match_dup 2) (match_dup 1))
3806 (set (match_dup 0) (match_dup 2))]
3807 {
3808 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3809 })
3810
3811 ;; Conversion from XFmode to SFmode.
3812
3813 (define_expand "truncxfsf2"
3814 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3815 (float_truncate:SF
3816 (match_operand:XF 1 "register_operand" "")))
3817 (clobber (match_dup 2))])]
3818 "TARGET_80387"
3819 {
3820 if (flag_unsafe_math_optimizations)
3821 {
3822 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3823 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3824 if (reg != operands[0])
3825 emit_move_insn (operands[0], reg);
3826 DONE;
3827 }
3828 else
3829 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3830 })
3831
3832 (define_insn "*truncxfsf2_mixed"
3833 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3834 (float_truncate:SF
3835 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3836 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3837 "TARGET_MIX_SSE_I387"
3838 {
3839 gcc_assert (!which_alternative);
3840 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3841 return "fstp%z0\t%y0";
3842 else
3843 return "fst%z0\t%y0";
3844 }
3845 [(set_attr "type" "fmov,multi,multi,multi")
3846 (set_attr "unit" "*,i387,i387,i387")
3847 (set_attr "mode" "SF")])
3848
3849 (define_insn "truncxfsf2_i387_noop"
3850 [(set (match_operand:SF 0 "register_operand" "=f")
3851 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3852 "TARGET_80387 && flag_unsafe_math_optimizations"
3853 {
3854 return output_387_reg_move (insn, operands);
3855 }
3856 [(set_attr "type" "fmov")
3857 (set_attr "mode" "SF")])
3858
3859 (define_insn "*truncxfsf2_i387"
3860 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3861 (float_truncate:SF
3862 (match_operand:XF 1 "register_operand" "f,f,f")))
3863 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3864 "TARGET_80387"
3865 {
3866 gcc_assert (!which_alternative);
3867 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3868 return "fstp%z0\t%y0";
3869 else
3870 return "fst%z0\t%y0";
3871 }
3872 [(set_attr "type" "fmov,multi,multi")
3873 (set_attr "unit" "*,i387,i387")
3874 (set_attr "mode" "SF")])
3875
3876 (define_insn "*truncxfsf2_i387_1"
3877 [(set (match_operand:SF 0 "memory_operand" "=m")
3878 (float_truncate:SF
3879 (match_operand:XF 1 "register_operand" "f")))]
3880 "TARGET_80387"
3881 {
3882 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3883 return "fstp%z0\t%y0";
3884 else
3885 return "fst%z0\t%y0";
3886 }
3887 [(set_attr "type" "fmov")
3888 (set_attr "mode" "SF")])
3889
3890 (define_split
3891 [(set (match_operand:SF 0 "register_operand" "")
3892 (float_truncate:SF
3893 (match_operand:XF 1 "register_operand" "")))
3894 (clobber (match_operand:SF 2 "memory_operand" ""))]
3895 "TARGET_80387 && reload_completed"
3896 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3897 (set (match_dup 0) (match_dup 2))]
3898 "")
3899
3900 (define_split
3901 [(set (match_operand:SF 0 "memory_operand" "")
3902 (float_truncate:SF
3903 (match_operand:XF 1 "register_operand" "")))
3904 (clobber (match_operand:SF 2 "memory_operand" ""))]
3905 "TARGET_80387"
3906 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3907 "")
3908
3909 ;; Conversion from XFmode to DFmode.
3910
3911 (define_expand "truncxfdf2"
3912 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3913 (float_truncate:DF
3914 (match_operand:XF 1 "register_operand" "")))
3915 (clobber (match_dup 2))])]
3916 "TARGET_80387"
3917 {
3918 if (flag_unsafe_math_optimizations)
3919 {
3920 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3921 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3922 if (reg != operands[0])
3923 emit_move_insn (operands[0], reg);
3924 DONE;
3925 }
3926 else
3927 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3928 })
3929
3930 (define_insn "*truncxfdf2_mixed"
3931 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3932 (float_truncate:DF
3933 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3934 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3935 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3936 {
3937 gcc_assert (!which_alternative);
3938 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3939 return "fstp%z0\t%y0";
3940 else
3941 return "fst%z0\t%y0";
3942 }
3943 [(set_attr "type" "fmov,multi,multi,multi")
3944 (set_attr "unit" "*,i387,i387,i387")
3945 (set_attr "mode" "DF")])
3946
3947 (define_insn "truncxfdf2_i387_noop"
3948 [(set (match_operand:DF 0 "register_operand" "=f")
3949 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3950 "TARGET_80387 && flag_unsafe_math_optimizations"
3951 {
3952 return output_387_reg_move (insn, operands);
3953 }
3954 [(set_attr "type" "fmov")
3955 (set_attr "mode" "DF")])
3956
3957 (define_insn "*truncxfdf2_i387"
3958 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3959 (float_truncate:DF
3960 (match_operand:XF 1 "register_operand" "f,f,f")))
3961 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3962 "TARGET_80387"
3963 {
3964 gcc_assert (!which_alternative);
3965 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3966 return "fstp%z0\t%y0";
3967 else
3968 return "fst%z0\t%y0";
3969 }
3970 [(set_attr "type" "fmov,multi,multi")
3971 (set_attr "unit" "*,i387,i387")
3972 (set_attr "mode" "DF")])
3973
3974 (define_insn "*truncxfdf2_i387_1"
3975 [(set (match_operand:DF 0 "memory_operand" "=m")
3976 (float_truncate:DF
3977 (match_operand:XF 1 "register_operand" "f")))]
3978 "TARGET_80387"
3979 {
3980 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3981 return "fstp%z0\t%y0";
3982 else
3983 return "fst%z0\t%y0";
3984 }
3985 [(set_attr "type" "fmov")
3986 (set_attr "mode" "DF")])
3987
3988 (define_split
3989 [(set (match_operand:DF 0 "register_operand" "")
3990 (float_truncate:DF
3991 (match_operand:XF 1 "register_operand" "")))
3992 (clobber (match_operand:DF 2 "memory_operand" ""))]
3993 "TARGET_80387 && reload_completed"
3994 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3995 (set (match_dup 0) (match_dup 2))]
3996 "")
3997
3998 (define_split
3999 [(set (match_operand:DF 0 "memory_operand" "")
4000 (float_truncate:DF
4001 (match_operand:XF 1 "register_operand" "")))
4002 (clobber (match_operand:DF 2 "memory_operand" ""))]
4003 "TARGET_80387"
4004 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4005 "")
4006 \f
4007 ;; Signed conversion to DImode.
4008
4009 (define_expand "fix_truncxfdi2"
4010 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4011 (fix:DI (match_operand:XF 1 "register_operand" "")))
4012 (clobber (reg:CC FLAGS_REG))])]
4013 "TARGET_80387"
4014 {
4015 if (TARGET_FISTTP)
4016 {
4017 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4018 DONE;
4019 }
4020 })
4021
4022 (define_expand "fix_trunc<mode>di2"
4023 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4024 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4025 (clobber (reg:CC FLAGS_REG))])]
4026 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4027 {
4028 if (TARGET_FISTTP
4029 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4030 {
4031 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4032 DONE;
4033 }
4034 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4035 {
4036 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4037 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4038 if (out != operands[0])
4039 emit_move_insn (operands[0], out);
4040 DONE;
4041 }
4042 })
4043
4044 ;; Signed conversion to SImode.
4045
4046 (define_expand "fix_truncxfsi2"
4047 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4048 (fix:SI (match_operand:XF 1 "register_operand" "")))
4049 (clobber (reg:CC FLAGS_REG))])]
4050 "TARGET_80387"
4051 {
4052 if (TARGET_FISTTP)
4053 {
4054 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4055 DONE;
4056 }
4057 })
4058
4059 (define_expand "fix_trunc<mode>si2"
4060 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4061 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4062 (clobber (reg:CC FLAGS_REG))])]
4063 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4064 {
4065 if (TARGET_FISTTP
4066 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4067 {
4068 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4069 DONE;
4070 }
4071 if (SSE_FLOAT_MODE_P (<MODE>mode))
4072 {
4073 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4074 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4075 if (out != operands[0])
4076 emit_move_insn (operands[0], out);
4077 DONE;
4078 }
4079 })
4080
4081 ;; Signed conversion to HImode.
4082
4083 (define_expand "fix_trunc<mode>hi2"
4084 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4085 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4086 (clobber (reg:CC FLAGS_REG))])]
4087 "TARGET_80387
4088 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4089 {
4090 if (TARGET_FISTTP)
4091 {
4092 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4093 DONE;
4094 }
4095 })
4096
4097 ;; When SSE is available, it is always faster to use it!
4098 (define_insn "fix_truncsfdi_sse"
4099 [(set (match_operand:DI 0 "register_operand" "=r,r")
4100 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4101 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4102 "cvttss2si{q}\t{%1, %0|%0, %1}"
4103 [(set_attr "type" "sseicvt")
4104 (set_attr "mode" "SF")
4105 (set_attr "athlon_decode" "double,vector")])
4106
4107 (define_insn "fix_truncdfdi_sse"
4108 [(set (match_operand:DI 0 "register_operand" "=r,r")
4109 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4110 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4111 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4112 [(set_attr "type" "sseicvt")
4113 (set_attr "mode" "DF")
4114 (set_attr "athlon_decode" "double,vector")])
4115
4116 (define_insn "fix_truncsfsi_sse"
4117 [(set (match_operand:SI 0 "register_operand" "=r,r")
4118 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4119 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4120 "cvttss2si\t{%1, %0|%0, %1}"
4121 [(set_attr "type" "sseicvt")
4122 (set_attr "mode" "DF")
4123 (set_attr "athlon_decode" "double,vector")])
4124
4125 (define_insn "fix_truncdfsi_sse"
4126 [(set (match_operand:SI 0 "register_operand" "=r,r")
4127 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4128 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4129 "cvttsd2si\t{%1, %0|%0, %1}"
4130 [(set_attr "type" "sseicvt")
4131 (set_attr "mode" "DF")
4132 (set_attr "athlon_decode" "double,vector")])
4133
4134 ;; Avoid vector decoded forms of the instruction.
4135 (define_peephole2
4136 [(match_scratch:DF 2 "Y")
4137 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4138 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4139 "TARGET_K8 && !optimize_size"
4140 [(set (match_dup 2) (match_dup 1))
4141 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4142 "")
4143
4144 (define_peephole2
4145 [(match_scratch:SF 2 "x")
4146 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4147 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4148 "TARGET_K8 && !optimize_size"
4149 [(set (match_dup 2) (match_dup 1))
4150 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4151 "")
4152
4153 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4154 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4155 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4156 "TARGET_80387 && TARGET_FISTTP
4157 && FLOAT_MODE_P (GET_MODE (operands[1]))
4158 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4159 && (TARGET_64BIT || <MODE>mode != DImode))
4160 && TARGET_SSE_MATH)
4161 && !(reload_completed || reload_in_progress)"
4162 "#"
4163 "&& 1"
4164 [(const_int 0)]
4165 {
4166 if (memory_operand (operands[0], VOIDmode))
4167 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4168 else
4169 {
4170 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4171 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4172 operands[1],
4173 operands[2]));
4174 }
4175 DONE;
4176 }
4177 [(set_attr "type" "fisttp")
4178 (set_attr "mode" "<MODE>")])
4179
4180 (define_insn "fix_trunc<mode>_i387_fisttp"
4181 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4182 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4183 (clobber (match_scratch:XF 2 "=&1f"))]
4184 "TARGET_80387 && TARGET_FISTTP
4185 && FLOAT_MODE_P (GET_MODE (operands[1]))
4186 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4187 && (TARGET_64BIT || <MODE>mode != DImode))
4188 && TARGET_SSE_MATH)"
4189 "* return output_fix_trunc (insn, operands, 1);"
4190 [(set_attr "type" "fisttp")
4191 (set_attr "mode" "<MODE>")])
4192
4193 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4194 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4195 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4196 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4197 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4198 "TARGET_80387 && TARGET_FISTTP
4199 && FLOAT_MODE_P (GET_MODE (operands[1]))
4200 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4201 && (TARGET_64BIT || <MODE>mode != DImode))
4202 && TARGET_SSE_MATH)"
4203 "#"
4204 [(set_attr "type" "fisttp")
4205 (set_attr "mode" "<MODE>")])
4206
4207 (define_split
4208 [(set (match_operand:X87MODEI 0 "register_operand" "")
4209 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4210 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4211 (clobber (match_scratch 3 ""))]
4212 "reload_completed"
4213 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4214 (clobber (match_dup 3))])
4215 (set (match_dup 0) (match_dup 2))]
4216 "")
4217
4218 (define_split
4219 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4220 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4221 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4222 (clobber (match_scratch 3 ""))]
4223 "reload_completed"
4224 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4225 (clobber (match_dup 3))])]
4226 "")
4227
4228 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4229 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4230 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4231 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4232 ;; function in i386.c.
4233 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4234 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4235 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4236 (clobber (reg:CC FLAGS_REG))]
4237 "TARGET_80387 && !TARGET_FISTTP
4238 && FLOAT_MODE_P (GET_MODE (operands[1]))
4239 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4240 && (TARGET_64BIT || <MODE>mode != DImode))
4241 && !(reload_completed || reload_in_progress)"
4242 "#"
4243 "&& 1"
4244 [(const_int 0)]
4245 {
4246 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4247
4248 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4249 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4250 if (memory_operand (operands[0], VOIDmode))
4251 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4252 operands[2], operands[3]));
4253 else
4254 {
4255 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4256 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4257 operands[2], operands[3],
4258 operands[4]));
4259 }
4260 DONE;
4261 }
4262 [(set_attr "type" "fistp")
4263 (set_attr "i387_cw" "trunc")
4264 (set_attr "mode" "<MODE>")])
4265
4266 (define_insn "fix_truncdi_i387"
4267 [(set (match_operand:DI 0 "memory_operand" "=m")
4268 (fix:DI (match_operand 1 "register_operand" "f")))
4269 (use (match_operand:HI 2 "memory_operand" "m"))
4270 (use (match_operand:HI 3 "memory_operand" "m"))
4271 (clobber (match_scratch:XF 4 "=&1f"))]
4272 "TARGET_80387 && !TARGET_FISTTP
4273 && FLOAT_MODE_P (GET_MODE (operands[1]))
4274 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4275 "* return output_fix_trunc (insn, operands, 0);"
4276 [(set_attr "type" "fistp")
4277 (set_attr "i387_cw" "trunc")
4278 (set_attr "mode" "DI")])
4279
4280 (define_insn "fix_truncdi_i387_with_temp"
4281 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4282 (fix:DI (match_operand 1 "register_operand" "f,f")))
4283 (use (match_operand:HI 2 "memory_operand" "m,m"))
4284 (use (match_operand:HI 3 "memory_operand" "m,m"))
4285 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4286 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4287 "TARGET_80387 && !TARGET_FISTTP
4288 && FLOAT_MODE_P (GET_MODE (operands[1]))
4289 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4290 "#"
4291 [(set_attr "type" "fistp")
4292 (set_attr "i387_cw" "trunc")
4293 (set_attr "mode" "DI")])
4294
4295 (define_split
4296 [(set (match_operand:DI 0 "register_operand" "")
4297 (fix:DI (match_operand 1 "register_operand" "")))
4298 (use (match_operand:HI 2 "memory_operand" ""))
4299 (use (match_operand:HI 3 "memory_operand" ""))
4300 (clobber (match_operand:DI 4 "memory_operand" ""))
4301 (clobber (match_scratch 5 ""))]
4302 "reload_completed"
4303 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4304 (use (match_dup 2))
4305 (use (match_dup 3))
4306 (clobber (match_dup 5))])
4307 (set (match_dup 0) (match_dup 4))]
4308 "")
4309
4310 (define_split
4311 [(set (match_operand:DI 0 "memory_operand" "")
4312 (fix:DI (match_operand 1 "register_operand" "")))
4313 (use (match_operand:HI 2 "memory_operand" ""))
4314 (use (match_operand:HI 3 "memory_operand" ""))
4315 (clobber (match_operand:DI 4 "memory_operand" ""))
4316 (clobber (match_scratch 5 ""))]
4317 "reload_completed"
4318 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4319 (use (match_dup 2))
4320 (use (match_dup 3))
4321 (clobber (match_dup 5))])]
4322 "")
4323
4324 (define_insn "fix_trunc<mode>_i387"
4325 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4326 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4327 (use (match_operand:HI 2 "memory_operand" "m"))
4328 (use (match_operand:HI 3 "memory_operand" "m"))]
4329 "TARGET_80387 && !TARGET_FISTTP
4330 && FLOAT_MODE_P (GET_MODE (operands[1]))
4331 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4332 "* return output_fix_trunc (insn, operands, 0);"
4333 [(set_attr "type" "fistp")
4334 (set_attr "i387_cw" "trunc")
4335 (set_attr "mode" "<MODE>")])
4336
4337 (define_insn "fix_trunc<mode>_i387_with_temp"
4338 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4339 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4340 (use (match_operand:HI 2 "memory_operand" "m,m"))
4341 (use (match_operand:HI 3 "memory_operand" "m,m"))
4342 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4343 "TARGET_80387 && !TARGET_FISTTP
4344 && FLOAT_MODE_P (GET_MODE (operands[1]))
4345 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4346 "#"
4347 [(set_attr "type" "fistp")
4348 (set_attr "i387_cw" "trunc")
4349 (set_attr "mode" "<MODE>")])
4350
4351 (define_split
4352 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4353 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4354 (use (match_operand:HI 2 "memory_operand" ""))
4355 (use (match_operand:HI 3 "memory_operand" ""))
4356 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4357 "reload_completed"
4358 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4359 (use (match_dup 2))
4360 (use (match_dup 3))])
4361 (set (match_dup 0) (match_dup 4))]
4362 "")
4363
4364 (define_split
4365 [(set (match_operand:X87MODEI12 0 "memory_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 0) (fix:X87MODEI12 (match_dup 1)))
4372 (use (match_dup 2))
4373 (use (match_dup 3))])]
4374 "")
4375
4376 (define_insn "x86_fnstcw_1"
4377 [(set (match_operand:HI 0 "memory_operand" "=m")
4378 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4379 "TARGET_80387"
4380 "fnstcw\t%0"
4381 [(set_attr "length" "2")
4382 (set_attr "mode" "HI")
4383 (set_attr "unit" "i387")])
4384
4385 (define_insn "x86_fldcw_1"
4386 [(set (reg:HI FPSR_REG)
4387 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4388 "TARGET_80387"
4389 "fldcw\t%0"
4390 [(set_attr "length" "2")
4391 (set_attr "mode" "HI")
4392 (set_attr "unit" "i387")
4393 (set_attr "athlon_decode" "vector")])
4394 \f
4395 ;; Conversion between fixed point and floating point.
4396
4397 ;; Even though we only accept memory inputs, the backend _really_
4398 ;; wants to be able to do this between registers.
4399
4400 (define_expand "floathisf2"
4401 [(set (match_operand:SF 0 "register_operand" "")
4402 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4403 "TARGET_80387 || TARGET_SSE_MATH"
4404 {
4405 if (TARGET_SSE_MATH)
4406 {
4407 emit_insn (gen_floatsisf2 (operands[0],
4408 convert_to_mode (SImode, operands[1], 0)));
4409 DONE;
4410 }
4411 })
4412
4413 (define_insn "*floathisf2_i387"
4414 [(set (match_operand:SF 0 "register_operand" "=f,f")
4415 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4416 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4417 "@
4418 fild%z1\t%1
4419 #"
4420 [(set_attr "type" "fmov,multi")
4421 (set_attr "mode" "SF")
4422 (set_attr "unit" "*,i387")
4423 (set_attr "fp_int_src" "true")])
4424
4425 (define_expand "floatsisf2"
4426 [(set (match_operand:SF 0 "register_operand" "")
4427 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4428 "TARGET_80387 || TARGET_SSE_MATH"
4429 "")
4430
4431 (define_insn "*floatsisf2_mixed"
4432 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4433 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4434 "TARGET_MIX_SSE_I387"
4435 "@
4436 fild%z1\t%1
4437 #
4438 cvtsi2ss\t{%1, %0|%0, %1}
4439 cvtsi2ss\t{%1, %0|%0, %1}"
4440 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4441 (set_attr "mode" "SF")
4442 (set_attr "unit" "*,i387,*,*")
4443 (set_attr "athlon_decode" "*,*,vector,double")
4444 (set_attr "fp_int_src" "true")])
4445
4446 (define_insn "*floatsisf2_sse"
4447 [(set (match_operand:SF 0 "register_operand" "=x,x")
4448 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4449 "TARGET_SSE_MATH"
4450 "cvtsi2ss\t{%1, %0|%0, %1}"
4451 [(set_attr "type" "sseicvt")
4452 (set_attr "mode" "SF")
4453 (set_attr "athlon_decode" "vector,double")
4454 (set_attr "fp_int_src" "true")])
4455
4456 (define_insn "*floatsisf2_i387"
4457 [(set (match_operand:SF 0 "register_operand" "=f,f")
4458 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4459 "TARGET_80387"
4460 "@
4461 fild%z1\t%1
4462 #"
4463 [(set_attr "type" "fmov,multi")
4464 (set_attr "mode" "SF")
4465 (set_attr "unit" "*,i387")
4466 (set_attr "fp_int_src" "true")])
4467
4468 (define_expand "floatdisf2"
4469 [(set (match_operand:SF 0 "register_operand" "")
4470 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4471 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4472 "")
4473
4474 (define_insn "*floatdisf2_mixed"
4475 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4476 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4477 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4478 "@
4479 fild%z1\t%1
4480 #
4481 cvtsi2ss{q}\t{%1, %0|%0, %1}
4482 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4483 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4484 (set_attr "mode" "SF")
4485 (set_attr "unit" "*,i387,*,*")
4486 (set_attr "athlon_decode" "*,*,vector,double")
4487 (set_attr "fp_int_src" "true")])
4488
4489 (define_insn "*floatdisf2_sse"
4490 [(set (match_operand:SF 0 "register_operand" "=x,x")
4491 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4492 "TARGET_64BIT && TARGET_SSE_MATH"
4493 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4494 [(set_attr "type" "sseicvt")
4495 (set_attr "mode" "SF")
4496 (set_attr "athlon_decode" "vector,double")
4497 (set_attr "fp_int_src" "true")])
4498
4499 (define_insn "*floatdisf2_i387"
4500 [(set (match_operand:SF 0 "register_operand" "=f,f")
4501 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4502 "TARGET_80387"
4503 "@
4504 fild%z1\t%1
4505 #"
4506 [(set_attr "type" "fmov,multi")
4507 (set_attr "mode" "SF")
4508 (set_attr "unit" "*,i387")
4509 (set_attr "fp_int_src" "true")])
4510
4511 (define_expand "floathidf2"
4512 [(set (match_operand:DF 0 "register_operand" "")
4513 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4514 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4515 {
4516 if (TARGET_SSE2 && TARGET_SSE_MATH)
4517 {
4518 emit_insn (gen_floatsidf2 (operands[0],
4519 convert_to_mode (SImode, operands[1], 0)));
4520 DONE;
4521 }
4522 })
4523
4524 (define_insn "*floathidf2_i387"
4525 [(set (match_operand:DF 0 "register_operand" "=f,f")
4526 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4527 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4528 "@
4529 fild%z1\t%1
4530 #"
4531 [(set_attr "type" "fmov,multi")
4532 (set_attr "mode" "DF")
4533 (set_attr "unit" "*,i387")
4534 (set_attr "fp_int_src" "true")])
4535
4536 (define_expand "floatsidf2"
4537 [(set (match_operand:DF 0 "register_operand" "")
4538 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4539 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4540 "")
4541
4542 (define_insn "*floatsidf2_mixed"
4543 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4544 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4545 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4546 "@
4547 fild%z1\t%1
4548 #
4549 cvtsi2sd\t{%1, %0|%0, %1}
4550 cvtsi2sd\t{%1, %0|%0, %1}"
4551 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4552 (set_attr "mode" "DF")
4553 (set_attr "unit" "*,i387,*,*")
4554 (set_attr "athlon_decode" "*,*,double,direct")
4555 (set_attr "fp_int_src" "true")])
4556
4557 (define_insn "*floatsidf2_sse"
4558 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4559 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4560 "TARGET_SSE2 && TARGET_SSE_MATH"
4561 "cvtsi2sd\t{%1, %0|%0, %1}"
4562 [(set_attr "type" "sseicvt")
4563 (set_attr "mode" "DF")
4564 (set_attr "athlon_decode" "double,direct")
4565 (set_attr "fp_int_src" "true")])
4566
4567 (define_insn "*floatsidf2_i387"
4568 [(set (match_operand:DF 0 "register_operand" "=f,f")
4569 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4570 "TARGET_80387"
4571 "@
4572 fild%z1\t%1
4573 #"
4574 [(set_attr "type" "fmov,multi")
4575 (set_attr "mode" "DF")
4576 (set_attr "unit" "*,i387")
4577 (set_attr "fp_int_src" "true")])
4578
4579 (define_expand "floatdidf2"
4580 [(set (match_operand:DF 0 "register_operand" "")
4581 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4582 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4583 "")
4584
4585 (define_insn "*floatdidf2_mixed"
4586 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4587 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4588 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4589 "@
4590 fild%z1\t%1
4591 #
4592 cvtsi2sd{q}\t{%1, %0|%0, %1}
4593 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4594 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4595 (set_attr "mode" "DF")
4596 (set_attr "unit" "*,i387,*,*")
4597 (set_attr "athlon_decode" "*,*,double,direct")
4598 (set_attr "fp_int_src" "true")])
4599
4600 (define_insn "*floatdidf2_sse"
4601 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4602 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4603 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4604 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4605 [(set_attr "type" "sseicvt")
4606 (set_attr "mode" "DF")
4607 (set_attr "athlon_decode" "double,direct")
4608 (set_attr "fp_int_src" "true")])
4609
4610 (define_insn "*floatdidf2_i387"
4611 [(set (match_operand:DF 0 "register_operand" "=f,f")
4612 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4613 "TARGET_80387"
4614 "@
4615 fild%z1\t%1
4616 #"
4617 [(set_attr "type" "fmov,multi")
4618 (set_attr "mode" "DF")
4619 (set_attr "unit" "*,i387")
4620 (set_attr "fp_int_src" "true")])
4621
4622 (define_insn "floathixf2"
4623 [(set (match_operand:XF 0 "register_operand" "=f,f")
4624 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4625 "TARGET_80387"
4626 "@
4627 fild%z1\t%1
4628 #"
4629 [(set_attr "type" "fmov,multi")
4630 (set_attr "mode" "XF")
4631 (set_attr "unit" "*,i387")
4632 (set_attr "fp_int_src" "true")])
4633
4634 (define_insn "floatsixf2"
4635 [(set (match_operand:XF 0 "register_operand" "=f,f")
4636 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4637 "TARGET_80387"
4638 "@
4639 fild%z1\t%1
4640 #"
4641 [(set_attr "type" "fmov,multi")
4642 (set_attr "mode" "XF")
4643 (set_attr "unit" "*,i387")
4644 (set_attr "fp_int_src" "true")])
4645
4646 (define_insn "floatdixf2"
4647 [(set (match_operand:XF 0 "register_operand" "=f,f")
4648 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4649 "TARGET_80387"
4650 "@
4651 fild%z1\t%1
4652 #"
4653 [(set_attr "type" "fmov,multi")
4654 (set_attr "mode" "XF")
4655 (set_attr "unit" "*,i387")
4656 (set_attr "fp_int_src" "true")])
4657
4658 ;; %%% Kill these when reload knows how to do it.
4659 (define_split
4660 [(set (match_operand 0 "fp_register_operand" "")
4661 (float (match_operand 1 "register_operand" "")))]
4662 "reload_completed
4663 && TARGET_80387
4664 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4665 [(const_int 0)]
4666 {
4667 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4668 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4669 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4670 ix86_free_from_memory (GET_MODE (operands[1]));
4671 DONE;
4672 })
4673
4674 (define_expand "floatunssisf2"
4675 [(use (match_operand:SF 0 "register_operand" ""))
4676 (use (match_operand:SI 1 "register_operand" ""))]
4677 "!TARGET_64BIT && TARGET_SSE_MATH"
4678 "x86_emit_floatuns (operands); DONE;")
4679
4680 (define_expand "floatunsdisf2"
4681 [(use (match_operand:SF 0 "register_operand" ""))
4682 (use (match_operand:DI 1 "register_operand" ""))]
4683 "TARGET_64BIT && TARGET_SSE_MATH"
4684 "x86_emit_floatuns (operands); DONE;")
4685
4686 (define_expand "floatunsdidf2"
4687 [(use (match_operand:DF 0 "register_operand" ""))
4688 (use (match_operand:DI 1 "register_operand" ""))]
4689 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4690 "x86_emit_floatuns (operands); DONE;")
4691 \f
4692 ;; SSE extract/set expanders
4693
4694 \f
4695 ;; Add instructions
4696
4697 ;; %%% splits for addsidi3
4698 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4699 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4700 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4701
4702 (define_expand "adddi3"
4703 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4704 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4705 (match_operand:DI 2 "x86_64_general_operand" "")))
4706 (clobber (reg:CC FLAGS_REG))]
4707 ""
4708 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4709
4710 (define_insn "*adddi3_1"
4711 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4712 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4713 (match_operand:DI 2 "general_operand" "roiF,riF")))
4714 (clobber (reg:CC FLAGS_REG))]
4715 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4716 "#")
4717
4718 (define_split
4719 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4720 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4721 (match_operand:DI 2 "general_operand" "")))
4722 (clobber (reg:CC FLAGS_REG))]
4723 "!TARGET_64BIT && reload_completed"
4724 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4725 UNSPEC_ADD_CARRY))
4726 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4727 (parallel [(set (match_dup 3)
4728 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4729 (match_dup 4))
4730 (match_dup 5)))
4731 (clobber (reg:CC FLAGS_REG))])]
4732 "split_di (operands+0, 1, operands+0, operands+3);
4733 split_di (operands+1, 1, operands+1, operands+4);
4734 split_di (operands+2, 1, operands+2, operands+5);")
4735
4736 (define_insn "adddi3_carry_rex64"
4737 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4738 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4739 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4740 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4741 (clobber (reg:CC FLAGS_REG))]
4742 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4743 "adc{q}\t{%2, %0|%0, %2}"
4744 [(set_attr "type" "alu")
4745 (set_attr "pent_pair" "pu")
4746 (set_attr "mode" "DI")])
4747
4748 (define_insn "*adddi3_cc_rex64"
4749 [(set (reg:CC FLAGS_REG)
4750 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4751 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4752 UNSPEC_ADD_CARRY))
4753 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4754 (plus:DI (match_dup 1) (match_dup 2)))]
4755 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4756 "add{q}\t{%2, %0|%0, %2}"
4757 [(set_attr "type" "alu")
4758 (set_attr "mode" "DI")])
4759
4760 (define_insn "addqi3_carry"
4761 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4762 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4763 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4764 (match_operand:QI 2 "general_operand" "qi,qm")))
4765 (clobber (reg:CC FLAGS_REG))]
4766 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4767 "adc{b}\t{%2, %0|%0, %2}"
4768 [(set_attr "type" "alu")
4769 (set_attr "pent_pair" "pu")
4770 (set_attr "mode" "QI")])
4771
4772 (define_insn "addhi3_carry"
4773 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4774 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4775 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4776 (match_operand:HI 2 "general_operand" "ri,rm")))
4777 (clobber (reg:CC FLAGS_REG))]
4778 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4779 "adc{w}\t{%2, %0|%0, %2}"
4780 [(set_attr "type" "alu")
4781 (set_attr "pent_pair" "pu")
4782 (set_attr "mode" "HI")])
4783
4784 (define_insn "addsi3_carry"
4785 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4786 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4787 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4788 (match_operand:SI 2 "general_operand" "ri,rm")))
4789 (clobber (reg:CC FLAGS_REG))]
4790 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4791 "adc{l}\t{%2, %0|%0, %2}"
4792 [(set_attr "type" "alu")
4793 (set_attr "pent_pair" "pu")
4794 (set_attr "mode" "SI")])
4795
4796 (define_insn "*addsi3_carry_zext"
4797 [(set (match_operand:DI 0 "register_operand" "=r")
4798 (zero_extend:DI
4799 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4800 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4801 (match_operand:SI 2 "general_operand" "rim"))))
4802 (clobber (reg:CC FLAGS_REG))]
4803 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4804 "adc{l}\t{%2, %k0|%k0, %2}"
4805 [(set_attr "type" "alu")
4806 (set_attr "pent_pair" "pu")
4807 (set_attr "mode" "SI")])
4808
4809 (define_insn "*addsi3_cc"
4810 [(set (reg:CC FLAGS_REG)
4811 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4812 (match_operand:SI 2 "general_operand" "ri,rm")]
4813 UNSPEC_ADD_CARRY))
4814 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4815 (plus:SI (match_dup 1) (match_dup 2)))]
4816 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4817 "add{l}\t{%2, %0|%0, %2}"
4818 [(set_attr "type" "alu")
4819 (set_attr "mode" "SI")])
4820
4821 (define_insn "addqi3_cc"
4822 [(set (reg:CC FLAGS_REG)
4823 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4824 (match_operand:QI 2 "general_operand" "qi,qm")]
4825 UNSPEC_ADD_CARRY))
4826 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4827 (plus:QI (match_dup 1) (match_dup 2)))]
4828 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4829 "add{b}\t{%2, %0|%0, %2}"
4830 [(set_attr "type" "alu")
4831 (set_attr "mode" "QI")])
4832
4833 (define_expand "addsi3"
4834 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4835 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4836 (match_operand:SI 2 "general_operand" "")))
4837 (clobber (reg:CC FLAGS_REG))])]
4838 ""
4839 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4840
4841 (define_insn "*lea_1"
4842 [(set (match_operand:SI 0 "register_operand" "=r")
4843 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4844 "!TARGET_64BIT"
4845 "lea{l}\t{%a1, %0|%0, %a1}"
4846 [(set_attr "type" "lea")
4847 (set_attr "mode" "SI")])
4848
4849 (define_insn "*lea_1_rex64"
4850 [(set (match_operand:SI 0 "register_operand" "=r")
4851 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4852 "TARGET_64BIT"
4853 "lea{l}\t{%a1, %0|%0, %a1}"
4854 [(set_attr "type" "lea")
4855 (set_attr "mode" "SI")])
4856
4857 (define_insn "*lea_1_zext"
4858 [(set (match_operand:DI 0 "register_operand" "=r")
4859 (zero_extend:DI
4860 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4861 "TARGET_64BIT"
4862 "lea{l}\t{%a1, %k0|%k0, %a1}"
4863 [(set_attr "type" "lea")
4864 (set_attr "mode" "SI")])
4865
4866 (define_insn "*lea_2_rex64"
4867 [(set (match_operand:DI 0 "register_operand" "=r")
4868 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4869 "TARGET_64BIT"
4870 "lea{q}\t{%a1, %0|%0, %a1}"
4871 [(set_attr "type" "lea")
4872 (set_attr "mode" "DI")])
4873
4874 ;; The lea patterns for non-Pmodes needs to be matched by several
4875 ;; insns converted to real lea by splitters.
4876
4877 (define_insn_and_split "*lea_general_1"
4878 [(set (match_operand 0 "register_operand" "=r")
4879 (plus (plus (match_operand 1 "index_register_operand" "l")
4880 (match_operand 2 "register_operand" "r"))
4881 (match_operand 3 "immediate_operand" "i")))]
4882 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4883 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4884 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4885 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4886 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4887 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4888 || GET_MODE (operands[3]) == VOIDmode)"
4889 "#"
4890 "&& reload_completed"
4891 [(const_int 0)]
4892 {
4893 rtx pat;
4894 operands[0] = gen_lowpart (SImode, operands[0]);
4895 operands[1] = gen_lowpart (Pmode, operands[1]);
4896 operands[2] = gen_lowpart (Pmode, operands[2]);
4897 operands[3] = gen_lowpart (Pmode, operands[3]);
4898 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4899 operands[3]);
4900 if (Pmode != SImode)
4901 pat = gen_rtx_SUBREG (SImode, pat, 0);
4902 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4903 DONE;
4904 }
4905 [(set_attr "type" "lea")
4906 (set_attr "mode" "SI")])
4907
4908 (define_insn_and_split "*lea_general_1_zext"
4909 [(set (match_operand:DI 0 "register_operand" "=r")
4910 (zero_extend:DI
4911 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4912 (match_operand:SI 2 "register_operand" "r"))
4913 (match_operand:SI 3 "immediate_operand" "i"))))]
4914 "TARGET_64BIT"
4915 "#"
4916 "&& reload_completed"
4917 [(set (match_dup 0)
4918 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4919 (match_dup 2))
4920 (match_dup 3)) 0)))]
4921 {
4922 operands[1] = gen_lowpart (Pmode, operands[1]);
4923 operands[2] = gen_lowpart (Pmode, operands[2]);
4924 operands[3] = gen_lowpart (Pmode, operands[3]);
4925 }
4926 [(set_attr "type" "lea")
4927 (set_attr "mode" "SI")])
4928
4929 (define_insn_and_split "*lea_general_2"
4930 [(set (match_operand 0 "register_operand" "=r")
4931 (plus (mult (match_operand 1 "index_register_operand" "l")
4932 (match_operand 2 "const248_operand" "i"))
4933 (match_operand 3 "nonmemory_operand" "ri")))]
4934 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4935 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4936 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4937 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4938 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4939 || GET_MODE (operands[3]) == VOIDmode)"
4940 "#"
4941 "&& reload_completed"
4942 [(const_int 0)]
4943 {
4944 rtx pat;
4945 operands[0] = gen_lowpart (SImode, operands[0]);
4946 operands[1] = gen_lowpart (Pmode, operands[1]);
4947 operands[3] = gen_lowpart (Pmode, operands[3]);
4948 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4949 operands[3]);
4950 if (Pmode != SImode)
4951 pat = gen_rtx_SUBREG (SImode, pat, 0);
4952 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4953 DONE;
4954 }
4955 [(set_attr "type" "lea")
4956 (set_attr "mode" "SI")])
4957
4958 (define_insn_and_split "*lea_general_2_zext"
4959 [(set (match_operand:DI 0 "register_operand" "=r")
4960 (zero_extend:DI
4961 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
4962 (match_operand:SI 2 "const248_operand" "n"))
4963 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4964 "TARGET_64BIT"
4965 "#"
4966 "&& reload_completed"
4967 [(set (match_dup 0)
4968 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4969 (match_dup 2))
4970 (match_dup 3)) 0)))]
4971 {
4972 operands[1] = gen_lowpart (Pmode, operands[1]);
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_3"
4979 [(set (match_operand 0 "register_operand" "=r")
4980 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
4981 (match_operand 2 "const248_operand" "i"))
4982 (match_operand 3 "register_operand" "r"))
4983 (match_operand 4 "immediate_operand" "i")))]
4984 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4985 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4986 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4987 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4988 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
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 operands[4] = gen_lowpart (Pmode, operands[4]);
4998 pat = gen_rtx_PLUS (Pmode,
4999 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5000 operands[2]),
5001 operands[3]),
5002 operands[4]);
5003 if (Pmode != SImode)
5004 pat = gen_rtx_SUBREG (SImode, pat, 0);
5005 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5006 DONE;
5007 }
5008 [(set_attr "type" "lea")
5009 (set_attr "mode" "SI")])
5010
5011 (define_insn_and_split "*lea_general_3_zext"
5012 [(set (match_operand:DI 0 "register_operand" "=r")
5013 (zero_extend:DI
5014 (plus:SI (plus:SI (mult:SI
5015 (match_operand:SI 1 "index_register_operand" "l")
5016 (match_operand:SI 2 "const248_operand" "n"))
5017 (match_operand:SI 3 "register_operand" "r"))
5018 (match_operand:SI 4 "immediate_operand" "i"))))]
5019 "TARGET_64BIT"
5020 "#"
5021 "&& reload_completed"
5022 [(set (match_dup 0)
5023 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5024 (match_dup 2))
5025 (match_dup 3))
5026 (match_dup 4)) 0)))]
5027 {
5028 operands[1] = gen_lowpart (Pmode, operands[1]);
5029 operands[3] = gen_lowpart (Pmode, operands[3]);
5030 operands[4] = gen_lowpart (Pmode, operands[4]);
5031 }
5032 [(set_attr "type" "lea")
5033 (set_attr "mode" "SI")])
5034
5035 (define_insn "*adddi_1_rex64"
5036 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5037 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5038 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5039 (clobber (reg:CC FLAGS_REG))]
5040 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5041 {
5042 switch (get_attr_type (insn))
5043 {
5044 case TYPE_LEA:
5045 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5046 return "lea{q}\t{%a2, %0|%0, %a2}";
5047
5048 case TYPE_INCDEC:
5049 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5050 if (operands[2] == const1_rtx)
5051 return "inc{q}\t%0";
5052 else
5053 {
5054 gcc_assert (operands[2] == constm1_rtx);
5055 return "dec{q}\t%0";
5056 }
5057
5058 default:
5059 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5060
5061 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5062 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5063 if (GET_CODE (operands[2]) == CONST_INT
5064 /* Avoid overflows. */
5065 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5066 && (INTVAL (operands[2]) == 128
5067 || (INTVAL (operands[2]) < 0
5068 && INTVAL (operands[2]) != -128)))
5069 {
5070 operands[2] = GEN_INT (-INTVAL (operands[2]));
5071 return "sub{q}\t{%2, %0|%0, %2}";
5072 }
5073 return "add{q}\t{%2, %0|%0, %2}";
5074 }
5075 }
5076 [(set (attr "type")
5077 (cond [(eq_attr "alternative" "2")
5078 (const_string "lea")
5079 ; Current assemblers are broken and do not allow @GOTOFF in
5080 ; ought but a memory context.
5081 (match_operand:DI 2 "pic_symbolic_operand" "")
5082 (const_string "lea")
5083 (match_operand:DI 2 "incdec_operand" "")
5084 (const_string "incdec")
5085 ]
5086 (const_string "alu")))
5087 (set_attr "mode" "DI")])
5088
5089 ;; Convert lea to the lea pattern to avoid flags dependency.
5090 (define_split
5091 [(set (match_operand:DI 0 "register_operand" "")
5092 (plus:DI (match_operand:DI 1 "register_operand" "")
5093 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5094 (clobber (reg:CC FLAGS_REG))]
5095 "TARGET_64BIT && reload_completed
5096 && true_regnum (operands[0]) != true_regnum (operands[1])"
5097 [(set (match_dup 0)
5098 (plus:DI (match_dup 1)
5099 (match_dup 2)))]
5100 "")
5101
5102 (define_insn "*adddi_2_rex64"
5103 [(set (reg FLAGS_REG)
5104 (compare
5105 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5106 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5107 (const_int 0)))
5108 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5109 (plus:DI (match_dup 1) (match_dup 2)))]
5110 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5111 && ix86_binary_operator_ok (PLUS, DImode, operands)
5112 /* Current assemblers are broken and do not allow @GOTOFF in
5113 ought but a memory context. */
5114 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5115 {
5116 switch (get_attr_type (insn))
5117 {
5118 case TYPE_INCDEC:
5119 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5120 if (operands[2] == const1_rtx)
5121 return "inc{q}\t%0";
5122 else
5123 {
5124 gcc_assert (operands[2] == constm1_rtx);
5125 return "dec{q}\t%0";
5126 }
5127
5128 default:
5129 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5130 /* ???? We ought to handle there the 32bit case too
5131 - do we need new constraint? */
5132 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5133 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5134 if (GET_CODE (operands[2]) == CONST_INT
5135 /* Avoid overflows. */
5136 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5137 && (INTVAL (operands[2]) == 128
5138 || (INTVAL (operands[2]) < 0
5139 && INTVAL (operands[2]) != -128)))
5140 {
5141 operands[2] = GEN_INT (-INTVAL (operands[2]));
5142 return "sub{q}\t{%2, %0|%0, %2}";
5143 }
5144 return "add{q}\t{%2, %0|%0, %2}";
5145 }
5146 }
5147 [(set (attr "type")
5148 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5149 (const_string "incdec")
5150 (const_string "alu")))
5151 (set_attr "mode" "DI")])
5152
5153 (define_insn "*adddi_3_rex64"
5154 [(set (reg FLAGS_REG)
5155 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5156 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5157 (clobber (match_scratch:DI 0 "=r"))]
5158 "TARGET_64BIT
5159 && ix86_match_ccmode (insn, CCZmode)
5160 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
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 ; For comparisons against 1, -1 and 128, we may generate better code
5203 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5204 ; is matched then. We can't accept general immediate, because for
5205 ; case of overflows, the result is messed up.
5206 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5207 ; when negated.
5208 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5209 ; only for comparisons not depending on it.
5210 (define_insn "*adddi_4_rex64"
5211 [(set (reg FLAGS_REG)
5212 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5213 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5214 (clobber (match_scratch:DI 0 "=rm"))]
5215 "TARGET_64BIT
5216 && ix86_match_ccmode (insn, CCGCmode)"
5217 {
5218 switch (get_attr_type (insn))
5219 {
5220 case TYPE_INCDEC:
5221 if (operands[2] == constm1_rtx)
5222 return "inc{q}\t%0";
5223 else
5224 {
5225 gcc_assert (operands[2] == const1_rtx);
5226 return "dec{q}\t%0";
5227 }
5228
5229 default:
5230 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5231 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5232 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5233 if ((INTVAL (operands[2]) == -128
5234 || (INTVAL (operands[2]) > 0
5235 && INTVAL (operands[2]) != 128))
5236 /* Avoid overflows. */
5237 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5238 return "sub{q}\t{%2, %0|%0, %2}";
5239 operands[2] = GEN_INT (-INTVAL (operands[2]));
5240 return "add{q}\t{%2, %0|%0, %2}";
5241 }
5242 }
5243 [(set (attr "type")
5244 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5245 (const_string "incdec")
5246 (const_string "alu")))
5247 (set_attr "mode" "DI")])
5248
5249 (define_insn "*adddi_5_rex64"
5250 [(set (reg FLAGS_REG)
5251 (compare
5252 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5253 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5254 (const_int 0)))
5255 (clobber (match_scratch:DI 0 "=r"))]
5256 "TARGET_64BIT
5257 && ix86_match_ccmode (insn, CCGOCmode)
5258 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5259 /* Current assemblers are broken and do not allow @GOTOFF in
5260 ought but a memory context. */
5261 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5262 {
5263 switch (get_attr_type (insn))
5264 {
5265 case TYPE_INCDEC:
5266 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5267 if (operands[2] == const1_rtx)
5268 return "inc{q}\t%0";
5269 else
5270 {
5271 gcc_assert (operands[2] == constm1_rtx);
5272 return "dec{q}\t%0";
5273 }
5274
5275 default:
5276 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5277 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5278 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5279 if (GET_CODE (operands[2]) == CONST_INT
5280 /* Avoid overflows. */
5281 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5282 && (INTVAL (operands[2]) == 128
5283 || (INTVAL (operands[2]) < 0
5284 && INTVAL (operands[2]) != -128)))
5285 {
5286 operands[2] = GEN_INT (-INTVAL (operands[2]));
5287 return "sub{q}\t{%2, %0|%0, %2}";
5288 }
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
5299 (define_insn "*addsi_1"
5300 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5301 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5302 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5303 (clobber (reg:CC FLAGS_REG))]
5304 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5305 {
5306 switch (get_attr_type (insn))
5307 {
5308 case TYPE_LEA:
5309 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5310 return "lea{l}\t{%a2, %0|%0, %a2}";
5311
5312 case TYPE_INCDEC:
5313 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5314 if (operands[2] == const1_rtx)
5315 return "inc{l}\t%0";
5316 else
5317 {
5318 gcc_assert (operands[2] == constm1_rtx);
5319 return "dec{l}\t%0";
5320 }
5321
5322 default:
5323 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5324
5325 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5326 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5327 if (GET_CODE (operands[2]) == CONST_INT
5328 && (INTVAL (operands[2]) == 128
5329 || (INTVAL (operands[2]) < 0
5330 && INTVAL (operands[2]) != -128)))
5331 {
5332 operands[2] = GEN_INT (-INTVAL (operands[2]));
5333 return "sub{l}\t{%2, %0|%0, %2}";
5334 }
5335 return "add{l}\t{%2, %0|%0, %2}";
5336 }
5337 }
5338 [(set (attr "type")
5339 (cond [(eq_attr "alternative" "2")
5340 (const_string "lea")
5341 ; Current assemblers are broken and do not allow @GOTOFF in
5342 ; ought but a memory context.
5343 (match_operand:SI 2 "pic_symbolic_operand" "")
5344 (const_string "lea")
5345 (match_operand:SI 2 "incdec_operand" "")
5346 (const_string "incdec")
5347 ]
5348 (const_string "alu")))
5349 (set_attr "mode" "SI")])
5350
5351 ;; Convert lea to the lea pattern to avoid flags dependency.
5352 (define_split
5353 [(set (match_operand 0 "register_operand" "")
5354 (plus (match_operand 1 "register_operand" "")
5355 (match_operand 2 "nonmemory_operand" "")))
5356 (clobber (reg:CC FLAGS_REG))]
5357 "reload_completed
5358 && true_regnum (operands[0]) != true_regnum (operands[1])"
5359 [(const_int 0)]
5360 {
5361 rtx pat;
5362 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5363 may confuse gen_lowpart. */
5364 if (GET_MODE (operands[0]) != Pmode)
5365 {
5366 operands[1] = gen_lowpart (Pmode, operands[1]);
5367 operands[2] = gen_lowpart (Pmode, operands[2]);
5368 }
5369 operands[0] = gen_lowpart (SImode, operands[0]);
5370 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5371 if (Pmode != SImode)
5372 pat = gen_rtx_SUBREG (SImode, pat, 0);
5373 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5374 DONE;
5375 })
5376
5377 ;; It may seem that nonimmediate operand is proper one for operand 1.
5378 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5379 ;; we take care in ix86_binary_operator_ok to not allow two memory
5380 ;; operands so proper swapping will be done in reload. This allow
5381 ;; patterns constructed from addsi_1 to match.
5382 (define_insn "addsi_1_zext"
5383 [(set (match_operand:DI 0 "register_operand" "=r,r")
5384 (zero_extend:DI
5385 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5386 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5387 (clobber (reg:CC FLAGS_REG))]
5388 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5389 {
5390 switch (get_attr_type (insn))
5391 {
5392 case TYPE_LEA:
5393 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5394 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5395
5396 case TYPE_INCDEC:
5397 if (operands[2] == const1_rtx)
5398 return "inc{l}\t%k0";
5399 else
5400 {
5401 gcc_assert (operands[2] == constm1_rtx);
5402 return "dec{l}\t%k0";
5403 }
5404
5405 default:
5406 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5407 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5408 if (GET_CODE (operands[2]) == CONST_INT
5409 && (INTVAL (operands[2]) == 128
5410 || (INTVAL (operands[2]) < 0
5411 && INTVAL (operands[2]) != -128)))
5412 {
5413 operands[2] = GEN_INT (-INTVAL (operands[2]));
5414 return "sub{l}\t{%2, %k0|%k0, %2}";
5415 }
5416 return "add{l}\t{%2, %k0|%k0, %2}";
5417 }
5418 }
5419 [(set (attr "type")
5420 (cond [(eq_attr "alternative" "1")
5421 (const_string "lea")
5422 ; Current assemblers are broken and do not allow @GOTOFF in
5423 ; ought but a memory context.
5424 (match_operand:SI 2 "pic_symbolic_operand" "")
5425 (const_string "lea")
5426 (match_operand:SI 2 "incdec_operand" "")
5427 (const_string "incdec")
5428 ]
5429 (const_string "alu")))
5430 (set_attr "mode" "SI")])
5431
5432 ;; Convert lea to the lea pattern to avoid flags dependency.
5433 (define_split
5434 [(set (match_operand:DI 0 "register_operand" "")
5435 (zero_extend:DI
5436 (plus:SI (match_operand:SI 1 "register_operand" "")
5437 (match_operand:SI 2 "nonmemory_operand" ""))))
5438 (clobber (reg:CC FLAGS_REG))]
5439 "TARGET_64BIT && reload_completed
5440 && true_regnum (operands[0]) != true_regnum (operands[1])"
5441 [(set (match_dup 0)
5442 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5443 {
5444 operands[1] = gen_lowpart (Pmode, operands[1]);
5445 operands[2] = gen_lowpart (Pmode, operands[2]);
5446 })
5447
5448 (define_insn "*addsi_2"
5449 [(set (reg FLAGS_REG)
5450 (compare
5451 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5452 (match_operand:SI 2 "general_operand" "rmni,rni"))
5453 (const_int 0)))
5454 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5455 (plus:SI (match_dup 1) (match_dup 2)))]
5456 "ix86_match_ccmode (insn, CCGOCmode)
5457 && ix86_binary_operator_ok (PLUS, SImode, operands)
5458 /* Current assemblers are broken and do not allow @GOTOFF in
5459 ought but a memory context. */
5460 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5461 {
5462 switch (get_attr_type (insn))
5463 {
5464 case TYPE_INCDEC:
5465 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5466 if (operands[2] == const1_rtx)
5467 return "inc{l}\t%0";
5468 else
5469 {
5470 gcc_assert (operands[2] == constm1_rtx);
5471 return "dec{l}\t%0";
5472 }
5473
5474 default:
5475 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5476 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5477 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5478 if (GET_CODE (operands[2]) == CONST_INT
5479 && (INTVAL (operands[2]) == 128
5480 || (INTVAL (operands[2]) < 0
5481 && INTVAL (operands[2]) != -128)))
5482 {
5483 operands[2] = GEN_INT (-INTVAL (operands[2]));
5484 return "sub{l}\t{%2, %0|%0, %2}";
5485 }
5486 return "add{l}\t{%2, %0|%0, %2}";
5487 }
5488 }
5489 [(set (attr "type")
5490 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5491 (const_string "incdec")
5492 (const_string "alu")))
5493 (set_attr "mode" "SI")])
5494
5495 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5496 (define_insn "*addsi_2_zext"
5497 [(set (reg FLAGS_REG)
5498 (compare
5499 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5500 (match_operand:SI 2 "general_operand" "rmni"))
5501 (const_int 0)))
5502 (set (match_operand:DI 0 "register_operand" "=r")
5503 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5504 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5505 && ix86_binary_operator_ok (PLUS, SImode, operands)
5506 /* Current assemblers are broken and do not allow @GOTOFF in
5507 ought but a memory context. */
5508 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5509 {
5510 switch (get_attr_type (insn))
5511 {
5512 case TYPE_INCDEC:
5513 if (operands[2] == const1_rtx)
5514 return "inc{l}\t%k0";
5515 else
5516 {
5517 gcc_assert (operands[2] == constm1_rtx);
5518 return "dec{l}\t%k0";
5519 }
5520
5521 default:
5522 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5523 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5524 if (GET_CODE (operands[2]) == CONST_INT
5525 && (INTVAL (operands[2]) == 128
5526 || (INTVAL (operands[2]) < 0
5527 && INTVAL (operands[2]) != -128)))
5528 {
5529 operands[2] = GEN_INT (-INTVAL (operands[2]));
5530 return "sub{l}\t{%2, %k0|%k0, %2}";
5531 }
5532 return "add{l}\t{%2, %k0|%k0, %2}";
5533 }
5534 }
5535 [(set (attr "type")
5536 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5537 (const_string "incdec")
5538 (const_string "alu")))
5539 (set_attr "mode" "SI")])
5540
5541 (define_insn "*addsi_3"
5542 [(set (reg FLAGS_REG)
5543 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5544 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5545 (clobber (match_scratch:SI 0 "=r"))]
5546 "ix86_match_ccmode (insn, CCZmode)
5547 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5548 /* Current assemblers are broken and do not allow @GOTOFF in
5549 ought but a memory context. */
5550 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5551 {
5552 switch (get_attr_type (insn))
5553 {
5554 case TYPE_INCDEC:
5555 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5556 if (operands[2] == const1_rtx)
5557 return "inc{l}\t%0";
5558 else
5559 {
5560 gcc_assert (operands[2] == constm1_rtx);
5561 return "dec{l}\t%0";
5562 }
5563
5564 default:
5565 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5566 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5567 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5568 if (GET_CODE (operands[2]) == CONST_INT
5569 && (INTVAL (operands[2]) == 128
5570 || (INTVAL (operands[2]) < 0
5571 && INTVAL (operands[2]) != -128)))
5572 {
5573 operands[2] = GEN_INT (-INTVAL (operands[2]));
5574 return "sub{l}\t{%2, %0|%0, %2}";
5575 }
5576 return "add{l}\t{%2, %0|%0, %2}";
5577 }
5578 }
5579 [(set (attr "type")
5580 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5581 (const_string "incdec")
5582 (const_string "alu")))
5583 (set_attr "mode" "SI")])
5584
5585 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5586 (define_insn "*addsi_3_zext"
5587 [(set (reg FLAGS_REG)
5588 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5589 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5590 (set (match_operand:DI 0 "register_operand" "=r")
5591 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5592 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5593 && ix86_binary_operator_ok (PLUS, SImode, operands)
5594 /* Current assemblers are broken and do not allow @GOTOFF in
5595 ought but a memory context. */
5596 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5597 {
5598 switch (get_attr_type (insn))
5599 {
5600 case TYPE_INCDEC:
5601 if (operands[2] == const1_rtx)
5602 return "inc{l}\t%k0";
5603 else
5604 {
5605 gcc_assert (operands[2] == constm1_rtx);
5606 return "dec{l}\t%k0";
5607 }
5608
5609 default:
5610 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5611 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5612 if (GET_CODE (operands[2]) == CONST_INT
5613 && (INTVAL (operands[2]) == 128
5614 || (INTVAL (operands[2]) < 0
5615 && INTVAL (operands[2]) != -128)))
5616 {
5617 operands[2] = GEN_INT (-INTVAL (operands[2]));
5618 return "sub{l}\t{%2, %k0|%k0, %2}";
5619 }
5620 return "add{l}\t{%2, %k0|%k0, %2}";
5621 }
5622 }
5623 [(set (attr "type")
5624 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5625 (const_string "incdec")
5626 (const_string "alu")))
5627 (set_attr "mode" "SI")])
5628
5629 ; For comparisons against 1, -1 and 128, we may generate better code
5630 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5631 ; is matched then. We can't accept general immediate, because for
5632 ; case of overflows, the result is messed up.
5633 ; This pattern also don't hold of 0x80000000, since the value overflows
5634 ; when negated.
5635 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5636 ; only for comparisons not depending on it.
5637 (define_insn "*addsi_4"
5638 [(set (reg FLAGS_REG)
5639 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5640 (match_operand:SI 2 "const_int_operand" "n")))
5641 (clobber (match_scratch:SI 0 "=rm"))]
5642 "ix86_match_ccmode (insn, CCGCmode)
5643 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5644 {
5645 switch (get_attr_type (insn))
5646 {
5647 case TYPE_INCDEC:
5648 if (operands[2] == constm1_rtx)
5649 return "inc{l}\t%0";
5650 else
5651 {
5652 gcc_assert (operands[2] == const1_rtx);
5653 return "dec{l}\t%0";
5654 }
5655
5656 default:
5657 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5658 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5659 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5660 if ((INTVAL (operands[2]) == -128
5661 || (INTVAL (operands[2]) > 0
5662 && INTVAL (operands[2]) != 128)))
5663 return "sub{l}\t{%2, %0|%0, %2}";
5664 operands[2] = GEN_INT (-INTVAL (operands[2]));
5665 return "add{l}\t{%2, %0|%0, %2}";
5666 }
5667 }
5668 [(set (attr "type")
5669 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5670 (const_string "incdec")
5671 (const_string "alu")))
5672 (set_attr "mode" "SI")])
5673
5674 (define_insn "*addsi_5"
5675 [(set (reg FLAGS_REG)
5676 (compare
5677 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5678 (match_operand:SI 2 "general_operand" "rmni"))
5679 (const_int 0)))
5680 (clobber (match_scratch:SI 0 "=r"))]
5681 "ix86_match_ccmode (insn, CCGOCmode)
5682 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5683 /* Current assemblers are broken and do not allow @GOTOFF in
5684 ought but a memory context. */
5685 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5686 {
5687 switch (get_attr_type (insn))
5688 {
5689 case TYPE_INCDEC:
5690 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5691 if (operands[2] == const1_rtx)
5692 return "inc{l}\t%0";
5693 else
5694 {
5695 gcc_assert (operands[2] == constm1_rtx);
5696 return "dec{l}\t%0";
5697 }
5698
5699 default:
5700 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5701 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5702 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5703 if (GET_CODE (operands[2]) == CONST_INT
5704 && (INTVAL (operands[2]) == 128
5705 || (INTVAL (operands[2]) < 0
5706 && INTVAL (operands[2]) != -128)))
5707 {
5708 operands[2] = GEN_INT (-INTVAL (operands[2]));
5709 return "sub{l}\t{%2, %0|%0, %2}";
5710 }
5711 return "add{l}\t{%2, %0|%0, %2}";
5712 }
5713 }
5714 [(set (attr "type")
5715 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5716 (const_string "incdec")
5717 (const_string "alu")))
5718 (set_attr "mode" "SI")])
5719
5720 (define_expand "addhi3"
5721 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5722 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5723 (match_operand:HI 2 "general_operand" "")))
5724 (clobber (reg:CC FLAGS_REG))])]
5725 "TARGET_HIMODE_MATH"
5726 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5727
5728 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5729 ;; type optimizations enabled by define-splits. This is not important
5730 ;; for PII, and in fact harmful because of partial register stalls.
5731
5732 (define_insn "*addhi_1_lea"
5733 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5734 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5735 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5736 (clobber (reg:CC FLAGS_REG))]
5737 "!TARGET_PARTIAL_REG_STALL
5738 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5739 {
5740 switch (get_attr_type (insn))
5741 {
5742 case TYPE_LEA:
5743 return "#";
5744 case TYPE_INCDEC:
5745 if (operands[2] == const1_rtx)
5746 return "inc{w}\t%0";
5747 else
5748 {
5749 gcc_assert (operands[2] == constm1_rtx);
5750 return "dec{w}\t%0";
5751 }
5752
5753 default:
5754 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5755 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5756 if (GET_CODE (operands[2]) == CONST_INT
5757 && (INTVAL (operands[2]) == 128
5758 || (INTVAL (operands[2]) < 0
5759 && INTVAL (operands[2]) != -128)))
5760 {
5761 operands[2] = GEN_INT (-INTVAL (operands[2]));
5762 return "sub{w}\t{%2, %0|%0, %2}";
5763 }
5764 return "add{w}\t{%2, %0|%0, %2}";
5765 }
5766 }
5767 [(set (attr "type")
5768 (if_then_else (eq_attr "alternative" "2")
5769 (const_string "lea")
5770 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5771 (const_string "incdec")
5772 (const_string "alu"))))
5773 (set_attr "mode" "HI,HI,SI")])
5774
5775 (define_insn "*addhi_1"
5776 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5777 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5778 (match_operand:HI 2 "general_operand" "ri,rm")))
5779 (clobber (reg:CC FLAGS_REG))]
5780 "TARGET_PARTIAL_REG_STALL
5781 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5782 {
5783 switch (get_attr_type (insn))
5784 {
5785 case TYPE_INCDEC:
5786 if (operands[2] == const1_rtx)
5787 return "inc{w}\t%0";
5788 else
5789 {
5790 gcc_assert (operands[2] == constm1_rtx);
5791 return "dec{w}\t%0";
5792 }
5793
5794 default:
5795 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5796 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5797 if (GET_CODE (operands[2]) == CONST_INT
5798 && (INTVAL (operands[2]) == 128
5799 || (INTVAL (operands[2]) < 0
5800 && INTVAL (operands[2]) != -128)))
5801 {
5802 operands[2] = GEN_INT (-INTVAL (operands[2]));
5803 return "sub{w}\t{%2, %0|%0, %2}";
5804 }
5805 return "add{w}\t{%2, %0|%0, %2}";
5806 }
5807 }
5808 [(set (attr "type")
5809 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5810 (const_string "incdec")
5811 (const_string "alu")))
5812 (set_attr "mode" "HI")])
5813
5814 (define_insn "*addhi_2"
5815 [(set (reg FLAGS_REG)
5816 (compare
5817 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5818 (match_operand:HI 2 "general_operand" "rmni,rni"))
5819 (const_int 0)))
5820 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5821 (plus:HI (match_dup 1) (match_dup 2)))]
5822 "ix86_match_ccmode (insn, CCGOCmode)
5823 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5824 {
5825 switch (get_attr_type (insn))
5826 {
5827 case TYPE_INCDEC:
5828 if (operands[2] == const1_rtx)
5829 return "inc{w}\t%0";
5830 else
5831 {
5832 gcc_assert (operands[2] == constm1_rtx);
5833 return "dec{w}\t%0";
5834 }
5835
5836 default:
5837 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5838 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5839 if (GET_CODE (operands[2]) == CONST_INT
5840 && (INTVAL (operands[2]) == 128
5841 || (INTVAL (operands[2]) < 0
5842 && INTVAL (operands[2]) != -128)))
5843 {
5844 operands[2] = GEN_INT (-INTVAL (operands[2]));
5845 return "sub{w}\t{%2, %0|%0, %2}";
5846 }
5847 return "add{w}\t{%2, %0|%0, %2}";
5848 }
5849 }
5850 [(set (attr "type")
5851 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5852 (const_string "incdec")
5853 (const_string "alu")))
5854 (set_attr "mode" "HI")])
5855
5856 (define_insn "*addhi_3"
5857 [(set (reg FLAGS_REG)
5858 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5859 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5860 (clobber (match_scratch:HI 0 "=r"))]
5861 "ix86_match_ccmode (insn, CCZmode)
5862 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5863 {
5864 switch (get_attr_type (insn))
5865 {
5866 case TYPE_INCDEC:
5867 if (operands[2] == const1_rtx)
5868 return "inc{w}\t%0";
5869 else
5870 {
5871 gcc_assert (operands[2] == constm1_rtx);
5872 return "dec{w}\t%0";
5873 }
5874
5875 default:
5876 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5877 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5878 if (GET_CODE (operands[2]) == CONST_INT
5879 && (INTVAL (operands[2]) == 128
5880 || (INTVAL (operands[2]) < 0
5881 && INTVAL (operands[2]) != -128)))
5882 {
5883 operands[2] = GEN_INT (-INTVAL (operands[2]));
5884 return "sub{w}\t{%2, %0|%0, %2}";
5885 }
5886 return "add{w}\t{%2, %0|%0, %2}";
5887 }
5888 }
5889 [(set (attr "type")
5890 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5891 (const_string "incdec")
5892 (const_string "alu")))
5893 (set_attr "mode" "HI")])
5894
5895 ; See comments above addsi_4 for details.
5896 (define_insn "*addhi_4"
5897 [(set (reg FLAGS_REG)
5898 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5899 (match_operand:HI 2 "const_int_operand" "n")))
5900 (clobber (match_scratch:HI 0 "=rm"))]
5901 "ix86_match_ccmode (insn, CCGCmode)
5902 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5903 {
5904 switch (get_attr_type (insn))
5905 {
5906 case TYPE_INCDEC:
5907 if (operands[2] == constm1_rtx)
5908 return "inc{w}\t%0";
5909 else
5910 {
5911 gcc_assert (operands[2] == const1_rtx);
5912 return "dec{w}\t%0";
5913 }
5914
5915 default:
5916 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5917 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5918 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5919 if ((INTVAL (operands[2]) == -128
5920 || (INTVAL (operands[2]) > 0
5921 && INTVAL (operands[2]) != 128)))
5922 return "sub{w}\t{%2, %0|%0, %2}";
5923 operands[2] = GEN_INT (-INTVAL (operands[2]));
5924 return "add{w}\t{%2, %0|%0, %2}";
5925 }
5926 }
5927 [(set (attr "type")
5928 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5929 (const_string "incdec")
5930 (const_string "alu")))
5931 (set_attr "mode" "SI")])
5932
5933
5934 (define_insn "*addhi_5"
5935 [(set (reg FLAGS_REG)
5936 (compare
5937 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5938 (match_operand:HI 2 "general_operand" "rmni"))
5939 (const_int 0)))
5940 (clobber (match_scratch:HI 0 "=r"))]
5941 "ix86_match_ccmode (insn, CCGOCmode)
5942 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5943 {
5944 switch (get_attr_type (insn))
5945 {
5946 case TYPE_INCDEC:
5947 if (operands[2] == const1_rtx)
5948 return "inc{w}\t%0";
5949 else
5950 {
5951 gcc_assert (operands[2] == constm1_rtx);
5952 return "dec{w}\t%0";
5953 }
5954
5955 default:
5956 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5957 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5958 if (GET_CODE (operands[2]) == CONST_INT
5959 && (INTVAL (operands[2]) == 128
5960 || (INTVAL (operands[2]) < 0
5961 && INTVAL (operands[2]) != -128)))
5962 {
5963 operands[2] = GEN_INT (-INTVAL (operands[2]));
5964 return "sub{w}\t{%2, %0|%0, %2}";
5965 }
5966 return "add{w}\t{%2, %0|%0, %2}";
5967 }
5968 }
5969 [(set (attr "type")
5970 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5971 (const_string "incdec")
5972 (const_string "alu")))
5973 (set_attr "mode" "HI")])
5974
5975 (define_expand "addqi3"
5976 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5977 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5978 (match_operand:QI 2 "general_operand" "")))
5979 (clobber (reg:CC FLAGS_REG))])]
5980 "TARGET_QIMODE_MATH"
5981 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5982
5983 ;; %%% Potential partial reg stall on alternative 2. What to do?
5984 (define_insn "*addqi_1_lea"
5985 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5986 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5987 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
5988 (clobber (reg:CC FLAGS_REG))]
5989 "!TARGET_PARTIAL_REG_STALL
5990 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5991 {
5992 int widen = (which_alternative == 2);
5993 switch (get_attr_type (insn))
5994 {
5995 case TYPE_LEA:
5996 return "#";
5997 case TYPE_INCDEC:
5998 if (operands[2] == const1_rtx)
5999 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6000 else
6001 {
6002 gcc_assert (operands[2] == constm1_rtx);
6003 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6004 }
6005
6006 default:
6007 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6008 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6009 if (GET_CODE (operands[2]) == CONST_INT
6010 && (INTVAL (operands[2]) == 128
6011 || (INTVAL (operands[2]) < 0
6012 && INTVAL (operands[2]) != -128)))
6013 {
6014 operands[2] = GEN_INT (-INTVAL (operands[2]));
6015 if (widen)
6016 return "sub{l}\t{%2, %k0|%k0, %2}";
6017 else
6018 return "sub{b}\t{%2, %0|%0, %2}";
6019 }
6020 if (widen)
6021 return "add{l}\t{%k2, %k0|%k0, %k2}";
6022 else
6023 return "add{b}\t{%2, %0|%0, %2}";
6024 }
6025 }
6026 [(set (attr "type")
6027 (if_then_else (eq_attr "alternative" "3")
6028 (const_string "lea")
6029 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6030 (const_string "incdec")
6031 (const_string "alu"))))
6032 (set_attr "mode" "QI,QI,SI,SI")])
6033
6034 (define_insn "*addqi_1"
6035 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6036 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6037 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6038 (clobber (reg:CC FLAGS_REG))]
6039 "TARGET_PARTIAL_REG_STALL
6040 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6041 {
6042 int widen = (which_alternative == 2);
6043 switch (get_attr_type (insn))
6044 {
6045 case TYPE_INCDEC:
6046 if (operands[2] == const1_rtx)
6047 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6048 else
6049 {
6050 gcc_assert (operands[2] == constm1_rtx);
6051 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6052 }
6053
6054 default:
6055 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6056 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6057 if (GET_CODE (operands[2]) == CONST_INT
6058 && (INTVAL (operands[2]) == 128
6059 || (INTVAL (operands[2]) < 0
6060 && INTVAL (operands[2]) != -128)))
6061 {
6062 operands[2] = GEN_INT (-INTVAL (operands[2]));
6063 if (widen)
6064 return "sub{l}\t{%2, %k0|%k0, %2}";
6065 else
6066 return "sub{b}\t{%2, %0|%0, %2}";
6067 }
6068 if (widen)
6069 return "add{l}\t{%k2, %k0|%k0, %k2}";
6070 else
6071 return "add{b}\t{%2, %0|%0, %2}";
6072 }
6073 }
6074 [(set (attr "type")
6075 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6076 (const_string "incdec")
6077 (const_string "alu")))
6078 (set_attr "mode" "QI,QI,SI")])
6079
6080 (define_insn "*addqi_1_slp"
6081 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6082 (plus:QI (match_dup 0)
6083 (match_operand:QI 1 "general_operand" "qn,qnm")))
6084 (clobber (reg:CC FLAGS_REG))]
6085 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6086 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6087 {
6088 switch (get_attr_type (insn))
6089 {
6090 case TYPE_INCDEC:
6091 if (operands[1] == const1_rtx)
6092 return "inc{b}\t%0";
6093 else
6094 {
6095 gcc_assert (operands[1] == constm1_rtx);
6096 return "dec{b}\t%0";
6097 }
6098
6099 default:
6100 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6101 if (GET_CODE (operands[1]) == CONST_INT
6102 && INTVAL (operands[1]) < 0)
6103 {
6104 operands[1] = GEN_INT (-INTVAL (operands[1]));
6105 return "sub{b}\t{%1, %0|%0, %1}";
6106 }
6107 return "add{b}\t{%1, %0|%0, %1}";
6108 }
6109 }
6110 [(set (attr "type")
6111 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6112 (const_string "incdec")
6113 (const_string "alu1")))
6114 (set (attr "memory")
6115 (if_then_else (match_operand 1 "memory_operand" "")
6116 (const_string "load")
6117 (const_string "none")))
6118 (set_attr "mode" "QI")])
6119
6120 (define_insn "*addqi_2"
6121 [(set (reg FLAGS_REG)
6122 (compare
6123 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6124 (match_operand:QI 2 "general_operand" "qmni,qni"))
6125 (const_int 0)))
6126 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6127 (plus:QI (match_dup 1) (match_dup 2)))]
6128 "ix86_match_ccmode (insn, CCGOCmode)
6129 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6130 {
6131 switch (get_attr_type (insn))
6132 {
6133 case TYPE_INCDEC:
6134 if (operands[2] == const1_rtx)
6135 return "inc{b}\t%0";
6136 else
6137 {
6138 gcc_assert (operands[2] == constm1_rtx
6139 || (GET_CODE (operands[2]) == CONST_INT
6140 && INTVAL (operands[2]) == 255));
6141 return "dec{b}\t%0";
6142 }
6143
6144 default:
6145 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6146 if (GET_CODE (operands[2]) == CONST_INT
6147 && INTVAL (operands[2]) < 0)
6148 {
6149 operands[2] = GEN_INT (-INTVAL (operands[2]));
6150 return "sub{b}\t{%2, %0|%0, %2}";
6151 }
6152 return "add{b}\t{%2, %0|%0, %2}";
6153 }
6154 }
6155 [(set (attr "type")
6156 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6157 (const_string "incdec")
6158 (const_string "alu")))
6159 (set_attr "mode" "QI")])
6160
6161 (define_insn "*addqi_3"
6162 [(set (reg FLAGS_REG)
6163 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6164 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6165 (clobber (match_scratch:QI 0 "=q"))]
6166 "ix86_match_ccmode (insn, CCZmode)
6167 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6168 {
6169 switch (get_attr_type (insn))
6170 {
6171 case TYPE_INCDEC:
6172 if (operands[2] == const1_rtx)
6173 return "inc{b}\t%0";
6174 else
6175 {
6176 gcc_assert (operands[2] == constm1_rtx
6177 || (GET_CODE (operands[2]) == CONST_INT
6178 && INTVAL (operands[2]) == 255));
6179 return "dec{b}\t%0";
6180 }
6181
6182 default:
6183 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6184 if (GET_CODE (operands[2]) == CONST_INT
6185 && INTVAL (operands[2]) < 0)
6186 {
6187 operands[2] = GEN_INT (-INTVAL (operands[2]));
6188 return "sub{b}\t{%2, %0|%0, %2}";
6189 }
6190 return "add{b}\t{%2, %0|%0, %2}";
6191 }
6192 }
6193 [(set (attr "type")
6194 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6195 (const_string "incdec")
6196 (const_string "alu")))
6197 (set_attr "mode" "QI")])
6198
6199 ; See comments above addsi_4 for details.
6200 (define_insn "*addqi_4"
6201 [(set (reg FLAGS_REG)
6202 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6203 (match_operand:QI 2 "const_int_operand" "n")))
6204 (clobber (match_scratch:QI 0 "=qm"))]
6205 "ix86_match_ccmode (insn, CCGCmode)
6206 && (INTVAL (operands[2]) & 0xff) != 0x80"
6207 {
6208 switch (get_attr_type (insn))
6209 {
6210 case TYPE_INCDEC:
6211 if (operands[2] == constm1_rtx
6212 || (GET_CODE (operands[2]) == CONST_INT
6213 && INTVAL (operands[2]) == 255))
6214 return "inc{b}\t%0";
6215 else
6216 {
6217 gcc_assert (operands[2] == const1_rtx);
6218 return "dec{b}\t%0";
6219 }
6220
6221 default:
6222 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6223 if (INTVAL (operands[2]) < 0)
6224 {
6225 operands[2] = GEN_INT (-INTVAL (operands[2]));
6226 return "add{b}\t{%2, %0|%0, %2}";
6227 }
6228 return "sub{b}\t{%2, %0|%0, %2}";
6229 }
6230 }
6231 [(set (attr "type")
6232 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6233 (const_string "incdec")
6234 (const_string "alu")))
6235 (set_attr "mode" "QI")])
6236
6237
6238 (define_insn "*addqi_5"
6239 [(set (reg FLAGS_REG)
6240 (compare
6241 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6242 (match_operand:QI 2 "general_operand" "qmni"))
6243 (const_int 0)))
6244 (clobber (match_scratch:QI 0 "=q"))]
6245 "ix86_match_ccmode (insn, CCGOCmode)
6246 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6247 {
6248 switch (get_attr_type (insn))
6249 {
6250 case TYPE_INCDEC:
6251 if (operands[2] == const1_rtx)
6252 return "inc{b}\t%0";
6253 else
6254 {
6255 gcc_assert (operands[2] == constm1_rtx
6256 || (GET_CODE (operands[2]) == CONST_INT
6257 && INTVAL (operands[2]) == 255));
6258 return "dec{b}\t%0";
6259 }
6260
6261 default:
6262 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6263 if (GET_CODE (operands[2]) == CONST_INT
6264 && INTVAL (operands[2]) < 0)
6265 {
6266 operands[2] = GEN_INT (-INTVAL (operands[2]));
6267 return "sub{b}\t{%2, %0|%0, %2}";
6268 }
6269 return "add{b}\t{%2, %0|%0, %2}";
6270 }
6271 }
6272 [(set (attr "type")
6273 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6274 (const_string "incdec")
6275 (const_string "alu")))
6276 (set_attr "mode" "QI")])
6277
6278
6279 (define_insn "addqi_ext_1"
6280 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6281 (const_int 8)
6282 (const_int 8))
6283 (plus:SI
6284 (zero_extract:SI
6285 (match_operand 1 "ext_register_operand" "0")
6286 (const_int 8)
6287 (const_int 8))
6288 (match_operand:QI 2 "general_operand" "Qmn")))
6289 (clobber (reg:CC FLAGS_REG))]
6290 "!TARGET_64BIT"
6291 {
6292 switch (get_attr_type (insn))
6293 {
6294 case TYPE_INCDEC:
6295 if (operands[2] == const1_rtx)
6296 return "inc{b}\t%h0";
6297 else
6298 {
6299 gcc_assert (operands[2] == constm1_rtx
6300 || (GET_CODE (operands[2]) == CONST_INT
6301 && INTVAL (operands[2]) == 255));
6302 return "dec{b}\t%h0";
6303 }
6304
6305 default:
6306 return "add{b}\t{%2, %h0|%h0, %2}";
6307 }
6308 }
6309 [(set (attr "type")
6310 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6311 (const_string "incdec")
6312 (const_string "alu")))
6313 (set_attr "mode" "QI")])
6314
6315 (define_insn "*addqi_ext_1_rex64"
6316 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6317 (const_int 8)
6318 (const_int 8))
6319 (plus:SI
6320 (zero_extract:SI
6321 (match_operand 1 "ext_register_operand" "0")
6322 (const_int 8)
6323 (const_int 8))
6324 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6325 (clobber (reg:CC FLAGS_REG))]
6326 "TARGET_64BIT"
6327 {
6328 switch (get_attr_type (insn))
6329 {
6330 case TYPE_INCDEC:
6331 if (operands[2] == const1_rtx)
6332 return "inc{b}\t%h0";
6333 else
6334 {
6335 gcc_assert (operands[2] == constm1_rtx
6336 || (GET_CODE (operands[2]) == CONST_INT
6337 && INTVAL (operands[2]) == 255));
6338 return "dec{b}\t%h0";
6339 }
6340
6341 default:
6342 return "add{b}\t{%2, %h0|%h0, %2}";
6343 }
6344 }
6345 [(set (attr "type")
6346 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6347 (const_string "incdec")
6348 (const_string "alu")))
6349 (set_attr "mode" "QI")])
6350
6351 (define_insn "*addqi_ext_2"
6352 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6353 (const_int 8)
6354 (const_int 8))
6355 (plus:SI
6356 (zero_extract:SI
6357 (match_operand 1 "ext_register_operand" "%0")
6358 (const_int 8)
6359 (const_int 8))
6360 (zero_extract:SI
6361 (match_operand 2 "ext_register_operand" "Q")
6362 (const_int 8)
6363 (const_int 8))))
6364 (clobber (reg:CC FLAGS_REG))]
6365 ""
6366 "add{b}\t{%h2, %h0|%h0, %h2}"
6367 [(set_attr "type" "alu")
6368 (set_attr "mode" "QI")])
6369
6370 ;; The patterns that match these are at the end of this file.
6371
6372 (define_expand "addxf3"
6373 [(set (match_operand:XF 0 "register_operand" "")
6374 (plus:XF (match_operand:XF 1 "register_operand" "")
6375 (match_operand:XF 2 "register_operand" "")))]
6376 "TARGET_80387"
6377 "")
6378
6379 (define_expand "adddf3"
6380 [(set (match_operand:DF 0 "register_operand" "")
6381 (plus:DF (match_operand:DF 1 "register_operand" "")
6382 (match_operand:DF 2 "nonimmediate_operand" "")))]
6383 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6384 "")
6385
6386 (define_expand "addsf3"
6387 [(set (match_operand:SF 0 "register_operand" "")
6388 (plus:SF (match_operand:SF 1 "register_operand" "")
6389 (match_operand:SF 2 "nonimmediate_operand" "")))]
6390 "TARGET_80387 || TARGET_SSE_MATH"
6391 "")
6392 \f
6393 ;; Subtract instructions
6394
6395 ;; %%% splits for subsidi3
6396
6397 (define_expand "subdi3"
6398 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6399 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6400 (match_operand:DI 2 "x86_64_general_operand" "")))
6401 (clobber (reg:CC FLAGS_REG))])]
6402 ""
6403 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6404
6405 (define_insn "*subdi3_1"
6406 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6407 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6408 (match_operand:DI 2 "general_operand" "roiF,riF")))
6409 (clobber (reg:CC FLAGS_REG))]
6410 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6411 "#")
6412
6413 (define_split
6414 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6415 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6416 (match_operand:DI 2 "general_operand" "")))
6417 (clobber (reg:CC FLAGS_REG))]
6418 "!TARGET_64BIT && reload_completed"
6419 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6420 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6421 (parallel [(set (match_dup 3)
6422 (minus:SI (match_dup 4)
6423 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6424 (match_dup 5))))
6425 (clobber (reg:CC FLAGS_REG))])]
6426 "split_di (operands+0, 1, operands+0, operands+3);
6427 split_di (operands+1, 1, operands+1, operands+4);
6428 split_di (operands+2, 1, operands+2, operands+5);")
6429
6430 (define_insn "subdi3_carry_rex64"
6431 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6432 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6433 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6434 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6435 (clobber (reg:CC FLAGS_REG))]
6436 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6437 "sbb{q}\t{%2, %0|%0, %2}"
6438 [(set_attr "type" "alu")
6439 (set_attr "pent_pair" "pu")
6440 (set_attr "mode" "DI")])
6441
6442 (define_insn "*subdi_1_rex64"
6443 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6444 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6445 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6446 (clobber (reg:CC FLAGS_REG))]
6447 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6448 "sub{q}\t{%2, %0|%0, %2}"
6449 [(set_attr "type" "alu")
6450 (set_attr "mode" "DI")])
6451
6452 (define_insn "*subdi_2_rex64"
6453 [(set (reg FLAGS_REG)
6454 (compare
6455 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6456 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6457 (const_int 0)))
6458 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6459 (minus:DI (match_dup 1) (match_dup 2)))]
6460 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6461 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6462 "sub{q}\t{%2, %0|%0, %2}"
6463 [(set_attr "type" "alu")
6464 (set_attr "mode" "DI")])
6465
6466 (define_insn "*subdi_3_rex63"
6467 [(set (reg FLAGS_REG)
6468 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6469 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6470 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6471 (minus:DI (match_dup 1) (match_dup 2)))]
6472 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6473 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6474 "sub{q}\t{%2, %0|%0, %2}"
6475 [(set_attr "type" "alu")
6476 (set_attr "mode" "DI")])
6477
6478 (define_insn "subqi3_carry"
6479 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6480 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6481 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6482 (match_operand:QI 2 "general_operand" "qi,qm"))))
6483 (clobber (reg:CC FLAGS_REG))]
6484 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6485 "sbb{b}\t{%2, %0|%0, %2}"
6486 [(set_attr "type" "alu")
6487 (set_attr "pent_pair" "pu")
6488 (set_attr "mode" "QI")])
6489
6490 (define_insn "subhi3_carry"
6491 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6492 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6493 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6494 (match_operand:HI 2 "general_operand" "ri,rm"))))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6497 "sbb{w}\t{%2, %0|%0, %2}"
6498 [(set_attr "type" "alu")
6499 (set_attr "pent_pair" "pu")
6500 (set_attr "mode" "HI")])
6501
6502 (define_insn "subsi3_carry"
6503 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6504 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6505 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6506 (match_operand:SI 2 "general_operand" "ri,rm"))))
6507 (clobber (reg:CC FLAGS_REG))]
6508 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6509 "sbb{l}\t{%2, %0|%0, %2}"
6510 [(set_attr "type" "alu")
6511 (set_attr "pent_pair" "pu")
6512 (set_attr "mode" "SI")])
6513
6514 (define_insn "subsi3_carry_zext"
6515 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6516 (zero_extend:DI
6517 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6518 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6519 (match_operand:SI 2 "general_operand" "ri,rm")))))
6520 (clobber (reg:CC FLAGS_REG))]
6521 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6522 "sbb{l}\t{%2, %k0|%k0, %2}"
6523 [(set_attr "type" "alu")
6524 (set_attr "pent_pair" "pu")
6525 (set_attr "mode" "SI")])
6526
6527 (define_expand "subsi3"
6528 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6529 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6530 (match_operand:SI 2 "general_operand" "")))
6531 (clobber (reg:CC FLAGS_REG))])]
6532 ""
6533 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6534
6535 (define_insn "*subsi_1"
6536 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6537 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6538 (match_operand:SI 2 "general_operand" "ri,rm")))
6539 (clobber (reg:CC FLAGS_REG))]
6540 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6541 "sub{l}\t{%2, %0|%0, %2}"
6542 [(set_attr "type" "alu")
6543 (set_attr "mode" "SI")])
6544
6545 (define_insn "*subsi_1_zext"
6546 [(set (match_operand:DI 0 "register_operand" "=r")
6547 (zero_extend:DI
6548 (minus:SI (match_operand:SI 1 "register_operand" "0")
6549 (match_operand:SI 2 "general_operand" "rim"))))
6550 (clobber (reg:CC FLAGS_REG))]
6551 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6552 "sub{l}\t{%2, %k0|%k0, %2}"
6553 [(set_attr "type" "alu")
6554 (set_attr "mode" "SI")])
6555
6556 (define_insn "*subsi_2"
6557 [(set (reg FLAGS_REG)
6558 (compare
6559 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6560 (match_operand:SI 2 "general_operand" "ri,rm"))
6561 (const_int 0)))
6562 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6563 (minus:SI (match_dup 1) (match_dup 2)))]
6564 "ix86_match_ccmode (insn, CCGOCmode)
6565 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6566 "sub{l}\t{%2, %0|%0, %2}"
6567 [(set_attr "type" "alu")
6568 (set_attr "mode" "SI")])
6569
6570 (define_insn "*subsi_2_zext"
6571 [(set (reg FLAGS_REG)
6572 (compare
6573 (minus:SI (match_operand:SI 1 "register_operand" "0")
6574 (match_operand:SI 2 "general_operand" "rim"))
6575 (const_int 0)))
6576 (set (match_operand:DI 0 "register_operand" "=r")
6577 (zero_extend:DI
6578 (minus:SI (match_dup 1)
6579 (match_dup 2))))]
6580 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6581 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6582 "sub{l}\t{%2, %k0|%k0, %2}"
6583 [(set_attr "type" "alu")
6584 (set_attr "mode" "SI")])
6585
6586 (define_insn "*subsi_3"
6587 [(set (reg FLAGS_REG)
6588 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6589 (match_operand:SI 2 "general_operand" "ri,rm")))
6590 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6591 (minus:SI (match_dup 1) (match_dup 2)))]
6592 "ix86_match_ccmode (insn, CCmode)
6593 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6594 "sub{l}\t{%2, %0|%0, %2}"
6595 [(set_attr "type" "alu")
6596 (set_attr "mode" "SI")])
6597
6598 (define_insn "*subsi_3_zext"
6599 [(set (reg FLAGS_REG)
6600 (compare (match_operand:SI 1 "register_operand" "0")
6601 (match_operand:SI 2 "general_operand" "rim")))
6602 (set (match_operand:DI 0 "register_operand" "=r")
6603 (zero_extend:DI
6604 (minus:SI (match_dup 1)
6605 (match_dup 2))))]
6606 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6607 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6608 "sub{q}\t{%2, %0|%0, %2}"
6609 [(set_attr "type" "alu")
6610 (set_attr "mode" "DI")])
6611
6612 (define_expand "subhi3"
6613 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6614 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6615 (match_operand:HI 2 "general_operand" "")))
6616 (clobber (reg:CC FLAGS_REG))])]
6617 "TARGET_HIMODE_MATH"
6618 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6619
6620 (define_insn "*subhi_1"
6621 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6622 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6623 (match_operand:HI 2 "general_operand" "ri,rm")))
6624 (clobber (reg:CC FLAGS_REG))]
6625 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6626 "sub{w}\t{%2, %0|%0, %2}"
6627 [(set_attr "type" "alu")
6628 (set_attr "mode" "HI")])
6629
6630 (define_insn "*subhi_2"
6631 [(set (reg FLAGS_REG)
6632 (compare
6633 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6634 (match_operand:HI 2 "general_operand" "ri,rm"))
6635 (const_int 0)))
6636 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6637 (minus:HI (match_dup 1) (match_dup 2)))]
6638 "ix86_match_ccmode (insn, CCGOCmode)
6639 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6640 "sub{w}\t{%2, %0|%0, %2}"
6641 [(set_attr "type" "alu")
6642 (set_attr "mode" "HI")])
6643
6644 (define_insn "*subhi_3"
6645 [(set (reg FLAGS_REG)
6646 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6647 (match_operand:HI 2 "general_operand" "ri,rm")))
6648 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6649 (minus:HI (match_dup 1) (match_dup 2)))]
6650 "ix86_match_ccmode (insn, CCmode)
6651 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6652 "sub{w}\t{%2, %0|%0, %2}"
6653 [(set_attr "type" "alu")
6654 (set_attr "mode" "HI")])
6655
6656 (define_expand "subqi3"
6657 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6658 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6659 (match_operand:QI 2 "general_operand" "")))
6660 (clobber (reg:CC FLAGS_REG))])]
6661 "TARGET_QIMODE_MATH"
6662 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6663
6664 (define_insn "*subqi_1"
6665 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6666 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6667 (match_operand:QI 2 "general_operand" "qn,qmn")))
6668 (clobber (reg:CC FLAGS_REG))]
6669 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6670 "sub{b}\t{%2, %0|%0, %2}"
6671 [(set_attr "type" "alu")
6672 (set_attr "mode" "QI")])
6673
6674 (define_insn "*subqi_1_slp"
6675 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6676 (minus:QI (match_dup 0)
6677 (match_operand:QI 1 "general_operand" "qn,qmn")))
6678 (clobber (reg:CC FLAGS_REG))]
6679 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6680 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6681 "sub{b}\t{%1, %0|%0, %1}"
6682 [(set_attr "type" "alu1")
6683 (set_attr "mode" "QI")])
6684
6685 (define_insn "*subqi_2"
6686 [(set (reg FLAGS_REG)
6687 (compare
6688 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6689 (match_operand:QI 2 "general_operand" "qi,qm"))
6690 (const_int 0)))
6691 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6692 (minus:HI (match_dup 1) (match_dup 2)))]
6693 "ix86_match_ccmode (insn, CCGOCmode)
6694 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6695 "sub{b}\t{%2, %0|%0, %2}"
6696 [(set_attr "type" "alu")
6697 (set_attr "mode" "QI")])
6698
6699 (define_insn "*subqi_3"
6700 [(set (reg FLAGS_REG)
6701 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6702 (match_operand:QI 2 "general_operand" "qi,qm")))
6703 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6704 (minus:HI (match_dup 1) (match_dup 2)))]
6705 "ix86_match_ccmode (insn, CCmode)
6706 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6707 "sub{b}\t{%2, %0|%0, %2}"
6708 [(set_attr "type" "alu")
6709 (set_attr "mode" "QI")])
6710
6711 ;; The patterns that match these are at the end of this file.
6712
6713 (define_expand "subxf3"
6714 [(set (match_operand:XF 0 "register_operand" "")
6715 (minus:XF (match_operand:XF 1 "register_operand" "")
6716 (match_operand:XF 2 "register_operand" "")))]
6717 "TARGET_80387"
6718 "")
6719
6720 (define_expand "subdf3"
6721 [(set (match_operand:DF 0 "register_operand" "")
6722 (minus:DF (match_operand:DF 1 "register_operand" "")
6723 (match_operand:DF 2 "nonimmediate_operand" "")))]
6724 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6725 "")
6726
6727 (define_expand "subsf3"
6728 [(set (match_operand:SF 0 "register_operand" "")
6729 (minus:SF (match_operand:SF 1 "register_operand" "")
6730 (match_operand:SF 2 "nonimmediate_operand" "")))]
6731 "TARGET_80387 || TARGET_SSE_MATH"
6732 "")
6733 \f
6734 ;; Multiply instructions
6735
6736 (define_expand "muldi3"
6737 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6738 (mult:DI (match_operand:DI 1 "register_operand" "")
6739 (match_operand:DI 2 "x86_64_general_operand" "")))
6740 (clobber (reg:CC FLAGS_REG))])]
6741 "TARGET_64BIT"
6742 "")
6743
6744 (define_insn "*muldi3_1_rex64"
6745 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6746 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6747 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6748 (clobber (reg:CC FLAGS_REG))]
6749 "TARGET_64BIT
6750 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6751 "@
6752 imul{q}\t{%2, %1, %0|%0, %1, %2}
6753 imul{q}\t{%2, %1, %0|%0, %1, %2}
6754 imul{q}\t{%2, %0|%0, %2}"
6755 [(set_attr "type" "imul")
6756 (set_attr "prefix_0f" "0,0,1")
6757 (set (attr "athlon_decode")
6758 (cond [(eq_attr "cpu" "athlon")
6759 (const_string "vector")
6760 (eq_attr "alternative" "1")
6761 (const_string "vector")
6762 (and (eq_attr "alternative" "2")
6763 (match_operand 1 "memory_operand" ""))
6764 (const_string "vector")]
6765 (const_string "direct")))
6766 (set_attr "mode" "DI")])
6767
6768 (define_expand "mulsi3"
6769 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6770 (mult:SI (match_operand:SI 1 "register_operand" "")
6771 (match_operand:SI 2 "general_operand" "")))
6772 (clobber (reg:CC FLAGS_REG))])]
6773 ""
6774 "")
6775
6776 (define_insn "*mulsi3_1"
6777 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6778 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6779 (match_operand:SI 2 "general_operand" "K,i,mr")))
6780 (clobber (reg:CC FLAGS_REG))]
6781 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6782 "@
6783 imul{l}\t{%2, %1, %0|%0, %1, %2}
6784 imul{l}\t{%2, %1, %0|%0, %1, %2}
6785 imul{l}\t{%2, %0|%0, %2}"
6786 [(set_attr "type" "imul")
6787 (set_attr "prefix_0f" "0,0,1")
6788 (set (attr "athlon_decode")
6789 (cond [(eq_attr "cpu" "athlon")
6790 (const_string "vector")
6791 (eq_attr "alternative" "1")
6792 (const_string "vector")
6793 (and (eq_attr "alternative" "2")
6794 (match_operand 1 "memory_operand" ""))
6795 (const_string "vector")]
6796 (const_string "direct")))
6797 (set_attr "mode" "SI")])
6798
6799 (define_insn "*mulsi3_1_zext"
6800 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6801 (zero_extend:DI
6802 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6803 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6804 (clobber (reg:CC FLAGS_REG))]
6805 "TARGET_64BIT
6806 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6807 "@
6808 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6809 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6810 imul{l}\t{%2, %k0|%k0, %2}"
6811 [(set_attr "type" "imul")
6812 (set_attr "prefix_0f" "0,0,1")
6813 (set (attr "athlon_decode")
6814 (cond [(eq_attr "cpu" "athlon")
6815 (const_string "vector")
6816 (eq_attr "alternative" "1")
6817 (const_string "vector")
6818 (and (eq_attr "alternative" "2")
6819 (match_operand 1 "memory_operand" ""))
6820 (const_string "vector")]
6821 (const_string "direct")))
6822 (set_attr "mode" "SI")])
6823
6824 (define_expand "mulhi3"
6825 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6826 (mult:HI (match_operand:HI 1 "register_operand" "")
6827 (match_operand:HI 2 "general_operand" "")))
6828 (clobber (reg:CC FLAGS_REG))])]
6829 "TARGET_HIMODE_MATH"
6830 "")
6831
6832 (define_insn "*mulhi3_1"
6833 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6834 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6835 (match_operand:HI 2 "general_operand" "K,i,mr")))
6836 (clobber (reg:CC FLAGS_REG))]
6837 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6838 "@
6839 imul{w}\t{%2, %1, %0|%0, %1, %2}
6840 imul{w}\t{%2, %1, %0|%0, %1, %2}
6841 imul{w}\t{%2, %0|%0, %2}"
6842 [(set_attr "type" "imul")
6843 (set_attr "prefix_0f" "0,0,1")
6844 (set (attr "athlon_decode")
6845 (cond [(eq_attr "cpu" "athlon")
6846 (const_string "vector")
6847 (eq_attr "alternative" "1,2")
6848 (const_string "vector")]
6849 (const_string "direct")))
6850 (set_attr "mode" "HI")])
6851
6852 (define_expand "mulqi3"
6853 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6854 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6855 (match_operand:QI 2 "register_operand" "")))
6856 (clobber (reg:CC FLAGS_REG))])]
6857 "TARGET_QIMODE_MATH"
6858 "")
6859
6860 (define_insn "*mulqi3_1"
6861 [(set (match_operand:QI 0 "register_operand" "=a")
6862 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6863 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6864 (clobber (reg:CC FLAGS_REG))]
6865 "TARGET_QIMODE_MATH
6866 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6867 "mul{b}\t%2"
6868 [(set_attr "type" "imul")
6869 (set_attr "length_immediate" "0")
6870 (set (attr "athlon_decode")
6871 (if_then_else (eq_attr "cpu" "athlon")
6872 (const_string "vector")
6873 (const_string "direct")))
6874 (set_attr "mode" "QI")])
6875
6876 (define_expand "umulqihi3"
6877 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6878 (mult:HI (zero_extend:HI
6879 (match_operand:QI 1 "nonimmediate_operand" ""))
6880 (zero_extend:HI
6881 (match_operand:QI 2 "register_operand" ""))))
6882 (clobber (reg:CC FLAGS_REG))])]
6883 "TARGET_QIMODE_MATH"
6884 "")
6885
6886 (define_insn "*umulqihi3_1"
6887 [(set (match_operand:HI 0 "register_operand" "=a")
6888 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6889 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6890 (clobber (reg:CC FLAGS_REG))]
6891 "TARGET_QIMODE_MATH
6892 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6893 "mul{b}\t%2"
6894 [(set_attr "type" "imul")
6895 (set_attr "length_immediate" "0")
6896 (set (attr "athlon_decode")
6897 (if_then_else (eq_attr "cpu" "athlon")
6898 (const_string "vector")
6899 (const_string "direct")))
6900 (set_attr "mode" "QI")])
6901
6902 (define_expand "mulqihi3"
6903 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6904 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6905 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6906 (clobber (reg:CC FLAGS_REG))])]
6907 "TARGET_QIMODE_MATH"
6908 "")
6909
6910 (define_insn "*mulqihi3_insn"
6911 [(set (match_operand:HI 0 "register_operand" "=a")
6912 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6913 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6914 (clobber (reg:CC FLAGS_REG))]
6915 "TARGET_QIMODE_MATH
6916 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6917 "imul{b}\t%2"
6918 [(set_attr "type" "imul")
6919 (set_attr "length_immediate" "0")
6920 (set (attr "athlon_decode")
6921 (if_then_else (eq_attr "cpu" "athlon")
6922 (const_string "vector")
6923 (const_string "direct")))
6924 (set_attr "mode" "QI")])
6925
6926 (define_expand "umulditi3"
6927 [(parallel [(set (match_operand:TI 0 "register_operand" "")
6928 (mult:TI (zero_extend:TI
6929 (match_operand:DI 1 "nonimmediate_operand" ""))
6930 (zero_extend:TI
6931 (match_operand:DI 2 "register_operand" ""))))
6932 (clobber (reg:CC FLAGS_REG))])]
6933 "TARGET_64BIT"
6934 "")
6935
6936 (define_insn "*umulditi3_insn"
6937 [(set (match_operand:TI 0 "register_operand" "=A")
6938 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6939 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6940 (clobber (reg:CC FLAGS_REG))]
6941 "TARGET_64BIT
6942 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6943 "mul{q}\t%2"
6944 [(set_attr "type" "imul")
6945 (set_attr "length_immediate" "0")
6946 (set (attr "athlon_decode")
6947 (if_then_else (eq_attr "cpu" "athlon")
6948 (const_string "vector")
6949 (const_string "double")))
6950 (set_attr "mode" "DI")])
6951
6952 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6953 (define_expand "umulsidi3"
6954 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6955 (mult:DI (zero_extend:DI
6956 (match_operand:SI 1 "nonimmediate_operand" ""))
6957 (zero_extend:DI
6958 (match_operand:SI 2 "register_operand" ""))))
6959 (clobber (reg:CC FLAGS_REG))])]
6960 "!TARGET_64BIT"
6961 "")
6962
6963 (define_insn "*umulsidi3_insn"
6964 [(set (match_operand:DI 0 "register_operand" "=A")
6965 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6966 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6967 (clobber (reg:CC FLAGS_REG))]
6968 "!TARGET_64BIT
6969 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6970 "mul{l}\t%2"
6971 [(set_attr "type" "imul")
6972 (set_attr "length_immediate" "0")
6973 (set (attr "athlon_decode")
6974 (if_then_else (eq_attr "cpu" "athlon")
6975 (const_string "vector")
6976 (const_string "double")))
6977 (set_attr "mode" "SI")])
6978
6979 (define_expand "mulditi3"
6980 [(parallel [(set (match_operand:TI 0 "register_operand" "")
6981 (mult:TI (sign_extend:TI
6982 (match_operand:DI 1 "nonimmediate_operand" ""))
6983 (sign_extend:TI
6984 (match_operand:DI 2 "register_operand" ""))))
6985 (clobber (reg:CC FLAGS_REG))])]
6986 "TARGET_64BIT"
6987 "")
6988
6989 (define_insn "*mulditi3_insn"
6990 [(set (match_operand:TI 0 "register_operand" "=A")
6991 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6992 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6993 (clobber (reg:CC FLAGS_REG))]
6994 "TARGET_64BIT
6995 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6996 "imul{q}\t%2"
6997 [(set_attr "type" "imul")
6998 (set_attr "length_immediate" "0")
6999 (set (attr "athlon_decode")
7000 (if_then_else (eq_attr "cpu" "athlon")
7001 (const_string "vector")
7002 (const_string "double")))
7003 (set_attr "mode" "DI")])
7004
7005 (define_expand "mulsidi3"
7006 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7007 (mult:DI (sign_extend:DI
7008 (match_operand:SI 1 "nonimmediate_operand" ""))
7009 (sign_extend:DI
7010 (match_operand:SI 2 "register_operand" ""))))
7011 (clobber (reg:CC FLAGS_REG))])]
7012 "!TARGET_64BIT"
7013 "")
7014
7015 (define_insn "*mulsidi3_insn"
7016 [(set (match_operand:DI 0 "register_operand" "=A")
7017 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7018 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7019 (clobber (reg:CC FLAGS_REG))]
7020 "!TARGET_64BIT
7021 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7022 "imul{l}\t%2"
7023 [(set_attr "type" "imul")
7024 (set_attr "length_immediate" "0")
7025 (set (attr "athlon_decode")
7026 (if_then_else (eq_attr "cpu" "athlon")
7027 (const_string "vector")
7028 (const_string "double")))
7029 (set_attr "mode" "SI")])
7030
7031 (define_expand "umuldi3_highpart"
7032 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7033 (truncate:DI
7034 (lshiftrt:TI
7035 (mult:TI (zero_extend:TI
7036 (match_operand:DI 1 "nonimmediate_operand" ""))
7037 (zero_extend:TI
7038 (match_operand:DI 2 "register_operand" "")))
7039 (const_int 64))))
7040 (clobber (match_scratch:DI 3 ""))
7041 (clobber (reg:CC FLAGS_REG))])]
7042 "TARGET_64BIT"
7043 "")
7044
7045 (define_insn "*umuldi3_highpart_rex64"
7046 [(set (match_operand:DI 0 "register_operand" "=d")
7047 (truncate:DI
7048 (lshiftrt:TI
7049 (mult:TI (zero_extend:TI
7050 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7051 (zero_extend:TI
7052 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7053 (const_int 64))))
7054 (clobber (match_scratch:DI 3 "=1"))
7055 (clobber (reg:CC FLAGS_REG))]
7056 "TARGET_64BIT
7057 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7058 "mul{q}\t%2"
7059 [(set_attr "type" "imul")
7060 (set_attr "length_immediate" "0")
7061 (set (attr "athlon_decode")
7062 (if_then_else (eq_attr "cpu" "athlon")
7063 (const_string "vector")
7064 (const_string "double")))
7065 (set_attr "mode" "DI")])
7066
7067 (define_expand "umulsi3_highpart"
7068 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7069 (truncate:SI
7070 (lshiftrt:DI
7071 (mult:DI (zero_extend:DI
7072 (match_operand:SI 1 "nonimmediate_operand" ""))
7073 (zero_extend:DI
7074 (match_operand:SI 2 "register_operand" "")))
7075 (const_int 32))))
7076 (clobber (match_scratch:SI 3 ""))
7077 (clobber (reg:CC FLAGS_REG))])]
7078 ""
7079 "")
7080
7081 (define_insn "*umulsi3_highpart_insn"
7082 [(set (match_operand:SI 0 "register_operand" "=d")
7083 (truncate:SI
7084 (lshiftrt:DI
7085 (mult:DI (zero_extend:DI
7086 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7087 (zero_extend:DI
7088 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7089 (const_int 32))))
7090 (clobber (match_scratch:SI 3 "=1"))
7091 (clobber (reg:CC FLAGS_REG))]
7092 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7093 "mul{l}\t%2"
7094 [(set_attr "type" "imul")
7095 (set_attr "length_immediate" "0")
7096 (set (attr "athlon_decode")
7097 (if_then_else (eq_attr "cpu" "athlon")
7098 (const_string "vector")
7099 (const_string "double")))
7100 (set_attr "mode" "SI")])
7101
7102 (define_insn "*umulsi3_highpart_zext"
7103 [(set (match_operand:DI 0 "register_operand" "=d")
7104 (zero_extend:DI (truncate:SI
7105 (lshiftrt:DI
7106 (mult:DI (zero_extend:DI
7107 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7108 (zero_extend:DI
7109 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7110 (const_int 32)))))
7111 (clobber (match_scratch:SI 3 "=1"))
7112 (clobber (reg:CC FLAGS_REG))]
7113 "TARGET_64BIT
7114 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7115 "mul{l}\t%2"
7116 [(set_attr "type" "imul")
7117 (set_attr "length_immediate" "0")
7118 (set (attr "athlon_decode")
7119 (if_then_else (eq_attr "cpu" "athlon")
7120 (const_string "vector")
7121 (const_string "double")))
7122 (set_attr "mode" "SI")])
7123
7124 (define_expand "smuldi3_highpart"
7125 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7126 (truncate:DI
7127 (lshiftrt:TI
7128 (mult:TI (sign_extend:TI
7129 (match_operand:DI 1 "nonimmediate_operand" ""))
7130 (sign_extend:TI
7131 (match_operand:DI 2 "register_operand" "")))
7132 (const_int 64))))
7133 (clobber (match_scratch:DI 3 ""))
7134 (clobber (reg:CC FLAGS_REG))])]
7135 "TARGET_64BIT"
7136 "")
7137
7138 (define_insn "*smuldi3_highpart_rex64"
7139 [(set (match_operand:DI 0 "register_operand" "=d")
7140 (truncate:DI
7141 (lshiftrt:TI
7142 (mult:TI (sign_extend:TI
7143 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7144 (sign_extend:TI
7145 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7146 (const_int 64))))
7147 (clobber (match_scratch:DI 3 "=1"))
7148 (clobber (reg:CC FLAGS_REG))]
7149 "TARGET_64BIT
7150 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7151 "imul{q}\t%2"
7152 [(set_attr "type" "imul")
7153 (set (attr "athlon_decode")
7154 (if_then_else (eq_attr "cpu" "athlon")
7155 (const_string "vector")
7156 (const_string "double")))
7157 (set_attr "mode" "DI")])
7158
7159 (define_expand "smulsi3_highpart"
7160 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7161 (truncate:SI
7162 (lshiftrt:DI
7163 (mult:DI (sign_extend:DI
7164 (match_operand:SI 1 "nonimmediate_operand" ""))
7165 (sign_extend:DI
7166 (match_operand:SI 2 "register_operand" "")))
7167 (const_int 32))))
7168 (clobber (match_scratch:SI 3 ""))
7169 (clobber (reg:CC FLAGS_REG))])]
7170 ""
7171 "")
7172
7173 (define_insn "*smulsi3_highpart_insn"
7174 [(set (match_operand:SI 0 "register_operand" "=d")
7175 (truncate:SI
7176 (lshiftrt:DI
7177 (mult:DI (sign_extend:DI
7178 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7179 (sign_extend:DI
7180 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7181 (const_int 32))))
7182 (clobber (match_scratch:SI 3 "=1"))
7183 (clobber (reg:CC FLAGS_REG))]
7184 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7185 "imul{l}\t%2"
7186 [(set_attr "type" "imul")
7187 (set (attr "athlon_decode")
7188 (if_then_else (eq_attr "cpu" "athlon")
7189 (const_string "vector")
7190 (const_string "double")))
7191 (set_attr "mode" "SI")])
7192
7193 (define_insn "*smulsi3_highpart_zext"
7194 [(set (match_operand:DI 0 "register_operand" "=d")
7195 (zero_extend:DI (truncate:SI
7196 (lshiftrt:DI
7197 (mult:DI (sign_extend:DI
7198 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7199 (sign_extend:DI
7200 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7201 (const_int 32)))))
7202 (clobber (match_scratch:SI 3 "=1"))
7203 (clobber (reg:CC FLAGS_REG))]
7204 "TARGET_64BIT
7205 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7206 "imul{l}\t%2"
7207 [(set_attr "type" "imul")
7208 (set (attr "athlon_decode")
7209 (if_then_else (eq_attr "cpu" "athlon")
7210 (const_string "vector")
7211 (const_string "double")))
7212 (set_attr "mode" "SI")])
7213
7214 ;; The patterns that match these are at the end of this file.
7215
7216 (define_expand "mulxf3"
7217 [(set (match_operand:XF 0 "register_operand" "")
7218 (mult:XF (match_operand:XF 1 "register_operand" "")
7219 (match_operand:XF 2 "register_operand" "")))]
7220 "TARGET_80387"
7221 "")
7222
7223 (define_expand "muldf3"
7224 [(set (match_operand:DF 0 "register_operand" "")
7225 (mult:DF (match_operand:DF 1 "register_operand" "")
7226 (match_operand:DF 2 "nonimmediate_operand" "")))]
7227 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7228 "")
7229
7230 (define_expand "mulsf3"
7231 [(set (match_operand:SF 0 "register_operand" "")
7232 (mult:SF (match_operand:SF 1 "register_operand" "")
7233 (match_operand:SF 2 "nonimmediate_operand" "")))]
7234 "TARGET_80387 || TARGET_SSE_MATH"
7235 "")
7236 \f
7237 ;; Divide instructions
7238
7239 (define_insn "divqi3"
7240 [(set (match_operand:QI 0 "register_operand" "=a")
7241 (div:QI (match_operand:HI 1 "register_operand" "0")
7242 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7243 (clobber (reg:CC FLAGS_REG))]
7244 "TARGET_QIMODE_MATH"
7245 "idiv{b}\t%2"
7246 [(set_attr "type" "idiv")
7247 (set_attr "mode" "QI")])
7248
7249 (define_insn "udivqi3"
7250 [(set (match_operand:QI 0 "register_operand" "=a")
7251 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7252 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7253 (clobber (reg:CC FLAGS_REG))]
7254 "TARGET_QIMODE_MATH"
7255 "div{b}\t%2"
7256 [(set_attr "type" "idiv")
7257 (set_attr "mode" "QI")])
7258
7259 ;; The patterns that match these are at the end of this file.
7260
7261 (define_expand "divxf3"
7262 [(set (match_operand:XF 0 "register_operand" "")
7263 (div:XF (match_operand:XF 1 "register_operand" "")
7264 (match_operand:XF 2 "register_operand" "")))]
7265 "TARGET_80387"
7266 "")
7267
7268 (define_expand "divdf3"
7269 [(set (match_operand:DF 0 "register_operand" "")
7270 (div:DF (match_operand:DF 1 "register_operand" "")
7271 (match_operand:DF 2 "nonimmediate_operand" "")))]
7272 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7273 "")
7274
7275 (define_expand "divsf3"
7276 [(set (match_operand:SF 0 "register_operand" "")
7277 (div:SF (match_operand:SF 1 "register_operand" "")
7278 (match_operand:SF 2 "nonimmediate_operand" "")))]
7279 "TARGET_80387 || TARGET_SSE_MATH"
7280 "")
7281 \f
7282 ;; Remainder instructions.
7283
7284 (define_expand "divmoddi4"
7285 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7286 (div:DI (match_operand:DI 1 "register_operand" "")
7287 (match_operand:DI 2 "nonimmediate_operand" "")))
7288 (set (match_operand:DI 3 "register_operand" "")
7289 (mod:DI (match_dup 1) (match_dup 2)))
7290 (clobber (reg:CC FLAGS_REG))])]
7291 "TARGET_64BIT"
7292 "")
7293
7294 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7295 ;; Penalize eax case slightly because it results in worse scheduling
7296 ;; of code.
7297 (define_insn "*divmoddi4_nocltd_rex64"
7298 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7299 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7300 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7301 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7302 (mod:DI (match_dup 2) (match_dup 3)))
7303 (clobber (reg:CC FLAGS_REG))]
7304 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7305 "#"
7306 [(set_attr "type" "multi")])
7307
7308 (define_insn "*divmoddi4_cltd_rex64"
7309 [(set (match_operand:DI 0 "register_operand" "=a")
7310 (div:DI (match_operand:DI 2 "register_operand" "a")
7311 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7312 (set (match_operand:DI 1 "register_operand" "=&d")
7313 (mod:DI (match_dup 2) (match_dup 3)))
7314 (clobber (reg:CC FLAGS_REG))]
7315 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7316 "#"
7317 [(set_attr "type" "multi")])
7318
7319 (define_insn "*divmoddi_noext_rex64"
7320 [(set (match_operand:DI 0 "register_operand" "=a")
7321 (div:DI (match_operand:DI 1 "register_operand" "0")
7322 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7323 (set (match_operand:DI 3 "register_operand" "=d")
7324 (mod:DI (match_dup 1) (match_dup 2)))
7325 (use (match_operand:DI 4 "register_operand" "3"))
7326 (clobber (reg:CC FLAGS_REG))]
7327 "TARGET_64BIT"
7328 "idiv{q}\t%2"
7329 [(set_attr "type" "idiv")
7330 (set_attr "mode" "DI")])
7331
7332 (define_split
7333 [(set (match_operand:DI 0 "register_operand" "")
7334 (div:DI (match_operand:DI 1 "register_operand" "")
7335 (match_operand:DI 2 "nonimmediate_operand" "")))
7336 (set (match_operand:DI 3 "register_operand" "")
7337 (mod:DI (match_dup 1) (match_dup 2)))
7338 (clobber (reg:CC FLAGS_REG))]
7339 "TARGET_64BIT && reload_completed"
7340 [(parallel [(set (match_dup 3)
7341 (ashiftrt:DI (match_dup 4) (const_int 63)))
7342 (clobber (reg:CC FLAGS_REG))])
7343 (parallel [(set (match_dup 0)
7344 (div:DI (reg:DI 0) (match_dup 2)))
7345 (set (match_dup 3)
7346 (mod:DI (reg:DI 0) (match_dup 2)))
7347 (use (match_dup 3))
7348 (clobber (reg:CC FLAGS_REG))])]
7349 {
7350 /* Avoid use of cltd in favor of a mov+shift. */
7351 if (!TARGET_USE_CLTD && !optimize_size)
7352 {
7353 if (true_regnum (operands[1]))
7354 emit_move_insn (operands[0], operands[1]);
7355 else
7356 emit_move_insn (operands[3], operands[1]);
7357 operands[4] = operands[3];
7358 }
7359 else
7360 {
7361 gcc_assert (!true_regnum (operands[1]));
7362 operands[4] = operands[1];
7363 }
7364 })
7365
7366
7367 (define_expand "divmodsi4"
7368 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7369 (div:SI (match_operand:SI 1 "register_operand" "")
7370 (match_operand:SI 2 "nonimmediate_operand" "")))
7371 (set (match_operand:SI 3 "register_operand" "")
7372 (mod:SI (match_dup 1) (match_dup 2)))
7373 (clobber (reg:CC FLAGS_REG))])]
7374 ""
7375 "")
7376
7377 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7378 ;; Penalize eax case slightly because it results in worse scheduling
7379 ;; of code.
7380 (define_insn "*divmodsi4_nocltd"
7381 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7382 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7383 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7384 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7385 (mod:SI (match_dup 2) (match_dup 3)))
7386 (clobber (reg:CC FLAGS_REG))]
7387 "!optimize_size && !TARGET_USE_CLTD"
7388 "#"
7389 [(set_attr "type" "multi")])
7390
7391 (define_insn "*divmodsi4_cltd"
7392 [(set (match_operand:SI 0 "register_operand" "=a")
7393 (div:SI (match_operand:SI 2 "register_operand" "a")
7394 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7395 (set (match_operand:SI 1 "register_operand" "=&d")
7396 (mod:SI (match_dup 2) (match_dup 3)))
7397 (clobber (reg:CC FLAGS_REG))]
7398 "optimize_size || TARGET_USE_CLTD"
7399 "#"
7400 [(set_attr "type" "multi")])
7401
7402 (define_insn "*divmodsi_noext"
7403 [(set (match_operand:SI 0 "register_operand" "=a")
7404 (div:SI (match_operand:SI 1 "register_operand" "0")
7405 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7406 (set (match_operand:SI 3 "register_operand" "=d")
7407 (mod:SI (match_dup 1) (match_dup 2)))
7408 (use (match_operand:SI 4 "register_operand" "3"))
7409 (clobber (reg:CC FLAGS_REG))]
7410 ""
7411 "idiv{l}\t%2"
7412 [(set_attr "type" "idiv")
7413 (set_attr "mode" "SI")])
7414
7415 (define_split
7416 [(set (match_operand:SI 0 "register_operand" "")
7417 (div:SI (match_operand:SI 1 "register_operand" "")
7418 (match_operand:SI 2 "nonimmediate_operand" "")))
7419 (set (match_operand:SI 3 "register_operand" "")
7420 (mod:SI (match_dup 1) (match_dup 2)))
7421 (clobber (reg:CC FLAGS_REG))]
7422 "reload_completed"
7423 [(parallel [(set (match_dup 3)
7424 (ashiftrt:SI (match_dup 4) (const_int 31)))
7425 (clobber (reg:CC FLAGS_REG))])
7426 (parallel [(set (match_dup 0)
7427 (div:SI (reg:SI 0) (match_dup 2)))
7428 (set (match_dup 3)
7429 (mod:SI (reg:SI 0) (match_dup 2)))
7430 (use (match_dup 3))
7431 (clobber (reg:CC FLAGS_REG))])]
7432 {
7433 /* Avoid use of cltd in favor of a mov+shift. */
7434 if (!TARGET_USE_CLTD && !optimize_size)
7435 {
7436 if (true_regnum (operands[1]))
7437 emit_move_insn (operands[0], operands[1]);
7438 else
7439 emit_move_insn (operands[3], operands[1]);
7440 operands[4] = operands[3];
7441 }
7442 else
7443 {
7444 gcc_assert (!true_regnum (operands[1]));
7445 operands[4] = operands[1];
7446 }
7447 })
7448 ;; %%% Split me.
7449 (define_insn "divmodhi4"
7450 [(set (match_operand:HI 0 "register_operand" "=a")
7451 (div:HI (match_operand:HI 1 "register_operand" "0")
7452 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7453 (set (match_operand:HI 3 "register_operand" "=&d")
7454 (mod:HI (match_dup 1) (match_dup 2)))
7455 (clobber (reg:CC FLAGS_REG))]
7456 "TARGET_HIMODE_MATH"
7457 "cwtd\;idiv{w}\t%2"
7458 [(set_attr "type" "multi")
7459 (set_attr "length_immediate" "0")
7460 (set_attr "mode" "SI")])
7461
7462 (define_insn "udivmoddi4"
7463 [(set (match_operand:DI 0 "register_operand" "=a")
7464 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7465 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7466 (set (match_operand:DI 3 "register_operand" "=&d")
7467 (umod:DI (match_dup 1) (match_dup 2)))
7468 (clobber (reg:CC FLAGS_REG))]
7469 "TARGET_64BIT"
7470 "xor{q}\t%3, %3\;div{q}\t%2"
7471 [(set_attr "type" "multi")
7472 (set_attr "length_immediate" "0")
7473 (set_attr "mode" "DI")])
7474
7475 (define_insn "*udivmoddi4_noext"
7476 [(set (match_operand:DI 0 "register_operand" "=a")
7477 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7478 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7479 (set (match_operand:DI 3 "register_operand" "=d")
7480 (umod:DI (match_dup 1) (match_dup 2)))
7481 (use (match_dup 3))
7482 (clobber (reg:CC FLAGS_REG))]
7483 "TARGET_64BIT"
7484 "div{q}\t%2"
7485 [(set_attr "type" "idiv")
7486 (set_attr "mode" "DI")])
7487
7488 (define_split
7489 [(set (match_operand:DI 0 "register_operand" "")
7490 (udiv:DI (match_operand:DI 1 "register_operand" "")
7491 (match_operand:DI 2 "nonimmediate_operand" "")))
7492 (set (match_operand:DI 3 "register_operand" "")
7493 (umod:DI (match_dup 1) (match_dup 2)))
7494 (clobber (reg:CC FLAGS_REG))]
7495 "TARGET_64BIT && reload_completed"
7496 [(set (match_dup 3) (const_int 0))
7497 (parallel [(set (match_dup 0)
7498 (udiv:DI (match_dup 1) (match_dup 2)))
7499 (set (match_dup 3)
7500 (umod:DI (match_dup 1) (match_dup 2)))
7501 (use (match_dup 3))
7502 (clobber (reg:CC FLAGS_REG))])]
7503 "")
7504
7505 (define_insn "udivmodsi4"
7506 [(set (match_operand:SI 0 "register_operand" "=a")
7507 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7508 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7509 (set (match_operand:SI 3 "register_operand" "=&d")
7510 (umod:SI (match_dup 1) (match_dup 2)))
7511 (clobber (reg:CC FLAGS_REG))]
7512 ""
7513 "xor{l}\t%3, %3\;div{l}\t%2"
7514 [(set_attr "type" "multi")
7515 (set_attr "length_immediate" "0")
7516 (set_attr "mode" "SI")])
7517
7518 (define_insn "*udivmodsi4_noext"
7519 [(set (match_operand:SI 0 "register_operand" "=a")
7520 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7521 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7522 (set (match_operand:SI 3 "register_operand" "=d")
7523 (umod:SI (match_dup 1) (match_dup 2)))
7524 (use (match_dup 3))
7525 (clobber (reg:CC FLAGS_REG))]
7526 ""
7527 "div{l}\t%2"
7528 [(set_attr "type" "idiv")
7529 (set_attr "mode" "SI")])
7530
7531 (define_split
7532 [(set (match_operand:SI 0 "register_operand" "")
7533 (udiv:SI (match_operand:SI 1 "register_operand" "")
7534 (match_operand:SI 2 "nonimmediate_operand" "")))
7535 (set (match_operand:SI 3 "register_operand" "")
7536 (umod:SI (match_dup 1) (match_dup 2)))
7537 (clobber (reg:CC FLAGS_REG))]
7538 "reload_completed"
7539 [(set (match_dup 3) (const_int 0))
7540 (parallel [(set (match_dup 0)
7541 (udiv:SI (match_dup 1) (match_dup 2)))
7542 (set (match_dup 3)
7543 (umod:SI (match_dup 1) (match_dup 2)))
7544 (use (match_dup 3))
7545 (clobber (reg:CC FLAGS_REG))])]
7546 "")
7547
7548 (define_expand "udivmodhi4"
7549 [(set (match_dup 4) (const_int 0))
7550 (parallel [(set (match_operand:HI 0 "register_operand" "")
7551 (udiv:HI (match_operand:HI 1 "register_operand" "")
7552 (match_operand:HI 2 "nonimmediate_operand" "")))
7553 (set (match_operand:HI 3 "register_operand" "")
7554 (umod:HI (match_dup 1) (match_dup 2)))
7555 (use (match_dup 4))
7556 (clobber (reg:CC FLAGS_REG))])]
7557 "TARGET_HIMODE_MATH"
7558 "operands[4] = gen_reg_rtx (HImode);")
7559
7560 (define_insn "*udivmodhi_noext"
7561 [(set (match_operand:HI 0 "register_operand" "=a")
7562 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7563 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7564 (set (match_operand:HI 3 "register_operand" "=d")
7565 (umod:HI (match_dup 1) (match_dup 2)))
7566 (use (match_operand:HI 4 "register_operand" "3"))
7567 (clobber (reg:CC FLAGS_REG))]
7568 ""
7569 "div{w}\t%2"
7570 [(set_attr "type" "idiv")
7571 (set_attr "mode" "HI")])
7572
7573 ;; We cannot use div/idiv for double division, because it causes
7574 ;; "division by zero" on the overflow and that's not what we expect
7575 ;; from truncate. Because true (non truncating) double division is
7576 ;; never generated, we can't create this insn anyway.
7577 ;
7578 ;(define_insn ""
7579 ; [(set (match_operand:SI 0 "register_operand" "=a")
7580 ; (truncate:SI
7581 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7582 ; (zero_extend:DI
7583 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7584 ; (set (match_operand:SI 3 "register_operand" "=d")
7585 ; (truncate:SI
7586 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7587 ; (clobber (reg:CC FLAGS_REG))]
7588 ; ""
7589 ; "div{l}\t{%2, %0|%0, %2}"
7590 ; [(set_attr "type" "idiv")])
7591 \f
7592 ;;- Logical AND instructions
7593
7594 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7595 ;; Note that this excludes ah.
7596
7597 (define_insn "*testdi_1_rex64"
7598 [(set (reg FLAGS_REG)
7599 (compare
7600 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7601 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7602 (const_int 0)))]
7603 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7604 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7605 "@
7606 test{l}\t{%k1, %k0|%k0, %k1}
7607 test{l}\t{%k1, %k0|%k0, %k1}
7608 test{q}\t{%1, %0|%0, %1}
7609 test{q}\t{%1, %0|%0, %1}
7610 test{q}\t{%1, %0|%0, %1}"
7611 [(set_attr "type" "test")
7612 (set_attr "modrm" "0,1,0,1,1")
7613 (set_attr "mode" "SI,SI,DI,DI,DI")
7614 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7615
7616 (define_insn "testsi_1"
7617 [(set (reg FLAGS_REG)
7618 (compare
7619 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7620 (match_operand:SI 1 "general_operand" "in,in,rin"))
7621 (const_int 0)))]
7622 "ix86_match_ccmode (insn, CCNOmode)
7623 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7624 "test{l}\t{%1, %0|%0, %1}"
7625 [(set_attr "type" "test")
7626 (set_attr "modrm" "0,1,1")
7627 (set_attr "mode" "SI")
7628 (set_attr "pent_pair" "uv,np,uv")])
7629
7630 (define_expand "testsi_ccno_1"
7631 [(set (reg:CCNO FLAGS_REG)
7632 (compare:CCNO
7633 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7634 (match_operand:SI 1 "nonmemory_operand" ""))
7635 (const_int 0)))]
7636 ""
7637 "")
7638
7639 (define_insn "*testhi_1"
7640 [(set (reg FLAGS_REG)
7641 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7642 (match_operand:HI 1 "general_operand" "n,n,rn"))
7643 (const_int 0)))]
7644 "ix86_match_ccmode (insn, CCNOmode)
7645 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7646 "test{w}\t{%1, %0|%0, %1}"
7647 [(set_attr "type" "test")
7648 (set_attr "modrm" "0,1,1")
7649 (set_attr "mode" "HI")
7650 (set_attr "pent_pair" "uv,np,uv")])
7651
7652 (define_expand "testqi_ccz_1"
7653 [(set (reg:CCZ FLAGS_REG)
7654 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7655 (match_operand:QI 1 "nonmemory_operand" ""))
7656 (const_int 0)))]
7657 ""
7658 "")
7659
7660 (define_insn "*testqi_1_maybe_si"
7661 [(set (reg FLAGS_REG)
7662 (compare
7663 (and:QI
7664 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7665 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7666 (const_int 0)))]
7667 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7668 && ix86_match_ccmode (insn,
7669 GET_CODE (operands[1]) == CONST_INT
7670 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7671 {
7672 if (which_alternative == 3)
7673 {
7674 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7675 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7676 return "test{l}\t{%1, %k0|%k0, %1}";
7677 }
7678 return "test{b}\t{%1, %0|%0, %1}";
7679 }
7680 [(set_attr "type" "test")
7681 (set_attr "modrm" "0,1,1,1")
7682 (set_attr "mode" "QI,QI,QI,SI")
7683 (set_attr "pent_pair" "uv,np,uv,np")])
7684
7685 (define_insn "*testqi_1"
7686 [(set (reg FLAGS_REG)
7687 (compare
7688 (and:QI
7689 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7690 (match_operand:QI 1 "general_operand" "n,n,qn"))
7691 (const_int 0)))]
7692 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7693 && ix86_match_ccmode (insn, CCNOmode)"
7694 "test{b}\t{%1, %0|%0, %1}"
7695 [(set_attr "type" "test")
7696 (set_attr "modrm" "0,1,1")
7697 (set_attr "mode" "QI")
7698 (set_attr "pent_pair" "uv,np,uv")])
7699
7700 (define_expand "testqi_ext_ccno_0"
7701 [(set (reg:CCNO FLAGS_REG)
7702 (compare:CCNO
7703 (and:SI
7704 (zero_extract:SI
7705 (match_operand 0 "ext_register_operand" "")
7706 (const_int 8)
7707 (const_int 8))
7708 (match_operand 1 "const_int_operand" ""))
7709 (const_int 0)))]
7710 ""
7711 "")
7712
7713 (define_insn "*testqi_ext_0"
7714 [(set (reg FLAGS_REG)
7715 (compare
7716 (and:SI
7717 (zero_extract:SI
7718 (match_operand 0 "ext_register_operand" "Q")
7719 (const_int 8)
7720 (const_int 8))
7721 (match_operand 1 "const_int_operand" "n"))
7722 (const_int 0)))]
7723 "ix86_match_ccmode (insn, CCNOmode)"
7724 "test{b}\t{%1, %h0|%h0, %1}"
7725 [(set_attr "type" "test")
7726 (set_attr "mode" "QI")
7727 (set_attr "length_immediate" "1")
7728 (set_attr "pent_pair" "np")])
7729
7730 (define_insn "*testqi_ext_1"
7731 [(set (reg FLAGS_REG)
7732 (compare
7733 (and:SI
7734 (zero_extract:SI
7735 (match_operand 0 "ext_register_operand" "Q")
7736 (const_int 8)
7737 (const_int 8))
7738 (zero_extend:SI
7739 (match_operand:QI 1 "general_operand" "Qm")))
7740 (const_int 0)))]
7741 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7742 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7743 "test{b}\t{%1, %h0|%h0, %1}"
7744 [(set_attr "type" "test")
7745 (set_attr "mode" "QI")])
7746
7747 (define_insn "*testqi_ext_1_rex64"
7748 [(set (reg FLAGS_REG)
7749 (compare
7750 (and:SI
7751 (zero_extract:SI
7752 (match_operand 0 "ext_register_operand" "Q")
7753 (const_int 8)
7754 (const_int 8))
7755 (zero_extend:SI
7756 (match_operand:QI 1 "register_operand" "Q")))
7757 (const_int 0)))]
7758 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7759 "test{b}\t{%1, %h0|%h0, %1}"
7760 [(set_attr "type" "test")
7761 (set_attr "mode" "QI")])
7762
7763 (define_insn "*testqi_ext_2"
7764 [(set (reg FLAGS_REG)
7765 (compare
7766 (and:SI
7767 (zero_extract:SI
7768 (match_operand 0 "ext_register_operand" "Q")
7769 (const_int 8)
7770 (const_int 8))
7771 (zero_extract:SI
7772 (match_operand 1 "ext_register_operand" "Q")
7773 (const_int 8)
7774 (const_int 8)))
7775 (const_int 0)))]
7776 "ix86_match_ccmode (insn, CCNOmode)"
7777 "test{b}\t{%h1, %h0|%h0, %h1}"
7778 [(set_attr "type" "test")
7779 (set_attr "mode" "QI")])
7780
7781 ;; Combine likes to form bit extractions for some tests. Humor it.
7782 (define_insn "*testqi_ext_3"
7783 [(set (reg FLAGS_REG)
7784 (compare (zero_extract:SI
7785 (match_operand 0 "nonimmediate_operand" "rm")
7786 (match_operand:SI 1 "const_int_operand" "")
7787 (match_operand:SI 2 "const_int_operand" ""))
7788 (const_int 0)))]
7789 "ix86_match_ccmode (insn, CCNOmode)
7790 && (GET_MODE (operands[0]) == SImode
7791 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7792 || GET_MODE (operands[0]) == HImode
7793 || GET_MODE (operands[0]) == QImode)"
7794 "#")
7795
7796 (define_insn "*testqi_ext_3_rex64"
7797 [(set (reg FLAGS_REG)
7798 (compare (zero_extract:DI
7799 (match_operand 0 "nonimmediate_operand" "rm")
7800 (match_operand:DI 1 "const_int_operand" "")
7801 (match_operand:DI 2 "const_int_operand" ""))
7802 (const_int 0)))]
7803 "TARGET_64BIT
7804 && ix86_match_ccmode (insn, CCNOmode)
7805 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7806 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7807 /* Ensure that resulting mask is zero or sign extended operand. */
7808 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7809 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7810 && INTVAL (operands[1]) > 32))
7811 && (GET_MODE (operands[0]) == SImode
7812 || GET_MODE (operands[0]) == DImode
7813 || GET_MODE (operands[0]) == HImode
7814 || GET_MODE (operands[0]) == QImode)"
7815 "#")
7816
7817 (define_split
7818 [(set (match_operand 0 "flags_reg_operand" "")
7819 (match_operator 1 "compare_operator"
7820 [(zero_extract
7821 (match_operand 2 "nonimmediate_operand" "")
7822 (match_operand 3 "const_int_operand" "")
7823 (match_operand 4 "const_int_operand" ""))
7824 (const_int 0)]))]
7825 "ix86_match_ccmode (insn, CCNOmode)"
7826 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7827 {
7828 rtx val = operands[2];
7829 HOST_WIDE_INT len = INTVAL (operands[3]);
7830 HOST_WIDE_INT pos = INTVAL (operands[4]);
7831 HOST_WIDE_INT mask;
7832 enum machine_mode mode, submode;
7833
7834 mode = GET_MODE (val);
7835 if (GET_CODE (val) == MEM)
7836 {
7837 /* ??? Combine likes to put non-volatile mem extractions in QImode
7838 no matter the size of the test. So find a mode that works. */
7839 if (! MEM_VOLATILE_P (val))
7840 {
7841 mode = smallest_mode_for_size (pos + len, MODE_INT);
7842 val = adjust_address (val, mode, 0);
7843 }
7844 }
7845 else if (GET_CODE (val) == SUBREG
7846 && (submode = GET_MODE (SUBREG_REG (val)),
7847 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7848 && pos + len <= GET_MODE_BITSIZE (submode))
7849 {
7850 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7851 mode = submode;
7852 val = SUBREG_REG (val);
7853 }
7854 else if (mode == HImode && pos + len <= 8)
7855 {
7856 /* Small HImode tests can be converted to QImode. */
7857 mode = QImode;
7858 val = gen_lowpart (QImode, val);
7859 }
7860
7861 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7862 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7863
7864 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7865 })
7866
7867 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7868 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7869 ;; this is relatively important trick.
7870 ;; Do the conversion only post-reload to avoid limiting of the register class
7871 ;; to QI regs.
7872 (define_split
7873 [(set (match_operand 0 "flags_reg_operand" "")
7874 (match_operator 1 "compare_operator"
7875 [(and (match_operand 2 "register_operand" "")
7876 (match_operand 3 "const_int_operand" ""))
7877 (const_int 0)]))]
7878 "reload_completed
7879 && QI_REG_P (operands[2])
7880 && GET_MODE (operands[2]) != QImode
7881 && ((ix86_match_ccmode (insn, CCZmode)
7882 && !(INTVAL (operands[3]) & ~(255 << 8)))
7883 || (ix86_match_ccmode (insn, CCNOmode)
7884 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7885 [(set (match_dup 0)
7886 (match_op_dup 1
7887 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7888 (match_dup 3))
7889 (const_int 0)]))]
7890 "operands[2] = gen_lowpart (SImode, operands[2]);
7891 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7892
7893 (define_split
7894 [(set (match_operand 0 "flags_reg_operand" "")
7895 (match_operator 1 "compare_operator"
7896 [(and (match_operand 2 "nonimmediate_operand" "")
7897 (match_operand 3 "const_int_operand" ""))
7898 (const_int 0)]))]
7899 "reload_completed
7900 && GET_MODE (operands[2]) != QImode
7901 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7902 && ((ix86_match_ccmode (insn, CCZmode)
7903 && !(INTVAL (operands[3]) & ~255))
7904 || (ix86_match_ccmode (insn, CCNOmode)
7905 && !(INTVAL (operands[3]) & ~127)))"
7906 [(set (match_dup 0)
7907 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7908 (const_int 0)]))]
7909 "operands[2] = gen_lowpart (QImode, operands[2]);
7910 operands[3] = gen_lowpart (QImode, operands[3]);")
7911
7912
7913 ;; %%% This used to optimize known byte-wide and operations to memory,
7914 ;; and sometimes to QImode registers. If this is considered useful,
7915 ;; it should be done with splitters.
7916
7917 (define_expand "anddi3"
7918 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7919 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7920 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7921 (clobber (reg:CC FLAGS_REG))]
7922 "TARGET_64BIT"
7923 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7924
7925 (define_insn "*anddi_1_rex64"
7926 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7927 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7928 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7929 (clobber (reg:CC FLAGS_REG))]
7930 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7931 {
7932 switch (get_attr_type (insn))
7933 {
7934 case TYPE_IMOVX:
7935 {
7936 enum machine_mode mode;
7937
7938 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
7939 if (INTVAL (operands[2]) == 0xff)
7940 mode = QImode;
7941 else
7942 {
7943 gcc_assert (INTVAL (operands[2]) == 0xffff);
7944 mode = HImode;
7945 }
7946
7947 operands[1] = gen_lowpart (mode, operands[1]);
7948 if (mode == QImode)
7949 return "movz{bq|x}\t{%1,%0|%0, %1}";
7950 else
7951 return "movz{wq|x}\t{%1,%0|%0, %1}";
7952 }
7953
7954 default:
7955 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7956 if (get_attr_mode (insn) == MODE_SI)
7957 return "and{l}\t{%k2, %k0|%k0, %k2}";
7958 else
7959 return "and{q}\t{%2, %0|%0, %2}";
7960 }
7961 }
7962 [(set_attr "type" "alu,alu,alu,imovx")
7963 (set_attr "length_immediate" "*,*,*,0")
7964 (set_attr "mode" "SI,DI,DI,DI")])
7965
7966 (define_insn "*anddi_2"
7967 [(set (reg FLAGS_REG)
7968 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7969 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7970 (const_int 0)))
7971 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7972 (and:DI (match_dup 1) (match_dup 2)))]
7973 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7974 && ix86_binary_operator_ok (AND, DImode, operands)"
7975 "@
7976 and{l}\t{%k2, %k0|%k0, %k2}
7977 and{q}\t{%2, %0|%0, %2}
7978 and{q}\t{%2, %0|%0, %2}"
7979 [(set_attr "type" "alu")
7980 (set_attr "mode" "SI,DI,DI")])
7981
7982 (define_expand "andsi3"
7983 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7984 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7985 (match_operand:SI 2 "general_operand" "")))
7986 (clobber (reg:CC FLAGS_REG))]
7987 ""
7988 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7989
7990 (define_insn "*andsi_1"
7991 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7992 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7993 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7994 (clobber (reg:CC FLAGS_REG))]
7995 "ix86_binary_operator_ok (AND, SImode, operands)"
7996 {
7997 switch (get_attr_type (insn))
7998 {
7999 case TYPE_IMOVX:
8000 {
8001 enum machine_mode mode;
8002
8003 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8004 if (INTVAL (operands[2]) == 0xff)
8005 mode = QImode;
8006 else
8007 {
8008 gcc_assert (INTVAL (operands[2]) == 0xffff);
8009 mode = HImode;
8010 }
8011
8012 operands[1] = gen_lowpart (mode, operands[1]);
8013 if (mode == QImode)
8014 return "movz{bl|x}\t{%1,%0|%0, %1}";
8015 else
8016 return "movz{wl|x}\t{%1,%0|%0, %1}";
8017 }
8018
8019 default:
8020 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8021 return "and{l}\t{%2, %0|%0, %2}";
8022 }
8023 }
8024 [(set_attr "type" "alu,alu,imovx")
8025 (set_attr "length_immediate" "*,*,0")
8026 (set_attr "mode" "SI")])
8027
8028 (define_split
8029 [(set (match_operand 0 "register_operand" "")
8030 (and (match_dup 0)
8031 (const_int -65536)))
8032 (clobber (reg:CC FLAGS_REG))]
8033 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8034 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8035 "operands[1] = gen_lowpart (HImode, operands[0]);")
8036
8037 (define_split
8038 [(set (match_operand 0 "ext_register_operand" "")
8039 (and (match_dup 0)
8040 (const_int -256)))
8041 (clobber (reg:CC FLAGS_REG))]
8042 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8043 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8044 "operands[1] = gen_lowpart (QImode, operands[0]);")
8045
8046 (define_split
8047 [(set (match_operand 0 "ext_register_operand" "")
8048 (and (match_dup 0)
8049 (const_int -65281)))
8050 (clobber (reg:CC FLAGS_REG))]
8051 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8052 [(parallel [(set (zero_extract:SI (match_dup 0)
8053 (const_int 8)
8054 (const_int 8))
8055 (xor:SI
8056 (zero_extract:SI (match_dup 0)
8057 (const_int 8)
8058 (const_int 8))
8059 (zero_extract:SI (match_dup 0)
8060 (const_int 8)
8061 (const_int 8))))
8062 (clobber (reg:CC FLAGS_REG))])]
8063 "operands[0] = gen_lowpart (SImode, operands[0]);")
8064
8065 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8066 (define_insn "*andsi_1_zext"
8067 [(set (match_operand:DI 0 "register_operand" "=r")
8068 (zero_extend:DI
8069 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8070 (match_operand:SI 2 "general_operand" "rim"))))
8071 (clobber (reg:CC FLAGS_REG))]
8072 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8073 "and{l}\t{%2, %k0|%k0, %2}"
8074 [(set_attr "type" "alu")
8075 (set_attr "mode" "SI")])
8076
8077 (define_insn "*andsi_2"
8078 [(set (reg FLAGS_REG)
8079 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8080 (match_operand:SI 2 "general_operand" "rim,ri"))
8081 (const_int 0)))
8082 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8083 (and:SI (match_dup 1) (match_dup 2)))]
8084 "ix86_match_ccmode (insn, CCNOmode)
8085 && ix86_binary_operator_ok (AND, SImode, operands)"
8086 "and{l}\t{%2, %0|%0, %2}"
8087 [(set_attr "type" "alu")
8088 (set_attr "mode" "SI")])
8089
8090 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8091 (define_insn "*andsi_2_zext"
8092 [(set (reg FLAGS_REG)
8093 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8094 (match_operand:SI 2 "general_operand" "rim"))
8095 (const_int 0)))
8096 (set (match_operand:DI 0 "register_operand" "=r")
8097 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8098 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8099 && ix86_binary_operator_ok (AND, SImode, operands)"
8100 "and{l}\t{%2, %k0|%k0, %2}"
8101 [(set_attr "type" "alu")
8102 (set_attr "mode" "SI")])
8103
8104 (define_expand "andhi3"
8105 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8106 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8107 (match_operand:HI 2 "general_operand" "")))
8108 (clobber (reg:CC FLAGS_REG))]
8109 "TARGET_HIMODE_MATH"
8110 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8111
8112 (define_insn "*andhi_1"
8113 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8114 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8115 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8116 (clobber (reg:CC FLAGS_REG))]
8117 "ix86_binary_operator_ok (AND, HImode, operands)"
8118 {
8119 switch (get_attr_type (insn))
8120 {
8121 case TYPE_IMOVX:
8122 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8123 gcc_assert (INTVAL (operands[2]) == 0xff);
8124 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8125
8126 default:
8127 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8128
8129 return "and{w}\t{%2, %0|%0, %2}";
8130 }
8131 }
8132 [(set_attr "type" "alu,alu,imovx")
8133 (set_attr "length_immediate" "*,*,0")
8134 (set_attr "mode" "HI,HI,SI")])
8135
8136 (define_insn "*andhi_2"
8137 [(set (reg FLAGS_REG)
8138 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8139 (match_operand:HI 2 "general_operand" "rim,ri"))
8140 (const_int 0)))
8141 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8142 (and:HI (match_dup 1) (match_dup 2)))]
8143 "ix86_match_ccmode (insn, CCNOmode)
8144 && ix86_binary_operator_ok (AND, HImode, operands)"
8145 "and{w}\t{%2, %0|%0, %2}"
8146 [(set_attr "type" "alu")
8147 (set_attr "mode" "HI")])
8148
8149 (define_expand "andqi3"
8150 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8151 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8152 (match_operand:QI 2 "general_operand" "")))
8153 (clobber (reg:CC FLAGS_REG))]
8154 "TARGET_QIMODE_MATH"
8155 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8156
8157 ;; %%% Potential partial reg stall on alternative 2. What to do?
8158 (define_insn "*andqi_1"
8159 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8160 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8161 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8162 (clobber (reg:CC FLAGS_REG))]
8163 "ix86_binary_operator_ok (AND, QImode, operands)"
8164 "@
8165 and{b}\t{%2, %0|%0, %2}
8166 and{b}\t{%2, %0|%0, %2}
8167 and{l}\t{%k2, %k0|%k0, %k2}"
8168 [(set_attr "type" "alu")
8169 (set_attr "mode" "QI,QI,SI")])
8170
8171 (define_insn "*andqi_1_slp"
8172 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8173 (and:QI (match_dup 0)
8174 (match_operand:QI 1 "general_operand" "qi,qmi")))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8177 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8178 "and{b}\t{%1, %0|%0, %1}"
8179 [(set_attr "type" "alu1")
8180 (set_attr "mode" "QI")])
8181
8182 (define_insn "*andqi_2_maybe_si"
8183 [(set (reg FLAGS_REG)
8184 (compare (and:QI
8185 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8186 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8187 (const_int 0)))
8188 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8189 (and:QI (match_dup 1) (match_dup 2)))]
8190 "ix86_binary_operator_ok (AND, QImode, operands)
8191 && ix86_match_ccmode (insn,
8192 GET_CODE (operands[2]) == CONST_INT
8193 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8194 {
8195 if (which_alternative == 2)
8196 {
8197 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8198 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8199 return "and{l}\t{%2, %k0|%k0, %2}";
8200 }
8201 return "and{b}\t{%2, %0|%0, %2}";
8202 }
8203 [(set_attr "type" "alu")
8204 (set_attr "mode" "QI,QI,SI")])
8205
8206 (define_insn "*andqi_2"
8207 [(set (reg FLAGS_REG)
8208 (compare (and:QI
8209 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8210 (match_operand:QI 2 "general_operand" "qim,qi"))
8211 (const_int 0)))
8212 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8213 (and:QI (match_dup 1) (match_dup 2)))]
8214 "ix86_match_ccmode (insn, CCNOmode)
8215 && ix86_binary_operator_ok (AND, QImode, operands)"
8216 "and{b}\t{%2, %0|%0, %2}"
8217 [(set_attr "type" "alu")
8218 (set_attr "mode" "QI")])
8219
8220 (define_insn "*andqi_2_slp"
8221 [(set (reg FLAGS_REG)
8222 (compare (and:QI
8223 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8224 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8225 (const_int 0)))
8226 (set (strict_low_part (match_dup 0))
8227 (and:QI (match_dup 0) (match_dup 1)))]
8228 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8229 && ix86_match_ccmode (insn, CCNOmode)
8230 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8231 "and{b}\t{%1, %0|%0, %1}"
8232 [(set_attr "type" "alu1")
8233 (set_attr "mode" "QI")])
8234
8235 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8236 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8237 ;; for a QImode operand, which of course failed.
8238
8239 (define_insn "andqi_ext_0"
8240 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8241 (const_int 8)
8242 (const_int 8))
8243 (and:SI
8244 (zero_extract:SI
8245 (match_operand 1 "ext_register_operand" "0")
8246 (const_int 8)
8247 (const_int 8))
8248 (match_operand 2 "const_int_operand" "n")))
8249 (clobber (reg:CC FLAGS_REG))]
8250 ""
8251 "and{b}\t{%2, %h0|%h0, %2}"
8252 [(set_attr "type" "alu")
8253 (set_attr "length_immediate" "1")
8254 (set_attr "mode" "QI")])
8255
8256 ;; Generated by peephole translating test to and. This shows up
8257 ;; often in fp comparisons.
8258
8259 (define_insn "*andqi_ext_0_cc"
8260 [(set (reg FLAGS_REG)
8261 (compare
8262 (and:SI
8263 (zero_extract:SI
8264 (match_operand 1 "ext_register_operand" "0")
8265 (const_int 8)
8266 (const_int 8))
8267 (match_operand 2 "const_int_operand" "n"))
8268 (const_int 0)))
8269 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8270 (const_int 8)
8271 (const_int 8))
8272 (and:SI
8273 (zero_extract:SI
8274 (match_dup 1)
8275 (const_int 8)
8276 (const_int 8))
8277 (match_dup 2)))]
8278 "ix86_match_ccmode (insn, CCNOmode)"
8279 "and{b}\t{%2, %h0|%h0, %2}"
8280 [(set_attr "type" "alu")
8281 (set_attr "length_immediate" "1")
8282 (set_attr "mode" "QI")])
8283
8284 (define_insn "*andqi_ext_1"
8285 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8286 (const_int 8)
8287 (const_int 8))
8288 (and:SI
8289 (zero_extract:SI
8290 (match_operand 1 "ext_register_operand" "0")
8291 (const_int 8)
8292 (const_int 8))
8293 (zero_extend:SI
8294 (match_operand:QI 2 "general_operand" "Qm"))))
8295 (clobber (reg:CC FLAGS_REG))]
8296 "!TARGET_64BIT"
8297 "and{b}\t{%2, %h0|%h0, %2}"
8298 [(set_attr "type" "alu")
8299 (set_attr "length_immediate" "0")
8300 (set_attr "mode" "QI")])
8301
8302 (define_insn "*andqi_ext_1_rex64"
8303 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8304 (const_int 8)
8305 (const_int 8))
8306 (and:SI
8307 (zero_extract:SI
8308 (match_operand 1 "ext_register_operand" "0")
8309 (const_int 8)
8310 (const_int 8))
8311 (zero_extend:SI
8312 (match_operand 2 "ext_register_operand" "Q"))))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "TARGET_64BIT"
8315 "and{b}\t{%2, %h0|%h0, %2}"
8316 [(set_attr "type" "alu")
8317 (set_attr "length_immediate" "0")
8318 (set_attr "mode" "QI")])
8319
8320 (define_insn "*andqi_ext_2"
8321 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8322 (const_int 8)
8323 (const_int 8))
8324 (and:SI
8325 (zero_extract:SI
8326 (match_operand 1 "ext_register_operand" "%0")
8327 (const_int 8)
8328 (const_int 8))
8329 (zero_extract:SI
8330 (match_operand 2 "ext_register_operand" "Q")
8331 (const_int 8)
8332 (const_int 8))))
8333 (clobber (reg:CC FLAGS_REG))]
8334 ""
8335 "and{b}\t{%h2, %h0|%h0, %h2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "length_immediate" "0")
8338 (set_attr "mode" "QI")])
8339
8340 ;; Convert wide AND instructions with immediate operand to shorter QImode
8341 ;; equivalents when possible.
8342 ;; Don't do the splitting with memory operands, since it introduces risk
8343 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8344 ;; for size, but that can (should?) be handled by generic code instead.
8345 (define_split
8346 [(set (match_operand 0 "register_operand" "")
8347 (and (match_operand 1 "register_operand" "")
8348 (match_operand 2 "const_int_operand" "")))
8349 (clobber (reg:CC FLAGS_REG))]
8350 "reload_completed
8351 && QI_REG_P (operands[0])
8352 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8353 && !(~INTVAL (operands[2]) & ~(255 << 8))
8354 && GET_MODE (operands[0]) != QImode"
8355 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8356 (and:SI (zero_extract:SI (match_dup 1)
8357 (const_int 8) (const_int 8))
8358 (match_dup 2)))
8359 (clobber (reg:CC FLAGS_REG))])]
8360 "operands[0] = gen_lowpart (SImode, operands[0]);
8361 operands[1] = gen_lowpart (SImode, operands[1]);
8362 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8363
8364 ;; Since AND can be encoded with sign extended immediate, this is only
8365 ;; profitable when 7th bit is not set.
8366 (define_split
8367 [(set (match_operand 0 "register_operand" "")
8368 (and (match_operand 1 "general_operand" "")
8369 (match_operand 2 "const_int_operand" "")))
8370 (clobber (reg:CC FLAGS_REG))]
8371 "reload_completed
8372 && ANY_QI_REG_P (operands[0])
8373 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8374 && !(~INTVAL (operands[2]) & ~255)
8375 && !(INTVAL (operands[2]) & 128)
8376 && GET_MODE (operands[0]) != QImode"
8377 [(parallel [(set (strict_low_part (match_dup 0))
8378 (and:QI (match_dup 1)
8379 (match_dup 2)))
8380 (clobber (reg:CC FLAGS_REG))])]
8381 "operands[0] = gen_lowpart (QImode, operands[0]);
8382 operands[1] = gen_lowpart (QImode, operands[1]);
8383 operands[2] = gen_lowpart (QImode, operands[2]);")
8384 \f
8385 ;; Logical inclusive OR instructions
8386
8387 ;; %%% This used to optimize known byte-wide and operations to memory.
8388 ;; If this is considered useful, it should be done with splitters.
8389
8390 (define_expand "iordi3"
8391 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8392 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8393 (match_operand:DI 2 "x86_64_general_operand" "")))
8394 (clobber (reg:CC FLAGS_REG))]
8395 "TARGET_64BIT"
8396 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8397
8398 (define_insn "*iordi_1_rex64"
8399 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8400 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8401 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8402 (clobber (reg:CC FLAGS_REG))]
8403 "TARGET_64BIT
8404 && ix86_binary_operator_ok (IOR, DImode, operands)"
8405 "or{q}\t{%2, %0|%0, %2}"
8406 [(set_attr "type" "alu")
8407 (set_attr "mode" "DI")])
8408
8409 (define_insn "*iordi_2_rex64"
8410 [(set (reg FLAGS_REG)
8411 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8412 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8413 (const_int 0)))
8414 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8415 (ior:DI (match_dup 1) (match_dup 2)))]
8416 "TARGET_64BIT
8417 && ix86_match_ccmode (insn, CCNOmode)
8418 && ix86_binary_operator_ok (IOR, DImode, operands)"
8419 "or{q}\t{%2, %0|%0, %2}"
8420 [(set_attr "type" "alu")
8421 (set_attr "mode" "DI")])
8422
8423 (define_insn "*iordi_3_rex64"
8424 [(set (reg FLAGS_REG)
8425 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8426 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8427 (const_int 0)))
8428 (clobber (match_scratch:DI 0 "=r"))]
8429 "TARGET_64BIT
8430 && ix86_match_ccmode (insn, CCNOmode)
8431 && ix86_binary_operator_ok (IOR, DImode, operands)"
8432 "or{q}\t{%2, %0|%0, %2}"
8433 [(set_attr "type" "alu")
8434 (set_attr "mode" "DI")])
8435
8436
8437 (define_expand "iorsi3"
8438 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8439 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8440 (match_operand:SI 2 "general_operand" "")))
8441 (clobber (reg:CC FLAGS_REG))]
8442 ""
8443 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8444
8445 (define_insn "*iorsi_1"
8446 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8447 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8448 (match_operand:SI 2 "general_operand" "ri,rmi")))
8449 (clobber (reg:CC FLAGS_REG))]
8450 "ix86_binary_operator_ok (IOR, SImode, operands)"
8451 "or{l}\t{%2, %0|%0, %2}"
8452 [(set_attr "type" "alu")
8453 (set_attr "mode" "SI")])
8454
8455 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8456 (define_insn "*iorsi_1_zext"
8457 [(set (match_operand:DI 0 "register_operand" "=rm")
8458 (zero_extend:DI
8459 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8460 (match_operand:SI 2 "general_operand" "rim"))))
8461 (clobber (reg:CC FLAGS_REG))]
8462 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8463 "or{l}\t{%2, %k0|%k0, %2}"
8464 [(set_attr "type" "alu")
8465 (set_attr "mode" "SI")])
8466
8467 (define_insn "*iorsi_1_zext_imm"
8468 [(set (match_operand:DI 0 "register_operand" "=rm")
8469 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8470 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8471 (clobber (reg:CC FLAGS_REG))]
8472 "TARGET_64BIT"
8473 "or{l}\t{%2, %k0|%k0, %2}"
8474 [(set_attr "type" "alu")
8475 (set_attr "mode" "SI")])
8476
8477 (define_insn "*iorsi_2"
8478 [(set (reg FLAGS_REG)
8479 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8480 (match_operand:SI 2 "general_operand" "rim,ri"))
8481 (const_int 0)))
8482 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8483 (ior:SI (match_dup 1) (match_dup 2)))]
8484 "ix86_match_ccmode (insn, CCNOmode)
8485 && ix86_binary_operator_ok (IOR, SImode, operands)"
8486 "or{l}\t{%2, %0|%0, %2}"
8487 [(set_attr "type" "alu")
8488 (set_attr "mode" "SI")])
8489
8490 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8491 ;; ??? Special case for immediate operand is missing - it is tricky.
8492 (define_insn "*iorsi_2_zext"
8493 [(set (reg FLAGS_REG)
8494 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8495 (match_operand:SI 2 "general_operand" "rim"))
8496 (const_int 0)))
8497 (set (match_operand:DI 0 "register_operand" "=r")
8498 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8499 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8500 && ix86_binary_operator_ok (IOR, SImode, operands)"
8501 "or{l}\t{%2, %k0|%k0, %2}"
8502 [(set_attr "type" "alu")
8503 (set_attr "mode" "SI")])
8504
8505 (define_insn "*iorsi_2_zext_imm"
8506 [(set (reg FLAGS_REG)
8507 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8508 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8509 (const_int 0)))
8510 (set (match_operand:DI 0 "register_operand" "=r")
8511 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8512 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8513 && ix86_binary_operator_ok (IOR, SImode, operands)"
8514 "or{l}\t{%2, %k0|%k0, %2}"
8515 [(set_attr "type" "alu")
8516 (set_attr "mode" "SI")])
8517
8518 (define_insn "*iorsi_3"
8519 [(set (reg FLAGS_REG)
8520 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8521 (match_operand:SI 2 "general_operand" "rim"))
8522 (const_int 0)))
8523 (clobber (match_scratch:SI 0 "=r"))]
8524 "ix86_match_ccmode (insn, CCNOmode)
8525 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8526 "or{l}\t{%2, %0|%0, %2}"
8527 [(set_attr "type" "alu")
8528 (set_attr "mode" "SI")])
8529
8530 (define_expand "iorhi3"
8531 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8532 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8533 (match_operand:HI 2 "general_operand" "")))
8534 (clobber (reg:CC FLAGS_REG))]
8535 "TARGET_HIMODE_MATH"
8536 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8537
8538 (define_insn "*iorhi_1"
8539 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8540 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8541 (match_operand:HI 2 "general_operand" "rmi,ri")))
8542 (clobber (reg:CC FLAGS_REG))]
8543 "ix86_binary_operator_ok (IOR, HImode, operands)"
8544 "or{w}\t{%2, %0|%0, %2}"
8545 [(set_attr "type" "alu")
8546 (set_attr "mode" "HI")])
8547
8548 (define_insn "*iorhi_2"
8549 [(set (reg FLAGS_REG)
8550 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8551 (match_operand:HI 2 "general_operand" "rim,ri"))
8552 (const_int 0)))
8553 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8554 (ior:HI (match_dup 1) (match_dup 2)))]
8555 "ix86_match_ccmode (insn, CCNOmode)
8556 && ix86_binary_operator_ok (IOR, HImode, operands)"
8557 "or{w}\t{%2, %0|%0, %2}"
8558 [(set_attr "type" "alu")
8559 (set_attr "mode" "HI")])
8560
8561 (define_insn "*iorhi_3"
8562 [(set (reg FLAGS_REG)
8563 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8564 (match_operand:HI 2 "general_operand" "rim"))
8565 (const_int 0)))
8566 (clobber (match_scratch:HI 0 "=r"))]
8567 "ix86_match_ccmode (insn, CCNOmode)
8568 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8569 "or{w}\t{%2, %0|%0, %2}"
8570 [(set_attr "type" "alu")
8571 (set_attr "mode" "HI")])
8572
8573 (define_expand "iorqi3"
8574 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8575 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8576 (match_operand:QI 2 "general_operand" "")))
8577 (clobber (reg:CC FLAGS_REG))]
8578 "TARGET_QIMODE_MATH"
8579 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8580
8581 ;; %%% Potential partial reg stall on alternative 2. What to do?
8582 (define_insn "*iorqi_1"
8583 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8584 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8585 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8586 (clobber (reg:CC FLAGS_REG))]
8587 "ix86_binary_operator_ok (IOR, QImode, operands)"
8588 "@
8589 or{b}\t{%2, %0|%0, %2}
8590 or{b}\t{%2, %0|%0, %2}
8591 or{l}\t{%k2, %k0|%k0, %k2}"
8592 [(set_attr "type" "alu")
8593 (set_attr "mode" "QI,QI,SI")])
8594
8595 (define_insn "*iorqi_1_slp"
8596 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8597 (ior:QI (match_dup 0)
8598 (match_operand:QI 1 "general_operand" "qmi,qi")))
8599 (clobber (reg:CC FLAGS_REG))]
8600 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8601 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8602 "or{b}\t{%1, %0|%0, %1}"
8603 [(set_attr "type" "alu1")
8604 (set_attr "mode" "QI")])
8605
8606 (define_insn "*iorqi_2"
8607 [(set (reg FLAGS_REG)
8608 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8609 (match_operand:QI 2 "general_operand" "qim,qi"))
8610 (const_int 0)))
8611 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8612 (ior:QI (match_dup 1) (match_dup 2)))]
8613 "ix86_match_ccmode (insn, CCNOmode)
8614 && ix86_binary_operator_ok (IOR, QImode, operands)"
8615 "or{b}\t{%2, %0|%0, %2}"
8616 [(set_attr "type" "alu")
8617 (set_attr "mode" "QI")])
8618
8619 (define_insn "*iorqi_2_slp"
8620 [(set (reg FLAGS_REG)
8621 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8622 (match_operand:QI 1 "general_operand" "qim,qi"))
8623 (const_int 0)))
8624 (set (strict_low_part (match_dup 0))
8625 (ior:QI (match_dup 0) (match_dup 1)))]
8626 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8627 && ix86_match_ccmode (insn, CCNOmode)
8628 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8629 "or{b}\t{%1, %0|%0, %1}"
8630 [(set_attr "type" "alu1")
8631 (set_attr "mode" "QI")])
8632
8633 (define_insn "*iorqi_3"
8634 [(set (reg FLAGS_REG)
8635 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8636 (match_operand:QI 2 "general_operand" "qim"))
8637 (const_int 0)))
8638 (clobber (match_scratch:QI 0 "=q"))]
8639 "ix86_match_ccmode (insn, CCNOmode)
8640 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8641 "or{b}\t{%2, %0|%0, %2}"
8642 [(set_attr "type" "alu")
8643 (set_attr "mode" "QI")])
8644
8645 (define_insn "iorqi_ext_0"
8646 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8647 (const_int 8)
8648 (const_int 8))
8649 (ior:SI
8650 (zero_extract:SI
8651 (match_operand 1 "ext_register_operand" "0")
8652 (const_int 8)
8653 (const_int 8))
8654 (match_operand 2 "const_int_operand" "n")))
8655 (clobber (reg:CC FLAGS_REG))]
8656 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8657 "or{b}\t{%2, %h0|%h0, %2}"
8658 [(set_attr "type" "alu")
8659 (set_attr "length_immediate" "1")
8660 (set_attr "mode" "QI")])
8661
8662 (define_insn "*iorqi_ext_1"
8663 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8664 (const_int 8)
8665 (const_int 8))
8666 (ior:SI
8667 (zero_extract:SI
8668 (match_operand 1 "ext_register_operand" "0")
8669 (const_int 8)
8670 (const_int 8))
8671 (zero_extend:SI
8672 (match_operand:QI 2 "general_operand" "Qm"))))
8673 (clobber (reg:CC FLAGS_REG))]
8674 "!TARGET_64BIT
8675 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8676 "or{b}\t{%2, %h0|%h0, %2}"
8677 [(set_attr "type" "alu")
8678 (set_attr "length_immediate" "0")
8679 (set_attr "mode" "QI")])
8680
8681 (define_insn "*iorqi_ext_1_rex64"
8682 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8683 (const_int 8)
8684 (const_int 8))
8685 (ior:SI
8686 (zero_extract:SI
8687 (match_operand 1 "ext_register_operand" "0")
8688 (const_int 8)
8689 (const_int 8))
8690 (zero_extend:SI
8691 (match_operand 2 "ext_register_operand" "Q"))))
8692 (clobber (reg:CC FLAGS_REG))]
8693 "TARGET_64BIT
8694 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8695 "or{b}\t{%2, %h0|%h0, %2}"
8696 [(set_attr "type" "alu")
8697 (set_attr "length_immediate" "0")
8698 (set_attr "mode" "QI")])
8699
8700 (define_insn "*iorqi_ext_2"
8701 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8702 (const_int 8)
8703 (const_int 8))
8704 (ior:SI
8705 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8706 (const_int 8)
8707 (const_int 8))
8708 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8709 (const_int 8)
8710 (const_int 8))))
8711 (clobber (reg:CC FLAGS_REG))]
8712 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8713 "ior{b}\t{%h2, %h0|%h0, %h2}"
8714 [(set_attr "type" "alu")
8715 (set_attr "length_immediate" "0")
8716 (set_attr "mode" "QI")])
8717
8718 (define_split
8719 [(set (match_operand 0 "register_operand" "")
8720 (ior (match_operand 1 "register_operand" "")
8721 (match_operand 2 "const_int_operand" "")))
8722 (clobber (reg:CC FLAGS_REG))]
8723 "reload_completed
8724 && QI_REG_P (operands[0])
8725 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8726 && !(INTVAL (operands[2]) & ~(255 << 8))
8727 && GET_MODE (operands[0]) != QImode"
8728 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8729 (ior:SI (zero_extract:SI (match_dup 1)
8730 (const_int 8) (const_int 8))
8731 (match_dup 2)))
8732 (clobber (reg:CC FLAGS_REG))])]
8733 "operands[0] = gen_lowpart (SImode, operands[0]);
8734 operands[1] = gen_lowpart (SImode, operands[1]);
8735 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8736
8737 ;; Since OR can be encoded with sign extended immediate, this is only
8738 ;; profitable when 7th bit is set.
8739 (define_split
8740 [(set (match_operand 0 "register_operand" "")
8741 (ior (match_operand 1 "general_operand" "")
8742 (match_operand 2 "const_int_operand" "")))
8743 (clobber (reg:CC FLAGS_REG))]
8744 "reload_completed
8745 && ANY_QI_REG_P (operands[0])
8746 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8747 && !(INTVAL (operands[2]) & ~255)
8748 && (INTVAL (operands[2]) & 128)
8749 && GET_MODE (operands[0]) != QImode"
8750 [(parallel [(set (strict_low_part (match_dup 0))
8751 (ior:QI (match_dup 1)
8752 (match_dup 2)))
8753 (clobber (reg:CC FLAGS_REG))])]
8754 "operands[0] = gen_lowpart (QImode, operands[0]);
8755 operands[1] = gen_lowpart (QImode, operands[1]);
8756 operands[2] = gen_lowpart (QImode, operands[2]);")
8757 \f
8758 ;; Logical XOR instructions
8759
8760 ;; %%% This used to optimize known byte-wide and operations to memory.
8761 ;; If this is considered useful, it should be done with splitters.
8762
8763 (define_expand "xordi3"
8764 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8765 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8766 (match_operand:DI 2 "x86_64_general_operand" "")))
8767 (clobber (reg:CC FLAGS_REG))]
8768 "TARGET_64BIT"
8769 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8770
8771 (define_insn "*xordi_1_rex64"
8772 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8773 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8774 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8775 (clobber (reg:CC FLAGS_REG))]
8776 "TARGET_64BIT
8777 && ix86_binary_operator_ok (XOR, DImode, operands)"
8778 "@
8779 xor{q}\t{%2, %0|%0, %2}
8780 xor{q}\t{%2, %0|%0, %2}"
8781 [(set_attr "type" "alu")
8782 (set_attr "mode" "DI,DI")])
8783
8784 (define_insn "*xordi_2_rex64"
8785 [(set (reg FLAGS_REG)
8786 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8787 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8788 (const_int 0)))
8789 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8790 (xor:DI (match_dup 1) (match_dup 2)))]
8791 "TARGET_64BIT
8792 && ix86_match_ccmode (insn, CCNOmode)
8793 && ix86_binary_operator_ok (XOR, DImode, operands)"
8794 "@
8795 xor{q}\t{%2, %0|%0, %2}
8796 xor{q}\t{%2, %0|%0, %2}"
8797 [(set_attr "type" "alu")
8798 (set_attr "mode" "DI,DI")])
8799
8800 (define_insn "*xordi_3_rex64"
8801 [(set (reg FLAGS_REG)
8802 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8803 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8804 (const_int 0)))
8805 (clobber (match_scratch:DI 0 "=r"))]
8806 "TARGET_64BIT
8807 && ix86_match_ccmode (insn, CCNOmode)
8808 && ix86_binary_operator_ok (XOR, DImode, operands)"
8809 "xor{q}\t{%2, %0|%0, %2}"
8810 [(set_attr "type" "alu")
8811 (set_attr "mode" "DI")])
8812
8813 (define_expand "xorsi3"
8814 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8815 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8816 (match_operand:SI 2 "general_operand" "")))
8817 (clobber (reg:CC FLAGS_REG))]
8818 ""
8819 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8820
8821 (define_insn "*xorsi_1"
8822 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8823 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8824 (match_operand:SI 2 "general_operand" "ri,rm")))
8825 (clobber (reg:CC FLAGS_REG))]
8826 "ix86_binary_operator_ok (XOR, SImode, operands)"
8827 "xor{l}\t{%2, %0|%0, %2}"
8828 [(set_attr "type" "alu")
8829 (set_attr "mode" "SI")])
8830
8831 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8832 ;; Add speccase for immediates
8833 (define_insn "*xorsi_1_zext"
8834 [(set (match_operand:DI 0 "register_operand" "=r")
8835 (zero_extend:DI
8836 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8837 (match_operand:SI 2 "general_operand" "rim"))))
8838 (clobber (reg:CC FLAGS_REG))]
8839 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8840 "xor{l}\t{%2, %k0|%k0, %2}"
8841 [(set_attr "type" "alu")
8842 (set_attr "mode" "SI")])
8843
8844 (define_insn "*xorsi_1_zext_imm"
8845 [(set (match_operand:DI 0 "register_operand" "=r")
8846 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8847 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8848 (clobber (reg:CC FLAGS_REG))]
8849 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8850 "xor{l}\t{%2, %k0|%k0, %2}"
8851 [(set_attr "type" "alu")
8852 (set_attr "mode" "SI")])
8853
8854 (define_insn "*xorsi_2"
8855 [(set (reg FLAGS_REG)
8856 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8857 (match_operand:SI 2 "general_operand" "rim,ri"))
8858 (const_int 0)))
8859 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8860 (xor:SI (match_dup 1) (match_dup 2)))]
8861 "ix86_match_ccmode (insn, CCNOmode)
8862 && ix86_binary_operator_ok (XOR, SImode, operands)"
8863 "xor{l}\t{%2, %0|%0, %2}"
8864 [(set_attr "type" "alu")
8865 (set_attr "mode" "SI")])
8866
8867 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8868 ;; ??? Special case for immediate operand is missing - it is tricky.
8869 (define_insn "*xorsi_2_zext"
8870 [(set (reg FLAGS_REG)
8871 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8872 (match_operand:SI 2 "general_operand" "rim"))
8873 (const_int 0)))
8874 (set (match_operand:DI 0 "register_operand" "=r")
8875 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8876 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8877 && ix86_binary_operator_ok (XOR, SImode, operands)"
8878 "xor{l}\t{%2, %k0|%k0, %2}"
8879 [(set_attr "type" "alu")
8880 (set_attr "mode" "SI")])
8881
8882 (define_insn "*xorsi_2_zext_imm"
8883 [(set (reg FLAGS_REG)
8884 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8885 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8886 (const_int 0)))
8887 (set (match_operand:DI 0 "register_operand" "=r")
8888 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8889 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8890 && ix86_binary_operator_ok (XOR, SImode, operands)"
8891 "xor{l}\t{%2, %k0|%k0, %2}"
8892 [(set_attr "type" "alu")
8893 (set_attr "mode" "SI")])
8894
8895 (define_insn "*xorsi_3"
8896 [(set (reg FLAGS_REG)
8897 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8898 (match_operand:SI 2 "general_operand" "rim"))
8899 (const_int 0)))
8900 (clobber (match_scratch:SI 0 "=r"))]
8901 "ix86_match_ccmode (insn, CCNOmode)
8902 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8903 "xor{l}\t{%2, %0|%0, %2}"
8904 [(set_attr "type" "alu")
8905 (set_attr "mode" "SI")])
8906
8907 (define_expand "xorhi3"
8908 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8909 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8910 (match_operand:HI 2 "general_operand" "")))
8911 (clobber (reg:CC FLAGS_REG))]
8912 "TARGET_HIMODE_MATH"
8913 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8914
8915 (define_insn "*xorhi_1"
8916 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8917 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8918 (match_operand:HI 2 "general_operand" "rmi,ri")))
8919 (clobber (reg:CC FLAGS_REG))]
8920 "ix86_binary_operator_ok (XOR, HImode, operands)"
8921 "xor{w}\t{%2, %0|%0, %2}"
8922 [(set_attr "type" "alu")
8923 (set_attr "mode" "HI")])
8924
8925 (define_insn "*xorhi_2"
8926 [(set (reg FLAGS_REG)
8927 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8928 (match_operand:HI 2 "general_operand" "rim,ri"))
8929 (const_int 0)))
8930 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8931 (xor:HI (match_dup 1) (match_dup 2)))]
8932 "ix86_match_ccmode (insn, CCNOmode)
8933 && ix86_binary_operator_ok (XOR, HImode, operands)"
8934 "xor{w}\t{%2, %0|%0, %2}"
8935 [(set_attr "type" "alu")
8936 (set_attr "mode" "HI")])
8937
8938 (define_insn "*xorhi_3"
8939 [(set (reg FLAGS_REG)
8940 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8941 (match_operand:HI 2 "general_operand" "rim"))
8942 (const_int 0)))
8943 (clobber (match_scratch:HI 0 "=r"))]
8944 "ix86_match_ccmode (insn, CCNOmode)
8945 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8946 "xor{w}\t{%2, %0|%0, %2}"
8947 [(set_attr "type" "alu")
8948 (set_attr "mode" "HI")])
8949
8950 (define_expand "xorqi3"
8951 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8952 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8953 (match_operand:QI 2 "general_operand" "")))
8954 (clobber (reg:CC FLAGS_REG))]
8955 "TARGET_QIMODE_MATH"
8956 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8957
8958 ;; %%% Potential partial reg stall on alternative 2. What to do?
8959 (define_insn "*xorqi_1"
8960 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8961 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8962 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8963 (clobber (reg:CC FLAGS_REG))]
8964 "ix86_binary_operator_ok (XOR, QImode, operands)"
8965 "@
8966 xor{b}\t{%2, %0|%0, %2}
8967 xor{b}\t{%2, %0|%0, %2}
8968 xor{l}\t{%k2, %k0|%k0, %k2}"
8969 [(set_attr "type" "alu")
8970 (set_attr "mode" "QI,QI,SI")])
8971
8972 (define_insn "*xorqi_1_slp"
8973 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8974 (xor:QI (match_dup 0)
8975 (match_operand:QI 1 "general_operand" "qi,qmi")))
8976 (clobber (reg:CC FLAGS_REG))]
8977 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8978 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8979 "xor{b}\t{%1, %0|%0, %1}"
8980 [(set_attr "type" "alu1")
8981 (set_attr "mode" "QI")])
8982
8983 (define_insn "xorqi_ext_0"
8984 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8985 (const_int 8)
8986 (const_int 8))
8987 (xor:SI
8988 (zero_extract:SI
8989 (match_operand 1 "ext_register_operand" "0")
8990 (const_int 8)
8991 (const_int 8))
8992 (match_operand 2 "const_int_operand" "n")))
8993 (clobber (reg:CC FLAGS_REG))]
8994 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8995 "xor{b}\t{%2, %h0|%h0, %2}"
8996 [(set_attr "type" "alu")
8997 (set_attr "length_immediate" "1")
8998 (set_attr "mode" "QI")])
8999
9000 (define_insn "*xorqi_ext_1"
9001 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9002 (const_int 8)
9003 (const_int 8))
9004 (xor:SI
9005 (zero_extract:SI
9006 (match_operand 1 "ext_register_operand" "0")
9007 (const_int 8)
9008 (const_int 8))
9009 (zero_extend:SI
9010 (match_operand:QI 2 "general_operand" "Qm"))))
9011 (clobber (reg:CC FLAGS_REG))]
9012 "!TARGET_64BIT
9013 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9014 "xor{b}\t{%2, %h0|%h0, %2}"
9015 [(set_attr "type" "alu")
9016 (set_attr "length_immediate" "0")
9017 (set_attr "mode" "QI")])
9018
9019 (define_insn "*xorqi_ext_1_rex64"
9020 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9021 (const_int 8)
9022 (const_int 8))
9023 (xor:SI
9024 (zero_extract:SI
9025 (match_operand 1 "ext_register_operand" "0")
9026 (const_int 8)
9027 (const_int 8))
9028 (zero_extend:SI
9029 (match_operand 2 "ext_register_operand" "Q"))))
9030 (clobber (reg:CC FLAGS_REG))]
9031 "TARGET_64BIT
9032 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9033 "xor{b}\t{%2, %h0|%h0, %2}"
9034 [(set_attr "type" "alu")
9035 (set_attr "length_immediate" "0")
9036 (set_attr "mode" "QI")])
9037
9038 (define_insn "*xorqi_ext_2"
9039 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9040 (const_int 8)
9041 (const_int 8))
9042 (xor:SI
9043 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9044 (const_int 8)
9045 (const_int 8))
9046 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9047 (const_int 8)
9048 (const_int 8))))
9049 (clobber (reg:CC FLAGS_REG))]
9050 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9051 "xor{b}\t{%h2, %h0|%h0, %h2}"
9052 [(set_attr "type" "alu")
9053 (set_attr "length_immediate" "0")
9054 (set_attr "mode" "QI")])
9055
9056 (define_insn "*xorqi_cc_1"
9057 [(set (reg FLAGS_REG)
9058 (compare
9059 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9060 (match_operand:QI 2 "general_operand" "qim,qi"))
9061 (const_int 0)))
9062 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9063 (xor:QI (match_dup 1) (match_dup 2)))]
9064 "ix86_match_ccmode (insn, CCNOmode)
9065 && ix86_binary_operator_ok (XOR, QImode, operands)"
9066 "xor{b}\t{%2, %0|%0, %2}"
9067 [(set_attr "type" "alu")
9068 (set_attr "mode" "QI")])
9069
9070 (define_insn "*xorqi_2_slp"
9071 [(set (reg FLAGS_REG)
9072 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9073 (match_operand:QI 1 "general_operand" "qim,qi"))
9074 (const_int 0)))
9075 (set (strict_low_part (match_dup 0))
9076 (xor:QI (match_dup 0) (match_dup 1)))]
9077 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9078 && ix86_match_ccmode (insn, CCNOmode)
9079 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9080 "xor{b}\t{%1, %0|%0, %1}"
9081 [(set_attr "type" "alu1")
9082 (set_attr "mode" "QI")])
9083
9084 (define_insn "*xorqi_cc_2"
9085 [(set (reg FLAGS_REG)
9086 (compare
9087 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9088 (match_operand:QI 2 "general_operand" "qim"))
9089 (const_int 0)))
9090 (clobber (match_scratch:QI 0 "=q"))]
9091 "ix86_match_ccmode (insn, CCNOmode)
9092 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9093 "xor{b}\t{%2, %0|%0, %2}"
9094 [(set_attr "type" "alu")
9095 (set_attr "mode" "QI")])
9096
9097 (define_insn "*xorqi_cc_ext_1"
9098 [(set (reg FLAGS_REG)
9099 (compare
9100 (xor:SI
9101 (zero_extract:SI
9102 (match_operand 1 "ext_register_operand" "0")
9103 (const_int 8)
9104 (const_int 8))
9105 (match_operand:QI 2 "general_operand" "qmn"))
9106 (const_int 0)))
9107 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9108 (const_int 8)
9109 (const_int 8))
9110 (xor:SI
9111 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9112 (match_dup 2)))]
9113 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9114 "xor{b}\t{%2, %h0|%h0, %2}"
9115 [(set_attr "type" "alu")
9116 (set_attr "mode" "QI")])
9117
9118 (define_insn "*xorqi_cc_ext_1_rex64"
9119 [(set (reg FLAGS_REG)
9120 (compare
9121 (xor:SI
9122 (zero_extract:SI
9123 (match_operand 1 "ext_register_operand" "0")
9124 (const_int 8)
9125 (const_int 8))
9126 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9127 (const_int 0)))
9128 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9129 (const_int 8)
9130 (const_int 8))
9131 (xor:SI
9132 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9133 (match_dup 2)))]
9134 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9135 "xor{b}\t{%2, %h0|%h0, %2}"
9136 [(set_attr "type" "alu")
9137 (set_attr "mode" "QI")])
9138
9139 (define_expand "xorqi_cc_ext_1"
9140 [(parallel [
9141 (set (reg:CCNO FLAGS_REG)
9142 (compare:CCNO
9143 (xor:SI
9144 (zero_extract:SI
9145 (match_operand 1 "ext_register_operand" "")
9146 (const_int 8)
9147 (const_int 8))
9148 (match_operand:QI 2 "general_operand" ""))
9149 (const_int 0)))
9150 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9151 (const_int 8)
9152 (const_int 8))
9153 (xor:SI
9154 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9155 (match_dup 2)))])]
9156 ""
9157 "")
9158
9159 (define_split
9160 [(set (match_operand 0 "register_operand" "")
9161 (xor (match_operand 1 "register_operand" "")
9162 (match_operand 2 "const_int_operand" "")))
9163 (clobber (reg:CC FLAGS_REG))]
9164 "reload_completed
9165 && QI_REG_P (operands[0])
9166 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9167 && !(INTVAL (operands[2]) & ~(255 << 8))
9168 && GET_MODE (operands[0]) != QImode"
9169 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9170 (xor:SI (zero_extract:SI (match_dup 1)
9171 (const_int 8) (const_int 8))
9172 (match_dup 2)))
9173 (clobber (reg:CC FLAGS_REG))])]
9174 "operands[0] = gen_lowpart (SImode, operands[0]);
9175 operands[1] = gen_lowpart (SImode, operands[1]);
9176 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9177
9178 ;; Since XOR can be encoded with sign extended immediate, this is only
9179 ;; profitable when 7th bit is set.
9180 (define_split
9181 [(set (match_operand 0 "register_operand" "")
9182 (xor (match_operand 1 "general_operand" "")
9183 (match_operand 2 "const_int_operand" "")))
9184 (clobber (reg:CC FLAGS_REG))]
9185 "reload_completed
9186 && ANY_QI_REG_P (operands[0])
9187 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9188 && !(INTVAL (operands[2]) & ~255)
9189 && (INTVAL (operands[2]) & 128)
9190 && GET_MODE (operands[0]) != QImode"
9191 [(parallel [(set (strict_low_part (match_dup 0))
9192 (xor:QI (match_dup 1)
9193 (match_dup 2)))
9194 (clobber (reg:CC FLAGS_REG))])]
9195 "operands[0] = gen_lowpart (QImode, operands[0]);
9196 operands[1] = gen_lowpart (QImode, operands[1]);
9197 operands[2] = gen_lowpart (QImode, operands[2]);")
9198 \f
9199 ;; Negation instructions
9200
9201 (define_expand "negdi2"
9202 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9203 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9204 (clobber (reg:CC FLAGS_REG))])]
9205 ""
9206 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9207
9208 (define_insn "*negdi2_1"
9209 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9210 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9211 (clobber (reg:CC FLAGS_REG))]
9212 "!TARGET_64BIT
9213 && ix86_unary_operator_ok (NEG, DImode, operands)"
9214 "#")
9215
9216 (define_split
9217 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9218 (neg:DI (match_operand:DI 1 "general_operand" "")))
9219 (clobber (reg:CC FLAGS_REG))]
9220 "!TARGET_64BIT && reload_completed"
9221 [(parallel
9222 [(set (reg:CCZ FLAGS_REG)
9223 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9224 (set (match_dup 0) (neg:SI (match_dup 2)))])
9225 (parallel
9226 [(set (match_dup 1)
9227 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9228 (match_dup 3))
9229 (const_int 0)))
9230 (clobber (reg:CC FLAGS_REG))])
9231 (parallel
9232 [(set (match_dup 1)
9233 (neg:SI (match_dup 1)))
9234 (clobber (reg:CC FLAGS_REG))])]
9235 "split_di (operands+1, 1, operands+2, operands+3);
9236 split_di (operands+0, 1, operands+0, operands+1);")
9237
9238 (define_insn "*negdi2_1_rex64"
9239 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9240 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9241 (clobber (reg:CC FLAGS_REG))]
9242 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9243 "neg{q}\t%0"
9244 [(set_attr "type" "negnot")
9245 (set_attr "mode" "DI")])
9246
9247 ;; The problem with neg is that it does not perform (compare x 0),
9248 ;; it really performs (compare 0 x), which leaves us with the zero
9249 ;; flag being the only useful item.
9250
9251 (define_insn "*negdi2_cmpz_rex64"
9252 [(set (reg:CCZ FLAGS_REG)
9253 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9254 (const_int 0)))
9255 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9256 (neg:DI (match_dup 1)))]
9257 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9258 "neg{q}\t%0"
9259 [(set_attr "type" "negnot")
9260 (set_attr "mode" "DI")])
9261
9262
9263 (define_expand "negsi2"
9264 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9265 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9266 (clobber (reg:CC FLAGS_REG))])]
9267 ""
9268 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9269
9270 (define_insn "*negsi2_1"
9271 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9272 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9273 (clobber (reg:CC FLAGS_REG))]
9274 "ix86_unary_operator_ok (NEG, SImode, operands)"
9275 "neg{l}\t%0"
9276 [(set_attr "type" "negnot")
9277 (set_attr "mode" "SI")])
9278
9279 ;; Combine is quite creative about this pattern.
9280 (define_insn "*negsi2_1_zext"
9281 [(set (match_operand:DI 0 "register_operand" "=r")
9282 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9283 (const_int 32)))
9284 (const_int 32)))
9285 (clobber (reg:CC FLAGS_REG))]
9286 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9287 "neg{l}\t%k0"
9288 [(set_attr "type" "negnot")
9289 (set_attr "mode" "SI")])
9290
9291 ;; The problem with neg is that it does not perform (compare x 0),
9292 ;; it really performs (compare 0 x), which leaves us with the zero
9293 ;; flag being the only useful item.
9294
9295 (define_insn "*negsi2_cmpz"
9296 [(set (reg:CCZ FLAGS_REG)
9297 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9298 (const_int 0)))
9299 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9300 (neg:SI (match_dup 1)))]
9301 "ix86_unary_operator_ok (NEG, SImode, operands)"
9302 "neg{l}\t%0"
9303 [(set_attr "type" "negnot")
9304 (set_attr "mode" "SI")])
9305
9306 (define_insn "*negsi2_cmpz_zext"
9307 [(set (reg:CCZ FLAGS_REG)
9308 (compare:CCZ (lshiftrt:DI
9309 (neg:DI (ashift:DI
9310 (match_operand:DI 1 "register_operand" "0")
9311 (const_int 32)))
9312 (const_int 32))
9313 (const_int 0)))
9314 (set (match_operand:DI 0 "register_operand" "=r")
9315 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9316 (const_int 32)))
9317 (const_int 32)))]
9318 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9319 "neg{l}\t%k0"
9320 [(set_attr "type" "negnot")
9321 (set_attr "mode" "SI")])
9322
9323 (define_expand "neghi2"
9324 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9325 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9326 (clobber (reg:CC FLAGS_REG))])]
9327 "TARGET_HIMODE_MATH"
9328 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9329
9330 (define_insn "*neghi2_1"
9331 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9332 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9333 (clobber (reg:CC FLAGS_REG))]
9334 "ix86_unary_operator_ok (NEG, HImode, operands)"
9335 "neg{w}\t%0"
9336 [(set_attr "type" "negnot")
9337 (set_attr "mode" "HI")])
9338
9339 (define_insn "*neghi2_cmpz"
9340 [(set (reg:CCZ FLAGS_REG)
9341 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9342 (const_int 0)))
9343 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9344 (neg:HI (match_dup 1)))]
9345 "ix86_unary_operator_ok (NEG, HImode, operands)"
9346 "neg{w}\t%0"
9347 [(set_attr "type" "negnot")
9348 (set_attr "mode" "HI")])
9349
9350 (define_expand "negqi2"
9351 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9352 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9353 (clobber (reg:CC FLAGS_REG))])]
9354 "TARGET_QIMODE_MATH"
9355 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9356
9357 (define_insn "*negqi2_1"
9358 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9359 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9360 (clobber (reg:CC FLAGS_REG))]
9361 "ix86_unary_operator_ok (NEG, QImode, operands)"
9362 "neg{b}\t%0"
9363 [(set_attr "type" "negnot")
9364 (set_attr "mode" "QI")])
9365
9366 (define_insn "*negqi2_cmpz"
9367 [(set (reg:CCZ FLAGS_REG)
9368 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9369 (const_int 0)))
9370 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9371 (neg:QI (match_dup 1)))]
9372 "ix86_unary_operator_ok (NEG, QImode, operands)"
9373 "neg{b}\t%0"
9374 [(set_attr "type" "negnot")
9375 (set_attr "mode" "QI")])
9376
9377 ;; Changing of sign for FP values is doable using integer unit too.
9378
9379 (define_expand "negsf2"
9380 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9381 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9382 "TARGET_80387 || TARGET_SSE_MATH"
9383 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9384
9385 (define_expand "abssf2"
9386 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9387 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9388 "TARGET_80387 || TARGET_SSE_MATH"
9389 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9390
9391 (define_insn "*absnegsf2_mixed"
9392 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#f,x#f,f#x,rm")
9393 (match_operator:SF 3 "absneg_operator"
9394 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#f,0 ,0")]))
9395 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9396 (clobber (reg:CC FLAGS_REG))]
9397 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9398 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9399 "#")
9400
9401 (define_insn "*absnegsf2_sse"
9402 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9403 (match_operator:SF 3 "absneg_operator"
9404 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9405 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9406 (clobber (reg:CC FLAGS_REG))]
9407 "TARGET_SSE_MATH
9408 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9409 "#")
9410
9411 (define_insn "*absnegsf2_i387"
9412 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9413 (match_operator:SF 3 "absneg_operator"
9414 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9415 (use (match_operand 2 "" ""))
9416 (clobber (reg:CC FLAGS_REG))]
9417 "TARGET_80387 && !TARGET_SSE_MATH
9418 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9419 "#")
9420
9421 (define_expand "copysignsf3"
9422 [(match_operand:SF 0 "register_operand" "")
9423 (match_operand:SF 1 "nonmemory_operand" "")
9424 (match_operand:SF 2 "register_operand" "")]
9425 "TARGET_SSE_MATH"
9426 {
9427 ix86_expand_copysign (operands);
9428 DONE;
9429 })
9430
9431 (define_insn_and_split "copysignsf3_const"
9432 [(set (match_operand:SF 0 "register_operand" "=x")
9433 (unspec:SF
9434 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9435 (match_operand:SF 2 "register_operand" "0")
9436 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9437 UNSPEC_COPYSIGN))]
9438 "TARGET_SSE_MATH"
9439 "#"
9440 "&& reload_completed"
9441 [(const_int 0)]
9442 {
9443 ix86_split_copysign_const (operands);
9444 DONE;
9445 })
9446
9447 (define_insn "copysignsf3_var"
9448 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9449 (unspec:SF
9450 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9451 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9452 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9453 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9454 UNSPEC_COPYSIGN))
9455 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9456 "TARGET_SSE_MATH"
9457 "#")
9458
9459 (define_split
9460 [(set (match_operand:SF 0 "register_operand" "")
9461 (unspec:SF
9462 [(match_operand:SF 2 "register_operand" "")
9463 (match_operand:SF 3 "register_operand" "")
9464 (match_operand:V4SF 4 "" "")
9465 (match_operand:V4SF 5 "" "")]
9466 UNSPEC_COPYSIGN))
9467 (clobber (match_scratch:V4SF 1 ""))]
9468 "TARGET_SSE_MATH && reload_completed"
9469 [(const_int 0)]
9470 {
9471 ix86_split_copysign_var (operands);
9472 DONE;
9473 })
9474
9475 (define_expand "negdf2"
9476 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9477 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9478 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9479 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9480
9481 (define_expand "absdf2"
9482 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9483 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9484 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9485 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9486
9487 (define_insn "*absnegdf2_mixed"
9488 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,f#Y,rm")
9489 (match_operator:DF 3 "absneg_operator"
9490 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#f,0 ,0")]))
9491 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9492 (clobber (reg:CC FLAGS_REG))]
9493 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9494 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9495 "#")
9496
9497 (define_insn "*absnegdf2_sse"
9498 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9499 (match_operator:DF 3 "absneg_operator"
9500 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9501 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X"))
9502 (clobber (reg:CC FLAGS_REG))]
9503 "TARGET_SSE2 && TARGET_SSE_MATH
9504 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9505 "#")
9506
9507 (define_insn "*absnegdf2_i387"
9508 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9509 (match_operator:DF 3 "absneg_operator"
9510 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9511 (use (match_operand 2 "" ""))
9512 (clobber (reg:CC FLAGS_REG))]
9513 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9514 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9515 "#")
9516
9517 (define_expand "copysigndf3"
9518 [(match_operand:DF 0 "register_operand" "")
9519 (match_operand:DF 1 "nonmemory_operand" "")
9520 (match_operand:DF 2 "register_operand" "")]
9521 "TARGET_SSE2 && TARGET_SSE_MATH"
9522 {
9523 ix86_expand_copysign (operands);
9524 DONE;
9525 })
9526
9527 (define_insn_and_split "copysigndf3_const"
9528 [(set (match_operand:DF 0 "register_operand" "=x")
9529 (unspec:DF
9530 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9531 (match_operand:DF 2 "register_operand" "0")
9532 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9533 UNSPEC_COPYSIGN))]
9534 "TARGET_SSE2 && TARGET_SSE_MATH"
9535 "#"
9536 "&& reload_completed"
9537 [(const_int 0)]
9538 {
9539 ix86_split_copysign_const (operands);
9540 DONE;
9541 })
9542
9543 (define_insn "copysigndf3_var"
9544 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9545 (unspec:DF
9546 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9547 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9548 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9549 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9550 UNSPEC_COPYSIGN))
9551 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9552 "TARGET_SSE2 && TARGET_SSE_MATH"
9553 "#")
9554
9555 (define_split
9556 [(set (match_operand:DF 0 "register_operand" "")
9557 (unspec:DF
9558 [(match_operand:DF 2 "register_operand" "")
9559 (match_operand:DF 3 "register_operand" "")
9560 (match_operand:V2DF 4 "" "")
9561 (match_operand:V2DF 5 "" "")]
9562 UNSPEC_COPYSIGN))
9563 (clobber (match_scratch:V2DF 1 ""))]
9564 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9565 [(const_int 0)]
9566 {
9567 ix86_split_copysign_var (operands);
9568 DONE;
9569 })
9570
9571 (define_expand "negxf2"
9572 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9573 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9574 "TARGET_80387"
9575 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9576
9577 (define_expand "absxf2"
9578 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9579 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9580 "TARGET_80387"
9581 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9582
9583 (define_insn "*absnegxf2_i387"
9584 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9585 (match_operator:XF 3 "absneg_operator"
9586 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9587 (use (match_operand 2 "" ""))
9588 (clobber (reg:CC FLAGS_REG))]
9589 "TARGET_80387
9590 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9591 "#")
9592
9593 ;; Splitters for fp abs and neg.
9594
9595 (define_split
9596 [(set (match_operand 0 "fp_register_operand" "")
9597 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9598 (use (match_operand 2 "" ""))
9599 (clobber (reg:CC FLAGS_REG))]
9600 "reload_completed"
9601 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9602
9603 (define_split
9604 [(set (match_operand 0 "register_operand" "")
9605 (match_operator 3 "absneg_operator"
9606 [(match_operand 1 "register_operand" "")]))
9607 (use (match_operand 2 "nonimmediate_operand" ""))
9608 (clobber (reg:CC FLAGS_REG))]
9609 "reload_completed && SSE_REG_P (operands[0])"
9610 [(set (match_dup 0) (match_dup 3))]
9611 {
9612 enum machine_mode mode = GET_MODE (operands[0]);
9613 enum machine_mode vmode = GET_MODE (operands[2]);
9614 rtx tmp;
9615
9616 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9617 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9618 if (operands_match_p (operands[0], operands[2]))
9619 {
9620 tmp = operands[1];
9621 operands[1] = operands[2];
9622 operands[2] = tmp;
9623 }
9624 if (GET_CODE (operands[3]) == ABS)
9625 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9626 else
9627 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9628 operands[3] = tmp;
9629 })
9630
9631 (define_split
9632 [(set (match_operand:SF 0 "register_operand" "")
9633 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9634 (use (match_operand:V4SF 2 "" ""))
9635 (clobber (reg:CC FLAGS_REG))]
9636 "reload_completed"
9637 [(parallel [(set (match_dup 0) (match_dup 1))
9638 (clobber (reg:CC FLAGS_REG))])]
9639 {
9640 rtx tmp;
9641 operands[0] = gen_lowpart (SImode, operands[0]);
9642 if (GET_CODE (operands[1]) == ABS)
9643 {
9644 tmp = gen_int_mode (0x7fffffff, SImode);
9645 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9646 }
9647 else
9648 {
9649 tmp = gen_int_mode (0x80000000, SImode);
9650 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9651 }
9652 operands[1] = tmp;
9653 })
9654
9655 (define_split
9656 [(set (match_operand:DF 0 "register_operand" "")
9657 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9658 (use (match_operand 2 "" ""))
9659 (clobber (reg:CC FLAGS_REG))]
9660 "reload_completed"
9661 [(parallel [(set (match_dup 0) (match_dup 1))
9662 (clobber (reg:CC FLAGS_REG))])]
9663 {
9664 rtx tmp;
9665 if (TARGET_64BIT)
9666 {
9667 tmp = gen_lowpart (DImode, operands[0]);
9668 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9669 operands[0] = tmp;
9670
9671 if (GET_CODE (operands[1]) == ABS)
9672 tmp = const0_rtx;
9673 else
9674 tmp = gen_rtx_NOT (DImode, tmp);
9675 }
9676 else
9677 {
9678 operands[0] = gen_highpart (SImode, operands[0]);
9679 if (GET_CODE (operands[1]) == ABS)
9680 {
9681 tmp = gen_int_mode (0x7fffffff, SImode);
9682 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9683 }
9684 else
9685 {
9686 tmp = gen_int_mode (0x80000000, SImode);
9687 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9688 }
9689 }
9690 operands[1] = tmp;
9691 })
9692
9693 (define_split
9694 [(set (match_operand:XF 0 "register_operand" "")
9695 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9696 (use (match_operand 2 "" ""))
9697 (clobber (reg:CC FLAGS_REG))]
9698 "reload_completed"
9699 [(parallel [(set (match_dup 0) (match_dup 1))
9700 (clobber (reg:CC FLAGS_REG))])]
9701 {
9702 rtx tmp;
9703 operands[0] = gen_rtx_REG (SImode,
9704 true_regnum (operands[0])
9705 + (TARGET_64BIT ? 1 : 2));
9706 if (GET_CODE (operands[1]) == ABS)
9707 {
9708 tmp = GEN_INT (0x7fff);
9709 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9710 }
9711 else
9712 {
9713 tmp = GEN_INT (0x8000);
9714 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9715 }
9716 operands[1] = tmp;
9717 })
9718
9719 (define_split
9720 [(set (match_operand 0 "memory_operand" "")
9721 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9722 (use (match_operand 2 "" ""))
9723 (clobber (reg:CC FLAGS_REG))]
9724 "reload_completed"
9725 [(parallel [(set (match_dup 0) (match_dup 1))
9726 (clobber (reg:CC FLAGS_REG))])]
9727 {
9728 enum machine_mode mode = GET_MODE (operands[0]);
9729 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9730 rtx tmp;
9731
9732 operands[0] = adjust_address (operands[0], QImode, size - 1);
9733 if (GET_CODE (operands[1]) == ABS)
9734 {
9735 tmp = gen_int_mode (0x7f, QImode);
9736 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9737 }
9738 else
9739 {
9740 tmp = gen_int_mode (0x80, QImode);
9741 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9742 }
9743 operands[1] = tmp;
9744 })
9745
9746 ;; Conditionalize these after reload. If they match before reload, we
9747 ;; lose the clobber and ability to use integer instructions.
9748
9749 (define_insn "*negsf2_1"
9750 [(set (match_operand:SF 0 "register_operand" "=f")
9751 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9752 "TARGET_80387 && reload_completed"
9753 "fchs"
9754 [(set_attr "type" "fsgn")
9755 (set_attr "mode" "SF")])
9756
9757 (define_insn "*negdf2_1"
9758 [(set (match_operand:DF 0 "register_operand" "=f")
9759 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9760 "TARGET_80387 && reload_completed"
9761 "fchs"
9762 [(set_attr "type" "fsgn")
9763 (set_attr "mode" "DF")])
9764
9765 (define_insn "*negxf2_1"
9766 [(set (match_operand:XF 0 "register_operand" "=f")
9767 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9768 "TARGET_80387 && reload_completed"
9769 "fchs"
9770 [(set_attr "type" "fsgn")
9771 (set_attr "mode" "XF")])
9772
9773 (define_insn "*abssf2_1"
9774 [(set (match_operand:SF 0 "register_operand" "=f")
9775 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9776 "TARGET_80387 && reload_completed"
9777 "fabs"
9778 [(set_attr "type" "fsgn")
9779 (set_attr "mode" "SF")])
9780
9781 (define_insn "*absdf2_1"
9782 [(set (match_operand:DF 0 "register_operand" "=f")
9783 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9784 "TARGET_80387 && reload_completed"
9785 "fabs"
9786 [(set_attr "type" "fsgn")
9787 (set_attr "mode" "DF")])
9788
9789 (define_insn "*absxf2_1"
9790 [(set (match_operand:XF 0 "register_operand" "=f")
9791 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9792 "TARGET_80387 && reload_completed"
9793 "fabs"
9794 [(set_attr "type" "fsgn")
9795 (set_attr "mode" "DF")])
9796
9797 (define_insn "*negextendsfdf2"
9798 [(set (match_operand:DF 0 "register_operand" "=f")
9799 (neg:DF (float_extend:DF
9800 (match_operand:SF 1 "register_operand" "0"))))]
9801 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9802 "fchs"
9803 [(set_attr "type" "fsgn")
9804 (set_attr "mode" "DF")])
9805
9806 (define_insn "*negextenddfxf2"
9807 [(set (match_operand:XF 0 "register_operand" "=f")
9808 (neg:XF (float_extend:XF
9809 (match_operand:DF 1 "register_operand" "0"))))]
9810 "TARGET_80387"
9811 "fchs"
9812 [(set_attr "type" "fsgn")
9813 (set_attr "mode" "XF")])
9814
9815 (define_insn "*negextendsfxf2"
9816 [(set (match_operand:XF 0 "register_operand" "=f")
9817 (neg:XF (float_extend:XF
9818 (match_operand:SF 1 "register_operand" "0"))))]
9819 "TARGET_80387"
9820 "fchs"
9821 [(set_attr "type" "fsgn")
9822 (set_attr "mode" "XF")])
9823
9824 (define_insn "*absextendsfdf2"
9825 [(set (match_operand:DF 0 "register_operand" "=f")
9826 (abs:DF (float_extend:DF
9827 (match_operand:SF 1 "register_operand" "0"))))]
9828 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9829 "fabs"
9830 [(set_attr "type" "fsgn")
9831 (set_attr "mode" "DF")])
9832
9833 (define_insn "*absextenddfxf2"
9834 [(set (match_operand:XF 0 "register_operand" "=f")
9835 (abs:XF (float_extend:XF
9836 (match_operand:DF 1 "register_operand" "0"))))]
9837 "TARGET_80387"
9838 "fabs"
9839 [(set_attr "type" "fsgn")
9840 (set_attr "mode" "XF")])
9841
9842 (define_insn "*absextendsfxf2"
9843 [(set (match_operand:XF 0 "register_operand" "=f")
9844 (abs:XF (float_extend:XF
9845 (match_operand:SF 1 "register_operand" "0"))))]
9846 "TARGET_80387"
9847 "fabs"
9848 [(set_attr "type" "fsgn")
9849 (set_attr "mode" "XF")])
9850 \f
9851 ;; One complement instructions
9852
9853 (define_expand "one_cmpldi2"
9854 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9855 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9856 "TARGET_64BIT"
9857 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9858
9859 (define_insn "*one_cmpldi2_1_rex64"
9860 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9861 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9862 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9863 "not{q}\t%0"
9864 [(set_attr "type" "negnot")
9865 (set_attr "mode" "DI")])
9866
9867 (define_insn "*one_cmpldi2_2_rex64"
9868 [(set (reg FLAGS_REG)
9869 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9870 (const_int 0)))
9871 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9872 (not:DI (match_dup 1)))]
9873 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9874 && ix86_unary_operator_ok (NOT, DImode, operands)"
9875 "#"
9876 [(set_attr "type" "alu1")
9877 (set_attr "mode" "DI")])
9878
9879 (define_split
9880 [(set (match_operand 0 "flags_reg_operand" "")
9881 (match_operator 2 "compare_operator"
9882 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9883 (const_int 0)]))
9884 (set (match_operand:DI 1 "nonimmediate_operand" "")
9885 (not:DI (match_dup 3)))]
9886 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9887 [(parallel [(set (match_dup 0)
9888 (match_op_dup 2
9889 [(xor:DI (match_dup 3) (const_int -1))
9890 (const_int 0)]))
9891 (set (match_dup 1)
9892 (xor:DI (match_dup 3) (const_int -1)))])]
9893 "")
9894
9895 (define_expand "one_cmplsi2"
9896 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9897 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9898 ""
9899 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9900
9901 (define_insn "*one_cmplsi2_1"
9902 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9903 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9904 "ix86_unary_operator_ok (NOT, SImode, operands)"
9905 "not{l}\t%0"
9906 [(set_attr "type" "negnot")
9907 (set_attr "mode" "SI")])
9908
9909 ;; ??? Currently never generated - xor is used instead.
9910 (define_insn "*one_cmplsi2_1_zext"
9911 [(set (match_operand:DI 0 "register_operand" "=r")
9912 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9913 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9914 "not{l}\t%k0"
9915 [(set_attr "type" "negnot")
9916 (set_attr "mode" "SI")])
9917
9918 (define_insn "*one_cmplsi2_2"
9919 [(set (reg FLAGS_REG)
9920 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9921 (const_int 0)))
9922 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9923 (not:SI (match_dup 1)))]
9924 "ix86_match_ccmode (insn, CCNOmode)
9925 && ix86_unary_operator_ok (NOT, SImode, operands)"
9926 "#"
9927 [(set_attr "type" "alu1")
9928 (set_attr "mode" "SI")])
9929
9930 (define_split
9931 [(set (match_operand 0 "flags_reg_operand" "")
9932 (match_operator 2 "compare_operator"
9933 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9934 (const_int 0)]))
9935 (set (match_operand:SI 1 "nonimmediate_operand" "")
9936 (not:SI (match_dup 3)))]
9937 "ix86_match_ccmode (insn, CCNOmode)"
9938 [(parallel [(set (match_dup 0)
9939 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9940 (const_int 0)]))
9941 (set (match_dup 1)
9942 (xor:SI (match_dup 3) (const_int -1)))])]
9943 "")
9944
9945 ;; ??? Currently never generated - xor is used instead.
9946 (define_insn "*one_cmplsi2_2_zext"
9947 [(set (reg FLAGS_REG)
9948 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9949 (const_int 0)))
9950 (set (match_operand:DI 0 "register_operand" "=r")
9951 (zero_extend:DI (not:SI (match_dup 1))))]
9952 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9953 && ix86_unary_operator_ok (NOT, SImode, operands)"
9954 "#"
9955 [(set_attr "type" "alu1")
9956 (set_attr "mode" "SI")])
9957
9958 (define_split
9959 [(set (match_operand 0 "flags_reg_operand" "")
9960 (match_operator 2 "compare_operator"
9961 [(not:SI (match_operand:SI 3 "register_operand" ""))
9962 (const_int 0)]))
9963 (set (match_operand:DI 1 "register_operand" "")
9964 (zero_extend:DI (not:SI (match_dup 3))))]
9965 "ix86_match_ccmode (insn, CCNOmode)"
9966 [(parallel [(set (match_dup 0)
9967 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9968 (const_int 0)]))
9969 (set (match_dup 1)
9970 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9971 "")
9972
9973 (define_expand "one_cmplhi2"
9974 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9975 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9976 "TARGET_HIMODE_MATH"
9977 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9978
9979 (define_insn "*one_cmplhi2_1"
9980 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9981 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9982 "ix86_unary_operator_ok (NOT, HImode, operands)"
9983 "not{w}\t%0"
9984 [(set_attr "type" "negnot")
9985 (set_attr "mode" "HI")])
9986
9987 (define_insn "*one_cmplhi2_2"
9988 [(set (reg FLAGS_REG)
9989 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9990 (const_int 0)))
9991 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9992 (not:HI (match_dup 1)))]
9993 "ix86_match_ccmode (insn, CCNOmode)
9994 && ix86_unary_operator_ok (NEG, HImode, operands)"
9995 "#"
9996 [(set_attr "type" "alu1")
9997 (set_attr "mode" "HI")])
9998
9999 (define_split
10000 [(set (match_operand 0 "flags_reg_operand" "")
10001 (match_operator 2 "compare_operator"
10002 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10003 (const_int 0)]))
10004 (set (match_operand:HI 1 "nonimmediate_operand" "")
10005 (not:HI (match_dup 3)))]
10006 "ix86_match_ccmode (insn, CCNOmode)"
10007 [(parallel [(set (match_dup 0)
10008 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10009 (const_int 0)]))
10010 (set (match_dup 1)
10011 (xor:HI (match_dup 3) (const_int -1)))])]
10012 "")
10013
10014 ;; %%% Potential partial reg stall on alternative 1. What to do?
10015 (define_expand "one_cmplqi2"
10016 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10017 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10018 "TARGET_QIMODE_MATH"
10019 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10020
10021 (define_insn "*one_cmplqi2_1"
10022 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10023 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10024 "ix86_unary_operator_ok (NOT, QImode, operands)"
10025 "@
10026 not{b}\t%0
10027 not{l}\t%k0"
10028 [(set_attr "type" "negnot")
10029 (set_attr "mode" "QI,SI")])
10030
10031 (define_insn "*one_cmplqi2_2"
10032 [(set (reg FLAGS_REG)
10033 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10034 (const_int 0)))
10035 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10036 (not:QI (match_dup 1)))]
10037 "ix86_match_ccmode (insn, CCNOmode)
10038 && ix86_unary_operator_ok (NOT, QImode, operands)"
10039 "#"
10040 [(set_attr "type" "alu1")
10041 (set_attr "mode" "QI")])
10042
10043 (define_split
10044 [(set (match_operand 0 "flags_reg_operand" "")
10045 (match_operator 2 "compare_operator"
10046 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10047 (const_int 0)]))
10048 (set (match_operand:QI 1 "nonimmediate_operand" "")
10049 (not:QI (match_dup 3)))]
10050 "ix86_match_ccmode (insn, CCNOmode)"
10051 [(parallel [(set (match_dup 0)
10052 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10053 (const_int 0)]))
10054 (set (match_dup 1)
10055 (xor:QI (match_dup 3) (const_int -1)))])]
10056 "")
10057 \f
10058 ;; Arithmetic shift instructions
10059
10060 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10061 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10062 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10063 ;; from the assembler input.
10064 ;;
10065 ;; This instruction shifts the target reg/mem as usual, but instead of
10066 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10067 ;; is a left shift double, bits are taken from the high order bits of
10068 ;; reg, else if the insn is a shift right double, bits are taken from the
10069 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10070 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10071 ;;
10072 ;; Since sh[lr]d does not change the `reg' operand, that is done
10073 ;; separately, making all shifts emit pairs of shift double and normal
10074 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10075 ;; support a 63 bit shift, each shift where the count is in a reg expands
10076 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10077 ;;
10078 ;; If the shift count is a constant, we need never emit more than one
10079 ;; shift pair, instead using moves and sign extension for counts greater
10080 ;; than 31.
10081
10082 (define_expand "ashldi3"
10083 [(set (match_operand:DI 0 "shiftdi_operand" "")
10084 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10085 (match_operand:QI 2 "nonmemory_operand" "")))]
10086 ""
10087 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10088
10089 (define_insn "*ashldi3_1_rex64"
10090 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10091 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10092 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10093 (clobber (reg:CC FLAGS_REG))]
10094 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10095 {
10096 switch (get_attr_type (insn))
10097 {
10098 case TYPE_ALU:
10099 gcc_assert (operands[2] == const1_rtx);
10100 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10101 return "add{q}\t{%0, %0|%0, %0}";
10102
10103 case TYPE_LEA:
10104 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10105 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10106 operands[1] = gen_rtx_MULT (DImode, operands[1],
10107 GEN_INT (1 << INTVAL (operands[2])));
10108 return "lea{q}\t{%a1, %0|%0, %a1}";
10109
10110 default:
10111 if (REG_P (operands[2]))
10112 return "sal{q}\t{%b2, %0|%0, %b2}";
10113 else if (operands[2] == const1_rtx
10114 && (TARGET_SHIFT1 || optimize_size))
10115 return "sal{q}\t%0";
10116 else
10117 return "sal{q}\t{%2, %0|%0, %2}";
10118 }
10119 }
10120 [(set (attr "type")
10121 (cond [(eq_attr "alternative" "1")
10122 (const_string "lea")
10123 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10124 (const_int 0))
10125 (match_operand 0 "register_operand" ""))
10126 (match_operand 2 "const1_operand" ""))
10127 (const_string "alu")
10128 ]
10129 (const_string "ishift")))
10130 (set_attr "mode" "DI")])
10131
10132 ;; Convert lea to the lea pattern to avoid flags dependency.
10133 (define_split
10134 [(set (match_operand:DI 0 "register_operand" "")
10135 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10136 (match_operand:QI 2 "immediate_operand" "")))
10137 (clobber (reg:CC FLAGS_REG))]
10138 "TARGET_64BIT && reload_completed
10139 && true_regnum (operands[0]) != true_regnum (operands[1])"
10140 [(set (match_dup 0)
10141 (mult:DI (match_dup 1)
10142 (match_dup 2)))]
10143 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10144
10145 ;; This pattern can't accept a variable shift count, since shifts by
10146 ;; zero don't affect the flags. We assume that shifts by constant
10147 ;; zero are optimized away.
10148 (define_insn "*ashldi3_cmp_rex64"
10149 [(set (reg FLAGS_REG)
10150 (compare
10151 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10152 (match_operand:QI 2 "immediate_operand" "e"))
10153 (const_int 0)))
10154 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10155 (ashift:DI (match_dup 1) (match_dup 2)))]
10156 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10157 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10158 {
10159 switch (get_attr_type (insn))
10160 {
10161 case TYPE_ALU:
10162 gcc_assert (operands[2] == const1_rtx);
10163 return "add{q}\t{%0, %0|%0, %0}";
10164
10165 default:
10166 if (REG_P (operands[2]))
10167 return "sal{q}\t{%b2, %0|%0, %b2}";
10168 else if (operands[2] == const1_rtx
10169 && (TARGET_SHIFT1 || optimize_size))
10170 return "sal{q}\t%0";
10171 else
10172 return "sal{q}\t{%2, %0|%0, %2}";
10173 }
10174 }
10175 [(set (attr "type")
10176 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10177 (const_int 0))
10178 (match_operand 0 "register_operand" ""))
10179 (match_operand 2 "const1_operand" ""))
10180 (const_string "alu")
10181 ]
10182 (const_string "ishift")))
10183 (set_attr "mode" "DI")])
10184
10185 (define_insn "*ashldi3_1"
10186 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10187 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10188 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10189 (clobber (reg:CC FLAGS_REG))]
10190 "!TARGET_64BIT"
10191 "#"
10192 [(set_attr "type" "multi")])
10193
10194 ;; By default we don't ask for a scratch register, because when DImode
10195 ;; values are manipulated, registers are already at a premium. But if
10196 ;; we have one handy, we won't turn it away.
10197 (define_peephole2
10198 [(match_scratch:SI 3 "r")
10199 (parallel [(set (match_operand:DI 0 "register_operand" "")
10200 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10201 (match_operand:QI 2 "nonmemory_operand" "")))
10202 (clobber (reg:CC FLAGS_REG))])
10203 (match_dup 3)]
10204 "!TARGET_64BIT && TARGET_CMOVE"
10205 [(const_int 0)]
10206 "ix86_split_ashldi (operands, operands[3]); DONE;")
10207
10208 (define_split
10209 [(set (match_operand:DI 0 "register_operand" "")
10210 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10211 (match_operand:QI 2 "nonmemory_operand" "")))
10212 (clobber (reg:CC FLAGS_REG))]
10213 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10214 [(const_int 0)]
10215 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10216
10217 (define_insn "x86_shld_1"
10218 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10219 (ior:SI (ashift:SI (match_dup 0)
10220 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10221 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10222 (minus:QI (const_int 32) (match_dup 2)))))
10223 (clobber (reg:CC FLAGS_REG))]
10224 ""
10225 "@
10226 shld{l}\t{%2, %1, %0|%0, %1, %2}
10227 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10228 [(set_attr "type" "ishift")
10229 (set_attr "prefix_0f" "1")
10230 (set_attr "mode" "SI")
10231 (set_attr "pent_pair" "np")
10232 (set_attr "athlon_decode" "vector")])
10233
10234 (define_expand "x86_shift_adj_1"
10235 [(set (reg:CCZ FLAGS_REG)
10236 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10237 (const_int 32))
10238 (const_int 0)))
10239 (set (match_operand:SI 0 "register_operand" "")
10240 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10241 (match_operand:SI 1 "register_operand" "")
10242 (match_dup 0)))
10243 (set (match_dup 1)
10244 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10245 (match_operand:SI 3 "register_operand" "r")
10246 (match_dup 1)))]
10247 "TARGET_CMOVE"
10248 "")
10249
10250 (define_expand "x86_shift_adj_2"
10251 [(use (match_operand:SI 0 "register_operand" ""))
10252 (use (match_operand:SI 1 "register_operand" ""))
10253 (use (match_operand:QI 2 "register_operand" ""))]
10254 ""
10255 {
10256 rtx label = gen_label_rtx ();
10257 rtx tmp;
10258
10259 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10260
10261 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10262 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10263 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10264 gen_rtx_LABEL_REF (VOIDmode, label),
10265 pc_rtx);
10266 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10267 JUMP_LABEL (tmp) = label;
10268
10269 emit_move_insn (operands[0], operands[1]);
10270 ix86_expand_clear (operands[1]);
10271
10272 emit_label (label);
10273 LABEL_NUSES (label) = 1;
10274
10275 DONE;
10276 })
10277
10278 (define_expand "ashlsi3"
10279 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10280 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10281 (match_operand:QI 2 "nonmemory_operand" "")))
10282 (clobber (reg:CC FLAGS_REG))]
10283 ""
10284 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10285
10286 (define_insn "*ashlsi3_1"
10287 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10288 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10289 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10290 (clobber (reg:CC FLAGS_REG))]
10291 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10292 {
10293 switch (get_attr_type (insn))
10294 {
10295 case TYPE_ALU:
10296 gcc_assert (operands[2] == const1_rtx);
10297 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10298 return "add{l}\t{%0, %0|%0, %0}";
10299
10300 case TYPE_LEA:
10301 return "#";
10302
10303 default:
10304 if (REG_P (operands[2]))
10305 return "sal{l}\t{%b2, %0|%0, %b2}";
10306 else if (operands[2] == const1_rtx
10307 && (TARGET_SHIFT1 || optimize_size))
10308 return "sal{l}\t%0";
10309 else
10310 return "sal{l}\t{%2, %0|%0, %2}";
10311 }
10312 }
10313 [(set (attr "type")
10314 (cond [(eq_attr "alternative" "1")
10315 (const_string "lea")
10316 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10317 (const_int 0))
10318 (match_operand 0 "register_operand" ""))
10319 (match_operand 2 "const1_operand" ""))
10320 (const_string "alu")
10321 ]
10322 (const_string "ishift")))
10323 (set_attr "mode" "SI")])
10324
10325 ;; Convert lea to the lea pattern to avoid flags dependency.
10326 (define_split
10327 [(set (match_operand 0 "register_operand" "")
10328 (ashift (match_operand 1 "index_register_operand" "")
10329 (match_operand:QI 2 "const_int_operand" "")))
10330 (clobber (reg:CC FLAGS_REG))]
10331 "reload_completed
10332 && true_regnum (operands[0]) != true_regnum (operands[1])
10333 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10334 [(const_int 0)]
10335 {
10336 rtx pat;
10337 enum machine_mode mode = GET_MODE (operands[0]);
10338
10339 if (GET_MODE_SIZE (mode) < 4)
10340 operands[0] = gen_lowpart (SImode, operands[0]);
10341 if (mode != Pmode)
10342 operands[1] = gen_lowpart (Pmode, operands[1]);
10343 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10344
10345 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10346 if (Pmode != SImode)
10347 pat = gen_rtx_SUBREG (SImode, pat, 0);
10348 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10349 DONE;
10350 })
10351
10352 ;; Rare case of shifting RSP is handled by generating move and shift
10353 (define_split
10354 [(set (match_operand 0 "register_operand" "")
10355 (ashift (match_operand 1 "register_operand" "")
10356 (match_operand:QI 2 "const_int_operand" "")))
10357 (clobber (reg:CC FLAGS_REG))]
10358 "reload_completed
10359 && true_regnum (operands[0]) != true_regnum (operands[1])"
10360 [(const_int 0)]
10361 {
10362 rtx pat, clob;
10363 emit_move_insn (operands[1], operands[0]);
10364 pat = gen_rtx_SET (VOIDmode, operands[0],
10365 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10366 operands[0], operands[2]));
10367 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10368 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10369 DONE;
10370 })
10371
10372 (define_insn "*ashlsi3_1_zext"
10373 [(set (match_operand:DI 0 "register_operand" "=r,r")
10374 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10375 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10376 (clobber (reg:CC FLAGS_REG))]
10377 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10378 {
10379 switch (get_attr_type (insn))
10380 {
10381 case TYPE_ALU:
10382 gcc_assert (operands[2] == const1_rtx);
10383 return "add{l}\t{%k0, %k0|%k0, %k0}";
10384
10385 case TYPE_LEA:
10386 return "#";
10387
10388 default:
10389 if (REG_P (operands[2]))
10390 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10391 else if (operands[2] == const1_rtx
10392 && (TARGET_SHIFT1 || optimize_size))
10393 return "sal{l}\t%k0";
10394 else
10395 return "sal{l}\t{%2, %k0|%k0, %2}";
10396 }
10397 }
10398 [(set (attr "type")
10399 (cond [(eq_attr "alternative" "1")
10400 (const_string "lea")
10401 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10402 (const_int 0))
10403 (match_operand 2 "const1_operand" ""))
10404 (const_string "alu")
10405 ]
10406 (const_string "ishift")))
10407 (set_attr "mode" "SI")])
10408
10409 ;; Convert lea to the lea pattern to avoid flags dependency.
10410 (define_split
10411 [(set (match_operand:DI 0 "register_operand" "")
10412 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10413 (match_operand:QI 2 "const_int_operand" ""))))
10414 (clobber (reg:CC FLAGS_REG))]
10415 "TARGET_64BIT && reload_completed
10416 && true_regnum (operands[0]) != true_regnum (operands[1])"
10417 [(set (match_dup 0) (zero_extend:DI
10418 (subreg:SI (mult:SI (match_dup 1)
10419 (match_dup 2)) 0)))]
10420 {
10421 operands[1] = gen_lowpart (Pmode, operands[1]);
10422 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10423 })
10424
10425 ;; This pattern can't accept a variable shift count, since shifts by
10426 ;; zero don't affect the flags. We assume that shifts by constant
10427 ;; zero are optimized away.
10428 (define_insn "*ashlsi3_cmp"
10429 [(set (reg FLAGS_REG)
10430 (compare
10431 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10432 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10433 (const_int 0)))
10434 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10435 (ashift:SI (match_dup 1) (match_dup 2)))]
10436 "ix86_match_ccmode (insn, CCGOCmode)
10437 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10438 {
10439 switch (get_attr_type (insn))
10440 {
10441 case TYPE_ALU:
10442 gcc_assert (operands[2] == const1_rtx);
10443 return "add{l}\t{%0, %0|%0, %0}";
10444
10445 default:
10446 if (REG_P (operands[2]))
10447 return "sal{l}\t{%b2, %0|%0, %b2}";
10448 else if (operands[2] == const1_rtx
10449 && (TARGET_SHIFT1 || optimize_size))
10450 return "sal{l}\t%0";
10451 else
10452 return "sal{l}\t{%2, %0|%0, %2}";
10453 }
10454 }
10455 [(set (attr "type")
10456 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10457 (const_int 0))
10458 (match_operand 0 "register_operand" ""))
10459 (match_operand 2 "const1_operand" ""))
10460 (const_string "alu")
10461 ]
10462 (const_string "ishift")))
10463 (set_attr "mode" "SI")])
10464
10465 (define_insn "*ashlsi3_cmp_zext"
10466 [(set (reg FLAGS_REG)
10467 (compare
10468 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10469 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10470 (const_int 0)))
10471 (set (match_operand:DI 0 "register_operand" "=r")
10472 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10473 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10474 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10475 {
10476 switch (get_attr_type (insn))
10477 {
10478 case TYPE_ALU:
10479 gcc_assert (operands[2] == const1_rtx);
10480 return "add{l}\t{%k0, %k0|%k0, %k0}";
10481
10482 default:
10483 if (REG_P (operands[2]))
10484 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10485 else if (operands[2] == const1_rtx
10486 && (TARGET_SHIFT1 || optimize_size))
10487 return "sal{l}\t%k0";
10488 else
10489 return "sal{l}\t{%2, %k0|%k0, %2}";
10490 }
10491 }
10492 [(set (attr "type")
10493 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10494 (const_int 0))
10495 (match_operand 2 "const1_operand" ""))
10496 (const_string "alu")
10497 ]
10498 (const_string "ishift")))
10499 (set_attr "mode" "SI")])
10500
10501 (define_expand "ashlhi3"
10502 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10503 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10504 (match_operand:QI 2 "nonmemory_operand" "")))
10505 (clobber (reg:CC FLAGS_REG))]
10506 "TARGET_HIMODE_MATH"
10507 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10508
10509 (define_insn "*ashlhi3_1_lea"
10510 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10511 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10512 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10513 (clobber (reg:CC FLAGS_REG))]
10514 "!TARGET_PARTIAL_REG_STALL
10515 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10516 {
10517 switch (get_attr_type (insn))
10518 {
10519 case TYPE_LEA:
10520 return "#";
10521 case TYPE_ALU:
10522 gcc_assert (operands[2] == const1_rtx);
10523 return "add{w}\t{%0, %0|%0, %0}";
10524
10525 default:
10526 if (REG_P (operands[2]))
10527 return "sal{w}\t{%b2, %0|%0, %b2}";
10528 else if (operands[2] == const1_rtx
10529 && (TARGET_SHIFT1 || optimize_size))
10530 return "sal{w}\t%0";
10531 else
10532 return "sal{w}\t{%2, %0|%0, %2}";
10533 }
10534 }
10535 [(set (attr "type")
10536 (cond [(eq_attr "alternative" "1")
10537 (const_string "lea")
10538 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10539 (const_int 0))
10540 (match_operand 0 "register_operand" ""))
10541 (match_operand 2 "const1_operand" ""))
10542 (const_string "alu")
10543 ]
10544 (const_string "ishift")))
10545 (set_attr "mode" "HI,SI")])
10546
10547 (define_insn "*ashlhi3_1"
10548 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10549 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10550 (match_operand:QI 2 "nonmemory_operand" "cI")))
10551 (clobber (reg:CC FLAGS_REG))]
10552 "TARGET_PARTIAL_REG_STALL
10553 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10554 {
10555 switch (get_attr_type (insn))
10556 {
10557 case TYPE_ALU:
10558 gcc_assert (operands[2] == const1_rtx);
10559 return "add{w}\t{%0, %0|%0, %0}";
10560
10561 default:
10562 if (REG_P (operands[2]))
10563 return "sal{w}\t{%b2, %0|%0, %b2}";
10564 else if (operands[2] == const1_rtx
10565 && (TARGET_SHIFT1 || optimize_size))
10566 return "sal{w}\t%0";
10567 else
10568 return "sal{w}\t{%2, %0|%0, %2}";
10569 }
10570 }
10571 [(set (attr "type")
10572 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10573 (const_int 0))
10574 (match_operand 0 "register_operand" ""))
10575 (match_operand 2 "const1_operand" ""))
10576 (const_string "alu")
10577 ]
10578 (const_string "ishift")))
10579 (set_attr "mode" "HI")])
10580
10581 ;; This pattern can't accept a variable shift count, since shifts by
10582 ;; zero don't affect the flags. We assume that shifts by constant
10583 ;; zero are optimized away.
10584 (define_insn "*ashlhi3_cmp"
10585 [(set (reg FLAGS_REG)
10586 (compare
10587 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10588 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10589 (const_int 0)))
10590 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10591 (ashift:HI (match_dup 1) (match_dup 2)))]
10592 "ix86_match_ccmode (insn, CCGOCmode)
10593 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10594 {
10595 switch (get_attr_type (insn))
10596 {
10597 case TYPE_ALU:
10598 gcc_assert (operands[2] == const1_rtx);
10599 return "add{w}\t{%0, %0|%0, %0}";
10600
10601 default:
10602 if (REG_P (operands[2]))
10603 return "sal{w}\t{%b2, %0|%0, %b2}";
10604 else if (operands[2] == const1_rtx
10605 && (TARGET_SHIFT1 || optimize_size))
10606 return "sal{w}\t%0";
10607 else
10608 return "sal{w}\t{%2, %0|%0, %2}";
10609 }
10610 }
10611 [(set (attr "type")
10612 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10613 (const_int 0))
10614 (match_operand 0 "register_operand" ""))
10615 (match_operand 2 "const1_operand" ""))
10616 (const_string "alu")
10617 ]
10618 (const_string "ishift")))
10619 (set_attr "mode" "HI")])
10620
10621 (define_expand "ashlqi3"
10622 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10623 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10624 (match_operand:QI 2 "nonmemory_operand" "")))
10625 (clobber (reg:CC FLAGS_REG))]
10626 "TARGET_QIMODE_MATH"
10627 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10628
10629 ;; %%% Potential partial reg stall on alternative 2. What to do?
10630
10631 (define_insn "*ashlqi3_1_lea"
10632 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10633 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10634 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10635 (clobber (reg:CC FLAGS_REG))]
10636 "!TARGET_PARTIAL_REG_STALL
10637 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10638 {
10639 switch (get_attr_type (insn))
10640 {
10641 case TYPE_LEA:
10642 return "#";
10643 case TYPE_ALU:
10644 gcc_assert (operands[2] == const1_rtx);
10645 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10646 return "add{l}\t{%k0, %k0|%k0, %k0}";
10647 else
10648 return "add{b}\t{%0, %0|%0, %0}";
10649
10650 default:
10651 if (REG_P (operands[2]))
10652 {
10653 if (get_attr_mode (insn) == MODE_SI)
10654 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10655 else
10656 return "sal{b}\t{%b2, %0|%0, %b2}";
10657 }
10658 else if (operands[2] == const1_rtx
10659 && (TARGET_SHIFT1 || optimize_size))
10660 {
10661 if (get_attr_mode (insn) == MODE_SI)
10662 return "sal{l}\t%0";
10663 else
10664 return "sal{b}\t%0";
10665 }
10666 else
10667 {
10668 if (get_attr_mode (insn) == MODE_SI)
10669 return "sal{l}\t{%2, %k0|%k0, %2}";
10670 else
10671 return "sal{b}\t{%2, %0|%0, %2}";
10672 }
10673 }
10674 }
10675 [(set (attr "type")
10676 (cond [(eq_attr "alternative" "2")
10677 (const_string "lea")
10678 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10679 (const_int 0))
10680 (match_operand 0 "register_operand" ""))
10681 (match_operand 2 "const1_operand" ""))
10682 (const_string "alu")
10683 ]
10684 (const_string "ishift")))
10685 (set_attr "mode" "QI,SI,SI")])
10686
10687 (define_insn "*ashlqi3_1"
10688 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10689 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10690 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10691 (clobber (reg:CC FLAGS_REG))]
10692 "TARGET_PARTIAL_REG_STALL
10693 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10694 {
10695 switch (get_attr_type (insn))
10696 {
10697 case TYPE_ALU:
10698 gcc_assert (operands[2] == const1_rtx);
10699 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10700 return "add{l}\t{%k0, %k0|%k0, %k0}";
10701 else
10702 return "add{b}\t{%0, %0|%0, %0}";
10703
10704 default:
10705 if (REG_P (operands[2]))
10706 {
10707 if (get_attr_mode (insn) == MODE_SI)
10708 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10709 else
10710 return "sal{b}\t{%b2, %0|%0, %b2}";
10711 }
10712 else if (operands[2] == const1_rtx
10713 && (TARGET_SHIFT1 || optimize_size))
10714 {
10715 if (get_attr_mode (insn) == MODE_SI)
10716 return "sal{l}\t%0";
10717 else
10718 return "sal{b}\t%0";
10719 }
10720 else
10721 {
10722 if (get_attr_mode (insn) == MODE_SI)
10723 return "sal{l}\t{%2, %k0|%k0, %2}";
10724 else
10725 return "sal{b}\t{%2, %0|%0, %2}";
10726 }
10727 }
10728 }
10729 [(set (attr "type")
10730 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10731 (const_int 0))
10732 (match_operand 0 "register_operand" ""))
10733 (match_operand 2 "const1_operand" ""))
10734 (const_string "alu")
10735 ]
10736 (const_string "ishift")))
10737 (set_attr "mode" "QI,SI")])
10738
10739 ;; This pattern can't accept a variable shift count, since shifts by
10740 ;; zero don't affect the flags. We assume that shifts by constant
10741 ;; zero are optimized away.
10742 (define_insn "*ashlqi3_cmp"
10743 [(set (reg FLAGS_REG)
10744 (compare
10745 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10746 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10747 (const_int 0)))
10748 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10749 (ashift:QI (match_dup 1) (match_dup 2)))]
10750 "ix86_match_ccmode (insn, CCGOCmode)
10751 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10752 {
10753 switch (get_attr_type (insn))
10754 {
10755 case TYPE_ALU:
10756 gcc_assert (operands[2] == const1_rtx);
10757 return "add{b}\t{%0, %0|%0, %0}";
10758
10759 default:
10760 if (REG_P (operands[2]))
10761 return "sal{b}\t{%b2, %0|%0, %b2}";
10762 else if (operands[2] == const1_rtx
10763 && (TARGET_SHIFT1 || optimize_size))
10764 return "sal{b}\t%0";
10765 else
10766 return "sal{b}\t{%2, %0|%0, %2}";
10767 }
10768 }
10769 [(set (attr "type")
10770 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10771 (const_int 0))
10772 (match_operand 0 "register_operand" ""))
10773 (match_operand 2 "const1_operand" ""))
10774 (const_string "alu")
10775 ]
10776 (const_string "ishift")))
10777 (set_attr "mode" "QI")])
10778
10779 ;; See comment above `ashldi3' about how this works.
10780
10781 (define_expand "ashrdi3"
10782 [(set (match_operand:DI 0 "shiftdi_operand" "")
10783 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10784 (match_operand:QI 2 "nonmemory_operand" "")))]
10785 ""
10786 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10787
10788 (define_insn "*ashrdi3_63_rex64"
10789 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10790 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10791 (match_operand:DI 2 "const_int_operand" "i,i")))
10792 (clobber (reg:CC FLAGS_REG))]
10793 "TARGET_64BIT && INTVAL (operands[2]) == 63
10794 && (TARGET_USE_CLTD || optimize_size)
10795 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10796 "@
10797 {cqto|cqo}
10798 sar{q}\t{%2, %0|%0, %2}"
10799 [(set_attr "type" "imovx,ishift")
10800 (set_attr "prefix_0f" "0,*")
10801 (set_attr "length_immediate" "0,*")
10802 (set_attr "modrm" "0,1")
10803 (set_attr "mode" "DI")])
10804
10805 (define_insn "*ashrdi3_1_one_bit_rex64"
10806 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10807 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10808 (match_operand:QI 2 "const1_operand" "")))
10809 (clobber (reg:CC FLAGS_REG))]
10810 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10811 && (TARGET_SHIFT1 || optimize_size)"
10812 "sar{q}\t%0"
10813 [(set_attr "type" "ishift")
10814 (set (attr "length")
10815 (if_then_else (match_operand:DI 0 "register_operand" "")
10816 (const_string "2")
10817 (const_string "*")))])
10818
10819 (define_insn "*ashrdi3_1_rex64"
10820 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10821 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10822 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10823 (clobber (reg:CC FLAGS_REG))]
10824 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10825 "@
10826 sar{q}\t{%2, %0|%0, %2}
10827 sar{q}\t{%b2, %0|%0, %b2}"
10828 [(set_attr "type" "ishift")
10829 (set_attr "mode" "DI")])
10830
10831 ;; This pattern can't accept a variable shift count, since shifts by
10832 ;; zero don't affect the flags. We assume that shifts by constant
10833 ;; zero are optimized away.
10834 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10835 [(set (reg FLAGS_REG)
10836 (compare
10837 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10838 (match_operand:QI 2 "const1_operand" ""))
10839 (const_int 0)))
10840 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10841 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10842 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10843 && (TARGET_SHIFT1 || optimize_size)
10844 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10845 "sar{q}\t%0"
10846 [(set_attr "type" "ishift")
10847 (set (attr "length")
10848 (if_then_else (match_operand:DI 0 "register_operand" "")
10849 (const_string "2")
10850 (const_string "*")))])
10851
10852 ;; This pattern can't accept a variable shift count, since shifts by
10853 ;; zero don't affect the flags. We assume that shifts by constant
10854 ;; zero are optimized away.
10855 (define_insn "*ashrdi3_cmp_rex64"
10856 [(set (reg FLAGS_REG)
10857 (compare
10858 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10859 (match_operand:QI 2 "const_int_operand" "n"))
10860 (const_int 0)))
10861 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10862 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10863 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10864 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10865 "sar{q}\t{%2, %0|%0, %2}"
10866 [(set_attr "type" "ishift")
10867 (set_attr "mode" "DI")])
10868
10869 (define_insn "*ashrdi3_1"
10870 [(set (match_operand:DI 0 "register_operand" "=r")
10871 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10872 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10873 (clobber (reg:CC FLAGS_REG))]
10874 "!TARGET_64BIT"
10875 "#"
10876 [(set_attr "type" "multi")])
10877
10878 ;; By default we don't ask for a scratch register, because when DImode
10879 ;; values are manipulated, registers are already at a premium. But if
10880 ;; we have one handy, we won't turn it away.
10881 (define_peephole2
10882 [(match_scratch:SI 3 "r")
10883 (parallel [(set (match_operand:DI 0 "register_operand" "")
10884 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10885 (match_operand:QI 2 "nonmemory_operand" "")))
10886 (clobber (reg:CC FLAGS_REG))])
10887 (match_dup 3)]
10888 "!TARGET_64BIT && TARGET_CMOVE"
10889 [(const_int 0)]
10890 "ix86_split_ashrdi (operands, operands[3]); DONE;")
10891
10892 (define_split
10893 [(set (match_operand:DI 0 "register_operand" "")
10894 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10895 (match_operand:QI 2 "nonmemory_operand" "")))
10896 (clobber (reg:CC FLAGS_REG))]
10897 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10898 [(const_int 0)]
10899 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10900
10901 (define_insn "x86_shrd_1"
10902 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10903 (ior:SI (ashiftrt:SI (match_dup 0)
10904 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10905 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10906 (minus:QI (const_int 32) (match_dup 2)))))
10907 (clobber (reg:CC FLAGS_REG))]
10908 ""
10909 "@
10910 shrd{l}\t{%2, %1, %0|%0, %1, %2}
10911 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10912 [(set_attr "type" "ishift")
10913 (set_attr "prefix_0f" "1")
10914 (set_attr "pent_pair" "np")
10915 (set_attr "mode" "SI")])
10916
10917 (define_expand "x86_shift_adj_3"
10918 [(use (match_operand:SI 0 "register_operand" ""))
10919 (use (match_operand:SI 1 "register_operand" ""))
10920 (use (match_operand:QI 2 "register_operand" ""))]
10921 ""
10922 {
10923 rtx label = gen_label_rtx ();
10924 rtx tmp;
10925
10926 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10927
10928 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10929 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10930 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10931 gen_rtx_LABEL_REF (VOIDmode, label),
10932 pc_rtx);
10933 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10934 JUMP_LABEL (tmp) = label;
10935
10936 emit_move_insn (operands[0], operands[1]);
10937 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10938
10939 emit_label (label);
10940 LABEL_NUSES (label) = 1;
10941
10942 DONE;
10943 })
10944
10945 (define_insn "ashrsi3_31"
10946 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10947 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10948 (match_operand:SI 2 "const_int_operand" "i,i")))
10949 (clobber (reg:CC FLAGS_REG))]
10950 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10951 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10952 "@
10953 {cltd|cdq}
10954 sar{l}\t{%2, %0|%0, %2}"
10955 [(set_attr "type" "imovx,ishift")
10956 (set_attr "prefix_0f" "0,*")
10957 (set_attr "length_immediate" "0,*")
10958 (set_attr "modrm" "0,1")
10959 (set_attr "mode" "SI")])
10960
10961 (define_insn "*ashrsi3_31_zext"
10962 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10963 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10964 (match_operand:SI 2 "const_int_operand" "i,i"))))
10965 (clobber (reg:CC FLAGS_REG))]
10966 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10967 && INTVAL (operands[2]) == 31
10968 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10969 "@
10970 {cltd|cdq}
10971 sar{l}\t{%2, %k0|%k0, %2}"
10972 [(set_attr "type" "imovx,ishift")
10973 (set_attr "prefix_0f" "0,*")
10974 (set_attr "length_immediate" "0,*")
10975 (set_attr "modrm" "0,1")
10976 (set_attr "mode" "SI")])
10977
10978 (define_expand "ashrsi3"
10979 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10980 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10981 (match_operand:QI 2 "nonmemory_operand" "")))
10982 (clobber (reg:CC FLAGS_REG))]
10983 ""
10984 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10985
10986 (define_insn "*ashrsi3_1_one_bit"
10987 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10988 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10989 (match_operand:QI 2 "const1_operand" "")))
10990 (clobber (reg:CC FLAGS_REG))]
10991 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10992 && (TARGET_SHIFT1 || optimize_size)"
10993 "sar{l}\t%0"
10994 [(set_attr "type" "ishift")
10995 (set (attr "length")
10996 (if_then_else (match_operand:SI 0 "register_operand" "")
10997 (const_string "2")
10998 (const_string "*")))])
10999
11000 (define_insn "*ashrsi3_1_one_bit_zext"
11001 [(set (match_operand:DI 0 "register_operand" "=r")
11002 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11003 (match_operand:QI 2 "const1_operand" ""))))
11004 (clobber (reg:CC FLAGS_REG))]
11005 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11006 && (TARGET_SHIFT1 || optimize_size)"
11007 "sar{l}\t%k0"
11008 [(set_attr "type" "ishift")
11009 (set_attr "length" "2")])
11010
11011 (define_insn "*ashrsi3_1"
11012 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11013 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11014 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11015 (clobber (reg:CC FLAGS_REG))]
11016 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11017 "@
11018 sar{l}\t{%2, %0|%0, %2}
11019 sar{l}\t{%b2, %0|%0, %b2}"
11020 [(set_attr "type" "ishift")
11021 (set_attr "mode" "SI")])
11022
11023 (define_insn "*ashrsi3_1_zext"
11024 [(set (match_operand:DI 0 "register_operand" "=r,r")
11025 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11026 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11027 (clobber (reg:CC FLAGS_REG))]
11028 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11029 "@
11030 sar{l}\t{%2, %k0|%k0, %2}
11031 sar{l}\t{%b2, %k0|%k0, %b2}"
11032 [(set_attr "type" "ishift")
11033 (set_attr "mode" "SI")])
11034
11035 ;; This pattern can't accept a variable shift count, since shifts by
11036 ;; zero don't affect the flags. We assume that shifts by constant
11037 ;; zero are optimized away.
11038 (define_insn "*ashrsi3_one_bit_cmp"
11039 [(set (reg FLAGS_REG)
11040 (compare
11041 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11042 (match_operand:QI 2 "const1_operand" ""))
11043 (const_int 0)))
11044 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11045 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11046 "ix86_match_ccmode (insn, CCGOCmode)
11047 && (TARGET_SHIFT1 || optimize_size)
11048 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11049 "sar{l}\t%0"
11050 [(set_attr "type" "ishift")
11051 (set (attr "length")
11052 (if_then_else (match_operand:SI 0 "register_operand" "")
11053 (const_string "2")
11054 (const_string "*")))])
11055
11056 (define_insn "*ashrsi3_one_bit_cmp_zext"
11057 [(set (reg FLAGS_REG)
11058 (compare
11059 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11060 (match_operand:QI 2 "const1_operand" ""))
11061 (const_int 0)))
11062 (set (match_operand:DI 0 "register_operand" "=r")
11063 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11064 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11065 && (TARGET_SHIFT1 || optimize_size)
11066 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11067 "sar{l}\t%k0"
11068 [(set_attr "type" "ishift")
11069 (set_attr "length" "2")])
11070
11071 ;; This pattern can't accept a variable shift count, since shifts by
11072 ;; zero don't affect the flags. We assume that shifts by constant
11073 ;; zero are optimized away.
11074 (define_insn "*ashrsi3_cmp"
11075 [(set (reg FLAGS_REG)
11076 (compare
11077 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11078 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11079 (const_int 0)))
11080 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11081 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11082 "ix86_match_ccmode (insn, CCGOCmode)
11083 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11084 "sar{l}\t{%2, %0|%0, %2}"
11085 [(set_attr "type" "ishift")
11086 (set_attr "mode" "SI")])
11087
11088 (define_insn "*ashrsi3_cmp_zext"
11089 [(set (reg FLAGS_REG)
11090 (compare
11091 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11092 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11093 (const_int 0)))
11094 (set (match_operand:DI 0 "register_operand" "=r")
11095 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11096 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11097 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11098 "sar{l}\t{%2, %k0|%k0, %2}"
11099 [(set_attr "type" "ishift")
11100 (set_attr "mode" "SI")])
11101
11102 (define_expand "ashrhi3"
11103 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11104 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11105 (match_operand:QI 2 "nonmemory_operand" "")))
11106 (clobber (reg:CC FLAGS_REG))]
11107 "TARGET_HIMODE_MATH"
11108 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11109
11110 (define_insn "*ashrhi3_1_one_bit"
11111 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11112 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11113 (match_operand:QI 2 "const1_operand" "")))
11114 (clobber (reg:CC FLAGS_REG))]
11115 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11116 && (TARGET_SHIFT1 || optimize_size)"
11117 "sar{w}\t%0"
11118 [(set_attr "type" "ishift")
11119 (set (attr "length")
11120 (if_then_else (match_operand 0 "register_operand" "")
11121 (const_string "2")
11122 (const_string "*")))])
11123
11124 (define_insn "*ashrhi3_1"
11125 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11126 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11127 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11128 (clobber (reg:CC FLAGS_REG))]
11129 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11130 "@
11131 sar{w}\t{%2, %0|%0, %2}
11132 sar{w}\t{%b2, %0|%0, %b2}"
11133 [(set_attr "type" "ishift")
11134 (set_attr "mode" "HI")])
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 "*ashrhi3_one_bit_cmp"
11140 [(set (reg FLAGS_REG)
11141 (compare
11142 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11143 (match_operand:QI 2 "const1_operand" ""))
11144 (const_int 0)))
11145 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11146 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11147 "ix86_match_ccmode (insn, CCGOCmode)
11148 && (TARGET_SHIFT1 || optimize_size)
11149 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11150 "sar{w}\t%0"
11151 [(set_attr "type" "ishift")
11152 (set (attr "length")
11153 (if_then_else (match_operand 0 "register_operand" "")
11154 (const_string "2")
11155 (const_string "*")))])
11156
11157 ;; This pattern can't accept a variable shift count, since shifts by
11158 ;; zero don't affect the flags. We assume that shifts by constant
11159 ;; zero are optimized away.
11160 (define_insn "*ashrhi3_cmp"
11161 [(set (reg FLAGS_REG)
11162 (compare
11163 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11164 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11165 (const_int 0)))
11166 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11167 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11168 "ix86_match_ccmode (insn, CCGOCmode)
11169 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11170 "sar{w}\t{%2, %0|%0, %2}"
11171 [(set_attr "type" "ishift")
11172 (set_attr "mode" "HI")])
11173
11174 (define_expand "ashrqi3"
11175 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11176 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11177 (match_operand:QI 2 "nonmemory_operand" "")))
11178 (clobber (reg:CC FLAGS_REG))]
11179 "TARGET_QIMODE_MATH"
11180 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11181
11182 (define_insn "*ashrqi3_1_one_bit"
11183 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11184 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11185 (match_operand:QI 2 "const1_operand" "")))
11186 (clobber (reg:CC FLAGS_REG))]
11187 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11188 && (TARGET_SHIFT1 || optimize_size)"
11189 "sar{b}\t%0"
11190 [(set_attr "type" "ishift")
11191 (set (attr "length")
11192 (if_then_else (match_operand 0 "register_operand" "")
11193 (const_string "2")
11194 (const_string "*")))])
11195
11196 (define_insn "*ashrqi3_1_one_bit_slp"
11197 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11198 (ashiftrt:QI (match_dup 0)
11199 (match_operand:QI 1 "const1_operand" "")))
11200 (clobber (reg:CC FLAGS_REG))]
11201 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11202 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11203 && (TARGET_SHIFT1 || optimize_size)"
11204 "sar{b}\t%0"
11205 [(set_attr "type" "ishift1")
11206 (set (attr "length")
11207 (if_then_else (match_operand 0 "register_operand" "")
11208 (const_string "2")
11209 (const_string "*")))])
11210
11211 (define_insn "*ashrqi3_1"
11212 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11213 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11214 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11215 (clobber (reg:CC FLAGS_REG))]
11216 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11217 "@
11218 sar{b}\t{%2, %0|%0, %2}
11219 sar{b}\t{%b2, %0|%0, %b2}"
11220 [(set_attr "type" "ishift")
11221 (set_attr "mode" "QI")])
11222
11223 (define_insn "*ashrqi3_1_slp"
11224 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11225 (ashiftrt:QI (match_dup 0)
11226 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11227 (clobber (reg:CC FLAGS_REG))]
11228 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11229 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11230 "@
11231 sar{b}\t{%1, %0|%0, %1}
11232 sar{b}\t{%b1, %0|%0, %b1}"
11233 [(set_attr "type" "ishift1")
11234 (set_attr "mode" "QI")])
11235
11236 ;; This pattern can't accept a variable shift count, since shifts by
11237 ;; zero don't affect the flags. We assume that shifts by constant
11238 ;; zero are optimized away.
11239 (define_insn "*ashrqi3_one_bit_cmp"
11240 [(set (reg FLAGS_REG)
11241 (compare
11242 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11243 (match_operand:QI 2 "const1_operand" "I"))
11244 (const_int 0)))
11245 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11246 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11247 "ix86_match_ccmode (insn, CCGOCmode)
11248 && (TARGET_SHIFT1 || optimize_size)
11249 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11250 "sar{b}\t%0"
11251 [(set_attr "type" "ishift")
11252 (set (attr "length")
11253 (if_then_else (match_operand 0 "register_operand" "")
11254 (const_string "2")
11255 (const_string "*")))])
11256
11257 ;; This pattern can't accept a variable shift count, since shifts by
11258 ;; zero don't affect the flags. We assume that shifts by constant
11259 ;; zero are optimized away.
11260 (define_insn "*ashrqi3_cmp"
11261 [(set (reg FLAGS_REG)
11262 (compare
11263 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11264 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11265 (const_int 0)))
11266 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11267 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11268 "ix86_match_ccmode (insn, CCGOCmode)
11269 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11270 "sar{b}\t{%2, %0|%0, %2}"
11271 [(set_attr "type" "ishift")
11272 (set_attr "mode" "QI")])
11273 \f
11274 ;; Logical shift instructions
11275
11276 ;; See comment above `ashldi3' about how this works.
11277
11278 (define_expand "lshrdi3"
11279 [(set (match_operand:DI 0 "shiftdi_operand" "")
11280 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11281 (match_operand:QI 2 "nonmemory_operand" "")))]
11282 ""
11283 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11284
11285 (define_insn "*lshrdi3_1_one_bit_rex64"
11286 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11287 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11288 (match_operand:QI 2 "const1_operand" "")))
11289 (clobber (reg:CC FLAGS_REG))]
11290 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11291 && (TARGET_SHIFT1 || optimize_size)"
11292 "shr{q}\t%0"
11293 [(set_attr "type" "ishift")
11294 (set (attr "length")
11295 (if_then_else (match_operand:DI 0 "register_operand" "")
11296 (const_string "2")
11297 (const_string "*")))])
11298
11299 (define_insn "*lshrdi3_1_rex64"
11300 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11301 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11302 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11303 (clobber (reg:CC FLAGS_REG))]
11304 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11305 "@
11306 shr{q}\t{%2, %0|%0, %2}
11307 shr{q}\t{%b2, %0|%0, %b2}"
11308 [(set_attr "type" "ishift")
11309 (set_attr "mode" "DI")])
11310
11311 ;; This pattern can't accept a variable shift count, since shifts by
11312 ;; zero don't affect the flags. We assume that shifts by constant
11313 ;; zero are optimized away.
11314 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11315 [(set (reg FLAGS_REG)
11316 (compare
11317 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11318 (match_operand:QI 2 "const1_operand" ""))
11319 (const_int 0)))
11320 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11321 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11322 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11323 && (TARGET_SHIFT1 || optimize_size)
11324 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11325 "shr{q}\t%0"
11326 [(set_attr "type" "ishift")
11327 (set (attr "length")
11328 (if_then_else (match_operand:DI 0 "register_operand" "")
11329 (const_string "2")
11330 (const_string "*")))])
11331
11332 ;; This pattern can't accept a variable shift count, since shifts by
11333 ;; zero don't affect the flags. We assume that shifts by constant
11334 ;; zero are optimized away.
11335 (define_insn "*lshrdi3_cmp_rex64"
11336 [(set (reg FLAGS_REG)
11337 (compare
11338 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11339 (match_operand:QI 2 "const_int_operand" "e"))
11340 (const_int 0)))
11341 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11342 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11343 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11344 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11345 "shr{q}\t{%2, %0|%0, %2}"
11346 [(set_attr "type" "ishift")
11347 (set_attr "mode" "DI")])
11348
11349 (define_insn "*lshrdi3_1"
11350 [(set (match_operand:DI 0 "register_operand" "=r")
11351 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11352 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11353 (clobber (reg:CC FLAGS_REG))]
11354 "!TARGET_64BIT"
11355 "#"
11356 [(set_attr "type" "multi")])
11357
11358 ;; By default we don't ask for a scratch register, because when DImode
11359 ;; values are manipulated, registers are already at a premium. But if
11360 ;; we have one handy, we won't turn it away.
11361 (define_peephole2
11362 [(match_scratch:SI 3 "r")
11363 (parallel [(set (match_operand:DI 0 "register_operand" "")
11364 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11365 (match_operand:QI 2 "nonmemory_operand" "")))
11366 (clobber (reg:CC FLAGS_REG))])
11367 (match_dup 3)]
11368 "!TARGET_64BIT && TARGET_CMOVE"
11369 [(const_int 0)]
11370 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11371
11372 (define_split
11373 [(set (match_operand:DI 0 "register_operand" "")
11374 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11375 (match_operand:QI 2 "nonmemory_operand" "")))
11376 (clobber (reg:CC FLAGS_REG))]
11377 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11378 [(const_int 0)]
11379 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11380
11381 (define_expand "lshrsi3"
11382 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11383 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11384 (match_operand:QI 2 "nonmemory_operand" "")))
11385 (clobber (reg:CC FLAGS_REG))]
11386 ""
11387 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11388
11389 (define_insn "*lshrsi3_1_one_bit"
11390 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11391 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11392 (match_operand:QI 2 "const1_operand" "")))
11393 (clobber (reg:CC FLAGS_REG))]
11394 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11395 && (TARGET_SHIFT1 || optimize_size)"
11396 "shr{l}\t%0"
11397 [(set_attr "type" "ishift")
11398 (set (attr "length")
11399 (if_then_else (match_operand:SI 0 "register_operand" "")
11400 (const_string "2")
11401 (const_string "*")))])
11402
11403 (define_insn "*lshrsi3_1_one_bit_zext"
11404 [(set (match_operand:DI 0 "register_operand" "=r")
11405 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11406 (match_operand:QI 2 "const1_operand" "")))
11407 (clobber (reg:CC FLAGS_REG))]
11408 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11409 && (TARGET_SHIFT1 || optimize_size)"
11410 "shr{l}\t%k0"
11411 [(set_attr "type" "ishift")
11412 (set_attr "length" "2")])
11413
11414 (define_insn "*lshrsi3_1"
11415 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11416 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11417 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11418 (clobber (reg:CC FLAGS_REG))]
11419 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11420 "@
11421 shr{l}\t{%2, %0|%0, %2}
11422 shr{l}\t{%b2, %0|%0, %b2}"
11423 [(set_attr "type" "ishift")
11424 (set_attr "mode" "SI")])
11425
11426 (define_insn "*lshrsi3_1_zext"
11427 [(set (match_operand:DI 0 "register_operand" "=r,r")
11428 (zero_extend:DI
11429 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11430 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11431 (clobber (reg:CC FLAGS_REG))]
11432 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11433 "@
11434 shr{l}\t{%2, %k0|%k0, %2}
11435 shr{l}\t{%b2, %k0|%k0, %b2}"
11436 [(set_attr "type" "ishift")
11437 (set_attr "mode" "SI")])
11438
11439 ;; This pattern can't accept a variable shift count, since shifts by
11440 ;; zero don't affect the flags. We assume that shifts by constant
11441 ;; zero are optimized away.
11442 (define_insn "*lshrsi3_one_bit_cmp"
11443 [(set (reg FLAGS_REG)
11444 (compare
11445 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11446 (match_operand:QI 2 "const1_operand" ""))
11447 (const_int 0)))
11448 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11449 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11450 "ix86_match_ccmode (insn, CCGOCmode)
11451 && (TARGET_SHIFT1 || optimize_size)
11452 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11453 "shr{l}\t%0"
11454 [(set_attr "type" "ishift")
11455 (set (attr "length")
11456 (if_then_else (match_operand:SI 0 "register_operand" "")
11457 (const_string "2")
11458 (const_string "*")))])
11459
11460 (define_insn "*lshrsi3_cmp_one_bit_zext"
11461 [(set (reg FLAGS_REG)
11462 (compare
11463 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11464 (match_operand:QI 2 "const1_operand" ""))
11465 (const_int 0)))
11466 (set (match_operand:DI 0 "register_operand" "=r")
11467 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11468 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11469 && (TARGET_SHIFT1 || optimize_size)
11470 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11471 "shr{l}\t%k0"
11472 [(set_attr "type" "ishift")
11473 (set_attr "length" "2")])
11474
11475 ;; This pattern can't accept a variable shift count, since shifts by
11476 ;; zero don't affect the flags. We assume that shifts by constant
11477 ;; zero are optimized away.
11478 (define_insn "*lshrsi3_cmp"
11479 [(set (reg FLAGS_REG)
11480 (compare
11481 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11482 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11483 (const_int 0)))
11484 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11485 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11486 "ix86_match_ccmode (insn, CCGOCmode)
11487 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11488 "shr{l}\t{%2, %0|%0, %2}"
11489 [(set_attr "type" "ishift")
11490 (set_attr "mode" "SI")])
11491
11492 (define_insn "*lshrsi3_cmp_zext"
11493 [(set (reg FLAGS_REG)
11494 (compare
11495 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11496 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11497 (const_int 0)))
11498 (set (match_operand:DI 0 "register_operand" "=r")
11499 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11500 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11501 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11502 "shr{l}\t{%2, %k0|%k0, %2}"
11503 [(set_attr "type" "ishift")
11504 (set_attr "mode" "SI")])
11505
11506 (define_expand "lshrhi3"
11507 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11508 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11509 (match_operand:QI 2 "nonmemory_operand" "")))
11510 (clobber (reg:CC FLAGS_REG))]
11511 "TARGET_HIMODE_MATH"
11512 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11513
11514 (define_insn "*lshrhi3_1_one_bit"
11515 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11516 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11517 (match_operand:QI 2 "const1_operand" "")))
11518 (clobber (reg:CC FLAGS_REG))]
11519 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11520 && (TARGET_SHIFT1 || optimize_size)"
11521 "shr{w}\t%0"
11522 [(set_attr "type" "ishift")
11523 (set (attr "length")
11524 (if_then_else (match_operand 0 "register_operand" "")
11525 (const_string "2")
11526 (const_string "*")))])
11527
11528 (define_insn "*lshrhi3_1"
11529 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11530 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11531 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11532 (clobber (reg:CC FLAGS_REG))]
11533 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11534 "@
11535 shr{w}\t{%2, %0|%0, %2}
11536 shr{w}\t{%b2, %0|%0, %b2}"
11537 [(set_attr "type" "ishift")
11538 (set_attr "mode" "HI")])
11539
11540 ;; This pattern can't accept a variable shift count, since shifts by
11541 ;; zero don't affect the flags. We assume that shifts by constant
11542 ;; zero are optimized away.
11543 (define_insn "*lshrhi3_one_bit_cmp"
11544 [(set (reg FLAGS_REG)
11545 (compare
11546 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11547 (match_operand:QI 2 "const1_operand" ""))
11548 (const_int 0)))
11549 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11550 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11551 "ix86_match_ccmode (insn, CCGOCmode)
11552 && (TARGET_SHIFT1 || optimize_size)
11553 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11554 "shr{w}\t%0"
11555 [(set_attr "type" "ishift")
11556 (set (attr "length")
11557 (if_then_else (match_operand:SI 0 "register_operand" "")
11558 (const_string "2")
11559 (const_string "*")))])
11560
11561 ;; This pattern can't accept a variable shift count, since shifts by
11562 ;; zero don't affect the flags. We assume that shifts by constant
11563 ;; zero are optimized away.
11564 (define_insn "*lshrhi3_cmp"
11565 [(set (reg FLAGS_REG)
11566 (compare
11567 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11568 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11569 (const_int 0)))
11570 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11571 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11572 "ix86_match_ccmode (insn, CCGOCmode)
11573 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11574 "shr{w}\t{%2, %0|%0, %2}"
11575 [(set_attr "type" "ishift")
11576 (set_attr "mode" "HI")])
11577
11578 (define_expand "lshrqi3"
11579 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11580 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11581 (match_operand:QI 2 "nonmemory_operand" "")))
11582 (clobber (reg:CC FLAGS_REG))]
11583 "TARGET_QIMODE_MATH"
11584 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11585
11586 (define_insn "*lshrqi3_1_one_bit"
11587 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11588 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11589 (match_operand:QI 2 "const1_operand" "")))
11590 (clobber (reg:CC FLAGS_REG))]
11591 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11592 && (TARGET_SHIFT1 || optimize_size)"
11593 "shr{b}\t%0"
11594 [(set_attr "type" "ishift")
11595 (set (attr "length")
11596 (if_then_else (match_operand 0 "register_operand" "")
11597 (const_string "2")
11598 (const_string "*")))])
11599
11600 (define_insn "*lshrqi3_1_one_bit_slp"
11601 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11602 (lshiftrt:QI (match_dup 0)
11603 (match_operand:QI 1 "const1_operand" "")))
11604 (clobber (reg:CC FLAGS_REG))]
11605 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11606 && (TARGET_SHIFT1 || optimize_size)"
11607 "shr{b}\t%0"
11608 [(set_attr "type" "ishift1")
11609 (set (attr "length")
11610 (if_then_else (match_operand 0 "register_operand" "")
11611 (const_string "2")
11612 (const_string "*")))])
11613
11614 (define_insn "*lshrqi3_1"
11615 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11616 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11617 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11618 (clobber (reg:CC FLAGS_REG))]
11619 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11620 "@
11621 shr{b}\t{%2, %0|%0, %2}
11622 shr{b}\t{%b2, %0|%0, %b2}"
11623 [(set_attr "type" "ishift")
11624 (set_attr "mode" "QI")])
11625
11626 (define_insn "*lshrqi3_1_slp"
11627 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11628 (lshiftrt:QI (match_dup 0)
11629 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11630 (clobber (reg:CC FLAGS_REG))]
11631 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11632 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11633 "@
11634 shr{b}\t{%1, %0|%0, %1}
11635 shr{b}\t{%b1, %0|%0, %b1}"
11636 [(set_attr "type" "ishift1")
11637 (set_attr "mode" "QI")])
11638
11639 ;; This pattern can't accept a variable shift count, since shifts by
11640 ;; zero don't affect the flags. We assume that shifts by constant
11641 ;; zero are optimized away.
11642 (define_insn "*lshrqi2_one_bit_cmp"
11643 [(set (reg FLAGS_REG)
11644 (compare
11645 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11646 (match_operand:QI 2 "const1_operand" ""))
11647 (const_int 0)))
11648 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11649 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11650 "ix86_match_ccmode (insn, CCGOCmode)
11651 && (TARGET_SHIFT1 || optimize_size)
11652 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11653 "shr{b}\t%0"
11654 [(set_attr "type" "ishift")
11655 (set (attr "length")
11656 (if_then_else (match_operand:SI 0 "register_operand" "")
11657 (const_string "2")
11658 (const_string "*")))])
11659
11660 ;; This pattern can't accept a variable shift count, since shifts by
11661 ;; zero don't affect the flags. We assume that shifts by constant
11662 ;; zero are optimized away.
11663 (define_insn "*lshrqi2_cmp"
11664 [(set (reg FLAGS_REG)
11665 (compare
11666 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11667 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11668 (const_int 0)))
11669 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11670 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11671 "ix86_match_ccmode (insn, CCGOCmode)
11672 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11673 "shr{b}\t{%2, %0|%0, %2}"
11674 [(set_attr "type" "ishift")
11675 (set_attr "mode" "QI")])
11676 \f
11677 ;; Rotate instructions
11678
11679 (define_expand "rotldi3"
11680 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11681 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11682 (match_operand:QI 2 "nonmemory_operand" "")))
11683 (clobber (reg:CC FLAGS_REG))]
11684 "TARGET_64BIT"
11685 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11686
11687 (define_insn "*rotlsi3_1_one_bit_rex64"
11688 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11689 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11690 (match_operand:QI 2 "const1_operand" "")))
11691 (clobber (reg:CC FLAGS_REG))]
11692 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11693 && (TARGET_SHIFT1 || optimize_size)"
11694 "rol{q}\t%0"
11695 [(set_attr "type" "rotate")
11696 (set (attr "length")
11697 (if_then_else (match_operand:DI 0 "register_operand" "")
11698 (const_string "2")
11699 (const_string "*")))])
11700
11701 (define_insn "*rotldi3_1_rex64"
11702 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11703 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11704 (match_operand:QI 2 "nonmemory_operand" "e,c")))
11705 (clobber (reg:CC FLAGS_REG))]
11706 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11707 "@
11708 rol{q}\t{%2, %0|%0, %2}
11709 rol{q}\t{%b2, %0|%0, %b2}"
11710 [(set_attr "type" "rotate")
11711 (set_attr "mode" "DI")])
11712
11713 (define_expand "rotlsi3"
11714 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11715 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11716 (match_operand:QI 2 "nonmemory_operand" "")))
11717 (clobber (reg:CC FLAGS_REG))]
11718 ""
11719 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11720
11721 (define_insn "*rotlsi3_1_one_bit"
11722 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11723 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11724 (match_operand:QI 2 "const1_operand" "")))
11725 (clobber (reg:CC FLAGS_REG))]
11726 "ix86_binary_operator_ok (ROTATE, SImode, operands)
11727 && (TARGET_SHIFT1 || optimize_size)"
11728 "rol{l}\t%0"
11729 [(set_attr "type" "rotate")
11730 (set (attr "length")
11731 (if_then_else (match_operand:SI 0 "register_operand" "")
11732 (const_string "2")
11733 (const_string "*")))])
11734
11735 (define_insn "*rotlsi3_1_one_bit_zext"
11736 [(set (match_operand:DI 0 "register_operand" "=r")
11737 (zero_extend:DI
11738 (rotate:SI (match_operand:SI 1 "register_operand" "0")
11739 (match_operand:QI 2 "const1_operand" ""))))
11740 (clobber (reg:CC FLAGS_REG))]
11741 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11742 && (TARGET_SHIFT1 || optimize_size)"
11743 "rol{l}\t%k0"
11744 [(set_attr "type" "rotate")
11745 (set_attr "length" "2")])
11746
11747 (define_insn "*rotlsi3_1"
11748 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11749 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11750 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11751 (clobber (reg:CC FLAGS_REG))]
11752 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11753 "@
11754 rol{l}\t{%2, %0|%0, %2}
11755 rol{l}\t{%b2, %0|%0, %b2}"
11756 [(set_attr "type" "rotate")
11757 (set_attr "mode" "SI")])
11758
11759 (define_insn "*rotlsi3_1_zext"
11760 [(set (match_operand:DI 0 "register_operand" "=r,r")
11761 (zero_extend:DI
11762 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11763 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11764 (clobber (reg:CC FLAGS_REG))]
11765 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11766 "@
11767 rol{l}\t{%2, %k0|%k0, %2}
11768 rol{l}\t{%b2, %k0|%k0, %b2}"
11769 [(set_attr "type" "rotate")
11770 (set_attr "mode" "SI")])
11771
11772 (define_expand "rotlhi3"
11773 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11774 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11775 (match_operand:QI 2 "nonmemory_operand" "")))
11776 (clobber (reg:CC FLAGS_REG))]
11777 "TARGET_HIMODE_MATH"
11778 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11779
11780 (define_insn "*rotlhi3_1_one_bit"
11781 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11782 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11783 (match_operand:QI 2 "const1_operand" "")))
11784 (clobber (reg:CC FLAGS_REG))]
11785 "ix86_binary_operator_ok (ROTATE, HImode, operands)
11786 && (TARGET_SHIFT1 || optimize_size)"
11787 "rol{w}\t%0"
11788 [(set_attr "type" "rotate")
11789 (set (attr "length")
11790 (if_then_else (match_operand 0 "register_operand" "")
11791 (const_string "2")
11792 (const_string "*")))])
11793
11794 (define_insn "*rotlhi3_1"
11795 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11796 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11797 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11798 (clobber (reg:CC FLAGS_REG))]
11799 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11800 "@
11801 rol{w}\t{%2, %0|%0, %2}
11802 rol{w}\t{%b2, %0|%0, %b2}"
11803 [(set_attr "type" "rotate")
11804 (set_attr "mode" "HI")])
11805
11806 (define_expand "rotlqi3"
11807 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11808 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11809 (match_operand:QI 2 "nonmemory_operand" "")))
11810 (clobber (reg:CC FLAGS_REG))]
11811 "TARGET_QIMODE_MATH"
11812 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11813
11814 (define_insn "*rotlqi3_1_one_bit_slp"
11815 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11816 (rotate:QI (match_dup 0)
11817 (match_operand:QI 1 "const1_operand" "")))
11818 (clobber (reg:CC FLAGS_REG))]
11819 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11820 && (TARGET_SHIFT1 || optimize_size)"
11821 "rol{b}\t%0"
11822 [(set_attr "type" "rotate1")
11823 (set (attr "length")
11824 (if_then_else (match_operand 0 "register_operand" "")
11825 (const_string "2")
11826 (const_string "*")))])
11827
11828 (define_insn "*rotlqi3_1_one_bit"
11829 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11830 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11831 (match_operand:QI 2 "const1_operand" "")))
11832 (clobber (reg:CC FLAGS_REG))]
11833 "ix86_binary_operator_ok (ROTATE, QImode, operands)
11834 && (TARGET_SHIFT1 || optimize_size)"
11835 "rol{b}\t%0"
11836 [(set_attr "type" "rotate")
11837 (set (attr "length")
11838 (if_then_else (match_operand 0 "register_operand" "")
11839 (const_string "2")
11840 (const_string "*")))])
11841
11842 (define_insn "*rotlqi3_1_slp"
11843 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11844 (rotate:QI (match_dup 0)
11845 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11846 (clobber (reg:CC FLAGS_REG))]
11847 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11848 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11849 "@
11850 rol{b}\t{%1, %0|%0, %1}
11851 rol{b}\t{%b1, %0|%0, %b1}"
11852 [(set_attr "type" "rotate1")
11853 (set_attr "mode" "QI")])
11854
11855 (define_insn "*rotlqi3_1"
11856 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11857 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11858 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11859 (clobber (reg:CC FLAGS_REG))]
11860 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11861 "@
11862 rol{b}\t{%2, %0|%0, %2}
11863 rol{b}\t{%b2, %0|%0, %b2}"
11864 [(set_attr "type" "rotate")
11865 (set_attr "mode" "QI")])
11866
11867 (define_expand "rotrdi3"
11868 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11869 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11870 (match_operand:QI 2 "nonmemory_operand" "")))
11871 (clobber (reg:CC FLAGS_REG))]
11872 "TARGET_64BIT"
11873 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11874
11875 (define_insn "*rotrdi3_1_one_bit_rex64"
11876 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11877 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11878 (match_operand:QI 2 "const1_operand" "")))
11879 (clobber (reg:CC FLAGS_REG))]
11880 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11881 && (TARGET_SHIFT1 || optimize_size)"
11882 "ror{q}\t%0"
11883 [(set_attr "type" "rotate")
11884 (set (attr "length")
11885 (if_then_else (match_operand:DI 0 "register_operand" "")
11886 (const_string "2")
11887 (const_string "*")))])
11888
11889 (define_insn "*rotrdi3_1_rex64"
11890 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11891 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11892 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11893 (clobber (reg:CC FLAGS_REG))]
11894 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11895 "@
11896 ror{q}\t{%2, %0|%0, %2}
11897 ror{q}\t{%b2, %0|%0, %b2}"
11898 [(set_attr "type" "rotate")
11899 (set_attr "mode" "DI")])
11900
11901 (define_expand "rotrsi3"
11902 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11903 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11904 (match_operand:QI 2 "nonmemory_operand" "")))
11905 (clobber (reg:CC FLAGS_REG))]
11906 ""
11907 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11908
11909 (define_insn "*rotrsi3_1_one_bit"
11910 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11911 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11912 (match_operand:QI 2 "const1_operand" "")))
11913 (clobber (reg:CC FLAGS_REG))]
11914 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11915 && (TARGET_SHIFT1 || optimize_size)"
11916 "ror{l}\t%0"
11917 [(set_attr "type" "rotate")
11918 (set (attr "length")
11919 (if_then_else (match_operand:SI 0 "register_operand" "")
11920 (const_string "2")
11921 (const_string "*")))])
11922
11923 (define_insn "*rotrsi3_1_one_bit_zext"
11924 [(set (match_operand:DI 0 "register_operand" "=r")
11925 (zero_extend:DI
11926 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11927 (match_operand:QI 2 "const1_operand" ""))))
11928 (clobber (reg:CC FLAGS_REG))]
11929 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11930 && (TARGET_SHIFT1 || optimize_size)"
11931 "ror{l}\t%k0"
11932 [(set_attr "type" "rotate")
11933 (set (attr "length")
11934 (if_then_else (match_operand:SI 0 "register_operand" "")
11935 (const_string "2")
11936 (const_string "*")))])
11937
11938 (define_insn "*rotrsi3_1"
11939 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11940 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11941 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11942 (clobber (reg:CC FLAGS_REG))]
11943 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11944 "@
11945 ror{l}\t{%2, %0|%0, %2}
11946 ror{l}\t{%b2, %0|%0, %b2}"
11947 [(set_attr "type" "rotate")
11948 (set_attr "mode" "SI")])
11949
11950 (define_insn "*rotrsi3_1_zext"
11951 [(set (match_operand:DI 0 "register_operand" "=r,r")
11952 (zero_extend:DI
11953 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11954 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11955 (clobber (reg:CC FLAGS_REG))]
11956 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11957 "@
11958 ror{l}\t{%2, %k0|%k0, %2}
11959 ror{l}\t{%b2, %k0|%k0, %b2}"
11960 [(set_attr "type" "rotate")
11961 (set_attr "mode" "SI")])
11962
11963 (define_expand "rotrhi3"
11964 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11965 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11966 (match_operand:QI 2 "nonmemory_operand" "")))
11967 (clobber (reg:CC FLAGS_REG))]
11968 "TARGET_HIMODE_MATH"
11969 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11970
11971 (define_insn "*rotrhi3_one_bit"
11972 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11973 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11974 (match_operand:QI 2 "const1_operand" "")))
11975 (clobber (reg:CC FLAGS_REG))]
11976 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11977 && (TARGET_SHIFT1 || optimize_size)"
11978 "ror{w}\t%0"
11979 [(set_attr "type" "rotate")
11980 (set (attr "length")
11981 (if_then_else (match_operand 0 "register_operand" "")
11982 (const_string "2")
11983 (const_string "*")))])
11984
11985 (define_insn "*rotrhi3"
11986 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11987 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11988 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11989 (clobber (reg:CC FLAGS_REG))]
11990 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11991 "@
11992 ror{w}\t{%2, %0|%0, %2}
11993 ror{w}\t{%b2, %0|%0, %b2}"
11994 [(set_attr "type" "rotate")
11995 (set_attr "mode" "HI")])
11996
11997 (define_expand "rotrqi3"
11998 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11999 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12000 (match_operand:QI 2 "nonmemory_operand" "")))
12001 (clobber (reg:CC FLAGS_REG))]
12002 "TARGET_QIMODE_MATH"
12003 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12004
12005 (define_insn "*rotrqi3_1_one_bit"
12006 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12007 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12008 (match_operand:QI 2 "const1_operand" "")))
12009 (clobber (reg:CC FLAGS_REG))]
12010 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12011 && (TARGET_SHIFT1 || optimize_size)"
12012 "ror{b}\t%0"
12013 [(set_attr "type" "rotate")
12014 (set (attr "length")
12015 (if_then_else (match_operand 0 "register_operand" "")
12016 (const_string "2")
12017 (const_string "*")))])
12018
12019 (define_insn "*rotrqi3_1_one_bit_slp"
12020 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12021 (rotatert:QI (match_dup 0)
12022 (match_operand:QI 1 "const1_operand" "")))
12023 (clobber (reg:CC FLAGS_REG))]
12024 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12025 && (TARGET_SHIFT1 || optimize_size)"
12026 "ror{b}\t%0"
12027 [(set_attr "type" "rotate1")
12028 (set (attr "length")
12029 (if_then_else (match_operand 0 "register_operand" "")
12030 (const_string "2")
12031 (const_string "*")))])
12032
12033 (define_insn "*rotrqi3_1"
12034 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12035 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12036 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12037 (clobber (reg:CC FLAGS_REG))]
12038 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12039 "@
12040 ror{b}\t{%2, %0|%0, %2}
12041 ror{b}\t{%b2, %0|%0, %b2}"
12042 [(set_attr "type" "rotate")
12043 (set_attr "mode" "QI")])
12044
12045 (define_insn "*rotrqi3_1_slp"
12046 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12047 (rotatert:QI (match_dup 0)
12048 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12049 (clobber (reg:CC FLAGS_REG))]
12050 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12051 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12052 "@
12053 ror{b}\t{%1, %0|%0, %1}
12054 ror{b}\t{%b1, %0|%0, %b1}"
12055 [(set_attr "type" "rotate1")
12056 (set_attr "mode" "QI")])
12057 \f
12058 ;; Bit set / bit test instructions
12059
12060 (define_expand "extv"
12061 [(set (match_operand:SI 0 "register_operand" "")
12062 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12063 (match_operand:SI 2 "immediate_operand" "")
12064 (match_operand:SI 3 "immediate_operand" "")))]
12065 ""
12066 {
12067 /* Handle extractions from %ah et al. */
12068 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12069 FAIL;
12070
12071 /* From mips.md: extract_bit_field doesn't verify that our source
12072 matches the predicate, so check it again here. */
12073 if (! ext_register_operand (operands[1], VOIDmode))
12074 FAIL;
12075 })
12076
12077 (define_expand "extzv"
12078 [(set (match_operand:SI 0 "register_operand" "")
12079 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12080 (match_operand:SI 2 "immediate_operand" "")
12081 (match_operand:SI 3 "immediate_operand" "")))]
12082 ""
12083 {
12084 /* Handle extractions from %ah et al. */
12085 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12086 FAIL;
12087
12088 /* From mips.md: extract_bit_field doesn't verify that our source
12089 matches the predicate, so check it again here. */
12090 if (! ext_register_operand (operands[1], VOIDmode))
12091 FAIL;
12092 })
12093
12094 (define_expand "insv"
12095 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12096 (match_operand 1 "immediate_operand" "")
12097 (match_operand 2 "immediate_operand" ""))
12098 (match_operand 3 "register_operand" ""))]
12099 ""
12100 {
12101 /* Handle extractions from %ah et al. */
12102 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12103 FAIL;
12104
12105 /* From mips.md: insert_bit_field doesn't verify that our source
12106 matches the predicate, so check it again here. */
12107 if (! ext_register_operand (operands[0], VOIDmode))
12108 FAIL;
12109
12110 if (TARGET_64BIT)
12111 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12112 else
12113 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12114
12115 DONE;
12116 })
12117
12118 ;; %%% bts, btr, btc, bt.
12119 ;; In general these instructions are *slow* when applied to memory,
12120 ;; since they enforce atomic operation. When applied to registers,
12121 ;; it depends on the cpu implementation. They're never faster than
12122 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12123 ;; no point. But in 64-bit, we can't hold the relevant immediates
12124 ;; within the instruction itself, so operating on bits in the high
12125 ;; 32-bits of a register becomes easier.
12126 ;;
12127 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12128 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12129 ;; negdf respectively, so they can never be disabled entirely.
12130
12131 (define_insn "*btsq"
12132 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12133 (const_int 1)
12134 (match_operand:DI 1 "const_0_to_63_operand" ""))
12135 (const_int 1))
12136 (clobber (reg:CC FLAGS_REG))]
12137 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12138 "bts{q} %1,%0"
12139 [(set_attr "type" "alu1")])
12140
12141 (define_insn "*btrq"
12142 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12143 (const_int 1)
12144 (match_operand:DI 1 "const_0_to_63_operand" ""))
12145 (const_int 0))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12148 "btr{q} %1,%0"
12149 [(set_attr "type" "alu1")])
12150
12151 (define_insn "*btcq"
12152 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12153 (const_int 1)
12154 (match_operand:DI 1 "const_0_to_63_operand" ""))
12155 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12156 (clobber (reg:CC FLAGS_REG))]
12157 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12158 "btc{q} %1,%0"
12159 [(set_attr "type" "alu1")])
12160
12161 ;; Allow Nocona to avoid these instructions if a register is available.
12162
12163 (define_peephole2
12164 [(match_scratch:DI 2 "r")
12165 (parallel [(set (zero_extract:DI
12166 (match_operand:DI 0 "register_operand" "")
12167 (const_int 1)
12168 (match_operand:DI 1 "const_0_to_63_operand" ""))
12169 (const_int 1))
12170 (clobber (reg:CC FLAGS_REG))])]
12171 "TARGET_64BIT && !TARGET_USE_BT"
12172 [(const_int 0)]
12173 {
12174 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12175 rtx op1;
12176
12177 if (HOST_BITS_PER_WIDE_INT >= 64)
12178 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12179 else if (i < HOST_BITS_PER_WIDE_INT)
12180 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12181 else
12182 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12183
12184 op1 = immed_double_const (lo, hi, DImode);
12185 if (i >= 31)
12186 {
12187 emit_move_insn (operands[2], op1);
12188 op1 = operands[2];
12189 }
12190
12191 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12192 DONE;
12193 })
12194
12195 (define_peephole2
12196 [(match_scratch:DI 2 "r")
12197 (parallel [(set (zero_extract:DI
12198 (match_operand:DI 0 "register_operand" "")
12199 (const_int 1)
12200 (match_operand:DI 1 "const_0_to_63_operand" ""))
12201 (const_int 0))
12202 (clobber (reg:CC FLAGS_REG))])]
12203 "TARGET_64BIT && !TARGET_USE_BT"
12204 [(const_int 0)]
12205 {
12206 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12207 rtx op1;
12208
12209 if (HOST_BITS_PER_WIDE_INT >= 64)
12210 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12211 else if (i < HOST_BITS_PER_WIDE_INT)
12212 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12213 else
12214 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12215
12216 op1 = immed_double_const (~lo, ~hi, DImode);
12217 if (i >= 32)
12218 {
12219 emit_move_insn (operands[2], op1);
12220 op1 = operands[2];
12221 }
12222
12223 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12224 DONE;
12225 })
12226
12227 (define_peephole2
12228 [(match_scratch:DI 2 "r")
12229 (parallel [(set (zero_extract:DI
12230 (match_operand:DI 0 "register_operand" "")
12231 (const_int 1)
12232 (match_operand:DI 1 "const_0_to_63_operand" ""))
12233 (not:DI (zero_extract:DI
12234 (match_dup 0) (const_int 1) (match_dup 1))))
12235 (clobber (reg:CC FLAGS_REG))])]
12236 "TARGET_64BIT && !TARGET_USE_BT"
12237 [(const_int 0)]
12238 {
12239 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12240 rtx op1;
12241
12242 if (HOST_BITS_PER_WIDE_INT >= 64)
12243 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12244 else if (i < HOST_BITS_PER_WIDE_INT)
12245 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12246 else
12247 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12248
12249 op1 = immed_double_const (lo, hi, DImode);
12250 if (i >= 31)
12251 {
12252 emit_move_insn (operands[2], op1);
12253 op1 = operands[2];
12254 }
12255
12256 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12257 DONE;
12258 })
12259 \f
12260 ;; Store-flag instructions.
12261
12262 ;; For all sCOND expanders, also expand the compare or test insn that
12263 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12264
12265 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12266 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12267 ;; way, which can later delete the movzx if only QImode is needed.
12268
12269 (define_expand "seq"
12270 [(set (match_operand:QI 0 "register_operand" "")
12271 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12272 ""
12273 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12274
12275 (define_expand "sne"
12276 [(set (match_operand:QI 0 "register_operand" "")
12277 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12278 ""
12279 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12280
12281 (define_expand "sgt"
12282 [(set (match_operand:QI 0 "register_operand" "")
12283 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12284 ""
12285 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12286
12287 (define_expand "sgtu"
12288 [(set (match_operand:QI 0 "register_operand" "")
12289 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12290 ""
12291 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12292
12293 (define_expand "slt"
12294 [(set (match_operand:QI 0 "register_operand" "")
12295 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12296 ""
12297 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12298
12299 (define_expand "sltu"
12300 [(set (match_operand:QI 0 "register_operand" "")
12301 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12302 ""
12303 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12304
12305 (define_expand "sge"
12306 [(set (match_operand:QI 0 "register_operand" "")
12307 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12308 ""
12309 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12310
12311 (define_expand "sgeu"
12312 [(set (match_operand:QI 0 "register_operand" "")
12313 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12314 ""
12315 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12316
12317 (define_expand "sle"
12318 [(set (match_operand:QI 0 "register_operand" "")
12319 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12320 ""
12321 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12322
12323 (define_expand "sleu"
12324 [(set (match_operand:QI 0 "register_operand" "")
12325 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12326 ""
12327 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12328
12329 (define_expand "sunordered"
12330 [(set (match_operand:QI 0 "register_operand" "")
12331 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12332 "TARGET_80387 || TARGET_SSE"
12333 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12334
12335 (define_expand "sordered"
12336 [(set (match_operand:QI 0 "register_operand" "")
12337 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12338 "TARGET_80387"
12339 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12340
12341 (define_expand "suneq"
12342 [(set (match_operand:QI 0 "register_operand" "")
12343 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12344 "TARGET_80387 || TARGET_SSE"
12345 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12346
12347 (define_expand "sunge"
12348 [(set (match_operand:QI 0 "register_operand" "")
12349 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12350 "TARGET_80387 || TARGET_SSE"
12351 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12352
12353 (define_expand "sungt"
12354 [(set (match_operand:QI 0 "register_operand" "")
12355 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12356 "TARGET_80387 || TARGET_SSE"
12357 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12358
12359 (define_expand "sunle"
12360 [(set (match_operand:QI 0 "register_operand" "")
12361 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12362 "TARGET_80387 || TARGET_SSE"
12363 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12364
12365 (define_expand "sunlt"
12366 [(set (match_operand:QI 0 "register_operand" "")
12367 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12368 "TARGET_80387 || TARGET_SSE"
12369 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12370
12371 (define_expand "sltgt"
12372 [(set (match_operand:QI 0 "register_operand" "")
12373 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12374 "TARGET_80387 || TARGET_SSE"
12375 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12376
12377 (define_insn "*setcc_1"
12378 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12379 (match_operator:QI 1 "ix86_comparison_operator"
12380 [(reg FLAGS_REG) (const_int 0)]))]
12381 ""
12382 "set%C1\t%0"
12383 [(set_attr "type" "setcc")
12384 (set_attr "mode" "QI")])
12385
12386 (define_insn "*setcc_2"
12387 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12388 (match_operator:QI 1 "ix86_comparison_operator"
12389 [(reg FLAGS_REG) (const_int 0)]))]
12390 ""
12391 "set%C1\t%0"
12392 [(set_attr "type" "setcc")
12393 (set_attr "mode" "QI")])
12394
12395 ;; In general it is not safe to assume too much about CCmode registers,
12396 ;; so simplify-rtx stops when it sees a second one. Under certain
12397 ;; conditions this is safe on x86, so help combine not create
12398 ;;
12399 ;; seta %al
12400 ;; testb %al, %al
12401 ;; sete %al
12402
12403 (define_split
12404 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12405 (ne:QI (match_operator 1 "ix86_comparison_operator"
12406 [(reg FLAGS_REG) (const_int 0)])
12407 (const_int 0)))]
12408 ""
12409 [(set (match_dup 0) (match_dup 1))]
12410 {
12411 PUT_MODE (operands[1], QImode);
12412 })
12413
12414 (define_split
12415 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12416 (ne:QI (match_operator 1 "ix86_comparison_operator"
12417 [(reg FLAGS_REG) (const_int 0)])
12418 (const_int 0)))]
12419 ""
12420 [(set (match_dup 0) (match_dup 1))]
12421 {
12422 PUT_MODE (operands[1], QImode);
12423 })
12424
12425 (define_split
12426 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12427 (eq:QI (match_operator 1 "ix86_comparison_operator"
12428 [(reg FLAGS_REG) (const_int 0)])
12429 (const_int 0)))]
12430 ""
12431 [(set (match_dup 0) (match_dup 1))]
12432 {
12433 rtx new_op1 = copy_rtx (operands[1]);
12434 operands[1] = new_op1;
12435 PUT_MODE (new_op1, QImode);
12436 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12437 GET_MODE (XEXP (new_op1, 0))));
12438
12439 /* Make sure that (a) the CCmode we have for the flags is strong
12440 enough for the reversed compare or (b) we have a valid FP compare. */
12441 if (! ix86_comparison_operator (new_op1, VOIDmode))
12442 FAIL;
12443 })
12444
12445 (define_split
12446 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12447 (eq:QI (match_operator 1 "ix86_comparison_operator"
12448 [(reg FLAGS_REG) (const_int 0)])
12449 (const_int 0)))]
12450 ""
12451 [(set (match_dup 0) (match_dup 1))]
12452 {
12453 rtx new_op1 = copy_rtx (operands[1]);
12454 operands[1] = new_op1;
12455 PUT_MODE (new_op1, QImode);
12456 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12457 GET_MODE (XEXP (new_op1, 0))));
12458
12459 /* Make sure that (a) the CCmode we have for the flags is strong
12460 enough for the reversed compare or (b) we have a valid FP compare. */
12461 if (! ix86_comparison_operator (new_op1, VOIDmode))
12462 FAIL;
12463 })
12464
12465 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12466 ;; subsequent logical operations are used to imitate conditional moves.
12467 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12468 ;; it directly.
12469
12470 (define_insn "*sse_setccsf"
12471 [(set (match_operand:SF 0 "register_operand" "=x")
12472 (match_operator:SF 1 "sse_comparison_operator"
12473 [(match_operand:SF 2 "register_operand" "0")
12474 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12475 "TARGET_SSE"
12476 "cmp%D1ss\t{%3, %0|%0, %3}"
12477 [(set_attr "type" "ssecmp")
12478 (set_attr "mode" "SF")])
12479
12480 (define_insn "*sse_setccdf"
12481 [(set (match_operand:DF 0 "register_operand" "=Y")
12482 (match_operator:DF 1 "sse_comparison_operator"
12483 [(match_operand:DF 2 "register_operand" "0")
12484 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12485 "TARGET_SSE2"
12486 "cmp%D1sd\t{%3, %0|%0, %3}"
12487 [(set_attr "type" "ssecmp")
12488 (set_attr "mode" "DF")])
12489 \f
12490 ;; Basic conditional jump instructions.
12491 ;; We ignore the overflow flag for signed branch instructions.
12492
12493 ;; For all bCOND expanders, also expand the compare or test insn that
12494 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12495
12496 (define_expand "beq"
12497 [(set (pc)
12498 (if_then_else (match_dup 1)
12499 (label_ref (match_operand 0 "" ""))
12500 (pc)))]
12501 ""
12502 "ix86_expand_branch (EQ, operands[0]); DONE;")
12503
12504 (define_expand "bne"
12505 [(set (pc)
12506 (if_then_else (match_dup 1)
12507 (label_ref (match_operand 0 "" ""))
12508 (pc)))]
12509 ""
12510 "ix86_expand_branch (NE, operands[0]); DONE;")
12511
12512 (define_expand "bgt"
12513 [(set (pc)
12514 (if_then_else (match_dup 1)
12515 (label_ref (match_operand 0 "" ""))
12516 (pc)))]
12517 ""
12518 "ix86_expand_branch (GT, operands[0]); DONE;")
12519
12520 (define_expand "bgtu"
12521 [(set (pc)
12522 (if_then_else (match_dup 1)
12523 (label_ref (match_operand 0 "" ""))
12524 (pc)))]
12525 ""
12526 "ix86_expand_branch (GTU, operands[0]); DONE;")
12527
12528 (define_expand "blt"
12529 [(set (pc)
12530 (if_then_else (match_dup 1)
12531 (label_ref (match_operand 0 "" ""))
12532 (pc)))]
12533 ""
12534 "ix86_expand_branch (LT, operands[0]); DONE;")
12535
12536 (define_expand "bltu"
12537 [(set (pc)
12538 (if_then_else (match_dup 1)
12539 (label_ref (match_operand 0 "" ""))
12540 (pc)))]
12541 ""
12542 "ix86_expand_branch (LTU, operands[0]); DONE;")
12543
12544 (define_expand "bge"
12545 [(set (pc)
12546 (if_then_else (match_dup 1)
12547 (label_ref (match_operand 0 "" ""))
12548 (pc)))]
12549 ""
12550 "ix86_expand_branch (GE, operands[0]); DONE;")
12551
12552 (define_expand "bgeu"
12553 [(set (pc)
12554 (if_then_else (match_dup 1)
12555 (label_ref (match_operand 0 "" ""))
12556 (pc)))]
12557 ""
12558 "ix86_expand_branch (GEU, operands[0]); DONE;")
12559
12560 (define_expand "ble"
12561 [(set (pc)
12562 (if_then_else (match_dup 1)
12563 (label_ref (match_operand 0 "" ""))
12564 (pc)))]
12565 ""
12566 "ix86_expand_branch (LE, operands[0]); DONE;")
12567
12568 (define_expand "bleu"
12569 [(set (pc)
12570 (if_then_else (match_dup 1)
12571 (label_ref (match_operand 0 "" ""))
12572 (pc)))]
12573 ""
12574 "ix86_expand_branch (LEU, operands[0]); DONE;")
12575
12576 (define_expand "bunordered"
12577 [(set (pc)
12578 (if_then_else (match_dup 1)
12579 (label_ref (match_operand 0 "" ""))
12580 (pc)))]
12581 "TARGET_80387 || TARGET_SSE_MATH"
12582 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12583
12584 (define_expand "bordered"
12585 [(set (pc)
12586 (if_then_else (match_dup 1)
12587 (label_ref (match_operand 0 "" ""))
12588 (pc)))]
12589 "TARGET_80387 || TARGET_SSE_MATH"
12590 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12591
12592 (define_expand "buneq"
12593 [(set (pc)
12594 (if_then_else (match_dup 1)
12595 (label_ref (match_operand 0 "" ""))
12596 (pc)))]
12597 "TARGET_80387 || TARGET_SSE_MATH"
12598 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12599
12600 (define_expand "bunge"
12601 [(set (pc)
12602 (if_then_else (match_dup 1)
12603 (label_ref (match_operand 0 "" ""))
12604 (pc)))]
12605 "TARGET_80387 || TARGET_SSE_MATH"
12606 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12607
12608 (define_expand "bungt"
12609 [(set (pc)
12610 (if_then_else (match_dup 1)
12611 (label_ref (match_operand 0 "" ""))
12612 (pc)))]
12613 "TARGET_80387 || TARGET_SSE_MATH"
12614 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12615
12616 (define_expand "bunle"
12617 [(set (pc)
12618 (if_then_else (match_dup 1)
12619 (label_ref (match_operand 0 "" ""))
12620 (pc)))]
12621 "TARGET_80387 || TARGET_SSE_MATH"
12622 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12623
12624 (define_expand "bunlt"
12625 [(set (pc)
12626 (if_then_else (match_dup 1)
12627 (label_ref (match_operand 0 "" ""))
12628 (pc)))]
12629 "TARGET_80387 || TARGET_SSE_MATH"
12630 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12631
12632 (define_expand "bltgt"
12633 [(set (pc)
12634 (if_then_else (match_dup 1)
12635 (label_ref (match_operand 0 "" ""))
12636 (pc)))]
12637 "TARGET_80387 || TARGET_SSE_MATH"
12638 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12639
12640 (define_insn "*jcc_1"
12641 [(set (pc)
12642 (if_then_else (match_operator 1 "ix86_comparison_operator"
12643 [(reg FLAGS_REG) (const_int 0)])
12644 (label_ref (match_operand 0 "" ""))
12645 (pc)))]
12646 ""
12647 "%+j%C1\t%l0"
12648 [(set_attr "type" "ibr")
12649 (set_attr "modrm" "0")
12650 (set (attr "length")
12651 (if_then_else (and (ge (minus (match_dup 0) (pc))
12652 (const_int -126))
12653 (lt (minus (match_dup 0) (pc))
12654 (const_int 128)))
12655 (const_int 2)
12656 (const_int 6)))])
12657
12658 (define_insn "*jcc_2"
12659 [(set (pc)
12660 (if_then_else (match_operator 1 "ix86_comparison_operator"
12661 [(reg FLAGS_REG) (const_int 0)])
12662 (pc)
12663 (label_ref (match_operand 0 "" ""))))]
12664 ""
12665 "%+j%c1\t%l0"
12666 [(set_attr "type" "ibr")
12667 (set_attr "modrm" "0")
12668 (set (attr "length")
12669 (if_then_else (and (ge (minus (match_dup 0) (pc))
12670 (const_int -126))
12671 (lt (minus (match_dup 0) (pc))
12672 (const_int 128)))
12673 (const_int 2)
12674 (const_int 6)))])
12675
12676 ;; In general it is not safe to assume too much about CCmode registers,
12677 ;; so simplify-rtx stops when it sees a second one. Under certain
12678 ;; conditions this is safe on x86, so help combine not create
12679 ;;
12680 ;; seta %al
12681 ;; testb %al, %al
12682 ;; je Lfoo
12683
12684 (define_split
12685 [(set (pc)
12686 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12687 [(reg FLAGS_REG) (const_int 0)])
12688 (const_int 0))
12689 (label_ref (match_operand 1 "" ""))
12690 (pc)))]
12691 ""
12692 [(set (pc)
12693 (if_then_else (match_dup 0)
12694 (label_ref (match_dup 1))
12695 (pc)))]
12696 {
12697 PUT_MODE (operands[0], VOIDmode);
12698 })
12699
12700 (define_split
12701 [(set (pc)
12702 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12703 [(reg FLAGS_REG) (const_int 0)])
12704 (const_int 0))
12705 (label_ref (match_operand 1 "" ""))
12706 (pc)))]
12707 ""
12708 [(set (pc)
12709 (if_then_else (match_dup 0)
12710 (label_ref (match_dup 1))
12711 (pc)))]
12712 {
12713 rtx new_op0 = copy_rtx (operands[0]);
12714 operands[0] = new_op0;
12715 PUT_MODE (new_op0, VOIDmode);
12716 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12717 GET_MODE (XEXP (new_op0, 0))));
12718
12719 /* Make sure that (a) the CCmode we have for the flags is strong
12720 enough for the reversed compare or (b) we have a valid FP compare. */
12721 if (! ix86_comparison_operator (new_op0, VOIDmode))
12722 FAIL;
12723 })
12724
12725 ;; Define combination compare-and-branch fp compare instructions to use
12726 ;; during early optimization. Splitting the operation apart early makes
12727 ;; for bad code when we want to reverse the operation.
12728
12729 (define_insn "*fp_jcc_1_mixed"
12730 [(set (pc)
12731 (if_then_else (match_operator 0 "comparison_operator"
12732 [(match_operand 1 "register_operand" "f#x,x#f")
12733 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12734 (label_ref (match_operand 3 "" ""))
12735 (pc)))
12736 (clobber (reg:CCFP FPSR_REG))
12737 (clobber (reg:CCFP FLAGS_REG))]
12738 "TARGET_MIX_SSE_I387
12739 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12740 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12741 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12742 "#")
12743
12744 (define_insn "*fp_jcc_1_sse"
12745 [(set (pc)
12746 (if_then_else (match_operator 0 "comparison_operator"
12747 [(match_operand 1 "register_operand" "x")
12748 (match_operand 2 "nonimmediate_operand" "xm")])
12749 (label_ref (match_operand 3 "" ""))
12750 (pc)))
12751 (clobber (reg:CCFP FPSR_REG))
12752 (clobber (reg:CCFP FLAGS_REG))]
12753 "TARGET_SSE_MATH
12754 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12755 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12756 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12757 "#")
12758
12759 (define_insn "*fp_jcc_1_387"
12760 [(set (pc)
12761 (if_then_else (match_operator 0 "comparison_operator"
12762 [(match_operand 1 "register_operand" "f")
12763 (match_operand 2 "register_operand" "f")])
12764 (label_ref (match_operand 3 "" ""))
12765 (pc)))
12766 (clobber (reg:CCFP FPSR_REG))
12767 (clobber (reg:CCFP FLAGS_REG))]
12768 "TARGET_CMOVE && TARGET_80387
12769 && FLOAT_MODE_P (GET_MODE (operands[1]))
12770 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12771 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12772 "#")
12773
12774 (define_insn "*fp_jcc_2_mixed"
12775 [(set (pc)
12776 (if_then_else (match_operator 0 "comparison_operator"
12777 [(match_operand 1 "register_operand" "f#x,x#f")
12778 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12779 (pc)
12780 (label_ref (match_operand 3 "" ""))))
12781 (clobber (reg:CCFP FPSR_REG))
12782 (clobber (reg:CCFP FLAGS_REG))]
12783 "TARGET_MIX_SSE_I387
12784 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12785 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12786 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12787 "#")
12788
12789 (define_insn "*fp_jcc_2_sse"
12790 [(set (pc)
12791 (if_then_else (match_operator 0 "comparison_operator"
12792 [(match_operand 1 "register_operand" "x")
12793 (match_operand 2 "nonimmediate_operand" "xm")])
12794 (pc)
12795 (label_ref (match_operand 3 "" ""))))
12796 (clobber (reg:CCFP FPSR_REG))
12797 (clobber (reg:CCFP FLAGS_REG))]
12798 "TARGET_SSE_MATH
12799 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12800 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12801 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12802 "#")
12803
12804 (define_insn "*fp_jcc_2_387"
12805 [(set (pc)
12806 (if_then_else (match_operator 0 "comparison_operator"
12807 [(match_operand 1 "register_operand" "f")
12808 (match_operand 2 "register_operand" "f")])
12809 (pc)
12810 (label_ref (match_operand 3 "" ""))))
12811 (clobber (reg:CCFP FPSR_REG))
12812 (clobber (reg:CCFP FLAGS_REG))]
12813 "TARGET_CMOVE && TARGET_80387
12814 && FLOAT_MODE_P (GET_MODE (operands[1]))
12815 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12816 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12817 "#")
12818
12819 (define_insn "*fp_jcc_3_387"
12820 [(set (pc)
12821 (if_then_else (match_operator 0 "comparison_operator"
12822 [(match_operand 1 "register_operand" "f")
12823 (match_operand 2 "nonimmediate_operand" "fm")])
12824 (label_ref (match_operand 3 "" ""))
12825 (pc)))
12826 (clobber (reg:CCFP FPSR_REG))
12827 (clobber (reg:CCFP FLAGS_REG))
12828 (clobber (match_scratch:HI 4 "=a"))]
12829 "TARGET_80387
12830 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12831 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12832 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12833 && SELECT_CC_MODE (GET_CODE (operands[0]),
12834 operands[1], operands[2]) == CCFPmode
12835 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12836 "#")
12837
12838 (define_insn "*fp_jcc_4_387"
12839 [(set (pc)
12840 (if_then_else (match_operator 0 "comparison_operator"
12841 [(match_operand 1 "register_operand" "f")
12842 (match_operand 2 "nonimmediate_operand" "fm")])
12843 (pc)
12844 (label_ref (match_operand 3 "" ""))))
12845 (clobber (reg:CCFP FPSR_REG))
12846 (clobber (reg:CCFP FLAGS_REG))
12847 (clobber (match_scratch:HI 4 "=a"))]
12848 "TARGET_80387
12849 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12850 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12851 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12852 && SELECT_CC_MODE (GET_CODE (operands[0]),
12853 operands[1], operands[2]) == CCFPmode
12854 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12855 "#")
12856
12857 (define_insn "*fp_jcc_5_387"
12858 [(set (pc)
12859 (if_then_else (match_operator 0 "comparison_operator"
12860 [(match_operand 1 "register_operand" "f")
12861 (match_operand 2 "register_operand" "f")])
12862 (label_ref (match_operand 3 "" ""))
12863 (pc)))
12864 (clobber (reg:CCFP FPSR_REG))
12865 (clobber (reg:CCFP FLAGS_REG))
12866 (clobber (match_scratch:HI 4 "=a"))]
12867 "TARGET_80387
12868 && FLOAT_MODE_P (GET_MODE (operands[1]))
12869 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12870 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12871 "#")
12872
12873 (define_insn "*fp_jcc_6_387"
12874 [(set (pc)
12875 (if_then_else (match_operator 0 "comparison_operator"
12876 [(match_operand 1 "register_operand" "f")
12877 (match_operand 2 "register_operand" "f")])
12878 (pc)
12879 (label_ref (match_operand 3 "" ""))))
12880 (clobber (reg:CCFP FPSR_REG))
12881 (clobber (reg:CCFP FLAGS_REG))
12882 (clobber (match_scratch:HI 4 "=a"))]
12883 "TARGET_80387
12884 && FLOAT_MODE_P (GET_MODE (operands[1]))
12885 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12886 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12887 "#")
12888
12889 (define_insn "*fp_jcc_7_387"
12890 [(set (pc)
12891 (if_then_else (match_operator 0 "comparison_operator"
12892 [(match_operand 1 "register_operand" "f")
12893 (match_operand 2 "const0_operand" "X")])
12894 (label_ref (match_operand 3 "" ""))
12895 (pc)))
12896 (clobber (reg:CCFP FPSR_REG))
12897 (clobber (reg:CCFP FLAGS_REG))
12898 (clobber (match_scratch:HI 4 "=a"))]
12899 "TARGET_80387
12900 && FLOAT_MODE_P (GET_MODE (operands[1]))
12901 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12902 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12903 && SELECT_CC_MODE (GET_CODE (operands[0]),
12904 operands[1], operands[2]) == CCFPmode
12905 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12906 "#")
12907
12908 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
12909 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12910 ;; with a precedence over other operators and is always put in the first
12911 ;; place. Swap condition and operands to match ficom instruction.
12912
12913 (define_insn "*fp_jcc_8<mode>_387"
12914 [(set (pc)
12915 (if_then_else (match_operator 0 "comparison_operator"
12916 [(match_operator 1 "float_operator"
12917 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
12918 (match_operand 3 "register_operand" "f,f")])
12919 (label_ref (match_operand 4 "" ""))
12920 (pc)))
12921 (clobber (reg:CCFP FPSR_REG))
12922 (clobber (reg:CCFP FLAGS_REG))
12923 (clobber (match_scratch:HI 5 "=a,a"))]
12924 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
12925 && FLOAT_MODE_P (GET_MODE (operands[3]))
12926 && GET_MODE (operands[1]) == GET_MODE (operands[3])
12927 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12928 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12929 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12930 "#")
12931
12932 (define_split
12933 [(set (pc)
12934 (if_then_else (match_operator 0 "comparison_operator"
12935 [(match_operand 1 "register_operand" "")
12936 (match_operand 2 "nonimmediate_operand" "")])
12937 (match_operand 3 "" "")
12938 (match_operand 4 "" "")))
12939 (clobber (reg:CCFP FPSR_REG))
12940 (clobber (reg:CCFP FLAGS_REG))]
12941 "reload_completed"
12942 [(const_int 0)]
12943 {
12944 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12945 operands[3], operands[4], NULL_RTX, NULL_RTX);
12946 DONE;
12947 })
12948
12949 (define_split
12950 [(set (pc)
12951 (if_then_else (match_operator 0 "comparison_operator"
12952 [(match_operand 1 "register_operand" "")
12953 (match_operand 2 "general_operand" "")])
12954 (match_operand 3 "" "")
12955 (match_operand 4 "" "")))
12956 (clobber (reg:CCFP FPSR_REG))
12957 (clobber (reg:CCFP FLAGS_REG))
12958 (clobber (match_scratch:HI 5 "=a"))]
12959 "reload_completed"
12960 [(const_int 0)]
12961 {
12962 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12963 operands[3], operands[4], operands[5], NULL_RTX);
12964 DONE;
12965 })
12966
12967 (define_split
12968 [(set (pc)
12969 (if_then_else (match_operator 0 "comparison_operator"
12970 [(match_operator 1 "float_operator"
12971 [(match_operand:X87MODEI12 2 "memory_operand" "")])
12972 (match_operand 3 "register_operand" "")])
12973 (match_operand 4 "" "")
12974 (match_operand 5 "" "")))
12975 (clobber (reg:CCFP FPSR_REG))
12976 (clobber (reg:CCFP FLAGS_REG))
12977 (clobber (match_scratch:HI 6 "=a"))]
12978 "reload_completed"
12979 [(const_int 0)]
12980 {
12981 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12982 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12983 operands[3], operands[7],
12984 operands[4], operands[5], operands[6], NULL_RTX);
12985 DONE;
12986 })
12987
12988 ;; %%% Kill this when reload knows how to do it.
12989 (define_split
12990 [(set (pc)
12991 (if_then_else (match_operator 0 "comparison_operator"
12992 [(match_operator 1 "float_operator"
12993 [(match_operand:X87MODEI12 2 "register_operand" "")])
12994 (match_operand 3 "register_operand" "")])
12995 (match_operand 4 "" "")
12996 (match_operand 5 "" "")))
12997 (clobber (reg:CCFP FPSR_REG))
12998 (clobber (reg:CCFP FLAGS_REG))
12999 (clobber (match_scratch:HI 6 "=a"))]
13000 "reload_completed"
13001 [(const_int 0)]
13002 {
13003 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13004 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13005 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13006 operands[3], operands[7],
13007 operands[4], operands[5], operands[6], operands[2]);
13008 DONE;
13009 })
13010 \f
13011 ;; Unconditional and other jump instructions
13012
13013 (define_insn "jump"
13014 [(set (pc)
13015 (label_ref (match_operand 0 "" "")))]
13016 ""
13017 "jmp\t%l0"
13018 [(set_attr "type" "ibr")
13019 (set (attr "length")
13020 (if_then_else (and (ge (minus (match_dup 0) (pc))
13021 (const_int -126))
13022 (lt (minus (match_dup 0) (pc))
13023 (const_int 128)))
13024 (const_int 2)
13025 (const_int 5)))
13026 (set_attr "modrm" "0")])
13027
13028 (define_expand "indirect_jump"
13029 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13030 ""
13031 "")
13032
13033 (define_insn "*indirect_jump"
13034 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13035 "!TARGET_64BIT"
13036 "jmp\t%A0"
13037 [(set_attr "type" "ibr")
13038 (set_attr "length_immediate" "0")])
13039
13040 (define_insn "*indirect_jump_rtx64"
13041 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13042 "TARGET_64BIT"
13043 "jmp\t%A0"
13044 [(set_attr "type" "ibr")
13045 (set_attr "length_immediate" "0")])
13046
13047 (define_expand "tablejump"
13048 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13049 (use (label_ref (match_operand 1 "" "")))])]
13050 ""
13051 {
13052 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13053 relative. Convert the relative address to an absolute address. */
13054 if (flag_pic)
13055 {
13056 rtx op0, op1;
13057 enum rtx_code code;
13058
13059 if (TARGET_64BIT)
13060 {
13061 code = PLUS;
13062 op0 = operands[0];
13063 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13064 }
13065 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13066 {
13067 code = PLUS;
13068 op0 = operands[0];
13069 op1 = pic_offset_table_rtx;
13070 }
13071 else
13072 {
13073 code = MINUS;
13074 op0 = pic_offset_table_rtx;
13075 op1 = operands[0];
13076 }
13077
13078 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13079 OPTAB_DIRECT);
13080 }
13081 })
13082
13083 (define_insn "*tablejump_1"
13084 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13085 (use (label_ref (match_operand 1 "" "")))]
13086 "!TARGET_64BIT"
13087 "jmp\t%A0"
13088 [(set_attr "type" "ibr")
13089 (set_attr "length_immediate" "0")])
13090
13091 (define_insn "*tablejump_1_rtx64"
13092 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13093 (use (label_ref (match_operand 1 "" "")))]
13094 "TARGET_64BIT"
13095 "jmp\t%A0"
13096 [(set_attr "type" "ibr")
13097 (set_attr "length_immediate" "0")])
13098 \f
13099 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13100
13101 (define_peephole2
13102 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13103 (set (match_operand:QI 1 "register_operand" "")
13104 (match_operator:QI 2 "ix86_comparison_operator"
13105 [(reg FLAGS_REG) (const_int 0)]))
13106 (set (match_operand 3 "q_regs_operand" "")
13107 (zero_extend (match_dup 1)))]
13108 "(peep2_reg_dead_p (3, operands[1])
13109 || operands_match_p (operands[1], operands[3]))
13110 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13111 [(set (match_dup 4) (match_dup 0))
13112 (set (strict_low_part (match_dup 5))
13113 (match_dup 2))]
13114 {
13115 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13116 operands[5] = gen_lowpart (QImode, operands[3]);
13117 ix86_expand_clear (operands[3]);
13118 })
13119
13120 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13121
13122 (define_peephole2
13123 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13124 (set (match_operand:QI 1 "register_operand" "")
13125 (match_operator:QI 2 "ix86_comparison_operator"
13126 [(reg FLAGS_REG) (const_int 0)]))
13127 (parallel [(set (match_operand 3 "q_regs_operand" "")
13128 (zero_extend (match_dup 1)))
13129 (clobber (reg:CC FLAGS_REG))])]
13130 "(peep2_reg_dead_p (3, operands[1])
13131 || operands_match_p (operands[1], operands[3]))
13132 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13133 [(set (match_dup 4) (match_dup 0))
13134 (set (strict_low_part (match_dup 5))
13135 (match_dup 2))]
13136 {
13137 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13138 operands[5] = gen_lowpart (QImode, operands[3]);
13139 ix86_expand_clear (operands[3]);
13140 })
13141 \f
13142 ;; Call instructions.
13143
13144 ;; The predicates normally associated with named expanders are not properly
13145 ;; checked for calls. This is a bug in the generic code, but it isn't that
13146 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13147
13148 ;; Call subroutine returning no value.
13149
13150 (define_expand "call_pop"
13151 [(parallel [(call (match_operand:QI 0 "" "")
13152 (match_operand:SI 1 "" ""))
13153 (set (reg:SI SP_REG)
13154 (plus:SI (reg:SI SP_REG)
13155 (match_operand:SI 3 "" "")))])]
13156 "!TARGET_64BIT"
13157 {
13158 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13159 DONE;
13160 })
13161
13162 (define_insn "*call_pop_0"
13163 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13164 (match_operand:SI 1 "" ""))
13165 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13166 (match_operand:SI 2 "immediate_operand" "")))]
13167 "!TARGET_64BIT"
13168 {
13169 if (SIBLING_CALL_P (insn))
13170 return "jmp\t%P0";
13171 else
13172 return "call\t%P0";
13173 }
13174 [(set_attr "type" "call")])
13175
13176 (define_insn "*call_pop_1"
13177 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13178 (match_operand:SI 1 "" ""))
13179 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13180 (match_operand:SI 2 "immediate_operand" "i")))]
13181 "!TARGET_64BIT"
13182 {
13183 if (constant_call_address_operand (operands[0], Pmode))
13184 {
13185 if (SIBLING_CALL_P (insn))
13186 return "jmp\t%P0";
13187 else
13188 return "call\t%P0";
13189 }
13190 if (SIBLING_CALL_P (insn))
13191 return "jmp\t%A0";
13192 else
13193 return "call\t%A0";
13194 }
13195 [(set_attr "type" "call")])
13196
13197 (define_expand "call"
13198 [(call (match_operand:QI 0 "" "")
13199 (match_operand 1 "" ""))
13200 (use (match_operand 2 "" ""))]
13201 ""
13202 {
13203 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13204 DONE;
13205 })
13206
13207 (define_expand "sibcall"
13208 [(call (match_operand:QI 0 "" "")
13209 (match_operand 1 "" ""))
13210 (use (match_operand 2 "" ""))]
13211 ""
13212 {
13213 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13214 DONE;
13215 })
13216
13217 (define_insn "*call_0"
13218 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13219 (match_operand 1 "" ""))]
13220 ""
13221 {
13222 if (SIBLING_CALL_P (insn))
13223 return "jmp\t%P0";
13224 else
13225 return "call\t%P0";
13226 }
13227 [(set_attr "type" "call")])
13228
13229 (define_insn "*call_1"
13230 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13231 (match_operand 1 "" ""))]
13232 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13233 {
13234 if (constant_call_address_operand (operands[0], Pmode))
13235 return "call\t%P0";
13236 return "call\t%A0";
13237 }
13238 [(set_attr "type" "call")])
13239
13240 (define_insn "*sibcall_1"
13241 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13242 (match_operand 1 "" ""))]
13243 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13244 {
13245 if (constant_call_address_operand (operands[0], Pmode))
13246 return "jmp\t%P0";
13247 return "jmp\t%A0";
13248 }
13249 [(set_attr "type" "call")])
13250
13251 (define_insn "*call_1_rex64"
13252 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13253 (match_operand 1 "" ""))]
13254 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13255 {
13256 if (constant_call_address_operand (operands[0], Pmode))
13257 return "call\t%P0";
13258 return "call\t%A0";
13259 }
13260 [(set_attr "type" "call")])
13261
13262 (define_insn "*sibcall_1_rex64"
13263 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13264 (match_operand 1 "" ""))]
13265 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13266 "jmp\t%P0"
13267 [(set_attr "type" "call")])
13268
13269 (define_insn "*sibcall_1_rex64_v"
13270 [(call (mem:QI (reg:DI 40))
13271 (match_operand 0 "" ""))]
13272 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13273 "jmp\t*%%r11"
13274 [(set_attr "type" "call")])
13275
13276
13277 ;; Call subroutine, returning value in operand 0
13278
13279 (define_expand "call_value_pop"
13280 [(parallel [(set (match_operand 0 "" "")
13281 (call (match_operand:QI 1 "" "")
13282 (match_operand:SI 2 "" "")))
13283 (set (reg:SI SP_REG)
13284 (plus:SI (reg:SI SP_REG)
13285 (match_operand:SI 4 "" "")))])]
13286 "!TARGET_64BIT"
13287 {
13288 ix86_expand_call (operands[0], operands[1], operands[2],
13289 operands[3], operands[4], 0);
13290 DONE;
13291 })
13292
13293 (define_expand "call_value"
13294 [(set (match_operand 0 "" "")
13295 (call (match_operand:QI 1 "" "")
13296 (match_operand:SI 2 "" "")))
13297 (use (match_operand:SI 3 "" ""))]
13298 ;; Operand 2 not used on the i386.
13299 ""
13300 {
13301 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13302 DONE;
13303 })
13304
13305 (define_expand "sibcall_value"
13306 [(set (match_operand 0 "" "")
13307 (call (match_operand:QI 1 "" "")
13308 (match_operand:SI 2 "" "")))
13309 (use (match_operand:SI 3 "" ""))]
13310 ;; Operand 2 not used on the i386.
13311 ""
13312 {
13313 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13314 DONE;
13315 })
13316
13317 ;; Call subroutine returning any type.
13318
13319 (define_expand "untyped_call"
13320 [(parallel [(call (match_operand 0 "" "")
13321 (const_int 0))
13322 (match_operand 1 "" "")
13323 (match_operand 2 "" "")])]
13324 ""
13325 {
13326 int i;
13327
13328 /* In order to give reg-stack an easier job in validating two
13329 coprocessor registers as containing a possible return value,
13330 simply pretend the untyped call returns a complex long double
13331 value. */
13332
13333 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13334 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13335 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13336 NULL, 0);
13337
13338 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13339 {
13340 rtx set = XVECEXP (operands[2], 0, i);
13341 emit_move_insn (SET_DEST (set), SET_SRC (set));
13342 }
13343
13344 /* The optimizer does not know that the call sets the function value
13345 registers we stored in the result block. We avoid problems by
13346 claiming that all hard registers are used and clobbered at this
13347 point. */
13348 emit_insn (gen_blockage (const0_rtx));
13349
13350 DONE;
13351 })
13352 \f
13353 ;; Prologue and epilogue instructions
13354
13355 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13356 ;; all of memory. This blocks insns from being moved across this point.
13357
13358 (define_insn "blockage"
13359 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13360 ""
13361 ""
13362 [(set_attr "length" "0")])
13363
13364 ;; Insn emitted into the body of a function to return from a function.
13365 ;; This is only done if the function's epilogue is known to be simple.
13366 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13367
13368 (define_expand "return"
13369 [(return)]
13370 "ix86_can_use_return_insn_p ()"
13371 {
13372 if (current_function_pops_args)
13373 {
13374 rtx popc = GEN_INT (current_function_pops_args);
13375 emit_jump_insn (gen_return_pop_internal (popc));
13376 DONE;
13377 }
13378 })
13379
13380 (define_insn "return_internal"
13381 [(return)]
13382 "reload_completed"
13383 "ret"
13384 [(set_attr "length" "1")
13385 (set_attr "length_immediate" "0")
13386 (set_attr "modrm" "0")])
13387
13388 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13389 ;; instruction Athlon and K8 have.
13390
13391 (define_insn "return_internal_long"
13392 [(return)
13393 (unspec [(const_int 0)] UNSPEC_REP)]
13394 "reload_completed"
13395 "rep {;} ret"
13396 [(set_attr "length" "1")
13397 (set_attr "length_immediate" "0")
13398 (set_attr "prefix_rep" "1")
13399 (set_attr "modrm" "0")])
13400
13401 (define_insn "return_pop_internal"
13402 [(return)
13403 (use (match_operand:SI 0 "const_int_operand" ""))]
13404 "reload_completed"
13405 "ret\t%0"
13406 [(set_attr "length" "3")
13407 (set_attr "length_immediate" "2")
13408 (set_attr "modrm" "0")])
13409
13410 (define_insn "return_indirect_internal"
13411 [(return)
13412 (use (match_operand:SI 0 "register_operand" "r"))]
13413 "reload_completed"
13414 "jmp\t%A0"
13415 [(set_attr "type" "ibr")
13416 (set_attr "length_immediate" "0")])
13417
13418 (define_insn "nop"
13419 [(const_int 0)]
13420 ""
13421 "nop"
13422 [(set_attr "length" "1")
13423 (set_attr "length_immediate" "0")
13424 (set_attr "modrm" "0")])
13425
13426 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13427 ;; branch prediction penalty for the third jump in a 16-byte
13428 ;; block on K8.
13429
13430 (define_insn "align"
13431 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13432 ""
13433 {
13434 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13435 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13436 #else
13437 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13438 The align insn is used to avoid 3 jump instructions in the row to improve
13439 branch prediction and the benefits hardly outweight the cost of extra 8
13440 nops on the average inserted by full alignment pseudo operation. */
13441 #endif
13442 return "";
13443 }
13444 [(set_attr "length" "16")])
13445
13446 (define_expand "prologue"
13447 [(const_int 1)]
13448 ""
13449 "ix86_expand_prologue (); DONE;")
13450
13451 (define_insn "set_got"
13452 [(set (match_operand:SI 0 "register_operand" "=r")
13453 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13454 (clobber (reg:CC FLAGS_REG))]
13455 "!TARGET_64BIT"
13456 { return output_set_got (operands[0]); }
13457 [(set_attr "type" "multi")
13458 (set_attr "length" "12")])
13459
13460 (define_expand "epilogue"
13461 [(const_int 1)]
13462 ""
13463 "ix86_expand_epilogue (1); DONE;")
13464
13465 (define_expand "sibcall_epilogue"
13466 [(const_int 1)]
13467 ""
13468 "ix86_expand_epilogue (0); DONE;")
13469
13470 (define_expand "eh_return"
13471 [(use (match_operand 0 "register_operand" ""))]
13472 ""
13473 {
13474 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13475
13476 /* Tricky bit: we write the address of the handler to which we will
13477 be returning into someone else's stack frame, one word below the
13478 stack address we wish to restore. */
13479 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13480 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13481 tmp = gen_rtx_MEM (Pmode, tmp);
13482 emit_move_insn (tmp, ra);
13483
13484 if (Pmode == SImode)
13485 emit_jump_insn (gen_eh_return_si (sa));
13486 else
13487 emit_jump_insn (gen_eh_return_di (sa));
13488 emit_barrier ();
13489 DONE;
13490 })
13491
13492 (define_insn_and_split "eh_return_si"
13493 [(set (pc)
13494 (unspec [(match_operand:SI 0 "register_operand" "c")]
13495 UNSPEC_EH_RETURN))]
13496 "!TARGET_64BIT"
13497 "#"
13498 "reload_completed"
13499 [(const_int 1)]
13500 "ix86_expand_epilogue (2); DONE;")
13501
13502 (define_insn_and_split "eh_return_di"
13503 [(set (pc)
13504 (unspec [(match_operand:DI 0 "register_operand" "c")]
13505 UNSPEC_EH_RETURN))]
13506 "TARGET_64BIT"
13507 "#"
13508 "reload_completed"
13509 [(const_int 1)]
13510 "ix86_expand_epilogue (2); DONE;")
13511
13512 (define_insn "leave"
13513 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13514 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13515 (clobber (mem:BLK (scratch)))]
13516 "!TARGET_64BIT"
13517 "leave"
13518 [(set_attr "type" "leave")])
13519
13520 (define_insn "leave_rex64"
13521 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13522 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13523 (clobber (mem:BLK (scratch)))]
13524 "TARGET_64BIT"
13525 "leave"
13526 [(set_attr "type" "leave")])
13527 \f
13528 (define_expand "ffssi2"
13529 [(parallel
13530 [(set (match_operand:SI 0 "register_operand" "")
13531 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13532 (clobber (match_scratch:SI 2 ""))
13533 (clobber (reg:CC FLAGS_REG))])]
13534 ""
13535 "")
13536
13537 (define_insn_and_split "*ffs_cmove"
13538 [(set (match_operand:SI 0 "register_operand" "=r")
13539 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13540 (clobber (match_scratch:SI 2 "=&r"))
13541 (clobber (reg:CC FLAGS_REG))]
13542 "TARGET_CMOVE"
13543 "#"
13544 "&& reload_completed"
13545 [(set (match_dup 2) (const_int -1))
13546 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13547 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13548 (set (match_dup 0) (if_then_else:SI
13549 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13550 (match_dup 2)
13551 (match_dup 0)))
13552 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13553 (clobber (reg:CC FLAGS_REG))])]
13554 "")
13555
13556 (define_insn_and_split "*ffs_no_cmove"
13557 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13558 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13559 (clobber (match_scratch:SI 2 "=&q"))
13560 (clobber (reg:CC FLAGS_REG))]
13561 ""
13562 "#"
13563 "reload_completed"
13564 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13565 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13566 (set (strict_low_part (match_dup 3))
13567 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13568 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13569 (clobber (reg:CC FLAGS_REG))])
13570 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13571 (clobber (reg:CC FLAGS_REG))])
13572 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13573 (clobber (reg:CC FLAGS_REG))])]
13574 {
13575 operands[3] = gen_lowpart (QImode, operands[2]);
13576 ix86_expand_clear (operands[2]);
13577 })
13578
13579 (define_insn "*ffssi_1"
13580 [(set (reg:CCZ FLAGS_REG)
13581 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13582 (const_int 0)))
13583 (set (match_operand:SI 0 "register_operand" "=r")
13584 (ctz:SI (match_dup 1)))]
13585 ""
13586 "bsf{l}\t{%1, %0|%0, %1}"
13587 [(set_attr "prefix_0f" "1")])
13588
13589 (define_expand "ffsdi2"
13590 [(parallel
13591 [(set (match_operand:DI 0 "register_operand" "")
13592 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13593 (clobber (match_scratch:DI 2 ""))
13594 (clobber (reg:CC FLAGS_REG))])]
13595 "TARGET_64BIT && TARGET_CMOVE"
13596 "")
13597
13598 (define_insn_and_split "*ffs_rex64"
13599 [(set (match_operand:DI 0 "register_operand" "=r")
13600 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13601 (clobber (match_scratch:DI 2 "=&r"))
13602 (clobber (reg:CC FLAGS_REG))]
13603 "TARGET_64BIT && TARGET_CMOVE"
13604 "#"
13605 "&& reload_completed"
13606 [(set (match_dup 2) (const_int -1))
13607 (parallel [(set (reg:CCZ FLAGS_REG)
13608 (compare:CCZ (match_dup 1) (const_int 0)))
13609 (set (match_dup 0) (ctz:DI (match_dup 1)))])
13610 (set (match_dup 0) (if_then_else:DI
13611 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13612 (match_dup 2)
13613 (match_dup 0)))
13614 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13615 (clobber (reg:CC FLAGS_REG))])]
13616 "")
13617
13618 (define_insn "*ffsdi_1"
13619 [(set (reg:CCZ FLAGS_REG)
13620 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13621 (const_int 0)))
13622 (set (match_operand:DI 0 "register_operand" "=r")
13623 (ctz:DI (match_dup 1)))]
13624 "TARGET_64BIT"
13625 "bsf{q}\t{%1, %0|%0, %1}"
13626 [(set_attr "prefix_0f" "1")])
13627
13628 (define_insn "ctzsi2"
13629 [(set (match_operand:SI 0 "register_operand" "=r")
13630 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13631 (clobber (reg:CC FLAGS_REG))]
13632 ""
13633 "bsf{l}\t{%1, %0|%0, %1}"
13634 [(set_attr "prefix_0f" "1")])
13635
13636 (define_insn "ctzdi2"
13637 [(set (match_operand:DI 0 "register_operand" "=r")
13638 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13639 (clobber (reg:CC FLAGS_REG))]
13640 "TARGET_64BIT"
13641 "bsf{q}\t{%1, %0|%0, %1}"
13642 [(set_attr "prefix_0f" "1")])
13643
13644 (define_expand "clzsi2"
13645 [(parallel
13646 [(set (match_operand:SI 0 "register_operand" "")
13647 (minus:SI (const_int 31)
13648 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13649 (clobber (reg:CC FLAGS_REG))])
13650 (parallel
13651 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13652 (clobber (reg:CC FLAGS_REG))])]
13653 ""
13654 "")
13655
13656 (define_insn "*bsr"
13657 [(set (match_operand:SI 0 "register_operand" "=r")
13658 (minus:SI (const_int 31)
13659 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13660 (clobber (reg:CC FLAGS_REG))]
13661 ""
13662 "bsr{l}\t{%1, %0|%0, %1}"
13663 [(set_attr "prefix_0f" "1")])
13664
13665 (define_expand "clzdi2"
13666 [(parallel
13667 [(set (match_operand:DI 0 "register_operand" "")
13668 (minus:DI (const_int 63)
13669 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13670 (clobber (reg:CC FLAGS_REG))])
13671 (parallel
13672 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13673 (clobber (reg:CC FLAGS_REG))])]
13674 "TARGET_64BIT"
13675 "")
13676
13677 (define_insn "*bsr_rex64"
13678 [(set (match_operand:DI 0 "register_operand" "=r")
13679 (minus:DI (const_int 63)
13680 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13681 (clobber (reg:CC FLAGS_REG))]
13682 "TARGET_64BIT"
13683 "bsr{q}\t{%1, %0|%0, %1}"
13684 [(set_attr "prefix_0f" "1")])
13685 \f
13686 ;; Thread-local storage patterns for ELF.
13687 ;;
13688 ;; Note that these code sequences must appear exactly as shown
13689 ;; in order to allow linker relaxation.
13690
13691 (define_insn "*tls_global_dynamic_32_gnu"
13692 [(set (match_operand:SI 0 "register_operand" "=a")
13693 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13694 (match_operand:SI 2 "tls_symbolic_operand" "")
13695 (match_operand:SI 3 "call_insn_operand" "")]
13696 UNSPEC_TLS_GD))
13697 (clobber (match_scratch:SI 4 "=d"))
13698 (clobber (match_scratch:SI 5 "=c"))
13699 (clobber (reg:CC FLAGS_REG))]
13700 "!TARGET_64BIT && TARGET_GNU_TLS"
13701 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13702 [(set_attr "type" "multi")
13703 (set_attr "length" "12")])
13704
13705 (define_insn "*tls_global_dynamic_32_sun"
13706 [(set (match_operand:SI 0 "register_operand" "=a")
13707 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13708 (match_operand:SI 2 "tls_symbolic_operand" "")
13709 (match_operand:SI 3 "call_insn_operand" "")]
13710 UNSPEC_TLS_GD))
13711 (clobber (match_scratch:SI 4 "=d"))
13712 (clobber (match_scratch:SI 5 "=c"))
13713 (clobber (reg:CC FLAGS_REG))]
13714 "!TARGET_64BIT && TARGET_SUN_TLS"
13715 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13716 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13717 [(set_attr "type" "multi")
13718 (set_attr "length" "14")])
13719
13720 (define_expand "tls_global_dynamic_32"
13721 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13722 (unspec:SI
13723 [(match_dup 2)
13724 (match_operand:SI 1 "tls_symbolic_operand" "")
13725 (match_dup 3)]
13726 UNSPEC_TLS_GD))
13727 (clobber (match_scratch:SI 4 ""))
13728 (clobber (match_scratch:SI 5 ""))
13729 (clobber (reg:CC FLAGS_REG))])]
13730 ""
13731 {
13732 if (flag_pic)
13733 operands[2] = pic_offset_table_rtx;
13734 else
13735 {
13736 operands[2] = gen_reg_rtx (Pmode);
13737 emit_insn (gen_set_got (operands[2]));
13738 }
13739 operands[3] = ix86_tls_get_addr ();
13740 })
13741
13742 (define_insn "*tls_global_dynamic_64"
13743 [(set (match_operand:DI 0 "register_operand" "=a")
13744 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13745 (match_operand:DI 3 "" "")))
13746 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13747 UNSPEC_TLS_GD)]
13748 "TARGET_64BIT"
13749 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13750 [(set_attr "type" "multi")
13751 (set_attr "length" "16")])
13752
13753 (define_expand "tls_global_dynamic_64"
13754 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13755 (call (mem:QI (match_dup 2)) (const_int 0)))
13756 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13757 UNSPEC_TLS_GD)])]
13758 ""
13759 {
13760 operands[2] = ix86_tls_get_addr ();
13761 })
13762
13763 (define_insn "*tls_local_dynamic_base_32_gnu"
13764 [(set (match_operand:SI 0 "register_operand" "=a")
13765 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13766 (match_operand:SI 2 "call_insn_operand" "")]
13767 UNSPEC_TLS_LD_BASE))
13768 (clobber (match_scratch:SI 3 "=d"))
13769 (clobber (match_scratch:SI 4 "=c"))
13770 (clobber (reg:CC FLAGS_REG))]
13771 "!TARGET_64BIT && TARGET_GNU_TLS"
13772 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13773 [(set_attr "type" "multi")
13774 (set_attr "length" "11")])
13775
13776 (define_insn "*tls_local_dynamic_base_32_sun"
13777 [(set (match_operand:SI 0 "register_operand" "=a")
13778 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13779 (match_operand:SI 2 "call_insn_operand" "")]
13780 UNSPEC_TLS_LD_BASE))
13781 (clobber (match_scratch:SI 3 "=d"))
13782 (clobber (match_scratch:SI 4 "=c"))
13783 (clobber (reg:CC FLAGS_REG))]
13784 "!TARGET_64BIT && TARGET_SUN_TLS"
13785 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13786 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13787 [(set_attr "type" "multi")
13788 (set_attr "length" "13")])
13789
13790 (define_expand "tls_local_dynamic_base_32"
13791 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13792 (unspec:SI [(match_dup 1) (match_dup 2)]
13793 UNSPEC_TLS_LD_BASE))
13794 (clobber (match_scratch:SI 3 ""))
13795 (clobber (match_scratch:SI 4 ""))
13796 (clobber (reg:CC FLAGS_REG))])]
13797 ""
13798 {
13799 if (flag_pic)
13800 operands[1] = pic_offset_table_rtx;
13801 else
13802 {
13803 operands[1] = gen_reg_rtx (Pmode);
13804 emit_insn (gen_set_got (operands[1]));
13805 }
13806 operands[2] = ix86_tls_get_addr ();
13807 })
13808
13809 (define_insn "*tls_local_dynamic_base_64"
13810 [(set (match_operand:DI 0 "register_operand" "=a")
13811 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13812 (match_operand:DI 2 "" "")))
13813 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13814 "TARGET_64BIT"
13815 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13816 [(set_attr "type" "multi")
13817 (set_attr "length" "12")])
13818
13819 (define_expand "tls_local_dynamic_base_64"
13820 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13821 (call (mem:QI (match_dup 1)) (const_int 0)))
13822 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13823 ""
13824 {
13825 operands[1] = ix86_tls_get_addr ();
13826 })
13827
13828 ;; Local dynamic of a single variable is a lose. Show combine how
13829 ;; to convert that back to global dynamic.
13830
13831 (define_insn_and_split "*tls_local_dynamic_32_once"
13832 [(set (match_operand:SI 0 "register_operand" "=a")
13833 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13834 (match_operand:SI 2 "call_insn_operand" "")]
13835 UNSPEC_TLS_LD_BASE)
13836 (const:SI (unspec:SI
13837 [(match_operand:SI 3 "tls_symbolic_operand" "")]
13838 UNSPEC_DTPOFF))))
13839 (clobber (match_scratch:SI 4 "=d"))
13840 (clobber (match_scratch:SI 5 "=c"))
13841 (clobber (reg:CC FLAGS_REG))]
13842 ""
13843 "#"
13844 ""
13845 [(parallel [(set (match_dup 0)
13846 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13847 UNSPEC_TLS_GD))
13848 (clobber (match_dup 4))
13849 (clobber (match_dup 5))
13850 (clobber (reg:CC FLAGS_REG))])]
13851 "")
13852
13853 ;; Load and add the thread base pointer from %gs:0.
13854
13855 (define_insn "*load_tp_si"
13856 [(set (match_operand:SI 0 "register_operand" "=r")
13857 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13858 "!TARGET_64BIT"
13859 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13860 [(set_attr "type" "imov")
13861 (set_attr "modrm" "0")
13862 (set_attr "length" "7")
13863 (set_attr "memory" "load")
13864 (set_attr "imm_disp" "false")])
13865
13866 (define_insn "*add_tp_si"
13867 [(set (match_operand:SI 0 "register_operand" "=r")
13868 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13869 (match_operand:SI 1 "register_operand" "0")))
13870 (clobber (reg:CC FLAGS_REG))]
13871 "!TARGET_64BIT"
13872 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13873 [(set_attr "type" "alu")
13874 (set_attr "modrm" "0")
13875 (set_attr "length" "7")
13876 (set_attr "memory" "load")
13877 (set_attr "imm_disp" "false")])
13878
13879 (define_insn "*load_tp_di"
13880 [(set (match_operand:DI 0 "register_operand" "=r")
13881 (unspec:DI [(const_int 0)] UNSPEC_TP))]
13882 "TARGET_64BIT"
13883 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13884 [(set_attr "type" "imov")
13885 (set_attr "modrm" "0")
13886 (set_attr "length" "7")
13887 (set_attr "memory" "load")
13888 (set_attr "imm_disp" "false")])
13889
13890 (define_insn "*add_tp_di"
13891 [(set (match_operand:DI 0 "register_operand" "=r")
13892 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
13893 (match_operand:DI 1 "register_operand" "0")))
13894 (clobber (reg:CC FLAGS_REG))]
13895 "TARGET_64BIT"
13896 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13897 [(set_attr "type" "alu")
13898 (set_attr "modrm" "0")
13899 (set_attr "length" "7")
13900 (set_attr "memory" "load")
13901 (set_attr "imm_disp" "false")])
13902 \f
13903 ;; These patterns match the binary 387 instructions for addM3, subM3,
13904 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13905 ;; SFmode. The first is the normal insn, the second the same insn but
13906 ;; with one operand a conversion, and the third the same insn but with
13907 ;; the other operand a conversion. The conversion may be SFmode or
13908 ;; SImode if the target mode DFmode, but only SImode if the target mode
13909 ;; is SFmode.
13910
13911 ;; Gcc is slightly more smart about handling normal two address instructions
13912 ;; so use special patterns for add and mull.
13913
13914 (define_insn "*fop_sf_comm_mixed"
13915 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13916 (match_operator:SF 3 "binary_fp_operator"
13917 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
13918 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13919 "TARGET_MIX_SSE_I387
13920 && COMMUTATIVE_ARITH_P (operands[3])
13921 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13922 "* return output_387_binary_op (insn, operands);"
13923 [(set (attr "type")
13924 (if_then_else (eq_attr "alternative" "1")
13925 (if_then_else (match_operand:SF 3 "mult_operator" "")
13926 (const_string "ssemul")
13927 (const_string "sseadd"))
13928 (if_then_else (match_operand:SF 3 "mult_operator" "")
13929 (const_string "fmul")
13930 (const_string "fop"))))
13931 (set_attr "mode" "SF")])
13932
13933 (define_insn "*fop_sf_comm_sse"
13934 [(set (match_operand:SF 0 "register_operand" "=x")
13935 (match_operator:SF 3 "binary_fp_operator"
13936 [(match_operand:SF 1 "nonimmediate_operand" "%0")
13937 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13938 "TARGET_SSE_MATH
13939 && COMMUTATIVE_ARITH_P (operands[3])
13940 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13941 "* return output_387_binary_op (insn, operands);"
13942 [(set (attr "type")
13943 (if_then_else (match_operand:SF 3 "mult_operator" "")
13944 (const_string "ssemul")
13945 (const_string "sseadd")))
13946 (set_attr "mode" "SF")])
13947
13948 (define_insn "*fop_sf_comm_i387"
13949 [(set (match_operand:SF 0 "register_operand" "=f")
13950 (match_operator:SF 3 "binary_fp_operator"
13951 [(match_operand:SF 1 "nonimmediate_operand" "%0")
13952 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
13953 "TARGET_80387
13954 && COMMUTATIVE_ARITH_P (operands[3])
13955 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13956 "* return output_387_binary_op (insn, operands);"
13957 [(set (attr "type")
13958 (if_then_else (match_operand:SF 3 "mult_operator" "")
13959 (const_string "fmul")
13960 (const_string "fop")))
13961 (set_attr "mode" "SF")])
13962
13963 (define_insn "*fop_sf_1_mixed"
13964 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
13965 (match_operator:SF 3 "binary_fp_operator"
13966 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
13967 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
13968 "TARGET_MIX_SSE_I387
13969 && !COMMUTATIVE_ARITH_P (operands[3])
13970 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13971 "* return output_387_binary_op (insn, operands);"
13972 [(set (attr "type")
13973 (cond [(and (eq_attr "alternative" "2")
13974 (match_operand:SF 3 "mult_operator" ""))
13975 (const_string "ssemul")
13976 (and (eq_attr "alternative" "2")
13977 (match_operand:SF 3 "div_operator" ""))
13978 (const_string "ssediv")
13979 (eq_attr "alternative" "2")
13980 (const_string "sseadd")
13981 (match_operand:SF 3 "mult_operator" "")
13982 (const_string "fmul")
13983 (match_operand:SF 3 "div_operator" "")
13984 (const_string "fdiv")
13985 ]
13986 (const_string "fop")))
13987 (set_attr "mode" "SF")])
13988
13989 (define_insn "*fop_sf_1_sse"
13990 [(set (match_operand:SF 0 "register_operand" "=x")
13991 (match_operator:SF 3 "binary_fp_operator"
13992 [(match_operand:SF 1 "register_operand" "0")
13993 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13994 "TARGET_SSE_MATH
13995 && !COMMUTATIVE_ARITH_P (operands[3])"
13996 "* return output_387_binary_op (insn, operands);"
13997 [(set (attr "type")
13998 (cond [(match_operand:SF 3 "mult_operator" "")
13999 (const_string "ssemul")
14000 (match_operand:SF 3 "div_operator" "")
14001 (const_string "ssediv")
14002 ]
14003 (const_string "sseadd")))
14004 (set_attr "mode" "SF")])
14005
14006 ;; This pattern is not fully shadowed by the pattern above.
14007 (define_insn "*fop_sf_1_i387"
14008 [(set (match_operand:SF 0 "register_operand" "=f,f")
14009 (match_operator:SF 3 "binary_fp_operator"
14010 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14011 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14012 "TARGET_80387 && !TARGET_SSE_MATH
14013 && !COMMUTATIVE_ARITH_P (operands[3])
14014 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14015 "* return output_387_binary_op (insn, operands);"
14016 [(set (attr "type")
14017 (cond [(match_operand:SF 3 "mult_operator" "")
14018 (const_string "fmul")
14019 (match_operand:SF 3 "div_operator" "")
14020 (const_string "fdiv")
14021 ]
14022 (const_string "fop")))
14023 (set_attr "mode" "SF")])
14024
14025 ;; ??? Add SSE splitters for these!
14026 (define_insn "*fop_sf_2<mode>_i387"
14027 [(set (match_operand:SF 0 "register_operand" "=f,f")
14028 (match_operator:SF 3 "binary_fp_operator"
14029 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14030 (match_operand:SF 2 "register_operand" "0,0")]))]
14031 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14032 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14033 [(set (attr "type")
14034 (cond [(match_operand:SF 3 "mult_operator" "")
14035 (const_string "fmul")
14036 (match_operand:SF 3 "div_operator" "")
14037 (const_string "fdiv")
14038 ]
14039 (const_string "fop")))
14040 (set_attr "fp_int_src" "true")
14041 (set_attr "mode" "<MODE>")])
14042
14043 (define_insn "*fop_sf_3<mode>_i387"
14044 [(set (match_operand:SF 0 "register_operand" "=f,f")
14045 (match_operator:SF 3 "binary_fp_operator"
14046 [(match_operand:SF 1 "register_operand" "0,0")
14047 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14048 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14049 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14050 [(set (attr "type")
14051 (cond [(match_operand:SF 3 "mult_operator" "")
14052 (const_string "fmul")
14053 (match_operand:SF 3 "div_operator" "")
14054 (const_string "fdiv")
14055 ]
14056 (const_string "fop")))
14057 (set_attr "fp_int_src" "true")
14058 (set_attr "mode" "<MODE>")])
14059
14060 (define_insn "*fop_df_comm_mixed"
14061 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14062 (match_operator:DF 3 "binary_fp_operator"
14063 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14064 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14065 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14066 && COMMUTATIVE_ARITH_P (operands[3])
14067 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14068 "* return output_387_binary_op (insn, operands);"
14069 [(set (attr "type")
14070 (if_then_else (eq_attr "alternative" "1")
14071 (if_then_else (match_operand:SF 3 "mult_operator" "")
14072 (const_string "ssemul")
14073 (const_string "sseadd"))
14074 (if_then_else (match_operand:SF 3 "mult_operator" "")
14075 (const_string "fmul")
14076 (const_string "fop"))))
14077 (set_attr "mode" "DF")])
14078
14079 (define_insn "*fop_df_comm_sse"
14080 [(set (match_operand:DF 0 "register_operand" "=Y")
14081 (match_operator:DF 3 "binary_fp_operator"
14082 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14083 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14084 "TARGET_SSE2 && TARGET_SSE_MATH
14085 && COMMUTATIVE_ARITH_P (operands[3])
14086 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14087 "* return output_387_binary_op (insn, operands);"
14088 [(set (attr "type")
14089 (if_then_else (match_operand:SF 3 "mult_operator" "")
14090 (const_string "ssemul")
14091 (const_string "sseadd")))
14092 (set_attr "mode" "DF")])
14093
14094 (define_insn "*fop_df_comm_i387"
14095 [(set (match_operand:DF 0 "register_operand" "=f")
14096 (match_operator:DF 3 "binary_fp_operator"
14097 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14098 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14099 "TARGET_80387
14100 && COMMUTATIVE_ARITH_P (operands[3])
14101 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14102 "* return output_387_binary_op (insn, operands);"
14103 [(set (attr "type")
14104 (if_then_else (match_operand:SF 3 "mult_operator" "")
14105 (const_string "fmul")
14106 (const_string "fop")))
14107 (set_attr "mode" "DF")])
14108
14109 (define_insn "*fop_df_1_mixed"
14110 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14111 (match_operator:DF 3 "binary_fp_operator"
14112 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14113 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14114 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14115 && !COMMUTATIVE_ARITH_P (operands[3])
14116 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14117 "* return output_387_binary_op (insn, operands);"
14118 [(set (attr "type")
14119 (cond [(and (eq_attr "alternative" "2")
14120 (match_operand:SF 3 "mult_operator" ""))
14121 (const_string "ssemul")
14122 (and (eq_attr "alternative" "2")
14123 (match_operand:SF 3 "div_operator" ""))
14124 (const_string "ssediv")
14125 (eq_attr "alternative" "2")
14126 (const_string "sseadd")
14127 (match_operand:DF 3 "mult_operator" "")
14128 (const_string "fmul")
14129 (match_operand:DF 3 "div_operator" "")
14130 (const_string "fdiv")
14131 ]
14132 (const_string "fop")))
14133 (set_attr "mode" "DF")])
14134
14135 (define_insn "*fop_df_1_sse"
14136 [(set (match_operand:DF 0 "register_operand" "=Y")
14137 (match_operator:DF 3 "binary_fp_operator"
14138 [(match_operand:DF 1 "register_operand" "0")
14139 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14140 "TARGET_SSE2 && TARGET_SSE_MATH
14141 && !COMMUTATIVE_ARITH_P (operands[3])"
14142 "* return output_387_binary_op (insn, operands);"
14143 [(set_attr "mode" "DF")
14144 (set (attr "type")
14145 (cond [(match_operand:SF 3 "mult_operator" "")
14146 (const_string "ssemul")
14147 (match_operand:SF 3 "div_operator" "")
14148 (const_string "ssediv")
14149 ]
14150 (const_string "sseadd")))])
14151
14152 ;; This pattern is not fully shadowed by the pattern above.
14153 (define_insn "*fop_df_1_i387"
14154 [(set (match_operand:DF 0 "register_operand" "=f,f")
14155 (match_operator:DF 3 "binary_fp_operator"
14156 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14157 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14158 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14159 && !COMMUTATIVE_ARITH_P (operands[3])
14160 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14161 "* return output_387_binary_op (insn, operands);"
14162 [(set (attr "type")
14163 (cond [(match_operand:DF 3 "mult_operator" "")
14164 (const_string "fmul")
14165 (match_operand:DF 3 "div_operator" "")
14166 (const_string "fdiv")
14167 ]
14168 (const_string "fop")))
14169 (set_attr "mode" "DF")])
14170
14171 ;; ??? Add SSE splitters for these!
14172 (define_insn "*fop_df_2<mode>_i387"
14173 [(set (match_operand:DF 0 "register_operand" "=f,f")
14174 (match_operator:DF 3 "binary_fp_operator"
14175 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14176 (match_operand:DF 2 "register_operand" "0,0")]))]
14177 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14178 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14179 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14180 [(set (attr "type")
14181 (cond [(match_operand:DF 3 "mult_operator" "")
14182 (const_string "fmul")
14183 (match_operand:DF 3 "div_operator" "")
14184 (const_string "fdiv")
14185 ]
14186 (const_string "fop")))
14187 (set_attr "fp_int_src" "true")
14188 (set_attr "mode" "<MODE>")])
14189
14190 (define_insn "*fop_df_3<mode>_i387"
14191 [(set (match_operand:DF 0 "register_operand" "=f,f")
14192 (match_operator:DF 3 "binary_fp_operator"
14193 [(match_operand:DF 1 "register_operand" "0,0")
14194 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14195 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14196 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14197 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14198 [(set (attr "type")
14199 (cond [(match_operand:DF 3 "mult_operator" "")
14200 (const_string "fmul")
14201 (match_operand:DF 3 "div_operator" "")
14202 (const_string "fdiv")
14203 ]
14204 (const_string "fop")))
14205 (set_attr "fp_int_src" "true")
14206 (set_attr "mode" "<MODE>")])
14207
14208 (define_insn "*fop_df_4_i387"
14209 [(set (match_operand:DF 0 "register_operand" "=f,f")
14210 (match_operator:DF 3 "binary_fp_operator"
14211 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14212 (match_operand:DF 2 "register_operand" "0,f")]))]
14213 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14214 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14215 "* return output_387_binary_op (insn, operands);"
14216 [(set (attr "type")
14217 (cond [(match_operand:DF 3 "mult_operator" "")
14218 (const_string "fmul")
14219 (match_operand:DF 3 "div_operator" "")
14220 (const_string "fdiv")
14221 ]
14222 (const_string "fop")))
14223 (set_attr "mode" "SF")])
14224
14225 (define_insn "*fop_df_5_i387"
14226 [(set (match_operand:DF 0 "register_operand" "=f,f")
14227 (match_operator:DF 3 "binary_fp_operator"
14228 [(match_operand:DF 1 "register_operand" "0,f")
14229 (float_extend:DF
14230 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14231 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14232 "* return output_387_binary_op (insn, operands);"
14233 [(set (attr "type")
14234 (cond [(match_operand:DF 3 "mult_operator" "")
14235 (const_string "fmul")
14236 (match_operand:DF 3 "div_operator" "")
14237 (const_string "fdiv")
14238 ]
14239 (const_string "fop")))
14240 (set_attr "mode" "SF")])
14241
14242 (define_insn "*fop_df_6_i387"
14243 [(set (match_operand:DF 0 "register_operand" "=f,f")
14244 (match_operator:DF 3 "binary_fp_operator"
14245 [(float_extend:DF
14246 (match_operand:SF 1 "register_operand" "0,f"))
14247 (float_extend:DF
14248 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14249 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14250 "* return output_387_binary_op (insn, operands);"
14251 [(set (attr "type")
14252 (cond [(match_operand:DF 3 "mult_operator" "")
14253 (const_string "fmul")
14254 (match_operand:DF 3 "div_operator" "")
14255 (const_string "fdiv")
14256 ]
14257 (const_string "fop")))
14258 (set_attr "mode" "SF")])
14259
14260 (define_insn "*fop_xf_comm_i387"
14261 [(set (match_operand:XF 0 "register_operand" "=f")
14262 (match_operator:XF 3 "binary_fp_operator"
14263 [(match_operand:XF 1 "register_operand" "%0")
14264 (match_operand:XF 2 "register_operand" "f")]))]
14265 "TARGET_80387
14266 && COMMUTATIVE_ARITH_P (operands[3])"
14267 "* return output_387_binary_op (insn, operands);"
14268 [(set (attr "type")
14269 (if_then_else (match_operand:XF 3 "mult_operator" "")
14270 (const_string "fmul")
14271 (const_string "fop")))
14272 (set_attr "mode" "XF")])
14273
14274 (define_insn "*fop_xf_1_i387"
14275 [(set (match_operand:XF 0 "register_operand" "=f,f")
14276 (match_operator:XF 3 "binary_fp_operator"
14277 [(match_operand:XF 1 "register_operand" "0,f")
14278 (match_operand:XF 2 "register_operand" "f,0")]))]
14279 "TARGET_80387
14280 && !COMMUTATIVE_ARITH_P (operands[3])"
14281 "* return output_387_binary_op (insn, operands);"
14282 [(set (attr "type")
14283 (cond [(match_operand:XF 3 "mult_operator" "")
14284 (const_string "fmul")
14285 (match_operand:XF 3 "div_operator" "")
14286 (const_string "fdiv")
14287 ]
14288 (const_string "fop")))
14289 (set_attr "mode" "XF")])
14290
14291 (define_insn "*fop_xf_2<mode>_i387"
14292 [(set (match_operand:XF 0 "register_operand" "=f,f")
14293 (match_operator:XF 3 "binary_fp_operator"
14294 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14295 (match_operand:XF 2 "register_operand" "0,0")]))]
14296 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14297 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14298 [(set (attr "type")
14299 (cond [(match_operand:XF 3 "mult_operator" "")
14300 (const_string "fmul")
14301 (match_operand:XF 3 "div_operator" "")
14302 (const_string "fdiv")
14303 ]
14304 (const_string "fop")))
14305 (set_attr "fp_int_src" "true")
14306 (set_attr "mode" "<MODE>")])
14307
14308 (define_insn "*fop_xf_3<mode>_i387"
14309 [(set (match_operand:XF 0 "register_operand" "=f,f")
14310 (match_operator:XF 3 "binary_fp_operator"
14311 [(match_operand:XF 1 "register_operand" "0,0")
14312 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14313 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14314 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14315 [(set (attr "type")
14316 (cond [(match_operand:XF 3 "mult_operator" "")
14317 (const_string "fmul")
14318 (match_operand:XF 3 "div_operator" "")
14319 (const_string "fdiv")
14320 ]
14321 (const_string "fop")))
14322 (set_attr "fp_int_src" "true")
14323 (set_attr "mode" "<MODE>")])
14324
14325 (define_insn "*fop_xf_4_i387"
14326 [(set (match_operand:XF 0 "register_operand" "=f,f")
14327 (match_operator:XF 3 "binary_fp_operator"
14328 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14329 (match_operand:XF 2 "register_operand" "0,f")]))]
14330 "TARGET_80387"
14331 "* return output_387_binary_op (insn, operands);"
14332 [(set (attr "type")
14333 (cond [(match_operand:XF 3 "mult_operator" "")
14334 (const_string "fmul")
14335 (match_operand:XF 3 "div_operator" "")
14336 (const_string "fdiv")
14337 ]
14338 (const_string "fop")))
14339 (set_attr "mode" "SF")])
14340
14341 (define_insn "*fop_xf_5_i387"
14342 [(set (match_operand:XF 0 "register_operand" "=f,f")
14343 (match_operator:XF 3 "binary_fp_operator"
14344 [(match_operand:XF 1 "register_operand" "0,f")
14345 (float_extend:XF
14346 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14347 "TARGET_80387"
14348 "* return output_387_binary_op (insn, operands);"
14349 [(set (attr "type")
14350 (cond [(match_operand:XF 3 "mult_operator" "")
14351 (const_string "fmul")
14352 (match_operand:XF 3 "div_operator" "")
14353 (const_string "fdiv")
14354 ]
14355 (const_string "fop")))
14356 (set_attr "mode" "SF")])
14357
14358 (define_insn "*fop_xf_6_i387"
14359 [(set (match_operand:XF 0 "register_operand" "=f,f")
14360 (match_operator:XF 3 "binary_fp_operator"
14361 [(float_extend:XF
14362 (match_operand 1 "register_operand" "0,f"))
14363 (float_extend:XF
14364 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14365 "TARGET_80387"
14366 "* return output_387_binary_op (insn, operands);"
14367 [(set (attr "type")
14368 (cond [(match_operand:XF 3 "mult_operator" "")
14369 (const_string "fmul")
14370 (match_operand:XF 3 "div_operator" "")
14371 (const_string "fdiv")
14372 ]
14373 (const_string "fop")))
14374 (set_attr "mode" "SF")])
14375
14376 (define_split
14377 [(set (match_operand 0 "register_operand" "")
14378 (match_operator 3 "binary_fp_operator"
14379 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14380 (match_operand 2 "register_operand" "")]))]
14381 "TARGET_80387 && reload_completed
14382 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14383 [(const_int 0)]
14384 {
14385 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14386 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14387 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14388 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14389 GET_MODE (operands[3]),
14390 operands[4],
14391 operands[2])));
14392 ix86_free_from_memory (GET_MODE (operands[1]));
14393 DONE;
14394 })
14395
14396 (define_split
14397 [(set (match_operand 0 "register_operand" "")
14398 (match_operator 3 "binary_fp_operator"
14399 [(match_operand 1 "register_operand" "")
14400 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14401 "TARGET_80387 && reload_completed
14402 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14403 [(const_int 0)]
14404 {
14405 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14406 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14407 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14408 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14409 GET_MODE (operands[3]),
14410 operands[1],
14411 operands[4])));
14412 ix86_free_from_memory (GET_MODE (operands[2]));
14413 DONE;
14414 })
14415 \f
14416 ;; FPU special functions.
14417
14418 (define_expand "sqrtsf2"
14419 [(set (match_operand:SF 0 "register_operand" "")
14420 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14421 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14422 {
14423 if (!TARGET_SSE_MATH)
14424 operands[1] = force_reg (SFmode, operands[1]);
14425 })
14426
14427 (define_insn "*sqrtsf2_mixed"
14428 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14429 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14430 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14431 "@
14432 fsqrt
14433 sqrtss\t{%1, %0|%0, %1}"
14434 [(set_attr "type" "fpspc,sse")
14435 (set_attr "mode" "SF,SF")
14436 (set_attr "athlon_decode" "direct,*")])
14437
14438 (define_insn "*sqrtsf2_sse"
14439 [(set (match_operand:SF 0 "register_operand" "=x")
14440 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14441 "TARGET_SSE_MATH"
14442 "sqrtss\t{%1, %0|%0, %1}"
14443 [(set_attr "type" "sse")
14444 (set_attr "mode" "SF")
14445 (set_attr "athlon_decode" "*")])
14446
14447 (define_insn "*sqrtsf2_i387"
14448 [(set (match_operand:SF 0 "register_operand" "=f")
14449 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14450 "TARGET_USE_FANCY_MATH_387"
14451 "fsqrt"
14452 [(set_attr "type" "fpspc")
14453 (set_attr "mode" "SF")
14454 (set_attr "athlon_decode" "direct")])
14455
14456 (define_expand "sqrtdf2"
14457 [(set (match_operand:DF 0 "register_operand" "")
14458 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14459 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14460 {
14461 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14462 operands[1] = force_reg (DFmode, operands[1]);
14463 })
14464
14465 (define_insn "*sqrtdf2_mixed"
14466 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14467 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14468 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14469 "@
14470 fsqrt
14471 sqrtsd\t{%1, %0|%0, %1}"
14472 [(set_attr "type" "fpspc,sse")
14473 (set_attr "mode" "DF,DF")
14474 (set_attr "athlon_decode" "direct,*")])
14475
14476 (define_insn "*sqrtdf2_sse"
14477 [(set (match_operand:DF 0 "register_operand" "=Y")
14478 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14479 "TARGET_SSE2 && TARGET_SSE_MATH"
14480 "sqrtsd\t{%1, %0|%0, %1}"
14481 [(set_attr "type" "sse")
14482 (set_attr "mode" "DF")
14483 (set_attr "athlon_decode" "*")])
14484
14485 (define_insn "*sqrtdf2_i387"
14486 [(set (match_operand:DF 0 "register_operand" "=f")
14487 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14488 "TARGET_USE_FANCY_MATH_387"
14489 "fsqrt"
14490 [(set_attr "type" "fpspc")
14491 (set_attr "mode" "DF")
14492 (set_attr "athlon_decode" "direct")])
14493
14494 (define_insn "*sqrtextendsfdf2_i387"
14495 [(set (match_operand:DF 0 "register_operand" "=f")
14496 (sqrt:DF (float_extend:DF
14497 (match_operand:SF 1 "register_operand" "0"))))]
14498 "TARGET_USE_FANCY_MATH_387
14499 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14500 "fsqrt"
14501 [(set_attr "type" "fpspc")
14502 (set_attr "mode" "DF")
14503 (set_attr "athlon_decode" "direct")])
14504
14505 (define_insn "sqrtxf2"
14506 [(set (match_operand:XF 0 "register_operand" "=f")
14507 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14508 "TARGET_USE_FANCY_MATH_387
14509 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14510 "fsqrt"
14511 [(set_attr "type" "fpspc")
14512 (set_attr "mode" "XF")
14513 (set_attr "athlon_decode" "direct")])
14514
14515 (define_insn "*sqrtextendsfxf2_i387"
14516 [(set (match_operand:XF 0 "register_operand" "=f")
14517 (sqrt:XF (float_extend:XF
14518 (match_operand:SF 1 "register_operand" "0"))))]
14519 "TARGET_USE_FANCY_MATH_387"
14520 "fsqrt"
14521 [(set_attr "type" "fpspc")
14522 (set_attr "mode" "XF")
14523 (set_attr "athlon_decode" "direct")])
14524
14525 (define_insn "*sqrtextenddfxf2_i387"
14526 [(set (match_operand:XF 0 "register_operand" "=f")
14527 (sqrt:XF (float_extend:XF
14528 (match_operand:DF 1 "register_operand" "0"))))]
14529 "TARGET_USE_FANCY_MATH_387"
14530 "fsqrt"
14531 [(set_attr "type" "fpspc")
14532 (set_attr "mode" "XF")
14533 (set_attr "athlon_decode" "direct")])
14534
14535 (define_insn "fpremxf4"
14536 [(set (match_operand:XF 0 "register_operand" "=f")
14537 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14538 (match_operand:XF 3 "register_operand" "1")]
14539 UNSPEC_FPREM_F))
14540 (set (match_operand:XF 1 "register_operand" "=u")
14541 (unspec:XF [(match_dup 2) (match_dup 3)]
14542 UNSPEC_FPREM_U))
14543 (set (reg:CCFP FPSR_REG)
14544 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14545 "TARGET_USE_FANCY_MATH_387
14546 && flag_unsafe_math_optimizations"
14547 "fprem"
14548 [(set_attr "type" "fpspc")
14549 (set_attr "mode" "XF")])
14550
14551 (define_expand "fmodsf3"
14552 [(use (match_operand:SF 0 "register_operand" ""))
14553 (use (match_operand:SF 1 "register_operand" ""))
14554 (use (match_operand:SF 2 "register_operand" ""))]
14555 "TARGET_USE_FANCY_MATH_387
14556 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14557 && flag_unsafe_math_optimizations"
14558 {
14559 rtx label = gen_label_rtx ();
14560
14561 rtx op1 = gen_reg_rtx (XFmode);
14562 rtx op2 = gen_reg_rtx (XFmode);
14563
14564 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14565 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14566
14567 emit_label (label);
14568
14569 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14570 ix86_emit_fp_unordered_jump (label);
14571
14572 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14573 DONE;
14574 })
14575
14576 (define_expand "fmoddf3"
14577 [(use (match_operand:DF 0 "register_operand" ""))
14578 (use (match_operand:DF 1 "register_operand" ""))
14579 (use (match_operand:DF 2 "register_operand" ""))]
14580 "TARGET_USE_FANCY_MATH_387
14581 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14582 && flag_unsafe_math_optimizations"
14583 {
14584 rtx label = gen_label_rtx ();
14585
14586 rtx op1 = gen_reg_rtx (XFmode);
14587 rtx op2 = gen_reg_rtx (XFmode);
14588
14589 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14590 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14591
14592 emit_label (label);
14593
14594 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14595 ix86_emit_fp_unordered_jump (label);
14596
14597 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14598 DONE;
14599 })
14600
14601 (define_expand "fmodxf3"
14602 [(use (match_operand:XF 0 "register_operand" ""))
14603 (use (match_operand:XF 1 "register_operand" ""))
14604 (use (match_operand:XF 2 "register_operand" ""))]
14605 "TARGET_USE_FANCY_MATH_387
14606 && flag_unsafe_math_optimizations"
14607 {
14608 rtx label = gen_label_rtx ();
14609
14610 emit_label (label);
14611
14612 emit_insn (gen_fpremxf4 (operands[1], operands[2],
14613 operands[1], operands[2]));
14614 ix86_emit_fp_unordered_jump (label);
14615
14616 emit_move_insn (operands[0], operands[1]);
14617 DONE;
14618 })
14619
14620 (define_insn "fprem1xf4"
14621 [(set (match_operand:XF 0 "register_operand" "=f")
14622 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14623 (match_operand:XF 3 "register_operand" "1")]
14624 UNSPEC_FPREM1_F))
14625 (set (match_operand:XF 1 "register_operand" "=u")
14626 (unspec:XF [(match_dup 2) (match_dup 3)]
14627 UNSPEC_FPREM1_U))
14628 (set (reg:CCFP FPSR_REG)
14629 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14630 "TARGET_USE_FANCY_MATH_387
14631 && flag_unsafe_math_optimizations"
14632 "fprem1"
14633 [(set_attr "type" "fpspc")
14634 (set_attr "mode" "XF")])
14635
14636 (define_expand "dremsf3"
14637 [(use (match_operand:SF 0 "register_operand" ""))
14638 (use (match_operand:SF 1 "register_operand" ""))
14639 (use (match_operand:SF 2 "register_operand" ""))]
14640 "TARGET_USE_FANCY_MATH_387
14641 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14642 && flag_unsafe_math_optimizations"
14643 {
14644 rtx label = gen_label_rtx ();
14645
14646 rtx op1 = gen_reg_rtx (XFmode);
14647 rtx op2 = gen_reg_rtx (XFmode);
14648
14649 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14650 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14651
14652 emit_label (label);
14653
14654 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14655 ix86_emit_fp_unordered_jump (label);
14656
14657 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14658 DONE;
14659 })
14660
14661 (define_expand "dremdf3"
14662 [(use (match_operand:DF 0 "register_operand" ""))
14663 (use (match_operand:DF 1 "register_operand" ""))
14664 (use (match_operand:DF 2 "register_operand" ""))]
14665 "TARGET_USE_FANCY_MATH_387
14666 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14667 && flag_unsafe_math_optimizations"
14668 {
14669 rtx label = gen_label_rtx ();
14670
14671 rtx op1 = gen_reg_rtx (XFmode);
14672 rtx op2 = gen_reg_rtx (XFmode);
14673
14674 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14675 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14676
14677 emit_label (label);
14678
14679 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14680 ix86_emit_fp_unordered_jump (label);
14681
14682 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14683 DONE;
14684 })
14685
14686 (define_expand "dremxf3"
14687 [(use (match_operand:XF 0 "register_operand" ""))
14688 (use (match_operand:XF 1 "register_operand" ""))
14689 (use (match_operand:XF 2 "register_operand" ""))]
14690 "TARGET_USE_FANCY_MATH_387
14691 && flag_unsafe_math_optimizations"
14692 {
14693 rtx label = gen_label_rtx ();
14694
14695 emit_label (label);
14696
14697 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14698 operands[1], operands[2]));
14699 ix86_emit_fp_unordered_jump (label);
14700
14701 emit_move_insn (operands[0], operands[1]);
14702 DONE;
14703 })
14704
14705 (define_insn "*sindf2"
14706 [(set (match_operand:DF 0 "register_operand" "=f")
14707 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14708 "TARGET_USE_FANCY_MATH_387
14709 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14710 && flag_unsafe_math_optimizations"
14711 "fsin"
14712 [(set_attr "type" "fpspc")
14713 (set_attr "mode" "DF")])
14714
14715 (define_insn "*sinsf2"
14716 [(set (match_operand:SF 0 "register_operand" "=f")
14717 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14718 "TARGET_USE_FANCY_MATH_387
14719 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14720 && flag_unsafe_math_optimizations"
14721 "fsin"
14722 [(set_attr "type" "fpspc")
14723 (set_attr "mode" "SF")])
14724
14725 (define_insn "*sinextendsfdf2"
14726 [(set (match_operand:DF 0 "register_operand" "=f")
14727 (unspec:DF [(float_extend:DF
14728 (match_operand:SF 1 "register_operand" "0"))]
14729 UNSPEC_SIN))]
14730 "TARGET_USE_FANCY_MATH_387
14731 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14732 && flag_unsafe_math_optimizations"
14733 "fsin"
14734 [(set_attr "type" "fpspc")
14735 (set_attr "mode" "DF")])
14736
14737 (define_insn "*sinxf2"
14738 [(set (match_operand:XF 0 "register_operand" "=f")
14739 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14740 "TARGET_USE_FANCY_MATH_387
14741 && flag_unsafe_math_optimizations"
14742 "fsin"
14743 [(set_attr "type" "fpspc")
14744 (set_attr "mode" "XF")])
14745
14746 (define_insn "*cosdf2"
14747 [(set (match_operand:DF 0 "register_operand" "=f")
14748 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14749 "TARGET_USE_FANCY_MATH_387
14750 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14751 && flag_unsafe_math_optimizations"
14752 "fcos"
14753 [(set_attr "type" "fpspc")
14754 (set_attr "mode" "DF")])
14755
14756 (define_insn "*cossf2"
14757 [(set (match_operand:SF 0 "register_operand" "=f")
14758 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14759 "TARGET_USE_FANCY_MATH_387
14760 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14761 && flag_unsafe_math_optimizations"
14762 "fcos"
14763 [(set_attr "type" "fpspc")
14764 (set_attr "mode" "SF")])
14765
14766 (define_insn "*cosextendsfdf2"
14767 [(set (match_operand:DF 0 "register_operand" "=f")
14768 (unspec:DF [(float_extend:DF
14769 (match_operand:SF 1 "register_operand" "0"))]
14770 UNSPEC_COS))]
14771 "TARGET_USE_FANCY_MATH_387
14772 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14773 && flag_unsafe_math_optimizations"
14774 "fcos"
14775 [(set_attr "type" "fpspc")
14776 (set_attr "mode" "DF")])
14777
14778 (define_insn "*cosxf2"
14779 [(set (match_operand:XF 0 "register_operand" "=f")
14780 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14781 "TARGET_USE_FANCY_MATH_387
14782 && flag_unsafe_math_optimizations"
14783 "fcos"
14784 [(set_attr "type" "fpspc")
14785 (set_attr "mode" "XF")])
14786
14787 ;; With sincos pattern defined, sin and cos builtin function will be
14788 ;; expanded to sincos pattern with one of its outputs left unused.
14789 ;; Cse pass will detected, if two sincos patterns can be combined,
14790 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14791 ;; depending on the unused output.
14792
14793 (define_insn "sincosdf3"
14794 [(set (match_operand:DF 0 "register_operand" "=f")
14795 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14796 UNSPEC_SINCOS_COS))
14797 (set (match_operand:DF 1 "register_operand" "=u")
14798 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14799 "TARGET_USE_FANCY_MATH_387
14800 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14801 && flag_unsafe_math_optimizations"
14802 "fsincos"
14803 [(set_attr "type" "fpspc")
14804 (set_attr "mode" "DF")])
14805
14806 (define_split
14807 [(set (match_operand:DF 0 "register_operand" "")
14808 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14809 UNSPEC_SINCOS_COS))
14810 (set (match_operand:DF 1 "register_operand" "")
14811 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14812 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14813 && !reload_completed && !reload_in_progress"
14814 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14815 "")
14816
14817 (define_split
14818 [(set (match_operand:DF 0 "register_operand" "")
14819 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14820 UNSPEC_SINCOS_COS))
14821 (set (match_operand:DF 1 "register_operand" "")
14822 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14823 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14824 && !reload_completed && !reload_in_progress"
14825 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14826 "")
14827
14828 (define_insn "sincossf3"
14829 [(set (match_operand:SF 0 "register_operand" "=f")
14830 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14831 UNSPEC_SINCOS_COS))
14832 (set (match_operand:SF 1 "register_operand" "=u")
14833 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14834 "TARGET_USE_FANCY_MATH_387
14835 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14836 && flag_unsafe_math_optimizations"
14837 "fsincos"
14838 [(set_attr "type" "fpspc")
14839 (set_attr "mode" "SF")])
14840
14841 (define_split
14842 [(set (match_operand:SF 0 "register_operand" "")
14843 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14844 UNSPEC_SINCOS_COS))
14845 (set (match_operand:SF 1 "register_operand" "")
14846 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14847 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14848 && !reload_completed && !reload_in_progress"
14849 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14850 "")
14851
14852 (define_split
14853 [(set (match_operand:SF 0 "register_operand" "")
14854 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14855 UNSPEC_SINCOS_COS))
14856 (set (match_operand:SF 1 "register_operand" "")
14857 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14858 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14859 && !reload_completed && !reload_in_progress"
14860 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14861 "")
14862
14863 (define_insn "*sincosextendsfdf3"
14864 [(set (match_operand:DF 0 "register_operand" "=f")
14865 (unspec:DF [(float_extend:DF
14866 (match_operand:SF 2 "register_operand" "0"))]
14867 UNSPEC_SINCOS_COS))
14868 (set (match_operand:DF 1 "register_operand" "=u")
14869 (unspec:DF [(float_extend:DF
14870 (match_dup 2))] UNSPEC_SINCOS_SIN))]
14871 "TARGET_USE_FANCY_MATH_387
14872 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14873 && flag_unsafe_math_optimizations"
14874 "fsincos"
14875 [(set_attr "type" "fpspc")
14876 (set_attr "mode" "DF")])
14877
14878 (define_split
14879 [(set (match_operand:DF 0 "register_operand" "")
14880 (unspec:DF [(float_extend:DF
14881 (match_operand:SF 2 "register_operand" ""))]
14882 UNSPEC_SINCOS_COS))
14883 (set (match_operand:DF 1 "register_operand" "")
14884 (unspec:DF [(float_extend:DF
14885 (match_dup 2))] UNSPEC_SINCOS_SIN))]
14886 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14887 && !reload_completed && !reload_in_progress"
14888 [(set (match_dup 1) (unspec:DF [(float_extend:DF
14889 (match_dup 2))] UNSPEC_SIN))]
14890 "")
14891
14892 (define_split
14893 [(set (match_operand:DF 0 "register_operand" "")
14894 (unspec:DF [(float_extend:DF
14895 (match_operand:SF 2 "register_operand" ""))]
14896 UNSPEC_SINCOS_COS))
14897 (set (match_operand:DF 1 "register_operand" "")
14898 (unspec:DF [(float_extend:DF
14899 (match_dup 2))] UNSPEC_SINCOS_SIN))]
14900 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14901 && !reload_completed && !reload_in_progress"
14902 [(set (match_dup 0) (unspec:DF [(float_extend:DF
14903 (match_dup 2))] UNSPEC_COS))]
14904 "")
14905
14906 (define_insn "sincosxf3"
14907 [(set (match_operand:XF 0 "register_operand" "=f")
14908 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14909 UNSPEC_SINCOS_COS))
14910 (set (match_operand:XF 1 "register_operand" "=u")
14911 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14912 "TARGET_USE_FANCY_MATH_387
14913 && flag_unsafe_math_optimizations"
14914 "fsincos"
14915 [(set_attr "type" "fpspc")
14916 (set_attr "mode" "XF")])
14917
14918 (define_split
14919 [(set (match_operand:XF 0 "register_operand" "")
14920 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14921 UNSPEC_SINCOS_COS))
14922 (set (match_operand:XF 1 "register_operand" "")
14923 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14924 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14925 && !reload_completed && !reload_in_progress"
14926 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
14927 "")
14928
14929 (define_split
14930 [(set (match_operand:XF 0 "register_operand" "")
14931 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14932 UNSPEC_SINCOS_COS))
14933 (set (match_operand:XF 1 "register_operand" "")
14934 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14935 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14936 && !reload_completed && !reload_in_progress"
14937 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
14938 "")
14939
14940 (define_insn "*tandf3_1"
14941 [(set (match_operand:DF 0 "register_operand" "=f")
14942 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14943 UNSPEC_TAN_ONE))
14944 (set (match_operand:DF 1 "register_operand" "=u")
14945 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
14946 "TARGET_USE_FANCY_MATH_387
14947 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14948 && flag_unsafe_math_optimizations"
14949 "fptan"
14950 [(set_attr "type" "fpspc")
14951 (set_attr "mode" "DF")])
14952
14953 ;; optimize sequence: fptan
14954 ;; fstp %st(0)
14955 ;; fld1
14956 ;; into fptan insn.
14957
14958 (define_peephole2
14959 [(parallel[(set (match_operand:DF 0 "register_operand" "")
14960 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14961 UNSPEC_TAN_ONE))
14962 (set (match_operand:DF 1 "register_operand" "")
14963 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
14964 (set (match_dup 0)
14965 (match_operand:DF 3 "immediate_operand" ""))]
14966 "standard_80387_constant_p (operands[3]) == 2"
14967 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
14968 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
14969 "")
14970
14971 (define_expand "tandf2"
14972 [(parallel [(set (match_dup 2)
14973 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
14974 UNSPEC_TAN_ONE))
14975 (set (match_operand:DF 0 "register_operand" "")
14976 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
14977 "TARGET_USE_FANCY_MATH_387
14978 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14979 && flag_unsafe_math_optimizations"
14980 {
14981 operands[2] = gen_reg_rtx (DFmode);
14982 })
14983
14984 (define_insn "*tansf3_1"
14985 [(set (match_operand:SF 0 "register_operand" "=f")
14986 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14987 UNSPEC_TAN_ONE))
14988 (set (match_operand:SF 1 "register_operand" "=u")
14989 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
14990 "TARGET_USE_FANCY_MATH_387
14991 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14992 && flag_unsafe_math_optimizations"
14993 "fptan"
14994 [(set_attr "type" "fpspc")
14995 (set_attr "mode" "SF")])
14996
14997 ;; optimize sequence: fptan
14998 ;; fstp %st(0)
14999 ;; fld1
15000 ;; into fptan insn.
15001
15002 (define_peephole2
15003 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15004 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15005 UNSPEC_TAN_ONE))
15006 (set (match_operand:SF 1 "register_operand" "")
15007 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15008 (set (match_dup 0)
15009 (match_operand:SF 3 "immediate_operand" ""))]
15010 "standard_80387_constant_p (operands[3]) == 2"
15011 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15012 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15013 "")
15014
15015 (define_expand "tansf2"
15016 [(parallel [(set (match_dup 2)
15017 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15018 UNSPEC_TAN_ONE))
15019 (set (match_operand:SF 0 "register_operand" "")
15020 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15021 "TARGET_USE_FANCY_MATH_387
15022 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15023 && flag_unsafe_math_optimizations"
15024 {
15025 operands[2] = gen_reg_rtx (SFmode);
15026 })
15027
15028 (define_insn "*tanxf3_1"
15029 [(set (match_operand:XF 0 "register_operand" "=f")
15030 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15031 UNSPEC_TAN_ONE))
15032 (set (match_operand:XF 1 "register_operand" "=u")
15033 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15034 "TARGET_USE_FANCY_MATH_387
15035 && flag_unsafe_math_optimizations"
15036 "fptan"
15037 [(set_attr "type" "fpspc")
15038 (set_attr "mode" "XF")])
15039
15040 ;; optimize sequence: fptan
15041 ;; fstp %st(0)
15042 ;; fld1
15043 ;; into fptan insn.
15044
15045 (define_peephole2
15046 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15047 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15048 UNSPEC_TAN_ONE))
15049 (set (match_operand:XF 1 "register_operand" "")
15050 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15051 (set (match_dup 0)
15052 (match_operand:XF 3 "immediate_operand" ""))]
15053 "standard_80387_constant_p (operands[3]) == 2"
15054 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15055 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15056 "")
15057
15058 (define_expand "tanxf2"
15059 [(parallel [(set (match_dup 2)
15060 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15061 UNSPEC_TAN_ONE))
15062 (set (match_operand:XF 0 "register_operand" "")
15063 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15064 "TARGET_USE_FANCY_MATH_387
15065 && flag_unsafe_math_optimizations"
15066 {
15067 operands[2] = gen_reg_rtx (XFmode);
15068 })
15069
15070 (define_insn "atan2df3_1"
15071 [(set (match_operand:DF 0 "register_operand" "=f")
15072 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15073 (match_operand:DF 1 "register_operand" "u")]
15074 UNSPEC_FPATAN))
15075 (clobber (match_scratch:DF 3 "=1"))]
15076 "TARGET_USE_FANCY_MATH_387
15077 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15078 && flag_unsafe_math_optimizations"
15079 "fpatan"
15080 [(set_attr "type" "fpspc")
15081 (set_attr "mode" "DF")])
15082
15083 (define_expand "atan2df3"
15084 [(use (match_operand:DF 0 "register_operand" ""))
15085 (use (match_operand:DF 2 "register_operand" ""))
15086 (use (match_operand:DF 1 "register_operand" ""))]
15087 "TARGET_USE_FANCY_MATH_387
15088 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15089 && flag_unsafe_math_optimizations"
15090 {
15091 rtx copy = gen_reg_rtx (DFmode);
15092 emit_move_insn (copy, operands[1]);
15093 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15094 DONE;
15095 })
15096
15097 (define_expand "atandf2"
15098 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15099 (unspec:DF [(match_dup 2)
15100 (match_operand:DF 1 "register_operand" "")]
15101 UNSPEC_FPATAN))
15102 (clobber (match_scratch:DF 3 ""))])]
15103 "TARGET_USE_FANCY_MATH_387
15104 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15105 && flag_unsafe_math_optimizations"
15106 {
15107 operands[2] = gen_reg_rtx (DFmode);
15108 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15109 })
15110
15111 (define_insn "atan2sf3_1"
15112 [(set (match_operand:SF 0 "register_operand" "=f")
15113 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15114 (match_operand:SF 1 "register_operand" "u")]
15115 UNSPEC_FPATAN))
15116 (clobber (match_scratch:SF 3 "=1"))]
15117 "TARGET_USE_FANCY_MATH_387
15118 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15119 && flag_unsafe_math_optimizations"
15120 "fpatan"
15121 [(set_attr "type" "fpspc")
15122 (set_attr "mode" "SF")])
15123
15124 (define_expand "atan2sf3"
15125 [(use (match_operand:SF 0 "register_operand" ""))
15126 (use (match_operand:SF 2 "register_operand" ""))
15127 (use (match_operand:SF 1 "register_operand" ""))]
15128 "TARGET_USE_FANCY_MATH_387
15129 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15130 && flag_unsafe_math_optimizations"
15131 {
15132 rtx copy = gen_reg_rtx (SFmode);
15133 emit_move_insn (copy, operands[1]);
15134 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15135 DONE;
15136 })
15137
15138 (define_expand "atansf2"
15139 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15140 (unspec:SF [(match_dup 2)
15141 (match_operand:SF 1 "register_operand" "")]
15142 UNSPEC_FPATAN))
15143 (clobber (match_scratch:SF 3 ""))])]
15144 "TARGET_USE_FANCY_MATH_387
15145 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15146 && flag_unsafe_math_optimizations"
15147 {
15148 operands[2] = gen_reg_rtx (SFmode);
15149 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15150 })
15151
15152 (define_insn "atan2xf3_1"
15153 [(set (match_operand:XF 0 "register_operand" "=f")
15154 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15155 (match_operand:XF 1 "register_operand" "u")]
15156 UNSPEC_FPATAN))
15157 (clobber (match_scratch:XF 3 "=1"))]
15158 "TARGET_USE_FANCY_MATH_387
15159 && flag_unsafe_math_optimizations"
15160 "fpatan"
15161 [(set_attr "type" "fpspc")
15162 (set_attr "mode" "XF")])
15163
15164 (define_expand "atan2xf3"
15165 [(use (match_operand:XF 0 "register_operand" ""))
15166 (use (match_operand:XF 2 "register_operand" ""))
15167 (use (match_operand:XF 1 "register_operand" ""))]
15168 "TARGET_USE_FANCY_MATH_387
15169 && flag_unsafe_math_optimizations"
15170 {
15171 rtx copy = gen_reg_rtx (XFmode);
15172 emit_move_insn (copy, operands[1]);
15173 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15174 DONE;
15175 })
15176
15177 (define_expand "atanxf2"
15178 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15179 (unspec:XF [(match_dup 2)
15180 (match_operand:XF 1 "register_operand" "")]
15181 UNSPEC_FPATAN))
15182 (clobber (match_scratch:XF 3 ""))])]
15183 "TARGET_USE_FANCY_MATH_387
15184 && flag_unsafe_math_optimizations"
15185 {
15186 operands[2] = gen_reg_rtx (XFmode);
15187 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15188 })
15189
15190 (define_expand "asindf2"
15191 [(set (match_dup 2)
15192 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15193 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15194 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15195 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15196 (parallel [(set (match_dup 7)
15197 (unspec:XF [(match_dup 6) (match_dup 2)]
15198 UNSPEC_FPATAN))
15199 (clobber (match_scratch:XF 8 ""))])
15200 (set (match_operand:DF 0 "register_operand" "")
15201 (float_truncate:DF (match_dup 7)))]
15202 "TARGET_USE_FANCY_MATH_387
15203 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15204 && flag_unsafe_math_optimizations"
15205 {
15206 int i;
15207
15208 for (i=2; i<8; i++)
15209 operands[i] = gen_reg_rtx (XFmode);
15210
15211 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15212 })
15213
15214 (define_expand "asinsf2"
15215 [(set (match_dup 2)
15216 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15217 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15218 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15219 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15220 (parallel [(set (match_dup 7)
15221 (unspec:XF [(match_dup 6) (match_dup 2)]
15222 UNSPEC_FPATAN))
15223 (clobber (match_scratch:XF 8 ""))])
15224 (set (match_operand:SF 0 "register_operand" "")
15225 (float_truncate:SF (match_dup 7)))]
15226 "TARGET_USE_FANCY_MATH_387
15227 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15228 && flag_unsafe_math_optimizations"
15229 {
15230 int i;
15231
15232 for (i=2; i<8; i++)
15233 operands[i] = gen_reg_rtx (XFmode);
15234
15235 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15236 })
15237
15238 (define_expand "asinxf2"
15239 [(set (match_dup 2)
15240 (mult:XF (match_operand:XF 1 "register_operand" "")
15241 (match_dup 1)))
15242 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15243 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15244 (parallel [(set (match_operand:XF 0 "register_operand" "")
15245 (unspec:XF [(match_dup 5) (match_dup 1)]
15246 UNSPEC_FPATAN))
15247 (clobber (match_scratch:XF 6 ""))])]
15248 "TARGET_USE_FANCY_MATH_387
15249 && flag_unsafe_math_optimizations"
15250 {
15251 int i;
15252
15253 for (i=2; i<6; i++)
15254 operands[i] = gen_reg_rtx (XFmode);
15255
15256 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15257 })
15258
15259 (define_expand "acosdf2"
15260 [(set (match_dup 2)
15261 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15262 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15263 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15264 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15265 (parallel [(set (match_dup 7)
15266 (unspec:XF [(match_dup 2) (match_dup 6)]
15267 UNSPEC_FPATAN))
15268 (clobber (match_scratch:XF 8 ""))])
15269 (set (match_operand:DF 0 "register_operand" "")
15270 (float_truncate:DF (match_dup 7)))]
15271 "TARGET_USE_FANCY_MATH_387
15272 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15273 && flag_unsafe_math_optimizations"
15274 {
15275 int i;
15276
15277 for (i=2; i<8; i++)
15278 operands[i] = gen_reg_rtx (XFmode);
15279
15280 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15281 })
15282
15283 (define_expand "acossf2"
15284 [(set (match_dup 2)
15285 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15286 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15287 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15288 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15289 (parallel [(set (match_dup 7)
15290 (unspec:XF [(match_dup 2) (match_dup 6)]
15291 UNSPEC_FPATAN))
15292 (clobber (match_scratch:XF 8 ""))])
15293 (set (match_operand:SF 0 "register_operand" "")
15294 (float_truncate:SF (match_dup 7)))]
15295 "TARGET_USE_FANCY_MATH_387
15296 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15297 && flag_unsafe_math_optimizations"
15298 {
15299 int i;
15300
15301 for (i=2; i<8; i++)
15302 operands[i] = gen_reg_rtx (XFmode);
15303
15304 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15305 })
15306
15307 (define_expand "acosxf2"
15308 [(set (match_dup 2)
15309 (mult:XF (match_operand:XF 1 "register_operand" "")
15310 (match_dup 1)))
15311 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15312 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15313 (parallel [(set (match_operand:XF 0 "register_operand" "")
15314 (unspec:XF [(match_dup 1) (match_dup 5)]
15315 UNSPEC_FPATAN))
15316 (clobber (match_scratch:XF 6 ""))])]
15317 "TARGET_USE_FANCY_MATH_387
15318 && flag_unsafe_math_optimizations"
15319 {
15320 int i;
15321
15322 for (i=2; i<6; i++)
15323 operands[i] = gen_reg_rtx (XFmode);
15324
15325 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15326 })
15327
15328 (define_insn "fyl2x_xf3"
15329 [(set (match_operand:XF 0 "register_operand" "=f")
15330 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15331 (match_operand:XF 1 "register_operand" "u")]
15332 UNSPEC_FYL2X))
15333 (clobber (match_scratch:XF 3 "=1"))]
15334 "TARGET_USE_FANCY_MATH_387
15335 && flag_unsafe_math_optimizations"
15336 "fyl2x"
15337 [(set_attr "type" "fpspc")
15338 (set_attr "mode" "XF")])
15339
15340 (define_expand "logsf2"
15341 [(set (match_dup 2)
15342 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15343 (parallel [(set (match_dup 4)
15344 (unspec:XF [(match_dup 2)
15345 (match_dup 3)] UNSPEC_FYL2X))
15346 (clobber (match_scratch:XF 5 ""))])
15347 (set (match_operand:SF 0 "register_operand" "")
15348 (float_truncate:SF (match_dup 4)))]
15349 "TARGET_USE_FANCY_MATH_387
15350 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15351 && flag_unsafe_math_optimizations"
15352 {
15353 rtx temp;
15354
15355 operands[2] = gen_reg_rtx (XFmode);
15356 operands[3] = gen_reg_rtx (XFmode);
15357 operands[4] = gen_reg_rtx (XFmode);
15358
15359 temp = standard_80387_constant_rtx (4); /* fldln2 */
15360 emit_move_insn (operands[3], temp);
15361 })
15362
15363 (define_expand "logdf2"
15364 [(set (match_dup 2)
15365 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15366 (parallel [(set (match_dup 4)
15367 (unspec:XF [(match_dup 2)
15368 (match_dup 3)] UNSPEC_FYL2X))
15369 (clobber (match_scratch:XF 5 ""))])
15370 (set (match_operand:DF 0 "register_operand" "")
15371 (float_truncate:DF (match_dup 4)))]
15372 "TARGET_USE_FANCY_MATH_387
15373 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15374 && flag_unsafe_math_optimizations"
15375 {
15376 rtx temp;
15377
15378 operands[2] = gen_reg_rtx (XFmode);
15379 operands[3] = gen_reg_rtx (XFmode);
15380 operands[4] = gen_reg_rtx (XFmode);
15381
15382 temp = standard_80387_constant_rtx (4); /* fldln2 */
15383 emit_move_insn (operands[3], temp);
15384 })
15385
15386 (define_expand "logxf2"
15387 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15388 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15389 (match_dup 2)] UNSPEC_FYL2X))
15390 (clobber (match_scratch:XF 3 ""))])]
15391 "TARGET_USE_FANCY_MATH_387
15392 && flag_unsafe_math_optimizations"
15393 {
15394 rtx temp;
15395
15396 operands[2] = gen_reg_rtx (XFmode);
15397 temp = standard_80387_constant_rtx (4); /* fldln2 */
15398 emit_move_insn (operands[2], temp);
15399 })
15400
15401 (define_expand "log10sf2"
15402 [(set (match_dup 2)
15403 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15404 (parallel [(set (match_dup 4)
15405 (unspec:XF [(match_dup 2)
15406 (match_dup 3)] UNSPEC_FYL2X))
15407 (clobber (match_scratch:XF 5 ""))])
15408 (set (match_operand:SF 0 "register_operand" "")
15409 (float_truncate:SF (match_dup 4)))]
15410 "TARGET_USE_FANCY_MATH_387
15411 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15412 && flag_unsafe_math_optimizations"
15413 {
15414 rtx temp;
15415
15416 operands[2] = gen_reg_rtx (XFmode);
15417 operands[3] = gen_reg_rtx (XFmode);
15418 operands[4] = gen_reg_rtx (XFmode);
15419
15420 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15421 emit_move_insn (operands[3], temp);
15422 })
15423
15424 (define_expand "log10df2"
15425 [(set (match_dup 2)
15426 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15427 (parallel [(set (match_dup 4)
15428 (unspec:XF [(match_dup 2)
15429 (match_dup 3)] UNSPEC_FYL2X))
15430 (clobber (match_scratch:XF 5 ""))])
15431 (set (match_operand:DF 0 "register_operand" "")
15432 (float_truncate:DF (match_dup 4)))]
15433 "TARGET_USE_FANCY_MATH_387
15434 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15435 && flag_unsafe_math_optimizations"
15436 {
15437 rtx temp;
15438
15439 operands[2] = gen_reg_rtx (XFmode);
15440 operands[3] = gen_reg_rtx (XFmode);
15441 operands[4] = gen_reg_rtx (XFmode);
15442
15443 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15444 emit_move_insn (operands[3], temp);
15445 })
15446
15447 (define_expand "log10xf2"
15448 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15449 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15450 (match_dup 2)] UNSPEC_FYL2X))
15451 (clobber (match_scratch:XF 3 ""))])]
15452 "TARGET_USE_FANCY_MATH_387
15453 && flag_unsafe_math_optimizations"
15454 {
15455 rtx temp;
15456
15457 operands[2] = gen_reg_rtx (XFmode);
15458 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15459 emit_move_insn (operands[2], temp);
15460 })
15461
15462 (define_expand "log2sf2"
15463 [(set (match_dup 2)
15464 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15465 (parallel [(set (match_dup 4)
15466 (unspec:XF [(match_dup 2)
15467 (match_dup 3)] UNSPEC_FYL2X))
15468 (clobber (match_scratch:XF 5 ""))])
15469 (set (match_operand:SF 0 "register_operand" "")
15470 (float_truncate:SF (match_dup 4)))]
15471 "TARGET_USE_FANCY_MATH_387
15472 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15473 && flag_unsafe_math_optimizations"
15474 {
15475 operands[2] = gen_reg_rtx (XFmode);
15476 operands[3] = gen_reg_rtx (XFmode);
15477 operands[4] = gen_reg_rtx (XFmode);
15478
15479 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15480 })
15481
15482 (define_expand "log2df2"
15483 [(set (match_dup 2)
15484 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15485 (parallel [(set (match_dup 4)
15486 (unspec:XF [(match_dup 2)
15487 (match_dup 3)] UNSPEC_FYL2X))
15488 (clobber (match_scratch:XF 5 ""))])
15489 (set (match_operand:DF 0 "register_operand" "")
15490 (float_truncate:DF (match_dup 4)))]
15491 "TARGET_USE_FANCY_MATH_387
15492 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15493 && flag_unsafe_math_optimizations"
15494 {
15495 operands[2] = gen_reg_rtx (XFmode);
15496 operands[3] = gen_reg_rtx (XFmode);
15497 operands[4] = gen_reg_rtx (XFmode);
15498
15499 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15500 })
15501
15502 (define_expand "log2xf2"
15503 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15504 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15505 (match_dup 2)] UNSPEC_FYL2X))
15506 (clobber (match_scratch:XF 3 ""))])]
15507 "TARGET_USE_FANCY_MATH_387
15508 && flag_unsafe_math_optimizations"
15509 {
15510 operands[2] = gen_reg_rtx (XFmode);
15511 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15512 })
15513
15514 (define_insn "fyl2xp1_xf3"
15515 [(set (match_operand:XF 0 "register_operand" "=f")
15516 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15517 (match_operand:XF 1 "register_operand" "u")]
15518 UNSPEC_FYL2XP1))
15519 (clobber (match_scratch:XF 3 "=1"))]
15520 "TARGET_USE_FANCY_MATH_387
15521 && flag_unsafe_math_optimizations"
15522 "fyl2xp1"
15523 [(set_attr "type" "fpspc")
15524 (set_attr "mode" "XF")])
15525
15526 (define_expand "log1psf2"
15527 [(use (match_operand:SF 0 "register_operand" ""))
15528 (use (match_operand:SF 1 "register_operand" ""))]
15529 "TARGET_USE_FANCY_MATH_387
15530 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15531 && flag_unsafe_math_optimizations"
15532 {
15533 rtx op0 = gen_reg_rtx (XFmode);
15534 rtx op1 = gen_reg_rtx (XFmode);
15535
15536 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15537 ix86_emit_i387_log1p (op0, op1);
15538 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15539 DONE;
15540 })
15541
15542 (define_expand "log1pdf2"
15543 [(use (match_operand:DF 0 "register_operand" ""))
15544 (use (match_operand:DF 1 "register_operand" ""))]
15545 "TARGET_USE_FANCY_MATH_387
15546 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15547 && flag_unsafe_math_optimizations"
15548 {
15549 rtx op0 = gen_reg_rtx (XFmode);
15550 rtx op1 = gen_reg_rtx (XFmode);
15551
15552 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15553 ix86_emit_i387_log1p (op0, op1);
15554 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15555 DONE;
15556 })
15557
15558 (define_expand "log1pxf2"
15559 [(use (match_operand:XF 0 "register_operand" ""))
15560 (use (match_operand:XF 1 "register_operand" ""))]
15561 "TARGET_USE_FANCY_MATH_387
15562 && flag_unsafe_math_optimizations"
15563 {
15564 ix86_emit_i387_log1p (operands[0], operands[1]);
15565 DONE;
15566 })
15567
15568 (define_insn "*fxtractxf3"
15569 [(set (match_operand:XF 0 "register_operand" "=f")
15570 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15571 UNSPEC_XTRACT_FRACT))
15572 (set (match_operand:XF 1 "register_operand" "=u")
15573 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15574 "TARGET_USE_FANCY_MATH_387
15575 && flag_unsafe_math_optimizations"
15576 "fxtract"
15577 [(set_attr "type" "fpspc")
15578 (set_attr "mode" "XF")])
15579
15580 (define_expand "logbsf2"
15581 [(set (match_dup 2)
15582 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15583 (parallel [(set (match_dup 3)
15584 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15585 (set (match_dup 4)
15586 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15587 (set (match_operand:SF 0 "register_operand" "")
15588 (float_truncate:SF (match_dup 4)))]
15589 "TARGET_USE_FANCY_MATH_387
15590 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15591 && flag_unsafe_math_optimizations"
15592 {
15593 operands[2] = gen_reg_rtx (XFmode);
15594 operands[3] = gen_reg_rtx (XFmode);
15595 operands[4] = gen_reg_rtx (XFmode);
15596 })
15597
15598 (define_expand "logbdf2"
15599 [(set (match_dup 2)
15600 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15601 (parallel [(set (match_dup 3)
15602 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15603 (set (match_dup 4)
15604 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15605 (set (match_operand:DF 0 "register_operand" "")
15606 (float_truncate:DF (match_dup 4)))]
15607 "TARGET_USE_FANCY_MATH_387
15608 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15609 && flag_unsafe_math_optimizations"
15610 {
15611 operands[2] = gen_reg_rtx (XFmode);
15612 operands[3] = gen_reg_rtx (XFmode);
15613 operands[4] = gen_reg_rtx (XFmode);
15614 })
15615
15616 (define_expand "logbxf2"
15617 [(parallel [(set (match_dup 2)
15618 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15619 UNSPEC_XTRACT_FRACT))
15620 (set (match_operand:XF 0 "register_operand" "")
15621 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15622 "TARGET_USE_FANCY_MATH_387
15623 && flag_unsafe_math_optimizations"
15624 {
15625 operands[2] = gen_reg_rtx (XFmode);
15626 })
15627
15628 (define_expand "ilogbsi2"
15629 [(parallel [(set (match_dup 2)
15630 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15631 UNSPEC_XTRACT_FRACT))
15632 (set (match_operand:XF 3 "register_operand" "")
15633 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15634 (parallel [(set (match_operand:SI 0 "register_operand" "")
15635 (fix:SI (match_dup 3)))
15636 (clobber (reg:CC FLAGS_REG))])]
15637 "TARGET_USE_FANCY_MATH_387
15638 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15639 && flag_unsafe_math_optimizations"
15640 {
15641 operands[2] = gen_reg_rtx (XFmode);
15642 operands[3] = gen_reg_rtx (XFmode);
15643 })
15644
15645 (define_insn "*f2xm1xf2"
15646 [(set (match_operand:XF 0 "register_operand" "=f")
15647 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15648 UNSPEC_F2XM1))]
15649 "TARGET_USE_FANCY_MATH_387
15650 && flag_unsafe_math_optimizations"
15651 "f2xm1"
15652 [(set_attr "type" "fpspc")
15653 (set_attr "mode" "XF")])
15654
15655 (define_insn "*fscalexf4"
15656 [(set (match_operand:XF 0 "register_operand" "=f")
15657 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15658 (match_operand:XF 3 "register_operand" "1")]
15659 UNSPEC_FSCALE_FRACT))
15660 (set (match_operand:XF 1 "register_operand" "=u")
15661 (unspec:XF [(match_dup 2) (match_dup 3)]
15662 UNSPEC_FSCALE_EXP))]
15663 "TARGET_USE_FANCY_MATH_387
15664 && flag_unsafe_math_optimizations"
15665 "fscale"
15666 [(set_attr "type" "fpspc")
15667 (set_attr "mode" "XF")])
15668
15669 (define_expand "expsf2"
15670 [(set (match_dup 2)
15671 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15672 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15673 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15674 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15675 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15676 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15677 (parallel [(set (match_dup 10)
15678 (unspec:XF [(match_dup 9) (match_dup 5)]
15679 UNSPEC_FSCALE_FRACT))
15680 (set (match_dup 11)
15681 (unspec:XF [(match_dup 9) (match_dup 5)]
15682 UNSPEC_FSCALE_EXP))])
15683 (set (match_operand:SF 0 "register_operand" "")
15684 (float_truncate:SF (match_dup 10)))]
15685 "TARGET_USE_FANCY_MATH_387
15686 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15687 && flag_unsafe_math_optimizations"
15688 {
15689 rtx temp;
15690 int i;
15691
15692 for (i=2; i<12; i++)
15693 operands[i] = gen_reg_rtx (XFmode);
15694 temp = standard_80387_constant_rtx (5); /* fldl2e */
15695 emit_move_insn (operands[3], temp);
15696 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15697 })
15698
15699 (define_expand "expdf2"
15700 [(set (match_dup 2)
15701 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15702 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15703 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15704 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15705 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15706 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15707 (parallel [(set (match_dup 10)
15708 (unspec:XF [(match_dup 9) (match_dup 5)]
15709 UNSPEC_FSCALE_FRACT))
15710 (set (match_dup 11)
15711 (unspec:XF [(match_dup 9) (match_dup 5)]
15712 UNSPEC_FSCALE_EXP))])
15713 (set (match_operand:DF 0 "register_operand" "")
15714 (float_truncate:DF (match_dup 10)))]
15715 "TARGET_USE_FANCY_MATH_387
15716 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15717 && flag_unsafe_math_optimizations"
15718 {
15719 rtx temp;
15720 int i;
15721
15722 for (i=2; i<12; i++)
15723 operands[i] = gen_reg_rtx (XFmode);
15724 temp = standard_80387_constant_rtx (5); /* fldl2e */
15725 emit_move_insn (operands[3], temp);
15726 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15727 })
15728
15729 (define_expand "expxf2"
15730 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15731 (match_dup 2)))
15732 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15733 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15734 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15735 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15736 (parallel [(set (match_operand:XF 0 "register_operand" "")
15737 (unspec:XF [(match_dup 8) (match_dup 4)]
15738 UNSPEC_FSCALE_FRACT))
15739 (set (match_dup 9)
15740 (unspec:XF [(match_dup 8) (match_dup 4)]
15741 UNSPEC_FSCALE_EXP))])]
15742 "TARGET_USE_FANCY_MATH_387
15743 && flag_unsafe_math_optimizations"
15744 {
15745 rtx temp;
15746 int i;
15747
15748 for (i=2; i<10; i++)
15749 operands[i] = gen_reg_rtx (XFmode);
15750 temp = standard_80387_constant_rtx (5); /* fldl2e */
15751 emit_move_insn (operands[2], temp);
15752 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15753 })
15754
15755 (define_expand "exp10sf2"
15756 [(set (match_dup 2)
15757 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15758 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15759 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15760 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15761 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15762 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15763 (parallel [(set (match_dup 10)
15764 (unspec:XF [(match_dup 9) (match_dup 5)]
15765 UNSPEC_FSCALE_FRACT))
15766 (set (match_dup 11)
15767 (unspec:XF [(match_dup 9) (match_dup 5)]
15768 UNSPEC_FSCALE_EXP))])
15769 (set (match_operand:SF 0 "register_operand" "")
15770 (float_truncate:SF (match_dup 10)))]
15771 "TARGET_USE_FANCY_MATH_387
15772 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15773 && flag_unsafe_math_optimizations"
15774 {
15775 rtx temp;
15776 int i;
15777
15778 for (i=2; i<12; i++)
15779 operands[i] = gen_reg_rtx (XFmode);
15780 temp = standard_80387_constant_rtx (6); /* fldl2t */
15781 emit_move_insn (operands[3], temp);
15782 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15783 })
15784
15785 (define_expand "exp10df2"
15786 [(set (match_dup 2)
15787 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15788 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15789 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15790 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15791 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15792 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15793 (parallel [(set (match_dup 10)
15794 (unspec:XF [(match_dup 9) (match_dup 5)]
15795 UNSPEC_FSCALE_FRACT))
15796 (set (match_dup 11)
15797 (unspec:XF [(match_dup 9) (match_dup 5)]
15798 UNSPEC_FSCALE_EXP))])
15799 (set (match_operand:DF 0 "register_operand" "")
15800 (float_truncate:DF (match_dup 10)))]
15801 "TARGET_USE_FANCY_MATH_387
15802 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15803 && flag_unsafe_math_optimizations"
15804 {
15805 rtx temp;
15806 int i;
15807
15808 for (i=2; i<12; i++)
15809 operands[i] = gen_reg_rtx (XFmode);
15810 temp = standard_80387_constant_rtx (6); /* fldl2t */
15811 emit_move_insn (operands[3], temp);
15812 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15813 })
15814
15815 (define_expand "exp10xf2"
15816 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15817 (match_dup 2)))
15818 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15819 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15820 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15821 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15822 (parallel [(set (match_operand:XF 0 "register_operand" "")
15823 (unspec:XF [(match_dup 8) (match_dup 4)]
15824 UNSPEC_FSCALE_FRACT))
15825 (set (match_dup 9)
15826 (unspec:XF [(match_dup 8) (match_dup 4)]
15827 UNSPEC_FSCALE_EXP))])]
15828 "TARGET_USE_FANCY_MATH_387
15829 && flag_unsafe_math_optimizations"
15830 {
15831 rtx temp;
15832 int i;
15833
15834 for (i=2; i<10; i++)
15835 operands[i] = gen_reg_rtx (XFmode);
15836 temp = standard_80387_constant_rtx (6); /* fldl2t */
15837 emit_move_insn (operands[2], temp);
15838 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15839 })
15840
15841 (define_expand "exp2sf2"
15842 [(set (match_dup 2)
15843 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15844 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15845 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15846 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15847 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15848 (parallel [(set (match_dup 8)
15849 (unspec:XF [(match_dup 7) (match_dup 3)]
15850 UNSPEC_FSCALE_FRACT))
15851 (set (match_dup 9)
15852 (unspec:XF [(match_dup 7) (match_dup 3)]
15853 UNSPEC_FSCALE_EXP))])
15854 (set (match_operand:SF 0 "register_operand" "")
15855 (float_truncate:SF (match_dup 8)))]
15856 "TARGET_USE_FANCY_MATH_387
15857 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15858 && flag_unsafe_math_optimizations"
15859 {
15860 int i;
15861
15862 for (i=2; i<10; i++)
15863 operands[i] = gen_reg_rtx (XFmode);
15864 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15865 })
15866
15867 (define_expand "exp2df2"
15868 [(set (match_dup 2)
15869 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15870 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15871 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15872 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15873 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15874 (parallel [(set (match_dup 8)
15875 (unspec:XF [(match_dup 7) (match_dup 3)]
15876 UNSPEC_FSCALE_FRACT))
15877 (set (match_dup 9)
15878 (unspec:XF [(match_dup 7) (match_dup 3)]
15879 UNSPEC_FSCALE_EXP))])
15880 (set (match_operand:DF 0 "register_operand" "")
15881 (float_truncate:DF (match_dup 8)))]
15882 "TARGET_USE_FANCY_MATH_387
15883 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15884 && flag_unsafe_math_optimizations"
15885 {
15886 int i;
15887
15888 for (i=2; i<10; i++)
15889 operands[i] = gen_reg_rtx (XFmode);
15890 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15891 })
15892
15893 (define_expand "exp2xf2"
15894 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15895 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15896 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15897 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15898 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15899 (parallel [(set (match_operand:XF 0 "register_operand" "")
15900 (unspec:XF [(match_dup 7) (match_dup 3)]
15901 UNSPEC_FSCALE_FRACT))
15902 (set (match_dup 8)
15903 (unspec:XF [(match_dup 7) (match_dup 3)]
15904 UNSPEC_FSCALE_EXP))])]
15905 "TARGET_USE_FANCY_MATH_387
15906 && flag_unsafe_math_optimizations"
15907 {
15908 int i;
15909
15910 for (i=2; i<9; i++)
15911 operands[i] = gen_reg_rtx (XFmode);
15912 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15913 })
15914
15915 (define_expand "expm1df2"
15916 [(set (match_dup 2)
15917 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15918 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15919 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15920 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15921 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15922 (parallel [(set (match_dup 8)
15923 (unspec:XF [(match_dup 7) (match_dup 5)]
15924 UNSPEC_FSCALE_FRACT))
15925 (set (match_dup 9)
15926 (unspec:XF [(match_dup 7) (match_dup 5)]
15927 UNSPEC_FSCALE_EXP))])
15928 (parallel [(set (match_dup 11)
15929 (unspec:XF [(match_dup 10) (match_dup 9)]
15930 UNSPEC_FSCALE_FRACT))
15931 (set (match_dup 12)
15932 (unspec:XF [(match_dup 10) (match_dup 9)]
15933 UNSPEC_FSCALE_EXP))])
15934 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15935 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15936 (set (match_operand:DF 0 "register_operand" "")
15937 (float_truncate:DF (match_dup 14)))]
15938 "TARGET_USE_FANCY_MATH_387
15939 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15940 && flag_unsafe_math_optimizations"
15941 {
15942 rtx temp;
15943 int i;
15944
15945 for (i=2; i<15; i++)
15946 operands[i] = gen_reg_rtx (XFmode);
15947 temp = standard_80387_constant_rtx (5); /* fldl2e */
15948 emit_move_insn (operands[3], temp);
15949 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
15950 })
15951
15952 (define_expand "expm1sf2"
15953 [(set (match_dup 2)
15954 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15955 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15956 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15957 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15958 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15959 (parallel [(set (match_dup 8)
15960 (unspec:XF [(match_dup 7) (match_dup 5)]
15961 UNSPEC_FSCALE_FRACT))
15962 (set (match_dup 9)
15963 (unspec:XF [(match_dup 7) (match_dup 5)]
15964 UNSPEC_FSCALE_EXP))])
15965 (parallel [(set (match_dup 11)
15966 (unspec:XF [(match_dup 10) (match_dup 9)]
15967 UNSPEC_FSCALE_FRACT))
15968 (set (match_dup 12)
15969 (unspec:XF [(match_dup 10) (match_dup 9)]
15970 UNSPEC_FSCALE_EXP))])
15971 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15972 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15973 (set (match_operand:SF 0 "register_operand" "")
15974 (float_truncate:SF (match_dup 14)))]
15975 "TARGET_USE_FANCY_MATH_387
15976 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15977 && flag_unsafe_math_optimizations"
15978 {
15979 rtx temp;
15980 int i;
15981
15982 for (i=2; i<15; i++)
15983 operands[i] = gen_reg_rtx (XFmode);
15984 temp = standard_80387_constant_rtx (5); /* fldl2e */
15985 emit_move_insn (operands[3], temp);
15986 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
15987 })
15988
15989 (define_expand "expm1xf2"
15990 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15991 (match_dup 2)))
15992 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15993 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15994 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15995 (parallel [(set (match_dup 7)
15996 (unspec:XF [(match_dup 6) (match_dup 4)]
15997 UNSPEC_FSCALE_FRACT))
15998 (set (match_dup 8)
15999 (unspec:XF [(match_dup 6) (match_dup 4)]
16000 UNSPEC_FSCALE_EXP))])
16001 (parallel [(set (match_dup 10)
16002 (unspec:XF [(match_dup 9) (match_dup 8)]
16003 UNSPEC_FSCALE_FRACT))
16004 (set (match_dup 11)
16005 (unspec:XF [(match_dup 9) (match_dup 8)]
16006 UNSPEC_FSCALE_EXP))])
16007 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16008 (set (match_operand:XF 0 "register_operand" "")
16009 (plus:XF (match_dup 12) (match_dup 7)))]
16010 "TARGET_USE_FANCY_MATH_387
16011 && flag_unsafe_math_optimizations"
16012 {
16013 rtx temp;
16014 int i;
16015
16016 for (i=2; i<13; i++)
16017 operands[i] = gen_reg_rtx (XFmode);
16018 temp = standard_80387_constant_rtx (5); /* fldl2e */
16019 emit_move_insn (operands[2], temp);
16020 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16021 })
16022
16023 (define_expand "ldexpdf3"
16024 [(set (match_dup 3)
16025 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16026 (set (match_dup 4)
16027 (float:XF (match_operand:SI 2 "register_operand" "")))
16028 (parallel [(set (match_dup 5)
16029 (unspec:XF [(match_dup 3) (match_dup 4)]
16030 UNSPEC_FSCALE_FRACT))
16031 (set (match_dup 6)
16032 (unspec:XF [(match_dup 3) (match_dup 4)]
16033 UNSPEC_FSCALE_EXP))])
16034 (set (match_operand:DF 0 "register_operand" "")
16035 (float_truncate:DF (match_dup 5)))]
16036 "TARGET_USE_FANCY_MATH_387
16037 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16038 && flag_unsafe_math_optimizations"
16039 {
16040 int i;
16041
16042 for (i=3; i<7; i++)
16043 operands[i] = gen_reg_rtx (XFmode);
16044 })
16045
16046 (define_expand "ldexpsf3"
16047 [(set (match_dup 3)
16048 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16049 (set (match_dup 4)
16050 (float:XF (match_operand:SI 2 "register_operand" "")))
16051 (parallel [(set (match_dup 5)
16052 (unspec:XF [(match_dup 3) (match_dup 4)]
16053 UNSPEC_FSCALE_FRACT))
16054 (set (match_dup 6)
16055 (unspec:XF [(match_dup 3) (match_dup 4)]
16056 UNSPEC_FSCALE_EXP))])
16057 (set (match_operand:SF 0 "register_operand" "")
16058 (float_truncate:SF (match_dup 5)))]
16059 "TARGET_USE_FANCY_MATH_387
16060 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16061 && flag_unsafe_math_optimizations"
16062 {
16063 int i;
16064
16065 for (i=3; i<7; i++)
16066 operands[i] = gen_reg_rtx (XFmode);
16067 })
16068
16069 (define_expand "ldexpxf3"
16070 [(set (match_dup 3)
16071 (float:XF (match_operand:SI 2 "register_operand" "")))
16072 (parallel [(set (match_operand:XF 0 " register_operand" "")
16073 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16074 (match_dup 3)]
16075 UNSPEC_FSCALE_FRACT))
16076 (set (match_dup 4)
16077 (unspec:XF [(match_dup 1) (match_dup 3)]
16078 UNSPEC_FSCALE_EXP))])]
16079 "TARGET_USE_FANCY_MATH_387
16080 && flag_unsafe_math_optimizations"
16081 {
16082 int i;
16083
16084 for (i=3; i<5; i++)
16085 operands[i] = gen_reg_rtx (XFmode);
16086 })
16087 \f
16088
16089 (define_insn "frndintxf2"
16090 [(set (match_operand:XF 0 "register_operand" "=f")
16091 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16092 UNSPEC_FRNDINT))]
16093 "TARGET_USE_FANCY_MATH_387
16094 && flag_unsafe_math_optimizations"
16095 "frndint"
16096 [(set_attr "type" "fpspc")
16097 (set_attr "mode" "XF")])
16098
16099 (define_expand "rintdf2"
16100 [(use (match_operand:DF 0 "register_operand" ""))
16101 (use (match_operand:DF 1 "register_operand" ""))]
16102 "TARGET_USE_FANCY_MATH_387
16103 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16104 && flag_unsafe_math_optimizations"
16105 {
16106 rtx op0 = gen_reg_rtx (XFmode);
16107 rtx op1 = gen_reg_rtx (XFmode);
16108
16109 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16110 emit_insn (gen_frndintxf2 (op0, op1));
16111
16112 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16113 DONE;
16114 })
16115
16116 (define_expand "rintsf2"
16117 [(use (match_operand:SF 0 "register_operand" ""))
16118 (use (match_operand:SF 1 "register_operand" ""))]
16119 "TARGET_USE_FANCY_MATH_387
16120 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16121 && flag_unsafe_math_optimizations"
16122 {
16123 rtx op0 = gen_reg_rtx (XFmode);
16124 rtx op1 = gen_reg_rtx (XFmode);
16125
16126 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16127 emit_insn (gen_frndintxf2 (op0, op1));
16128
16129 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16130 DONE;
16131 })
16132
16133 (define_expand "rintxf2"
16134 [(use (match_operand:XF 0 "register_operand" ""))
16135 (use (match_operand:XF 1 "register_operand" ""))]
16136 "TARGET_USE_FANCY_MATH_387
16137 && flag_unsafe_math_optimizations"
16138 {
16139 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16140 DONE;
16141 })
16142
16143 (define_insn "fistdi2"
16144 [(set (match_operand:DI 0 "memory_operand" "=m")
16145 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16146 UNSPEC_FIST))
16147 (clobber (match_scratch:XF 2 "=&1f"))]
16148 "TARGET_USE_FANCY_MATH_387
16149 && flag_unsafe_math_optimizations"
16150 "* return output_fix_trunc (insn, operands, 0);"
16151 [(set_attr "type" "fpspc")
16152 (set_attr "mode" "DI")])
16153
16154 (define_insn "fistdi2_with_temp"
16155 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16156 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16157 UNSPEC_FIST))
16158 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16159 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16160 "TARGET_USE_FANCY_MATH_387
16161 && flag_unsafe_math_optimizations"
16162 "#"
16163 [(set_attr "type" "fpspc")
16164 (set_attr "mode" "DI")])
16165
16166 (define_split
16167 [(set (match_operand:DI 0 "register_operand" "")
16168 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16169 UNSPEC_FIST))
16170 (clobber (match_operand:DI 2 "memory_operand" ""))
16171 (clobber (match_scratch 3 ""))]
16172 "reload_completed"
16173 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16174 (clobber (match_dup 3))])
16175 (set (match_dup 0) (match_dup 2))]
16176 "")
16177
16178 (define_split
16179 [(set (match_operand:DI 0 "memory_operand" "")
16180 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16181 UNSPEC_FIST))
16182 (clobber (match_operand:DI 2 "memory_operand" ""))
16183 (clobber (match_scratch 3 ""))]
16184 "reload_completed"
16185 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16186 (clobber (match_dup 3))])]
16187 "")
16188
16189 (define_insn "fist<mode>2"
16190 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16191 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16192 UNSPEC_FIST))]
16193 "TARGET_USE_FANCY_MATH_387
16194 && flag_unsafe_math_optimizations"
16195 "* return output_fix_trunc (insn, operands, 0);"
16196 [(set_attr "type" "fpspc")
16197 (set_attr "mode" "<MODE>")])
16198
16199 (define_insn "fist<mode>2_with_temp"
16200 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16201 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16202 UNSPEC_FIST))
16203 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16204 "TARGET_USE_FANCY_MATH_387
16205 && flag_unsafe_math_optimizations"
16206 "#"
16207 [(set_attr "type" "fpspc")
16208 (set_attr "mode" "<MODE>")])
16209
16210 (define_split
16211 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16212 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16213 UNSPEC_FIST))
16214 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16215 "reload_completed"
16216 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16217 UNSPEC_FIST))
16218 (set (match_dup 0) (match_dup 2))]
16219 "")
16220
16221 (define_split
16222 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16223 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16224 UNSPEC_FIST))
16225 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16226 "reload_completed"
16227 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16228 UNSPEC_FIST))]
16229 "")
16230
16231 (define_expand "lrint<mode>2"
16232 [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
16233 (use (match_operand:XF 1 "register_operand" ""))]
16234 "TARGET_USE_FANCY_MATH_387
16235 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16236 && flag_unsafe_math_optimizations"
16237 {
16238 if (memory_operand (operands[0], VOIDmode))
16239 emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16240 else
16241 {
16242 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16243 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16244 operands[2]));
16245 }
16246 DONE;
16247 })
16248
16249 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16250 (define_insn_and_split "frndintxf2_floor"
16251 [(set (match_operand:XF 0 "register_operand" "=f")
16252 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16253 UNSPEC_FRNDINT_FLOOR))
16254 (clobber (reg:CC FLAGS_REG))]
16255 "TARGET_USE_FANCY_MATH_387
16256 && flag_unsafe_math_optimizations
16257 && !(reload_completed || reload_in_progress)"
16258 "#"
16259 "&& 1"
16260 [(const_int 0)]
16261 {
16262 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16263
16264 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16265 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16266
16267 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16268 operands[2], operands[3]));
16269 DONE;
16270 }
16271 [(set_attr "type" "frndint")
16272 (set_attr "i387_cw" "floor")
16273 (set_attr "mode" "XF")])
16274
16275 (define_insn "frndintxf2_floor_i387"
16276 [(set (match_operand:XF 0 "register_operand" "=f")
16277 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16278 UNSPEC_FRNDINT_FLOOR))
16279 (use (match_operand:HI 2 "memory_operand" "m"))
16280 (use (match_operand:HI 3 "memory_operand" "m"))]
16281 "TARGET_USE_FANCY_MATH_387
16282 && flag_unsafe_math_optimizations"
16283 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16284 [(set_attr "type" "frndint")
16285 (set_attr "i387_cw" "floor")
16286 (set_attr "mode" "XF")])
16287
16288 (define_expand "floorxf2"
16289 [(use (match_operand:XF 0 "register_operand" ""))
16290 (use (match_operand:XF 1 "register_operand" ""))]
16291 "TARGET_USE_FANCY_MATH_387
16292 && flag_unsafe_math_optimizations"
16293 {
16294 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16295 DONE;
16296 })
16297
16298 (define_expand "floordf2"
16299 [(use (match_operand:DF 0 "register_operand" ""))
16300 (use (match_operand:DF 1 "register_operand" ""))]
16301 "TARGET_USE_FANCY_MATH_387
16302 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16303 && flag_unsafe_math_optimizations"
16304 {
16305 rtx op0 = gen_reg_rtx (XFmode);
16306 rtx op1 = gen_reg_rtx (XFmode);
16307
16308 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16309 emit_insn (gen_frndintxf2_floor (op0, op1));
16310
16311 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16312 DONE;
16313 })
16314
16315 (define_expand "floorsf2"
16316 [(use (match_operand:SF 0 "register_operand" ""))
16317 (use (match_operand:SF 1 "register_operand" ""))]
16318 "TARGET_USE_FANCY_MATH_387
16319 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16320 && flag_unsafe_math_optimizations"
16321 {
16322 rtx op0 = gen_reg_rtx (XFmode);
16323 rtx op1 = gen_reg_rtx (XFmode);
16324
16325 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16326 emit_insn (gen_frndintxf2_floor (op0, op1));
16327
16328 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16329 DONE;
16330 })
16331
16332 (define_insn_and_split "*fist<mode>2_floor_1"
16333 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16334 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16335 UNSPEC_FIST_FLOOR))
16336 (clobber (reg:CC FLAGS_REG))]
16337 "TARGET_USE_FANCY_MATH_387
16338 && flag_unsafe_math_optimizations
16339 && !(reload_completed || reload_in_progress)"
16340 "#"
16341 "&& 1"
16342 [(const_int 0)]
16343 {
16344 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16345
16346 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16347 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16348 if (memory_operand (operands[0], VOIDmode))
16349 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16350 operands[2], operands[3]));
16351 else
16352 {
16353 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16354 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16355 operands[2], operands[3],
16356 operands[4]));
16357 }
16358 DONE;
16359 }
16360 [(set_attr "type" "fistp")
16361 (set_attr "i387_cw" "floor")
16362 (set_attr "mode" "<MODE>")])
16363
16364 (define_insn "fistdi2_floor"
16365 [(set (match_operand:DI 0 "memory_operand" "=m")
16366 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16367 UNSPEC_FIST_FLOOR))
16368 (use (match_operand:HI 2 "memory_operand" "m"))
16369 (use (match_operand:HI 3 "memory_operand" "m"))
16370 (clobber (match_scratch:XF 4 "=&1f"))]
16371 "TARGET_USE_FANCY_MATH_387
16372 && flag_unsafe_math_optimizations"
16373 "* return output_fix_trunc (insn, operands, 0);"
16374 [(set_attr "type" "fistp")
16375 (set_attr "i387_cw" "floor")
16376 (set_attr "mode" "DI")])
16377
16378 (define_insn "fistdi2_floor_with_temp"
16379 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16380 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16381 UNSPEC_FIST_FLOOR))
16382 (use (match_operand:HI 2 "memory_operand" "m,m"))
16383 (use (match_operand:HI 3 "memory_operand" "m,m"))
16384 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16385 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16386 "TARGET_USE_FANCY_MATH_387
16387 && flag_unsafe_math_optimizations"
16388 "#"
16389 [(set_attr "type" "fistp")
16390 (set_attr "i387_cw" "floor")
16391 (set_attr "mode" "DI")])
16392
16393 (define_split
16394 [(set (match_operand:DI 0 "register_operand" "")
16395 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16396 UNSPEC_FIST_FLOOR))
16397 (use (match_operand:HI 2 "memory_operand" ""))
16398 (use (match_operand:HI 3 "memory_operand" ""))
16399 (clobber (match_operand:DI 4 "memory_operand" ""))
16400 (clobber (match_scratch 5 ""))]
16401 "reload_completed"
16402 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16403 (use (match_dup 2))
16404 (use (match_dup 3))
16405 (clobber (match_dup 5))])
16406 (set (match_dup 0) (match_dup 4))]
16407 "")
16408
16409 (define_split
16410 [(set (match_operand:DI 0 "memory_operand" "")
16411 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16412 UNSPEC_FIST_FLOOR))
16413 (use (match_operand:HI 2 "memory_operand" ""))
16414 (use (match_operand:HI 3 "memory_operand" ""))
16415 (clobber (match_operand:DI 4 "memory_operand" ""))
16416 (clobber (match_scratch 5 ""))]
16417 "reload_completed"
16418 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16419 (use (match_dup 2))
16420 (use (match_dup 3))
16421 (clobber (match_dup 5))])]
16422 "")
16423
16424 (define_insn "fist<mode>2_floor"
16425 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16426 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16427 UNSPEC_FIST_FLOOR))
16428 (use (match_operand:HI 2 "memory_operand" "m"))
16429 (use (match_operand:HI 3 "memory_operand" "m"))]
16430 "TARGET_USE_FANCY_MATH_387
16431 && flag_unsafe_math_optimizations"
16432 "* return output_fix_trunc (insn, operands, 0);"
16433 [(set_attr "type" "fistp")
16434 (set_attr "i387_cw" "floor")
16435 (set_attr "mode" "<MODE>")])
16436
16437 (define_insn "fist<mode>2_floor_with_temp"
16438 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16439 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16440 UNSPEC_FIST_FLOOR))
16441 (use (match_operand:HI 2 "memory_operand" "m,m"))
16442 (use (match_operand:HI 3 "memory_operand" "m,m"))
16443 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16444 "TARGET_USE_FANCY_MATH_387
16445 && flag_unsafe_math_optimizations"
16446 "#"
16447 [(set_attr "type" "fistp")
16448 (set_attr "i387_cw" "floor")
16449 (set_attr "mode" "<MODE>")])
16450
16451 (define_split
16452 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16453 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16454 UNSPEC_FIST_FLOOR))
16455 (use (match_operand:HI 2 "memory_operand" ""))
16456 (use (match_operand:HI 3 "memory_operand" ""))
16457 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16458 "reload_completed"
16459 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16460 UNSPEC_FIST_FLOOR))
16461 (use (match_dup 2))
16462 (use (match_dup 3))])
16463 (set (match_dup 0) (match_dup 4))]
16464 "")
16465
16466 (define_split
16467 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16468 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16469 UNSPEC_FIST_FLOOR))
16470 (use (match_operand:HI 2 "memory_operand" ""))
16471 (use (match_operand:HI 3 "memory_operand" ""))
16472 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16473 "reload_completed"
16474 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16475 UNSPEC_FIST_FLOOR))
16476 (use (match_dup 2))
16477 (use (match_dup 3))])]
16478 "")
16479
16480 (define_expand "lfloor<mode>2"
16481 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16482 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16483 UNSPEC_FIST_FLOOR))
16484 (clobber (reg:CC FLAGS_REG))])]
16485 "TARGET_USE_FANCY_MATH_387
16486 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16487 && flag_unsafe_math_optimizations"
16488 "")
16489
16490 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16491 (define_insn_and_split "frndintxf2_ceil"
16492 [(set (match_operand:XF 0 "register_operand" "=f")
16493 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16494 UNSPEC_FRNDINT_CEIL))
16495 (clobber (reg:CC FLAGS_REG))]
16496 "TARGET_USE_FANCY_MATH_387
16497 && flag_unsafe_math_optimizations
16498 && !(reload_completed || reload_in_progress)"
16499 "#"
16500 "&& 1"
16501 [(const_int 0)]
16502 {
16503 ix86_optimize_mode_switching[I387_CEIL] = 1;
16504
16505 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16506 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16507
16508 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16509 operands[2], operands[3]));
16510 DONE;
16511 }
16512 [(set_attr "type" "frndint")
16513 (set_attr "i387_cw" "ceil")
16514 (set_attr "mode" "XF")])
16515
16516 (define_insn "frndintxf2_ceil_i387"
16517 [(set (match_operand:XF 0 "register_operand" "=f")
16518 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16519 UNSPEC_FRNDINT_CEIL))
16520 (use (match_operand:HI 2 "memory_operand" "m"))
16521 (use (match_operand:HI 3 "memory_operand" "m"))]
16522 "TARGET_USE_FANCY_MATH_387
16523 && flag_unsafe_math_optimizations"
16524 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16525 [(set_attr "type" "frndint")
16526 (set_attr "i387_cw" "ceil")
16527 (set_attr "mode" "XF")])
16528
16529 (define_expand "ceilxf2"
16530 [(use (match_operand:XF 0 "register_operand" ""))
16531 (use (match_operand:XF 1 "register_operand" ""))]
16532 "TARGET_USE_FANCY_MATH_387
16533 && flag_unsafe_math_optimizations"
16534 {
16535 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16536 DONE;
16537 })
16538
16539 (define_expand "ceildf2"
16540 [(use (match_operand:DF 0 "register_operand" ""))
16541 (use (match_operand:DF 1 "register_operand" ""))]
16542 "TARGET_USE_FANCY_MATH_387
16543 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16544 && flag_unsafe_math_optimizations"
16545 {
16546 rtx op0 = gen_reg_rtx (XFmode);
16547 rtx op1 = gen_reg_rtx (XFmode);
16548
16549 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16550 emit_insn (gen_frndintxf2_ceil (op0, op1));
16551
16552 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16553 DONE;
16554 })
16555
16556 (define_expand "ceilsf2"
16557 [(use (match_operand:SF 0 "register_operand" ""))
16558 (use (match_operand:SF 1 "register_operand" ""))]
16559 "TARGET_USE_FANCY_MATH_387
16560 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16561 && flag_unsafe_math_optimizations"
16562 {
16563 rtx op0 = gen_reg_rtx (XFmode);
16564 rtx op1 = gen_reg_rtx (XFmode);
16565
16566 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16567 emit_insn (gen_frndintxf2_ceil (op0, op1));
16568
16569 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16570 DONE;
16571 })
16572
16573 (define_insn_and_split "*fist<mode>2_ceil_1"
16574 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16575 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16576 UNSPEC_FIST_CEIL))
16577 (clobber (reg:CC FLAGS_REG))]
16578 "TARGET_USE_FANCY_MATH_387
16579 && flag_unsafe_math_optimizations
16580 && !(reload_completed || reload_in_progress)"
16581 "#"
16582 "&& 1"
16583 [(const_int 0)]
16584 {
16585 ix86_optimize_mode_switching[I387_CEIL] = 1;
16586
16587 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16588 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16589 if (memory_operand (operands[0], VOIDmode))
16590 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16591 operands[2], operands[3]));
16592 else
16593 {
16594 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16595 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16596 operands[2], operands[3],
16597 operands[4]));
16598 }
16599 DONE;
16600 }
16601 [(set_attr "type" "fistp")
16602 (set_attr "i387_cw" "ceil")
16603 (set_attr "mode" "<MODE>")])
16604
16605 (define_insn "fistdi2_ceil"
16606 [(set (match_operand:DI 0 "memory_operand" "=m")
16607 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16608 UNSPEC_FIST_CEIL))
16609 (use (match_operand:HI 2 "memory_operand" "m"))
16610 (use (match_operand:HI 3 "memory_operand" "m"))
16611 (clobber (match_scratch:XF 4 "=&1f"))]
16612 "TARGET_USE_FANCY_MATH_387
16613 && flag_unsafe_math_optimizations"
16614 "* return output_fix_trunc (insn, operands, 0);"
16615 [(set_attr "type" "fistp")
16616 (set_attr "i387_cw" "ceil")
16617 (set_attr "mode" "DI")])
16618
16619 (define_insn "fistdi2_ceil_with_temp"
16620 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16621 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16622 UNSPEC_FIST_CEIL))
16623 (use (match_operand:HI 2 "memory_operand" "m,m"))
16624 (use (match_operand:HI 3 "memory_operand" "m,m"))
16625 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16626 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16627 "TARGET_USE_FANCY_MATH_387
16628 && flag_unsafe_math_optimizations"
16629 "#"
16630 [(set_attr "type" "fistp")
16631 (set_attr "i387_cw" "ceil")
16632 (set_attr "mode" "DI")])
16633
16634 (define_split
16635 [(set (match_operand:DI 0 "register_operand" "")
16636 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16637 UNSPEC_FIST_CEIL))
16638 (use (match_operand:HI 2 "memory_operand" ""))
16639 (use (match_operand:HI 3 "memory_operand" ""))
16640 (clobber (match_operand:DI 4 "memory_operand" ""))
16641 (clobber (match_scratch 5 ""))]
16642 "reload_completed"
16643 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16644 (use (match_dup 2))
16645 (use (match_dup 3))
16646 (clobber (match_dup 5))])
16647 (set (match_dup 0) (match_dup 4))]
16648 "")
16649
16650 (define_split
16651 [(set (match_operand:DI 0 "memory_operand" "")
16652 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16653 UNSPEC_FIST_CEIL))
16654 (use (match_operand:HI 2 "memory_operand" ""))
16655 (use (match_operand:HI 3 "memory_operand" ""))
16656 (clobber (match_operand:DI 4 "memory_operand" ""))
16657 (clobber (match_scratch 5 ""))]
16658 "reload_completed"
16659 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16660 (use (match_dup 2))
16661 (use (match_dup 3))
16662 (clobber (match_dup 5))])]
16663 "")
16664
16665 (define_insn "fist<mode>2_ceil"
16666 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16667 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16668 UNSPEC_FIST_CEIL))
16669 (use (match_operand:HI 2 "memory_operand" "m"))
16670 (use (match_operand:HI 3 "memory_operand" "m"))]
16671 "TARGET_USE_FANCY_MATH_387
16672 && flag_unsafe_math_optimizations"
16673 "* return output_fix_trunc (insn, operands, 0);"
16674 [(set_attr "type" "fistp")
16675 (set_attr "i387_cw" "ceil")
16676 (set_attr "mode" "<MODE>")])
16677
16678 (define_insn "fist<mode>2_ceil_with_temp"
16679 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16680 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16681 UNSPEC_FIST_CEIL))
16682 (use (match_operand:HI 2 "memory_operand" "m,m"))
16683 (use (match_operand:HI 3 "memory_operand" "m,m"))
16684 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16685 "TARGET_USE_FANCY_MATH_387
16686 && flag_unsafe_math_optimizations"
16687 "#"
16688 [(set_attr "type" "fistp")
16689 (set_attr "i387_cw" "ceil")
16690 (set_attr "mode" "<MODE>")])
16691
16692 (define_split
16693 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16694 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16695 UNSPEC_FIST_CEIL))
16696 (use (match_operand:HI 2 "memory_operand" ""))
16697 (use (match_operand:HI 3 "memory_operand" ""))
16698 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16699 "reload_completed"
16700 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16701 UNSPEC_FIST_CEIL))
16702 (use (match_dup 2))
16703 (use (match_dup 3))])
16704 (set (match_dup 0) (match_dup 4))]
16705 "")
16706
16707 (define_split
16708 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16709 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16710 UNSPEC_FIST_CEIL))
16711 (use (match_operand:HI 2 "memory_operand" ""))
16712 (use (match_operand:HI 3 "memory_operand" ""))
16713 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16714 "reload_completed"
16715 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16716 UNSPEC_FIST_CEIL))
16717 (use (match_dup 2))
16718 (use (match_dup 3))])]
16719 "")
16720
16721 (define_expand "lceil<mode>2"
16722 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16723 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16724 UNSPEC_FIST_CEIL))
16725 (clobber (reg:CC FLAGS_REG))])]
16726 "TARGET_USE_FANCY_MATH_387
16727 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16728 && flag_unsafe_math_optimizations"
16729 "")
16730
16731 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16732 (define_insn_and_split "frndintxf2_trunc"
16733 [(set (match_operand:XF 0 "register_operand" "=f")
16734 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16735 UNSPEC_FRNDINT_TRUNC))
16736 (clobber (reg:CC FLAGS_REG))]
16737 "TARGET_USE_FANCY_MATH_387
16738 && flag_unsafe_math_optimizations
16739 && !(reload_completed || reload_in_progress)"
16740 "#"
16741 "&& 1"
16742 [(const_int 0)]
16743 {
16744 ix86_optimize_mode_switching[I387_TRUNC] = 1;
16745
16746 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16747 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
16748
16749 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16750 operands[2], operands[3]));
16751 DONE;
16752 }
16753 [(set_attr "type" "frndint")
16754 (set_attr "i387_cw" "trunc")
16755 (set_attr "mode" "XF")])
16756
16757 (define_insn "frndintxf2_trunc_i387"
16758 [(set (match_operand:XF 0 "register_operand" "=f")
16759 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16760 UNSPEC_FRNDINT_TRUNC))
16761 (use (match_operand:HI 2 "memory_operand" "m"))
16762 (use (match_operand:HI 3 "memory_operand" "m"))]
16763 "TARGET_USE_FANCY_MATH_387
16764 && flag_unsafe_math_optimizations"
16765 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16766 [(set_attr "type" "frndint")
16767 (set_attr "i387_cw" "trunc")
16768 (set_attr "mode" "XF")])
16769
16770 (define_expand "btruncxf2"
16771 [(use (match_operand:XF 0 "register_operand" ""))
16772 (use (match_operand:XF 1 "register_operand" ""))]
16773 "TARGET_USE_FANCY_MATH_387
16774 && flag_unsafe_math_optimizations"
16775 {
16776 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16777 DONE;
16778 })
16779
16780 (define_expand "btruncdf2"
16781 [(use (match_operand:DF 0 "register_operand" ""))
16782 (use (match_operand:DF 1 "register_operand" ""))]
16783 "TARGET_USE_FANCY_MATH_387
16784 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16785 && flag_unsafe_math_optimizations"
16786 {
16787 rtx op0 = gen_reg_rtx (XFmode);
16788 rtx op1 = gen_reg_rtx (XFmode);
16789
16790 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16791 emit_insn (gen_frndintxf2_trunc (op0, op1));
16792
16793 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16794 DONE;
16795 })
16796
16797 (define_expand "btruncsf2"
16798 [(use (match_operand:SF 0 "register_operand" ""))
16799 (use (match_operand:SF 1 "register_operand" ""))]
16800 "TARGET_USE_FANCY_MATH_387
16801 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16802 && flag_unsafe_math_optimizations"
16803 {
16804 rtx op0 = gen_reg_rtx (XFmode);
16805 rtx op1 = gen_reg_rtx (XFmode);
16806
16807 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16808 emit_insn (gen_frndintxf2_trunc (op0, op1));
16809
16810 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16811 DONE;
16812 })
16813
16814 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16815 (define_insn_and_split "frndintxf2_mask_pm"
16816 [(set (match_operand:XF 0 "register_operand" "=f")
16817 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16818 UNSPEC_FRNDINT_MASK_PM))
16819 (clobber (reg:CC FLAGS_REG))]
16820 "TARGET_USE_FANCY_MATH_387
16821 && flag_unsafe_math_optimizations
16822 && !(reload_completed || reload_in_progress)"
16823 "#"
16824 "&& 1"
16825 [(const_int 0)]
16826 {
16827 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16828
16829 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16830 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16831
16832 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16833 operands[2], operands[3]));
16834 DONE;
16835 }
16836 [(set_attr "type" "frndint")
16837 (set_attr "i387_cw" "mask_pm")
16838 (set_attr "mode" "XF")])
16839
16840 (define_insn "frndintxf2_mask_pm_i387"
16841 [(set (match_operand:XF 0 "register_operand" "=f")
16842 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16843 UNSPEC_FRNDINT_MASK_PM))
16844 (use (match_operand:HI 2 "memory_operand" "m"))
16845 (use (match_operand:HI 3 "memory_operand" "m"))]
16846 "TARGET_USE_FANCY_MATH_387
16847 && flag_unsafe_math_optimizations"
16848 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16849 [(set_attr "type" "frndint")
16850 (set_attr "i387_cw" "mask_pm")
16851 (set_attr "mode" "XF")])
16852
16853 (define_expand "nearbyintxf2"
16854 [(use (match_operand:XF 0 "register_operand" ""))
16855 (use (match_operand:XF 1 "register_operand" ""))]
16856 "TARGET_USE_FANCY_MATH_387
16857 && flag_unsafe_math_optimizations"
16858 {
16859 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16860
16861 DONE;
16862 })
16863
16864 (define_expand "nearbyintdf2"
16865 [(use (match_operand:DF 0 "register_operand" ""))
16866 (use (match_operand:DF 1 "register_operand" ""))]
16867 "TARGET_USE_FANCY_MATH_387
16868 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16869 && flag_unsafe_math_optimizations"
16870 {
16871 rtx op0 = gen_reg_rtx (XFmode);
16872 rtx op1 = gen_reg_rtx (XFmode);
16873
16874 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16875 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16876
16877 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16878 DONE;
16879 })
16880
16881 (define_expand "nearbyintsf2"
16882 [(use (match_operand:SF 0 "register_operand" ""))
16883 (use (match_operand:SF 1 "register_operand" ""))]
16884 "TARGET_USE_FANCY_MATH_387
16885 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16886 && flag_unsafe_math_optimizations"
16887 {
16888 rtx op0 = gen_reg_rtx (XFmode);
16889 rtx op1 = gen_reg_rtx (XFmode);
16890
16891 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16892 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16893
16894 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16895 DONE;
16896 })
16897
16898 \f
16899 ;; Block operation instructions
16900
16901 (define_insn "cld"
16902 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16903 ""
16904 "cld"
16905 [(set_attr "type" "cld")])
16906
16907 (define_expand "movmemsi"
16908 [(use (match_operand:BLK 0 "memory_operand" ""))
16909 (use (match_operand:BLK 1 "memory_operand" ""))
16910 (use (match_operand:SI 2 "nonmemory_operand" ""))
16911 (use (match_operand:SI 3 "const_int_operand" ""))]
16912 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16913 {
16914 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16915 DONE;
16916 else
16917 FAIL;
16918 })
16919
16920 (define_expand "movmemdi"
16921 [(use (match_operand:BLK 0 "memory_operand" ""))
16922 (use (match_operand:BLK 1 "memory_operand" ""))
16923 (use (match_operand:DI 2 "nonmemory_operand" ""))
16924 (use (match_operand:DI 3 "const_int_operand" ""))]
16925 "TARGET_64BIT"
16926 {
16927 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16928 DONE;
16929 else
16930 FAIL;
16931 })
16932
16933 ;; Most CPUs don't like single string operations
16934 ;; Handle this case here to simplify previous expander.
16935
16936 (define_expand "strmov"
16937 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16938 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16939 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16940 (clobber (reg:CC FLAGS_REG))])
16941 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16942 (clobber (reg:CC FLAGS_REG))])]
16943 ""
16944 {
16945 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16946
16947 /* If .md ever supports :P for Pmode, these can be directly
16948 in the pattern above. */
16949 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16950 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16951
16952 if (TARGET_SINGLE_STRINGOP || optimize_size)
16953 {
16954 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16955 operands[2], operands[3],
16956 operands[5], operands[6]));
16957 DONE;
16958 }
16959
16960 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16961 })
16962
16963 (define_expand "strmov_singleop"
16964 [(parallel [(set (match_operand 1 "memory_operand" "")
16965 (match_operand 3 "memory_operand" ""))
16966 (set (match_operand 0 "register_operand" "")
16967 (match_operand 4 "" ""))
16968 (set (match_operand 2 "register_operand" "")
16969 (match_operand 5 "" ""))
16970 (use (reg:SI DIRFLAG_REG))])]
16971 "TARGET_SINGLE_STRINGOP || optimize_size"
16972 "")
16973
16974 (define_insn "*strmovdi_rex_1"
16975 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16976 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16977 (set (match_operand:DI 0 "register_operand" "=D")
16978 (plus:DI (match_dup 2)
16979 (const_int 8)))
16980 (set (match_operand:DI 1 "register_operand" "=S")
16981 (plus:DI (match_dup 3)
16982 (const_int 8)))
16983 (use (reg:SI DIRFLAG_REG))]
16984 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16985 "movsq"
16986 [(set_attr "type" "str")
16987 (set_attr "mode" "DI")
16988 (set_attr "memory" "both")])
16989
16990 (define_insn "*strmovsi_1"
16991 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16992 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16993 (set (match_operand:SI 0 "register_operand" "=D")
16994 (plus:SI (match_dup 2)
16995 (const_int 4)))
16996 (set (match_operand:SI 1 "register_operand" "=S")
16997 (plus:SI (match_dup 3)
16998 (const_int 4)))
16999 (use (reg:SI DIRFLAG_REG))]
17000 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17001 "{movsl|movsd}"
17002 [(set_attr "type" "str")
17003 (set_attr "mode" "SI")
17004 (set_attr "memory" "both")])
17005
17006 (define_insn "*strmovsi_rex_1"
17007 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17008 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17009 (set (match_operand:DI 0 "register_operand" "=D")
17010 (plus:DI (match_dup 2)
17011 (const_int 4)))
17012 (set (match_operand:DI 1 "register_operand" "=S")
17013 (plus:DI (match_dup 3)
17014 (const_int 4)))
17015 (use (reg:SI DIRFLAG_REG))]
17016 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17017 "{movsl|movsd}"
17018 [(set_attr "type" "str")
17019 (set_attr "mode" "SI")
17020 (set_attr "memory" "both")])
17021
17022 (define_insn "*strmovhi_1"
17023 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17024 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17025 (set (match_operand:SI 0 "register_operand" "=D")
17026 (plus:SI (match_dup 2)
17027 (const_int 2)))
17028 (set (match_operand:SI 1 "register_operand" "=S")
17029 (plus:SI (match_dup 3)
17030 (const_int 2)))
17031 (use (reg:SI DIRFLAG_REG))]
17032 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17033 "movsw"
17034 [(set_attr "type" "str")
17035 (set_attr "memory" "both")
17036 (set_attr "mode" "HI")])
17037
17038 (define_insn "*strmovhi_rex_1"
17039 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17040 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17041 (set (match_operand:DI 0 "register_operand" "=D")
17042 (plus:DI (match_dup 2)
17043 (const_int 2)))
17044 (set (match_operand:DI 1 "register_operand" "=S")
17045 (plus:DI (match_dup 3)
17046 (const_int 2)))
17047 (use (reg:SI DIRFLAG_REG))]
17048 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17049 "movsw"
17050 [(set_attr "type" "str")
17051 (set_attr "memory" "both")
17052 (set_attr "mode" "HI")])
17053
17054 (define_insn "*strmovqi_1"
17055 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17056 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17057 (set (match_operand:SI 0 "register_operand" "=D")
17058 (plus:SI (match_dup 2)
17059 (const_int 1)))
17060 (set (match_operand:SI 1 "register_operand" "=S")
17061 (plus:SI (match_dup 3)
17062 (const_int 1)))
17063 (use (reg:SI DIRFLAG_REG))]
17064 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17065 "movsb"
17066 [(set_attr "type" "str")
17067 (set_attr "memory" "both")
17068 (set_attr "mode" "QI")])
17069
17070 (define_insn "*strmovqi_rex_1"
17071 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17072 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17073 (set (match_operand:DI 0 "register_operand" "=D")
17074 (plus:DI (match_dup 2)
17075 (const_int 1)))
17076 (set (match_operand:DI 1 "register_operand" "=S")
17077 (plus:DI (match_dup 3)
17078 (const_int 1)))
17079 (use (reg:SI DIRFLAG_REG))]
17080 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17081 "movsb"
17082 [(set_attr "type" "str")
17083 (set_attr "memory" "both")
17084 (set_attr "mode" "QI")])
17085
17086 (define_expand "rep_mov"
17087 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17088 (set (match_operand 0 "register_operand" "")
17089 (match_operand 5 "" ""))
17090 (set (match_operand 2 "register_operand" "")
17091 (match_operand 6 "" ""))
17092 (set (match_operand 1 "memory_operand" "")
17093 (match_operand 3 "memory_operand" ""))
17094 (use (match_dup 4))
17095 (use (reg:SI DIRFLAG_REG))])]
17096 ""
17097 "")
17098
17099 (define_insn "*rep_movdi_rex64"
17100 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17101 (set (match_operand:DI 0 "register_operand" "=D")
17102 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17103 (const_int 3))
17104 (match_operand:DI 3 "register_operand" "0")))
17105 (set (match_operand:DI 1 "register_operand" "=S")
17106 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17107 (match_operand:DI 4 "register_operand" "1")))
17108 (set (mem:BLK (match_dup 3))
17109 (mem:BLK (match_dup 4)))
17110 (use (match_dup 5))
17111 (use (reg:SI DIRFLAG_REG))]
17112 "TARGET_64BIT"
17113 "{rep\;movsq|rep movsq}"
17114 [(set_attr "type" "str")
17115 (set_attr "prefix_rep" "1")
17116 (set_attr "memory" "both")
17117 (set_attr "mode" "DI")])
17118
17119 (define_insn "*rep_movsi"
17120 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17121 (set (match_operand:SI 0 "register_operand" "=D")
17122 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17123 (const_int 2))
17124 (match_operand:SI 3 "register_operand" "0")))
17125 (set (match_operand:SI 1 "register_operand" "=S")
17126 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17127 (match_operand:SI 4 "register_operand" "1")))
17128 (set (mem:BLK (match_dup 3))
17129 (mem:BLK (match_dup 4)))
17130 (use (match_dup 5))
17131 (use (reg:SI DIRFLAG_REG))]
17132 "!TARGET_64BIT"
17133 "{rep\;movsl|rep movsd}"
17134 [(set_attr "type" "str")
17135 (set_attr "prefix_rep" "1")
17136 (set_attr "memory" "both")
17137 (set_attr "mode" "SI")])
17138
17139 (define_insn "*rep_movsi_rex64"
17140 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17141 (set (match_operand:DI 0 "register_operand" "=D")
17142 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17143 (const_int 2))
17144 (match_operand:DI 3 "register_operand" "0")))
17145 (set (match_operand:DI 1 "register_operand" "=S")
17146 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17147 (match_operand:DI 4 "register_operand" "1")))
17148 (set (mem:BLK (match_dup 3))
17149 (mem:BLK (match_dup 4)))
17150 (use (match_dup 5))
17151 (use (reg:SI DIRFLAG_REG))]
17152 "TARGET_64BIT"
17153 "{rep\;movsl|rep movsd}"
17154 [(set_attr "type" "str")
17155 (set_attr "prefix_rep" "1")
17156 (set_attr "memory" "both")
17157 (set_attr "mode" "SI")])
17158
17159 (define_insn "*rep_movqi"
17160 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17161 (set (match_operand:SI 0 "register_operand" "=D")
17162 (plus:SI (match_operand:SI 3 "register_operand" "0")
17163 (match_operand:SI 5 "register_operand" "2")))
17164 (set (match_operand:SI 1 "register_operand" "=S")
17165 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17166 (set (mem:BLK (match_dup 3))
17167 (mem:BLK (match_dup 4)))
17168 (use (match_dup 5))
17169 (use (reg:SI DIRFLAG_REG))]
17170 "!TARGET_64BIT"
17171 "{rep\;movsb|rep movsb}"
17172 [(set_attr "type" "str")
17173 (set_attr "prefix_rep" "1")
17174 (set_attr "memory" "both")
17175 (set_attr "mode" "SI")])
17176
17177 (define_insn "*rep_movqi_rex64"
17178 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17179 (set (match_operand:DI 0 "register_operand" "=D")
17180 (plus:DI (match_operand:DI 3 "register_operand" "0")
17181 (match_operand:DI 5 "register_operand" "2")))
17182 (set (match_operand:DI 1 "register_operand" "=S")
17183 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17184 (set (mem:BLK (match_dup 3))
17185 (mem:BLK (match_dup 4)))
17186 (use (match_dup 5))
17187 (use (reg:SI DIRFLAG_REG))]
17188 "TARGET_64BIT"
17189 "{rep\;movsb|rep movsb}"
17190 [(set_attr "type" "str")
17191 (set_attr "prefix_rep" "1")
17192 (set_attr "memory" "both")
17193 (set_attr "mode" "SI")])
17194
17195 (define_expand "setmemsi"
17196 [(use (match_operand:BLK 0 "memory_operand" ""))
17197 (use (match_operand:SI 1 "nonmemory_operand" ""))
17198 (use (match_operand 2 "const_int_operand" ""))
17199 (use (match_operand 3 "const_int_operand" ""))]
17200 ""
17201 {
17202 /* If value to set is not zero, use the library routine. */
17203 if (operands[2] != const0_rtx)
17204 FAIL;
17205
17206 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17207 DONE;
17208 else
17209 FAIL;
17210 })
17211
17212 (define_expand "setmemdi"
17213 [(use (match_operand:BLK 0 "memory_operand" ""))
17214 (use (match_operand:DI 1 "nonmemory_operand" ""))
17215 (use (match_operand 2 "const_int_operand" ""))
17216 (use (match_operand 3 "const_int_operand" ""))]
17217 "TARGET_64BIT"
17218 {
17219 /* If value to set is not zero, use the library routine. */
17220 if (operands[2] != const0_rtx)
17221 FAIL;
17222
17223 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17224 DONE;
17225 else
17226 FAIL;
17227 })
17228
17229 ;; Most CPUs don't like single string operations
17230 ;; Handle this case here to simplify previous expander.
17231
17232 (define_expand "strset"
17233 [(set (match_operand 1 "memory_operand" "")
17234 (match_operand 2 "register_operand" ""))
17235 (parallel [(set (match_operand 0 "register_operand" "")
17236 (match_dup 3))
17237 (clobber (reg:CC FLAGS_REG))])]
17238 ""
17239 {
17240 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17241 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17242
17243 /* If .md ever supports :P for Pmode, this can be directly
17244 in the pattern above. */
17245 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17246 GEN_INT (GET_MODE_SIZE (GET_MODE
17247 (operands[2]))));
17248 if (TARGET_SINGLE_STRINGOP || optimize_size)
17249 {
17250 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17251 operands[3]));
17252 DONE;
17253 }
17254 })
17255
17256 (define_expand "strset_singleop"
17257 [(parallel [(set (match_operand 1 "memory_operand" "")
17258 (match_operand 2 "register_operand" ""))
17259 (set (match_operand 0 "register_operand" "")
17260 (match_operand 3 "" ""))
17261 (use (reg:SI DIRFLAG_REG))])]
17262 "TARGET_SINGLE_STRINGOP || optimize_size"
17263 "")
17264
17265 (define_insn "*strsetdi_rex_1"
17266 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17267 (match_operand:DI 2 "register_operand" "a"))
17268 (set (match_operand:DI 0 "register_operand" "=D")
17269 (plus:DI (match_dup 1)
17270 (const_int 8)))
17271 (use (reg:SI DIRFLAG_REG))]
17272 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17273 "stosq"
17274 [(set_attr "type" "str")
17275 (set_attr "memory" "store")
17276 (set_attr "mode" "DI")])
17277
17278 (define_insn "*strsetsi_1"
17279 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17280 (match_operand:SI 2 "register_operand" "a"))
17281 (set (match_operand:SI 0 "register_operand" "=D")
17282 (plus:SI (match_dup 1)
17283 (const_int 4)))
17284 (use (reg:SI DIRFLAG_REG))]
17285 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17286 "{stosl|stosd}"
17287 [(set_attr "type" "str")
17288 (set_attr "memory" "store")
17289 (set_attr "mode" "SI")])
17290
17291 (define_insn "*strsetsi_rex_1"
17292 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17293 (match_operand:SI 2 "register_operand" "a"))
17294 (set (match_operand:DI 0 "register_operand" "=D")
17295 (plus:DI (match_dup 1)
17296 (const_int 4)))
17297 (use (reg:SI DIRFLAG_REG))]
17298 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17299 "{stosl|stosd}"
17300 [(set_attr "type" "str")
17301 (set_attr "memory" "store")
17302 (set_attr "mode" "SI")])
17303
17304 (define_insn "*strsethi_1"
17305 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17306 (match_operand:HI 2 "register_operand" "a"))
17307 (set (match_operand:SI 0 "register_operand" "=D")
17308 (plus:SI (match_dup 1)
17309 (const_int 2)))
17310 (use (reg:SI DIRFLAG_REG))]
17311 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17312 "stosw"
17313 [(set_attr "type" "str")
17314 (set_attr "memory" "store")
17315 (set_attr "mode" "HI")])
17316
17317 (define_insn "*strsethi_rex_1"
17318 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17319 (match_operand:HI 2 "register_operand" "a"))
17320 (set (match_operand:DI 0 "register_operand" "=D")
17321 (plus:DI (match_dup 1)
17322 (const_int 2)))
17323 (use (reg:SI DIRFLAG_REG))]
17324 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17325 "stosw"
17326 [(set_attr "type" "str")
17327 (set_attr "memory" "store")
17328 (set_attr "mode" "HI")])
17329
17330 (define_insn "*strsetqi_1"
17331 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17332 (match_operand:QI 2 "register_operand" "a"))
17333 (set (match_operand:SI 0 "register_operand" "=D")
17334 (plus:SI (match_dup 1)
17335 (const_int 1)))
17336 (use (reg:SI DIRFLAG_REG))]
17337 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17338 "stosb"
17339 [(set_attr "type" "str")
17340 (set_attr "memory" "store")
17341 (set_attr "mode" "QI")])
17342
17343 (define_insn "*strsetqi_rex_1"
17344 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17345 (match_operand:QI 2 "register_operand" "a"))
17346 (set (match_operand:DI 0 "register_operand" "=D")
17347 (plus:DI (match_dup 1)
17348 (const_int 1)))
17349 (use (reg:SI DIRFLAG_REG))]
17350 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17351 "stosb"
17352 [(set_attr "type" "str")
17353 (set_attr "memory" "store")
17354 (set_attr "mode" "QI")])
17355
17356 (define_expand "rep_stos"
17357 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17358 (set (match_operand 0 "register_operand" "")
17359 (match_operand 4 "" ""))
17360 (set (match_operand 2 "memory_operand" "") (const_int 0))
17361 (use (match_operand 3 "register_operand" ""))
17362 (use (match_dup 1))
17363 (use (reg:SI DIRFLAG_REG))])]
17364 ""
17365 "")
17366
17367 (define_insn "*rep_stosdi_rex64"
17368 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17369 (set (match_operand:DI 0 "register_operand" "=D")
17370 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17371 (const_int 3))
17372 (match_operand:DI 3 "register_operand" "0")))
17373 (set (mem:BLK (match_dup 3))
17374 (const_int 0))
17375 (use (match_operand:DI 2 "register_operand" "a"))
17376 (use (match_dup 4))
17377 (use (reg:SI DIRFLAG_REG))]
17378 "TARGET_64BIT"
17379 "{rep\;stosq|rep stosq}"
17380 [(set_attr "type" "str")
17381 (set_attr "prefix_rep" "1")
17382 (set_attr "memory" "store")
17383 (set_attr "mode" "DI")])
17384
17385 (define_insn "*rep_stossi"
17386 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17387 (set (match_operand:SI 0 "register_operand" "=D")
17388 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17389 (const_int 2))
17390 (match_operand:SI 3 "register_operand" "0")))
17391 (set (mem:BLK (match_dup 3))
17392 (const_int 0))
17393 (use (match_operand:SI 2 "register_operand" "a"))
17394 (use (match_dup 4))
17395 (use (reg:SI DIRFLAG_REG))]
17396 "!TARGET_64BIT"
17397 "{rep\;stosl|rep stosd}"
17398 [(set_attr "type" "str")
17399 (set_attr "prefix_rep" "1")
17400 (set_attr "memory" "store")
17401 (set_attr "mode" "SI")])
17402
17403 (define_insn "*rep_stossi_rex64"
17404 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17405 (set (match_operand:DI 0 "register_operand" "=D")
17406 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17407 (const_int 2))
17408 (match_operand:DI 3 "register_operand" "0")))
17409 (set (mem:BLK (match_dup 3))
17410 (const_int 0))
17411 (use (match_operand:SI 2 "register_operand" "a"))
17412 (use (match_dup 4))
17413 (use (reg:SI DIRFLAG_REG))]
17414 "TARGET_64BIT"
17415 "{rep\;stosl|rep stosd}"
17416 [(set_attr "type" "str")
17417 (set_attr "prefix_rep" "1")
17418 (set_attr "memory" "store")
17419 (set_attr "mode" "SI")])
17420
17421 (define_insn "*rep_stosqi"
17422 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17423 (set (match_operand:SI 0 "register_operand" "=D")
17424 (plus:SI (match_operand:SI 3 "register_operand" "0")
17425 (match_operand:SI 4 "register_operand" "1")))
17426 (set (mem:BLK (match_dup 3))
17427 (const_int 0))
17428 (use (match_operand:QI 2 "register_operand" "a"))
17429 (use (match_dup 4))
17430 (use (reg:SI DIRFLAG_REG))]
17431 "!TARGET_64BIT"
17432 "{rep\;stosb|rep stosb}"
17433 [(set_attr "type" "str")
17434 (set_attr "prefix_rep" "1")
17435 (set_attr "memory" "store")
17436 (set_attr "mode" "QI")])
17437
17438 (define_insn "*rep_stosqi_rex64"
17439 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17440 (set (match_operand:DI 0 "register_operand" "=D")
17441 (plus:DI (match_operand:DI 3 "register_operand" "0")
17442 (match_operand:DI 4 "register_operand" "1")))
17443 (set (mem:BLK (match_dup 3))
17444 (const_int 0))
17445 (use (match_operand:QI 2 "register_operand" "a"))
17446 (use (match_dup 4))
17447 (use (reg:SI DIRFLAG_REG))]
17448 "TARGET_64BIT"
17449 "{rep\;stosb|rep stosb}"
17450 [(set_attr "type" "str")
17451 (set_attr "prefix_rep" "1")
17452 (set_attr "memory" "store")
17453 (set_attr "mode" "QI")])
17454
17455 (define_expand "cmpstrnsi"
17456 [(set (match_operand:SI 0 "register_operand" "")
17457 (compare:SI (match_operand:BLK 1 "general_operand" "")
17458 (match_operand:BLK 2 "general_operand" "")))
17459 (use (match_operand 3 "general_operand" ""))
17460 (use (match_operand 4 "immediate_operand" ""))]
17461 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17462 {
17463 rtx addr1, addr2, out, outlow, count, countreg, align;
17464
17465 /* Can't use this if the user has appropriated esi or edi. */
17466 if (global_regs[4] || global_regs[5])
17467 FAIL;
17468
17469 out = operands[0];
17470 if (GET_CODE (out) != REG)
17471 out = gen_reg_rtx (SImode);
17472
17473 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17474 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17475 if (addr1 != XEXP (operands[1], 0))
17476 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17477 if (addr2 != XEXP (operands[2], 0))
17478 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17479
17480 count = operands[3];
17481 countreg = ix86_zero_extend_to_Pmode (count);
17482
17483 /* %%% Iff we are testing strict equality, we can use known alignment
17484 to good advantage. This may be possible with combine, particularly
17485 once cc0 is dead. */
17486 align = operands[4];
17487
17488 emit_insn (gen_cld ());
17489 if (GET_CODE (count) == CONST_INT)
17490 {
17491 if (INTVAL (count) == 0)
17492 {
17493 emit_move_insn (operands[0], const0_rtx);
17494 DONE;
17495 }
17496 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17497 operands[1], operands[2]));
17498 }
17499 else
17500 {
17501 if (TARGET_64BIT)
17502 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17503 else
17504 emit_insn (gen_cmpsi_1 (countreg, countreg));
17505 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17506 operands[1], operands[2]));
17507 }
17508
17509 outlow = gen_lowpart (QImode, out);
17510 emit_insn (gen_cmpintqi (outlow));
17511 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17512
17513 if (operands[0] != out)
17514 emit_move_insn (operands[0], out);
17515
17516 DONE;
17517 })
17518
17519 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17520
17521 (define_expand "cmpintqi"
17522 [(set (match_dup 1)
17523 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17524 (set (match_dup 2)
17525 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17526 (parallel [(set (match_operand:QI 0 "register_operand" "")
17527 (minus:QI (match_dup 1)
17528 (match_dup 2)))
17529 (clobber (reg:CC FLAGS_REG))])]
17530 ""
17531 "operands[1] = gen_reg_rtx (QImode);
17532 operands[2] = gen_reg_rtx (QImode);")
17533
17534 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17535 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17536
17537 (define_expand "cmpstrnqi_nz_1"
17538 [(parallel [(set (reg:CC FLAGS_REG)
17539 (compare:CC (match_operand 4 "memory_operand" "")
17540 (match_operand 5 "memory_operand" "")))
17541 (use (match_operand 2 "register_operand" ""))
17542 (use (match_operand:SI 3 "immediate_operand" ""))
17543 (use (reg:SI DIRFLAG_REG))
17544 (clobber (match_operand 0 "register_operand" ""))
17545 (clobber (match_operand 1 "register_operand" ""))
17546 (clobber (match_dup 2))])]
17547 ""
17548 "")
17549
17550 (define_insn "*cmpstrnqi_nz_1"
17551 [(set (reg:CC FLAGS_REG)
17552 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17553 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17554 (use (match_operand:SI 6 "register_operand" "2"))
17555 (use (match_operand:SI 3 "immediate_operand" "i"))
17556 (use (reg:SI DIRFLAG_REG))
17557 (clobber (match_operand:SI 0 "register_operand" "=S"))
17558 (clobber (match_operand:SI 1 "register_operand" "=D"))
17559 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17560 "!TARGET_64BIT"
17561 "repz{\;| }cmpsb"
17562 [(set_attr "type" "str")
17563 (set_attr "mode" "QI")
17564 (set_attr "prefix_rep" "1")])
17565
17566 (define_insn "*cmpstrnqi_nz_rex_1"
17567 [(set (reg:CC FLAGS_REG)
17568 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17569 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17570 (use (match_operand:DI 6 "register_operand" "2"))
17571 (use (match_operand:SI 3 "immediate_operand" "i"))
17572 (use (reg:SI DIRFLAG_REG))
17573 (clobber (match_operand:DI 0 "register_operand" "=S"))
17574 (clobber (match_operand:DI 1 "register_operand" "=D"))
17575 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17576 "TARGET_64BIT"
17577 "repz{\;| }cmpsb"
17578 [(set_attr "type" "str")
17579 (set_attr "mode" "QI")
17580 (set_attr "prefix_rep" "1")])
17581
17582 ;; The same, but the count is not known to not be zero.
17583
17584 (define_expand "cmpstrnqi_1"
17585 [(parallel [(set (reg:CC FLAGS_REG)
17586 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17587 (const_int 0))
17588 (compare:CC (match_operand 4 "memory_operand" "")
17589 (match_operand 5 "memory_operand" ""))
17590 (const_int 0)))
17591 (use (match_operand:SI 3 "immediate_operand" ""))
17592 (use (reg:CC FLAGS_REG))
17593 (use (reg:SI DIRFLAG_REG))
17594 (clobber (match_operand 0 "register_operand" ""))
17595 (clobber (match_operand 1 "register_operand" ""))
17596 (clobber (match_dup 2))])]
17597 ""
17598 "")
17599
17600 (define_insn "*cmpstrnqi_1"
17601 [(set (reg:CC FLAGS_REG)
17602 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17603 (const_int 0))
17604 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17605 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17606 (const_int 0)))
17607 (use (match_operand:SI 3 "immediate_operand" "i"))
17608 (use (reg:CC FLAGS_REG))
17609 (use (reg:SI DIRFLAG_REG))
17610 (clobber (match_operand:SI 0 "register_operand" "=S"))
17611 (clobber (match_operand:SI 1 "register_operand" "=D"))
17612 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17613 "!TARGET_64BIT"
17614 "repz{\;| }cmpsb"
17615 [(set_attr "type" "str")
17616 (set_attr "mode" "QI")
17617 (set_attr "prefix_rep" "1")])
17618
17619 (define_insn "*cmpstrnqi_rex_1"
17620 [(set (reg:CC FLAGS_REG)
17621 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17622 (const_int 0))
17623 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17624 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17625 (const_int 0)))
17626 (use (match_operand:SI 3 "immediate_operand" "i"))
17627 (use (reg:CC FLAGS_REG))
17628 (use (reg:SI DIRFLAG_REG))
17629 (clobber (match_operand:DI 0 "register_operand" "=S"))
17630 (clobber (match_operand:DI 1 "register_operand" "=D"))
17631 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17632 "TARGET_64BIT"
17633 "repz{\;| }cmpsb"
17634 [(set_attr "type" "str")
17635 (set_attr "mode" "QI")
17636 (set_attr "prefix_rep" "1")])
17637
17638 (define_expand "strlensi"
17639 [(set (match_operand:SI 0 "register_operand" "")
17640 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17641 (match_operand:QI 2 "immediate_operand" "")
17642 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17643 ""
17644 {
17645 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17646 DONE;
17647 else
17648 FAIL;
17649 })
17650
17651 (define_expand "strlendi"
17652 [(set (match_operand:DI 0 "register_operand" "")
17653 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17654 (match_operand:QI 2 "immediate_operand" "")
17655 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17656 ""
17657 {
17658 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17659 DONE;
17660 else
17661 FAIL;
17662 })
17663
17664 (define_expand "strlenqi_1"
17665 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17666 (use (reg:SI DIRFLAG_REG))
17667 (clobber (match_operand 1 "register_operand" ""))
17668 (clobber (reg:CC FLAGS_REG))])]
17669 ""
17670 "")
17671
17672 (define_insn "*strlenqi_1"
17673 [(set (match_operand:SI 0 "register_operand" "=&c")
17674 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17675 (match_operand:QI 2 "register_operand" "a")
17676 (match_operand:SI 3 "immediate_operand" "i")
17677 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17678 (use (reg:SI DIRFLAG_REG))
17679 (clobber (match_operand:SI 1 "register_operand" "=D"))
17680 (clobber (reg:CC FLAGS_REG))]
17681 "!TARGET_64BIT"
17682 "repnz{\;| }scasb"
17683 [(set_attr "type" "str")
17684 (set_attr "mode" "QI")
17685 (set_attr "prefix_rep" "1")])
17686
17687 (define_insn "*strlenqi_rex_1"
17688 [(set (match_operand:DI 0 "register_operand" "=&c")
17689 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17690 (match_operand:QI 2 "register_operand" "a")
17691 (match_operand:DI 3 "immediate_operand" "i")
17692 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17693 (use (reg:SI DIRFLAG_REG))
17694 (clobber (match_operand:DI 1 "register_operand" "=D"))
17695 (clobber (reg:CC FLAGS_REG))]
17696 "TARGET_64BIT"
17697 "repnz{\;| }scasb"
17698 [(set_attr "type" "str")
17699 (set_attr "mode" "QI")
17700 (set_attr "prefix_rep" "1")])
17701
17702 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17703 ;; handled in combine, but it is not currently up to the task.
17704 ;; When used for their truth value, the cmpstrn* expanders generate
17705 ;; code like this:
17706 ;;
17707 ;; repz cmpsb
17708 ;; seta %al
17709 ;; setb %dl
17710 ;; cmpb %al, %dl
17711 ;; jcc label
17712 ;;
17713 ;; The intermediate three instructions are unnecessary.
17714
17715 ;; This one handles cmpstrn*_nz_1...
17716 (define_peephole2
17717 [(parallel[
17718 (set (reg:CC FLAGS_REG)
17719 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17720 (mem:BLK (match_operand 5 "register_operand" ""))))
17721 (use (match_operand 6 "register_operand" ""))
17722 (use (match_operand:SI 3 "immediate_operand" ""))
17723 (use (reg:SI DIRFLAG_REG))
17724 (clobber (match_operand 0 "register_operand" ""))
17725 (clobber (match_operand 1 "register_operand" ""))
17726 (clobber (match_operand 2 "register_operand" ""))])
17727 (set (match_operand:QI 7 "register_operand" "")
17728 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17729 (set (match_operand:QI 8 "register_operand" "")
17730 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17731 (set (reg FLAGS_REG)
17732 (compare (match_dup 7) (match_dup 8)))
17733 ]
17734 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17735 [(parallel[
17736 (set (reg:CC FLAGS_REG)
17737 (compare:CC (mem:BLK (match_dup 4))
17738 (mem:BLK (match_dup 5))))
17739 (use (match_dup 6))
17740 (use (match_dup 3))
17741 (use (reg:SI DIRFLAG_REG))
17742 (clobber (match_dup 0))
17743 (clobber (match_dup 1))
17744 (clobber (match_dup 2))])]
17745 "")
17746
17747 ;; ...and this one handles cmpstrn*_1.
17748 (define_peephole2
17749 [(parallel[
17750 (set (reg:CC FLAGS_REG)
17751 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17752 (const_int 0))
17753 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17754 (mem:BLK (match_operand 5 "register_operand" "")))
17755 (const_int 0)))
17756 (use (match_operand:SI 3 "immediate_operand" ""))
17757 (use (reg:CC FLAGS_REG))
17758 (use (reg:SI DIRFLAG_REG))
17759 (clobber (match_operand 0 "register_operand" ""))
17760 (clobber (match_operand 1 "register_operand" ""))
17761 (clobber (match_operand 2 "register_operand" ""))])
17762 (set (match_operand:QI 7 "register_operand" "")
17763 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17764 (set (match_operand:QI 8 "register_operand" "")
17765 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17766 (set (reg FLAGS_REG)
17767 (compare (match_dup 7) (match_dup 8)))
17768 ]
17769 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17770 [(parallel[
17771 (set (reg:CC FLAGS_REG)
17772 (if_then_else:CC (ne (match_dup 6)
17773 (const_int 0))
17774 (compare:CC (mem:BLK (match_dup 4))
17775 (mem:BLK (match_dup 5)))
17776 (const_int 0)))
17777 (use (match_dup 3))
17778 (use (reg:CC FLAGS_REG))
17779 (use (reg:SI DIRFLAG_REG))
17780 (clobber (match_dup 0))
17781 (clobber (match_dup 1))
17782 (clobber (match_dup 2))])]
17783 "")
17784
17785
17786 \f
17787 ;; Conditional move instructions.
17788
17789 (define_expand "movdicc"
17790 [(set (match_operand:DI 0 "register_operand" "")
17791 (if_then_else:DI (match_operand 1 "comparison_operator" "")
17792 (match_operand:DI 2 "general_operand" "")
17793 (match_operand:DI 3 "general_operand" "")))]
17794 "TARGET_64BIT"
17795 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17796
17797 (define_insn "x86_movdicc_0_m1_rex64"
17798 [(set (match_operand:DI 0 "register_operand" "=r")
17799 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17800 (const_int -1)
17801 (const_int 0)))
17802 (clobber (reg:CC FLAGS_REG))]
17803 "TARGET_64BIT"
17804 "sbb{q}\t%0, %0"
17805 ; Since we don't have the proper number of operands for an alu insn,
17806 ; fill in all the blanks.
17807 [(set_attr "type" "alu")
17808 (set_attr "pent_pair" "pu")
17809 (set_attr "memory" "none")
17810 (set_attr "imm_disp" "false")
17811 (set_attr "mode" "DI")
17812 (set_attr "length_immediate" "0")])
17813
17814 (define_insn "*movdicc_c_rex64"
17815 [(set (match_operand:DI 0 "register_operand" "=r,r")
17816 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17817 [(reg FLAGS_REG) (const_int 0)])
17818 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17819 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17820 "TARGET_64BIT && TARGET_CMOVE
17821 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17822 "@
17823 cmov%O2%C1\t{%2, %0|%0, %2}
17824 cmov%O2%c1\t{%3, %0|%0, %3}"
17825 [(set_attr "type" "icmov")
17826 (set_attr "mode" "DI")])
17827
17828 (define_expand "movsicc"
17829 [(set (match_operand:SI 0 "register_operand" "")
17830 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17831 (match_operand:SI 2 "general_operand" "")
17832 (match_operand:SI 3 "general_operand" "")))]
17833 ""
17834 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17835
17836 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17837 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17838 ;; So just document what we're doing explicitly.
17839
17840 (define_insn "x86_movsicc_0_m1"
17841 [(set (match_operand:SI 0 "register_operand" "=r")
17842 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17843 (const_int -1)
17844 (const_int 0)))
17845 (clobber (reg:CC FLAGS_REG))]
17846 ""
17847 "sbb{l}\t%0, %0"
17848 ; Since we don't have the proper number of operands for an alu insn,
17849 ; fill in all the blanks.
17850 [(set_attr "type" "alu")
17851 (set_attr "pent_pair" "pu")
17852 (set_attr "memory" "none")
17853 (set_attr "imm_disp" "false")
17854 (set_attr "mode" "SI")
17855 (set_attr "length_immediate" "0")])
17856
17857 (define_insn "*movsicc_noc"
17858 [(set (match_operand:SI 0 "register_operand" "=r,r")
17859 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17860 [(reg FLAGS_REG) (const_int 0)])
17861 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17862 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17863 "TARGET_CMOVE
17864 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17865 "@
17866 cmov%O2%C1\t{%2, %0|%0, %2}
17867 cmov%O2%c1\t{%3, %0|%0, %3}"
17868 [(set_attr "type" "icmov")
17869 (set_attr "mode" "SI")])
17870
17871 (define_expand "movhicc"
17872 [(set (match_operand:HI 0 "register_operand" "")
17873 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17874 (match_operand:HI 2 "general_operand" "")
17875 (match_operand:HI 3 "general_operand" "")))]
17876 "TARGET_HIMODE_MATH"
17877 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17878
17879 (define_insn "*movhicc_noc"
17880 [(set (match_operand:HI 0 "register_operand" "=r,r")
17881 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17882 [(reg FLAGS_REG) (const_int 0)])
17883 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17884 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17885 "TARGET_CMOVE
17886 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17887 "@
17888 cmov%O2%C1\t{%2, %0|%0, %2}
17889 cmov%O2%c1\t{%3, %0|%0, %3}"
17890 [(set_attr "type" "icmov")
17891 (set_attr "mode" "HI")])
17892
17893 (define_expand "movqicc"
17894 [(set (match_operand:QI 0 "register_operand" "")
17895 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17896 (match_operand:QI 2 "general_operand" "")
17897 (match_operand:QI 3 "general_operand" "")))]
17898 "TARGET_QIMODE_MATH"
17899 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17900
17901 (define_insn_and_split "*movqicc_noc"
17902 [(set (match_operand:QI 0 "register_operand" "=r,r")
17903 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17904 [(match_operand 4 "flags_reg_operand" "")
17905 (const_int 0)])
17906 (match_operand:QI 2 "register_operand" "r,0")
17907 (match_operand:QI 3 "register_operand" "0,r")))]
17908 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17909 "#"
17910 "&& reload_completed"
17911 [(set (match_dup 0)
17912 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17913 (match_dup 2)
17914 (match_dup 3)))]
17915 "operands[0] = gen_lowpart (SImode, operands[0]);
17916 operands[2] = gen_lowpart (SImode, operands[2]);
17917 operands[3] = gen_lowpart (SImode, operands[3]);"
17918 [(set_attr "type" "icmov")
17919 (set_attr "mode" "SI")])
17920
17921 (define_expand "movsfcc"
17922 [(set (match_operand:SF 0 "register_operand" "")
17923 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17924 (match_operand:SF 2 "register_operand" "")
17925 (match_operand:SF 3 "register_operand" "")))]
17926 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17927 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17928
17929 (define_insn "*movsfcc_1_387"
17930 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17931 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17932 [(reg FLAGS_REG) (const_int 0)])
17933 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17934 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17935 "TARGET_80387 && TARGET_CMOVE
17936 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17937 "@
17938 fcmov%F1\t{%2, %0|%0, %2}
17939 fcmov%f1\t{%3, %0|%0, %3}
17940 cmov%O2%C1\t{%2, %0|%0, %2}
17941 cmov%O2%c1\t{%3, %0|%0, %3}"
17942 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17943 (set_attr "mode" "SF,SF,SI,SI")])
17944
17945 (define_expand "movdfcc"
17946 [(set (match_operand:DF 0 "register_operand" "")
17947 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17948 (match_operand:DF 2 "register_operand" "")
17949 (match_operand:DF 3 "register_operand" "")))]
17950 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17951 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17952
17953 (define_insn "*movdfcc_1"
17954 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17955 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17956 [(reg FLAGS_REG) (const_int 0)])
17957 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17958 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17959 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17960 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17961 "@
17962 fcmov%F1\t{%2, %0|%0, %2}
17963 fcmov%f1\t{%3, %0|%0, %3}
17964 #
17965 #"
17966 [(set_attr "type" "fcmov,fcmov,multi,multi")
17967 (set_attr "mode" "DF")])
17968
17969 (define_insn "*movdfcc_1_rex64"
17970 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17971 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17972 [(reg FLAGS_REG) (const_int 0)])
17973 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17974 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17975 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17976 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17977 "@
17978 fcmov%F1\t{%2, %0|%0, %2}
17979 fcmov%f1\t{%3, %0|%0, %3}
17980 cmov%O2%C1\t{%2, %0|%0, %2}
17981 cmov%O2%c1\t{%3, %0|%0, %3}"
17982 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17983 (set_attr "mode" "DF")])
17984
17985 (define_split
17986 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17987 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17988 [(match_operand 4 "flags_reg_operand" "")
17989 (const_int 0)])
17990 (match_operand:DF 2 "nonimmediate_operand" "")
17991 (match_operand:DF 3 "nonimmediate_operand" "")))]
17992 "!TARGET_64BIT && reload_completed"
17993 [(set (match_dup 2)
17994 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17995 (match_dup 5)
17996 (match_dup 7)))
17997 (set (match_dup 3)
17998 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17999 (match_dup 6)
18000 (match_dup 8)))]
18001 "split_di (operands+2, 1, operands+5, operands+6);
18002 split_di (operands+3, 1, operands+7, operands+8);
18003 split_di (operands, 1, operands+2, operands+3);")
18004
18005 (define_expand "movxfcc"
18006 [(set (match_operand:XF 0 "register_operand" "")
18007 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18008 (match_operand:XF 2 "register_operand" "")
18009 (match_operand:XF 3 "register_operand" "")))]
18010 "TARGET_80387 && TARGET_CMOVE"
18011 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18012
18013 (define_insn "*movxfcc_1"
18014 [(set (match_operand:XF 0 "register_operand" "=f,f")
18015 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18016 [(reg FLAGS_REG) (const_int 0)])
18017 (match_operand:XF 2 "register_operand" "f,0")
18018 (match_operand:XF 3 "register_operand" "0,f")))]
18019 "TARGET_80387 && TARGET_CMOVE"
18020 "@
18021 fcmov%F1\t{%2, %0|%0, %2}
18022 fcmov%f1\t{%3, %0|%0, %3}"
18023 [(set_attr "type" "fcmov")
18024 (set_attr "mode" "XF")])
18025
18026 ;; These versions of the min/max patterns are intentionally ignorant of
18027 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18028 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18029 ;; are undefined in this condition, we're certain this is correct.
18030
18031 (define_insn "sminsf3"
18032 [(set (match_operand:SF 0 "register_operand" "=x")
18033 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18034 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18035 "TARGET_SSE_MATH"
18036 "minss\t{%2, %0|%0, %2}"
18037 [(set_attr "type" "sseadd")
18038 (set_attr "mode" "SF")])
18039
18040 (define_insn "smaxsf3"
18041 [(set (match_operand:SF 0 "register_operand" "=x")
18042 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18043 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18044 "TARGET_SSE_MATH"
18045 "maxss\t{%2, %0|%0, %2}"
18046 [(set_attr "type" "sseadd")
18047 (set_attr "mode" "SF")])
18048
18049 (define_insn "smindf3"
18050 [(set (match_operand:DF 0 "register_operand" "=x")
18051 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18052 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18053 "TARGET_SSE2 && TARGET_SSE_MATH"
18054 "minsd\t{%2, %0|%0, %2}"
18055 [(set_attr "type" "sseadd")
18056 (set_attr "mode" "DF")])
18057
18058 (define_insn "smaxdf3"
18059 [(set (match_operand:DF 0 "register_operand" "=x")
18060 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18061 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18062 "TARGET_SSE2 && TARGET_SSE_MATH"
18063 "maxsd\t{%2, %0|%0, %2}"
18064 [(set_attr "type" "sseadd")
18065 (set_attr "mode" "DF")])
18066
18067 ;; These versions of the min/max patterns implement exactly the operations
18068 ;; min = (op1 < op2 ? op1 : op2)
18069 ;; max = (!(op1 < op2) ? op1 : op2)
18070 ;; Their operands are not commutative, and thus they may be used in the
18071 ;; presence of -0.0 and NaN.
18072
18073 (define_insn "*ieee_sminsf3"
18074 [(set (match_operand:SF 0 "register_operand" "=x")
18075 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18076 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18077 UNSPEC_IEEE_MIN))]
18078 "TARGET_SSE_MATH"
18079 "minss\t{%2, %0|%0, %2}"
18080 [(set_attr "type" "sseadd")
18081 (set_attr "mode" "SF")])
18082
18083 (define_insn "*ieee_smaxsf3"
18084 [(set (match_operand:SF 0 "register_operand" "=x")
18085 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18086 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18087 UNSPEC_IEEE_MAX))]
18088 "TARGET_SSE_MATH"
18089 "maxss\t{%2, %0|%0, %2}"
18090 [(set_attr "type" "sseadd")
18091 (set_attr "mode" "SF")])
18092
18093 (define_insn "*ieee_smindf3"
18094 [(set (match_operand:DF 0 "register_operand" "=x")
18095 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18096 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18097 UNSPEC_IEEE_MIN))]
18098 "TARGET_SSE2 && TARGET_SSE_MATH"
18099 "minsd\t{%2, %0|%0, %2}"
18100 [(set_attr "type" "sseadd")
18101 (set_attr "mode" "DF")])
18102
18103 (define_insn "*ieee_smaxdf3"
18104 [(set (match_operand:DF 0 "register_operand" "=x")
18105 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18106 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18107 UNSPEC_IEEE_MAX))]
18108 "TARGET_SSE2 && TARGET_SSE_MATH"
18109 "maxsd\t{%2, %0|%0, %2}"
18110 [(set_attr "type" "sseadd")
18111 (set_attr "mode" "DF")])
18112
18113 ;; Conditional addition patterns
18114 (define_expand "addqicc"
18115 [(match_operand:QI 0 "register_operand" "")
18116 (match_operand 1 "comparison_operator" "")
18117 (match_operand:QI 2 "register_operand" "")
18118 (match_operand:QI 3 "const_int_operand" "")]
18119 ""
18120 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18121
18122 (define_expand "addhicc"
18123 [(match_operand:HI 0 "register_operand" "")
18124 (match_operand 1 "comparison_operator" "")
18125 (match_operand:HI 2 "register_operand" "")
18126 (match_operand:HI 3 "const_int_operand" "")]
18127 ""
18128 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18129
18130 (define_expand "addsicc"
18131 [(match_operand:SI 0 "register_operand" "")
18132 (match_operand 1 "comparison_operator" "")
18133 (match_operand:SI 2 "register_operand" "")
18134 (match_operand:SI 3 "const_int_operand" "")]
18135 ""
18136 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18137
18138 (define_expand "adddicc"
18139 [(match_operand:DI 0 "register_operand" "")
18140 (match_operand 1 "comparison_operator" "")
18141 (match_operand:DI 2 "register_operand" "")
18142 (match_operand:DI 3 "const_int_operand" "")]
18143 "TARGET_64BIT"
18144 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18145
18146 \f
18147 ;; Misc patterns (?)
18148
18149 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18150 ;; Otherwise there will be nothing to keep
18151 ;;
18152 ;; [(set (reg ebp) (reg esp))]
18153 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18154 ;; (clobber (eflags)]
18155 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18156 ;;
18157 ;; in proper program order.
18158 (define_insn "pro_epilogue_adjust_stack_1"
18159 [(set (match_operand:SI 0 "register_operand" "=r,r")
18160 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18161 (match_operand:SI 2 "immediate_operand" "i,i")))
18162 (clobber (reg:CC FLAGS_REG))
18163 (clobber (mem:BLK (scratch)))]
18164 "!TARGET_64BIT"
18165 {
18166 switch (get_attr_type (insn))
18167 {
18168 case TYPE_IMOV:
18169 return "mov{l}\t{%1, %0|%0, %1}";
18170
18171 case TYPE_ALU:
18172 if (GET_CODE (operands[2]) == CONST_INT
18173 && (INTVAL (operands[2]) == 128
18174 || (INTVAL (operands[2]) < 0
18175 && INTVAL (operands[2]) != -128)))
18176 {
18177 operands[2] = GEN_INT (-INTVAL (operands[2]));
18178 return "sub{l}\t{%2, %0|%0, %2}";
18179 }
18180 return "add{l}\t{%2, %0|%0, %2}";
18181
18182 case TYPE_LEA:
18183 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18184 return "lea{l}\t{%a2, %0|%0, %a2}";
18185
18186 default:
18187 gcc_unreachable ();
18188 }
18189 }
18190 [(set (attr "type")
18191 (cond [(eq_attr "alternative" "0")
18192 (const_string "alu")
18193 (match_operand:SI 2 "const0_operand" "")
18194 (const_string "imov")
18195 ]
18196 (const_string "lea")))
18197 (set_attr "mode" "SI")])
18198
18199 (define_insn "pro_epilogue_adjust_stack_rex64"
18200 [(set (match_operand:DI 0 "register_operand" "=r,r")
18201 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18202 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18203 (clobber (reg:CC FLAGS_REG))
18204 (clobber (mem:BLK (scratch)))]
18205 "TARGET_64BIT"
18206 {
18207 switch (get_attr_type (insn))
18208 {
18209 case TYPE_IMOV:
18210 return "mov{q}\t{%1, %0|%0, %1}";
18211
18212 case TYPE_ALU:
18213 if (GET_CODE (operands[2]) == CONST_INT
18214 /* Avoid overflows. */
18215 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18216 && (INTVAL (operands[2]) == 128
18217 || (INTVAL (operands[2]) < 0
18218 && INTVAL (operands[2]) != -128)))
18219 {
18220 operands[2] = GEN_INT (-INTVAL (operands[2]));
18221 return "sub{q}\t{%2, %0|%0, %2}";
18222 }
18223 return "add{q}\t{%2, %0|%0, %2}";
18224
18225 case TYPE_LEA:
18226 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18227 return "lea{q}\t{%a2, %0|%0, %a2}";
18228
18229 default:
18230 gcc_unreachable ();
18231 }
18232 }
18233 [(set (attr "type")
18234 (cond [(eq_attr "alternative" "0")
18235 (const_string "alu")
18236 (match_operand:DI 2 "const0_operand" "")
18237 (const_string "imov")
18238 ]
18239 (const_string "lea")))
18240 (set_attr "mode" "DI")])
18241
18242 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18243 [(set (match_operand:DI 0 "register_operand" "=r,r")
18244 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18245 (match_operand:DI 3 "immediate_operand" "i,i")))
18246 (use (match_operand:DI 2 "register_operand" "r,r"))
18247 (clobber (reg:CC FLAGS_REG))
18248 (clobber (mem:BLK (scratch)))]
18249 "TARGET_64BIT"
18250 {
18251 switch (get_attr_type (insn))
18252 {
18253 case TYPE_ALU:
18254 return "add{q}\t{%2, %0|%0, %2}";
18255
18256 case TYPE_LEA:
18257 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18258 return "lea{q}\t{%a2, %0|%0, %a2}";
18259
18260 default:
18261 gcc_unreachable ();
18262 }
18263 }
18264 [(set_attr "type" "alu,lea")
18265 (set_attr "mode" "DI")])
18266
18267 (define_expand "allocate_stack_worker"
18268 [(match_operand:SI 0 "register_operand" "")]
18269 "TARGET_STACK_PROBE"
18270 {
18271 if (reload_completed)
18272 {
18273 if (TARGET_64BIT)
18274 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18275 else
18276 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18277 }
18278 else
18279 {
18280 if (TARGET_64BIT)
18281 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18282 else
18283 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18284 }
18285 DONE;
18286 })
18287
18288 (define_insn "allocate_stack_worker_1"
18289 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18290 UNSPECV_STACK_PROBE)
18291 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18292 (clobber (match_scratch:SI 1 "=0"))
18293 (clobber (reg:CC FLAGS_REG))]
18294 "!TARGET_64BIT && TARGET_STACK_PROBE"
18295 "call\t__alloca"
18296 [(set_attr "type" "multi")
18297 (set_attr "length" "5")])
18298
18299 (define_expand "allocate_stack_worker_postreload"
18300 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18301 UNSPECV_STACK_PROBE)
18302 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18303 (clobber (match_dup 0))
18304 (clobber (reg:CC FLAGS_REG))])]
18305 ""
18306 "")
18307
18308 (define_insn "allocate_stack_worker_rex64"
18309 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18310 UNSPECV_STACK_PROBE)
18311 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18312 (clobber (match_scratch:DI 1 "=0"))
18313 (clobber (reg:CC FLAGS_REG))]
18314 "TARGET_64BIT && TARGET_STACK_PROBE"
18315 "call\t__alloca"
18316 [(set_attr "type" "multi")
18317 (set_attr "length" "5")])
18318
18319 (define_expand "allocate_stack_worker_rex64_postreload"
18320 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18321 UNSPECV_STACK_PROBE)
18322 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18323 (clobber (match_dup 0))
18324 (clobber (reg:CC FLAGS_REG))])]
18325 ""
18326 "")
18327
18328 (define_expand "allocate_stack"
18329 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18330 (minus:SI (reg:SI SP_REG)
18331 (match_operand:SI 1 "general_operand" "")))
18332 (clobber (reg:CC FLAGS_REG))])
18333 (parallel [(set (reg:SI SP_REG)
18334 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18335 (clobber (reg:CC FLAGS_REG))])]
18336 "TARGET_STACK_PROBE"
18337 {
18338 #ifdef CHECK_STACK_LIMIT
18339 if (GET_CODE (operands[1]) == CONST_INT
18340 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18341 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18342 operands[1]));
18343 else
18344 #endif
18345 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18346 operands[1])));
18347
18348 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18349 DONE;
18350 })
18351
18352 (define_expand "builtin_setjmp_receiver"
18353 [(label_ref (match_operand 0 "" ""))]
18354 "!TARGET_64BIT && flag_pic"
18355 {
18356 emit_insn (gen_set_got (pic_offset_table_rtx));
18357 DONE;
18358 })
18359 \f
18360 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18361
18362 (define_split
18363 [(set (match_operand 0 "register_operand" "")
18364 (match_operator 3 "promotable_binary_operator"
18365 [(match_operand 1 "register_operand" "")
18366 (match_operand 2 "aligned_operand" "")]))
18367 (clobber (reg:CC FLAGS_REG))]
18368 "! TARGET_PARTIAL_REG_STALL && reload_completed
18369 && ((GET_MODE (operands[0]) == HImode
18370 && ((!optimize_size && !TARGET_FAST_PREFIX)
18371 || GET_CODE (operands[2]) != CONST_INT
18372 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18373 || (GET_MODE (operands[0]) == QImode
18374 && (TARGET_PROMOTE_QImode || optimize_size)))"
18375 [(parallel [(set (match_dup 0)
18376 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18377 (clobber (reg:CC FLAGS_REG))])]
18378 "operands[0] = gen_lowpart (SImode, operands[0]);
18379 operands[1] = gen_lowpart (SImode, operands[1]);
18380 if (GET_CODE (operands[3]) != ASHIFT)
18381 operands[2] = gen_lowpart (SImode, operands[2]);
18382 PUT_MODE (operands[3], SImode);")
18383
18384 ; Promote the QImode tests, as i386 has encoding of the AND
18385 ; instruction with 32-bit sign-extended immediate and thus the
18386 ; instruction size is unchanged, except in the %eax case for
18387 ; which it is increased by one byte, hence the ! optimize_size.
18388 (define_split
18389 [(set (match_operand 0 "flags_reg_operand" "")
18390 (match_operator 2 "compare_operator"
18391 [(and (match_operand 3 "aligned_operand" "")
18392 (match_operand 4 "const_int_operand" ""))
18393 (const_int 0)]))
18394 (set (match_operand 1 "register_operand" "")
18395 (and (match_dup 3) (match_dup 4)))]
18396 "! TARGET_PARTIAL_REG_STALL && reload_completed
18397 /* Ensure that the operand will remain sign-extended immediate. */
18398 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18399 && ! optimize_size
18400 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18401 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18402 [(parallel [(set (match_dup 0)
18403 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18404 (const_int 0)]))
18405 (set (match_dup 1)
18406 (and:SI (match_dup 3) (match_dup 4)))])]
18407 {
18408 operands[4]
18409 = gen_int_mode (INTVAL (operands[4])
18410 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18411 operands[1] = gen_lowpart (SImode, operands[1]);
18412 operands[3] = gen_lowpart (SImode, operands[3]);
18413 })
18414
18415 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18416 ; the TEST instruction with 32-bit sign-extended immediate and thus
18417 ; the instruction size would at least double, which is not what we
18418 ; want even with ! optimize_size.
18419 (define_split
18420 [(set (match_operand 0 "flags_reg_operand" "")
18421 (match_operator 1 "compare_operator"
18422 [(and (match_operand:HI 2 "aligned_operand" "")
18423 (match_operand:HI 3 "const_int_operand" ""))
18424 (const_int 0)]))]
18425 "! TARGET_PARTIAL_REG_STALL && reload_completed
18426 /* Ensure that the operand will remain sign-extended immediate. */
18427 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18428 && ! TARGET_FAST_PREFIX
18429 && ! optimize_size"
18430 [(set (match_dup 0)
18431 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18432 (const_int 0)]))]
18433 {
18434 operands[3]
18435 = gen_int_mode (INTVAL (operands[3])
18436 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18437 operands[2] = gen_lowpart (SImode, operands[2]);
18438 })
18439
18440 (define_split
18441 [(set (match_operand 0 "register_operand" "")
18442 (neg (match_operand 1 "register_operand" "")))
18443 (clobber (reg:CC FLAGS_REG))]
18444 "! TARGET_PARTIAL_REG_STALL && reload_completed
18445 && (GET_MODE (operands[0]) == HImode
18446 || (GET_MODE (operands[0]) == QImode
18447 && (TARGET_PROMOTE_QImode || optimize_size)))"
18448 [(parallel [(set (match_dup 0)
18449 (neg:SI (match_dup 1)))
18450 (clobber (reg:CC FLAGS_REG))])]
18451 "operands[0] = gen_lowpart (SImode, operands[0]);
18452 operands[1] = gen_lowpart (SImode, operands[1]);")
18453
18454 (define_split
18455 [(set (match_operand 0 "register_operand" "")
18456 (not (match_operand 1 "register_operand" "")))]
18457 "! TARGET_PARTIAL_REG_STALL && reload_completed
18458 && (GET_MODE (operands[0]) == HImode
18459 || (GET_MODE (operands[0]) == QImode
18460 && (TARGET_PROMOTE_QImode || optimize_size)))"
18461 [(set (match_dup 0)
18462 (not:SI (match_dup 1)))]
18463 "operands[0] = gen_lowpart (SImode, operands[0]);
18464 operands[1] = gen_lowpart (SImode, operands[1]);")
18465
18466 (define_split
18467 [(set (match_operand 0 "register_operand" "")
18468 (if_then_else (match_operator 1 "comparison_operator"
18469 [(reg FLAGS_REG) (const_int 0)])
18470 (match_operand 2 "register_operand" "")
18471 (match_operand 3 "register_operand" "")))]
18472 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18473 && (GET_MODE (operands[0]) == HImode
18474 || (GET_MODE (operands[0]) == QImode
18475 && (TARGET_PROMOTE_QImode || optimize_size)))"
18476 [(set (match_dup 0)
18477 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18478 "operands[0] = gen_lowpart (SImode, operands[0]);
18479 operands[2] = gen_lowpart (SImode, operands[2]);
18480 operands[3] = gen_lowpart (SImode, operands[3]);")
18481
18482 \f
18483 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18484 ;; transform a complex memory operation into two memory to register operations.
18485
18486 ;; Don't push memory operands
18487 (define_peephole2
18488 [(set (match_operand:SI 0 "push_operand" "")
18489 (match_operand:SI 1 "memory_operand" ""))
18490 (match_scratch:SI 2 "r")]
18491 "! optimize_size && ! TARGET_PUSH_MEMORY"
18492 [(set (match_dup 2) (match_dup 1))
18493 (set (match_dup 0) (match_dup 2))]
18494 "")
18495
18496 (define_peephole2
18497 [(set (match_operand:DI 0 "push_operand" "")
18498 (match_operand:DI 1 "memory_operand" ""))
18499 (match_scratch:DI 2 "r")]
18500 "! optimize_size && ! TARGET_PUSH_MEMORY"
18501 [(set (match_dup 2) (match_dup 1))
18502 (set (match_dup 0) (match_dup 2))]
18503 "")
18504
18505 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18506 ;; SImode pushes.
18507 (define_peephole2
18508 [(set (match_operand:SF 0 "push_operand" "")
18509 (match_operand:SF 1 "memory_operand" ""))
18510 (match_scratch:SF 2 "r")]
18511 "! optimize_size && ! TARGET_PUSH_MEMORY"
18512 [(set (match_dup 2) (match_dup 1))
18513 (set (match_dup 0) (match_dup 2))]
18514 "")
18515
18516 (define_peephole2
18517 [(set (match_operand:HI 0 "push_operand" "")
18518 (match_operand:HI 1 "memory_operand" ""))
18519 (match_scratch:HI 2 "r")]
18520 "! optimize_size && ! TARGET_PUSH_MEMORY"
18521 [(set (match_dup 2) (match_dup 1))
18522 (set (match_dup 0) (match_dup 2))]
18523 "")
18524
18525 (define_peephole2
18526 [(set (match_operand:QI 0 "push_operand" "")
18527 (match_operand:QI 1 "memory_operand" ""))
18528 (match_scratch:QI 2 "q")]
18529 "! optimize_size && ! TARGET_PUSH_MEMORY"
18530 [(set (match_dup 2) (match_dup 1))
18531 (set (match_dup 0) (match_dup 2))]
18532 "")
18533
18534 ;; Don't move an immediate directly to memory when the instruction
18535 ;; gets too big.
18536 (define_peephole2
18537 [(match_scratch:SI 1 "r")
18538 (set (match_operand:SI 0 "memory_operand" "")
18539 (const_int 0))]
18540 "! optimize_size
18541 && ! TARGET_USE_MOV0
18542 && TARGET_SPLIT_LONG_MOVES
18543 && get_attr_length (insn) >= ix86_cost->large_insn
18544 && peep2_regno_dead_p (0, FLAGS_REG)"
18545 [(parallel [(set (match_dup 1) (const_int 0))
18546 (clobber (reg:CC FLAGS_REG))])
18547 (set (match_dup 0) (match_dup 1))]
18548 "")
18549
18550 (define_peephole2
18551 [(match_scratch:HI 1 "r")
18552 (set (match_operand:HI 0 "memory_operand" "")
18553 (const_int 0))]
18554 "! optimize_size
18555 && ! TARGET_USE_MOV0
18556 && TARGET_SPLIT_LONG_MOVES
18557 && get_attr_length (insn) >= ix86_cost->large_insn
18558 && peep2_regno_dead_p (0, FLAGS_REG)"
18559 [(parallel [(set (match_dup 2) (const_int 0))
18560 (clobber (reg:CC FLAGS_REG))])
18561 (set (match_dup 0) (match_dup 1))]
18562 "operands[2] = gen_lowpart (SImode, operands[1]);")
18563
18564 (define_peephole2
18565 [(match_scratch:QI 1 "q")
18566 (set (match_operand:QI 0 "memory_operand" "")
18567 (const_int 0))]
18568 "! optimize_size
18569 && ! TARGET_USE_MOV0
18570 && TARGET_SPLIT_LONG_MOVES
18571 && get_attr_length (insn) >= ix86_cost->large_insn
18572 && peep2_regno_dead_p (0, FLAGS_REG)"
18573 [(parallel [(set (match_dup 2) (const_int 0))
18574 (clobber (reg:CC FLAGS_REG))])
18575 (set (match_dup 0) (match_dup 1))]
18576 "operands[2] = gen_lowpart (SImode, operands[1]);")
18577
18578 (define_peephole2
18579 [(match_scratch:SI 2 "r")
18580 (set (match_operand:SI 0 "memory_operand" "")
18581 (match_operand:SI 1 "immediate_operand" ""))]
18582 "! optimize_size
18583 && get_attr_length (insn) >= ix86_cost->large_insn
18584 && TARGET_SPLIT_LONG_MOVES"
18585 [(set (match_dup 2) (match_dup 1))
18586 (set (match_dup 0) (match_dup 2))]
18587 "")
18588
18589 (define_peephole2
18590 [(match_scratch:HI 2 "r")
18591 (set (match_operand:HI 0 "memory_operand" "")
18592 (match_operand:HI 1 "immediate_operand" ""))]
18593 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18594 && TARGET_SPLIT_LONG_MOVES"
18595 [(set (match_dup 2) (match_dup 1))
18596 (set (match_dup 0) (match_dup 2))]
18597 "")
18598
18599 (define_peephole2
18600 [(match_scratch:QI 2 "q")
18601 (set (match_operand:QI 0 "memory_operand" "")
18602 (match_operand:QI 1 "immediate_operand" ""))]
18603 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18604 && TARGET_SPLIT_LONG_MOVES"
18605 [(set (match_dup 2) (match_dup 1))
18606 (set (match_dup 0) (match_dup 2))]
18607 "")
18608
18609 ;; Don't compare memory with zero, load and use a test instead.
18610 (define_peephole2
18611 [(set (match_operand 0 "flags_reg_operand" "")
18612 (match_operator 1 "compare_operator"
18613 [(match_operand:SI 2 "memory_operand" "")
18614 (const_int 0)]))
18615 (match_scratch:SI 3 "r")]
18616 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18617 [(set (match_dup 3) (match_dup 2))
18618 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18619 "")
18620
18621 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18622 ;; Don't split NOTs with a displacement operand, because resulting XOR
18623 ;; will not be pairable anyway.
18624 ;;
18625 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18626 ;; represented using a modRM byte. The XOR replacement is long decoded,
18627 ;; so this split helps here as well.
18628 ;;
18629 ;; Note: Can't do this as a regular split because we can't get proper
18630 ;; lifetime information then.
18631
18632 (define_peephole2
18633 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18634 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18635 "!optimize_size
18636 && peep2_regno_dead_p (0, FLAGS_REG)
18637 && ((TARGET_PENTIUM
18638 && (GET_CODE (operands[0]) != MEM
18639 || !memory_displacement_operand (operands[0], SImode)))
18640 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18641 [(parallel [(set (match_dup 0)
18642 (xor:SI (match_dup 1) (const_int -1)))
18643 (clobber (reg:CC FLAGS_REG))])]
18644 "")
18645
18646 (define_peephole2
18647 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18648 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18649 "!optimize_size
18650 && peep2_regno_dead_p (0, FLAGS_REG)
18651 && ((TARGET_PENTIUM
18652 && (GET_CODE (operands[0]) != MEM
18653 || !memory_displacement_operand (operands[0], HImode)))
18654 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18655 [(parallel [(set (match_dup 0)
18656 (xor:HI (match_dup 1) (const_int -1)))
18657 (clobber (reg:CC FLAGS_REG))])]
18658 "")
18659
18660 (define_peephole2
18661 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18662 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18663 "!optimize_size
18664 && peep2_regno_dead_p (0, FLAGS_REG)
18665 && ((TARGET_PENTIUM
18666 && (GET_CODE (operands[0]) != MEM
18667 || !memory_displacement_operand (operands[0], QImode)))
18668 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18669 [(parallel [(set (match_dup 0)
18670 (xor:QI (match_dup 1) (const_int -1)))
18671 (clobber (reg:CC FLAGS_REG))])]
18672 "")
18673
18674 ;; Non pairable "test imm, reg" instructions can be translated to
18675 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18676 ;; byte opcode instead of two, have a short form for byte operands),
18677 ;; so do it for other CPUs as well. Given that the value was dead,
18678 ;; this should not create any new dependencies. Pass on the sub-word
18679 ;; versions if we're concerned about partial register stalls.
18680
18681 (define_peephole2
18682 [(set (match_operand 0 "flags_reg_operand" "")
18683 (match_operator 1 "compare_operator"
18684 [(and:SI (match_operand:SI 2 "register_operand" "")
18685 (match_operand:SI 3 "immediate_operand" ""))
18686 (const_int 0)]))]
18687 "ix86_match_ccmode (insn, CCNOmode)
18688 && (true_regnum (operands[2]) != 0
18689 || (GET_CODE (operands[3]) == CONST_INT
18690 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18691 && peep2_reg_dead_p (1, operands[2])"
18692 [(parallel
18693 [(set (match_dup 0)
18694 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18695 (const_int 0)]))
18696 (set (match_dup 2)
18697 (and:SI (match_dup 2) (match_dup 3)))])]
18698 "")
18699
18700 ;; We don't need to handle HImode case, because it will be promoted to SImode
18701 ;; on ! TARGET_PARTIAL_REG_STALL
18702
18703 (define_peephole2
18704 [(set (match_operand 0 "flags_reg_operand" "")
18705 (match_operator 1 "compare_operator"
18706 [(and:QI (match_operand:QI 2 "register_operand" "")
18707 (match_operand:QI 3 "immediate_operand" ""))
18708 (const_int 0)]))]
18709 "! TARGET_PARTIAL_REG_STALL
18710 && ix86_match_ccmode (insn, CCNOmode)
18711 && true_regnum (operands[2]) != 0
18712 && peep2_reg_dead_p (1, operands[2])"
18713 [(parallel
18714 [(set (match_dup 0)
18715 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18716 (const_int 0)]))
18717 (set (match_dup 2)
18718 (and:QI (match_dup 2) (match_dup 3)))])]
18719 "")
18720
18721 (define_peephole2
18722 [(set (match_operand 0 "flags_reg_operand" "")
18723 (match_operator 1 "compare_operator"
18724 [(and:SI
18725 (zero_extract:SI
18726 (match_operand 2 "ext_register_operand" "")
18727 (const_int 8)
18728 (const_int 8))
18729 (match_operand 3 "const_int_operand" ""))
18730 (const_int 0)]))]
18731 "! TARGET_PARTIAL_REG_STALL
18732 && ix86_match_ccmode (insn, CCNOmode)
18733 && true_regnum (operands[2]) != 0
18734 && peep2_reg_dead_p (1, operands[2])"
18735 [(parallel [(set (match_dup 0)
18736 (match_op_dup 1
18737 [(and:SI
18738 (zero_extract:SI
18739 (match_dup 2)
18740 (const_int 8)
18741 (const_int 8))
18742 (match_dup 3))
18743 (const_int 0)]))
18744 (set (zero_extract:SI (match_dup 2)
18745 (const_int 8)
18746 (const_int 8))
18747 (and:SI
18748 (zero_extract:SI
18749 (match_dup 2)
18750 (const_int 8)
18751 (const_int 8))
18752 (match_dup 3)))])]
18753 "")
18754
18755 ;; Don't do logical operations with memory inputs.
18756 (define_peephole2
18757 [(match_scratch:SI 2 "r")
18758 (parallel [(set (match_operand:SI 0 "register_operand" "")
18759 (match_operator:SI 3 "arith_or_logical_operator"
18760 [(match_dup 0)
18761 (match_operand:SI 1 "memory_operand" "")]))
18762 (clobber (reg:CC FLAGS_REG))])]
18763 "! optimize_size && ! TARGET_READ_MODIFY"
18764 [(set (match_dup 2) (match_dup 1))
18765 (parallel [(set (match_dup 0)
18766 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18767 (clobber (reg:CC FLAGS_REG))])]
18768 "")
18769
18770 (define_peephole2
18771 [(match_scratch:SI 2 "r")
18772 (parallel [(set (match_operand:SI 0 "register_operand" "")
18773 (match_operator:SI 3 "arith_or_logical_operator"
18774 [(match_operand:SI 1 "memory_operand" "")
18775 (match_dup 0)]))
18776 (clobber (reg:CC FLAGS_REG))])]
18777 "! optimize_size && ! TARGET_READ_MODIFY"
18778 [(set (match_dup 2) (match_dup 1))
18779 (parallel [(set (match_dup 0)
18780 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18781 (clobber (reg:CC FLAGS_REG))])]
18782 "")
18783
18784 ; Don't do logical operations with memory outputs
18785 ;
18786 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18787 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18788 ; the same decoder scheduling characteristics as the original.
18789
18790 (define_peephole2
18791 [(match_scratch:SI 2 "r")
18792 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18793 (match_operator:SI 3 "arith_or_logical_operator"
18794 [(match_dup 0)
18795 (match_operand:SI 1 "nonmemory_operand" "")]))
18796 (clobber (reg:CC FLAGS_REG))])]
18797 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18798 [(set (match_dup 2) (match_dup 0))
18799 (parallel [(set (match_dup 2)
18800 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18801 (clobber (reg:CC FLAGS_REG))])
18802 (set (match_dup 0) (match_dup 2))]
18803 "")
18804
18805 (define_peephole2
18806 [(match_scratch:SI 2 "r")
18807 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18808 (match_operator:SI 3 "arith_or_logical_operator"
18809 [(match_operand:SI 1 "nonmemory_operand" "")
18810 (match_dup 0)]))
18811 (clobber (reg:CC FLAGS_REG))])]
18812 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18813 [(set (match_dup 2) (match_dup 0))
18814 (parallel [(set (match_dup 2)
18815 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18816 (clobber (reg:CC FLAGS_REG))])
18817 (set (match_dup 0) (match_dup 2))]
18818 "")
18819
18820 ;; Attempt to always use XOR for zeroing registers.
18821 (define_peephole2
18822 [(set (match_operand 0 "register_operand" "")
18823 (match_operand 1 "const0_operand" ""))]
18824 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18825 && (! TARGET_USE_MOV0 || optimize_size)
18826 && GENERAL_REG_P (operands[0])
18827 && peep2_regno_dead_p (0, FLAGS_REG)"
18828 [(parallel [(set (match_dup 0) (const_int 0))
18829 (clobber (reg:CC FLAGS_REG))])]
18830 {
18831 operands[0] = gen_lowpart (word_mode, operands[0]);
18832 })
18833
18834 (define_peephole2
18835 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18836 (const_int 0))]
18837 "(GET_MODE (operands[0]) == QImode
18838 || GET_MODE (operands[0]) == HImode)
18839 && (! TARGET_USE_MOV0 || optimize_size)
18840 && peep2_regno_dead_p (0, FLAGS_REG)"
18841 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18842 (clobber (reg:CC FLAGS_REG))])])
18843
18844 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18845 (define_peephole2
18846 [(set (match_operand 0 "register_operand" "")
18847 (const_int -1))]
18848 "(GET_MODE (operands[0]) == HImode
18849 || GET_MODE (operands[0]) == SImode
18850 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18851 && (optimize_size || TARGET_PENTIUM)
18852 && peep2_regno_dead_p (0, FLAGS_REG)"
18853 [(parallel [(set (match_dup 0) (const_int -1))
18854 (clobber (reg:CC FLAGS_REG))])]
18855 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18856 operands[0]);")
18857
18858 ;; Attempt to convert simple leas to adds. These can be created by
18859 ;; move expanders.
18860 (define_peephole2
18861 [(set (match_operand:SI 0 "register_operand" "")
18862 (plus:SI (match_dup 0)
18863 (match_operand:SI 1 "nonmemory_operand" "")))]
18864 "peep2_regno_dead_p (0, FLAGS_REG)"
18865 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18866 (clobber (reg:CC FLAGS_REG))])]
18867 "")
18868
18869 (define_peephole2
18870 [(set (match_operand:SI 0 "register_operand" "")
18871 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18872 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18873 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18874 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18875 (clobber (reg:CC FLAGS_REG))])]
18876 "operands[2] = gen_lowpart (SImode, operands[2]);")
18877
18878 (define_peephole2
18879 [(set (match_operand:DI 0 "register_operand" "")
18880 (plus:DI (match_dup 0)
18881 (match_operand:DI 1 "x86_64_general_operand" "")))]
18882 "peep2_regno_dead_p (0, FLAGS_REG)"
18883 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18884 (clobber (reg:CC FLAGS_REG))])]
18885 "")
18886
18887 (define_peephole2
18888 [(set (match_operand:SI 0 "register_operand" "")
18889 (mult:SI (match_dup 0)
18890 (match_operand:SI 1 "const_int_operand" "")))]
18891 "exact_log2 (INTVAL (operands[1])) >= 0
18892 && peep2_regno_dead_p (0, FLAGS_REG)"
18893 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18894 (clobber (reg:CC FLAGS_REG))])]
18895 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18896
18897 (define_peephole2
18898 [(set (match_operand:DI 0 "register_operand" "")
18899 (mult:DI (match_dup 0)
18900 (match_operand:DI 1 "const_int_operand" "")))]
18901 "exact_log2 (INTVAL (operands[1])) >= 0
18902 && peep2_regno_dead_p (0, FLAGS_REG)"
18903 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18904 (clobber (reg:CC FLAGS_REG))])]
18905 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18906
18907 (define_peephole2
18908 [(set (match_operand:SI 0 "register_operand" "")
18909 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18910 (match_operand:DI 2 "const_int_operand" "")) 0))]
18911 "exact_log2 (INTVAL (operands[2])) >= 0
18912 && REGNO (operands[0]) == REGNO (operands[1])
18913 && peep2_regno_dead_p (0, FLAGS_REG)"
18914 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18915 (clobber (reg:CC FLAGS_REG))])]
18916 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18917
18918 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18919 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18920 ;; many CPUs it is also faster, since special hardware to avoid esp
18921 ;; dependencies is present.
18922
18923 ;; While some of these conversions may be done using splitters, we use peepholes
18924 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18925
18926 ;; Convert prologue esp subtractions to push.
18927 ;; We need register to push. In order to keep verify_flow_info happy we have
18928 ;; two choices
18929 ;; - use scratch and clobber it in order to avoid dependencies
18930 ;; - use already live register
18931 ;; We can't use the second way right now, since there is no reliable way how to
18932 ;; verify that given register is live. First choice will also most likely in
18933 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18934 ;; call clobbered registers are dead. We may want to use base pointer as an
18935 ;; alternative when no register is available later.
18936
18937 (define_peephole2
18938 [(match_scratch:SI 0 "r")
18939 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18940 (clobber (reg:CC FLAGS_REG))
18941 (clobber (mem:BLK (scratch)))])]
18942 "optimize_size || !TARGET_SUB_ESP_4"
18943 [(clobber (match_dup 0))
18944 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18945 (clobber (mem:BLK (scratch)))])])
18946
18947 (define_peephole2
18948 [(match_scratch:SI 0 "r")
18949 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18950 (clobber (reg:CC FLAGS_REG))
18951 (clobber (mem:BLK (scratch)))])]
18952 "optimize_size || !TARGET_SUB_ESP_8"
18953 [(clobber (match_dup 0))
18954 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18955 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18956 (clobber (mem:BLK (scratch)))])])
18957
18958 ;; Convert esp subtractions to push.
18959 (define_peephole2
18960 [(match_scratch:SI 0 "r")
18961 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18962 (clobber (reg:CC FLAGS_REG))])]
18963 "optimize_size || !TARGET_SUB_ESP_4"
18964 [(clobber (match_dup 0))
18965 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18966
18967 (define_peephole2
18968 [(match_scratch:SI 0 "r")
18969 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18970 (clobber (reg:CC FLAGS_REG))])]
18971 "optimize_size || !TARGET_SUB_ESP_8"
18972 [(clobber (match_dup 0))
18973 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18974 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18975
18976 ;; Convert epilogue deallocator to pop.
18977 (define_peephole2
18978 [(match_scratch:SI 0 "r")
18979 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18980 (clobber (reg:CC FLAGS_REG))
18981 (clobber (mem:BLK (scratch)))])]
18982 "optimize_size || !TARGET_ADD_ESP_4"
18983 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18984 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18985 (clobber (mem:BLK (scratch)))])]
18986 "")
18987
18988 ;; Two pops case is tricky, since pop causes dependency on destination register.
18989 ;; We use two registers if available.
18990 (define_peephole2
18991 [(match_scratch:SI 0 "r")
18992 (match_scratch:SI 1 "r")
18993 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18994 (clobber (reg:CC FLAGS_REG))
18995 (clobber (mem:BLK (scratch)))])]
18996 "optimize_size || !TARGET_ADD_ESP_8"
18997 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18998 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18999 (clobber (mem:BLK (scratch)))])
19000 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19001 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19002 "")
19003
19004 (define_peephole2
19005 [(match_scratch:SI 0 "r")
19006 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19007 (clobber (reg:CC FLAGS_REG))
19008 (clobber (mem:BLK (scratch)))])]
19009 "optimize_size"
19010 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19011 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19012 (clobber (mem:BLK (scratch)))])
19013 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19014 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19015 "")
19016
19017 ;; Convert esp additions to pop.
19018 (define_peephole2
19019 [(match_scratch:SI 0 "r")
19020 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19021 (clobber (reg:CC FLAGS_REG))])]
19022 ""
19023 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19024 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19025 "")
19026
19027 ;; Two pops case is tricky, since pop causes dependency on destination register.
19028 ;; We use two registers if available.
19029 (define_peephole2
19030 [(match_scratch:SI 0 "r")
19031 (match_scratch:SI 1 "r")
19032 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19033 (clobber (reg:CC FLAGS_REG))])]
19034 ""
19035 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19036 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19037 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19038 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19039 "")
19040
19041 (define_peephole2
19042 [(match_scratch:SI 0 "r")
19043 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19044 (clobber (reg:CC FLAGS_REG))])]
19045 "optimize_size"
19046 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19047 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19048 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19049 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19050 "")
19051 \f
19052 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19053 ;; required and register dies. Similarly for 128 to plus -128.
19054 (define_peephole2
19055 [(set (match_operand 0 "flags_reg_operand" "")
19056 (match_operator 1 "compare_operator"
19057 [(match_operand 2 "register_operand" "")
19058 (match_operand 3 "const_int_operand" "")]))]
19059 "(INTVAL (operands[3]) == -1
19060 || INTVAL (operands[3]) == 1
19061 || INTVAL (operands[3]) == 128)
19062 && ix86_match_ccmode (insn, CCGCmode)
19063 && peep2_reg_dead_p (1, operands[2])"
19064 [(parallel [(set (match_dup 0)
19065 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19066 (clobber (match_dup 2))])]
19067 "")
19068 \f
19069 (define_peephole2
19070 [(match_scratch:DI 0 "r")
19071 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19072 (clobber (reg:CC FLAGS_REG))
19073 (clobber (mem:BLK (scratch)))])]
19074 "optimize_size || !TARGET_SUB_ESP_4"
19075 [(clobber (match_dup 0))
19076 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19077 (clobber (mem:BLK (scratch)))])])
19078
19079 (define_peephole2
19080 [(match_scratch:DI 0 "r")
19081 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19082 (clobber (reg:CC FLAGS_REG))
19083 (clobber (mem:BLK (scratch)))])]
19084 "optimize_size || !TARGET_SUB_ESP_8"
19085 [(clobber (match_dup 0))
19086 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19087 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19088 (clobber (mem:BLK (scratch)))])])
19089
19090 ;; Convert esp subtractions to push.
19091 (define_peephole2
19092 [(match_scratch:DI 0 "r")
19093 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19094 (clobber (reg:CC FLAGS_REG))])]
19095 "optimize_size || !TARGET_SUB_ESP_4"
19096 [(clobber (match_dup 0))
19097 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19098
19099 (define_peephole2
19100 [(match_scratch:DI 0 "r")
19101 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19102 (clobber (reg:CC FLAGS_REG))])]
19103 "optimize_size || !TARGET_SUB_ESP_8"
19104 [(clobber (match_dup 0))
19105 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19106 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19107
19108 ;; Convert epilogue deallocator to pop.
19109 (define_peephole2
19110 [(match_scratch:DI 0 "r")
19111 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19112 (clobber (reg:CC FLAGS_REG))
19113 (clobber (mem:BLK (scratch)))])]
19114 "optimize_size || !TARGET_ADD_ESP_4"
19115 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19116 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19117 (clobber (mem:BLK (scratch)))])]
19118 "")
19119
19120 ;; Two pops case is tricky, since pop causes dependency on destination register.
19121 ;; We use two registers if available.
19122 (define_peephole2
19123 [(match_scratch:DI 0 "r")
19124 (match_scratch:DI 1 "r")
19125 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19126 (clobber (reg:CC FLAGS_REG))
19127 (clobber (mem:BLK (scratch)))])]
19128 "optimize_size || !TARGET_ADD_ESP_8"
19129 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19130 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19131 (clobber (mem:BLK (scratch)))])
19132 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19133 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19134 "")
19135
19136 (define_peephole2
19137 [(match_scratch:DI 0 "r")
19138 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19139 (clobber (reg:CC FLAGS_REG))
19140 (clobber (mem:BLK (scratch)))])]
19141 "optimize_size"
19142 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19143 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19144 (clobber (mem:BLK (scratch)))])
19145 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19146 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19147 "")
19148
19149 ;; Convert esp additions to pop.
19150 (define_peephole2
19151 [(match_scratch:DI 0 "r")
19152 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19153 (clobber (reg:CC FLAGS_REG))])]
19154 ""
19155 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19156 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19157 "")
19158
19159 ;; Two pops case is tricky, since pop causes dependency on destination register.
19160 ;; We use two registers if available.
19161 (define_peephole2
19162 [(match_scratch:DI 0 "r")
19163 (match_scratch:DI 1 "r")
19164 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19165 (clobber (reg:CC FLAGS_REG))])]
19166 ""
19167 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19168 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19169 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19170 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19171 "")
19172
19173 (define_peephole2
19174 [(match_scratch:DI 0 "r")
19175 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19176 (clobber (reg:CC FLAGS_REG))])]
19177 "optimize_size"
19178 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19179 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19180 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19181 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19182 "")
19183 \f
19184 ;; Convert imul by three, five and nine into lea
19185 (define_peephole2
19186 [(parallel
19187 [(set (match_operand:SI 0 "register_operand" "")
19188 (mult:SI (match_operand:SI 1 "register_operand" "")
19189 (match_operand:SI 2 "const_int_operand" "")))
19190 (clobber (reg:CC FLAGS_REG))])]
19191 "INTVAL (operands[2]) == 3
19192 || INTVAL (operands[2]) == 5
19193 || INTVAL (operands[2]) == 9"
19194 [(set (match_dup 0)
19195 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19196 (match_dup 1)))]
19197 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19198
19199 (define_peephole2
19200 [(parallel
19201 [(set (match_operand:SI 0 "register_operand" "")
19202 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19203 (match_operand:SI 2 "const_int_operand" "")))
19204 (clobber (reg:CC FLAGS_REG))])]
19205 "!optimize_size
19206 && (INTVAL (operands[2]) == 3
19207 || INTVAL (operands[2]) == 5
19208 || INTVAL (operands[2]) == 9)"
19209 [(set (match_dup 0) (match_dup 1))
19210 (set (match_dup 0)
19211 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19212 (match_dup 0)))]
19213 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19214
19215 (define_peephole2
19216 [(parallel
19217 [(set (match_operand:DI 0 "register_operand" "")
19218 (mult:DI (match_operand:DI 1 "register_operand" "")
19219 (match_operand:DI 2 "const_int_operand" "")))
19220 (clobber (reg:CC FLAGS_REG))])]
19221 "TARGET_64BIT
19222 && (INTVAL (operands[2]) == 3
19223 || INTVAL (operands[2]) == 5
19224 || INTVAL (operands[2]) == 9)"
19225 [(set (match_dup 0)
19226 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19227 (match_dup 1)))]
19228 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19229
19230 (define_peephole2
19231 [(parallel
19232 [(set (match_operand:DI 0 "register_operand" "")
19233 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19234 (match_operand:DI 2 "const_int_operand" "")))
19235 (clobber (reg:CC FLAGS_REG))])]
19236 "TARGET_64BIT
19237 && !optimize_size
19238 && (INTVAL (operands[2]) == 3
19239 || INTVAL (operands[2]) == 5
19240 || INTVAL (operands[2]) == 9)"
19241 [(set (match_dup 0) (match_dup 1))
19242 (set (match_dup 0)
19243 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19244 (match_dup 0)))]
19245 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19246
19247 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19248 ;; imul $32bit_imm, reg, reg is direct decoded.
19249 (define_peephole2
19250 [(match_scratch:DI 3 "r")
19251 (parallel [(set (match_operand:DI 0 "register_operand" "")
19252 (mult:DI (match_operand:DI 1 "memory_operand" "")
19253 (match_operand:DI 2 "immediate_operand" "")))
19254 (clobber (reg:CC FLAGS_REG))])]
19255 "TARGET_K8 && !optimize_size
19256 && (GET_CODE (operands[2]) != CONST_INT
19257 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19258 [(set (match_dup 3) (match_dup 1))
19259 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19260 (clobber (reg:CC FLAGS_REG))])]
19261 "")
19262
19263 (define_peephole2
19264 [(match_scratch:SI 3 "r")
19265 (parallel [(set (match_operand:SI 0 "register_operand" "")
19266 (mult:SI (match_operand:SI 1 "memory_operand" "")
19267 (match_operand:SI 2 "immediate_operand" "")))
19268 (clobber (reg:CC FLAGS_REG))])]
19269 "TARGET_K8 && !optimize_size
19270 && (GET_CODE (operands[2]) != CONST_INT
19271 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19272 [(set (match_dup 3) (match_dup 1))
19273 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19274 (clobber (reg:CC FLAGS_REG))])]
19275 "")
19276
19277 (define_peephole2
19278 [(match_scratch:SI 3 "r")
19279 (parallel [(set (match_operand:DI 0 "register_operand" "")
19280 (zero_extend:DI
19281 (mult:SI (match_operand:SI 1 "memory_operand" "")
19282 (match_operand:SI 2 "immediate_operand" ""))))
19283 (clobber (reg:CC FLAGS_REG))])]
19284 "TARGET_K8 && !optimize_size
19285 && (GET_CODE (operands[2]) != CONST_INT
19286 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19287 [(set (match_dup 3) (match_dup 1))
19288 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19289 (clobber (reg:CC FLAGS_REG))])]
19290 "")
19291
19292 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19293 ;; Convert it into imul reg, reg
19294 ;; It would be better to force assembler to encode instruction using long
19295 ;; immediate, but there is apparently no way to do so.
19296 (define_peephole2
19297 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19298 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19299 (match_operand:DI 2 "const_int_operand" "")))
19300 (clobber (reg:CC FLAGS_REG))])
19301 (match_scratch:DI 3 "r")]
19302 "TARGET_K8 && !optimize_size
19303 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19304 [(set (match_dup 3) (match_dup 2))
19305 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19306 (clobber (reg:CC FLAGS_REG))])]
19307 {
19308 if (!rtx_equal_p (operands[0], operands[1]))
19309 emit_move_insn (operands[0], operands[1]);
19310 })
19311
19312 (define_peephole2
19313 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19314 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19315 (match_operand:SI 2 "const_int_operand" "")))
19316 (clobber (reg:CC FLAGS_REG))])
19317 (match_scratch:SI 3 "r")]
19318 "TARGET_K8 && !optimize_size
19319 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19320 [(set (match_dup 3) (match_dup 2))
19321 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19322 (clobber (reg:CC FLAGS_REG))])]
19323 {
19324 if (!rtx_equal_p (operands[0], operands[1]))
19325 emit_move_insn (operands[0], operands[1]);
19326 })
19327
19328 (define_peephole2
19329 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19330 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19331 (match_operand:HI 2 "immediate_operand" "")))
19332 (clobber (reg:CC FLAGS_REG))])
19333 (match_scratch:HI 3 "r")]
19334 "TARGET_K8 && !optimize_size"
19335 [(set (match_dup 3) (match_dup 2))
19336 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19337 (clobber (reg:CC FLAGS_REG))])]
19338 {
19339 if (!rtx_equal_p (operands[0], operands[1]))
19340 emit_move_insn (operands[0], operands[1]);
19341 })
19342 \f
19343 ;; Call-value patterns last so that the wildcard operand does not
19344 ;; disrupt insn-recog's switch tables.
19345
19346 (define_insn "*call_value_pop_0"
19347 [(set (match_operand 0 "" "")
19348 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19349 (match_operand:SI 2 "" "")))
19350 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19351 (match_operand:SI 3 "immediate_operand" "")))]
19352 "!TARGET_64BIT"
19353 {
19354 if (SIBLING_CALL_P (insn))
19355 return "jmp\t%P1";
19356 else
19357 return "call\t%P1";
19358 }
19359 [(set_attr "type" "callv")])
19360
19361 (define_insn "*call_value_pop_1"
19362 [(set (match_operand 0 "" "")
19363 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19364 (match_operand:SI 2 "" "")))
19365 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19366 (match_operand:SI 3 "immediate_operand" "i")))]
19367 "!TARGET_64BIT"
19368 {
19369 if (constant_call_address_operand (operands[1], Pmode))
19370 {
19371 if (SIBLING_CALL_P (insn))
19372 return "jmp\t%P1";
19373 else
19374 return "call\t%P1";
19375 }
19376 if (SIBLING_CALL_P (insn))
19377 return "jmp\t%A1";
19378 else
19379 return "call\t%A1";
19380 }
19381 [(set_attr "type" "callv")])
19382
19383 (define_insn "*call_value_0"
19384 [(set (match_operand 0 "" "")
19385 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19386 (match_operand:SI 2 "" "")))]
19387 "!TARGET_64BIT"
19388 {
19389 if (SIBLING_CALL_P (insn))
19390 return "jmp\t%P1";
19391 else
19392 return "call\t%P1";
19393 }
19394 [(set_attr "type" "callv")])
19395
19396 (define_insn "*call_value_0_rex64"
19397 [(set (match_operand 0 "" "")
19398 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19399 (match_operand:DI 2 "const_int_operand" "")))]
19400 "TARGET_64BIT"
19401 {
19402 if (SIBLING_CALL_P (insn))
19403 return "jmp\t%P1";
19404 else
19405 return "call\t%P1";
19406 }
19407 [(set_attr "type" "callv")])
19408
19409 (define_insn "*call_value_1"
19410 [(set (match_operand 0 "" "")
19411 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19412 (match_operand:SI 2 "" "")))]
19413 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19414 {
19415 if (constant_call_address_operand (operands[1], Pmode))
19416 return "call\t%P1";
19417 return "call\t%A1";
19418 }
19419 [(set_attr "type" "callv")])
19420
19421 (define_insn "*sibcall_value_1"
19422 [(set (match_operand 0 "" "")
19423 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19424 (match_operand:SI 2 "" "")))]
19425 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19426 {
19427 if (constant_call_address_operand (operands[1], Pmode))
19428 return "jmp\t%P1";
19429 return "jmp\t%A1";
19430 }
19431 [(set_attr "type" "callv")])
19432
19433 (define_insn "*call_value_1_rex64"
19434 [(set (match_operand 0 "" "")
19435 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19436 (match_operand:DI 2 "" "")))]
19437 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19438 {
19439 if (constant_call_address_operand (operands[1], Pmode))
19440 return "call\t%P1";
19441 return "call\t%A1";
19442 }
19443 [(set_attr "type" "callv")])
19444
19445 (define_insn "*sibcall_value_1_rex64"
19446 [(set (match_operand 0 "" "")
19447 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19448 (match_operand:DI 2 "" "")))]
19449 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19450 "jmp\t%P1"
19451 [(set_attr "type" "callv")])
19452
19453 (define_insn "*sibcall_value_1_rex64_v"
19454 [(set (match_operand 0 "" "")
19455 (call (mem:QI (reg:DI 40))
19456 (match_operand:DI 1 "" "")))]
19457 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19458 "jmp\t*%%r11"
19459 [(set_attr "type" "callv")])
19460 \f
19461 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19462 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19463 ;; caught for use by garbage collectors and the like. Using an insn that
19464 ;; maps to SIGILL makes it more likely the program will rightfully die.
19465 ;; Keeping with tradition, "6" is in honor of #UD.
19466 (define_insn "trap"
19467 [(trap_if (const_int 1) (const_int 6))]
19468 ""
19469 "ud2"
19470 [(set_attr "length" "2")])
19471
19472 (define_expand "sse_prologue_save"
19473 [(parallel [(set (match_operand:BLK 0 "" "")
19474 (unspec:BLK [(reg:DI 21)
19475 (reg:DI 22)
19476 (reg:DI 23)
19477 (reg:DI 24)
19478 (reg:DI 25)
19479 (reg:DI 26)
19480 (reg:DI 27)
19481 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19482 (use (match_operand:DI 1 "register_operand" ""))
19483 (use (match_operand:DI 2 "immediate_operand" ""))
19484 (use (label_ref:DI (match_operand 3 "" "")))])]
19485 "TARGET_64BIT"
19486 "")
19487
19488 (define_insn "*sse_prologue_save_insn"
19489 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19490 (match_operand:DI 4 "const_int_operand" "n")))
19491 (unspec:BLK [(reg:DI 21)
19492 (reg:DI 22)
19493 (reg:DI 23)
19494 (reg:DI 24)
19495 (reg:DI 25)
19496 (reg:DI 26)
19497 (reg:DI 27)
19498 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19499 (use (match_operand:DI 1 "register_operand" "r"))
19500 (use (match_operand:DI 2 "const_int_operand" "i"))
19501 (use (label_ref:DI (match_operand 3 "" "X")))]
19502 "TARGET_64BIT
19503 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19504 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19505 "*
19506 {
19507 int i;
19508 operands[0] = gen_rtx_MEM (Pmode,
19509 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19510 output_asm_insn (\"jmp\\t%A1\", operands);
19511 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19512 {
19513 operands[4] = adjust_address (operands[0], DImode, i*16);
19514 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19515 PUT_MODE (operands[4], TImode);
19516 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19517 output_asm_insn (\"rex\", operands);
19518 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19519 }
19520 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19521 CODE_LABEL_NUMBER (operands[3]));
19522 RET;
19523 }
19524 "
19525 [(set_attr "type" "other")
19526 (set_attr "length_immediate" "0")
19527 (set_attr "length_address" "0")
19528 (set_attr "length" "135")
19529 (set_attr "memory" "store")
19530 (set_attr "modrm" "0")
19531 (set_attr "mode" "DI")])
19532
19533 (define_expand "prefetch"
19534 [(prefetch (match_operand 0 "address_operand" "")
19535 (match_operand:SI 1 "const_int_operand" "")
19536 (match_operand:SI 2 "const_int_operand" ""))]
19537 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19538 {
19539 int rw = INTVAL (operands[1]);
19540 int locality = INTVAL (operands[2]);
19541
19542 gcc_assert (rw == 0 || rw == 1);
19543 gcc_assert (locality >= 0 && locality <= 3);
19544 gcc_assert (GET_MODE (operands[0]) == Pmode
19545 || GET_MODE (operands[0]) == VOIDmode);
19546
19547 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19548 supported by SSE counterpart or the SSE prefetch is not available
19549 (K6 machines). Otherwise use SSE prefetch as it allows specifying
19550 of locality. */
19551 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19552 operands[2] = GEN_INT (3);
19553 else
19554 operands[1] = const0_rtx;
19555 })
19556
19557 (define_insn "*prefetch_sse"
19558 [(prefetch (match_operand:SI 0 "address_operand" "p")
19559 (const_int 0)
19560 (match_operand:SI 1 "const_int_operand" ""))]
19561 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19562 {
19563 static const char * const patterns[4] = {
19564 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19565 };
19566
19567 int locality = INTVAL (operands[1]);
19568 gcc_assert (locality >= 0 && locality <= 3);
19569
19570 return patterns[locality];
19571 }
19572 [(set_attr "type" "sse")
19573 (set_attr "memory" "none")])
19574
19575 (define_insn "*prefetch_sse_rex"
19576 [(prefetch (match_operand:DI 0 "address_operand" "p")
19577 (const_int 0)
19578 (match_operand:SI 1 "const_int_operand" ""))]
19579 "TARGET_PREFETCH_SSE && TARGET_64BIT"
19580 {
19581 static const char * const patterns[4] = {
19582 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19583 };
19584
19585 int locality = INTVAL (operands[1]);
19586 gcc_assert (locality >= 0 && locality <= 3);
19587
19588 return patterns[locality];
19589 }
19590 [(set_attr "type" "sse")
19591 (set_attr "memory" "none")])
19592
19593 (define_insn "*prefetch_3dnow"
19594 [(prefetch (match_operand:SI 0 "address_operand" "p")
19595 (match_operand:SI 1 "const_int_operand" "n")
19596 (const_int 3))]
19597 "TARGET_3DNOW && !TARGET_64BIT"
19598 {
19599 if (INTVAL (operands[1]) == 0)
19600 return "prefetch\t%a0";
19601 else
19602 return "prefetchw\t%a0";
19603 }
19604 [(set_attr "type" "mmx")
19605 (set_attr "memory" "none")])
19606
19607 (define_insn "*prefetch_3dnow_rex"
19608 [(prefetch (match_operand:DI 0 "address_operand" "p")
19609 (match_operand:SI 1 "const_int_operand" "n")
19610 (const_int 3))]
19611 "TARGET_3DNOW && TARGET_64BIT"
19612 {
19613 if (INTVAL (operands[1]) == 0)
19614 return "prefetch\t%a0";
19615 else
19616 return "prefetchw\t%a0";
19617 }
19618 [(set_attr "type" "mmx")
19619 (set_attr "memory" "none")])
19620
19621 (define_expand "stack_protect_set"
19622 [(match_operand 0 "memory_operand" "")
19623 (match_operand 1 "memory_operand" "")]
19624 ""
19625 {
19626 #ifdef TARGET_THREAD_SSP_OFFSET
19627 if (TARGET_64BIT)
19628 emit_insn (gen_stack_tls_protect_set_di (operands[0],
19629 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19630 else
19631 emit_insn (gen_stack_tls_protect_set_si (operands[0],
19632 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19633 #else
19634 if (TARGET_64BIT)
19635 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
19636 else
19637 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
19638 #endif
19639 DONE;
19640 })
19641
19642 (define_insn "stack_protect_set_si"
19643 [(set (match_operand:SI 0 "memory_operand" "=m")
19644 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19645 (set (match_scratch:SI 2 "=&r") (const_int 0))
19646 (clobber (reg:CC FLAGS_REG))]
19647 ""
19648 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19649 [(set_attr "type" "multi")])
19650
19651 (define_insn "stack_protect_set_di"
19652 [(set (match_operand:DI 0 "memory_operand" "=m")
19653 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19654 (set (match_scratch:DI 2 "=&r") (const_int 0))
19655 (clobber (reg:CC FLAGS_REG))]
19656 "TARGET_64BIT"
19657 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19658 [(set_attr "type" "multi")])
19659
19660 (define_insn "stack_tls_protect_set_si"
19661 [(set (match_operand:SI 0 "memory_operand" "=m")
19662 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
19663 (set (match_scratch:SI 2 "=&r") (const_int 0))
19664 (clobber (reg:CC FLAGS_REG))]
19665 ""
19666 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19667 [(set_attr "type" "multi")])
19668
19669 (define_insn "stack_tls_protect_set_di"
19670 [(set (match_operand:DI 0 "memory_operand" "=m")
19671 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
19672 (set (match_scratch:DI 2 "=&r") (const_int 0))
19673 (clobber (reg:CC FLAGS_REG))]
19674 "TARGET_64BIT"
19675 "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19676 [(set_attr "type" "multi")])
19677
19678 (define_expand "stack_protect_test"
19679 [(match_operand 0 "memory_operand" "")
19680 (match_operand 1 "memory_operand" "")
19681 (match_operand 2 "" "")]
19682 ""
19683 {
19684 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19685 ix86_compare_op0 = operands[0];
19686 ix86_compare_op1 = operands[1];
19687 ix86_compare_emitted = flags;
19688
19689 #ifdef TARGET_THREAD_SSP_OFFSET
19690 if (TARGET_64BIT)
19691 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
19692 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19693 else
19694 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
19695 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19696 #else
19697 if (TARGET_64BIT)
19698 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
19699 else
19700 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
19701 #endif
19702 emit_jump_insn (gen_beq (operands[2]));
19703 DONE;
19704 })
19705
19706 (define_insn "stack_protect_test_si"
19707 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19708 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19709 (match_operand:SI 2 "memory_operand" "m")]
19710 UNSPEC_SP_TEST))
19711 (clobber (match_scratch:SI 3 "=&r"))]
19712 ""
19713 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
19714 [(set_attr "type" "multi")])
19715
19716 (define_insn "stack_protect_test_di"
19717 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19718 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19719 (match_operand:DI 2 "memory_operand" "m")]
19720 UNSPEC_SP_TEST))
19721 (clobber (match_scratch:DI 3 "=&r"))]
19722 "TARGET_64BIT"
19723 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
19724 [(set_attr "type" "multi")])
19725
19726 (define_insn "stack_tls_protect_test_si"
19727 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19728 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19729 (match_operand:SI 2 "const_int_operand" "i")]
19730 UNSPEC_SP_TLS_TEST))
19731 (clobber (match_scratch:SI 3 "=r"))]
19732 ""
19733 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
19734 [(set_attr "type" "multi")])
19735
19736 (define_insn "stack_tls_protect_test_di"
19737 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19738 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19739 (match_operand:DI 2 "const_int_operand" "i")]
19740 UNSPEC_SP_TLS_TEST))
19741 (clobber (match_scratch:DI 3 "=r"))]
19742 "TARGET_64BIT"
19743 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
19744 [(set_attr "type" "multi")])
19745
19746 (include "sse.md")
19747 (include "mmx.md")
19748 (include "sync.md")