0851dde2f8053a9677d8fd2793f4e0fe6444d11d
[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, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, 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_SIN 21)
78 (UNSPEC_COS 22)
79 (UNSPEC_FNSTSW 24)
80 (UNSPEC_SAHF 25)
81 (UNSPEC_FSTCW 26)
82 (UNSPEC_ADD_CARRY 27)
83 (UNSPEC_FLDCW 28)
84
85 ; For SSE/MMX support:
86 (UNSPEC_FIX 30)
87 (UNSPEC_MASKMOV 32)
88 (UNSPEC_MOVMSK 33)
89 (UNSPEC_MOVNT 34)
90 (UNSPEC_MOVA 38)
91 (UNSPEC_MOVU 39)
92 (UNSPEC_SHUFFLE 41)
93 (UNSPEC_RCP 42)
94 (UNSPEC_RSQRT 43)
95 (UNSPEC_SFENCE 44)
96 (UNSPEC_NOP 45) ; prevents combiner cleverness
97 (UNSPEC_PAVGUSB 49)
98 (UNSPEC_PFRCP 50)
99 (UNSPEC_PFRCPIT1 51)
100 (UNSPEC_PFRCPIT2 52)
101 (UNSPEC_PFRSQRT 53)
102 (UNSPEC_PFRSQIT1 54)
103 (UNSPEC_PSHUFLW 55)
104 (UNSPEC_PSHUFHW 56)
105 (UNSPEC_MFENCE 59)
106 (UNSPEC_LFENCE 60)
107 (UNSPEC_PSADBW 61)
108 (UNSPEC_ADDSUB 71)
109 (UNSPEC_HADD 72)
110 (UNSPEC_HSUB 73)
111 (UNSPEC_MOVSHDUP 74)
112 (UNSPEC_MOVSLDUP 75)
113 (UNSPEC_LDQQU 76)
114 (UNSPEC_MOVDDUP 77)
115
116 ; x87 Floating point
117 (UNSPEC_FPATAN 65)
118 (UNSPEC_FYL2X 66)
119 (UNSPEC_FYL2XP1 67)
120 (UNSPEC_FRNDINT 68)
121 (UNSPEC_F2XM1 69)
122
123 ; x87 Double output FP
124 (UNSPEC_SINCOS_COS 80)
125 (UNSPEC_SINCOS_SIN 81)
126 (UNSPEC_TAN_ONE 82)
127 (UNSPEC_TAN_TAN 83)
128 (UNSPEC_XTRACT_FRACT 84)
129 (UNSPEC_XTRACT_EXP 85)
130 (UNSPEC_FSCALE_FRACT 86)
131 (UNSPEC_FSCALE_EXP 87)
132 (UNSPEC_FPREM_F 88)
133 (UNSPEC_FPREM_U 89)
134 (UNSPEC_FPREM1_F 90)
135 (UNSPEC_FPREM1_U 91)
136
137 ; x87 Rounding
138 (UNSPEC_FRNDINT_FLOOR 96)
139 (UNSPEC_FRNDINT_CEIL 97)
140 (UNSPEC_FRNDINT_TRUNC 98)
141 (UNSPEC_FRNDINT_MASK_PM 99)
142
143 ; REP instruction
144 (UNSPEC_REP 75)
145
146 (UNSPEC_EH_RETURN 76)
147 ])
148
149 (define_constants
150 [(UNSPECV_BLOCKAGE 0)
151 (UNSPECV_STACK_PROBE 10)
152 (UNSPECV_EMMS 31)
153 (UNSPECV_LDMXCSR 37)
154 (UNSPECV_STMXCSR 40)
155 (UNSPECV_FEMMS 46)
156 (UNSPECV_CLFLUSH 57)
157 (UNSPECV_ALIGN 68)
158 (UNSPECV_MONITOR 69)
159 (UNSPECV_MWAIT 70)
160 ])
161
162 ;; Registers by name.
163 (define_constants
164 [(BP_REG 6)
165 (SP_REG 7)
166 (FLAGS_REG 17)
167 (FPSR_REG 18)
168 (DIRFLAG_REG 19)
169 ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first. This allows for better optimization. For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type. This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183 (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type. Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188 "other,multi,
189 alu,alu1,negnot,imov,imovx,lea,
190 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191 icmp,test,ibr,setcc,icmov,
192 push,pop,call,callv,leave,
193 str,cld,
194 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195 sselog,sseiadd,sseishft,sseimul,
196 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198 (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
203 (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208 (const_string "i387")
209 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211 (const_string "sse")
212 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213 (const_string "mmx")
214 (eq_attr "type" "other")
215 (const_string "unknown")]
216 (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221 (const_int 0)
222 (eq_attr "unit" "i387,sse,mmx")
223 (const_int 0)
224 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225 imul,icmp,push,pop")
226 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227 (eq_attr "type" "imov,test")
228 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229 (eq_attr "type" "call")
230 (if_then_else (match_operand 0 "constant_call_address_operand" "")
231 (const_int 4)
232 (const_int 0))
233 (eq_attr "type" "callv")
234 (if_then_else (match_operand 1 "constant_call_address_operand" "")
235 (const_int 4)
236 (const_int 0))
237 ;; We don't know the size before shorten_branches. Expect
238 ;; the instruction to fit for better scheduling.
239 (eq_attr "type" "ibr")
240 (const_int 1)
241 ]
242 (symbol_ref "/* Update immediate_length and other attributes! */
243 abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248 (const_int 0)
249 (and (eq_attr "type" "call")
250 (match_operand 0 "constant_call_address_operand" ""))
251 (const_int 0)
252 (and (eq_attr "type" "callv")
253 (match_operand 1 "constant_call_address_operand" ""))
254 (const_int 0)
255 ]
256 (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260 (if_then_else (ior (eq_attr "mode" "HI")
261 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262 (const_int 1)
263 (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" ""
267 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268 (const_int 1)
269 (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273 (if_then_else
274 (ior (eq_attr "type" "imovx,setcc,icmov")
275 (eq_attr "unit" "sse,mmx"))
276 (const_int 1)
277 (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281 (cond [(and (eq_attr "mode" "DI")
282 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283 (const_int 1)
284 (and (eq_attr "mode" "QI")
285 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286 (const_int 0)))
287 (const_int 1)
288 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289 (const_int 0))
290 (const_int 1)
291 ]
292 (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296 (cond [(eq_attr "type" "str,cld,leave")
297 (const_int 0)
298 (eq_attr "unit" "i387")
299 (const_int 0)
300 (and (eq_attr "type" "incdec")
301 (ior (match_operand:SI 1 "register_operand" "")
302 (match_operand:HI 1 "register_operand" "")))
303 (const_int 0)
304 (and (eq_attr "type" "push")
305 (not (match_operand 1 "memory_operand" "")))
306 (const_int 0)
307 (and (eq_attr "type" "pop")
308 (not (match_operand 0 "memory_operand" "")))
309 (const_int 0)
310 (and (eq_attr "type" "imov")
311 (and (match_operand 0 "register_operand" "")
312 (match_operand 1 "immediate_operand" "")))
313 (const_int 0)
314 (and (eq_attr "type" "call")
315 (match_operand 0 "constant_call_address_operand" ""))
316 (const_int 0)
317 (and (eq_attr "type" "callv")
318 (match_operand 1 "constant_call_address_operand" ""))
319 (const_int 0)
320 ]
321 (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328 (cond [(eq_attr "type" "other,multi,fistp,frndint")
329 (const_int 16)
330 (eq_attr "type" "fcmp")
331 (const_int 4)
332 (eq_attr "unit" "i387")
333 (plus (const_int 2)
334 (plus (attr "prefix_data16")
335 (attr "length_address")))]
336 (plus (plus (attr "modrm")
337 (plus (attr "prefix_0f")
338 (plus (attr "prefix_rex")
339 (const_int 1))))
340 (plus (attr "prefix_rep")
341 (plus (attr "prefix_data16")
342 (plus (attr "length_immediate")
343 (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350 (cond [(eq_attr "type" "other,multi,str")
351 (const_string "unknown")
352 (eq_attr "type" "lea,fcmov,fpspc,cld")
353 (const_string "none")
354 (eq_attr "type" "fistp,leave")
355 (const_string "both")
356 (eq_attr "type" "frndint")
357 (const_string "load")
358 (eq_attr "type" "push")
359 (if_then_else (match_operand 1 "memory_operand" "")
360 (const_string "both")
361 (const_string "store"))
362 (eq_attr "type" "pop")
363 (if_then_else (match_operand 0 "memory_operand" "")
364 (const_string "both")
365 (const_string "load"))
366 (eq_attr "type" "setcc")
367 (if_then_else (match_operand 0 "memory_operand" "")
368 (const_string "store")
369 (const_string "none"))
370 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371 (if_then_else (ior (match_operand 0 "memory_operand" "")
372 (match_operand 1 "memory_operand" ""))
373 (const_string "load")
374 (const_string "none"))
375 (eq_attr "type" "ibr")
376 (if_then_else (match_operand 0 "memory_operand" "")
377 (const_string "load")
378 (const_string "none"))
379 (eq_attr "type" "call")
380 (if_then_else (match_operand 0 "constant_call_address_operand" "")
381 (const_string "none")
382 (const_string "load"))
383 (eq_attr "type" "callv")
384 (if_then_else (match_operand 1 "constant_call_address_operand" "")
385 (const_string "none")
386 (const_string "load"))
387 (and (eq_attr "type" "alu1,negnot,ishift1")
388 (match_operand 1 "memory_operand" ""))
389 (const_string "both")
390 (and (match_operand 0 "memory_operand" "")
391 (match_operand 1 "memory_operand" ""))
392 (const_string "both")
393 (match_operand 0 "memory_operand" "")
394 (const_string "store")
395 (match_operand 1 "memory_operand" "")
396 (const_string "load")
397 (and (eq_attr "type"
398 "!alu1,negnot,ishift1,
399 imov,imovx,icmp,test,
400 fmov,fcmp,fsgn,
401 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402 mmx,mmxmov,mmxcmp,mmxcvt")
403 (match_operand 2 "memory_operand" ""))
404 (const_string "load")
405 (and (eq_attr "type" "icmov")
406 (match_operand 3 "memory_operand" ""))
407 (const_string "load")
408 ]
409 (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414 (cond [(eq_attr "type" "other,multi")
415 (const_string "unknown")
416 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417 (and (match_operand 0 "memory_displacement_operand" "")
418 (match_operand 1 "immediate_operand" "")))
419 (const_string "true")
420 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421 (and (match_operand 0 "memory_displacement_operand" "")
422 (match_operand 2 "immediate_operand" "")))
423 (const_string "true")
424 ]
425 (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430 (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435 (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439 [(set_attr "length" "128")
440 (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462 [(set (reg:CC FLAGS_REG)
463 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464 (match_operand:DI 1 "x86_64_general_operand" "")))]
465 ""
466 {
467 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468 operands[0] = force_reg (DImode, operands[0]);
469 ix86_compare_op0 = operands[0];
470 ix86_compare_op1 = operands[1];
471 DONE;
472 })
473
474 (define_expand "cmpsi"
475 [(set (reg:CC FLAGS_REG)
476 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477 (match_operand:SI 1 "general_operand" "")))]
478 ""
479 {
480 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481 operands[0] = force_reg (SImode, operands[0]);
482 ix86_compare_op0 = operands[0];
483 ix86_compare_op1 = operands[1];
484 DONE;
485 })
486
487 (define_expand "cmphi"
488 [(set (reg:CC FLAGS_REG)
489 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490 (match_operand:HI 1 "general_operand" "")))]
491 ""
492 {
493 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494 operands[0] = force_reg (HImode, operands[0]);
495 ix86_compare_op0 = operands[0];
496 ix86_compare_op1 = operands[1];
497 DONE;
498 })
499
500 (define_expand "cmpqi"
501 [(set (reg:CC FLAGS_REG)
502 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503 (match_operand:QI 1 "general_operand" "")))]
504 "TARGET_QIMODE_MATH"
505 {
506 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507 operands[0] = force_reg (QImode, operands[0]);
508 ix86_compare_op0 = operands[0];
509 ix86_compare_op1 = operands[1];
510 DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514 [(set (reg FLAGS_REG)
515 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516 (match_operand:DI 1 "const0_operand" "n,n")))]
517 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518 "@
519 test{q}\t{%0, %0|%0, %0}
520 cmp{q}\t{%1, %0|%0, %1}"
521 [(set_attr "type" "test,icmp")
522 (set_attr "length_immediate" "0,1")
523 (set_attr "mode" "DI")])
524
525 (define_insn "*cmpdi_minus_1_rex64"
526 [(set (reg FLAGS_REG)
527 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529 (const_int 0)))]
530 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531 "cmp{q}\t{%1, %0|%0, %1}"
532 [(set_attr "type" "icmp")
533 (set_attr "mode" "DI")])
534
535 (define_expand "cmpdi_1_rex64"
536 [(set (reg:CC FLAGS_REG)
537 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538 (match_operand:DI 1 "general_operand" "")))]
539 "TARGET_64BIT"
540 "")
541
542 (define_insn "cmpdi_1_insn_rex64"
543 [(set (reg FLAGS_REG)
544 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547 "cmp{q}\t{%1, %0|%0, %1}"
548 [(set_attr "type" "icmp")
549 (set_attr "mode" "DI")])
550
551
552 (define_insn "*cmpsi_ccno_1"
553 [(set (reg FLAGS_REG)
554 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555 (match_operand:SI 1 "const0_operand" "n,n")))]
556 "ix86_match_ccmode (insn, CCNOmode)"
557 "@
558 test{l}\t{%0, %0|%0, %0}
559 cmp{l}\t{%1, %0|%0, %1}"
560 [(set_attr "type" "test,icmp")
561 (set_attr "length_immediate" "0,1")
562 (set_attr "mode" "SI")])
563
564 (define_insn "*cmpsi_minus_1"
565 [(set (reg FLAGS_REG)
566 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567 (match_operand:SI 1 "general_operand" "ri,mr"))
568 (const_int 0)))]
569 "ix86_match_ccmode (insn, CCGOCmode)"
570 "cmp{l}\t{%1, %0|%0, %1}"
571 [(set_attr "type" "icmp")
572 (set_attr "mode" "SI")])
573
574 (define_expand "cmpsi_1"
575 [(set (reg:CC FLAGS_REG)
576 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577 (match_operand:SI 1 "general_operand" "ri,mr")))]
578 ""
579 "")
580
581 (define_insn "*cmpsi_1_insn"
582 [(set (reg FLAGS_REG)
583 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584 (match_operand:SI 1 "general_operand" "ri,mr")))]
585 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586 && ix86_match_ccmode (insn, CCmode)"
587 "cmp{l}\t{%1, %0|%0, %1}"
588 [(set_attr "type" "icmp")
589 (set_attr "mode" "SI")])
590
591 (define_insn "*cmphi_ccno_1"
592 [(set (reg FLAGS_REG)
593 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594 (match_operand:HI 1 "const0_operand" "n,n")))]
595 "ix86_match_ccmode (insn, CCNOmode)"
596 "@
597 test{w}\t{%0, %0|%0, %0}
598 cmp{w}\t{%1, %0|%0, %1}"
599 [(set_attr "type" "test,icmp")
600 (set_attr "length_immediate" "0,1")
601 (set_attr "mode" "HI")])
602
603 (define_insn "*cmphi_minus_1"
604 [(set (reg FLAGS_REG)
605 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606 (match_operand:HI 1 "general_operand" "ri,mr"))
607 (const_int 0)))]
608 "ix86_match_ccmode (insn, CCGOCmode)"
609 "cmp{w}\t{%1, %0|%0, %1}"
610 [(set_attr "type" "icmp")
611 (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_1"
614 [(set (reg FLAGS_REG)
615 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616 (match_operand:HI 1 "general_operand" "ri,mr")))]
617 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618 && ix86_match_ccmode (insn, CCmode)"
619 "cmp{w}\t{%1, %0|%0, %1}"
620 [(set_attr "type" "icmp")
621 (set_attr "mode" "HI")])
622
623 (define_insn "*cmpqi_ccno_1"
624 [(set (reg FLAGS_REG)
625 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626 (match_operand:QI 1 "const0_operand" "n,n")))]
627 "ix86_match_ccmode (insn, CCNOmode)"
628 "@
629 test{b}\t{%0, %0|%0, %0}
630 cmp{b}\t{$0, %0|%0, 0}"
631 [(set_attr "type" "test,icmp")
632 (set_attr "length_immediate" "0,1")
633 (set_attr "mode" "QI")])
634
635 (define_insn "*cmpqi_1"
636 [(set (reg FLAGS_REG)
637 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638 (match_operand:QI 1 "general_operand" "qi,mq")))]
639 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640 && ix86_match_ccmode (insn, CCmode)"
641 "cmp{b}\t{%1, %0|%0, %1}"
642 [(set_attr "type" "icmp")
643 (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_minus_1"
646 [(set (reg FLAGS_REG)
647 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648 (match_operand:QI 1 "general_operand" "qi,mq"))
649 (const_int 0)))]
650 "ix86_match_ccmode (insn, CCGOCmode)"
651 "cmp{b}\t{%1, %0|%0, %1}"
652 [(set_attr "type" "icmp")
653 (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1"
656 [(set (reg FLAGS_REG)
657 (compare
658 (match_operand:QI 0 "general_operand" "Qm")
659 (subreg:QI
660 (zero_extract:SI
661 (match_operand 1 "ext_register_operand" "Q")
662 (const_int 8)
663 (const_int 8)) 0)))]
664 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665 "cmp{b}\t{%h1, %0|%0, %h1}"
666 [(set_attr "type" "icmp")
667 (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_1_rex64"
670 [(set (reg FLAGS_REG)
671 (compare
672 (match_operand:QI 0 "register_operand" "Q")
673 (subreg:QI
674 (zero_extract:SI
675 (match_operand 1 "ext_register_operand" "Q")
676 (const_int 8)
677 (const_int 8)) 0)))]
678 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679 "cmp{b}\t{%h1, %0|%0, %h1}"
680 [(set_attr "type" "icmp")
681 (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_2"
684 [(set (reg FLAGS_REG)
685 (compare
686 (subreg:QI
687 (zero_extract:SI
688 (match_operand 0 "ext_register_operand" "Q")
689 (const_int 8)
690 (const_int 8)) 0)
691 (match_operand:QI 1 "const0_operand" "n")))]
692 "ix86_match_ccmode (insn, CCNOmode)"
693 "test{b}\t%h0, %h0"
694 [(set_attr "type" "test")
695 (set_attr "length_immediate" "0")
696 (set_attr "mode" "QI")])
697
698 (define_expand "cmpqi_ext_3"
699 [(set (reg:CC FLAGS_REG)
700 (compare:CC
701 (subreg:QI
702 (zero_extract:SI
703 (match_operand 0 "ext_register_operand" "")
704 (const_int 8)
705 (const_int 8)) 0)
706 (match_operand:QI 1 "general_operand" "")))]
707 ""
708 "")
709
710 (define_insn "cmpqi_ext_3_insn"
711 [(set (reg FLAGS_REG)
712 (compare
713 (subreg:QI
714 (zero_extract:SI
715 (match_operand 0 "ext_register_operand" "Q")
716 (const_int 8)
717 (const_int 8)) 0)
718 (match_operand:QI 1 "general_operand" "Qmn")))]
719 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720 "cmp{b}\t{%1, %h0|%h0, %1}"
721 [(set_attr "type" "icmp")
722 (set_attr "mode" "QI")])
723
724 (define_insn "cmpqi_ext_3_insn_rex64"
725 [(set (reg FLAGS_REG)
726 (compare
727 (subreg:QI
728 (zero_extract:SI
729 (match_operand 0 "ext_register_operand" "Q")
730 (const_int 8)
731 (const_int 8)) 0)
732 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734 "cmp{b}\t{%1, %h0|%h0, %1}"
735 [(set_attr "type" "icmp")
736 (set_attr "mode" "QI")])
737
738 (define_insn "*cmpqi_ext_4"
739 [(set (reg FLAGS_REG)
740 (compare
741 (subreg:QI
742 (zero_extract:SI
743 (match_operand 0 "ext_register_operand" "Q")
744 (const_int 8)
745 (const_int 8)) 0)
746 (subreg:QI
747 (zero_extract:SI
748 (match_operand 1 "ext_register_operand" "Q")
749 (const_int 8)
750 (const_int 8)) 0)))]
751 "ix86_match_ccmode (insn, CCmode)"
752 "cmp{b}\t{%h1, %h0|%h0, %h1}"
753 [(set_attr "type" "icmp")
754 (set_attr "mode" "QI")])
755
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares. Which is what
759 ;; the old patterns did, but with many more of them.
760
761 (define_expand "cmpxf"
762 [(set (reg:CC FLAGS_REG)
763 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765 "TARGET_80387"
766 {
767 ix86_compare_op0 = operands[0];
768 ix86_compare_op1 = operands[1];
769 DONE;
770 })
771
772 (define_expand "cmpdf"
773 [(set (reg:CC FLAGS_REG)
774 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776 "TARGET_80387 || TARGET_SSE2"
777 {
778 ix86_compare_op0 = operands[0];
779 ix86_compare_op1 = operands[1];
780 DONE;
781 })
782
783 (define_expand "cmpsf"
784 [(set (reg:CC FLAGS_REG)
785 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787 "TARGET_80387 || TARGET_SSE"
788 {
789 ix86_compare_op0 = operands[0];
790 ix86_compare_op1 = operands[1];
791 DONE;
792 })
793
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
796 ;;
797 ;; CCFPmode compare with exceptions
798 ;; CCFPUmode compare with no exceptions
799
800 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
801 ;; used to manage the reg stack popping would not be preserved.
802
803 (define_insn "*cmpfp_0_sf"
804 [(set (match_operand:HI 0 "register_operand" "=a")
805 (unspec:HI
806 [(compare:CCFP
807 (match_operand:SF 1 "register_operand" "f")
808 (match_operand:SF 2 "const0_operand" "X"))]
809 UNSPEC_FNSTSW))]
810 "TARGET_80387"
811 "* return output_fp_compare (insn, operands, 0, 0);"
812 [(set_attr "type" "multi")
813 (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_0_df"
816 [(set (match_operand:HI 0 "register_operand" "=a")
817 (unspec:HI
818 [(compare:CCFP
819 (match_operand:DF 1 "register_operand" "f")
820 (match_operand:DF 2 "const0_operand" "X"))]
821 UNSPEC_FNSTSW))]
822 "TARGET_80387"
823 "* return output_fp_compare (insn, operands, 0, 0);"
824 [(set_attr "type" "multi")
825 (set_attr "mode" "DF")])
826
827 (define_insn "*cmpfp_0_xf"
828 [(set (match_operand:HI 0 "register_operand" "=a")
829 (unspec:HI
830 [(compare:CCFP
831 (match_operand:XF 1 "register_operand" "f")
832 (match_operand:XF 2 "const0_operand" "X"))]
833 UNSPEC_FNSTSW))]
834 "TARGET_80387"
835 "* return output_fp_compare (insn, operands, 0, 0);"
836 [(set_attr "type" "multi")
837 (set_attr "mode" "XF")])
838
839 (define_insn "*cmpfp_sf"
840 [(set (match_operand:HI 0 "register_operand" "=a")
841 (unspec:HI
842 [(compare:CCFP
843 (match_operand:SF 1 "register_operand" "f")
844 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845 UNSPEC_FNSTSW))]
846 "TARGET_80387"
847 "* return output_fp_compare (insn, operands, 0, 0);"
848 [(set_attr "type" "multi")
849 (set_attr "mode" "SF")])
850
851 (define_insn "*cmpfp_df"
852 [(set (match_operand:HI 0 "register_operand" "=a")
853 (unspec:HI
854 [(compare:CCFP
855 (match_operand:DF 1 "register_operand" "f")
856 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857 UNSPEC_FNSTSW))]
858 "TARGET_80387"
859 "* return output_fp_compare (insn, operands, 0, 0);"
860 [(set_attr "type" "multi")
861 (set_attr "mode" "DF")])
862
863 (define_insn "*cmpfp_xf"
864 [(set (match_operand:HI 0 "register_operand" "=a")
865 (unspec:HI
866 [(compare:CCFP
867 (match_operand:XF 1 "register_operand" "f")
868 (match_operand:XF 2 "register_operand" "f"))]
869 UNSPEC_FNSTSW))]
870 "TARGET_80387"
871 "* return output_fp_compare (insn, operands, 0, 0);"
872 [(set_attr "type" "multi")
873 (set_attr "mode" "XF")])
874
875 (define_insn "*cmpfp_u"
876 [(set (match_operand:HI 0 "register_operand" "=a")
877 (unspec:HI
878 [(compare:CCFPU
879 (match_operand 1 "register_operand" "f")
880 (match_operand 2 "register_operand" "f"))]
881 UNSPEC_FNSTSW))]
882 "TARGET_80387
883 && FLOAT_MODE_P (GET_MODE (operands[1]))
884 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
885 "* return output_fp_compare (insn, operands, 0, 1);"
886 [(set_attr "type" "multi")
887 (set (attr "mode")
888 (cond [(match_operand:SF 1 "" "")
889 (const_string "SF")
890 (match_operand:DF 1 "" "")
891 (const_string "DF")
892 ]
893 (const_string "XF")))])
894
895 (define_insn "*cmpfp_si"
896 [(set (match_operand:HI 0 "register_operand" "=a")
897 (unspec:HI
898 [(compare:CCFP
899 (match_operand 1 "register_operand" "f")
900 (match_operator 3 "float_operator"
901 [(match_operand:SI 2 "memory_operand" "m")]))]
902 UNSPEC_FNSTSW))]
903 "TARGET_80387 && TARGET_USE_FIOP
904 && FLOAT_MODE_P (GET_MODE (operands[1]))
905 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906 "* return output_fp_compare (insn, operands, 0, 0);"
907 [(set_attr "type" "multi")
908 (set_attr "fp_int_src" "true")
909 (set_attr "mode" "SI")])
910
911 ;; FP compares, step 2
912 ;; Move the fpsw to ax.
913
914 (define_insn "x86_fnstsw_1"
915 [(set (match_operand:HI 0 "register_operand" "=a")
916 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
917 "TARGET_80387"
918 "fnstsw\t%0"
919 [(set_attr "length" "2")
920 (set_attr "mode" "SI")
921 (set_attr "unit" "i387")])
922
923 ;; FP compares, step 3
924 ;; Get ax into flags, general case.
925
926 (define_insn "x86_sahf_1"
927 [(set (reg:CC FLAGS_REG)
928 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
929 "!TARGET_64BIT"
930 "sahf"
931 [(set_attr "length" "1")
932 (set_attr "athlon_decode" "vector")
933 (set_attr "mode" "SI")])
934
935 ;; Pentium Pro can do steps 1 through 3 in one go.
936
937 (define_insn "*cmpfp_i"
938 [(set (reg:CCFP FLAGS_REG)
939 (compare:CCFP (match_operand 0 "register_operand" "f")
940 (match_operand 1 "register_operand" "f")))]
941 "TARGET_80387 && TARGET_CMOVE
942 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
943 && FLOAT_MODE_P (GET_MODE (operands[0]))
944 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945 "* return output_fp_compare (insn, operands, 1, 0);"
946 [(set_attr "type" "fcmp")
947 (set (attr "mode")
948 (cond [(match_operand:SF 1 "" "")
949 (const_string "SF")
950 (match_operand:DF 1 "" "")
951 (const_string "DF")
952 ]
953 (const_string "XF")))
954 (set_attr "athlon_decode" "vector")])
955
956 (define_insn "*cmpfp_i_sse"
957 [(set (reg:CCFP FLAGS_REG)
958 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960 "TARGET_80387
961 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963 "* return output_fp_compare (insn, operands, 1, 0);"
964 [(set_attr "type" "fcmp,ssecomi")
965 (set (attr "mode")
966 (if_then_else (match_operand:SF 1 "" "")
967 (const_string "SF")
968 (const_string "DF")))
969 (set_attr "athlon_decode" "vector")])
970
971 (define_insn "*cmpfp_i_sse_only"
972 [(set (reg:CCFP FLAGS_REG)
973 (compare:CCFP (match_operand 0 "register_operand" "x")
974 (match_operand 1 "nonimmediate_operand" "xm")))]
975 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977 "* return output_fp_compare (insn, operands, 1, 0);"
978 [(set_attr "type" "ssecomi")
979 (set (attr "mode")
980 (if_then_else (match_operand:SF 1 "" "")
981 (const_string "SF")
982 (const_string "DF")))
983 (set_attr "athlon_decode" "vector")])
984
985 (define_insn "*cmpfp_iu"
986 [(set (reg:CCFPU FLAGS_REG)
987 (compare:CCFPU (match_operand 0 "register_operand" "f")
988 (match_operand 1 "register_operand" "f")))]
989 "TARGET_80387 && TARGET_CMOVE
990 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991 && FLOAT_MODE_P (GET_MODE (operands[0]))
992 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993 "* return output_fp_compare (insn, operands, 1, 1);"
994 [(set_attr "type" "fcmp")
995 (set (attr "mode")
996 (cond [(match_operand:SF 1 "" "")
997 (const_string "SF")
998 (match_operand:DF 1 "" "")
999 (const_string "DF")
1000 ]
1001 (const_string "XF")))
1002 (set_attr "athlon_decode" "vector")])
1003
1004 (define_insn "*cmpfp_iu_sse"
1005 [(set (reg:CCFPU FLAGS_REG)
1006 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1007 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008 "TARGET_80387
1009 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011 "* return output_fp_compare (insn, operands, 1, 1);"
1012 [(set_attr "type" "fcmp,ssecomi")
1013 (set (attr "mode")
1014 (if_then_else (match_operand:SF 1 "" "")
1015 (const_string "SF")
1016 (const_string "DF")))
1017 (set_attr "athlon_decode" "vector")])
1018
1019 (define_insn "*cmpfp_iu_sse_only"
1020 [(set (reg:CCFPU FLAGS_REG)
1021 (compare:CCFPU (match_operand 0 "register_operand" "x")
1022 (match_operand 1 "nonimmediate_operand" "xm")))]
1023 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025 "* return output_fp_compare (insn, operands, 1, 1);"
1026 [(set_attr "type" "ssecomi")
1027 (set (attr "mode")
1028 (if_then_else (match_operand:SF 1 "" "")
1029 (const_string "SF")
1030 (const_string "DF")))
1031 (set_attr "athlon_decode" "vector")])
1032 \f
1033 ;; Move instructions.
1034
1035 ;; General case of fullword move.
1036
1037 (define_expand "movsi"
1038 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039 (match_operand:SI 1 "general_operand" ""))]
1040 ""
1041 "ix86_expand_move (SImode, operands); DONE;")
1042
1043 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1044 ;; general_operand.
1045 ;;
1046 ;; %%% We don't use a post-inc memory reference because x86 is not a
1047 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049 ;; targets without our curiosities, and it is just as easy to represent
1050 ;; this differently.
1051
1052 (define_insn "*pushsi2"
1053 [(set (match_operand:SI 0 "push_operand" "=<")
1054 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1055 "!TARGET_64BIT"
1056 "push{l}\t%1"
1057 [(set_attr "type" "push")
1058 (set_attr "mode" "SI")])
1059
1060 ;; For 64BIT abi we always round up to 8 bytes.
1061 (define_insn "*pushsi2_rex64"
1062 [(set (match_operand:SI 0 "push_operand" "=X")
1063 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064 "TARGET_64BIT"
1065 "push{q}\t%q1"
1066 [(set_attr "type" "push")
1067 (set_attr "mode" "SI")])
1068
1069 (define_insn "*pushsi2_prologue"
1070 [(set (match_operand:SI 0 "push_operand" "=<")
1071 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1072 (clobber (mem:BLK (scratch)))]
1073 "!TARGET_64BIT"
1074 "push{l}\t%1"
1075 [(set_attr "type" "push")
1076 (set_attr "mode" "SI")])
1077
1078 (define_insn "*popsi1_epilogue"
1079 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1080 (mem:SI (reg:SI SP_REG)))
1081 (set (reg:SI SP_REG)
1082 (plus:SI (reg:SI SP_REG) (const_int 4)))
1083 (clobber (mem:BLK (scratch)))]
1084 "!TARGET_64BIT"
1085 "pop{l}\t%0"
1086 [(set_attr "type" "pop")
1087 (set_attr "mode" "SI")])
1088
1089 (define_insn "popsi1"
1090 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1091 (mem:SI (reg:SI SP_REG)))
1092 (set (reg:SI SP_REG)
1093 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1094 "!TARGET_64BIT"
1095 "pop{l}\t%0"
1096 [(set_attr "type" "pop")
1097 (set_attr "mode" "SI")])
1098
1099 (define_insn "*movsi_xor"
1100 [(set (match_operand:SI 0 "register_operand" "=r")
1101 (match_operand:SI 1 "const0_operand" "i"))
1102 (clobber (reg:CC FLAGS_REG))]
1103 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1104 "xor{l}\t{%0, %0|%0, %0}"
1105 [(set_attr "type" "alu1")
1106 (set_attr "mode" "SI")
1107 (set_attr "length_immediate" "0")])
1108
1109 (define_insn "*movsi_or"
1110 [(set (match_operand:SI 0 "register_operand" "=r")
1111 (match_operand:SI 1 "immediate_operand" "i"))
1112 (clobber (reg:CC FLAGS_REG))]
1113 "reload_completed
1114 && operands[1] == constm1_rtx
1115 && (TARGET_PENTIUM || optimize_size)"
1116 {
1117 operands[1] = constm1_rtx;
1118 return "or{l}\t{%1, %0|%0, %1}";
1119 }
1120 [(set_attr "type" "alu1")
1121 (set_attr "mode" "SI")
1122 (set_attr "length_immediate" "1")])
1123
1124 (define_insn "*movsi_1"
1125 [(set (match_operand:SI 0 "nonimmediate_operand"
1126 "=r ,m ,!*y,!rm,!*y,!*x,!rm,!*x")
1127 (match_operand:SI 1 "general_operand"
1128 "rinm,rin,*y ,*y ,rm ,*x ,*x ,rm"))]
1129 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1130 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1131 {
1132 switch (get_attr_type (insn))
1133 {
1134 case TYPE_SSEMOV:
1135 if (get_attr_mode (insn) == MODE_TI)
1136 return "movdqa\t{%1, %0|%0, %1}";
1137 return "movd\t{%1, %0|%0, %1}";
1138
1139 case TYPE_MMXMOV:
1140 if (get_attr_mode (insn) == MODE_DI)
1141 return "movq\t{%1, %0|%0, %1}";
1142 return "movd\t{%1, %0|%0, %1}";
1143
1144 case TYPE_LEA:
1145 return "lea{l}\t{%1, %0|%0, %1}";
1146
1147 default:
1148 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1149 abort();
1150 return "mov{l}\t{%1, %0|%0, %1}";
1151 }
1152 }
1153 [(set (attr "type")
1154 (cond [(eq_attr "alternative" "2,3,4")
1155 (const_string "mmxmov")
1156 (eq_attr "alternative" "5,6,7")
1157 (const_string "ssemov")
1158 (and (ne (symbol_ref "flag_pic") (const_int 0))
1159 (match_operand:SI 1 "symbolic_operand" ""))
1160 (const_string "lea")
1161 ]
1162 (const_string "imov")))
1163 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1164
1165 (define_insn "*movsi_1_nointernunit"
1166 [(set (match_operand:SI 0 "nonimmediate_operand"
1167 "=r ,m ,!*y,!m,!*y,!*x,!m,!*x")
1168 (match_operand:SI 1 "general_operand"
1169 "rinm,rin,*y ,*y,m ,*x ,*x,m"))]
1170 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1171 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1172 {
1173 switch (get_attr_type (insn))
1174 {
1175 case TYPE_SSEMOV:
1176 if (get_attr_mode (insn) == MODE_TI)
1177 return "movdqa\t{%1, %0|%0, %1}";
1178 return "movd\t{%1, %0|%0, %1}";
1179
1180 case TYPE_MMXMOV:
1181 if (get_attr_mode (insn) == MODE_DI)
1182 return "movq\t{%1, %0|%0, %1}";
1183 return "movd\t{%1, %0|%0, %1}";
1184
1185 case TYPE_LEA:
1186 return "lea{l}\t{%1, %0|%0, %1}";
1187
1188 default:
1189 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1190 abort();
1191 return "mov{l}\t{%1, %0|%0, %1}";
1192 }
1193 }
1194 [(set (attr "type")
1195 (cond [(eq_attr "alternative" "2,3,4")
1196 (const_string "mmxmov")
1197 (eq_attr "alternative" "5,6,7")
1198 (const_string "ssemov")
1199 (and (ne (symbol_ref "flag_pic") (const_int 0))
1200 (match_operand:SI 1 "symbolic_operand" ""))
1201 (const_string "lea")
1202 ]
1203 (const_string "imov")))
1204 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1205
1206 ;; Stores and loads of ax to arbitrary constant address.
1207 ;; We fake an second form of instruction to force reload to load address
1208 ;; into register when rax is not available
1209 (define_insn "*movabssi_1_rex64"
1210 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1211 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1212 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1213 "@
1214 movabs{l}\t{%1, %P0|%P0, %1}
1215 mov{l}\t{%1, %a0|%a0, %1}"
1216 [(set_attr "type" "imov")
1217 (set_attr "modrm" "0,*")
1218 (set_attr "length_address" "8,0")
1219 (set_attr "length_immediate" "0,*")
1220 (set_attr "memory" "store")
1221 (set_attr "mode" "SI")])
1222
1223 (define_insn "*movabssi_2_rex64"
1224 [(set (match_operand:SI 0 "register_operand" "=a,r")
1225 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1226 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1227 "@
1228 movabs{l}\t{%P1, %0|%0, %P1}
1229 mov{l}\t{%a1, %0|%0, %a1}"
1230 [(set_attr "type" "imov")
1231 (set_attr "modrm" "0,*")
1232 (set_attr "length_address" "8,0")
1233 (set_attr "length_immediate" "0")
1234 (set_attr "memory" "load")
1235 (set_attr "mode" "SI")])
1236
1237 (define_insn "*swapsi"
1238 [(set (match_operand:SI 0 "register_operand" "+r")
1239 (match_operand:SI 1 "register_operand" "+r"))
1240 (set (match_dup 1)
1241 (match_dup 0))]
1242 ""
1243 "xchg{l}\t%1, %0"
1244 [(set_attr "type" "imov")
1245 (set_attr "mode" "SI")
1246 (set_attr "pent_pair" "np")
1247 (set_attr "athlon_decode" "vector")])
1248
1249 (define_expand "movhi"
1250 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1251 (match_operand:HI 1 "general_operand" ""))]
1252 ""
1253 "ix86_expand_move (HImode, operands); DONE;")
1254
1255 (define_insn "*pushhi2"
1256 [(set (match_operand:HI 0 "push_operand" "=<,<")
1257 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1258 "!TARGET_64BIT"
1259 "@
1260 push{w}\t{|WORD PTR }%1
1261 push{w}\t%1"
1262 [(set_attr "type" "push")
1263 (set_attr "mode" "HI")])
1264
1265 ;; For 64BIT abi we always round up to 8 bytes.
1266 (define_insn "*pushhi2_rex64"
1267 [(set (match_operand:HI 0 "push_operand" "=X")
1268 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1269 "TARGET_64BIT"
1270 "push{q}\t%q1"
1271 [(set_attr "type" "push")
1272 (set_attr "mode" "QI")])
1273
1274 (define_insn "*movhi_1"
1275 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1276 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1277 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1278 {
1279 switch (get_attr_type (insn))
1280 {
1281 case TYPE_IMOVX:
1282 /* movzwl is faster than movw on p2 due to partial word stalls,
1283 though not as fast as an aligned movl. */
1284 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1285 default:
1286 if (get_attr_mode (insn) == MODE_SI)
1287 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1288 else
1289 return "mov{w}\t{%1, %0|%0, %1}";
1290 }
1291 }
1292 [(set (attr "type")
1293 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1294 (const_string "imov")
1295 (and (eq_attr "alternative" "0")
1296 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1297 (const_int 0))
1298 (eq (symbol_ref "TARGET_HIMODE_MATH")
1299 (const_int 0))))
1300 (const_string "imov")
1301 (and (eq_attr "alternative" "1,2")
1302 (match_operand:HI 1 "aligned_operand" ""))
1303 (const_string "imov")
1304 (and (ne (symbol_ref "TARGET_MOVX")
1305 (const_int 0))
1306 (eq_attr "alternative" "0,2"))
1307 (const_string "imovx")
1308 ]
1309 (const_string "imov")))
1310 (set (attr "mode")
1311 (cond [(eq_attr "type" "imovx")
1312 (const_string "SI")
1313 (and (eq_attr "alternative" "1,2")
1314 (match_operand:HI 1 "aligned_operand" ""))
1315 (const_string "SI")
1316 (and (eq_attr "alternative" "0")
1317 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318 (const_int 0))
1319 (eq (symbol_ref "TARGET_HIMODE_MATH")
1320 (const_int 0))))
1321 (const_string "SI")
1322 ]
1323 (const_string "HI")))])
1324
1325 ;; Stores and loads of ax to arbitrary constant address.
1326 ;; We fake an second form of instruction to force reload to load address
1327 ;; into register when rax is not available
1328 (define_insn "*movabshi_1_rex64"
1329 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1330 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1331 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1332 "@
1333 movabs{w}\t{%1, %P0|%P0, %1}
1334 mov{w}\t{%1, %a0|%a0, %1}"
1335 [(set_attr "type" "imov")
1336 (set_attr "modrm" "0,*")
1337 (set_attr "length_address" "8,0")
1338 (set_attr "length_immediate" "0,*")
1339 (set_attr "memory" "store")
1340 (set_attr "mode" "HI")])
1341
1342 (define_insn "*movabshi_2_rex64"
1343 [(set (match_operand:HI 0 "register_operand" "=a,r")
1344 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1345 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1346 "@
1347 movabs{w}\t{%P1, %0|%0, %P1}
1348 mov{w}\t{%a1, %0|%0, %a1}"
1349 [(set_attr "type" "imov")
1350 (set_attr "modrm" "0,*")
1351 (set_attr "length_address" "8,0")
1352 (set_attr "length_immediate" "0")
1353 (set_attr "memory" "load")
1354 (set_attr "mode" "HI")])
1355
1356 (define_insn "*swaphi_1"
1357 [(set (match_operand:HI 0 "register_operand" "+r")
1358 (match_operand:HI 1 "register_operand" "+r"))
1359 (set (match_dup 1)
1360 (match_dup 0))]
1361 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1362 "xchg{l}\t%k1, %k0"
1363 [(set_attr "type" "imov")
1364 (set_attr "mode" "SI")
1365 (set_attr "pent_pair" "np")
1366 (set_attr "athlon_decode" "vector")])
1367
1368 (define_insn "*swaphi_2"
1369 [(set (match_operand:HI 0 "register_operand" "+r")
1370 (match_operand:HI 1 "register_operand" "+r"))
1371 (set (match_dup 1)
1372 (match_dup 0))]
1373 "TARGET_PARTIAL_REG_STALL"
1374 "xchg{w}\t%1, %0"
1375 [(set_attr "type" "imov")
1376 (set_attr "mode" "HI")
1377 (set_attr "pent_pair" "np")
1378 (set_attr "athlon_decode" "vector")])
1379
1380 (define_expand "movstricthi"
1381 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1382 (match_operand:HI 1 "general_operand" ""))]
1383 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1384 {
1385 /* Don't generate memory->memory moves, go through a register */
1386 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1387 operands[1] = force_reg (HImode, operands[1]);
1388 })
1389
1390 (define_insn "*movstricthi_1"
1391 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1392 (match_operand:HI 1 "general_operand" "rn,m"))]
1393 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1394 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1395 "mov{w}\t{%1, %0|%0, %1}"
1396 [(set_attr "type" "imov")
1397 (set_attr "mode" "HI")])
1398
1399 (define_insn "*movstricthi_xor"
1400 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1401 (match_operand:HI 1 "const0_operand" "i"))
1402 (clobber (reg:CC FLAGS_REG))]
1403 "reload_completed
1404 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1405 "xor{w}\t{%0, %0|%0, %0}"
1406 [(set_attr "type" "alu1")
1407 (set_attr "mode" "HI")
1408 (set_attr "length_immediate" "0")])
1409
1410 (define_expand "movqi"
1411 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1412 (match_operand:QI 1 "general_operand" ""))]
1413 ""
1414 "ix86_expand_move (QImode, operands); DONE;")
1415
1416 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1417 ;; "push a byte". But actually we use pushw, which has the effect
1418 ;; of rounding the amount pushed up to a halfword.
1419
1420 (define_insn "*pushqi2"
1421 [(set (match_operand:QI 0 "push_operand" "=X,X")
1422 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1423 "!TARGET_64BIT"
1424 "@
1425 push{w}\t{|word ptr }%1
1426 push{w}\t%w1"
1427 [(set_attr "type" "push")
1428 (set_attr "mode" "HI")])
1429
1430 ;; For 64BIT abi we always round up to 8 bytes.
1431 (define_insn "*pushqi2_rex64"
1432 [(set (match_operand:QI 0 "push_operand" "=X")
1433 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1434 "TARGET_64BIT"
1435 "push{q}\t%q1"
1436 [(set_attr "type" "push")
1437 (set_attr "mode" "QI")])
1438
1439 ;; Situation is quite tricky about when to choose full sized (SImode) move
1440 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1441 ;; partial register dependency machines (such as AMD Athlon), where QImode
1442 ;; moves issue extra dependency and for partial register stalls machines
1443 ;; that don't use QImode patterns (and QImode move cause stall on the next
1444 ;; instruction).
1445 ;;
1446 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1447 ;; register stall machines with, where we use QImode instructions, since
1448 ;; partial register stall can be caused there. Then we use movzx.
1449 (define_insn "*movqi_1"
1450 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1451 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1452 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1453 {
1454 switch (get_attr_type (insn))
1455 {
1456 case TYPE_IMOVX:
1457 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1458 abort ();
1459 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1460 default:
1461 if (get_attr_mode (insn) == MODE_SI)
1462 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1463 else
1464 return "mov{b}\t{%1, %0|%0, %1}";
1465 }
1466 }
1467 [(set (attr "type")
1468 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1469 (const_string "imov")
1470 (and (eq_attr "alternative" "3")
1471 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1472 (const_int 0))
1473 (eq (symbol_ref "TARGET_QIMODE_MATH")
1474 (const_int 0))))
1475 (const_string "imov")
1476 (eq_attr "alternative" "3,5")
1477 (const_string "imovx")
1478 (and (ne (symbol_ref "TARGET_MOVX")
1479 (const_int 0))
1480 (eq_attr "alternative" "2"))
1481 (const_string "imovx")
1482 ]
1483 (const_string "imov")))
1484 (set (attr "mode")
1485 (cond [(eq_attr "alternative" "3,4,5")
1486 (const_string "SI")
1487 (eq_attr "alternative" "6")
1488 (const_string "QI")
1489 (eq_attr "type" "imovx")
1490 (const_string "SI")
1491 (and (eq_attr "type" "imov")
1492 (and (eq_attr "alternative" "0,1")
1493 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1494 (const_int 0))))
1495 (const_string "SI")
1496 ;; Avoid partial register stalls when not using QImode arithmetic
1497 (and (eq_attr "type" "imov")
1498 (and (eq_attr "alternative" "0,1")
1499 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1500 (const_int 0))
1501 (eq (symbol_ref "TARGET_QIMODE_MATH")
1502 (const_int 0)))))
1503 (const_string "SI")
1504 ]
1505 (const_string "QI")))])
1506
1507 (define_expand "reload_outqi"
1508 [(parallel [(match_operand:QI 0 "" "=m")
1509 (match_operand:QI 1 "register_operand" "r")
1510 (match_operand:QI 2 "register_operand" "=&q")])]
1511 ""
1512 {
1513 rtx op0, op1, op2;
1514 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1515
1516 if (reg_overlap_mentioned_p (op2, op0))
1517 abort ();
1518 if (! q_regs_operand (op1, QImode))
1519 {
1520 emit_insn (gen_movqi (op2, op1));
1521 op1 = op2;
1522 }
1523 emit_insn (gen_movqi (op0, op1));
1524 DONE;
1525 })
1526
1527 (define_insn "*swapqi_1"
1528 [(set (match_operand:QI 0 "register_operand" "+r")
1529 (match_operand:QI 1 "register_operand" "+r"))
1530 (set (match_dup 1)
1531 (match_dup 0))]
1532 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1533 "xchg{l}\t%k1, %k0"
1534 [(set_attr "type" "imov")
1535 (set_attr "mode" "SI")
1536 (set_attr "pent_pair" "np")
1537 (set_attr "athlon_decode" "vector")])
1538
1539 (define_insn "*swapqi_2"
1540 [(set (match_operand:QI 0 "register_operand" "+q")
1541 (match_operand:QI 1 "register_operand" "+q"))
1542 (set (match_dup 1)
1543 (match_dup 0))]
1544 "TARGET_PARTIAL_REG_STALL"
1545 "xchg{b}\t%1, %0"
1546 [(set_attr "type" "imov")
1547 (set_attr "mode" "QI")
1548 (set_attr "pent_pair" "np")
1549 (set_attr "athlon_decode" "vector")])
1550
1551 (define_expand "movstrictqi"
1552 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1553 (match_operand:QI 1 "general_operand" ""))]
1554 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1555 {
1556 /* Don't generate memory->memory moves, go through a register. */
1557 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1558 operands[1] = force_reg (QImode, operands[1]);
1559 })
1560
1561 (define_insn "*movstrictqi_1"
1562 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1563 (match_operand:QI 1 "general_operand" "*qn,m"))]
1564 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1565 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1566 "mov{b}\t{%1, %0|%0, %1}"
1567 [(set_attr "type" "imov")
1568 (set_attr "mode" "QI")])
1569
1570 (define_insn "*movstrictqi_xor"
1571 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1572 (match_operand:QI 1 "const0_operand" "i"))
1573 (clobber (reg:CC FLAGS_REG))]
1574 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1575 "xor{b}\t{%0, %0|%0, %0}"
1576 [(set_attr "type" "alu1")
1577 (set_attr "mode" "QI")
1578 (set_attr "length_immediate" "0")])
1579
1580 (define_insn "*movsi_extv_1"
1581 [(set (match_operand:SI 0 "register_operand" "=R")
1582 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1583 (const_int 8)
1584 (const_int 8)))]
1585 ""
1586 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1587 [(set_attr "type" "imovx")
1588 (set_attr "mode" "SI")])
1589
1590 (define_insn "*movhi_extv_1"
1591 [(set (match_operand:HI 0 "register_operand" "=R")
1592 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1593 (const_int 8)
1594 (const_int 8)))]
1595 ""
1596 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1597 [(set_attr "type" "imovx")
1598 (set_attr "mode" "SI")])
1599
1600 (define_insn "*movqi_extv_1"
1601 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1602 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1603 (const_int 8)
1604 (const_int 8)))]
1605 "!TARGET_64BIT"
1606 {
1607 switch (get_attr_type (insn))
1608 {
1609 case TYPE_IMOVX:
1610 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1611 default:
1612 return "mov{b}\t{%h1, %0|%0, %h1}";
1613 }
1614 }
1615 [(set (attr "type")
1616 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1617 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1618 (ne (symbol_ref "TARGET_MOVX")
1619 (const_int 0))))
1620 (const_string "imovx")
1621 (const_string "imov")))
1622 (set (attr "mode")
1623 (if_then_else (eq_attr "type" "imovx")
1624 (const_string "SI")
1625 (const_string "QI")))])
1626
1627 (define_insn "*movqi_extv_1_rex64"
1628 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1629 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1630 (const_int 8)
1631 (const_int 8)))]
1632 "TARGET_64BIT"
1633 {
1634 switch (get_attr_type (insn))
1635 {
1636 case TYPE_IMOVX:
1637 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1638 default:
1639 return "mov{b}\t{%h1, %0|%0, %h1}";
1640 }
1641 }
1642 [(set (attr "type")
1643 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1644 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1645 (ne (symbol_ref "TARGET_MOVX")
1646 (const_int 0))))
1647 (const_string "imovx")
1648 (const_string "imov")))
1649 (set (attr "mode")
1650 (if_then_else (eq_attr "type" "imovx")
1651 (const_string "SI")
1652 (const_string "QI")))])
1653
1654 ;; Stores and loads of ax to arbitrary constant address.
1655 ;; We fake an second form of instruction to force reload to load address
1656 ;; into register when rax is not available
1657 (define_insn "*movabsqi_1_rex64"
1658 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1659 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1660 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1661 "@
1662 movabs{b}\t{%1, %P0|%P0, %1}
1663 mov{b}\t{%1, %a0|%a0, %1}"
1664 [(set_attr "type" "imov")
1665 (set_attr "modrm" "0,*")
1666 (set_attr "length_address" "8,0")
1667 (set_attr "length_immediate" "0,*")
1668 (set_attr "memory" "store")
1669 (set_attr "mode" "QI")])
1670
1671 (define_insn "*movabsqi_2_rex64"
1672 [(set (match_operand:QI 0 "register_operand" "=a,r")
1673 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1674 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1675 "@
1676 movabs{b}\t{%P1, %0|%0, %P1}
1677 mov{b}\t{%a1, %0|%0, %a1}"
1678 [(set_attr "type" "imov")
1679 (set_attr "modrm" "0,*")
1680 (set_attr "length_address" "8,0")
1681 (set_attr "length_immediate" "0")
1682 (set_attr "memory" "load")
1683 (set_attr "mode" "QI")])
1684
1685 (define_insn "*movsi_extzv_1"
1686 [(set (match_operand:SI 0 "register_operand" "=R")
1687 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1688 (const_int 8)
1689 (const_int 8)))]
1690 ""
1691 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1692 [(set_attr "type" "imovx")
1693 (set_attr "mode" "SI")])
1694
1695 (define_insn "*movqi_extzv_2"
1696 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1697 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1698 (const_int 8)
1699 (const_int 8)) 0))]
1700 "!TARGET_64BIT"
1701 {
1702 switch (get_attr_type (insn))
1703 {
1704 case TYPE_IMOVX:
1705 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1706 default:
1707 return "mov{b}\t{%h1, %0|%0, %h1}";
1708 }
1709 }
1710 [(set (attr "type")
1711 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1712 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1713 (ne (symbol_ref "TARGET_MOVX")
1714 (const_int 0))))
1715 (const_string "imovx")
1716 (const_string "imov")))
1717 (set (attr "mode")
1718 (if_then_else (eq_attr "type" "imovx")
1719 (const_string "SI")
1720 (const_string "QI")))])
1721
1722 (define_insn "*movqi_extzv_2_rex64"
1723 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1724 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1725 (const_int 8)
1726 (const_int 8)) 0))]
1727 "TARGET_64BIT"
1728 {
1729 switch (get_attr_type (insn))
1730 {
1731 case TYPE_IMOVX:
1732 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1733 default:
1734 return "mov{b}\t{%h1, %0|%0, %h1}";
1735 }
1736 }
1737 [(set (attr "type")
1738 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1739 (ne (symbol_ref "TARGET_MOVX")
1740 (const_int 0)))
1741 (const_string "imovx")
1742 (const_string "imov")))
1743 (set (attr "mode")
1744 (if_then_else (eq_attr "type" "imovx")
1745 (const_string "SI")
1746 (const_string "QI")))])
1747
1748 (define_insn "movsi_insv_1"
1749 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1750 (const_int 8)
1751 (const_int 8))
1752 (match_operand:SI 1 "general_operand" "Qmn"))]
1753 "!TARGET_64BIT"
1754 "mov{b}\t{%b1, %h0|%h0, %b1}"
1755 [(set_attr "type" "imov")
1756 (set_attr "mode" "QI")])
1757
1758 (define_insn "movdi_insv_1_rex64"
1759 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1760 (const_int 8)
1761 (const_int 8))
1762 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1763 "TARGET_64BIT"
1764 "mov{b}\t{%b1, %h0|%h0, %b1}"
1765 [(set_attr "type" "imov")
1766 (set_attr "mode" "QI")])
1767
1768 (define_insn "*movqi_insv_2"
1769 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1770 (const_int 8)
1771 (const_int 8))
1772 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1773 (const_int 8)))]
1774 ""
1775 "mov{b}\t{%h1, %h0|%h0, %h1}"
1776 [(set_attr "type" "imov")
1777 (set_attr "mode" "QI")])
1778
1779 (define_expand "movdi"
1780 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1781 (match_operand:DI 1 "general_operand" ""))]
1782 ""
1783 "ix86_expand_move (DImode, operands); DONE;")
1784
1785 (define_insn "*pushdi"
1786 [(set (match_operand:DI 0 "push_operand" "=<")
1787 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1788 "!TARGET_64BIT"
1789 "#")
1790
1791 (define_insn "*pushdi2_rex64"
1792 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1793 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1794 "TARGET_64BIT"
1795 "@
1796 push{q}\t%1
1797 #"
1798 [(set_attr "type" "push,multi")
1799 (set_attr "mode" "DI")])
1800
1801 ;; Convert impossible pushes of immediate to existing instructions.
1802 ;; First try to get scratch register and go through it. In case this
1803 ;; fails, push sign extended lower part first and then overwrite
1804 ;; upper part by 32bit move.
1805 (define_peephole2
1806 [(match_scratch:DI 2 "r")
1807 (set (match_operand:DI 0 "push_operand" "")
1808 (match_operand:DI 1 "immediate_operand" ""))]
1809 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1810 && !x86_64_immediate_operand (operands[1], DImode)"
1811 [(set (match_dup 2) (match_dup 1))
1812 (set (match_dup 0) (match_dup 2))]
1813 "")
1814
1815 ;; We need to define this as both peepholer and splitter for case
1816 ;; peephole2 pass is not run.
1817 ;; "&& 1" is needed to keep it from matching the previous pattern.
1818 (define_peephole2
1819 [(set (match_operand:DI 0 "push_operand" "")
1820 (match_operand:DI 1 "immediate_operand" ""))]
1821 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1822 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1823 [(set (match_dup 0) (match_dup 1))
1824 (set (match_dup 2) (match_dup 3))]
1825 "split_di (operands + 1, 1, operands + 2, operands + 3);
1826 operands[1] = gen_lowpart (DImode, operands[2]);
1827 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1828 GEN_INT (4)));
1829 ")
1830
1831 (define_split
1832 [(set (match_operand:DI 0 "push_operand" "")
1833 (match_operand:DI 1 "immediate_operand" ""))]
1834 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1835 && !symbolic_operand (operands[1], DImode)
1836 && !x86_64_immediate_operand (operands[1], DImode)"
1837 [(set (match_dup 0) (match_dup 1))
1838 (set (match_dup 2) (match_dup 3))]
1839 "split_di (operands + 1, 1, operands + 2, operands + 3);
1840 operands[1] = gen_lowpart (DImode, operands[2]);
1841 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1842 GEN_INT (4)));
1843 ")
1844
1845 (define_insn "*pushdi2_prologue_rex64"
1846 [(set (match_operand:DI 0 "push_operand" "=<")
1847 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1848 (clobber (mem:BLK (scratch)))]
1849 "TARGET_64BIT"
1850 "push{q}\t%1"
1851 [(set_attr "type" "push")
1852 (set_attr "mode" "DI")])
1853
1854 (define_insn "*popdi1_epilogue_rex64"
1855 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1856 (mem:DI (reg:DI SP_REG)))
1857 (set (reg:DI SP_REG)
1858 (plus:DI (reg:DI SP_REG) (const_int 8)))
1859 (clobber (mem:BLK (scratch)))]
1860 "TARGET_64BIT"
1861 "pop{q}\t%0"
1862 [(set_attr "type" "pop")
1863 (set_attr "mode" "DI")])
1864
1865 (define_insn "popdi1"
1866 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1867 (mem:DI (reg:DI SP_REG)))
1868 (set (reg:DI SP_REG)
1869 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1870 "TARGET_64BIT"
1871 "pop{q}\t%0"
1872 [(set_attr "type" "pop")
1873 (set_attr "mode" "DI")])
1874
1875 (define_insn "*movdi_xor_rex64"
1876 [(set (match_operand:DI 0 "register_operand" "=r")
1877 (match_operand:DI 1 "const0_operand" "i"))
1878 (clobber (reg:CC FLAGS_REG))]
1879 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1880 && reload_completed"
1881 "xor{l}\t{%k0, %k0|%k0, %k0}"
1882 [(set_attr "type" "alu1")
1883 (set_attr "mode" "SI")
1884 (set_attr "length_immediate" "0")])
1885
1886 (define_insn "*movdi_or_rex64"
1887 [(set (match_operand:DI 0 "register_operand" "=r")
1888 (match_operand:DI 1 "const_int_operand" "i"))
1889 (clobber (reg:CC FLAGS_REG))]
1890 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1891 && reload_completed
1892 && operands[1] == constm1_rtx"
1893 {
1894 operands[1] = constm1_rtx;
1895 return "or{q}\t{%1, %0|%0, %1}";
1896 }
1897 [(set_attr "type" "alu1")
1898 (set_attr "mode" "DI")
1899 (set_attr "length_immediate" "1")])
1900
1901 (define_insn "*movdi_2"
1902 [(set (match_operand:DI 0 "nonimmediate_operand"
1903 "=r ,o ,m*y,*y,m ,*Y,*Y,m ,*x,*x")
1904 (match_operand:DI 1 "general_operand"
1905 "riFo,riF,*y ,m ,*Y,*Y,m ,*x,*x,m "))]
1906 "!TARGET_64BIT
1907 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1908 "@
1909 #
1910 #
1911 movq\t{%1, %0|%0, %1}
1912 movq\t{%1, %0|%0, %1}
1913 movq\t{%1, %0|%0, %1}
1914 movdqa\t{%1, %0|%0, %1}
1915 movq\t{%1, %0|%0, %1}
1916 movlps\t{%1, %0|%0, %1}
1917 movaps\t{%1, %0|%0, %1}
1918 movlps\t{%1, %0|%0, %1}"
1919 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov")
1920 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,V2SF,V4SF,V2SF")])
1921
1922 (define_split
1923 [(set (match_operand:DI 0 "push_operand" "")
1924 (match_operand:DI 1 "general_operand" ""))]
1925 "!TARGET_64BIT && reload_completed
1926 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1927 [(const_int 0)]
1928 "ix86_split_long_move (operands); DONE;")
1929
1930 ;; %%% This multiword shite has got to go.
1931 (define_split
1932 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1933 (match_operand:DI 1 "general_operand" ""))]
1934 "!TARGET_64BIT && reload_completed
1935 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1936 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1937 [(const_int 0)]
1938 "ix86_split_long_move (operands); DONE;")
1939
1940 (define_insn "*movdi_1_rex64"
1941 [(set (match_operand:DI 0 "nonimmediate_operand"
1942 "=r,r ,r,mr,!mr,!*y,!rm,!*y,!*x,!rm,!*x,!*x,!*y")
1943 (match_operand:DI 1 "general_operand"
1944 "Z ,rem,i,re,n ,*y ,*y ,rm ,*x ,*x ,rm ,*y ,*x"))]
1945 "TARGET_64BIT
1946 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1947 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1948 {
1949 switch (get_attr_type (insn))
1950 {
1951 case TYPE_SSECVT:
1952 if (which_alternative == 11)
1953 return "movq2dq\t{%1, %0|%0, %1}";
1954 else
1955 return "movdq2q\t{%1, %0|%0, %1}";
1956 case TYPE_SSEMOV:
1957 if (get_attr_mode (insn) == MODE_TI)
1958 return "movdqa\t{%1, %0|%0, %1}";
1959 /* FALLTHRU */
1960 case TYPE_MMXMOV:
1961 /* Moves from and into integer register is done using movd opcode with
1962 REX prefix. */
1963 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1964 return "movd\t{%1, %0|%0, %1}";
1965 return "movq\t{%1, %0|%0, %1}";
1966 case TYPE_MULTI:
1967 return "#";
1968 case TYPE_LEA:
1969 return "lea{q}\t{%a1, %0|%0, %a1}";
1970 default:
1971 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1972 abort ();
1973 if (get_attr_mode (insn) == MODE_SI)
1974 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1975 else if (which_alternative == 2)
1976 return "movabs{q}\t{%1, %0|%0, %1}";
1977 else
1978 return "mov{q}\t{%1, %0|%0, %1}";
1979 }
1980 }
1981 [(set (attr "type")
1982 (cond [(eq_attr "alternative" "5,6,7")
1983 (const_string "mmxmov")
1984 (eq_attr "alternative" "8,9,10")
1985 (const_string "ssemov")
1986 (eq_attr "alternative" "11,12")
1987 (const_string "ssecvt")
1988 (eq_attr "alternative" "4")
1989 (const_string "multi")
1990 (and (ne (symbol_ref "flag_pic") (const_int 0))
1991 (match_operand:DI 1 "symbolic_operand" ""))
1992 (const_string "lea")
1993 ]
1994 (const_string "imov")))
1995 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1996 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1997 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1998
1999 (define_insn "*movdi_1_rex64_nointerunit"
2000 [(set (match_operand:DI 0 "nonimmediate_operand"
2001 "=r,r ,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2002 (match_operand:DI 1 "general_operand"
2003 "Z,rem,i,re,n ,*y ,*y,m ,*Y ,*Y,m"))]
2004 "TARGET_64BIT
2005 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2006 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2007 {
2008 switch (get_attr_type (insn))
2009 {
2010 case TYPE_SSEMOV:
2011 if (get_attr_mode (insn) == MODE_TI)
2012 return "movdqa\t{%1, %0|%0, %1}";
2013 /* FALLTHRU */
2014 case TYPE_MMXMOV:
2015 return "movq\t{%1, %0|%0, %1}";
2016 case TYPE_MULTI:
2017 return "#";
2018 case TYPE_LEA:
2019 return "lea{q}\t{%a1, %0|%0, %a1}";
2020 default:
2021 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2022 abort ();
2023 if (get_attr_mode (insn) == MODE_SI)
2024 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2025 else if (which_alternative == 2)
2026 return "movabs{q}\t{%1, %0|%0, %1}";
2027 else
2028 return "mov{q}\t{%1, %0|%0, %1}";
2029 }
2030 }
2031 [(set (attr "type")
2032 (cond [(eq_attr "alternative" "5,6,7")
2033 (const_string "mmxmov")
2034 (eq_attr "alternative" "8,9,10")
2035 (const_string "ssemov")
2036 (eq_attr "alternative" "4")
2037 (const_string "multi")
2038 (and (ne (symbol_ref "flag_pic") (const_int 0))
2039 (match_operand:DI 1 "symbolic_operand" ""))
2040 (const_string "lea")
2041 ]
2042 (const_string "imov")))
2043 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2044 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2045 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2046
2047 ;; Stores and loads of ax to arbitrary constant address.
2048 ;; We fake an second form of instruction to force reload to load address
2049 ;; into register when rax is not available
2050 (define_insn "*movabsdi_1_rex64"
2051 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2052 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2053 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2054 "@
2055 movabs{q}\t{%1, %P0|%P0, %1}
2056 mov{q}\t{%1, %a0|%a0, %1}"
2057 [(set_attr "type" "imov")
2058 (set_attr "modrm" "0,*")
2059 (set_attr "length_address" "8,0")
2060 (set_attr "length_immediate" "0,*")
2061 (set_attr "memory" "store")
2062 (set_attr "mode" "DI")])
2063
2064 (define_insn "*movabsdi_2_rex64"
2065 [(set (match_operand:DI 0 "register_operand" "=a,r")
2066 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2067 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2068 "@
2069 movabs{q}\t{%P1, %0|%0, %P1}
2070 mov{q}\t{%a1, %0|%0, %a1}"
2071 [(set_attr "type" "imov")
2072 (set_attr "modrm" "0,*")
2073 (set_attr "length_address" "8,0")
2074 (set_attr "length_immediate" "0")
2075 (set_attr "memory" "load")
2076 (set_attr "mode" "DI")])
2077
2078 ;; Convert impossible stores of immediate to existing instructions.
2079 ;; First try to get scratch register and go through it. In case this
2080 ;; fails, move by 32bit parts.
2081 (define_peephole2
2082 [(match_scratch:DI 2 "r")
2083 (set (match_operand:DI 0 "memory_operand" "")
2084 (match_operand:DI 1 "immediate_operand" ""))]
2085 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2086 && !x86_64_immediate_operand (operands[1], DImode)"
2087 [(set (match_dup 2) (match_dup 1))
2088 (set (match_dup 0) (match_dup 2))]
2089 "")
2090
2091 ;; We need to define this as both peepholer and splitter for case
2092 ;; peephole2 pass is not run.
2093 ;; "&& 1" is needed to keep it from matching the previous pattern.
2094 (define_peephole2
2095 [(set (match_operand:DI 0 "memory_operand" "")
2096 (match_operand:DI 1 "immediate_operand" ""))]
2097 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2098 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2099 [(set (match_dup 2) (match_dup 3))
2100 (set (match_dup 4) (match_dup 5))]
2101 "split_di (operands, 2, operands + 2, operands + 4);")
2102
2103 (define_split
2104 [(set (match_operand:DI 0 "memory_operand" "")
2105 (match_operand:DI 1 "immediate_operand" ""))]
2106 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2107 && !symbolic_operand (operands[1], DImode)
2108 && !x86_64_immediate_operand (operands[1], DImode)"
2109 [(set (match_dup 2) (match_dup 3))
2110 (set (match_dup 4) (match_dup 5))]
2111 "split_di (operands, 2, operands + 2, operands + 4);")
2112
2113 (define_insn "*swapdi_rex64"
2114 [(set (match_operand:DI 0 "register_operand" "+r")
2115 (match_operand:DI 1 "register_operand" "+r"))
2116 (set (match_dup 1)
2117 (match_dup 0))]
2118 "TARGET_64BIT"
2119 "xchg{q}\t%1, %0"
2120 [(set_attr "type" "imov")
2121 (set_attr "mode" "DI")
2122 (set_attr "pent_pair" "np")
2123 (set_attr "athlon_decode" "vector")])
2124
2125 (define_expand "movsf"
2126 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2127 (match_operand:SF 1 "general_operand" ""))]
2128 ""
2129 "ix86_expand_move (SFmode, operands); DONE;")
2130
2131 (define_insn "*pushsf"
2132 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2133 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2134 "!TARGET_64BIT"
2135 {
2136 switch (which_alternative)
2137 {
2138 case 1:
2139 return "push{l}\t%1";
2140
2141 default:
2142 /* This insn should be already split before reg-stack. */
2143 abort ();
2144 }
2145 }
2146 [(set_attr "type" "multi,push,multi")
2147 (set_attr "mode" "SF,SI,SF")])
2148
2149 (define_insn "*pushsf_rex64"
2150 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2151 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2152 "TARGET_64BIT"
2153 {
2154 switch (which_alternative)
2155 {
2156 case 1:
2157 return "push{q}\t%q1";
2158
2159 default:
2160 /* This insn should be already split before reg-stack. */
2161 abort ();
2162 }
2163 }
2164 [(set_attr "type" "multi,push,multi")
2165 (set_attr "mode" "SF,DI,SF")])
2166
2167 (define_split
2168 [(set (match_operand:SF 0 "push_operand" "")
2169 (match_operand:SF 1 "memory_operand" ""))]
2170 "reload_completed
2171 && GET_CODE (operands[1]) == MEM
2172 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2173 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2174 [(set (match_dup 0)
2175 (match_dup 1))]
2176 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2177
2178
2179 ;; %%% Kill this when call knows how to work this out.
2180 (define_split
2181 [(set (match_operand:SF 0 "push_operand" "")
2182 (match_operand:SF 1 "any_fp_register_operand" ""))]
2183 "!TARGET_64BIT"
2184 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2185 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2186
2187 (define_split
2188 [(set (match_operand:SF 0 "push_operand" "")
2189 (match_operand:SF 1 "any_fp_register_operand" ""))]
2190 "TARGET_64BIT"
2191 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2192 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2193
2194 (define_insn "*movsf_1"
2195 [(set (match_operand:SF 0 "nonimmediate_operand"
2196 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2197 (match_operand:SF 1 "general_operand"
2198 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2199 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2200 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2201 && (reload_in_progress || reload_completed
2202 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2203 || GET_CODE (operands[1]) != CONST_DOUBLE
2204 || memory_operand (operands[0], SFmode))"
2205 {
2206 switch (which_alternative)
2207 {
2208 case 0:
2209 return output_387_reg_move (insn, operands);
2210
2211 case 1:
2212 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2213 return "fstp%z0\t%y0";
2214 else
2215 return "fst%z0\t%y0";
2216
2217 case 2:
2218 return standard_80387_constant_opcode (operands[1]);
2219
2220 case 3:
2221 case 4:
2222 return "mov{l}\t{%1, %0|%0, %1}";
2223 case 5:
2224 if (get_attr_mode (insn) == MODE_TI)
2225 return "pxor\t%0, %0";
2226 else
2227 return "xorps\t%0, %0";
2228 case 6:
2229 if (get_attr_mode (insn) == MODE_V4SF)
2230 return "movaps\t{%1, %0|%0, %1}";
2231 else
2232 return "movss\t{%1, %0|%0, %1}";
2233 case 7:
2234 case 8:
2235 return "movss\t{%1, %0|%0, %1}";
2236
2237 case 9:
2238 case 10:
2239 return "movd\t{%1, %0|%0, %1}";
2240
2241 case 11:
2242 return "movq\t{%1, %0|%0, %1}";
2243
2244 default:
2245 abort();
2246 }
2247 }
2248 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2249 (set (attr "mode")
2250 (cond [(eq_attr "alternative" "3,4,9,10")
2251 (const_string "SI")
2252 (eq_attr "alternative" "5")
2253 (if_then_else
2254 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2255 (const_int 0))
2256 (ne (symbol_ref "TARGET_SSE2")
2257 (const_int 0)))
2258 (eq (symbol_ref "optimize_size")
2259 (const_int 0)))
2260 (const_string "TI")
2261 (const_string "V4SF"))
2262 /* For architectures resolving dependencies on
2263 whole SSE registers use APS move to break dependency
2264 chains, otherwise use short move to avoid extra work.
2265
2266 Do the same for architectures resolving dependencies on
2267 the parts. While in DF mode it is better to always handle
2268 just register parts, the SF mode is different due to lack
2269 of instructions to load just part of the register. It is
2270 better to maintain the whole registers in single format
2271 to avoid problems on using packed logical operations. */
2272 (eq_attr "alternative" "6")
2273 (if_then_else
2274 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2275 (const_int 0))
2276 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2277 (const_int 0)))
2278 (const_string "V4SF")
2279 (const_string "SF"))
2280 (eq_attr "alternative" "11")
2281 (const_string "DI")]
2282 (const_string "SF")))])
2283
2284 (define_insn "*movsf_1_nointerunit"
2285 [(set (match_operand:SF 0 "nonimmediate_operand"
2286 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!m,!*y")
2287 (match_operand:SF 1 "general_operand"
2288 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,m ,*y,*y"))]
2289 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2290 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2291 && (reload_in_progress || reload_completed
2292 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2293 || GET_CODE (operands[1]) != CONST_DOUBLE
2294 || memory_operand (operands[0], SFmode))"
2295 {
2296 switch (which_alternative)
2297 {
2298 case 0:
2299 return output_387_reg_move (insn, operands);
2300
2301 case 1:
2302 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2303 return "fstp%z0\t%y0";
2304 else
2305 return "fst%z0\t%y0";
2306
2307 case 2:
2308 return standard_80387_constant_opcode (operands[1]);
2309
2310 case 3:
2311 case 4:
2312 return "mov{l}\t{%1, %0|%0, %1}";
2313 case 5:
2314 if (get_attr_mode (insn) == MODE_TI)
2315 return "pxor\t%0, %0";
2316 else
2317 return "xorps\t%0, %0";
2318 case 6:
2319 if (get_attr_mode (insn) == MODE_V4SF)
2320 return "movaps\t{%1, %0|%0, %1}";
2321 else
2322 return "movss\t{%1, %0|%0, %1}";
2323 case 7:
2324 case 8:
2325 return "movss\t{%1, %0|%0, %1}";
2326
2327 case 9:
2328 case 10:
2329 return "movd\t{%1, %0|%0, %1}";
2330
2331 case 11:
2332 return "movq\t{%1, %0|%0, %1}";
2333
2334 default:
2335 abort();
2336 }
2337 }
2338 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2339 (set (attr "mode")
2340 (cond [(eq_attr "alternative" "3,4,9,10")
2341 (const_string "SI")
2342 (eq_attr "alternative" "5")
2343 (if_then_else
2344 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2345 (const_int 0))
2346 (ne (symbol_ref "TARGET_SSE2")
2347 (const_int 0)))
2348 (eq (symbol_ref "optimize_size")
2349 (const_int 0)))
2350 (const_string "TI")
2351 (const_string "V4SF"))
2352 /* For architectures resolving dependencies on
2353 whole SSE registers use APS move to break dependency
2354 chains, otherwise use short move to avoid extra work.
2355
2356 Do the same for architectures resolving dependencies on
2357 the parts. While in DF mode it is better to always handle
2358 just register parts, the SF mode is different due to lack
2359 of instructions to load just part of the register. It is
2360 better to maintain the whole registers in single format
2361 to avoid problems on using packed logical operations. */
2362 (eq_attr "alternative" "6")
2363 (if_then_else
2364 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2365 (const_int 0))
2366 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2367 (const_int 0)))
2368 (const_string "V4SF")
2369 (const_string "SF"))
2370 (eq_attr "alternative" "11")
2371 (const_string "DI")]
2372 (const_string "SF")))])
2373
2374 (define_insn "*swapsf"
2375 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2376 (match_operand:SF 1 "fp_register_operand" "+f"))
2377 (set (match_dup 1)
2378 (match_dup 0))]
2379 "reload_completed || TARGET_80387"
2380 {
2381 if (STACK_TOP_P (operands[0]))
2382 return "fxch\t%1";
2383 else
2384 return "fxch\t%0";
2385 }
2386 [(set_attr "type" "fxch")
2387 (set_attr "mode" "SF")])
2388
2389 (define_expand "movdf"
2390 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2391 (match_operand:DF 1 "general_operand" ""))]
2392 ""
2393 "ix86_expand_move (DFmode, operands); DONE;")
2394
2395 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2396 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2397 ;; On the average, pushdf using integers can be still shorter. Allow this
2398 ;; pattern for optimize_size too.
2399
2400 (define_insn "*pushdf_nointeger"
2401 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2402 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2403 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2404 {
2405 /* This insn should be already split before reg-stack. */
2406 abort ();
2407 }
2408 [(set_attr "type" "multi")
2409 (set_attr "mode" "DF,SI,SI,DF")])
2410
2411 (define_insn "*pushdf_integer"
2412 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2413 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2414 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2415 {
2416 /* This insn should be already split before reg-stack. */
2417 abort ();
2418 }
2419 [(set_attr "type" "multi")
2420 (set_attr "mode" "DF,SI,DF")])
2421
2422 ;; %%% Kill this when call knows how to work this out.
2423 (define_split
2424 [(set (match_operand:DF 0 "push_operand" "")
2425 (match_operand:DF 1 "any_fp_register_operand" ""))]
2426 "!TARGET_64BIT && reload_completed"
2427 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2428 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2429 "")
2430
2431 (define_split
2432 [(set (match_operand:DF 0 "push_operand" "")
2433 (match_operand:DF 1 "any_fp_register_operand" ""))]
2434 "TARGET_64BIT && reload_completed"
2435 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2436 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2437 "")
2438
2439 (define_split
2440 [(set (match_operand:DF 0 "push_operand" "")
2441 (match_operand:DF 1 "general_operand" ""))]
2442 "reload_completed"
2443 [(const_int 0)]
2444 "ix86_split_long_move (operands); DONE;")
2445
2446 ;; Moving is usually shorter when only FP registers are used. This separate
2447 ;; movdf pattern avoids the use of integer registers for FP operations
2448 ;; when optimizing for size.
2449
2450 (define_insn "*movdf_nointeger"
2451 [(set (match_operand:DF 0 "nonimmediate_operand"
2452 "=f#Y,m ,f#Y,*r ,o ,Y#f*x,Y#f*x,Y#f*x ,m ")
2453 (match_operand:DF 1 "general_operand"
2454 "fm#Y,f#Y,G ,*roF,F*r,C ,Y#f*x,HmY#f*x,Y#f*x"))]
2455 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2456 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2457 && (reload_in_progress || reload_completed
2458 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2459 || GET_CODE (operands[1]) != CONST_DOUBLE
2460 || memory_operand (operands[0], DFmode))"
2461 {
2462 switch (which_alternative)
2463 {
2464 case 0:
2465 return output_387_reg_move (insn, operands);
2466
2467 case 1:
2468 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2469 return "fstp%z0\t%y0";
2470 else
2471 return "fst%z0\t%y0";
2472
2473 case 2:
2474 return standard_80387_constant_opcode (operands[1]);
2475
2476 case 3:
2477 case 4:
2478 return "#";
2479 case 5:
2480 switch (get_attr_mode (insn))
2481 {
2482 case MODE_V4SF:
2483 return "xorps\t%0, %0";
2484 case MODE_V2DF:
2485 return "xorpd\t%0, %0";
2486 case MODE_TI:
2487 return "pxor\t%0, %0";
2488 default:
2489 abort ();
2490 }
2491 case 6:
2492 case 7:
2493 case 8:
2494 switch (get_attr_mode (insn))
2495 {
2496 case MODE_V4SF:
2497 return "movaps\t{%1, %0|%0, %1}";
2498 case MODE_V2DF:
2499 return "movapd\t{%1, %0|%0, %1}";
2500 case MODE_TI:
2501 return "movdqa\t{%1, %0|%0, %1}";
2502 case MODE_DI:
2503 return "movq\t{%1, %0|%0, %1}";
2504 case MODE_DF:
2505 return "movsd\t{%1, %0|%0, %1}";
2506 case MODE_V1DF:
2507 return "movlpd\t{%1, %0|%0, %1}";
2508 case MODE_V2SF:
2509 return "movlps\t{%1, %0|%0, %1}";
2510 default:
2511 abort ();
2512 }
2513
2514 default:
2515 abort();
2516 }
2517 }
2518 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2519 (set (attr "mode")
2520 (cond [(eq_attr "alternative" "0,1,2")
2521 (const_string "DF")
2522 (eq_attr "alternative" "3,4")
2523 (const_string "SI")
2524
2525 /* For SSE1, we have many fewer alternatives. */
2526 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2527 (cond [(eq_attr "alternative" "5,6")
2528 (const_string "V4SF")
2529 ]
2530 (const_string "V2SF"))
2531
2532 /* xorps is one byte shorter. */
2533 (eq_attr "alternative" "5")
2534 (cond [(ne (symbol_ref "optimize_size")
2535 (const_int 0))
2536 (const_string "V4SF")
2537 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2538 (const_int 0))
2539 (const_string "TI")
2540 ]
2541 (const_string "V2DF"))
2542
2543 /* For architectures resolving dependencies on
2544 whole SSE registers use APD move to break dependency
2545 chains, otherwise use short move to avoid extra work.
2546
2547 movaps encodes one byte shorter. */
2548 (eq_attr "alternative" "6")
2549 (cond
2550 [(ne (symbol_ref "optimize_size")
2551 (const_int 0))
2552 (const_string "V4SF")
2553 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2554 (const_int 0))
2555 (const_string "V2DF")
2556 ]
2557 (const_string "DF"))
2558 /* For architectures resolving dependencies on register
2559 parts we may avoid extra work to zero out upper part
2560 of register. */
2561 (eq_attr "alternative" "7")
2562 (if_then_else
2563 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2564 (const_int 0))
2565 (const_string "V1DF")
2566 (const_string "DF"))
2567 ]
2568 (const_string "DF")))])
2569
2570 (define_insn "*movdf_integer"
2571 [(set (match_operand:DF 0 "nonimmediate_operand"
2572 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y#rf*x,Y#rf*x,Y#rf*x,m")
2573 (match_operand:DF 1 "general_operand"
2574 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y#rf*x,m ,Y#rf*x"))]
2575 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2576 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2577 && (reload_in_progress || reload_completed
2578 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2579 || GET_CODE (operands[1]) != CONST_DOUBLE
2580 || memory_operand (operands[0], DFmode))"
2581 {
2582 switch (which_alternative)
2583 {
2584 case 0:
2585 return output_387_reg_move (insn, operands);
2586
2587 case 1:
2588 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2589 return "fstp%z0\t%y0";
2590 else
2591 return "fst%z0\t%y0";
2592
2593 case 2:
2594 return standard_80387_constant_opcode (operands[1]);
2595
2596 case 3:
2597 case 4:
2598 return "#";
2599
2600 case 5:
2601 switch (get_attr_mode (insn))
2602 {
2603 case MODE_V4SF:
2604 return "xorps\t%0, %0";
2605 case MODE_V2DF:
2606 return "xorpd\t%0, %0";
2607 case MODE_TI:
2608 return "pxor\t%0, %0";
2609 default:
2610 abort ();
2611 }
2612 case 6:
2613 case 7:
2614 case 8:
2615 switch (get_attr_mode (insn))
2616 {
2617 case MODE_V4SF:
2618 return "movaps\t{%1, %0|%0, %1}";
2619 case MODE_V2DF:
2620 return "movapd\t{%1, %0|%0, %1}";
2621 case MODE_TI:
2622 return "movdqa\t{%1, %0|%0, %1}";
2623 case MODE_DI:
2624 return "movq\t{%1, %0|%0, %1}";
2625 case MODE_DF:
2626 return "movsd\t{%1, %0|%0, %1}";
2627 case MODE_V1DF:
2628 return "movlpd\t{%1, %0|%0, %1}";
2629 case MODE_V2SF:
2630 return "movlps\t{%1, %0|%0, %1}";
2631 default:
2632 abort ();
2633 }
2634
2635 default:
2636 abort();
2637 }
2638 }
2639 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2640 (set (attr "mode")
2641 (cond [(eq_attr "alternative" "0,1,2")
2642 (const_string "DF")
2643 (eq_attr "alternative" "3,4")
2644 (const_string "SI")
2645
2646 /* For SSE1, we have many fewer alternatives. */
2647 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2648 (cond [(eq_attr "alternative" "5,6")
2649 (const_string "V4SF")
2650 ]
2651 (const_string "V2SF"))
2652
2653 /* xorps is one byte shorter. */
2654 (eq_attr "alternative" "5")
2655 (cond [(ne (symbol_ref "optimize_size")
2656 (const_int 0))
2657 (const_string "V4SF")
2658 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2659 (const_int 0))
2660 (const_string "TI")
2661 ]
2662 (const_string "V2DF"))
2663
2664 /* For architectures resolving dependencies on
2665 whole SSE registers use APD move to break dependency
2666 chains, otherwise use short move to avoid extra work.
2667
2668 movaps encodes one byte shorter. */
2669 (eq_attr "alternative" "6")
2670 (cond
2671 [(ne (symbol_ref "optimize_size")
2672 (const_int 0))
2673 (const_string "V4SF")
2674 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2675 (const_int 0))
2676 (const_string "V2DF")
2677 ]
2678 (const_string "DF"))
2679 /* For architectures resolving dependencies on register
2680 parts we may avoid extra work to zero out upper part
2681 of register. */
2682 (eq_attr "alternative" "7")
2683 (if_then_else
2684 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2685 (const_int 0))
2686 (const_string "V1DF")
2687 (const_string "DF"))
2688 ]
2689 (const_string "DF")))])
2690
2691 (define_split
2692 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2693 (match_operand:DF 1 "general_operand" ""))]
2694 "reload_completed
2695 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2696 && ! (ANY_FP_REG_P (operands[0]) ||
2697 (GET_CODE (operands[0]) == SUBREG
2698 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2699 && ! (ANY_FP_REG_P (operands[1]) ||
2700 (GET_CODE (operands[1]) == SUBREG
2701 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2702 [(const_int 0)]
2703 "ix86_split_long_move (operands); DONE;")
2704
2705 (define_insn "*swapdf"
2706 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2707 (match_operand:DF 1 "fp_register_operand" "+f"))
2708 (set (match_dup 1)
2709 (match_dup 0))]
2710 "reload_completed || TARGET_80387"
2711 {
2712 if (STACK_TOP_P (operands[0]))
2713 return "fxch\t%1";
2714 else
2715 return "fxch\t%0";
2716 }
2717 [(set_attr "type" "fxch")
2718 (set_attr "mode" "DF")])
2719
2720 (define_expand "movxf"
2721 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2722 (match_operand:XF 1 "general_operand" ""))]
2723 ""
2724 "ix86_expand_move (XFmode, operands); DONE;")
2725
2726 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2727 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2728 ;; Pushing using integer instructions is longer except for constants
2729 ;; and direct memory references.
2730 ;; (assuming that any given constant is pushed only once, but this ought to be
2731 ;; handled elsewhere).
2732
2733 (define_insn "*pushxf_nointeger"
2734 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2735 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2736 "optimize_size"
2737 {
2738 /* This insn should be already split before reg-stack. */
2739 abort ();
2740 }
2741 [(set_attr "type" "multi")
2742 (set_attr "mode" "XF,SI,SI")])
2743
2744 (define_insn "*pushxf_integer"
2745 [(set (match_operand:XF 0 "push_operand" "=<,<")
2746 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2747 "!optimize_size"
2748 {
2749 /* This insn should be already split before reg-stack. */
2750 abort ();
2751 }
2752 [(set_attr "type" "multi")
2753 (set_attr "mode" "XF,SI")])
2754
2755 (define_split
2756 [(set (match_operand 0 "push_operand" "")
2757 (match_operand 1 "general_operand" ""))]
2758 "reload_completed
2759 && (GET_MODE (operands[0]) == XFmode
2760 || GET_MODE (operands[0]) == DFmode)
2761 && !ANY_FP_REG_P (operands[1])"
2762 [(const_int 0)]
2763 "ix86_split_long_move (operands); DONE;")
2764
2765 (define_split
2766 [(set (match_operand:XF 0 "push_operand" "")
2767 (match_operand:XF 1 "any_fp_register_operand" ""))]
2768 "!TARGET_64BIT"
2769 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2770 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2771 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2772
2773 (define_split
2774 [(set (match_operand:XF 0 "push_operand" "")
2775 (match_operand:XF 1 "any_fp_register_operand" ""))]
2776 "TARGET_64BIT"
2777 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2778 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2779 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2780
2781 ;; Do not use integer registers when optimizing for size
2782 (define_insn "*movxf_nointeger"
2783 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2784 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2785 "optimize_size
2786 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2787 && (reload_in_progress || reload_completed
2788 || GET_CODE (operands[1]) != CONST_DOUBLE
2789 || memory_operand (operands[0], XFmode))"
2790 {
2791 switch (which_alternative)
2792 {
2793 case 0:
2794 return output_387_reg_move (insn, operands);
2795
2796 case 1:
2797 /* There is no non-popping store to memory for XFmode. So if
2798 we need one, follow the store with a load. */
2799 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2800 return "fstp%z0\t%y0\;fld%z0\t%y0";
2801 else
2802 return "fstp%z0\t%y0";
2803
2804 case 2:
2805 return standard_80387_constant_opcode (operands[1]);
2806
2807 case 3: case 4:
2808 return "#";
2809 }
2810 abort();
2811 }
2812 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2813 (set_attr "mode" "XF,XF,XF,SI,SI")])
2814
2815 (define_insn "*movxf_integer"
2816 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2817 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2818 "!optimize_size
2819 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2820 && (reload_in_progress || reload_completed
2821 || GET_CODE (operands[1]) != CONST_DOUBLE
2822 || memory_operand (operands[0], XFmode))"
2823 {
2824 switch (which_alternative)
2825 {
2826 case 0:
2827 return output_387_reg_move (insn, operands);
2828
2829 case 1:
2830 /* There is no non-popping store to memory for XFmode. So if
2831 we need one, follow the store with a load. */
2832 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2833 return "fstp%z0\t%y0\;fld%z0\t%y0";
2834 else
2835 return "fstp%z0\t%y0";
2836
2837 case 2:
2838 return standard_80387_constant_opcode (operands[1]);
2839
2840 case 3: case 4:
2841 return "#";
2842 }
2843 abort();
2844 }
2845 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2846 (set_attr "mode" "XF,XF,XF,SI,SI")])
2847
2848 (define_split
2849 [(set (match_operand 0 "nonimmediate_operand" "")
2850 (match_operand 1 "general_operand" ""))]
2851 "reload_completed
2852 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2853 && GET_MODE (operands[0]) == XFmode
2854 && ! (ANY_FP_REG_P (operands[0]) ||
2855 (GET_CODE (operands[0]) == SUBREG
2856 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2857 && ! (ANY_FP_REG_P (operands[1]) ||
2858 (GET_CODE (operands[1]) == SUBREG
2859 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2860 [(const_int 0)]
2861 "ix86_split_long_move (operands); DONE;")
2862
2863 (define_split
2864 [(set (match_operand 0 "register_operand" "")
2865 (match_operand 1 "memory_operand" ""))]
2866 "reload_completed
2867 && GET_CODE (operands[1]) == MEM
2868 && (GET_MODE (operands[0]) == XFmode
2869 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2870 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2871 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2872 [(set (match_dup 0) (match_dup 1))]
2873 {
2874 rtx c = get_pool_constant (XEXP (operands[1], 0));
2875 rtx r = operands[0];
2876
2877 if (GET_CODE (r) == SUBREG)
2878 r = SUBREG_REG (r);
2879
2880 if (SSE_REG_P (r))
2881 {
2882 if (!standard_sse_constant_p (c))
2883 FAIL;
2884 }
2885 else if (FP_REG_P (r))
2886 {
2887 if (!standard_80387_constant_p (c))
2888 FAIL;
2889 }
2890 else if (MMX_REG_P (r))
2891 FAIL;
2892
2893 operands[1] = c;
2894 })
2895
2896 (define_insn "swapxf"
2897 [(set (match_operand:XF 0 "register_operand" "+f")
2898 (match_operand:XF 1 "register_operand" "+f"))
2899 (set (match_dup 1)
2900 (match_dup 0))]
2901 "TARGET_80387"
2902 {
2903 if (STACK_TOP_P (operands[0]))
2904 return "fxch\t%1";
2905 else
2906 return "fxch\t%0";
2907 }
2908 [(set_attr "type" "fxch")
2909 (set_attr "mode" "XF")])
2910 \f
2911 ;; Zero extension instructions
2912
2913 (define_expand "zero_extendhisi2"
2914 [(set (match_operand:SI 0 "register_operand" "")
2915 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2916 ""
2917 {
2918 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2919 {
2920 operands[1] = force_reg (HImode, operands[1]);
2921 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2922 DONE;
2923 }
2924 })
2925
2926 (define_insn "zero_extendhisi2_and"
2927 [(set (match_operand:SI 0 "register_operand" "=r")
2928 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2929 (clobber (reg:CC FLAGS_REG))]
2930 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2931 "#"
2932 [(set_attr "type" "alu1")
2933 (set_attr "mode" "SI")])
2934
2935 (define_split
2936 [(set (match_operand:SI 0 "register_operand" "")
2937 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2938 (clobber (reg:CC FLAGS_REG))]
2939 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2940 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2941 (clobber (reg:CC FLAGS_REG))])]
2942 "")
2943
2944 (define_insn "*zero_extendhisi2_movzwl"
2945 [(set (match_operand:SI 0 "register_operand" "=r")
2946 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2947 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2948 "movz{wl|x}\t{%1, %0|%0, %1}"
2949 [(set_attr "type" "imovx")
2950 (set_attr "mode" "SI")])
2951
2952 (define_expand "zero_extendqihi2"
2953 [(parallel
2954 [(set (match_operand:HI 0 "register_operand" "")
2955 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2956 (clobber (reg:CC FLAGS_REG))])]
2957 ""
2958 "")
2959
2960 (define_insn "*zero_extendqihi2_and"
2961 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2962 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2963 (clobber (reg:CC FLAGS_REG))]
2964 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2965 "#"
2966 [(set_attr "type" "alu1")
2967 (set_attr "mode" "HI")])
2968
2969 (define_insn "*zero_extendqihi2_movzbw_and"
2970 [(set (match_operand:HI 0 "register_operand" "=r,r")
2971 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2972 (clobber (reg:CC FLAGS_REG))]
2973 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2974 "#"
2975 [(set_attr "type" "imovx,alu1")
2976 (set_attr "mode" "HI")])
2977
2978 (define_insn "*zero_extendqihi2_movzbw"
2979 [(set (match_operand:HI 0 "register_operand" "=r")
2980 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2981 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2982 "movz{bw|x}\t{%1, %0|%0, %1}"
2983 [(set_attr "type" "imovx")
2984 (set_attr "mode" "HI")])
2985
2986 ;; For the movzbw case strip only the clobber
2987 (define_split
2988 [(set (match_operand:HI 0 "register_operand" "")
2989 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2990 (clobber (reg:CC FLAGS_REG))]
2991 "reload_completed
2992 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2993 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2994 [(set (match_operand:HI 0 "register_operand" "")
2995 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2996
2997 ;; When source and destination does not overlap, clear destination
2998 ;; first and then do the movb
2999 (define_split
3000 [(set (match_operand:HI 0 "register_operand" "")
3001 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3002 (clobber (reg:CC FLAGS_REG))]
3003 "reload_completed
3004 && ANY_QI_REG_P (operands[0])
3005 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3006 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3007 [(set (match_dup 0) (const_int 0))
3008 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3009 "operands[2] = gen_lowpart (QImode, operands[0]);")
3010
3011 ;; Rest is handled by single and.
3012 (define_split
3013 [(set (match_operand:HI 0 "register_operand" "")
3014 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3015 (clobber (reg:CC FLAGS_REG))]
3016 "reload_completed
3017 && true_regnum (operands[0]) == true_regnum (operands[1])"
3018 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3019 (clobber (reg:CC FLAGS_REG))])]
3020 "")
3021
3022 (define_expand "zero_extendqisi2"
3023 [(parallel
3024 [(set (match_operand:SI 0 "register_operand" "")
3025 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3026 (clobber (reg:CC FLAGS_REG))])]
3027 ""
3028 "")
3029
3030 (define_insn "*zero_extendqisi2_and"
3031 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3032 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3033 (clobber (reg:CC FLAGS_REG))]
3034 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3035 "#"
3036 [(set_attr "type" "alu1")
3037 (set_attr "mode" "SI")])
3038
3039 (define_insn "*zero_extendqisi2_movzbw_and"
3040 [(set (match_operand:SI 0 "register_operand" "=r,r")
3041 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3042 (clobber (reg:CC FLAGS_REG))]
3043 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3044 "#"
3045 [(set_attr "type" "imovx,alu1")
3046 (set_attr "mode" "SI")])
3047
3048 (define_insn "*zero_extendqisi2_movzbw"
3049 [(set (match_operand:SI 0 "register_operand" "=r")
3050 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3051 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3052 "movz{bl|x}\t{%1, %0|%0, %1}"
3053 [(set_attr "type" "imovx")
3054 (set_attr "mode" "SI")])
3055
3056 ;; For the movzbl case strip only the clobber
3057 (define_split
3058 [(set (match_operand:SI 0 "register_operand" "")
3059 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3060 (clobber (reg:CC FLAGS_REG))]
3061 "reload_completed
3062 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3063 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3064 [(set (match_dup 0)
3065 (zero_extend:SI (match_dup 1)))])
3066
3067 ;; When source and destination does not overlap, clear destination
3068 ;; first and then do the movb
3069 (define_split
3070 [(set (match_operand:SI 0 "register_operand" "")
3071 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3072 (clobber (reg:CC FLAGS_REG))]
3073 "reload_completed
3074 && ANY_QI_REG_P (operands[0])
3075 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3076 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3077 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3078 [(set (match_dup 0) (const_int 0))
3079 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3080 "operands[2] = gen_lowpart (QImode, operands[0]);")
3081
3082 ;; Rest is handled by single and.
3083 (define_split
3084 [(set (match_operand:SI 0 "register_operand" "")
3085 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3086 (clobber (reg:CC FLAGS_REG))]
3087 "reload_completed
3088 && true_regnum (operands[0]) == true_regnum (operands[1])"
3089 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3090 (clobber (reg:CC FLAGS_REG))])]
3091 "")
3092
3093 ;; %%% Kill me once multi-word ops are sane.
3094 (define_expand "zero_extendsidi2"
3095 [(set (match_operand:DI 0 "register_operand" "=r")
3096 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3097 ""
3098 "if (!TARGET_64BIT)
3099 {
3100 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3101 DONE;
3102 }
3103 ")
3104
3105 (define_insn "zero_extendsidi2_32"
3106 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3107 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3108 (clobber (reg:CC FLAGS_REG))]
3109 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3110 "@
3111 #
3112 #
3113 #
3114 movd\t{%1, %0|%0, %1}
3115 movd\t{%1, %0|%0, %1}"
3116 [(set_attr "mode" "SI,SI,SI,DI,TI")
3117 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3118
3119 (define_insn "*zero_extendsidi2_32_1"
3120 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3121 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3122 (clobber (reg:CC FLAGS_REG))]
3123 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3124 "@
3125 #
3126 #
3127 #
3128 movd\t{%1, %0|%0, %1}
3129 movd\t{%1, %0|%0, %1}"
3130 [(set_attr "mode" "SI,SI,SI,DI,TI")
3131 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3132
3133 (define_insn "zero_extendsidi2_rex64"
3134 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3135 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3136 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3137 "@
3138 mov\t{%k1, %k0|%k0, %k1}
3139 #
3140 movd\t{%1, %0|%0, %1}
3141 movd\t{%1, %0|%0, %1}"
3142 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3143 (set_attr "mode" "SI,DI,DI,TI")])
3144
3145 (define_insn "*zero_extendsidi2_rex64_1"
3146 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3147 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3148 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3149 "@
3150 mov\t{%k1, %k0|%k0, %k1}
3151 #
3152 movd\t{%1, %0|%0, %1}
3153 movd\t{%1, %0|%0, %1}"
3154 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3155 (set_attr "mode" "SI,DI,SI,SI")])
3156
3157 (define_split
3158 [(set (match_operand:DI 0 "memory_operand" "")
3159 (zero_extend:DI (match_dup 0)))]
3160 "TARGET_64BIT"
3161 [(set (match_dup 4) (const_int 0))]
3162 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3163
3164 (define_split
3165 [(set (match_operand:DI 0 "register_operand" "")
3166 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3167 (clobber (reg:CC FLAGS_REG))]
3168 "!TARGET_64BIT && reload_completed
3169 && true_regnum (operands[0]) == true_regnum (operands[1])"
3170 [(set (match_dup 4) (const_int 0))]
3171 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3172
3173 (define_split
3174 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3175 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3176 (clobber (reg:CC FLAGS_REG))]
3177 "!TARGET_64BIT && reload_completed
3178 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3179 [(set (match_dup 3) (match_dup 1))
3180 (set (match_dup 4) (const_int 0))]
3181 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3182
3183 (define_insn "zero_extendhidi2"
3184 [(set (match_operand:DI 0 "register_operand" "=r,r")
3185 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3186 "TARGET_64BIT"
3187 "@
3188 movz{wl|x}\t{%1, %k0|%k0, %1}
3189 movz{wq|x}\t{%1, %0|%0, %1}"
3190 [(set_attr "type" "imovx")
3191 (set_attr "mode" "SI,DI")])
3192
3193 (define_insn "zero_extendqidi2"
3194 [(set (match_operand:DI 0 "register_operand" "=r,r")
3195 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3196 "TARGET_64BIT"
3197 "@
3198 movz{bl|x}\t{%1, %k0|%k0, %1}
3199 movz{bq|x}\t{%1, %0|%0, %1}"
3200 [(set_attr "type" "imovx")
3201 (set_attr "mode" "SI,DI")])
3202 \f
3203 ;; Sign extension instructions
3204
3205 (define_expand "extendsidi2"
3206 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3207 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3208 (clobber (reg:CC FLAGS_REG))
3209 (clobber (match_scratch:SI 2 ""))])]
3210 ""
3211 {
3212 if (TARGET_64BIT)
3213 {
3214 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3215 DONE;
3216 }
3217 })
3218
3219 (define_insn "*extendsidi2_1"
3220 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3221 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3222 (clobber (reg:CC FLAGS_REG))
3223 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3224 "!TARGET_64BIT"
3225 "#")
3226
3227 (define_insn "extendsidi2_rex64"
3228 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3229 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3230 "TARGET_64BIT"
3231 "@
3232 {cltq|cdqe}
3233 movs{lq|x}\t{%1,%0|%0, %1}"
3234 [(set_attr "type" "imovx")
3235 (set_attr "mode" "DI")
3236 (set_attr "prefix_0f" "0")
3237 (set_attr "modrm" "0,1")])
3238
3239 (define_insn "extendhidi2"
3240 [(set (match_operand:DI 0 "register_operand" "=r")
3241 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3242 "TARGET_64BIT"
3243 "movs{wq|x}\t{%1,%0|%0, %1}"
3244 [(set_attr "type" "imovx")
3245 (set_attr "mode" "DI")])
3246
3247 (define_insn "extendqidi2"
3248 [(set (match_operand:DI 0 "register_operand" "=r")
3249 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3250 "TARGET_64BIT"
3251 "movs{bq|x}\t{%1,%0|%0, %1}"
3252 [(set_attr "type" "imovx")
3253 (set_attr "mode" "DI")])
3254
3255 ;; Extend to memory case when source register does die.
3256 (define_split
3257 [(set (match_operand:DI 0 "memory_operand" "")
3258 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3259 (clobber (reg:CC FLAGS_REG))
3260 (clobber (match_operand:SI 2 "register_operand" ""))]
3261 "(reload_completed
3262 && dead_or_set_p (insn, operands[1])
3263 && !reg_mentioned_p (operands[1], operands[0]))"
3264 [(set (match_dup 3) (match_dup 1))
3265 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3266 (clobber (reg:CC FLAGS_REG))])
3267 (set (match_dup 4) (match_dup 1))]
3268 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3269
3270 ;; Extend to memory case when source register does not die.
3271 (define_split
3272 [(set (match_operand:DI 0 "memory_operand" "")
3273 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3274 (clobber (reg:CC FLAGS_REG))
3275 (clobber (match_operand:SI 2 "register_operand" ""))]
3276 "reload_completed"
3277 [(const_int 0)]
3278 {
3279 split_di (&operands[0], 1, &operands[3], &operands[4]);
3280
3281 emit_move_insn (operands[3], operands[1]);
3282
3283 /* Generate a cltd if possible and doing so it profitable. */
3284 if (true_regnum (operands[1]) == 0
3285 && true_regnum (operands[2]) == 1
3286 && (optimize_size || TARGET_USE_CLTD))
3287 {
3288 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3289 }
3290 else
3291 {
3292 emit_move_insn (operands[2], operands[1]);
3293 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3294 }
3295 emit_move_insn (operands[4], operands[2]);
3296 DONE;
3297 })
3298
3299 ;; Extend to register case. Optimize case where source and destination
3300 ;; registers match and cases where we can use cltd.
3301 (define_split
3302 [(set (match_operand:DI 0 "register_operand" "")
3303 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3304 (clobber (reg:CC FLAGS_REG))
3305 (clobber (match_scratch:SI 2 ""))]
3306 "reload_completed"
3307 [(const_int 0)]
3308 {
3309 split_di (&operands[0], 1, &operands[3], &operands[4]);
3310
3311 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3312 emit_move_insn (operands[3], operands[1]);
3313
3314 /* Generate a cltd if possible and doing so it profitable. */
3315 if (true_regnum (operands[3]) == 0
3316 && (optimize_size || TARGET_USE_CLTD))
3317 {
3318 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3319 DONE;
3320 }
3321
3322 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3323 emit_move_insn (operands[4], operands[1]);
3324
3325 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3326 DONE;
3327 })
3328
3329 (define_insn "extendhisi2"
3330 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3331 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3332 ""
3333 {
3334 switch (get_attr_prefix_0f (insn))
3335 {
3336 case 0:
3337 return "{cwtl|cwde}";
3338 default:
3339 return "movs{wl|x}\t{%1,%0|%0, %1}";
3340 }
3341 }
3342 [(set_attr "type" "imovx")
3343 (set_attr "mode" "SI")
3344 (set (attr "prefix_0f")
3345 ;; movsx is short decodable while cwtl is vector decoded.
3346 (if_then_else (and (eq_attr "cpu" "!k6")
3347 (eq_attr "alternative" "0"))
3348 (const_string "0")
3349 (const_string "1")))
3350 (set (attr "modrm")
3351 (if_then_else (eq_attr "prefix_0f" "0")
3352 (const_string "0")
3353 (const_string "1")))])
3354
3355 (define_insn "*extendhisi2_zext"
3356 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3357 (zero_extend:DI
3358 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3359 "TARGET_64BIT"
3360 {
3361 switch (get_attr_prefix_0f (insn))
3362 {
3363 case 0:
3364 return "{cwtl|cwde}";
3365 default:
3366 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3367 }
3368 }
3369 [(set_attr "type" "imovx")
3370 (set_attr "mode" "SI")
3371 (set (attr "prefix_0f")
3372 ;; movsx is short decodable while cwtl is vector decoded.
3373 (if_then_else (and (eq_attr "cpu" "!k6")
3374 (eq_attr "alternative" "0"))
3375 (const_string "0")
3376 (const_string "1")))
3377 (set (attr "modrm")
3378 (if_then_else (eq_attr "prefix_0f" "0")
3379 (const_string "0")
3380 (const_string "1")))])
3381
3382 (define_insn "extendqihi2"
3383 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3384 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3385 ""
3386 {
3387 switch (get_attr_prefix_0f (insn))
3388 {
3389 case 0:
3390 return "{cbtw|cbw}";
3391 default:
3392 return "movs{bw|x}\t{%1,%0|%0, %1}";
3393 }
3394 }
3395 [(set_attr "type" "imovx")
3396 (set_attr "mode" "HI")
3397 (set (attr "prefix_0f")
3398 ;; movsx is short decodable while cwtl is vector decoded.
3399 (if_then_else (and (eq_attr "cpu" "!k6")
3400 (eq_attr "alternative" "0"))
3401 (const_string "0")
3402 (const_string "1")))
3403 (set (attr "modrm")
3404 (if_then_else (eq_attr "prefix_0f" "0")
3405 (const_string "0")
3406 (const_string "1")))])
3407
3408 (define_insn "extendqisi2"
3409 [(set (match_operand:SI 0 "register_operand" "=r")
3410 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3411 ""
3412 "movs{bl|x}\t{%1,%0|%0, %1}"
3413 [(set_attr "type" "imovx")
3414 (set_attr "mode" "SI")])
3415
3416 (define_insn "*extendqisi2_zext"
3417 [(set (match_operand:DI 0 "register_operand" "=r")
3418 (zero_extend:DI
3419 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3420 "TARGET_64BIT"
3421 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3422 [(set_attr "type" "imovx")
3423 (set_attr "mode" "SI")])
3424 \f
3425 ;; Conversions between float and double.
3426
3427 ;; These are all no-ops in the model used for the 80387. So just
3428 ;; emit moves.
3429
3430 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3431 (define_insn "*dummy_extendsfdf2"
3432 [(set (match_operand:DF 0 "push_operand" "=<")
3433 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3434 "0"
3435 "#")
3436
3437 (define_split
3438 [(set (match_operand:DF 0 "push_operand" "")
3439 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3440 "!TARGET_64BIT"
3441 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3442 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3443
3444 (define_split
3445 [(set (match_operand:DF 0 "push_operand" "")
3446 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3447 "TARGET_64BIT"
3448 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3449 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3450
3451 (define_insn "*dummy_extendsfxf2"
3452 [(set (match_operand:XF 0 "push_operand" "=<")
3453 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3454 "0"
3455 "#")
3456
3457 (define_split
3458 [(set (match_operand:XF 0 "push_operand" "")
3459 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3460 ""
3461 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3462 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3463 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3464
3465 (define_split
3466 [(set (match_operand:XF 0 "push_operand" "")
3467 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3468 "TARGET_64BIT"
3469 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3470 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3471 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3472
3473 (define_split
3474 [(set (match_operand:XF 0 "push_operand" "")
3475 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3476 ""
3477 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3478 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3479 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3480
3481 (define_split
3482 [(set (match_operand:XF 0 "push_operand" "")
3483 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3484 "TARGET_64BIT"
3485 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3486 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3487 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3488
3489 (define_expand "extendsfdf2"
3490 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3491 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3492 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3493 {
3494 /* ??? Needed for compress_float_constant since all fp constants
3495 are LEGITIMATE_CONSTANT_P. */
3496 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3497 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3498 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3499 operands[1] = force_reg (SFmode, operands[1]);
3500 })
3501
3502 (define_insn "*extendsfdf2_mixed"
3503 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3504 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3505 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3506 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3507 {
3508 switch (which_alternative)
3509 {
3510 case 0:
3511 return output_387_reg_move (insn, operands);
3512
3513 case 1:
3514 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3515 return "fstp%z0\t%y0";
3516 else
3517 return "fst%z0\t%y0";
3518
3519 case 2:
3520 return "cvtss2sd\t{%1, %0|%0, %1}";
3521
3522 default:
3523 abort ();
3524 }
3525 }
3526 [(set_attr "type" "fmov,fmov,ssecvt")
3527 (set_attr "mode" "SF,XF,DF")])
3528
3529 (define_insn "*extendsfdf2_sse"
3530 [(set (match_operand:DF 0 "register_operand" "=Y")
3531 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3532 "TARGET_SSE2 && TARGET_SSE_MATH
3533 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3534 "cvtss2sd\t{%1, %0|%0, %1}"
3535 [(set_attr "type" "ssecvt")
3536 (set_attr "mode" "DF")])
3537
3538 (define_insn "*extendsfdf2_i387"
3539 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3540 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3541 "TARGET_80387
3542 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3543 {
3544 switch (which_alternative)
3545 {
3546 case 0:
3547 return output_387_reg_move (insn, operands);
3548
3549 case 1:
3550 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3551 return "fstp%z0\t%y0";
3552 else
3553 return "fst%z0\t%y0";
3554
3555 default:
3556 abort ();
3557 }
3558 }
3559 [(set_attr "type" "fmov")
3560 (set_attr "mode" "SF,XF")])
3561
3562 (define_expand "extendsfxf2"
3563 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3564 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3565 "TARGET_80387"
3566 {
3567 /* ??? Needed for compress_float_constant since all fp constants
3568 are LEGITIMATE_CONSTANT_P. */
3569 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3570 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3571 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3572 operands[1] = force_reg (SFmode, operands[1]);
3573 })
3574
3575 (define_insn "*extendsfxf2_i387"
3576 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3577 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3578 "TARGET_80387
3579 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3580 {
3581 switch (which_alternative)
3582 {
3583 case 0:
3584 return output_387_reg_move (insn, operands);
3585
3586 case 1:
3587 /* There is no non-popping store to memory for XFmode. So if
3588 we need one, follow the store with a load. */
3589 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3590 return "fstp%z0\t%y0";
3591 else
3592 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3593
3594 default:
3595 abort ();
3596 }
3597 }
3598 [(set_attr "type" "fmov")
3599 (set_attr "mode" "SF,XF")])
3600
3601 (define_expand "extenddfxf2"
3602 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3603 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3604 "TARGET_80387"
3605 {
3606 /* ??? Needed for compress_float_constant since all fp constants
3607 are LEGITIMATE_CONSTANT_P. */
3608 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3609 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3610 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3611 operands[1] = force_reg (DFmode, operands[1]);
3612 })
3613
3614 (define_insn "*extenddfxf2_i387"
3615 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3616 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3617 "TARGET_80387
3618 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3619 {
3620 switch (which_alternative)
3621 {
3622 case 0:
3623 return output_387_reg_move (insn, operands);
3624
3625 case 1:
3626 /* There is no non-popping store to memory for XFmode. So if
3627 we need one, follow the store with a load. */
3628 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3629 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3630 else
3631 return "fstp%z0\t%y0";
3632
3633 default:
3634 abort ();
3635 }
3636 }
3637 [(set_attr "type" "fmov")
3638 (set_attr "mode" "DF,XF")])
3639
3640 ;; %%% This seems bad bad news.
3641 ;; This cannot output into an f-reg because there is no way to be sure
3642 ;; of truncating in that case. Otherwise this is just like a simple move
3643 ;; insn. So we pretend we can output to a reg in order to get better
3644 ;; register preferencing, but we really use a stack slot.
3645
3646 ;; Conversion from DFmode to SFmode.
3647
3648 (define_expand "truncdfsf2"
3649 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3650 (float_truncate:SF
3651 (match_operand:DF 1 "nonimmediate_operand" "")))]
3652 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3653 {
3654 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3655 operands[1] = force_reg (DFmode, operands[1]);
3656
3657 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3658 ;
3659 else if (flag_unsafe_math_optimizations)
3660 ;
3661 else
3662 {
3663 rtx temp = assign_386_stack_local (SFmode, 0);
3664 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3665 DONE;
3666 }
3667 })
3668
3669 (define_expand "truncdfsf2_with_temp"
3670 [(parallel [(set (match_operand:SF 0 "" "")
3671 (float_truncate:SF (match_operand:DF 1 "" "")))
3672 (clobber (match_operand:SF 2 "" ""))])]
3673 "")
3674
3675 (define_insn "*truncdfsf_fast_mixed"
3676 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3677 (float_truncate:SF
3678 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3679 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3680 {
3681 switch (which_alternative)
3682 {
3683 case 0:
3684 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3685 return "fstp%z0\t%y0";
3686 else
3687 return "fst%z0\t%y0";
3688 case 1:
3689 return output_387_reg_move (insn, operands);
3690 case 2:
3691 return "cvtsd2ss\t{%1, %0|%0, %1}";
3692 default:
3693 abort ();
3694 }
3695 }
3696 [(set_attr "type" "fmov,fmov,ssecvt")
3697 (set_attr "mode" "SF")])
3698
3699 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3700 ;; because nothing we do here is unsafe.
3701 (define_insn "*truncdfsf_fast_sse"
3702 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3703 (float_truncate:SF
3704 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3705 "TARGET_SSE2 && TARGET_SSE_MATH"
3706 "cvtsd2ss\t{%1, %0|%0, %1}"
3707 [(set_attr "type" "ssecvt")
3708 (set_attr "mode" "SF")])
3709
3710 (define_insn "*truncdfsf_fast_i387"
3711 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3712 (float_truncate:SF
3713 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3714 "TARGET_80387 && flag_unsafe_math_optimizations"
3715 "* return output_387_reg_move (insn, operands);"
3716 [(set_attr "type" "fmov")
3717 (set_attr "mode" "SF")])
3718
3719 (define_insn "*truncdfsf_mixed"
3720 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3721 (float_truncate:SF
3722 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3723 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3724 "TARGET_MIX_SSE_I387"
3725 {
3726 switch (which_alternative)
3727 {
3728 case 0:
3729 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3730 return "fstp%z0\t%y0";
3731 else
3732 return "fst%z0\t%y0";
3733 case 1:
3734 return "#";
3735 case 2:
3736 return "cvtsd2ss\t{%1, %0|%0, %1}";
3737 default:
3738 abort ();
3739 }
3740 }
3741 [(set_attr "type" "fmov,multi,ssecvt")
3742 (set_attr "mode" "SF")])
3743
3744 (define_insn "*truncdfsf_i387"
3745 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3746 (float_truncate:SF
3747 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3748 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3749 "TARGET_80387"
3750 {
3751 switch (which_alternative)
3752 {
3753 case 0:
3754 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3755 return "fstp%z0\t%y0";
3756 else
3757 return "fst%z0\t%y0";
3758 case 1:
3759 return "#";
3760 default:
3761 abort ();
3762 }
3763 }
3764 [(set_attr "type" "fmov,multi")
3765 (set_attr "mode" "SF")])
3766
3767 (define_split
3768 [(set (match_operand:SF 0 "register_operand" "")
3769 (float_truncate:SF
3770 (match_operand:DF 1 "fp_register_operand" "")))
3771 (clobber (match_operand 2 "" ""))]
3772 "reload_completed"
3773 [(set (match_dup 2) (match_dup 1))
3774 (set (match_dup 0) (match_dup 2))]
3775 {
3776 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3777 })
3778
3779 ;; Conversion from XFmode to SFmode.
3780
3781 (define_expand "truncxfsf2"
3782 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3783 (float_truncate:SF
3784 (match_operand:XF 1 "register_operand" "")))
3785 (clobber (match_dup 2))])]
3786 "TARGET_80387"
3787 {
3788 if (flag_unsafe_math_optimizations)
3789 {
3790 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3791 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3792 if (reg != operands[0])
3793 emit_move_insn (operands[0], reg);
3794 DONE;
3795 }
3796 else
3797 operands[2] = assign_386_stack_local (SFmode, 0);
3798 })
3799
3800 (define_insn "*truncxfsf2_mixed"
3801 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3802 (float_truncate:SF
3803 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3804 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3805 "TARGET_MIX_SSE_I387"
3806 {
3807 switch (which_alternative)
3808 {
3809 case 0:
3810 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3811 return "fstp%z0\t%y0";
3812 else
3813 return "fst%z0\t%y0";
3814 default:
3815 abort();
3816 }
3817 }
3818 [(set_attr "type" "fmov,multi,multi,multi")
3819 (set_attr "mode" "SF")])
3820
3821 (define_insn "truncxfsf2_i387_noop"
3822 [(set (match_operand:SF 0 "register_operand" "=f")
3823 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3824 "TARGET_80387 && flag_unsafe_math_optimizations"
3825 {
3826 return output_387_reg_move (insn, operands);
3827 }
3828 [(set_attr "type" "fmov")
3829 (set_attr "mode" "SF")])
3830
3831 (define_insn "*truncxfsf2_i387"
3832 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3833 (float_truncate:SF
3834 (match_operand:XF 1 "register_operand" "f,f,f")))
3835 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3836 "TARGET_80387"
3837 {
3838 switch (which_alternative)
3839 {
3840 case 0:
3841 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3842 return "fstp%z0\t%y0";
3843 else
3844 return "fst%z0\t%y0";
3845 default:
3846 abort ();
3847 }
3848 }
3849 [(set_attr "type" "fmov,multi,multi")
3850 (set_attr "mode" "SF")])
3851
3852 (define_insn "*truncxfsf2_i387_1"
3853 [(set (match_operand:SF 0 "memory_operand" "=m")
3854 (float_truncate:SF
3855 (match_operand:XF 1 "register_operand" "f")))]
3856 "TARGET_80387"
3857 {
3858 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3859 return "fstp%z0\t%y0";
3860 else
3861 return "fst%z0\t%y0";
3862 }
3863 [(set_attr "type" "fmov")
3864 (set_attr "mode" "SF")])
3865
3866 (define_split
3867 [(set (match_operand:SF 0 "register_operand" "")
3868 (float_truncate:SF
3869 (match_operand:XF 1 "register_operand" "")))
3870 (clobber (match_operand:SF 2 "memory_operand" ""))]
3871 "TARGET_80387 && reload_completed"
3872 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3873 (set (match_dup 0) (match_dup 2))]
3874 "")
3875
3876 (define_split
3877 [(set (match_operand:SF 0 "memory_operand" "")
3878 (float_truncate:SF
3879 (match_operand:XF 1 "register_operand" "")))
3880 (clobber (match_operand:SF 2 "memory_operand" ""))]
3881 "TARGET_80387"
3882 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3883 "")
3884
3885 ;; Conversion from XFmode to DFmode.
3886
3887 (define_expand "truncxfdf2"
3888 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3889 (float_truncate:DF
3890 (match_operand:XF 1 "register_operand" "")))
3891 (clobber (match_dup 2))])]
3892 "TARGET_80387"
3893 {
3894 if (flag_unsafe_math_optimizations)
3895 {
3896 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3897 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3898 if (reg != operands[0])
3899 emit_move_insn (operands[0], reg);
3900 DONE;
3901 }
3902 else
3903 operands[2] = assign_386_stack_local (DFmode, 0);
3904 })
3905
3906 (define_insn "*truncxfdf2_mixed"
3907 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3908 (float_truncate:DF
3909 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3910 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3911 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3912 {
3913 switch (which_alternative)
3914 {
3915 case 0:
3916 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3917 return "fstp%z0\t%y0";
3918 else
3919 return "fst%z0\t%y0";
3920 default:
3921 abort();
3922 }
3923 abort ();
3924 }
3925 [(set_attr "type" "fmov,multi,multi,multi")
3926 (set_attr "mode" "DF")])
3927
3928 (define_insn "truncxfdf2_i387_noop"
3929 [(set (match_operand:DF 0 "register_operand" "=f")
3930 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3931 "TARGET_80387 && flag_unsafe_math_optimizations"
3932 {
3933 return output_387_reg_move (insn, operands);
3934 }
3935 [(set_attr "type" "fmov")
3936 (set_attr "mode" "DF")])
3937
3938 (define_insn "*truncxfdf2_i387"
3939 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3940 (float_truncate:DF
3941 (match_operand:XF 1 "register_operand" "f,f,f")))
3942 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3943 "TARGET_80387"
3944 {
3945 switch (which_alternative)
3946 {
3947 case 0:
3948 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3949 return "fstp%z0\t%y0";
3950 else
3951 return "fst%z0\t%y0";
3952 default:
3953 abort ();
3954 }
3955 }
3956 [(set_attr "type" "fmov,multi,multi")
3957 (set_attr "mode" "DF")])
3958
3959 (define_insn "*truncxfdf2_i387_1"
3960 [(set (match_operand:DF 0 "memory_operand" "=m")
3961 (float_truncate:DF
3962 (match_operand:XF 1 "register_operand" "f")))]
3963 "TARGET_80387"
3964 {
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")
3971 (set_attr "mode" "DF")])
3972
3973 (define_split
3974 [(set (match_operand:DF 0 "register_operand" "")
3975 (float_truncate:DF
3976 (match_operand:XF 1 "register_operand" "")))
3977 (clobber (match_operand:DF 2 "memory_operand" ""))]
3978 "TARGET_80387 && reload_completed"
3979 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3980 (set (match_dup 0) (match_dup 2))]
3981 "")
3982
3983 (define_split
3984 [(set (match_operand:DF 0 "memory_operand" "")
3985 (float_truncate:DF
3986 (match_operand:XF 1 "register_operand" "")))
3987 (clobber (match_operand:DF 2 "memory_operand" ""))]
3988 "TARGET_80387"
3989 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3990 "")
3991 \f
3992 ;; %%% Break up all these bad boys.
3993
3994 ;; Signed conversion to DImode.
3995
3996 (define_expand "fix_truncxfdi2"
3997 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3998 (fix:DI (match_operand:XF 1 "register_operand" "")))
3999 (clobber (reg:CC FLAGS_REG))])]
4000 "TARGET_80387"
4001 "")
4002
4003 (define_expand "fix_truncdfdi2"
4004 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4005 (fix:DI (match_operand:DF 1 "register_operand" "")))
4006 (clobber (reg:CC FLAGS_REG))])]
4007 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2)"
4008 {
4009 if (TARGET_64BIT && TARGET_SSE2)
4010 {
4011 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4012 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4013 if (out != operands[0])
4014 emit_move_insn (operands[0], out);
4015 DONE;
4016 }
4017 })
4018
4019 (define_expand "fix_truncsfdi2"
4020 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4021 (fix:DI (match_operand:SF 1 "register_operand" "")))
4022 (clobber (reg:CC FLAGS_REG))])]
4023 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE)"
4024 {
4025 if (TARGET_64BIT && TARGET_SSE)
4026 {
4027 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4028 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4029 if (out != operands[0])
4030 emit_move_insn (operands[0], out);
4031 DONE;
4032 }
4033 })
4034
4035 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4036 ;; of the machinery.
4037 (define_insn_and_split "*fix_truncdi_i387"
4038 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4039 (fix:DI (match_operand 1 "register_operand" "f,f")))
4040 (clobber (reg:CC FLAGS_REG))]
4041 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4042 && !reload_completed && !reload_in_progress
4043 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4044 "#"
4045 "&& 1"
4046 [(const_int 0)]
4047 {
4048 ix86_optimize_mode_switching = 1;
4049 operands[2] = assign_386_stack_local (HImode, 1);
4050 operands[3] = assign_386_stack_local (HImode, 2);
4051 if (memory_operand (operands[0], VOIDmode))
4052 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4053 operands[2], operands[3]));
4054 else
4055 {
4056 operands[4] = assign_386_stack_local (DImode, 0);
4057 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4058 operands[2], operands[3],
4059 operands[4]));
4060 }
4061 DONE;
4062 }
4063 [(set_attr "type" "fistp")
4064 (set_attr "i387_cw" "trunc")
4065 (set_attr "mode" "DI")])
4066
4067 (define_insn "fix_truncdi_nomemory"
4068 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4069 (fix:DI (match_operand 1 "register_operand" "f,f")))
4070 (use (match_operand:HI 2 "memory_operand" "m,m"))
4071 (use (match_operand:HI 3 "memory_operand" "m,m"))
4072 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4073 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4074 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4075 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4076 "#"
4077 [(set_attr "type" "fistp")
4078 (set_attr "i387_cw" "trunc")
4079 (set_attr "mode" "DI")])
4080
4081 (define_insn "fix_truncdi_memory"
4082 [(set (match_operand:DI 0 "memory_operand" "=m")
4083 (fix:DI (match_operand 1 "register_operand" "f")))
4084 (use (match_operand:HI 2 "memory_operand" "m"))
4085 (use (match_operand:HI 3 "memory_operand" "m"))
4086 (clobber (match_scratch:DF 4 "=&1f"))]
4087 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4088 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4089 "* return output_fix_trunc (insn, operands);"
4090 [(set_attr "type" "fistp")
4091 (set_attr "i387_cw" "trunc")
4092 (set_attr "mode" "DI")])
4093
4094 (define_split
4095 [(set (match_operand:DI 0 "register_operand" "")
4096 (fix:DI (match_operand 1 "register_operand" "")))
4097 (use (match_operand:HI 2 "memory_operand" ""))
4098 (use (match_operand:HI 3 "memory_operand" ""))
4099 (clobber (match_operand:DI 4 "memory_operand" ""))
4100 (clobber (match_scratch 5 ""))]
4101 "reload_completed"
4102 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4103 (use (match_dup 2))
4104 (use (match_dup 3))
4105 (clobber (match_dup 5))])
4106 (set (match_dup 0) (match_dup 4))]
4107 "")
4108
4109 (define_split
4110 [(set (match_operand:DI 0 "memory_operand" "")
4111 (fix:DI (match_operand 1 "register_operand" "")))
4112 (use (match_operand:HI 2 "memory_operand" ""))
4113 (use (match_operand:HI 3 "memory_operand" ""))
4114 (clobber (match_operand:DI 4 "memory_operand" ""))
4115 (clobber (match_scratch 5 ""))]
4116 "reload_completed"
4117 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4118 (use (match_dup 2))
4119 (use (match_dup 3))
4120 (clobber (match_dup 5))])]
4121 "")
4122
4123 ;; When SSE available, it is always faster to use it!
4124 (define_insn "fix_truncsfdi_sse"
4125 [(set (match_operand:DI 0 "register_operand" "=r,r")
4126 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4127 "TARGET_64BIT && TARGET_SSE"
4128 "cvttss2si{q}\t{%1, %0|%0, %1}"
4129 [(set_attr "type" "sseicvt")
4130 (set_attr "mode" "SF")
4131 (set_attr "athlon_decode" "double,vector")])
4132
4133 ;; Avoid vector decoded form of the instruction.
4134 (define_peephole2
4135 [(match_scratch:SF 2 "x")
4136 (set (match_operand:DI 0 "register_operand" "")
4137 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4138 "TARGET_K8 && !optimize_size"
4139 [(set (match_dup 2) (match_dup 1))
4140 (set (match_dup 0) (fix:DI (match_dup 2)))]
4141 "")
4142
4143 (define_insn "fix_truncdfdi_sse"
4144 [(set (match_operand:DI 0 "register_operand" "=r,r")
4145 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4146 "TARGET_64BIT && TARGET_SSE2"
4147 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4148 [(set_attr "type" "sseicvt,sseicvt")
4149 (set_attr "mode" "DF")
4150 (set_attr "athlon_decode" "double,vector")])
4151
4152 ;; Avoid vector decoded form of the instruction.
4153 (define_peephole2
4154 [(match_scratch:DF 2 "Y")
4155 (set (match_operand:DI 0 "register_operand" "")
4156 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4157 "TARGET_K8 && !optimize_size"
4158 [(set (match_dup 2) (match_dup 1))
4159 (set (match_dup 0) (fix:DI (match_dup 2)))]
4160 "")
4161
4162 ;; Signed conversion to SImode.
4163
4164 (define_expand "fix_truncxfsi2"
4165 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4166 (fix:SI (match_operand:XF 1 "register_operand" "")))
4167 (clobber (reg:CC FLAGS_REG))])]
4168 "TARGET_80387"
4169 "")
4170
4171 (define_expand "fix_truncdfsi2"
4172 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4173 (fix:SI (match_operand:DF 1 "register_operand" "")))
4174 (clobber (reg:CC FLAGS_REG))])]
4175 "TARGET_80387 || TARGET_SSE2"
4176 {
4177 if (TARGET_SSE2)
4178 {
4179 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4180 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4181 if (out != operands[0])
4182 emit_move_insn (operands[0], out);
4183 DONE;
4184 }
4185 })
4186
4187 (define_expand "fix_truncsfsi2"
4188 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4189 (fix:SI (match_operand:SF 1 "register_operand" "")))
4190 (clobber (reg:CC FLAGS_REG))])]
4191 "TARGET_80387 || TARGET_SSE"
4192 {
4193 if (TARGET_SSE)
4194 {
4195 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4196 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4197 if (out != operands[0])
4198 emit_move_insn (operands[0], out);
4199 DONE;
4200 }
4201 })
4202
4203 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4204 ;; of the machinery.
4205 (define_insn_and_split "*fix_truncsi_i387"
4206 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4207 (fix:SI (match_operand 1 "register_operand" "f,f")))
4208 (clobber (reg:CC FLAGS_REG))]
4209 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4210 && !reload_completed && !reload_in_progress
4211 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4212 "#"
4213 "&& 1"
4214 [(const_int 0)]
4215 {
4216 ix86_optimize_mode_switching = 1;
4217 operands[2] = assign_386_stack_local (HImode, 1);
4218 operands[3] = assign_386_stack_local (HImode, 2);
4219 if (memory_operand (operands[0], VOIDmode))
4220 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4221 operands[2], operands[3]));
4222 else
4223 {
4224 operands[4] = assign_386_stack_local (SImode, 0);
4225 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4226 operands[2], operands[3],
4227 operands[4]));
4228 }
4229 DONE;
4230 }
4231 [(set_attr "type" "fistp")
4232 (set_attr "i387_cw" "trunc")
4233 (set_attr "mode" "SI")])
4234
4235 (define_insn "fix_truncsi_nomemory"
4236 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4237 (fix:SI (match_operand 1 "register_operand" "f,f")))
4238 (use (match_operand:HI 2 "memory_operand" "m,m"))
4239 (use (match_operand:HI 3 "memory_operand" "m,m"))
4240 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4241 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4242 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4243 "#"
4244 [(set_attr "type" "fistp")
4245 (set_attr "i387_cw" "trunc")
4246 (set_attr "mode" "SI")])
4247
4248 (define_insn "fix_truncsi_memory"
4249 [(set (match_operand:SI 0 "memory_operand" "=m")
4250 (fix:SI (match_operand 1 "register_operand" "f")))
4251 (use (match_operand:HI 2 "memory_operand" "m"))
4252 (use (match_operand:HI 3 "memory_operand" "m"))]
4253 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4254 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4255 "* return output_fix_trunc (insn, operands);"
4256 [(set_attr "type" "fistp")
4257 (set_attr "i387_cw" "trunc")
4258 (set_attr "mode" "SI")])
4259
4260 ;; When SSE available, it is always faster to use it!
4261 (define_insn "fix_truncsfsi_sse"
4262 [(set (match_operand:SI 0 "register_operand" "=r,r")
4263 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4264 "TARGET_SSE"
4265 "cvttss2si\t{%1, %0|%0, %1}"
4266 [(set_attr "type" "sseicvt")
4267 (set_attr "mode" "DF")
4268 (set_attr "athlon_decode" "double,vector")])
4269
4270 ;; Avoid vector decoded form of the instruction.
4271 (define_peephole2
4272 [(match_scratch:SF 2 "x")
4273 (set (match_operand:SI 0 "register_operand" "")
4274 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4275 "TARGET_K8 && !optimize_size"
4276 [(set (match_dup 2) (match_dup 1))
4277 (set (match_dup 0) (fix:SI (match_dup 2)))]
4278 "")
4279
4280 (define_insn "fix_truncdfsi_sse"
4281 [(set (match_operand:SI 0 "register_operand" "=r,r")
4282 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4283 "TARGET_SSE2"
4284 "cvttsd2si\t{%1, %0|%0, %1}"
4285 [(set_attr "type" "sseicvt")
4286 (set_attr "mode" "DF")
4287 (set_attr "athlon_decode" "double,vector")])
4288
4289 ;; Avoid vector decoded form of the instruction.
4290 (define_peephole2
4291 [(match_scratch:DF 2 "Y")
4292 (set (match_operand:SI 0 "register_operand" "")
4293 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4294 "TARGET_K8 && !optimize_size"
4295 [(set (match_dup 2) (match_dup 1))
4296 (set (match_dup 0) (fix:SI (match_dup 2)))]
4297 "")
4298
4299 (define_split
4300 [(set (match_operand:SI 0 "register_operand" "")
4301 (fix:SI (match_operand 1 "register_operand" "")))
4302 (use (match_operand:HI 2 "memory_operand" ""))
4303 (use (match_operand:HI 3 "memory_operand" ""))
4304 (clobber (match_operand:SI 4 "memory_operand" ""))]
4305 "reload_completed"
4306 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4307 (use (match_dup 2))
4308 (use (match_dup 3))])
4309 (set (match_dup 0) (match_dup 4))]
4310 "")
4311
4312 (define_split
4313 [(set (match_operand:SI 0 "memory_operand" "")
4314 (fix:SI (match_operand 1 "register_operand" "")))
4315 (use (match_operand:HI 2 "memory_operand" ""))
4316 (use (match_operand:HI 3 "memory_operand" ""))
4317 (clobber (match_operand:SI 4 "memory_operand" ""))]
4318 "reload_completed"
4319 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4320 (use (match_dup 2))
4321 (use (match_dup 3))])]
4322 "")
4323
4324 ;; Signed conversion to HImode.
4325
4326 (define_expand "fix_truncxfhi2"
4327 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4328 (fix:HI (match_operand:XF 1 "register_operand" "")))
4329 (clobber (reg:CC FLAGS_REG))])]
4330 "TARGET_80387"
4331 "")
4332
4333 (define_expand "fix_truncdfhi2"
4334 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4335 (fix:HI (match_operand:DF 1 "register_operand" "")))
4336 (clobber (reg:CC FLAGS_REG))])]
4337 "TARGET_80387 && !TARGET_SSE2"
4338 "")
4339
4340 (define_expand "fix_truncsfhi2"
4341 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4342 (fix:HI (match_operand:SF 1 "register_operand" "")))
4343 (clobber (reg:CC FLAGS_REG))])]
4344 "TARGET_80387 && !TARGET_SSE"
4345 "")
4346
4347 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4348 ;; of the machinery.
4349 (define_insn_and_split "*fix_trunchi_i387"
4350 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4351 (fix:HI (match_operand 1 "register_operand" "f,f")))
4352 (clobber (reg:CC FLAGS_REG))]
4353 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4354 && !reload_completed && !reload_in_progress
4355 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4356 "#"
4357 "&& 1"
4358 [(const_int 0)]
4359 {
4360 ix86_optimize_mode_switching = 1;
4361 operands[2] = assign_386_stack_local (HImode, 1);
4362 operands[3] = assign_386_stack_local (HImode, 2);
4363 if (memory_operand (operands[0], VOIDmode))
4364 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4365 operands[2], operands[3]));
4366 else
4367 {
4368 operands[4] = assign_386_stack_local (HImode, 0);
4369 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4370 operands[2], operands[3],
4371 operands[4]));
4372 }
4373 DONE;
4374 }
4375 [(set_attr "type" "fistp")
4376 (set_attr "i387_cw" "trunc")
4377 (set_attr "mode" "HI")])
4378
4379 (define_insn "fix_trunchi_nomemory"
4380 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4381 (fix:HI (match_operand 1 "register_operand" "f,f")))
4382 (use (match_operand:HI 2 "memory_operand" "m,m"))
4383 (use (match_operand:HI 3 "memory_operand" "m,m"))
4384 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4385 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4386 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4387 "#"
4388 [(set_attr "type" "fistp")
4389 (set_attr "i387_cw" "trunc")
4390 (set_attr "mode" "HI")])
4391
4392 (define_insn "fix_trunchi_memory"
4393 [(set (match_operand:HI 0 "memory_operand" "=m")
4394 (fix:HI (match_operand 1 "register_operand" "f")))
4395 (use (match_operand:HI 2 "memory_operand" "m"))
4396 (use (match_operand:HI 3 "memory_operand" "m"))]
4397 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4398 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4399 "* return output_fix_trunc (insn, operands);"
4400 [(set_attr "type" "fistp")
4401 (set_attr "i387_cw" "trunc")
4402 (set_attr "mode" "HI")])
4403
4404 (define_split
4405 [(set (match_operand:HI 0 "memory_operand" "")
4406 (fix:HI (match_operand 1 "register_operand" "")))
4407 (use (match_operand:HI 2 "memory_operand" ""))
4408 (use (match_operand:HI 3 "memory_operand" ""))
4409 (clobber (match_operand:HI 4 "memory_operand" ""))]
4410 "reload_completed"
4411 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4412 (use (match_dup 2))
4413 (use (match_dup 3))])]
4414 "")
4415
4416 (define_split
4417 [(set (match_operand:HI 0 "register_operand" "")
4418 (fix:HI (match_operand 1 "register_operand" "")))
4419 (use (match_operand:HI 2 "memory_operand" ""))
4420 (use (match_operand:HI 3 "memory_operand" ""))
4421 (clobber (match_operand:HI 4 "memory_operand" ""))]
4422 "reload_completed"
4423 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4424 (use (match_dup 2))
4425 (use (match_dup 3))
4426 (clobber (match_dup 4))])
4427 (set (match_dup 0) (match_dup 4))]
4428 "")
4429
4430 (define_insn "x86_fnstcw_1"
4431 [(set (match_operand:HI 0 "memory_operand" "=m")
4432 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4433 "TARGET_80387"
4434 "fnstcw\t%0"
4435 [(set_attr "length" "2")
4436 (set_attr "mode" "HI")
4437 (set_attr "unit" "i387")])
4438
4439 (define_insn "x86_fldcw_1"
4440 [(set (reg:HI FPSR_REG)
4441 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4442 "TARGET_80387"
4443 "fldcw\t%0"
4444 [(set_attr "length" "2")
4445 (set_attr "mode" "HI")
4446 (set_attr "unit" "i387")
4447 (set_attr "athlon_decode" "vector")])
4448 \f
4449 ;; Conversion between fixed point and floating point.
4450
4451 ;; Even though we only accept memory inputs, the backend _really_
4452 ;; wants to be able to do this between registers.
4453
4454 (define_expand "floathisf2"
4455 [(set (match_operand:SF 0 "register_operand" "")
4456 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4457 "TARGET_80387 || TARGET_SSE_MATH"
4458 {
4459 if (TARGET_SSE_MATH)
4460 {
4461 emit_insn (gen_floatsisf2 (operands[0],
4462 convert_to_mode (SImode, operands[1], 0)));
4463 DONE;
4464 }
4465 })
4466
4467 (define_insn "*floathisf2_i387"
4468 [(set (match_operand:SF 0 "register_operand" "=f,f")
4469 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4470 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4471 "@
4472 fild%z1\t%1
4473 #"
4474 [(set_attr "type" "fmov,multi")
4475 (set_attr "mode" "SF")
4476 (set_attr "fp_int_src" "true")])
4477
4478 (define_expand "floatsisf2"
4479 [(set (match_operand:SF 0 "register_operand" "")
4480 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4481 "TARGET_80387 || TARGET_SSE_MATH"
4482 "")
4483
4484 (define_insn "*floatsisf2_mixed"
4485 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4486 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4487 "TARGET_MIX_SSE_I387"
4488 "@
4489 fild%z1\t%1
4490 #
4491 cvtsi2ss\t{%1, %0|%0, %1}
4492 cvtsi2ss\t{%1, %0|%0, %1}"
4493 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4494 (set_attr "mode" "SF")
4495 (set_attr "athlon_decode" "*,*,vector,double")
4496 (set_attr "fp_int_src" "true")])
4497
4498 (define_insn "*floatsisf2_sse"
4499 [(set (match_operand:SF 0 "register_operand" "=x,x")
4500 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4501 "TARGET_SSE_MATH"
4502 "cvtsi2ss\t{%1, %0|%0, %1}"
4503 [(set_attr "type" "sseicvt")
4504 (set_attr "mode" "SF")
4505 (set_attr "athlon_decode" "vector,double")
4506 (set_attr "fp_int_src" "true")])
4507
4508 (define_insn "*floatsisf2_i387"
4509 [(set (match_operand:SF 0 "register_operand" "=f,f")
4510 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4511 "TARGET_80387"
4512 "@
4513 fild%z1\t%1
4514 #"
4515 [(set_attr "type" "fmov,multi")
4516 (set_attr "mode" "SF")
4517 (set_attr "fp_int_src" "true")])
4518
4519 (define_expand "floatdisf2"
4520 [(set (match_operand:SF 0 "register_operand" "")
4521 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4522 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4523 "")
4524
4525 (define_insn "*floatdisf2_mixed"
4526 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4527 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4528 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4529 "@
4530 fild%z1\t%1
4531 #
4532 cvtsi2ss{q}\t{%1, %0|%0, %1}
4533 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4534 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4535 (set_attr "mode" "SF")
4536 (set_attr "athlon_decode" "*,*,vector,double")
4537 (set_attr "fp_int_src" "true")])
4538
4539 (define_insn "*floatdisf2_sse"
4540 [(set (match_operand:SF 0 "register_operand" "=x,x")
4541 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4542 "TARGET_64BIT && TARGET_SSE_MATH"
4543 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4544 [(set_attr "type" "sseicvt")
4545 (set_attr "mode" "SF")
4546 (set_attr "athlon_decode" "vector,double")
4547 (set_attr "fp_int_src" "true")])
4548
4549 (define_insn "*floatdisf2_i387"
4550 [(set (match_operand:SF 0 "register_operand" "=f,f")
4551 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4552 "TARGET_80387"
4553 "@
4554 fild%z1\t%1
4555 #"
4556 [(set_attr "type" "fmov,multi")
4557 (set_attr "mode" "SF")
4558 (set_attr "fp_int_src" "true")])
4559
4560 (define_expand "floathidf2"
4561 [(set (match_operand:DF 0 "register_operand" "")
4562 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4563 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4564 {
4565 if (TARGET_SSE2 && TARGET_SSE_MATH)
4566 {
4567 emit_insn (gen_floatsidf2 (operands[0],
4568 convert_to_mode (SImode, operands[1], 0)));
4569 DONE;
4570 }
4571 })
4572
4573 (define_insn "*floathidf2_i387"
4574 [(set (match_operand:DF 0 "register_operand" "=f,f")
4575 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4576 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4577 "@
4578 fild%z1\t%1
4579 #"
4580 [(set_attr "type" "fmov,multi")
4581 (set_attr "mode" "DF")
4582 (set_attr "fp_int_src" "true")])
4583
4584 (define_expand "floatsidf2"
4585 [(set (match_operand:DF 0 "register_operand" "")
4586 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4587 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4588 "")
4589
4590 (define_insn "*floatsidf2_mixed"
4591 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4592 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4593 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4594 "@
4595 fild%z1\t%1
4596 #
4597 cvtsi2sd\t{%1, %0|%0, %1}
4598 cvtsi2sd\t{%1, %0|%0, %1}"
4599 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4600 (set_attr "mode" "DF")
4601 (set_attr "athlon_decode" "*,*,double,direct")
4602 (set_attr "fp_int_src" "true")])
4603
4604 (define_insn "*floatsidf2_sse"
4605 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4606 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4607 "TARGET_SSE2 && TARGET_SSE_MATH"
4608 "cvtsi2sd\t{%1, %0|%0, %1}"
4609 [(set_attr "type" "sseicvt")
4610 (set_attr "mode" "DF")
4611 (set_attr "athlon_decode" "double,direct")
4612 (set_attr "fp_int_src" "true")])
4613
4614 (define_insn "*floatsidf2_i387"
4615 [(set (match_operand:DF 0 "register_operand" "=f,f")
4616 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4617 "TARGET_80387"
4618 "@
4619 fild%z1\t%1
4620 #"
4621 [(set_attr "type" "fmov,multi")
4622 (set_attr "mode" "DF")
4623 (set_attr "fp_int_src" "true")])
4624
4625 (define_expand "floatdidf2"
4626 [(set (match_operand:DF 0 "register_operand" "")
4627 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4628 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4629 "")
4630
4631 (define_insn "*floatdidf2_mixed"
4632 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4633 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4634 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4635 "@
4636 fild%z1\t%1
4637 #
4638 cvtsi2sd{q}\t{%1, %0|%0, %1}
4639 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4640 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4641 (set_attr "mode" "DF")
4642 (set_attr "athlon_decode" "*,*,double,direct")
4643 (set_attr "fp_int_src" "true")])
4644
4645 (define_insn "*floatdidf2_sse"
4646 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4647 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4648 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4649 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4650 [(set_attr "type" "sseicvt")
4651 (set_attr "mode" "DF")
4652 (set_attr "athlon_decode" "double,direct")
4653 (set_attr "fp_int_src" "true")])
4654
4655 (define_insn "*floatdidf2_i387"
4656 [(set (match_operand:DF 0 "register_operand" "=f,f")
4657 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4658 "TARGET_80387"
4659 "@
4660 fild%z1\t%1
4661 #"
4662 [(set_attr "type" "fmov,multi")
4663 (set_attr "mode" "DF")
4664 (set_attr "fp_int_src" "true")])
4665
4666 (define_insn "floathixf2"
4667 [(set (match_operand:XF 0 "register_operand" "=f,f")
4668 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4669 "TARGET_80387"
4670 "@
4671 fild%z1\t%1
4672 #"
4673 [(set_attr "type" "fmov,multi")
4674 (set_attr "mode" "XF")
4675 (set_attr "fp_int_src" "true")])
4676
4677 (define_insn "floatsixf2"
4678 [(set (match_operand:XF 0 "register_operand" "=f,f")
4679 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4680 "TARGET_80387"
4681 "@
4682 fild%z1\t%1
4683 #"
4684 [(set_attr "type" "fmov,multi")
4685 (set_attr "mode" "XF")
4686 (set_attr "fp_int_src" "true")])
4687
4688 (define_insn "floatdixf2"
4689 [(set (match_operand:XF 0 "register_operand" "=f,f")
4690 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4691 "TARGET_80387"
4692 "@
4693 fild%z1\t%1
4694 #"
4695 [(set_attr "type" "fmov,multi")
4696 (set_attr "mode" "XF")
4697 (set_attr "fp_int_src" "true")])
4698
4699 ;; %%% Kill these when reload knows how to do it.
4700 (define_split
4701 [(set (match_operand 0 "fp_register_operand" "")
4702 (float (match_operand 1 "register_operand" "")))]
4703 "reload_completed
4704 && TARGET_80387
4705 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4706 [(const_int 0)]
4707 {
4708 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4709 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4710 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4711 ix86_free_from_memory (GET_MODE (operands[1]));
4712 DONE;
4713 })
4714
4715 (define_expand "floatunssisf2"
4716 [(use (match_operand:SF 0 "register_operand" ""))
4717 (use (match_operand:SI 1 "register_operand" ""))]
4718 "!TARGET_64BIT && TARGET_SSE_MATH"
4719 "x86_emit_floatuns (operands); DONE;")
4720
4721 (define_expand "floatunsdisf2"
4722 [(use (match_operand:SF 0 "register_operand" ""))
4723 (use (match_operand:DI 1 "register_operand" ""))]
4724 "TARGET_64BIT && TARGET_SSE_MATH"
4725 "x86_emit_floatuns (operands); DONE;")
4726
4727 (define_expand "floatunsdidf2"
4728 [(use (match_operand:DF 0 "register_operand" ""))
4729 (use (match_operand:DI 1 "register_operand" ""))]
4730 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4731 "x86_emit_floatuns (operands); DONE;")
4732 \f
4733 ;; SSE extract/set expanders
4734
4735 (define_expand "vec_setv2df"
4736 [(match_operand:V2DF 0 "register_operand" "")
4737 (match_operand:DF 1 "register_operand" "")
4738 (match_operand 2 "const_int_operand" "")]
4739 "TARGET_SSE2"
4740 {
4741 switch (INTVAL (operands[2]))
4742 {
4743 case 0:
4744 emit_insn (gen_sse2_loadlpd (operands[0], operands[0], operands[1]));
4745 break;
4746 case 1:
4747 emit_insn (gen_sse2_loadhpd (operands[0], operands[0], operands[1]));
4748 break;
4749 default:
4750 abort ();
4751 }
4752 DONE;
4753 })
4754
4755 (define_expand "vec_extractv2df"
4756 [(match_operand:DF 0 "register_operand" "")
4757 (match_operand:V2DF 1 "register_operand" "")
4758 (match_operand 2 "const_int_operand" "")]
4759 "TARGET_SSE2"
4760 {
4761 switch (INTVAL (operands[2]))
4762 {
4763 case 0:
4764 emit_insn (gen_sse2_storelpd (operands[0], operands[1]));
4765 break;
4766 case 1:
4767 emit_insn (gen_sse2_storehpd (operands[0], operands[1]));
4768 break;
4769 default:
4770 abort ();
4771 }
4772 DONE;
4773 })
4774
4775 (define_expand "vec_initv2df"
4776 [(match_operand:V2DF 0 "register_operand" "")
4777 (match_operand 1 "" "")]
4778 "TARGET_SSE2"
4779 {
4780 ix86_expand_vector_init (operands[0], operands[1]);
4781 DONE;
4782 })
4783
4784 (define_expand "vec_setv4sf"
4785 [(match_operand:V4SF 0 "register_operand" "")
4786 (match_operand:SF 1 "register_operand" "")
4787 (match_operand 2 "const_int_operand" "")]
4788 "TARGET_SSE"
4789 {
4790 switch (INTVAL (operands[2]))
4791 {
4792 case 0:
4793 emit_insn (gen_sse_movss (operands[0], operands[0],
4794 simplify_gen_subreg (V4SFmode, operands[1],
4795 SFmode, 0)));
4796 break;
4797 case 1:
4798 {
4799 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4800 rtx tmp = gen_reg_rtx (V4SFmode);
4801
4802 emit_move_insn (tmp, operands[0]);
4803 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4804 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4805 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4806 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4807 }
4808 break;
4809 case 2:
4810 {
4811 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4812 rtx tmp = gen_reg_rtx (V4SFmode);
4813
4814 emit_move_insn (tmp, operands[0]);
4815 emit_insn (gen_sse_movss (tmp, tmp, op1));
4816 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4817 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4818 }
4819 break;
4820 case 3:
4821 {
4822 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4823 rtx tmp = gen_reg_rtx (V4SFmode);
4824
4825 emit_move_insn (tmp, operands[0]);
4826 emit_insn (gen_sse_movss (tmp, tmp, op1));
4827 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4828 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4829 }
4830 break;
4831 default:
4832 abort ();
4833 }
4834 DONE;
4835 })
4836
4837 (define_expand "vec_extractv4sf"
4838 [(match_operand:SF 0 "register_operand" "")
4839 (match_operand:V4SF 1 "register_operand" "")
4840 (match_operand 2 "const_int_operand" "")]
4841 "TARGET_SSE"
4842 {
4843 switch (INTVAL (operands[2]))
4844 {
4845 case 0:
4846 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4847 break;
4848 case 1:
4849 {
4850 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4851 rtx tmp = gen_reg_rtx (V4SFmode);
4852
4853 emit_move_insn (tmp, operands[1]);
4854 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4855 const1_rtx));
4856 }
4857 break;
4858 case 2:
4859 {
4860 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4861 rtx tmp = gen_reg_rtx (V4SFmode);
4862
4863 emit_move_insn (tmp, operands[1]);
4864 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4865 }
4866 break;
4867 case 3:
4868 {
4869 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4870 rtx tmp = gen_reg_rtx (V4SFmode);
4871
4872 emit_move_insn (tmp, operands[1]);
4873 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4874 GEN_INT (3)));
4875 }
4876 break;
4877 default:
4878 abort ();
4879 }
4880 DONE;
4881 })
4882
4883 (define_expand "vec_initv4sf"
4884 [(match_operand:V4SF 0 "register_operand" "")
4885 (match_operand 1 "" "")]
4886 "TARGET_SSE"
4887 {
4888 ix86_expand_vector_init (operands[0], operands[1]);
4889 DONE;
4890 })
4891 \f
4892 ;; Add instructions
4893
4894 ;; %%% splits for addsidi3
4895 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4896 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4897 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4898
4899 (define_expand "adddi3"
4900 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4901 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4902 (match_operand:DI 2 "x86_64_general_operand" "")))
4903 (clobber (reg:CC FLAGS_REG))]
4904 ""
4905 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4906
4907 (define_insn "*adddi3_1"
4908 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4909 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4910 (match_operand:DI 2 "general_operand" "roiF,riF")))
4911 (clobber (reg:CC FLAGS_REG))]
4912 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4913 "#")
4914
4915 (define_split
4916 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4917 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4918 (match_operand:DI 2 "general_operand" "")))
4919 (clobber (reg:CC FLAGS_REG))]
4920 "!TARGET_64BIT && reload_completed"
4921 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4922 UNSPEC_ADD_CARRY))
4923 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4924 (parallel [(set (match_dup 3)
4925 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4926 (match_dup 4))
4927 (match_dup 5)))
4928 (clobber (reg:CC FLAGS_REG))])]
4929 "split_di (operands+0, 1, operands+0, operands+3);
4930 split_di (operands+1, 1, operands+1, operands+4);
4931 split_di (operands+2, 1, operands+2, operands+5);")
4932
4933 (define_insn "adddi3_carry_rex64"
4934 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4935 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4936 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4937 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4938 (clobber (reg:CC FLAGS_REG))]
4939 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4940 "adc{q}\t{%2, %0|%0, %2}"
4941 [(set_attr "type" "alu")
4942 (set_attr "pent_pair" "pu")
4943 (set_attr "mode" "DI")])
4944
4945 (define_insn "*adddi3_cc_rex64"
4946 [(set (reg:CC FLAGS_REG)
4947 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4948 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4949 UNSPEC_ADD_CARRY))
4950 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4951 (plus:DI (match_dup 1) (match_dup 2)))]
4952 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4953 "add{q}\t{%2, %0|%0, %2}"
4954 [(set_attr "type" "alu")
4955 (set_attr "mode" "DI")])
4956
4957 (define_insn "addqi3_carry"
4958 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4959 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4960 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4961 (match_operand:QI 2 "general_operand" "qi,qm")))
4962 (clobber (reg:CC FLAGS_REG))]
4963 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4964 "adc{b}\t{%2, %0|%0, %2}"
4965 [(set_attr "type" "alu")
4966 (set_attr "pent_pair" "pu")
4967 (set_attr "mode" "QI")])
4968
4969 (define_insn "addhi3_carry"
4970 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4971 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4972 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4973 (match_operand:HI 2 "general_operand" "ri,rm")))
4974 (clobber (reg:CC FLAGS_REG))]
4975 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4976 "adc{w}\t{%2, %0|%0, %2}"
4977 [(set_attr "type" "alu")
4978 (set_attr "pent_pair" "pu")
4979 (set_attr "mode" "HI")])
4980
4981 (define_insn "addsi3_carry"
4982 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4983 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4984 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4985 (match_operand:SI 2 "general_operand" "ri,rm")))
4986 (clobber (reg:CC FLAGS_REG))]
4987 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4988 "adc{l}\t{%2, %0|%0, %2}"
4989 [(set_attr "type" "alu")
4990 (set_attr "pent_pair" "pu")
4991 (set_attr "mode" "SI")])
4992
4993 (define_insn "*addsi3_carry_zext"
4994 [(set (match_operand:DI 0 "register_operand" "=r")
4995 (zero_extend:DI
4996 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4997 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4998 (match_operand:SI 2 "general_operand" "rim"))))
4999 (clobber (reg:CC FLAGS_REG))]
5000 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5001 "adc{l}\t{%2, %k0|%k0, %2}"
5002 [(set_attr "type" "alu")
5003 (set_attr "pent_pair" "pu")
5004 (set_attr "mode" "SI")])
5005
5006 (define_insn "*addsi3_cc"
5007 [(set (reg:CC FLAGS_REG)
5008 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5009 (match_operand:SI 2 "general_operand" "ri,rm")]
5010 UNSPEC_ADD_CARRY))
5011 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5012 (plus:SI (match_dup 1) (match_dup 2)))]
5013 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5014 "add{l}\t{%2, %0|%0, %2}"
5015 [(set_attr "type" "alu")
5016 (set_attr "mode" "SI")])
5017
5018 (define_insn "addqi3_cc"
5019 [(set (reg:CC FLAGS_REG)
5020 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5021 (match_operand:QI 2 "general_operand" "qi,qm")]
5022 UNSPEC_ADD_CARRY))
5023 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5024 (plus:QI (match_dup 1) (match_dup 2)))]
5025 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5026 "add{b}\t{%2, %0|%0, %2}"
5027 [(set_attr "type" "alu")
5028 (set_attr "mode" "QI")])
5029
5030 (define_expand "addsi3"
5031 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5032 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5033 (match_operand:SI 2 "general_operand" "")))
5034 (clobber (reg:CC FLAGS_REG))])]
5035 ""
5036 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5037
5038 (define_insn "*lea_1"
5039 [(set (match_operand:SI 0 "register_operand" "=r")
5040 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5041 "!TARGET_64BIT"
5042 "lea{l}\t{%a1, %0|%0, %a1}"
5043 [(set_attr "type" "lea")
5044 (set_attr "mode" "SI")])
5045
5046 (define_insn "*lea_1_rex64"
5047 [(set (match_operand:SI 0 "register_operand" "=r")
5048 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5049 "TARGET_64BIT"
5050 "lea{l}\t{%a1, %0|%0, %a1}"
5051 [(set_attr "type" "lea")
5052 (set_attr "mode" "SI")])
5053
5054 (define_insn "*lea_1_zext"
5055 [(set (match_operand:DI 0 "register_operand" "=r")
5056 (zero_extend:DI
5057 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5058 "TARGET_64BIT"
5059 "lea{l}\t{%a1, %k0|%k0, %a1}"
5060 [(set_attr "type" "lea")
5061 (set_attr "mode" "SI")])
5062
5063 (define_insn "*lea_2_rex64"
5064 [(set (match_operand:DI 0 "register_operand" "=r")
5065 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5066 "TARGET_64BIT"
5067 "lea{q}\t{%a1, %0|%0, %a1}"
5068 [(set_attr "type" "lea")
5069 (set_attr "mode" "DI")])
5070
5071 ;; The lea patterns for non-Pmodes needs to be matched by several
5072 ;; insns converted to real lea by splitters.
5073
5074 (define_insn_and_split "*lea_general_1"
5075 [(set (match_operand 0 "register_operand" "=r")
5076 (plus (plus (match_operand 1 "index_register_operand" "l")
5077 (match_operand 2 "register_operand" "r"))
5078 (match_operand 3 "immediate_operand" "i")))]
5079 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5080 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5081 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5082 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5083 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5084 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5085 || GET_MODE (operands[3]) == VOIDmode)"
5086 "#"
5087 "&& reload_completed"
5088 [(const_int 0)]
5089 {
5090 rtx pat;
5091 operands[0] = gen_lowpart (SImode, operands[0]);
5092 operands[1] = gen_lowpart (Pmode, operands[1]);
5093 operands[2] = gen_lowpart (Pmode, operands[2]);
5094 operands[3] = gen_lowpart (Pmode, operands[3]);
5095 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5096 operands[3]);
5097 if (Pmode != SImode)
5098 pat = gen_rtx_SUBREG (SImode, pat, 0);
5099 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5100 DONE;
5101 }
5102 [(set_attr "type" "lea")
5103 (set_attr "mode" "SI")])
5104
5105 (define_insn_and_split "*lea_general_1_zext"
5106 [(set (match_operand:DI 0 "register_operand" "=r")
5107 (zero_extend:DI
5108 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5109 (match_operand:SI 2 "register_operand" "r"))
5110 (match_operand:SI 3 "immediate_operand" "i"))))]
5111 "TARGET_64BIT"
5112 "#"
5113 "&& reload_completed"
5114 [(set (match_dup 0)
5115 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5116 (match_dup 2))
5117 (match_dup 3)) 0)))]
5118 {
5119 operands[1] = gen_lowpart (Pmode, operands[1]);
5120 operands[2] = gen_lowpart (Pmode, operands[2]);
5121 operands[3] = gen_lowpart (Pmode, operands[3]);
5122 }
5123 [(set_attr "type" "lea")
5124 (set_attr "mode" "SI")])
5125
5126 (define_insn_and_split "*lea_general_2"
5127 [(set (match_operand 0 "register_operand" "=r")
5128 (plus (mult (match_operand 1 "index_register_operand" "l")
5129 (match_operand 2 "const248_operand" "i"))
5130 (match_operand 3 "nonmemory_operand" "ri")))]
5131 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5132 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5133 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5134 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5135 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5136 || GET_MODE (operands[3]) == VOIDmode)"
5137 "#"
5138 "&& reload_completed"
5139 [(const_int 0)]
5140 {
5141 rtx pat;
5142 operands[0] = gen_lowpart (SImode, operands[0]);
5143 operands[1] = gen_lowpart (Pmode, operands[1]);
5144 operands[3] = gen_lowpart (Pmode, operands[3]);
5145 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5146 operands[3]);
5147 if (Pmode != SImode)
5148 pat = gen_rtx_SUBREG (SImode, pat, 0);
5149 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5150 DONE;
5151 }
5152 [(set_attr "type" "lea")
5153 (set_attr "mode" "SI")])
5154
5155 (define_insn_and_split "*lea_general_2_zext"
5156 [(set (match_operand:DI 0 "register_operand" "=r")
5157 (zero_extend:DI
5158 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5159 (match_operand:SI 2 "const248_operand" "n"))
5160 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5161 "TARGET_64BIT"
5162 "#"
5163 "&& reload_completed"
5164 [(set (match_dup 0)
5165 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5166 (match_dup 2))
5167 (match_dup 3)) 0)))]
5168 {
5169 operands[1] = gen_lowpart (Pmode, operands[1]);
5170 operands[3] = gen_lowpart (Pmode, operands[3]);
5171 }
5172 [(set_attr "type" "lea")
5173 (set_attr "mode" "SI")])
5174
5175 (define_insn_and_split "*lea_general_3"
5176 [(set (match_operand 0 "register_operand" "=r")
5177 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5178 (match_operand 2 "const248_operand" "i"))
5179 (match_operand 3 "register_operand" "r"))
5180 (match_operand 4 "immediate_operand" "i")))]
5181 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5182 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5183 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5184 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5185 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5186 "#"
5187 "&& reload_completed"
5188 [(const_int 0)]
5189 {
5190 rtx pat;
5191 operands[0] = gen_lowpart (SImode, operands[0]);
5192 operands[1] = gen_lowpart (Pmode, operands[1]);
5193 operands[3] = gen_lowpart (Pmode, operands[3]);
5194 operands[4] = gen_lowpart (Pmode, operands[4]);
5195 pat = gen_rtx_PLUS (Pmode,
5196 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5197 operands[2]),
5198 operands[3]),
5199 operands[4]);
5200 if (Pmode != SImode)
5201 pat = gen_rtx_SUBREG (SImode, pat, 0);
5202 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5203 DONE;
5204 }
5205 [(set_attr "type" "lea")
5206 (set_attr "mode" "SI")])
5207
5208 (define_insn_and_split "*lea_general_3_zext"
5209 [(set (match_operand:DI 0 "register_operand" "=r")
5210 (zero_extend:DI
5211 (plus:SI (plus:SI (mult:SI
5212 (match_operand:SI 1 "index_register_operand" "l")
5213 (match_operand:SI 2 "const248_operand" "n"))
5214 (match_operand:SI 3 "register_operand" "r"))
5215 (match_operand:SI 4 "immediate_operand" "i"))))]
5216 "TARGET_64BIT"
5217 "#"
5218 "&& reload_completed"
5219 [(set (match_dup 0)
5220 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5221 (match_dup 2))
5222 (match_dup 3))
5223 (match_dup 4)) 0)))]
5224 {
5225 operands[1] = gen_lowpart (Pmode, operands[1]);
5226 operands[3] = gen_lowpart (Pmode, operands[3]);
5227 operands[4] = gen_lowpart (Pmode, operands[4]);
5228 }
5229 [(set_attr "type" "lea")
5230 (set_attr "mode" "SI")])
5231
5232 (define_insn "*adddi_1_rex64"
5233 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5234 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5235 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5236 (clobber (reg:CC FLAGS_REG))]
5237 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5238 {
5239 switch (get_attr_type (insn))
5240 {
5241 case TYPE_LEA:
5242 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5243 return "lea{q}\t{%a2, %0|%0, %a2}";
5244
5245 case TYPE_INCDEC:
5246 if (! rtx_equal_p (operands[0], operands[1]))
5247 abort ();
5248 if (operands[2] == const1_rtx)
5249 return "inc{q}\t%0";
5250 else if (operands[2] == constm1_rtx)
5251 return "dec{q}\t%0";
5252 else
5253 abort ();
5254
5255 default:
5256 if (! rtx_equal_p (operands[0], operands[1]))
5257 abort ();
5258
5259 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5260 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5261 if (GET_CODE (operands[2]) == CONST_INT
5262 /* Avoid overflows. */
5263 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5264 && (INTVAL (operands[2]) == 128
5265 || (INTVAL (operands[2]) < 0
5266 && INTVAL (operands[2]) != -128)))
5267 {
5268 operands[2] = GEN_INT (-INTVAL (operands[2]));
5269 return "sub{q}\t{%2, %0|%0, %2}";
5270 }
5271 return "add{q}\t{%2, %0|%0, %2}";
5272 }
5273 }
5274 [(set (attr "type")
5275 (cond [(eq_attr "alternative" "2")
5276 (const_string "lea")
5277 ; Current assemblers are broken and do not allow @GOTOFF in
5278 ; ought but a memory context.
5279 (match_operand:DI 2 "pic_symbolic_operand" "")
5280 (const_string "lea")
5281 (match_operand:DI 2 "incdec_operand" "")
5282 (const_string "incdec")
5283 ]
5284 (const_string "alu")))
5285 (set_attr "mode" "DI")])
5286
5287 ;; Convert lea to the lea pattern to avoid flags dependency.
5288 (define_split
5289 [(set (match_operand:DI 0 "register_operand" "")
5290 (plus:DI (match_operand:DI 1 "register_operand" "")
5291 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5292 (clobber (reg:CC FLAGS_REG))]
5293 "TARGET_64BIT && reload_completed
5294 && true_regnum (operands[0]) != true_regnum (operands[1])"
5295 [(set (match_dup 0)
5296 (plus:DI (match_dup 1)
5297 (match_dup 2)))]
5298 "")
5299
5300 (define_insn "*adddi_2_rex64"
5301 [(set (reg FLAGS_REG)
5302 (compare
5303 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5304 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5305 (const_int 0)))
5306 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5307 (plus:DI (match_dup 1) (match_dup 2)))]
5308 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5309 && ix86_binary_operator_ok (PLUS, DImode, operands)
5310 /* Current assemblers are broken and do not allow @GOTOFF in
5311 ought but a memory context. */
5312 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5313 {
5314 switch (get_attr_type (insn))
5315 {
5316 case TYPE_INCDEC:
5317 if (! rtx_equal_p (operands[0], operands[1]))
5318 abort ();
5319 if (operands[2] == const1_rtx)
5320 return "inc{q}\t%0";
5321 else if (operands[2] == constm1_rtx)
5322 return "dec{q}\t%0";
5323 else
5324 abort ();
5325
5326 default:
5327 if (! rtx_equal_p (operands[0], operands[1]))
5328 abort ();
5329 /* ???? We ought to handle there the 32bit case too
5330 - do we need new constraint? */
5331 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5332 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5333 if (GET_CODE (operands[2]) == CONST_INT
5334 /* Avoid overflows. */
5335 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5336 && (INTVAL (operands[2]) == 128
5337 || (INTVAL (operands[2]) < 0
5338 && INTVAL (operands[2]) != -128)))
5339 {
5340 operands[2] = GEN_INT (-INTVAL (operands[2]));
5341 return "sub{q}\t{%2, %0|%0, %2}";
5342 }
5343 return "add{q}\t{%2, %0|%0, %2}";
5344 }
5345 }
5346 [(set (attr "type")
5347 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5348 (const_string "incdec")
5349 (const_string "alu")))
5350 (set_attr "mode" "DI")])
5351
5352 (define_insn "*adddi_3_rex64"
5353 [(set (reg FLAGS_REG)
5354 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5355 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5356 (clobber (match_scratch:DI 0 "=r"))]
5357 "TARGET_64BIT
5358 && ix86_match_ccmode (insn, CCZmode)
5359 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5360 /* Current assemblers are broken and do not allow @GOTOFF in
5361 ought but a memory context. */
5362 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5363 {
5364 switch (get_attr_type (insn))
5365 {
5366 case TYPE_INCDEC:
5367 if (! rtx_equal_p (operands[0], operands[1]))
5368 abort ();
5369 if (operands[2] == const1_rtx)
5370 return "inc{q}\t%0";
5371 else if (operands[2] == constm1_rtx)
5372 return "dec{q}\t%0";
5373 else
5374 abort ();
5375
5376 default:
5377 if (! rtx_equal_p (operands[0], operands[1]))
5378 abort ();
5379 /* ???? We ought to handle there the 32bit case too
5380 - do we need new constraint? */
5381 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5382 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5383 if (GET_CODE (operands[2]) == CONST_INT
5384 /* Avoid overflows. */
5385 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5386 && (INTVAL (operands[2]) == 128
5387 || (INTVAL (operands[2]) < 0
5388 && INTVAL (operands[2]) != -128)))
5389 {
5390 operands[2] = GEN_INT (-INTVAL (operands[2]));
5391 return "sub{q}\t{%2, %0|%0, %2}";
5392 }
5393 return "add{q}\t{%2, %0|%0, %2}";
5394 }
5395 }
5396 [(set (attr "type")
5397 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5398 (const_string "incdec")
5399 (const_string "alu")))
5400 (set_attr "mode" "DI")])
5401
5402 ; For comparisons against 1, -1 and 128, we may generate better code
5403 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5404 ; is matched then. We can't accept general immediate, because for
5405 ; case of overflows, the result is messed up.
5406 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5407 ; when negated.
5408 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5409 ; only for comparisons not depending on it.
5410 (define_insn "*adddi_4_rex64"
5411 [(set (reg FLAGS_REG)
5412 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5413 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5414 (clobber (match_scratch:DI 0 "=rm"))]
5415 "TARGET_64BIT
5416 && ix86_match_ccmode (insn, CCGCmode)"
5417 {
5418 switch (get_attr_type (insn))
5419 {
5420 case TYPE_INCDEC:
5421 if (operands[2] == constm1_rtx)
5422 return "inc{q}\t%0";
5423 else if (operands[2] == const1_rtx)
5424 return "dec{q}\t%0";
5425 else
5426 abort();
5427
5428 default:
5429 if (! rtx_equal_p (operands[0], operands[1]))
5430 abort ();
5431 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5432 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5433 if ((INTVAL (operands[2]) == -128
5434 || (INTVAL (operands[2]) > 0
5435 && INTVAL (operands[2]) != 128))
5436 /* Avoid overflows. */
5437 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5438 return "sub{q}\t{%2, %0|%0, %2}";
5439 operands[2] = GEN_INT (-INTVAL (operands[2]));
5440 return "add{q}\t{%2, %0|%0, %2}";
5441 }
5442 }
5443 [(set (attr "type")
5444 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5445 (const_string "incdec")
5446 (const_string "alu")))
5447 (set_attr "mode" "DI")])
5448
5449 (define_insn "*adddi_5_rex64"
5450 [(set (reg FLAGS_REG)
5451 (compare
5452 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5453 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5454 (const_int 0)))
5455 (clobber (match_scratch:DI 0 "=r"))]
5456 "TARGET_64BIT
5457 && ix86_match_ccmode (insn, CCGOCmode)
5458 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5459 /* Current assemblers are broken and do not allow @GOTOFF in
5460 ought but a memory context. */
5461 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5462 {
5463 switch (get_attr_type (insn))
5464 {
5465 case TYPE_INCDEC:
5466 if (! rtx_equal_p (operands[0], operands[1]))
5467 abort ();
5468 if (operands[2] == const1_rtx)
5469 return "inc{q}\t%0";
5470 else if (operands[2] == constm1_rtx)
5471 return "dec{q}\t%0";
5472 else
5473 abort();
5474
5475 default:
5476 if (! rtx_equal_p (operands[0], operands[1]))
5477 abort ();
5478 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5479 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5480 if (GET_CODE (operands[2]) == CONST_INT
5481 /* Avoid overflows. */
5482 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5483 && (INTVAL (operands[2]) == 128
5484 || (INTVAL (operands[2]) < 0
5485 && INTVAL (operands[2]) != -128)))
5486 {
5487 operands[2] = GEN_INT (-INTVAL (operands[2]));
5488 return "sub{q}\t{%2, %0|%0, %2}";
5489 }
5490 return "add{q}\t{%2, %0|%0, %2}";
5491 }
5492 }
5493 [(set (attr "type")
5494 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5495 (const_string "incdec")
5496 (const_string "alu")))
5497 (set_attr "mode" "DI")])
5498
5499
5500 (define_insn "*addsi_1"
5501 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5502 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5503 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5504 (clobber (reg:CC FLAGS_REG))]
5505 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5506 {
5507 switch (get_attr_type (insn))
5508 {
5509 case TYPE_LEA:
5510 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5511 return "lea{l}\t{%a2, %0|%0, %a2}";
5512
5513 case TYPE_INCDEC:
5514 if (! rtx_equal_p (operands[0], operands[1]))
5515 abort ();
5516 if (operands[2] == const1_rtx)
5517 return "inc{l}\t%0";
5518 else if (operands[2] == constm1_rtx)
5519 return "dec{l}\t%0";
5520 else
5521 abort();
5522
5523 default:
5524 if (! rtx_equal_p (operands[0], operands[1]))
5525 abort ();
5526
5527 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5528 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5529 if (GET_CODE (operands[2]) == CONST_INT
5530 && (INTVAL (operands[2]) == 128
5531 || (INTVAL (operands[2]) < 0
5532 && INTVAL (operands[2]) != -128)))
5533 {
5534 operands[2] = GEN_INT (-INTVAL (operands[2]));
5535 return "sub{l}\t{%2, %0|%0, %2}";
5536 }
5537 return "add{l}\t{%2, %0|%0, %2}";
5538 }
5539 }
5540 [(set (attr "type")
5541 (cond [(eq_attr "alternative" "2")
5542 (const_string "lea")
5543 ; Current assemblers are broken and do not allow @GOTOFF in
5544 ; ought but a memory context.
5545 (match_operand:SI 2 "pic_symbolic_operand" "")
5546 (const_string "lea")
5547 (match_operand:SI 2 "incdec_operand" "")
5548 (const_string "incdec")
5549 ]
5550 (const_string "alu")))
5551 (set_attr "mode" "SI")])
5552
5553 ;; Convert lea to the lea pattern to avoid flags dependency.
5554 (define_split
5555 [(set (match_operand 0 "register_operand" "")
5556 (plus (match_operand 1 "register_operand" "")
5557 (match_operand 2 "nonmemory_operand" "")))
5558 (clobber (reg:CC FLAGS_REG))]
5559 "reload_completed
5560 && true_regnum (operands[0]) != true_regnum (operands[1])"
5561 [(const_int 0)]
5562 {
5563 rtx pat;
5564 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5565 may confuse gen_lowpart. */
5566 if (GET_MODE (operands[0]) != Pmode)
5567 {
5568 operands[1] = gen_lowpart (Pmode, operands[1]);
5569 operands[2] = gen_lowpart (Pmode, operands[2]);
5570 }
5571 operands[0] = gen_lowpart (SImode, operands[0]);
5572 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5573 if (Pmode != SImode)
5574 pat = gen_rtx_SUBREG (SImode, pat, 0);
5575 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5576 DONE;
5577 })
5578
5579 ;; It may seem that nonimmediate operand is proper one for operand 1.
5580 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5581 ;; we take care in ix86_binary_operator_ok to not allow two memory
5582 ;; operands so proper swapping will be done in reload. This allow
5583 ;; patterns constructed from addsi_1 to match.
5584 (define_insn "addsi_1_zext"
5585 [(set (match_operand:DI 0 "register_operand" "=r,r")
5586 (zero_extend:DI
5587 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5588 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5589 (clobber (reg:CC FLAGS_REG))]
5590 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5591 {
5592 switch (get_attr_type (insn))
5593 {
5594 case TYPE_LEA:
5595 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5596 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5597
5598 case TYPE_INCDEC:
5599 if (operands[2] == const1_rtx)
5600 return "inc{l}\t%k0";
5601 else if (operands[2] == constm1_rtx)
5602 return "dec{l}\t%k0";
5603 else
5604 abort();
5605
5606 default:
5607 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5608 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5609 if (GET_CODE (operands[2]) == CONST_INT
5610 && (INTVAL (operands[2]) == 128
5611 || (INTVAL (operands[2]) < 0
5612 && INTVAL (operands[2]) != -128)))
5613 {
5614 operands[2] = GEN_INT (-INTVAL (operands[2]));
5615 return "sub{l}\t{%2, %k0|%k0, %2}";
5616 }
5617 return "add{l}\t{%2, %k0|%k0, %2}";
5618 }
5619 }
5620 [(set (attr "type")
5621 (cond [(eq_attr "alternative" "1")
5622 (const_string "lea")
5623 ; Current assemblers are broken and do not allow @GOTOFF in
5624 ; ought but a memory context.
5625 (match_operand:SI 2 "pic_symbolic_operand" "")
5626 (const_string "lea")
5627 (match_operand:SI 2 "incdec_operand" "")
5628 (const_string "incdec")
5629 ]
5630 (const_string "alu")))
5631 (set_attr "mode" "SI")])
5632
5633 ;; Convert lea to the lea pattern to avoid flags dependency.
5634 (define_split
5635 [(set (match_operand:DI 0 "register_operand" "")
5636 (zero_extend:DI
5637 (plus:SI (match_operand:SI 1 "register_operand" "")
5638 (match_operand:SI 2 "nonmemory_operand" ""))))
5639 (clobber (reg:CC FLAGS_REG))]
5640 "TARGET_64BIT && reload_completed
5641 && true_regnum (operands[0]) != true_regnum (operands[1])"
5642 [(set (match_dup 0)
5643 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5644 {
5645 operands[1] = gen_lowpart (Pmode, operands[1]);
5646 operands[2] = gen_lowpart (Pmode, operands[2]);
5647 })
5648
5649 (define_insn "*addsi_2"
5650 [(set (reg FLAGS_REG)
5651 (compare
5652 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5653 (match_operand:SI 2 "general_operand" "rmni,rni"))
5654 (const_int 0)))
5655 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5656 (plus:SI (match_dup 1) (match_dup 2)))]
5657 "ix86_match_ccmode (insn, CCGOCmode)
5658 && ix86_binary_operator_ok (PLUS, SImode, operands)
5659 /* Current assemblers are broken and do not allow @GOTOFF in
5660 ought but a memory context. */
5661 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5662 {
5663 switch (get_attr_type (insn))
5664 {
5665 case TYPE_INCDEC:
5666 if (! rtx_equal_p (operands[0], operands[1]))
5667 abort ();
5668 if (operands[2] == const1_rtx)
5669 return "inc{l}\t%0";
5670 else if (operands[2] == constm1_rtx)
5671 return "dec{l}\t%0";
5672 else
5673 abort();
5674
5675 default:
5676 if (! rtx_equal_p (operands[0], operands[1]))
5677 abort ();
5678 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5679 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5680 if (GET_CODE (operands[2]) == CONST_INT
5681 && (INTVAL (operands[2]) == 128
5682 || (INTVAL (operands[2]) < 0
5683 && INTVAL (operands[2]) != -128)))
5684 {
5685 operands[2] = GEN_INT (-INTVAL (operands[2]));
5686 return "sub{l}\t{%2, %0|%0, %2}";
5687 }
5688 return "add{l}\t{%2, %0|%0, %2}";
5689 }
5690 }
5691 [(set (attr "type")
5692 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5693 (const_string "incdec")
5694 (const_string "alu")))
5695 (set_attr "mode" "SI")])
5696
5697 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5698 (define_insn "*addsi_2_zext"
5699 [(set (reg FLAGS_REG)
5700 (compare
5701 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5702 (match_operand:SI 2 "general_operand" "rmni"))
5703 (const_int 0)))
5704 (set (match_operand:DI 0 "register_operand" "=r")
5705 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5706 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5707 && ix86_binary_operator_ok (PLUS, SImode, operands)
5708 /* Current assemblers are broken and do not allow @GOTOFF in
5709 ought but a memory context. */
5710 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5711 {
5712 switch (get_attr_type (insn))
5713 {
5714 case TYPE_INCDEC:
5715 if (operands[2] == const1_rtx)
5716 return "inc{l}\t%k0";
5717 else if (operands[2] == constm1_rtx)
5718 return "dec{l}\t%k0";
5719 else
5720 abort();
5721
5722 default:
5723 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5724 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5725 if (GET_CODE (operands[2]) == CONST_INT
5726 && (INTVAL (operands[2]) == 128
5727 || (INTVAL (operands[2]) < 0
5728 && INTVAL (operands[2]) != -128)))
5729 {
5730 operands[2] = GEN_INT (-INTVAL (operands[2]));
5731 return "sub{l}\t{%2, %k0|%k0, %2}";
5732 }
5733 return "add{l}\t{%2, %k0|%k0, %2}";
5734 }
5735 }
5736 [(set (attr "type")
5737 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5738 (const_string "incdec")
5739 (const_string "alu")))
5740 (set_attr "mode" "SI")])
5741
5742 (define_insn "*addsi_3"
5743 [(set (reg FLAGS_REG)
5744 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5745 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5746 (clobber (match_scratch:SI 0 "=r"))]
5747 "ix86_match_ccmode (insn, CCZmode)
5748 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5749 /* Current assemblers are broken and do not allow @GOTOFF in
5750 ought but a memory context. */
5751 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5752 {
5753 switch (get_attr_type (insn))
5754 {
5755 case TYPE_INCDEC:
5756 if (! rtx_equal_p (operands[0], operands[1]))
5757 abort ();
5758 if (operands[2] == const1_rtx)
5759 return "inc{l}\t%0";
5760 else if (operands[2] == constm1_rtx)
5761 return "dec{l}\t%0";
5762 else
5763 abort();
5764
5765 default:
5766 if (! rtx_equal_p (operands[0], operands[1]))
5767 abort ();
5768 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5769 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5770 if (GET_CODE (operands[2]) == CONST_INT
5771 && (INTVAL (operands[2]) == 128
5772 || (INTVAL (operands[2]) < 0
5773 && INTVAL (operands[2]) != -128)))
5774 {
5775 operands[2] = GEN_INT (-INTVAL (operands[2]));
5776 return "sub{l}\t{%2, %0|%0, %2}";
5777 }
5778 return "add{l}\t{%2, %0|%0, %2}";
5779 }
5780 }
5781 [(set (attr "type")
5782 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5783 (const_string "incdec")
5784 (const_string "alu")))
5785 (set_attr "mode" "SI")])
5786
5787 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5788 (define_insn "*addsi_3_zext"
5789 [(set (reg FLAGS_REG)
5790 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5791 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5792 (set (match_operand:DI 0 "register_operand" "=r")
5793 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5794 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5795 && ix86_binary_operator_ok (PLUS, SImode, operands)
5796 /* Current assemblers are broken and do not allow @GOTOFF in
5797 ought but a memory context. */
5798 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5799 {
5800 switch (get_attr_type (insn))
5801 {
5802 case TYPE_INCDEC:
5803 if (operands[2] == const1_rtx)
5804 return "inc{l}\t%k0";
5805 else if (operands[2] == constm1_rtx)
5806 return "dec{l}\t%k0";
5807 else
5808 abort();
5809
5810 default:
5811 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5812 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5813 if (GET_CODE (operands[2]) == CONST_INT
5814 && (INTVAL (operands[2]) == 128
5815 || (INTVAL (operands[2]) < 0
5816 && INTVAL (operands[2]) != -128)))
5817 {
5818 operands[2] = GEN_INT (-INTVAL (operands[2]));
5819 return "sub{l}\t{%2, %k0|%k0, %2}";
5820 }
5821 return "add{l}\t{%2, %k0|%k0, %2}";
5822 }
5823 }
5824 [(set (attr "type")
5825 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5826 (const_string "incdec")
5827 (const_string "alu")))
5828 (set_attr "mode" "SI")])
5829
5830 ; For comparisons against 1, -1 and 128, we may generate better code
5831 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5832 ; is matched then. We can't accept general immediate, because for
5833 ; case of overflows, the result is messed up.
5834 ; This pattern also don't hold of 0x80000000, since the value overflows
5835 ; when negated.
5836 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5837 ; only for comparisons not depending on it.
5838 (define_insn "*addsi_4"
5839 [(set (reg FLAGS_REG)
5840 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5841 (match_operand:SI 2 "const_int_operand" "n")))
5842 (clobber (match_scratch:SI 0 "=rm"))]
5843 "ix86_match_ccmode (insn, CCGCmode)
5844 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5845 {
5846 switch (get_attr_type (insn))
5847 {
5848 case TYPE_INCDEC:
5849 if (operands[2] == constm1_rtx)
5850 return "inc{l}\t%0";
5851 else if (operands[2] == const1_rtx)
5852 return "dec{l}\t%0";
5853 else
5854 abort();
5855
5856 default:
5857 if (! rtx_equal_p (operands[0], operands[1]))
5858 abort ();
5859 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5860 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5861 if ((INTVAL (operands[2]) == -128
5862 || (INTVAL (operands[2]) > 0
5863 && INTVAL (operands[2]) != 128)))
5864 return "sub{l}\t{%2, %0|%0, %2}";
5865 operands[2] = GEN_INT (-INTVAL (operands[2]));
5866 return "add{l}\t{%2, %0|%0, %2}";
5867 }
5868 }
5869 [(set (attr "type")
5870 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5871 (const_string "incdec")
5872 (const_string "alu")))
5873 (set_attr "mode" "SI")])
5874
5875 (define_insn "*addsi_5"
5876 [(set (reg FLAGS_REG)
5877 (compare
5878 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5879 (match_operand:SI 2 "general_operand" "rmni"))
5880 (const_int 0)))
5881 (clobber (match_scratch:SI 0 "=r"))]
5882 "ix86_match_ccmode (insn, CCGOCmode)
5883 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5884 /* Current assemblers are broken and do not allow @GOTOFF in
5885 ought but a memory context. */
5886 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5887 {
5888 switch (get_attr_type (insn))
5889 {
5890 case TYPE_INCDEC:
5891 if (! rtx_equal_p (operands[0], operands[1]))
5892 abort ();
5893 if (operands[2] == const1_rtx)
5894 return "inc{l}\t%0";
5895 else if (operands[2] == constm1_rtx)
5896 return "dec{l}\t%0";
5897 else
5898 abort();
5899
5900 default:
5901 if (! rtx_equal_p (operands[0], operands[1]))
5902 abort ();
5903 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5904 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5905 if (GET_CODE (operands[2]) == CONST_INT
5906 && (INTVAL (operands[2]) == 128
5907 || (INTVAL (operands[2]) < 0
5908 && INTVAL (operands[2]) != -128)))
5909 {
5910 operands[2] = GEN_INT (-INTVAL (operands[2]));
5911 return "sub{l}\t{%2, %0|%0, %2}";
5912 }
5913 return "add{l}\t{%2, %0|%0, %2}";
5914 }
5915 }
5916 [(set (attr "type")
5917 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5918 (const_string "incdec")
5919 (const_string "alu")))
5920 (set_attr "mode" "SI")])
5921
5922 (define_expand "addhi3"
5923 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5924 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5925 (match_operand:HI 2 "general_operand" "")))
5926 (clobber (reg:CC FLAGS_REG))])]
5927 "TARGET_HIMODE_MATH"
5928 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5929
5930 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5931 ;; type optimizations enabled by define-splits. This is not important
5932 ;; for PII, and in fact harmful because of partial register stalls.
5933
5934 (define_insn "*addhi_1_lea"
5935 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5936 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5937 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5938 (clobber (reg:CC FLAGS_REG))]
5939 "!TARGET_PARTIAL_REG_STALL
5940 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5941 {
5942 switch (get_attr_type (insn))
5943 {
5944 case TYPE_LEA:
5945 return "#";
5946 case TYPE_INCDEC:
5947 if (operands[2] == const1_rtx)
5948 return "inc{w}\t%0";
5949 else if (operands[2] == constm1_rtx)
5950 return "dec{w}\t%0";
5951 abort();
5952
5953 default:
5954 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5955 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5956 if (GET_CODE (operands[2]) == CONST_INT
5957 && (INTVAL (operands[2]) == 128
5958 || (INTVAL (operands[2]) < 0
5959 && INTVAL (operands[2]) != -128)))
5960 {
5961 operands[2] = GEN_INT (-INTVAL (operands[2]));
5962 return "sub{w}\t{%2, %0|%0, %2}";
5963 }
5964 return "add{w}\t{%2, %0|%0, %2}";
5965 }
5966 }
5967 [(set (attr "type")
5968 (if_then_else (eq_attr "alternative" "2")
5969 (const_string "lea")
5970 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5971 (const_string "incdec")
5972 (const_string "alu"))))
5973 (set_attr "mode" "HI,HI,SI")])
5974
5975 (define_insn "*addhi_1"
5976 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5977 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5978 (match_operand:HI 2 "general_operand" "ri,rm")))
5979 (clobber (reg:CC FLAGS_REG))]
5980 "TARGET_PARTIAL_REG_STALL
5981 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5982 {
5983 switch (get_attr_type (insn))
5984 {
5985 case TYPE_INCDEC:
5986 if (operands[2] == const1_rtx)
5987 return "inc{w}\t%0";
5988 else if (operands[2] == constm1_rtx)
5989 return "dec{w}\t%0";
5990 abort();
5991
5992 default:
5993 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5994 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5995 if (GET_CODE (operands[2]) == CONST_INT
5996 && (INTVAL (operands[2]) == 128
5997 || (INTVAL (operands[2]) < 0
5998 && INTVAL (operands[2]) != -128)))
5999 {
6000 operands[2] = GEN_INT (-INTVAL (operands[2]));
6001 return "sub{w}\t{%2, %0|%0, %2}";
6002 }
6003 return "add{w}\t{%2, %0|%0, %2}";
6004 }
6005 }
6006 [(set (attr "type")
6007 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6008 (const_string "incdec")
6009 (const_string "alu")))
6010 (set_attr "mode" "HI")])
6011
6012 (define_insn "*addhi_2"
6013 [(set (reg FLAGS_REG)
6014 (compare
6015 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6016 (match_operand:HI 2 "general_operand" "rmni,rni"))
6017 (const_int 0)))
6018 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6019 (plus:HI (match_dup 1) (match_dup 2)))]
6020 "ix86_match_ccmode (insn, CCGOCmode)
6021 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6022 {
6023 switch (get_attr_type (insn))
6024 {
6025 case TYPE_INCDEC:
6026 if (operands[2] == const1_rtx)
6027 return "inc{w}\t%0";
6028 else if (operands[2] == constm1_rtx)
6029 return "dec{w}\t%0";
6030 abort();
6031
6032 default:
6033 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6034 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6035 if (GET_CODE (operands[2]) == CONST_INT
6036 && (INTVAL (operands[2]) == 128
6037 || (INTVAL (operands[2]) < 0
6038 && INTVAL (operands[2]) != -128)))
6039 {
6040 operands[2] = GEN_INT (-INTVAL (operands[2]));
6041 return "sub{w}\t{%2, %0|%0, %2}";
6042 }
6043 return "add{w}\t{%2, %0|%0, %2}";
6044 }
6045 }
6046 [(set (attr "type")
6047 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6048 (const_string "incdec")
6049 (const_string "alu")))
6050 (set_attr "mode" "HI")])
6051
6052 (define_insn "*addhi_3"
6053 [(set (reg FLAGS_REG)
6054 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6055 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6056 (clobber (match_scratch:HI 0 "=r"))]
6057 "ix86_match_ccmode (insn, CCZmode)
6058 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6059 {
6060 switch (get_attr_type (insn))
6061 {
6062 case TYPE_INCDEC:
6063 if (operands[2] == const1_rtx)
6064 return "inc{w}\t%0";
6065 else if (operands[2] == constm1_rtx)
6066 return "dec{w}\t%0";
6067 abort();
6068
6069 default:
6070 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6071 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6072 if (GET_CODE (operands[2]) == CONST_INT
6073 && (INTVAL (operands[2]) == 128
6074 || (INTVAL (operands[2]) < 0
6075 && INTVAL (operands[2]) != -128)))
6076 {
6077 operands[2] = GEN_INT (-INTVAL (operands[2]));
6078 return "sub{w}\t{%2, %0|%0, %2}";
6079 }
6080 return "add{w}\t{%2, %0|%0, %2}";
6081 }
6082 }
6083 [(set (attr "type")
6084 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6085 (const_string "incdec")
6086 (const_string "alu")))
6087 (set_attr "mode" "HI")])
6088
6089 ; See comments above addsi_3_imm for details.
6090 (define_insn "*addhi_4"
6091 [(set (reg FLAGS_REG)
6092 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6093 (match_operand:HI 2 "const_int_operand" "n")))
6094 (clobber (match_scratch:HI 0 "=rm"))]
6095 "ix86_match_ccmode (insn, CCGCmode)
6096 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6097 {
6098 switch (get_attr_type (insn))
6099 {
6100 case TYPE_INCDEC:
6101 if (operands[2] == constm1_rtx)
6102 return "inc{w}\t%0";
6103 else if (operands[2] == const1_rtx)
6104 return "dec{w}\t%0";
6105 else
6106 abort();
6107
6108 default:
6109 if (! rtx_equal_p (operands[0], operands[1]))
6110 abort ();
6111 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6112 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6113 if ((INTVAL (operands[2]) == -128
6114 || (INTVAL (operands[2]) > 0
6115 && INTVAL (operands[2]) != 128)))
6116 return "sub{w}\t{%2, %0|%0, %2}";
6117 operands[2] = GEN_INT (-INTVAL (operands[2]));
6118 return "add{w}\t{%2, %0|%0, %2}";
6119 }
6120 }
6121 [(set (attr "type")
6122 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6123 (const_string "incdec")
6124 (const_string "alu")))
6125 (set_attr "mode" "SI")])
6126
6127
6128 (define_insn "*addhi_5"
6129 [(set (reg FLAGS_REG)
6130 (compare
6131 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6132 (match_operand:HI 2 "general_operand" "rmni"))
6133 (const_int 0)))
6134 (clobber (match_scratch:HI 0 "=r"))]
6135 "ix86_match_ccmode (insn, CCGOCmode)
6136 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6137 {
6138 switch (get_attr_type (insn))
6139 {
6140 case TYPE_INCDEC:
6141 if (operands[2] == const1_rtx)
6142 return "inc{w}\t%0";
6143 else if (operands[2] == constm1_rtx)
6144 return "dec{w}\t%0";
6145 abort();
6146
6147 default:
6148 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6149 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6150 if (GET_CODE (operands[2]) == CONST_INT
6151 && (INTVAL (operands[2]) == 128
6152 || (INTVAL (operands[2]) < 0
6153 && INTVAL (operands[2]) != -128)))
6154 {
6155 operands[2] = GEN_INT (-INTVAL (operands[2]));
6156 return "sub{w}\t{%2, %0|%0, %2}";
6157 }
6158 return "add{w}\t{%2, %0|%0, %2}";
6159 }
6160 }
6161 [(set (attr "type")
6162 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6163 (const_string "incdec")
6164 (const_string "alu")))
6165 (set_attr "mode" "HI")])
6166
6167 (define_expand "addqi3"
6168 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6169 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6170 (match_operand:QI 2 "general_operand" "")))
6171 (clobber (reg:CC FLAGS_REG))])]
6172 "TARGET_QIMODE_MATH"
6173 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6174
6175 ;; %%% Potential partial reg stall on alternative 2. What to do?
6176 (define_insn "*addqi_1_lea"
6177 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6178 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6179 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6180 (clobber (reg:CC FLAGS_REG))]
6181 "!TARGET_PARTIAL_REG_STALL
6182 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6183 {
6184 int widen = (which_alternative == 2);
6185 switch (get_attr_type (insn))
6186 {
6187 case TYPE_LEA:
6188 return "#";
6189 case TYPE_INCDEC:
6190 if (operands[2] == const1_rtx)
6191 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6192 else if (operands[2] == constm1_rtx)
6193 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6194 abort();
6195
6196 default:
6197 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6198 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6199 if (GET_CODE (operands[2]) == CONST_INT
6200 && (INTVAL (operands[2]) == 128
6201 || (INTVAL (operands[2]) < 0
6202 && INTVAL (operands[2]) != -128)))
6203 {
6204 operands[2] = GEN_INT (-INTVAL (operands[2]));
6205 if (widen)
6206 return "sub{l}\t{%2, %k0|%k0, %2}";
6207 else
6208 return "sub{b}\t{%2, %0|%0, %2}";
6209 }
6210 if (widen)
6211 return "add{l}\t{%k2, %k0|%k0, %k2}";
6212 else
6213 return "add{b}\t{%2, %0|%0, %2}";
6214 }
6215 }
6216 [(set (attr "type")
6217 (if_then_else (eq_attr "alternative" "3")
6218 (const_string "lea")
6219 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6220 (const_string "incdec")
6221 (const_string "alu"))))
6222 (set_attr "mode" "QI,QI,SI,SI")])
6223
6224 (define_insn "*addqi_1"
6225 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6226 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6227 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6228 (clobber (reg:CC FLAGS_REG))]
6229 "TARGET_PARTIAL_REG_STALL
6230 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6231 {
6232 int widen = (which_alternative == 2);
6233 switch (get_attr_type (insn))
6234 {
6235 case TYPE_INCDEC:
6236 if (operands[2] == const1_rtx)
6237 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6238 else if (operands[2] == constm1_rtx)
6239 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6240 abort();
6241
6242 default:
6243 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6244 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6245 if (GET_CODE (operands[2]) == CONST_INT
6246 && (INTVAL (operands[2]) == 128
6247 || (INTVAL (operands[2]) < 0
6248 && INTVAL (operands[2]) != -128)))
6249 {
6250 operands[2] = GEN_INT (-INTVAL (operands[2]));
6251 if (widen)
6252 return "sub{l}\t{%2, %k0|%k0, %2}";
6253 else
6254 return "sub{b}\t{%2, %0|%0, %2}";
6255 }
6256 if (widen)
6257 return "add{l}\t{%k2, %k0|%k0, %k2}";
6258 else
6259 return "add{b}\t{%2, %0|%0, %2}";
6260 }
6261 }
6262 [(set (attr "type")
6263 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6264 (const_string "incdec")
6265 (const_string "alu")))
6266 (set_attr "mode" "QI,QI,SI")])
6267
6268 (define_insn "*addqi_1_slp"
6269 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6270 (plus:QI (match_dup 0)
6271 (match_operand:QI 1 "general_operand" "qn,qnm")))
6272 (clobber (reg:CC FLAGS_REG))]
6273 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6274 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6275 {
6276 switch (get_attr_type (insn))
6277 {
6278 case TYPE_INCDEC:
6279 if (operands[1] == const1_rtx)
6280 return "inc{b}\t%0";
6281 else if (operands[1] == constm1_rtx)
6282 return "dec{b}\t%0";
6283 abort();
6284
6285 default:
6286 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6287 if (GET_CODE (operands[1]) == CONST_INT
6288 && INTVAL (operands[1]) < 0)
6289 {
6290 operands[1] = GEN_INT (-INTVAL (operands[1]));
6291 return "sub{b}\t{%1, %0|%0, %1}";
6292 }
6293 return "add{b}\t{%1, %0|%0, %1}";
6294 }
6295 }
6296 [(set (attr "type")
6297 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6298 (const_string "incdec")
6299 (const_string "alu1")))
6300 (set (attr "memory")
6301 (if_then_else (match_operand 1 "memory_operand" "")
6302 (const_string "load")
6303 (const_string "none")))
6304 (set_attr "mode" "QI")])
6305
6306 (define_insn "*addqi_2"
6307 [(set (reg FLAGS_REG)
6308 (compare
6309 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6310 (match_operand:QI 2 "general_operand" "qmni,qni"))
6311 (const_int 0)))
6312 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6313 (plus:QI (match_dup 1) (match_dup 2)))]
6314 "ix86_match_ccmode (insn, CCGOCmode)
6315 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6316 {
6317 switch (get_attr_type (insn))
6318 {
6319 case TYPE_INCDEC:
6320 if (operands[2] == const1_rtx)
6321 return "inc{b}\t%0";
6322 else if (operands[2] == constm1_rtx
6323 || (GET_CODE (operands[2]) == CONST_INT
6324 && INTVAL (operands[2]) == 255))
6325 return "dec{b}\t%0";
6326 abort();
6327
6328 default:
6329 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6330 if (GET_CODE (operands[2]) == CONST_INT
6331 && INTVAL (operands[2]) < 0)
6332 {
6333 operands[2] = GEN_INT (-INTVAL (operands[2]));
6334 return "sub{b}\t{%2, %0|%0, %2}";
6335 }
6336 return "add{b}\t{%2, %0|%0, %2}";
6337 }
6338 }
6339 [(set (attr "type")
6340 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6341 (const_string "incdec")
6342 (const_string "alu")))
6343 (set_attr "mode" "QI")])
6344
6345 (define_insn "*addqi_3"
6346 [(set (reg FLAGS_REG)
6347 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6348 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6349 (clobber (match_scratch:QI 0 "=q"))]
6350 "ix86_match_ccmode (insn, CCZmode)
6351 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6352 {
6353 switch (get_attr_type (insn))
6354 {
6355 case TYPE_INCDEC:
6356 if (operands[2] == const1_rtx)
6357 return "inc{b}\t%0";
6358 else if (operands[2] == constm1_rtx
6359 || (GET_CODE (operands[2]) == CONST_INT
6360 && INTVAL (operands[2]) == 255))
6361 return "dec{b}\t%0";
6362 abort();
6363
6364 default:
6365 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6366 if (GET_CODE (operands[2]) == CONST_INT
6367 && INTVAL (operands[2]) < 0)
6368 {
6369 operands[2] = GEN_INT (-INTVAL (operands[2]));
6370 return "sub{b}\t{%2, %0|%0, %2}";
6371 }
6372 return "add{b}\t{%2, %0|%0, %2}";
6373 }
6374 }
6375 [(set (attr "type")
6376 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6377 (const_string "incdec")
6378 (const_string "alu")))
6379 (set_attr "mode" "QI")])
6380
6381 ; See comments above addsi_3_imm for details.
6382 (define_insn "*addqi_4"
6383 [(set (reg FLAGS_REG)
6384 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6385 (match_operand:QI 2 "const_int_operand" "n")))
6386 (clobber (match_scratch:QI 0 "=qm"))]
6387 "ix86_match_ccmode (insn, CCGCmode)
6388 && (INTVAL (operands[2]) & 0xff) != 0x80"
6389 {
6390 switch (get_attr_type (insn))
6391 {
6392 case TYPE_INCDEC:
6393 if (operands[2] == constm1_rtx
6394 || (GET_CODE (operands[2]) == CONST_INT
6395 && INTVAL (operands[2]) == 255))
6396 return "inc{b}\t%0";
6397 else if (operands[2] == const1_rtx)
6398 return "dec{b}\t%0";
6399 else
6400 abort();
6401
6402 default:
6403 if (! rtx_equal_p (operands[0], operands[1]))
6404 abort ();
6405 if (INTVAL (operands[2]) < 0)
6406 {
6407 operands[2] = GEN_INT (-INTVAL (operands[2]));
6408 return "add{b}\t{%2, %0|%0, %2}";
6409 }
6410 return "sub{b}\t{%2, %0|%0, %2}";
6411 }
6412 }
6413 [(set (attr "type")
6414 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6415 (const_string "incdec")
6416 (const_string "alu")))
6417 (set_attr "mode" "QI")])
6418
6419
6420 (define_insn "*addqi_5"
6421 [(set (reg FLAGS_REG)
6422 (compare
6423 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6424 (match_operand:QI 2 "general_operand" "qmni"))
6425 (const_int 0)))
6426 (clobber (match_scratch:QI 0 "=q"))]
6427 "ix86_match_ccmode (insn, CCGOCmode)
6428 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6429 {
6430 switch (get_attr_type (insn))
6431 {
6432 case TYPE_INCDEC:
6433 if (operands[2] == const1_rtx)
6434 return "inc{b}\t%0";
6435 else if (operands[2] == constm1_rtx
6436 || (GET_CODE (operands[2]) == CONST_INT
6437 && INTVAL (operands[2]) == 255))
6438 return "dec{b}\t%0";
6439 abort();
6440
6441 default:
6442 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6443 if (GET_CODE (operands[2]) == CONST_INT
6444 && INTVAL (operands[2]) < 0)
6445 {
6446 operands[2] = GEN_INT (-INTVAL (operands[2]));
6447 return "sub{b}\t{%2, %0|%0, %2}";
6448 }
6449 return "add{b}\t{%2, %0|%0, %2}";
6450 }
6451 }
6452 [(set (attr "type")
6453 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6454 (const_string "incdec")
6455 (const_string "alu")))
6456 (set_attr "mode" "QI")])
6457
6458
6459 (define_insn "addqi_ext_1"
6460 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6461 (const_int 8)
6462 (const_int 8))
6463 (plus:SI
6464 (zero_extract:SI
6465 (match_operand 1 "ext_register_operand" "0")
6466 (const_int 8)
6467 (const_int 8))
6468 (match_operand:QI 2 "general_operand" "Qmn")))
6469 (clobber (reg:CC FLAGS_REG))]
6470 "!TARGET_64BIT"
6471 {
6472 switch (get_attr_type (insn))
6473 {
6474 case TYPE_INCDEC:
6475 if (operands[2] == const1_rtx)
6476 return "inc{b}\t%h0";
6477 else if (operands[2] == constm1_rtx
6478 || (GET_CODE (operands[2]) == CONST_INT
6479 && INTVAL (operands[2]) == 255))
6480 return "dec{b}\t%h0";
6481 abort();
6482
6483 default:
6484 return "add{b}\t{%2, %h0|%h0, %2}";
6485 }
6486 }
6487 [(set (attr "type")
6488 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6489 (const_string "incdec")
6490 (const_string "alu")))
6491 (set_attr "mode" "QI")])
6492
6493 (define_insn "*addqi_ext_1_rex64"
6494 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6495 (const_int 8)
6496 (const_int 8))
6497 (plus:SI
6498 (zero_extract:SI
6499 (match_operand 1 "ext_register_operand" "0")
6500 (const_int 8)
6501 (const_int 8))
6502 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6503 (clobber (reg:CC FLAGS_REG))]
6504 "TARGET_64BIT"
6505 {
6506 switch (get_attr_type (insn))
6507 {
6508 case TYPE_INCDEC:
6509 if (operands[2] == const1_rtx)
6510 return "inc{b}\t%h0";
6511 else if (operands[2] == constm1_rtx
6512 || (GET_CODE (operands[2]) == CONST_INT
6513 && INTVAL (operands[2]) == 255))
6514 return "dec{b}\t%h0";
6515 abort();
6516
6517 default:
6518 return "add{b}\t{%2, %h0|%h0, %2}";
6519 }
6520 }
6521 [(set (attr "type")
6522 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6523 (const_string "incdec")
6524 (const_string "alu")))
6525 (set_attr "mode" "QI")])
6526
6527 (define_insn "*addqi_ext_2"
6528 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6529 (const_int 8)
6530 (const_int 8))
6531 (plus:SI
6532 (zero_extract:SI
6533 (match_operand 1 "ext_register_operand" "%0")
6534 (const_int 8)
6535 (const_int 8))
6536 (zero_extract:SI
6537 (match_operand 2 "ext_register_operand" "Q")
6538 (const_int 8)
6539 (const_int 8))))
6540 (clobber (reg:CC FLAGS_REG))]
6541 ""
6542 "add{b}\t{%h2, %h0|%h0, %h2}"
6543 [(set_attr "type" "alu")
6544 (set_attr "mode" "QI")])
6545
6546 ;; The patterns that match these are at the end of this file.
6547
6548 (define_expand "addxf3"
6549 [(set (match_operand:XF 0 "register_operand" "")
6550 (plus:XF (match_operand:XF 1 "register_operand" "")
6551 (match_operand:XF 2 "register_operand" "")))]
6552 "TARGET_80387"
6553 "")
6554
6555 (define_expand "adddf3"
6556 [(set (match_operand:DF 0 "register_operand" "")
6557 (plus:DF (match_operand:DF 1 "register_operand" "")
6558 (match_operand:DF 2 "nonimmediate_operand" "")))]
6559 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6560 "")
6561
6562 (define_expand "addsf3"
6563 [(set (match_operand:SF 0 "register_operand" "")
6564 (plus:SF (match_operand:SF 1 "register_operand" "")
6565 (match_operand:SF 2 "nonimmediate_operand" "")))]
6566 "TARGET_80387 || TARGET_SSE_MATH"
6567 "")
6568 \f
6569 ;; Subtract instructions
6570
6571 ;; %%% splits for subsidi3
6572
6573 (define_expand "subdi3"
6574 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6575 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6576 (match_operand:DI 2 "x86_64_general_operand" "")))
6577 (clobber (reg:CC FLAGS_REG))])]
6578 ""
6579 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6580
6581 (define_insn "*subdi3_1"
6582 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6583 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6584 (match_operand:DI 2 "general_operand" "roiF,riF")))
6585 (clobber (reg:CC FLAGS_REG))]
6586 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6587 "#")
6588
6589 (define_split
6590 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6591 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6592 (match_operand:DI 2 "general_operand" "")))
6593 (clobber (reg:CC FLAGS_REG))]
6594 "!TARGET_64BIT && reload_completed"
6595 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6596 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6597 (parallel [(set (match_dup 3)
6598 (minus:SI (match_dup 4)
6599 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6600 (match_dup 5))))
6601 (clobber (reg:CC FLAGS_REG))])]
6602 "split_di (operands+0, 1, operands+0, operands+3);
6603 split_di (operands+1, 1, operands+1, operands+4);
6604 split_di (operands+2, 1, operands+2, operands+5);")
6605
6606 (define_insn "subdi3_carry_rex64"
6607 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6608 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6609 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6610 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6613 "sbb{q}\t{%2, %0|%0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "pent_pair" "pu")
6616 (set_attr "mode" "DI")])
6617
6618 (define_insn "*subdi_1_rex64"
6619 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6620 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6621 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6622 (clobber (reg:CC FLAGS_REG))]
6623 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6624 "sub{q}\t{%2, %0|%0, %2}"
6625 [(set_attr "type" "alu")
6626 (set_attr "mode" "DI")])
6627
6628 (define_insn "*subdi_2_rex64"
6629 [(set (reg FLAGS_REG)
6630 (compare
6631 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6632 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6633 (const_int 0)))
6634 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6635 (minus:DI (match_dup 1) (match_dup 2)))]
6636 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6637 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6638 "sub{q}\t{%2, %0|%0, %2}"
6639 [(set_attr "type" "alu")
6640 (set_attr "mode" "DI")])
6641
6642 (define_insn "*subdi_3_rex63"
6643 [(set (reg FLAGS_REG)
6644 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6645 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6646 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6647 (minus:DI (match_dup 1) (match_dup 2)))]
6648 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6649 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650 "sub{q}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "mode" "DI")])
6653
6654 (define_insn "subqi3_carry"
6655 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6656 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6657 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6658 (match_operand:QI 2 "general_operand" "qi,qm"))))
6659 (clobber (reg:CC FLAGS_REG))]
6660 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6661 "sbb{b}\t{%2, %0|%0, %2}"
6662 [(set_attr "type" "alu")
6663 (set_attr "pent_pair" "pu")
6664 (set_attr "mode" "QI")])
6665
6666 (define_insn "subhi3_carry"
6667 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6668 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6669 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6670 (match_operand:HI 2 "general_operand" "ri,rm"))))
6671 (clobber (reg:CC FLAGS_REG))]
6672 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6673 "sbb{w}\t{%2, %0|%0, %2}"
6674 [(set_attr "type" "alu")
6675 (set_attr "pent_pair" "pu")
6676 (set_attr "mode" "HI")])
6677
6678 (define_insn "subsi3_carry"
6679 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6680 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6681 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6682 (match_operand:SI 2 "general_operand" "ri,rm"))))
6683 (clobber (reg:CC FLAGS_REG))]
6684 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6685 "sbb{l}\t{%2, %0|%0, %2}"
6686 [(set_attr "type" "alu")
6687 (set_attr "pent_pair" "pu")
6688 (set_attr "mode" "SI")])
6689
6690 (define_insn "subsi3_carry_zext"
6691 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6692 (zero_extend:DI
6693 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6694 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6695 (match_operand:SI 2 "general_operand" "ri,rm")))))
6696 (clobber (reg:CC FLAGS_REG))]
6697 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6698 "sbb{l}\t{%2, %k0|%k0, %2}"
6699 [(set_attr "type" "alu")
6700 (set_attr "pent_pair" "pu")
6701 (set_attr "mode" "SI")])
6702
6703 (define_expand "subsi3"
6704 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6705 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6706 (match_operand:SI 2 "general_operand" "")))
6707 (clobber (reg:CC FLAGS_REG))])]
6708 ""
6709 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6710
6711 (define_insn "*subsi_1"
6712 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6713 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6714 (match_operand:SI 2 "general_operand" "ri,rm")))
6715 (clobber (reg:CC FLAGS_REG))]
6716 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6717 "sub{l}\t{%2, %0|%0, %2}"
6718 [(set_attr "type" "alu")
6719 (set_attr "mode" "SI")])
6720
6721 (define_insn "*subsi_1_zext"
6722 [(set (match_operand:DI 0 "register_operand" "=r")
6723 (zero_extend:DI
6724 (minus:SI (match_operand:SI 1 "register_operand" "0")
6725 (match_operand:SI 2 "general_operand" "rim"))))
6726 (clobber (reg:CC FLAGS_REG))]
6727 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6728 "sub{l}\t{%2, %k0|%k0, %2}"
6729 [(set_attr "type" "alu")
6730 (set_attr "mode" "SI")])
6731
6732 (define_insn "*subsi_2"
6733 [(set (reg FLAGS_REG)
6734 (compare
6735 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6736 (match_operand:SI 2 "general_operand" "ri,rm"))
6737 (const_int 0)))
6738 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6739 (minus:SI (match_dup 1) (match_dup 2)))]
6740 "ix86_match_ccmode (insn, CCGOCmode)
6741 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6742 "sub{l}\t{%2, %0|%0, %2}"
6743 [(set_attr "type" "alu")
6744 (set_attr "mode" "SI")])
6745
6746 (define_insn "*subsi_2_zext"
6747 [(set (reg FLAGS_REG)
6748 (compare
6749 (minus:SI (match_operand:SI 1 "register_operand" "0")
6750 (match_operand:SI 2 "general_operand" "rim"))
6751 (const_int 0)))
6752 (set (match_operand:DI 0 "register_operand" "=r")
6753 (zero_extend:DI
6754 (minus:SI (match_dup 1)
6755 (match_dup 2))))]
6756 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6757 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6758 "sub{l}\t{%2, %k0|%k0, %2}"
6759 [(set_attr "type" "alu")
6760 (set_attr "mode" "SI")])
6761
6762 (define_insn "*subsi_3"
6763 [(set (reg FLAGS_REG)
6764 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6765 (match_operand:SI 2 "general_operand" "ri,rm")))
6766 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6767 (minus:SI (match_dup 1) (match_dup 2)))]
6768 "ix86_match_ccmode (insn, CCmode)
6769 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6770 "sub{l}\t{%2, %0|%0, %2}"
6771 [(set_attr "type" "alu")
6772 (set_attr "mode" "SI")])
6773
6774 (define_insn "*subsi_3_zext"
6775 [(set (reg FLAGS_REG)
6776 (compare (match_operand:SI 1 "register_operand" "0")
6777 (match_operand:SI 2 "general_operand" "rim")))
6778 (set (match_operand:DI 0 "register_operand" "=r")
6779 (zero_extend:DI
6780 (minus:SI (match_dup 1)
6781 (match_dup 2))))]
6782 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6783 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6784 "sub{q}\t{%2, %0|%0, %2}"
6785 [(set_attr "type" "alu")
6786 (set_attr "mode" "DI")])
6787
6788 (define_expand "subhi3"
6789 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6790 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6791 (match_operand:HI 2 "general_operand" "")))
6792 (clobber (reg:CC FLAGS_REG))])]
6793 "TARGET_HIMODE_MATH"
6794 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6795
6796 (define_insn "*subhi_1"
6797 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6798 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6799 (match_operand:HI 2 "general_operand" "ri,rm")))
6800 (clobber (reg:CC FLAGS_REG))]
6801 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6802 "sub{w}\t{%2, %0|%0, %2}"
6803 [(set_attr "type" "alu")
6804 (set_attr "mode" "HI")])
6805
6806 (define_insn "*subhi_2"
6807 [(set (reg FLAGS_REG)
6808 (compare
6809 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6810 (match_operand:HI 2 "general_operand" "ri,rm"))
6811 (const_int 0)))
6812 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6813 (minus:HI (match_dup 1) (match_dup 2)))]
6814 "ix86_match_ccmode (insn, CCGOCmode)
6815 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6816 "sub{w}\t{%2, %0|%0, %2}"
6817 [(set_attr "type" "alu")
6818 (set_attr "mode" "HI")])
6819
6820 (define_insn "*subhi_3"
6821 [(set (reg FLAGS_REG)
6822 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6823 (match_operand:HI 2 "general_operand" "ri,rm")))
6824 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6825 (minus:HI (match_dup 1) (match_dup 2)))]
6826 "ix86_match_ccmode (insn, CCmode)
6827 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6828 "sub{w}\t{%2, %0|%0, %2}"
6829 [(set_attr "type" "alu")
6830 (set_attr "mode" "HI")])
6831
6832 (define_expand "subqi3"
6833 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6834 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6835 (match_operand:QI 2 "general_operand" "")))
6836 (clobber (reg:CC FLAGS_REG))])]
6837 "TARGET_QIMODE_MATH"
6838 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6839
6840 (define_insn "*subqi_1"
6841 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6842 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6843 (match_operand:QI 2 "general_operand" "qn,qmn")))
6844 (clobber (reg:CC FLAGS_REG))]
6845 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6846 "sub{b}\t{%2, %0|%0, %2}"
6847 [(set_attr "type" "alu")
6848 (set_attr "mode" "QI")])
6849
6850 (define_insn "*subqi_1_slp"
6851 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6852 (minus:QI (match_dup 0)
6853 (match_operand:QI 1 "general_operand" "qn,qmn")))
6854 (clobber (reg:CC FLAGS_REG))]
6855 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6856 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6857 "sub{b}\t{%1, %0|%0, %1}"
6858 [(set_attr "type" "alu1")
6859 (set_attr "mode" "QI")])
6860
6861 (define_insn "*subqi_2"
6862 [(set (reg FLAGS_REG)
6863 (compare
6864 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6865 (match_operand:QI 2 "general_operand" "qi,qm"))
6866 (const_int 0)))
6867 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6868 (minus:HI (match_dup 1) (match_dup 2)))]
6869 "ix86_match_ccmode (insn, CCGOCmode)
6870 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6871 "sub{b}\t{%2, %0|%0, %2}"
6872 [(set_attr "type" "alu")
6873 (set_attr "mode" "QI")])
6874
6875 (define_insn "*subqi_3"
6876 [(set (reg FLAGS_REG)
6877 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6878 (match_operand:QI 2 "general_operand" "qi,qm")))
6879 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6880 (minus:HI (match_dup 1) (match_dup 2)))]
6881 "ix86_match_ccmode (insn, CCmode)
6882 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6883 "sub{b}\t{%2, %0|%0, %2}"
6884 [(set_attr "type" "alu")
6885 (set_attr "mode" "QI")])
6886
6887 ;; The patterns that match these are at the end of this file.
6888
6889 (define_expand "subxf3"
6890 [(set (match_operand:XF 0 "register_operand" "")
6891 (minus:XF (match_operand:XF 1 "register_operand" "")
6892 (match_operand:XF 2 "register_operand" "")))]
6893 "TARGET_80387"
6894 "")
6895
6896 (define_expand "subdf3"
6897 [(set (match_operand:DF 0 "register_operand" "")
6898 (minus:DF (match_operand:DF 1 "register_operand" "")
6899 (match_operand:DF 2 "nonimmediate_operand" "")))]
6900 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6901 "")
6902
6903 (define_expand "subsf3"
6904 [(set (match_operand:SF 0 "register_operand" "")
6905 (minus:SF (match_operand:SF 1 "register_operand" "")
6906 (match_operand:SF 2 "nonimmediate_operand" "")))]
6907 "TARGET_80387 || TARGET_SSE_MATH"
6908 "")
6909 \f
6910 ;; Multiply instructions
6911
6912 (define_expand "muldi3"
6913 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6914 (mult:DI (match_operand:DI 1 "register_operand" "")
6915 (match_operand:DI 2 "x86_64_general_operand" "")))
6916 (clobber (reg:CC FLAGS_REG))])]
6917 "TARGET_64BIT"
6918 "")
6919
6920 (define_insn "*muldi3_1_rex64"
6921 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6922 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6923 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6924 (clobber (reg:CC FLAGS_REG))]
6925 "TARGET_64BIT
6926 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6927 "@
6928 imul{q}\t{%2, %1, %0|%0, %1, %2}
6929 imul{q}\t{%2, %1, %0|%0, %1, %2}
6930 imul{q}\t{%2, %0|%0, %2}"
6931 [(set_attr "type" "imul")
6932 (set_attr "prefix_0f" "0,0,1")
6933 (set (attr "athlon_decode")
6934 (cond [(eq_attr "cpu" "athlon")
6935 (const_string "vector")
6936 (eq_attr "alternative" "1")
6937 (const_string "vector")
6938 (and (eq_attr "alternative" "2")
6939 (match_operand 1 "memory_operand" ""))
6940 (const_string "vector")]
6941 (const_string "direct")))
6942 (set_attr "mode" "DI")])
6943
6944 (define_expand "mulsi3"
6945 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6946 (mult:SI (match_operand:SI 1 "register_operand" "")
6947 (match_operand:SI 2 "general_operand" "")))
6948 (clobber (reg:CC FLAGS_REG))])]
6949 ""
6950 "")
6951
6952 (define_insn "*mulsi3_1"
6953 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6954 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6955 (match_operand:SI 2 "general_operand" "K,i,mr")))
6956 (clobber (reg:CC FLAGS_REG))]
6957 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6958 "@
6959 imul{l}\t{%2, %1, %0|%0, %1, %2}
6960 imul{l}\t{%2, %1, %0|%0, %1, %2}
6961 imul{l}\t{%2, %0|%0, %2}"
6962 [(set_attr "type" "imul")
6963 (set_attr "prefix_0f" "0,0,1")
6964 (set (attr "athlon_decode")
6965 (cond [(eq_attr "cpu" "athlon")
6966 (const_string "vector")
6967 (eq_attr "alternative" "1")
6968 (const_string "vector")
6969 (and (eq_attr "alternative" "2")
6970 (match_operand 1 "memory_operand" ""))
6971 (const_string "vector")]
6972 (const_string "direct")))
6973 (set_attr "mode" "SI")])
6974
6975 (define_insn "*mulsi3_1_zext"
6976 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6977 (zero_extend:DI
6978 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6979 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6980 (clobber (reg:CC FLAGS_REG))]
6981 "TARGET_64BIT
6982 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6983 "@
6984 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6985 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6986 imul{l}\t{%2, %k0|%k0, %2}"
6987 [(set_attr "type" "imul")
6988 (set_attr "prefix_0f" "0,0,1")
6989 (set (attr "athlon_decode")
6990 (cond [(eq_attr "cpu" "athlon")
6991 (const_string "vector")
6992 (eq_attr "alternative" "1")
6993 (const_string "vector")
6994 (and (eq_attr "alternative" "2")
6995 (match_operand 1 "memory_operand" ""))
6996 (const_string "vector")]
6997 (const_string "direct")))
6998 (set_attr "mode" "SI")])
6999
7000 (define_expand "mulhi3"
7001 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7002 (mult:HI (match_operand:HI 1 "register_operand" "")
7003 (match_operand:HI 2 "general_operand" "")))
7004 (clobber (reg:CC FLAGS_REG))])]
7005 "TARGET_HIMODE_MATH"
7006 "")
7007
7008 (define_insn "*mulhi3_1"
7009 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7010 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7011 (match_operand:HI 2 "general_operand" "K,i,mr")))
7012 (clobber (reg:CC FLAGS_REG))]
7013 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7014 "@
7015 imul{w}\t{%2, %1, %0|%0, %1, %2}
7016 imul{w}\t{%2, %1, %0|%0, %1, %2}
7017 imul{w}\t{%2, %0|%0, %2}"
7018 [(set_attr "type" "imul")
7019 (set_attr "prefix_0f" "0,0,1")
7020 (set (attr "athlon_decode")
7021 (cond [(eq_attr "cpu" "athlon")
7022 (const_string "vector")
7023 (eq_attr "alternative" "1,2")
7024 (const_string "vector")]
7025 (const_string "direct")))
7026 (set_attr "mode" "HI")])
7027
7028 (define_expand "mulqi3"
7029 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7030 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7031 (match_operand:QI 2 "register_operand" "")))
7032 (clobber (reg:CC FLAGS_REG))])]
7033 "TARGET_QIMODE_MATH"
7034 "")
7035
7036 (define_insn "*mulqi3_1"
7037 [(set (match_operand:QI 0 "register_operand" "=a")
7038 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7039 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7040 (clobber (reg:CC FLAGS_REG))]
7041 "TARGET_QIMODE_MATH
7042 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7043 "mul{b}\t%2"
7044 [(set_attr "type" "imul")
7045 (set_attr "length_immediate" "0")
7046 (set (attr "athlon_decode")
7047 (if_then_else (eq_attr "cpu" "athlon")
7048 (const_string "vector")
7049 (const_string "direct")))
7050 (set_attr "mode" "QI")])
7051
7052 (define_expand "umulqihi3"
7053 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7054 (mult:HI (zero_extend:HI
7055 (match_operand:QI 1 "nonimmediate_operand" ""))
7056 (zero_extend:HI
7057 (match_operand:QI 2 "register_operand" ""))))
7058 (clobber (reg:CC FLAGS_REG))])]
7059 "TARGET_QIMODE_MATH"
7060 "")
7061
7062 (define_insn "*umulqihi3_1"
7063 [(set (match_operand:HI 0 "register_operand" "=a")
7064 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7065 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7066 (clobber (reg:CC FLAGS_REG))]
7067 "TARGET_QIMODE_MATH
7068 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7069 "mul{b}\t%2"
7070 [(set_attr "type" "imul")
7071 (set_attr "length_immediate" "0")
7072 (set (attr "athlon_decode")
7073 (if_then_else (eq_attr "cpu" "athlon")
7074 (const_string "vector")
7075 (const_string "direct")))
7076 (set_attr "mode" "QI")])
7077
7078 (define_expand "mulqihi3"
7079 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7080 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7081 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7082 (clobber (reg:CC FLAGS_REG))])]
7083 "TARGET_QIMODE_MATH"
7084 "")
7085
7086 (define_insn "*mulqihi3_insn"
7087 [(set (match_operand:HI 0 "register_operand" "=a")
7088 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7089 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7090 (clobber (reg:CC FLAGS_REG))]
7091 "TARGET_QIMODE_MATH
7092 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7093 "imul{b}\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 "direct")))
7100 (set_attr "mode" "QI")])
7101
7102 (define_expand "umulditi3"
7103 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7104 (mult:TI (zero_extend:TI
7105 (match_operand:DI 1 "nonimmediate_operand" ""))
7106 (zero_extend:TI
7107 (match_operand:DI 2 "register_operand" ""))))
7108 (clobber (reg:CC FLAGS_REG))])]
7109 "TARGET_64BIT"
7110 "")
7111
7112 (define_insn "*umulditi3_insn"
7113 [(set (match_operand:TI 0 "register_operand" "=A")
7114 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7115 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7116 (clobber (reg:CC FLAGS_REG))]
7117 "TARGET_64BIT
7118 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7119 "mul{q}\t%2"
7120 [(set_attr "type" "imul")
7121 (set_attr "length_immediate" "0")
7122 (set (attr "athlon_decode")
7123 (if_then_else (eq_attr "cpu" "athlon")
7124 (const_string "vector")
7125 (const_string "double")))
7126 (set_attr "mode" "DI")])
7127
7128 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7129 (define_expand "umulsidi3"
7130 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7131 (mult:DI (zero_extend:DI
7132 (match_operand:SI 1 "nonimmediate_operand" ""))
7133 (zero_extend:DI
7134 (match_operand:SI 2 "register_operand" ""))))
7135 (clobber (reg:CC FLAGS_REG))])]
7136 "!TARGET_64BIT"
7137 "")
7138
7139 (define_insn "*umulsidi3_insn"
7140 [(set (match_operand:DI 0 "register_operand" "=A")
7141 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7142 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7143 (clobber (reg:CC FLAGS_REG))]
7144 "!TARGET_64BIT
7145 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7146 "mul{l}\t%2"
7147 [(set_attr "type" "imul")
7148 (set_attr "length_immediate" "0")
7149 (set (attr "athlon_decode")
7150 (if_then_else (eq_attr "cpu" "athlon")
7151 (const_string "vector")
7152 (const_string "double")))
7153 (set_attr "mode" "SI")])
7154
7155 (define_expand "mulditi3"
7156 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7157 (mult:TI (sign_extend:TI
7158 (match_operand:DI 1 "nonimmediate_operand" ""))
7159 (sign_extend:TI
7160 (match_operand:DI 2 "register_operand" ""))))
7161 (clobber (reg:CC FLAGS_REG))])]
7162 "TARGET_64BIT"
7163 "")
7164
7165 (define_insn "*mulditi3_insn"
7166 [(set (match_operand:TI 0 "register_operand" "=A")
7167 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7168 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7169 (clobber (reg:CC FLAGS_REG))]
7170 "TARGET_64BIT
7171 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7172 "imul{q}\t%2"
7173 [(set_attr "type" "imul")
7174 (set_attr "length_immediate" "0")
7175 (set (attr "athlon_decode")
7176 (if_then_else (eq_attr "cpu" "athlon")
7177 (const_string "vector")
7178 (const_string "double")))
7179 (set_attr "mode" "DI")])
7180
7181 (define_expand "mulsidi3"
7182 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7183 (mult:DI (sign_extend:DI
7184 (match_operand:SI 1 "nonimmediate_operand" ""))
7185 (sign_extend:DI
7186 (match_operand:SI 2 "register_operand" ""))))
7187 (clobber (reg:CC FLAGS_REG))])]
7188 "!TARGET_64BIT"
7189 "")
7190
7191 (define_insn "*mulsidi3_insn"
7192 [(set (match_operand:DI 0 "register_operand" "=A")
7193 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7194 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7195 (clobber (reg:CC FLAGS_REG))]
7196 "!TARGET_64BIT
7197 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7198 "imul{l}\t%2"
7199 [(set_attr "type" "imul")
7200 (set_attr "length_immediate" "0")
7201 (set (attr "athlon_decode")
7202 (if_then_else (eq_attr "cpu" "athlon")
7203 (const_string "vector")
7204 (const_string "double")))
7205 (set_attr "mode" "SI")])
7206
7207 (define_expand "umuldi3_highpart"
7208 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7209 (truncate:DI
7210 (lshiftrt:TI
7211 (mult:TI (zero_extend:TI
7212 (match_operand:DI 1 "nonimmediate_operand" ""))
7213 (zero_extend:TI
7214 (match_operand:DI 2 "register_operand" "")))
7215 (const_int 64))))
7216 (clobber (match_scratch:DI 3 ""))
7217 (clobber (reg:CC FLAGS_REG))])]
7218 "TARGET_64BIT"
7219 "")
7220
7221 (define_insn "*umuldi3_highpart_rex64"
7222 [(set (match_operand:DI 0 "register_operand" "=d")
7223 (truncate:DI
7224 (lshiftrt:TI
7225 (mult:TI (zero_extend:TI
7226 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7227 (zero_extend:TI
7228 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7229 (const_int 64))))
7230 (clobber (match_scratch:DI 3 "=1"))
7231 (clobber (reg:CC FLAGS_REG))]
7232 "TARGET_64BIT
7233 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7234 "mul{q}\t%2"
7235 [(set_attr "type" "imul")
7236 (set_attr "length_immediate" "0")
7237 (set (attr "athlon_decode")
7238 (if_then_else (eq_attr "cpu" "athlon")
7239 (const_string "vector")
7240 (const_string "double")))
7241 (set_attr "mode" "DI")])
7242
7243 (define_expand "umulsi3_highpart"
7244 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7245 (truncate:SI
7246 (lshiftrt:DI
7247 (mult:DI (zero_extend:DI
7248 (match_operand:SI 1 "nonimmediate_operand" ""))
7249 (zero_extend:DI
7250 (match_operand:SI 2 "register_operand" "")))
7251 (const_int 32))))
7252 (clobber (match_scratch:SI 3 ""))
7253 (clobber (reg:CC FLAGS_REG))])]
7254 ""
7255 "")
7256
7257 (define_insn "*umulsi3_highpart_insn"
7258 [(set (match_operand:SI 0 "register_operand" "=d")
7259 (truncate:SI
7260 (lshiftrt:DI
7261 (mult:DI (zero_extend:DI
7262 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7263 (zero_extend:DI
7264 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7265 (const_int 32))))
7266 (clobber (match_scratch:SI 3 "=1"))
7267 (clobber (reg:CC FLAGS_REG))]
7268 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7269 "mul{l}\t%2"
7270 [(set_attr "type" "imul")
7271 (set_attr "length_immediate" "0")
7272 (set (attr "athlon_decode")
7273 (if_then_else (eq_attr "cpu" "athlon")
7274 (const_string "vector")
7275 (const_string "double")))
7276 (set_attr "mode" "SI")])
7277
7278 (define_insn "*umulsi3_highpart_zext"
7279 [(set (match_operand:DI 0 "register_operand" "=d")
7280 (zero_extend:DI (truncate:SI
7281 (lshiftrt:DI
7282 (mult:DI (zero_extend:DI
7283 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7284 (zero_extend:DI
7285 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7286 (const_int 32)))))
7287 (clobber (match_scratch:SI 3 "=1"))
7288 (clobber (reg:CC FLAGS_REG))]
7289 "TARGET_64BIT
7290 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7291 "mul{l}\t%2"
7292 [(set_attr "type" "imul")
7293 (set_attr "length_immediate" "0")
7294 (set (attr "athlon_decode")
7295 (if_then_else (eq_attr "cpu" "athlon")
7296 (const_string "vector")
7297 (const_string "double")))
7298 (set_attr "mode" "SI")])
7299
7300 (define_expand "smuldi3_highpart"
7301 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7302 (truncate:DI
7303 (lshiftrt:TI
7304 (mult:TI (sign_extend:TI
7305 (match_operand:DI 1 "nonimmediate_operand" ""))
7306 (sign_extend:TI
7307 (match_operand:DI 2 "register_operand" "")))
7308 (const_int 64))))
7309 (clobber (match_scratch:DI 3 ""))
7310 (clobber (reg:CC FLAGS_REG))])]
7311 "TARGET_64BIT"
7312 "")
7313
7314 (define_insn "*smuldi3_highpart_rex64"
7315 [(set (match_operand:DI 0 "register_operand" "=d")
7316 (truncate:DI
7317 (lshiftrt:TI
7318 (mult:TI (sign_extend:TI
7319 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7320 (sign_extend:TI
7321 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7322 (const_int 64))))
7323 (clobber (match_scratch:DI 3 "=1"))
7324 (clobber (reg:CC FLAGS_REG))]
7325 "TARGET_64BIT
7326 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7327 "imul{q}\t%2"
7328 [(set_attr "type" "imul")
7329 (set (attr "athlon_decode")
7330 (if_then_else (eq_attr "cpu" "athlon")
7331 (const_string "vector")
7332 (const_string "double")))
7333 (set_attr "mode" "DI")])
7334
7335 (define_expand "smulsi3_highpart"
7336 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7337 (truncate:SI
7338 (lshiftrt:DI
7339 (mult:DI (sign_extend:DI
7340 (match_operand:SI 1 "nonimmediate_operand" ""))
7341 (sign_extend:DI
7342 (match_operand:SI 2 "register_operand" "")))
7343 (const_int 32))))
7344 (clobber (match_scratch:SI 3 ""))
7345 (clobber (reg:CC FLAGS_REG))])]
7346 ""
7347 "")
7348
7349 (define_insn "*smulsi3_highpart_insn"
7350 [(set (match_operand:SI 0 "register_operand" "=d")
7351 (truncate:SI
7352 (lshiftrt:DI
7353 (mult:DI (sign_extend:DI
7354 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7355 (sign_extend:DI
7356 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7357 (const_int 32))))
7358 (clobber (match_scratch:SI 3 "=1"))
7359 (clobber (reg:CC FLAGS_REG))]
7360 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7361 "imul{l}\t%2"
7362 [(set_attr "type" "imul")
7363 (set (attr "athlon_decode")
7364 (if_then_else (eq_attr "cpu" "athlon")
7365 (const_string "vector")
7366 (const_string "double")))
7367 (set_attr "mode" "SI")])
7368
7369 (define_insn "*smulsi3_highpart_zext"
7370 [(set (match_operand:DI 0 "register_operand" "=d")
7371 (zero_extend:DI (truncate:SI
7372 (lshiftrt:DI
7373 (mult:DI (sign_extend:DI
7374 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7375 (sign_extend:DI
7376 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7377 (const_int 32)))))
7378 (clobber (match_scratch:SI 3 "=1"))
7379 (clobber (reg:CC FLAGS_REG))]
7380 "TARGET_64BIT
7381 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7382 "imul{l}\t%2"
7383 [(set_attr "type" "imul")
7384 (set (attr "athlon_decode")
7385 (if_then_else (eq_attr "cpu" "athlon")
7386 (const_string "vector")
7387 (const_string "double")))
7388 (set_attr "mode" "SI")])
7389
7390 ;; The patterns that match these are at the end of this file.
7391
7392 (define_expand "mulxf3"
7393 [(set (match_operand:XF 0 "register_operand" "")
7394 (mult:XF (match_operand:XF 1 "register_operand" "")
7395 (match_operand:XF 2 "register_operand" "")))]
7396 "TARGET_80387"
7397 "")
7398
7399 (define_expand "muldf3"
7400 [(set (match_operand:DF 0 "register_operand" "")
7401 (mult:DF (match_operand:DF 1 "register_operand" "")
7402 (match_operand:DF 2 "nonimmediate_operand" "")))]
7403 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7404 "")
7405
7406 (define_expand "mulsf3"
7407 [(set (match_operand:SF 0 "register_operand" "")
7408 (mult:SF (match_operand:SF 1 "register_operand" "")
7409 (match_operand:SF 2 "nonimmediate_operand" "")))]
7410 "TARGET_80387 || TARGET_SSE_MATH"
7411 "")
7412 \f
7413 ;; Divide instructions
7414
7415 (define_insn "divqi3"
7416 [(set (match_operand:QI 0 "register_operand" "=a")
7417 (div:QI (match_operand:HI 1 "register_operand" "0")
7418 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7419 (clobber (reg:CC FLAGS_REG))]
7420 "TARGET_QIMODE_MATH"
7421 "idiv{b}\t%2"
7422 [(set_attr "type" "idiv")
7423 (set_attr "mode" "QI")])
7424
7425 (define_insn "udivqi3"
7426 [(set (match_operand:QI 0 "register_operand" "=a")
7427 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7428 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7429 (clobber (reg:CC FLAGS_REG))]
7430 "TARGET_QIMODE_MATH"
7431 "div{b}\t%2"
7432 [(set_attr "type" "idiv")
7433 (set_attr "mode" "QI")])
7434
7435 ;; The patterns that match these are at the end of this file.
7436
7437 (define_expand "divxf3"
7438 [(set (match_operand:XF 0 "register_operand" "")
7439 (div:XF (match_operand:XF 1 "register_operand" "")
7440 (match_operand:XF 2 "register_operand" "")))]
7441 "TARGET_80387"
7442 "")
7443
7444 (define_expand "divdf3"
7445 [(set (match_operand:DF 0 "register_operand" "")
7446 (div:DF (match_operand:DF 1 "register_operand" "")
7447 (match_operand:DF 2 "nonimmediate_operand" "")))]
7448 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7449 "")
7450
7451 (define_expand "divsf3"
7452 [(set (match_operand:SF 0 "register_operand" "")
7453 (div:SF (match_operand:SF 1 "register_operand" "")
7454 (match_operand:SF 2 "nonimmediate_operand" "")))]
7455 "TARGET_80387 || TARGET_SSE_MATH"
7456 "")
7457 \f
7458 ;; Remainder instructions.
7459
7460 (define_expand "divmoddi4"
7461 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7462 (div:DI (match_operand:DI 1 "register_operand" "")
7463 (match_operand:DI 2 "nonimmediate_operand" "")))
7464 (set (match_operand:DI 3 "register_operand" "")
7465 (mod:DI (match_dup 1) (match_dup 2)))
7466 (clobber (reg:CC FLAGS_REG))])]
7467 "TARGET_64BIT"
7468 "")
7469
7470 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7471 ;; Penalize eax case slightly because it results in worse scheduling
7472 ;; of code.
7473 (define_insn "*divmoddi4_nocltd_rex64"
7474 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7475 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7476 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7477 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7478 (mod:DI (match_dup 2) (match_dup 3)))
7479 (clobber (reg:CC FLAGS_REG))]
7480 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7481 "#"
7482 [(set_attr "type" "multi")])
7483
7484 (define_insn "*divmoddi4_cltd_rex64"
7485 [(set (match_operand:DI 0 "register_operand" "=a")
7486 (div:DI (match_operand:DI 2 "register_operand" "a")
7487 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7488 (set (match_operand:DI 1 "register_operand" "=&d")
7489 (mod:DI (match_dup 2) (match_dup 3)))
7490 (clobber (reg:CC FLAGS_REG))]
7491 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7492 "#"
7493 [(set_attr "type" "multi")])
7494
7495 (define_insn "*divmoddi_noext_rex64"
7496 [(set (match_operand:DI 0 "register_operand" "=a")
7497 (div:DI (match_operand:DI 1 "register_operand" "0")
7498 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7499 (set (match_operand:DI 3 "register_operand" "=d")
7500 (mod:DI (match_dup 1) (match_dup 2)))
7501 (use (match_operand:DI 4 "register_operand" "3"))
7502 (clobber (reg:CC FLAGS_REG))]
7503 "TARGET_64BIT"
7504 "idiv{q}\t%2"
7505 [(set_attr "type" "idiv")
7506 (set_attr "mode" "DI")])
7507
7508 (define_split
7509 [(set (match_operand:DI 0 "register_operand" "")
7510 (div:DI (match_operand:DI 1 "register_operand" "")
7511 (match_operand:DI 2 "nonimmediate_operand" "")))
7512 (set (match_operand:DI 3 "register_operand" "")
7513 (mod:DI (match_dup 1) (match_dup 2)))
7514 (clobber (reg:CC FLAGS_REG))]
7515 "TARGET_64BIT && reload_completed"
7516 [(parallel [(set (match_dup 3)
7517 (ashiftrt:DI (match_dup 4) (const_int 63)))
7518 (clobber (reg:CC FLAGS_REG))])
7519 (parallel [(set (match_dup 0)
7520 (div:DI (reg:DI 0) (match_dup 2)))
7521 (set (match_dup 3)
7522 (mod:DI (reg:DI 0) (match_dup 2)))
7523 (use (match_dup 3))
7524 (clobber (reg:CC FLAGS_REG))])]
7525 {
7526 /* Avoid use of cltd in favor of a mov+shift. */
7527 if (!TARGET_USE_CLTD && !optimize_size)
7528 {
7529 if (true_regnum (operands[1]))
7530 emit_move_insn (operands[0], operands[1]);
7531 else
7532 emit_move_insn (operands[3], operands[1]);
7533 operands[4] = operands[3];
7534 }
7535 else
7536 {
7537 if (true_regnum (operands[1]))
7538 abort();
7539 operands[4] = operands[1];
7540 }
7541 })
7542
7543
7544 (define_expand "divmodsi4"
7545 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7546 (div:SI (match_operand:SI 1 "register_operand" "")
7547 (match_operand:SI 2 "nonimmediate_operand" "")))
7548 (set (match_operand:SI 3 "register_operand" "")
7549 (mod:SI (match_dup 1) (match_dup 2)))
7550 (clobber (reg:CC FLAGS_REG))])]
7551 ""
7552 "")
7553
7554 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7555 ;; Penalize eax case slightly because it results in worse scheduling
7556 ;; of code.
7557 (define_insn "*divmodsi4_nocltd"
7558 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7559 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7560 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7561 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7562 (mod:SI (match_dup 2) (match_dup 3)))
7563 (clobber (reg:CC FLAGS_REG))]
7564 "!optimize_size && !TARGET_USE_CLTD"
7565 "#"
7566 [(set_attr "type" "multi")])
7567
7568 (define_insn "*divmodsi4_cltd"
7569 [(set (match_operand:SI 0 "register_operand" "=a")
7570 (div:SI (match_operand:SI 2 "register_operand" "a")
7571 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7572 (set (match_operand:SI 1 "register_operand" "=&d")
7573 (mod:SI (match_dup 2) (match_dup 3)))
7574 (clobber (reg:CC FLAGS_REG))]
7575 "optimize_size || TARGET_USE_CLTD"
7576 "#"
7577 [(set_attr "type" "multi")])
7578
7579 (define_insn "*divmodsi_noext"
7580 [(set (match_operand:SI 0 "register_operand" "=a")
7581 (div:SI (match_operand:SI 1 "register_operand" "0")
7582 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7583 (set (match_operand:SI 3 "register_operand" "=d")
7584 (mod:SI (match_dup 1) (match_dup 2)))
7585 (use (match_operand:SI 4 "register_operand" "3"))
7586 (clobber (reg:CC FLAGS_REG))]
7587 ""
7588 "idiv{l}\t%2"
7589 [(set_attr "type" "idiv")
7590 (set_attr "mode" "SI")])
7591
7592 (define_split
7593 [(set (match_operand:SI 0 "register_operand" "")
7594 (div:SI (match_operand:SI 1 "register_operand" "")
7595 (match_operand:SI 2 "nonimmediate_operand" "")))
7596 (set (match_operand:SI 3 "register_operand" "")
7597 (mod:SI (match_dup 1) (match_dup 2)))
7598 (clobber (reg:CC FLAGS_REG))]
7599 "reload_completed"
7600 [(parallel [(set (match_dup 3)
7601 (ashiftrt:SI (match_dup 4) (const_int 31)))
7602 (clobber (reg:CC FLAGS_REG))])
7603 (parallel [(set (match_dup 0)
7604 (div:SI (reg:SI 0) (match_dup 2)))
7605 (set (match_dup 3)
7606 (mod:SI (reg:SI 0) (match_dup 2)))
7607 (use (match_dup 3))
7608 (clobber (reg:CC FLAGS_REG))])]
7609 {
7610 /* Avoid use of cltd in favor of a mov+shift. */
7611 if (!TARGET_USE_CLTD && !optimize_size)
7612 {
7613 if (true_regnum (operands[1]))
7614 emit_move_insn (operands[0], operands[1]);
7615 else
7616 emit_move_insn (operands[3], operands[1]);
7617 operands[4] = operands[3];
7618 }
7619 else
7620 {
7621 if (true_regnum (operands[1]))
7622 abort();
7623 operands[4] = operands[1];
7624 }
7625 })
7626 ;; %%% Split me.
7627 (define_insn "divmodhi4"
7628 [(set (match_operand:HI 0 "register_operand" "=a")
7629 (div:HI (match_operand:HI 1 "register_operand" "0")
7630 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7631 (set (match_operand:HI 3 "register_operand" "=&d")
7632 (mod:HI (match_dup 1) (match_dup 2)))
7633 (clobber (reg:CC FLAGS_REG))]
7634 "TARGET_HIMODE_MATH"
7635 "cwtd\;idiv{w}\t%2"
7636 [(set_attr "type" "multi")
7637 (set_attr "length_immediate" "0")
7638 (set_attr "mode" "SI")])
7639
7640 (define_insn "udivmoddi4"
7641 [(set (match_operand:DI 0 "register_operand" "=a")
7642 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7643 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7644 (set (match_operand:DI 3 "register_operand" "=&d")
7645 (umod:DI (match_dup 1) (match_dup 2)))
7646 (clobber (reg:CC FLAGS_REG))]
7647 "TARGET_64BIT"
7648 "xor{q}\t%3, %3\;div{q}\t%2"
7649 [(set_attr "type" "multi")
7650 (set_attr "length_immediate" "0")
7651 (set_attr "mode" "DI")])
7652
7653 (define_insn "*udivmoddi4_noext"
7654 [(set (match_operand:DI 0 "register_operand" "=a")
7655 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7656 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7657 (set (match_operand:DI 3 "register_operand" "=d")
7658 (umod:DI (match_dup 1) (match_dup 2)))
7659 (use (match_dup 3))
7660 (clobber (reg:CC FLAGS_REG))]
7661 "TARGET_64BIT"
7662 "div{q}\t%2"
7663 [(set_attr "type" "idiv")
7664 (set_attr "mode" "DI")])
7665
7666 (define_split
7667 [(set (match_operand:DI 0 "register_operand" "")
7668 (udiv:DI (match_operand:DI 1 "register_operand" "")
7669 (match_operand:DI 2 "nonimmediate_operand" "")))
7670 (set (match_operand:DI 3 "register_operand" "")
7671 (umod:DI (match_dup 1) (match_dup 2)))
7672 (clobber (reg:CC FLAGS_REG))]
7673 "TARGET_64BIT && reload_completed"
7674 [(set (match_dup 3) (const_int 0))
7675 (parallel [(set (match_dup 0)
7676 (udiv:DI (match_dup 1) (match_dup 2)))
7677 (set (match_dup 3)
7678 (umod:DI (match_dup 1) (match_dup 2)))
7679 (use (match_dup 3))
7680 (clobber (reg:CC FLAGS_REG))])]
7681 "")
7682
7683 (define_insn "udivmodsi4"
7684 [(set (match_operand:SI 0 "register_operand" "=a")
7685 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7686 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7687 (set (match_operand:SI 3 "register_operand" "=&d")
7688 (umod:SI (match_dup 1) (match_dup 2)))
7689 (clobber (reg:CC FLAGS_REG))]
7690 ""
7691 "xor{l}\t%3, %3\;div{l}\t%2"
7692 [(set_attr "type" "multi")
7693 (set_attr "length_immediate" "0")
7694 (set_attr "mode" "SI")])
7695
7696 (define_insn "*udivmodsi4_noext"
7697 [(set (match_operand:SI 0 "register_operand" "=a")
7698 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7699 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7700 (set (match_operand:SI 3 "register_operand" "=d")
7701 (umod:SI (match_dup 1) (match_dup 2)))
7702 (use (match_dup 3))
7703 (clobber (reg:CC FLAGS_REG))]
7704 ""
7705 "div{l}\t%2"
7706 [(set_attr "type" "idiv")
7707 (set_attr "mode" "SI")])
7708
7709 (define_split
7710 [(set (match_operand:SI 0 "register_operand" "")
7711 (udiv:SI (match_operand:SI 1 "register_operand" "")
7712 (match_operand:SI 2 "nonimmediate_operand" "")))
7713 (set (match_operand:SI 3 "register_operand" "")
7714 (umod:SI (match_dup 1) (match_dup 2)))
7715 (clobber (reg:CC FLAGS_REG))]
7716 "reload_completed"
7717 [(set (match_dup 3) (const_int 0))
7718 (parallel [(set (match_dup 0)
7719 (udiv:SI (match_dup 1) (match_dup 2)))
7720 (set (match_dup 3)
7721 (umod:SI (match_dup 1) (match_dup 2)))
7722 (use (match_dup 3))
7723 (clobber (reg:CC FLAGS_REG))])]
7724 "")
7725
7726 (define_expand "udivmodhi4"
7727 [(set (match_dup 4) (const_int 0))
7728 (parallel [(set (match_operand:HI 0 "register_operand" "")
7729 (udiv:HI (match_operand:HI 1 "register_operand" "")
7730 (match_operand:HI 2 "nonimmediate_operand" "")))
7731 (set (match_operand:HI 3 "register_operand" "")
7732 (umod:HI (match_dup 1) (match_dup 2)))
7733 (use (match_dup 4))
7734 (clobber (reg:CC FLAGS_REG))])]
7735 "TARGET_HIMODE_MATH"
7736 "operands[4] = gen_reg_rtx (HImode);")
7737
7738 (define_insn "*udivmodhi_noext"
7739 [(set (match_operand:HI 0 "register_operand" "=a")
7740 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7741 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7742 (set (match_operand:HI 3 "register_operand" "=d")
7743 (umod:HI (match_dup 1) (match_dup 2)))
7744 (use (match_operand:HI 4 "register_operand" "3"))
7745 (clobber (reg:CC FLAGS_REG))]
7746 ""
7747 "div{w}\t%2"
7748 [(set_attr "type" "idiv")
7749 (set_attr "mode" "HI")])
7750
7751 ;; We cannot use div/idiv for double division, because it causes
7752 ;; "division by zero" on the overflow and that's not what we expect
7753 ;; from truncate. Because true (non truncating) double division is
7754 ;; never generated, we can't create this insn anyway.
7755 ;
7756 ;(define_insn ""
7757 ; [(set (match_operand:SI 0 "register_operand" "=a")
7758 ; (truncate:SI
7759 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7760 ; (zero_extend:DI
7761 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7762 ; (set (match_operand:SI 3 "register_operand" "=d")
7763 ; (truncate:SI
7764 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7765 ; (clobber (reg:CC FLAGS_REG))]
7766 ; ""
7767 ; "div{l}\t{%2, %0|%0, %2}"
7768 ; [(set_attr "type" "idiv")])
7769 \f
7770 ;;- Logical AND instructions
7771
7772 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7773 ;; Note that this excludes ah.
7774
7775 (define_insn "*testdi_1_rex64"
7776 [(set (reg FLAGS_REG)
7777 (compare
7778 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7779 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7780 (const_int 0)))]
7781 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7782 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7783 "@
7784 test{l}\t{%k1, %k0|%k0, %k1}
7785 test{l}\t{%k1, %k0|%k0, %k1}
7786 test{q}\t{%1, %0|%0, %1}
7787 test{q}\t{%1, %0|%0, %1}
7788 test{q}\t{%1, %0|%0, %1}"
7789 [(set_attr "type" "test")
7790 (set_attr "modrm" "0,1,0,1,1")
7791 (set_attr "mode" "SI,SI,DI,DI,DI")
7792 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7793
7794 (define_insn "testsi_1"
7795 [(set (reg FLAGS_REG)
7796 (compare
7797 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7798 (match_operand:SI 1 "general_operand" "in,in,rin"))
7799 (const_int 0)))]
7800 "ix86_match_ccmode (insn, CCNOmode)
7801 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7802 "test{l}\t{%1, %0|%0, %1}"
7803 [(set_attr "type" "test")
7804 (set_attr "modrm" "0,1,1")
7805 (set_attr "mode" "SI")
7806 (set_attr "pent_pair" "uv,np,uv")])
7807
7808 (define_expand "testsi_ccno_1"
7809 [(set (reg:CCNO FLAGS_REG)
7810 (compare:CCNO
7811 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7812 (match_operand:SI 1 "nonmemory_operand" ""))
7813 (const_int 0)))]
7814 ""
7815 "")
7816
7817 (define_insn "*testhi_1"
7818 [(set (reg FLAGS_REG)
7819 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7820 (match_operand:HI 1 "general_operand" "n,n,rn"))
7821 (const_int 0)))]
7822 "ix86_match_ccmode (insn, CCNOmode)
7823 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7824 "test{w}\t{%1, %0|%0, %1}"
7825 [(set_attr "type" "test")
7826 (set_attr "modrm" "0,1,1")
7827 (set_attr "mode" "HI")
7828 (set_attr "pent_pair" "uv,np,uv")])
7829
7830 (define_expand "testqi_ccz_1"
7831 [(set (reg:CCZ FLAGS_REG)
7832 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7833 (match_operand:QI 1 "nonmemory_operand" ""))
7834 (const_int 0)))]
7835 ""
7836 "")
7837
7838 (define_insn "*testqi_1_maybe_si"
7839 [(set (reg FLAGS_REG)
7840 (compare
7841 (and:QI
7842 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7843 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7844 (const_int 0)))]
7845 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7846 && ix86_match_ccmode (insn,
7847 GET_CODE (operands[1]) == CONST_INT
7848 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7849 {
7850 if (which_alternative == 3)
7851 {
7852 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7853 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7854 return "test{l}\t{%1, %k0|%k0, %1}";
7855 }
7856 return "test{b}\t{%1, %0|%0, %1}";
7857 }
7858 [(set_attr "type" "test")
7859 (set_attr "modrm" "0,1,1,1")
7860 (set_attr "mode" "QI,QI,QI,SI")
7861 (set_attr "pent_pair" "uv,np,uv,np")])
7862
7863 (define_insn "*testqi_1"
7864 [(set (reg FLAGS_REG)
7865 (compare
7866 (and:QI
7867 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7868 (match_operand:QI 1 "general_operand" "n,n,qn"))
7869 (const_int 0)))]
7870 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7871 && ix86_match_ccmode (insn, CCNOmode)"
7872 "test{b}\t{%1, %0|%0, %1}"
7873 [(set_attr "type" "test")
7874 (set_attr "modrm" "0,1,1")
7875 (set_attr "mode" "QI")
7876 (set_attr "pent_pair" "uv,np,uv")])
7877
7878 (define_expand "testqi_ext_ccno_0"
7879 [(set (reg:CCNO FLAGS_REG)
7880 (compare:CCNO
7881 (and:SI
7882 (zero_extract:SI
7883 (match_operand 0 "ext_register_operand" "")
7884 (const_int 8)
7885 (const_int 8))
7886 (match_operand 1 "const_int_operand" ""))
7887 (const_int 0)))]
7888 ""
7889 "")
7890
7891 (define_insn "*testqi_ext_0"
7892 [(set (reg FLAGS_REG)
7893 (compare
7894 (and:SI
7895 (zero_extract:SI
7896 (match_operand 0 "ext_register_operand" "Q")
7897 (const_int 8)
7898 (const_int 8))
7899 (match_operand 1 "const_int_operand" "n"))
7900 (const_int 0)))]
7901 "ix86_match_ccmode (insn, CCNOmode)"
7902 "test{b}\t{%1, %h0|%h0, %1}"
7903 [(set_attr "type" "test")
7904 (set_attr "mode" "QI")
7905 (set_attr "length_immediate" "1")
7906 (set_attr "pent_pair" "np")])
7907
7908 (define_insn "*testqi_ext_1"
7909 [(set (reg FLAGS_REG)
7910 (compare
7911 (and:SI
7912 (zero_extract:SI
7913 (match_operand 0 "ext_register_operand" "Q")
7914 (const_int 8)
7915 (const_int 8))
7916 (zero_extend:SI
7917 (match_operand:QI 1 "general_operand" "Qm")))
7918 (const_int 0)))]
7919 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7920 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7921 "test{b}\t{%1, %h0|%h0, %1}"
7922 [(set_attr "type" "test")
7923 (set_attr "mode" "QI")])
7924
7925 (define_insn "*testqi_ext_1_rex64"
7926 [(set (reg FLAGS_REG)
7927 (compare
7928 (and:SI
7929 (zero_extract:SI
7930 (match_operand 0 "ext_register_operand" "Q")
7931 (const_int 8)
7932 (const_int 8))
7933 (zero_extend:SI
7934 (match_operand:QI 1 "register_operand" "Q")))
7935 (const_int 0)))]
7936 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7937 "test{b}\t{%1, %h0|%h0, %1}"
7938 [(set_attr "type" "test")
7939 (set_attr "mode" "QI")])
7940
7941 (define_insn "*testqi_ext_2"
7942 [(set (reg FLAGS_REG)
7943 (compare
7944 (and:SI
7945 (zero_extract:SI
7946 (match_operand 0 "ext_register_operand" "Q")
7947 (const_int 8)
7948 (const_int 8))
7949 (zero_extract:SI
7950 (match_operand 1 "ext_register_operand" "Q")
7951 (const_int 8)
7952 (const_int 8)))
7953 (const_int 0)))]
7954 "ix86_match_ccmode (insn, CCNOmode)"
7955 "test{b}\t{%h1, %h0|%h0, %h1}"
7956 [(set_attr "type" "test")
7957 (set_attr "mode" "QI")])
7958
7959 ;; Combine likes to form bit extractions for some tests. Humor it.
7960 (define_insn "*testqi_ext_3"
7961 [(set (reg FLAGS_REG)
7962 (compare (zero_extract:SI
7963 (match_operand 0 "nonimmediate_operand" "rm")
7964 (match_operand:SI 1 "const_int_operand" "")
7965 (match_operand:SI 2 "const_int_operand" ""))
7966 (const_int 0)))]
7967 "ix86_match_ccmode (insn, CCNOmode)
7968 && (GET_MODE (operands[0]) == SImode
7969 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7970 || GET_MODE (operands[0]) == HImode
7971 || GET_MODE (operands[0]) == QImode)"
7972 "#")
7973
7974 (define_insn "*testqi_ext_3_rex64"
7975 [(set (reg FLAGS_REG)
7976 (compare (zero_extract:DI
7977 (match_operand 0 "nonimmediate_operand" "rm")
7978 (match_operand:DI 1 "const_int_operand" "")
7979 (match_operand:DI 2 "const_int_operand" ""))
7980 (const_int 0)))]
7981 "TARGET_64BIT
7982 && ix86_match_ccmode (insn, CCNOmode)
7983 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7984 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7985 /* Ensure that resulting mask is zero or sign extended operand. */
7986 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7987 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7988 && INTVAL (operands[1]) > 32))
7989 && (GET_MODE (operands[0]) == SImode
7990 || GET_MODE (operands[0]) == DImode
7991 || GET_MODE (operands[0]) == HImode
7992 || GET_MODE (operands[0]) == QImode)"
7993 "#")
7994
7995 (define_split
7996 [(set (match_operand 0 "flags_reg_operand" "")
7997 (match_operator 1 "compare_operator"
7998 [(zero_extract
7999 (match_operand 2 "nonimmediate_operand" "")
8000 (match_operand 3 "const_int_operand" "")
8001 (match_operand 4 "const_int_operand" ""))
8002 (const_int 0)]))]
8003 "ix86_match_ccmode (insn, CCNOmode)"
8004 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8005 {
8006 rtx val = operands[2];
8007 HOST_WIDE_INT len = INTVAL (operands[3]);
8008 HOST_WIDE_INT pos = INTVAL (operands[4]);
8009 HOST_WIDE_INT mask;
8010 enum machine_mode mode, submode;
8011
8012 mode = GET_MODE (val);
8013 if (GET_CODE (val) == MEM)
8014 {
8015 /* ??? Combine likes to put non-volatile mem extractions in QImode
8016 no matter the size of the test. So find a mode that works. */
8017 if (! MEM_VOLATILE_P (val))
8018 {
8019 mode = smallest_mode_for_size (pos + len, MODE_INT);
8020 val = adjust_address (val, mode, 0);
8021 }
8022 }
8023 else if (GET_CODE (val) == SUBREG
8024 && (submode = GET_MODE (SUBREG_REG (val)),
8025 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8026 && pos + len <= GET_MODE_BITSIZE (submode))
8027 {
8028 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8029 mode = submode;
8030 val = SUBREG_REG (val);
8031 }
8032 else if (mode == HImode && pos + len <= 8)
8033 {
8034 /* Small HImode tests can be converted to QImode. */
8035 mode = QImode;
8036 val = gen_lowpart (QImode, val);
8037 }
8038
8039 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8040 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8041
8042 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8043 })
8044
8045 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8046 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8047 ;; this is relatively important trick.
8048 ;; Do the conversion only post-reload to avoid limiting of the register class
8049 ;; to QI regs.
8050 (define_split
8051 [(set (match_operand 0 "flags_reg_operand" "")
8052 (match_operator 1 "compare_operator"
8053 [(and (match_operand 2 "register_operand" "")
8054 (match_operand 3 "const_int_operand" ""))
8055 (const_int 0)]))]
8056 "reload_completed
8057 && QI_REG_P (operands[2])
8058 && GET_MODE (operands[2]) != QImode
8059 && ((ix86_match_ccmode (insn, CCZmode)
8060 && !(INTVAL (operands[3]) & ~(255 << 8)))
8061 || (ix86_match_ccmode (insn, CCNOmode)
8062 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8063 [(set (match_dup 0)
8064 (match_op_dup 1
8065 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8066 (match_dup 3))
8067 (const_int 0)]))]
8068 "operands[2] = gen_lowpart (SImode, operands[2]);
8069 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8070
8071 (define_split
8072 [(set (match_operand 0 "flags_reg_operand" "")
8073 (match_operator 1 "compare_operator"
8074 [(and (match_operand 2 "nonimmediate_operand" "")
8075 (match_operand 3 "const_int_operand" ""))
8076 (const_int 0)]))]
8077 "reload_completed
8078 && GET_MODE (operands[2]) != QImode
8079 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8080 && ((ix86_match_ccmode (insn, CCZmode)
8081 && !(INTVAL (operands[3]) & ~255))
8082 || (ix86_match_ccmode (insn, CCNOmode)
8083 && !(INTVAL (operands[3]) & ~127)))"
8084 [(set (match_dup 0)
8085 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8086 (const_int 0)]))]
8087 "operands[2] = gen_lowpart (QImode, operands[2]);
8088 operands[3] = gen_lowpart (QImode, operands[3]);")
8089
8090
8091 ;; %%% This used to optimize known byte-wide and operations to memory,
8092 ;; and sometimes to QImode registers. If this is considered useful,
8093 ;; it should be done with splitters.
8094
8095 (define_expand "anddi3"
8096 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8097 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8098 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8099 (clobber (reg:CC FLAGS_REG))]
8100 "TARGET_64BIT"
8101 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8102
8103 (define_insn "*anddi_1_rex64"
8104 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8105 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8106 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8107 (clobber (reg:CC FLAGS_REG))]
8108 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8109 {
8110 switch (get_attr_type (insn))
8111 {
8112 case TYPE_IMOVX:
8113 {
8114 enum machine_mode mode;
8115
8116 if (GET_CODE (operands[2]) != CONST_INT)
8117 abort ();
8118 if (INTVAL (operands[2]) == 0xff)
8119 mode = QImode;
8120 else if (INTVAL (operands[2]) == 0xffff)
8121 mode = HImode;
8122 else
8123 abort ();
8124
8125 operands[1] = gen_lowpart (mode, operands[1]);
8126 if (mode == QImode)
8127 return "movz{bq|x}\t{%1,%0|%0, %1}";
8128 else
8129 return "movz{wq|x}\t{%1,%0|%0, %1}";
8130 }
8131
8132 default:
8133 if (! rtx_equal_p (operands[0], operands[1]))
8134 abort ();
8135 if (get_attr_mode (insn) == MODE_SI)
8136 return "and{l}\t{%k2, %k0|%k0, %k2}";
8137 else
8138 return "and{q}\t{%2, %0|%0, %2}";
8139 }
8140 }
8141 [(set_attr "type" "alu,alu,alu,imovx")
8142 (set_attr "length_immediate" "*,*,*,0")
8143 (set_attr "mode" "SI,DI,DI,DI")])
8144
8145 (define_insn "*anddi_2"
8146 [(set (reg FLAGS_REG)
8147 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8148 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8149 (const_int 0)))
8150 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8151 (and:DI (match_dup 1) (match_dup 2)))]
8152 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8153 && ix86_binary_operator_ok (AND, DImode, operands)"
8154 "@
8155 and{l}\t{%k2, %k0|%k0, %k2}
8156 and{q}\t{%2, %0|%0, %2}
8157 and{q}\t{%2, %0|%0, %2}"
8158 [(set_attr "type" "alu")
8159 (set_attr "mode" "SI,DI,DI")])
8160
8161 (define_expand "andsi3"
8162 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8163 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8164 (match_operand:SI 2 "general_operand" "")))
8165 (clobber (reg:CC FLAGS_REG))]
8166 ""
8167 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8168
8169 (define_insn "*andsi_1"
8170 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8171 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8172 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8173 (clobber (reg:CC FLAGS_REG))]
8174 "ix86_binary_operator_ok (AND, SImode, operands)"
8175 {
8176 switch (get_attr_type (insn))
8177 {
8178 case TYPE_IMOVX:
8179 {
8180 enum machine_mode mode;
8181
8182 if (GET_CODE (operands[2]) != CONST_INT)
8183 abort ();
8184 if (INTVAL (operands[2]) == 0xff)
8185 mode = QImode;
8186 else if (INTVAL (operands[2]) == 0xffff)
8187 mode = HImode;
8188 else
8189 abort ();
8190
8191 operands[1] = gen_lowpart (mode, operands[1]);
8192 if (mode == QImode)
8193 return "movz{bl|x}\t{%1,%0|%0, %1}";
8194 else
8195 return "movz{wl|x}\t{%1,%0|%0, %1}";
8196 }
8197
8198 default:
8199 if (! rtx_equal_p (operands[0], operands[1]))
8200 abort ();
8201 return "and{l}\t{%2, %0|%0, %2}";
8202 }
8203 }
8204 [(set_attr "type" "alu,alu,imovx")
8205 (set_attr "length_immediate" "*,*,0")
8206 (set_attr "mode" "SI")])
8207
8208 (define_split
8209 [(set (match_operand 0 "register_operand" "")
8210 (and (match_dup 0)
8211 (const_int -65536)))
8212 (clobber (reg:CC FLAGS_REG))]
8213 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8214 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8215 "operands[1] = gen_lowpart (HImode, operands[0]);")
8216
8217 (define_split
8218 [(set (match_operand 0 "ext_register_operand" "")
8219 (and (match_dup 0)
8220 (const_int -256)))
8221 (clobber (reg:CC FLAGS_REG))]
8222 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8223 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8224 "operands[1] = gen_lowpart (QImode, operands[0]);")
8225
8226 (define_split
8227 [(set (match_operand 0 "ext_register_operand" "")
8228 (and (match_dup 0)
8229 (const_int -65281)))
8230 (clobber (reg:CC FLAGS_REG))]
8231 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8232 [(parallel [(set (zero_extract:SI (match_dup 0)
8233 (const_int 8)
8234 (const_int 8))
8235 (xor:SI
8236 (zero_extract:SI (match_dup 0)
8237 (const_int 8)
8238 (const_int 8))
8239 (zero_extract:SI (match_dup 0)
8240 (const_int 8)
8241 (const_int 8))))
8242 (clobber (reg:CC FLAGS_REG))])]
8243 "operands[0] = gen_lowpart (SImode, operands[0]);")
8244
8245 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8246 (define_insn "*andsi_1_zext"
8247 [(set (match_operand:DI 0 "register_operand" "=r")
8248 (zero_extend:DI
8249 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8250 (match_operand:SI 2 "general_operand" "rim"))))
8251 (clobber (reg:CC FLAGS_REG))]
8252 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8253 "and{l}\t{%2, %k0|%k0, %2}"
8254 [(set_attr "type" "alu")
8255 (set_attr "mode" "SI")])
8256
8257 (define_insn "*andsi_2"
8258 [(set (reg FLAGS_REG)
8259 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8260 (match_operand:SI 2 "general_operand" "rim,ri"))
8261 (const_int 0)))
8262 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8263 (and:SI (match_dup 1) (match_dup 2)))]
8264 "ix86_match_ccmode (insn, CCNOmode)
8265 && ix86_binary_operator_ok (AND, SImode, operands)"
8266 "and{l}\t{%2, %0|%0, %2}"
8267 [(set_attr "type" "alu")
8268 (set_attr "mode" "SI")])
8269
8270 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8271 (define_insn "*andsi_2_zext"
8272 [(set (reg FLAGS_REG)
8273 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8274 (match_operand:SI 2 "general_operand" "rim"))
8275 (const_int 0)))
8276 (set (match_operand:DI 0 "register_operand" "=r")
8277 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8278 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8279 && ix86_binary_operator_ok (AND, SImode, operands)"
8280 "and{l}\t{%2, %k0|%k0, %2}"
8281 [(set_attr "type" "alu")
8282 (set_attr "mode" "SI")])
8283
8284 (define_expand "andhi3"
8285 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8286 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8287 (match_operand:HI 2 "general_operand" "")))
8288 (clobber (reg:CC FLAGS_REG))]
8289 "TARGET_HIMODE_MATH"
8290 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8291
8292 (define_insn "*andhi_1"
8293 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8294 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8295 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8296 (clobber (reg:CC FLAGS_REG))]
8297 "ix86_binary_operator_ok (AND, HImode, operands)"
8298 {
8299 switch (get_attr_type (insn))
8300 {
8301 case TYPE_IMOVX:
8302 if (GET_CODE (operands[2]) != CONST_INT)
8303 abort ();
8304 if (INTVAL (operands[2]) == 0xff)
8305 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8306 abort ();
8307
8308 default:
8309 if (! rtx_equal_p (operands[0], operands[1]))
8310 abort ();
8311
8312 return "and{w}\t{%2, %0|%0, %2}";
8313 }
8314 }
8315 [(set_attr "type" "alu,alu,imovx")
8316 (set_attr "length_immediate" "*,*,0")
8317 (set_attr "mode" "HI,HI,SI")])
8318
8319 (define_insn "*andhi_2"
8320 [(set (reg FLAGS_REG)
8321 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8322 (match_operand:HI 2 "general_operand" "rim,ri"))
8323 (const_int 0)))
8324 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8325 (and:HI (match_dup 1) (match_dup 2)))]
8326 "ix86_match_ccmode (insn, CCNOmode)
8327 && ix86_binary_operator_ok (AND, HImode, operands)"
8328 "and{w}\t{%2, %0|%0, %2}"
8329 [(set_attr "type" "alu")
8330 (set_attr "mode" "HI")])
8331
8332 (define_expand "andqi3"
8333 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8334 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8335 (match_operand:QI 2 "general_operand" "")))
8336 (clobber (reg:CC FLAGS_REG))]
8337 "TARGET_QIMODE_MATH"
8338 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8339
8340 ;; %%% Potential partial reg stall on alternative 2. What to do?
8341 (define_insn "*andqi_1"
8342 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8343 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8344 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8345 (clobber (reg:CC FLAGS_REG))]
8346 "ix86_binary_operator_ok (AND, QImode, operands)"
8347 "@
8348 and{b}\t{%2, %0|%0, %2}
8349 and{b}\t{%2, %0|%0, %2}
8350 and{l}\t{%k2, %k0|%k0, %k2}"
8351 [(set_attr "type" "alu")
8352 (set_attr "mode" "QI,QI,SI")])
8353
8354 (define_insn "*andqi_1_slp"
8355 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8356 (and:QI (match_dup 0)
8357 (match_operand:QI 1 "general_operand" "qi,qmi")))
8358 (clobber (reg:CC FLAGS_REG))]
8359 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8360 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8361 "and{b}\t{%1, %0|%0, %1}"
8362 [(set_attr "type" "alu1")
8363 (set_attr "mode" "QI")])
8364
8365 (define_insn "*andqi_2_maybe_si"
8366 [(set (reg FLAGS_REG)
8367 (compare (and:QI
8368 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8369 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8370 (const_int 0)))
8371 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8372 (and:QI (match_dup 1) (match_dup 2)))]
8373 "ix86_binary_operator_ok (AND, QImode, operands)
8374 && ix86_match_ccmode (insn,
8375 GET_CODE (operands[2]) == CONST_INT
8376 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8377 {
8378 if (which_alternative == 2)
8379 {
8380 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8381 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8382 return "and{l}\t{%2, %k0|%k0, %2}";
8383 }
8384 return "and{b}\t{%2, %0|%0, %2}";
8385 }
8386 [(set_attr "type" "alu")
8387 (set_attr "mode" "QI,QI,SI")])
8388
8389 (define_insn "*andqi_2"
8390 [(set (reg FLAGS_REG)
8391 (compare (and:QI
8392 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8393 (match_operand:QI 2 "general_operand" "qim,qi"))
8394 (const_int 0)))
8395 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8396 (and:QI (match_dup 1) (match_dup 2)))]
8397 "ix86_match_ccmode (insn, CCNOmode)
8398 && ix86_binary_operator_ok (AND, QImode, operands)"
8399 "and{b}\t{%2, %0|%0, %2}"
8400 [(set_attr "type" "alu")
8401 (set_attr "mode" "QI")])
8402
8403 (define_insn "*andqi_2_slp"
8404 [(set (reg FLAGS_REG)
8405 (compare (and:QI
8406 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8407 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8408 (const_int 0)))
8409 (set (strict_low_part (match_dup 0))
8410 (and:QI (match_dup 0) (match_dup 1)))]
8411 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8412 && ix86_match_ccmode (insn, CCNOmode)
8413 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8414 "and{b}\t{%1, %0|%0, %1}"
8415 [(set_attr "type" "alu1")
8416 (set_attr "mode" "QI")])
8417
8418 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8419 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8420 ;; for a QImode operand, which of course failed.
8421
8422 (define_insn "andqi_ext_0"
8423 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8424 (const_int 8)
8425 (const_int 8))
8426 (and:SI
8427 (zero_extract:SI
8428 (match_operand 1 "ext_register_operand" "0")
8429 (const_int 8)
8430 (const_int 8))
8431 (match_operand 2 "const_int_operand" "n")))
8432 (clobber (reg:CC FLAGS_REG))]
8433 ""
8434 "and{b}\t{%2, %h0|%h0, %2}"
8435 [(set_attr "type" "alu")
8436 (set_attr "length_immediate" "1")
8437 (set_attr "mode" "QI")])
8438
8439 ;; Generated by peephole translating test to and. This shows up
8440 ;; often in fp comparisons.
8441
8442 (define_insn "*andqi_ext_0_cc"
8443 [(set (reg FLAGS_REG)
8444 (compare
8445 (and:SI
8446 (zero_extract:SI
8447 (match_operand 1 "ext_register_operand" "0")
8448 (const_int 8)
8449 (const_int 8))
8450 (match_operand 2 "const_int_operand" "n"))
8451 (const_int 0)))
8452 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8453 (const_int 8)
8454 (const_int 8))
8455 (and:SI
8456 (zero_extract:SI
8457 (match_dup 1)
8458 (const_int 8)
8459 (const_int 8))
8460 (match_dup 2)))]
8461 "ix86_match_ccmode (insn, CCNOmode)"
8462 "and{b}\t{%2, %h0|%h0, %2}"
8463 [(set_attr "type" "alu")
8464 (set_attr "length_immediate" "1")
8465 (set_attr "mode" "QI")])
8466
8467 (define_insn "*andqi_ext_1"
8468 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8469 (const_int 8)
8470 (const_int 8))
8471 (and:SI
8472 (zero_extract:SI
8473 (match_operand 1 "ext_register_operand" "0")
8474 (const_int 8)
8475 (const_int 8))
8476 (zero_extend:SI
8477 (match_operand:QI 2 "general_operand" "Qm"))))
8478 (clobber (reg:CC FLAGS_REG))]
8479 "!TARGET_64BIT"
8480 "and{b}\t{%2, %h0|%h0, %2}"
8481 [(set_attr "type" "alu")
8482 (set_attr "length_immediate" "0")
8483 (set_attr "mode" "QI")])
8484
8485 (define_insn "*andqi_ext_1_rex64"
8486 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8487 (const_int 8)
8488 (const_int 8))
8489 (and:SI
8490 (zero_extract:SI
8491 (match_operand 1 "ext_register_operand" "0")
8492 (const_int 8)
8493 (const_int 8))
8494 (zero_extend:SI
8495 (match_operand 2 "ext_register_operand" "Q"))))
8496 (clobber (reg:CC FLAGS_REG))]
8497 "TARGET_64BIT"
8498 "and{b}\t{%2, %h0|%h0, %2}"
8499 [(set_attr "type" "alu")
8500 (set_attr "length_immediate" "0")
8501 (set_attr "mode" "QI")])
8502
8503 (define_insn "*andqi_ext_2"
8504 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8505 (const_int 8)
8506 (const_int 8))
8507 (and:SI
8508 (zero_extract:SI
8509 (match_operand 1 "ext_register_operand" "%0")
8510 (const_int 8)
8511 (const_int 8))
8512 (zero_extract:SI
8513 (match_operand 2 "ext_register_operand" "Q")
8514 (const_int 8)
8515 (const_int 8))))
8516 (clobber (reg:CC FLAGS_REG))]
8517 ""
8518 "and{b}\t{%h2, %h0|%h0, %h2}"
8519 [(set_attr "type" "alu")
8520 (set_attr "length_immediate" "0")
8521 (set_attr "mode" "QI")])
8522
8523 ;; Convert wide AND instructions with immediate operand to shorter QImode
8524 ;; equivalents when possible.
8525 ;; Don't do the splitting with memory operands, since it introduces risk
8526 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8527 ;; for size, but that can (should?) be handled by generic code instead.
8528 (define_split
8529 [(set (match_operand 0 "register_operand" "")
8530 (and (match_operand 1 "register_operand" "")
8531 (match_operand 2 "const_int_operand" "")))
8532 (clobber (reg:CC FLAGS_REG))]
8533 "reload_completed
8534 && QI_REG_P (operands[0])
8535 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8536 && !(~INTVAL (operands[2]) & ~(255 << 8))
8537 && GET_MODE (operands[0]) != QImode"
8538 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8539 (and:SI (zero_extract:SI (match_dup 1)
8540 (const_int 8) (const_int 8))
8541 (match_dup 2)))
8542 (clobber (reg:CC FLAGS_REG))])]
8543 "operands[0] = gen_lowpart (SImode, operands[0]);
8544 operands[1] = gen_lowpart (SImode, operands[1]);
8545 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8546
8547 ;; Since AND can be encoded with sign extended immediate, this is only
8548 ;; profitable when 7th bit is not set.
8549 (define_split
8550 [(set (match_operand 0 "register_operand" "")
8551 (and (match_operand 1 "general_operand" "")
8552 (match_operand 2 "const_int_operand" "")))
8553 (clobber (reg:CC FLAGS_REG))]
8554 "reload_completed
8555 && ANY_QI_REG_P (operands[0])
8556 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8557 && !(~INTVAL (operands[2]) & ~255)
8558 && !(INTVAL (operands[2]) & 128)
8559 && GET_MODE (operands[0]) != QImode"
8560 [(parallel [(set (strict_low_part (match_dup 0))
8561 (and:QI (match_dup 1)
8562 (match_dup 2)))
8563 (clobber (reg:CC FLAGS_REG))])]
8564 "operands[0] = gen_lowpart (QImode, operands[0]);
8565 operands[1] = gen_lowpart (QImode, operands[1]);
8566 operands[2] = gen_lowpart (QImode, operands[2]);")
8567 \f
8568 ;; Logical inclusive OR instructions
8569
8570 ;; %%% This used to optimize known byte-wide and operations to memory.
8571 ;; If this is considered useful, it should be done with splitters.
8572
8573 (define_expand "iordi3"
8574 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8575 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8576 (match_operand:DI 2 "x86_64_general_operand" "")))
8577 (clobber (reg:CC FLAGS_REG))]
8578 "TARGET_64BIT"
8579 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8580
8581 (define_insn "*iordi_1_rex64"
8582 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8583 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8584 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8585 (clobber (reg:CC FLAGS_REG))]
8586 "TARGET_64BIT
8587 && ix86_binary_operator_ok (IOR, DImode, operands)"
8588 "or{q}\t{%2, %0|%0, %2}"
8589 [(set_attr "type" "alu")
8590 (set_attr "mode" "DI")])
8591
8592 (define_insn "*iordi_2_rex64"
8593 [(set (reg FLAGS_REG)
8594 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8595 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8596 (const_int 0)))
8597 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8598 (ior:DI (match_dup 1) (match_dup 2)))]
8599 "TARGET_64BIT
8600 && ix86_match_ccmode (insn, CCNOmode)
8601 && ix86_binary_operator_ok (IOR, DImode, operands)"
8602 "or{q}\t{%2, %0|%0, %2}"
8603 [(set_attr "type" "alu")
8604 (set_attr "mode" "DI")])
8605
8606 (define_insn "*iordi_3_rex64"
8607 [(set (reg FLAGS_REG)
8608 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8609 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8610 (const_int 0)))
8611 (clobber (match_scratch:DI 0 "=r"))]
8612 "TARGET_64BIT
8613 && ix86_match_ccmode (insn, CCNOmode)
8614 && ix86_binary_operator_ok (IOR, DImode, operands)"
8615 "or{q}\t{%2, %0|%0, %2}"
8616 [(set_attr "type" "alu")
8617 (set_attr "mode" "DI")])
8618
8619
8620 (define_expand "iorsi3"
8621 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8622 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8623 (match_operand:SI 2 "general_operand" "")))
8624 (clobber (reg:CC FLAGS_REG))]
8625 ""
8626 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8627
8628 (define_insn "*iorsi_1"
8629 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8630 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8631 (match_operand:SI 2 "general_operand" "ri,rmi")))
8632 (clobber (reg:CC FLAGS_REG))]
8633 "ix86_binary_operator_ok (IOR, SImode, operands)"
8634 "or{l}\t{%2, %0|%0, %2}"
8635 [(set_attr "type" "alu")
8636 (set_attr "mode" "SI")])
8637
8638 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8639 (define_insn "*iorsi_1_zext"
8640 [(set (match_operand:DI 0 "register_operand" "=rm")
8641 (zero_extend:DI
8642 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8643 (match_operand:SI 2 "general_operand" "rim"))))
8644 (clobber (reg:CC FLAGS_REG))]
8645 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8646 "or{l}\t{%2, %k0|%k0, %2}"
8647 [(set_attr "type" "alu")
8648 (set_attr "mode" "SI")])
8649
8650 (define_insn "*iorsi_1_zext_imm"
8651 [(set (match_operand:DI 0 "register_operand" "=rm")
8652 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8653 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8654 (clobber (reg:CC FLAGS_REG))]
8655 "TARGET_64BIT"
8656 "or{l}\t{%2, %k0|%k0, %2}"
8657 [(set_attr "type" "alu")
8658 (set_attr "mode" "SI")])
8659
8660 (define_insn "*iorsi_2"
8661 [(set (reg FLAGS_REG)
8662 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8663 (match_operand:SI 2 "general_operand" "rim,ri"))
8664 (const_int 0)))
8665 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8666 (ior:SI (match_dup 1) (match_dup 2)))]
8667 "ix86_match_ccmode (insn, CCNOmode)
8668 && ix86_binary_operator_ok (IOR, SImode, operands)"
8669 "or{l}\t{%2, %0|%0, %2}"
8670 [(set_attr "type" "alu")
8671 (set_attr "mode" "SI")])
8672
8673 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8674 ;; ??? Special case for immediate operand is missing - it is tricky.
8675 (define_insn "*iorsi_2_zext"
8676 [(set (reg FLAGS_REG)
8677 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8678 (match_operand:SI 2 "general_operand" "rim"))
8679 (const_int 0)))
8680 (set (match_operand:DI 0 "register_operand" "=r")
8681 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8682 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8683 && ix86_binary_operator_ok (IOR, SImode, operands)"
8684 "or{l}\t{%2, %k0|%k0, %2}"
8685 [(set_attr "type" "alu")
8686 (set_attr "mode" "SI")])
8687
8688 (define_insn "*iorsi_2_zext_imm"
8689 [(set (reg FLAGS_REG)
8690 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8691 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8692 (const_int 0)))
8693 (set (match_operand:DI 0 "register_operand" "=r")
8694 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8695 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8696 && ix86_binary_operator_ok (IOR, SImode, operands)"
8697 "or{l}\t{%2, %k0|%k0, %2}"
8698 [(set_attr "type" "alu")
8699 (set_attr "mode" "SI")])
8700
8701 (define_insn "*iorsi_3"
8702 [(set (reg FLAGS_REG)
8703 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8704 (match_operand:SI 2 "general_operand" "rim"))
8705 (const_int 0)))
8706 (clobber (match_scratch:SI 0 "=r"))]
8707 "ix86_match_ccmode (insn, CCNOmode)
8708 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8709 "or{l}\t{%2, %0|%0, %2}"
8710 [(set_attr "type" "alu")
8711 (set_attr "mode" "SI")])
8712
8713 (define_expand "iorhi3"
8714 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8715 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8716 (match_operand:HI 2 "general_operand" "")))
8717 (clobber (reg:CC FLAGS_REG))]
8718 "TARGET_HIMODE_MATH"
8719 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8720
8721 (define_insn "*iorhi_1"
8722 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8723 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8724 (match_operand:HI 2 "general_operand" "rmi,ri")))
8725 (clobber (reg:CC FLAGS_REG))]
8726 "ix86_binary_operator_ok (IOR, HImode, operands)"
8727 "or{w}\t{%2, %0|%0, %2}"
8728 [(set_attr "type" "alu")
8729 (set_attr "mode" "HI")])
8730
8731 (define_insn "*iorhi_2"
8732 [(set (reg FLAGS_REG)
8733 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8734 (match_operand:HI 2 "general_operand" "rim,ri"))
8735 (const_int 0)))
8736 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8737 (ior:HI (match_dup 1) (match_dup 2)))]
8738 "ix86_match_ccmode (insn, CCNOmode)
8739 && ix86_binary_operator_ok (IOR, HImode, operands)"
8740 "or{w}\t{%2, %0|%0, %2}"
8741 [(set_attr "type" "alu")
8742 (set_attr "mode" "HI")])
8743
8744 (define_insn "*iorhi_3"
8745 [(set (reg FLAGS_REG)
8746 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8747 (match_operand:HI 2 "general_operand" "rim"))
8748 (const_int 0)))
8749 (clobber (match_scratch:HI 0 "=r"))]
8750 "ix86_match_ccmode (insn, CCNOmode)
8751 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8752 "or{w}\t{%2, %0|%0, %2}"
8753 [(set_attr "type" "alu")
8754 (set_attr "mode" "HI")])
8755
8756 (define_expand "iorqi3"
8757 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8758 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8759 (match_operand:QI 2 "general_operand" "")))
8760 (clobber (reg:CC FLAGS_REG))]
8761 "TARGET_QIMODE_MATH"
8762 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8763
8764 ;; %%% Potential partial reg stall on alternative 2. What to do?
8765 (define_insn "*iorqi_1"
8766 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8767 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8768 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8769 (clobber (reg:CC FLAGS_REG))]
8770 "ix86_binary_operator_ok (IOR, QImode, operands)"
8771 "@
8772 or{b}\t{%2, %0|%0, %2}
8773 or{b}\t{%2, %0|%0, %2}
8774 or{l}\t{%k2, %k0|%k0, %k2}"
8775 [(set_attr "type" "alu")
8776 (set_attr "mode" "QI,QI,SI")])
8777
8778 (define_insn "*iorqi_1_slp"
8779 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8780 (ior:QI (match_dup 0)
8781 (match_operand:QI 1 "general_operand" "qmi,qi")))
8782 (clobber (reg:CC FLAGS_REG))]
8783 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8784 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8785 "or{b}\t{%1, %0|%0, %1}"
8786 [(set_attr "type" "alu1")
8787 (set_attr "mode" "QI")])
8788
8789 (define_insn "*iorqi_2"
8790 [(set (reg FLAGS_REG)
8791 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8792 (match_operand:QI 2 "general_operand" "qim,qi"))
8793 (const_int 0)))
8794 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8795 (ior:QI (match_dup 1) (match_dup 2)))]
8796 "ix86_match_ccmode (insn, CCNOmode)
8797 && ix86_binary_operator_ok (IOR, QImode, operands)"
8798 "or{b}\t{%2, %0|%0, %2}"
8799 [(set_attr "type" "alu")
8800 (set_attr "mode" "QI")])
8801
8802 (define_insn "*iorqi_2_slp"
8803 [(set (reg FLAGS_REG)
8804 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8805 (match_operand:QI 1 "general_operand" "qim,qi"))
8806 (const_int 0)))
8807 (set (strict_low_part (match_dup 0))
8808 (ior:QI (match_dup 0) (match_dup 1)))]
8809 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8810 && ix86_match_ccmode (insn, CCNOmode)
8811 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8812 "or{b}\t{%1, %0|%0, %1}"
8813 [(set_attr "type" "alu1")
8814 (set_attr "mode" "QI")])
8815
8816 (define_insn "*iorqi_3"
8817 [(set (reg FLAGS_REG)
8818 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8819 (match_operand:QI 2 "general_operand" "qim"))
8820 (const_int 0)))
8821 (clobber (match_scratch:QI 0 "=q"))]
8822 "ix86_match_ccmode (insn, CCNOmode)
8823 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8824 "or{b}\t{%2, %0|%0, %2}"
8825 [(set_attr "type" "alu")
8826 (set_attr "mode" "QI")])
8827
8828 (define_insn "iorqi_ext_0"
8829 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8830 (const_int 8)
8831 (const_int 8))
8832 (ior:SI
8833 (zero_extract:SI
8834 (match_operand 1 "ext_register_operand" "0")
8835 (const_int 8)
8836 (const_int 8))
8837 (match_operand 2 "const_int_operand" "n")))
8838 (clobber (reg:CC FLAGS_REG))]
8839 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8840 "or{b}\t{%2, %h0|%h0, %2}"
8841 [(set_attr "type" "alu")
8842 (set_attr "length_immediate" "1")
8843 (set_attr "mode" "QI")])
8844
8845 (define_insn "*iorqi_ext_1"
8846 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8847 (const_int 8)
8848 (const_int 8))
8849 (ior:SI
8850 (zero_extract:SI
8851 (match_operand 1 "ext_register_operand" "0")
8852 (const_int 8)
8853 (const_int 8))
8854 (zero_extend:SI
8855 (match_operand:QI 2 "general_operand" "Qm"))))
8856 (clobber (reg:CC FLAGS_REG))]
8857 "!TARGET_64BIT
8858 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8859 "or{b}\t{%2, %h0|%h0, %2}"
8860 [(set_attr "type" "alu")
8861 (set_attr "length_immediate" "0")
8862 (set_attr "mode" "QI")])
8863
8864 (define_insn "*iorqi_ext_1_rex64"
8865 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8866 (const_int 8)
8867 (const_int 8))
8868 (ior:SI
8869 (zero_extract:SI
8870 (match_operand 1 "ext_register_operand" "0")
8871 (const_int 8)
8872 (const_int 8))
8873 (zero_extend:SI
8874 (match_operand 2 "ext_register_operand" "Q"))))
8875 (clobber (reg:CC FLAGS_REG))]
8876 "TARGET_64BIT
8877 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8878 "or{b}\t{%2, %h0|%h0, %2}"
8879 [(set_attr "type" "alu")
8880 (set_attr "length_immediate" "0")
8881 (set_attr "mode" "QI")])
8882
8883 (define_insn "*iorqi_ext_2"
8884 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8885 (const_int 8)
8886 (const_int 8))
8887 (ior:SI
8888 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8889 (const_int 8)
8890 (const_int 8))
8891 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8892 (const_int 8)
8893 (const_int 8))))
8894 (clobber (reg:CC FLAGS_REG))]
8895 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8896 "ior{b}\t{%h2, %h0|%h0, %h2}"
8897 [(set_attr "type" "alu")
8898 (set_attr "length_immediate" "0")
8899 (set_attr "mode" "QI")])
8900
8901 (define_split
8902 [(set (match_operand 0 "register_operand" "")
8903 (ior (match_operand 1 "register_operand" "")
8904 (match_operand 2 "const_int_operand" "")))
8905 (clobber (reg:CC FLAGS_REG))]
8906 "reload_completed
8907 && QI_REG_P (operands[0])
8908 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8909 && !(INTVAL (operands[2]) & ~(255 << 8))
8910 && GET_MODE (operands[0]) != QImode"
8911 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8912 (ior:SI (zero_extract:SI (match_dup 1)
8913 (const_int 8) (const_int 8))
8914 (match_dup 2)))
8915 (clobber (reg:CC FLAGS_REG))])]
8916 "operands[0] = gen_lowpart (SImode, operands[0]);
8917 operands[1] = gen_lowpart (SImode, operands[1]);
8918 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8919
8920 ;; Since OR can be encoded with sign extended immediate, this is only
8921 ;; profitable when 7th bit is set.
8922 (define_split
8923 [(set (match_operand 0 "register_operand" "")
8924 (ior (match_operand 1 "general_operand" "")
8925 (match_operand 2 "const_int_operand" "")))
8926 (clobber (reg:CC FLAGS_REG))]
8927 "reload_completed
8928 && ANY_QI_REG_P (operands[0])
8929 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8930 && !(INTVAL (operands[2]) & ~255)
8931 && (INTVAL (operands[2]) & 128)
8932 && GET_MODE (operands[0]) != QImode"
8933 [(parallel [(set (strict_low_part (match_dup 0))
8934 (ior:QI (match_dup 1)
8935 (match_dup 2)))
8936 (clobber (reg:CC FLAGS_REG))])]
8937 "operands[0] = gen_lowpart (QImode, operands[0]);
8938 operands[1] = gen_lowpart (QImode, operands[1]);
8939 operands[2] = gen_lowpart (QImode, operands[2]);")
8940 \f
8941 ;; Logical XOR instructions
8942
8943 ;; %%% This used to optimize known byte-wide and operations to memory.
8944 ;; If this is considered useful, it should be done with splitters.
8945
8946 (define_expand "xordi3"
8947 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8948 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8949 (match_operand:DI 2 "x86_64_general_operand" "")))
8950 (clobber (reg:CC FLAGS_REG))]
8951 "TARGET_64BIT"
8952 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8953
8954 (define_insn "*xordi_1_rex64"
8955 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8956 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8957 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8958 (clobber (reg:CC FLAGS_REG))]
8959 "TARGET_64BIT
8960 && ix86_binary_operator_ok (XOR, DImode, operands)"
8961 "@
8962 xor{q}\t{%2, %0|%0, %2}
8963 xor{q}\t{%2, %0|%0, %2}"
8964 [(set_attr "type" "alu")
8965 (set_attr "mode" "DI,DI")])
8966
8967 (define_insn "*xordi_2_rex64"
8968 [(set (reg FLAGS_REG)
8969 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8970 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8971 (const_int 0)))
8972 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8973 (xor:DI (match_dup 1) (match_dup 2)))]
8974 "TARGET_64BIT
8975 && ix86_match_ccmode (insn, CCNOmode)
8976 && ix86_binary_operator_ok (XOR, DImode, operands)"
8977 "@
8978 xor{q}\t{%2, %0|%0, %2}
8979 xor{q}\t{%2, %0|%0, %2}"
8980 [(set_attr "type" "alu")
8981 (set_attr "mode" "DI,DI")])
8982
8983 (define_insn "*xordi_3_rex64"
8984 [(set (reg FLAGS_REG)
8985 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8986 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8987 (const_int 0)))
8988 (clobber (match_scratch:DI 0 "=r"))]
8989 "TARGET_64BIT
8990 && ix86_match_ccmode (insn, CCNOmode)
8991 && ix86_binary_operator_ok (XOR, DImode, operands)"
8992 "xor{q}\t{%2, %0|%0, %2}"
8993 [(set_attr "type" "alu")
8994 (set_attr "mode" "DI")])
8995
8996 (define_expand "xorsi3"
8997 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8998 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8999 (match_operand:SI 2 "general_operand" "")))
9000 (clobber (reg:CC FLAGS_REG))]
9001 ""
9002 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9003
9004 (define_insn "*xorsi_1"
9005 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9006 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9007 (match_operand:SI 2 "general_operand" "ri,rm")))
9008 (clobber (reg:CC FLAGS_REG))]
9009 "ix86_binary_operator_ok (XOR, SImode, operands)"
9010 "xor{l}\t{%2, %0|%0, %2}"
9011 [(set_attr "type" "alu")
9012 (set_attr "mode" "SI")])
9013
9014 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9015 ;; Add speccase for immediates
9016 (define_insn "*xorsi_1_zext"
9017 [(set (match_operand:DI 0 "register_operand" "=r")
9018 (zero_extend:DI
9019 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9020 (match_operand:SI 2 "general_operand" "rim"))))
9021 (clobber (reg:CC FLAGS_REG))]
9022 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9023 "xor{l}\t{%2, %k0|%k0, %2}"
9024 [(set_attr "type" "alu")
9025 (set_attr "mode" "SI")])
9026
9027 (define_insn "*xorsi_1_zext_imm"
9028 [(set (match_operand:DI 0 "register_operand" "=r")
9029 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9030 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9031 (clobber (reg:CC FLAGS_REG))]
9032 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9033 "xor{l}\t{%2, %k0|%k0, %2}"
9034 [(set_attr "type" "alu")
9035 (set_attr "mode" "SI")])
9036
9037 (define_insn "*xorsi_2"
9038 [(set (reg FLAGS_REG)
9039 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9040 (match_operand:SI 2 "general_operand" "rim,ri"))
9041 (const_int 0)))
9042 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9043 (xor:SI (match_dup 1) (match_dup 2)))]
9044 "ix86_match_ccmode (insn, CCNOmode)
9045 && ix86_binary_operator_ok (XOR, SImode, operands)"
9046 "xor{l}\t{%2, %0|%0, %2}"
9047 [(set_attr "type" "alu")
9048 (set_attr "mode" "SI")])
9049
9050 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9051 ;; ??? Special case for immediate operand is missing - it is tricky.
9052 (define_insn "*xorsi_2_zext"
9053 [(set (reg FLAGS_REG)
9054 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9055 (match_operand:SI 2 "general_operand" "rim"))
9056 (const_int 0)))
9057 (set (match_operand:DI 0 "register_operand" "=r")
9058 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9059 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9060 && ix86_binary_operator_ok (XOR, SImode, operands)"
9061 "xor{l}\t{%2, %k0|%k0, %2}"
9062 [(set_attr "type" "alu")
9063 (set_attr "mode" "SI")])
9064
9065 (define_insn "*xorsi_2_zext_imm"
9066 [(set (reg FLAGS_REG)
9067 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9068 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9069 (const_int 0)))
9070 (set (match_operand:DI 0 "register_operand" "=r")
9071 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9072 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9073 && ix86_binary_operator_ok (XOR, SImode, operands)"
9074 "xor{l}\t{%2, %k0|%k0, %2}"
9075 [(set_attr "type" "alu")
9076 (set_attr "mode" "SI")])
9077
9078 (define_insn "*xorsi_3"
9079 [(set (reg FLAGS_REG)
9080 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9081 (match_operand:SI 2 "general_operand" "rim"))
9082 (const_int 0)))
9083 (clobber (match_scratch:SI 0 "=r"))]
9084 "ix86_match_ccmode (insn, CCNOmode)
9085 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9086 "xor{l}\t{%2, %0|%0, %2}"
9087 [(set_attr "type" "alu")
9088 (set_attr "mode" "SI")])
9089
9090 (define_expand "xorhi3"
9091 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9092 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9093 (match_operand:HI 2 "general_operand" "")))
9094 (clobber (reg:CC FLAGS_REG))]
9095 "TARGET_HIMODE_MATH"
9096 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9097
9098 (define_insn "*xorhi_1"
9099 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9100 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9101 (match_operand:HI 2 "general_operand" "rmi,ri")))
9102 (clobber (reg:CC FLAGS_REG))]
9103 "ix86_binary_operator_ok (XOR, HImode, operands)"
9104 "xor{w}\t{%2, %0|%0, %2}"
9105 [(set_attr "type" "alu")
9106 (set_attr "mode" "HI")])
9107
9108 (define_insn "*xorhi_2"
9109 [(set (reg FLAGS_REG)
9110 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9111 (match_operand:HI 2 "general_operand" "rim,ri"))
9112 (const_int 0)))
9113 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9114 (xor:HI (match_dup 1) (match_dup 2)))]
9115 "ix86_match_ccmode (insn, CCNOmode)
9116 && ix86_binary_operator_ok (XOR, HImode, operands)"
9117 "xor{w}\t{%2, %0|%0, %2}"
9118 [(set_attr "type" "alu")
9119 (set_attr "mode" "HI")])
9120
9121 (define_insn "*xorhi_3"
9122 [(set (reg FLAGS_REG)
9123 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9124 (match_operand:HI 2 "general_operand" "rim"))
9125 (const_int 0)))
9126 (clobber (match_scratch:HI 0 "=r"))]
9127 "ix86_match_ccmode (insn, CCNOmode)
9128 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9129 "xor{w}\t{%2, %0|%0, %2}"
9130 [(set_attr "type" "alu")
9131 (set_attr "mode" "HI")])
9132
9133 (define_expand "xorqi3"
9134 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9135 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9136 (match_operand:QI 2 "general_operand" "")))
9137 (clobber (reg:CC FLAGS_REG))]
9138 "TARGET_QIMODE_MATH"
9139 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9140
9141 ;; %%% Potential partial reg stall on alternative 2. What to do?
9142 (define_insn "*xorqi_1"
9143 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9144 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9145 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9146 (clobber (reg:CC FLAGS_REG))]
9147 "ix86_binary_operator_ok (XOR, QImode, operands)"
9148 "@
9149 xor{b}\t{%2, %0|%0, %2}
9150 xor{b}\t{%2, %0|%0, %2}
9151 xor{l}\t{%k2, %k0|%k0, %k2}"
9152 [(set_attr "type" "alu")
9153 (set_attr "mode" "QI,QI,SI")])
9154
9155 (define_insn "*xorqi_1_slp"
9156 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9157 (xor:QI (match_dup 0)
9158 (match_operand:QI 1 "general_operand" "qi,qmi")))
9159 (clobber (reg:CC FLAGS_REG))]
9160 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9161 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9162 "xor{b}\t{%1, %0|%0, %1}"
9163 [(set_attr "type" "alu1")
9164 (set_attr "mode" "QI")])
9165
9166 (define_insn "xorqi_ext_0"
9167 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9168 (const_int 8)
9169 (const_int 8))
9170 (xor:SI
9171 (zero_extract:SI
9172 (match_operand 1 "ext_register_operand" "0")
9173 (const_int 8)
9174 (const_int 8))
9175 (match_operand 2 "const_int_operand" "n")))
9176 (clobber (reg:CC FLAGS_REG))]
9177 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9178 "xor{b}\t{%2, %h0|%h0, %2}"
9179 [(set_attr "type" "alu")
9180 (set_attr "length_immediate" "1")
9181 (set_attr "mode" "QI")])
9182
9183 (define_insn "*xorqi_ext_1"
9184 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9185 (const_int 8)
9186 (const_int 8))
9187 (xor:SI
9188 (zero_extract:SI
9189 (match_operand 1 "ext_register_operand" "0")
9190 (const_int 8)
9191 (const_int 8))
9192 (zero_extend:SI
9193 (match_operand:QI 2 "general_operand" "Qm"))))
9194 (clobber (reg:CC FLAGS_REG))]
9195 "!TARGET_64BIT
9196 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9197 "xor{b}\t{%2, %h0|%h0, %2}"
9198 [(set_attr "type" "alu")
9199 (set_attr "length_immediate" "0")
9200 (set_attr "mode" "QI")])
9201
9202 (define_insn "*xorqi_ext_1_rex64"
9203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9204 (const_int 8)
9205 (const_int 8))
9206 (xor:SI
9207 (zero_extract:SI
9208 (match_operand 1 "ext_register_operand" "0")
9209 (const_int 8)
9210 (const_int 8))
9211 (zero_extend:SI
9212 (match_operand 2 "ext_register_operand" "Q"))))
9213 (clobber (reg:CC FLAGS_REG))]
9214 "TARGET_64BIT
9215 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9216 "xor{b}\t{%2, %h0|%h0, %2}"
9217 [(set_attr "type" "alu")
9218 (set_attr "length_immediate" "0")
9219 (set_attr "mode" "QI")])
9220
9221 (define_insn "*xorqi_ext_2"
9222 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9223 (const_int 8)
9224 (const_int 8))
9225 (xor:SI
9226 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9227 (const_int 8)
9228 (const_int 8))
9229 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9230 (const_int 8)
9231 (const_int 8))))
9232 (clobber (reg:CC FLAGS_REG))]
9233 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9234 "xor{b}\t{%h2, %h0|%h0, %h2}"
9235 [(set_attr "type" "alu")
9236 (set_attr "length_immediate" "0")
9237 (set_attr "mode" "QI")])
9238
9239 (define_insn "*xorqi_cc_1"
9240 [(set (reg FLAGS_REG)
9241 (compare
9242 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9243 (match_operand:QI 2 "general_operand" "qim,qi"))
9244 (const_int 0)))
9245 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9246 (xor:QI (match_dup 1) (match_dup 2)))]
9247 "ix86_match_ccmode (insn, CCNOmode)
9248 && ix86_binary_operator_ok (XOR, QImode, operands)"
9249 "xor{b}\t{%2, %0|%0, %2}"
9250 [(set_attr "type" "alu")
9251 (set_attr "mode" "QI")])
9252
9253 (define_insn "*xorqi_2_slp"
9254 [(set (reg FLAGS_REG)
9255 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9256 (match_operand:QI 1 "general_operand" "qim,qi"))
9257 (const_int 0)))
9258 (set (strict_low_part (match_dup 0))
9259 (xor:QI (match_dup 0) (match_dup 1)))]
9260 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9261 && ix86_match_ccmode (insn, CCNOmode)
9262 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9263 "xor{b}\t{%1, %0|%0, %1}"
9264 [(set_attr "type" "alu1")
9265 (set_attr "mode" "QI")])
9266
9267 (define_insn "*xorqi_cc_2"
9268 [(set (reg FLAGS_REG)
9269 (compare
9270 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9271 (match_operand:QI 2 "general_operand" "qim"))
9272 (const_int 0)))
9273 (clobber (match_scratch:QI 0 "=q"))]
9274 "ix86_match_ccmode (insn, CCNOmode)
9275 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9276 "xor{b}\t{%2, %0|%0, %2}"
9277 [(set_attr "type" "alu")
9278 (set_attr "mode" "QI")])
9279
9280 (define_insn "*xorqi_cc_ext_1"
9281 [(set (reg FLAGS_REG)
9282 (compare
9283 (xor:SI
9284 (zero_extract:SI
9285 (match_operand 1 "ext_register_operand" "0")
9286 (const_int 8)
9287 (const_int 8))
9288 (match_operand:QI 2 "general_operand" "qmn"))
9289 (const_int 0)))
9290 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9291 (const_int 8)
9292 (const_int 8))
9293 (xor:SI
9294 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9295 (match_dup 2)))]
9296 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9297 "xor{b}\t{%2, %h0|%h0, %2}"
9298 [(set_attr "type" "alu")
9299 (set_attr "mode" "QI")])
9300
9301 (define_insn "*xorqi_cc_ext_1_rex64"
9302 [(set (reg FLAGS_REG)
9303 (compare
9304 (xor:SI
9305 (zero_extract:SI
9306 (match_operand 1 "ext_register_operand" "0")
9307 (const_int 8)
9308 (const_int 8))
9309 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9310 (const_int 0)))
9311 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9312 (const_int 8)
9313 (const_int 8))
9314 (xor:SI
9315 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9316 (match_dup 2)))]
9317 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9318 "xor{b}\t{%2, %h0|%h0, %2}"
9319 [(set_attr "type" "alu")
9320 (set_attr "mode" "QI")])
9321
9322 (define_expand "xorqi_cc_ext_1"
9323 [(parallel [
9324 (set (reg:CCNO FLAGS_REG)
9325 (compare:CCNO
9326 (xor:SI
9327 (zero_extract:SI
9328 (match_operand 1 "ext_register_operand" "")
9329 (const_int 8)
9330 (const_int 8))
9331 (match_operand:QI 2 "general_operand" ""))
9332 (const_int 0)))
9333 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9334 (const_int 8)
9335 (const_int 8))
9336 (xor:SI
9337 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9338 (match_dup 2)))])]
9339 ""
9340 "")
9341
9342 (define_split
9343 [(set (match_operand 0 "register_operand" "")
9344 (xor (match_operand 1 "register_operand" "")
9345 (match_operand 2 "const_int_operand" "")))
9346 (clobber (reg:CC FLAGS_REG))]
9347 "reload_completed
9348 && QI_REG_P (operands[0])
9349 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9350 && !(INTVAL (operands[2]) & ~(255 << 8))
9351 && GET_MODE (operands[0]) != QImode"
9352 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9353 (xor:SI (zero_extract:SI (match_dup 1)
9354 (const_int 8) (const_int 8))
9355 (match_dup 2)))
9356 (clobber (reg:CC FLAGS_REG))])]
9357 "operands[0] = gen_lowpart (SImode, operands[0]);
9358 operands[1] = gen_lowpart (SImode, operands[1]);
9359 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9360
9361 ;; Since XOR can be encoded with sign extended immediate, this is only
9362 ;; profitable when 7th bit is set.
9363 (define_split
9364 [(set (match_operand 0 "register_operand" "")
9365 (xor (match_operand 1 "general_operand" "")
9366 (match_operand 2 "const_int_operand" "")))
9367 (clobber (reg:CC FLAGS_REG))]
9368 "reload_completed
9369 && ANY_QI_REG_P (operands[0])
9370 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9371 && !(INTVAL (operands[2]) & ~255)
9372 && (INTVAL (operands[2]) & 128)
9373 && GET_MODE (operands[0]) != QImode"
9374 [(parallel [(set (strict_low_part (match_dup 0))
9375 (xor:QI (match_dup 1)
9376 (match_dup 2)))
9377 (clobber (reg:CC FLAGS_REG))])]
9378 "operands[0] = gen_lowpart (QImode, operands[0]);
9379 operands[1] = gen_lowpart (QImode, operands[1]);
9380 operands[2] = gen_lowpart (QImode, operands[2]);")
9381 \f
9382 ;; Negation instructions
9383
9384 (define_expand "negdi2"
9385 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9386 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9387 (clobber (reg:CC FLAGS_REG))])]
9388 ""
9389 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9390
9391 (define_insn "*negdi2_1"
9392 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9393 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9394 (clobber (reg:CC FLAGS_REG))]
9395 "!TARGET_64BIT
9396 && ix86_unary_operator_ok (NEG, DImode, operands)"
9397 "#")
9398
9399 (define_split
9400 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9401 (neg:DI (match_operand:DI 1 "general_operand" "")))
9402 (clobber (reg:CC FLAGS_REG))]
9403 "!TARGET_64BIT && reload_completed"
9404 [(parallel
9405 [(set (reg:CCZ FLAGS_REG)
9406 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9407 (set (match_dup 0) (neg:SI (match_dup 2)))])
9408 (parallel
9409 [(set (match_dup 1)
9410 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9411 (match_dup 3))
9412 (const_int 0)))
9413 (clobber (reg:CC FLAGS_REG))])
9414 (parallel
9415 [(set (match_dup 1)
9416 (neg:SI (match_dup 1)))
9417 (clobber (reg:CC FLAGS_REG))])]
9418 "split_di (operands+1, 1, operands+2, operands+3);
9419 split_di (operands+0, 1, operands+0, operands+1);")
9420
9421 (define_insn "*negdi2_1_rex64"
9422 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9423 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9424 (clobber (reg:CC FLAGS_REG))]
9425 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9426 "neg{q}\t%0"
9427 [(set_attr "type" "negnot")
9428 (set_attr "mode" "DI")])
9429
9430 ;; The problem with neg is that it does not perform (compare x 0),
9431 ;; it really performs (compare 0 x), which leaves us with the zero
9432 ;; flag being the only useful item.
9433
9434 (define_insn "*negdi2_cmpz_rex64"
9435 [(set (reg:CCZ FLAGS_REG)
9436 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9437 (const_int 0)))
9438 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9439 (neg:DI (match_dup 1)))]
9440 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9441 "neg{q}\t%0"
9442 [(set_attr "type" "negnot")
9443 (set_attr "mode" "DI")])
9444
9445
9446 (define_expand "negsi2"
9447 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9448 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9449 (clobber (reg:CC FLAGS_REG))])]
9450 ""
9451 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9452
9453 (define_insn "*negsi2_1"
9454 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9455 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9456 (clobber (reg:CC FLAGS_REG))]
9457 "ix86_unary_operator_ok (NEG, SImode, operands)"
9458 "neg{l}\t%0"
9459 [(set_attr "type" "negnot")
9460 (set_attr "mode" "SI")])
9461
9462 ;; Combine is quite creative about this pattern.
9463 (define_insn "*negsi2_1_zext"
9464 [(set (match_operand:DI 0 "register_operand" "=r")
9465 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9466 (const_int 32)))
9467 (const_int 32)))
9468 (clobber (reg:CC FLAGS_REG))]
9469 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9470 "neg{l}\t%k0"
9471 [(set_attr "type" "negnot")
9472 (set_attr "mode" "SI")])
9473
9474 ;; The problem with neg is that it does not perform (compare x 0),
9475 ;; it really performs (compare 0 x), which leaves us with the zero
9476 ;; flag being the only useful item.
9477
9478 (define_insn "*negsi2_cmpz"
9479 [(set (reg:CCZ FLAGS_REG)
9480 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9481 (const_int 0)))
9482 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9483 (neg:SI (match_dup 1)))]
9484 "ix86_unary_operator_ok (NEG, SImode, operands)"
9485 "neg{l}\t%0"
9486 [(set_attr "type" "negnot")
9487 (set_attr "mode" "SI")])
9488
9489 (define_insn "*negsi2_cmpz_zext"
9490 [(set (reg:CCZ FLAGS_REG)
9491 (compare:CCZ (lshiftrt:DI
9492 (neg:DI (ashift:DI
9493 (match_operand:DI 1 "register_operand" "0")
9494 (const_int 32)))
9495 (const_int 32))
9496 (const_int 0)))
9497 (set (match_operand:DI 0 "register_operand" "=r")
9498 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9499 (const_int 32)))
9500 (const_int 32)))]
9501 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9502 "neg{l}\t%k0"
9503 [(set_attr "type" "negnot")
9504 (set_attr "mode" "SI")])
9505
9506 (define_expand "neghi2"
9507 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9508 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9509 (clobber (reg:CC FLAGS_REG))])]
9510 "TARGET_HIMODE_MATH"
9511 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9512
9513 (define_insn "*neghi2_1"
9514 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9515 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9516 (clobber (reg:CC FLAGS_REG))]
9517 "ix86_unary_operator_ok (NEG, HImode, operands)"
9518 "neg{w}\t%0"
9519 [(set_attr "type" "negnot")
9520 (set_attr "mode" "HI")])
9521
9522 (define_insn "*neghi2_cmpz"
9523 [(set (reg:CCZ FLAGS_REG)
9524 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9525 (const_int 0)))
9526 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9527 (neg:HI (match_dup 1)))]
9528 "ix86_unary_operator_ok (NEG, HImode, operands)"
9529 "neg{w}\t%0"
9530 [(set_attr "type" "negnot")
9531 (set_attr "mode" "HI")])
9532
9533 (define_expand "negqi2"
9534 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9535 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9536 (clobber (reg:CC FLAGS_REG))])]
9537 "TARGET_QIMODE_MATH"
9538 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9539
9540 (define_insn "*negqi2_1"
9541 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9542 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9543 (clobber (reg:CC FLAGS_REG))]
9544 "ix86_unary_operator_ok (NEG, QImode, operands)"
9545 "neg{b}\t%0"
9546 [(set_attr "type" "negnot")
9547 (set_attr "mode" "QI")])
9548
9549 (define_insn "*negqi2_cmpz"
9550 [(set (reg:CCZ FLAGS_REG)
9551 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9552 (const_int 0)))
9553 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9554 (neg:QI (match_dup 1)))]
9555 "ix86_unary_operator_ok (NEG, QImode, operands)"
9556 "neg{b}\t%0"
9557 [(set_attr "type" "negnot")
9558 (set_attr "mode" "QI")])
9559
9560 ;; Changing of sign for FP values is doable using integer unit too.
9561
9562 (define_expand "negsf2"
9563 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9564 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9565 "TARGET_80387 || TARGET_SSE_MATH"
9566 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9567
9568 (define_expand "abssf2"
9569 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9570 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9571 "TARGET_80387 || TARGET_SSE_MATH"
9572 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9573
9574 (define_insn "*absnegsf2_mixed"
9575 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9576 (match_operator:SF 3 "absneg_operator"
9577 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#fr,0 ,0")]))
9578 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9579 (clobber (reg:CC FLAGS_REG))]
9580 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9581 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9582 "#")
9583
9584 (define_insn "*absnegsf2_sse"
9585 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#r,x#r,rm#x")
9586 (match_operator:SF 3 "absneg_operator"
9587 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#r,0")]))
9588 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X"))
9589 (clobber (reg:CC FLAGS_REG))]
9590 "TARGET_SSE_MATH
9591 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9592 "#")
9593
9594 (define_insn "*absnegsf2_i387"
9595 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9596 (match_operator:SF 3 "absneg_operator"
9597 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9598 (use (match_operand 2 "" ""))
9599 (clobber (reg:CC FLAGS_REG))]
9600 "TARGET_80387 && !TARGET_SSE_MATH
9601 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9602 "#")
9603
9604 (define_expand "negdf2"
9605 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9606 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9607 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9608 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9609
9610 (define_expand "absdf2"
9611 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9612 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9613 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9614 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9615
9616 (define_insn "*absnegdf2_mixed"
9617 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9618 (match_operator:DF 3 "absneg_operator"
9619 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#fr,0 ,0")]))
9620 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9621 (clobber (reg:CC FLAGS_REG))]
9622 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9623 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9624 "#")
9625
9626 (define_insn "*absnegdf2_sse"
9627 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#r,Y#r,rm#Y")
9628 (match_operator:DF 3 "absneg_operator"
9629 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#r,0")]))
9630 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X"))
9631 (clobber (reg:CC FLAGS_REG))]
9632 "TARGET_SSE2 && TARGET_SSE_MATH
9633 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9634 "#")
9635
9636 (define_insn "*absnegdf2_i387"
9637 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9638 (match_operator:DF 3 "absneg_operator"
9639 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9640 (use (match_operand 2 "" ""))
9641 (clobber (reg:CC FLAGS_REG))]
9642 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9643 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9644 "#")
9645
9646 (define_expand "negxf2"
9647 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9648 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9649 "TARGET_80387"
9650 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9651
9652 (define_expand "absxf2"
9653 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9654 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9655 "TARGET_80387"
9656 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9657
9658 (define_insn "*absnegxf2_i387"
9659 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9660 (match_operator:XF 3 "absneg_operator"
9661 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9662 (use (match_operand 2 "" ""))
9663 (clobber (reg:CC FLAGS_REG))]
9664 "TARGET_80387
9665 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9666 "#")
9667
9668 ;; Splitters for fp abs and neg.
9669
9670 (define_split
9671 [(set (match_operand 0 "fp_register_operand" "")
9672 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9673 (use (match_operand 2 "" ""))
9674 (clobber (reg:CC FLAGS_REG))]
9675 "reload_completed"
9676 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9677
9678 (define_split
9679 [(set (match_operand 0 "register_operand" "")
9680 (match_operator 3 "absneg_operator"
9681 [(match_operand 1 "register_operand" "")]))
9682 (use (match_operand 2 "nonimmediate_operand" ""))
9683 (clobber (reg:CC FLAGS_REG))]
9684 "reload_completed && SSE_REG_P (operands[0])"
9685 [(set (match_dup 0) (match_dup 3))]
9686 {
9687 enum machine_mode mode = GET_MODE (operands[0]);
9688 enum machine_mode vmode = GET_MODE (operands[2]);
9689 rtx tmp;
9690
9691 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9692 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9693 if (operands_match_p (operands[0], operands[2]))
9694 {
9695 tmp = operands[1];
9696 operands[1] = operands[2];
9697 operands[2] = tmp;
9698 }
9699 if (GET_CODE (operands[3]) == ABS)
9700 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9701 else
9702 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9703 operands[3] = tmp;
9704 })
9705
9706 (define_split
9707 [(set (match_operand:SF 0 "register_operand" "")
9708 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9709 (use (match_operand:V4SF 2 "" ""))
9710 (clobber (reg:CC FLAGS_REG))]
9711 "reload_completed"
9712 [(parallel [(set (match_dup 0) (match_dup 1))
9713 (clobber (reg:CC FLAGS_REG))])]
9714 {
9715 rtx tmp;
9716 operands[0] = gen_lowpart (SImode, operands[0]);
9717 if (GET_CODE (operands[1]) == ABS)
9718 {
9719 tmp = gen_int_mode (0x7fffffff, SImode);
9720 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9721 }
9722 else
9723 {
9724 tmp = gen_int_mode (0x80000000, SImode);
9725 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9726 }
9727 operands[1] = tmp;
9728 })
9729
9730 (define_split
9731 [(set (match_operand:DF 0 "register_operand" "")
9732 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9733 (use (match_operand 2 "" ""))
9734 (clobber (reg:CC FLAGS_REG))]
9735 "reload_completed"
9736 [(parallel [(set (match_dup 0) (match_dup 1))
9737 (clobber (reg:CC FLAGS_REG))])]
9738 {
9739 rtx tmp;
9740 if (TARGET_64BIT)
9741 {
9742 tmp = gen_lowpart (DImode, operands[0]);
9743 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9744 operands[0] = tmp;
9745
9746 if (GET_CODE (operands[1]) == ABS)
9747 tmp = const0_rtx;
9748 else
9749 tmp = gen_rtx_NOT (DImode, tmp);
9750 }
9751 else
9752 {
9753 operands[0] = gen_highpart (SImode, operands[0]);
9754 if (GET_CODE (operands[1]) == ABS)
9755 {
9756 tmp = gen_int_mode (0x7fffffff, SImode);
9757 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9758 }
9759 else
9760 {
9761 tmp = gen_int_mode (0x80000000, SImode);
9762 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9763 }
9764 }
9765 operands[1] = tmp;
9766 })
9767
9768 (define_split
9769 [(set (match_operand:XF 0 "register_operand" "")
9770 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9771 (use (match_operand 2 "" ""))
9772 (clobber (reg:CC FLAGS_REG))]
9773 "reload_completed"
9774 [(parallel [(set (match_dup 0) (match_dup 1))
9775 (clobber (reg:CC FLAGS_REG))])]
9776 {
9777 rtx tmp;
9778 operands[0] = gen_rtx_REG (SImode,
9779 true_regnum (operands[0])
9780 + (TARGET_64BIT ? 1 : 2));
9781 if (GET_CODE (operands[1]) == ABS)
9782 {
9783 tmp = GEN_INT (0x7fff);
9784 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9785 }
9786 else
9787 {
9788 tmp = GEN_INT (0x8000);
9789 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9790 }
9791 operands[1] = tmp;
9792 })
9793
9794 (define_split
9795 [(set (match_operand 0 "memory_operand" "")
9796 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9797 (use (match_operand 2 "" ""))
9798 (clobber (reg:CC FLAGS_REG))]
9799 "reload_completed"
9800 [(parallel [(set (match_dup 0) (match_dup 1))
9801 (clobber (reg:CC FLAGS_REG))])]
9802 {
9803 enum machine_mode mode = GET_MODE (operands[0]);
9804 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9805 rtx tmp;
9806
9807 operands[0] = adjust_address (operands[0], QImode, size - 1);
9808 if (GET_CODE (operands[1]) == ABS)
9809 {
9810 tmp = gen_int_mode (0x7f, QImode);
9811 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9812 }
9813 else
9814 {
9815 tmp = gen_int_mode (0x80, QImode);
9816 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9817 }
9818 operands[1] = tmp;
9819 })
9820
9821 ;; Conditionalize these after reload. If they match before reload, we
9822 ;; lose the clobber and ability to use integer instructions.
9823
9824 (define_insn "*negsf2_1"
9825 [(set (match_operand:SF 0 "register_operand" "=f")
9826 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9827 "TARGET_80387 && reload_completed"
9828 "fchs"
9829 [(set_attr "type" "fsgn")
9830 (set_attr "mode" "SF")])
9831
9832 (define_insn "*negdf2_1"
9833 [(set (match_operand:DF 0 "register_operand" "=f")
9834 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9835 "TARGET_80387 && reload_completed"
9836 "fchs"
9837 [(set_attr "type" "fsgn")
9838 (set_attr "mode" "DF")])
9839
9840 (define_insn "*negxf2_1"
9841 [(set (match_operand:XF 0 "register_operand" "=f")
9842 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9843 "TARGET_80387 && reload_completed"
9844 "fchs"
9845 [(set_attr "type" "fsgn")
9846 (set_attr "mode" "XF")])
9847
9848 (define_insn "*abssf2_1"
9849 [(set (match_operand:SF 0 "register_operand" "=f")
9850 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9851 "TARGET_80387 && reload_completed"
9852 "fabs"
9853 [(set_attr "type" "fsgn")
9854 (set_attr "mode" "SF")])
9855
9856 (define_insn "*absdf2_1"
9857 [(set (match_operand:DF 0 "register_operand" "=f")
9858 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9859 "TARGET_80387 && reload_completed"
9860 "fabs"
9861 [(set_attr "type" "fsgn")
9862 (set_attr "mode" "DF")])
9863
9864 (define_insn "*absxf2_1"
9865 [(set (match_operand:XF 0 "register_operand" "=f")
9866 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9867 "TARGET_80387 && reload_completed"
9868 "fabs"
9869 [(set_attr "type" "fsgn")
9870 (set_attr "mode" "DF")])
9871
9872 (define_insn "*negextendsfdf2"
9873 [(set (match_operand:DF 0 "register_operand" "=f")
9874 (neg:DF (float_extend:DF
9875 (match_operand:SF 1 "register_operand" "0"))))]
9876 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9877 "fchs"
9878 [(set_attr "type" "fsgn")
9879 (set_attr "mode" "DF")])
9880
9881 (define_insn "*negextenddfxf2"
9882 [(set (match_operand:XF 0 "register_operand" "=f")
9883 (neg:XF (float_extend:XF
9884 (match_operand:DF 1 "register_operand" "0"))))]
9885 "TARGET_80387"
9886 "fchs"
9887 [(set_attr "type" "fsgn")
9888 (set_attr "mode" "XF")])
9889
9890 (define_insn "*negextendsfxf2"
9891 [(set (match_operand:XF 0 "register_operand" "=f")
9892 (neg:XF (float_extend:XF
9893 (match_operand:SF 1 "register_operand" "0"))))]
9894 "TARGET_80387"
9895 "fchs"
9896 [(set_attr "type" "fsgn")
9897 (set_attr "mode" "XF")])
9898
9899 (define_insn "*absextendsfdf2"
9900 [(set (match_operand:DF 0 "register_operand" "=f")
9901 (abs:DF (float_extend:DF
9902 (match_operand:SF 1 "register_operand" "0"))))]
9903 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9904 "fabs"
9905 [(set_attr "type" "fsgn")
9906 (set_attr "mode" "DF")])
9907
9908 (define_insn "*absextenddfxf2"
9909 [(set (match_operand:XF 0 "register_operand" "=f")
9910 (abs:XF (float_extend:XF
9911 (match_operand:DF 1 "register_operand" "0"))))]
9912 "TARGET_80387"
9913 "fabs"
9914 [(set_attr "type" "fsgn")
9915 (set_attr "mode" "XF")])
9916
9917 (define_insn "*absextendsfxf2"
9918 [(set (match_operand:XF 0 "register_operand" "=f")
9919 (abs:XF (float_extend:XF
9920 (match_operand:SF 1 "register_operand" "0"))))]
9921 "TARGET_80387"
9922 "fabs"
9923 [(set_attr "type" "fsgn")
9924 (set_attr "mode" "XF")])
9925 \f
9926 ;; One complement instructions
9927
9928 (define_expand "one_cmpldi2"
9929 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9930 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9931 "TARGET_64BIT"
9932 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9933
9934 (define_insn "*one_cmpldi2_1_rex64"
9935 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9936 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9937 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9938 "not{q}\t%0"
9939 [(set_attr "type" "negnot")
9940 (set_attr "mode" "DI")])
9941
9942 (define_insn "*one_cmpldi2_2_rex64"
9943 [(set (reg FLAGS_REG)
9944 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9945 (const_int 0)))
9946 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9947 (not:DI (match_dup 1)))]
9948 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9949 && ix86_unary_operator_ok (NOT, DImode, operands)"
9950 "#"
9951 [(set_attr "type" "alu1")
9952 (set_attr "mode" "DI")])
9953
9954 (define_split
9955 [(set (match_operand 0 "flags_reg_operand" "")
9956 (match_operator 2 "compare_operator"
9957 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9958 (const_int 0)]))
9959 (set (match_operand:DI 1 "nonimmediate_operand" "")
9960 (not:DI (match_dup 3)))]
9961 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9962 [(parallel [(set (match_dup 0)
9963 (match_op_dup 2
9964 [(xor:DI (match_dup 3) (const_int -1))
9965 (const_int 0)]))
9966 (set (match_dup 1)
9967 (xor:DI (match_dup 3) (const_int -1)))])]
9968 "")
9969
9970 (define_expand "one_cmplsi2"
9971 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9972 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9973 ""
9974 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9975
9976 (define_insn "*one_cmplsi2_1"
9977 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9978 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9979 "ix86_unary_operator_ok (NOT, SImode, operands)"
9980 "not{l}\t%0"
9981 [(set_attr "type" "negnot")
9982 (set_attr "mode" "SI")])
9983
9984 ;; ??? Currently never generated - xor is used instead.
9985 (define_insn "*one_cmplsi2_1_zext"
9986 [(set (match_operand:DI 0 "register_operand" "=r")
9987 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9988 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9989 "not{l}\t%k0"
9990 [(set_attr "type" "negnot")
9991 (set_attr "mode" "SI")])
9992
9993 (define_insn "*one_cmplsi2_2"
9994 [(set (reg FLAGS_REG)
9995 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9996 (const_int 0)))
9997 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9998 (not:SI (match_dup 1)))]
9999 "ix86_match_ccmode (insn, CCNOmode)
10000 && ix86_unary_operator_ok (NOT, SImode, operands)"
10001 "#"
10002 [(set_attr "type" "alu1")
10003 (set_attr "mode" "SI")])
10004
10005 (define_split
10006 [(set (match_operand 0 "flags_reg_operand" "")
10007 (match_operator 2 "compare_operator"
10008 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10009 (const_int 0)]))
10010 (set (match_operand:SI 1 "nonimmediate_operand" "")
10011 (not:SI (match_dup 3)))]
10012 "ix86_match_ccmode (insn, CCNOmode)"
10013 [(parallel [(set (match_dup 0)
10014 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10015 (const_int 0)]))
10016 (set (match_dup 1)
10017 (xor:SI (match_dup 3) (const_int -1)))])]
10018 "")
10019
10020 ;; ??? Currently never generated - xor is used instead.
10021 (define_insn "*one_cmplsi2_2_zext"
10022 [(set (reg FLAGS_REG)
10023 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10024 (const_int 0)))
10025 (set (match_operand:DI 0 "register_operand" "=r")
10026 (zero_extend:DI (not:SI (match_dup 1))))]
10027 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10028 && ix86_unary_operator_ok (NOT, SImode, operands)"
10029 "#"
10030 [(set_attr "type" "alu1")
10031 (set_attr "mode" "SI")])
10032
10033 (define_split
10034 [(set (match_operand 0 "flags_reg_operand" "")
10035 (match_operator 2 "compare_operator"
10036 [(not:SI (match_operand:SI 3 "register_operand" ""))
10037 (const_int 0)]))
10038 (set (match_operand:DI 1 "register_operand" "")
10039 (zero_extend:DI (not:SI (match_dup 3))))]
10040 "ix86_match_ccmode (insn, CCNOmode)"
10041 [(parallel [(set (match_dup 0)
10042 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10043 (const_int 0)]))
10044 (set (match_dup 1)
10045 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10046 "")
10047
10048 (define_expand "one_cmplhi2"
10049 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10050 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10051 "TARGET_HIMODE_MATH"
10052 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10053
10054 (define_insn "*one_cmplhi2_1"
10055 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10056 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10057 "ix86_unary_operator_ok (NOT, HImode, operands)"
10058 "not{w}\t%0"
10059 [(set_attr "type" "negnot")
10060 (set_attr "mode" "HI")])
10061
10062 (define_insn "*one_cmplhi2_2"
10063 [(set (reg FLAGS_REG)
10064 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10065 (const_int 0)))
10066 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10067 (not:HI (match_dup 1)))]
10068 "ix86_match_ccmode (insn, CCNOmode)
10069 && ix86_unary_operator_ok (NEG, HImode, operands)"
10070 "#"
10071 [(set_attr "type" "alu1")
10072 (set_attr "mode" "HI")])
10073
10074 (define_split
10075 [(set (match_operand 0 "flags_reg_operand" "")
10076 (match_operator 2 "compare_operator"
10077 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10078 (const_int 0)]))
10079 (set (match_operand:HI 1 "nonimmediate_operand" "")
10080 (not:HI (match_dup 3)))]
10081 "ix86_match_ccmode (insn, CCNOmode)"
10082 [(parallel [(set (match_dup 0)
10083 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10084 (const_int 0)]))
10085 (set (match_dup 1)
10086 (xor:HI (match_dup 3) (const_int -1)))])]
10087 "")
10088
10089 ;; %%% Potential partial reg stall on alternative 1. What to do?
10090 (define_expand "one_cmplqi2"
10091 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10092 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10093 "TARGET_QIMODE_MATH"
10094 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10095
10096 (define_insn "*one_cmplqi2_1"
10097 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10098 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10099 "ix86_unary_operator_ok (NOT, QImode, operands)"
10100 "@
10101 not{b}\t%0
10102 not{l}\t%k0"
10103 [(set_attr "type" "negnot")
10104 (set_attr "mode" "QI,SI")])
10105
10106 (define_insn "*one_cmplqi2_2"
10107 [(set (reg FLAGS_REG)
10108 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10109 (const_int 0)))
10110 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10111 (not:QI (match_dup 1)))]
10112 "ix86_match_ccmode (insn, CCNOmode)
10113 && ix86_unary_operator_ok (NOT, QImode, operands)"
10114 "#"
10115 [(set_attr "type" "alu1")
10116 (set_attr "mode" "QI")])
10117
10118 (define_split
10119 [(set (match_operand 0 "flags_reg_operand" "")
10120 (match_operator 2 "compare_operator"
10121 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10122 (const_int 0)]))
10123 (set (match_operand:QI 1 "nonimmediate_operand" "")
10124 (not:QI (match_dup 3)))]
10125 "ix86_match_ccmode (insn, CCNOmode)"
10126 [(parallel [(set (match_dup 0)
10127 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10128 (const_int 0)]))
10129 (set (match_dup 1)
10130 (xor:QI (match_dup 3) (const_int -1)))])]
10131 "")
10132 \f
10133 ;; Arithmetic shift instructions
10134
10135 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10136 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10137 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10138 ;; from the assembler input.
10139 ;;
10140 ;; This instruction shifts the target reg/mem as usual, but instead of
10141 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10142 ;; is a left shift double, bits are taken from the high order bits of
10143 ;; reg, else if the insn is a shift right double, bits are taken from the
10144 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10145 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10146 ;;
10147 ;; Since sh[lr]d does not change the `reg' operand, that is done
10148 ;; separately, making all shifts emit pairs of shift double and normal
10149 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10150 ;; support a 63 bit shift, each shift where the count is in a reg expands
10151 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10152 ;;
10153 ;; If the shift count is a constant, we need never emit more than one
10154 ;; shift pair, instead using moves and sign extension for counts greater
10155 ;; than 31.
10156
10157 (define_expand "ashldi3"
10158 [(set (match_operand:DI 0 "shiftdi_operand" "")
10159 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10160 (match_operand:QI 2 "nonmemory_operand" "")))]
10161 ""
10162 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10163
10164 (define_insn "*ashldi3_1_rex64"
10165 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10166 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10167 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10168 (clobber (reg:CC FLAGS_REG))]
10169 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10170 {
10171 switch (get_attr_type (insn))
10172 {
10173 case TYPE_ALU:
10174 if (operands[2] != const1_rtx)
10175 abort ();
10176 if (!rtx_equal_p (operands[0], operands[1]))
10177 abort ();
10178 return "add{q}\t{%0, %0|%0, %0}";
10179
10180 case TYPE_LEA:
10181 if (GET_CODE (operands[2]) != CONST_INT
10182 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10183 abort ();
10184 operands[1] = gen_rtx_MULT (DImode, operands[1],
10185 GEN_INT (1 << INTVAL (operands[2])));
10186 return "lea{q}\t{%a1, %0|%0, %a1}";
10187
10188 default:
10189 if (REG_P (operands[2]))
10190 return "sal{q}\t{%b2, %0|%0, %b2}";
10191 else if (operands[2] == const1_rtx
10192 && (TARGET_SHIFT1 || optimize_size))
10193 return "sal{q}\t%0";
10194 else
10195 return "sal{q}\t{%2, %0|%0, %2}";
10196 }
10197 }
10198 [(set (attr "type")
10199 (cond [(eq_attr "alternative" "1")
10200 (const_string "lea")
10201 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10202 (const_int 0))
10203 (match_operand 0 "register_operand" ""))
10204 (match_operand 2 "const1_operand" ""))
10205 (const_string "alu")
10206 ]
10207 (const_string "ishift")))
10208 (set_attr "mode" "DI")])
10209
10210 ;; Convert lea to the lea pattern to avoid flags dependency.
10211 (define_split
10212 [(set (match_operand:DI 0 "register_operand" "")
10213 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10214 (match_operand:QI 2 "immediate_operand" "")))
10215 (clobber (reg:CC FLAGS_REG))]
10216 "TARGET_64BIT && reload_completed
10217 && true_regnum (operands[0]) != true_regnum (operands[1])"
10218 [(set (match_dup 0)
10219 (mult:DI (match_dup 1)
10220 (match_dup 2)))]
10221 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10222
10223 ;; This pattern can't accept a variable shift count, since shifts by
10224 ;; zero don't affect the flags. We assume that shifts by constant
10225 ;; zero are optimized away.
10226 (define_insn "*ashldi3_cmp_rex64"
10227 [(set (reg FLAGS_REG)
10228 (compare
10229 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10230 (match_operand:QI 2 "immediate_operand" "e"))
10231 (const_int 0)))
10232 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10233 (ashift:DI (match_dup 1) (match_dup 2)))]
10234 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10235 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10236 {
10237 switch (get_attr_type (insn))
10238 {
10239 case TYPE_ALU:
10240 if (operands[2] != const1_rtx)
10241 abort ();
10242 return "add{q}\t{%0, %0|%0, %0}";
10243
10244 default:
10245 if (REG_P (operands[2]))
10246 return "sal{q}\t{%b2, %0|%0, %b2}";
10247 else if (operands[2] == const1_rtx
10248 && (TARGET_SHIFT1 || optimize_size))
10249 return "sal{q}\t%0";
10250 else
10251 return "sal{q}\t{%2, %0|%0, %2}";
10252 }
10253 }
10254 [(set (attr "type")
10255 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10256 (const_int 0))
10257 (match_operand 0 "register_operand" ""))
10258 (match_operand 2 "const1_operand" ""))
10259 (const_string "alu")
10260 ]
10261 (const_string "ishift")))
10262 (set_attr "mode" "DI")])
10263
10264 (define_insn "*ashldi3_1"
10265 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10266 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10267 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10268 (clobber (reg:CC FLAGS_REG))]
10269 "!TARGET_64BIT"
10270 "#"
10271 [(set_attr "type" "multi")])
10272
10273 ;; By default we don't ask for a scratch register, because when DImode
10274 ;; values are manipulated, registers are already at a premium. But if
10275 ;; we have one handy, we won't turn it away.
10276 (define_peephole2
10277 [(match_scratch:SI 3 "r")
10278 (parallel [(set (match_operand:DI 0 "register_operand" "")
10279 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10280 (match_operand:QI 2 "nonmemory_operand" "")))
10281 (clobber (reg:CC FLAGS_REG))])
10282 (match_dup 3)]
10283 "!TARGET_64BIT && TARGET_CMOVE"
10284 [(const_int 0)]
10285 "ix86_split_ashldi (operands, operands[3]); DONE;")
10286
10287 (define_split
10288 [(set (match_operand:DI 0 "register_operand" "")
10289 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10290 (match_operand:QI 2 "nonmemory_operand" "")))
10291 (clobber (reg:CC FLAGS_REG))]
10292 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10293 [(const_int 0)]
10294 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10295
10296 (define_insn "x86_shld_1"
10297 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10298 (ior:SI (ashift:SI (match_dup 0)
10299 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10300 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10301 (minus:QI (const_int 32) (match_dup 2)))))
10302 (clobber (reg:CC FLAGS_REG))]
10303 ""
10304 "@
10305 shld{l}\t{%2, %1, %0|%0, %1, %2}
10306 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10307 [(set_attr "type" "ishift")
10308 (set_attr "prefix_0f" "1")
10309 (set_attr "mode" "SI")
10310 (set_attr "pent_pair" "np")
10311 (set_attr "athlon_decode" "vector")])
10312
10313 (define_expand "x86_shift_adj_1"
10314 [(set (reg:CCZ FLAGS_REG)
10315 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10316 (const_int 32))
10317 (const_int 0)))
10318 (set (match_operand:SI 0 "register_operand" "")
10319 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10320 (match_operand:SI 1 "register_operand" "")
10321 (match_dup 0)))
10322 (set (match_dup 1)
10323 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10324 (match_operand:SI 3 "register_operand" "r")
10325 (match_dup 1)))]
10326 "TARGET_CMOVE"
10327 "")
10328
10329 (define_expand "x86_shift_adj_2"
10330 [(use (match_operand:SI 0 "register_operand" ""))
10331 (use (match_operand:SI 1 "register_operand" ""))
10332 (use (match_operand:QI 2 "register_operand" ""))]
10333 ""
10334 {
10335 rtx label = gen_label_rtx ();
10336 rtx tmp;
10337
10338 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10339
10340 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10341 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10342 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10343 gen_rtx_LABEL_REF (VOIDmode, label),
10344 pc_rtx);
10345 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10346 JUMP_LABEL (tmp) = label;
10347
10348 emit_move_insn (operands[0], operands[1]);
10349 ix86_expand_clear (operands[1]);
10350
10351 emit_label (label);
10352 LABEL_NUSES (label) = 1;
10353
10354 DONE;
10355 })
10356
10357 (define_expand "ashlsi3"
10358 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10359 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10360 (match_operand:QI 2 "nonmemory_operand" "")))
10361 (clobber (reg:CC FLAGS_REG))]
10362 ""
10363 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10364
10365 (define_insn "*ashlsi3_1"
10366 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10367 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10368 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10369 (clobber (reg:CC FLAGS_REG))]
10370 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10371 {
10372 switch (get_attr_type (insn))
10373 {
10374 case TYPE_ALU:
10375 if (operands[2] != const1_rtx)
10376 abort ();
10377 if (!rtx_equal_p (operands[0], operands[1]))
10378 abort ();
10379 return "add{l}\t{%0, %0|%0, %0}";
10380
10381 case TYPE_LEA:
10382 return "#";
10383
10384 default:
10385 if (REG_P (operands[2]))
10386 return "sal{l}\t{%b2, %0|%0, %b2}";
10387 else if (operands[2] == const1_rtx
10388 && (TARGET_SHIFT1 || optimize_size))
10389 return "sal{l}\t%0";
10390 else
10391 return "sal{l}\t{%2, %0|%0, %2}";
10392 }
10393 }
10394 [(set (attr "type")
10395 (cond [(eq_attr "alternative" "1")
10396 (const_string "lea")
10397 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10398 (const_int 0))
10399 (match_operand 0 "register_operand" ""))
10400 (match_operand 2 "const1_operand" ""))
10401 (const_string "alu")
10402 ]
10403 (const_string "ishift")))
10404 (set_attr "mode" "SI")])
10405
10406 ;; Convert lea to the lea pattern to avoid flags dependency.
10407 (define_split
10408 [(set (match_operand 0 "register_operand" "")
10409 (ashift (match_operand 1 "index_register_operand" "")
10410 (match_operand:QI 2 "const_int_operand" "")))
10411 (clobber (reg:CC FLAGS_REG))]
10412 "reload_completed
10413 && true_regnum (operands[0]) != true_regnum (operands[1])
10414 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10415 [(const_int 0)]
10416 {
10417 rtx pat;
10418 enum machine_mode mode = GET_MODE (operands[0]);
10419
10420 if (GET_MODE_SIZE (mode) < 4)
10421 operands[0] = gen_lowpart (SImode, operands[0]);
10422 if (mode != Pmode)
10423 operands[1] = gen_lowpart (Pmode, operands[1]);
10424 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10425
10426 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10427 if (Pmode != SImode)
10428 pat = gen_rtx_SUBREG (SImode, pat, 0);
10429 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10430 DONE;
10431 })
10432
10433 ;; Rare case of shifting RSP is handled by generating move and shift
10434 (define_split
10435 [(set (match_operand 0 "register_operand" "")
10436 (ashift (match_operand 1 "register_operand" "")
10437 (match_operand:QI 2 "const_int_operand" "")))
10438 (clobber (reg:CC FLAGS_REG))]
10439 "reload_completed
10440 && true_regnum (operands[0]) != true_regnum (operands[1])"
10441 [(const_int 0)]
10442 {
10443 rtx pat, clob;
10444 emit_move_insn (operands[1], operands[0]);
10445 pat = gen_rtx_SET (VOIDmode, operands[0],
10446 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10447 operands[0], operands[2]));
10448 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10449 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10450 DONE;
10451 })
10452
10453 (define_insn "*ashlsi3_1_zext"
10454 [(set (match_operand:DI 0 "register_operand" "=r,r")
10455 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10456 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10457 (clobber (reg:CC FLAGS_REG))]
10458 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10459 {
10460 switch (get_attr_type (insn))
10461 {
10462 case TYPE_ALU:
10463 if (operands[2] != const1_rtx)
10464 abort ();
10465 return "add{l}\t{%k0, %k0|%k0, %k0}";
10466
10467 case TYPE_LEA:
10468 return "#";
10469
10470 default:
10471 if (REG_P (operands[2]))
10472 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10473 else if (operands[2] == const1_rtx
10474 && (TARGET_SHIFT1 || optimize_size))
10475 return "sal{l}\t%k0";
10476 else
10477 return "sal{l}\t{%2, %k0|%k0, %2}";
10478 }
10479 }
10480 [(set (attr "type")
10481 (cond [(eq_attr "alternative" "1")
10482 (const_string "lea")
10483 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10484 (const_int 0))
10485 (match_operand 2 "const1_operand" ""))
10486 (const_string "alu")
10487 ]
10488 (const_string "ishift")))
10489 (set_attr "mode" "SI")])
10490
10491 ;; Convert lea to the lea pattern to avoid flags dependency.
10492 (define_split
10493 [(set (match_operand:DI 0 "register_operand" "")
10494 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10495 (match_operand:QI 2 "const_int_operand" ""))))
10496 (clobber (reg:CC FLAGS_REG))]
10497 "TARGET_64BIT && reload_completed
10498 && true_regnum (operands[0]) != true_regnum (operands[1])"
10499 [(set (match_dup 0) (zero_extend:DI
10500 (subreg:SI (mult:SI (match_dup 1)
10501 (match_dup 2)) 0)))]
10502 {
10503 operands[1] = gen_lowpart (Pmode, operands[1]);
10504 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10505 })
10506
10507 ;; This pattern can't accept a variable shift count, since shifts by
10508 ;; zero don't affect the flags. We assume that shifts by constant
10509 ;; zero are optimized away.
10510 (define_insn "*ashlsi3_cmp"
10511 [(set (reg FLAGS_REG)
10512 (compare
10513 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10514 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10515 (const_int 0)))
10516 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10517 (ashift:SI (match_dup 1) (match_dup 2)))]
10518 "ix86_match_ccmode (insn, CCGOCmode)
10519 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10520 {
10521 switch (get_attr_type (insn))
10522 {
10523 case TYPE_ALU:
10524 if (operands[2] != const1_rtx)
10525 abort ();
10526 return "add{l}\t{%0, %0|%0, %0}";
10527
10528 default:
10529 if (REG_P (operands[2]))
10530 return "sal{l}\t{%b2, %0|%0, %b2}";
10531 else if (operands[2] == const1_rtx
10532 && (TARGET_SHIFT1 || optimize_size))
10533 return "sal{l}\t%0";
10534 else
10535 return "sal{l}\t{%2, %0|%0, %2}";
10536 }
10537 }
10538 [(set (attr "type")
10539 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10540 (const_int 0))
10541 (match_operand 0 "register_operand" ""))
10542 (match_operand 2 "const1_operand" ""))
10543 (const_string "alu")
10544 ]
10545 (const_string "ishift")))
10546 (set_attr "mode" "SI")])
10547
10548 (define_insn "*ashlsi3_cmp_zext"
10549 [(set (reg FLAGS_REG)
10550 (compare
10551 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10552 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10553 (const_int 0)))
10554 (set (match_operand:DI 0 "register_operand" "=r")
10555 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10556 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10557 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10558 {
10559 switch (get_attr_type (insn))
10560 {
10561 case TYPE_ALU:
10562 if (operands[2] != const1_rtx)
10563 abort ();
10564 return "add{l}\t{%k0, %k0|%k0, %k0}";
10565
10566 default:
10567 if (REG_P (operands[2]))
10568 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10569 else if (operands[2] == const1_rtx
10570 && (TARGET_SHIFT1 || optimize_size))
10571 return "sal{l}\t%k0";
10572 else
10573 return "sal{l}\t{%2, %k0|%k0, %2}";
10574 }
10575 }
10576 [(set (attr "type")
10577 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10578 (const_int 0))
10579 (match_operand 2 "const1_operand" ""))
10580 (const_string "alu")
10581 ]
10582 (const_string "ishift")))
10583 (set_attr "mode" "SI")])
10584
10585 (define_expand "ashlhi3"
10586 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10587 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10588 (match_operand:QI 2 "nonmemory_operand" "")))
10589 (clobber (reg:CC FLAGS_REG))]
10590 "TARGET_HIMODE_MATH"
10591 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10592
10593 (define_insn "*ashlhi3_1_lea"
10594 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10595 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10596 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10597 (clobber (reg:CC FLAGS_REG))]
10598 "!TARGET_PARTIAL_REG_STALL
10599 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10600 {
10601 switch (get_attr_type (insn))
10602 {
10603 case TYPE_LEA:
10604 return "#";
10605 case TYPE_ALU:
10606 if (operands[2] != const1_rtx)
10607 abort ();
10608 return "add{w}\t{%0, %0|%0, %0}";
10609
10610 default:
10611 if (REG_P (operands[2]))
10612 return "sal{w}\t{%b2, %0|%0, %b2}";
10613 else if (operands[2] == const1_rtx
10614 && (TARGET_SHIFT1 || optimize_size))
10615 return "sal{w}\t%0";
10616 else
10617 return "sal{w}\t{%2, %0|%0, %2}";
10618 }
10619 }
10620 [(set (attr "type")
10621 (cond [(eq_attr "alternative" "1")
10622 (const_string "lea")
10623 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10624 (const_int 0))
10625 (match_operand 0 "register_operand" ""))
10626 (match_operand 2 "const1_operand" ""))
10627 (const_string "alu")
10628 ]
10629 (const_string "ishift")))
10630 (set_attr "mode" "HI,SI")])
10631
10632 (define_insn "*ashlhi3_1"
10633 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10634 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10635 (match_operand:QI 2 "nonmemory_operand" "cI")))
10636 (clobber (reg:CC FLAGS_REG))]
10637 "TARGET_PARTIAL_REG_STALL
10638 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10639 {
10640 switch (get_attr_type (insn))
10641 {
10642 case TYPE_ALU:
10643 if (operands[2] != const1_rtx)
10644 abort ();
10645 return "add{w}\t{%0, %0|%0, %0}";
10646
10647 default:
10648 if (REG_P (operands[2]))
10649 return "sal{w}\t{%b2, %0|%0, %b2}";
10650 else if (operands[2] == const1_rtx
10651 && (TARGET_SHIFT1 || optimize_size))
10652 return "sal{w}\t%0";
10653 else
10654 return "sal{w}\t{%2, %0|%0, %2}";
10655 }
10656 }
10657 [(set (attr "type")
10658 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10659 (const_int 0))
10660 (match_operand 0 "register_operand" ""))
10661 (match_operand 2 "const1_operand" ""))
10662 (const_string "alu")
10663 ]
10664 (const_string "ishift")))
10665 (set_attr "mode" "HI")])
10666
10667 ;; This pattern can't accept a variable shift count, since shifts by
10668 ;; zero don't affect the flags. We assume that shifts by constant
10669 ;; zero are optimized away.
10670 (define_insn "*ashlhi3_cmp"
10671 [(set (reg FLAGS_REG)
10672 (compare
10673 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10674 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10675 (const_int 0)))
10676 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10677 (ashift:HI (match_dup 1) (match_dup 2)))]
10678 "ix86_match_ccmode (insn, CCGOCmode)
10679 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10680 {
10681 switch (get_attr_type (insn))
10682 {
10683 case TYPE_ALU:
10684 if (operands[2] != const1_rtx)
10685 abort ();
10686 return "add{w}\t{%0, %0|%0, %0}";
10687
10688 default:
10689 if (REG_P (operands[2]))
10690 return "sal{w}\t{%b2, %0|%0, %b2}";
10691 else if (operands[2] == const1_rtx
10692 && (TARGET_SHIFT1 || optimize_size))
10693 return "sal{w}\t%0";
10694 else
10695 return "sal{w}\t{%2, %0|%0, %2}";
10696 }
10697 }
10698 [(set (attr "type")
10699 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10700 (const_int 0))
10701 (match_operand 0 "register_operand" ""))
10702 (match_operand 2 "const1_operand" ""))
10703 (const_string "alu")
10704 ]
10705 (const_string "ishift")))
10706 (set_attr "mode" "HI")])
10707
10708 (define_expand "ashlqi3"
10709 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10710 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10711 (match_operand:QI 2 "nonmemory_operand" "")))
10712 (clobber (reg:CC FLAGS_REG))]
10713 "TARGET_QIMODE_MATH"
10714 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10715
10716 ;; %%% Potential partial reg stall on alternative 2. What to do?
10717
10718 (define_insn "*ashlqi3_1_lea"
10719 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10720 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10721 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10722 (clobber (reg:CC FLAGS_REG))]
10723 "!TARGET_PARTIAL_REG_STALL
10724 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10725 {
10726 switch (get_attr_type (insn))
10727 {
10728 case TYPE_LEA:
10729 return "#";
10730 case TYPE_ALU:
10731 if (operands[2] != const1_rtx)
10732 abort ();
10733 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10734 return "add{l}\t{%k0, %k0|%k0, %k0}";
10735 else
10736 return "add{b}\t{%0, %0|%0, %0}";
10737
10738 default:
10739 if (REG_P (operands[2]))
10740 {
10741 if (get_attr_mode (insn) == MODE_SI)
10742 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10743 else
10744 return "sal{b}\t{%b2, %0|%0, %b2}";
10745 }
10746 else if (operands[2] == const1_rtx
10747 && (TARGET_SHIFT1 || optimize_size))
10748 {
10749 if (get_attr_mode (insn) == MODE_SI)
10750 return "sal{l}\t%0";
10751 else
10752 return "sal{b}\t%0";
10753 }
10754 else
10755 {
10756 if (get_attr_mode (insn) == MODE_SI)
10757 return "sal{l}\t{%2, %k0|%k0, %2}";
10758 else
10759 return "sal{b}\t{%2, %0|%0, %2}";
10760 }
10761 }
10762 }
10763 [(set (attr "type")
10764 (cond [(eq_attr "alternative" "2")
10765 (const_string "lea")
10766 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10767 (const_int 0))
10768 (match_operand 0 "register_operand" ""))
10769 (match_operand 2 "const1_operand" ""))
10770 (const_string "alu")
10771 ]
10772 (const_string "ishift")))
10773 (set_attr "mode" "QI,SI,SI")])
10774
10775 (define_insn "*ashlqi3_1"
10776 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10777 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10778 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10779 (clobber (reg:CC FLAGS_REG))]
10780 "TARGET_PARTIAL_REG_STALL
10781 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10782 {
10783 switch (get_attr_type (insn))
10784 {
10785 case TYPE_ALU:
10786 if (operands[2] != const1_rtx)
10787 abort ();
10788 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10789 return "add{l}\t{%k0, %k0|%k0, %k0}";
10790 else
10791 return "add{b}\t{%0, %0|%0, %0}";
10792
10793 default:
10794 if (REG_P (operands[2]))
10795 {
10796 if (get_attr_mode (insn) == MODE_SI)
10797 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10798 else
10799 return "sal{b}\t{%b2, %0|%0, %b2}";
10800 }
10801 else if (operands[2] == const1_rtx
10802 && (TARGET_SHIFT1 || optimize_size))
10803 {
10804 if (get_attr_mode (insn) == MODE_SI)
10805 return "sal{l}\t%0";
10806 else
10807 return "sal{b}\t%0";
10808 }
10809 else
10810 {
10811 if (get_attr_mode (insn) == MODE_SI)
10812 return "sal{l}\t{%2, %k0|%k0, %2}";
10813 else
10814 return "sal{b}\t{%2, %0|%0, %2}";
10815 }
10816 }
10817 }
10818 [(set (attr "type")
10819 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10820 (const_int 0))
10821 (match_operand 0 "register_operand" ""))
10822 (match_operand 2 "const1_operand" ""))
10823 (const_string "alu")
10824 ]
10825 (const_string "ishift")))
10826 (set_attr "mode" "QI,SI")])
10827
10828 ;; This pattern can't accept a variable shift count, since shifts by
10829 ;; zero don't affect the flags. We assume that shifts by constant
10830 ;; zero are optimized away.
10831 (define_insn "*ashlqi3_cmp"
10832 [(set (reg FLAGS_REG)
10833 (compare
10834 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10835 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10836 (const_int 0)))
10837 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10838 (ashift:QI (match_dup 1) (match_dup 2)))]
10839 "ix86_match_ccmode (insn, CCGOCmode)
10840 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10841 {
10842 switch (get_attr_type (insn))
10843 {
10844 case TYPE_ALU:
10845 if (operands[2] != const1_rtx)
10846 abort ();
10847 return "add{b}\t{%0, %0|%0, %0}";
10848
10849 default:
10850 if (REG_P (operands[2]))
10851 return "sal{b}\t{%b2, %0|%0, %b2}";
10852 else if (operands[2] == const1_rtx
10853 && (TARGET_SHIFT1 || optimize_size))
10854 return "sal{b}\t%0";
10855 else
10856 return "sal{b}\t{%2, %0|%0, %2}";
10857 }
10858 }
10859 [(set (attr "type")
10860 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10861 (const_int 0))
10862 (match_operand 0 "register_operand" ""))
10863 (match_operand 2 "const1_operand" ""))
10864 (const_string "alu")
10865 ]
10866 (const_string "ishift")))
10867 (set_attr "mode" "QI")])
10868
10869 ;; See comment above `ashldi3' about how this works.
10870
10871 (define_expand "ashrdi3"
10872 [(set (match_operand:DI 0 "shiftdi_operand" "")
10873 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10874 (match_operand:QI 2 "nonmemory_operand" "")))]
10875 ""
10876 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10877
10878 (define_insn "*ashrdi3_63_rex64"
10879 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10880 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10881 (match_operand:DI 2 "const_int_operand" "i,i")))
10882 (clobber (reg:CC FLAGS_REG))]
10883 "TARGET_64BIT && INTVAL (operands[2]) == 63
10884 && (TARGET_USE_CLTD || optimize_size)
10885 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10886 "@
10887 {cqto|cqo}
10888 sar{q}\t{%2, %0|%0, %2}"
10889 [(set_attr "type" "imovx,ishift")
10890 (set_attr "prefix_0f" "0,*")
10891 (set_attr "length_immediate" "0,*")
10892 (set_attr "modrm" "0,1")
10893 (set_attr "mode" "DI")])
10894
10895 (define_insn "*ashrdi3_1_one_bit_rex64"
10896 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10897 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10898 (match_operand:QI 2 "const1_operand" "")))
10899 (clobber (reg:CC FLAGS_REG))]
10900 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10901 && (TARGET_SHIFT1 || optimize_size)"
10902 "sar{q}\t%0"
10903 [(set_attr "type" "ishift")
10904 (set (attr "length")
10905 (if_then_else (match_operand:DI 0 "register_operand" "")
10906 (const_string "2")
10907 (const_string "*")))])
10908
10909 (define_insn "*ashrdi3_1_rex64"
10910 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10911 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10912 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10913 (clobber (reg:CC FLAGS_REG))]
10914 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10915 "@
10916 sar{q}\t{%2, %0|%0, %2}
10917 sar{q}\t{%b2, %0|%0, %b2}"
10918 [(set_attr "type" "ishift")
10919 (set_attr "mode" "DI")])
10920
10921 ;; This pattern can't accept a variable shift count, since shifts by
10922 ;; zero don't affect the flags. We assume that shifts by constant
10923 ;; zero are optimized away.
10924 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10925 [(set (reg FLAGS_REG)
10926 (compare
10927 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10928 (match_operand:QI 2 "const1_operand" ""))
10929 (const_int 0)))
10930 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10931 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10932 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10933 && (TARGET_SHIFT1 || optimize_size)
10934 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10935 "sar{q}\t%0"
10936 [(set_attr "type" "ishift")
10937 (set (attr "length")
10938 (if_then_else (match_operand:DI 0 "register_operand" "")
10939 (const_string "2")
10940 (const_string "*")))])
10941
10942 ;; This pattern can't accept a variable shift count, since shifts by
10943 ;; zero don't affect the flags. We assume that shifts by constant
10944 ;; zero are optimized away.
10945 (define_insn "*ashrdi3_cmp_rex64"
10946 [(set (reg FLAGS_REG)
10947 (compare
10948 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10949 (match_operand:QI 2 "const_int_operand" "n"))
10950 (const_int 0)))
10951 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10952 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10953 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10954 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10955 "sar{q}\t{%2, %0|%0, %2}"
10956 [(set_attr "type" "ishift")
10957 (set_attr "mode" "DI")])
10958
10959 (define_insn "*ashrdi3_1"
10960 [(set (match_operand:DI 0 "register_operand" "=r")
10961 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10962 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10963 (clobber (reg:CC FLAGS_REG))]
10964 "!TARGET_64BIT"
10965 "#"
10966 [(set_attr "type" "multi")])
10967
10968 ;; By default we don't ask for a scratch register, because when DImode
10969 ;; values are manipulated, registers are already at a premium. But if
10970 ;; we have one handy, we won't turn it away.
10971 (define_peephole2
10972 [(match_scratch:SI 3 "r")
10973 (parallel [(set (match_operand:DI 0 "register_operand" "")
10974 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10975 (match_operand:QI 2 "nonmemory_operand" "")))
10976 (clobber (reg:CC FLAGS_REG))])
10977 (match_dup 3)]
10978 "!TARGET_64BIT && TARGET_CMOVE"
10979 [(const_int 0)]
10980 "ix86_split_ashrdi (operands, operands[3]); DONE;")
10981
10982 (define_split
10983 [(set (match_operand:DI 0 "register_operand" "")
10984 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10985 (match_operand:QI 2 "nonmemory_operand" "")))
10986 (clobber (reg:CC FLAGS_REG))]
10987 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10988 [(const_int 0)]
10989 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10990
10991 (define_insn "x86_shrd_1"
10992 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10993 (ior:SI (ashiftrt:SI (match_dup 0)
10994 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10995 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10996 (minus:QI (const_int 32) (match_dup 2)))))
10997 (clobber (reg:CC FLAGS_REG))]
10998 ""
10999 "@
11000 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11001 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11002 [(set_attr "type" "ishift")
11003 (set_attr "prefix_0f" "1")
11004 (set_attr "pent_pair" "np")
11005 (set_attr "mode" "SI")])
11006
11007 (define_expand "x86_shift_adj_3"
11008 [(use (match_operand:SI 0 "register_operand" ""))
11009 (use (match_operand:SI 1 "register_operand" ""))
11010 (use (match_operand:QI 2 "register_operand" ""))]
11011 ""
11012 {
11013 rtx label = gen_label_rtx ();
11014 rtx tmp;
11015
11016 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11017
11018 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11019 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11020 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11021 gen_rtx_LABEL_REF (VOIDmode, label),
11022 pc_rtx);
11023 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11024 JUMP_LABEL (tmp) = label;
11025
11026 emit_move_insn (operands[0], operands[1]);
11027 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11028
11029 emit_label (label);
11030 LABEL_NUSES (label) = 1;
11031
11032 DONE;
11033 })
11034
11035 (define_insn "ashrsi3_31"
11036 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11037 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11038 (match_operand:SI 2 "const_int_operand" "i,i")))
11039 (clobber (reg:CC FLAGS_REG))]
11040 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11041 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11042 "@
11043 {cltd|cdq}
11044 sar{l}\t{%2, %0|%0, %2}"
11045 [(set_attr "type" "imovx,ishift")
11046 (set_attr "prefix_0f" "0,*")
11047 (set_attr "length_immediate" "0,*")
11048 (set_attr "modrm" "0,1")
11049 (set_attr "mode" "SI")])
11050
11051 (define_insn "*ashrsi3_31_zext"
11052 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11053 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11054 (match_operand:SI 2 "const_int_operand" "i,i"))))
11055 (clobber (reg:CC FLAGS_REG))]
11056 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11057 && INTVAL (operands[2]) == 31
11058 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11059 "@
11060 {cltd|cdq}
11061 sar{l}\t{%2, %k0|%k0, %2}"
11062 [(set_attr "type" "imovx,ishift")
11063 (set_attr "prefix_0f" "0,*")
11064 (set_attr "length_immediate" "0,*")
11065 (set_attr "modrm" "0,1")
11066 (set_attr "mode" "SI")])
11067
11068 (define_expand "ashrsi3"
11069 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11070 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11071 (match_operand:QI 2 "nonmemory_operand" "")))
11072 (clobber (reg:CC FLAGS_REG))]
11073 ""
11074 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11075
11076 (define_insn "*ashrsi3_1_one_bit"
11077 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11078 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11079 (match_operand:QI 2 "const1_operand" "")))
11080 (clobber (reg:CC FLAGS_REG))]
11081 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11082 && (TARGET_SHIFT1 || optimize_size)"
11083 "sar{l}\t%0"
11084 [(set_attr "type" "ishift")
11085 (set (attr "length")
11086 (if_then_else (match_operand:SI 0 "register_operand" "")
11087 (const_string "2")
11088 (const_string "*")))])
11089
11090 (define_insn "*ashrsi3_1_one_bit_zext"
11091 [(set (match_operand:DI 0 "register_operand" "=r")
11092 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11093 (match_operand:QI 2 "const1_operand" ""))))
11094 (clobber (reg:CC FLAGS_REG))]
11095 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11096 && (TARGET_SHIFT1 || optimize_size)"
11097 "sar{l}\t%k0"
11098 [(set_attr "type" "ishift")
11099 (set_attr "length" "2")])
11100
11101 (define_insn "*ashrsi3_1"
11102 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11103 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11104 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11105 (clobber (reg:CC FLAGS_REG))]
11106 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11107 "@
11108 sar{l}\t{%2, %0|%0, %2}
11109 sar{l}\t{%b2, %0|%0, %b2}"
11110 [(set_attr "type" "ishift")
11111 (set_attr "mode" "SI")])
11112
11113 (define_insn "*ashrsi3_1_zext"
11114 [(set (match_operand:DI 0 "register_operand" "=r,r")
11115 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11116 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11117 (clobber (reg:CC FLAGS_REG))]
11118 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11119 "@
11120 sar{l}\t{%2, %k0|%k0, %2}
11121 sar{l}\t{%b2, %k0|%k0, %b2}"
11122 [(set_attr "type" "ishift")
11123 (set_attr "mode" "SI")])
11124
11125 ;; This pattern can't accept a variable shift count, since shifts by
11126 ;; zero don't affect the flags. We assume that shifts by constant
11127 ;; zero are optimized away.
11128 (define_insn "*ashrsi3_one_bit_cmp"
11129 [(set (reg FLAGS_REG)
11130 (compare
11131 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11132 (match_operand:QI 2 "const1_operand" ""))
11133 (const_int 0)))
11134 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11135 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11136 "ix86_match_ccmode (insn, CCGOCmode)
11137 && (TARGET_SHIFT1 || optimize_size)
11138 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11139 "sar{l}\t%0"
11140 [(set_attr "type" "ishift")
11141 (set (attr "length")
11142 (if_then_else (match_operand:SI 0 "register_operand" "")
11143 (const_string "2")
11144 (const_string "*")))])
11145
11146 (define_insn "*ashrsi3_one_bit_cmp_zext"
11147 [(set (reg FLAGS_REG)
11148 (compare
11149 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11150 (match_operand:QI 2 "const1_operand" ""))
11151 (const_int 0)))
11152 (set (match_operand:DI 0 "register_operand" "=r")
11153 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11154 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11155 && (TARGET_SHIFT1 || optimize_size)
11156 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11157 "sar{l}\t%k0"
11158 [(set_attr "type" "ishift")
11159 (set_attr "length" "2")])
11160
11161 ;; This pattern can't accept a variable shift count, since shifts by
11162 ;; zero don't affect the flags. We assume that shifts by constant
11163 ;; zero are optimized away.
11164 (define_insn "*ashrsi3_cmp"
11165 [(set (reg FLAGS_REG)
11166 (compare
11167 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11168 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11169 (const_int 0)))
11170 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11171 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11172 "ix86_match_ccmode (insn, CCGOCmode)
11173 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11174 "sar{l}\t{%2, %0|%0, %2}"
11175 [(set_attr "type" "ishift")
11176 (set_attr "mode" "SI")])
11177
11178 (define_insn "*ashrsi3_cmp_zext"
11179 [(set (reg FLAGS_REG)
11180 (compare
11181 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11182 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11183 (const_int 0)))
11184 (set (match_operand:DI 0 "register_operand" "=r")
11185 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11186 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11187 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11188 "sar{l}\t{%2, %k0|%k0, %2}"
11189 [(set_attr "type" "ishift")
11190 (set_attr "mode" "SI")])
11191
11192 (define_expand "ashrhi3"
11193 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11194 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11195 (match_operand:QI 2 "nonmemory_operand" "")))
11196 (clobber (reg:CC FLAGS_REG))]
11197 "TARGET_HIMODE_MATH"
11198 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11199
11200 (define_insn "*ashrhi3_1_one_bit"
11201 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11202 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11203 (match_operand:QI 2 "const1_operand" "")))
11204 (clobber (reg:CC FLAGS_REG))]
11205 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11206 && (TARGET_SHIFT1 || optimize_size)"
11207 "sar{w}\t%0"
11208 [(set_attr "type" "ishift")
11209 (set (attr "length")
11210 (if_then_else (match_operand 0 "register_operand" "")
11211 (const_string "2")
11212 (const_string "*")))])
11213
11214 (define_insn "*ashrhi3_1"
11215 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11216 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11217 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11218 (clobber (reg:CC FLAGS_REG))]
11219 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11220 "@
11221 sar{w}\t{%2, %0|%0, %2}
11222 sar{w}\t{%b2, %0|%0, %b2}"
11223 [(set_attr "type" "ishift")
11224 (set_attr "mode" "HI")])
11225
11226 ;; This pattern can't accept a variable shift count, since shifts by
11227 ;; zero don't affect the flags. We assume that shifts by constant
11228 ;; zero are optimized away.
11229 (define_insn "*ashrhi3_one_bit_cmp"
11230 [(set (reg FLAGS_REG)
11231 (compare
11232 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11233 (match_operand:QI 2 "const1_operand" ""))
11234 (const_int 0)))
11235 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11236 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11237 "ix86_match_ccmode (insn, CCGOCmode)
11238 && (TARGET_SHIFT1 || optimize_size)
11239 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11240 "sar{w}\t%0"
11241 [(set_attr "type" "ishift")
11242 (set (attr "length")
11243 (if_then_else (match_operand 0 "register_operand" "")
11244 (const_string "2")
11245 (const_string "*")))])
11246
11247 ;; This pattern can't accept a variable shift count, since shifts by
11248 ;; zero don't affect the flags. We assume that shifts by constant
11249 ;; zero are optimized away.
11250 (define_insn "*ashrhi3_cmp"
11251 [(set (reg FLAGS_REG)
11252 (compare
11253 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11254 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11255 (const_int 0)))
11256 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11257 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11258 "ix86_match_ccmode (insn, CCGOCmode)
11259 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11260 "sar{w}\t{%2, %0|%0, %2}"
11261 [(set_attr "type" "ishift")
11262 (set_attr "mode" "HI")])
11263
11264 (define_expand "ashrqi3"
11265 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11266 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11267 (match_operand:QI 2 "nonmemory_operand" "")))
11268 (clobber (reg:CC FLAGS_REG))]
11269 "TARGET_QIMODE_MATH"
11270 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11271
11272 (define_insn "*ashrqi3_1_one_bit"
11273 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11274 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11275 (match_operand:QI 2 "const1_operand" "")))
11276 (clobber (reg:CC FLAGS_REG))]
11277 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11278 && (TARGET_SHIFT1 || optimize_size)"
11279 "sar{b}\t%0"
11280 [(set_attr "type" "ishift")
11281 (set (attr "length")
11282 (if_then_else (match_operand 0 "register_operand" "")
11283 (const_string "2")
11284 (const_string "*")))])
11285
11286 (define_insn "*ashrqi3_1_one_bit_slp"
11287 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11288 (ashiftrt:QI (match_dup 0)
11289 (match_operand:QI 1 "const1_operand" "")))
11290 (clobber (reg:CC FLAGS_REG))]
11291 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11292 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11293 && (TARGET_SHIFT1 || optimize_size)"
11294 "sar{b}\t%0"
11295 [(set_attr "type" "ishift1")
11296 (set (attr "length")
11297 (if_then_else (match_operand 0 "register_operand" "")
11298 (const_string "2")
11299 (const_string "*")))])
11300
11301 (define_insn "*ashrqi3_1"
11302 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11303 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11304 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11305 (clobber (reg:CC FLAGS_REG))]
11306 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11307 "@
11308 sar{b}\t{%2, %0|%0, %2}
11309 sar{b}\t{%b2, %0|%0, %b2}"
11310 [(set_attr "type" "ishift")
11311 (set_attr "mode" "QI")])
11312
11313 (define_insn "*ashrqi3_1_slp"
11314 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11315 (ashiftrt:QI (match_dup 0)
11316 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11317 (clobber (reg:CC FLAGS_REG))]
11318 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11319 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11320 "@
11321 sar{b}\t{%1, %0|%0, %1}
11322 sar{b}\t{%b1, %0|%0, %b1}"
11323 [(set_attr "type" "ishift1")
11324 (set_attr "mode" "QI")])
11325
11326 ;; This pattern can't accept a variable shift count, since shifts by
11327 ;; zero don't affect the flags. We assume that shifts by constant
11328 ;; zero are optimized away.
11329 (define_insn "*ashrqi3_one_bit_cmp"
11330 [(set (reg FLAGS_REG)
11331 (compare
11332 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11333 (match_operand:QI 2 "const1_operand" "I"))
11334 (const_int 0)))
11335 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11336 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11337 "ix86_match_ccmode (insn, CCGOCmode)
11338 && (TARGET_SHIFT1 || optimize_size)
11339 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11340 "sar{b}\t%0"
11341 [(set_attr "type" "ishift")
11342 (set (attr "length")
11343 (if_then_else (match_operand 0 "register_operand" "")
11344 (const_string "2")
11345 (const_string "*")))])
11346
11347 ;; This pattern can't accept a variable shift count, since shifts by
11348 ;; zero don't affect the flags. We assume that shifts by constant
11349 ;; zero are optimized away.
11350 (define_insn "*ashrqi3_cmp"
11351 [(set (reg FLAGS_REG)
11352 (compare
11353 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11354 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11355 (const_int 0)))
11356 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11357 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11358 "ix86_match_ccmode (insn, CCGOCmode)
11359 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11360 "sar{b}\t{%2, %0|%0, %2}"
11361 [(set_attr "type" "ishift")
11362 (set_attr "mode" "QI")])
11363 \f
11364 ;; Logical shift instructions
11365
11366 ;; See comment above `ashldi3' about how this works.
11367
11368 (define_expand "lshrdi3"
11369 [(set (match_operand:DI 0 "shiftdi_operand" "")
11370 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11371 (match_operand:QI 2 "nonmemory_operand" "")))]
11372 ""
11373 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11374
11375 (define_insn "*lshrdi3_1_one_bit_rex64"
11376 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11377 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11378 (match_operand:QI 2 "const1_operand" "")))
11379 (clobber (reg:CC FLAGS_REG))]
11380 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11381 && (TARGET_SHIFT1 || optimize_size)"
11382 "shr{q}\t%0"
11383 [(set_attr "type" "ishift")
11384 (set (attr "length")
11385 (if_then_else (match_operand:DI 0 "register_operand" "")
11386 (const_string "2")
11387 (const_string "*")))])
11388
11389 (define_insn "*lshrdi3_1_rex64"
11390 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11391 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11392 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11393 (clobber (reg:CC FLAGS_REG))]
11394 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11395 "@
11396 shr{q}\t{%2, %0|%0, %2}
11397 shr{q}\t{%b2, %0|%0, %b2}"
11398 [(set_attr "type" "ishift")
11399 (set_attr "mode" "DI")])
11400
11401 ;; This pattern can't accept a variable shift count, since shifts by
11402 ;; zero don't affect the flags. We assume that shifts by constant
11403 ;; zero are optimized away.
11404 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11405 [(set (reg FLAGS_REG)
11406 (compare
11407 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11408 (match_operand:QI 2 "const1_operand" ""))
11409 (const_int 0)))
11410 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11411 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11412 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11413 && (TARGET_SHIFT1 || optimize_size)
11414 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11415 "shr{q}\t%0"
11416 [(set_attr "type" "ishift")
11417 (set (attr "length")
11418 (if_then_else (match_operand:DI 0 "register_operand" "")
11419 (const_string "2")
11420 (const_string "*")))])
11421
11422 ;; This pattern can't accept a variable shift count, since shifts by
11423 ;; zero don't affect the flags. We assume that shifts by constant
11424 ;; zero are optimized away.
11425 (define_insn "*lshrdi3_cmp_rex64"
11426 [(set (reg FLAGS_REG)
11427 (compare
11428 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11429 (match_operand:QI 2 "const_int_operand" "e"))
11430 (const_int 0)))
11431 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11432 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11433 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11434 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11435 "shr{q}\t{%2, %0|%0, %2}"
11436 [(set_attr "type" "ishift")
11437 (set_attr "mode" "DI")])
11438
11439 (define_insn "*lshrdi3_1"
11440 [(set (match_operand:DI 0 "register_operand" "=r")
11441 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11442 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11443 (clobber (reg:CC FLAGS_REG))]
11444 "!TARGET_64BIT"
11445 "#"
11446 [(set_attr "type" "multi")])
11447
11448 ;; By default we don't ask for a scratch register, because when DImode
11449 ;; values are manipulated, registers are already at a premium. But if
11450 ;; we have one handy, we won't turn it away.
11451 (define_peephole2
11452 [(match_scratch:SI 3 "r")
11453 (parallel [(set (match_operand:DI 0 "register_operand" "")
11454 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11455 (match_operand:QI 2 "nonmemory_operand" "")))
11456 (clobber (reg:CC FLAGS_REG))])
11457 (match_dup 3)]
11458 "!TARGET_64BIT && TARGET_CMOVE"
11459 [(const_int 0)]
11460 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11461
11462 (define_split
11463 [(set (match_operand:DI 0 "register_operand" "")
11464 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11465 (match_operand:QI 2 "nonmemory_operand" "")))
11466 (clobber (reg:CC FLAGS_REG))]
11467 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11468 [(const_int 0)]
11469 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11470
11471 (define_expand "lshrsi3"
11472 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11473 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11474 (match_operand:QI 2 "nonmemory_operand" "")))
11475 (clobber (reg:CC FLAGS_REG))]
11476 ""
11477 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11478
11479 (define_insn "*lshrsi3_1_one_bit"
11480 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11481 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11482 (match_operand:QI 2 "const1_operand" "")))
11483 (clobber (reg:CC FLAGS_REG))]
11484 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11485 && (TARGET_SHIFT1 || optimize_size)"
11486 "shr{l}\t%0"
11487 [(set_attr "type" "ishift")
11488 (set (attr "length")
11489 (if_then_else (match_operand:SI 0 "register_operand" "")
11490 (const_string "2")
11491 (const_string "*")))])
11492
11493 (define_insn "*lshrsi3_1_one_bit_zext"
11494 [(set (match_operand:DI 0 "register_operand" "=r")
11495 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11496 (match_operand:QI 2 "const1_operand" "")))
11497 (clobber (reg:CC FLAGS_REG))]
11498 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11499 && (TARGET_SHIFT1 || optimize_size)"
11500 "shr{l}\t%k0"
11501 [(set_attr "type" "ishift")
11502 (set_attr "length" "2")])
11503
11504 (define_insn "*lshrsi3_1"
11505 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11506 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11507 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11508 (clobber (reg:CC FLAGS_REG))]
11509 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11510 "@
11511 shr{l}\t{%2, %0|%0, %2}
11512 shr{l}\t{%b2, %0|%0, %b2}"
11513 [(set_attr "type" "ishift")
11514 (set_attr "mode" "SI")])
11515
11516 (define_insn "*lshrsi3_1_zext"
11517 [(set (match_operand:DI 0 "register_operand" "=r,r")
11518 (zero_extend:DI
11519 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11520 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11521 (clobber (reg:CC FLAGS_REG))]
11522 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11523 "@
11524 shr{l}\t{%2, %k0|%k0, %2}
11525 shr{l}\t{%b2, %k0|%k0, %b2}"
11526 [(set_attr "type" "ishift")
11527 (set_attr "mode" "SI")])
11528
11529 ;; This pattern can't accept a variable shift count, since shifts by
11530 ;; zero don't affect the flags. We assume that shifts by constant
11531 ;; zero are optimized away.
11532 (define_insn "*lshrsi3_one_bit_cmp"
11533 [(set (reg FLAGS_REG)
11534 (compare
11535 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11536 (match_operand:QI 2 "const1_operand" ""))
11537 (const_int 0)))
11538 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11539 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11540 "ix86_match_ccmode (insn, CCGOCmode)
11541 && (TARGET_SHIFT1 || optimize_size)
11542 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11543 "shr{l}\t%0"
11544 [(set_attr "type" "ishift")
11545 (set (attr "length")
11546 (if_then_else (match_operand:SI 0 "register_operand" "")
11547 (const_string "2")
11548 (const_string "*")))])
11549
11550 (define_insn "*lshrsi3_cmp_one_bit_zext"
11551 [(set (reg FLAGS_REG)
11552 (compare
11553 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11554 (match_operand:QI 2 "const1_operand" ""))
11555 (const_int 0)))
11556 (set (match_operand:DI 0 "register_operand" "=r")
11557 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11558 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11559 && (TARGET_SHIFT1 || optimize_size)
11560 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11561 "shr{l}\t%k0"
11562 [(set_attr "type" "ishift")
11563 (set_attr "length" "2")])
11564
11565 ;; This pattern can't accept a variable shift count, since shifts by
11566 ;; zero don't affect the flags. We assume that shifts by constant
11567 ;; zero are optimized away.
11568 (define_insn "*lshrsi3_cmp"
11569 [(set (reg FLAGS_REG)
11570 (compare
11571 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11572 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11573 (const_int 0)))
11574 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11575 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11576 "ix86_match_ccmode (insn, CCGOCmode)
11577 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11578 "shr{l}\t{%2, %0|%0, %2}"
11579 [(set_attr "type" "ishift")
11580 (set_attr "mode" "SI")])
11581
11582 (define_insn "*lshrsi3_cmp_zext"
11583 [(set (reg FLAGS_REG)
11584 (compare
11585 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11586 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11587 (const_int 0)))
11588 (set (match_operand:DI 0 "register_operand" "=r")
11589 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11590 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11591 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11592 "shr{l}\t{%2, %k0|%k0, %2}"
11593 [(set_attr "type" "ishift")
11594 (set_attr "mode" "SI")])
11595
11596 (define_expand "lshrhi3"
11597 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11598 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11599 (match_operand:QI 2 "nonmemory_operand" "")))
11600 (clobber (reg:CC FLAGS_REG))]
11601 "TARGET_HIMODE_MATH"
11602 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11603
11604 (define_insn "*lshrhi3_1_one_bit"
11605 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11606 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11607 (match_operand:QI 2 "const1_operand" "")))
11608 (clobber (reg:CC FLAGS_REG))]
11609 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11610 && (TARGET_SHIFT1 || optimize_size)"
11611 "shr{w}\t%0"
11612 [(set_attr "type" "ishift")
11613 (set (attr "length")
11614 (if_then_else (match_operand 0 "register_operand" "")
11615 (const_string "2")
11616 (const_string "*")))])
11617
11618 (define_insn "*lshrhi3_1"
11619 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11620 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11621 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11622 (clobber (reg:CC FLAGS_REG))]
11623 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11624 "@
11625 shr{w}\t{%2, %0|%0, %2}
11626 shr{w}\t{%b2, %0|%0, %b2}"
11627 [(set_attr "type" "ishift")
11628 (set_attr "mode" "HI")])
11629
11630 ;; This pattern can't accept a variable shift count, since shifts by
11631 ;; zero don't affect the flags. We assume that shifts by constant
11632 ;; zero are optimized away.
11633 (define_insn "*lshrhi3_one_bit_cmp"
11634 [(set (reg FLAGS_REG)
11635 (compare
11636 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11637 (match_operand:QI 2 "const1_operand" ""))
11638 (const_int 0)))
11639 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11640 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11641 "ix86_match_ccmode (insn, CCGOCmode)
11642 && (TARGET_SHIFT1 || optimize_size)
11643 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11644 "shr{w}\t%0"
11645 [(set_attr "type" "ishift")
11646 (set (attr "length")
11647 (if_then_else (match_operand:SI 0 "register_operand" "")
11648 (const_string "2")
11649 (const_string "*")))])
11650
11651 ;; This pattern can't accept a variable shift count, since shifts by
11652 ;; zero don't affect the flags. We assume that shifts by constant
11653 ;; zero are optimized away.
11654 (define_insn "*lshrhi3_cmp"
11655 [(set (reg FLAGS_REG)
11656 (compare
11657 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11658 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11659 (const_int 0)))
11660 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11661 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11662 "ix86_match_ccmode (insn, CCGOCmode)
11663 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11664 "shr{w}\t{%2, %0|%0, %2}"
11665 [(set_attr "type" "ishift")
11666 (set_attr "mode" "HI")])
11667
11668 (define_expand "lshrqi3"
11669 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11670 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11671 (match_operand:QI 2 "nonmemory_operand" "")))
11672 (clobber (reg:CC FLAGS_REG))]
11673 "TARGET_QIMODE_MATH"
11674 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11675
11676 (define_insn "*lshrqi3_1_one_bit"
11677 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11678 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11679 (match_operand:QI 2 "const1_operand" "")))
11680 (clobber (reg:CC FLAGS_REG))]
11681 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11682 && (TARGET_SHIFT1 || optimize_size)"
11683 "shr{b}\t%0"
11684 [(set_attr "type" "ishift")
11685 (set (attr "length")
11686 (if_then_else (match_operand 0 "register_operand" "")
11687 (const_string "2")
11688 (const_string "*")))])
11689
11690 (define_insn "*lshrqi3_1_one_bit_slp"
11691 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11692 (lshiftrt:QI (match_dup 0)
11693 (match_operand:QI 1 "const1_operand" "")))
11694 (clobber (reg:CC FLAGS_REG))]
11695 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11696 && (TARGET_SHIFT1 || optimize_size)"
11697 "shr{b}\t%0"
11698 [(set_attr "type" "ishift1")
11699 (set (attr "length")
11700 (if_then_else (match_operand 0 "register_operand" "")
11701 (const_string "2")
11702 (const_string "*")))])
11703
11704 (define_insn "*lshrqi3_1"
11705 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11706 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11707 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11708 (clobber (reg:CC FLAGS_REG))]
11709 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11710 "@
11711 shr{b}\t{%2, %0|%0, %2}
11712 shr{b}\t{%b2, %0|%0, %b2}"
11713 [(set_attr "type" "ishift")
11714 (set_attr "mode" "QI")])
11715
11716 (define_insn "*lshrqi3_1_slp"
11717 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11718 (lshiftrt:QI (match_dup 0)
11719 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11720 (clobber (reg:CC FLAGS_REG))]
11721 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11722 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11723 "@
11724 shr{b}\t{%1, %0|%0, %1}
11725 shr{b}\t{%b1, %0|%0, %b1}"
11726 [(set_attr "type" "ishift1")
11727 (set_attr "mode" "QI")])
11728
11729 ;; This pattern can't accept a variable shift count, since shifts by
11730 ;; zero don't affect the flags. We assume that shifts by constant
11731 ;; zero are optimized away.
11732 (define_insn "*lshrqi2_one_bit_cmp"
11733 [(set (reg FLAGS_REG)
11734 (compare
11735 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11736 (match_operand:QI 2 "const1_operand" ""))
11737 (const_int 0)))
11738 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11739 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11740 "ix86_match_ccmode (insn, CCGOCmode)
11741 && (TARGET_SHIFT1 || optimize_size)
11742 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11743 "shr{b}\t%0"
11744 [(set_attr "type" "ishift")
11745 (set (attr "length")
11746 (if_then_else (match_operand:SI 0 "register_operand" "")
11747 (const_string "2")
11748 (const_string "*")))])
11749
11750 ;; This pattern can't accept a variable shift count, since shifts by
11751 ;; zero don't affect the flags. We assume that shifts by constant
11752 ;; zero are optimized away.
11753 (define_insn "*lshrqi2_cmp"
11754 [(set (reg FLAGS_REG)
11755 (compare
11756 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11757 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11758 (const_int 0)))
11759 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11760 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11761 "ix86_match_ccmode (insn, CCGOCmode)
11762 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11763 "shr{b}\t{%2, %0|%0, %2}"
11764 [(set_attr "type" "ishift")
11765 (set_attr "mode" "QI")])
11766 \f
11767 ;; Rotate instructions
11768
11769 (define_expand "rotldi3"
11770 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11771 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11772 (match_operand:QI 2 "nonmemory_operand" "")))
11773 (clobber (reg:CC FLAGS_REG))]
11774 "TARGET_64BIT"
11775 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11776
11777 (define_insn "*rotlsi3_1_one_bit_rex64"
11778 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11779 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11780 (match_operand:QI 2 "const1_operand" "")))
11781 (clobber (reg:CC FLAGS_REG))]
11782 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11783 && (TARGET_SHIFT1 || optimize_size)"
11784 "rol{q}\t%0"
11785 [(set_attr "type" "rotate")
11786 (set (attr "length")
11787 (if_then_else (match_operand:DI 0 "register_operand" "")
11788 (const_string "2")
11789 (const_string "*")))])
11790
11791 (define_insn "*rotldi3_1_rex64"
11792 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11793 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11794 (match_operand:QI 2 "nonmemory_operand" "e,c")))
11795 (clobber (reg:CC FLAGS_REG))]
11796 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11797 "@
11798 rol{q}\t{%2, %0|%0, %2}
11799 rol{q}\t{%b2, %0|%0, %b2}"
11800 [(set_attr "type" "rotate")
11801 (set_attr "mode" "DI")])
11802
11803 (define_expand "rotlsi3"
11804 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11805 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11806 (match_operand:QI 2 "nonmemory_operand" "")))
11807 (clobber (reg:CC FLAGS_REG))]
11808 ""
11809 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11810
11811 (define_insn "*rotlsi3_1_one_bit"
11812 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11813 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11814 (match_operand:QI 2 "const1_operand" "")))
11815 (clobber (reg:CC FLAGS_REG))]
11816 "ix86_binary_operator_ok (ROTATE, SImode, operands)
11817 && (TARGET_SHIFT1 || optimize_size)"
11818 "rol{l}\t%0"
11819 [(set_attr "type" "rotate")
11820 (set (attr "length")
11821 (if_then_else (match_operand:SI 0 "register_operand" "")
11822 (const_string "2")
11823 (const_string "*")))])
11824
11825 (define_insn "*rotlsi3_1_one_bit_zext"
11826 [(set (match_operand:DI 0 "register_operand" "=r")
11827 (zero_extend:DI
11828 (rotate:SI (match_operand:SI 1 "register_operand" "0")
11829 (match_operand:QI 2 "const1_operand" ""))))
11830 (clobber (reg:CC FLAGS_REG))]
11831 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11832 && (TARGET_SHIFT1 || optimize_size)"
11833 "rol{l}\t%k0"
11834 [(set_attr "type" "rotate")
11835 (set_attr "length" "2")])
11836
11837 (define_insn "*rotlsi3_1"
11838 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11839 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11840 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11841 (clobber (reg:CC FLAGS_REG))]
11842 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11843 "@
11844 rol{l}\t{%2, %0|%0, %2}
11845 rol{l}\t{%b2, %0|%0, %b2}"
11846 [(set_attr "type" "rotate")
11847 (set_attr "mode" "SI")])
11848
11849 (define_insn "*rotlsi3_1_zext"
11850 [(set (match_operand:DI 0 "register_operand" "=r,r")
11851 (zero_extend:DI
11852 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11853 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11854 (clobber (reg:CC FLAGS_REG))]
11855 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11856 "@
11857 rol{l}\t{%2, %k0|%k0, %2}
11858 rol{l}\t{%b2, %k0|%k0, %b2}"
11859 [(set_attr "type" "rotate")
11860 (set_attr "mode" "SI")])
11861
11862 (define_expand "rotlhi3"
11863 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11864 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11865 (match_operand:QI 2 "nonmemory_operand" "")))
11866 (clobber (reg:CC FLAGS_REG))]
11867 "TARGET_HIMODE_MATH"
11868 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11869
11870 (define_insn "*rotlhi3_1_one_bit"
11871 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11872 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11873 (match_operand:QI 2 "const1_operand" "")))
11874 (clobber (reg:CC FLAGS_REG))]
11875 "ix86_binary_operator_ok (ROTATE, HImode, operands)
11876 && (TARGET_SHIFT1 || optimize_size)"
11877 "rol{w}\t%0"
11878 [(set_attr "type" "rotate")
11879 (set (attr "length")
11880 (if_then_else (match_operand 0 "register_operand" "")
11881 (const_string "2")
11882 (const_string "*")))])
11883
11884 (define_insn "*rotlhi3_1"
11885 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11886 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11887 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11888 (clobber (reg:CC FLAGS_REG))]
11889 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11890 "@
11891 rol{w}\t{%2, %0|%0, %2}
11892 rol{w}\t{%b2, %0|%0, %b2}"
11893 [(set_attr "type" "rotate")
11894 (set_attr "mode" "HI")])
11895
11896 (define_expand "rotlqi3"
11897 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11898 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11899 (match_operand:QI 2 "nonmemory_operand" "")))
11900 (clobber (reg:CC FLAGS_REG))]
11901 "TARGET_QIMODE_MATH"
11902 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11903
11904 (define_insn "*rotlqi3_1_one_bit_slp"
11905 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11906 (rotate:QI (match_dup 0)
11907 (match_operand:QI 1 "const1_operand" "")))
11908 (clobber (reg:CC FLAGS_REG))]
11909 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11910 && (TARGET_SHIFT1 || optimize_size)"
11911 "rol{b}\t%0"
11912 [(set_attr "type" "rotate1")
11913 (set (attr "length")
11914 (if_then_else (match_operand 0 "register_operand" "")
11915 (const_string "2")
11916 (const_string "*")))])
11917
11918 (define_insn "*rotlqi3_1_one_bit"
11919 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11920 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11921 (match_operand:QI 2 "const1_operand" "")))
11922 (clobber (reg:CC FLAGS_REG))]
11923 "ix86_binary_operator_ok (ROTATE, QImode, operands)
11924 && (TARGET_SHIFT1 || optimize_size)"
11925 "rol{b}\t%0"
11926 [(set_attr "type" "rotate")
11927 (set (attr "length")
11928 (if_then_else (match_operand 0 "register_operand" "")
11929 (const_string "2")
11930 (const_string "*")))])
11931
11932 (define_insn "*rotlqi3_1_slp"
11933 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11934 (rotate:QI (match_dup 0)
11935 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11936 (clobber (reg:CC FLAGS_REG))]
11937 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11938 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11939 "@
11940 rol{b}\t{%1, %0|%0, %1}
11941 rol{b}\t{%b1, %0|%0, %b1}"
11942 [(set_attr "type" "rotate1")
11943 (set_attr "mode" "QI")])
11944
11945 (define_insn "*rotlqi3_1"
11946 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11947 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11948 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11949 (clobber (reg:CC FLAGS_REG))]
11950 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11951 "@
11952 rol{b}\t{%2, %0|%0, %2}
11953 rol{b}\t{%b2, %0|%0, %b2}"
11954 [(set_attr "type" "rotate")
11955 (set_attr "mode" "QI")])
11956
11957 (define_expand "rotrdi3"
11958 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11959 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11960 (match_operand:QI 2 "nonmemory_operand" "")))
11961 (clobber (reg:CC FLAGS_REG))]
11962 "TARGET_64BIT"
11963 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11964
11965 (define_insn "*rotrdi3_1_one_bit_rex64"
11966 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11967 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11968 (match_operand:QI 2 "const1_operand" "")))
11969 (clobber (reg:CC FLAGS_REG))]
11970 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11971 && (TARGET_SHIFT1 || optimize_size)"
11972 "ror{q}\t%0"
11973 [(set_attr "type" "rotate")
11974 (set (attr "length")
11975 (if_then_else (match_operand:DI 0 "register_operand" "")
11976 (const_string "2")
11977 (const_string "*")))])
11978
11979 (define_insn "*rotrdi3_1_rex64"
11980 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11981 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11982 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11983 (clobber (reg:CC FLAGS_REG))]
11984 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11985 "@
11986 ror{q}\t{%2, %0|%0, %2}
11987 ror{q}\t{%b2, %0|%0, %b2}"
11988 [(set_attr "type" "rotate")
11989 (set_attr "mode" "DI")])
11990
11991 (define_expand "rotrsi3"
11992 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11993 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11994 (match_operand:QI 2 "nonmemory_operand" "")))
11995 (clobber (reg:CC FLAGS_REG))]
11996 ""
11997 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11998
11999 (define_insn "*rotrsi3_1_one_bit"
12000 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12001 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12002 (match_operand:QI 2 "const1_operand" "")))
12003 (clobber (reg:CC FLAGS_REG))]
12004 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12005 && (TARGET_SHIFT1 || optimize_size)"
12006 "ror{l}\t%0"
12007 [(set_attr "type" "rotate")
12008 (set (attr "length")
12009 (if_then_else (match_operand:SI 0 "register_operand" "")
12010 (const_string "2")
12011 (const_string "*")))])
12012
12013 (define_insn "*rotrsi3_1_one_bit_zext"
12014 [(set (match_operand:DI 0 "register_operand" "=r")
12015 (zero_extend:DI
12016 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12017 (match_operand:QI 2 "const1_operand" ""))))
12018 (clobber (reg:CC FLAGS_REG))]
12019 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12020 && (TARGET_SHIFT1 || optimize_size)"
12021 "ror{l}\t%k0"
12022 [(set_attr "type" "rotate")
12023 (set (attr "length")
12024 (if_then_else (match_operand:SI 0 "register_operand" "")
12025 (const_string "2")
12026 (const_string "*")))])
12027
12028 (define_insn "*rotrsi3_1"
12029 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12030 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12031 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12032 (clobber (reg:CC FLAGS_REG))]
12033 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12034 "@
12035 ror{l}\t{%2, %0|%0, %2}
12036 ror{l}\t{%b2, %0|%0, %b2}"
12037 [(set_attr "type" "rotate")
12038 (set_attr "mode" "SI")])
12039
12040 (define_insn "*rotrsi3_1_zext"
12041 [(set (match_operand:DI 0 "register_operand" "=r,r")
12042 (zero_extend:DI
12043 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12044 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12045 (clobber (reg:CC FLAGS_REG))]
12046 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12047 "@
12048 ror{l}\t{%2, %k0|%k0, %2}
12049 ror{l}\t{%b2, %k0|%k0, %b2}"
12050 [(set_attr "type" "rotate")
12051 (set_attr "mode" "SI")])
12052
12053 (define_expand "rotrhi3"
12054 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12055 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12056 (match_operand:QI 2 "nonmemory_operand" "")))
12057 (clobber (reg:CC FLAGS_REG))]
12058 "TARGET_HIMODE_MATH"
12059 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12060
12061 (define_insn "*rotrhi3_one_bit"
12062 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12063 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12064 (match_operand:QI 2 "const1_operand" "")))
12065 (clobber (reg:CC FLAGS_REG))]
12066 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12067 && (TARGET_SHIFT1 || optimize_size)"
12068 "ror{w}\t%0"
12069 [(set_attr "type" "rotate")
12070 (set (attr "length")
12071 (if_then_else (match_operand 0 "register_operand" "")
12072 (const_string "2")
12073 (const_string "*")))])
12074
12075 (define_insn "*rotrhi3"
12076 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12077 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12078 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12079 (clobber (reg:CC FLAGS_REG))]
12080 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12081 "@
12082 ror{w}\t{%2, %0|%0, %2}
12083 ror{w}\t{%b2, %0|%0, %b2}"
12084 [(set_attr "type" "rotate")
12085 (set_attr "mode" "HI")])
12086
12087 (define_expand "rotrqi3"
12088 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12089 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12090 (match_operand:QI 2 "nonmemory_operand" "")))
12091 (clobber (reg:CC FLAGS_REG))]
12092 "TARGET_QIMODE_MATH"
12093 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12094
12095 (define_insn "*rotrqi3_1_one_bit"
12096 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12097 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12098 (match_operand:QI 2 "const1_operand" "")))
12099 (clobber (reg:CC FLAGS_REG))]
12100 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12101 && (TARGET_SHIFT1 || optimize_size)"
12102 "ror{b}\t%0"
12103 [(set_attr "type" "rotate")
12104 (set (attr "length")
12105 (if_then_else (match_operand 0 "register_operand" "")
12106 (const_string "2")
12107 (const_string "*")))])
12108
12109 (define_insn "*rotrqi3_1_one_bit_slp"
12110 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12111 (rotatert:QI (match_dup 0)
12112 (match_operand:QI 1 "const1_operand" "")))
12113 (clobber (reg:CC FLAGS_REG))]
12114 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12115 && (TARGET_SHIFT1 || optimize_size)"
12116 "ror{b}\t%0"
12117 [(set_attr "type" "rotate1")
12118 (set (attr "length")
12119 (if_then_else (match_operand 0 "register_operand" "")
12120 (const_string "2")
12121 (const_string "*")))])
12122
12123 (define_insn "*rotrqi3_1"
12124 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12125 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12126 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12127 (clobber (reg:CC FLAGS_REG))]
12128 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12129 "@
12130 ror{b}\t{%2, %0|%0, %2}
12131 ror{b}\t{%b2, %0|%0, %b2}"
12132 [(set_attr "type" "rotate")
12133 (set_attr "mode" "QI")])
12134
12135 (define_insn "*rotrqi3_1_slp"
12136 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12137 (rotatert:QI (match_dup 0)
12138 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12139 (clobber (reg:CC FLAGS_REG))]
12140 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12141 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12142 "@
12143 ror{b}\t{%1, %0|%0, %1}
12144 ror{b}\t{%b1, %0|%0, %b1}"
12145 [(set_attr "type" "rotate1")
12146 (set_attr "mode" "QI")])
12147 \f
12148 ;; Bit set / bit test instructions
12149
12150 (define_expand "extv"
12151 [(set (match_operand:SI 0 "register_operand" "")
12152 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12153 (match_operand:SI 2 "immediate_operand" "")
12154 (match_operand:SI 3 "immediate_operand" "")))]
12155 ""
12156 {
12157 /* Handle extractions from %ah et al. */
12158 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12159 FAIL;
12160
12161 /* From mips.md: extract_bit_field doesn't verify that our source
12162 matches the predicate, so check it again here. */
12163 if (! ext_register_operand (operands[1], VOIDmode))
12164 FAIL;
12165 })
12166
12167 (define_expand "extzv"
12168 [(set (match_operand:SI 0 "register_operand" "")
12169 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12170 (match_operand:SI 2 "immediate_operand" "")
12171 (match_operand:SI 3 "immediate_operand" "")))]
12172 ""
12173 {
12174 /* Handle extractions from %ah et al. */
12175 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12176 FAIL;
12177
12178 /* From mips.md: extract_bit_field doesn't verify that our source
12179 matches the predicate, so check it again here. */
12180 if (! ext_register_operand (operands[1], VOIDmode))
12181 FAIL;
12182 })
12183
12184 (define_expand "insv"
12185 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12186 (match_operand 1 "immediate_operand" "")
12187 (match_operand 2 "immediate_operand" ""))
12188 (match_operand 3 "register_operand" ""))]
12189 ""
12190 {
12191 /* Handle extractions from %ah et al. */
12192 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12193 FAIL;
12194
12195 /* From mips.md: insert_bit_field doesn't verify that our source
12196 matches the predicate, so check it again here. */
12197 if (! ext_register_operand (operands[0], VOIDmode))
12198 FAIL;
12199
12200 if (TARGET_64BIT)
12201 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12202 else
12203 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12204
12205 DONE;
12206 })
12207
12208 ;; %%% bts, btr, btc, bt.
12209 ;; In general these instructions are *slow* when applied to memory,
12210 ;; since they enforce atomic operation. When applied to registers,
12211 ;; it depends on the cpu implementation. They're never faster than
12212 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12213 ;; no point. But in 64-bit, we can't hold the relevant immediates
12214 ;; within the instruction itself, so operating on bits in the high
12215 ;; 32-bits of a register becomes easier.
12216 ;;
12217 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12218 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12219 ;; negdf respectively, so they can never be disabled entirely.
12220
12221 (define_insn "*btsq"
12222 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12223 (const_int 1)
12224 (match_operand:DI 1 "const_0_to_63_operand" ""))
12225 (const_int 1))
12226 (clobber (reg:CC FLAGS_REG))]
12227 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12228 "bts{q} %1,%0"
12229 [(set_attr "type" "alu1")])
12230
12231 (define_insn "*btrq"
12232 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12233 (const_int 1)
12234 (match_operand:DI 1 "const_0_to_63_operand" ""))
12235 (const_int 0))
12236 (clobber (reg:CC FLAGS_REG))]
12237 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12238 "btr{q} %1,%0"
12239 [(set_attr "type" "alu1")])
12240
12241 (define_insn "*btcq"
12242 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12243 (const_int 1)
12244 (match_operand:DI 1 "const_0_to_63_operand" ""))
12245 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12246 (clobber (reg:CC FLAGS_REG))]
12247 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12248 "btc{q} %1,%0"
12249 [(set_attr "type" "alu1")])
12250
12251 ;; Allow Nocona to avoid these instructions if a register is available.
12252
12253 (define_peephole2
12254 [(match_scratch:DI 2 "r")
12255 (parallel [(set (zero_extract:DI
12256 (match_operand:DI 0 "register_operand" "")
12257 (const_int 1)
12258 (match_operand:DI 1 "const_0_to_63_operand" ""))
12259 (const_int 1))
12260 (clobber (reg:CC FLAGS_REG))])]
12261 "TARGET_64BIT && !TARGET_USE_BT"
12262 [(const_int 0)]
12263 {
12264 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12265 rtx op1;
12266
12267 if (HOST_BITS_PER_WIDE_INT >= 64)
12268 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12269 else if (i < HOST_BITS_PER_WIDE_INT)
12270 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12271 else
12272 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12273
12274 op1 = immed_double_const (lo, hi, DImode);
12275 if (i >= 31)
12276 {
12277 emit_move_insn (operands[2], op1);
12278 op1 = operands[2];
12279 }
12280
12281 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12282 DONE;
12283 })
12284
12285 (define_peephole2
12286 [(match_scratch:DI 2 "r")
12287 (parallel [(set (zero_extract:DI
12288 (match_operand:DI 0 "register_operand" "")
12289 (const_int 1)
12290 (match_operand:DI 1 "const_0_to_63_operand" ""))
12291 (const_int 0))
12292 (clobber (reg:CC FLAGS_REG))])]
12293 "TARGET_64BIT && !TARGET_USE_BT"
12294 [(const_int 0)]
12295 {
12296 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12297 rtx op1;
12298
12299 if (HOST_BITS_PER_WIDE_INT >= 64)
12300 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12301 else if (i < HOST_BITS_PER_WIDE_INT)
12302 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12303 else
12304 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12305
12306 op1 = immed_double_const (~lo, ~hi, DImode);
12307 if (i >= 32)
12308 {
12309 emit_move_insn (operands[2], op1);
12310 op1 = operands[2];
12311 }
12312
12313 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12314 DONE;
12315 })
12316
12317 (define_peephole2
12318 [(match_scratch:DI 2 "r")
12319 (parallel [(set (zero_extract:DI
12320 (match_operand:DI 0 "register_operand" "")
12321 (const_int 1)
12322 (match_operand:DI 1 "const_0_to_63_operand" ""))
12323 (not:DI (zero_extract:DI
12324 (match_dup 0) (const_int 1) (match_dup 1))))
12325 (clobber (reg:CC FLAGS_REG))])]
12326 "TARGET_64BIT && !TARGET_USE_BT"
12327 [(const_int 0)]
12328 {
12329 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12330 rtx op1;
12331
12332 if (HOST_BITS_PER_WIDE_INT >= 64)
12333 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12334 else if (i < HOST_BITS_PER_WIDE_INT)
12335 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12336 else
12337 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12338
12339 op1 = immed_double_const (lo, hi, DImode);
12340 if (i >= 31)
12341 {
12342 emit_move_insn (operands[2], op1);
12343 op1 = operands[2];
12344 }
12345
12346 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12347 DONE;
12348 })
12349 \f
12350 ;; Store-flag instructions.
12351
12352 ;; For all sCOND expanders, also expand the compare or test insn that
12353 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12354
12355 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12356 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12357 ;; way, which can later delete the movzx if only QImode is needed.
12358
12359 (define_expand "seq"
12360 [(set (match_operand:QI 0 "register_operand" "")
12361 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12362 ""
12363 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12364
12365 (define_expand "sne"
12366 [(set (match_operand:QI 0 "register_operand" "")
12367 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12368 ""
12369 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12370
12371 (define_expand "sgt"
12372 [(set (match_operand:QI 0 "register_operand" "")
12373 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12374 ""
12375 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12376
12377 (define_expand "sgtu"
12378 [(set (match_operand:QI 0 "register_operand" "")
12379 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12380 ""
12381 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12382
12383 (define_expand "slt"
12384 [(set (match_operand:QI 0 "register_operand" "")
12385 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12386 ""
12387 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12388
12389 (define_expand "sltu"
12390 [(set (match_operand:QI 0 "register_operand" "")
12391 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12392 ""
12393 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12394
12395 (define_expand "sge"
12396 [(set (match_operand:QI 0 "register_operand" "")
12397 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12398 ""
12399 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12400
12401 (define_expand "sgeu"
12402 [(set (match_operand:QI 0 "register_operand" "")
12403 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12404 ""
12405 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12406
12407 (define_expand "sle"
12408 [(set (match_operand:QI 0 "register_operand" "")
12409 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12410 ""
12411 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12412
12413 (define_expand "sleu"
12414 [(set (match_operand:QI 0 "register_operand" "")
12415 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12416 ""
12417 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12418
12419 (define_expand "sunordered"
12420 [(set (match_operand:QI 0 "register_operand" "")
12421 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12422 "TARGET_80387 || TARGET_SSE"
12423 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12424
12425 (define_expand "sordered"
12426 [(set (match_operand:QI 0 "register_operand" "")
12427 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12428 "TARGET_80387"
12429 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12430
12431 (define_expand "suneq"
12432 [(set (match_operand:QI 0 "register_operand" "")
12433 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12434 "TARGET_80387 || TARGET_SSE"
12435 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12436
12437 (define_expand "sunge"
12438 [(set (match_operand:QI 0 "register_operand" "")
12439 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12440 "TARGET_80387 || TARGET_SSE"
12441 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12442
12443 (define_expand "sungt"
12444 [(set (match_operand:QI 0 "register_operand" "")
12445 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12446 "TARGET_80387 || TARGET_SSE"
12447 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12448
12449 (define_expand "sunle"
12450 [(set (match_operand:QI 0 "register_operand" "")
12451 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12452 "TARGET_80387 || TARGET_SSE"
12453 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12454
12455 (define_expand "sunlt"
12456 [(set (match_operand:QI 0 "register_operand" "")
12457 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12458 "TARGET_80387 || TARGET_SSE"
12459 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12460
12461 (define_expand "sltgt"
12462 [(set (match_operand:QI 0 "register_operand" "")
12463 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12464 "TARGET_80387 || TARGET_SSE"
12465 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12466
12467 (define_insn "*setcc_1"
12468 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12469 (match_operator:QI 1 "ix86_comparison_operator"
12470 [(reg FLAGS_REG) (const_int 0)]))]
12471 ""
12472 "set%C1\t%0"
12473 [(set_attr "type" "setcc")
12474 (set_attr "mode" "QI")])
12475
12476 (define_insn "*setcc_2"
12477 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12478 (match_operator:QI 1 "ix86_comparison_operator"
12479 [(reg FLAGS_REG) (const_int 0)]))]
12480 ""
12481 "set%C1\t%0"
12482 [(set_attr "type" "setcc")
12483 (set_attr "mode" "QI")])
12484
12485 ;; In general it is not safe to assume too much about CCmode registers,
12486 ;; so simplify-rtx stops when it sees a second one. Under certain
12487 ;; conditions this is safe on x86, so help combine not create
12488 ;;
12489 ;; seta %al
12490 ;; testb %al, %al
12491 ;; sete %al
12492
12493 (define_split
12494 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12495 (ne:QI (match_operator 1 "ix86_comparison_operator"
12496 [(reg FLAGS_REG) (const_int 0)])
12497 (const_int 0)))]
12498 ""
12499 [(set (match_dup 0) (match_dup 1))]
12500 {
12501 PUT_MODE (operands[1], QImode);
12502 })
12503
12504 (define_split
12505 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12506 (ne:QI (match_operator 1 "ix86_comparison_operator"
12507 [(reg FLAGS_REG) (const_int 0)])
12508 (const_int 0)))]
12509 ""
12510 [(set (match_dup 0) (match_dup 1))]
12511 {
12512 PUT_MODE (operands[1], QImode);
12513 })
12514
12515 (define_split
12516 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12517 (eq:QI (match_operator 1 "ix86_comparison_operator"
12518 [(reg FLAGS_REG) (const_int 0)])
12519 (const_int 0)))]
12520 ""
12521 [(set (match_dup 0) (match_dup 1))]
12522 {
12523 rtx new_op1 = copy_rtx (operands[1]);
12524 operands[1] = new_op1;
12525 PUT_MODE (new_op1, QImode);
12526 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12527 GET_MODE (XEXP (new_op1, 0))));
12528
12529 /* Make sure that (a) the CCmode we have for the flags is strong
12530 enough for the reversed compare or (b) we have a valid FP compare. */
12531 if (! ix86_comparison_operator (new_op1, VOIDmode))
12532 FAIL;
12533 })
12534
12535 (define_split
12536 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12537 (eq:QI (match_operator 1 "ix86_comparison_operator"
12538 [(reg FLAGS_REG) (const_int 0)])
12539 (const_int 0)))]
12540 ""
12541 [(set (match_dup 0) (match_dup 1))]
12542 {
12543 rtx new_op1 = copy_rtx (operands[1]);
12544 operands[1] = new_op1;
12545 PUT_MODE (new_op1, QImode);
12546 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12547 GET_MODE (XEXP (new_op1, 0))));
12548
12549 /* Make sure that (a) the CCmode we have for the flags is strong
12550 enough for the reversed compare or (b) we have a valid FP compare. */
12551 if (! ix86_comparison_operator (new_op1, VOIDmode))
12552 FAIL;
12553 })
12554
12555 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12556 ;; subsequent logical operations are used to imitate conditional moves.
12557 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12558 ;; it directly. Further holding this value in pseudo register might bring
12559 ;; problem in implicit normalization in spill code.
12560 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12561 ;; instructions after reload by splitting the conditional move patterns.
12562
12563 (define_insn "*sse_setccsf"
12564 [(set (match_operand:SF 0 "register_operand" "=x")
12565 (match_operator:SF 1 "sse_comparison_operator"
12566 [(match_operand:SF 2 "register_operand" "0")
12567 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12568 "TARGET_SSE && reload_completed"
12569 "cmp%D1ss\t{%3, %0|%0, %3}"
12570 [(set_attr "type" "ssecmp")
12571 (set_attr "mode" "SF")])
12572
12573 (define_insn "*sse_setccdf"
12574 [(set (match_operand:DF 0 "register_operand" "=Y")
12575 (match_operator:DF 1 "sse_comparison_operator"
12576 [(match_operand:DF 2 "register_operand" "0")
12577 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12578 "TARGET_SSE2 && reload_completed"
12579 "cmp%D1sd\t{%3, %0|%0, %3}"
12580 [(set_attr "type" "ssecmp")
12581 (set_attr "mode" "DF")])
12582 \f
12583 ;; Basic conditional jump instructions.
12584 ;; We ignore the overflow flag for signed branch instructions.
12585
12586 ;; For all bCOND expanders, also expand the compare or test insn that
12587 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12588
12589 (define_expand "beq"
12590 [(set (pc)
12591 (if_then_else (match_dup 1)
12592 (label_ref (match_operand 0 "" ""))
12593 (pc)))]
12594 ""
12595 "ix86_expand_branch (EQ, operands[0]); DONE;")
12596
12597 (define_expand "bne"
12598 [(set (pc)
12599 (if_then_else (match_dup 1)
12600 (label_ref (match_operand 0 "" ""))
12601 (pc)))]
12602 ""
12603 "ix86_expand_branch (NE, operands[0]); DONE;")
12604
12605 (define_expand "bgt"
12606 [(set (pc)
12607 (if_then_else (match_dup 1)
12608 (label_ref (match_operand 0 "" ""))
12609 (pc)))]
12610 ""
12611 "ix86_expand_branch (GT, operands[0]); DONE;")
12612
12613 (define_expand "bgtu"
12614 [(set (pc)
12615 (if_then_else (match_dup 1)
12616 (label_ref (match_operand 0 "" ""))
12617 (pc)))]
12618 ""
12619 "ix86_expand_branch (GTU, operands[0]); DONE;")
12620
12621 (define_expand "blt"
12622 [(set (pc)
12623 (if_then_else (match_dup 1)
12624 (label_ref (match_operand 0 "" ""))
12625 (pc)))]
12626 ""
12627 "ix86_expand_branch (LT, operands[0]); DONE;")
12628
12629 (define_expand "bltu"
12630 [(set (pc)
12631 (if_then_else (match_dup 1)
12632 (label_ref (match_operand 0 "" ""))
12633 (pc)))]
12634 ""
12635 "ix86_expand_branch (LTU, operands[0]); DONE;")
12636
12637 (define_expand "bge"
12638 [(set (pc)
12639 (if_then_else (match_dup 1)
12640 (label_ref (match_operand 0 "" ""))
12641 (pc)))]
12642 ""
12643 "ix86_expand_branch (GE, operands[0]); DONE;")
12644
12645 (define_expand "bgeu"
12646 [(set (pc)
12647 (if_then_else (match_dup 1)
12648 (label_ref (match_operand 0 "" ""))
12649 (pc)))]
12650 ""
12651 "ix86_expand_branch (GEU, operands[0]); DONE;")
12652
12653 (define_expand "ble"
12654 [(set (pc)
12655 (if_then_else (match_dup 1)
12656 (label_ref (match_operand 0 "" ""))
12657 (pc)))]
12658 ""
12659 "ix86_expand_branch (LE, operands[0]); DONE;")
12660
12661 (define_expand "bleu"
12662 [(set (pc)
12663 (if_then_else (match_dup 1)
12664 (label_ref (match_operand 0 "" ""))
12665 (pc)))]
12666 ""
12667 "ix86_expand_branch (LEU, operands[0]); DONE;")
12668
12669 (define_expand "bunordered"
12670 [(set (pc)
12671 (if_then_else (match_dup 1)
12672 (label_ref (match_operand 0 "" ""))
12673 (pc)))]
12674 "TARGET_80387 || TARGET_SSE"
12675 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12676
12677 (define_expand "bordered"
12678 [(set (pc)
12679 (if_then_else (match_dup 1)
12680 (label_ref (match_operand 0 "" ""))
12681 (pc)))]
12682 "TARGET_80387 || TARGET_SSE"
12683 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12684
12685 (define_expand "buneq"
12686 [(set (pc)
12687 (if_then_else (match_dup 1)
12688 (label_ref (match_operand 0 "" ""))
12689 (pc)))]
12690 "TARGET_80387 || TARGET_SSE"
12691 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12692
12693 (define_expand "bunge"
12694 [(set (pc)
12695 (if_then_else (match_dup 1)
12696 (label_ref (match_operand 0 "" ""))
12697 (pc)))]
12698 "TARGET_80387 || TARGET_SSE"
12699 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12700
12701 (define_expand "bungt"
12702 [(set (pc)
12703 (if_then_else (match_dup 1)
12704 (label_ref (match_operand 0 "" ""))
12705 (pc)))]
12706 "TARGET_80387 || TARGET_SSE"
12707 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12708
12709 (define_expand "bunle"
12710 [(set (pc)
12711 (if_then_else (match_dup 1)
12712 (label_ref (match_operand 0 "" ""))
12713 (pc)))]
12714 "TARGET_80387 || TARGET_SSE"
12715 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12716
12717 (define_expand "bunlt"
12718 [(set (pc)
12719 (if_then_else (match_dup 1)
12720 (label_ref (match_operand 0 "" ""))
12721 (pc)))]
12722 "TARGET_80387 || TARGET_SSE"
12723 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12724
12725 (define_expand "bltgt"
12726 [(set (pc)
12727 (if_then_else (match_dup 1)
12728 (label_ref (match_operand 0 "" ""))
12729 (pc)))]
12730 "TARGET_80387 || TARGET_SSE"
12731 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12732
12733 (define_insn "*jcc_1"
12734 [(set (pc)
12735 (if_then_else (match_operator 1 "ix86_comparison_operator"
12736 [(reg FLAGS_REG) (const_int 0)])
12737 (label_ref (match_operand 0 "" ""))
12738 (pc)))]
12739 ""
12740 "%+j%C1\t%l0"
12741 [(set_attr "type" "ibr")
12742 (set_attr "modrm" "0")
12743 (set (attr "length")
12744 (if_then_else (and (ge (minus (match_dup 0) (pc))
12745 (const_int -126))
12746 (lt (minus (match_dup 0) (pc))
12747 (const_int 128)))
12748 (const_int 2)
12749 (const_int 6)))])
12750
12751 (define_insn "*jcc_2"
12752 [(set (pc)
12753 (if_then_else (match_operator 1 "ix86_comparison_operator"
12754 [(reg FLAGS_REG) (const_int 0)])
12755 (pc)
12756 (label_ref (match_operand 0 "" ""))))]
12757 ""
12758 "%+j%c1\t%l0"
12759 [(set_attr "type" "ibr")
12760 (set_attr "modrm" "0")
12761 (set (attr "length")
12762 (if_then_else (and (ge (minus (match_dup 0) (pc))
12763 (const_int -126))
12764 (lt (minus (match_dup 0) (pc))
12765 (const_int 128)))
12766 (const_int 2)
12767 (const_int 6)))])
12768
12769 ;; In general it is not safe to assume too much about CCmode registers,
12770 ;; so simplify-rtx stops when it sees a second one. Under certain
12771 ;; conditions this is safe on x86, so help combine not create
12772 ;;
12773 ;; seta %al
12774 ;; testb %al, %al
12775 ;; je Lfoo
12776
12777 (define_split
12778 [(set (pc)
12779 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12780 [(reg FLAGS_REG) (const_int 0)])
12781 (const_int 0))
12782 (label_ref (match_operand 1 "" ""))
12783 (pc)))]
12784 ""
12785 [(set (pc)
12786 (if_then_else (match_dup 0)
12787 (label_ref (match_dup 1))
12788 (pc)))]
12789 {
12790 PUT_MODE (operands[0], VOIDmode);
12791 })
12792
12793 (define_split
12794 [(set (pc)
12795 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12796 [(reg FLAGS_REG) (const_int 0)])
12797 (const_int 0))
12798 (label_ref (match_operand 1 "" ""))
12799 (pc)))]
12800 ""
12801 [(set (pc)
12802 (if_then_else (match_dup 0)
12803 (label_ref (match_dup 1))
12804 (pc)))]
12805 {
12806 rtx new_op0 = copy_rtx (operands[0]);
12807 operands[0] = new_op0;
12808 PUT_MODE (new_op0, VOIDmode);
12809 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12810 GET_MODE (XEXP (new_op0, 0))));
12811
12812 /* Make sure that (a) the CCmode we have for the flags is strong
12813 enough for the reversed compare or (b) we have a valid FP compare. */
12814 if (! ix86_comparison_operator (new_op0, VOIDmode))
12815 FAIL;
12816 })
12817
12818 ;; Define combination compare-and-branch fp compare instructions to use
12819 ;; during early optimization. Splitting the operation apart early makes
12820 ;; for bad code when we want to reverse the operation.
12821
12822 (define_insn "*fp_jcc_1"
12823 [(set (pc)
12824 (if_then_else (match_operator 0 "comparison_operator"
12825 [(match_operand 1 "register_operand" "f")
12826 (match_operand 2 "register_operand" "f")])
12827 (label_ref (match_operand 3 "" ""))
12828 (pc)))
12829 (clobber (reg:CCFP FPSR_REG))
12830 (clobber (reg:CCFP FLAGS_REG))]
12831 "TARGET_CMOVE && TARGET_80387
12832 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12833 && FLOAT_MODE_P (GET_MODE (operands[1]))
12834 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12835 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12836 "#")
12837
12838 (define_insn "*fp_jcc_1_sse"
12839 [(set (pc)
12840 (if_then_else (match_operator 0 "comparison_operator"
12841 [(match_operand 1 "register_operand" "f#x,x#f")
12842 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12843 (label_ref (match_operand 3 "" ""))
12844 (pc)))
12845 (clobber (reg:CCFP FPSR_REG))
12846 (clobber (reg:CCFP FLAGS_REG))]
12847 "TARGET_80387
12848 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12849 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12850 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12851 "#")
12852
12853 (define_insn "*fp_jcc_1_sse_only"
12854 [(set (pc)
12855 (if_then_else (match_operator 0 "comparison_operator"
12856 [(match_operand 1 "register_operand" "x")
12857 (match_operand 2 "nonimmediate_operand" "xm")])
12858 (label_ref (match_operand 3 "" ""))
12859 (pc)))
12860 (clobber (reg:CCFP FPSR_REG))
12861 (clobber (reg:CCFP FLAGS_REG))]
12862 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12863 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12864 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12865 "#")
12866
12867 (define_insn "*fp_jcc_2"
12868 [(set (pc)
12869 (if_then_else (match_operator 0 "comparison_operator"
12870 [(match_operand 1 "register_operand" "f")
12871 (match_operand 2 "register_operand" "f")])
12872 (pc)
12873 (label_ref (match_operand 3 "" ""))))
12874 (clobber (reg:CCFP FPSR_REG))
12875 (clobber (reg:CCFP FLAGS_REG))]
12876 "TARGET_CMOVE && TARGET_80387
12877 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12878 && FLOAT_MODE_P (GET_MODE (operands[1]))
12879 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12880 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12881 "#")
12882
12883 (define_insn "*fp_jcc_2_sse"
12884 [(set (pc)
12885 (if_then_else (match_operator 0 "comparison_operator"
12886 [(match_operand 1 "register_operand" "f#x,x#f")
12887 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12888 (pc)
12889 (label_ref (match_operand 3 "" ""))))
12890 (clobber (reg:CCFP FPSR_REG))
12891 (clobber (reg:CCFP FLAGS_REG))]
12892 "TARGET_80387
12893 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12894 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12895 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12896 "#")
12897
12898 (define_insn "*fp_jcc_2_sse_only"
12899 [(set (pc)
12900 (if_then_else (match_operator 0 "comparison_operator"
12901 [(match_operand 1 "register_operand" "x")
12902 (match_operand 2 "nonimmediate_operand" "xm")])
12903 (pc)
12904 (label_ref (match_operand 3 "" ""))))
12905 (clobber (reg:CCFP FPSR_REG))
12906 (clobber (reg:CCFP FLAGS_REG))]
12907 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12908 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12909 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12910 "#")
12911
12912 (define_insn "*fp_jcc_3"
12913 [(set (pc)
12914 (if_then_else (match_operator 0 "comparison_operator"
12915 [(match_operand 1 "register_operand" "f")
12916 (match_operand 2 "nonimmediate_operand" "fm")])
12917 (label_ref (match_operand 3 "" ""))
12918 (pc)))
12919 (clobber (reg:CCFP FPSR_REG))
12920 (clobber (reg:CCFP FLAGS_REG))
12921 (clobber (match_scratch:HI 4 "=a"))]
12922 "TARGET_80387
12923 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12924 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12925 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12926 && SELECT_CC_MODE (GET_CODE (operands[0]),
12927 operands[1], operands[2]) == CCFPmode
12928 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12929 "#")
12930
12931 (define_insn "*fp_jcc_4"
12932 [(set (pc)
12933 (if_then_else (match_operator 0 "comparison_operator"
12934 [(match_operand 1 "register_operand" "f")
12935 (match_operand 2 "nonimmediate_operand" "fm")])
12936 (pc)
12937 (label_ref (match_operand 3 "" ""))))
12938 (clobber (reg:CCFP FPSR_REG))
12939 (clobber (reg:CCFP FLAGS_REG))
12940 (clobber (match_scratch:HI 4 "=a"))]
12941 "TARGET_80387
12942 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12943 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12944 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12945 && SELECT_CC_MODE (GET_CODE (operands[0]),
12946 operands[1], operands[2]) == CCFPmode
12947 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12948 "#")
12949
12950 (define_insn "*fp_jcc_5"
12951 [(set (pc)
12952 (if_then_else (match_operator 0 "comparison_operator"
12953 [(match_operand 1 "register_operand" "f")
12954 (match_operand 2 "register_operand" "f")])
12955 (label_ref (match_operand 3 "" ""))
12956 (pc)))
12957 (clobber (reg:CCFP FPSR_REG))
12958 (clobber (reg:CCFP FLAGS_REG))
12959 (clobber (match_scratch:HI 4 "=a"))]
12960 "TARGET_80387
12961 && FLOAT_MODE_P (GET_MODE (operands[1]))
12962 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12963 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12964 "#")
12965
12966 (define_insn "*fp_jcc_6"
12967 [(set (pc)
12968 (if_then_else (match_operator 0 "comparison_operator"
12969 [(match_operand 1 "register_operand" "f")
12970 (match_operand 2 "register_operand" "f")])
12971 (pc)
12972 (label_ref (match_operand 3 "" ""))))
12973 (clobber (reg:CCFP FPSR_REG))
12974 (clobber (reg:CCFP FLAGS_REG))
12975 (clobber (match_scratch:HI 4 "=a"))]
12976 "TARGET_80387
12977 && FLOAT_MODE_P (GET_MODE (operands[1]))
12978 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12979 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12980 "#")
12981
12982 (define_insn "*fp_jcc_7"
12983 [(set (pc)
12984 (if_then_else (match_operator 0 "comparison_operator"
12985 [(match_operand 1 "register_operand" "f")
12986 (match_operand 2 "const_double_operand" "C")])
12987 (label_ref (match_operand 3 "" ""))
12988 (pc)))
12989 (clobber (reg:CCFP FPSR_REG))
12990 (clobber (reg:CCFP FLAGS_REG))
12991 (clobber (match_scratch:HI 4 "=a"))]
12992 "TARGET_80387
12993 && FLOAT_MODE_P (GET_MODE (operands[1]))
12994 && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
12995 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12996 && SELECT_CC_MODE (GET_CODE (operands[0]),
12997 operands[1], operands[2]) == CCFPmode
12998 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12999 "#")
13000
13001 ;; The order of operands in *fp_jcc_8 is forced by combine in
13002 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13003 ;; with a precedence over other operators and is always put in the first
13004 ;; place. Swap condition and operands to match ficom instruction.
13005
13006 (define_insn "*fp_jcc_8"
13007 [(set (pc)
13008 (if_then_else (match_operator 0 "comparison_operator"
13009 [(match_operator 1 "float_operator"
13010 [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13011 (match_operand 3 "register_operand" "f,f")])
13012 (label_ref (match_operand 4 "" ""))
13013 (pc)))
13014 (clobber (reg:CCFP FPSR_REG))
13015 (clobber (reg:CCFP FLAGS_REG))
13016 (clobber (match_scratch:HI 5 "=a,a"))]
13017 "TARGET_80387 && TARGET_USE_FIOP
13018 && FLOAT_MODE_P (GET_MODE (operands[3]))
13019 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13020 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13021 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13022 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13023 "#")
13024
13025 (define_split
13026 [(set (pc)
13027 (if_then_else (match_operator 0 "comparison_operator"
13028 [(match_operand 1 "register_operand" "")
13029 (match_operand 2 "nonimmediate_operand" "")])
13030 (match_operand 3 "" "")
13031 (match_operand 4 "" "")))
13032 (clobber (reg:CCFP FPSR_REG))
13033 (clobber (reg:CCFP FLAGS_REG))]
13034 "reload_completed"
13035 [(const_int 0)]
13036 {
13037 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13038 operands[3], operands[4], NULL_RTX, NULL_RTX);
13039 DONE;
13040 })
13041
13042 (define_split
13043 [(set (pc)
13044 (if_then_else (match_operator 0 "comparison_operator"
13045 [(match_operand 1 "register_operand" "")
13046 (match_operand 2 "general_operand" "")])
13047 (match_operand 3 "" "")
13048 (match_operand 4 "" "")))
13049 (clobber (reg:CCFP FPSR_REG))
13050 (clobber (reg:CCFP FLAGS_REG))
13051 (clobber (match_scratch:HI 5 "=a"))]
13052 "reload_completed"
13053 [(const_int 0)]
13054 {
13055 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13056 operands[3], operands[4], operands[5], NULL_RTX);
13057 DONE;
13058 })
13059
13060 (define_split
13061 [(set (pc)
13062 (if_then_else (match_operator 0 "comparison_operator"
13063 [(match_operator 1 "float_operator"
13064 [(match_operand:SI 2 "memory_operand" "")])
13065 (match_operand 3 "register_operand" "")])
13066 (match_operand 4 "" "")
13067 (match_operand 5 "" "")))
13068 (clobber (reg:CCFP FPSR_REG))
13069 (clobber (reg:CCFP FLAGS_REG))
13070 (clobber (match_scratch:HI 6 "=a"))]
13071 "reload_completed"
13072 [(const_int 0)]
13073 {
13074 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13075 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13076 operands[3], operands[7],
13077 operands[4], operands[5], operands[6], NULL_RTX);
13078 DONE;
13079 })
13080
13081 ;; %%% Kill this when reload knows how to do it.
13082 (define_split
13083 [(set (pc)
13084 (if_then_else (match_operator 0 "comparison_operator"
13085 [(match_operator 1 "float_operator"
13086 [(match_operand:SI 2 "register_operand" "")])
13087 (match_operand 3 "register_operand" "")])
13088 (match_operand 4 "" "")
13089 (match_operand 5 "" "")))
13090 (clobber (reg:CCFP FPSR_REG))
13091 (clobber (reg:CCFP FLAGS_REG))
13092 (clobber (match_scratch:HI 6 "=a"))]
13093 "reload_completed"
13094 [(const_int 0)]
13095 {
13096 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13097 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13098 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13099 operands[3], operands[7],
13100 operands[4], operands[5], operands[6], operands[2]);
13101 DONE;
13102 })
13103 \f
13104 ;; Unconditional and other jump instructions
13105
13106 (define_insn "jump"
13107 [(set (pc)
13108 (label_ref (match_operand 0 "" "")))]
13109 ""
13110 "jmp\t%l0"
13111 [(set_attr "type" "ibr")
13112 (set (attr "length")
13113 (if_then_else (and (ge (minus (match_dup 0) (pc))
13114 (const_int -126))
13115 (lt (minus (match_dup 0) (pc))
13116 (const_int 128)))
13117 (const_int 2)
13118 (const_int 5)))
13119 (set_attr "modrm" "0")])
13120
13121 (define_expand "indirect_jump"
13122 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13123 ""
13124 "")
13125
13126 (define_insn "*indirect_jump"
13127 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13128 "!TARGET_64BIT"
13129 "jmp\t%A0"
13130 [(set_attr "type" "ibr")
13131 (set_attr "length_immediate" "0")])
13132
13133 (define_insn "*indirect_jump_rtx64"
13134 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13135 "TARGET_64BIT"
13136 "jmp\t%A0"
13137 [(set_attr "type" "ibr")
13138 (set_attr "length_immediate" "0")])
13139
13140 (define_expand "tablejump"
13141 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13142 (use (label_ref (match_operand 1 "" "")))])]
13143 ""
13144 {
13145 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13146 relative. Convert the relative address to an absolute address. */
13147 if (flag_pic)
13148 {
13149 rtx op0, op1;
13150 enum rtx_code code;
13151
13152 if (TARGET_64BIT)
13153 {
13154 code = PLUS;
13155 op0 = operands[0];
13156 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13157 }
13158 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13159 {
13160 code = PLUS;
13161 op0 = operands[0];
13162 op1 = pic_offset_table_rtx;
13163 }
13164 else
13165 {
13166 code = MINUS;
13167 op0 = pic_offset_table_rtx;
13168 op1 = operands[0];
13169 }
13170
13171 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13172 OPTAB_DIRECT);
13173 }
13174 })
13175
13176 (define_insn "*tablejump_1"
13177 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13178 (use (label_ref (match_operand 1 "" "")))]
13179 "!TARGET_64BIT"
13180 "jmp\t%A0"
13181 [(set_attr "type" "ibr")
13182 (set_attr "length_immediate" "0")])
13183
13184 (define_insn "*tablejump_1_rtx64"
13185 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13186 (use (label_ref (match_operand 1 "" "")))]
13187 "TARGET_64BIT"
13188 "jmp\t%A0"
13189 [(set_attr "type" "ibr")
13190 (set_attr "length_immediate" "0")])
13191 \f
13192 ;; Loop instruction
13193 ;;
13194 ;; This is all complicated by the fact that since this is a jump insn
13195 ;; we must handle our own reloads.
13196
13197 (define_expand "doloop_end"
13198 [(use (match_operand 0 "" "")) ; loop pseudo
13199 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13200 (use (match_operand 2 "" "")) ; max iterations
13201 (use (match_operand 3 "" "")) ; loop level
13202 (use (match_operand 4 "" ""))] ; label
13203 "!TARGET_64BIT && TARGET_USE_LOOP"
13204 "
13205 {
13206 /* Only use cloop on innermost loops. */
13207 if (INTVAL (operands[3]) > 1)
13208 FAIL;
13209 if (GET_MODE (operands[0]) != SImode)
13210 FAIL;
13211 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13212 operands[0]));
13213 DONE;
13214 }")
13215
13216 (define_insn "doloop_end_internal"
13217 [(set (pc)
13218 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13219 (const_int 1))
13220 (label_ref (match_operand 0 "" ""))
13221 (pc)))
13222 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13223 (plus:SI (match_dup 1)
13224 (const_int -1)))
13225 (clobber (match_scratch:SI 3 "=X,X,r"))
13226 (clobber (reg:CC FLAGS_REG))]
13227 "!TARGET_64BIT && TARGET_USE_LOOP
13228 && (reload_in_progress || reload_completed
13229 || register_operand (operands[2], VOIDmode))"
13230 {
13231 if (which_alternative != 0)
13232 return "#";
13233 if (get_attr_length (insn) == 2)
13234 return "%+loop\t%l0";
13235 else
13236 return "dec{l}\t%1\;%+jne\t%l0";
13237 }
13238 [(set (attr "length")
13239 (if_then_else (and (eq_attr "alternative" "0")
13240 (and (ge (minus (match_dup 0) (pc))
13241 (const_int -126))
13242 (lt (minus (match_dup 0) (pc))
13243 (const_int 128))))
13244 (const_int 2)
13245 (const_int 16)))
13246 ;; We don't know the type before shorten branches. Optimistically expect
13247 ;; the loop instruction to match.
13248 (set (attr "type") (const_string "ibr"))])
13249
13250 (define_split
13251 [(set (pc)
13252 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13253 (const_int 1))
13254 (match_operand 0 "" "")
13255 (pc)))
13256 (set (match_dup 1)
13257 (plus:SI (match_dup 1)
13258 (const_int -1)))
13259 (clobber (match_scratch:SI 2 ""))
13260 (clobber (reg:CC FLAGS_REG))]
13261 "!TARGET_64BIT && TARGET_USE_LOOP
13262 && reload_completed
13263 && REGNO (operands[1]) != 2"
13264 [(parallel [(set (reg:CCZ FLAGS_REG)
13265 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13266 (const_int 0)))
13267 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13268 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13269 (match_dup 0)
13270 (pc)))]
13271 "")
13272
13273 (define_split
13274 [(set (pc)
13275 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13276 (const_int 1))
13277 (match_operand 0 "" "")
13278 (pc)))
13279 (set (match_operand:SI 2 "nonimmediate_operand" "")
13280 (plus:SI (match_dup 1)
13281 (const_int -1)))
13282 (clobber (match_scratch:SI 3 ""))
13283 (clobber (reg:CC FLAGS_REG))]
13284 "!TARGET_64BIT && TARGET_USE_LOOP
13285 && reload_completed
13286 && (! REG_P (operands[2])
13287 || ! rtx_equal_p (operands[1], operands[2]))"
13288 [(set (match_dup 3) (match_dup 1))
13289 (parallel [(set (reg:CCZ FLAGS_REG)
13290 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13291 (const_int 0)))
13292 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13293 (set (match_dup 2) (match_dup 3))
13294 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13295 (match_dup 0)
13296 (pc)))]
13297 "")
13298
13299 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13300
13301 (define_peephole2
13302 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13303 (set (match_operand:QI 1 "register_operand" "")
13304 (match_operator:QI 2 "ix86_comparison_operator"
13305 [(reg FLAGS_REG) (const_int 0)]))
13306 (set (match_operand 3 "q_regs_operand" "")
13307 (zero_extend (match_dup 1)))]
13308 "(peep2_reg_dead_p (3, operands[1])
13309 || operands_match_p (operands[1], operands[3]))
13310 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13311 [(set (match_dup 4) (match_dup 0))
13312 (set (strict_low_part (match_dup 5))
13313 (match_dup 2))]
13314 {
13315 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13316 operands[5] = gen_lowpart (QImode, operands[3]);
13317 ix86_expand_clear (operands[3]);
13318 })
13319
13320 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13321
13322 (define_peephole2
13323 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13324 (set (match_operand:QI 1 "register_operand" "")
13325 (match_operator:QI 2 "ix86_comparison_operator"
13326 [(reg FLAGS_REG) (const_int 0)]))
13327 (parallel [(set (match_operand 3 "q_regs_operand" "")
13328 (zero_extend (match_dup 1)))
13329 (clobber (reg:CC FLAGS_REG))])]
13330 "(peep2_reg_dead_p (3, operands[1])
13331 || operands_match_p (operands[1], operands[3]))
13332 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13333 [(set (match_dup 4) (match_dup 0))
13334 (set (strict_low_part (match_dup 5))
13335 (match_dup 2))]
13336 {
13337 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13338 operands[5] = gen_lowpart (QImode, operands[3]);
13339 ix86_expand_clear (operands[3]);
13340 })
13341 \f
13342 ;; Call instructions.
13343
13344 ;; The predicates normally associated with named expanders are not properly
13345 ;; checked for calls. This is a bug in the generic code, but it isn't that
13346 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13347
13348 ;; Call subroutine returning no value.
13349
13350 (define_expand "call_pop"
13351 [(parallel [(call (match_operand:QI 0 "" "")
13352 (match_operand:SI 1 "" ""))
13353 (set (reg:SI SP_REG)
13354 (plus:SI (reg:SI SP_REG)
13355 (match_operand:SI 3 "" "")))])]
13356 "!TARGET_64BIT"
13357 {
13358 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13359 DONE;
13360 })
13361
13362 (define_insn "*call_pop_0"
13363 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13364 (match_operand:SI 1 "" ""))
13365 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13366 (match_operand:SI 2 "immediate_operand" "")))]
13367 "!TARGET_64BIT"
13368 {
13369 if (SIBLING_CALL_P (insn))
13370 return "jmp\t%P0";
13371 else
13372 return "call\t%P0";
13373 }
13374 [(set_attr "type" "call")])
13375
13376 (define_insn "*call_pop_1"
13377 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13378 (match_operand:SI 1 "" ""))
13379 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13380 (match_operand:SI 2 "immediate_operand" "i")))]
13381 "!TARGET_64BIT"
13382 {
13383 if (constant_call_address_operand (operands[0], Pmode))
13384 {
13385 if (SIBLING_CALL_P (insn))
13386 return "jmp\t%P0";
13387 else
13388 return "call\t%P0";
13389 }
13390 if (SIBLING_CALL_P (insn))
13391 return "jmp\t%A0";
13392 else
13393 return "call\t%A0";
13394 }
13395 [(set_attr "type" "call")])
13396
13397 (define_expand "call"
13398 [(call (match_operand:QI 0 "" "")
13399 (match_operand 1 "" ""))
13400 (use (match_operand 2 "" ""))]
13401 ""
13402 {
13403 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13404 DONE;
13405 })
13406
13407 (define_expand "sibcall"
13408 [(call (match_operand:QI 0 "" "")
13409 (match_operand 1 "" ""))
13410 (use (match_operand 2 "" ""))]
13411 ""
13412 {
13413 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13414 DONE;
13415 })
13416
13417 (define_insn "*call_0"
13418 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13419 (match_operand 1 "" ""))]
13420 ""
13421 {
13422 if (SIBLING_CALL_P (insn))
13423 return "jmp\t%P0";
13424 else
13425 return "call\t%P0";
13426 }
13427 [(set_attr "type" "call")])
13428
13429 (define_insn "*call_1"
13430 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13431 (match_operand 1 "" ""))]
13432 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13433 {
13434 if (constant_call_address_operand (operands[0], Pmode))
13435 return "call\t%P0";
13436 return "call\t%A0";
13437 }
13438 [(set_attr "type" "call")])
13439
13440 (define_insn "*sibcall_1"
13441 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13442 (match_operand 1 "" ""))]
13443 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13444 {
13445 if (constant_call_address_operand (operands[0], Pmode))
13446 return "jmp\t%P0";
13447 return "jmp\t%A0";
13448 }
13449 [(set_attr "type" "call")])
13450
13451 (define_insn "*call_1_rex64"
13452 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13453 (match_operand 1 "" ""))]
13454 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13455 {
13456 if (constant_call_address_operand (operands[0], Pmode))
13457 return "call\t%P0";
13458 return "call\t%A0";
13459 }
13460 [(set_attr "type" "call")])
13461
13462 (define_insn "*sibcall_1_rex64"
13463 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13464 (match_operand 1 "" ""))]
13465 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13466 "jmp\t%P0"
13467 [(set_attr "type" "call")])
13468
13469 (define_insn "*sibcall_1_rex64_v"
13470 [(call (mem:QI (reg:DI 40))
13471 (match_operand 0 "" ""))]
13472 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13473 "jmp\t*%%r11"
13474 [(set_attr "type" "call")])
13475
13476
13477 ;; Call subroutine, returning value in operand 0
13478
13479 (define_expand "call_value_pop"
13480 [(parallel [(set (match_operand 0 "" "")
13481 (call (match_operand:QI 1 "" "")
13482 (match_operand:SI 2 "" "")))
13483 (set (reg:SI SP_REG)
13484 (plus:SI (reg:SI SP_REG)
13485 (match_operand:SI 4 "" "")))])]
13486 "!TARGET_64BIT"
13487 {
13488 ix86_expand_call (operands[0], operands[1], operands[2],
13489 operands[3], operands[4], 0);
13490 DONE;
13491 })
13492
13493 (define_expand "call_value"
13494 [(set (match_operand 0 "" "")
13495 (call (match_operand:QI 1 "" "")
13496 (match_operand:SI 2 "" "")))
13497 (use (match_operand:SI 3 "" ""))]
13498 ;; Operand 2 not used on the i386.
13499 ""
13500 {
13501 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13502 DONE;
13503 })
13504
13505 (define_expand "sibcall_value"
13506 [(set (match_operand 0 "" "")
13507 (call (match_operand:QI 1 "" "")
13508 (match_operand:SI 2 "" "")))
13509 (use (match_operand:SI 3 "" ""))]
13510 ;; Operand 2 not used on the i386.
13511 ""
13512 {
13513 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13514 DONE;
13515 })
13516
13517 ;; Call subroutine returning any type.
13518
13519 (define_expand "untyped_call"
13520 [(parallel [(call (match_operand 0 "" "")
13521 (const_int 0))
13522 (match_operand 1 "" "")
13523 (match_operand 2 "" "")])]
13524 ""
13525 {
13526 int i;
13527
13528 /* In order to give reg-stack an easier job in validating two
13529 coprocessor registers as containing a possible return value,
13530 simply pretend the untyped call returns a complex long double
13531 value. */
13532
13533 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13534 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13535 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13536 NULL, 0);
13537
13538 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13539 {
13540 rtx set = XVECEXP (operands[2], 0, i);
13541 emit_move_insn (SET_DEST (set), SET_SRC (set));
13542 }
13543
13544 /* The optimizer does not know that the call sets the function value
13545 registers we stored in the result block. We avoid problems by
13546 claiming that all hard registers are used and clobbered at this
13547 point. */
13548 emit_insn (gen_blockage (const0_rtx));
13549
13550 DONE;
13551 })
13552 \f
13553 ;; Prologue and epilogue instructions
13554
13555 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13556 ;; all of memory. This blocks insns from being moved across this point.
13557
13558 (define_insn "blockage"
13559 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13560 ""
13561 ""
13562 [(set_attr "length" "0")])
13563
13564 ;; Insn emitted into the body of a function to return from a function.
13565 ;; This is only done if the function's epilogue is known to be simple.
13566 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13567
13568 (define_expand "return"
13569 [(return)]
13570 "ix86_can_use_return_insn_p ()"
13571 {
13572 if (current_function_pops_args)
13573 {
13574 rtx popc = GEN_INT (current_function_pops_args);
13575 emit_jump_insn (gen_return_pop_internal (popc));
13576 DONE;
13577 }
13578 })
13579
13580 (define_insn "return_internal"
13581 [(return)]
13582 "reload_completed"
13583 "ret"
13584 [(set_attr "length" "1")
13585 (set_attr "length_immediate" "0")
13586 (set_attr "modrm" "0")])
13587
13588 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13589 ;; instruction Athlon and K8 have.
13590
13591 (define_insn "return_internal_long"
13592 [(return)
13593 (unspec [(const_int 0)] UNSPEC_REP)]
13594 "reload_completed"
13595 "rep {;} ret"
13596 [(set_attr "length" "1")
13597 (set_attr "length_immediate" "0")
13598 (set_attr "prefix_rep" "1")
13599 (set_attr "modrm" "0")])
13600
13601 (define_insn "return_pop_internal"
13602 [(return)
13603 (use (match_operand:SI 0 "const_int_operand" ""))]
13604 "reload_completed"
13605 "ret\t%0"
13606 [(set_attr "length" "3")
13607 (set_attr "length_immediate" "2")
13608 (set_attr "modrm" "0")])
13609
13610 (define_insn "return_indirect_internal"
13611 [(return)
13612 (use (match_operand:SI 0 "register_operand" "r"))]
13613 "reload_completed"
13614 "jmp\t%A0"
13615 [(set_attr "type" "ibr")
13616 (set_attr "length_immediate" "0")])
13617
13618 (define_insn "nop"
13619 [(const_int 0)]
13620 ""
13621 "nop"
13622 [(set_attr "length" "1")
13623 (set_attr "length_immediate" "0")
13624 (set_attr "modrm" "0")])
13625
13626 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13627 ;; branch prediction penalty for the third jump in a 16-byte
13628 ;; block on K8.
13629
13630 (define_insn "align"
13631 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13632 ""
13633 {
13634 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13635 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13636 #else
13637 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13638 The align insn is used to avoid 3 jump instructions in the row to improve
13639 branch prediction and the benefits hardly outweight the cost of extra 8
13640 nops on the average inserted by full alignment pseudo operation. */
13641 #endif
13642 return "";
13643 }
13644 [(set_attr "length" "16")])
13645
13646 (define_expand "prologue"
13647 [(const_int 1)]
13648 ""
13649 "ix86_expand_prologue (); DONE;")
13650
13651 (define_insn "set_got"
13652 [(set (match_operand:SI 0 "register_operand" "=r")
13653 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13654 (clobber (reg:CC FLAGS_REG))]
13655 "!TARGET_64BIT"
13656 { return output_set_got (operands[0]); }
13657 [(set_attr "type" "multi")
13658 (set_attr "length" "12")])
13659
13660 (define_expand "epilogue"
13661 [(const_int 1)]
13662 ""
13663 "ix86_expand_epilogue (1); DONE;")
13664
13665 (define_expand "sibcall_epilogue"
13666 [(const_int 1)]
13667 ""
13668 "ix86_expand_epilogue (0); DONE;")
13669
13670 (define_expand "eh_return"
13671 [(use (match_operand 0 "register_operand" ""))]
13672 ""
13673 {
13674 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13675
13676 /* Tricky bit: we write the address of the handler to which we will
13677 be returning into someone else's stack frame, one word below the
13678 stack address we wish to restore. */
13679 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13680 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13681 tmp = gen_rtx_MEM (Pmode, tmp);
13682 emit_move_insn (tmp, ra);
13683
13684 if (Pmode == SImode)
13685 emit_jump_insn (gen_eh_return_si (sa));
13686 else
13687 emit_jump_insn (gen_eh_return_di (sa));
13688 emit_barrier ();
13689 DONE;
13690 })
13691
13692 (define_insn_and_split "eh_return_si"
13693 [(set (pc)
13694 (unspec [(match_operand:SI 0 "register_operand" "c")]
13695 UNSPEC_EH_RETURN))]
13696 "!TARGET_64BIT"
13697 "#"
13698 "reload_completed"
13699 [(const_int 1)]
13700 "ix86_expand_epilogue (2); DONE;")
13701
13702 (define_insn_and_split "eh_return_di"
13703 [(set (pc)
13704 (unspec [(match_operand:DI 0 "register_operand" "c")]
13705 UNSPEC_EH_RETURN))]
13706 "TARGET_64BIT"
13707 "#"
13708 "reload_completed"
13709 [(const_int 1)]
13710 "ix86_expand_epilogue (2); DONE;")
13711
13712 (define_insn "leave"
13713 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13714 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13715 (clobber (mem:BLK (scratch)))]
13716 "!TARGET_64BIT"
13717 "leave"
13718 [(set_attr "type" "leave")])
13719
13720 (define_insn "leave_rex64"
13721 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13722 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13723 (clobber (mem:BLK (scratch)))]
13724 "TARGET_64BIT"
13725 "leave"
13726 [(set_attr "type" "leave")])
13727 \f
13728 (define_expand "ffssi2"
13729 [(parallel
13730 [(set (match_operand:SI 0 "register_operand" "")
13731 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13732 (clobber (match_scratch:SI 2 ""))
13733 (clobber (reg:CC FLAGS_REG))])]
13734 ""
13735 "")
13736
13737 (define_insn_and_split "*ffs_cmove"
13738 [(set (match_operand:SI 0 "register_operand" "=r")
13739 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13740 (clobber (match_scratch:SI 2 "=&r"))
13741 (clobber (reg:CC FLAGS_REG))]
13742 "TARGET_CMOVE"
13743 "#"
13744 "&& reload_completed"
13745 [(set (match_dup 2) (const_int -1))
13746 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13747 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13748 (set (match_dup 0) (if_then_else:SI
13749 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13750 (match_dup 2)
13751 (match_dup 0)))
13752 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13753 (clobber (reg:CC FLAGS_REG))])]
13754 "")
13755
13756 (define_insn_and_split "*ffs_no_cmove"
13757 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13758 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13759 (clobber (match_scratch:SI 2 "=&q"))
13760 (clobber (reg:CC FLAGS_REG))]
13761 ""
13762 "#"
13763 "reload_completed"
13764 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13765 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13766 (set (strict_low_part (match_dup 3))
13767 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13768 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13769 (clobber (reg:CC FLAGS_REG))])
13770 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13771 (clobber (reg:CC FLAGS_REG))])
13772 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13773 (clobber (reg:CC FLAGS_REG))])]
13774 {
13775 operands[3] = gen_lowpart (QImode, operands[2]);
13776 ix86_expand_clear (operands[2]);
13777 })
13778
13779 (define_insn "*ffssi_1"
13780 [(set (reg:CCZ FLAGS_REG)
13781 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13782 (const_int 0)))
13783 (set (match_operand:SI 0 "register_operand" "=r")
13784 (ctz:SI (match_dup 1)))]
13785 ""
13786 "bsf{l}\t{%1, %0|%0, %1}"
13787 [(set_attr "prefix_0f" "1")])
13788
13789 (define_expand "ffsdi2"
13790 [(parallel
13791 [(set (match_operand:DI 0 "register_operand" "")
13792 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13793 (clobber (match_scratch:DI 2 ""))
13794 (clobber (reg:CC FLAGS_REG))])]
13795 "TARGET_64BIT && TARGET_CMOVE"
13796 "")
13797
13798 (define_insn_and_split "*ffs_rex64"
13799 [(set (match_operand:DI 0 "register_operand" "=r")
13800 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13801 (clobber (match_scratch:DI 2 "=&r"))
13802 (clobber (reg:CC FLAGS_REG))]
13803 "TARGET_64BIT && TARGET_CMOVE"
13804 "#"
13805 "&& reload_completed"
13806 [(set (match_dup 2) (const_int -1))
13807 (parallel [(set (reg:CCZ FLAGS_REG)
13808 (compare:CCZ (match_dup 1) (const_int 0)))
13809 (set (match_dup 0) (ctz:DI (match_dup 1)))])
13810 (set (match_dup 0) (if_then_else:DI
13811 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13812 (match_dup 2)
13813 (match_dup 0)))
13814 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13815 (clobber (reg:CC FLAGS_REG))])]
13816 "")
13817
13818 (define_insn "*ffsdi_1"
13819 [(set (reg:CCZ FLAGS_REG)
13820 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13821 (const_int 0)))
13822 (set (match_operand:DI 0 "register_operand" "=r")
13823 (ctz:DI (match_dup 1)))]
13824 "TARGET_64BIT"
13825 "bsf{q}\t{%1, %0|%0, %1}"
13826 [(set_attr "prefix_0f" "1")])
13827
13828 (define_insn "ctzsi2"
13829 [(set (match_operand:SI 0 "register_operand" "=r")
13830 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13831 (clobber (reg:CC FLAGS_REG))]
13832 ""
13833 "bsf{l}\t{%1, %0|%0, %1}"
13834 [(set_attr "prefix_0f" "1")])
13835
13836 (define_insn "ctzdi2"
13837 [(set (match_operand:DI 0 "register_operand" "=r")
13838 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13839 (clobber (reg:CC FLAGS_REG))]
13840 "TARGET_64BIT"
13841 "bsf{q}\t{%1, %0|%0, %1}"
13842 [(set_attr "prefix_0f" "1")])
13843
13844 (define_expand "clzsi2"
13845 [(parallel
13846 [(set (match_operand:SI 0 "register_operand" "")
13847 (minus:SI (const_int 31)
13848 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13849 (clobber (reg:CC FLAGS_REG))])
13850 (parallel
13851 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13852 (clobber (reg:CC FLAGS_REG))])]
13853 ""
13854 "")
13855
13856 (define_insn "*bsr"
13857 [(set (match_operand:SI 0 "register_operand" "=r")
13858 (minus:SI (const_int 31)
13859 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13860 (clobber (reg:CC FLAGS_REG))]
13861 ""
13862 "bsr{l}\t{%1, %0|%0, %1}"
13863 [(set_attr "prefix_0f" "1")])
13864
13865 (define_expand "clzdi2"
13866 [(parallel
13867 [(set (match_operand:DI 0 "register_operand" "")
13868 (minus:DI (const_int 63)
13869 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13870 (clobber (reg:CC FLAGS_REG))])
13871 (parallel
13872 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13873 (clobber (reg:CC FLAGS_REG))])]
13874 "TARGET_64BIT"
13875 "")
13876
13877 (define_insn "*bsr_rex64"
13878 [(set (match_operand:DI 0 "register_operand" "=r")
13879 (minus:DI (const_int 63)
13880 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13881 (clobber (reg:CC FLAGS_REG))]
13882 "TARGET_64BIT"
13883 "bsr{q}\t{%1, %0|%0, %1}"
13884 [(set_attr "prefix_0f" "1")])
13885 \f
13886 ;; Thread-local storage patterns for ELF.
13887 ;;
13888 ;; Note that these code sequences must appear exactly as shown
13889 ;; in order to allow linker relaxation.
13890
13891 (define_insn "*tls_global_dynamic_32_gnu"
13892 [(set (match_operand:SI 0 "register_operand" "=a")
13893 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13894 (match_operand:SI 2 "tls_symbolic_operand" "")
13895 (match_operand:SI 3 "call_insn_operand" "")]
13896 UNSPEC_TLS_GD))
13897 (clobber (match_scratch:SI 4 "=d"))
13898 (clobber (match_scratch:SI 5 "=c"))
13899 (clobber (reg:CC FLAGS_REG))]
13900 "!TARGET_64BIT && TARGET_GNU_TLS"
13901 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13902 [(set_attr "type" "multi")
13903 (set_attr "length" "12")])
13904
13905 (define_insn "*tls_global_dynamic_32_sun"
13906 [(set (match_operand:SI 0 "register_operand" "=a")
13907 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13908 (match_operand:SI 2 "tls_symbolic_operand" "")
13909 (match_operand:SI 3 "call_insn_operand" "")]
13910 UNSPEC_TLS_GD))
13911 (clobber (match_scratch:SI 4 "=d"))
13912 (clobber (match_scratch:SI 5 "=c"))
13913 (clobber (reg:CC FLAGS_REG))]
13914 "!TARGET_64BIT && TARGET_SUN_TLS"
13915 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13916 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13917 [(set_attr "type" "multi")
13918 (set_attr "length" "14")])
13919
13920 (define_expand "tls_global_dynamic_32"
13921 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13922 (unspec:SI
13923 [(match_dup 2)
13924 (match_operand:SI 1 "tls_symbolic_operand" "")
13925 (match_dup 3)]
13926 UNSPEC_TLS_GD))
13927 (clobber (match_scratch:SI 4 ""))
13928 (clobber (match_scratch:SI 5 ""))
13929 (clobber (reg:CC FLAGS_REG))])]
13930 ""
13931 {
13932 if (flag_pic)
13933 operands[2] = pic_offset_table_rtx;
13934 else
13935 {
13936 operands[2] = gen_reg_rtx (Pmode);
13937 emit_insn (gen_set_got (operands[2]));
13938 }
13939 operands[3] = ix86_tls_get_addr ();
13940 })
13941
13942 (define_insn "*tls_global_dynamic_64"
13943 [(set (match_operand:DI 0 "register_operand" "=a")
13944 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13945 (match_operand:DI 3 "" "")))
13946 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13947 UNSPEC_TLS_GD)]
13948 "TARGET_64BIT"
13949 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13950 [(set_attr "type" "multi")
13951 (set_attr "length" "16")])
13952
13953 (define_expand "tls_global_dynamic_64"
13954 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13955 (call (mem:QI (match_dup 2)) (const_int 0)))
13956 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13957 UNSPEC_TLS_GD)])]
13958 ""
13959 {
13960 operands[2] = ix86_tls_get_addr ();
13961 })
13962
13963 (define_insn "*tls_local_dynamic_base_32_gnu"
13964 [(set (match_operand:SI 0 "register_operand" "=a")
13965 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13966 (match_operand:SI 2 "call_insn_operand" "")]
13967 UNSPEC_TLS_LD_BASE))
13968 (clobber (match_scratch:SI 3 "=d"))
13969 (clobber (match_scratch:SI 4 "=c"))
13970 (clobber (reg:CC FLAGS_REG))]
13971 "!TARGET_64BIT && TARGET_GNU_TLS"
13972 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13973 [(set_attr "type" "multi")
13974 (set_attr "length" "11")])
13975
13976 (define_insn "*tls_local_dynamic_base_32_sun"
13977 [(set (match_operand:SI 0 "register_operand" "=a")
13978 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13979 (match_operand:SI 2 "call_insn_operand" "")]
13980 UNSPEC_TLS_LD_BASE))
13981 (clobber (match_scratch:SI 3 "=d"))
13982 (clobber (match_scratch:SI 4 "=c"))
13983 (clobber (reg:CC FLAGS_REG))]
13984 "!TARGET_64BIT && TARGET_SUN_TLS"
13985 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13986 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13987 [(set_attr "type" "multi")
13988 (set_attr "length" "13")])
13989
13990 (define_expand "tls_local_dynamic_base_32"
13991 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13992 (unspec:SI [(match_dup 1) (match_dup 2)]
13993 UNSPEC_TLS_LD_BASE))
13994 (clobber (match_scratch:SI 3 ""))
13995 (clobber (match_scratch:SI 4 ""))
13996 (clobber (reg:CC FLAGS_REG))])]
13997 ""
13998 {
13999 if (flag_pic)
14000 operands[1] = pic_offset_table_rtx;
14001 else
14002 {
14003 operands[1] = gen_reg_rtx (Pmode);
14004 emit_insn (gen_set_got (operands[1]));
14005 }
14006 operands[2] = ix86_tls_get_addr ();
14007 })
14008
14009 (define_insn "*tls_local_dynamic_base_64"
14010 [(set (match_operand:DI 0 "register_operand" "=a")
14011 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14012 (match_operand:DI 2 "" "")))
14013 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14014 "TARGET_64BIT"
14015 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14016 [(set_attr "type" "multi")
14017 (set_attr "length" "12")])
14018
14019 (define_expand "tls_local_dynamic_base_64"
14020 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14021 (call (mem:QI (match_dup 1)) (const_int 0)))
14022 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14023 ""
14024 {
14025 operands[1] = ix86_tls_get_addr ();
14026 })
14027
14028 ;; Local dynamic of a single variable is a lose. Show combine how
14029 ;; to convert that back to global dynamic.
14030
14031 (define_insn_and_split "*tls_local_dynamic_32_once"
14032 [(set (match_operand:SI 0 "register_operand" "=a")
14033 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14034 (match_operand:SI 2 "call_insn_operand" "")]
14035 UNSPEC_TLS_LD_BASE)
14036 (const:SI (unspec:SI
14037 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14038 UNSPEC_DTPOFF))))
14039 (clobber (match_scratch:SI 4 "=d"))
14040 (clobber (match_scratch:SI 5 "=c"))
14041 (clobber (reg:CC FLAGS_REG))]
14042 ""
14043 "#"
14044 ""
14045 [(parallel [(set (match_dup 0)
14046 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14047 UNSPEC_TLS_GD))
14048 (clobber (match_dup 4))
14049 (clobber (match_dup 5))
14050 (clobber (reg:CC FLAGS_REG))])]
14051 "")
14052
14053 ;; Load and add the thread base pointer from %gs:0.
14054
14055 (define_insn "*load_tp_si"
14056 [(set (match_operand:SI 0 "register_operand" "=r")
14057 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14058 "!TARGET_64BIT"
14059 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14060 [(set_attr "type" "imov")
14061 (set_attr "modrm" "0")
14062 (set_attr "length" "7")
14063 (set_attr "memory" "load")
14064 (set_attr "imm_disp" "false")])
14065
14066 (define_insn "*add_tp_si"
14067 [(set (match_operand:SI 0 "register_operand" "=r")
14068 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14069 (match_operand:SI 1 "register_operand" "0")))
14070 (clobber (reg:CC FLAGS_REG))]
14071 "!TARGET_64BIT"
14072 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14073 [(set_attr "type" "alu")
14074 (set_attr "modrm" "0")
14075 (set_attr "length" "7")
14076 (set_attr "memory" "load")
14077 (set_attr "imm_disp" "false")])
14078
14079 (define_insn "*load_tp_di"
14080 [(set (match_operand:DI 0 "register_operand" "=r")
14081 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14082 "TARGET_64BIT"
14083 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14084 [(set_attr "type" "imov")
14085 (set_attr "modrm" "0")
14086 (set_attr "length" "7")
14087 (set_attr "memory" "load")
14088 (set_attr "imm_disp" "false")])
14089
14090 (define_insn "*add_tp_di"
14091 [(set (match_operand:DI 0 "register_operand" "=r")
14092 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14093 (match_operand:DI 1 "register_operand" "0")))
14094 (clobber (reg:CC FLAGS_REG))]
14095 "TARGET_64BIT"
14096 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14097 [(set_attr "type" "alu")
14098 (set_attr "modrm" "0")
14099 (set_attr "length" "7")
14100 (set_attr "memory" "load")
14101 (set_attr "imm_disp" "false")])
14102 \f
14103 ;; These patterns match the binary 387 instructions for addM3, subM3,
14104 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14105 ;; SFmode. The first is the normal insn, the second the same insn but
14106 ;; with one operand a conversion, and the third the same insn but with
14107 ;; the other operand a conversion. The conversion may be SFmode or
14108 ;; SImode if the target mode DFmode, but only SImode if the target mode
14109 ;; is SFmode.
14110
14111 ;; Gcc is slightly more smart about handling normal two address instructions
14112 ;; so use special patterns for add and mull.
14113
14114 (define_insn "*fop_sf_comm_mixed"
14115 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14116 (match_operator:SF 3 "binary_fp_operator"
14117 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14118 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14119 "TARGET_MIX_SSE_I387
14120 && COMMUTATIVE_ARITH_P (operands[3])
14121 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14122 "* return output_387_binary_op (insn, operands);"
14123 [(set (attr "type")
14124 (if_then_else (eq_attr "alternative" "1")
14125 (if_then_else (match_operand:SF 3 "mult_operator" "")
14126 (const_string "ssemul")
14127 (const_string "sseadd"))
14128 (if_then_else (match_operand:SF 3 "mult_operator" "")
14129 (const_string "fmul")
14130 (const_string "fop"))))
14131 (set_attr "mode" "SF")])
14132
14133 (define_insn "*fop_sf_comm_sse"
14134 [(set (match_operand:SF 0 "register_operand" "=x")
14135 (match_operator:SF 3 "binary_fp_operator"
14136 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14137 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14138 "TARGET_SSE_MATH
14139 && COMMUTATIVE_ARITH_P (operands[3])
14140 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14141 "* return output_387_binary_op (insn, operands);"
14142 [(set (attr "type")
14143 (if_then_else (match_operand:SF 3 "mult_operator" "")
14144 (const_string "ssemul")
14145 (const_string "sseadd")))
14146 (set_attr "mode" "SF")])
14147
14148 (define_insn "*fop_sf_comm_i387"
14149 [(set (match_operand:SF 0 "register_operand" "=f")
14150 (match_operator:SF 3 "binary_fp_operator"
14151 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14152 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14153 "TARGET_80387
14154 && COMMUTATIVE_ARITH_P (operands[3])
14155 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14156 "* return output_387_binary_op (insn, operands);"
14157 [(set (attr "type")
14158 (if_then_else (match_operand:SF 3 "mult_operator" "")
14159 (const_string "fmul")
14160 (const_string "fop")))
14161 (set_attr "mode" "SF")])
14162
14163 (define_insn "*fop_sf_1_mixed"
14164 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14165 (match_operator:SF 3 "binary_fp_operator"
14166 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14167 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14168 "TARGET_MIX_SSE_I387
14169 && !COMMUTATIVE_ARITH_P (operands[3])
14170 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14171 "* return output_387_binary_op (insn, operands);"
14172 [(set (attr "type")
14173 (cond [(and (eq_attr "alternative" "2")
14174 (match_operand:SF 3 "mult_operator" ""))
14175 (const_string "ssemul")
14176 (and (eq_attr "alternative" "2")
14177 (match_operand:SF 3 "div_operator" ""))
14178 (const_string "ssediv")
14179 (eq_attr "alternative" "2")
14180 (const_string "sseadd")
14181 (match_operand:SF 3 "mult_operator" "")
14182 (const_string "fmul")
14183 (match_operand:SF 3 "div_operator" "")
14184 (const_string "fdiv")
14185 ]
14186 (const_string "fop")))
14187 (set_attr "mode" "SF")])
14188
14189 (define_insn "*fop_sf_1_sse"
14190 [(set (match_operand:SF 0 "register_operand" "=x")
14191 (match_operator:SF 3 "binary_fp_operator"
14192 [(match_operand:SF 1 "register_operand" "0")
14193 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14194 "TARGET_SSE_MATH
14195 && !COMMUTATIVE_ARITH_P (operands[3])"
14196 "* return output_387_binary_op (insn, operands);"
14197 [(set (attr "type")
14198 (cond [(match_operand:SF 3 "mult_operator" "")
14199 (const_string "ssemul")
14200 (match_operand:SF 3 "div_operator" "")
14201 (const_string "ssediv")
14202 ]
14203 (const_string "sseadd")))
14204 (set_attr "mode" "SF")])
14205
14206 ;; This pattern is not fully shadowed by the pattern above.
14207 (define_insn "*fop_sf_1_i387"
14208 [(set (match_operand:SF 0 "register_operand" "=f,f")
14209 (match_operator:SF 3 "binary_fp_operator"
14210 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14211 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14212 "TARGET_80387 && !TARGET_SSE_MATH
14213 && !COMMUTATIVE_ARITH_P (operands[3])
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:SF 3 "mult_operator" "")
14218 (const_string "fmul")
14219 (match_operand:SF 3 "div_operator" "")
14220 (const_string "fdiv")
14221 ]
14222 (const_string "fop")))
14223 (set_attr "mode" "SF")])
14224
14225
14226 ;; ??? Add SSE splitters for these!
14227 (define_insn "*fop_sf_2_i387"
14228 [(set (match_operand:SF 0 "register_operand" "=f,f")
14229 (match_operator:SF 3 "binary_fp_operator"
14230 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14231 (match_operand:SF 2 "register_operand" "0,0")]))]
14232 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14233 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14234 [(set (attr "type")
14235 (cond [(match_operand:SF 3 "mult_operator" "")
14236 (const_string "fmul")
14237 (match_operand:SF 3 "div_operator" "")
14238 (const_string "fdiv")
14239 ]
14240 (const_string "fop")))
14241 (set_attr "fp_int_src" "true")
14242 (set_attr "mode" "SI")])
14243
14244 (define_insn "*fop_sf_3_i387"
14245 [(set (match_operand:SF 0 "register_operand" "=f,f")
14246 (match_operator:SF 3 "binary_fp_operator"
14247 [(match_operand:SF 1 "register_operand" "0,0")
14248 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14249 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14250 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14251 [(set (attr "type")
14252 (cond [(match_operand:SF 3 "mult_operator" "")
14253 (const_string "fmul")
14254 (match_operand:SF 3 "div_operator" "")
14255 (const_string "fdiv")
14256 ]
14257 (const_string "fop")))
14258 (set_attr "fp_int_src" "true")
14259 (set_attr "mode" "SI")])
14260
14261 (define_insn "*fop_df_comm_mixed"
14262 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14263 (match_operator:DF 3 "binary_fp_operator"
14264 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14265 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14266 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14267 && COMMUTATIVE_ARITH_P (operands[3])
14268 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14269 "* return output_387_binary_op (insn, operands);"
14270 [(set (attr "type")
14271 (if_then_else (eq_attr "alternative" "1")
14272 (if_then_else (match_operand:SF 3 "mult_operator" "")
14273 (const_string "ssemul")
14274 (const_string "sseadd"))
14275 (if_then_else (match_operand:SF 3 "mult_operator" "")
14276 (const_string "fmul")
14277 (const_string "fop"))))
14278 (set_attr "mode" "DF")])
14279
14280 (define_insn "*fop_df_comm_sse"
14281 [(set (match_operand:DF 0 "register_operand" "=Y")
14282 (match_operator:DF 3 "binary_fp_operator"
14283 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14284 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14285 "TARGET_SSE2 && TARGET_SSE_MATH
14286 && COMMUTATIVE_ARITH_P (operands[3])
14287 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14288 "* return output_387_binary_op (insn, operands);"
14289 [(set (attr "type")
14290 (if_then_else (match_operand:SF 3 "mult_operator" "")
14291 (const_string "ssemul")
14292 (const_string "sseadd")))
14293 (set_attr "mode" "DF")])
14294
14295 (define_insn "*fop_df_comm_i387"
14296 [(set (match_operand:DF 0 "register_operand" "=f")
14297 (match_operator:DF 3 "binary_fp_operator"
14298 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14299 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14300 "TARGET_80387
14301 && COMMUTATIVE_ARITH_P (operands[3])
14302 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14303 "* return output_387_binary_op (insn, operands);"
14304 [(set (attr "type")
14305 (if_then_else (match_operand:SF 3 "mult_operator" "")
14306 (const_string "fmul")
14307 (const_string "fop")))
14308 (set_attr "mode" "DF")])
14309
14310 (define_insn "*fop_df_1_mixed"
14311 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14312 (match_operator:DF 3 "binary_fp_operator"
14313 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14314 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14315 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14316 && !COMMUTATIVE_ARITH_P (operands[3])
14317 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14318 "* return output_387_binary_op (insn, operands);"
14319 [(set (attr "type")
14320 (cond [(and (eq_attr "alternative" "2")
14321 (match_operand:SF 3 "mult_operator" ""))
14322 (const_string "ssemul")
14323 (and (eq_attr "alternative" "2")
14324 (match_operand:SF 3 "div_operator" ""))
14325 (const_string "ssediv")
14326 (eq_attr "alternative" "2")
14327 (const_string "sseadd")
14328 (match_operand:DF 3 "mult_operator" "")
14329 (const_string "fmul")
14330 (match_operand:DF 3 "div_operator" "")
14331 (const_string "fdiv")
14332 ]
14333 (const_string "fop")))
14334 (set_attr "mode" "DF")])
14335
14336 (define_insn "*fop_df_1_sse"
14337 [(set (match_operand:DF 0 "register_operand" "=Y")
14338 (match_operator:DF 3 "binary_fp_operator"
14339 [(match_operand:DF 1 "register_operand" "0")
14340 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14341 "TARGET_SSE2 && TARGET_SSE_MATH
14342 && !COMMUTATIVE_ARITH_P (operands[3])"
14343 "* return output_387_binary_op (insn, operands);"
14344 [(set_attr "mode" "DF")
14345 (set (attr "type")
14346 (cond [(match_operand:SF 3 "mult_operator" "")
14347 (const_string "ssemul")
14348 (match_operand:SF 3 "div_operator" "")
14349 (const_string "ssediv")
14350 ]
14351 (const_string "sseadd")))])
14352
14353 ;; This pattern is not fully shadowed by the pattern above.
14354 (define_insn "*fop_df_1_i387"
14355 [(set (match_operand:DF 0 "register_operand" "=f,f")
14356 (match_operator:DF 3 "binary_fp_operator"
14357 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14358 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14359 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14360 && !COMMUTATIVE_ARITH_P (operands[3])
14361 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14362 "* return output_387_binary_op (insn, operands);"
14363 [(set (attr "type")
14364 (cond [(match_operand:DF 3 "mult_operator" "")
14365 (const_string "fmul")
14366 (match_operand:DF 3 "div_operator" "")
14367 (const_string "fdiv")
14368 ]
14369 (const_string "fop")))
14370 (set_attr "mode" "DF")])
14371
14372 ;; ??? Add SSE splitters for these!
14373 (define_insn "*fop_df_2_i387"
14374 [(set (match_operand:DF 0 "register_operand" "=f,f")
14375 (match_operator:DF 3 "binary_fp_operator"
14376 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14377 (match_operand:DF 2 "register_operand" "0,0")]))]
14378 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14379 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14380 [(set (attr "type")
14381 (cond [(match_operand:DF 3 "mult_operator" "")
14382 (const_string "fmul")
14383 (match_operand:DF 3 "div_operator" "")
14384 (const_string "fdiv")
14385 ]
14386 (const_string "fop")))
14387 (set_attr "fp_int_src" "true")
14388 (set_attr "mode" "SI")])
14389
14390 (define_insn "*fop_df_3_i387"
14391 [(set (match_operand:DF 0 "register_operand" "=f,f")
14392 (match_operator:DF 3 "binary_fp_operator"
14393 [(match_operand:DF 1 "register_operand" "0,0")
14394 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14395 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14396 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14397 [(set (attr "type")
14398 (cond [(match_operand:DF 3 "mult_operator" "")
14399 (const_string "fmul")
14400 (match_operand:DF 3 "div_operator" "")
14401 (const_string "fdiv")
14402 ]
14403 (const_string "fop")))
14404 (set_attr "fp_int_src" "true")
14405 (set_attr "mode" "SI")])
14406
14407 (define_insn "*fop_df_4_i387"
14408 [(set (match_operand:DF 0 "register_operand" "=f,f")
14409 (match_operator:DF 3 "binary_fp_operator"
14410 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14411 (match_operand:DF 2 "register_operand" "0,f")]))]
14412 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14413 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14414 "* return output_387_binary_op (insn, operands);"
14415 [(set (attr "type")
14416 (cond [(match_operand:DF 3 "mult_operator" "")
14417 (const_string "fmul")
14418 (match_operand:DF 3 "div_operator" "")
14419 (const_string "fdiv")
14420 ]
14421 (const_string "fop")))
14422 (set_attr "mode" "SF")])
14423
14424 (define_insn "*fop_df_5_i387"
14425 [(set (match_operand:DF 0 "register_operand" "=f,f")
14426 (match_operator:DF 3 "binary_fp_operator"
14427 [(match_operand:DF 1 "register_operand" "0,f")
14428 (float_extend:DF
14429 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14430 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14431 "* return output_387_binary_op (insn, operands);"
14432 [(set (attr "type")
14433 (cond [(match_operand:DF 3 "mult_operator" "")
14434 (const_string "fmul")
14435 (match_operand:DF 3 "div_operator" "")
14436 (const_string "fdiv")
14437 ]
14438 (const_string "fop")))
14439 (set_attr "mode" "SF")])
14440
14441 (define_insn "*fop_df_6_i387"
14442 [(set (match_operand:DF 0 "register_operand" "=f,f")
14443 (match_operator:DF 3 "binary_fp_operator"
14444 [(float_extend:DF
14445 (match_operand:SF 1 "register_operand" "0,f"))
14446 (float_extend:DF
14447 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14448 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14449 "* return output_387_binary_op (insn, operands);"
14450 [(set (attr "type")
14451 (cond [(match_operand:DF 3 "mult_operator" "")
14452 (const_string "fmul")
14453 (match_operand:DF 3 "div_operator" "")
14454 (const_string "fdiv")
14455 ]
14456 (const_string "fop")))
14457 (set_attr "mode" "SF")])
14458
14459 (define_insn "*fop_xf_comm_i387"
14460 [(set (match_operand:XF 0 "register_operand" "=f")
14461 (match_operator:XF 3 "binary_fp_operator"
14462 [(match_operand:XF 1 "register_operand" "%0")
14463 (match_operand:XF 2 "register_operand" "f")]))]
14464 "TARGET_80387
14465 && COMMUTATIVE_ARITH_P (operands[3])"
14466 "* return output_387_binary_op (insn, operands);"
14467 [(set (attr "type")
14468 (if_then_else (match_operand:XF 3 "mult_operator" "")
14469 (const_string "fmul")
14470 (const_string "fop")))
14471 (set_attr "mode" "XF")])
14472
14473 (define_insn "*fop_xf_1_i387"
14474 [(set (match_operand:XF 0 "register_operand" "=f,f")
14475 (match_operator:XF 3 "binary_fp_operator"
14476 [(match_operand:XF 1 "register_operand" "0,f")
14477 (match_operand:XF 2 "register_operand" "f,0")]))]
14478 "TARGET_80387
14479 && !COMMUTATIVE_ARITH_P (operands[3])"
14480 "* return output_387_binary_op (insn, operands);"
14481 [(set (attr "type")
14482 (cond [(match_operand:XF 3 "mult_operator" "")
14483 (const_string "fmul")
14484 (match_operand:XF 3 "div_operator" "")
14485 (const_string "fdiv")
14486 ]
14487 (const_string "fop")))
14488 (set_attr "mode" "XF")])
14489
14490 (define_insn "*fop_xf_2_i387"
14491 [(set (match_operand:XF 0 "register_operand" "=f,f")
14492 (match_operator:XF 3 "binary_fp_operator"
14493 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14494 (match_operand:XF 2 "register_operand" "0,0")]))]
14495 "TARGET_80387 && TARGET_USE_FIOP"
14496 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14497 [(set (attr "type")
14498 (cond [(match_operand:XF 3 "mult_operator" "")
14499 (const_string "fmul")
14500 (match_operand:XF 3 "div_operator" "")
14501 (const_string "fdiv")
14502 ]
14503 (const_string "fop")))
14504 (set_attr "fp_int_src" "true")
14505 (set_attr "mode" "SI")])
14506
14507 (define_insn "*fop_xf_3_i387"
14508 [(set (match_operand:XF 0 "register_operand" "=f,f")
14509 (match_operator:XF 3 "binary_fp_operator"
14510 [(match_operand:XF 1 "register_operand" "0,0")
14511 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14512 "TARGET_80387 && TARGET_USE_FIOP"
14513 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14514 [(set (attr "type")
14515 (cond [(match_operand:XF 3 "mult_operator" "")
14516 (const_string "fmul")
14517 (match_operand:XF 3 "div_operator" "")
14518 (const_string "fdiv")
14519 ]
14520 (const_string "fop")))
14521 (set_attr "fp_int_src" "true")
14522 (set_attr "mode" "SI")])
14523
14524 (define_insn "*fop_xf_4_i387"
14525 [(set (match_operand:XF 0 "register_operand" "=f,f")
14526 (match_operator:XF 3 "binary_fp_operator"
14527 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14528 (match_operand:XF 2 "register_operand" "0,f")]))]
14529 "TARGET_80387"
14530 "* return output_387_binary_op (insn, operands);"
14531 [(set (attr "type")
14532 (cond [(match_operand:XF 3 "mult_operator" "")
14533 (const_string "fmul")
14534 (match_operand:XF 3 "div_operator" "")
14535 (const_string "fdiv")
14536 ]
14537 (const_string "fop")))
14538 (set_attr "mode" "SF")])
14539
14540 (define_insn "*fop_xf_5_i387"
14541 [(set (match_operand:XF 0 "register_operand" "=f,f")
14542 (match_operator:XF 3 "binary_fp_operator"
14543 [(match_operand:XF 1 "register_operand" "0,f")
14544 (float_extend:XF
14545 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14546 "TARGET_80387"
14547 "* return output_387_binary_op (insn, operands);"
14548 [(set (attr "type")
14549 (cond [(match_operand:XF 3 "mult_operator" "")
14550 (const_string "fmul")
14551 (match_operand:XF 3 "div_operator" "")
14552 (const_string "fdiv")
14553 ]
14554 (const_string "fop")))
14555 (set_attr "mode" "SF")])
14556
14557 (define_insn "*fop_xf_6_i387"
14558 [(set (match_operand:XF 0 "register_operand" "=f,f")
14559 (match_operator:XF 3 "binary_fp_operator"
14560 [(float_extend:XF
14561 (match_operand 1 "register_operand" "0,f"))
14562 (float_extend:XF
14563 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14564 "TARGET_80387"
14565 "* return output_387_binary_op (insn, operands);"
14566 [(set (attr "type")
14567 (cond [(match_operand:XF 3 "mult_operator" "")
14568 (const_string "fmul")
14569 (match_operand:XF 3 "div_operator" "")
14570 (const_string "fdiv")
14571 ]
14572 (const_string "fop")))
14573 (set_attr "mode" "SF")])
14574
14575 (define_split
14576 [(set (match_operand 0 "register_operand" "")
14577 (match_operator 3 "binary_fp_operator"
14578 [(float (match_operand:SI 1 "register_operand" ""))
14579 (match_operand 2 "register_operand" "")]))]
14580 "TARGET_80387 && reload_completed
14581 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14582 [(const_int 0)]
14583 {
14584 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14585 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14586 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14587 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14588 GET_MODE (operands[3]),
14589 operands[4],
14590 operands[2])));
14591 ix86_free_from_memory (GET_MODE (operands[1]));
14592 DONE;
14593 })
14594
14595 (define_split
14596 [(set (match_operand 0 "register_operand" "")
14597 (match_operator 3 "binary_fp_operator"
14598 [(match_operand 1 "register_operand" "")
14599 (float (match_operand:SI 2 "register_operand" ""))]))]
14600 "TARGET_80387 && reload_completed
14601 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14602 [(const_int 0)]
14603 {
14604 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14605 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14606 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14607 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14608 GET_MODE (operands[3]),
14609 operands[1],
14610 operands[4])));
14611 ix86_free_from_memory (GET_MODE (operands[2]));
14612 DONE;
14613 })
14614 \f
14615 ;; FPU special functions.
14616
14617 (define_expand "sqrtsf2"
14618 [(set (match_operand:SF 0 "register_operand" "")
14619 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14620 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14621 {
14622 if (!TARGET_SSE_MATH)
14623 operands[1] = force_reg (SFmode, operands[1]);
14624 })
14625
14626 (define_insn "*sqrtsf2_mixed"
14627 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14628 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14629 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14630 "@
14631 fsqrt
14632 sqrtss\t{%1, %0|%0, %1}"
14633 [(set_attr "type" "fpspc,sse")
14634 (set_attr "mode" "SF,SF")
14635 (set_attr "athlon_decode" "direct,*")])
14636
14637 (define_insn "*sqrtsf2_sse"
14638 [(set (match_operand:SF 0 "register_operand" "=x")
14639 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14640 "TARGET_SSE_MATH"
14641 "sqrtss\t{%1, %0|%0, %1}"
14642 [(set_attr "type" "sse")
14643 (set_attr "mode" "SF")
14644 (set_attr "athlon_decode" "*")])
14645
14646 (define_insn "*sqrtsf2_i387"
14647 [(set (match_operand:SF 0 "register_operand" "=f")
14648 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14649 "TARGET_USE_FANCY_MATH_387"
14650 "fsqrt"
14651 [(set_attr "type" "fpspc")
14652 (set_attr "mode" "SF")
14653 (set_attr "athlon_decode" "direct")])
14654
14655 (define_expand "sqrtdf2"
14656 [(set (match_operand:DF 0 "register_operand" "")
14657 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14658 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14659 {
14660 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14661 operands[1] = force_reg (DFmode, operands[1]);
14662 })
14663
14664 (define_insn "*sqrtdf2_mixed"
14665 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14666 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14667 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14668 "@
14669 fsqrt
14670 sqrtsd\t{%1, %0|%0, %1}"
14671 [(set_attr "type" "fpspc,sse")
14672 (set_attr "mode" "DF,DF")
14673 (set_attr "athlon_decode" "direct,*")])
14674
14675 (define_insn "*sqrtdf2_sse"
14676 [(set (match_operand:DF 0 "register_operand" "=Y")
14677 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14678 "TARGET_SSE2 && TARGET_SSE_MATH"
14679 "sqrtsd\t{%1, %0|%0, %1}"
14680 [(set_attr "type" "sse")
14681 (set_attr "mode" "DF")
14682 (set_attr "athlon_decode" "*")])
14683
14684 (define_insn "*sqrtdf2_i387"
14685 [(set (match_operand:DF 0 "register_operand" "=f")
14686 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14687 "TARGET_USE_FANCY_MATH_387"
14688 "fsqrt"
14689 [(set_attr "type" "fpspc")
14690 (set_attr "mode" "DF")
14691 (set_attr "athlon_decode" "direct")])
14692
14693 (define_insn "*sqrtextendsfdf2_i387"
14694 [(set (match_operand:DF 0 "register_operand" "=f")
14695 (sqrt:DF (float_extend:DF
14696 (match_operand:SF 1 "register_operand" "0"))))]
14697 "TARGET_USE_FANCY_MATH_387
14698 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14699 "fsqrt"
14700 [(set_attr "type" "fpspc")
14701 (set_attr "mode" "DF")
14702 (set_attr "athlon_decode" "direct")])
14703
14704 (define_insn "sqrtxf2"
14705 [(set (match_operand:XF 0 "register_operand" "=f")
14706 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14707 "TARGET_USE_FANCY_MATH_387
14708 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14709 "fsqrt"
14710 [(set_attr "type" "fpspc")
14711 (set_attr "mode" "XF")
14712 (set_attr "athlon_decode" "direct")])
14713
14714 (define_insn "*sqrtextendsfxf2_i387"
14715 [(set (match_operand:XF 0 "register_operand" "=f")
14716 (sqrt:XF (float_extend:XF
14717 (match_operand:SF 1 "register_operand" "0"))))]
14718 "TARGET_USE_FANCY_MATH_387"
14719 "fsqrt"
14720 [(set_attr "type" "fpspc")
14721 (set_attr "mode" "XF")
14722 (set_attr "athlon_decode" "direct")])
14723
14724 (define_insn "*sqrtextenddfxf2_i387"
14725 [(set (match_operand:XF 0 "register_operand" "=f")
14726 (sqrt:XF (float_extend:XF
14727 (match_operand:DF 1 "register_operand" "0"))))]
14728 "TARGET_USE_FANCY_MATH_387"
14729 "fsqrt"
14730 [(set_attr "type" "fpspc")
14731 (set_attr "mode" "XF")
14732 (set_attr "athlon_decode" "direct")])
14733
14734 (define_insn "fpremxf4"
14735 [(set (match_operand:XF 0 "register_operand" "=f")
14736 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14737 (match_operand:XF 3 "register_operand" "1")]
14738 UNSPEC_FPREM_F))
14739 (set (match_operand:XF 1 "register_operand" "=u")
14740 (unspec:XF [(match_dup 2) (match_dup 3)]
14741 UNSPEC_FPREM_U))
14742 (set (reg:CCFP FPSR_REG)
14743 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14744 "TARGET_USE_FANCY_MATH_387
14745 && flag_unsafe_math_optimizations"
14746 "fprem"
14747 [(set_attr "type" "fpspc")
14748 (set_attr "mode" "XF")])
14749
14750 (define_expand "fmodsf3"
14751 [(use (match_operand:SF 0 "register_operand" ""))
14752 (use (match_operand:SF 1 "register_operand" ""))
14753 (use (match_operand:SF 2 "register_operand" ""))]
14754 "TARGET_USE_FANCY_MATH_387
14755 && flag_unsafe_math_optimizations"
14756 {
14757 rtx label = gen_label_rtx ();
14758
14759 rtx op1 = gen_reg_rtx (XFmode);
14760 rtx op2 = gen_reg_rtx (XFmode);
14761
14762 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14763 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14764
14765 emit_label (label);
14766
14767 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14768 ix86_emit_fp_unordered_jump (label);
14769
14770 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14771 DONE;
14772 })
14773
14774 (define_expand "fmoddf3"
14775 [(use (match_operand:DF 0 "register_operand" ""))
14776 (use (match_operand:DF 1 "register_operand" ""))
14777 (use (match_operand:DF 2 "register_operand" ""))]
14778 "TARGET_USE_FANCY_MATH_387
14779 && flag_unsafe_math_optimizations"
14780 {
14781 rtx label = gen_label_rtx ();
14782
14783 rtx op1 = gen_reg_rtx (XFmode);
14784 rtx op2 = gen_reg_rtx (XFmode);
14785
14786 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14787 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14788
14789 emit_label (label);
14790
14791 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14792 ix86_emit_fp_unordered_jump (label);
14793
14794 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14795 DONE;
14796 })
14797
14798 (define_expand "fmodxf3"
14799 [(use (match_operand:XF 0 "register_operand" ""))
14800 (use (match_operand:XF 1 "register_operand" ""))
14801 (use (match_operand:XF 2 "register_operand" ""))]
14802 "TARGET_USE_FANCY_MATH_387
14803 && flag_unsafe_math_optimizations"
14804 {
14805 rtx label = gen_label_rtx ();
14806
14807 emit_label (label);
14808
14809 emit_insn (gen_fpremxf4 (operands[1], operands[2],
14810 operands[1], operands[2]));
14811 ix86_emit_fp_unordered_jump (label);
14812
14813 emit_move_insn (operands[0], operands[1]);
14814 DONE;
14815 })
14816
14817 (define_insn "fprem1xf4"
14818 [(set (match_operand:XF 0 "register_operand" "=f")
14819 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14820 (match_operand:XF 3 "register_operand" "1")]
14821 UNSPEC_FPREM1_F))
14822 (set (match_operand:XF 1 "register_operand" "=u")
14823 (unspec:XF [(match_dup 2) (match_dup 3)]
14824 UNSPEC_FPREM1_U))
14825 (set (reg:CCFP FPSR_REG)
14826 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14827 "TARGET_USE_FANCY_MATH_387
14828 && flag_unsafe_math_optimizations"
14829 "fprem1"
14830 [(set_attr "type" "fpspc")
14831 (set_attr "mode" "XF")])
14832
14833 (define_expand "dremsf3"
14834 [(use (match_operand:SF 0 "register_operand" ""))
14835 (use (match_operand:SF 1 "register_operand" ""))
14836 (use (match_operand:SF 2 "register_operand" ""))]
14837 "TARGET_USE_FANCY_MATH_387
14838 && flag_unsafe_math_optimizations"
14839 {
14840 rtx label = gen_label_rtx ();
14841
14842 rtx op1 = gen_reg_rtx (XFmode);
14843 rtx op2 = gen_reg_rtx (XFmode);
14844
14845 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14846 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14847
14848 emit_label (label);
14849
14850 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14851 ix86_emit_fp_unordered_jump (label);
14852
14853 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14854 DONE;
14855 })
14856
14857 (define_expand "dremdf3"
14858 [(use (match_operand:DF 0 "register_operand" ""))
14859 (use (match_operand:DF 1 "register_operand" ""))
14860 (use (match_operand:DF 2 "register_operand" ""))]
14861 "TARGET_USE_FANCY_MATH_387
14862 && flag_unsafe_math_optimizations"
14863 {
14864 rtx label = gen_label_rtx ();
14865
14866 rtx op1 = gen_reg_rtx (XFmode);
14867 rtx op2 = gen_reg_rtx (XFmode);
14868
14869 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14870 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14871
14872 emit_label (label);
14873
14874 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14875 ix86_emit_fp_unordered_jump (label);
14876
14877 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14878 DONE;
14879 })
14880
14881 (define_expand "dremxf3"
14882 [(use (match_operand:XF 0 "register_operand" ""))
14883 (use (match_operand:XF 1 "register_operand" ""))
14884 (use (match_operand:XF 2 "register_operand" ""))]
14885 "TARGET_USE_FANCY_MATH_387
14886 && flag_unsafe_math_optimizations"
14887 {
14888 rtx label = gen_label_rtx ();
14889
14890 emit_label (label);
14891
14892 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14893 operands[1], operands[2]));
14894 ix86_emit_fp_unordered_jump (label);
14895
14896 emit_move_insn (operands[0], operands[1]);
14897 DONE;
14898 })
14899
14900 (define_insn "*sindf2"
14901 [(set (match_operand:DF 0 "register_operand" "=f")
14902 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14903 "TARGET_USE_FANCY_MATH_387
14904 && flag_unsafe_math_optimizations"
14905 "fsin"
14906 [(set_attr "type" "fpspc")
14907 (set_attr "mode" "DF")])
14908
14909 (define_insn "*sinsf2"
14910 [(set (match_operand:SF 0 "register_operand" "=f")
14911 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14912 "TARGET_USE_FANCY_MATH_387
14913 && flag_unsafe_math_optimizations"
14914 "fsin"
14915 [(set_attr "type" "fpspc")
14916 (set_attr "mode" "SF")])
14917
14918 (define_insn "*sinextendsfdf2"
14919 [(set (match_operand:DF 0 "register_operand" "=f")
14920 (unspec:DF [(float_extend:DF
14921 (match_operand:SF 1 "register_operand" "0"))]
14922 UNSPEC_SIN))]
14923 "TARGET_USE_FANCY_MATH_387
14924 && flag_unsafe_math_optimizations"
14925 "fsin"
14926 [(set_attr "type" "fpspc")
14927 (set_attr "mode" "DF")])
14928
14929 (define_insn "*sinxf2"
14930 [(set (match_operand:XF 0 "register_operand" "=f")
14931 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14932 "TARGET_USE_FANCY_MATH_387
14933 && flag_unsafe_math_optimizations"
14934 "fsin"
14935 [(set_attr "type" "fpspc")
14936 (set_attr "mode" "XF")])
14937
14938 (define_insn "*cosdf2"
14939 [(set (match_operand:DF 0 "register_operand" "=f")
14940 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14941 "TARGET_USE_FANCY_MATH_387
14942 && flag_unsafe_math_optimizations"
14943 "fcos"
14944 [(set_attr "type" "fpspc")
14945 (set_attr "mode" "DF")])
14946
14947 (define_insn "*cossf2"
14948 [(set (match_operand:SF 0 "register_operand" "=f")
14949 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14950 "TARGET_USE_FANCY_MATH_387
14951 && flag_unsafe_math_optimizations"
14952 "fcos"
14953 [(set_attr "type" "fpspc")
14954 (set_attr "mode" "SF")])
14955
14956 (define_insn "*cosextendsfdf2"
14957 [(set (match_operand:DF 0 "register_operand" "=f")
14958 (unspec:DF [(float_extend:DF
14959 (match_operand:SF 1 "register_operand" "0"))]
14960 UNSPEC_COS))]
14961 "TARGET_USE_FANCY_MATH_387
14962 && flag_unsafe_math_optimizations"
14963 "fcos"
14964 [(set_attr "type" "fpspc")
14965 (set_attr "mode" "DF")])
14966
14967 (define_insn "*cosxf2"
14968 [(set (match_operand:XF 0 "register_operand" "=f")
14969 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14970 "TARGET_USE_FANCY_MATH_387
14971 && flag_unsafe_math_optimizations"
14972 "fcos"
14973 [(set_attr "type" "fpspc")
14974 (set_attr "mode" "XF")])
14975
14976 ;; With sincos pattern defined, sin and cos builtin function will be
14977 ;; expanded to sincos pattern with one of its outputs left unused.
14978 ;; Cse pass will detected, if two sincos patterns can be combined,
14979 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14980 ;; depending on the unused output.
14981
14982 (define_insn "sincosdf3"
14983 [(set (match_operand:DF 0 "register_operand" "=f")
14984 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14985 UNSPEC_SINCOS_COS))
14986 (set (match_operand:DF 1 "register_operand" "=u")
14987 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14988 "TARGET_USE_FANCY_MATH_387
14989 && flag_unsafe_math_optimizations"
14990 "fsincos"
14991 [(set_attr "type" "fpspc")
14992 (set_attr "mode" "DF")])
14993
14994 (define_split
14995 [(set (match_operand:DF 0 "register_operand" "")
14996 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14997 UNSPEC_SINCOS_COS))
14998 (set (match_operand:DF 1 "register_operand" "")
14999 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15000 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15001 && !reload_completed && !reload_in_progress"
15002 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15003 "")
15004
15005 (define_split
15006 [(set (match_operand:DF 0 "register_operand" "")
15007 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15008 UNSPEC_SINCOS_COS))
15009 (set (match_operand:DF 1 "register_operand" "")
15010 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15011 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15012 && !reload_completed && !reload_in_progress"
15013 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15014 "")
15015
15016 (define_insn "sincossf3"
15017 [(set (match_operand:SF 0 "register_operand" "=f")
15018 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15019 UNSPEC_SINCOS_COS))
15020 (set (match_operand:SF 1 "register_operand" "=u")
15021 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15022 "TARGET_USE_FANCY_MATH_387
15023 && flag_unsafe_math_optimizations"
15024 "fsincos"
15025 [(set_attr "type" "fpspc")
15026 (set_attr "mode" "SF")])
15027
15028 (define_split
15029 [(set (match_operand:SF 0 "register_operand" "")
15030 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15031 UNSPEC_SINCOS_COS))
15032 (set (match_operand:SF 1 "register_operand" "")
15033 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15034 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15035 && !reload_completed && !reload_in_progress"
15036 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15037 "")
15038
15039 (define_split
15040 [(set (match_operand:SF 0 "register_operand" "")
15041 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15042 UNSPEC_SINCOS_COS))
15043 (set (match_operand:SF 1 "register_operand" "")
15044 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15045 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15046 && !reload_completed && !reload_in_progress"
15047 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15048 "")
15049
15050 (define_insn "*sincosextendsfdf3"
15051 [(set (match_operand:DF 0 "register_operand" "=f")
15052 (unspec:DF [(float_extend:DF
15053 (match_operand:SF 2 "register_operand" "0"))]
15054 UNSPEC_SINCOS_COS))
15055 (set (match_operand:DF 1 "register_operand" "=u")
15056 (unspec:DF [(float_extend:DF
15057 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15058 "TARGET_USE_FANCY_MATH_387
15059 && flag_unsafe_math_optimizations"
15060 "fsincos"
15061 [(set_attr "type" "fpspc")
15062 (set_attr "mode" "DF")])
15063
15064 (define_split
15065 [(set (match_operand:DF 0 "register_operand" "")
15066 (unspec:DF [(float_extend:DF
15067 (match_operand:SF 2 "register_operand" ""))]
15068 UNSPEC_SINCOS_COS))
15069 (set (match_operand:DF 1 "register_operand" "")
15070 (unspec:DF [(float_extend:DF
15071 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15072 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15073 && !reload_completed && !reload_in_progress"
15074 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15075 (match_dup 2))] UNSPEC_SIN))]
15076 "")
15077
15078 (define_split
15079 [(set (match_operand:DF 0 "register_operand" "")
15080 (unspec:DF [(float_extend:DF
15081 (match_operand:SF 2 "register_operand" ""))]
15082 UNSPEC_SINCOS_COS))
15083 (set (match_operand:DF 1 "register_operand" "")
15084 (unspec:DF [(float_extend:DF
15085 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15086 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15087 && !reload_completed && !reload_in_progress"
15088 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15089 (match_dup 2))] UNSPEC_COS))]
15090 "")
15091
15092 (define_insn "sincosxf3"
15093 [(set (match_operand:XF 0 "register_operand" "=f")
15094 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15095 UNSPEC_SINCOS_COS))
15096 (set (match_operand:XF 1 "register_operand" "=u")
15097 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15098 "TARGET_USE_FANCY_MATH_387
15099 && flag_unsafe_math_optimizations"
15100 "fsincos"
15101 [(set_attr "type" "fpspc")
15102 (set_attr "mode" "XF")])
15103
15104 (define_split
15105 [(set (match_operand:XF 0 "register_operand" "")
15106 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15107 UNSPEC_SINCOS_COS))
15108 (set (match_operand:XF 1 "register_operand" "")
15109 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15110 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15111 && !reload_completed && !reload_in_progress"
15112 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15113 "")
15114
15115 (define_split
15116 [(set (match_operand:XF 0 "register_operand" "")
15117 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15118 UNSPEC_SINCOS_COS))
15119 (set (match_operand:XF 1 "register_operand" "")
15120 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15121 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15122 && !reload_completed && !reload_in_progress"
15123 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15124 "")
15125
15126 (define_insn "*tandf3_1"
15127 [(set (match_operand:DF 0 "register_operand" "=f")
15128 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15129 UNSPEC_TAN_ONE))
15130 (set (match_operand:DF 1 "register_operand" "=u")
15131 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15132 "TARGET_USE_FANCY_MATH_387
15133 && flag_unsafe_math_optimizations"
15134 "fptan"
15135 [(set_attr "type" "fpspc")
15136 (set_attr "mode" "DF")])
15137
15138 ;; optimize sequence: fptan
15139 ;; fstp %st(0)
15140 ;; fld1
15141 ;; into fptan insn.
15142
15143 (define_peephole2
15144 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15145 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15146 UNSPEC_TAN_ONE))
15147 (set (match_operand:DF 1 "register_operand" "")
15148 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15149 (set (match_dup 0)
15150 (match_operand:DF 3 "immediate_operand" ""))]
15151 "standard_80387_constant_p (operands[3]) == 2"
15152 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15153 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15154 "")
15155
15156 (define_expand "tandf2"
15157 [(parallel [(set (match_dup 2)
15158 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15159 UNSPEC_TAN_ONE))
15160 (set (match_operand:DF 0 "register_operand" "")
15161 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15162 "TARGET_USE_FANCY_MATH_387
15163 && flag_unsafe_math_optimizations"
15164 {
15165 operands[2] = gen_reg_rtx (DFmode);
15166 })
15167
15168 (define_insn "*tansf3_1"
15169 [(set (match_operand:SF 0 "register_operand" "=f")
15170 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15171 UNSPEC_TAN_ONE))
15172 (set (match_operand:SF 1 "register_operand" "=u")
15173 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15174 "TARGET_USE_FANCY_MATH_387
15175 && flag_unsafe_math_optimizations"
15176 "fptan"
15177 [(set_attr "type" "fpspc")
15178 (set_attr "mode" "SF")])
15179
15180 ;; optimize sequence: fptan
15181 ;; fstp %st(0)
15182 ;; fld1
15183 ;; into fptan insn.
15184
15185 (define_peephole2
15186 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15187 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15188 UNSPEC_TAN_ONE))
15189 (set (match_operand:SF 1 "register_operand" "")
15190 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15191 (set (match_dup 0)
15192 (match_operand:SF 3 "immediate_operand" ""))]
15193 "standard_80387_constant_p (operands[3]) == 2"
15194 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15195 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15196 "")
15197
15198 (define_expand "tansf2"
15199 [(parallel [(set (match_dup 2)
15200 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15201 UNSPEC_TAN_ONE))
15202 (set (match_operand:SF 0 "register_operand" "")
15203 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15204 "TARGET_USE_FANCY_MATH_387
15205 && flag_unsafe_math_optimizations"
15206 {
15207 operands[2] = gen_reg_rtx (SFmode);
15208 })
15209
15210 (define_insn "*tanxf3_1"
15211 [(set (match_operand:XF 0 "register_operand" "=f")
15212 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15213 UNSPEC_TAN_ONE))
15214 (set (match_operand:XF 1 "register_operand" "=u")
15215 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15216 "TARGET_USE_FANCY_MATH_387
15217 && flag_unsafe_math_optimizations"
15218 "fptan"
15219 [(set_attr "type" "fpspc")
15220 (set_attr "mode" "XF")])
15221
15222 ;; optimize sequence: fptan
15223 ;; fstp %st(0)
15224 ;; fld1
15225 ;; into fptan insn.
15226
15227 (define_peephole2
15228 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15229 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15230 UNSPEC_TAN_ONE))
15231 (set (match_operand:XF 1 "register_operand" "")
15232 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15233 (set (match_dup 0)
15234 (match_operand:XF 3 "immediate_operand" ""))]
15235 "standard_80387_constant_p (operands[3]) == 2"
15236 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15237 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15238 "")
15239
15240 (define_expand "tanxf2"
15241 [(parallel [(set (match_dup 2)
15242 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15243 UNSPEC_TAN_ONE))
15244 (set (match_operand:XF 0 "register_operand" "")
15245 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15246 "TARGET_USE_FANCY_MATH_387
15247 && flag_unsafe_math_optimizations"
15248 {
15249 operands[2] = gen_reg_rtx (XFmode);
15250 })
15251
15252 (define_insn "atan2df3_1"
15253 [(set (match_operand:DF 0 "register_operand" "=f")
15254 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15255 (match_operand:DF 1 "register_operand" "u")]
15256 UNSPEC_FPATAN))
15257 (clobber (match_scratch:DF 3 "=1"))]
15258 "TARGET_USE_FANCY_MATH_387
15259 && flag_unsafe_math_optimizations"
15260 "fpatan"
15261 [(set_attr "type" "fpspc")
15262 (set_attr "mode" "DF")])
15263
15264 (define_expand "atan2df3"
15265 [(use (match_operand:DF 0 "register_operand" "=f"))
15266 (use (match_operand:DF 2 "register_operand" "0"))
15267 (use (match_operand:DF 1 "register_operand" "u"))]
15268 "TARGET_USE_FANCY_MATH_387
15269 && flag_unsafe_math_optimizations"
15270 {
15271 rtx copy = gen_reg_rtx (DFmode);
15272 emit_move_insn (copy, operands[1]);
15273 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15274 DONE;
15275 })
15276
15277 (define_expand "atandf2"
15278 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15279 (unspec:DF [(match_dup 2)
15280 (match_operand:DF 1 "register_operand" "")]
15281 UNSPEC_FPATAN))
15282 (clobber (match_scratch:DF 3 ""))])]
15283 "TARGET_USE_FANCY_MATH_387
15284 && flag_unsafe_math_optimizations"
15285 {
15286 operands[2] = gen_reg_rtx (DFmode);
15287 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15288 })
15289
15290 (define_insn "atan2sf3_1"
15291 [(set (match_operand:SF 0 "register_operand" "=f")
15292 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15293 (match_operand:SF 1 "register_operand" "u")]
15294 UNSPEC_FPATAN))
15295 (clobber (match_scratch:SF 3 "=1"))]
15296 "TARGET_USE_FANCY_MATH_387
15297 && flag_unsafe_math_optimizations"
15298 "fpatan"
15299 [(set_attr "type" "fpspc")
15300 (set_attr "mode" "SF")])
15301
15302 (define_expand "atan2sf3"
15303 [(use (match_operand:SF 0 "register_operand" "=f"))
15304 (use (match_operand:SF 2 "register_operand" "0"))
15305 (use (match_operand:SF 1 "register_operand" "u"))]
15306 "TARGET_USE_FANCY_MATH_387
15307 && flag_unsafe_math_optimizations"
15308 {
15309 rtx copy = gen_reg_rtx (SFmode);
15310 emit_move_insn (copy, operands[1]);
15311 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15312 DONE;
15313 })
15314
15315 (define_expand "atansf2"
15316 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15317 (unspec:SF [(match_dup 2)
15318 (match_operand:SF 1 "register_operand" "")]
15319 UNSPEC_FPATAN))
15320 (clobber (match_scratch:SF 3 ""))])]
15321 "TARGET_USE_FANCY_MATH_387
15322 && flag_unsafe_math_optimizations"
15323 {
15324 operands[2] = gen_reg_rtx (SFmode);
15325 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15326 })
15327
15328 (define_insn "atan2xf3_1"
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_FPATAN))
15333 (clobber (match_scratch:XF 3 "=1"))]
15334 "TARGET_USE_FANCY_MATH_387
15335 && flag_unsafe_math_optimizations"
15336 "fpatan"
15337 [(set_attr "type" "fpspc")
15338 (set_attr "mode" "XF")])
15339
15340 (define_expand "atan2xf3"
15341 [(use (match_operand:XF 0 "register_operand" "=f"))
15342 (use (match_operand:XF 2 "register_operand" "0"))
15343 (use (match_operand:XF 1 "register_operand" "u"))]
15344 "TARGET_USE_FANCY_MATH_387
15345 && flag_unsafe_math_optimizations"
15346 {
15347 rtx copy = gen_reg_rtx (XFmode);
15348 emit_move_insn (copy, operands[1]);
15349 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15350 DONE;
15351 })
15352
15353 (define_expand "atanxf2"
15354 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15355 (unspec:XF [(match_dup 2)
15356 (match_operand:XF 1 "register_operand" "")]
15357 UNSPEC_FPATAN))
15358 (clobber (match_scratch:XF 3 ""))])]
15359 "TARGET_USE_FANCY_MATH_387
15360 && flag_unsafe_math_optimizations"
15361 {
15362 operands[2] = gen_reg_rtx (XFmode);
15363 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15364 })
15365
15366 (define_expand "asindf2"
15367 [(set (match_dup 2)
15368 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15369 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15370 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15371 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15372 (parallel [(set (match_dup 7)
15373 (unspec:XF [(match_dup 6) (match_dup 2)]
15374 UNSPEC_FPATAN))
15375 (clobber (match_scratch:XF 8 ""))])
15376 (set (match_operand:DF 0 "register_operand" "")
15377 (float_truncate:DF (match_dup 7)))]
15378 "TARGET_USE_FANCY_MATH_387
15379 && flag_unsafe_math_optimizations"
15380 {
15381 int i;
15382
15383 for (i=2; i<8; i++)
15384 operands[i] = gen_reg_rtx (XFmode);
15385
15386 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15387 })
15388
15389 (define_expand "asinsf2"
15390 [(set (match_dup 2)
15391 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15392 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15393 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15394 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15395 (parallel [(set (match_dup 7)
15396 (unspec:XF [(match_dup 6) (match_dup 2)]
15397 UNSPEC_FPATAN))
15398 (clobber (match_scratch:XF 8 ""))])
15399 (set (match_operand:SF 0 "register_operand" "")
15400 (float_truncate:SF (match_dup 7)))]
15401 "TARGET_USE_FANCY_MATH_387
15402 && flag_unsafe_math_optimizations"
15403 {
15404 int i;
15405
15406 for (i=2; i<8; i++)
15407 operands[i] = gen_reg_rtx (XFmode);
15408
15409 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15410 })
15411
15412 (define_expand "asinxf2"
15413 [(set (match_dup 2)
15414 (mult:XF (match_operand:XF 1 "register_operand" "")
15415 (match_dup 1)))
15416 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15417 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15418 (parallel [(set (match_operand:XF 0 "register_operand" "")
15419 (unspec:XF [(match_dup 5) (match_dup 1)]
15420 UNSPEC_FPATAN))
15421 (clobber (match_scratch:XF 6 ""))])]
15422 "TARGET_USE_FANCY_MATH_387
15423 && flag_unsafe_math_optimizations"
15424 {
15425 int i;
15426
15427 for (i=2; i<6; i++)
15428 operands[i] = gen_reg_rtx (XFmode);
15429
15430 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15431 })
15432
15433 (define_expand "acosdf2"
15434 [(set (match_dup 2)
15435 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15436 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15437 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15438 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15439 (parallel [(set (match_dup 7)
15440 (unspec:XF [(match_dup 2) (match_dup 6)]
15441 UNSPEC_FPATAN))
15442 (clobber (match_scratch:XF 8 ""))])
15443 (set (match_operand:DF 0 "register_operand" "")
15444 (float_truncate:DF (match_dup 7)))]
15445 "TARGET_USE_FANCY_MATH_387
15446 && flag_unsafe_math_optimizations"
15447 {
15448 int i;
15449
15450 for (i=2; i<8; i++)
15451 operands[i] = gen_reg_rtx (XFmode);
15452
15453 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15454 })
15455
15456 (define_expand "acossf2"
15457 [(set (match_dup 2)
15458 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15459 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15460 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15461 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15462 (parallel [(set (match_dup 7)
15463 (unspec:XF [(match_dup 2) (match_dup 6)]
15464 UNSPEC_FPATAN))
15465 (clobber (match_scratch:XF 8 ""))])
15466 (set (match_operand:SF 0 "register_operand" "")
15467 (float_truncate:SF (match_dup 7)))]
15468 "TARGET_USE_FANCY_MATH_387
15469 && flag_unsafe_math_optimizations"
15470 {
15471 int i;
15472
15473 for (i=2; i<8; i++)
15474 operands[i] = gen_reg_rtx (XFmode);
15475
15476 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15477 })
15478
15479 (define_expand "acosxf2"
15480 [(set (match_dup 2)
15481 (mult:XF (match_operand:XF 1 "register_operand" "")
15482 (match_dup 1)))
15483 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15484 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15485 (parallel [(set (match_operand:XF 0 "register_operand" "")
15486 (unspec:XF [(match_dup 1) (match_dup 5)]
15487 UNSPEC_FPATAN))
15488 (clobber (match_scratch:XF 6 ""))])]
15489 "TARGET_USE_FANCY_MATH_387
15490 && flag_unsafe_math_optimizations"
15491 {
15492 int i;
15493
15494 for (i=2; i<6; i++)
15495 operands[i] = gen_reg_rtx (XFmode);
15496
15497 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15498 })
15499
15500 (define_insn "fyl2x_xf3"
15501 [(set (match_operand:XF 0 "register_operand" "=f")
15502 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15503 (match_operand:XF 1 "register_operand" "u")]
15504 UNSPEC_FYL2X))
15505 (clobber (match_scratch:XF 3 "=1"))]
15506 "TARGET_USE_FANCY_MATH_387
15507 && flag_unsafe_math_optimizations"
15508 "fyl2x"
15509 [(set_attr "type" "fpspc")
15510 (set_attr "mode" "XF")])
15511
15512 (define_expand "logsf2"
15513 [(set (match_dup 2)
15514 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15515 (parallel [(set (match_dup 4)
15516 (unspec:XF [(match_dup 2)
15517 (match_dup 3)] UNSPEC_FYL2X))
15518 (clobber (match_scratch:XF 5 ""))])
15519 (set (match_operand:SF 0 "register_operand" "")
15520 (float_truncate:SF (match_dup 4)))]
15521 "TARGET_USE_FANCY_MATH_387
15522 && flag_unsafe_math_optimizations"
15523 {
15524 rtx temp;
15525
15526 operands[2] = gen_reg_rtx (XFmode);
15527 operands[3] = gen_reg_rtx (XFmode);
15528 operands[4] = gen_reg_rtx (XFmode);
15529
15530 temp = standard_80387_constant_rtx (4); /* fldln2 */
15531 emit_move_insn (operands[3], temp);
15532 })
15533
15534 (define_expand "logdf2"
15535 [(set (match_dup 2)
15536 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15537 (parallel [(set (match_dup 4)
15538 (unspec:XF [(match_dup 2)
15539 (match_dup 3)] UNSPEC_FYL2X))
15540 (clobber (match_scratch:XF 5 ""))])
15541 (set (match_operand:DF 0 "register_operand" "")
15542 (float_truncate:DF (match_dup 4)))]
15543 "TARGET_USE_FANCY_MATH_387
15544 && flag_unsafe_math_optimizations"
15545 {
15546 rtx temp;
15547
15548 operands[2] = gen_reg_rtx (XFmode);
15549 operands[3] = gen_reg_rtx (XFmode);
15550 operands[4] = gen_reg_rtx (XFmode);
15551
15552 temp = standard_80387_constant_rtx (4); /* fldln2 */
15553 emit_move_insn (operands[3], temp);
15554 })
15555
15556 (define_expand "logxf2"
15557 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15558 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15559 (match_dup 2)] UNSPEC_FYL2X))
15560 (clobber (match_scratch:XF 3 ""))])]
15561 "TARGET_USE_FANCY_MATH_387
15562 && flag_unsafe_math_optimizations"
15563 {
15564 rtx temp;
15565
15566 operands[2] = gen_reg_rtx (XFmode);
15567 temp = standard_80387_constant_rtx (4); /* fldln2 */
15568 emit_move_insn (operands[2], temp);
15569 })
15570
15571 (define_expand "log10sf2"
15572 [(set (match_dup 2)
15573 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15574 (parallel [(set (match_dup 4)
15575 (unspec:XF [(match_dup 2)
15576 (match_dup 3)] UNSPEC_FYL2X))
15577 (clobber (match_scratch:XF 5 ""))])
15578 (set (match_operand:SF 0 "register_operand" "")
15579 (float_truncate:SF (match_dup 4)))]
15580 "TARGET_USE_FANCY_MATH_387
15581 && flag_unsafe_math_optimizations"
15582 {
15583 rtx temp;
15584
15585 operands[2] = gen_reg_rtx (XFmode);
15586 operands[3] = gen_reg_rtx (XFmode);
15587 operands[4] = gen_reg_rtx (XFmode);
15588
15589 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15590 emit_move_insn (operands[3], temp);
15591 })
15592
15593 (define_expand "log10df2"
15594 [(set (match_dup 2)
15595 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15596 (parallel [(set (match_dup 4)
15597 (unspec:XF [(match_dup 2)
15598 (match_dup 3)] UNSPEC_FYL2X))
15599 (clobber (match_scratch:XF 5 ""))])
15600 (set (match_operand:DF 0 "register_operand" "")
15601 (float_truncate:DF (match_dup 4)))]
15602 "TARGET_USE_FANCY_MATH_387
15603 && flag_unsafe_math_optimizations"
15604 {
15605 rtx temp;
15606
15607 operands[2] = gen_reg_rtx (XFmode);
15608 operands[3] = gen_reg_rtx (XFmode);
15609 operands[4] = gen_reg_rtx (XFmode);
15610
15611 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15612 emit_move_insn (operands[3], temp);
15613 })
15614
15615 (define_expand "log10xf2"
15616 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15617 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15618 (match_dup 2)] UNSPEC_FYL2X))
15619 (clobber (match_scratch:XF 3 ""))])]
15620 "TARGET_USE_FANCY_MATH_387
15621 && flag_unsafe_math_optimizations"
15622 {
15623 rtx temp;
15624
15625 operands[2] = gen_reg_rtx (XFmode);
15626 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15627 emit_move_insn (operands[2], temp);
15628 })
15629
15630 (define_expand "log2sf2"
15631 [(set (match_dup 2)
15632 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15633 (parallel [(set (match_dup 4)
15634 (unspec:XF [(match_dup 2)
15635 (match_dup 3)] UNSPEC_FYL2X))
15636 (clobber (match_scratch:XF 5 ""))])
15637 (set (match_operand:SF 0 "register_operand" "")
15638 (float_truncate:SF (match_dup 4)))]
15639 "TARGET_USE_FANCY_MATH_387
15640 && flag_unsafe_math_optimizations"
15641 {
15642 operands[2] = gen_reg_rtx (XFmode);
15643 operands[3] = gen_reg_rtx (XFmode);
15644 operands[4] = gen_reg_rtx (XFmode);
15645
15646 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15647 })
15648
15649 (define_expand "log2df2"
15650 [(set (match_dup 2)
15651 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15652 (parallel [(set (match_dup 4)
15653 (unspec:XF [(match_dup 2)
15654 (match_dup 3)] UNSPEC_FYL2X))
15655 (clobber (match_scratch:XF 5 ""))])
15656 (set (match_operand:DF 0 "register_operand" "")
15657 (float_truncate:DF (match_dup 4)))]
15658 "TARGET_USE_FANCY_MATH_387
15659 && flag_unsafe_math_optimizations"
15660 {
15661 operands[2] = gen_reg_rtx (XFmode);
15662 operands[3] = gen_reg_rtx (XFmode);
15663 operands[4] = gen_reg_rtx (XFmode);
15664
15665 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15666 })
15667
15668 (define_expand "log2xf2"
15669 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15670 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15671 (match_dup 2)] UNSPEC_FYL2X))
15672 (clobber (match_scratch:XF 3 ""))])]
15673 "TARGET_USE_FANCY_MATH_387
15674 && flag_unsafe_math_optimizations"
15675 {
15676 operands[2] = gen_reg_rtx (XFmode);
15677 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15678 })
15679
15680 (define_insn "fyl2xp1_xf3"
15681 [(set (match_operand:XF 0 "register_operand" "=f")
15682 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15683 (match_operand:XF 1 "register_operand" "u")]
15684 UNSPEC_FYL2XP1))
15685 (clobber (match_scratch:XF 3 "=1"))]
15686 "TARGET_USE_FANCY_MATH_387
15687 && flag_unsafe_math_optimizations"
15688 "fyl2xp1"
15689 [(set_attr "type" "fpspc")
15690 (set_attr "mode" "XF")])
15691
15692 (define_expand "log1psf2"
15693 [(use (match_operand:SF 0 "register_operand" ""))
15694 (use (match_operand:SF 1 "register_operand" ""))]
15695 "TARGET_USE_FANCY_MATH_387
15696 && flag_unsafe_math_optimizations"
15697 {
15698 rtx op0 = gen_reg_rtx (XFmode);
15699 rtx op1 = gen_reg_rtx (XFmode);
15700
15701 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15702 ix86_emit_i387_log1p (op0, op1);
15703 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15704 DONE;
15705 })
15706
15707 (define_expand "log1pdf2"
15708 [(use (match_operand:DF 0 "register_operand" ""))
15709 (use (match_operand:DF 1 "register_operand" ""))]
15710 "TARGET_USE_FANCY_MATH_387
15711 && flag_unsafe_math_optimizations"
15712 {
15713 rtx op0 = gen_reg_rtx (XFmode);
15714 rtx op1 = gen_reg_rtx (XFmode);
15715
15716 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15717 ix86_emit_i387_log1p (op0, op1);
15718 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15719 DONE;
15720 })
15721
15722 (define_expand "log1pxf2"
15723 [(use (match_operand:XF 0 "register_operand" ""))
15724 (use (match_operand:XF 1 "register_operand" ""))]
15725 "TARGET_USE_FANCY_MATH_387
15726 && flag_unsafe_math_optimizations"
15727 {
15728 ix86_emit_i387_log1p (operands[0], operands[1]);
15729 DONE;
15730 })
15731
15732 (define_insn "*fxtractxf3"
15733 [(set (match_operand:XF 0 "register_operand" "=f")
15734 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15735 UNSPEC_XTRACT_FRACT))
15736 (set (match_operand:XF 1 "register_operand" "=u")
15737 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15738 "TARGET_USE_FANCY_MATH_387
15739 && flag_unsafe_math_optimizations"
15740 "fxtract"
15741 [(set_attr "type" "fpspc")
15742 (set_attr "mode" "XF")])
15743
15744 (define_expand "logbsf2"
15745 [(set (match_dup 2)
15746 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15747 (parallel [(set (match_dup 3)
15748 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15749 (set (match_dup 4)
15750 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15751 (set (match_operand:SF 0 "register_operand" "")
15752 (float_truncate:SF (match_dup 4)))]
15753 "TARGET_USE_FANCY_MATH_387
15754 && flag_unsafe_math_optimizations"
15755 {
15756 operands[2] = gen_reg_rtx (XFmode);
15757 operands[3] = gen_reg_rtx (XFmode);
15758 operands[4] = gen_reg_rtx (XFmode);
15759 })
15760
15761 (define_expand "logbdf2"
15762 [(set (match_dup 2)
15763 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15764 (parallel [(set (match_dup 3)
15765 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15766 (set (match_dup 4)
15767 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15768 (set (match_operand:DF 0 "register_operand" "")
15769 (float_truncate:DF (match_dup 4)))]
15770 "TARGET_USE_FANCY_MATH_387
15771 && flag_unsafe_math_optimizations"
15772 {
15773 operands[2] = gen_reg_rtx (XFmode);
15774 operands[3] = gen_reg_rtx (XFmode);
15775 operands[4] = gen_reg_rtx (XFmode);
15776 })
15777
15778 (define_expand "logbxf2"
15779 [(parallel [(set (match_dup 2)
15780 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15781 UNSPEC_XTRACT_FRACT))
15782 (set (match_operand:XF 0 "register_operand" "")
15783 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15784 "TARGET_USE_FANCY_MATH_387
15785 && flag_unsafe_math_optimizations"
15786 {
15787 operands[2] = gen_reg_rtx (XFmode);
15788 })
15789
15790 (define_expand "ilogbsi2"
15791 [(parallel [(set (match_dup 2)
15792 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15793 UNSPEC_XTRACT_FRACT))
15794 (set (match_operand:XF 3 "register_operand" "")
15795 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15796 (parallel [(set (match_operand:SI 0 "register_operand" "")
15797 (fix:SI (match_dup 3)))
15798 (clobber (reg:CC FLAGS_REG))])]
15799 "TARGET_USE_FANCY_MATH_387
15800 && flag_unsafe_math_optimizations"
15801 {
15802 operands[2] = gen_reg_rtx (XFmode);
15803 operands[3] = gen_reg_rtx (XFmode);
15804 })
15805
15806 (define_insn "*f2xm1xf2"
15807 [(set (match_operand:XF 0 "register_operand" "=f")
15808 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15809 UNSPEC_F2XM1))]
15810 "TARGET_USE_FANCY_MATH_387
15811 && flag_unsafe_math_optimizations"
15812 "f2xm1"
15813 [(set_attr "type" "fpspc")
15814 (set_attr "mode" "XF")])
15815
15816 (define_insn "*fscalexf4"
15817 [(set (match_operand:XF 0 "register_operand" "=f")
15818 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15819 (match_operand:XF 3 "register_operand" "1")]
15820 UNSPEC_FSCALE_FRACT))
15821 (set (match_operand:XF 1 "register_operand" "=u")
15822 (unspec:XF [(match_dup 2) (match_dup 3)]
15823 UNSPEC_FSCALE_EXP))]
15824 "TARGET_USE_FANCY_MATH_387
15825 && flag_unsafe_math_optimizations"
15826 "fscale"
15827 [(set_attr "type" "fpspc")
15828 (set_attr "mode" "XF")])
15829
15830 (define_expand "expsf2"
15831 [(set (match_dup 2)
15832 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15833 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15834 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15835 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15836 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15837 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15838 (parallel [(set (match_dup 10)
15839 (unspec:XF [(match_dup 9) (match_dup 5)]
15840 UNSPEC_FSCALE_FRACT))
15841 (set (match_dup 11)
15842 (unspec:XF [(match_dup 9) (match_dup 5)]
15843 UNSPEC_FSCALE_EXP))])
15844 (set (match_operand:SF 0 "register_operand" "")
15845 (float_truncate:SF (match_dup 10)))]
15846 "TARGET_USE_FANCY_MATH_387
15847 && flag_unsafe_math_optimizations"
15848 {
15849 rtx temp;
15850 int i;
15851
15852 for (i=2; i<12; i++)
15853 operands[i] = gen_reg_rtx (XFmode);
15854 temp = standard_80387_constant_rtx (5); /* fldl2e */
15855 emit_move_insn (operands[3], temp);
15856 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15857 })
15858
15859 (define_expand "expdf2"
15860 [(set (match_dup 2)
15861 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15862 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15863 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15864 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15865 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15866 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15867 (parallel [(set (match_dup 10)
15868 (unspec:XF [(match_dup 9) (match_dup 5)]
15869 UNSPEC_FSCALE_FRACT))
15870 (set (match_dup 11)
15871 (unspec:XF [(match_dup 9) (match_dup 5)]
15872 UNSPEC_FSCALE_EXP))])
15873 (set (match_operand:DF 0 "register_operand" "")
15874 (float_truncate:DF (match_dup 10)))]
15875 "TARGET_USE_FANCY_MATH_387
15876 && flag_unsafe_math_optimizations"
15877 {
15878 rtx temp;
15879 int i;
15880
15881 for (i=2; i<12; i++)
15882 operands[i] = gen_reg_rtx (XFmode);
15883 temp = standard_80387_constant_rtx (5); /* fldl2e */
15884 emit_move_insn (operands[3], temp);
15885 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15886 })
15887
15888 (define_expand "expxf2"
15889 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15890 (match_dup 2)))
15891 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15892 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15893 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15894 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15895 (parallel [(set (match_operand:XF 0 "register_operand" "")
15896 (unspec:XF [(match_dup 8) (match_dup 4)]
15897 UNSPEC_FSCALE_FRACT))
15898 (set (match_dup 9)
15899 (unspec:XF [(match_dup 8) (match_dup 4)]
15900 UNSPEC_FSCALE_EXP))])]
15901 "TARGET_USE_FANCY_MATH_387
15902 && flag_unsafe_math_optimizations"
15903 {
15904 rtx temp;
15905 int i;
15906
15907 for (i=2; i<10; i++)
15908 operands[i] = gen_reg_rtx (XFmode);
15909 temp = standard_80387_constant_rtx (5); /* fldl2e */
15910 emit_move_insn (operands[2], temp);
15911 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15912 })
15913
15914 (define_expand "exp10sf2"
15915 [(set (match_dup 2)
15916 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15917 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15918 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15919 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15920 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15921 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15922 (parallel [(set (match_dup 10)
15923 (unspec:XF [(match_dup 9) (match_dup 5)]
15924 UNSPEC_FSCALE_FRACT))
15925 (set (match_dup 11)
15926 (unspec:XF [(match_dup 9) (match_dup 5)]
15927 UNSPEC_FSCALE_EXP))])
15928 (set (match_operand:SF 0 "register_operand" "")
15929 (float_truncate:SF (match_dup 10)))]
15930 "TARGET_USE_FANCY_MATH_387
15931 && flag_unsafe_math_optimizations"
15932 {
15933 rtx temp;
15934 int i;
15935
15936 for (i=2; i<12; i++)
15937 operands[i] = gen_reg_rtx (XFmode);
15938 temp = standard_80387_constant_rtx (6); /* fldl2t */
15939 emit_move_insn (operands[3], temp);
15940 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15941 })
15942
15943 (define_expand "exp10df2"
15944 [(set (match_dup 2)
15945 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15946 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15947 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15948 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15949 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15950 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15951 (parallel [(set (match_dup 10)
15952 (unspec:XF [(match_dup 9) (match_dup 5)]
15953 UNSPEC_FSCALE_FRACT))
15954 (set (match_dup 11)
15955 (unspec:XF [(match_dup 9) (match_dup 5)]
15956 UNSPEC_FSCALE_EXP))])
15957 (set (match_operand:DF 0 "register_operand" "")
15958 (float_truncate:DF (match_dup 10)))]
15959 "TARGET_USE_FANCY_MATH_387
15960 && flag_unsafe_math_optimizations"
15961 {
15962 rtx temp;
15963 int i;
15964
15965 for (i=2; i<12; i++)
15966 operands[i] = gen_reg_rtx (XFmode);
15967 temp = standard_80387_constant_rtx (6); /* fldl2t */
15968 emit_move_insn (operands[3], temp);
15969 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15970 })
15971
15972 (define_expand "exp10xf2"
15973 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15974 (match_dup 2)))
15975 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15976 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15977 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15978 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15979 (parallel [(set (match_operand:XF 0 "register_operand" "")
15980 (unspec:XF [(match_dup 8) (match_dup 4)]
15981 UNSPEC_FSCALE_FRACT))
15982 (set (match_dup 9)
15983 (unspec:XF [(match_dup 8) (match_dup 4)]
15984 UNSPEC_FSCALE_EXP))])]
15985 "TARGET_USE_FANCY_MATH_387
15986 && flag_unsafe_math_optimizations"
15987 {
15988 rtx temp;
15989 int i;
15990
15991 for (i=2; i<10; i++)
15992 operands[i] = gen_reg_rtx (XFmode);
15993 temp = standard_80387_constant_rtx (6); /* fldl2t */
15994 emit_move_insn (operands[2], temp);
15995 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15996 })
15997
15998 (define_expand "exp2sf2"
15999 [(set (match_dup 2)
16000 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16001 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16002 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16003 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16004 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16005 (parallel [(set (match_dup 8)
16006 (unspec:XF [(match_dup 7) (match_dup 3)]
16007 UNSPEC_FSCALE_FRACT))
16008 (set (match_dup 9)
16009 (unspec:XF [(match_dup 7) (match_dup 3)]
16010 UNSPEC_FSCALE_EXP))])
16011 (set (match_operand:SF 0 "register_operand" "")
16012 (float_truncate:SF (match_dup 8)))]
16013 "TARGET_USE_FANCY_MATH_387
16014 && flag_unsafe_math_optimizations"
16015 {
16016 int i;
16017
16018 for (i=2; i<10; i++)
16019 operands[i] = gen_reg_rtx (XFmode);
16020 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16021 })
16022
16023 (define_expand "exp2df2"
16024 [(set (match_dup 2)
16025 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16026 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16027 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16028 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16029 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16030 (parallel [(set (match_dup 8)
16031 (unspec:XF [(match_dup 7) (match_dup 3)]
16032 UNSPEC_FSCALE_FRACT))
16033 (set (match_dup 9)
16034 (unspec:XF [(match_dup 7) (match_dup 3)]
16035 UNSPEC_FSCALE_EXP))])
16036 (set (match_operand:DF 0 "register_operand" "")
16037 (float_truncate:DF (match_dup 8)))]
16038 "TARGET_USE_FANCY_MATH_387
16039 && flag_unsafe_math_optimizations"
16040 {
16041 int i;
16042
16043 for (i=2; i<10; i++)
16044 operands[i] = gen_reg_rtx (XFmode);
16045 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16046 })
16047
16048 (define_expand "exp2xf2"
16049 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16050 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16051 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16052 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16053 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16054 (parallel [(set (match_operand:XF 0 "register_operand" "")
16055 (unspec:XF [(match_dup 7) (match_dup 3)]
16056 UNSPEC_FSCALE_FRACT))
16057 (set (match_dup 8)
16058 (unspec:XF [(match_dup 7) (match_dup 3)]
16059 UNSPEC_FSCALE_EXP))])]
16060 "TARGET_USE_FANCY_MATH_387
16061 && flag_unsafe_math_optimizations"
16062 {
16063 int i;
16064
16065 for (i=2; i<9; i++)
16066 operands[i] = gen_reg_rtx (XFmode);
16067 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16068 })
16069
16070 (define_expand "expm1df2"
16071 [(set (match_dup 2)
16072 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16073 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16074 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16075 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16076 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16077 (parallel [(set (match_dup 8)
16078 (unspec:XF [(match_dup 7) (match_dup 5)]
16079 UNSPEC_FSCALE_FRACT))
16080 (set (match_dup 9)
16081 (unspec:XF [(match_dup 7) (match_dup 5)]
16082 UNSPEC_FSCALE_EXP))])
16083 (parallel [(set (match_dup 11)
16084 (unspec:XF [(match_dup 10) (match_dup 9)]
16085 UNSPEC_FSCALE_FRACT))
16086 (set (match_dup 12)
16087 (unspec:XF [(match_dup 10) (match_dup 9)]
16088 UNSPEC_FSCALE_EXP))])
16089 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16090 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16091 (set (match_operand:DF 0 "register_operand" "")
16092 (float_truncate:DF (match_dup 14)))]
16093 "TARGET_USE_FANCY_MATH_387
16094 && flag_unsafe_math_optimizations"
16095 {
16096 rtx temp;
16097 int i;
16098
16099 for (i=2; i<15; i++)
16100 operands[i] = gen_reg_rtx (XFmode);
16101 temp = standard_80387_constant_rtx (5); /* fldl2e */
16102 emit_move_insn (operands[3], temp);
16103 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16104 })
16105
16106 (define_expand "expm1sf2"
16107 [(set (match_dup 2)
16108 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16109 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16110 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16111 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16112 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16113 (parallel [(set (match_dup 8)
16114 (unspec:XF [(match_dup 7) (match_dup 5)]
16115 UNSPEC_FSCALE_FRACT))
16116 (set (match_dup 9)
16117 (unspec:XF [(match_dup 7) (match_dup 5)]
16118 UNSPEC_FSCALE_EXP))])
16119 (parallel [(set (match_dup 11)
16120 (unspec:XF [(match_dup 10) (match_dup 9)]
16121 UNSPEC_FSCALE_FRACT))
16122 (set (match_dup 12)
16123 (unspec:XF [(match_dup 10) (match_dup 9)]
16124 UNSPEC_FSCALE_EXP))])
16125 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16126 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16127 (set (match_operand:SF 0 "register_operand" "")
16128 (float_truncate:SF (match_dup 14)))]
16129 "TARGET_USE_FANCY_MATH_387
16130 && flag_unsafe_math_optimizations"
16131 {
16132 rtx temp;
16133 int i;
16134
16135 for (i=2; i<15; i++)
16136 operands[i] = gen_reg_rtx (XFmode);
16137 temp = standard_80387_constant_rtx (5); /* fldl2e */
16138 emit_move_insn (operands[3], temp);
16139 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16140 })
16141
16142 (define_expand "expm1xf2"
16143 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16144 (match_dup 2)))
16145 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16146 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16147 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16148 (parallel [(set (match_dup 7)
16149 (unspec:XF [(match_dup 6) (match_dup 4)]
16150 UNSPEC_FSCALE_FRACT))
16151 (set (match_dup 8)
16152 (unspec:XF [(match_dup 6) (match_dup 4)]
16153 UNSPEC_FSCALE_EXP))])
16154 (parallel [(set (match_dup 10)
16155 (unspec:XF [(match_dup 9) (match_dup 8)]
16156 UNSPEC_FSCALE_FRACT))
16157 (set (match_dup 11)
16158 (unspec:XF [(match_dup 9) (match_dup 8)]
16159 UNSPEC_FSCALE_EXP))])
16160 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16161 (set (match_operand:XF 0 "register_operand" "")
16162 (plus:XF (match_dup 12) (match_dup 7)))]
16163 "TARGET_USE_FANCY_MATH_387
16164 && flag_unsafe_math_optimizations"
16165 {
16166 rtx temp;
16167 int i;
16168
16169 for (i=2; i<13; i++)
16170 operands[i] = gen_reg_rtx (XFmode);
16171 temp = standard_80387_constant_rtx (5); /* fldl2e */
16172 emit_move_insn (operands[2], temp);
16173 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16174 })
16175 \f
16176
16177 (define_insn "frndintxf2"
16178 [(set (match_operand:XF 0 "register_operand" "=f")
16179 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16180 UNSPEC_FRNDINT))]
16181 "TARGET_USE_FANCY_MATH_387
16182 && flag_unsafe_math_optimizations"
16183 "frndint"
16184 [(set_attr "type" "fpspc")
16185 (set_attr "mode" "XF")])
16186
16187 (define_expand "rintdf2"
16188 [(use (match_operand:DF 0 "register_operand" ""))
16189 (use (match_operand:DF 1 "register_operand" ""))]
16190 "TARGET_USE_FANCY_MATH_387
16191 && flag_unsafe_math_optimizations"
16192 {
16193 rtx op0 = gen_reg_rtx (XFmode);
16194 rtx op1 = gen_reg_rtx (XFmode);
16195
16196 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16197 emit_insn (gen_frndintxf2 (op0, op1));
16198
16199 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16200 DONE;
16201 })
16202
16203 (define_expand "rintsf2"
16204 [(use (match_operand:SF 0 "register_operand" ""))
16205 (use (match_operand:SF 1 "register_operand" ""))]
16206 "TARGET_USE_FANCY_MATH_387
16207 && flag_unsafe_math_optimizations"
16208 {
16209 rtx op0 = gen_reg_rtx (XFmode);
16210 rtx op1 = gen_reg_rtx (XFmode);
16211
16212 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16213 emit_insn (gen_frndintxf2 (op0, op1));
16214
16215 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16216 DONE;
16217 })
16218
16219 (define_expand "rintxf2"
16220 [(use (match_operand:XF 0 "register_operand" ""))
16221 (use (match_operand:XF 1 "register_operand" ""))]
16222 "TARGET_USE_FANCY_MATH_387
16223 && flag_unsafe_math_optimizations"
16224 {
16225 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16226 DONE;
16227 })
16228
16229 (define_insn "frndintxf2_floor"
16230 [(set (match_operand:XF 0 "register_operand" "=f")
16231 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16232 UNSPEC_FRNDINT_FLOOR))
16233 (use (match_operand:HI 2 "memory_operand" "m"))
16234 (use (match_operand:HI 3 "memory_operand" "m"))]
16235 "TARGET_USE_FANCY_MATH_387
16236 && flag_unsafe_math_optimizations"
16237 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16238 [(set_attr "type" "frndint")
16239 (set_attr "i387_cw" "floor")
16240 (set_attr "mode" "XF")])
16241
16242 (define_expand "floordf2"
16243 [(use (match_operand:DF 0 "register_operand" ""))
16244 (use (match_operand:DF 1 "register_operand" ""))]
16245 "TARGET_USE_FANCY_MATH_387
16246 && flag_unsafe_math_optimizations"
16247 {
16248 rtx op0 = gen_reg_rtx (XFmode);
16249 rtx op1 = gen_reg_rtx (XFmode);
16250 rtx op2 = assign_386_stack_local (HImode, 1);
16251 rtx op3 = assign_386_stack_local (HImode, 2);
16252
16253 ix86_optimize_mode_switching = 1;
16254
16255 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16256 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16257
16258 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16259 DONE;
16260 })
16261
16262 (define_expand "floorsf2"
16263 [(use (match_operand:SF 0 "register_operand" ""))
16264 (use (match_operand:SF 1 "register_operand" ""))]
16265 "TARGET_USE_FANCY_MATH_387
16266 && flag_unsafe_math_optimizations"
16267 {
16268 rtx op0 = gen_reg_rtx (XFmode);
16269 rtx op1 = gen_reg_rtx (XFmode);
16270 rtx op2 = assign_386_stack_local (HImode, 1);
16271 rtx op3 = assign_386_stack_local (HImode, 2);
16272
16273 ix86_optimize_mode_switching = 1;
16274
16275 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16276 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16277
16278 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16279 DONE;
16280 })
16281
16282 (define_expand "floorxf2"
16283 [(use (match_operand:XF 0 "register_operand" ""))
16284 (use (match_operand:XF 1 "register_operand" ""))]
16285 "TARGET_USE_FANCY_MATH_387
16286 && flag_unsafe_math_optimizations"
16287 {
16288 rtx op2 = assign_386_stack_local (HImode, 1);
16289 rtx op3 = assign_386_stack_local (HImode, 2);
16290
16291 ix86_optimize_mode_switching = 1;
16292
16293 emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16294 DONE;
16295 })
16296
16297 (define_insn "frndintxf2_ceil"
16298 [(set (match_operand:XF 0 "register_operand" "=f")
16299 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16300 UNSPEC_FRNDINT_CEIL))
16301 (use (match_operand:HI 2 "memory_operand" "m"))
16302 (use (match_operand:HI 3 "memory_operand" "m"))]
16303 "TARGET_USE_FANCY_MATH_387
16304 && flag_unsafe_math_optimizations"
16305 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16306 [(set_attr "type" "frndint")
16307 (set_attr "i387_cw" "ceil")
16308 (set_attr "mode" "XF")])
16309
16310 (define_expand "ceildf2"
16311 [(use (match_operand:DF 0 "register_operand" ""))
16312 (use (match_operand:DF 1 "register_operand" ""))]
16313 "TARGET_USE_FANCY_MATH_387
16314 && flag_unsafe_math_optimizations"
16315 {
16316 rtx op0 = gen_reg_rtx (XFmode);
16317 rtx op1 = gen_reg_rtx (XFmode);
16318 rtx op2 = assign_386_stack_local (HImode, 1);
16319 rtx op3 = assign_386_stack_local (HImode, 2);
16320
16321 ix86_optimize_mode_switching = 1;
16322
16323 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16324 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16325
16326 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16327 DONE;
16328 })
16329
16330 (define_expand "ceilsf2"
16331 [(use (match_operand:SF 0 "register_operand" ""))
16332 (use (match_operand:SF 1 "register_operand" ""))]
16333 "TARGET_USE_FANCY_MATH_387
16334 && flag_unsafe_math_optimizations"
16335 {
16336 rtx op0 = gen_reg_rtx (XFmode);
16337 rtx op1 = gen_reg_rtx (XFmode);
16338 rtx op2 = assign_386_stack_local (HImode, 1);
16339 rtx op3 = assign_386_stack_local (HImode, 2);
16340
16341 ix86_optimize_mode_switching = 1;
16342
16343 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16344 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16345
16346 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16347 DONE;
16348 })
16349
16350 (define_expand "ceilxf2"
16351 [(use (match_operand:XF 0 "register_operand" ""))
16352 (use (match_operand:XF 1 "register_operand" ""))]
16353 "TARGET_USE_FANCY_MATH_387
16354 && flag_unsafe_math_optimizations"
16355 {
16356 rtx op2 = assign_386_stack_local (HImode, 1);
16357 rtx op3 = assign_386_stack_local (HImode, 2);
16358
16359 ix86_optimize_mode_switching = 1;
16360
16361 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16362 DONE;
16363 })
16364
16365 (define_insn "frndintxf2_trunc"
16366 [(set (match_operand:XF 0 "register_operand" "=f")
16367 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16368 UNSPEC_FRNDINT_TRUNC))
16369 (use (match_operand:HI 2 "memory_operand" "m"))
16370 (use (match_operand:HI 3 "memory_operand" "m"))]
16371 "TARGET_USE_FANCY_MATH_387
16372 && flag_unsafe_math_optimizations"
16373 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16374 [(set_attr "type" "frndint")
16375 (set_attr "i387_cw" "trunc")
16376 (set_attr "mode" "XF")])
16377
16378 (define_expand "btruncdf2"
16379 [(use (match_operand:DF 0 "register_operand" ""))
16380 (use (match_operand:DF 1 "register_operand" ""))]
16381 "TARGET_USE_FANCY_MATH_387
16382 && flag_unsafe_math_optimizations"
16383 {
16384 rtx op0 = gen_reg_rtx (XFmode);
16385 rtx op1 = gen_reg_rtx (XFmode);
16386 rtx op2 = assign_386_stack_local (HImode, 1);
16387 rtx op3 = assign_386_stack_local (HImode, 2);
16388
16389 ix86_optimize_mode_switching = 1;
16390
16391 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16392 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16393
16394 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16395 DONE;
16396 })
16397
16398 (define_expand "btruncsf2"
16399 [(use (match_operand:SF 0 "register_operand" ""))
16400 (use (match_operand:SF 1 "register_operand" ""))]
16401 "TARGET_USE_FANCY_MATH_387
16402 && flag_unsafe_math_optimizations"
16403 {
16404 rtx op0 = gen_reg_rtx (XFmode);
16405 rtx op1 = gen_reg_rtx (XFmode);
16406 rtx op2 = assign_386_stack_local (HImode, 1);
16407 rtx op3 = assign_386_stack_local (HImode, 2);
16408
16409 ix86_optimize_mode_switching = 1;
16410
16411 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16412 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16413
16414 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16415 DONE;
16416 })
16417
16418 (define_expand "btruncxf2"
16419 [(use (match_operand:XF 0 "register_operand" ""))
16420 (use (match_operand:XF 1 "register_operand" ""))]
16421 "TARGET_USE_FANCY_MATH_387
16422 && flag_unsafe_math_optimizations"
16423 {
16424 rtx op2 = assign_386_stack_local (HImode, 1);
16425 rtx op3 = assign_386_stack_local (HImode, 2);
16426
16427 ix86_optimize_mode_switching = 1;
16428
16429 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16430 DONE;
16431 })
16432
16433 (define_insn "frndintxf2_mask_pm"
16434 [(set (match_operand:XF 0 "register_operand" "=f")
16435 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16436 UNSPEC_FRNDINT_MASK_PM))
16437 (use (match_operand:HI 2 "memory_operand" "m"))
16438 (use (match_operand:HI 3 "memory_operand" "m"))]
16439 "TARGET_USE_FANCY_MATH_387
16440 && flag_unsafe_math_optimizations"
16441 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16442 [(set_attr "type" "frndint")
16443 (set_attr "i387_cw" "mask_pm")
16444 (set_attr "mode" "XF")])
16445
16446 (define_expand "nearbyintdf2"
16447 [(use (match_operand:DF 0 "register_operand" ""))
16448 (use (match_operand:DF 1 "register_operand" ""))]
16449 "TARGET_USE_FANCY_MATH_387
16450 && flag_unsafe_math_optimizations"
16451 {
16452 rtx op0 = gen_reg_rtx (XFmode);
16453 rtx op1 = gen_reg_rtx (XFmode);
16454 rtx op2 = assign_386_stack_local (HImode, 1);
16455 rtx op3 = assign_386_stack_local (HImode, 2);
16456
16457 ix86_optimize_mode_switching = 1;
16458
16459 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16460 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16461
16462 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16463 DONE;
16464 })
16465
16466 (define_expand "nearbyintsf2"
16467 [(use (match_operand:SF 0 "register_operand" ""))
16468 (use (match_operand:SF 1 "register_operand" ""))]
16469 "TARGET_USE_FANCY_MATH_387
16470 && flag_unsafe_math_optimizations"
16471 {
16472 rtx op0 = gen_reg_rtx (XFmode);
16473 rtx op1 = gen_reg_rtx (XFmode);
16474 rtx op2 = assign_386_stack_local (HImode, 1);
16475 rtx op3 = assign_386_stack_local (HImode, 2);
16476
16477 ix86_optimize_mode_switching = 1;
16478
16479 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16480 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16481
16482 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16483 DONE;
16484 })
16485
16486 (define_expand "nearbyintxf2"
16487 [(use (match_operand:XF 0 "register_operand" ""))
16488 (use (match_operand:XF 1 "register_operand" ""))]
16489 "TARGET_USE_FANCY_MATH_387
16490 && flag_unsafe_math_optimizations"
16491 {
16492 rtx op2 = assign_386_stack_local (HImode, 1);
16493 rtx op3 = assign_386_stack_local (HImode, 2);
16494
16495 ix86_optimize_mode_switching = 1;
16496
16497 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16498 op2, op3));
16499 DONE;
16500 })
16501
16502 \f
16503 ;; Block operation instructions
16504
16505 (define_insn "cld"
16506 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16507 ""
16508 "cld"
16509 [(set_attr "type" "cld")])
16510
16511 (define_expand "movmemsi"
16512 [(use (match_operand:BLK 0 "memory_operand" ""))
16513 (use (match_operand:BLK 1 "memory_operand" ""))
16514 (use (match_operand:SI 2 "nonmemory_operand" ""))
16515 (use (match_operand:SI 3 "const_int_operand" ""))]
16516 "! optimize_size"
16517 {
16518 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16519 DONE;
16520 else
16521 FAIL;
16522 })
16523
16524 (define_expand "movmemdi"
16525 [(use (match_operand:BLK 0 "memory_operand" ""))
16526 (use (match_operand:BLK 1 "memory_operand" ""))
16527 (use (match_operand:DI 2 "nonmemory_operand" ""))
16528 (use (match_operand:DI 3 "const_int_operand" ""))]
16529 "TARGET_64BIT"
16530 {
16531 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16532 DONE;
16533 else
16534 FAIL;
16535 })
16536
16537 ;; Most CPUs don't like single string operations
16538 ;; Handle this case here to simplify previous expander.
16539
16540 (define_expand "strmov"
16541 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16542 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16543 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16544 (clobber (reg:CC FLAGS_REG))])
16545 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16546 (clobber (reg:CC FLAGS_REG))])]
16547 ""
16548 {
16549 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16550
16551 /* If .md ever supports :P for Pmode, these can be directly
16552 in the pattern above. */
16553 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16554 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16555
16556 if (TARGET_SINGLE_STRINGOP || optimize_size)
16557 {
16558 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16559 operands[2], operands[3],
16560 operands[5], operands[6]));
16561 DONE;
16562 }
16563
16564 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16565 })
16566
16567 (define_expand "strmov_singleop"
16568 [(parallel [(set (match_operand 1 "memory_operand" "")
16569 (match_operand 3 "memory_operand" ""))
16570 (set (match_operand 0 "register_operand" "")
16571 (match_operand 4 "" ""))
16572 (set (match_operand 2 "register_operand" "")
16573 (match_operand 5 "" ""))
16574 (use (reg:SI DIRFLAG_REG))])]
16575 "TARGET_SINGLE_STRINGOP || optimize_size"
16576 "")
16577
16578 (define_insn "*strmovdi_rex_1"
16579 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16580 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16581 (set (match_operand:DI 0 "register_operand" "=D")
16582 (plus:DI (match_dup 2)
16583 (const_int 8)))
16584 (set (match_operand:DI 1 "register_operand" "=S")
16585 (plus:DI (match_dup 3)
16586 (const_int 8)))
16587 (use (reg:SI DIRFLAG_REG))]
16588 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16589 "movsq"
16590 [(set_attr "type" "str")
16591 (set_attr "mode" "DI")
16592 (set_attr "memory" "both")])
16593
16594 (define_insn "*strmovsi_1"
16595 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16596 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16597 (set (match_operand:SI 0 "register_operand" "=D")
16598 (plus:SI (match_dup 2)
16599 (const_int 4)))
16600 (set (match_operand:SI 1 "register_operand" "=S")
16601 (plus:SI (match_dup 3)
16602 (const_int 4)))
16603 (use (reg:SI DIRFLAG_REG))]
16604 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16605 "{movsl|movsd}"
16606 [(set_attr "type" "str")
16607 (set_attr "mode" "SI")
16608 (set_attr "memory" "both")])
16609
16610 (define_insn "*strmovsi_rex_1"
16611 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16612 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16613 (set (match_operand:DI 0 "register_operand" "=D")
16614 (plus:DI (match_dup 2)
16615 (const_int 4)))
16616 (set (match_operand:DI 1 "register_operand" "=S")
16617 (plus:DI (match_dup 3)
16618 (const_int 4)))
16619 (use (reg:SI DIRFLAG_REG))]
16620 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16621 "{movsl|movsd}"
16622 [(set_attr "type" "str")
16623 (set_attr "mode" "SI")
16624 (set_attr "memory" "both")])
16625
16626 (define_insn "*strmovhi_1"
16627 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16628 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16629 (set (match_operand:SI 0 "register_operand" "=D")
16630 (plus:SI (match_dup 2)
16631 (const_int 2)))
16632 (set (match_operand:SI 1 "register_operand" "=S")
16633 (plus:SI (match_dup 3)
16634 (const_int 2)))
16635 (use (reg:SI DIRFLAG_REG))]
16636 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16637 "movsw"
16638 [(set_attr "type" "str")
16639 (set_attr "memory" "both")
16640 (set_attr "mode" "HI")])
16641
16642 (define_insn "*strmovhi_rex_1"
16643 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16644 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16645 (set (match_operand:DI 0 "register_operand" "=D")
16646 (plus:DI (match_dup 2)
16647 (const_int 2)))
16648 (set (match_operand:DI 1 "register_operand" "=S")
16649 (plus:DI (match_dup 3)
16650 (const_int 2)))
16651 (use (reg:SI DIRFLAG_REG))]
16652 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16653 "movsw"
16654 [(set_attr "type" "str")
16655 (set_attr "memory" "both")
16656 (set_attr "mode" "HI")])
16657
16658 (define_insn "*strmovqi_1"
16659 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16660 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16661 (set (match_operand:SI 0 "register_operand" "=D")
16662 (plus:SI (match_dup 2)
16663 (const_int 1)))
16664 (set (match_operand:SI 1 "register_operand" "=S")
16665 (plus:SI (match_dup 3)
16666 (const_int 1)))
16667 (use (reg:SI DIRFLAG_REG))]
16668 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16669 "movsb"
16670 [(set_attr "type" "str")
16671 (set_attr "memory" "both")
16672 (set_attr "mode" "QI")])
16673
16674 (define_insn "*strmovqi_rex_1"
16675 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16676 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16677 (set (match_operand:DI 0 "register_operand" "=D")
16678 (plus:DI (match_dup 2)
16679 (const_int 1)))
16680 (set (match_operand:DI 1 "register_operand" "=S")
16681 (plus:DI (match_dup 3)
16682 (const_int 1)))
16683 (use (reg:SI DIRFLAG_REG))]
16684 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16685 "movsb"
16686 [(set_attr "type" "str")
16687 (set_attr "memory" "both")
16688 (set_attr "mode" "QI")])
16689
16690 (define_expand "rep_mov"
16691 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16692 (set (match_operand 0 "register_operand" "")
16693 (match_operand 5 "" ""))
16694 (set (match_operand 2 "register_operand" "")
16695 (match_operand 6 "" ""))
16696 (set (match_operand 1 "memory_operand" "")
16697 (match_operand 3 "memory_operand" ""))
16698 (use (match_dup 4))
16699 (use (reg:SI DIRFLAG_REG))])]
16700 ""
16701 "")
16702
16703 (define_insn "*rep_movdi_rex64"
16704 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16705 (set (match_operand:DI 0 "register_operand" "=D")
16706 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16707 (const_int 3))
16708 (match_operand:DI 3 "register_operand" "0")))
16709 (set (match_operand:DI 1 "register_operand" "=S")
16710 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16711 (match_operand:DI 4 "register_operand" "1")))
16712 (set (mem:BLK (match_dup 3))
16713 (mem:BLK (match_dup 4)))
16714 (use (match_dup 5))
16715 (use (reg:SI DIRFLAG_REG))]
16716 "TARGET_64BIT"
16717 "{rep\;movsq|rep movsq}"
16718 [(set_attr "type" "str")
16719 (set_attr "prefix_rep" "1")
16720 (set_attr "memory" "both")
16721 (set_attr "mode" "DI")])
16722
16723 (define_insn "*rep_movsi"
16724 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16725 (set (match_operand:SI 0 "register_operand" "=D")
16726 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16727 (const_int 2))
16728 (match_operand:SI 3 "register_operand" "0")))
16729 (set (match_operand:SI 1 "register_operand" "=S")
16730 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16731 (match_operand:SI 4 "register_operand" "1")))
16732 (set (mem:BLK (match_dup 3))
16733 (mem:BLK (match_dup 4)))
16734 (use (match_dup 5))
16735 (use (reg:SI DIRFLAG_REG))]
16736 "!TARGET_64BIT"
16737 "{rep\;movsl|rep movsd}"
16738 [(set_attr "type" "str")
16739 (set_attr "prefix_rep" "1")
16740 (set_attr "memory" "both")
16741 (set_attr "mode" "SI")])
16742
16743 (define_insn "*rep_movsi_rex64"
16744 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16745 (set (match_operand:DI 0 "register_operand" "=D")
16746 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16747 (const_int 2))
16748 (match_operand:DI 3 "register_operand" "0")))
16749 (set (match_operand:DI 1 "register_operand" "=S")
16750 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16751 (match_operand:DI 4 "register_operand" "1")))
16752 (set (mem:BLK (match_dup 3))
16753 (mem:BLK (match_dup 4)))
16754 (use (match_dup 5))
16755 (use (reg:SI DIRFLAG_REG))]
16756 "TARGET_64BIT"
16757 "{rep\;movsl|rep movsd}"
16758 [(set_attr "type" "str")
16759 (set_attr "prefix_rep" "1")
16760 (set_attr "memory" "both")
16761 (set_attr "mode" "SI")])
16762
16763 (define_insn "*rep_movqi"
16764 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16765 (set (match_operand:SI 0 "register_operand" "=D")
16766 (plus:SI (match_operand:SI 3 "register_operand" "0")
16767 (match_operand:SI 5 "register_operand" "2")))
16768 (set (match_operand:SI 1 "register_operand" "=S")
16769 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16770 (set (mem:BLK (match_dup 3))
16771 (mem:BLK (match_dup 4)))
16772 (use (match_dup 5))
16773 (use (reg:SI DIRFLAG_REG))]
16774 "!TARGET_64BIT"
16775 "{rep\;movsb|rep movsb}"
16776 [(set_attr "type" "str")
16777 (set_attr "prefix_rep" "1")
16778 (set_attr "memory" "both")
16779 (set_attr "mode" "SI")])
16780
16781 (define_insn "*rep_movqi_rex64"
16782 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16783 (set (match_operand:DI 0 "register_operand" "=D")
16784 (plus:DI (match_operand:DI 3 "register_operand" "0")
16785 (match_operand:DI 5 "register_operand" "2")))
16786 (set (match_operand:DI 1 "register_operand" "=S")
16787 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16788 (set (mem:BLK (match_dup 3))
16789 (mem:BLK (match_dup 4)))
16790 (use (match_dup 5))
16791 (use (reg:SI DIRFLAG_REG))]
16792 "TARGET_64BIT"
16793 "{rep\;movsb|rep movsb}"
16794 [(set_attr "type" "str")
16795 (set_attr "prefix_rep" "1")
16796 (set_attr "memory" "both")
16797 (set_attr "mode" "SI")])
16798
16799 (define_expand "clrmemsi"
16800 [(use (match_operand:BLK 0 "memory_operand" ""))
16801 (use (match_operand:SI 1 "nonmemory_operand" ""))
16802 (use (match_operand 2 "const_int_operand" ""))]
16803 ""
16804 {
16805 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16806 DONE;
16807 else
16808 FAIL;
16809 })
16810
16811 (define_expand "clrmemdi"
16812 [(use (match_operand:BLK 0 "memory_operand" ""))
16813 (use (match_operand:DI 1 "nonmemory_operand" ""))
16814 (use (match_operand 2 "const_int_operand" ""))]
16815 "TARGET_64BIT"
16816 {
16817 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16818 DONE;
16819 else
16820 FAIL;
16821 })
16822
16823 ;; Most CPUs don't like single string operations
16824 ;; Handle this case here to simplify previous expander.
16825
16826 (define_expand "strset"
16827 [(set (match_operand 1 "memory_operand" "")
16828 (match_operand 2 "register_operand" ""))
16829 (parallel [(set (match_operand 0 "register_operand" "")
16830 (match_dup 3))
16831 (clobber (reg:CC FLAGS_REG))])]
16832 ""
16833 {
16834 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16835 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16836
16837 /* If .md ever supports :P for Pmode, this can be directly
16838 in the pattern above. */
16839 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16840 GEN_INT (GET_MODE_SIZE (GET_MODE
16841 (operands[2]))));
16842 if (TARGET_SINGLE_STRINGOP || optimize_size)
16843 {
16844 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16845 operands[3]));
16846 DONE;
16847 }
16848 })
16849
16850 (define_expand "strset_singleop"
16851 [(parallel [(set (match_operand 1 "memory_operand" "")
16852 (match_operand 2 "register_operand" ""))
16853 (set (match_operand 0 "register_operand" "")
16854 (match_operand 3 "" ""))
16855 (use (reg:SI DIRFLAG_REG))])]
16856 "TARGET_SINGLE_STRINGOP || optimize_size"
16857 "")
16858
16859 (define_insn "*strsetdi_rex_1"
16860 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16861 (match_operand:DI 2 "register_operand" "a"))
16862 (set (match_operand:DI 0 "register_operand" "=D")
16863 (plus:DI (match_dup 1)
16864 (const_int 8)))
16865 (use (reg:SI DIRFLAG_REG))]
16866 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16867 "stosq"
16868 [(set_attr "type" "str")
16869 (set_attr "memory" "store")
16870 (set_attr "mode" "DI")])
16871
16872 (define_insn "*strsetsi_1"
16873 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16874 (match_operand:SI 2 "register_operand" "a"))
16875 (set (match_operand:SI 0 "register_operand" "=D")
16876 (plus:SI (match_dup 1)
16877 (const_int 4)))
16878 (use (reg:SI DIRFLAG_REG))]
16879 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16880 "{stosl|stosd}"
16881 [(set_attr "type" "str")
16882 (set_attr "memory" "store")
16883 (set_attr "mode" "SI")])
16884
16885 (define_insn "*strsetsi_rex_1"
16886 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16887 (match_operand:SI 2 "register_operand" "a"))
16888 (set (match_operand:DI 0 "register_operand" "=D")
16889 (plus:DI (match_dup 1)
16890 (const_int 4)))
16891 (use (reg:SI DIRFLAG_REG))]
16892 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16893 "{stosl|stosd}"
16894 [(set_attr "type" "str")
16895 (set_attr "memory" "store")
16896 (set_attr "mode" "SI")])
16897
16898 (define_insn "*strsethi_1"
16899 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16900 (match_operand:HI 2 "register_operand" "a"))
16901 (set (match_operand:SI 0 "register_operand" "=D")
16902 (plus:SI (match_dup 1)
16903 (const_int 2)))
16904 (use (reg:SI DIRFLAG_REG))]
16905 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16906 "stosw"
16907 [(set_attr "type" "str")
16908 (set_attr "memory" "store")
16909 (set_attr "mode" "HI")])
16910
16911 (define_insn "*strsethi_rex_1"
16912 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16913 (match_operand:HI 2 "register_operand" "a"))
16914 (set (match_operand:DI 0 "register_operand" "=D")
16915 (plus:DI (match_dup 1)
16916 (const_int 2)))
16917 (use (reg:SI DIRFLAG_REG))]
16918 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16919 "stosw"
16920 [(set_attr "type" "str")
16921 (set_attr "memory" "store")
16922 (set_attr "mode" "HI")])
16923
16924 (define_insn "*strsetqi_1"
16925 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16926 (match_operand:QI 2 "register_operand" "a"))
16927 (set (match_operand:SI 0 "register_operand" "=D")
16928 (plus:SI (match_dup 1)
16929 (const_int 1)))
16930 (use (reg:SI DIRFLAG_REG))]
16931 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16932 "stosb"
16933 [(set_attr "type" "str")
16934 (set_attr "memory" "store")
16935 (set_attr "mode" "QI")])
16936
16937 (define_insn "*strsetqi_rex_1"
16938 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16939 (match_operand:QI 2 "register_operand" "a"))
16940 (set (match_operand:DI 0 "register_operand" "=D")
16941 (plus:DI (match_dup 1)
16942 (const_int 1)))
16943 (use (reg:SI DIRFLAG_REG))]
16944 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16945 "stosb"
16946 [(set_attr "type" "str")
16947 (set_attr "memory" "store")
16948 (set_attr "mode" "QI")])
16949
16950 (define_expand "rep_stos"
16951 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16952 (set (match_operand 0 "register_operand" "")
16953 (match_operand 4 "" ""))
16954 (set (match_operand 2 "memory_operand" "") (const_int 0))
16955 (use (match_operand 3 "register_operand" ""))
16956 (use (match_dup 1))
16957 (use (reg:SI DIRFLAG_REG))])]
16958 ""
16959 "")
16960
16961 (define_insn "*rep_stosdi_rex64"
16962 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16963 (set (match_operand:DI 0 "register_operand" "=D")
16964 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16965 (const_int 3))
16966 (match_operand:DI 3 "register_operand" "0")))
16967 (set (mem:BLK (match_dup 3))
16968 (const_int 0))
16969 (use (match_operand:DI 2 "register_operand" "a"))
16970 (use (match_dup 4))
16971 (use (reg:SI DIRFLAG_REG))]
16972 "TARGET_64BIT"
16973 "{rep\;stosq|rep stosq}"
16974 [(set_attr "type" "str")
16975 (set_attr "prefix_rep" "1")
16976 (set_attr "memory" "store")
16977 (set_attr "mode" "DI")])
16978
16979 (define_insn "*rep_stossi"
16980 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16981 (set (match_operand:SI 0 "register_operand" "=D")
16982 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16983 (const_int 2))
16984 (match_operand:SI 3 "register_operand" "0")))
16985 (set (mem:BLK (match_dup 3))
16986 (const_int 0))
16987 (use (match_operand:SI 2 "register_operand" "a"))
16988 (use (match_dup 4))
16989 (use (reg:SI DIRFLAG_REG))]
16990 "!TARGET_64BIT"
16991 "{rep\;stosl|rep stosd}"
16992 [(set_attr "type" "str")
16993 (set_attr "prefix_rep" "1")
16994 (set_attr "memory" "store")
16995 (set_attr "mode" "SI")])
16996
16997 (define_insn "*rep_stossi_rex64"
16998 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16999 (set (match_operand:DI 0 "register_operand" "=D")
17000 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17001 (const_int 2))
17002 (match_operand:DI 3 "register_operand" "0")))
17003 (set (mem:BLK (match_dup 3))
17004 (const_int 0))
17005 (use (match_operand:SI 2 "register_operand" "a"))
17006 (use (match_dup 4))
17007 (use (reg:SI DIRFLAG_REG))]
17008 "TARGET_64BIT"
17009 "{rep\;stosl|rep stosd}"
17010 [(set_attr "type" "str")
17011 (set_attr "prefix_rep" "1")
17012 (set_attr "memory" "store")
17013 (set_attr "mode" "SI")])
17014
17015 (define_insn "*rep_stosqi"
17016 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17017 (set (match_operand:SI 0 "register_operand" "=D")
17018 (plus:SI (match_operand:SI 3 "register_operand" "0")
17019 (match_operand:SI 4 "register_operand" "1")))
17020 (set (mem:BLK (match_dup 3))
17021 (const_int 0))
17022 (use (match_operand:QI 2 "register_operand" "a"))
17023 (use (match_dup 4))
17024 (use (reg:SI DIRFLAG_REG))]
17025 "!TARGET_64BIT"
17026 "{rep\;stosb|rep stosb}"
17027 [(set_attr "type" "str")
17028 (set_attr "prefix_rep" "1")
17029 (set_attr "memory" "store")
17030 (set_attr "mode" "QI")])
17031
17032 (define_insn "*rep_stosqi_rex64"
17033 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17034 (set (match_operand:DI 0 "register_operand" "=D")
17035 (plus:DI (match_operand:DI 3 "register_operand" "0")
17036 (match_operand:DI 4 "register_operand" "1")))
17037 (set (mem:BLK (match_dup 3))
17038 (const_int 0))
17039 (use (match_operand:QI 2 "register_operand" "a"))
17040 (use (match_dup 4))
17041 (use (reg:SI DIRFLAG_REG))]
17042 "TARGET_64BIT"
17043 "{rep\;stosb|rep stosb}"
17044 [(set_attr "type" "str")
17045 (set_attr "prefix_rep" "1")
17046 (set_attr "memory" "store")
17047 (set_attr "mode" "QI")])
17048
17049 (define_expand "cmpstrsi"
17050 [(set (match_operand:SI 0 "register_operand" "")
17051 (compare:SI (match_operand:BLK 1 "general_operand" "")
17052 (match_operand:BLK 2 "general_operand" "")))
17053 (use (match_operand 3 "general_operand" ""))
17054 (use (match_operand 4 "immediate_operand" ""))]
17055 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17056 {
17057 rtx addr1, addr2, out, outlow, count, countreg, align;
17058
17059 /* Can't use this if the user has appropriated esi or edi. */
17060 if (global_regs[4] || global_regs[5])
17061 FAIL;
17062
17063 out = operands[0];
17064 if (GET_CODE (out) != REG)
17065 out = gen_reg_rtx (SImode);
17066
17067 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17068 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17069 if (addr1 != XEXP (operands[1], 0))
17070 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17071 if (addr2 != XEXP (operands[2], 0))
17072 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17073
17074 count = operands[3];
17075 countreg = ix86_zero_extend_to_Pmode (count);
17076
17077 /* %%% Iff we are testing strict equality, we can use known alignment
17078 to good advantage. This may be possible with combine, particularly
17079 once cc0 is dead. */
17080 align = operands[4];
17081
17082 emit_insn (gen_cld ());
17083 if (GET_CODE (count) == CONST_INT)
17084 {
17085 if (INTVAL (count) == 0)
17086 {
17087 emit_move_insn (operands[0], const0_rtx);
17088 DONE;
17089 }
17090 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17091 operands[1], operands[2]));
17092 }
17093 else
17094 {
17095 if (TARGET_64BIT)
17096 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17097 else
17098 emit_insn (gen_cmpsi_1 (countreg, countreg));
17099 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17100 operands[1], operands[2]));
17101 }
17102
17103 outlow = gen_lowpart (QImode, out);
17104 emit_insn (gen_cmpintqi (outlow));
17105 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17106
17107 if (operands[0] != out)
17108 emit_move_insn (operands[0], out);
17109
17110 DONE;
17111 })
17112
17113 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17114
17115 (define_expand "cmpintqi"
17116 [(set (match_dup 1)
17117 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17118 (set (match_dup 2)
17119 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17120 (parallel [(set (match_operand:QI 0 "register_operand" "")
17121 (minus:QI (match_dup 1)
17122 (match_dup 2)))
17123 (clobber (reg:CC FLAGS_REG))])]
17124 ""
17125 "operands[1] = gen_reg_rtx (QImode);
17126 operands[2] = gen_reg_rtx (QImode);")
17127
17128 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17129 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17130
17131 (define_expand "cmpstrqi_nz_1"
17132 [(parallel [(set (reg:CC FLAGS_REG)
17133 (compare:CC (match_operand 4 "memory_operand" "")
17134 (match_operand 5 "memory_operand" "")))
17135 (use (match_operand 2 "register_operand" ""))
17136 (use (match_operand:SI 3 "immediate_operand" ""))
17137 (use (reg:SI DIRFLAG_REG))
17138 (clobber (match_operand 0 "register_operand" ""))
17139 (clobber (match_operand 1 "register_operand" ""))
17140 (clobber (match_dup 2))])]
17141 ""
17142 "")
17143
17144 (define_insn "*cmpstrqi_nz_1"
17145 [(set (reg:CC FLAGS_REG)
17146 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17147 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17148 (use (match_operand:SI 6 "register_operand" "2"))
17149 (use (match_operand:SI 3 "immediate_operand" "i"))
17150 (use (reg:SI DIRFLAG_REG))
17151 (clobber (match_operand:SI 0 "register_operand" "=S"))
17152 (clobber (match_operand:SI 1 "register_operand" "=D"))
17153 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17154 "!TARGET_64BIT"
17155 "repz{\;| }cmpsb"
17156 [(set_attr "type" "str")
17157 (set_attr "mode" "QI")
17158 (set_attr "prefix_rep" "1")])
17159
17160 (define_insn "*cmpstrqi_nz_rex_1"
17161 [(set (reg:CC FLAGS_REG)
17162 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17163 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17164 (use (match_operand:DI 6 "register_operand" "2"))
17165 (use (match_operand:SI 3 "immediate_operand" "i"))
17166 (use (reg:SI DIRFLAG_REG))
17167 (clobber (match_operand:DI 0 "register_operand" "=S"))
17168 (clobber (match_operand:DI 1 "register_operand" "=D"))
17169 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17170 "TARGET_64BIT"
17171 "repz{\;| }cmpsb"
17172 [(set_attr "type" "str")
17173 (set_attr "mode" "QI")
17174 (set_attr "prefix_rep" "1")])
17175
17176 ;; The same, but the count is not known to not be zero.
17177
17178 (define_expand "cmpstrqi_1"
17179 [(parallel [(set (reg:CC FLAGS_REG)
17180 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17181 (const_int 0))
17182 (compare:CC (match_operand 4 "memory_operand" "")
17183 (match_operand 5 "memory_operand" ""))
17184 (const_int 0)))
17185 (use (match_operand:SI 3 "immediate_operand" ""))
17186 (use (reg:CC FLAGS_REG))
17187 (use (reg:SI DIRFLAG_REG))
17188 (clobber (match_operand 0 "register_operand" ""))
17189 (clobber (match_operand 1 "register_operand" ""))
17190 (clobber (match_dup 2))])]
17191 ""
17192 "")
17193
17194 (define_insn "*cmpstrqi_1"
17195 [(set (reg:CC FLAGS_REG)
17196 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17197 (const_int 0))
17198 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17199 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17200 (const_int 0)))
17201 (use (match_operand:SI 3 "immediate_operand" "i"))
17202 (use (reg:CC FLAGS_REG))
17203 (use (reg:SI DIRFLAG_REG))
17204 (clobber (match_operand:SI 0 "register_operand" "=S"))
17205 (clobber (match_operand:SI 1 "register_operand" "=D"))
17206 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17207 "!TARGET_64BIT"
17208 "repz{\;| }cmpsb"
17209 [(set_attr "type" "str")
17210 (set_attr "mode" "QI")
17211 (set_attr "prefix_rep" "1")])
17212
17213 (define_insn "*cmpstrqi_rex_1"
17214 [(set (reg:CC FLAGS_REG)
17215 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17216 (const_int 0))
17217 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17218 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17219 (const_int 0)))
17220 (use (match_operand:SI 3 "immediate_operand" "i"))
17221 (use (reg:CC FLAGS_REG))
17222 (use (reg:SI DIRFLAG_REG))
17223 (clobber (match_operand:DI 0 "register_operand" "=S"))
17224 (clobber (match_operand:DI 1 "register_operand" "=D"))
17225 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17226 "TARGET_64BIT"
17227 "repz{\;| }cmpsb"
17228 [(set_attr "type" "str")
17229 (set_attr "mode" "QI")
17230 (set_attr "prefix_rep" "1")])
17231
17232 (define_expand "strlensi"
17233 [(set (match_operand:SI 0 "register_operand" "")
17234 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17235 (match_operand:QI 2 "immediate_operand" "")
17236 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17237 ""
17238 {
17239 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17240 DONE;
17241 else
17242 FAIL;
17243 })
17244
17245 (define_expand "strlendi"
17246 [(set (match_operand:DI 0 "register_operand" "")
17247 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17248 (match_operand:QI 2 "immediate_operand" "")
17249 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17250 ""
17251 {
17252 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17253 DONE;
17254 else
17255 FAIL;
17256 })
17257
17258 (define_expand "strlenqi_1"
17259 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17260 (use (reg:SI DIRFLAG_REG))
17261 (clobber (match_operand 1 "register_operand" ""))
17262 (clobber (reg:CC FLAGS_REG))])]
17263 ""
17264 "")
17265
17266 (define_insn "*strlenqi_1"
17267 [(set (match_operand:SI 0 "register_operand" "=&c")
17268 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17269 (match_operand:QI 2 "register_operand" "a")
17270 (match_operand:SI 3 "immediate_operand" "i")
17271 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17272 (use (reg:SI DIRFLAG_REG))
17273 (clobber (match_operand:SI 1 "register_operand" "=D"))
17274 (clobber (reg:CC FLAGS_REG))]
17275 "!TARGET_64BIT"
17276 "repnz{\;| }scasb"
17277 [(set_attr "type" "str")
17278 (set_attr "mode" "QI")
17279 (set_attr "prefix_rep" "1")])
17280
17281 (define_insn "*strlenqi_rex_1"
17282 [(set (match_operand:DI 0 "register_operand" "=&c")
17283 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17284 (match_operand:QI 2 "register_operand" "a")
17285 (match_operand:DI 3 "immediate_operand" "i")
17286 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17287 (use (reg:SI DIRFLAG_REG))
17288 (clobber (match_operand:DI 1 "register_operand" "=D"))
17289 (clobber (reg:CC FLAGS_REG))]
17290 "TARGET_64BIT"
17291 "repnz{\;| }scasb"
17292 [(set_attr "type" "str")
17293 (set_attr "mode" "QI")
17294 (set_attr "prefix_rep" "1")])
17295
17296 ;; Peephole optimizations to clean up after cmpstr*. This should be
17297 ;; handled in combine, but it is not currently up to the task.
17298 ;; When used for their truth value, the cmpstr* expanders generate
17299 ;; code like this:
17300 ;;
17301 ;; repz cmpsb
17302 ;; seta %al
17303 ;; setb %dl
17304 ;; cmpb %al, %dl
17305 ;; jcc label
17306 ;;
17307 ;; The intermediate three instructions are unnecessary.
17308
17309 ;; This one handles cmpstr*_nz_1...
17310 (define_peephole2
17311 [(parallel[
17312 (set (reg:CC FLAGS_REG)
17313 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17314 (mem:BLK (match_operand 5 "register_operand" ""))))
17315 (use (match_operand 6 "register_operand" ""))
17316 (use (match_operand:SI 3 "immediate_operand" ""))
17317 (use (reg:SI DIRFLAG_REG))
17318 (clobber (match_operand 0 "register_operand" ""))
17319 (clobber (match_operand 1 "register_operand" ""))
17320 (clobber (match_operand 2 "register_operand" ""))])
17321 (set (match_operand:QI 7 "register_operand" "")
17322 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17323 (set (match_operand:QI 8 "register_operand" "")
17324 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17325 (set (reg FLAGS_REG)
17326 (compare (match_dup 7) (match_dup 8)))
17327 ]
17328 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17329 [(parallel[
17330 (set (reg:CC FLAGS_REG)
17331 (compare:CC (mem:BLK (match_dup 4))
17332 (mem:BLK (match_dup 5))))
17333 (use (match_dup 6))
17334 (use (match_dup 3))
17335 (use (reg:SI DIRFLAG_REG))
17336 (clobber (match_dup 0))
17337 (clobber (match_dup 1))
17338 (clobber (match_dup 2))])]
17339 "")
17340
17341 ;; ...and this one handles cmpstr*_1.
17342 (define_peephole2
17343 [(parallel[
17344 (set (reg:CC FLAGS_REG)
17345 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17346 (const_int 0))
17347 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17348 (mem:BLK (match_operand 5 "register_operand" "")))
17349 (const_int 0)))
17350 (use (match_operand:SI 3 "immediate_operand" ""))
17351 (use (reg:CC FLAGS_REG))
17352 (use (reg:SI DIRFLAG_REG))
17353 (clobber (match_operand 0 "register_operand" ""))
17354 (clobber (match_operand 1 "register_operand" ""))
17355 (clobber (match_operand 2 "register_operand" ""))])
17356 (set (match_operand:QI 7 "register_operand" "")
17357 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17358 (set (match_operand:QI 8 "register_operand" "")
17359 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17360 (set (reg FLAGS_REG)
17361 (compare (match_dup 7) (match_dup 8)))
17362 ]
17363 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17364 [(parallel[
17365 (set (reg:CC FLAGS_REG)
17366 (if_then_else:CC (ne (match_dup 6)
17367 (const_int 0))
17368 (compare:CC (mem:BLK (match_dup 4))
17369 (mem:BLK (match_dup 5)))
17370 (const_int 0)))
17371 (use (match_dup 3))
17372 (use (reg:CC FLAGS_REG))
17373 (use (reg:SI DIRFLAG_REG))
17374 (clobber (match_dup 0))
17375 (clobber (match_dup 1))
17376 (clobber (match_dup 2))])]
17377 "")
17378
17379
17380 \f
17381 ;; Conditional move instructions.
17382
17383 (define_expand "movdicc"
17384 [(set (match_operand:DI 0 "register_operand" "")
17385 (if_then_else:DI (match_operand 1 "comparison_operator" "")
17386 (match_operand:DI 2 "general_operand" "")
17387 (match_operand:DI 3 "general_operand" "")))]
17388 "TARGET_64BIT"
17389 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17390
17391 (define_insn "x86_movdicc_0_m1_rex64"
17392 [(set (match_operand:DI 0 "register_operand" "=r")
17393 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17394 (const_int -1)
17395 (const_int 0)))
17396 (clobber (reg:CC FLAGS_REG))]
17397 "TARGET_64BIT"
17398 "sbb{q}\t%0, %0"
17399 ; Since we don't have the proper number of operands for an alu insn,
17400 ; fill in all the blanks.
17401 [(set_attr "type" "alu")
17402 (set_attr "pent_pair" "pu")
17403 (set_attr "memory" "none")
17404 (set_attr "imm_disp" "false")
17405 (set_attr "mode" "DI")
17406 (set_attr "length_immediate" "0")])
17407
17408 (define_insn "movdicc_c_rex64"
17409 [(set (match_operand:DI 0 "register_operand" "=r,r")
17410 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17411 [(reg FLAGS_REG) (const_int 0)])
17412 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17413 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17414 "TARGET_64BIT && TARGET_CMOVE
17415 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17416 "@
17417 cmov%O2%C1\t{%2, %0|%0, %2}
17418 cmov%O2%c1\t{%3, %0|%0, %3}"
17419 [(set_attr "type" "icmov")
17420 (set_attr "mode" "DI")])
17421
17422 (define_expand "movsicc"
17423 [(set (match_operand:SI 0 "register_operand" "")
17424 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17425 (match_operand:SI 2 "general_operand" "")
17426 (match_operand:SI 3 "general_operand" "")))]
17427 ""
17428 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17429
17430 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17431 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17432 ;; So just document what we're doing explicitly.
17433
17434 (define_insn "x86_movsicc_0_m1"
17435 [(set (match_operand:SI 0 "register_operand" "=r")
17436 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17437 (const_int -1)
17438 (const_int 0)))
17439 (clobber (reg:CC FLAGS_REG))]
17440 ""
17441 "sbb{l}\t%0, %0"
17442 ; Since we don't have the proper number of operands for an alu insn,
17443 ; fill in all the blanks.
17444 [(set_attr "type" "alu")
17445 (set_attr "pent_pair" "pu")
17446 (set_attr "memory" "none")
17447 (set_attr "imm_disp" "false")
17448 (set_attr "mode" "SI")
17449 (set_attr "length_immediate" "0")])
17450
17451 (define_insn "*movsicc_noc"
17452 [(set (match_operand:SI 0 "register_operand" "=r,r")
17453 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17454 [(reg FLAGS_REG) (const_int 0)])
17455 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17456 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17457 "TARGET_CMOVE
17458 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17459 "@
17460 cmov%O2%C1\t{%2, %0|%0, %2}
17461 cmov%O2%c1\t{%3, %0|%0, %3}"
17462 [(set_attr "type" "icmov")
17463 (set_attr "mode" "SI")])
17464
17465 (define_expand "movhicc"
17466 [(set (match_operand:HI 0 "register_operand" "")
17467 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17468 (match_operand:HI 2 "general_operand" "")
17469 (match_operand:HI 3 "general_operand" "")))]
17470 "TARGET_HIMODE_MATH"
17471 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17472
17473 (define_insn "*movhicc_noc"
17474 [(set (match_operand:HI 0 "register_operand" "=r,r")
17475 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17476 [(reg FLAGS_REG) (const_int 0)])
17477 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17478 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17479 "TARGET_CMOVE
17480 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17481 "@
17482 cmov%O2%C1\t{%2, %0|%0, %2}
17483 cmov%O2%c1\t{%3, %0|%0, %3}"
17484 [(set_attr "type" "icmov")
17485 (set_attr "mode" "HI")])
17486
17487 (define_expand "movqicc"
17488 [(set (match_operand:QI 0 "register_operand" "")
17489 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17490 (match_operand:QI 2 "general_operand" "")
17491 (match_operand:QI 3 "general_operand" "")))]
17492 "TARGET_QIMODE_MATH"
17493 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17494
17495 (define_insn_and_split "*movqicc_noc"
17496 [(set (match_operand:QI 0 "register_operand" "=r,r")
17497 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17498 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17499 (match_operand:QI 2 "register_operand" "r,0")
17500 (match_operand:QI 3 "register_operand" "0,r")))]
17501 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17502 "#"
17503 "&& reload_completed"
17504 [(set (match_dup 0)
17505 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17506 (match_dup 2)
17507 (match_dup 3)))]
17508 "operands[0] = gen_lowpart (SImode, operands[0]);
17509 operands[2] = gen_lowpart (SImode, operands[2]);
17510 operands[3] = gen_lowpart (SImode, operands[3]);"
17511 [(set_attr "type" "icmov")
17512 (set_attr "mode" "SI")])
17513
17514 (define_expand "movsfcc"
17515 [(set (match_operand:SF 0 "register_operand" "")
17516 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17517 (match_operand:SF 2 "register_operand" "")
17518 (match_operand:SF 3 "register_operand" "")))]
17519 "TARGET_CMOVE"
17520 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17521
17522 (define_insn "*movsfcc_1"
17523 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17524 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17525 [(reg FLAGS_REG) (const_int 0)])
17526 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17527 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17528 "TARGET_CMOVE
17529 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17530 "@
17531 fcmov%F1\t{%2, %0|%0, %2}
17532 fcmov%f1\t{%3, %0|%0, %3}
17533 cmov%O2%C1\t{%2, %0|%0, %2}
17534 cmov%O2%c1\t{%3, %0|%0, %3}"
17535 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17536 (set_attr "mode" "SF,SF,SI,SI")])
17537
17538 (define_expand "movdfcc"
17539 [(set (match_operand:DF 0 "register_operand" "")
17540 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17541 (match_operand:DF 2 "register_operand" "")
17542 (match_operand:DF 3 "register_operand" "")))]
17543 "TARGET_CMOVE"
17544 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17545
17546 (define_insn "*movdfcc_1"
17547 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17548 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17549 [(reg FLAGS_REG) (const_int 0)])
17550 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17551 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17552 "!TARGET_64BIT && TARGET_CMOVE
17553 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17554 "@
17555 fcmov%F1\t{%2, %0|%0, %2}
17556 fcmov%f1\t{%3, %0|%0, %3}
17557 #
17558 #"
17559 [(set_attr "type" "fcmov,fcmov,multi,multi")
17560 (set_attr "mode" "DF")])
17561
17562 (define_insn "*movdfcc_1_rex64"
17563 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17564 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17565 [(reg FLAGS_REG) (const_int 0)])
17566 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17567 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17568 "TARGET_64BIT && TARGET_CMOVE
17569 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17570 "@
17571 fcmov%F1\t{%2, %0|%0, %2}
17572 fcmov%f1\t{%3, %0|%0, %3}
17573 cmov%O2%C1\t{%2, %0|%0, %2}
17574 cmov%O2%c1\t{%3, %0|%0, %3}"
17575 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17576 (set_attr "mode" "DF")])
17577
17578 (define_split
17579 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17580 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17581 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17582 (match_operand:DF 2 "nonimmediate_operand" "")
17583 (match_operand:DF 3 "nonimmediate_operand" "")))]
17584 "!TARGET_64BIT && reload_completed"
17585 [(set (match_dup 2)
17586 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17587 (match_dup 5)
17588 (match_dup 7)))
17589 (set (match_dup 3)
17590 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17591 (match_dup 6)
17592 (match_dup 8)))]
17593 "split_di (operands+2, 1, operands+5, operands+6);
17594 split_di (operands+3, 1, operands+7, operands+8);
17595 split_di (operands, 1, operands+2, operands+3);")
17596
17597 (define_expand "movxfcc"
17598 [(set (match_operand:XF 0 "register_operand" "")
17599 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17600 (match_operand:XF 2 "register_operand" "")
17601 (match_operand:XF 3 "register_operand" "")))]
17602 "TARGET_CMOVE"
17603 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17604
17605 (define_insn "*movxfcc_1"
17606 [(set (match_operand:XF 0 "register_operand" "=f,f")
17607 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17608 [(reg FLAGS_REG) (const_int 0)])
17609 (match_operand:XF 2 "register_operand" "f,0")
17610 (match_operand:XF 3 "register_operand" "0,f")))]
17611 "TARGET_CMOVE"
17612 "@
17613 fcmov%F1\t{%2, %0|%0, %2}
17614 fcmov%f1\t{%3, %0|%0, %3}"
17615 [(set_attr "type" "fcmov")
17616 (set_attr "mode" "XF")])
17617
17618 (define_expand "minsf3"
17619 [(parallel [
17620 (set (match_operand:SF 0 "register_operand" "")
17621 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17622 (match_operand:SF 2 "nonimmediate_operand" ""))
17623 (match_dup 1)
17624 (match_dup 2)))
17625 (clobber (reg:CC FLAGS_REG))])]
17626 "TARGET_SSE"
17627 "")
17628
17629 (define_insn "*minsf"
17630 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17631 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17632 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17633 (match_dup 1)
17634 (match_dup 2)))
17635 (clobber (reg:CC FLAGS_REG))]
17636 "TARGET_SSE && TARGET_IEEE_FP"
17637 "#")
17638
17639 (define_insn "*minsf_nonieee"
17640 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17641 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17642 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17643 (match_dup 1)
17644 (match_dup 2)))
17645 (clobber (reg:CC FLAGS_REG))]
17646 "TARGET_SSE && !TARGET_IEEE_FP
17647 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17648 "#")
17649
17650 (define_split
17651 [(set (match_operand:SF 0 "register_operand" "")
17652 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17653 (match_operand:SF 2 "nonimmediate_operand" ""))
17654 (match_operand:SF 3 "register_operand" "")
17655 (match_operand:SF 4 "nonimmediate_operand" "")))
17656 (clobber (reg:CC FLAGS_REG))]
17657 "SSE_REG_P (operands[0]) && reload_completed
17658 && ((operands_match_p (operands[1], operands[3])
17659 && operands_match_p (operands[2], operands[4]))
17660 || (operands_match_p (operands[1], operands[4])
17661 && operands_match_p (operands[2], operands[3])))"
17662 [(set (match_dup 0)
17663 (if_then_else:SF (lt (match_dup 1)
17664 (match_dup 2))
17665 (match_dup 1)
17666 (match_dup 2)))])
17667
17668 ;; Conditional addition patterns
17669 (define_expand "addqicc"
17670 [(match_operand:QI 0 "register_operand" "")
17671 (match_operand 1 "comparison_operator" "")
17672 (match_operand:QI 2 "register_operand" "")
17673 (match_operand:QI 3 "const_int_operand" "")]
17674 ""
17675 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17676
17677 (define_expand "addhicc"
17678 [(match_operand:HI 0 "register_operand" "")
17679 (match_operand 1 "comparison_operator" "")
17680 (match_operand:HI 2 "register_operand" "")
17681 (match_operand:HI 3 "const_int_operand" "")]
17682 ""
17683 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17684
17685 (define_expand "addsicc"
17686 [(match_operand:SI 0 "register_operand" "")
17687 (match_operand 1 "comparison_operator" "")
17688 (match_operand:SI 2 "register_operand" "")
17689 (match_operand:SI 3 "const_int_operand" "")]
17690 ""
17691 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17692
17693 (define_expand "adddicc"
17694 [(match_operand:DI 0 "register_operand" "")
17695 (match_operand 1 "comparison_operator" "")
17696 (match_operand:DI 2 "register_operand" "")
17697 (match_operand:DI 3 "const_int_operand" "")]
17698 "TARGET_64BIT"
17699 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17700
17701 ;; We can't represent the LT test directly. Do this by swapping the operands.
17702
17703 (define_split
17704 [(set (match_operand:SF 0 "fp_register_operand" "")
17705 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17706 (match_operand:SF 2 "register_operand" ""))
17707 (match_operand:SF 3 "register_operand" "")
17708 (match_operand:SF 4 "register_operand" "")))
17709 (clobber (reg:CC FLAGS_REG))]
17710 "reload_completed
17711 && ((operands_match_p (operands[1], operands[3])
17712 && operands_match_p (operands[2], operands[4]))
17713 || (operands_match_p (operands[1], operands[4])
17714 && operands_match_p (operands[2], operands[3])))"
17715 [(set (reg:CCFP FLAGS_REG)
17716 (compare:CCFP (match_dup 2)
17717 (match_dup 1)))
17718 (set (match_dup 0)
17719 (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17720 (match_dup 1)
17721 (match_dup 2)))])
17722
17723 (define_insn "*minsf_sse"
17724 [(set (match_operand:SF 0 "register_operand" "=x")
17725 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17726 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17727 (match_dup 1)
17728 (match_dup 2)))]
17729 "TARGET_SSE && reload_completed"
17730 "minss\t{%2, %0|%0, %2}"
17731 [(set_attr "type" "sse")
17732 (set_attr "mode" "SF")])
17733
17734 (define_expand "mindf3"
17735 [(parallel [
17736 (set (match_operand:DF 0 "register_operand" "")
17737 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17738 (match_operand:DF 2 "nonimmediate_operand" ""))
17739 (match_dup 1)
17740 (match_dup 2)))
17741 (clobber (reg:CC FLAGS_REG))])]
17742 "TARGET_SSE2 && TARGET_SSE_MATH"
17743 "#")
17744
17745 (define_insn "*mindf"
17746 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17747 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17748 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17749 (match_dup 1)
17750 (match_dup 2)))
17751 (clobber (reg:CC FLAGS_REG))]
17752 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17753 "#")
17754
17755 (define_insn "*mindf_nonieee"
17756 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17757 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17758 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17759 (match_dup 1)
17760 (match_dup 2)))
17761 (clobber (reg:CC FLAGS_REG))]
17762 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17763 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17764 "#")
17765
17766 (define_split
17767 [(set (match_operand:DF 0 "register_operand" "")
17768 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17769 (match_operand:DF 2 "nonimmediate_operand" ""))
17770 (match_operand:DF 3 "register_operand" "")
17771 (match_operand:DF 4 "nonimmediate_operand" "")))
17772 (clobber (reg:CC FLAGS_REG))]
17773 "SSE_REG_P (operands[0]) && reload_completed
17774 && ((operands_match_p (operands[1], operands[3])
17775 && operands_match_p (operands[2], operands[4]))
17776 || (operands_match_p (operands[1], operands[4])
17777 && operands_match_p (operands[2], operands[3])))"
17778 [(set (match_dup 0)
17779 (if_then_else:DF (lt (match_dup 1)
17780 (match_dup 2))
17781 (match_dup 1)
17782 (match_dup 2)))])
17783
17784 ;; We can't represent the LT test directly. Do this by swapping the operands.
17785 (define_split
17786 [(set (match_operand:DF 0 "fp_register_operand" "")
17787 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17788 (match_operand:DF 2 "register_operand" ""))
17789 (match_operand:DF 3 "register_operand" "")
17790 (match_operand:DF 4 "register_operand" "")))
17791 (clobber (reg:CC FLAGS_REG))]
17792 "reload_completed
17793 && ((operands_match_p (operands[1], operands[3])
17794 && operands_match_p (operands[2], operands[4]))
17795 || (operands_match_p (operands[1], operands[4])
17796 && operands_match_p (operands[2], operands[3])))"
17797 [(set (reg:CCFP FLAGS_REG)
17798 (compare:CCFP (match_dup 2)
17799 (match_dup 1)))
17800 (set (match_dup 0)
17801 (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17802 (match_dup 1)
17803 (match_dup 2)))])
17804
17805 (define_insn "*mindf_sse"
17806 [(set (match_operand:DF 0 "register_operand" "=Y")
17807 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17808 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17809 (match_dup 1)
17810 (match_dup 2)))]
17811 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17812 "minsd\t{%2, %0|%0, %2}"
17813 [(set_attr "type" "sse")
17814 (set_attr "mode" "DF")])
17815
17816 (define_expand "maxsf3"
17817 [(parallel [
17818 (set (match_operand:SF 0 "register_operand" "")
17819 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17820 (match_operand:SF 2 "nonimmediate_operand" ""))
17821 (match_dup 1)
17822 (match_dup 2)))
17823 (clobber (reg:CC FLAGS_REG))])]
17824 "TARGET_SSE"
17825 "#")
17826
17827 (define_insn "*maxsf"
17828 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17829 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17830 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17831 (match_dup 1)
17832 (match_dup 2)))
17833 (clobber (reg:CC FLAGS_REG))]
17834 "TARGET_SSE && TARGET_IEEE_FP"
17835 "#")
17836
17837 (define_insn "*maxsf_nonieee"
17838 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17839 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17840 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17841 (match_dup 1)
17842 (match_dup 2)))
17843 (clobber (reg:CC FLAGS_REG))]
17844 "TARGET_SSE && !TARGET_IEEE_FP
17845 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17846 "#")
17847
17848 (define_split
17849 [(set (match_operand:SF 0 "register_operand" "")
17850 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17851 (match_operand:SF 2 "nonimmediate_operand" ""))
17852 (match_operand:SF 3 "register_operand" "")
17853 (match_operand:SF 4 "nonimmediate_operand" "")))
17854 (clobber (reg:CC FLAGS_REG))]
17855 "SSE_REG_P (operands[0]) && reload_completed
17856 && ((operands_match_p (operands[1], operands[3])
17857 && operands_match_p (operands[2], operands[4]))
17858 || (operands_match_p (operands[1], operands[4])
17859 && operands_match_p (operands[2], operands[3])))"
17860 [(set (match_dup 0)
17861 (if_then_else:SF (gt (match_dup 1)
17862 (match_dup 2))
17863 (match_dup 1)
17864 (match_dup 2)))])
17865
17866 (define_split
17867 [(set (match_operand:SF 0 "fp_register_operand" "")
17868 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17869 (match_operand:SF 2 "register_operand" ""))
17870 (match_operand:SF 3 "register_operand" "")
17871 (match_operand:SF 4 "register_operand" "")))
17872 (clobber (reg:CC FLAGS_REG))]
17873 "reload_completed
17874 && ((operands_match_p (operands[1], operands[3])
17875 && operands_match_p (operands[2], operands[4]))
17876 || (operands_match_p (operands[1], operands[4])
17877 && operands_match_p (operands[2], operands[3])))"
17878 [(set (reg:CCFP FLAGS_REG)
17879 (compare:CCFP (match_dup 1)
17880 (match_dup 2)))
17881 (set (match_dup 0)
17882 (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17883 (match_dup 1)
17884 (match_dup 2)))])
17885
17886 (define_insn "*maxsf_sse"
17887 [(set (match_operand:SF 0 "register_operand" "=x")
17888 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17889 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17890 (match_dup 1)
17891 (match_dup 2)))]
17892 "TARGET_SSE && reload_completed"
17893 "maxss\t{%2, %0|%0, %2}"
17894 [(set_attr "type" "sse")
17895 (set_attr "mode" "SF")])
17896
17897 (define_expand "maxdf3"
17898 [(parallel [
17899 (set (match_operand:DF 0 "register_operand" "")
17900 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17901 (match_operand:DF 2 "nonimmediate_operand" ""))
17902 (match_dup 1)
17903 (match_dup 2)))
17904 (clobber (reg:CC FLAGS_REG))])]
17905 "TARGET_SSE2 && TARGET_SSE_MATH"
17906 "#")
17907
17908 (define_insn "*maxdf"
17909 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17910 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17911 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17912 (match_dup 1)
17913 (match_dup 2)))
17914 (clobber (reg:CC FLAGS_REG))]
17915 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17916 "#")
17917
17918 (define_insn "*maxdf_nonieee"
17919 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17920 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17921 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17922 (match_dup 1)
17923 (match_dup 2)))
17924 (clobber (reg:CC FLAGS_REG))]
17925 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17926 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17927 "#")
17928
17929 (define_split
17930 [(set (match_operand:DF 0 "register_operand" "")
17931 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17932 (match_operand:DF 2 "nonimmediate_operand" ""))
17933 (match_operand:DF 3 "register_operand" "")
17934 (match_operand:DF 4 "nonimmediate_operand" "")))
17935 (clobber (reg:CC FLAGS_REG))]
17936 "SSE_REG_P (operands[0]) && reload_completed
17937 && ((operands_match_p (operands[1], operands[3])
17938 && operands_match_p (operands[2], operands[4]))
17939 || (operands_match_p (operands[1], operands[4])
17940 && operands_match_p (operands[2], operands[3])))"
17941 [(set (match_dup 0)
17942 (if_then_else:DF (gt (match_dup 1)
17943 (match_dup 2))
17944 (match_dup 1)
17945 (match_dup 2)))])
17946
17947 (define_split
17948 [(set (match_operand:DF 0 "fp_register_operand" "")
17949 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17950 (match_operand:DF 2 "register_operand" ""))
17951 (match_operand:DF 3 "register_operand" "")
17952 (match_operand:DF 4 "register_operand" "")))
17953 (clobber (reg:CC FLAGS_REG))]
17954 "reload_completed
17955 && ((operands_match_p (operands[1], operands[3])
17956 && operands_match_p (operands[2], operands[4]))
17957 || (operands_match_p (operands[1], operands[4])
17958 && operands_match_p (operands[2], operands[3])))"
17959 [(set (reg:CCFP FLAGS_REG)
17960 (compare:CCFP (match_dup 1)
17961 (match_dup 2)))
17962 (set (match_dup 0)
17963 (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17964 (match_dup 1)
17965 (match_dup 2)))])
17966
17967 (define_insn "*maxdf_sse"
17968 [(set (match_operand:DF 0 "register_operand" "=Y")
17969 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17970 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17971 (match_dup 1)
17972 (match_dup 2)))]
17973 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17974 "maxsd\t{%2, %0|%0, %2}"
17975 [(set_attr "type" "sse")
17976 (set_attr "mode" "DF")])
17977 \f
17978 ;; Misc patterns (?)
17979
17980 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17981 ;; Otherwise there will be nothing to keep
17982 ;;
17983 ;; [(set (reg ebp) (reg esp))]
17984 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17985 ;; (clobber (eflags)]
17986 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17987 ;;
17988 ;; in proper program order.
17989 (define_insn "pro_epilogue_adjust_stack_1"
17990 [(set (match_operand:SI 0 "register_operand" "=r,r")
17991 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17992 (match_operand:SI 2 "immediate_operand" "i,i")))
17993 (clobber (reg:CC FLAGS_REG))
17994 (clobber (mem:BLK (scratch)))]
17995 "!TARGET_64BIT"
17996 {
17997 switch (get_attr_type (insn))
17998 {
17999 case TYPE_IMOV:
18000 return "mov{l}\t{%1, %0|%0, %1}";
18001
18002 case TYPE_ALU:
18003 if (GET_CODE (operands[2]) == CONST_INT
18004 && (INTVAL (operands[2]) == 128
18005 || (INTVAL (operands[2]) < 0
18006 && INTVAL (operands[2]) != -128)))
18007 {
18008 operands[2] = GEN_INT (-INTVAL (operands[2]));
18009 return "sub{l}\t{%2, %0|%0, %2}";
18010 }
18011 return "add{l}\t{%2, %0|%0, %2}";
18012
18013 case TYPE_LEA:
18014 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18015 return "lea{l}\t{%a2, %0|%0, %a2}";
18016
18017 default:
18018 abort ();
18019 }
18020 }
18021 [(set (attr "type")
18022 (cond [(eq_attr "alternative" "0")
18023 (const_string "alu")
18024 (match_operand:SI 2 "const0_operand" "")
18025 (const_string "imov")
18026 ]
18027 (const_string "lea")))
18028 (set_attr "mode" "SI")])
18029
18030 (define_insn "pro_epilogue_adjust_stack_rex64"
18031 [(set (match_operand:DI 0 "register_operand" "=r,r")
18032 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18033 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18034 (clobber (reg:CC FLAGS_REG))
18035 (clobber (mem:BLK (scratch)))]
18036 "TARGET_64BIT"
18037 {
18038 switch (get_attr_type (insn))
18039 {
18040 case TYPE_IMOV:
18041 return "mov{q}\t{%1, %0|%0, %1}";
18042
18043 case TYPE_ALU:
18044 if (GET_CODE (operands[2]) == CONST_INT
18045 /* Avoid overflows. */
18046 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18047 && (INTVAL (operands[2]) == 128
18048 || (INTVAL (operands[2]) < 0
18049 && INTVAL (operands[2]) != -128)))
18050 {
18051 operands[2] = GEN_INT (-INTVAL (operands[2]));
18052 return "sub{q}\t{%2, %0|%0, %2}";
18053 }
18054 return "add{q}\t{%2, %0|%0, %2}";
18055
18056 case TYPE_LEA:
18057 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18058 return "lea{q}\t{%a2, %0|%0, %a2}";
18059
18060 default:
18061 abort ();
18062 }
18063 }
18064 [(set (attr "type")
18065 (cond [(eq_attr "alternative" "0")
18066 (const_string "alu")
18067 (match_operand:DI 2 "const0_operand" "")
18068 (const_string "imov")
18069 ]
18070 (const_string "lea")))
18071 (set_attr "mode" "DI")])
18072
18073 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18074 [(set (match_operand:DI 0 "register_operand" "=r,r")
18075 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18076 (match_operand:DI 3 "immediate_operand" "i,i")))
18077 (use (match_operand:DI 2 "register_operand" "r,r"))
18078 (clobber (reg:CC FLAGS_REG))
18079 (clobber (mem:BLK (scratch)))]
18080 "TARGET_64BIT"
18081 {
18082 switch (get_attr_type (insn))
18083 {
18084 case TYPE_ALU:
18085 return "add{q}\t{%2, %0|%0, %2}";
18086
18087 case TYPE_LEA:
18088 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18089 return "lea{q}\t{%a2, %0|%0, %a2}";
18090
18091 default:
18092 abort ();
18093 }
18094 }
18095 [(set_attr "type" "alu,lea")
18096 (set_attr "mode" "DI")])
18097
18098 ;; Placeholder for the conditional moves. This one is split either to SSE
18099 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
18100 ;; fact is that compares supported by the cmp??ss instructions are exactly
18101 ;; swapped of those supported by cmove sequence.
18102 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18103 ;; supported by i387 comparisons and we do need to emit two conditional moves
18104 ;; in tandem.
18105
18106 (define_insn "sse_movsfcc"
18107 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
18108 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18109 [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
18110 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
18111 (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
18112 (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
18113 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18114 (clobber (reg:CC FLAGS_REG))]
18115 "TARGET_SSE
18116 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18117 /* Avoid combine from being smart and converting min/max
18118 instruction patterns into conditional moves. */
18119 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18120 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18121 || !rtx_equal_p (operands[4], operands[2])
18122 || !rtx_equal_p (operands[5], operands[3]))
18123 && (!TARGET_IEEE_FP
18124 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18125 "#")
18126
18127 (define_insn "sse_movsfcc_eq"
18128 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18129 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18130 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18131 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18132 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18133 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18134 (clobber (reg:CC FLAGS_REG))]
18135 "TARGET_SSE
18136 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18137 "#")
18138
18139 (define_insn "sse_movdfcc"
18140 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
18141 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18142 [(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
18143 (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
18144 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
18145 (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
18146 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18147 (clobber (reg:CC FLAGS_REG))]
18148 "TARGET_SSE2
18149 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18150 /* Avoid combine from being smart and converting min/max
18151 instruction patterns into conditional moves. */
18152 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18153 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18154 || !rtx_equal_p (operands[4], operands[2])
18155 || !rtx_equal_p (operands[5], operands[3]))
18156 && (!TARGET_IEEE_FP
18157 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18158 "#")
18159
18160 (define_insn "sse_movdfcc_eq"
18161 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18162 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18163 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18164 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18165 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18166 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18167 (clobber (reg:CC FLAGS_REG))]
18168 "TARGET_SSE
18169 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18170 "#")
18171
18172 ;; For non-sse moves just expand the usual cmove sequence.
18173 (define_split
18174 [(set (match_operand 0 "register_operand" "")
18175 (if_then_else (match_operator 1 "comparison_operator"
18176 [(match_operand 4 "nonimmediate_operand" "")
18177 (match_operand 5 "register_operand" "")])
18178 (match_operand 2 "nonimmediate_operand" "")
18179 (match_operand 3 "nonimmediate_operand" "")))
18180 (clobber (match_operand 6 "" ""))
18181 (clobber (reg:CC FLAGS_REG))]
18182 "!SSE_REG_P (operands[0]) && reload_completed
18183 && (GET_MODE (operands[0]) == SFmode
18184 || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
18185 [(const_int 0)]
18186 {
18187 ix86_compare_op0 = operands[5];
18188 ix86_compare_op1 = operands[4];
18189 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18190 VOIDmode, operands[5], operands[4]);
18191 ix86_expand_fp_movcc (operands);
18192 DONE;
18193 })
18194
18195 ;; Split SSE based conditional move into sequence:
18196 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
18197 ;; and op2, op0 - zero op2 if comparison was false
18198 ;; nand op0, op3 - load op3 to op0 if comparison was false
18199 ;; or op2, op0 - get the nonzero one into the result.
18200 (define_split
18201 [(set (match_operand:SF 0 "register_operand" "")
18202 (if_then_else:SF (match_operator:SF 1 "sse_comparison_operator"
18203 [(match_operand:SF 4 "register_operand" "")
18204 (match_operand:SF 5 "nonimmediate_operand" "")])
18205 (match_operand:SF 2 "register_operand" "")
18206 (match_operand:SF 3 "register_operand" "")))
18207 (clobber (match_operand 6 "" ""))
18208 (clobber (reg:CC FLAGS_REG))]
18209 "SSE_REG_P (operands[0]) && reload_completed"
18210 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18211 (set (match_dup 2) (and:V4SF (match_dup 2)
18212 (match_dup 8)))
18213 (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18214 (match_dup 3)))
18215 (set (match_dup 0) (ior:V4SF (match_dup 6)
18216 (match_dup 7)))]
18217 {
18218 /* If op2 == op3, op3 would be clobbered before it is used. */
18219 if (operands_match_p (operands[2], operands[3]))
18220 {
18221 emit_move_insn (operands[0], operands[2]);
18222 DONE;
18223 }
18224
18225 PUT_MODE (operands[1], GET_MODE (operands[0]));
18226 if (operands_match_p (operands[0], operands[4]))
18227 operands[6] = operands[4], operands[7] = operands[2];
18228 else
18229 operands[6] = operands[2], operands[7] = operands[4];
18230 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18231 operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18232 operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18233 operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18234 operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18235 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18236 })
18237
18238 (define_split
18239 [(set (match_operand:DF 0 "register_operand" "")
18240 (if_then_else:DF (match_operator:DF 1 "sse_comparison_operator"
18241 [(match_operand:DF 4 "register_operand" "")
18242 (match_operand:DF 5 "nonimmediate_operand" "")])
18243 (match_operand:DF 2 "register_operand" "")
18244 (match_operand:DF 3 "register_operand" "")))
18245 (clobber (match_operand 6 "" ""))
18246 (clobber (reg:CC FLAGS_REG))]
18247 "SSE_REG_P (operands[0]) && reload_completed"
18248 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18249 (set (match_dup 2) (and:V2DF (match_dup 2)
18250 (match_dup 8)))
18251 (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18252 (match_dup 3)))
18253 (set (match_dup 0) (ior:V2DF (match_dup 6)
18254 (match_dup 7)))]
18255 {
18256 if (TARGET_SSE_SPLIT_REGS && !optimize_size)
18257 {
18258 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18259 emit_insn (gen_sse2_unpcklpd (op, op, op));
18260 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18261 emit_insn (gen_sse2_unpcklpd (op, op, op));
18262 }
18263
18264 /* If op2 == op3, op3 would be clobbered before it is used. */
18265 if (operands_match_p (operands[2], operands[3]))
18266 {
18267 emit_move_insn (operands[0], operands[2]);
18268 DONE;
18269 }
18270
18271 PUT_MODE (operands[1], GET_MODE (operands[0]));
18272 if (operands_match_p (operands[0], operands[4]))
18273 operands[6] = operands[4], operands[7] = operands[2];
18274 else
18275 operands[6] = operands[2], operands[7] = operands[4];
18276 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18277 operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18278 operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18279 operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18280 operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18281 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18282 })
18283
18284 ;; Special case of conditional move we can handle effectively.
18285 ;; Do not brother with the integer/floating point case, since these are
18286 ;; bot considerably slower, unlike in the generic case.
18287 (define_insn "*sse_movsfcc_const0_1"
18288 [(set (match_operand:SF 0 "register_operand" "=&x")
18289 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18290 [(match_operand:SF 4 "register_operand" "0")
18291 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18292 (match_operand:SF 2 "register_operand" "x")
18293 (match_operand:SF 3 "const0_operand" "X")))]
18294 "TARGET_SSE"
18295 "#")
18296
18297 (define_insn "*sse_movsfcc_const0_2"
18298 [(set (match_operand:SF 0 "register_operand" "=&x")
18299 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18300 [(match_operand:SF 4 "register_operand" "0")
18301 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18302 (match_operand:SF 2 "const0_operand" "X")
18303 (match_operand:SF 3 "register_operand" "x")))]
18304 "TARGET_SSE"
18305 "#")
18306
18307 (define_insn "*sse_movsfcc_const0_3"
18308 [(set (match_operand:SF 0 "register_operand" "=&x")
18309 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18310 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18311 (match_operand:SF 5 "register_operand" "0")])
18312 (match_operand:SF 2 "register_operand" "x")
18313 (match_operand:SF 3 "const0_operand" "X")))]
18314 "TARGET_SSE"
18315 "#")
18316
18317 (define_insn "*sse_movsfcc_const0_4"
18318 [(set (match_operand:SF 0 "register_operand" "=&x")
18319 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18320 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18321 (match_operand:SF 5 "register_operand" "0")])
18322 (match_operand:SF 2 "const0_operand" "X")
18323 (match_operand:SF 3 "register_operand" "x")))]
18324 "TARGET_SSE"
18325 "#")
18326
18327 (define_insn "*sse_movdfcc_const0_1"
18328 [(set (match_operand:DF 0 "register_operand" "=&Y")
18329 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18330 [(match_operand:DF 4 "register_operand" "0")
18331 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18332 (match_operand:DF 2 "register_operand" "Y")
18333 (match_operand:DF 3 "const0_operand" "X")))]
18334 "TARGET_SSE2"
18335 "#")
18336
18337 (define_insn "*sse_movdfcc_const0_2"
18338 [(set (match_operand:DF 0 "register_operand" "=&Y")
18339 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18340 [(match_operand:DF 4 "register_operand" "0")
18341 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18342 (match_operand:DF 2 "const0_operand" "X")
18343 (match_operand:DF 3 "register_operand" "Y")))]
18344 "TARGET_SSE2"
18345 "#")
18346
18347 (define_insn "*sse_movdfcc_const0_3"
18348 [(set (match_operand:DF 0 "register_operand" "=&Y")
18349 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18350 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18351 (match_operand:DF 5 "register_operand" "0")])
18352 (match_operand:DF 2 "register_operand" "Y")
18353 (match_operand:DF 3 "const0_operand" "X")))]
18354 "TARGET_SSE2"
18355 "#")
18356
18357 (define_insn "*sse_movdfcc_const0_4"
18358 [(set (match_operand:DF 0 "register_operand" "=&Y")
18359 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18360 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18361 (match_operand:DF 5 "register_operand" "0")])
18362 (match_operand:DF 2 "const0_operand" "X")
18363 (match_operand:DF 3 "register_operand" "Y")))]
18364 "TARGET_SSE2"
18365 "#")
18366
18367 (define_split
18368 [(set (match_operand:SF 0 "register_operand" "")
18369 (if_then_else:SF (match_operator 1 "comparison_operator"
18370 [(match_operand:SF 4 "nonimmediate_operand" "")
18371 (match_operand:SF 5 "nonimmediate_operand" "")])
18372 (match_operand:SF 2 "nonmemory_operand" "")
18373 (match_operand:SF 3 "nonmemory_operand" "")))]
18374 "SSE_REG_P (operands[0]) && reload_completed
18375 && (const0_operand (operands[2], GET_MODE (operands[0]))
18376 || const0_operand (operands[3], GET_MODE (operands[0])))"
18377 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18378 (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18379 {
18380 PUT_MODE (operands[1], GET_MODE (operands[0]));
18381 if (!sse_comparison_operator (operands[1], VOIDmode)
18382 || !rtx_equal_p (operands[0], operands[4]))
18383 {
18384 rtx tmp = operands[5];
18385 operands[5] = operands[4];
18386 operands[4] = tmp;
18387 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18388 }
18389 if (!rtx_equal_p (operands[0], operands[4]))
18390 abort ();
18391 operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18392 if (const0_operand (operands[2], GET_MODE (operands[2])))
18393 {
18394 operands[7] = operands[3];
18395 operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18396 }
18397 else
18398 {
18399 operands[7] = operands[2];
18400 operands[6] = operands[8];
18401 }
18402 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18403 })
18404
18405 (define_split
18406 [(set (match_operand:DF 0 "register_operand" "")
18407 (if_then_else:DF (match_operator 1 "comparison_operator"
18408 [(match_operand:DF 4 "nonimmediate_operand" "")
18409 (match_operand:DF 5 "nonimmediate_operand" "")])
18410 (match_operand:DF 2 "nonmemory_operand" "")
18411 (match_operand:DF 3 "nonmemory_operand" "")))]
18412 "SSE_REG_P (operands[0]) && reload_completed
18413 && (const0_operand (operands[2], GET_MODE (operands[0]))
18414 || const0_operand (operands[3], GET_MODE (operands[0])))"
18415 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18416 (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18417 {
18418 if (TARGET_SSE_SPLIT_REGS && !optimize_size)
18419 {
18420 if (REG_P (operands[2]))
18421 {
18422 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18423 emit_insn (gen_sse2_unpcklpd (op, op, op));
18424 }
18425 if (REG_P (operands[3]))
18426 {
18427 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18428 emit_insn (gen_sse2_unpcklpd (op, op, op));
18429 }
18430 }
18431 PUT_MODE (operands[1], GET_MODE (operands[0]));
18432 if (!sse_comparison_operator (operands[1], VOIDmode)
18433 || !rtx_equal_p (operands[0], operands[4]))
18434 {
18435 rtx tmp = operands[5];
18436 operands[5] = operands[4];
18437 operands[4] = tmp;
18438 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18439 }
18440 if (!rtx_equal_p (operands[0], operands[4]))
18441 abort ();
18442 operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18443 if (const0_operand (operands[2], GET_MODE (operands[2])))
18444 {
18445 operands[7] = operands[3];
18446 operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18447 }
18448 else
18449 {
18450 operands[7] = operands[2];
18451 operands[6] = operands[8];
18452 }
18453 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18454 })
18455
18456 (define_expand "allocate_stack_worker"
18457 [(match_operand:SI 0 "register_operand" "")]
18458 "TARGET_STACK_PROBE"
18459 {
18460 if (reload_completed)
18461 {
18462 if (TARGET_64BIT)
18463 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18464 else
18465 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18466 }
18467 else
18468 {
18469 if (TARGET_64BIT)
18470 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18471 else
18472 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18473 }
18474 DONE;
18475 })
18476
18477 (define_insn "allocate_stack_worker_1"
18478 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18479 UNSPECV_STACK_PROBE)
18480 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18481 (clobber (match_scratch:SI 1 "=0"))
18482 (clobber (reg:CC FLAGS_REG))]
18483 "!TARGET_64BIT && TARGET_STACK_PROBE"
18484 "call\t__alloca"
18485 [(set_attr "type" "multi")
18486 (set_attr "length" "5")])
18487
18488 (define_expand "allocate_stack_worker_postreload"
18489 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18490 UNSPECV_STACK_PROBE)
18491 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18492 (clobber (match_dup 0))
18493 (clobber (reg:CC FLAGS_REG))])]
18494 ""
18495 "")
18496
18497 (define_insn "allocate_stack_worker_rex64"
18498 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18499 UNSPECV_STACK_PROBE)
18500 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18501 (clobber (match_scratch:DI 1 "=0"))
18502 (clobber (reg:CC FLAGS_REG))]
18503 "TARGET_64BIT && TARGET_STACK_PROBE"
18504 "call\t__alloca"
18505 [(set_attr "type" "multi")
18506 (set_attr "length" "5")])
18507
18508 (define_expand "allocate_stack_worker_rex64_postreload"
18509 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18510 UNSPECV_STACK_PROBE)
18511 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18512 (clobber (match_dup 0))
18513 (clobber (reg:CC FLAGS_REG))])]
18514 ""
18515 "")
18516
18517 (define_expand "allocate_stack"
18518 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18519 (minus:SI (reg:SI SP_REG)
18520 (match_operand:SI 1 "general_operand" "")))
18521 (clobber (reg:CC FLAGS_REG))])
18522 (parallel [(set (reg:SI SP_REG)
18523 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18524 (clobber (reg:CC FLAGS_REG))])]
18525 "TARGET_STACK_PROBE"
18526 {
18527 #ifdef CHECK_STACK_LIMIT
18528 if (GET_CODE (operands[1]) == CONST_INT
18529 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18530 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18531 operands[1]));
18532 else
18533 #endif
18534 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18535 operands[1])));
18536
18537 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18538 DONE;
18539 })
18540
18541 (define_expand "builtin_setjmp_receiver"
18542 [(label_ref (match_operand 0 "" ""))]
18543 "!TARGET_64BIT && flag_pic"
18544 {
18545 emit_insn (gen_set_got (pic_offset_table_rtx));
18546 DONE;
18547 })
18548 \f
18549 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18550
18551 (define_split
18552 [(set (match_operand 0 "register_operand" "")
18553 (match_operator 3 "promotable_binary_operator"
18554 [(match_operand 1 "register_operand" "")
18555 (match_operand 2 "aligned_operand" "")]))
18556 (clobber (reg:CC FLAGS_REG))]
18557 "! TARGET_PARTIAL_REG_STALL && reload_completed
18558 && ((GET_MODE (operands[0]) == HImode
18559 && ((!optimize_size && !TARGET_FAST_PREFIX)
18560 || GET_CODE (operands[2]) != CONST_INT
18561 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18562 || (GET_MODE (operands[0]) == QImode
18563 && (TARGET_PROMOTE_QImode || optimize_size)))"
18564 [(parallel [(set (match_dup 0)
18565 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18566 (clobber (reg:CC FLAGS_REG))])]
18567 "operands[0] = gen_lowpart (SImode, operands[0]);
18568 operands[1] = gen_lowpart (SImode, operands[1]);
18569 if (GET_CODE (operands[3]) != ASHIFT)
18570 operands[2] = gen_lowpart (SImode, operands[2]);
18571 PUT_MODE (operands[3], SImode);")
18572
18573 ; Promote the QImode tests, as i386 has encoding of the AND
18574 ; instruction with 32-bit sign-extended immediate and thus the
18575 ; instruction size is unchanged, except in the %eax case for
18576 ; which it is increased by one byte, hence the ! optimize_size.
18577 (define_split
18578 [(set (match_operand 0 "flags_reg_operand" "")
18579 (match_operator 2 "compare_operator"
18580 [(and (match_operand 3 "aligned_operand" "")
18581 (match_operand 4 "const_int_operand" ""))
18582 (const_int 0)]))
18583 (set (match_operand 1 "register_operand" "")
18584 (and (match_dup 3) (match_dup 4)))]
18585 "! TARGET_PARTIAL_REG_STALL && reload_completed
18586 /* Ensure that the operand will remain sign-extended immediate. */
18587 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18588 && ! optimize_size
18589 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18590 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18591 [(parallel [(set (match_dup 0)
18592 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18593 (const_int 0)]))
18594 (set (match_dup 1)
18595 (and:SI (match_dup 3) (match_dup 4)))])]
18596 {
18597 operands[4]
18598 = gen_int_mode (INTVAL (operands[4])
18599 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18600 operands[1] = gen_lowpart (SImode, operands[1]);
18601 operands[3] = gen_lowpart (SImode, operands[3]);
18602 })
18603
18604 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18605 ; the TEST instruction with 32-bit sign-extended immediate and thus
18606 ; the instruction size would at least double, which is not what we
18607 ; want even with ! optimize_size.
18608 (define_split
18609 [(set (match_operand 0 "flags_reg_operand" "")
18610 (match_operator 1 "compare_operator"
18611 [(and (match_operand:HI 2 "aligned_operand" "")
18612 (match_operand:HI 3 "const_int_operand" ""))
18613 (const_int 0)]))]
18614 "! TARGET_PARTIAL_REG_STALL && reload_completed
18615 /* Ensure that the operand will remain sign-extended immediate. */
18616 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18617 && ! TARGET_FAST_PREFIX
18618 && ! optimize_size"
18619 [(set (match_dup 0)
18620 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18621 (const_int 0)]))]
18622 {
18623 operands[3]
18624 = gen_int_mode (INTVAL (operands[3])
18625 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18626 operands[2] = gen_lowpart (SImode, operands[2]);
18627 })
18628
18629 (define_split
18630 [(set (match_operand 0 "register_operand" "")
18631 (neg (match_operand 1 "register_operand" "")))
18632 (clobber (reg:CC FLAGS_REG))]
18633 "! TARGET_PARTIAL_REG_STALL && reload_completed
18634 && (GET_MODE (operands[0]) == HImode
18635 || (GET_MODE (operands[0]) == QImode
18636 && (TARGET_PROMOTE_QImode || optimize_size)))"
18637 [(parallel [(set (match_dup 0)
18638 (neg:SI (match_dup 1)))
18639 (clobber (reg:CC FLAGS_REG))])]
18640 "operands[0] = gen_lowpart (SImode, operands[0]);
18641 operands[1] = gen_lowpart (SImode, operands[1]);")
18642
18643 (define_split
18644 [(set (match_operand 0 "register_operand" "")
18645 (not (match_operand 1 "register_operand" "")))]
18646 "! TARGET_PARTIAL_REG_STALL && reload_completed
18647 && (GET_MODE (operands[0]) == HImode
18648 || (GET_MODE (operands[0]) == QImode
18649 && (TARGET_PROMOTE_QImode || optimize_size)))"
18650 [(set (match_dup 0)
18651 (not:SI (match_dup 1)))]
18652 "operands[0] = gen_lowpart (SImode, operands[0]);
18653 operands[1] = gen_lowpart (SImode, operands[1]);")
18654
18655 (define_split
18656 [(set (match_operand 0 "register_operand" "")
18657 (if_then_else (match_operator 1 "comparison_operator"
18658 [(reg FLAGS_REG) (const_int 0)])
18659 (match_operand 2 "register_operand" "")
18660 (match_operand 3 "register_operand" "")))]
18661 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18662 && (GET_MODE (operands[0]) == HImode
18663 || (GET_MODE (operands[0]) == QImode
18664 && (TARGET_PROMOTE_QImode || optimize_size)))"
18665 [(set (match_dup 0)
18666 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18667 "operands[0] = gen_lowpart (SImode, operands[0]);
18668 operands[2] = gen_lowpart (SImode, operands[2]);
18669 operands[3] = gen_lowpart (SImode, operands[3]);")
18670
18671 \f
18672 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18673 ;; transform a complex memory operation into two memory to register operations.
18674
18675 ;; Don't push memory operands
18676 (define_peephole2
18677 [(set (match_operand:SI 0 "push_operand" "")
18678 (match_operand:SI 1 "memory_operand" ""))
18679 (match_scratch:SI 2 "r")]
18680 "! optimize_size && ! TARGET_PUSH_MEMORY"
18681 [(set (match_dup 2) (match_dup 1))
18682 (set (match_dup 0) (match_dup 2))]
18683 "")
18684
18685 (define_peephole2
18686 [(set (match_operand:DI 0 "push_operand" "")
18687 (match_operand:DI 1 "memory_operand" ""))
18688 (match_scratch:DI 2 "r")]
18689 "! optimize_size && ! TARGET_PUSH_MEMORY"
18690 [(set (match_dup 2) (match_dup 1))
18691 (set (match_dup 0) (match_dup 2))]
18692 "")
18693
18694 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18695 ;; SImode pushes.
18696 (define_peephole2
18697 [(set (match_operand:SF 0 "push_operand" "")
18698 (match_operand:SF 1 "memory_operand" ""))
18699 (match_scratch:SF 2 "r")]
18700 "! optimize_size && ! TARGET_PUSH_MEMORY"
18701 [(set (match_dup 2) (match_dup 1))
18702 (set (match_dup 0) (match_dup 2))]
18703 "")
18704
18705 (define_peephole2
18706 [(set (match_operand:HI 0 "push_operand" "")
18707 (match_operand:HI 1 "memory_operand" ""))
18708 (match_scratch:HI 2 "r")]
18709 "! optimize_size && ! TARGET_PUSH_MEMORY"
18710 [(set (match_dup 2) (match_dup 1))
18711 (set (match_dup 0) (match_dup 2))]
18712 "")
18713
18714 (define_peephole2
18715 [(set (match_operand:QI 0 "push_operand" "")
18716 (match_operand:QI 1 "memory_operand" ""))
18717 (match_scratch:QI 2 "q")]
18718 "! optimize_size && ! TARGET_PUSH_MEMORY"
18719 [(set (match_dup 2) (match_dup 1))
18720 (set (match_dup 0) (match_dup 2))]
18721 "")
18722
18723 ;; Don't move an immediate directly to memory when the instruction
18724 ;; gets too big.
18725 (define_peephole2
18726 [(match_scratch:SI 1 "r")
18727 (set (match_operand:SI 0 "memory_operand" "")
18728 (const_int 0))]
18729 "! optimize_size
18730 && ! TARGET_USE_MOV0
18731 && TARGET_SPLIT_LONG_MOVES
18732 && get_attr_length (insn) >= ix86_cost->large_insn
18733 && peep2_regno_dead_p (0, FLAGS_REG)"
18734 [(parallel [(set (match_dup 1) (const_int 0))
18735 (clobber (reg:CC FLAGS_REG))])
18736 (set (match_dup 0) (match_dup 1))]
18737 "")
18738
18739 (define_peephole2
18740 [(match_scratch:HI 1 "r")
18741 (set (match_operand:HI 0 "memory_operand" "")
18742 (const_int 0))]
18743 "! optimize_size
18744 && ! TARGET_USE_MOV0
18745 && TARGET_SPLIT_LONG_MOVES
18746 && get_attr_length (insn) >= ix86_cost->large_insn
18747 && peep2_regno_dead_p (0, FLAGS_REG)"
18748 [(parallel [(set (match_dup 2) (const_int 0))
18749 (clobber (reg:CC FLAGS_REG))])
18750 (set (match_dup 0) (match_dup 1))]
18751 "operands[2] = gen_lowpart (SImode, operands[1]);")
18752
18753 (define_peephole2
18754 [(match_scratch:QI 1 "q")
18755 (set (match_operand:QI 0 "memory_operand" "")
18756 (const_int 0))]
18757 "! optimize_size
18758 && ! TARGET_USE_MOV0
18759 && TARGET_SPLIT_LONG_MOVES
18760 && get_attr_length (insn) >= ix86_cost->large_insn
18761 && peep2_regno_dead_p (0, FLAGS_REG)"
18762 [(parallel [(set (match_dup 2) (const_int 0))
18763 (clobber (reg:CC FLAGS_REG))])
18764 (set (match_dup 0) (match_dup 1))]
18765 "operands[2] = gen_lowpart (SImode, operands[1]);")
18766
18767 (define_peephole2
18768 [(match_scratch:SI 2 "r")
18769 (set (match_operand:SI 0 "memory_operand" "")
18770 (match_operand:SI 1 "immediate_operand" ""))]
18771 "! optimize_size
18772 && get_attr_length (insn) >= ix86_cost->large_insn
18773 && TARGET_SPLIT_LONG_MOVES"
18774 [(set (match_dup 2) (match_dup 1))
18775 (set (match_dup 0) (match_dup 2))]
18776 "")
18777
18778 (define_peephole2
18779 [(match_scratch:HI 2 "r")
18780 (set (match_operand:HI 0 "memory_operand" "")
18781 (match_operand:HI 1 "immediate_operand" ""))]
18782 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18783 && TARGET_SPLIT_LONG_MOVES"
18784 [(set (match_dup 2) (match_dup 1))
18785 (set (match_dup 0) (match_dup 2))]
18786 "")
18787
18788 (define_peephole2
18789 [(match_scratch:QI 2 "q")
18790 (set (match_operand:QI 0 "memory_operand" "")
18791 (match_operand:QI 1 "immediate_operand" ""))]
18792 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18793 && TARGET_SPLIT_LONG_MOVES"
18794 [(set (match_dup 2) (match_dup 1))
18795 (set (match_dup 0) (match_dup 2))]
18796 "")
18797
18798 ;; Don't compare memory with zero, load and use a test instead.
18799 (define_peephole2
18800 [(set (match_operand 0 "flags_reg_operand" "")
18801 (match_operator 1 "compare_operator"
18802 [(match_operand:SI 2 "memory_operand" "")
18803 (const_int 0)]))
18804 (match_scratch:SI 3 "r")]
18805 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18806 [(set (match_dup 3) (match_dup 2))
18807 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18808 "")
18809
18810 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18811 ;; Don't split NOTs with a displacement operand, because resulting XOR
18812 ;; will not be pairable anyway.
18813 ;;
18814 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18815 ;; represented using a modRM byte. The XOR replacement is long decoded,
18816 ;; so this split helps here as well.
18817 ;;
18818 ;; Note: Can't do this as a regular split because we can't get proper
18819 ;; lifetime information then.
18820
18821 (define_peephole2
18822 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18823 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18824 "!optimize_size
18825 && peep2_regno_dead_p (0, FLAGS_REG)
18826 && ((TARGET_PENTIUM
18827 && (GET_CODE (operands[0]) != MEM
18828 || !memory_displacement_operand (operands[0], SImode)))
18829 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18830 [(parallel [(set (match_dup 0)
18831 (xor:SI (match_dup 1) (const_int -1)))
18832 (clobber (reg:CC FLAGS_REG))])]
18833 "")
18834
18835 (define_peephole2
18836 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18837 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18838 "!optimize_size
18839 && peep2_regno_dead_p (0, FLAGS_REG)
18840 && ((TARGET_PENTIUM
18841 && (GET_CODE (operands[0]) != MEM
18842 || !memory_displacement_operand (operands[0], HImode)))
18843 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18844 [(parallel [(set (match_dup 0)
18845 (xor:HI (match_dup 1) (const_int -1)))
18846 (clobber (reg:CC FLAGS_REG))])]
18847 "")
18848
18849 (define_peephole2
18850 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18851 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18852 "!optimize_size
18853 && peep2_regno_dead_p (0, FLAGS_REG)
18854 && ((TARGET_PENTIUM
18855 && (GET_CODE (operands[0]) != MEM
18856 || !memory_displacement_operand (operands[0], QImode)))
18857 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18858 [(parallel [(set (match_dup 0)
18859 (xor:QI (match_dup 1) (const_int -1)))
18860 (clobber (reg:CC FLAGS_REG))])]
18861 "")
18862
18863 ;; Non pairable "test imm, reg" instructions can be translated to
18864 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18865 ;; byte opcode instead of two, have a short form for byte operands),
18866 ;; so do it for other CPUs as well. Given that the value was dead,
18867 ;; this should not create any new dependencies. Pass on the sub-word
18868 ;; versions if we're concerned about partial register stalls.
18869
18870 (define_peephole2
18871 [(set (match_operand 0 "flags_reg_operand" "")
18872 (match_operator 1 "compare_operator"
18873 [(and:SI (match_operand:SI 2 "register_operand" "")
18874 (match_operand:SI 3 "immediate_operand" ""))
18875 (const_int 0)]))]
18876 "ix86_match_ccmode (insn, CCNOmode)
18877 && (true_regnum (operands[2]) != 0
18878 || (GET_CODE (operands[3]) == CONST_INT
18879 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18880 && peep2_reg_dead_p (1, operands[2])"
18881 [(parallel
18882 [(set (match_dup 0)
18883 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18884 (const_int 0)]))
18885 (set (match_dup 2)
18886 (and:SI (match_dup 2) (match_dup 3)))])]
18887 "")
18888
18889 ;; We don't need to handle HImode case, because it will be promoted to SImode
18890 ;; on ! TARGET_PARTIAL_REG_STALL
18891
18892 (define_peephole2
18893 [(set (match_operand 0 "flags_reg_operand" "")
18894 (match_operator 1 "compare_operator"
18895 [(and:QI (match_operand:QI 2 "register_operand" "")
18896 (match_operand:QI 3 "immediate_operand" ""))
18897 (const_int 0)]))]
18898 "! TARGET_PARTIAL_REG_STALL
18899 && ix86_match_ccmode (insn, CCNOmode)
18900 && true_regnum (operands[2]) != 0
18901 && peep2_reg_dead_p (1, operands[2])"
18902 [(parallel
18903 [(set (match_dup 0)
18904 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18905 (const_int 0)]))
18906 (set (match_dup 2)
18907 (and:QI (match_dup 2) (match_dup 3)))])]
18908 "")
18909
18910 (define_peephole2
18911 [(set (match_operand 0 "flags_reg_operand" "")
18912 (match_operator 1 "compare_operator"
18913 [(and:SI
18914 (zero_extract:SI
18915 (match_operand 2 "ext_register_operand" "")
18916 (const_int 8)
18917 (const_int 8))
18918 (match_operand 3 "const_int_operand" ""))
18919 (const_int 0)]))]
18920 "! TARGET_PARTIAL_REG_STALL
18921 && ix86_match_ccmode (insn, CCNOmode)
18922 && true_regnum (operands[2]) != 0
18923 && peep2_reg_dead_p (1, operands[2])"
18924 [(parallel [(set (match_dup 0)
18925 (match_op_dup 1
18926 [(and:SI
18927 (zero_extract:SI
18928 (match_dup 2)
18929 (const_int 8)
18930 (const_int 8))
18931 (match_dup 3))
18932 (const_int 0)]))
18933 (set (zero_extract:SI (match_dup 2)
18934 (const_int 8)
18935 (const_int 8))
18936 (and:SI
18937 (zero_extract:SI
18938 (match_dup 2)
18939 (const_int 8)
18940 (const_int 8))
18941 (match_dup 3)))])]
18942 "")
18943
18944 ;; Don't do logical operations with memory inputs.
18945 (define_peephole2
18946 [(match_scratch:SI 2 "r")
18947 (parallel [(set (match_operand:SI 0 "register_operand" "")
18948 (match_operator:SI 3 "arith_or_logical_operator"
18949 [(match_dup 0)
18950 (match_operand:SI 1 "memory_operand" "")]))
18951 (clobber (reg:CC FLAGS_REG))])]
18952 "! optimize_size && ! TARGET_READ_MODIFY"
18953 [(set (match_dup 2) (match_dup 1))
18954 (parallel [(set (match_dup 0)
18955 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18956 (clobber (reg:CC FLAGS_REG))])]
18957 "")
18958
18959 (define_peephole2
18960 [(match_scratch:SI 2 "r")
18961 (parallel [(set (match_operand:SI 0 "register_operand" "")
18962 (match_operator:SI 3 "arith_or_logical_operator"
18963 [(match_operand:SI 1 "memory_operand" "")
18964 (match_dup 0)]))
18965 (clobber (reg:CC FLAGS_REG))])]
18966 "! optimize_size && ! TARGET_READ_MODIFY"
18967 [(set (match_dup 2) (match_dup 1))
18968 (parallel [(set (match_dup 0)
18969 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18970 (clobber (reg:CC FLAGS_REG))])]
18971 "")
18972
18973 ; Don't do logical operations with memory outputs
18974 ;
18975 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18976 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18977 ; the same decoder scheduling characteristics as the original.
18978
18979 (define_peephole2
18980 [(match_scratch:SI 2 "r")
18981 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18982 (match_operator:SI 3 "arith_or_logical_operator"
18983 [(match_dup 0)
18984 (match_operand:SI 1 "nonmemory_operand" "")]))
18985 (clobber (reg:CC FLAGS_REG))])]
18986 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18987 [(set (match_dup 2) (match_dup 0))
18988 (parallel [(set (match_dup 2)
18989 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18990 (clobber (reg:CC FLAGS_REG))])
18991 (set (match_dup 0) (match_dup 2))]
18992 "")
18993
18994 (define_peephole2
18995 [(match_scratch:SI 2 "r")
18996 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18997 (match_operator:SI 3 "arith_or_logical_operator"
18998 [(match_operand:SI 1 "nonmemory_operand" "")
18999 (match_dup 0)]))
19000 (clobber (reg:CC FLAGS_REG))])]
19001 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19002 [(set (match_dup 2) (match_dup 0))
19003 (parallel [(set (match_dup 2)
19004 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19005 (clobber (reg:CC FLAGS_REG))])
19006 (set (match_dup 0) (match_dup 2))]
19007 "")
19008
19009 ;; Attempt to always use XOR for zeroing registers.
19010 (define_peephole2
19011 [(set (match_operand 0 "register_operand" "")
19012 (const_int 0))]
19013 "(GET_MODE (operands[0]) == QImode
19014 || GET_MODE (operands[0]) == HImode
19015 || GET_MODE (operands[0]) == SImode
19016 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19017 && (! TARGET_USE_MOV0 || optimize_size)
19018 && peep2_regno_dead_p (0, FLAGS_REG)"
19019 [(parallel [(set (match_dup 0) (const_int 0))
19020 (clobber (reg:CC FLAGS_REG))])]
19021 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19022 operands[0]);")
19023
19024 (define_peephole2
19025 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19026 (const_int 0))]
19027 "(GET_MODE (operands[0]) == QImode
19028 || GET_MODE (operands[0]) == HImode)
19029 && (! TARGET_USE_MOV0 || optimize_size)
19030 && peep2_regno_dead_p (0, FLAGS_REG)"
19031 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19032 (clobber (reg:CC FLAGS_REG))])])
19033
19034 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19035 (define_peephole2
19036 [(set (match_operand 0 "register_operand" "")
19037 (const_int -1))]
19038 "(GET_MODE (operands[0]) == HImode
19039 || GET_MODE (operands[0]) == SImode
19040 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19041 && (optimize_size || TARGET_PENTIUM)
19042 && peep2_regno_dead_p (0, FLAGS_REG)"
19043 [(parallel [(set (match_dup 0) (const_int -1))
19044 (clobber (reg:CC FLAGS_REG))])]
19045 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19046 operands[0]);")
19047
19048 ;; Attempt to convert simple leas to adds. These can be created by
19049 ;; move expanders.
19050 (define_peephole2
19051 [(set (match_operand:SI 0 "register_operand" "")
19052 (plus:SI (match_dup 0)
19053 (match_operand:SI 1 "nonmemory_operand" "")))]
19054 "peep2_regno_dead_p (0, FLAGS_REG)"
19055 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19056 (clobber (reg:CC FLAGS_REG))])]
19057 "")
19058
19059 (define_peephole2
19060 [(set (match_operand:SI 0 "register_operand" "")
19061 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19062 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19063 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19064 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19065 (clobber (reg:CC FLAGS_REG))])]
19066 "operands[2] = gen_lowpart (SImode, operands[2]);")
19067
19068 (define_peephole2
19069 [(set (match_operand:DI 0 "register_operand" "")
19070 (plus:DI (match_dup 0)
19071 (match_operand:DI 1 "x86_64_general_operand" "")))]
19072 "peep2_regno_dead_p (0, FLAGS_REG)"
19073 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19074 (clobber (reg:CC FLAGS_REG))])]
19075 "")
19076
19077 (define_peephole2
19078 [(set (match_operand:SI 0 "register_operand" "")
19079 (mult:SI (match_dup 0)
19080 (match_operand:SI 1 "const_int_operand" "")))]
19081 "exact_log2 (INTVAL (operands[1])) >= 0
19082 && peep2_regno_dead_p (0, FLAGS_REG)"
19083 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19084 (clobber (reg:CC FLAGS_REG))])]
19085 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19086
19087 (define_peephole2
19088 [(set (match_operand:DI 0 "register_operand" "")
19089 (mult:DI (match_dup 0)
19090 (match_operand:DI 1 "const_int_operand" "")))]
19091 "exact_log2 (INTVAL (operands[1])) >= 0
19092 && peep2_regno_dead_p (0, FLAGS_REG)"
19093 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19094 (clobber (reg:CC FLAGS_REG))])]
19095 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19096
19097 (define_peephole2
19098 [(set (match_operand:SI 0 "register_operand" "")
19099 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19100 (match_operand:DI 2 "const_int_operand" "")) 0))]
19101 "exact_log2 (INTVAL (operands[2])) >= 0
19102 && REGNO (operands[0]) == REGNO (operands[1])
19103 && peep2_regno_dead_p (0, FLAGS_REG)"
19104 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19105 (clobber (reg:CC FLAGS_REG))])]
19106 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19107
19108 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19109 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19110 ;; many CPUs it is also faster, since special hardware to avoid esp
19111 ;; dependencies is present.
19112
19113 ;; While some of these conversions may be done using splitters, we use peepholes
19114 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19115
19116 ;; Convert prologue esp subtractions to push.
19117 ;; We need register to push. In order to keep verify_flow_info happy we have
19118 ;; two choices
19119 ;; - use scratch and clobber it in order to avoid dependencies
19120 ;; - use already live register
19121 ;; We can't use the second way right now, since there is no reliable way how to
19122 ;; verify that given register is live. First choice will also most likely in
19123 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19124 ;; call clobbered registers are dead. We may want to use base pointer as an
19125 ;; alternative when no register is available later.
19126
19127 (define_peephole2
19128 [(match_scratch:SI 0 "r")
19129 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19130 (clobber (reg:CC FLAGS_REG))
19131 (clobber (mem:BLK (scratch)))])]
19132 "optimize_size || !TARGET_SUB_ESP_4"
19133 [(clobber (match_dup 0))
19134 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19135 (clobber (mem:BLK (scratch)))])])
19136
19137 (define_peephole2
19138 [(match_scratch:SI 0 "r")
19139 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19140 (clobber (reg:CC FLAGS_REG))
19141 (clobber (mem:BLK (scratch)))])]
19142 "optimize_size || !TARGET_SUB_ESP_8"
19143 [(clobber (match_dup 0))
19144 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19145 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19146 (clobber (mem:BLK (scratch)))])])
19147
19148 ;; Convert esp subtractions to push.
19149 (define_peephole2
19150 [(match_scratch:SI 0 "r")
19151 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19152 (clobber (reg:CC FLAGS_REG))])]
19153 "optimize_size || !TARGET_SUB_ESP_4"
19154 [(clobber (match_dup 0))
19155 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19156
19157 (define_peephole2
19158 [(match_scratch:SI 0 "r")
19159 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19160 (clobber (reg:CC FLAGS_REG))])]
19161 "optimize_size || !TARGET_SUB_ESP_8"
19162 [(clobber (match_dup 0))
19163 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19164 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19165
19166 ;; Convert epilogue deallocator to pop.
19167 (define_peephole2
19168 [(match_scratch:SI 0 "r")
19169 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19170 (clobber (reg:CC FLAGS_REG))
19171 (clobber (mem:BLK (scratch)))])]
19172 "optimize_size || !TARGET_ADD_ESP_4"
19173 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19174 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19175 (clobber (mem:BLK (scratch)))])]
19176 "")
19177
19178 ;; Two pops case is tricky, since pop causes dependency on destination register.
19179 ;; We use two registers if available.
19180 (define_peephole2
19181 [(match_scratch:SI 0 "r")
19182 (match_scratch:SI 1 "r")
19183 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19184 (clobber (reg:CC FLAGS_REG))
19185 (clobber (mem:BLK (scratch)))])]
19186 "optimize_size || !TARGET_ADD_ESP_8"
19187 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19188 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19189 (clobber (mem:BLK (scratch)))])
19190 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19191 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19192 "")
19193
19194 (define_peephole2
19195 [(match_scratch:SI 0 "r")
19196 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19197 (clobber (reg:CC FLAGS_REG))
19198 (clobber (mem:BLK (scratch)))])]
19199 "optimize_size"
19200 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19201 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19202 (clobber (mem:BLK (scratch)))])
19203 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19204 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19205 "")
19206
19207 ;; Convert esp additions to pop.
19208 (define_peephole2
19209 [(match_scratch:SI 0 "r")
19210 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19211 (clobber (reg:CC FLAGS_REG))])]
19212 ""
19213 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19214 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19215 "")
19216
19217 ;; Two pops case is tricky, since pop causes dependency on destination register.
19218 ;; We use two registers if available.
19219 (define_peephole2
19220 [(match_scratch:SI 0 "r")
19221 (match_scratch:SI 1 "r")
19222 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19223 (clobber (reg:CC FLAGS_REG))])]
19224 ""
19225 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19226 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19227 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19228 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19229 "")
19230
19231 (define_peephole2
19232 [(match_scratch:SI 0 "r")
19233 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19234 (clobber (reg:CC FLAGS_REG))])]
19235 "optimize_size"
19236 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19237 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19238 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19239 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19240 "")
19241 \f
19242 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19243 ;; required and register dies. Similarly for 128 to plus -128.
19244 (define_peephole2
19245 [(set (match_operand 0 "flags_reg_operand" "")
19246 (match_operator 1 "compare_operator"
19247 [(match_operand 2 "register_operand" "")
19248 (match_operand 3 "const_int_operand" "")]))]
19249 "(INTVAL (operands[3]) == -1
19250 || INTVAL (operands[3]) == 1
19251 || INTVAL (operands[3]) == 128)
19252 && ix86_match_ccmode (insn, CCGCmode)
19253 && peep2_reg_dead_p (1, operands[2])"
19254 [(parallel [(set (match_dup 0)
19255 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19256 (clobber (match_dup 2))])]
19257 "")
19258 \f
19259 (define_peephole2
19260 [(match_scratch:DI 0 "r")
19261 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19262 (clobber (reg:CC FLAGS_REG))
19263 (clobber (mem:BLK (scratch)))])]
19264 "optimize_size || !TARGET_SUB_ESP_4"
19265 [(clobber (match_dup 0))
19266 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19267 (clobber (mem:BLK (scratch)))])])
19268
19269 (define_peephole2
19270 [(match_scratch:DI 0 "r")
19271 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19272 (clobber (reg:CC FLAGS_REG))
19273 (clobber (mem:BLK (scratch)))])]
19274 "optimize_size || !TARGET_SUB_ESP_8"
19275 [(clobber (match_dup 0))
19276 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19277 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19278 (clobber (mem:BLK (scratch)))])])
19279
19280 ;; Convert esp subtractions to push.
19281 (define_peephole2
19282 [(match_scratch:DI 0 "r")
19283 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19284 (clobber (reg:CC FLAGS_REG))])]
19285 "optimize_size || !TARGET_SUB_ESP_4"
19286 [(clobber (match_dup 0))
19287 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19288
19289 (define_peephole2
19290 [(match_scratch:DI 0 "r")
19291 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19292 (clobber (reg:CC FLAGS_REG))])]
19293 "optimize_size || !TARGET_SUB_ESP_8"
19294 [(clobber (match_dup 0))
19295 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19296 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19297
19298 ;; Convert epilogue deallocator to pop.
19299 (define_peephole2
19300 [(match_scratch:DI 0 "r")
19301 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19302 (clobber (reg:CC FLAGS_REG))
19303 (clobber (mem:BLK (scratch)))])]
19304 "optimize_size || !TARGET_ADD_ESP_4"
19305 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19306 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19307 (clobber (mem:BLK (scratch)))])]
19308 "")
19309
19310 ;; Two pops case is tricky, since pop causes dependency on destination register.
19311 ;; We use two registers if available.
19312 (define_peephole2
19313 [(match_scratch:DI 0 "r")
19314 (match_scratch:DI 1 "r")
19315 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19316 (clobber (reg:CC FLAGS_REG))
19317 (clobber (mem:BLK (scratch)))])]
19318 "optimize_size || !TARGET_ADD_ESP_8"
19319 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19320 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19321 (clobber (mem:BLK (scratch)))])
19322 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19323 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19324 "")
19325
19326 (define_peephole2
19327 [(match_scratch:DI 0 "r")
19328 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19329 (clobber (reg:CC FLAGS_REG))
19330 (clobber (mem:BLK (scratch)))])]
19331 "optimize_size"
19332 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19333 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19334 (clobber (mem:BLK (scratch)))])
19335 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19336 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19337 "")
19338
19339 ;; Convert esp additions to pop.
19340 (define_peephole2
19341 [(match_scratch:DI 0 "r")
19342 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19343 (clobber (reg:CC FLAGS_REG))])]
19344 ""
19345 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19346 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19347 "")
19348
19349 ;; Two pops case is tricky, since pop causes dependency on destination register.
19350 ;; We use two registers if available.
19351 (define_peephole2
19352 [(match_scratch:DI 0 "r")
19353 (match_scratch:DI 1 "r")
19354 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19355 (clobber (reg:CC FLAGS_REG))])]
19356 ""
19357 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19358 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19359 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19360 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19361 "")
19362
19363 (define_peephole2
19364 [(match_scratch:DI 0 "r")
19365 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19366 (clobber (reg:CC FLAGS_REG))])]
19367 "optimize_size"
19368 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19369 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19370 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19371 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19372 "")
19373 \f
19374 ;; Convert imul by three, five and nine into lea
19375 (define_peephole2
19376 [(parallel
19377 [(set (match_operand:SI 0 "register_operand" "")
19378 (mult:SI (match_operand:SI 1 "register_operand" "")
19379 (match_operand:SI 2 "const_int_operand" "")))
19380 (clobber (reg:CC FLAGS_REG))])]
19381 "INTVAL (operands[2]) == 3
19382 || INTVAL (operands[2]) == 5
19383 || INTVAL (operands[2]) == 9"
19384 [(set (match_dup 0)
19385 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19386 (match_dup 1)))]
19387 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19388
19389 (define_peephole2
19390 [(parallel
19391 [(set (match_operand:SI 0 "register_operand" "")
19392 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19393 (match_operand:SI 2 "const_int_operand" "")))
19394 (clobber (reg:CC FLAGS_REG))])]
19395 "!optimize_size
19396 && (INTVAL (operands[2]) == 3
19397 || INTVAL (operands[2]) == 5
19398 || INTVAL (operands[2]) == 9)"
19399 [(set (match_dup 0) (match_dup 1))
19400 (set (match_dup 0)
19401 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19402 (match_dup 0)))]
19403 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19404
19405 (define_peephole2
19406 [(parallel
19407 [(set (match_operand:DI 0 "register_operand" "")
19408 (mult:DI (match_operand:DI 1 "register_operand" "")
19409 (match_operand:DI 2 "const_int_operand" "")))
19410 (clobber (reg:CC FLAGS_REG))])]
19411 "TARGET_64BIT
19412 && (INTVAL (operands[2]) == 3
19413 || INTVAL (operands[2]) == 5
19414 || INTVAL (operands[2]) == 9)"
19415 [(set (match_dup 0)
19416 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19417 (match_dup 1)))]
19418 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19419
19420 (define_peephole2
19421 [(parallel
19422 [(set (match_operand:DI 0 "register_operand" "")
19423 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19424 (match_operand:DI 2 "const_int_operand" "")))
19425 (clobber (reg:CC FLAGS_REG))])]
19426 "TARGET_64BIT
19427 && !optimize_size
19428 && (INTVAL (operands[2]) == 3
19429 || INTVAL (operands[2]) == 5
19430 || INTVAL (operands[2]) == 9)"
19431 [(set (match_dup 0) (match_dup 1))
19432 (set (match_dup 0)
19433 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19434 (match_dup 0)))]
19435 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19436
19437 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19438 ;; imul $32bit_imm, reg, reg is direct decoded.
19439 (define_peephole2
19440 [(match_scratch:DI 3 "r")
19441 (parallel [(set (match_operand:DI 0 "register_operand" "")
19442 (mult:DI (match_operand:DI 1 "memory_operand" "")
19443 (match_operand:DI 2 "immediate_operand" "")))
19444 (clobber (reg:CC FLAGS_REG))])]
19445 "TARGET_K8 && !optimize_size
19446 && (GET_CODE (operands[2]) != CONST_INT
19447 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19448 [(set (match_dup 3) (match_dup 1))
19449 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19450 (clobber (reg:CC FLAGS_REG))])]
19451 "")
19452
19453 (define_peephole2
19454 [(match_scratch:SI 3 "r")
19455 (parallel [(set (match_operand:SI 0 "register_operand" "")
19456 (mult:SI (match_operand:SI 1 "memory_operand" "")
19457 (match_operand:SI 2 "immediate_operand" "")))
19458 (clobber (reg:CC FLAGS_REG))])]
19459 "TARGET_K8 && !optimize_size
19460 && (GET_CODE (operands[2]) != CONST_INT
19461 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19462 [(set (match_dup 3) (match_dup 1))
19463 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19464 (clobber (reg:CC FLAGS_REG))])]
19465 "")
19466
19467 (define_peephole2
19468 [(match_scratch:SI 3 "r")
19469 (parallel [(set (match_operand:DI 0 "register_operand" "")
19470 (zero_extend:DI
19471 (mult:SI (match_operand:SI 1 "memory_operand" "")
19472 (match_operand:SI 2 "immediate_operand" ""))))
19473 (clobber (reg:CC FLAGS_REG))])]
19474 "TARGET_K8 && !optimize_size
19475 && (GET_CODE (operands[2]) != CONST_INT
19476 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19477 [(set (match_dup 3) (match_dup 1))
19478 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19479 (clobber (reg:CC FLAGS_REG))])]
19480 "")
19481
19482 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19483 ;; Convert it into imul reg, reg
19484 ;; It would be better to force assembler to encode instruction using long
19485 ;; immediate, but there is apparently no way to do so.
19486 (define_peephole2
19487 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19488 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19489 (match_operand:DI 2 "const_int_operand" "")))
19490 (clobber (reg:CC FLAGS_REG))])
19491 (match_scratch:DI 3 "r")]
19492 "TARGET_K8 && !optimize_size
19493 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19494 [(set (match_dup 3) (match_dup 2))
19495 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19496 (clobber (reg:CC FLAGS_REG))])]
19497 {
19498 if (!rtx_equal_p (operands[0], operands[1]))
19499 emit_move_insn (operands[0], operands[1]);
19500 })
19501
19502 (define_peephole2
19503 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19504 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19505 (match_operand:SI 2 "const_int_operand" "")))
19506 (clobber (reg:CC FLAGS_REG))])
19507 (match_scratch:SI 3 "r")]
19508 "TARGET_K8 && !optimize_size
19509 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19510 [(set (match_dup 3) (match_dup 2))
19511 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19512 (clobber (reg:CC FLAGS_REG))])]
19513 {
19514 if (!rtx_equal_p (operands[0], operands[1]))
19515 emit_move_insn (operands[0], operands[1]);
19516 })
19517
19518 (define_peephole2
19519 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19520 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19521 (match_operand:HI 2 "immediate_operand" "")))
19522 (clobber (reg:CC FLAGS_REG))])
19523 (match_scratch:HI 3 "r")]
19524 "TARGET_K8 && !optimize_size"
19525 [(set (match_dup 3) (match_dup 2))
19526 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19527 (clobber (reg:CC FLAGS_REG))])]
19528 {
19529 if (!rtx_equal_p (operands[0], operands[1]))
19530 emit_move_insn (operands[0], operands[1]);
19531 })
19532 \f
19533 ;; Call-value patterns last so that the wildcard operand does not
19534 ;; disrupt insn-recog's switch tables.
19535
19536 (define_insn "*call_value_pop_0"
19537 [(set (match_operand 0 "" "")
19538 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19539 (match_operand:SI 2 "" "")))
19540 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19541 (match_operand:SI 3 "immediate_operand" "")))]
19542 "!TARGET_64BIT"
19543 {
19544 if (SIBLING_CALL_P (insn))
19545 return "jmp\t%P1";
19546 else
19547 return "call\t%P1";
19548 }
19549 [(set_attr "type" "callv")])
19550
19551 (define_insn "*call_value_pop_1"
19552 [(set (match_operand 0 "" "")
19553 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19554 (match_operand:SI 2 "" "")))
19555 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19556 (match_operand:SI 3 "immediate_operand" "i")))]
19557 "!TARGET_64BIT"
19558 {
19559 if (constant_call_address_operand (operands[1], Pmode))
19560 {
19561 if (SIBLING_CALL_P (insn))
19562 return "jmp\t%P1";
19563 else
19564 return "call\t%P1";
19565 }
19566 if (SIBLING_CALL_P (insn))
19567 return "jmp\t%A1";
19568 else
19569 return "call\t%A1";
19570 }
19571 [(set_attr "type" "callv")])
19572
19573 (define_insn "*call_value_0"
19574 [(set (match_operand 0 "" "")
19575 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19576 (match_operand:SI 2 "" "")))]
19577 "!TARGET_64BIT"
19578 {
19579 if (SIBLING_CALL_P (insn))
19580 return "jmp\t%P1";
19581 else
19582 return "call\t%P1";
19583 }
19584 [(set_attr "type" "callv")])
19585
19586 (define_insn "*call_value_0_rex64"
19587 [(set (match_operand 0 "" "")
19588 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19589 (match_operand:DI 2 "const_int_operand" "")))]
19590 "TARGET_64BIT"
19591 {
19592 if (SIBLING_CALL_P (insn))
19593 return "jmp\t%P1";
19594 else
19595 return "call\t%P1";
19596 }
19597 [(set_attr "type" "callv")])
19598
19599 (define_insn "*call_value_1"
19600 [(set (match_operand 0 "" "")
19601 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19602 (match_operand:SI 2 "" "")))]
19603 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19604 {
19605 if (constant_call_address_operand (operands[1], Pmode))
19606 return "call\t%P1";
19607 return "call\t%A1";
19608 }
19609 [(set_attr "type" "callv")])
19610
19611 (define_insn "*sibcall_value_1"
19612 [(set (match_operand 0 "" "")
19613 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19614 (match_operand:SI 2 "" "")))]
19615 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19616 {
19617 if (constant_call_address_operand (operands[1], Pmode))
19618 return "jmp\t%P1";
19619 return "jmp\t%A1";
19620 }
19621 [(set_attr "type" "callv")])
19622
19623 (define_insn "*call_value_1_rex64"
19624 [(set (match_operand 0 "" "")
19625 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19626 (match_operand:DI 2 "" "")))]
19627 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19628 {
19629 if (constant_call_address_operand (operands[1], Pmode))
19630 return "call\t%P1";
19631 return "call\t%A1";
19632 }
19633 [(set_attr "type" "callv")])
19634
19635 (define_insn "*sibcall_value_1_rex64"
19636 [(set (match_operand 0 "" "")
19637 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19638 (match_operand:DI 2 "" "")))]
19639 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19640 "jmp\t%P1"
19641 [(set_attr "type" "callv")])
19642
19643 (define_insn "*sibcall_value_1_rex64_v"
19644 [(set (match_operand 0 "" "")
19645 (call (mem:QI (reg:DI 40))
19646 (match_operand:DI 1 "" "")))]
19647 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19648 "jmp\t*%%r11"
19649 [(set_attr "type" "callv")])
19650 \f
19651 (define_insn "trap"
19652 [(trap_if (const_int 1) (const_int 5))]
19653 ""
19654 "int\t$5")
19655
19656 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19657 ;;; for the sake of bounds checking. By emitting bounds checks as
19658 ;;; conditional traps rather than as conditional jumps around
19659 ;;; unconditional traps we avoid introducing spurious basic-block
19660 ;;; boundaries and facilitate elimination of redundant checks. In
19661 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19662 ;;; interrupt 5.
19663 ;;;
19664 ;;; FIXME: Static branch prediction rules for ix86 are such that
19665 ;;; forward conditional branches predict as untaken. As implemented
19666 ;;; below, pseudo conditional traps violate that rule. We should use
19667 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19668 ;;; section loaded at the end of the text segment and branch forward
19669 ;;; there on bounds-failure, and then jump back immediately (in case
19670 ;;; the system chooses to ignore bounds violations, or to report
19671 ;;; violations and continue execution).
19672
19673 (define_expand "conditional_trap"
19674 [(trap_if (match_operator 0 "comparison_operator"
19675 [(match_dup 2) (const_int 0)])
19676 (match_operand 1 "const_int_operand" ""))]
19677 ""
19678 {
19679 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19680 ix86_expand_compare (GET_CODE (operands[0]),
19681 NULL, NULL),
19682 operands[1]));
19683 DONE;
19684 })
19685
19686 (define_insn "*conditional_trap_1"
19687 [(trap_if (match_operator 0 "comparison_operator"
19688 [(reg FLAGS_REG) (const_int 0)])
19689 (match_operand 1 "const_int_operand" ""))]
19690 ""
19691 {
19692 operands[2] = gen_label_rtx ();
19693 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19694 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19695 CODE_LABEL_NUMBER (operands[2]));
19696 RET;
19697 })
19698
19699 ;; Pentium III SIMD instructions.
19700
19701 ;; Moves for SSE/MMX regs.
19702
19703 (define_expand "movv4sf"
19704 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19705 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19706 "TARGET_SSE"
19707 {
19708 ix86_expand_vector_move (V4SFmode, operands);
19709 DONE;
19710 })
19711
19712 (define_insn "*movv4sf_internal"
19713 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19714 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19715 "TARGET_SSE"
19716 "@
19717 xorps\t%0, %0
19718 movaps\t{%1, %0|%0, %1}
19719 movaps\t{%1, %0|%0, %1}"
19720 [(set_attr "type" "ssemov")
19721 (set_attr "mode" "V4SF")])
19722
19723 (define_split
19724 [(set (match_operand:V4SF 0 "register_operand" "")
19725 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19726 "TARGET_SSE && reload_completed"
19727 [(set (match_dup 0)
19728 (vec_merge:V4SF
19729 (vec_duplicate:V4SF (match_dup 1))
19730 (match_dup 2)
19731 (const_int 1)))]
19732 {
19733 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19734 operands[2] = CONST0_RTX (V4SFmode);
19735 })
19736
19737 (define_expand "movv2df"
19738 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19739 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19740 "TARGET_SSE"
19741 {
19742 ix86_expand_vector_move (V2DFmode, operands);
19743 DONE;
19744 })
19745
19746 (define_insn "*movv2df_internal"
19747 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19748 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19749 "TARGET_SSE
19750 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19751 {
19752 switch (which_alternative)
19753 {
19754 case 0:
19755 if (get_attr_mode (insn) == MODE_V4SF)
19756 return "xorps\t%0, %0";
19757 else
19758 return "xorpd\t%0, %0";
19759 case 1:
19760 case 2:
19761 if (get_attr_mode (insn) == MODE_V4SF)
19762 return "movaps\t{%1, %0|%0, %1}";
19763 else
19764 return "movapd\t{%1, %0|%0, %1}";
19765 default:
19766 abort ();
19767 }
19768 }
19769 [(set_attr "type" "ssemov")
19770 (set (attr "mode")
19771 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
19772 (const_string "V4SF")
19773 (eq_attr "alternative" "0,1")
19774 (if_then_else
19775 (ne (symbol_ref "optimize_size")
19776 (const_int 0))
19777 (const_string "V4SF")
19778 (const_string "V2DF"))
19779 (eq_attr "alternative" "2")
19780 (if_then_else
19781 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19782 (const_int 0))
19783 (ne (symbol_ref "optimize_size")
19784 (const_int 0)))
19785 (const_string "V4SF")
19786 (const_string "V2DF"))]
19787 (const_string "V2DF")))])
19788
19789 (define_split
19790 [(set (match_operand:V2DF 0 "register_operand" "")
19791 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19792 "TARGET_SSE2 && reload_completed"
19793 [(set (match_dup 0)
19794 (vec_merge:V2DF
19795 (vec_duplicate:V2DF (match_dup 1))
19796 (match_dup 2)
19797 (const_int 1)))]
19798 {
19799 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19800 operands[2] = CONST0_RTX (V2DFmode);
19801 })
19802
19803 ;; 16 byte integral modes handled by SSE, minus TImode, which gets
19804 ;; special-cased for TARGET_64BIT.
19805 (define_mode_macro SSEMODEI [V16QI V8HI V4SI V2DI])
19806
19807 (define_expand "mov<mode>"
19808 [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "")
19809 (match_operand:SSEMODEI 1 "nonimmediate_operand" ""))]
19810 "TARGET_SSE"
19811 {
19812 ix86_expand_vector_move (<MODE>mode, operands);
19813 DONE;
19814 })
19815
19816 (define_insn "*mov<mode>_internal"
19817 [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "=x,x ,m")
19818 (match_operand:SSEMODEI 1 "vector_move_operand" "C ,xm,x"))]
19819 "TARGET_SSE
19820 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19821 {
19822 switch (which_alternative)
19823 {
19824 case 0:
19825 if (get_attr_mode (insn) == MODE_V4SF)
19826 return "xorps\t%0, %0";
19827 else
19828 return "pxor\t%0, %0";
19829 case 1:
19830 case 2:
19831 if (get_attr_mode (insn) == MODE_V4SF)
19832 return "movaps\t{%1, %0|%0, %1}";
19833 else
19834 return "movdqa\t{%1, %0|%0, %1}";
19835 default:
19836 abort ();
19837 }
19838 }
19839 [(set_attr "type" "ssemov")
19840 (set (attr "mode")
19841 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
19842 (const_string "V4SF")
19843
19844 (eq_attr "alternative" "0,1")
19845 (if_then_else
19846 (ne (symbol_ref "optimize_size")
19847 (const_int 0))
19848 (const_string "V4SF")
19849 (const_string "TI"))
19850 (eq_attr "alternative" "2")
19851 (if_then_else
19852 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19853 (const_int 0))
19854 (ne (symbol_ref "optimize_size")
19855 (const_int 0)))
19856 (const_string "V4SF")
19857 (const_string "TI"))]
19858 (const_string "TI")))])
19859
19860 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
19861 (define_mode_macro MMXMODEI [V8QI V4HI V2SI])
19862
19863 (define_expand "mov<mode>"
19864 [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" "")
19865 (match_operand:MMXMODEI 1 "nonimmediate_operand" ""))]
19866 "TARGET_MMX"
19867 {
19868 ix86_expand_vector_move (<MODE>mode, operands);
19869 DONE;
19870 })
19871
19872 (define_insn "*mov<mode>_internal_rex64"
19873 [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
19874 "=rm,r,*y,*y ,m ,*y,Y ,x,x ,m,r,x")
19875 (match_operand:MMXMODEI 1 "vector_move_operand"
19876 "Cr ,m,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
19877 "TARGET_64BIT && TARGET_MMX
19878 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19879 "@
19880 movq\t{%1, %0|%0, %1}
19881 movq\t{%1, %0|%0, %1}
19882 pxor\t%0, %0
19883 movq\t{%1, %0|%0, %1}
19884 movq\t{%1, %0|%0, %1}
19885 movdq2q\t{%1, %0|%0, %1}
19886 movq2dq\t{%1, %0|%0, %1}
19887 pxor\t%0, %0
19888 movq\t{%1, %0|%0, %1}
19889 movq\t{%1, %0|%0, %1}
19890 movd\t{%1, %0|%0, %1}
19891 movd\t{%1, %0|%0, %1}"
19892 [(set_attr "type" "imov,imov,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov")
19893 (set_attr "mode" "DI")])
19894
19895 (define_insn "*mov<mode>_internal"
19896 [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
19897 "=*y,*y ,m ,*y,*Y,*Y,*Y ,m ,*x,*x,*x,m")
19898 (match_operand:MMXMODEI 1 "vector_move_operand"
19899 "C ,*ym,*y,*Y,*y,C ,*Ym,*Y,C ,*x,m ,*x"))]
19900 "TARGET_MMX
19901 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19902 "@
19903 pxor\t%0, %0
19904 movq\t{%1, %0|%0, %1}
19905 movq\t{%1, %0|%0, %1}
19906 movdq2q\t{%1, %0|%0, %1}
19907 movq2dq\t{%1, %0|%0, %1}
19908 pxor\t%0, %0
19909 movq\t{%1, %0|%0, %1}
19910 movq\t{%1, %0|%0, %1}
19911 xorps\t%0, %0
19912 movaps\t{%1, %0|%0, %1}
19913 movlps\t{%1, %0|%0, %1}
19914 movlps\t{%1, %0|%0, %1}"
19915 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov")
19916 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF")])
19917
19918 (define_expand "movv2sf"
19919 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19920 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19921 "TARGET_MMX"
19922 {
19923 ix86_expand_vector_move (V2SFmode, operands);
19924 DONE;
19925 })
19926
19927 (define_insn "*movv2sf_internal_rex64"
19928 [(set (match_operand:V2SF 0 "nonimmediate_operand"
19929 "=rm,r,*y ,*y ,m ,*y,Y ,x,x ,m,r,x")
19930 (match_operand:V2SF 1 "vector_move_operand"
19931 "Cr ,m ,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
19932 "TARGET_64BIT && TARGET_MMX
19933 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19934 "@
19935 movq\t{%1, %0|%0, %1}
19936 movq\t{%1, %0|%0, %1}
19937 pxor\t%0, %0
19938 movq\t{%1, %0|%0, %1}
19939 movq\t{%1, %0|%0, %1}
19940 movdq2q\t{%1, %0|%0, %1}
19941 movq2dq\t{%1, %0|%0, %1}
19942 xorps\t%0, %0
19943 movlps\t{%1, %0|%0, %1}
19944 movlps\t{%1, %0|%0, %1}
19945 movd\t{%1, %0|%0, %1}
19946 movd\t{%1, %0|%0, %1}"
19947 [(set_attr "type" "imov,imov,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov")
19948 (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V2SF,V2SF,DI,DI")])
19949
19950 (define_insn "*movv2sf_internal"
19951 [(set (match_operand:V2SF 0 "nonimmediate_operand"
19952 "=*y,*y ,m,*y,*Y,*x,*x ,m")
19953 (match_operand:V2SF 1 "vector_move_operand"
19954 "C ,*ym,*y,*Y,*y,C ,*xm,*x"))]
19955 "TARGET_MMX
19956 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19957 "@
19958 pxor\t%0, %0
19959 movq\t{%1, %0|%0, %1}
19960 movq\t{%1, %0|%0, %1}
19961 movdq2q\t{%1, %0|%0, %1}
19962 movq2dq\t{%1, %0|%0, %1}
19963 xorps\t%0, %0
19964 movlps\t{%1, %0|%0, %1}
19965 movlps\t{%1, %0|%0, %1}"
19966 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
19967 (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V2SF,V2SF")])
19968
19969 (define_expand "movti"
19970 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19971 (match_operand:TI 1 "nonimmediate_operand" ""))]
19972 "TARGET_SSE || TARGET_64BIT"
19973 {
19974 if (TARGET_64BIT)
19975 ix86_expand_move (TImode, operands);
19976 else
19977 ix86_expand_vector_move (TImode, operands);
19978 DONE;
19979 })
19980
19981 (define_insn "*movti_internal"
19982 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19983 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19984 "TARGET_SSE && !TARGET_64BIT
19985 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19986 {
19987 switch (which_alternative)
19988 {
19989 case 0:
19990 if (get_attr_mode (insn) == MODE_V4SF)
19991 return "xorps\t%0, %0";
19992 else
19993 return "pxor\t%0, %0";
19994 case 1:
19995 case 2:
19996 if (get_attr_mode (insn) == MODE_V4SF)
19997 return "movaps\t{%1, %0|%0, %1}";
19998 else
19999 return "movdqa\t{%1, %0|%0, %1}";
20000 default:
20001 abort ();
20002 }
20003 }
20004 [(set_attr "type" "ssemov,ssemov,ssemov")
20005 (set (attr "mode")
20006 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
20007 (const_string "V4SF")
20008
20009 (eq_attr "alternative" "0,1")
20010 (if_then_else
20011 (ne (symbol_ref "optimize_size")
20012 (const_int 0))
20013 (const_string "V4SF")
20014 (const_string "TI"))
20015 (eq_attr "alternative" "2")
20016 (if_then_else
20017 (ne (symbol_ref "optimize_size")
20018 (const_int 0))
20019 (const_string "V4SF")
20020 (const_string "TI"))]
20021 (const_string "TI")))])
20022
20023 (define_insn "*movti_rex64"
20024 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20025 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20026 "TARGET_64BIT
20027 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20028 {
20029 switch (which_alternative)
20030 {
20031 case 0:
20032 case 1:
20033 return "#";
20034 case 2:
20035 if (get_attr_mode (insn) == MODE_V4SF)
20036 return "xorps\t%0, %0";
20037 else
20038 return "pxor\t%0, %0";
20039 case 3:
20040 case 4:
20041 if (get_attr_mode (insn) == MODE_V4SF)
20042 return "movaps\t{%1, %0|%0, %1}";
20043 else
20044 return "movdqa\t{%1, %0|%0, %1}";
20045 default:
20046 abort ();
20047 }
20048 }
20049 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20050 (set (attr "mode")
20051 (cond [(eq_attr "alternative" "2,3")
20052 (if_then_else
20053 (ne (symbol_ref "optimize_size")
20054 (const_int 0))
20055 (const_string "V4SF")
20056 (const_string "TI"))
20057 (eq_attr "alternative" "4")
20058 (if_then_else
20059 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20060 (const_int 0))
20061 (ne (symbol_ref "optimize_size")
20062 (const_int 0)))
20063 (const_string "V4SF")
20064 (const_string "TI"))]
20065 (const_string "DI")))])
20066
20067 (define_expand "movtf"
20068 [(set (match_operand:TF 0 "nonimmediate_operand" "")
20069 (match_operand:TF 1 "nonimmediate_operand" ""))]
20070 "TARGET_64BIT"
20071 {
20072 ix86_expand_move (TFmode, operands);
20073 DONE;
20074 })
20075
20076 (define_insn "*movtf_internal"
20077 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20078 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20079 "TARGET_64BIT
20080 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20081 {
20082 switch (which_alternative)
20083 {
20084 case 0:
20085 case 1:
20086 return "#";
20087 case 2:
20088 if (get_attr_mode (insn) == MODE_V4SF)
20089 return "xorps\t%0, %0";
20090 else
20091 return "pxor\t%0, %0";
20092 case 3:
20093 case 4:
20094 if (get_attr_mode (insn) == MODE_V4SF)
20095 return "movaps\t{%1, %0|%0, %1}";
20096 else
20097 return "movdqa\t{%1, %0|%0, %1}";
20098 default:
20099 abort ();
20100 }
20101 }
20102 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20103 (set (attr "mode")
20104 (cond [(eq_attr "alternative" "2,3")
20105 (if_then_else
20106 (ne (symbol_ref "optimize_size")
20107 (const_int 0))
20108 (const_string "V4SF")
20109 (const_string "TI"))
20110 (eq_attr "alternative" "4")
20111 (if_then_else
20112 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20113 (const_int 0))
20114 (ne (symbol_ref "optimize_size")
20115 (const_int 0)))
20116 (const_string "V4SF")
20117 (const_string "TI"))]
20118 (const_string "DI")))])
20119
20120 (define_mode_macro SSEPUSH [V16QI V8HI V4SI V2DI TI V4SF V2DF])
20121
20122 (define_insn "*push<mode>"
20123 [(set (match_operand:SSEPUSH 0 "push_operand" "=<")
20124 (match_operand:SSEPUSH 1 "register_operand" "x"))]
20125 "TARGET_SSE"
20126 "#")
20127
20128 (define_mode_macro MMXPUSH [V8QI V4HI V2SI V2SF])
20129
20130 (define_insn "*push<mode>"
20131 [(set (match_operand:MMXPUSH 0 "push_operand" "=<")
20132 (match_operand:MMXPUSH 1 "register_operand" "xy"))]
20133 "TARGET_MMX"
20134 "#")
20135
20136 (define_split
20137 [(set (match_operand 0 "push_operand" "")
20138 (match_operand 1 "register_operand" ""))]
20139 "!TARGET_64BIT && reload_completed
20140 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20141 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20142 (set (match_dup 2) (match_dup 1))]
20143 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20144 stack_pointer_rtx);
20145 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20146
20147 (define_split
20148 [(set (match_operand 0 "push_operand" "")
20149 (match_operand 1 "register_operand" ""))]
20150 "TARGET_64BIT && reload_completed
20151 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20152 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20153 (set (match_dup 2) (match_dup 1))]
20154 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20155 stack_pointer_rtx);
20156 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20157
20158
20159 (define_split
20160 [(set (match_operand:TI 0 "nonimmediate_operand" "")
20161 (match_operand:TI 1 "general_operand" ""))]
20162 "reload_completed && !SSE_REG_P (operands[0])
20163 && !SSE_REG_P (operands[1])"
20164 [(const_int 0)]
20165 "ix86_split_long_move (operands); DONE;")
20166
20167 (define_split
20168 [(set (match_operand:TF 0 "nonimmediate_operand" "")
20169 (match_operand:TF 1 "general_operand" ""))]
20170 "reload_completed && !SSE_REG_P (operands[0])
20171 && !SSE_REG_P (operands[1])"
20172 [(const_int 0)]
20173 "ix86_split_long_move (operands); DONE;")
20174
20175 ;; All 16-byte vector modes handled by SSE
20176 (define_mode_macro SSEMODE [V16QI V8HI V4SI V2DI V4SF V2DF])
20177
20178 (define_expand "movmisalign<mode>"
20179 [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "")
20180 (match_operand:SSEMODE 1 "nonimmediate_operand" ""))]
20181 "TARGET_SSE"
20182 {
20183 ix86_expand_vector_move_misalign (<MODE>mode, operands);
20184 DONE;
20185 })
20186
20187 ;; All 8-byte vector modes handled by MMX
20188 (define_mode_macro MMXMODE [V8QI V4HI V2SI V2SF])
20189
20190 (define_expand "movmisalign<mode>"
20191 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
20192 (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
20193 "TARGET_MMX"
20194 {
20195 ix86_expand_vector_move (<MODE>mode, operands);
20196 DONE;
20197 })
20198
20199 ;; These two patterns are useful for specifying exactly whether to use
20200 ;; movaps or movups
20201 (define_expand "sse_movaps"
20202 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20203 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20204 UNSPEC_MOVA))]
20205 "TARGET_SSE"
20206 {
20207 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20208 {
20209 rtx tmp = gen_reg_rtx (V4SFmode);
20210 emit_insn (gen_sse_movaps (tmp, operands[1]));
20211 emit_move_insn (operands[0], tmp);
20212 DONE;
20213 }
20214 })
20215
20216 (define_insn "*sse_movaps_1"
20217 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20218 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20219 UNSPEC_MOVA))]
20220 "TARGET_SSE
20221 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20222 "movaps\t{%1, %0|%0, %1}"
20223 [(set_attr "type" "ssemov,ssemov")
20224 (set_attr "mode" "V4SF")])
20225
20226 (define_expand "sse_movups"
20227 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20228 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20229 UNSPEC_MOVU))]
20230 "TARGET_SSE"
20231 {
20232 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20233 {
20234 rtx tmp = gen_reg_rtx (V4SFmode);
20235 emit_insn (gen_sse_movups (tmp, operands[1]));
20236 emit_move_insn (operands[0], tmp);
20237 DONE;
20238 }
20239 })
20240
20241 (define_insn "*sse_movups_1"
20242 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20243 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20244 UNSPEC_MOVU))]
20245 "TARGET_SSE
20246 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20247 "movups\t{%1, %0|%0, %1}"
20248 [(set_attr "type" "ssecvt,ssecvt")
20249 (set_attr "mode" "V4SF")])
20250
20251 ;; SSE Strange Moves.
20252
20253 (define_insn "sse_movmskps"
20254 [(set (match_operand:SI 0 "register_operand" "=r")
20255 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20256 UNSPEC_MOVMSK))]
20257 "TARGET_SSE"
20258 "movmskps\t{%1, %0|%0, %1}"
20259 [(set_attr "type" "ssecvt")
20260 (set_attr "mode" "V4SF")])
20261
20262 (define_insn "mmx_pmovmskb"
20263 [(set (match_operand:SI 0 "register_operand" "=r")
20264 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20265 UNSPEC_MOVMSK))]
20266 "TARGET_SSE || TARGET_3DNOW_A"
20267 "pmovmskb\t{%1, %0|%0, %1}"
20268 [(set_attr "type" "ssecvt")
20269 (set_attr "mode" "V4SF")])
20270
20271
20272 (define_insn "mmx_maskmovq"
20273 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20274 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20275 (match_operand:V8QI 2 "register_operand" "y")]
20276 UNSPEC_MASKMOV))]
20277 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20278 ;; @@@ check ordering of operands in intel/nonintel syntax
20279 "maskmovq\t{%2, %1|%1, %2}"
20280 [(set_attr "type" "mmxcvt")
20281 (set_attr "mode" "DI")])
20282
20283 (define_insn "mmx_maskmovq_rex"
20284 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20285 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20286 (match_operand:V8QI 2 "register_operand" "y")]
20287 UNSPEC_MASKMOV))]
20288 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20289 ;; @@@ check ordering of operands in intel/nonintel syntax
20290 "maskmovq\t{%2, %1|%1, %2}"
20291 [(set_attr "type" "mmxcvt")
20292 (set_attr "mode" "DI")])
20293
20294 (define_insn "sse_movntv4sf"
20295 [(set (match_operand:V4SF 0 "memory_operand" "=m")
20296 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20297 UNSPEC_MOVNT))]
20298 "TARGET_SSE"
20299 "movntps\t{%1, %0|%0, %1}"
20300 [(set_attr "type" "ssemov")
20301 (set_attr "mode" "V4SF")])
20302
20303 (define_insn "sse_movntdi"
20304 [(set (match_operand:DI 0 "memory_operand" "=m")
20305 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20306 UNSPEC_MOVNT))]
20307 "TARGET_SSE || TARGET_3DNOW_A"
20308 "movntq\t{%1, %0|%0, %1}"
20309 [(set_attr "type" "mmxmov")
20310 (set_attr "mode" "DI")])
20311
20312 (define_insn "sse_movhlps"
20313 [(set (match_operand:V4SF 0 "register_operand" "=x")
20314 (vec_merge:V4SF
20315 (match_operand:V4SF 1 "register_operand" "0")
20316 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20317 (parallel [(const_int 2)
20318 (const_int 3)
20319 (const_int 0)
20320 (const_int 1)]))
20321 (const_int 3)))]
20322 "TARGET_SSE"
20323 "movhlps\t{%2, %0|%0, %2}"
20324 [(set_attr "type" "ssecvt")
20325 (set_attr "mode" "V4SF")])
20326
20327 (define_insn "sse_movlhps"
20328 [(set (match_operand:V4SF 0 "register_operand" "=x")
20329 (vec_merge:V4SF
20330 (match_operand:V4SF 1 "register_operand" "0")
20331 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20332 (parallel [(const_int 2)
20333 (const_int 3)
20334 (const_int 0)
20335 (const_int 1)]))
20336 (const_int 12)))]
20337 "TARGET_SSE"
20338 "movlhps\t{%2, %0|%0, %2}"
20339 [(set_attr "type" "ssecvt")
20340 (set_attr "mode" "V4SF")])
20341
20342 ;; Store the high V2SF of the source vector to the destination.
20343 (define_insn "sse_storehps"
20344 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
20345 (vec_select:V2SF
20346 (match_operand:V4SF 1 "nonimmediate_operand" "x,x,o")
20347 (parallel [(const_int 2) (const_int 3)])))]
20348 "TARGET_SSE"
20349 "@
20350 movhps\t{%1, %0|%0, %1}
20351 movhlps\t{%1, %0|%0, %1}
20352 #"
20353 [(set_attr "type" "ssecvt")
20354 (set_attr "mode" "V2SF")])
20355
20356 (define_split
20357 [(set (match_operand:V2SF 0 "register_operand" "")
20358 (vec_select:V2SF
20359 (match_operand:V4SF 1 "memory_operand" "")
20360 (parallel [(const_int 2) (const_int 3)])))]
20361 "TARGET_SSE && reload_completed"
20362 [(const_int 0)]
20363 {
20364 emit_move_insn (operands[0], adjust_address (operands[1], V2SFmode, 8));
20365 DONE;
20366 })
20367
20368 ;; Load the high V2SF of the target vector from the source vector.
20369 (define_insn "sse_loadhps"
20370 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o")
20371 (vec_concat:V4SF
20372 (vec_select:V2SF
20373 (match_operand:V4SF 1 "nonimmediate_operand" "0,0,0")
20374 (parallel [(const_int 0) (const_int 1)]))
20375 (match_operand:V2SF 2 "nonimmediate_operand" "m,x,x")))]
20376 "TARGET_SSE"
20377 "@
20378 movhps\t{%2, %0|%0, %2}
20379 movlhps\t{%2, %0|%0, %2}
20380 #"
20381 [(set_attr "type" "ssecvt")
20382 (set_attr "mode" "V2SF")])
20383
20384 (define_split
20385 [(set (match_operand:V4SF 0 "memory_operand" "")
20386 (vec_concat:V4SF
20387 (vec_select:V2SF
20388 (match_dup 0)
20389 (parallel [(const_int 0) (const_int 1)]))
20390 (match_operand:V2SF 1 "register_operand" "")))]
20391 "TARGET_SSE && reload_completed"
20392 [(const_int 0)]
20393 {
20394 emit_move_insn (adjust_address (operands[0], V2SFmode, 8), operands[1]);
20395 DONE;
20396 })
20397
20398 ;; Store the low V2SF of the source vector to the destination.
20399 (define_expand "sse_storelps"
20400 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20401 (vec_select:V2SF
20402 (match_operand:V4SF 1 "nonimmediate_operand" "")
20403 (parallel [(const_int 0) (const_int 1)])))]
20404 "TARGET_SSE"
20405 {
20406 operands[1] = gen_lowpart (V2SFmode, operands[1]);
20407 emit_move_insn (operands[0], operands[1]);
20408 DONE;
20409 })
20410
20411 ;; Load the low V2SF of the target vector from the source vector.
20412 (define_insn "sse_loadlps"
20413 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
20414 (vec_concat:V4SF
20415 (match_operand:V2SF 2 "nonimmediate_operand" "m,0,x")
20416 (vec_select:V2SF
20417 (match_operand:V4SF 1 "nonimmediate_operand" "0,x,0")
20418 (parallel [(const_int 2) (const_int 3)]))))]
20419 "TARGET_SSE"
20420 {
20421 static const char * const alt[] = {
20422 "movlps\t{%2, %0|%0, %2}",
20423 "shufps\t{%2, %1, %0|%0, %1, %2}",
20424 "movlps\t{%2, %0|%0, %2}"
20425 };
20426
20427 if (which_alternative == 1)
20428 operands[2] = GEN_INT (0xe4);
20429
20430 return alt[which_alternative];
20431 }
20432 [(set_attr "type" "ssecvt")
20433 (set_attr "mode" "V2SF")])
20434
20435 (define_expand "sse_loadss"
20436 [(match_operand:V4SF 0 "register_operand" "")
20437 (match_operand:SF 1 "memory_operand" "")]
20438 "TARGET_SSE"
20439 {
20440 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20441 CONST0_RTX (V4SFmode)));
20442 DONE;
20443 })
20444
20445 (define_insn "sse_loadss_1"
20446 [(set (match_operand:V4SF 0 "register_operand" "=x")
20447 (vec_merge:V4SF
20448 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20449 (match_operand:V4SF 2 "const0_operand" "X")
20450 (const_int 1)))]
20451 "TARGET_SSE"
20452 "movss\t{%1, %0|%0, %1}"
20453 [(set_attr "type" "ssemov")
20454 (set_attr "mode" "SF")])
20455
20456 (define_insn "sse_movss"
20457 [(set (match_operand:V4SF 0 "register_operand" "=x")
20458 (vec_merge:V4SF
20459 (match_operand:V4SF 1 "register_operand" "0")
20460 (match_operand:V4SF 2 "register_operand" "x")
20461 (const_int 14)))]
20462 "TARGET_SSE"
20463 "movss\t{%2, %0|%0, %2}"
20464 [(set_attr "type" "ssemov")
20465 (set_attr "mode" "SF")])
20466
20467 (define_insn "sse_storess"
20468 [(set (match_operand:SF 0 "memory_operand" "=m")
20469 (vec_select:SF
20470 (match_operand:V4SF 1 "register_operand" "x")
20471 (parallel [(const_int 0)])))]
20472 "TARGET_SSE"
20473 "movss\t{%1, %0|%0, %1}"
20474 [(set_attr "type" "ssemov")
20475 (set_attr "mode" "SF")])
20476
20477 (define_insn "sse_shufps"
20478 [(set (match_operand:V4SF 0 "register_operand" "=x")
20479 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20480 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20481 (match_operand:SI 3 "const_int_operand" "n")]
20482 UNSPEC_SHUFFLE))]
20483 "TARGET_SSE"
20484 "shufps\t{%3, %2, %0|%0, %2, %3}"
20485 [(set_attr "type" "ssecvt")
20486 (set_attr "mode" "V4SF")])
20487
20488
20489 ;; SSE arithmetic
20490
20491 (define_insn "addv4sf3"
20492 [(set (match_operand:V4SF 0 "register_operand" "=x")
20493 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20494 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20495 "TARGET_SSE"
20496 "addps\t{%2, %0|%0, %2}"
20497 [(set_attr "type" "sseadd")
20498 (set_attr "mode" "V4SF")])
20499
20500 (define_insn "vmaddv4sf3"
20501 [(set (match_operand:V4SF 0 "register_operand" "=x")
20502 (vec_merge:V4SF
20503 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20504 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20505 (match_dup 1)
20506 (const_int 1)))]
20507 "TARGET_SSE"
20508 "addss\t{%2, %0|%0, %2}"
20509 [(set_attr "type" "sseadd")
20510 (set_attr "mode" "SF")])
20511
20512 (define_insn "subv4sf3"
20513 [(set (match_operand:V4SF 0 "register_operand" "=x")
20514 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20515 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20516 "TARGET_SSE"
20517 "subps\t{%2, %0|%0, %2}"
20518 [(set_attr "type" "sseadd")
20519 (set_attr "mode" "V4SF")])
20520
20521 (define_insn "vmsubv4sf3"
20522 [(set (match_operand:V4SF 0 "register_operand" "=x")
20523 (vec_merge:V4SF
20524 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20525 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20526 (match_dup 1)
20527 (const_int 1)))]
20528 "TARGET_SSE"
20529 "subss\t{%2, %0|%0, %2}"
20530 [(set_attr "type" "sseadd")
20531 (set_attr "mode" "SF")])
20532
20533 ;; ??? Should probably be done by generic code instead.
20534 (define_expand "negv4sf2"
20535 [(set (match_operand:V4SF 0 "register_operand" "")
20536 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20537 (match_dup 2)))]
20538 "TARGET_SSE"
20539 {
20540 rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20541 rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20542 operands[2] = force_reg (V4SFmode, vm0);
20543 })
20544
20545 (define_insn "mulv4sf3"
20546 [(set (match_operand:V4SF 0 "register_operand" "=x")
20547 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20548 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20549 "TARGET_SSE"
20550 "mulps\t{%2, %0|%0, %2}"
20551 [(set_attr "type" "ssemul")
20552 (set_attr "mode" "V4SF")])
20553
20554 (define_insn "vmmulv4sf3"
20555 [(set (match_operand:V4SF 0 "register_operand" "=x")
20556 (vec_merge:V4SF
20557 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20558 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20559 (match_dup 1)
20560 (const_int 1)))]
20561 "TARGET_SSE"
20562 "mulss\t{%2, %0|%0, %2}"
20563 [(set_attr "type" "ssemul")
20564 (set_attr "mode" "SF")])
20565
20566 (define_insn "divv4sf3"
20567 [(set (match_operand:V4SF 0 "register_operand" "=x")
20568 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20569 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20570 "TARGET_SSE"
20571 "divps\t{%2, %0|%0, %2}"
20572 [(set_attr "type" "ssediv")
20573 (set_attr "mode" "V4SF")])
20574
20575 (define_insn "vmdivv4sf3"
20576 [(set (match_operand:V4SF 0 "register_operand" "=x")
20577 (vec_merge:V4SF
20578 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20579 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20580 (match_dup 1)
20581 (const_int 1)))]
20582 "TARGET_SSE"
20583 "divss\t{%2, %0|%0, %2}"
20584 [(set_attr "type" "ssediv")
20585 (set_attr "mode" "SF")])
20586
20587
20588 ;; SSE square root/reciprocal
20589
20590 (define_insn "rcpv4sf2"
20591 [(set (match_operand:V4SF 0 "register_operand" "=x")
20592 (unspec:V4SF
20593 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20594 "TARGET_SSE"
20595 "rcpps\t{%1, %0|%0, %1}"
20596 [(set_attr "type" "sse")
20597 (set_attr "mode" "V4SF")])
20598
20599 (define_insn "vmrcpv4sf2"
20600 [(set (match_operand:V4SF 0 "register_operand" "=x")
20601 (vec_merge:V4SF
20602 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20603 UNSPEC_RCP)
20604 (match_operand:V4SF 2 "register_operand" "0")
20605 (const_int 1)))]
20606 "TARGET_SSE"
20607 "rcpss\t{%1, %0|%0, %1}"
20608 [(set_attr "type" "sse")
20609 (set_attr "mode" "SF")])
20610
20611 (define_insn "rsqrtv4sf2"
20612 [(set (match_operand:V4SF 0 "register_operand" "=x")
20613 (unspec:V4SF
20614 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20615 "TARGET_SSE"
20616 "rsqrtps\t{%1, %0|%0, %1}"
20617 [(set_attr "type" "sse")
20618 (set_attr "mode" "V4SF")])
20619
20620 (define_insn "vmrsqrtv4sf2"
20621 [(set (match_operand:V4SF 0 "register_operand" "=x")
20622 (vec_merge:V4SF
20623 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20624 UNSPEC_RSQRT)
20625 (match_operand:V4SF 2 "register_operand" "0")
20626 (const_int 1)))]
20627 "TARGET_SSE"
20628 "rsqrtss\t{%1, %0|%0, %1}"
20629 [(set_attr "type" "sse")
20630 (set_attr "mode" "SF")])
20631
20632 (define_insn "sqrtv4sf2"
20633 [(set (match_operand:V4SF 0 "register_operand" "=x")
20634 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20635 "TARGET_SSE"
20636 "sqrtps\t{%1, %0|%0, %1}"
20637 [(set_attr "type" "sse")
20638 (set_attr "mode" "V4SF")])
20639
20640 (define_insn "vmsqrtv4sf2"
20641 [(set (match_operand:V4SF 0 "register_operand" "=x")
20642 (vec_merge:V4SF
20643 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20644 (match_operand:V4SF 2 "register_operand" "0")
20645 (const_int 1)))]
20646 "TARGET_SSE"
20647 "sqrtss\t{%1, %0|%0, %1}"
20648 [(set_attr "type" "sse")
20649 (set_attr "mode" "SF")])
20650
20651 ;; SSE logical operations.
20652
20653 ;; SSE defines logical operations on floating point values. This brings
20654 ;; interesting challenge to RTL representation where logicals are only valid
20655 ;; on integral types. We deal with this by representing the floating point
20656 ;; logical as logical on arguments casted to TImode as this is what hardware
20657 ;; really does. Unfortunately hardware requires the type information to be
20658 ;; present and thus we must avoid subregs from being simplified and eliminated
20659 ;; in later compilation phases.
20660 ;;
20661 ;; We have following variants from each instruction:
20662 ;; sse_andsf3 - the operation taking V4SF vector operands
20663 ;; and doing TImode cast on them
20664 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20665 ;; TImode, since backend insist on eliminating casts
20666 ;; on memory operands
20667 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20668 ;; We cannot accept memory operand here as instruction reads
20669 ;; whole scalar. This is generated only post reload by GCC
20670 ;; scalar float operations that expands to logicals (fabs)
20671 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20672 ;; memory operand. Eventually combine can be able
20673 ;; to synthesize these using splitter.
20674 ;; sse2_anddf3, *sse2_anddf3_memory
20675 ;;
20676 ;;
20677 ;; These are not called andti3 etc. because we really really don't want
20678 ;; the compiler to widen DImode ands to TImode ands and then try to move
20679 ;; into DImode subregs of SSE registers, and them together, and move out
20680 ;; of DImode subregs again!
20681 ;; SSE1 single precision floating point logical operation
20682 (define_expand "sse_andv4sf3"
20683 [(set (match_operand:V4SF 0 "register_operand" "")
20684 (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20685 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20686 "TARGET_SSE"
20687 "")
20688
20689 (define_insn "*sse_andv4sf3"
20690 [(set (match_operand:V4SF 0 "register_operand" "=x")
20691 (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20692 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20693 "TARGET_SSE
20694 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20695 "andps\t{%2, %0|%0, %2}"
20696 [(set_attr "type" "sselog")
20697 (set_attr "mode" "V4SF")])
20698
20699 (define_expand "sse_nandv4sf3"
20700 [(set (match_operand:V4SF 0 "register_operand" "")
20701 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20702 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20703 "TARGET_SSE"
20704 "")
20705
20706 (define_insn "*sse_nandv4sf3"
20707 [(set (match_operand:V4SF 0 "register_operand" "=x")
20708 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20709 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20710 "TARGET_SSE"
20711 "andnps\t{%2, %0|%0, %2}"
20712 [(set_attr "type" "sselog")
20713 (set_attr "mode" "V4SF")])
20714
20715 (define_expand "sse_iorv4sf3"
20716 [(set (match_operand:V4SF 0 "register_operand" "")
20717 (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20718 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20719 "TARGET_SSE"
20720 "")
20721
20722 (define_insn "*sse_iorv4sf3"
20723 [(set (match_operand:V4SF 0 "register_operand" "=x")
20724 (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20725 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20726 "TARGET_SSE
20727 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20728 "orps\t{%2, %0|%0, %2}"
20729 [(set_attr "type" "sselog")
20730 (set_attr "mode" "V4SF")])
20731
20732 (define_expand "sse_xorv4sf3"
20733 [(set (match_operand:V4SF 0 "register_operand" "")
20734 (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20735 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20736 "TARGET_SSE"
20737 "")
20738
20739 (define_insn "*sse_xorv4sf3"
20740 [(set (match_operand:V4SF 0 "register_operand" "=x")
20741 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20742 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20743 "TARGET_SSE
20744 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20745 "xorps\t{%2, %0|%0, %2}"
20746 [(set_attr "type" "sselog")
20747 (set_attr "mode" "V4SF")])
20748
20749 ;; SSE2 double precision floating point logical operation
20750
20751 (define_expand "sse2_andv2df3"
20752 [(set (match_operand:V2DF 0 "register_operand" "")
20753 (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20754 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20755 "TARGET_SSE2"
20756 "")
20757
20758 (define_insn "*sse2_andv2df3"
20759 [(set (match_operand:V2DF 0 "register_operand" "=x")
20760 (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20761 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20762 "TARGET_SSE2
20763 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20764 "andpd\t{%2, %0|%0, %2}"
20765 [(set_attr "type" "sselog")
20766 (set_attr "mode" "V2DF")])
20767
20768 (define_expand "sse2_nandv2df3"
20769 [(set (match_operand:V2DF 0 "register_operand" "")
20770 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20771 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20772 "TARGET_SSE2"
20773 "")
20774
20775 (define_insn "*sse2_nandv2df3"
20776 [(set (match_operand:V2DF 0 "register_operand" "=x")
20777 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20778 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20779 "TARGET_SSE2"
20780 "andnpd\t{%2, %0|%0, %2}"
20781 [(set_attr "type" "sselog")
20782 (set_attr "mode" "V2DF")])
20783
20784 (define_expand "sse2_iorv2df3"
20785 [(set (match_operand:V2DF 0 "register_operand" "")
20786 (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20787 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20788 "TARGET_SSE2"
20789 "")
20790
20791 (define_insn "*sse2_iorv2df3"
20792 [(set (match_operand:V2DF 0 "register_operand" "=x")
20793 (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20794 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20795 "TARGET_SSE2
20796 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20797 "orpd\t{%2, %0|%0, %2}"
20798 [(set_attr "type" "sselog")
20799 (set_attr "mode" "V2DF")])
20800
20801 (define_expand "sse2_xorv2df3"
20802 [(set (match_operand:V2DF 0 "register_operand" "")
20803 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20804 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20805 "TARGET_SSE2"
20806 "")
20807
20808 (define_insn "*sse2_xorv2df3"
20809 [(set (match_operand:V2DF 0 "register_operand" "=x")
20810 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20811 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20812 "TARGET_SSE2
20813 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20814 "xorpd\t{%2, %0|%0, %2}"
20815 [(set_attr "type" "sselog")
20816 (set_attr "mode" "V2DF")])
20817
20818 ;; SSE2 integral logicals. These patterns must always come after floating
20819 ;; point ones since we don't want compiler to use integer opcodes on floating
20820 ;; point SSE values to avoid matching of subregs in the match_operand.
20821 (define_insn "*sse2_andti3"
20822 [(set (match_operand:TI 0 "register_operand" "=x")
20823 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20824 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20825 "TARGET_SSE2
20826 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20827 "pand\t{%2, %0|%0, %2}"
20828 [(set_attr "type" "sselog")
20829 (set_attr "mode" "TI")])
20830
20831 (define_insn "sse2_andv2di3"
20832 [(set (match_operand:V2DI 0 "register_operand" "=x")
20833 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20834 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20835 "TARGET_SSE2
20836 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20837 "pand\t{%2, %0|%0, %2}"
20838 [(set_attr "type" "sselog")
20839 (set_attr "mode" "TI")])
20840
20841 (define_insn "*sse2_nandti3"
20842 [(set (match_operand:TI 0 "register_operand" "=x")
20843 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20844 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20845 "TARGET_SSE2"
20846 "pandn\t{%2, %0|%0, %2}"
20847 [(set_attr "type" "sselog")
20848 (set_attr "mode" "TI")])
20849
20850 (define_insn "sse2_nandv2di3"
20851 [(set (match_operand:V2DI 0 "register_operand" "=x")
20852 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20853 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20854 "TARGET_SSE2
20855 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20856 "pandn\t{%2, %0|%0, %2}"
20857 [(set_attr "type" "sselog")
20858 (set_attr "mode" "TI")])
20859
20860 (define_insn "*sse2_iorti3"
20861 [(set (match_operand:TI 0 "register_operand" "=x")
20862 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20863 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20864 "TARGET_SSE2
20865 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20866 "por\t{%2, %0|%0, %2}"
20867 [(set_attr "type" "sselog")
20868 (set_attr "mode" "TI")])
20869
20870 (define_insn "sse2_iorv2di3"
20871 [(set (match_operand:V2DI 0 "register_operand" "=x")
20872 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20873 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20874 "TARGET_SSE2
20875 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20876 "por\t{%2, %0|%0, %2}"
20877 [(set_attr "type" "sselog")
20878 (set_attr "mode" "TI")])
20879
20880 (define_insn "*sse2_xorti3"
20881 [(set (match_operand:TI 0 "register_operand" "=x")
20882 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20883 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20884 "TARGET_SSE2
20885 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20886 "pxor\t{%2, %0|%0, %2}"
20887 [(set_attr "type" "sselog")
20888 (set_attr "mode" "TI")])
20889
20890 (define_insn "sse2_xorv2di3"
20891 [(set (match_operand:V2DI 0 "register_operand" "=x")
20892 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20893 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20894 "TARGET_SSE2
20895 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20896 "pxor\t{%2, %0|%0, %2}"
20897 [(set_attr "type" "sselog")
20898 (set_attr "mode" "TI")])
20899
20900 ;; Use xor, but don't show input operands so they aren't live before
20901 ;; this insn.
20902 (define_insn "sse_clrv4sf"
20903 [(set (match_operand:V4SF 0 "register_operand" "=x")
20904 (match_operand:V4SF 1 "const0_operand" "X"))]
20905 "TARGET_SSE"
20906 {
20907 if (get_attr_mode (insn) == MODE_TI)
20908 return "pxor\t{%0, %0|%0, %0}";
20909 else
20910 return "xorps\t{%0, %0|%0, %0}";
20911 }
20912 [(set_attr "type" "sselog")
20913 (set_attr "memory" "none")
20914 (set (attr "mode")
20915 (if_then_else
20916 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20917 (const_int 0))
20918 (ne (symbol_ref "TARGET_SSE2")
20919 (const_int 0)))
20920 (eq (symbol_ref "optimize_size")
20921 (const_int 0)))
20922 (const_string "TI")
20923 (const_string "V4SF")))])
20924
20925 ;; Use xor, but don't show input operands so they aren't live before
20926 ;; this insn.
20927 (define_insn "sse_clrv2df"
20928 [(set (match_operand:V2DF 0 "register_operand" "=x")
20929 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20930 "TARGET_SSE2"
20931 "xorpd\t{%0, %0|%0, %0}"
20932 [(set_attr "type" "sselog")
20933 (set_attr "memory" "none")
20934 (set_attr "mode" "V4SF")])
20935
20936 ;; SSE mask-generating compares
20937
20938 (define_insn "maskcmpv4sf3"
20939 [(set (match_operand:V4SI 0 "register_operand" "=x")
20940 (match_operator:V4SI 3 "sse_comparison_operator"
20941 [(match_operand:V4SF 1 "register_operand" "0")
20942 (match_operand:V4SF 2 "register_operand" "x")]))]
20943 "TARGET_SSE"
20944 "cmp%D3ps\t{%2, %0|%0, %2}"
20945 [(set_attr "type" "ssecmp")
20946 (set_attr "mode" "V4SF")])
20947
20948 (define_insn "maskncmpv4sf3"
20949 [(set (match_operand:V4SI 0 "register_operand" "=x")
20950 (not:V4SI
20951 (match_operator:V4SI 3 "sse_comparison_operator"
20952 [(match_operand:V4SF 1 "register_operand" "0")
20953 (match_operand:V4SF 2 "register_operand" "x")])))]
20954 "TARGET_SSE"
20955 {
20956 if (GET_CODE (operands[3]) == UNORDERED)
20957 return "cmpordps\t{%2, %0|%0, %2}";
20958 else
20959 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20960 }
20961 [(set_attr "type" "ssecmp")
20962 (set_attr "mode" "V4SF")])
20963
20964 (define_insn "vmmaskcmpv4sf3"
20965 [(set (match_operand:V4SI 0 "register_operand" "=x")
20966 (vec_merge:V4SI
20967 (match_operator:V4SI 3 "sse_comparison_operator"
20968 [(match_operand:V4SF 1 "register_operand" "0")
20969 (match_operand:V4SF 2 "register_operand" "x")])
20970 (subreg:V4SI (match_dup 1) 0)
20971 (const_int 1)))]
20972 "TARGET_SSE"
20973 "cmp%D3ss\t{%2, %0|%0, %2}"
20974 [(set_attr "type" "ssecmp")
20975 (set_attr "mode" "SF")])
20976
20977 (define_insn "vmmaskncmpv4sf3"
20978 [(set (match_operand:V4SI 0 "register_operand" "=x")
20979 (vec_merge:V4SI
20980 (not:V4SI
20981 (match_operator:V4SI 3 "sse_comparison_operator"
20982 [(match_operand:V4SF 1 "register_operand" "0")
20983 (match_operand:V4SF 2 "register_operand" "x")]))
20984 (subreg:V4SI (match_dup 1) 0)
20985 (const_int 1)))]
20986 "TARGET_SSE"
20987 {
20988 if (GET_CODE (operands[3]) == UNORDERED)
20989 return "cmpordss\t{%2, %0|%0, %2}";
20990 else
20991 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20992 }
20993 [(set_attr "type" "ssecmp")
20994 (set_attr "mode" "SF")])
20995
20996 (define_insn "sse_comi"
20997 [(set (reg:CCFP FLAGS_REG)
20998 (compare:CCFP (vec_select:SF
20999 (match_operand:V4SF 0 "register_operand" "x")
21000 (parallel [(const_int 0)]))
21001 (vec_select:SF
21002 (match_operand:V4SF 1 "register_operand" "x")
21003 (parallel [(const_int 0)]))))]
21004 "TARGET_SSE"
21005 "comiss\t{%1, %0|%0, %1}"
21006 [(set_attr "type" "ssecomi")
21007 (set_attr "mode" "SF")])
21008
21009 (define_insn "sse_ucomi"
21010 [(set (reg:CCFPU FLAGS_REG)
21011 (compare:CCFPU (vec_select:SF
21012 (match_operand:V4SF 0 "register_operand" "x")
21013 (parallel [(const_int 0)]))
21014 (vec_select:SF
21015 (match_operand:V4SF 1 "register_operand" "x")
21016 (parallel [(const_int 0)]))))]
21017 "TARGET_SSE"
21018 "ucomiss\t{%1, %0|%0, %1}"
21019 [(set_attr "type" "ssecomi")
21020 (set_attr "mode" "SF")])
21021
21022
21023 ;; SSE unpack
21024
21025 (define_insn "sse_unpckhps"
21026 [(set (match_operand:V4SF 0 "register_operand" "=x")
21027 (vec_merge:V4SF
21028 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21029 (parallel [(const_int 2)
21030 (const_int 0)
21031 (const_int 3)
21032 (const_int 1)]))
21033 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21034 (parallel [(const_int 0)
21035 (const_int 2)
21036 (const_int 1)
21037 (const_int 3)]))
21038 (const_int 5)))]
21039 "TARGET_SSE"
21040 "unpckhps\t{%2, %0|%0, %2}"
21041 [(set_attr "type" "ssecvt")
21042 (set_attr "mode" "V4SF")])
21043
21044 (define_insn "sse_unpcklps"
21045 [(set (match_operand:V4SF 0 "register_operand" "=x")
21046 (vec_merge:V4SF
21047 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21048 (parallel [(const_int 0)
21049 (const_int 2)
21050 (const_int 1)
21051 (const_int 3)]))
21052 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21053 (parallel [(const_int 2)
21054 (const_int 0)
21055 (const_int 3)
21056 (const_int 1)]))
21057 (const_int 5)))]
21058 "TARGET_SSE"
21059 "unpcklps\t{%2, %0|%0, %2}"
21060 [(set_attr "type" "ssecvt")
21061 (set_attr "mode" "V4SF")])
21062
21063
21064 ;; SSE min/max
21065
21066 (define_insn "smaxv4sf3"
21067 [(set (match_operand:V4SF 0 "register_operand" "=x")
21068 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21069 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21070 "TARGET_SSE"
21071 "maxps\t{%2, %0|%0, %2}"
21072 [(set_attr "type" "sse")
21073 (set_attr "mode" "V4SF")])
21074
21075 (define_insn "vmsmaxv4sf3"
21076 [(set (match_operand:V4SF 0 "register_operand" "=x")
21077 (vec_merge:V4SF
21078 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21079 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21080 (match_dup 1)
21081 (const_int 1)))]
21082 "TARGET_SSE"
21083 "maxss\t{%2, %0|%0, %2}"
21084 [(set_attr "type" "sse")
21085 (set_attr "mode" "SF")])
21086
21087 (define_insn "sminv4sf3"
21088 [(set (match_operand:V4SF 0 "register_operand" "=x")
21089 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21090 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21091 "TARGET_SSE"
21092 "minps\t{%2, %0|%0, %2}"
21093 [(set_attr "type" "sse")
21094 (set_attr "mode" "V4SF")])
21095
21096 (define_insn "vmsminv4sf3"
21097 [(set (match_operand:V4SF 0 "register_operand" "=x")
21098 (vec_merge:V4SF
21099 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21100 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21101 (match_dup 1)
21102 (const_int 1)))]
21103 "TARGET_SSE"
21104 "minss\t{%2, %0|%0, %2}"
21105 [(set_attr "type" "sse")
21106 (set_attr "mode" "SF")])
21107
21108 ;; SSE <-> integer/MMX conversions
21109
21110 (define_insn "cvtpi2ps"
21111 [(set (match_operand:V4SF 0 "register_operand" "=x")
21112 (vec_merge:V4SF
21113 (match_operand:V4SF 1 "register_operand" "0")
21114 (vec_duplicate:V4SF
21115 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21116 (const_int 12)))]
21117 "TARGET_SSE"
21118 "cvtpi2ps\t{%2, %0|%0, %2}"
21119 [(set_attr "type" "ssecvt")
21120 (set_attr "mode" "V4SF")])
21121
21122 (define_insn "cvtps2pi"
21123 [(set (match_operand:V2SI 0 "register_operand" "=y")
21124 (vec_select:V2SI
21125 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21126 (parallel [(const_int 0) (const_int 1)])))]
21127 "TARGET_SSE"
21128 "cvtps2pi\t{%1, %0|%0, %1}"
21129 [(set_attr "type" "ssecvt")
21130 (set_attr "mode" "V4SF")])
21131
21132 (define_insn "cvttps2pi"
21133 [(set (match_operand:V2SI 0 "register_operand" "=y")
21134 (vec_select:V2SI
21135 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21136 UNSPEC_FIX)
21137 (parallel [(const_int 0) (const_int 1)])))]
21138 "TARGET_SSE"
21139 "cvttps2pi\t{%1, %0|%0, %1}"
21140 [(set_attr "type" "ssecvt")
21141 (set_attr "mode" "SF")])
21142
21143 (define_insn "cvtsi2ss"
21144 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21145 (vec_merge:V4SF
21146 (match_operand:V4SF 1 "register_operand" "0,0")
21147 (vec_duplicate:V4SF
21148 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21149 (const_int 14)))]
21150 "TARGET_SSE"
21151 "cvtsi2ss\t{%2, %0|%0, %2}"
21152 [(set_attr "type" "sseicvt")
21153 (set_attr "athlon_decode" "vector,double")
21154 (set_attr "mode" "SF")])
21155
21156 (define_insn "cvtsi2ssq"
21157 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21158 (vec_merge:V4SF
21159 (match_operand:V4SF 1 "register_operand" "0,0")
21160 (vec_duplicate:V4SF
21161 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21162 (const_int 14)))]
21163 "TARGET_SSE && TARGET_64BIT"
21164 "cvtsi2ssq\t{%2, %0|%0, %2}"
21165 [(set_attr "type" "sseicvt")
21166 (set_attr "athlon_decode" "vector,double")
21167 (set_attr "mode" "SF")])
21168
21169 (define_insn "cvtss2si"
21170 [(set (match_operand:SI 0 "register_operand" "=r,r")
21171 (vec_select:SI
21172 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21173 (parallel [(const_int 0)])))]
21174 "TARGET_SSE"
21175 "cvtss2si\t{%1, %0|%0, %1}"
21176 [(set_attr "type" "sseicvt")
21177 (set_attr "athlon_decode" "double,vector")
21178 (set_attr "mode" "SI")])
21179
21180 (define_insn "cvtss2siq"
21181 [(set (match_operand:DI 0 "register_operand" "=r,r")
21182 (vec_select:DI
21183 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21184 (parallel [(const_int 0)])))]
21185 "TARGET_SSE"
21186 "cvtss2siq\t{%1, %0|%0, %1}"
21187 [(set_attr "type" "sseicvt")
21188 (set_attr "athlon_decode" "double,vector")
21189 (set_attr "mode" "DI")])
21190
21191 (define_insn "cvttss2si"
21192 [(set (match_operand:SI 0 "register_operand" "=r,r")
21193 (vec_select:SI
21194 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21195 UNSPEC_FIX)
21196 (parallel [(const_int 0)])))]
21197 "TARGET_SSE"
21198 "cvttss2si\t{%1, %0|%0, %1}"
21199 [(set_attr "type" "sseicvt")
21200 (set_attr "mode" "SF")
21201 (set_attr "athlon_decode" "double,vector")])
21202
21203 (define_insn "cvttss2siq"
21204 [(set (match_operand:DI 0 "register_operand" "=r,r")
21205 (vec_select:DI
21206 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21207 UNSPEC_FIX)
21208 (parallel [(const_int 0)])))]
21209 "TARGET_SSE && TARGET_64BIT"
21210 "cvttss2siq\t{%1, %0|%0, %1}"
21211 [(set_attr "type" "sseicvt")
21212 (set_attr "mode" "SF")
21213 (set_attr "athlon_decode" "double,vector")])
21214
21215
21216 ;; MMX insns
21217
21218 ;; MMX arithmetic
21219
21220 (define_insn "addv8qi3"
21221 [(set (match_operand:V8QI 0 "register_operand" "=y")
21222 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21223 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21224 "TARGET_MMX"
21225 "paddb\t{%2, %0|%0, %2}"
21226 [(set_attr "type" "mmxadd")
21227 (set_attr "mode" "DI")])
21228
21229 (define_insn "addv4hi3"
21230 [(set (match_operand:V4HI 0 "register_operand" "=y")
21231 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21232 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21233 "TARGET_MMX"
21234 "paddw\t{%2, %0|%0, %2}"
21235 [(set_attr "type" "mmxadd")
21236 (set_attr "mode" "DI")])
21237
21238 (define_insn "addv2si3"
21239 [(set (match_operand:V2SI 0 "register_operand" "=y")
21240 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21241 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21242 "TARGET_MMX"
21243 "paddd\t{%2, %0|%0, %2}"
21244 [(set_attr "type" "mmxadd")
21245 (set_attr "mode" "DI")])
21246
21247 (define_insn "mmx_adddi3"
21248 [(set (match_operand:DI 0 "register_operand" "=y")
21249 (unspec:DI
21250 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21251 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21252 UNSPEC_NOP))]
21253 "TARGET_MMX"
21254 "paddq\t{%2, %0|%0, %2}"
21255 [(set_attr "type" "mmxadd")
21256 (set_attr "mode" "DI")])
21257
21258 (define_insn "ssaddv8qi3"
21259 [(set (match_operand:V8QI 0 "register_operand" "=y")
21260 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21261 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21262 "TARGET_MMX"
21263 "paddsb\t{%2, %0|%0, %2}"
21264 [(set_attr "type" "mmxadd")
21265 (set_attr "mode" "DI")])
21266
21267 (define_insn "ssaddv4hi3"
21268 [(set (match_operand:V4HI 0 "register_operand" "=y")
21269 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21270 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21271 "TARGET_MMX"
21272 "paddsw\t{%2, %0|%0, %2}"
21273 [(set_attr "type" "mmxadd")
21274 (set_attr "mode" "DI")])
21275
21276 (define_insn "usaddv8qi3"
21277 [(set (match_operand:V8QI 0 "register_operand" "=y")
21278 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21279 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21280 "TARGET_MMX"
21281 "paddusb\t{%2, %0|%0, %2}"
21282 [(set_attr "type" "mmxadd")
21283 (set_attr "mode" "DI")])
21284
21285 (define_insn "usaddv4hi3"
21286 [(set (match_operand:V4HI 0 "register_operand" "=y")
21287 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21288 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21289 "TARGET_MMX"
21290 "paddusw\t{%2, %0|%0, %2}"
21291 [(set_attr "type" "mmxadd")
21292 (set_attr "mode" "DI")])
21293
21294 (define_insn "subv8qi3"
21295 [(set (match_operand:V8QI 0 "register_operand" "=y")
21296 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21297 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21298 "TARGET_MMX"
21299 "psubb\t{%2, %0|%0, %2}"
21300 [(set_attr "type" "mmxadd")
21301 (set_attr "mode" "DI")])
21302
21303 (define_insn "subv4hi3"
21304 [(set (match_operand:V4HI 0 "register_operand" "=y")
21305 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21306 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21307 "TARGET_MMX"
21308 "psubw\t{%2, %0|%0, %2}"
21309 [(set_attr "type" "mmxadd")
21310 (set_attr "mode" "DI")])
21311
21312 (define_insn "subv2si3"
21313 [(set (match_operand:V2SI 0 "register_operand" "=y")
21314 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21315 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21316 "TARGET_MMX"
21317 "psubd\t{%2, %0|%0, %2}"
21318 [(set_attr "type" "mmxadd")
21319 (set_attr "mode" "DI")])
21320
21321 (define_insn "mmx_subdi3"
21322 [(set (match_operand:DI 0 "register_operand" "=y")
21323 (unspec:DI
21324 [(minus:DI (match_operand:DI 1 "register_operand" "0")
21325 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21326 UNSPEC_NOP))]
21327 "TARGET_MMX"
21328 "psubq\t{%2, %0|%0, %2}"
21329 [(set_attr "type" "mmxadd")
21330 (set_attr "mode" "DI")])
21331
21332 (define_insn "sssubv8qi3"
21333 [(set (match_operand:V8QI 0 "register_operand" "=y")
21334 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21335 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21336 "TARGET_MMX"
21337 "psubsb\t{%2, %0|%0, %2}"
21338 [(set_attr "type" "mmxadd")
21339 (set_attr "mode" "DI")])
21340
21341 (define_insn "sssubv4hi3"
21342 [(set (match_operand:V4HI 0 "register_operand" "=y")
21343 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21344 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21345 "TARGET_MMX"
21346 "psubsw\t{%2, %0|%0, %2}"
21347 [(set_attr "type" "mmxadd")
21348 (set_attr "mode" "DI")])
21349
21350 (define_insn "ussubv8qi3"
21351 [(set (match_operand:V8QI 0 "register_operand" "=y")
21352 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21353 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21354 "TARGET_MMX"
21355 "psubusb\t{%2, %0|%0, %2}"
21356 [(set_attr "type" "mmxadd")
21357 (set_attr "mode" "DI")])
21358
21359 (define_insn "ussubv4hi3"
21360 [(set (match_operand:V4HI 0 "register_operand" "=y")
21361 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21362 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21363 "TARGET_MMX"
21364 "psubusw\t{%2, %0|%0, %2}"
21365 [(set_attr "type" "mmxadd")
21366 (set_attr "mode" "DI")])
21367
21368 (define_insn "mulv4hi3"
21369 [(set (match_operand:V4HI 0 "register_operand" "=y")
21370 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21371 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21372 "TARGET_MMX"
21373 "pmullw\t{%2, %0|%0, %2}"
21374 [(set_attr "type" "mmxmul")
21375 (set_attr "mode" "DI")])
21376
21377 (define_insn "smulv4hi3_highpart"
21378 [(set (match_operand:V4HI 0 "register_operand" "=y")
21379 (truncate:V4HI
21380 (lshiftrt:V4SI
21381 (mult:V4SI (sign_extend:V4SI
21382 (match_operand:V4HI 1 "register_operand" "0"))
21383 (sign_extend:V4SI
21384 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21385 (const_int 16))))]
21386 "TARGET_MMX"
21387 "pmulhw\t{%2, %0|%0, %2}"
21388 [(set_attr "type" "mmxmul")
21389 (set_attr "mode" "DI")])
21390
21391 (define_insn "umulv4hi3_highpart"
21392 [(set (match_operand:V4HI 0 "register_operand" "=y")
21393 (truncate:V4HI
21394 (lshiftrt:V4SI
21395 (mult:V4SI (zero_extend:V4SI
21396 (match_operand:V4HI 1 "register_operand" "0"))
21397 (zero_extend:V4SI
21398 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21399 (const_int 16))))]
21400 "TARGET_SSE || TARGET_3DNOW_A"
21401 "pmulhuw\t{%2, %0|%0, %2}"
21402 [(set_attr "type" "mmxmul")
21403 (set_attr "mode" "DI")])
21404
21405 (define_insn "mmx_pmaddwd"
21406 [(set (match_operand:V2SI 0 "register_operand" "=y")
21407 (plus:V2SI
21408 (mult:V2SI
21409 (sign_extend:V2SI
21410 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21411 (parallel [(const_int 0) (const_int 2)])))
21412 (sign_extend:V2SI
21413 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21414 (parallel [(const_int 0) (const_int 2)]))))
21415 (mult:V2SI
21416 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21417 (parallel [(const_int 1)
21418 (const_int 3)])))
21419 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21420 (parallel [(const_int 1)
21421 (const_int 3)]))))))]
21422 "TARGET_MMX"
21423 "pmaddwd\t{%2, %0|%0, %2}"
21424 [(set_attr "type" "mmxmul")
21425 (set_attr "mode" "DI")])
21426
21427
21428 ;; MMX logical operations
21429 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21430 ;; normal code that also wants to use the FPU from getting broken.
21431 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21432 (define_insn "mmx_iordi3"
21433 [(set (match_operand:DI 0 "register_operand" "=y")
21434 (unspec:DI
21435 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21436 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21437 UNSPEC_NOP))]
21438 "TARGET_MMX"
21439 "por\t{%2, %0|%0, %2}"
21440 [(set_attr "type" "mmxadd")
21441 (set_attr "mode" "DI")])
21442
21443 (define_insn "mmx_xordi3"
21444 [(set (match_operand:DI 0 "register_operand" "=y")
21445 (unspec:DI
21446 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21447 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21448 UNSPEC_NOP))]
21449 "TARGET_MMX"
21450 "pxor\t{%2, %0|%0, %2}"
21451 [(set_attr "type" "mmxadd")
21452 (set_attr "mode" "DI")
21453 (set_attr "memory" "none")])
21454
21455 ;; Same as pxor, but don't show input operands so that we don't think
21456 ;; they are live.
21457 (define_insn "mmx_clrdi"
21458 [(set (match_operand:DI 0 "register_operand" "=y")
21459 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21460 "TARGET_MMX"
21461 "pxor\t{%0, %0|%0, %0}"
21462 [(set_attr "type" "mmxadd")
21463 (set_attr "mode" "DI")
21464 (set_attr "memory" "none")])
21465
21466 (define_insn "mmx_anddi3"
21467 [(set (match_operand:DI 0 "register_operand" "=y")
21468 (unspec:DI
21469 [(and:DI (match_operand:DI 1 "register_operand" "%0")
21470 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21471 UNSPEC_NOP))]
21472 "TARGET_MMX"
21473 "pand\t{%2, %0|%0, %2}"
21474 [(set_attr "type" "mmxadd")
21475 (set_attr "mode" "DI")])
21476
21477 (define_insn "mmx_nanddi3"
21478 [(set (match_operand:DI 0 "register_operand" "=y")
21479 (unspec:DI
21480 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21481 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21482 UNSPEC_NOP))]
21483 "TARGET_MMX"
21484 "pandn\t{%2, %0|%0, %2}"
21485 [(set_attr "type" "mmxadd")
21486 (set_attr "mode" "DI")])
21487
21488
21489 ;; MMX unsigned averages/sum of absolute differences
21490
21491 (define_insn "mmx_uavgv8qi3"
21492 [(set (match_operand:V8QI 0 "register_operand" "=y")
21493 (ashiftrt:V8QI
21494 (plus:V8QI (plus:V8QI
21495 (match_operand:V8QI 1 "register_operand" "0")
21496 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21497 (const_vector:V8QI [(const_int 1)
21498 (const_int 1)
21499 (const_int 1)
21500 (const_int 1)
21501 (const_int 1)
21502 (const_int 1)
21503 (const_int 1)
21504 (const_int 1)]))
21505 (const_int 1)))]
21506 "TARGET_SSE || TARGET_3DNOW_A"
21507 "pavgb\t{%2, %0|%0, %2}"
21508 [(set_attr "type" "mmxshft")
21509 (set_attr "mode" "DI")])
21510
21511 (define_insn "mmx_uavgv4hi3"
21512 [(set (match_operand:V4HI 0 "register_operand" "=y")
21513 (ashiftrt:V4HI
21514 (plus:V4HI (plus:V4HI
21515 (match_operand:V4HI 1 "register_operand" "0")
21516 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21517 (const_vector:V4HI [(const_int 1)
21518 (const_int 1)
21519 (const_int 1)
21520 (const_int 1)]))
21521 (const_int 1)))]
21522 "TARGET_SSE || TARGET_3DNOW_A"
21523 "pavgw\t{%2, %0|%0, %2}"
21524 [(set_attr "type" "mmxshft")
21525 (set_attr "mode" "DI")])
21526
21527 (define_insn "mmx_psadbw"
21528 [(set (match_operand:DI 0 "register_operand" "=y")
21529 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21530 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21531 UNSPEC_PSADBW))]
21532 "TARGET_SSE || TARGET_3DNOW_A"
21533 "psadbw\t{%2, %0|%0, %2}"
21534 [(set_attr "type" "mmxshft")
21535 (set_attr "mode" "DI")])
21536
21537
21538 ;; MMX insert/extract/shuffle
21539
21540 (define_expand "mmx_pinsrw"
21541 [(set (match_operand:V4HI 0 "register_operand" "")
21542 (vec_merge:V4HI
21543 (match_operand:V4HI 1 "register_operand" "")
21544 (vec_duplicate:V4HI
21545 (match_operand:SI 2 "nonimmediate_operand" ""))
21546 (match_operand:SI 3 "const_0_to_3_operand" "")))]
21547 "TARGET_SSE || TARGET_3DNOW_A"
21548 {
21549 operands[2] = gen_lowpart (HImode, operands[2]);
21550 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
21551 })
21552
21553 (define_insn "*mmx_pinsrw"
21554 [(set (match_operand:V4HI 0 "register_operand" "=y")
21555 (vec_merge:V4HI
21556 (match_operand:V4HI 1 "register_operand" "0")
21557 (vec_duplicate:V4HI
21558 (match_operand:HI 2 "nonimmediate_operand" "rm"))
21559 (match_operand:SI 3 "const_pow2_1_to_8_operand" "N")))]
21560 "TARGET_SSE || TARGET_3DNOW_A"
21561 {
21562 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
21563 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
21564 }
21565 [(set_attr "type" "mmxcvt")
21566 (set_attr "mode" "DI")])
21567
21568 (define_insn "mmx_pextrw"
21569 [(set (match_operand:SI 0 "register_operand" "=r")
21570 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21571 (parallel
21572 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21573 "TARGET_SSE || TARGET_3DNOW_A"
21574 "pextrw\t{%2, %1, %0|%0, %1, %2}"
21575 [(set_attr "type" "mmxcvt")
21576 (set_attr "mode" "DI")])
21577
21578 (define_insn "mmx_pshufw"
21579 [(set (match_operand:V4HI 0 "register_operand" "=y")
21580 (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21581 (match_operand:SI 2 "immediate_operand" "i")]
21582 UNSPEC_SHUFFLE))]
21583 "TARGET_SSE || TARGET_3DNOW_A"
21584 "pshufw\t{%2, %1, %0|%0, %1, %2}"
21585 [(set_attr "type" "mmxcvt")
21586 (set_attr "mode" "DI")])
21587
21588
21589 ;; MMX mask-generating comparisons
21590
21591 (define_insn "eqv8qi3"
21592 [(set (match_operand:V8QI 0 "register_operand" "=y")
21593 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21594 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21595 "TARGET_MMX"
21596 "pcmpeqb\t{%2, %0|%0, %2}"
21597 [(set_attr "type" "mmxcmp")
21598 (set_attr "mode" "DI")])
21599
21600 (define_insn "eqv4hi3"
21601 [(set (match_operand:V4HI 0 "register_operand" "=y")
21602 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21603 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21604 "TARGET_MMX"
21605 "pcmpeqw\t{%2, %0|%0, %2}"
21606 [(set_attr "type" "mmxcmp")
21607 (set_attr "mode" "DI")])
21608
21609 (define_insn "eqv2si3"
21610 [(set (match_operand:V2SI 0 "register_operand" "=y")
21611 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21612 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21613 "TARGET_MMX"
21614 "pcmpeqd\t{%2, %0|%0, %2}"
21615 [(set_attr "type" "mmxcmp")
21616 (set_attr "mode" "DI")])
21617
21618 (define_insn "gtv8qi3"
21619 [(set (match_operand:V8QI 0 "register_operand" "=y")
21620 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21621 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21622 "TARGET_MMX"
21623 "pcmpgtb\t{%2, %0|%0, %2}"
21624 [(set_attr "type" "mmxcmp")
21625 (set_attr "mode" "DI")])
21626
21627 (define_insn "gtv4hi3"
21628 [(set (match_operand:V4HI 0 "register_operand" "=y")
21629 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21630 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21631 "TARGET_MMX"
21632 "pcmpgtw\t{%2, %0|%0, %2}"
21633 [(set_attr "type" "mmxcmp")
21634 (set_attr "mode" "DI")])
21635
21636 (define_insn "gtv2si3"
21637 [(set (match_operand:V2SI 0 "register_operand" "=y")
21638 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21639 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21640 "TARGET_MMX"
21641 "pcmpgtd\t{%2, %0|%0, %2}"
21642 [(set_attr "type" "mmxcmp")
21643 (set_attr "mode" "DI")])
21644
21645
21646 ;; MMX max/min insns
21647
21648 (define_insn "umaxv8qi3"
21649 [(set (match_operand:V8QI 0 "register_operand" "=y")
21650 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21651 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21652 "TARGET_SSE || TARGET_3DNOW_A"
21653 "pmaxub\t{%2, %0|%0, %2}"
21654 [(set_attr "type" "mmxadd")
21655 (set_attr "mode" "DI")])
21656
21657 (define_insn "smaxv4hi3"
21658 [(set (match_operand:V4HI 0 "register_operand" "=y")
21659 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21660 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21661 "TARGET_SSE || TARGET_3DNOW_A"
21662 "pmaxsw\t{%2, %0|%0, %2}"
21663 [(set_attr "type" "mmxadd")
21664 (set_attr "mode" "DI")])
21665
21666 (define_insn "uminv8qi3"
21667 [(set (match_operand:V8QI 0 "register_operand" "=y")
21668 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21669 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21670 "TARGET_SSE || TARGET_3DNOW_A"
21671 "pminub\t{%2, %0|%0, %2}"
21672 [(set_attr "type" "mmxadd")
21673 (set_attr "mode" "DI")])
21674
21675 (define_insn "sminv4hi3"
21676 [(set (match_operand:V4HI 0 "register_operand" "=y")
21677 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21678 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21679 "TARGET_SSE || TARGET_3DNOW_A"
21680 "pminsw\t{%2, %0|%0, %2}"
21681 [(set_attr "type" "mmxadd")
21682 (set_attr "mode" "DI")])
21683
21684
21685 ;; MMX shifts
21686
21687 (define_insn "ashrv4hi3"
21688 [(set (match_operand:V4HI 0 "register_operand" "=y")
21689 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21690 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21691 "TARGET_MMX"
21692 "psraw\t{%2, %0|%0, %2}"
21693 [(set_attr "type" "mmxshft")
21694 (set_attr "mode" "DI")])
21695
21696 (define_insn "ashrv2si3"
21697 [(set (match_operand:V2SI 0 "register_operand" "=y")
21698 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21699 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21700 "TARGET_MMX"
21701 "psrad\t{%2, %0|%0, %2}"
21702 [(set_attr "type" "mmxshft")
21703 (set_attr "mode" "DI")])
21704
21705 (define_insn "lshrv4hi3"
21706 [(set (match_operand:V4HI 0 "register_operand" "=y")
21707 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21708 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21709 "TARGET_MMX"
21710 "psrlw\t{%2, %0|%0, %2}"
21711 [(set_attr "type" "mmxshft")
21712 (set_attr "mode" "DI")])
21713
21714 (define_insn "lshrv2si3"
21715 [(set (match_operand:V2SI 0 "register_operand" "=y")
21716 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21717 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21718 "TARGET_MMX"
21719 "psrld\t{%2, %0|%0, %2}"
21720 [(set_attr "type" "mmxshft")
21721 (set_attr "mode" "DI")])
21722
21723 ;; See logical MMX insns.
21724 (define_insn "mmx_lshrdi3"
21725 [(set (match_operand:DI 0 "register_operand" "=y")
21726 (unspec:DI
21727 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21728 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21729 UNSPEC_NOP))]
21730 "TARGET_MMX"
21731 "psrlq\t{%2, %0|%0, %2}"
21732 [(set_attr "type" "mmxshft")
21733 (set_attr "mode" "DI")])
21734
21735 (define_insn "ashlv4hi3"
21736 [(set (match_operand:V4HI 0 "register_operand" "=y")
21737 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21738 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21739 "TARGET_MMX"
21740 "psllw\t{%2, %0|%0, %2}"
21741 [(set_attr "type" "mmxshft")
21742 (set_attr "mode" "DI")])
21743
21744 (define_insn "ashlv2si3"
21745 [(set (match_operand:V2SI 0 "register_operand" "=y")
21746 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21747 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21748 "TARGET_MMX"
21749 "pslld\t{%2, %0|%0, %2}"
21750 [(set_attr "type" "mmxshft")
21751 (set_attr "mode" "DI")])
21752
21753 ;; See logical MMX insns.
21754 (define_insn "mmx_ashldi3"
21755 [(set (match_operand:DI 0 "register_operand" "=y")
21756 (unspec:DI
21757 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21758 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21759 UNSPEC_NOP))]
21760 "TARGET_MMX"
21761 "psllq\t{%2, %0|%0, %2}"
21762 [(set_attr "type" "mmxshft")
21763 (set_attr "mode" "DI")])
21764
21765
21766 ;; MMX pack/unpack insns.
21767
21768 (define_insn "mmx_packsswb"
21769 [(set (match_operand:V8QI 0 "register_operand" "=y")
21770 (vec_concat:V8QI
21771 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21772 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21773 "TARGET_MMX"
21774 "packsswb\t{%2, %0|%0, %2}"
21775 [(set_attr "type" "mmxshft")
21776 (set_attr "mode" "DI")])
21777
21778 (define_insn "mmx_packssdw"
21779 [(set (match_operand:V4HI 0 "register_operand" "=y")
21780 (vec_concat:V4HI
21781 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21782 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21783 "TARGET_MMX"
21784 "packssdw\t{%2, %0|%0, %2}"
21785 [(set_attr "type" "mmxshft")
21786 (set_attr "mode" "DI")])
21787
21788 (define_insn "mmx_packuswb"
21789 [(set (match_operand:V8QI 0 "register_operand" "=y")
21790 (vec_concat:V8QI
21791 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21792 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21793 "TARGET_MMX"
21794 "packuswb\t{%2, %0|%0, %2}"
21795 [(set_attr "type" "mmxshft")
21796 (set_attr "mode" "DI")])
21797
21798 (define_insn "mmx_punpckhbw"
21799 [(set (match_operand:V8QI 0 "register_operand" "=y")
21800 (vec_merge:V8QI
21801 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21802 (parallel [(const_int 4)
21803 (const_int 0)
21804 (const_int 5)
21805 (const_int 1)
21806 (const_int 6)
21807 (const_int 2)
21808 (const_int 7)
21809 (const_int 3)]))
21810 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21811 (parallel [(const_int 0)
21812 (const_int 4)
21813 (const_int 1)
21814 (const_int 5)
21815 (const_int 2)
21816 (const_int 6)
21817 (const_int 3)
21818 (const_int 7)]))
21819 (const_int 85)))]
21820 "TARGET_MMX"
21821 "punpckhbw\t{%2, %0|%0, %2}"
21822 [(set_attr "type" "mmxcvt")
21823 (set_attr "mode" "DI")])
21824
21825 (define_insn "mmx_punpckhwd"
21826 [(set (match_operand:V4HI 0 "register_operand" "=y")
21827 (vec_merge:V4HI
21828 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21829 (parallel [(const_int 0)
21830 (const_int 2)
21831 (const_int 1)
21832 (const_int 3)]))
21833 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21834 (parallel [(const_int 2)
21835 (const_int 0)
21836 (const_int 3)
21837 (const_int 1)]))
21838 (const_int 5)))]
21839 "TARGET_MMX"
21840 "punpckhwd\t{%2, %0|%0, %2}"
21841 [(set_attr "type" "mmxcvt")
21842 (set_attr "mode" "DI")])
21843
21844 (define_insn "mmx_punpckhdq"
21845 [(set (match_operand:V2SI 0 "register_operand" "=y")
21846 (vec_merge:V2SI
21847 (match_operand:V2SI 1 "register_operand" "0")
21848 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21849 (parallel [(const_int 1)
21850 (const_int 0)]))
21851 (const_int 1)))]
21852 "TARGET_MMX"
21853 "punpckhdq\t{%2, %0|%0, %2}"
21854 [(set_attr "type" "mmxcvt")
21855 (set_attr "mode" "DI")])
21856
21857 (define_insn "mmx_punpcklbw"
21858 [(set (match_operand:V8QI 0 "register_operand" "=y")
21859 (vec_merge:V8QI
21860 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21861 (parallel [(const_int 0)
21862 (const_int 4)
21863 (const_int 1)
21864 (const_int 5)
21865 (const_int 2)
21866 (const_int 6)
21867 (const_int 3)
21868 (const_int 7)]))
21869 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21870 (parallel [(const_int 4)
21871 (const_int 0)
21872 (const_int 5)
21873 (const_int 1)
21874 (const_int 6)
21875 (const_int 2)
21876 (const_int 7)
21877 (const_int 3)]))
21878 (const_int 85)))]
21879 "TARGET_MMX"
21880 "punpcklbw\t{%2, %0|%0, %2}"
21881 [(set_attr "type" "mmxcvt")
21882 (set_attr "mode" "DI")])
21883
21884 (define_insn "mmx_punpcklwd"
21885 [(set (match_operand:V4HI 0 "register_operand" "=y")
21886 (vec_merge:V4HI
21887 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21888 (parallel [(const_int 2)
21889 (const_int 0)
21890 (const_int 3)
21891 (const_int 1)]))
21892 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21893 (parallel [(const_int 0)
21894 (const_int 2)
21895 (const_int 1)
21896 (const_int 3)]))
21897 (const_int 5)))]
21898 "TARGET_MMX"
21899 "punpcklwd\t{%2, %0|%0, %2}"
21900 [(set_attr "type" "mmxcvt")
21901 (set_attr "mode" "DI")])
21902
21903 (define_insn "mmx_punpckldq"
21904 [(set (match_operand:V2SI 0 "register_operand" "=y")
21905 (vec_merge:V2SI
21906 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21907 (parallel [(const_int 1)
21908 (const_int 0)]))
21909 (match_operand:V2SI 2 "register_operand" "y")
21910 (const_int 1)))]
21911 "TARGET_MMX"
21912 "punpckldq\t{%2, %0|%0, %2}"
21913 [(set_attr "type" "mmxcvt")
21914 (set_attr "mode" "DI")])
21915
21916
21917 ;; Miscellaneous stuff
21918
21919 (define_insn "emms"
21920 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21921 (clobber (reg:XF 8))
21922 (clobber (reg:XF 9))
21923 (clobber (reg:XF 10))
21924 (clobber (reg:XF 11))
21925 (clobber (reg:XF 12))
21926 (clobber (reg:XF 13))
21927 (clobber (reg:XF 14))
21928 (clobber (reg:XF 15))
21929 (clobber (reg:DI 29))
21930 (clobber (reg:DI 30))
21931 (clobber (reg:DI 31))
21932 (clobber (reg:DI 32))
21933 (clobber (reg:DI 33))
21934 (clobber (reg:DI 34))
21935 (clobber (reg:DI 35))
21936 (clobber (reg:DI 36))]
21937 "TARGET_MMX"
21938 "emms"
21939 [(set_attr "type" "mmx")
21940 (set_attr "memory" "unknown")])
21941
21942 (define_insn "ldmxcsr"
21943 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21944 UNSPECV_LDMXCSR)]
21945 "TARGET_SSE"
21946 "ldmxcsr\t%0"
21947 [(set_attr "type" "sse")
21948 (set_attr "memory" "load")])
21949
21950 (define_insn "stmxcsr"
21951 [(set (match_operand:SI 0 "memory_operand" "=m")
21952 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21953 "TARGET_SSE"
21954 "stmxcsr\t%0"
21955 [(set_attr "type" "sse")
21956 (set_attr "memory" "store")])
21957
21958 (define_expand "sfence"
21959 [(set (match_dup 0)
21960 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21961 "TARGET_SSE || TARGET_3DNOW_A"
21962 {
21963 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21964 MEM_VOLATILE_P (operands[0]) = 1;
21965 })
21966
21967 (define_insn "*sfence_insn"
21968 [(set (match_operand:BLK 0 "" "")
21969 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21970 "TARGET_SSE || TARGET_3DNOW_A"
21971 "sfence"
21972 [(set_attr "type" "sse")
21973 (set_attr "memory" "unknown")])
21974
21975 (define_expand "sse_prologue_save"
21976 [(parallel [(set (match_operand:BLK 0 "" "")
21977 (unspec:BLK [(reg:DI 21)
21978 (reg:DI 22)
21979 (reg:DI 23)
21980 (reg:DI 24)
21981 (reg:DI 25)
21982 (reg:DI 26)
21983 (reg:DI 27)
21984 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21985 (use (match_operand:DI 1 "register_operand" ""))
21986 (use (match_operand:DI 2 "immediate_operand" ""))
21987 (use (label_ref:DI (match_operand 3 "" "")))])]
21988 "TARGET_64BIT"
21989 "")
21990
21991 (define_insn "*sse_prologue_save_insn"
21992 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21993 (match_operand:DI 4 "const_int_operand" "n")))
21994 (unspec:BLK [(reg:DI 21)
21995 (reg:DI 22)
21996 (reg:DI 23)
21997 (reg:DI 24)
21998 (reg:DI 25)
21999 (reg:DI 26)
22000 (reg:DI 27)
22001 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22002 (use (match_operand:DI 1 "register_operand" "r"))
22003 (use (match_operand:DI 2 "const_int_operand" "i"))
22004 (use (label_ref:DI (match_operand 3 "" "X")))]
22005 "TARGET_64BIT
22006 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22007 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22008 "*
22009 {
22010 int i;
22011 operands[0] = gen_rtx_MEM (Pmode,
22012 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22013 output_asm_insn (\"jmp\\t%A1\", operands);
22014 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22015 {
22016 operands[4] = adjust_address (operands[0], DImode, i*16);
22017 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22018 PUT_MODE (operands[4], TImode);
22019 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22020 output_asm_insn (\"rex\", operands);
22021 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22022 }
22023 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22024 CODE_LABEL_NUMBER (operands[3]));
22025 RET;
22026 }
22027 "
22028 [(set_attr "type" "other")
22029 (set_attr "length_immediate" "0")
22030 (set_attr "length_address" "0")
22031 (set_attr "length" "135")
22032 (set_attr "memory" "store")
22033 (set_attr "modrm" "0")
22034 (set_attr "mode" "DI")])
22035
22036 ;; 3Dnow! instructions
22037
22038 (define_insn "addv2sf3"
22039 [(set (match_operand:V2SF 0 "register_operand" "=y")
22040 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22041 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22042 "TARGET_3DNOW"
22043 "pfadd\\t{%2, %0|%0, %2}"
22044 [(set_attr "type" "mmxadd")
22045 (set_attr "mode" "V2SF")])
22046
22047 (define_insn "subv2sf3"
22048 [(set (match_operand:V2SF 0 "register_operand" "=y")
22049 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22050 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22051 "TARGET_3DNOW"
22052 "pfsub\\t{%2, %0|%0, %2}"
22053 [(set_attr "type" "mmxadd")
22054 (set_attr "mode" "V2SF")])
22055
22056 (define_insn "subrv2sf3"
22057 [(set (match_operand:V2SF 0 "register_operand" "=y")
22058 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22059 (match_operand:V2SF 1 "register_operand" "0")))]
22060 "TARGET_3DNOW"
22061 "pfsubr\\t{%2, %0|%0, %2}"
22062 [(set_attr "type" "mmxadd")
22063 (set_attr "mode" "V2SF")])
22064
22065 (define_insn "gtv2sf3"
22066 [(set (match_operand:V2SI 0 "register_operand" "=y")
22067 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22068 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22069 "TARGET_3DNOW"
22070 "pfcmpgt\\t{%2, %0|%0, %2}"
22071 [(set_attr "type" "mmxcmp")
22072 (set_attr "mode" "V2SF")])
22073
22074 (define_insn "gev2sf3"
22075 [(set (match_operand:V2SI 0 "register_operand" "=y")
22076 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22077 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22078 "TARGET_3DNOW"
22079 "pfcmpge\\t{%2, %0|%0, %2}"
22080 [(set_attr "type" "mmxcmp")
22081 (set_attr "mode" "V2SF")])
22082
22083 (define_insn "eqv2sf3"
22084 [(set (match_operand:V2SI 0 "register_operand" "=y")
22085 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22086 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22087 "TARGET_3DNOW"
22088 "pfcmpeq\\t{%2, %0|%0, %2}"
22089 [(set_attr "type" "mmxcmp")
22090 (set_attr "mode" "V2SF")])
22091
22092 (define_insn "pfmaxv2sf3"
22093 [(set (match_operand:V2SF 0 "register_operand" "=y")
22094 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22095 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22096 "TARGET_3DNOW"
22097 "pfmax\\t{%2, %0|%0, %2}"
22098 [(set_attr "type" "mmxadd")
22099 (set_attr "mode" "V2SF")])
22100
22101 (define_insn "pfminv2sf3"
22102 [(set (match_operand:V2SF 0 "register_operand" "=y")
22103 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22104 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22105 "TARGET_3DNOW"
22106 "pfmin\\t{%2, %0|%0, %2}"
22107 [(set_attr "type" "mmxadd")
22108 (set_attr "mode" "V2SF")])
22109
22110 (define_insn "mulv2sf3"
22111 [(set (match_operand:V2SF 0 "register_operand" "=y")
22112 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22113 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22114 "TARGET_3DNOW"
22115 "pfmul\\t{%2, %0|%0, %2}"
22116 [(set_attr "type" "mmxmul")
22117 (set_attr "mode" "V2SF")])
22118
22119 (define_insn "femms"
22120 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22121 (clobber (reg:XF 8))
22122 (clobber (reg:XF 9))
22123 (clobber (reg:XF 10))
22124 (clobber (reg:XF 11))
22125 (clobber (reg:XF 12))
22126 (clobber (reg:XF 13))
22127 (clobber (reg:XF 14))
22128 (clobber (reg:XF 15))
22129 (clobber (reg:DI 29))
22130 (clobber (reg:DI 30))
22131 (clobber (reg:DI 31))
22132 (clobber (reg:DI 32))
22133 (clobber (reg:DI 33))
22134 (clobber (reg:DI 34))
22135 (clobber (reg:DI 35))
22136 (clobber (reg:DI 36))]
22137 "TARGET_3DNOW"
22138 "femms"
22139 [(set_attr "type" "mmx")
22140 (set_attr "memory" "none")])
22141
22142 (define_insn "pf2id"
22143 [(set (match_operand:V2SI 0 "register_operand" "=y")
22144 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22145 "TARGET_3DNOW"
22146 "pf2id\\t{%1, %0|%0, %1}"
22147 [(set_attr "type" "mmxcvt")
22148 (set_attr "mode" "V2SF")])
22149
22150 (define_insn "pf2iw"
22151 [(set (match_operand:V2SI 0 "register_operand" "=y")
22152 (sign_extend:V2SI
22153 (ss_truncate:V2HI
22154 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22155 "TARGET_3DNOW_A"
22156 "pf2iw\\t{%1, %0|%0, %1}"
22157 [(set_attr "type" "mmxcvt")
22158 (set_attr "mode" "V2SF")])
22159
22160 (define_insn "pfacc"
22161 [(set (match_operand:V2SF 0 "register_operand" "=y")
22162 (vec_concat:V2SF
22163 (plus:SF
22164 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22165 (parallel [(const_int 0)]))
22166 (vec_select:SF (match_dup 1)
22167 (parallel [(const_int 1)])))
22168 (plus:SF
22169 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22170 (parallel [(const_int 0)]))
22171 (vec_select:SF (match_dup 2)
22172 (parallel [(const_int 1)])))))]
22173 "TARGET_3DNOW"
22174 "pfacc\\t{%2, %0|%0, %2}"
22175 [(set_attr "type" "mmxadd")
22176 (set_attr "mode" "V2SF")])
22177
22178 (define_insn "pfnacc"
22179 [(set (match_operand:V2SF 0 "register_operand" "=y")
22180 (vec_concat:V2SF
22181 (minus:SF
22182 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22183 (parallel [(const_int 0)]))
22184 (vec_select:SF (match_dup 1)
22185 (parallel [(const_int 1)])))
22186 (minus:SF
22187 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22188 (parallel [(const_int 0)]))
22189 (vec_select:SF (match_dup 2)
22190 (parallel [(const_int 1)])))))]
22191 "TARGET_3DNOW_A"
22192 "pfnacc\\t{%2, %0|%0, %2}"
22193 [(set_attr "type" "mmxadd")
22194 (set_attr "mode" "V2SF")])
22195
22196 (define_insn "pfpnacc"
22197 [(set (match_operand:V2SF 0 "register_operand" "=y")
22198 (vec_concat:V2SF
22199 (minus:SF
22200 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22201 (parallel [(const_int 0)]))
22202 (vec_select:SF (match_dup 1)
22203 (parallel [(const_int 1)])))
22204 (plus:SF
22205 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22206 (parallel [(const_int 0)]))
22207 (vec_select:SF (match_dup 2)
22208 (parallel [(const_int 1)])))))]
22209 "TARGET_3DNOW_A"
22210 "pfpnacc\\t{%2, %0|%0, %2}"
22211 [(set_attr "type" "mmxadd")
22212 (set_attr "mode" "V2SF")])
22213
22214 (define_insn "pi2fw"
22215 [(set (match_operand:V2SF 0 "register_operand" "=y")
22216 (float:V2SF
22217 (vec_concat:V2SI
22218 (sign_extend:SI
22219 (truncate:HI
22220 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22221 (parallel [(const_int 0)]))))
22222 (sign_extend:SI
22223 (truncate:HI
22224 (vec_select:SI (match_dup 1)
22225 (parallel [(const_int 1)])))))))]
22226 "TARGET_3DNOW_A"
22227 "pi2fw\\t{%1, %0|%0, %1}"
22228 [(set_attr "type" "mmxcvt")
22229 (set_attr "mode" "V2SF")])
22230
22231 (define_insn "floatv2si2"
22232 [(set (match_operand:V2SF 0 "register_operand" "=y")
22233 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22234 "TARGET_3DNOW"
22235 "pi2fd\\t{%1, %0|%0, %1}"
22236 [(set_attr "type" "mmxcvt")
22237 (set_attr "mode" "V2SF")])
22238
22239 ;; This insn is identical to pavgb in operation, but the opcode is
22240 ;; different. To avoid accidentally matching pavgb, use an unspec.
22241
22242 (define_insn "pavgusb"
22243 [(set (match_operand:V8QI 0 "register_operand" "=y")
22244 (unspec:V8QI
22245 [(match_operand:V8QI 1 "register_operand" "0")
22246 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22247 UNSPEC_PAVGUSB))]
22248 "TARGET_3DNOW"
22249 "pavgusb\\t{%2, %0|%0, %2}"
22250 [(set_attr "type" "mmxshft")
22251 (set_attr "mode" "TI")])
22252
22253 ;; 3DNow reciprocal and sqrt
22254
22255 (define_insn "pfrcpv2sf2"
22256 [(set (match_operand:V2SF 0 "register_operand" "=y")
22257 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22258 UNSPEC_PFRCP))]
22259 "TARGET_3DNOW"
22260 "pfrcp\\t{%1, %0|%0, %1}"
22261 [(set_attr "type" "mmx")
22262 (set_attr "mode" "TI")])
22263
22264 (define_insn "pfrcpit1v2sf3"
22265 [(set (match_operand:V2SF 0 "register_operand" "=y")
22266 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22267 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22268 UNSPEC_PFRCPIT1))]
22269 "TARGET_3DNOW"
22270 "pfrcpit1\\t{%2, %0|%0, %2}"
22271 [(set_attr "type" "mmx")
22272 (set_attr "mode" "TI")])
22273
22274 (define_insn "pfrcpit2v2sf3"
22275 [(set (match_operand:V2SF 0 "register_operand" "=y")
22276 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22277 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22278 UNSPEC_PFRCPIT2))]
22279 "TARGET_3DNOW"
22280 "pfrcpit2\\t{%2, %0|%0, %2}"
22281 [(set_attr "type" "mmx")
22282 (set_attr "mode" "TI")])
22283
22284 (define_insn "pfrsqrtv2sf2"
22285 [(set (match_operand:V2SF 0 "register_operand" "=y")
22286 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22287 UNSPEC_PFRSQRT))]
22288 "TARGET_3DNOW"
22289 "pfrsqrt\\t{%1, %0|%0, %1}"
22290 [(set_attr "type" "mmx")
22291 (set_attr "mode" "TI")])
22292
22293 (define_insn "pfrsqit1v2sf3"
22294 [(set (match_operand:V2SF 0 "register_operand" "=y")
22295 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22296 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22297 UNSPEC_PFRSQIT1))]
22298 "TARGET_3DNOW"
22299 "pfrsqit1\\t{%2, %0|%0, %2}"
22300 [(set_attr "type" "mmx")
22301 (set_attr "mode" "TI")])
22302
22303 (define_insn "pmulhrwv4hi3"
22304 [(set (match_operand:V4HI 0 "register_operand" "=y")
22305 (truncate:V4HI
22306 (lshiftrt:V4SI
22307 (plus:V4SI
22308 (mult:V4SI
22309 (sign_extend:V4SI
22310 (match_operand:V4HI 1 "register_operand" "0"))
22311 (sign_extend:V4SI
22312 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22313 (const_vector:V4SI [(const_int 32768)
22314 (const_int 32768)
22315 (const_int 32768)
22316 (const_int 32768)]))
22317 (const_int 16))))]
22318 "TARGET_3DNOW"
22319 "pmulhrw\\t{%2, %0|%0, %2}"
22320 [(set_attr "type" "mmxmul")
22321 (set_attr "mode" "TI")])
22322
22323 (define_insn "pswapdv2si2"
22324 [(set (match_operand:V2SI 0 "register_operand" "=y")
22325 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22326 (parallel [(const_int 1) (const_int 0)])))]
22327 "TARGET_3DNOW_A"
22328 "pswapd\\t{%1, %0|%0, %1}"
22329 [(set_attr "type" "mmxcvt")
22330 (set_attr "mode" "TI")])
22331
22332 (define_insn "pswapdv2sf2"
22333 [(set (match_operand:V2SF 0 "register_operand" "=y")
22334 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22335 (parallel [(const_int 1) (const_int 0)])))]
22336 "TARGET_3DNOW_A"
22337 "pswapd\\t{%1, %0|%0, %1}"
22338 [(set_attr "type" "mmxcvt")
22339 (set_attr "mode" "TI")])
22340
22341 (define_expand "prefetch"
22342 [(prefetch (match_operand 0 "address_operand" "")
22343 (match_operand:SI 1 "const_int_operand" "")
22344 (match_operand:SI 2 "const_int_operand" ""))]
22345 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22346 {
22347 int rw = INTVAL (operands[1]);
22348 int locality = INTVAL (operands[2]);
22349
22350 if (rw != 0 && rw != 1)
22351 abort ();
22352 if (locality < 0 || locality > 3)
22353 abort ();
22354 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22355 abort ();
22356
22357 /* Use 3dNOW prefetch in case we are asking for write prefetch not
22358 suported by SSE counterpart or the SSE prefetch is not available
22359 (K6 machines). Otherwise use SSE prefetch as it allows specifying
22360 of locality. */
22361 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22362 operands[2] = GEN_INT (3);
22363 else
22364 operands[1] = const0_rtx;
22365 })
22366
22367 (define_insn "*prefetch_sse"
22368 [(prefetch (match_operand:SI 0 "address_operand" "p")
22369 (const_int 0)
22370 (match_operand:SI 1 "const_int_operand" ""))]
22371 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22372 {
22373 static const char * const patterns[4] = {
22374 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22375 };
22376
22377 int locality = INTVAL (operands[1]);
22378 if (locality < 0 || locality > 3)
22379 abort ();
22380
22381 return patterns[locality];
22382 }
22383 [(set_attr "type" "sse")
22384 (set_attr "memory" "none")])
22385
22386 (define_insn "*prefetch_sse_rex"
22387 [(prefetch (match_operand:DI 0 "address_operand" "p")
22388 (const_int 0)
22389 (match_operand:SI 1 "const_int_operand" ""))]
22390 "TARGET_PREFETCH_SSE && TARGET_64BIT"
22391 {
22392 static const char * const patterns[4] = {
22393 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22394 };
22395
22396 int locality = INTVAL (operands[1]);
22397 if (locality < 0 || locality > 3)
22398 abort ();
22399
22400 return patterns[locality];
22401 }
22402 [(set_attr "type" "sse")
22403 (set_attr "memory" "none")])
22404
22405 (define_insn "*prefetch_3dnow"
22406 [(prefetch (match_operand:SI 0 "address_operand" "p")
22407 (match_operand:SI 1 "const_int_operand" "n")
22408 (const_int 3))]
22409 "TARGET_3DNOW && !TARGET_64BIT"
22410 {
22411 if (INTVAL (operands[1]) == 0)
22412 return "prefetch\t%a0";
22413 else
22414 return "prefetchw\t%a0";
22415 }
22416 [(set_attr "type" "mmx")
22417 (set_attr "memory" "none")])
22418
22419 (define_insn "*prefetch_3dnow_rex"
22420 [(prefetch (match_operand:DI 0 "address_operand" "p")
22421 (match_operand:SI 1 "const_int_operand" "n")
22422 (const_int 3))]
22423 "TARGET_3DNOW && TARGET_64BIT"
22424 {
22425 if (INTVAL (operands[1]) == 0)
22426 return "prefetch\t%a0";
22427 else
22428 return "prefetchw\t%a0";
22429 }
22430 [(set_attr "type" "mmx")
22431 (set_attr "memory" "none")])
22432
22433 ;; SSE2 support
22434
22435 (define_insn "addv2df3"
22436 [(set (match_operand:V2DF 0 "register_operand" "=x")
22437 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22438 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22439 "TARGET_SSE2"
22440 "addpd\t{%2, %0|%0, %2}"
22441 [(set_attr "type" "sseadd")
22442 (set_attr "mode" "V2DF")])
22443
22444 (define_insn "vmaddv2df3"
22445 [(set (match_operand:V2DF 0 "register_operand" "=x")
22446 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22447 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22448 (match_dup 1)
22449 (const_int 1)))]
22450 "TARGET_SSE2"
22451 "addsd\t{%2, %0|%0, %2}"
22452 [(set_attr "type" "sseadd")
22453 (set_attr "mode" "DF")])
22454
22455 (define_insn "subv2df3"
22456 [(set (match_operand:V2DF 0 "register_operand" "=x")
22457 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22458 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22459 "TARGET_SSE2"
22460 "subpd\t{%2, %0|%0, %2}"
22461 [(set_attr "type" "sseadd")
22462 (set_attr "mode" "V2DF")])
22463
22464 (define_insn "vmsubv2df3"
22465 [(set (match_operand:V2DF 0 "register_operand" "=x")
22466 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22467 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22468 (match_dup 1)
22469 (const_int 1)))]
22470 "TARGET_SSE2"
22471 "subsd\t{%2, %0|%0, %2}"
22472 [(set_attr "type" "sseadd")
22473 (set_attr "mode" "DF")])
22474
22475 (define_insn "mulv2df3"
22476 [(set (match_operand:V2DF 0 "register_operand" "=x")
22477 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22478 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22479 "TARGET_SSE2"
22480 "mulpd\t{%2, %0|%0, %2}"
22481 [(set_attr "type" "ssemul")
22482 (set_attr "mode" "V2DF")])
22483
22484 (define_insn "vmmulv2df3"
22485 [(set (match_operand:V2DF 0 "register_operand" "=x")
22486 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22487 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22488 (match_dup 1)
22489 (const_int 1)))]
22490 "TARGET_SSE2"
22491 "mulsd\t{%2, %0|%0, %2}"
22492 [(set_attr "type" "ssemul")
22493 (set_attr "mode" "DF")])
22494
22495 (define_insn "divv2df3"
22496 [(set (match_operand:V2DF 0 "register_operand" "=x")
22497 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22498 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22499 "TARGET_SSE2"
22500 "divpd\t{%2, %0|%0, %2}"
22501 [(set_attr "type" "ssediv")
22502 (set_attr "mode" "V2DF")])
22503
22504 (define_insn "vmdivv2df3"
22505 [(set (match_operand:V2DF 0 "register_operand" "=x")
22506 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22507 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22508 (match_dup 1)
22509 (const_int 1)))]
22510 "TARGET_SSE2"
22511 "divsd\t{%2, %0|%0, %2}"
22512 [(set_attr "type" "ssediv")
22513 (set_attr "mode" "DF")])
22514
22515 ;; SSE min/max
22516
22517 (define_insn "smaxv2df3"
22518 [(set (match_operand:V2DF 0 "register_operand" "=x")
22519 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22520 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22521 "TARGET_SSE2"
22522 "maxpd\t{%2, %0|%0, %2}"
22523 [(set_attr "type" "sseadd")
22524 (set_attr "mode" "V2DF")])
22525
22526 (define_insn "vmsmaxv2df3"
22527 [(set (match_operand:V2DF 0 "register_operand" "=x")
22528 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22529 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22530 (match_dup 1)
22531 (const_int 1)))]
22532 "TARGET_SSE2"
22533 "maxsd\t{%2, %0|%0, %2}"
22534 [(set_attr "type" "sseadd")
22535 (set_attr "mode" "DF")])
22536
22537 (define_insn "sminv2df3"
22538 [(set (match_operand:V2DF 0 "register_operand" "=x")
22539 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22540 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22541 "TARGET_SSE2"
22542 "minpd\t{%2, %0|%0, %2}"
22543 [(set_attr "type" "sseadd")
22544 (set_attr "mode" "V2DF")])
22545
22546 (define_insn "vmsminv2df3"
22547 [(set (match_operand:V2DF 0 "register_operand" "=x")
22548 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22549 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22550 (match_dup 1)
22551 (const_int 1)))]
22552 "TARGET_SSE2"
22553 "minsd\t{%2, %0|%0, %2}"
22554 [(set_attr "type" "sseadd")
22555 (set_attr "mode" "DF")])
22556 ;; SSE2 square root. There doesn't appear to be an extension for the
22557 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22558
22559 (define_insn "sqrtv2df2"
22560 [(set (match_operand:V2DF 0 "register_operand" "=x")
22561 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22562 "TARGET_SSE2"
22563 "sqrtpd\t{%1, %0|%0, %1}"
22564 [(set_attr "type" "sse")
22565 (set_attr "mode" "V2DF")])
22566
22567 (define_insn "vmsqrtv2df2"
22568 [(set (match_operand:V2DF 0 "register_operand" "=x")
22569 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22570 (match_operand:V2DF 2 "register_operand" "0")
22571 (const_int 1)))]
22572 "TARGET_SSE2"
22573 "sqrtsd\t{%1, %0|%0, %1}"
22574 [(set_attr "type" "sse")
22575 (set_attr "mode" "SF")])
22576
22577 ;; SSE mask-generating compares
22578
22579 (define_insn "maskcmpv2df3"
22580 [(set (match_operand:V2DI 0 "register_operand" "=x")
22581 (match_operator:V2DI 3 "sse_comparison_operator"
22582 [(match_operand:V2DF 1 "register_operand" "0")
22583 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22584 "TARGET_SSE2"
22585 "cmp%D3pd\t{%2, %0|%0, %2}"
22586 [(set_attr "type" "ssecmp")
22587 (set_attr "mode" "V2DF")])
22588
22589 (define_insn "maskncmpv2df3"
22590 [(set (match_operand:V2DI 0 "register_operand" "=x")
22591 (not:V2DI
22592 (match_operator:V2DI 3 "sse_comparison_operator"
22593 [(match_operand:V2DF 1 "register_operand" "0")
22594 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22595 "TARGET_SSE2"
22596 {
22597 if (GET_CODE (operands[3]) == UNORDERED)
22598 return "cmpordps\t{%2, %0|%0, %2}";
22599 else
22600 return "cmpn%D3pd\t{%2, %0|%0, %2}";
22601 }
22602 [(set_attr "type" "ssecmp")
22603 (set_attr "mode" "V2DF")])
22604
22605 (define_insn "vmmaskcmpv2df3"
22606 [(set (match_operand:V2DI 0 "register_operand" "=x")
22607 (vec_merge:V2DI
22608 (match_operator:V2DI 3 "sse_comparison_operator"
22609 [(match_operand:V2DF 1 "register_operand" "0")
22610 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22611 (subreg:V2DI (match_dup 1) 0)
22612 (const_int 1)))]
22613 "TARGET_SSE2"
22614 "cmp%D3sd\t{%2, %0|%0, %2}"
22615 [(set_attr "type" "ssecmp")
22616 (set_attr "mode" "DF")])
22617
22618 (define_insn "vmmaskncmpv2df3"
22619 [(set (match_operand:V2DI 0 "register_operand" "=x")
22620 (vec_merge:V2DI
22621 (not:V2DI
22622 (match_operator:V2DI 3 "sse_comparison_operator"
22623 [(match_operand:V2DF 1 "register_operand" "0")
22624 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22625 (subreg:V2DI (match_dup 1) 0)
22626 (const_int 1)))]
22627 "TARGET_SSE2"
22628 {
22629 if (GET_CODE (operands[3]) == UNORDERED)
22630 return "cmpordsd\t{%2, %0|%0, %2}";
22631 else
22632 return "cmpn%D3sd\t{%2, %0|%0, %2}";
22633 }
22634 [(set_attr "type" "ssecmp")
22635 (set_attr "mode" "DF")])
22636
22637 (define_insn "sse2_comi"
22638 [(set (reg:CCFP FLAGS_REG)
22639 (compare:CCFP (vec_select:DF
22640 (match_operand:V2DF 0 "register_operand" "x")
22641 (parallel [(const_int 0)]))
22642 (vec_select:DF
22643 (match_operand:V2DF 1 "register_operand" "x")
22644 (parallel [(const_int 0)]))))]
22645 "TARGET_SSE2"
22646 "comisd\t{%1, %0|%0, %1}"
22647 [(set_attr "type" "ssecomi")
22648 (set_attr "mode" "DF")])
22649
22650 (define_insn "sse2_ucomi"
22651 [(set (reg:CCFPU FLAGS_REG)
22652 (compare:CCFPU (vec_select:DF
22653 (match_operand:V2DF 0 "register_operand" "x")
22654 (parallel [(const_int 0)]))
22655 (vec_select:DF
22656 (match_operand:V2DF 1 "register_operand" "x")
22657 (parallel [(const_int 0)]))))]
22658 "TARGET_SSE2"
22659 "ucomisd\t{%1, %0|%0, %1}"
22660 [(set_attr "type" "ssecomi")
22661 (set_attr "mode" "DF")])
22662
22663 ;; SSE Strange Moves.
22664
22665 (define_insn "sse2_movmskpd"
22666 [(set (match_operand:SI 0 "register_operand" "=r")
22667 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22668 UNSPEC_MOVMSK))]
22669 "TARGET_SSE2"
22670 "movmskpd\t{%1, %0|%0, %1}"
22671 [(set_attr "type" "ssecvt")
22672 (set_attr "mode" "V2DF")])
22673
22674 (define_insn "sse2_pmovmskb"
22675 [(set (match_operand:SI 0 "register_operand" "=r")
22676 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22677 UNSPEC_MOVMSK))]
22678 "TARGET_SSE2"
22679 "pmovmskb\t{%1, %0|%0, %1}"
22680 [(set_attr "type" "ssecvt")
22681 (set_attr "mode" "V2DF")])
22682
22683 (define_insn "sse2_maskmovdqu"
22684 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22685 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22686 (match_operand:V16QI 2 "register_operand" "x")]
22687 UNSPEC_MASKMOV))]
22688 "TARGET_SSE2"
22689 ;; @@@ check ordering of operands in intel/nonintel syntax
22690 "maskmovdqu\t{%2, %1|%1, %2}"
22691 [(set_attr "type" "ssecvt")
22692 (set_attr "mode" "TI")])
22693
22694 (define_insn "sse2_maskmovdqu_rex64"
22695 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22696 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22697 (match_operand:V16QI 2 "register_operand" "x")]
22698 UNSPEC_MASKMOV))]
22699 "TARGET_SSE2"
22700 ;; @@@ check ordering of operands in intel/nonintel syntax
22701 "maskmovdqu\t{%2, %1|%1, %2}"
22702 [(set_attr "type" "ssecvt")
22703 (set_attr "mode" "TI")])
22704
22705 (define_insn "sse2_movntv2df"
22706 [(set (match_operand:V2DF 0 "memory_operand" "=m")
22707 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22708 UNSPEC_MOVNT))]
22709 "TARGET_SSE2"
22710 "movntpd\t{%1, %0|%0, %1}"
22711 [(set_attr "type" "ssecvt")
22712 (set_attr "mode" "V2DF")])
22713
22714 (define_insn "sse2_movntv2di"
22715 [(set (match_operand:V2DI 0 "memory_operand" "=m")
22716 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22717 UNSPEC_MOVNT))]
22718 "TARGET_SSE2"
22719 "movntdq\t{%1, %0|%0, %1}"
22720 [(set_attr "type" "ssecvt")
22721 (set_attr "mode" "TI")])
22722
22723 (define_insn "sse2_movntsi"
22724 [(set (match_operand:SI 0 "memory_operand" "=m")
22725 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22726 UNSPEC_MOVNT))]
22727 "TARGET_SSE2"
22728 "movnti\t{%1, %0|%0, %1}"
22729 [(set_attr "type" "ssecvt")
22730 (set_attr "mode" "V2DF")])
22731
22732 ;; SSE <-> integer/MMX conversions
22733
22734 ;; Conversions between SI and SF
22735
22736 (define_insn "cvtdq2ps"
22737 [(set (match_operand:V4SF 0 "register_operand" "=x")
22738 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22739 "TARGET_SSE2"
22740 "cvtdq2ps\t{%1, %0|%0, %1}"
22741 [(set_attr "type" "ssecvt")
22742 (set_attr "mode" "V2DF")])
22743
22744 (define_insn "cvtps2dq"
22745 [(set (match_operand:V4SI 0 "register_operand" "=x")
22746 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22747 "TARGET_SSE2"
22748 "cvtps2dq\t{%1, %0|%0, %1}"
22749 [(set_attr "type" "ssecvt")
22750 (set_attr "mode" "TI")])
22751
22752 (define_insn "cvttps2dq"
22753 [(set (match_operand:V4SI 0 "register_operand" "=x")
22754 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22755 UNSPEC_FIX))]
22756 "TARGET_SSE2"
22757 "cvttps2dq\t{%1, %0|%0, %1}"
22758 [(set_attr "type" "ssecvt")
22759 (set_attr "mode" "TI")])
22760
22761 ;; Conversions between SI and DF
22762
22763 (define_insn "cvtdq2pd"
22764 [(set (match_operand:V2DF 0 "register_operand" "=x")
22765 (float:V2DF (vec_select:V2SI
22766 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22767 (parallel
22768 [(const_int 0)
22769 (const_int 1)]))))]
22770 "TARGET_SSE2"
22771 "cvtdq2pd\t{%1, %0|%0, %1}"
22772 [(set_attr "type" "ssecvt")
22773 (set_attr "mode" "V2DF")])
22774
22775 (define_insn "cvtpd2dq"
22776 [(set (match_operand:V4SI 0 "register_operand" "=x")
22777 (vec_concat:V4SI
22778 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22779 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22780 "TARGET_SSE2"
22781 "cvtpd2dq\t{%1, %0|%0, %1}"
22782 [(set_attr "type" "ssecvt")
22783 (set_attr "mode" "TI")])
22784
22785 (define_insn "cvttpd2dq"
22786 [(set (match_operand:V4SI 0 "register_operand" "=x")
22787 (vec_concat:V4SI
22788 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22789 UNSPEC_FIX)
22790 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22791 "TARGET_SSE2"
22792 "cvttpd2dq\t{%1, %0|%0, %1}"
22793 [(set_attr "type" "ssecvt")
22794 (set_attr "mode" "TI")])
22795
22796 (define_insn "cvtpd2pi"
22797 [(set (match_operand:V2SI 0 "register_operand" "=y")
22798 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22799 "TARGET_SSE2"
22800 "cvtpd2pi\t{%1, %0|%0, %1}"
22801 [(set_attr "type" "ssecvt")
22802 (set_attr "mode" "TI")])
22803
22804 (define_insn "cvttpd2pi"
22805 [(set (match_operand:V2SI 0 "register_operand" "=y")
22806 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22807 UNSPEC_FIX))]
22808 "TARGET_SSE2"
22809 "cvttpd2pi\t{%1, %0|%0, %1}"
22810 [(set_attr "type" "ssecvt")
22811 (set_attr "mode" "TI")])
22812
22813 (define_insn "cvtpi2pd"
22814 [(set (match_operand:V2DF 0 "register_operand" "=x")
22815 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22816 "TARGET_SSE2"
22817 "cvtpi2pd\t{%1, %0|%0, %1}"
22818 [(set_attr "type" "ssecvt")
22819 (set_attr "mode" "TI")])
22820
22821 ;; Conversions between SI and DF
22822
22823 (define_insn "cvtsd2si"
22824 [(set (match_operand:SI 0 "register_operand" "=r,r")
22825 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22826 (parallel [(const_int 0)]))))]
22827 "TARGET_SSE2"
22828 "cvtsd2si\t{%1, %0|%0, %1}"
22829 [(set_attr "type" "sseicvt")
22830 (set_attr "athlon_decode" "double,vector")
22831 (set_attr "mode" "SI")])
22832
22833 (define_insn "cvtsd2siq"
22834 [(set (match_operand:DI 0 "register_operand" "=r,r")
22835 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22836 (parallel [(const_int 0)]))))]
22837 "TARGET_SSE2 && TARGET_64BIT"
22838 "cvtsd2siq\t{%1, %0|%0, %1}"
22839 [(set_attr "type" "sseicvt")
22840 (set_attr "athlon_decode" "double,vector")
22841 (set_attr "mode" "DI")])
22842
22843 (define_insn "cvttsd2si"
22844 [(set (match_operand:SI 0 "register_operand" "=r,r")
22845 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22846 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22847 "TARGET_SSE2"
22848 "cvttsd2si\t{%1, %0|%0, %1}"
22849 [(set_attr "type" "sseicvt")
22850 (set_attr "mode" "SI")
22851 (set_attr "athlon_decode" "double,vector")])
22852
22853 (define_insn "cvttsd2siq"
22854 [(set (match_operand:DI 0 "register_operand" "=r,r")
22855 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22856 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22857 "TARGET_SSE2 && TARGET_64BIT"
22858 "cvttsd2siq\t{%1, %0|%0, %1}"
22859 [(set_attr "type" "sseicvt")
22860 (set_attr "mode" "DI")
22861 (set_attr "athlon_decode" "double,vector")])
22862
22863 (define_insn "cvtsi2sd"
22864 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22865 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22866 (vec_duplicate:V2DF
22867 (float:DF
22868 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22869 (const_int 2)))]
22870 "TARGET_SSE2"
22871 "cvtsi2sd\t{%2, %0|%0, %2}"
22872 [(set_attr "type" "sseicvt")
22873 (set_attr "mode" "DF")
22874 (set_attr "athlon_decode" "double,direct")])
22875
22876 (define_insn "cvtsi2sdq"
22877 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22878 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22879 (vec_duplicate:V2DF
22880 (float:DF
22881 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22882 (const_int 2)))]
22883 "TARGET_SSE2 && TARGET_64BIT"
22884 "cvtsi2sdq\t{%2, %0|%0, %2}"
22885 [(set_attr "type" "sseicvt")
22886 (set_attr "mode" "DF")
22887 (set_attr "athlon_decode" "double,direct")])
22888
22889 ;; Conversions between SF and DF
22890
22891 (define_insn "cvtsd2ss"
22892 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22893 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22894 (vec_duplicate:V4SF
22895 (float_truncate:V2SF
22896 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22897 (const_int 14)))]
22898 "TARGET_SSE2"
22899 "cvtsd2ss\t{%2, %0|%0, %2}"
22900 [(set_attr "type" "ssecvt")
22901 (set_attr "athlon_decode" "vector,double")
22902 (set_attr "mode" "SF")])
22903
22904 (define_insn "cvtss2sd"
22905 [(set (match_operand:V2DF 0 "register_operand" "=x")
22906 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22907 (float_extend:V2DF
22908 (vec_select:V2SF
22909 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22910 (parallel [(const_int 0)
22911 (const_int 1)])))
22912 (const_int 2)))]
22913 "TARGET_SSE2"
22914 "cvtss2sd\t{%2, %0|%0, %2}"
22915 [(set_attr "type" "ssecvt")
22916 (set_attr "mode" "DF")])
22917
22918 (define_insn "cvtpd2ps"
22919 [(set (match_operand:V4SF 0 "register_operand" "=x")
22920 (subreg:V4SF
22921 (vec_concat:V4SI
22922 (subreg:V2SI (float_truncate:V2SF
22923 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22924 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22925 "TARGET_SSE2"
22926 "cvtpd2ps\t{%1, %0|%0, %1}"
22927 [(set_attr "type" "ssecvt")
22928 (set_attr "mode" "V4SF")])
22929
22930 (define_insn "cvtps2pd"
22931 [(set (match_operand:V2DF 0 "register_operand" "=x")
22932 (float_extend:V2DF
22933 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22934 (parallel [(const_int 0)
22935 (const_int 1)]))))]
22936 "TARGET_SSE2"
22937 "cvtps2pd\t{%1, %0|%0, %1}"
22938 [(set_attr "type" "ssecvt")
22939 (set_attr "mode" "V2DF")])
22940
22941 ;; SSE2 variants of MMX insns
22942
22943 ;; MMX arithmetic
22944
22945 (define_insn "addv16qi3"
22946 [(set (match_operand:V16QI 0 "register_operand" "=x")
22947 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22948 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22949 "TARGET_SSE2"
22950 "paddb\t{%2, %0|%0, %2}"
22951 [(set_attr "type" "sseiadd")
22952 (set_attr "mode" "TI")])
22953
22954 (define_insn "addv8hi3"
22955 [(set (match_operand:V8HI 0 "register_operand" "=x")
22956 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22957 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22958 "TARGET_SSE2"
22959 "paddw\t{%2, %0|%0, %2}"
22960 [(set_attr "type" "sseiadd")
22961 (set_attr "mode" "TI")])
22962
22963 (define_insn "addv4si3"
22964 [(set (match_operand:V4SI 0 "register_operand" "=x")
22965 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22966 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22967 "TARGET_SSE2"
22968 "paddd\t{%2, %0|%0, %2}"
22969 [(set_attr "type" "sseiadd")
22970 (set_attr "mode" "TI")])
22971
22972 (define_insn "addv2di3"
22973 [(set (match_operand:V2DI 0 "register_operand" "=x")
22974 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22975 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22976 "TARGET_SSE2"
22977 "paddq\t{%2, %0|%0, %2}"
22978 [(set_attr "type" "sseiadd")
22979 (set_attr "mode" "TI")])
22980
22981 (define_insn "ssaddv16qi3"
22982 [(set (match_operand:V16QI 0 "register_operand" "=x")
22983 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22984 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22985 "TARGET_SSE2"
22986 "paddsb\t{%2, %0|%0, %2}"
22987 [(set_attr "type" "sseiadd")
22988 (set_attr "mode" "TI")])
22989
22990 (define_insn "ssaddv8hi3"
22991 [(set (match_operand:V8HI 0 "register_operand" "=x")
22992 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22993 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22994 "TARGET_SSE2"
22995 "paddsw\t{%2, %0|%0, %2}"
22996 [(set_attr "type" "sseiadd")
22997 (set_attr "mode" "TI")])
22998
22999 (define_insn "usaddv16qi3"
23000 [(set (match_operand:V16QI 0 "register_operand" "=x")
23001 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23002 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23003 "TARGET_SSE2"
23004 "paddusb\t{%2, %0|%0, %2}"
23005 [(set_attr "type" "sseiadd")
23006 (set_attr "mode" "TI")])
23007
23008 (define_insn "usaddv8hi3"
23009 [(set (match_operand:V8HI 0 "register_operand" "=x")
23010 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23011 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23012 "TARGET_SSE2"
23013 "paddusw\t{%2, %0|%0, %2}"
23014 [(set_attr "type" "sseiadd")
23015 (set_attr "mode" "TI")])
23016
23017 (define_insn "subv16qi3"
23018 [(set (match_operand:V16QI 0 "register_operand" "=x")
23019 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23020 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23021 "TARGET_SSE2"
23022 "psubb\t{%2, %0|%0, %2}"
23023 [(set_attr "type" "sseiadd")
23024 (set_attr "mode" "TI")])
23025
23026 (define_insn "subv8hi3"
23027 [(set (match_operand:V8HI 0 "register_operand" "=x")
23028 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23029 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23030 "TARGET_SSE2"
23031 "psubw\t{%2, %0|%0, %2}"
23032 [(set_attr "type" "sseiadd")
23033 (set_attr "mode" "TI")])
23034
23035 (define_insn "subv4si3"
23036 [(set (match_operand:V4SI 0 "register_operand" "=x")
23037 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23038 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23039 "TARGET_SSE2"
23040 "psubd\t{%2, %0|%0, %2}"
23041 [(set_attr "type" "sseiadd")
23042 (set_attr "mode" "TI")])
23043
23044 (define_insn "subv2di3"
23045 [(set (match_operand:V2DI 0 "register_operand" "=x")
23046 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23047 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23048 "TARGET_SSE2"
23049 "psubq\t{%2, %0|%0, %2}"
23050 [(set_attr "type" "sseiadd")
23051 (set_attr "mode" "TI")])
23052
23053 (define_insn "sssubv16qi3"
23054 [(set (match_operand:V16QI 0 "register_operand" "=x")
23055 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23056 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23057 "TARGET_SSE2"
23058 "psubsb\t{%2, %0|%0, %2}"
23059 [(set_attr "type" "sseiadd")
23060 (set_attr "mode" "TI")])
23061
23062 (define_insn "sssubv8hi3"
23063 [(set (match_operand:V8HI 0 "register_operand" "=x")
23064 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23065 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23066 "TARGET_SSE2"
23067 "psubsw\t{%2, %0|%0, %2}"
23068 [(set_attr "type" "sseiadd")
23069 (set_attr "mode" "TI")])
23070
23071 (define_insn "ussubv16qi3"
23072 [(set (match_operand:V16QI 0 "register_operand" "=x")
23073 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23074 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23075 "TARGET_SSE2"
23076 "psubusb\t{%2, %0|%0, %2}"
23077 [(set_attr "type" "sseiadd")
23078 (set_attr "mode" "TI")])
23079
23080 (define_insn "ussubv8hi3"
23081 [(set (match_operand:V8HI 0 "register_operand" "=x")
23082 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23083 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23084 "TARGET_SSE2"
23085 "psubusw\t{%2, %0|%0, %2}"
23086 [(set_attr "type" "sseiadd")
23087 (set_attr "mode" "TI")])
23088
23089 (define_insn "mulv8hi3"
23090 [(set (match_operand:V8HI 0 "register_operand" "=x")
23091 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23092 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23093 "TARGET_SSE2"
23094 "pmullw\t{%2, %0|%0, %2}"
23095 [(set_attr "type" "sseimul")
23096 (set_attr "mode" "TI")])
23097
23098 (define_insn "smulv8hi3_highpart"
23099 [(set (match_operand:V8HI 0 "register_operand" "=x")
23100 (truncate:V8HI
23101 (lshiftrt:V8SI
23102 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23103 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23104 (const_int 16))))]
23105 "TARGET_SSE2"
23106 "pmulhw\t{%2, %0|%0, %2}"
23107 [(set_attr "type" "sseimul")
23108 (set_attr "mode" "TI")])
23109
23110 (define_insn "umulv8hi3_highpart"
23111 [(set (match_operand:V8HI 0 "register_operand" "=x")
23112 (truncate:V8HI
23113 (lshiftrt:V8SI
23114 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23115 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23116 (const_int 16))))]
23117 "TARGET_SSE2"
23118 "pmulhuw\t{%2, %0|%0, %2}"
23119 [(set_attr "type" "sseimul")
23120 (set_attr "mode" "TI")])
23121
23122 (define_insn "sse2_umulsidi3"
23123 [(set (match_operand:DI 0 "register_operand" "=y")
23124 (mult:DI (zero_extend:DI (vec_select:SI
23125 (match_operand:V2SI 1 "register_operand" "0")
23126 (parallel [(const_int 0)])))
23127 (zero_extend:DI (vec_select:SI
23128 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23129 (parallel [(const_int 0)])))))]
23130 "TARGET_SSE2"
23131 "pmuludq\t{%2, %0|%0, %2}"
23132 [(set_attr "type" "mmxmul")
23133 (set_attr "mode" "DI")])
23134
23135 (define_insn "sse2_umulv2siv2di3"
23136 [(set (match_operand:V2DI 0 "register_operand" "=x")
23137 (mult:V2DI (zero_extend:V2DI
23138 (vec_select:V2SI
23139 (match_operand:V4SI 1 "register_operand" "0")
23140 (parallel [(const_int 0) (const_int 2)])))
23141 (zero_extend:V2DI
23142 (vec_select:V2SI
23143 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23144 (parallel [(const_int 0) (const_int 2)])))))]
23145 "TARGET_SSE2"
23146 "pmuludq\t{%2, %0|%0, %2}"
23147 [(set_attr "type" "sseimul")
23148 (set_attr "mode" "TI")])
23149
23150 (define_insn "sse2_pmaddwd"
23151 [(set (match_operand:V4SI 0 "register_operand" "=x")
23152 (plus:V4SI
23153 (mult:V4SI
23154 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23155 (parallel [(const_int 0)
23156 (const_int 2)
23157 (const_int 4)
23158 (const_int 6)])))
23159 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23160 (parallel [(const_int 0)
23161 (const_int 2)
23162 (const_int 4)
23163 (const_int 6)]))))
23164 (mult:V4SI
23165 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23166 (parallel [(const_int 1)
23167 (const_int 3)
23168 (const_int 5)
23169 (const_int 7)])))
23170 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23171 (parallel [(const_int 1)
23172 (const_int 3)
23173 (const_int 5)
23174 (const_int 7)]))))))]
23175 "TARGET_SSE2"
23176 "pmaddwd\t{%2, %0|%0, %2}"
23177 [(set_attr "type" "sseiadd")
23178 (set_attr "mode" "TI")])
23179
23180 ;; Same as pxor, but don't show input operands so that we don't think
23181 ;; they are live.
23182 (define_insn "sse2_clrti"
23183 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23184 "TARGET_SSE2"
23185 {
23186 if (get_attr_mode (insn) == MODE_TI)
23187 return "pxor\t%0, %0";
23188 else
23189 return "xorps\t%0, %0";
23190 }
23191 [(set_attr "type" "ssemov")
23192 (set_attr "memory" "none")
23193 (set (attr "mode")
23194 (if_then_else
23195 (ne (symbol_ref "optimize_size")
23196 (const_int 0))
23197 (const_string "V4SF")
23198 (const_string "TI")))])
23199
23200 ;; MMX unsigned averages/sum of absolute differences
23201
23202 (define_insn "sse2_uavgv16qi3"
23203 [(set (match_operand:V16QI 0 "register_operand" "=x")
23204 (ashiftrt:V16QI
23205 (plus:V16QI (plus:V16QI
23206 (match_operand:V16QI 1 "register_operand" "0")
23207 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23208 (const_vector:V16QI [(const_int 1) (const_int 1)
23209 (const_int 1) (const_int 1)
23210 (const_int 1) (const_int 1)
23211 (const_int 1) (const_int 1)
23212 (const_int 1) (const_int 1)
23213 (const_int 1) (const_int 1)
23214 (const_int 1) (const_int 1)
23215 (const_int 1) (const_int 1)]))
23216 (const_int 1)))]
23217 "TARGET_SSE2"
23218 "pavgb\t{%2, %0|%0, %2}"
23219 [(set_attr "type" "sseiadd")
23220 (set_attr "mode" "TI")])
23221
23222 (define_insn "sse2_uavgv8hi3"
23223 [(set (match_operand:V8HI 0 "register_operand" "=x")
23224 (ashiftrt:V8HI
23225 (plus:V8HI (plus:V8HI
23226 (match_operand:V8HI 1 "register_operand" "0")
23227 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23228 (const_vector:V8HI [(const_int 1) (const_int 1)
23229 (const_int 1) (const_int 1)
23230 (const_int 1) (const_int 1)
23231 (const_int 1) (const_int 1)]))
23232 (const_int 1)))]
23233 "TARGET_SSE2"
23234 "pavgw\t{%2, %0|%0, %2}"
23235 [(set_attr "type" "sseiadd")
23236 (set_attr "mode" "TI")])
23237
23238 ;; @@@ this isn't the right representation.
23239 (define_insn "sse2_psadbw"
23240 [(set (match_operand:V2DI 0 "register_operand" "=x")
23241 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23242 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23243 UNSPEC_PSADBW))]
23244 "TARGET_SSE2"
23245 "psadbw\t{%2, %0|%0, %2}"
23246 [(set_attr "type" "sseiadd")
23247 (set_attr "mode" "TI")])
23248
23249
23250 ;; MMX insert/extract/shuffle
23251
23252 (define_expand "sse2_pinsrw"
23253 [(set (match_operand:V8HI 0 "register_operand" "")
23254 (vec_merge:V8HI
23255 (match_operand:V8HI 1 "register_operand" "")
23256 (vec_duplicate:V8HI
23257 (match_operand:SI 2 "nonimmediate_operand" ""))
23258 (match_operand:SI 3 "const_0_to_7_operand" "")))]
23259 "TARGET_SSE2"
23260 {
23261 operands[2] = gen_lowpart (HImode, operands[2]);
23262 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
23263 })
23264
23265 (define_insn "*sse2_pinsrw"
23266 [(set (match_operand:V8HI 0 "register_operand" "=x")
23267 (vec_merge:V8HI
23268 (match_operand:V8HI 1 "register_operand" "0")
23269 (vec_duplicate:V8HI
23270 (match_operand:HI 2 "nonimmediate_operand" "rm"))
23271 (match_operand:SI 3 "const_pow2_1_to_128_operand" "N")))]
23272 "TARGET_SSE2"
23273 {
23274 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
23275 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
23276 }
23277 [(set_attr "type" "ssecvt")
23278 (set_attr "mode" "TI")])
23279
23280 (define_insn "sse2_pextrw"
23281 [(set (match_operand:SI 0 "register_operand" "=r")
23282 (zero_extend:SI
23283 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23284 (parallel
23285 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23286 "TARGET_SSE2"
23287 "pextrw\t{%2, %1, %0|%0, %1, %2}"
23288 [(set_attr "type" "ssecvt")
23289 (set_attr "mode" "TI")])
23290
23291 (define_insn "sse2_pshufd"
23292 [(set (match_operand:V4SI 0 "register_operand" "=x")
23293 (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23294 (match_operand:SI 2 "immediate_operand" "i")]
23295 UNSPEC_SHUFFLE))]
23296 "TARGET_SSE2"
23297 "pshufd\t{%2, %1, %0|%0, %1, %2}"
23298 [(set_attr "type" "ssecvt")
23299 (set_attr "mode" "TI")])
23300
23301 (define_insn "sse2_pshuflw"
23302 [(set (match_operand:V8HI 0 "register_operand" "=x")
23303 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23304 (match_operand:SI 2 "immediate_operand" "i")]
23305 UNSPEC_PSHUFLW))]
23306 "TARGET_SSE2"
23307 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23308 [(set_attr "type" "ssecvt")
23309 (set_attr "mode" "TI")])
23310
23311 (define_insn "sse2_pshufhw"
23312 [(set (match_operand:V8HI 0 "register_operand" "=x")
23313 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23314 (match_operand:SI 2 "immediate_operand" "i")]
23315 UNSPEC_PSHUFHW))]
23316 "TARGET_SSE2"
23317 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23318 [(set_attr "type" "ssecvt")
23319 (set_attr "mode" "TI")])
23320
23321 ;; MMX mask-generating comparisons
23322
23323 (define_insn "eqv16qi3"
23324 [(set (match_operand:V16QI 0 "register_operand" "=x")
23325 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23326 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23327 "TARGET_SSE2"
23328 "pcmpeqb\t{%2, %0|%0, %2}"
23329 [(set_attr "type" "ssecmp")
23330 (set_attr "mode" "TI")])
23331
23332 (define_insn "eqv8hi3"
23333 [(set (match_operand:V8HI 0 "register_operand" "=x")
23334 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23335 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23336 "TARGET_SSE2"
23337 "pcmpeqw\t{%2, %0|%0, %2}"
23338 [(set_attr "type" "ssecmp")
23339 (set_attr "mode" "TI")])
23340
23341 (define_insn "eqv4si3"
23342 [(set (match_operand:V4SI 0 "register_operand" "=x")
23343 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23344 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23345 "TARGET_SSE2"
23346 "pcmpeqd\t{%2, %0|%0, %2}"
23347 [(set_attr "type" "ssecmp")
23348 (set_attr "mode" "TI")])
23349
23350 (define_insn "gtv16qi3"
23351 [(set (match_operand:V16QI 0 "register_operand" "=x")
23352 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23353 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23354 "TARGET_SSE2"
23355 "pcmpgtb\t{%2, %0|%0, %2}"
23356 [(set_attr "type" "ssecmp")
23357 (set_attr "mode" "TI")])
23358
23359 (define_insn "gtv8hi3"
23360 [(set (match_operand:V8HI 0 "register_operand" "=x")
23361 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23362 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23363 "TARGET_SSE2"
23364 "pcmpgtw\t{%2, %0|%0, %2}"
23365 [(set_attr "type" "ssecmp")
23366 (set_attr "mode" "TI")])
23367
23368 (define_insn "gtv4si3"
23369 [(set (match_operand:V4SI 0 "register_operand" "=x")
23370 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23371 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23372 "TARGET_SSE2"
23373 "pcmpgtd\t{%2, %0|%0, %2}"
23374 [(set_attr "type" "ssecmp")
23375 (set_attr "mode" "TI")])
23376
23377
23378 ;; MMX max/min insns
23379
23380 (define_insn "umaxv16qi3"
23381 [(set (match_operand:V16QI 0 "register_operand" "=x")
23382 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23383 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23384 "TARGET_SSE2"
23385 "pmaxub\t{%2, %0|%0, %2}"
23386 [(set_attr "type" "sseiadd")
23387 (set_attr "mode" "TI")])
23388
23389 (define_insn "smaxv8hi3"
23390 [(set (match_operand:V8HI 0 "register_operand" "=x")
23391 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23392 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23393 "TARGET_SSE2"
23394 "pmaxsw\t{%2, %0|%0, %2}"
23395 [(set_attr "type" "sseiadd")
23396 (set_attr "mode" "TI")])
23397
23398 (define_insn "uminv16qi3"
23399 [(set (match_operand:V16QI 0 "register_operand" "=x")
23400 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23401 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23402 "TARGET_SSE2"
23403 "pminub\t{%2, %0|%0, %2}"
23404 [(set_attr "type" "sseiadd")
23405 (set_attr "mode" "TI")])
23406
23407 (define_insn "sminv8hi3"
23408 [(set (match_operand:V8HI 0 "register_operand" "=x")
23409 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23410 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23411 "TARGET_SSE2"
23412 "pminsw\t{%2, %0|%0, %2}"
23413 [(set_attr "type" "sseiadd")
23414 (set_attr "mode" "TI")])
23415
23416
23417 ;; MMX shifts
23418
23419 (define_insn "ashrv8hi3"
23420 [(set (match_operand:V8HI 0 "register_operand" "=x")
23421 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23422 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23423 "TARGET_SSE2"
23424 "psraw\t{%2, %0|%0, %2}"
23425 [(set_attr "type" "sseishft")
23426 (set_attr "mode" "TI")])
23427
23428 (define_insn "ashrv4si3"
23429 [(set (match_operand:V4SI 0 "register_operand" "=x")
23430 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23431 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23432 "TARGET_SSE2"
23433 "psrad\t{%2, %0|%0, %2}"
23434 [(set_attr "type" "sseishft")
23435 (set_attr "mode" "TI")])
23436
23437 (define_insn "lshrv8hi3"
23438 [(set (match_operand:V8HI 0 "register_operand" "=x")
23439 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23440 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23441 "TARGET_SSE2"
23442 "psrlw\t{%2, %0|%0, %2}"
23443 [(set_attr "type" "sseishft")
23444 (set_attr "mode" "TI")])
23445
23446 (define_insn "lshrv4si3"
23447 [(set (match_operand:V4SI 0 "register_operand" "=x")
23448 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23449 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23450 "TARGET_SSE2"
23451 "psrld\t{%2, %0|%0, %2}"
23452 [(set_attr "type" "sseishft")
23453 (set_attr "mode" "TI")])
23454
23455 (define_insn "lshrv2di3"
23456 [(set (match_operand:V2DI 0 "register_operand" "=x")
23457 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23458 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23459 "TARGET_SSE2"
23460 "psrlq\t{%2, %0|%0, %2}"
23461 [(set_attr "type" "sseishft")
23462 (set_attr "mode" "TI")])
23463
23464 (define_insn "ashlv8hi3"
23465 [(set (match_operand:V8HI 0 "register_operand" "=x")
23466 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23467 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23468 "TARGET_SSE2"
23469 "psllw\t{%2, %0|%0, %2}"
23470 [(set_attr "type" "sseishft")
23471 (set_attr "mode" "TI")])
23472
23473 (define_insn "ashlv4si3"
23474 [(set (match_operand:V4SI 0 "register_operand" "=x")
23475 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23476 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23477 "TARGET_SSE2"
23478 "pslld\t{%2, %0|%0, %2}"
23479 [(set_attr "type" "sseishft")
23480 (set_attr "mode" "TI")])
23481
23482 (define_insn "ashlv2di3"
23483 [(set (match_operand:V2DI 0 "register_operand" "=x")
23484 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23485 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23486 "TARGET_SSE2"
23487 "psllq\t{%2, %0|%0, %2}"
23488 [(set_attr "type" "sseishft")
23489 (set_attr "mode" "TI")])
23490
23491 (define_insn "ashrv8hi3_ti"
23492 [(set (match_operand:V8HI 0 "register_operand" "=x")
23493 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23494 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23495 "TARGET_SSE2"
23496 "psraw\t{%2, %0|%0, %2}"
23497 [(set_attr "type" "sseishft")
23498 (set_attr "mode" "TI")])
23499
23500 (define_insn "ashrv4si3_ti"
23501 [(set (match_operand:V4SI 0 "register_operand" "=x")
23502 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23503 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23504 "TARGET_SSE2"
23505 "psrad\t{%2, %0|%0, %2}"
23506 [(set_attr "type" "sseishft")
23507 (set_attr "mode" "TI")])
23508
23509 (define_insn "lshrv8hi3_ti"
23510 [(set (match_operand:V8HI 0 "register_operand" "=x")
23511 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23512 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23513 "TARGET_SSE2"
23514 "psrlw\t{%2, %0|%0, %2}"
23515 [(set_attr "type" "sseishft")
23516 (set_attr "mode" "TI")])
23517
23518 (define_insn "lshrv4si3_ti"
23519 [(set (match_operand:V4SI 0 "register_operand" "=x")
23520 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23521 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23522 "TARGET_SSE2"
23523 "psrld\t{%2, %0|%0, %2}"
23524 [(set_attr "type" "sseishft")
23525 (set_attr "mode" "TI")])
23526
23527 (define_insn "lshrv2di3_ti"
23528 [(set (match_operand:V2DI 0 "register_operand" "=x")
23529 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23530 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23531 "TARGET_SSE2"
23532 "psrlq\t{%2, %0|%0, %2}"
23533 [(set_attr "type" "sseishft")
23534 (set_attr "mode" "TI")])
23535
23536 (define_insn "ashlv8hi3_ti"
23537 [(set (match_operand:V8HI 0 "register_operand" "=x")
23538 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23539 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23540 "TARGET_SSE2"
23541 "psllw\t{%2, %0|%0, %2}"
23542 [(set_attr "type" "sseishft")
23543 (set_attr "mode" "TI")])
23544
23545 (define_insn "ashlv4si3_ti"
23546 [(set (match_operand:V4SI 0 "register_operand" "=x")
23547 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23548 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23549 "TARGET_SSE2"
23550 "pslld\t{%2, %0|%0, %2}"
23551 [(set_attr "type" "sseishft")
23552 (set_attr "mode" "TI")])
23553
23554 (define_insn "ashlv2di3_ti"
23555 [(set (match_operand:V2DI 0 "register_operand" "=x")
23556 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23557 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23558 "TARGET_SSE2"
23559 "psllq\t{%2, %0|%0, %2}"
23560 [(set_attr "type" "sseishft")
23561 (set_attr "mode" "TI")])
23562
23563 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
23564 ;; we wouldn't need here it since we never generate TImode arithmetic.
23565
23566 ;; There has to be some kind of prize for the weirdest new instruction...
23567 (define_insn "sse2_ashlti3"
23568 [(set (match_operand:TI 0 "register_operand" "=x")
23569 (unspec:TI
23570 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23571 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23572 (const_int 8)))] UNSPEC_NOP))]
23573 "TARGET_SSE2"
23574 "pslldq\t{%2, %0|%0, %2}"
23575 [(set_attr "type" "sseishft")
23576 (set_attr "mode" "TI")])
23577
23578 (define_insn "sse2_lshrti3"
23579 [(set (match_operand:TI 0 "register_operand" "=x")
23580 (unspec:TI
23581 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23582 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23583 (const_int 8)))] UNSPEC_NOP))]
23584 "TARGET_SSE2"
23585 "psrldq\t{%2, %0|%0, %2}"
23586 [(set_attr "type" "sseishft")
23587 (set_attr "mode" "TI")])
23588
23589 ;; SSE unpack
23590
23591 (define_insn "sse2_unpckhpd"
23592 [(set (match_operand:V2DF 0 "register_operand" "=x")
23593 (vec_concat:V2DF
23594 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23595 (parallel [(const_int 1)]))
23596 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23597 (parallel [(const_int 1)]))))]
23598 "TARGET_SSE2"
23599 "unpckhpd\t{%2, %0|%0, %2}"
23600 [(set_attr "type" "ssecvt")
23601 (set_attr "mode" "V2DF")])
23602
23603 (define_insn "sse2_unpcklpd"
23604 [(set (match_operand:V2DF 0 "register_operand" "=x")
23605 (vec_concat:V2DF
23606 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23607 (parallel [(const_int 0)]))
23608 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23609 (parallel [(const_int 0)]))))]
23610 "TARGET_SSE2"
23611 "unpcklpd\t{%2, %0|%0, %2}"
23612 [(set_attr "type" "ssecvt")
23613 (set_attr "mode" "V2DF")])
23614
23615 ;; MMX pack/unpack insns.
23616
23617 (define_insn "sse2_packsswb"
23618 [(set (match_operand:V16QI 0 "register_operand" "=x")
23619 (vec_concat:V16QI
23620 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23621 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23622 "TARGET_SSE2"
23623 "packsswb\t{%2, %0|%0, %2}"
23624 [(set_attr "type" "ssecvt")
23625 (set_attr "mode" "TI")])
23626
23627 (define_insn "sse2_packssdw"
23628 [(set (match_operand:V8HI 0 "register_operand" "=x")
23629 (vec_concat:V8HI
23630 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23631 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23632 "TARGET_SSE2"
23633 "packssdw\t{%2, %0|%0, %2}"
23634 [(set_attr "type" "ssecvt")
23635 (set_attr "mode" "TI")])
23636
23637 (define_insn "sse2_packuswb"
23638 [(set (match_operand:V16QI 0 "register_operand" "=x")
23639 (vec_concat:V16QI
23640 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23641 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23642 "TARGET_SSE2"
23643 "packuswb\t{%2, %0|%0, %2}"
23644 [(set_attr "type" "ssecvt")
23645 (set_attr "mode" "TI")])
23646
23647 (define_insn "sse2_punpckhbw"
23648 [(set (match_operand:V16QI 0 "register_operand" "=x")
23649 (vec_merge:V16QI
23650 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23651 (parallel [(const_int 8) (const_int 0)
23652 (const_int 9) (const_int 1)
23653 (const_int 10) (const_int 2)
23654 (const_int 11) (const_int 3)
23655 (const_int 12) (const_int 4)
23656 (const_int 13) (const_int 5)
23657 (const_int 14) (const_int 6)
23658 (const_int 15) (const_int 7)]))
23659 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23660 (parallel [(const_int 0) (const_int 8)
23661 (const_int 1) (const_int 9)
23662 (const_int 2) (const_int 10)
23663 (const_int 3) (const_int 11)
23664 (const_int 4) (const_int 12)
23665 (const_int 5) (const_int 13)
23666 (const_int 6) (const_int 14)
23667 (const_int 7) (const_int 15)]))
23668 (const_int 21845)))]
23669 "TARGET_SSE2"
23670 "punpckhbw\t{%2, %0|%0, %2}"
23671 [(set_attr "type" "ssecvt")
23672 (set_attr "mode" "TI")])
23673
23674 (define_insn "sse2_punpckhwd"
23675 [(set (match_operand:V8HI 0 "register_operand" "=x")
23676 (vec_merge:V8HI
23677 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23678 (parallel [(const_int 4) (const_int 0)
23679 (const_int 5) (const_int 1)
23680 (const_int 6) (const_int 2)
23681 (const_int 7) (const_int 3)]))
23682 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23683 (parallel [(const_int 0) (const_int 4)
23684 (const_int 1) (const_int 5)
23685 (const_int 2) (const_int 6)
23686 (const_int 3) (const_int 7)]))
23687 (const_int 85)))]
23688 "TARGET_SSE2"
23689 "punpckhwd\t{%2, %0|%0, %2}"
23690 [(set_attr "type" "ssecvt")
23691 (set_attr "mode" "TI")])
23692
23693 (define_insn "sse2_punpckhdq"
23694 [(set (match_operand:V4SI 0 "register_operand" "=x")
23695 (vec_merge:V4SI
23696 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23697 (parallel [(const_int 2) (const_int 0)
23698 (const_int 3) (const_int 1)]))
23699 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23700 (parallel [(const_int 0) (const_int 2)
23701 (const_int 1) (const_int 3)]))
23702 (const_int 5)))]
23703 "TARGET_SSE2"
23704 "punpckhdq\t{%2, %0|%0, %2}"
23705 [(set_attr "type" "ssecvt")
23706 (set_attr "mode" "TI")])
23707
23708 (define_insn "sse2_punpcklbw"
23709 [(set (match_operand:V16QI 0 "register_operand" "=x")
23710 (vec_merge:V16QI
23711 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23712 (parallel [(const_int 0) (const_int 8)
23713 (const_int 1) (const_int 9)
23714 (const_int 2) (const_int 10)
23715 (const_int 3) (const_int 11)
23716 (const_int 4) (const_int 12)
23717 (const_int 5) (const_int 13)
23718 (const_int 6) (const_int 14)
23719 (const_int 7) (const_int 15)]))
23720 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23721 (parallel [(const_int 8) (const_int 0)
23722 (const_int 9) (const_int 1)
23723 (const_int 10) (const_int 2)
23724 (const_int 11) (const_int 3)
23725 (const_int 12) (const_int 4)
23726 (const_int 13) (const_int 5)
23727 (const_int 14) (const_int 6)
23728 (const_int 15) (const_int 7)]))
23729 (const_int 21845)))]
23730 "TARGET_SSE2"
23731 "punpcklbw\t{%2, %0|%0, %2}"
23732 [(set_attr "type" "ssecvt")
23733 (set_attr "mode" "TI")])
23734
23735 (define_insn "sse2_punpcklwd"
23736 [(set (match_operand:V8HI 0 "register_operand" "=x")
23737 (vec_merge:V8HI
23738 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23739 (parallel [(const_int 0) (const_int 4)
23740 (const_int 1) (const_int 5)
23741 (const_int 2) (const_int 6)
23742 (const_int 3) (const_int 7)]))
23743 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23744 (parallel [(const_int 4) (const_int 0)
23745 (const_int 5) (const_int 1)
23746 (const_int 6) (const_int 2)
23747 (const_int 7) (const_int 3)]))
23748 (const_int 85)))]
23749 "TARGET_SSE2"
23750 "punpcklwd\t{%2, %0|%0, %2}"
23751 [(set_attr "type" "ssecvt")
23752 (set_attr "mode" "TI")])
23753
23754 (define_insn "sse2_punpckldq"
23755 [(set (match_operand:V4SI 0 "register_operand" "=x")
23756 (vec_merge:V4SI
23757 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23758 (parallel [(const_int 0) (const_int 2)
23759 (const_int 1) (const_int 3)]))
23760 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23761 (parallel [(const_int 2) (const_int 0)
23762 (const_int 3) (const_int 1)]))
23763 (const_int 5)))]
23764 "TARGET_SSE2"
23765 "punpckldq\t{%2, %0|%0, %2}"
23766 [(set_attr "type" "ssecvt")
23767 (set_attr "mode" "TI")])
23768
23769 (define_insn "sse2_punpcklqdq"
23770 [(set (match_operand:V2DI 0 "register_operand" "=x")
23771 (vec_merge:V2DI
23772 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23773 (parallel [(const_int 1)
23774 (const_int 0)]))
23775 (match_operand:V2DI 1 "register_operand" "0")
23776 (const_int 1)))]
23777 "TARGET_SSE2"
23778 "punpcklqdq\t{%2, %0|%0, %2}"
23779 [(set_attr "type" "ssecvt")
23780 (set_attr "mode" "TI")])
23781
23782 (define_insn "sse2_punpckhqdq"
23783 [(set (match_operand:V2DI 0 "register_operand" "=x")
23784 (vec_merge:V2DI
23785 (match_operand:V2DI 1 "register_operand" "0")
23786 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23787 (parallel [(const_int 1)
23788 (const_int 0)]))
23789 (const_int 1)))]
23790 "TARGET_SSE2"
23791 "punpckhqdq\t{%2, %0|%0, %2}"
23792 [(set_attr "type" "ssecvt")
23793 (set_attr "mode" "TI")])
23794
23795 ;; SSE2 moves
23796
23797 (define_insn "sse2_movapd"
23798 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23799 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23800 UNSPEC_MOVA))]
23801 "TARGET_SSE2
23802 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23803 "movapd\t{%1, %0|%0, %1}"
23804 [(set_attr "type" "ssemov")
23805 (set_attr "mode" "V2DF")])
23806
23807 (define_insn "sse2_movupd"
23808 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23809 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23810 UNSPEC_MOVU))]
23811 "TARGET_SSE2
23812 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23813 "movupd\t{%1, %0|%0, %1}"
23814 [(set_attr "type" "ssecvt")
23815 (set_attr "mode" "V2DF")])
23816
23817 (define_insn "sse2_movdqa"
23818 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23819 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23820 UNSPEC_MOVA))]
23821 "TARGET_SSE2
23822 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23823 "movdqa\t{%1, %0|%0, %1}"
23824 [(set_attr "type" "ssemov")
23825 (set_attr "mode" "TI")])
23826
23827 (define_insn "sse2_movdqu"
23828 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23829 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23830 UNSPEC_MOVU))]
23831 "TARGET_SSE2
23832 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23833 "movdqu\t{%1, %0|%0, %1}"
23834 [(set_attr "type" "ssecvt")
23835 (set_attr "mode" "TI")])
23836
23837 (define_insn "sse2_movdq2q"
23838 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23839 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23840 (parallel [(const_int 0)])))]
23841 "TARGET_SSE2 && !TARGET_64BIT"
23842 "@
23843 movq\t{%1, %0|%0, %1}
23844 movdq2q\t{%1, %0|%0, %1}"
23845 [(set_attr "type" "ssecvt")
23846 (set_attr "mode" "TI")])
23847
23848 (define_insn "sse2_movdq2q_rex64"
23849 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23850 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23851 (parallel [(const_int 0)])))]
23852 "TARGET_SSE2 && TARGET_64BIT"
23853 "@
23854 movq\t{%1, %0|%0, %1}
23855 movdq2q\t{%1, %0|%0, %1}
23856 movd\t{%1, %0|%0, %1}"
23857 [(set_attr "type" "ssecvt")
23858 (set_attr "mode" "TI")])
23859
23860 (define_insn "sse2_movq2dq"
23861 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23862 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23863 (const_int 0)))]
23864 "TARGET_SSE2 && !TARGET_64BIT"
23865 "@
23866 movq\t{%1, %0|%0, %1}
23867 movq2dq\t{%1, %0|%0, %1}"
23868 [(set_attr "type" "ssecvt,ssemov")
23869 (set_attr "mode" "TI")])
23870
23871 (define_insn "sse2_movq2dq_rex64"
23872 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23873 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23874 (const_int 0)))]
23875 "TARGET_SSE2 && TARGET_64BIT"
23876 "@
23877 movq\t{%1, %0|%0, %1}
23878 movq2dq\t{%1, %0|%0, %1}
23879 movd\t{%1, %0|%0, %1}"
23880 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23881 (set_attr "mode" "TI")])
23882
23883 (define_insn "sse2_movq"
23884 [(set (match_operand:V2DI 0 "register_operand" "=x")
23885 (vec_concat:V2DI (vec_select:DI
23886 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23887 (parallel [(const_int 0)]))
23888 (const_int 0)))]
23889 "TARGET_SSE2"
23890 "movq\t{%1, %0|%0, %1}"
23891 [(set_attr "type" "ssemov")
23892 (set_attr "mode" "TI")])
23893
23894 (define_insn "sse2_loadd"
23895 [(set (match_operand:V4SI 0 "register_operand" "=x")
23896 (vec_merge:V4SI
23897 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23898 (const_vector:V4SI [(const_int 0)
23899 (const_int 0)
23900 (const_int 0)
23901 (const_int 0)])
23902 (const_int 1)))]
23903 "TARGET_SSE2"
23904 "movd\t{%1, %0|%0, %1}"
23905 [(set_attr "type" "ssemov")
23906 (set_attr "mode" "TI")])
23907
23908 (define_insn "sse2_stored"
23909 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23910 (vec_select:SI
23911 (match_operand:V4SI 1 "register_operand" "x")
23912 (parallel [(const_int 0)])))]
23913 "TARGET_SSE2"
23914 "movd\t{%1, %0|%0, %1}"
23915 [(set_attr "type" "ssemov")
23916 (set_attr "mode" "TI")])
23917
23918 ;; Store the high double of the source vector into the double destination.
23919 (define_insn "sse2_storehpd"
23920 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,Y,Y")
23921 (vec_select:DF
23922 (match_operand:V2DF 1 "nonimmediate_operand" " Y,0,o")
23923 (parallel [(const_int 1)])))]
23924 "TARGET_SSE2"
23925 "@
23926 movhpd\t{%1, %0|%0, %1}
23927 unpckhpd\t%0, %0
23928 #"
23929 [(set_attr "type" "ssecvt")
23930 (set_attr "mode" "V2DF")])
23931
23932 (define_split
23933 [(set (match_operand:DF 0 "register_operand" "")
23934 (vec_select:DF
23935 (match_operand:V2DF 1 "memory_operand" "")
23936 (parallel [(const_int 1)])))]
23937 "TARGET_SSE2 && reload_completed"
23938 [(const_int 0)]
23939 {
23940 emit_move_insn (operands[0], adjust_address (operands[1], DFmode, 8));
23941 DONE;
23942 })
23943
23944 ;; Load the high double of the target vector from the source scalar.
23945 (define_insn "sse2_loadhpd"
23946 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=Y,Y,o")
23947 (vec_concat:V2DF
23948 (vec_select:DF
23949 (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
23950 (parallel [(const_int 0)]))
23951 (match_operand:DF 2 "nonimmediate_operand" " m,Y,Y")))]
23952 "TARGET_SSE2"
23953 "@
23954 movhpd\t{%2, %0|%0, %2}
23955 unpcklpd\t{%2, %0|%0, %2}
23956 #"
23957 [(set_attr "type" "ssecvt")
23958 (set_attr "mode" "V2DF")])
23959
23960 (define_split
23961 [(set (match_operand:V2DF 0 "memory_operand" "")
23962 (vec_concat:V2DF
23963 (vec_select:DF (match_dup 0) (parallel [(const_int 0)]))
23964 (match_operand:DF 1 "register_operand" "")))]
23965 "TARGET_SSE2 && reload_completed"
23966 [(const_int 0)]
23967 {
23968 emit_move_insn (adjust_address (operands[0], DFmode, 8), operands[1]);
23969 DONE;
23970 })
23971
23972 ;; Store the low double of the source vector into the double destination.
23973 (define_expand "sse2_storelpd"
23974 [(set (match_operand:DF 0 "nonimmediate_operand" "")
23975 (vec_select:DF
23976 (match_operand:V2DF 1 "nonimmediate_operand" "")
23977 (parallel [(const_int 0)])))]
23978 "TARGET_SSE2"
23979 {
23980 operands[1] = gen_lowpart (DFmode, operands[1]);
23981 emit_move_insn (operands[0], operands[1]);
23982 DONE;
23983 })
23984
23985 ;; Load the low double of the target vector from the source scalar.
23986 (define_insn "sse2_loadlpd"
23987 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=Y,Y,m")
23988 (vec_concat:V2DF
23989 (match_operand:DF 2 "nonimmediate_operand" " m,Y,Y")
23990 (vec_select:DF
23991 (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
23992 (parallel [(const_int 1)]))))]
23993 "TARGET_SSE2"
23994 "@
23995 movlpd\t{%2, %0|%0, %2}
23996 movsd\t{%2, %0|%0, %2}
23997 movlpd\t{%2, %0|%0, %2}"
23998 [(set_attr "type" "ssecvt")
23999 (set_attr "mode" "V2DF")])
24000
24001 ;; Merge the low part of the source vector into the low part of the target.
24002 (define_insn "sse2_movsd"
24003 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=Y,Y,m")
24004 (vec_merge:V2DF
24005 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24006 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,Y")
24007 (const_int 2)))]
24008 "TARGET_SSE2"
24009 "@movsd\t{%2, %0|%0, %2}
24010 movlpd\t{%2, %0|%0, %2}
24011 movlpd\t{%2, %0|%0, %2}"
24012 [(set_attr "type" "ssecvt")
24013 (set_attr "mode" "DF,V2DF,V2DF")])
24014
24015 (define_expand "sse2_loadsd"
24016 [(match_operand:V2DF 0 "register_operand" "")
24017 (match_operand:DF 1 "memory_operand" "")]
24018 "TARGET_SSE2"
24019 {
24020 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24021 CONST0_RTX (V2DFmode)));
24022 DONE;
24023 })
24024
24025 (define_insn "sse2_loadsd_1"
24026 [(set (match_operand:V2DF 0 "register_operand" "=x")
24027 (vec_merge:V2DF
24028 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24029 (match_operand:V2DF 2 "const0_operand" "X")
24030 (const_int 1)))]
24031 "TARGET_SSE2"
24032 "movsd\t{%1, %0|%0, %1}"
24033 [(set_attr "type" "ssecvt")
24034 (set_attr "mode" "DF")])
24035
24036 (define_insn "sse2_storesd"
24037 [(set (match_operand:DF 0 "memory_operand" "=m")
24038 (vec_select:DF
24039 (match_operand:V2DF 1 "register_operand" "x")
24040 (parallel [(const_int 0)])))]
24041 "TARGET_SSE2"
24042 "movsd\t{%1, %0|%0, %1}"
24043 [(set_attr "type" "ssecvt")
24044 (set_attr "mode" "DF")])
24045
24046 (define_insn "sse2_shufpd"
24047 [(set (match_operand:V2DF 0 "register_operand" "=x")
24048 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24049 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24050 (match_operand:SI 3 "immediate_operand" "i")]
24051 UNSPEC_SHUFFLE))]
24052 "TARGET_SSE2"
24053 ;; @@@ check operand order for intel/nonintel syntax
24054 "shufpd\t{%3, %2, %0|%0, %2, %3}"
24055 [(set_attr "type" "ssecvt")
24056 (set_attr "mode" "V2DF")])
24057
24058 (define_insn "sse2_clflush"
24059 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24060 UNSPECV_CLFLUSH)]
24061 "TARGET_SSE2"
24062 "clflush\t%a0"
24063 [(set_attr "type" "sse")
24064 (set_attr "memory" "unknown")])
24065
24066 (define_expand "sse2_mfence"
24067 [(set (match_dup 0)
24068 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24069 "TARGET_SSE2"
24070 {
24071 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24072 MEM_VOLATILE_P (operands[0]) = 1;
24073 })
24074
24075 (define_insn "*mfence_insn"
24076 [(set (match_operand:BLK 0 "" "")
24077 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24078 "TARGET_SSE2"
24079 "mfence"
24080 [(set_attr "type" "sse")
24081 (set_attr "memory" "unknown")])
24082
24083 (define_expand "sse2_lfence"
24084 [(set (match_dup 0)
24085 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24086 "TARGET_SSE2"
24087 {
24088 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24089 MEM_VOLATILE_P (operands[0]) = 1;
24090 })
24091
24092 (define_insn "*lfence_insn"
24093 [(set (match_operand:BLK 0 "" "")
24094 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24095 "TARGET_SSE2"
24096 "lfence"
24097 [(set_attr "type" "sse")
24098 (set_attr "memory" "unknown")])
24099
24100 ;; SSE3
24101
24102 (define_insn "mwait"
24103 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24104 (match_operand:SI 1 "register_operand" "c")]
24105 UNSPECV_MWAIT)]
24106 "TARGET_SSE3"
24107 "mwait\t%0, %1"
24108 [(set_attr "length" "3")])
24109
24110 (define_insn "monitor"
24111 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24112 (match_operand:SI 1 "register_operand" "c")
24113 (match_operand:SI 2 "register_operand" "d")]
24114 UNSPECV_MONITOR)]
24115 "TARGET_SSE3"
24116 "monitor\t%0, %1, %2"
24117 [(set_attr "length" "3")])
24118
24119 ;; SSE3 arithmetic
24120
24121 (define_insn "addsubv4sf3"
24122 [(set (match_operand:V4SF 0 "register_operand" "=x")
24123 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24124 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24125 UNSPEC_ADDSUB))]
24126 "TARGET_SSE3"
24127 "addsubps\t{%2, %0|%0, %2}"
24128 [(set_attr "type" "sseadd")
24129 (set_attr "mode" "V4SF")])
24130
24131 (define_insn "addsubv2df3"
24132 [(set (match_operand:V2DF 0 "register_operand" "=x")
24133 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24134 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24135 UNSPEC_ADDSUB))]
24136 "TARGET_SSE3"
24137 "addsubpd\t{%2, %0|%0, %2}"
24138 [(set_attr "type" "sseadd")
24139 (set_attr "mode" "V2DF")])
24140
24141 (define_insn "haddv4sf3"
24142 [(set (match_operand:V4SF 0 "register_operand" "=x")
24143 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24144 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24145 UNSPEC_HADD))]
24146 "TARGET_SSE3"
24147 "haddps\t{%2, %0|%0, %2}"
24148 [(set_attr "type" "sseadd")
24149 (set_attr "mode" "V4SF")])
24150
24151 (define_insn "haddv2df3"
24152 [(set (match_operand:V2DF 0 "register_operand" "=x")
24153 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24154 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24155 UNSPEC_HADD))]
24156 "TARGET_SSE3"
24157 "haddpd\t{%2, %0|%0, %2}"
24158 [(set_attr "type" "sseadd")
24159 (set_attr "mode" "V2DF")])
24160
24161 (define_insn "hsubv4sf3"
24162 [(set (match_operand:V4SF 0 "register_operand" "=x")
24163 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24164 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24165 UNSPEC_HSUB))]
24166 "TARGET_SSE3"
24167 "hsubps\t{%2, %0|%0, %2}"
24168 [(set_attr "type" "sseadd")
24169 (set_attr "mode" "V4SF")])
24170
24171 (define_insn "hsubv2df3"
24172 [(set (match_operand:V2DF 0 "register_operand" "=x")
24173 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24174 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24175 UNSPEC_HSUB))]
24176 "TARGET_SSE3"
24177 "hsubpd\t{%2, %0|%0, %2}"
24178 [(set_attr "type" "sseadd")
24179 (set_attr "mode" "V2DF")])
24180
24181 (define_insn "movshdup"
24182 [(set (match_operand:V4SF 0 "register_operand" "=x")
24183 (unspec:V4SF
24184 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24185 "TARGET_SSE3"
24186 "movshdup\t{%1, %0|%0, %1}"
24187 [(set_attr "type" "sse")
24188 (set_attr "mode" "V4SF")])
24189
24190 (define_insn "movsldup"
24191 [(set (match_operand:V4SF 0 "register_operand" "=x")
24192 (unspec:V4SF
24193 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24194 "TARGET_SSE3"
24195 "movsldup\t{%1, %0|%0, %1}"
24196 [(set_attr "type" "sse")
24197 (set_attr "mode" "V4SF")])
24198
24199 (define_insn "lddqu"
24200 [(set (match_operand:V16QI 0 "register_operand" "=x")
24201 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24202 UNSPEC_LDQQU))]
24203 "TARGET_SSE3"
24204 "lddqu\t{%1, %0|%0, %1}"
24205 [(set_attr "type" "ssecvt")
24206 (set_attr "mode" "TI")])
24207
24208 (define_insn "loadddup"
24209 [(set (match_operand:V2DF 0 "register_operand" "=x")
24210 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24211 "TARGET_SSE3"
24212 "movddup\t{%1, %0|%0, %1}"
24213 [(set_attr "type" "ssecvt")
24214 (set_attr "mode" "DF")])
24215
24216 (define_insn "movddup"
24217 [(set (match_operand:V2DF 0 "register_operand" "=x")
24218 (vec_duplicate:V2DF
24219 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24220 (parallel [(const_int 0)]))))]
24221 "TARGET_SSE3"
24222 "movddup\t{%1, %0|%0, %1}"
24223 [(set_attr "type" "ssecvt")
24224 (set_attr "mode" "DF")])