]> gcc.gnu.org Git - gcc.git/blob - gcc/config/i386/i386.md
674d0935740aaf47126305640318ce0e7b992605
[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_FIX_NOTRUNC 31)
88 (UNSPEC_MASKMOV 32)
89 (UNSPEC_MOVMSK 33)
90 (UNSPEC_MOVNT 34)
91 (UNSPEC_MOVA 38)
92 (UNSPEC_MOVU 39)
93 (UNSPEC_SHUFFLE 41)
94 (UNSPEC_RCP 42)
95 (UNSPEC_RSQRT 43)
96 (UNSPEC_SFENCE 44)
97 (UNSPEC_NOP 45) ; prevents combiner cleverness
98 (UNSPEC_PAVGUSB 49)
99 (UNSPEC_PFRCP 50)
100 (UNSPEC_PFRCPIT1 51)
101 (UNSPEC_PFRCPIT2 52)
102 (UNSPEC_PFRSQRT 53)
103 (UNSPEC_PFRSQIT1 54)
104 (UNSPEC_PSHUFLW 55)
105 (UNSPEC_PSHUFHW 56)
106 (UNSPEC_MFENCE 59)
107 (UNSPEC_LFENCE 60)
108 (UNSPEC_PSADBW 61)
109 (UNSPEC_ADDSUB 71)
110 (UNSPEC_HADD 72)
111 (UNSPEC_HSUB 73)
112 (UNSPEC_MOVSHDUP 74)
113 (UNSPEC_MOVSLDUP 75)
114 (UNSPEC_LDQQU 76)
115 (UNSPEC_MOVDDUP 77)
116
117 ; x87 Floating point
118 (UNSPEC_FPATAN 65)
119 (UNSPEC_FYL2X 66)
120 (UNSPEC_FYL2XP1 67)
121 (UNSPEC_FRNDINT 68)
122 (UNSPEC_F2XM1 69)
123
124 ; x87 Double output FP
125 (UNSPEC_SINCOS_COS 80)
126 (UNSPEC_SINCOS_SIN 81)
127 (UNSPEC_TAN_ONE 82)
128 (UNSPEC_TAN_TAN 83)
129 (UNSPEC_XTRACT_FRACT 84)
130 (UNSPEC_XTRACT_EXP 85)
131 (UNSPEC_FSCALE_FRACT 86)
132 (UNSPEC_FSCALE_EXP 87)
133 (UNSPEC_FPREM_F 88)
134 (UNSPEC_FPREM_U 89)
135 (UNSPEC_FPREM1_F 90)
136 (UNSPEC_FPREM1_U 91)
137
138 ; x87 Rounding
139 (UNSPEC_FRNDINT_FLOOR 96)
140 (UNSPEC_FRNDINT_CEIL 97)
141 (UNSPEC_FRNDINT_TRUNC 98)
142 (UNSPEC_FRNDINT_MASK_PM 99)
143
144 ; REP instruction
145 (UNSPEC_REP 75)
146
147 (UNSPEC_EH_RETURN 76)
148 ])
149
150 (define_constants
151 [(UNSPECV_BLOCKAGE 0)
152 (UNSPECV_STACK_PROBE 10)
153 (UNSPECV_EMMS 31)
154 (UNSPECV_LDMXCSR 37)
155 (UNSPECV_STMXCSR 40)
156 (UNSPECV_FEMMS 46)
157 (UNSPECV_CLFLUSH 57)
158 (UNSPECV_ALIGN 68)
159 (UNSPECV_MONITOR 69)
160 (UNSPECV_MWAIT 70)
161 ])
162
163 ;; Registers by name.
164 (define_constants
165 [(BP_REG 6)
166 (SP_REG 7)
167 (FLAGS_REG 17)
168 (FPSR_REG 18)
169 (DIRFLAG_REG 19)
170 ])
171
172 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
173 ;; from i386.c.
174
175 ;; In C guard expressions, put expressions which may be compile-time
176 ;; constants first. This allows for better optimization. For
177 ;; example, write "TARGET_64BIT && reload_completed", not
178 ;; "reload_completed && TARGET_64BIT".
179
180 \f
181 ;; Processor type. This attribute must exactly match the processor_type
182 ;; enumeration in i386.h.
183 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
184 (const (symbol_ref "ix86_tune")))
185
186 ;; A basic instruction type. Refinements due to arguments to be
187 ;; provided in other attributes.
188 (define_attr "type"
189 "other,multi,
190 alu,alu1,negnot,imov,imovx,lea,
191 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
192 icmp,test,ibr,setcc,icmov,
193 push,pop,call,callv,leave,
194 str,cld,
195 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
196 sselog,sselog1,sseiadd,sseishft,sseimul,
197 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
198 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
199 (const_string "other"))
200
201 ;; Main data type used by the insn
202 (define_attr "mode"
203 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
204 (const_string "unknown"))
205
206 ;; The CPU unit operations uses.
207 (define_attr "unit" "integer,i387,sse,mmx,unknown"
208 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
209 (const_string "i387")
210 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
211 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
212 (const_string "sse")
213 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
214 (const_string "mmx")
215 (eq_attr "type" "other")
216 (const_string "unknown")]
217 (const_string "integer")))
218
219 ;; The (bounding maximum) length of an instruction immediate.
220 (define_attr "length_immediate" ""
221 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
222 (const_int 0)
223 (eq_attr "unit" "i387,sse,mmx")
224 (const_int 0)
225 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
226 imul,icmp,push,pop")
227 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
228 (eq_attr "type" "imov,test")
229 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
230 (eq_attr "type" "call")
231 (if_then_else (match_operand 0 "constant_call_address_operand" "")
232 (const_int 4)
233 (const_int 0))
234 (eq_attr "type" "callv")
235 (if_then_else (match_operand 1 "constant_call_address_operand" "")
236 (const_int 4)
237 (const_int 0))
238 ;; We don't know the size before shorten_branches. Expect
239 ;; the instruction to fit for better scheduling.
240 (eq_attr "type" "ibr")
241 (const_int 1)
242 ]
243 (symbol_ref "/* Update immediate_length and other attributes! */
244 abort(),1")))
245
246 ;; The (bounding maximum) length of an instruction address.
247 (define_attr "length_address" ""
248 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
249 (const_int 0)
250 (and (eq_attr "type" "call")
251 (match_operand 0 "constant_call_address_operand" ""))
252 (const_int 0)
253 (and (eq_attr "type" "callv")
254 (match_operand 1 "constant_call_address_operand" ""))
255 (const_int 0)
256 ]
257 (symbol_ref "ix86_attr_length_address_default (insn)")))
258
259 ;; Set when length prefix is used.
260 (define_attr "prefix_data16" ""
261 (if_then_else (ior (eq_attr "mode" "HI")
262 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
263 (const_int 1)
264 (const_int 0)))
265
266 ;; Set when string REP prefix is used.
267 (define_attr "prefix_rep" ""
268 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
269 (const_int 1)
270 (const_int 0)))
271
272 ;; Set when 0f opcode prefix is used.
273 (define_attr "prefix_0f" ""
274 (if_then_else
275 (ior (eq_attr "type" "imovx,setcc,icmov")
276 (eq_attr "unit" "sse,mmx"))
277 (const_int 1)
278 (const_int 0)))
279
280 ;; Set when REX opcode prefix is used.
281 (define_attr "prefix_rex" ""
282 (cond [(and (eq_attr "mode" "DI")
283 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
284 (const_int 1)
285 (and (eq_attr "mode" "QI")
286 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
287 (const_int 0)))
288 (const_int 1)
289 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
290 (const_int 0))
291 (const_int 1)
292 ]
293 (const_int 0)))
294
295 ;; Set when modrm byte is used.
296 (define_attr "modrm" ""
297 (cond [(eq_attr "type" "str,cld,leave")
298 (const_int 0)
299 (eq_attr "unit" "i387")
300 (const_int 0)
301 (and (eq_attr "type" "incdec")
302 (ior (match_operand:SI 1 "register_operand" "")
303 (match_operand:HI 1 "register_operand" "")))
304 (const_int 0)
305 (and (eq_attr "type" "push")
306 (not (match_operand 1 "memory_operand" "")))
307 (const_int 0)
308 (and (eq_attr "type" "pop")
309 (not (match_operand 0 "memory_operand" "")))
310 (const_int 0)
311 (and (eq_attr "type" "imov")
312 (and (match_operand 0 "register_operand" "")
313 (match_operand 1 "immediate_operand" "")))
314 (const_int 0)
315 (and (eq_attr "type" "call")
316 (match_operand 0 "constant_call_address_operand" ""))
317 (const_int 0)
318 (and (eq_attr "type" "callv")
319 (match_operand 1 "constant_call_address_operand" ""))
320 (const_int 0)
321 ]
322 (const_int 1)))
323
324 ;; The (bounding maximum) length of an instruction in bytes.
325 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
326 ;; Later we may want to split them and compute proper length as for
327 ;; other insns.
328 (define_attr "length" ""
329 (cond [(eq_attr "type" "other,multi,fistp,frndint")
330 (const_int 16)
331 (eq_attr "type" "fcmp")
332 (const_int 4)
333 (eq_attr "unit" "i387")
334 (plus (const_int 2)
335 (plus (attr "prefix_data16")
336 (attr "length_address")))]
337 (plus (plus (attr "modrm")
338 (plus (attr "prefix_0f")
339 (plus (attr "prefix_rex")
340 (const_int 1))))
341 (plus (attr "prefix_rep")
342 (plus (attr "prefix_data16")
343 (plus (attr "length_immediate")
344 (attr "length_address")))))))
345
346 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
347 ;; `store' if there is a simple memory reference therein, or `unknown'
348 ;; if the instruction is complex.
349
350 (define_attr "memory" "none,load,store,both,unknown"
351 (cond [(eq_attr "type" "other,multi,str")
352 (const_string "unknown")
353 (eq_attr "type" "lea,fcmov,fpspc,cld")
354 (const_string "none")
355 (eq_attr "type" "fistp,leave")
356 (const_string "both")
357 (eq_attr "type" "frndint")
358 (const_string "load")
359 (eq_attr "type" "push")
360 (if_then_else (match_operand 1 "memory_operand" "")
361 (const_string "both")
362 (const_string "store"))
363 (eq_attr "type" "pop")
364 (if_then_else (match_operand 0 "memory_operand" "")
365 (const_string "both")
366 (const_string "load"))
367 (eq_attr "type" "setcc")
368 (if_then_else (match_operand 0 "memory_operand" "")
369 (const_string "store")
370 (const_string "none"))
371 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
372 (if_then_else (ior (match_operand 0 "memory_operand" "")
373 (match_operand 1 "memory_operand" ""))
374 (const_string "load")
375 (const_string "none"))
376 (eq_attr "type" "ibr")
377 (if_then_else (match_operand 0 "memory_operand" "")
378 (const_string "load")
379 (const_string "none"))
380 (eq_attr "type" "call")
381 (if_then_else (match_operand 0 "constant_call_address_operand" "")
382 (const_string "none")
383 (const_string "load"))
384 (eq_attr "type" "callv")
385 (if_then_else (match_operand 1 "constant_call_address_operand" "")
386 (const_string "none")
387 (const_string "load"))
388 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
389 (match_operand 1 "memory_operand" ""))
390 (const_string "both")
391 (and (match_operand 0 "memory_operand" "")
392 (match_operand 1 "memory_operand" ""))
393 (const_string "both")
394 (match_operand 0 "memory_operand" "")
395 (const_string "store")
396 (match_operand 1 "memory_operand" "")
397 (const_string "load")
398 (and (eq_attr "type"
399 "!alu1,negnot,ishift1,
400 imov,imovx,icmp,test,
401 fmov,fcmp,fsgn,
402 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
403 mmx,mmxmov,mmxcmp,mmxcvt")
404 (match_operand 2 "memory_operand" ""))
405 (const_string "load")
406 (and (eq_attr "type" "icmov")
407 (match_operand 3 "memory_operand" ""))
408 (const_string "load")
409 ]
410 (const_string "none")))
411
412 ;; Indicates if an instruction has both an immediate and a displacement.
413
414 (define_attr "imm_disp" "false,true,unknown"
415 (cond [(eq_attr "type" "other,multi")
416 (const_string "unknown")
417 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
418 (and (match_operand 0 "memory_displacement_operand" "")
419 (match_operand 1 "immediate_operand" "")))
420 (const_string "true")
421 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
422 (and (match_operand 0 "memory_displacement_operand" "")
423 (match_operand 2 "immediate_operand" "")))
424 (const_string "true")
425 ]
426 (const_string "false")))
427
428 ;; Indicates if an FP operation has an integer source.
429
430 (define_attr "fp_int_src" "false,true"
431 (const_string "false"))
432
433 ;; Defines rounding mode of an FP operation.
434
435 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
436 (const_string "any"))
437
438 ;; Describe a user's asm statement.
439 (define_asm_attributes
440 [(set_attr "length" "128")
441 (set_attr "type" "multi")])
442 \f
443 ;; Scheduling descriptions
444
445 (include "pentium.md")
446 (include "ppro.md")
447 (include "k6.md")
448 (include "athlon.md")
449
450 \f
451 ;; Operand and operator predicates
452
453 (include "predicates.md")
454
455 \f
456 ;; Compare instructions.
457
458 ;; All compare insns have expanders that save the operands away without
459 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
460 ;; after the cmp) will actually emit the cmpM.
461
462 (define_expand "cmpdi"
463 [(set (reg:CC FLAGS_REG)
464 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
465 (match_operand:DI 1 "x86_64_general_operand" "")))]
466 ""
467 {
468 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
469 operands[0] = force_reg (DImode, operands[0]);
470 ix86_compare_op0 = operands[0];
471 ix86_compare_op1 = operands[1];
472 DONE;
473 })
474
475 (define_expand "cmpsi"
476 [(set (reg:CC FLAGS_REG)
477 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
478 (match_operand:SI 1 "general_operand" "")))]
479 ""
480 {
481 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
482 operands[0] = force_reg (SImode, operands[0]);
483 ix86_compare_op0 = operands[0];
484 ix86_compare_op1 = operands[1];
485 DONE;
486 })
487
488 (define_expand "cmphi"
489 [(set (reg:CC FLAGS_REG)
490 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
491 (match_operand:HI 1 "general_operand" "")))]
492 ""
493 {
494 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
495 operands[0] = force_reg (HImode, operands[0]);
496 ix86_compare_op0 = operands[0];
497 ix86_compare_op1 = operands[1];
498 DONE;
499 })
500
501 (define_expand "cmpqi"
502 [(set (reg:CC FLAGS_REG)
503 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
504 (match_operand:QI 1 "general_operand" "")))]
505 "TARGET_QIMODE_MATH"
506 {
507 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
508 operands[0] = force_reg (QImode, operands[0]);
509 ix86_compare_op0 = operands[0];
510 ix86_compare_op1 = operands[1];
511 DONE;
512 })
513
514 (define_insn "cmpdi_ccno_1_rex64"
515 [(set (reg FLAGS_REG)
516 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
517 (match_operand:DI 1 "const0_operand" "n,n")))]
518 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
519 "@
520 test{q}\t{%0, %0|%0, %0}
521 cmp{q}\t{%1, %0|%0, %1}"
522 [(set_attr "type" "test,icmp")
523 (set_attr "length_immediate" "0,1")
524 (set_attr "mode" "DI")])
525
526 (define_insn "*cmpdi_minus_1_rex64"
527 [(set (reg FLAGS_REG)
528 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
529 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
530 (const_int 0)))]
531 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
532 "cmp{q}\t{%1, %0|%0, %1}"
533 [(set_attr "type" "icmp")
534 (set_attr "mode" "DI")])
535
536 (define_expand "cmpdi_1_rex64"
537 [(set (reg:CC FLAGS_REG)
538 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
539 (match_operand:DI 1 "general_operand" "")))]
540 "TARGET_64BIT"
541 "")
542
543 (define_insn "cmpdi_1_insn_rex64"
544 [(set (reg FLAGS_REG)
545 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
546 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
547 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
548 "cmp{q}\t{%1, %0|%0, %1}"
549 [(set_attr "type" "icmp")
550 (set_attr "mode" "DI")])
551
552
553 (define_insn "*cmpsi_ccno_1"
554 [(set (reg FLAGS_REG)
555 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
556 (match_operand:SI 1 "const0_operand" "n,n")))]
557 "ix86_match_ccmode (insn, CCNOmode)"
558 "@
559 test{l}\t{%0, %0|%0, %0}
560 cmp{l}\t{%1, %0|%0, %1}"
561 [(set_attr "type" "test,icmp")
562 (set_attr "length_immediate" "0,1")
563 (set_attr "mode" "SI")])
564
565 (define_insn "*cmpsi_minus_1"
566 [(set (reg FLAGS_REG)
567 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
568 (match_operand:SI 1 "general_operand" "ri,mr"))
569 (const_int 0)))]
570 "ix86_match_ccmode (insn, CCGOCmode)"
571 "cmp{l}\t{%1, %0|%0, %1}"
572 [(set_attr "type" "icmp")
573 (set_attr "mode" "SI")])
574
575 (define_expand "cmpsi_1"
576 [(set (reg:CC FLAGS_REG)
577 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
578 (match_operand:SI 1 "general_operand" "ri,mr")))]
579 ""
580 "")
581
582 (define_insn "*cmpsi_1_insn"
583 [(set (reg FLAGS_REG)
584 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
585 (match_operand:SI 1 "general_operand" "ri,mr")))]
586 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
587 && ix86_match_ccmode (insn, CCmode)"
588 "cmp{l}\t{%1, %0|%0, %1}"
589 [(set_attr "type" "icmp")
590 (set_attr "mode" "SI")])
591
592 (define_insn "*cmphi_ccno_1"
593 [(set (reg FLAGS_REG)
594 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
595 (match_operand:HI 1 "const0_operand" "n,n")))]
596 "ix86_match_ccmode (insn, CCNOmode)"
597 "@
598 test{w}\t{%0, %0|%0, %0}
599 cmp{w}\t{%1, %0|%0, %1}"
600 [(set_attr "type" "test,icmp")
601 (set_attr "length_immediate" "0,1")
602 (set_attr "mode" "HI")])
603
604 (define_insn "*cmphi_minus_1"
605 [(set (reg FLAGS_REG)
606 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
607 (match_operand:HI 1 "general_operand" "ri,mr"))
608 (const_int 0)))]
609 "ix86_match_ccmode (insn, CCGOCmode)"
610 "cmp{w}\t{%1, %0|%0, %1}"
611 [(set_attr "type" "icmp")
612 (set_attr "mode" "HI")])
613
614 (define_insn "*cmphi_1"
615 [(set (reg FLAGS_REG)
616 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
617 (match_operand:HI 1 "general_operand" "ri,mr")))]
618 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
619 && ix86_match_ccmode (insn, CCmode)"
620 "cmp{w}\t{%1, %0|%0, %1}"
621 [(set_attr "type" "icmp")
622 (set_attr "mode" "HI")])
623
624 (define_insn "*cmpqi_ccno_1"
625 [(set (reg FLAGS_REG)
626 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
627 (match_operand:QI 1 "const0_operand" "n,n")))]
628 "ix86_match_ccmode (insn, CCNOmode)"
629 "@
630 test{b}\t{%0, %0|%0, %0}
631 cmp{b}\t{$0, %0|%0, 0}"
632 [(set_attr "type" "test,icmp")
633 (set_attr "length_immediate" "0,1")
634 (set_attr "mode" "QI")])
635
636 (define_insn "*cmpqi_1"
637 [(set (reg FLAGS_REG)
638 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
639 (match_operand:QI 1 "general_operand" "qi,mq")))]
640 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
641 && ix86_match_ccmode (insn, CCmode)"
642 "cmp{b}\t{%1, %0|%0, %1}"
643 [(set_attr "type" "icmp")
644 (set_attr "mode" "QI")])
645
646 (define_insn "*cmpqi_minus_1"
647 [(set (reg FLAGS_REG)
648 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
649 (match_operand:QI 1 "general_operand" "qi,mq"))
650 (const_int 0)))]
651 "ix86_match_ccmode (insn, CCGOCmode)"
652 "cmp{b}\t{%1, %0|%0, %1}"
653 [(set_attr "type" "icmp")
654 (set_attr "mode" "QI")])
655
656 (define_insn "*cmpqi_ext_1"
657 [(set (reg FLAGS_REG)
658 (compare
659 (match_operand:QI 0 "general_operand" "Qm")
660 (subreg:QI
661 (zero_extract:SI
662 (match_operand 1 "ext_register_operand" "Q")
663 (const_int 8)
664 (const_int 8)) 0)))]
665 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
666 "cmp{b}\t{%h1, %0|%0, %h1}"
667 [(set_attr "type" "icmp")
668 (set_attr "mode" "QI")])
669
670 (define_insn "*cmpqi_ext_1_rex64"
671 [(set (reg FLAGS_REG)
672 (compare
673 (match_operand:QI 0 "register_operand" "Q")
674 (subreg:QI
675 (zero_extract:SI
676 (match_operand 1 "ext_register_operand" "Q")
677 (const_int 8)
678 (const_int 8)) 0)))]
679 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
680 "cmp{b}\t{%h1, %0|%0, %h1}"
681 [(set_attr "type" "icmp")
682 (set_attr "mode" "QI")])
683
684 (define_insn "*cmpqi_ext_2"
685 [(set (reg FLAGS_REG)
686 (compare
687 (subreg:QI
688 (zero_extract:SI
689 (match_operand 0 "ext_register_operand" "Q")
690 (const_int 8)
691 (const_int 8)) 0)
692 (match_operand:QI 1 "const0_operand" "n")))]
693 "ix86_match_ccmode (insn, CCNOmode)"
694 "test{b}\t%h0, %h0"
695 [(set_attr "type" "test")
696 (set_attr "length_immediate" "0")
697 (set_attr "mode" "QI")])
698
699 (define_expand "cmpqi_ext_3"
700 [(set (reg:CC FLAGS_REG)
701 (compare:CC
702 (subreg:QI
703 (zero_extract:SI
704 (match_operand 0 "ext_register_operand" "")
705 (const_int 8)
706 (const_int 8)) 0)
707 (match_operand:QI 1 "general_operand" "")))]
708 ""
709 "")
710
711 (define_insn "cmpqi_ext_3_insn"
712 [(set (reg FLAGS_REG)
713 (compare
714 (subreg:QI
715 (zero_extract:SI
716 (match_operand 0 "ext_register_operand" "Q")
717 (const_int 8)
718 (const_int 8)) 0)
719 (match_operand:QI 1 "general_operand" "Qmn")))]
720 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721 "cmp{b}\t{%1, %h0|%h0, %1}"
722 [(set_attr "type" "icmp")
723 (set_attr "mode" "QI")])
724
725 (define_insn "cmpqi_ext_3_insn_rex64"
726 [(set (reg FLAGS_REG)
727 (compare
728 (subreg:QI
729 (zero_extract:SI
730 (match_operand 0 "ext_register_operand" "Q")
731 (const_int 8)
732 (const_int 8)) 0)
733 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
734 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735 "cmp{b}\t{%1, %h0|%h0, %1}"
736 [(set_attr "type" "icmp")
737 (set_attr "mode" "QI")])
738
739 (define_insn "*cmpqi_ext_4"
740 [(set (reg FLAGS_REG)
741 (compare
742 (subreg:QI
743 (zero_extract:SI
744 (match_operand 0 "ext_register_operand" "Q")
745 (const_int 8)
746 (const_int 8)) 0)
747 (subreg:QI
748 (zero_extract:SI
749 (match_operand 1 "ext_register_operand" "Q")
750 (const_int 8)
751 (const_int 8)) 0)))]
752 "ix86_match_ccmode (insn, CCmode)"
753 "cmp{b}\t{%h1, %h0|%h0, %h1}"
754 [(set_attr "type" "icmp")
755 (set_attr "mode" "QI")])
756
757 ;; These implement float point compares.
758 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
759 ;; which would allow mix and match FP modes on the compares. Which is what
760 ;; the old patterns did, but with many more of them.
761
762 (define_expand "cmpxf"
763 [(set (reg:CC FLAGS_REG)
764 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
765 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
766 "TARGET_80387"
767 {
768 ix86_compare_op0 = operands[0];
769 ix86_compare_op1 = operands[1];
770 DONE;
771 })
772
773 (define_expand "cmpdf"
774 [(set (reg:CC FLAGS_REG)
775 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
776 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
777 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
778 {
779 ix86_compare_op0 = operands[0];
780 ix86_compare_op1 = operands[1];
781 DONE;
782 })
783
784 (define_expand "cmpsf"
785 [(set (reg:CC FLAGS_REG)
786 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
787 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
788 "TARGET_80387 || TARGET_SSE_MATH"
789 {
790 ix86_compare_op0 = operands[0];
791 ix86_compare_op1 = operands[1];
792 DONE;
793 })
794
795 ;; FP compares, step 1:
796 ;; Set the FP condition codes.
797 ;;
798 ;; CCFPmode compare with exceptions
799 ;; CCFPUmode compare with no exceptions
800
801 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
802 ;; used to manage the reg stack popping would not be preserved.
803
804 (define_insn "*cmpfp_0_sf"
805 [(set (match_operand:HI 0 "register_operand" "=a")
806 (unspec:HI
807 [(compare:CCFP
808 (match_operand:SF 1 "register_operand" "f")
809 (match_operand:SF 2 "const0_operand" "X"))]
810 UNSPEC_FNSTSW))]
811 "TARGET_80387"
812 "* return output_fp_compare (insn, operands, 0, 0);"
813 [(set_attr "type" "multi")
814 (set_attr "mode" "SF")])
815
816 (define_insn "*cmpfp_0_df"
817 [(set (match_operand:HI 0 "register_operand" "=a")
818 (unspec:HI
819 [(compare:CCFP
820 (match_operand:DF 1 "register_operand" "f")
821 (match_operand:DF 2 "const0_operand" "X"))]
822 UNSPEC_FNSTSW))]
823 "TARGET_80387"
824 "* return output_fp_compare (insn, operands, 0, 0);"
825 [(set_attr "type" "multi")
826 (set_attr "mode" "DF")])
827
828 (define_insn "*cmpfp_0_xf"
829 [(set (match_operand:HI 0 "register_operand" "=a")
830 (unspec:HI
831 [(compare:CCFP
832 (match_operand:XF 1 "register_operand" "f")
833 (match_operand:XF 2 "const0_operand" "X"))]
834 UNSPEC_FNSTSW))]
835 "TARGET_80387"
836 "* return output_fp_compare (insn, operands, 0, 0);"
837 [(set_attr "type" "multi")
838 (set_attr "mode" "XF")])
839
840 (define_insn "*cmpfp_sf"
841 [(set (match_operand:HI 0 "register_operand" "=a")
842 (unspec:HI
843 [(compare:CCFP
844 (match_operand:SF 1 "register_operand" "f")
845 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
846 UNSPEC_FNSTSW))]
847 "TARGET_80387"
848 "* return output_fp_compare (insn, operands, 0, 0);"
849 [(set_attr "type" "multi")
850 (set_attr "mode" "SF")])
851
852 (define_insn "*cmpfp_df"
853 [(set (match_operand:HI 0 "register_operand" "=a")
854 (unspec:HI
855 [(compare:CCFP
856 (match_operand:DF 1 "register_operand" "f")
857 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
858 UNSPEC_FNSTSW))]
859 "TARGET_80387"
860 "* return output_fp_compare (insn, operands, 0, 0);"
861 [(set_attr "type" "multi")
862 (set_attr "mode" "DF")])
863
864 (define_insn "*cmpfp_xf"
865 [(set (match_operand:HI 0 "register_operand" "=a")
866 (unspec:HI
867 [(compare:CCFP
868 (match_operand:XF 1 "register_operand" "f")
869 (match_operand:XF 2 "register_operand" "f"))]
870 UNSPEC_FNSTSW))]
871 "TARGET_80387"
872 "* return output_fp_compare (insn, operands, 0, 0);"
873 [(set_attr "type" "multi")
874 (set_attr "mode" "XF")])
875
876 (define_insn "*cmpfp_u"
877 [(set (match_operand:HI 0 "register_operand" "=a")
878 (unspec:HI
879 [(compare:CCFPU
880 (match_operand 1 "register_operand" "f")
881 (match_operand 2 "register_operand" "f"))]
882 UNSPEC_FNSTSW))]
883 "TARGET_80387
884 && FLOAT_MODE_P (GET_MODE (operands[1]))
885 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
886 "* return output_fp_compare (insn, operands, 0, 1);"
887 [(set_attr "type" "multi")
888 (set (attr "mode")
889 (cond [(match_operand:SF 1 "" "")
890 (const_string "SF")
891 (match_operand:DF 1 "" "")
892 (const_string "DF")
893 ]
894 (const_string "XF")))])
895
896 (define_insn "*cmpfp_si"
897 [(set (match_operand:HI 0 "register_operand" "=a")
898 (unspec:HI
899 [(compare:CCFP
900 (match_operand 1 "register_operand" "f")
901 (match_operator 3 "float_operator"
902 [(match_operand:SI 2 "memory_operand" "m")]))]
903 UNSPEC_FNSTSW))]
904 "TARGET_80387 && TARGET_USE_FIOP
905 && FLOAT_MODE_P (GET_MODE (operands[1]))
906 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
907 "* return output_fp_compare (insn, operands, 0, 0);"
908 [(set_attr "type" "multi")
909 (set_attr "fp_int_src" "true")
910 (set_attr "mode" "SI")])
911
912 ;; FP compares, step 2
913 ;; Move the fpsw to ax.
914
915 (define_insn "x86_fnstsw_1"
916 [(set (match_operand:HI 0 "register_operand" "=a")
917 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
918 "TARGET_80387"
919 "fnstsw\t%0"
920 [(set_attr "length" "2")
921 (set_attr "mode" "SI")
922 (set_attr "unit" "i387")])
923
924 ;; FP compares, step 3
925 ;; Get ax into flags, general case.
926
927 (define_insn "x86_sahf_1"
928 [(set (reg:CC FLAGS_REG)
929 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
930 "!TARGET_64BIT"
931 "sahf"
932 [(set_attr "length" "1")
933 (set_attr "athlon_decode" "vector")
934 (set_attr "mode" "SI")])
935
936 ;; Pentium Pro can do steps 1 through 3 in one go.
937
938 (define_insn "*cmpfp_i_mixed"
939 [(set (reg:CCFP FLAGS_REG)
940 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
941 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
942 "TARGET_MIX_SSE_I387
943 && SSE_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,ssecomi")
947 (set (attr "mode")
948 (if_then_else (match_operand:SF 1 "" "")
949 (const_string "SF")
950 (const_string "DF")))
951 (set_attr "athlon_decode" "vector")])
952
953 (define_insn "*cmpfp_i_sse"
954 [(set (reg:CCFP FLAGS_REG)
955 (compare:CCFP (match_operand 0 "register_operand" "x")
956 (match_operand 1 "nonimmediate_operand" "xm")))]
957 "TARGET_SSE_MATH
958 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
959 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
960 "* return output_fp_compare (insn, operands, 1, 0);"
961 [(set_attr "type" "ssecomi")
962 (set (attr "mode")
963 (if_then_else (match_operand:SF 1 "" "")
964 (const_string "SF")
965 (const_string "DF")))
966 (set_attr "athlon_decode" "vector")])
967
968 (define_insn "*cmpfp_i_i387"
969 [(set (reg:CCFP FLAGS_REG)
970 (compare:CCFP (match_operand 0 "register_operand" "f")
971 (match_operand 1 "register_operand" "f")))]
972 "TARGET_80387 && TARGET_CMOVE
973 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
974 && FLOAT_MODE_P (GET_MODE (operands[0]))
975 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976 "* return output_fp_compare (insn, operands, 1, 0);"
977 [(set_attr "type" "fcmp")
978 (set (attr "mode")
979 (cond [(match_operand:SF 1 "" "")
980 (const_string "SF")
981 (match_operand:DF 1 "" "")
982 (const_string "DF")
983 ]
984 (const_string "XF")))
985 (set_attr "athlon_decode" "vector")])
986
987 (define_insn "*cmpfp_iu_mixed"
988 [(set (reg:CCFPU FLAGS_REG)
989 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
990 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
991 "TARGET_MIX_SSE_I387
992 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
993 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
994 "* return output_fp_compare (insn, operands, 1, 1);"
995 [(set_attr "type" "fcmp,ssecomi")
996 (set (attr "mode")
997 (if_then_else (match_operand:SF 1 "" "")
998 (const_string "SF")
999 (const_string "DF")))
1000 (set_attr "athlon_decode" "vector")])
1001
1002 (define_insn "*cmpfp_iu_sse"
1003 [(set (reg:CCFPU FLAGS_REG)
1004 (compare:CCFPU (match_operand 0 "register_operand" "x")
1005 (match_operand 1 "nonimmediate_operand" "xm")))]
1006 "TARGET_SSE_MATH
1007 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1008 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1009 "* return output_fp_compare (insn, operands, 1, 1);"
1010 [(set_attr "type" "ssecomi")
1011 (set (attr "mode")
1012 (if_then_else (match_operand:SF 1 "" "")
1013 (const_string "SF")
1014 (const_string "DF")))
1015 (set_attr "athlon_decode" "vector")])
1016
1017 (define_insn "*cmpfp_iu_387"
1018 [(set (reg:CCFPU FLAGS_REG)
1019 (compare:CCFPU (match_operand 0 "register_operand" "f")
1020 (match_operand 1 "register_operand" "f")))]
1021 "TARGET_80387 && TARGET_CMOVE
1022 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1023 && 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" "fcmp")
1027 (set (attr "mode")
1028 (cond [(match_operand:SF 1 "" "")
1029 (const_string "SF")
1030 (match_operand:DF 1 "" "")
1031 (const_string "DF")
1032 ]
1033 (const_string "XF")))
1034 (set_attr "athlon_decode" "vector")])
1035 \f
1036 ;; Move instructions.
1037
1038 ;; General case of fullword move.
1039
1040 (define_expand "movsi"
1041 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1042 (match_operand:SI 1 "general_operand" ""))]
1043 ""
1044 "ix86_expand_move (SImode, operands); DONE;")
1045
1046 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1047 ;; general_operand.
1048 ;;
1049 ;; %%% We don't use a post-inc memory reference because x86 is not a
1050 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1051 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1052 ;; targets without our curiosities, and it is just as easy to represent
1053 ;; this differently.
1054
1055 (define_insn "*pushsi2"
1056 [(set (match_operand:SI 0 "push_operand" "=<")
1057 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1058 "!TARGET_64BIT"
1059 "push{l}\t%1"
1060 [(set_attr "type" "push")
1061 (set_attr "mode" "SI")])
1062
1063 ;; For 64BIT abi we always round up to 8 bytes.
1064 (define_insn "*pushsi2_rex64"
1065 [(set (match_operand:SI 0 "push_operand" "=X")
1066 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1067 "TARGET_64BIT"
1068 "push{q}\t%q1"
1069 [(set_attr "type" "push")
1070 (set_attr "mode" "SI")])
1071
1072 (define_insn "*pushsi2_prologue"
1073 [(set (match_operand:SI 0 "push_operand" "=<")
1074 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1075 (clobber (mem:BLK (scratch)))]
1076 "!TARGET_64BIT"
1077 "push{l}\t%1"
1078 [(set_attr "type" "push")
1079 (set_attr "mode" "SI")])
1080
1081 (define_insn "*popsi1_epilogue"
1082 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1083 (mem:SI (reg:SI SP_REG)))
1084 (set (reg:SI SP_REG)
1085 (plus:SI (reg:SI SP_REG) (const_int 4)))
1086 (clobber (mem:BLK (scratch)))]
1087 "!TARGET_64BIT"
1088 "pop{l}\t%0"
1089 [(set_attr "type" "pop")
1090 (set_attr "mode" "SI")])
1091
1092 (define_insn "popsi1"
1093 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1094 (mem:SI (reg:SI SP_REG)))
1095 (set (reg:SI SP_REG)
1096 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1097 "!TARGET_64BIT"
1098 "pop{l}\t%0"
1099 [(set_attr "type" "pop")
1100 (set_attr "mode" "SI")])
1101
1102 (define_insn "*movsi_xor"
1103 [(set (match_operand:SI 0 "register_operand" "=r")
1104 (match_operand:SI 1 "const0_operand" "i"))
1105 (clobber (reg:CC FLAGS_REG))]
1106 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1107 "xor{l}\t{%0, %0|%0, %0}"
1108 [(set_attr "type" "alu1")
1109 (set_attr "mode" "SI")
1110 (set_attr "length_immediate" "0")])
1111
1112 (define_insn "*movsi_or"
1113 [(set (match_operand:SI 0 "register_operand" "=r")
1114 (match_operand:SI 1 "immediate_operand" "i"))
1115 (clobber (reg:CC FLAGS_REG))]
1116 "reload_completed
1117 && operands[1] == constm1_rtx
1118 && (TARGET_PENTIUM || optimize_size)"
1119 {
1120 operands[1] = constm1_rtx;
1121 return "or{l}\t{%1, %0|%0, %1}";
1122 }
1123 [(set_attr "type" "alu1")
1124 (set_attr "mode" "SI")
1125 (set_attr "length_immediate" "1")])
1126
1127 (define_insn "*movsi_1"
1128 [(set (match_operand:SI 0 "nonimmediate_operand"
1129 "=r ,m ,!*y,!rm,!*y,!*x,!rm,!*x")
1130 (match_operand:SI 1 "general_operand"
1131 "rinm,rin,*y ,*y ,rm ,*x ,*x ,rm"))]
1132 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1133 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1134 {
1135 switch (get_attr_type (insn))
1136 {
1137 case TYPE_SSEMOV:
1138 if (get_attr_mode (insn) == MODE_TI)
1139 return "movdqa\t{%1, %0|%0, %1}";
1140 return "movd\t{%1, %0|%0, %1}";
1141
1142 case TYPE_MMXMOV:
1143 if (get_attr_mode (insn) == MODE_DI)
1144 return "movq\t{%1, %0|%0, %1}";
1145 return "movd\t{%1, %0|%0, %1}";
1146
1147 case TYPE_LEA:
1148 return "lea{l}\t{%1, %0|%0, %1}";
1149
1150 default:
1151 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1152 abort();
1153 return "mov{l}\t{%1, %0|%0, %1}";
1154 }
1155 }
1156 [(set (attr "type")
1157 (cond [(eq_attr "alternative" "2,3,4")
1158 (const_string "mmxmov")
1159 (eq_attr "alternative" "5,6,7")
1160 (const_string "ssemov")
1161 (and (ne (symbol_ref "flag_pic") (const_int 0))
1162 (match_operand:SI 1 "symbolic_operand" ""))
1163 (const_string "lea")
1164 ]
1165 (const_string "imov")))
1166 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1167
1168 (define_insn "*movsi_1_nointernunit"
1169 [(set (match_operand:SI 0 "nonimmediate_operand"
1170 "=r ,m ,!*y,!m,!*y,!*x,!m,!*x")
1171 (match_operand:SI 1 "general_operand"
1172 "rinm,rin,*y ,*y,m ,*x ,*x,m"))]
1173 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1174 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1175 {
1176 switch (get_attr_type (insn))
1177 {
1178 case TYPE_SSEMOV:
1179 if (get_attr_mode (insn) == MODE_TI)
1180 return "movdqa\t{%1, %0|%0, %1}";
1181 return "movd\t{%1, %0|%0, %1}";
1182
1183 case TYPE_MMXMOV:
1184 if (get_attr_mode (insn) == MODE_DI)
1185 return "movq\t{%1, %0|%0, %1}";
1186 return "movd\t{%1, %0|%0, %1}";
1187
1188 case TYPE_LEA:
1189 return "lea{l}\t{%1, %0|%0, %1}";
1190
1191 default:
1192 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1193 abort();
1194 return "mov{l}\t{%1, %0|%0, %1}";
1195 }
1196 }
1197 [(set (attr "type")
1198 (cond [(eq_attr "alternative" "2,3,4")
1199 (const_string "mmxmov")
1200 (eq_attr "alternative" "5,6,7")
1201 (const_string "ssemov")
1202 (and (ne (symbol_ref "flag_pic") (const_int 0))
1203 (match_operand:SI 1 "symbolic_operand" ""))
1204 (const_string "lea")
1205 ]
1206 (const_string "imov")))
1207 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1208
1209 ;; Stores and loads of ax to arbitrary constant address.
1210 ;; We fake an second form of instruction to force reload to load address
1211 ;; into register when rax is not available
1212 (define_insn "*movabssi_1_rex64"
1213 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1214 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1215 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1216 "@
1217 movabs{l}\t{%1, %P0|%P0, %1}
1218 mov{l}\t{%1, %a0|%a0, %1}"
1219 [(set_attr "type" "imov")
1220 (set_attr "modrm" "0,*")
1221 (set_attr "length_address" "8,0")
1222 (set_attr "length_immediate" "0,*")
1223 (set_attr "memory" "store")
1224 (set_attr "mode" "SI")])
1225
1226 (define_insn "*movabssi_2_rex64"
1227 [(set (match_operand:SI 0 "register_operand" "=a,r")
1228 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1229 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1230 "@
1231 movabs{l}\t{%P1, %0|%0, %P1}
1232 mov{l}\t{%a1, %0|%0, %a1}"
1233 [(set_attr "type" "imov")
1234 (set_attr "modrm" "0,*")
1235 (set_attr "length_address" "8,0")
1236 (set_attr "length_immediate" "0")
1237 (set_attr "memory" "load")
1238 (set_attr "mode" "SI")])
1239
1240 (define_insn "*swapsi"
1241 [(set (match_operand:SI 0 "register_operand" "+r")
1242 (match_operand:SI 1 "register_operand" "+r"))
1243 (set (match_dup 1)
1244 (match_dup 0))]
1245 ""
1246 "xchg{l}\t%1, %0"
1247 [(set_attr "type" "imov")
1248 (set_attr "mode" "SI")
1249 (set_attr "pent_pair" "np")
1250 (set_attr "athlon_decode" "vector")])
1251
1252 (define_expand "movhi"
1253 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1254 (match_operand:HI 1 "general_operand" ""))]
1255 ""
1256 "ix86_expand_move (HImode, operands); DONE;")
1257
1258 (define_insn "*pushhi2"
1259 [(set (match_operand:HI 0 "push_operand" "=<,<")
1260 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1261 "!TARGET_64BIT"
1262 "@
1263 push{w}\t{|WORD PTR }%1
1264 push{w}\t%1"
1265 [(set_attr "type" "push")
1266 (set_attr "mode" "HI")])
1267
1268 ;; For 64BIT abi we always round up to 8 bytes.
1269 (define_insn "*pushhi2_rex64"
1270 [(set (match_operand:HI 0 "push_operand" "=X")
1271 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1272 "TARGET_64BIT"
1273 "push{q}\t%q1"
1274 [(set_attr "type" "push")
1275 (set_attr "mode" "QI")])
1276
1277 (define_insn "*movhi_1"
1278 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1279 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1280 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1281 {
1282 switch (get_attr_type (insn))
1283 {
1284 case TYPE_IMOVX:
1285 /* movzwl is faster than movw on p2 due to partial word stalls,
1286 though not as fast as an aligned movl. */
1287 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1288 default:
1289 if (get_attr_mode (insn) == MODE_SI)
1290 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1291 else
1292 return "mov{w}\t{%1, %0|%0, %1}";
1293 }
1294 }
1295 [(set (attr "type")
1296 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1297 (const_string "imov")
1298 (and (eq_attr "alternative" "0")
1299 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1300 (const_int 0))
1301 (eq (symbol_ref "TARGET_HIMODE_MATH")
1302 (const_int 0))))
1303 (const_string "imov")
1304 (and (eq_attr "alternative" "1,2")
1305 (match_operand:HI 1 "aligned_operand" ""))
1306 (const_string "imov")
1307 (and (ne (symbol_ref "TARGET_MOVX")
1308 (const_int 0))
1309 (eq_attr "alternative" "0,2"))
1310 (const_string "imovx")
1311 ]
1312 (const_string "imov")))
1313 (set (attr "mode")
1314 (cond [(eq_attr "type" "imovx")
1315 (const_string "SI")
1316 (and (eq_attr "alternative" "1,2")
1317 (match_operand:HI 1 "aligned_operand" ""))
1318 (const_string "SI")
1319 (and (eq_attr "alternative" "0")
1320 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1321 (const_int 0))
1322 (eq (symbol_ref "TARGET_HIMODE_MATH")
1323 (const_int 0))))
1324 (const_string "SI")
1325 ]
1326 (const_string "HI")))])
1327
1328 ;; Stores and loads of ax to arbitrary constant address.
1329 ;; We fake an second form of instruction to force reload to load address
1330 ;; into register when rax is not available
1331 (define_insn "*movabshi_1_rex64"
1332 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1333 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1334 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1335 "@
1336 movabs{w}\t{%1, %P0|%P0, %1}
1337 mov{w}\t{%1, %a0|%a0, %1}"
1338 [(set_attr "type" "imov")
1339 (set_attr "modrm" "0,*")
1340 (set_attr "length_address" "8,0")
1341 (set_attr "length_immediate" "0,*")
1342 (set_attr "memory" "store")
1343 (set_attr "mode" "HI")])
1344
1345 (define_insn "*movabshi_2_rex64"
1346 [(set (match_operand:HI 0 "register_operand" "=a,r")
1347 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1348 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1349 "@
1350 movabs{w}\t{%P1, %0|%0, %P1}
1351 mov{w}\t{%a1, %0|%0, %a1}"
1352 [(set_attr "type" "imov")
1353 (set_attr "modrm" "0,*")
1354 (set_attr "length_address" "8,0")
1355 (set_attr "length_immediate" "0")
1356 (set_attr "memory" "load")
1357 (set_attr "mode" "HI")])
1358
1359 (define_insn "*swaphi_1"
1360 [(set (match_operand:HI 0 "register_operand" "+r")
1361 (match_operand:HI 1 "register_operand" "+r"))
1362 (set (match_dup 1)
1363 (match_dup 0))]
1364 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1365 "xchg{l}\t%k1, %k0"
1366 [(set_attr "type" "imov")
1367 (set_attr "mode" "SI")
1368 (set_attr "pent_pair" "np")
1369 (set_attr "athlon_decode" "vector")])
1370
1371 (define_insn "*swaphi_2"
1372 [(set (match_operand:HI 0 "register_operand" "+r")
1373 (match_operand:HI 1 "register_operand" "+r"))
1374 (set (match_dup 1)
1375 (match_dup 0))]
1376 "TARGET_PARTIAL_REG_STALL"
1377 "xchg{w}\t%1, %0"
1378 [(set_attr "type" "imov")
1379 (set_attr "mode" "HI")
1380 (set_attr "pent_pair" "np")
1381 (set_attr "athlon_decode" "vector")])
1382
1383 (define_expand "movstricthi"
1384 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1385 (match_operand:HI 1 "general_operand" ""))]
1386 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1387 {
1388 /* Don't generate memory->memory moves, go through a register */
1389 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1390 operands[1] = force_reg (HImode, operands[1]);
1391 })
1392
1393 (define_insn "*movstricthi_1"
1394 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1395 (match_operand:HI 1 "general_operand" "rn,m"))]
1396 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1397 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1398 "mov{w}\t{%1, %0|%0, %1}"
1399 [(set_attr "type" "imov")
1400 (set_attr "mode" "HI")])
1401
1402 (define_insn "*movstricthi_xor"
1403 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1404 (match_operand:HI 1 "const0_operand" "i"))
1405 (clobber (reg:CC FLAGS_REG))]
1406 "reload_completed
1407 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1408 "xor{w}\t{%0, %0|%0, %0}"
1409 [(set_attr "type" "alu1")
1410 (set_attr "mode" "HI")
1411 (set_attr "length_immediate" "0")])
1412
1413 (define_expand "movqi"
1414 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1415 (match_operand:QI 1 "general_operand" ""))]
1416 ""
1417 "ix86_expand_move (QImode, operands); DONE;")
1418
1419 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1420 ;; "push a byte". But actually we use pushw, which has the effect
1421 ;; of rounding the amount pushed up to a halfword.
1422
1423 (define_insn "*pushqi2"
1424 [(set (match_operand:QI 0 "push_operand" "=X,X")
1425 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1426 "!TARGET_64BIT"
1427 "@
1428 push{w}\t{|word ptr }%1
1429 push{w}\t%w1"
1430 [(set_attr "type" "push")
1431 (set_attr "mode" "HI")])
1432
1433 ;; For 64BIT abi we always round up to 8 bytes.
1434 (define_insn "*pushqi2_rex64"
1435 [(set (match_operand:QI 0 "push_operand" "=X")
1436 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1437 "TARGET_64BIT"
1438 "push{q}\t%q1"
1439 [(set_attr "type" "push")
1440 (set_attr "mode" "QI")])
1441
1442 ;; Situation is quite tricky about when to choose full sized (SImode) move
1443 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1444 ;; partial register dependency machines (such as AMD Athlon), where QImode
1445 ;; moves issue extra dependency and for partial register stalls machines
1446 ;; that don't use QImode patterns (and QImode move cause stall on the next
1447 ;; instruction).
1448 ;;
1449 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1450 ;; register stall machines with, where we use QImode instructions, since
1451 ;; partial register stall can be caused there. Then we use movzx.
1452 (define_insn "*movqi_1"
1453 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1454 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1455 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1456 {
1457 switch (get_attr_type (insn))
1458 {
1459 case TYPE_IMOVX:
1460 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1461 abort ();
1462 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1463 default:
1464 if (get_attr_mode (insn) == MODE_SI)
1465 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1466 else
1467 return "mov{b}\t{%1, %0|%0, %1}";
1468 }
1469 }
1470 [(set (attr "type")
1471 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1472 (const_string "imov")
1473 (and (eq_attr "alternative" "3")
1474 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1475 (const_int 0))
1476 (eq (symbol_ref "TARGET_QIMODE_MATH")
1477 (const_int 0))))
1478 (const_string "imov")
1479 (eq_attr "alternative" "3,5")
1480 (const_string "imovx")
1481 (and (ne (symbol_ref "TARGET_MOVX")
1482 (const_int 0))
1483 (eq_attr "alternative" "2"))
1484 (const_string "imovx")
1485 ]
1486 (const_string "imov")))
1487 (set (attr "mode")
1488 (cond [(eq_attr "alternative" "3,4,5")
1489 (const_string "SI")
1490 (eq_attr "alternative" "6")
1491 (const_string "QI")
1492 (eq_attr "type" "imovx")
1493 (const_string "SI")
1494 (and (eq_attr "type" "imov")
1495 (and (eq_attr "alternative" "0,1")
1496 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1497 (const_int 0))))
1498 (const_string "SI")
1499 ;; Avoid partial register stalls when not using QImode arithmetic
1500 (and (eq_attr "type" "imov")
1501 (and (eq_attr "alternative" "0,1")
1502 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1503 (const_int 0))
1504 (eq (symbol_ref "TARGET_QIMODE_MATH")
1505 (const_int 0)))))
1506 (const_string "SI")
1507 ]
1508 (const_string "QI")))])
1509
1510 (define_expand "reload_outqi"
1511 [(parallel [(match_operand:QI 0 "" "=m")
1512 (match_operand:QI 1 "register_operand" "r")
1513 (match_operand:QI 2 "register_operand" "=&q")])]
1514 ""
1515 {
1516 rtx op0, op1, op2;
1517 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1518
1519 if (reg_overlap_mentioned_p (op2, op0))
1520 abort ();
1521 if (! q_regs_operand (op1, QImode))
1522 {
1523 emit_insn (gen_movqi (op2, op1));
1524 op1 = op2;
1525 }
1526 emit_insn (gen_movqi (op0, op1));
1527 DONE;
1528 })
1529
1530 (define_insn "*swapqi_1"
1531 [(set (match_operand:QI 0 "register_operand" "+r")
1532 (match_operand:QI 1 "register_operand" "+r"))
1533 (set (match_dup 1)
1534 (match_dup 0))]
1535 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1536 "xchg{l}\t%k1, %k0"
1537 [(set_attr "type" "imov")
1538 (set_attr "mode" "SI")
1539 (set_attr "pent_pair" "np")
1540 (set_attr "athlon_decode" "vector")])
1541
1542 (define_insn "*swapqi_2"
1543 [(set (match_operand:QI 0 "register_operand" "+q")
1544 (match_operand:QI 1 "register_operand" "+q"))
1545 (set (match_dup 1)
1546 (match_dup 0))]
1547 "TARGET_PARTIAL_REG_STALL"
1548 "xchg{b}\t%1, %0"
1549 [(set_attr "type" "imov")
1550 (set_attr "mode" "QI")
1551 (set_attr "pent_pair" "np")
1552 (set_attr "athlon_decode" "vector")])
1553
1554 (define_expand "movstrictqi"
1555 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1556 (match_operand:QI 1 "general_operand" ""))]
1557 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1558 {
1559 /* Don't generate memory->memory moves, go through a register. */
1560 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1561 operands[1] = force_reg (QImode, operands[1]);
1562 })
1563
1564 (define_insn "*movstrictqi_1"
1565 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1566 (match_operand:QI 1 "general_operand" "*qn,m"))]
1567 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1568 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1569 "mov{b}\t{%1, %0|%0, %1}"
1570 [(set_attr "type" "imov")
1571 (set_attr "mode" "QI")])
1572
1573 (define_insn "*movstrictqi_xor"
1574 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1575 (match_operand:QI 1 "const0_operand" "i"))
1576 (clobber (reg:CC FLAGS_REG))]
1577 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1578 "xor{b}\t{%0, %0|%0, %0}"
1579 [(set_attr "type" "alu1")
1580 (set_attr "mode" "QI")
1581 (set_attr "length_immediate" "0")])
1582
1583 (define_insn "*movsi_extv_1"
1584 [(set (match_operand:SI 0 "register_operand" "=R")
1585 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1586 (const_int 8)
1587 (const_int 8)))]
1588 ""
1589 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1590 [(set_attr "type" "imovx")
1591 (set_attr "mode" "SI")])
1592
1593 (define_insn "*movhi_extv_1"
1594 [(set (match_operand:HI 0 "register_operand" "=R")
1595 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1596 (const_int 8)
1597 (const_int 8)))]
1598 ""
1599 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1600 [(set_attr "type" "imovx")
1601 (set_attr "mode" "SI")])
1602
1603 (define_insn "*movqi_extv_1"
1604 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1605 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1606 (const_int 8)
1607 (const_int 8)))]
1608 "!TARGET_64BIT"
1609 {
1610 switch (get_attr_type (insn))
1611 {
1612 case TYPE_IMOVX:
1613 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1614 default:
1615 return "mov{b}\t{%h1, %0|%0, %h1}";
1616 }
1617 }
1618 [(set (attr "type")
1619 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1620 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1621 (ne (symbol_ref "TARGET_MOVX")
1622 (const_int 0))))
1623 (const_string "imovx")
1624 (const_string "imov")))
1625 (set (attr "mode")
1626 (if_then_else (eq_attr "type" "imovx")
1627 (const_string "SI")
1628 (const_string "QI")))])
1629
1630 (define_insn "*movqi_extv_1_rex64"
1631 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1632 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1633 (const_int 8)
1634 (const_int 8)))]
1635 "TARGET_64BIT"
1636 {
1637 switch (get_attr_type (insn))
1638 {
1639 case TYPE_IMOVX:
1640 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1641 default:
1642 return "mov{b}\t{%h1, %0|%0, %h1}";
1643 }
1644 }
1645 [(set (attr "type")
1646 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1647 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1648 (ne (symbol_ref "TARGET_MOVX")
1649 (const_int 0))))
1650 (const_string "imovx")
1651 (const_string "imov")))
1652 (set (attr "mode")
1653 (if_then_else (eq_attr "type" "imovx")
1654 (const_string "SI")
1655 (const_string "QI")))])
1656
1657 ;; Stores and loads of ax to arbitrary constant address.
1658 ;; We fake an second form of instruction to force reload to load address
1659 ;; into register when rax is not available
1660 (define_insn "*movabsqi_1_rex64"
1661 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1662 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1663 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1664 "@
1665 movabs{b}\t{%1, %P0|%P0, %1}
1666 mov{b}\t{%1, %a0|%a0, %1}"
1667 [(set_attr "type" "imov")
1668 (set_attr "modrm" "0,*")
1669 (set_attr "length_address" "8,0")
1670 (set_attr "length_immediate" "0,*")
1671 (set_attr "memory" "store")
1672 (set_attr "mode" "QI")])
1673
1674 (define_insn "*movabsqi_2_rex64"
1675 [(set (match_operand:QI 0 "register_operand" "=a,r")
1676 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1677 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1678 "@
1679 movabs{b}\t{%P1, %0|%0, %P1}
1680 mov{b}\t{%a1, %0|%0, %a1}"
1681 [(set_attr "type" "imov")
1682 (set_attr "modrm" "0,*")
1683 (set_attr "length_address" "8,0")
1684 (set_attr "length_immediate" "0")
1685 (set_attr "memory" "load")
1686 (set_attr "mode" "QI")])
1687
1688 (define_insn "*movsi_extzv_1"
1689 [(set (match_operand:SI 0 "register_operand" "=R")
1690 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1691 (const_int 8)
1692 (const_int 8)))]
1693 ""
1694 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1695 [(set_attr "type" "imovx")
1696 (set_attr "mode" "SI")])
1697
1698 (define_insn "*movqi_extzv_2"
1699 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1700 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1701 (const_int 8)
1702 (const_int 8)) 0))]
1703 "!TARGET_64BIT"
1704 {
1705 switch (get_attr_type (insn))
1706 {
1707 case TYPE_IMOVX:
1708 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1709 default:
1710 return "mov{b}\t{%h1, %0|%0, %h1}";
1711 }
1712 }
1713 [(set (attr "type")
1714 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1715 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1716 (ne (symbol_ref "TARGET_MOVX")
1717 (const_int 0))))
1718 (const_string "imovx")
1719 (const_string "imov")))
1720 (set (attr "mode")
1721 (if_then_else (eq_attr "type" "imovx")
1722 (const_string "SI")
1723 (const_string "QI")))])
1724
1725 (define_insn "*movqi_extzv_2_rex64"
1726 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1727 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1728 (const_int 8)
1729 (const_int 8)) 0))]
1730 "TARGET_64BIT"
1731 {
1732 switch (get_attr_type (insn))
1733 {
1734 case TYPE_IMOVX:
1735 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1736 default:
1737 return "mov{b}\t{%h1, %0|%0, %h1}";
1738 }
1739 }
1740 [(set (attr "type")
1741 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1742 (ne (symbol_ref "TARGET_MOVX")
1743 (const_int 0)))
1744 (const_string "imovx")
1745 (const_string "imov")))
1746 (set (attr "mode")
1747 (if_then_else (eq_attr "type" "imovx")
1748 (const_string "SI")
1749 (const_string "QI")))])
1750
1751 (define_insn "movsi_insv_1"
1752 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1753 (const_int 8)
1754 (const_int 8))
1755 (match_operand:SI 1 "general_operand" "Qmn"))]
1756 "!TARGET_64BIT"
1757 "mov{b}\t{%b1, %h0|%h0, %b1}"
1758 [(set_attr "type" "imov")
1759 (set_attr "mode" "QI")])
1760
1761 (define_insn "movdi_insv_1_rex64"
1762 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1763 (const_int 8)
1764 (const_int 8))
1765 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1766 "TARGET_64BIT"
1767 "mov{b}\t{%b1, %h0|%h0, %b1}"
1768 [(set_attr "type" "imov")
1769 (set_attr "mode" "QI")])
1770
1771 (define_insn "*movqi_insv_2"
1772 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1773 (const_int 8)
1774 (const_int 8))
1775 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1776 (const_int 8)))]
1777 ""
1778 "mov{b}\t{%h1, %h0|%h0, %h1}"
1779 [(set_attr "type" "imov")
1780 (set_attr "mode" "QI")])
1781
1782 (define_expand "movdi"
1783 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1784 (match_operand:DI 1 "general_operand" ""))]
1785 ""
1786 "ix86_expand_move (DImode, operands); DONE;")
1787
1788 (define_insn "*pushdi"
1789 [(set (match_operand:DI 0 "push_operand" "=<")
1790 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1791 "!TARGET_64BIT"
1792 "#")
1793
1794 (define_insn "*pushdi2_rex64"
1795 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1796 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1797 "TARGET_64BIT"
1798 "@
1799 push{q}\t%1
1800 #"
1801 [(set_attr "type" "push,multi")
1802 (set_attr "mode" "DI")])
1803
1804 ;; Convert impossible pushes of immediate to existing instructions.
1805 ;; First try to get scratch register and go through it. In case this
1806 ;; fails, push sign extended lower part first and then overwrite
1807 ;; upper part by 32bit move.
1808 (define_peephole2
1809 [(match_scratch:DI 2 "r")
1810 (set (match_operand:DI 0 "push_operand" "")
1811 (match_operand:DI 1 "immediate_operand" ""))]
1812 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1813 && !x86_64_immediate_operand (operands[1], DImode)"
1814 [(set (match_dup 2) (match_dup 1))
1815 (set (match_dup 0) (match_dup 2))]
1816 "")
1817
1818 ;; We need to define this as both peepholer and splitter for case
1819 ;; peephole2 pass is not run.
1820 ;; "&& 1" is needed to keep it from matching the previous pattern.
1821 (define_peephole2
1822 [(set (match_operand:DI 0 "push_operand" "")
1823 (match_operand:DI 1 "immediate_operand" ""))]
1824 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1825 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1826 [(set (match_dup 0) (match_dup 1))
1827 (set (match_dup 2) (match_dup 3))]
1828 "split_di (operands + 1, 1, operands + 2, operands + 3);
1829 operands[1] = gen_lowpart (DImode, operands[2]);
1830 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1831 GEN_INT (4)));
1832 ")
1833
1834 (define_split
1835 [(set (match_operand:DI 0 "push_operand" "")
1836 (match_operand:DI 1 "immediate_operand" ""))]
1837 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1838 && !symbolic_operand (operands[1], DImode)
1839 && !x86_64_immediate_operand (operands[1], DImode)"
1840 [(set (match_dup 0) (match_dup 1))
1841 (set (match_dup 2) (match_dup 3))]
1842 "split_di (operands + 1, 1, operands + 2, operands + 3);
1843 operands[1] = gen_lowpart (DImode, operands[2]);
1844 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1845 GEN_INT (4)));
1846 ")
1847
1848 (define_insn "*pushdi2_prologue_rex64"
1849 [(set (match_operand:DI 0 "push_operand" "=<")
1850 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1851 (clobber (mem:BLK (scratch)))]
1852 "TARGET_64BIT"
1853 "push{q}\t%1"
1854 [(set_attr "type" "push")
1855 (set_attr "mode" "DI")])
1856
1857 (define_insn "*popdi1_epilogue_rex64"
1858 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1859 (mem:DI (reg:DI SP_REG)))
1860 (set (reg:DI SP_REG)
1861 (plus:DI (reg:DI SP_REG) (const_int 8)))
1862 (clobber (mem:BLK (scratch)))]
1863 "TARGET_64BIT"
1864 "pop{q}\t%0"
1865 [(set_attr "type" "pop")
1866 (set_attr "mode" "DI")])
1867
1868 (define_insn "popdi1"
1869 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1870 (mem:DI (reg:DI SP_REG)))
1871 (set (reg:DI SP_REG)
1872 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1873 "TARGET_64BIT"
1874 "pop{q}\t%0"
1875 [(set_attr "type" "pop")
1876 (set_attr "mode" "DI")])
1877
1878 (define_insn "*movdi_xor_rex64"
1879 [(set (match_operand:DI 0 "register_operand" "=r")
1880 (match_operand:DI 1 "const0_operand" "i"))
1881 (clobber (reg:CC FLAGS_REG))]
1882 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1883 && reload_completed"
1884 "xor{l}\t{%k0, %k0|%k0, %k0}"
1885 [(set_attr "type" "alu1")
1886 (set_attr "mode" "SI")
1887 (set_attr "length_immediate" "0")])
1888
1889 (define_insn "*movdi_or_rex64"
1890 [(set (match_operand:DI 0 "register_operand" "=r")
1891 (match_operand:DI 1 "const_int_operand" "i"))
1892 (clobber (reg:CC FLAGS_REG))]
1893 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1894 && reload_completed
1895 && operands[1] == constm1_rtx"
1896 {
1897 operands[1] = constm1_rtx;
1898 return "or{q}\t{%1, %0|%0, %1}";
1899 }
1900 [(set_attr "type" "alu1")
1901 (set_attr "mode" "DI")
1902 (set_attr "length_immediate" "1")])
1903
1904 (define_insn "*movdi_2"
1905 [(set (match_operand:DI 0 "nonimmediate_operand"
1906 "=r ,o ,m*y,*y,m ,*Y,*Y,m ,*x,*x")
1907 (match_operand:DI 1 "general_operand"
1908 "riFo,riF,*y ,m ,*Y,*Y,m ,*x,*x,m "))]
1909 "!TARGET_64BIT
1910 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1911 "@
1912 #
1913 #
1914 movq\t{%1, %0|%0, %1}
1915 movq\t{%1, %0|%0, %1}
1916 movq\t{%1, %0|%0, %1}
1917 movdqa\t{%1, %0|%0, %1}
1918 movq\t{%1, %0|%0, %1}
1919 movlps\t{%1, %0|%0, %1}
1920 movaps\t{%1, %0|%0, %1}
1921 movlps\t{%1, %0|%0, %1}"
1922 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov")
1923 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,V2SF,V4SF,V2SF")])
1924
1925 (define_split
1926 [(set (match_operand:DI 0 "push_operand" "")
1927 (match_operand:DI 1 "general_operand" ""))]
1928 "!TARGET_64BIT && reload_completed
1929 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1930 [(const_int 0)]
1931 "ix86_split_long_move (operands); DONE;")
1932
1933 ;; %%% This multiword shite has got to go.
1934 (define_split
1935 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1936 (match_operand:DI 1 "general_operand" ""))]
1937 "!TARGET_64BIT && reload_completed
1938 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1939 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1940 [(const_int 0)]
1941 "ix86_split_long_move (operands); DONE;")
1942
1943 (define_insn "*movdi_1_rex64"
1944 [(set (match_operand:DI 0 "nonimmediate_operand"
1945 "=r,r ,r,mr,!mr,!*y,!rm,!*y,!*x,!rm,!*x,!*x,!*y")
1946 (match_operand:DI 1 "general_operand"
1947 "Z ,rem,i,re,n ,*y ,*y ,rm ,*x ,*x ,rm ,*y ,*x"))]
1948 "TARGET_64BIT
1949 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1950 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1951 {
1952 switch (get_attr_type (insn))
1953 {
1954 case TYPE_SSECVT:
1955 if (which_alternative == 11)
1956 return "movq2dq\t{%1, %0|%0, %1}";
1957 else
1958 return "movdq2q\t{%1, %0|%0, %1}";
1959 case TYPE_SSEMOV:
1960 if (get_attr_mode (insn) == MODE_TI)
1961 return "movdqa\t{%1, %0|%0, %1}";
1962 /* FALLTHRU */
1963 case TYPE_MMXMOV:
1964 /* Moves from and into integer register is done using movd opcode with
1965 REX prefix. */
1966 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1967 return "movd\t{%1, %0|%0, %1}";
1968 return "movq\t{%1, %0|%0, %1}";
1969 case TYPE_MULTI:
1970 return "#";
1971 case TYPE_LEA:
1972 return "lea{q}\t{%a1, %0|%0, %a1}";
1973 default:
1974 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1975 abort ();
1976 if (get_attr_mode (insn) == MODE_SI)
1977 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1978 else if (which_alternative == 2)
1979 return "movabs{q}\t{%1, %0|%0, %1}";
1980 else
1981 return "mov{q}\t{%1, %0|%0, %1}";
1982 }
1983 }
1984 [(set (attr "type")
1985 (cond [(eq_attr "alternative" "5,6,7")
1986 (const_string "mmxmov")
1987 (eq_attr "alternative" "8,9,10")
1988 (const_string "ssemov")
1989 (eq_attr "alternative" "11,12")
1990 (const_string "ssecvt")
1991 (eq_attr "alternative" "4")
1992 (const_string "multi")
1993 (and (ne (symbol_ref "flag_pic") (const_int 0))
1994 (match_operand:DI 1 "symbolic_operand" ""))
1995 (const_string "lea")
1996 ]
1997 (const_string "imov")))
1998 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1999 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
2000 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
2001
2002 (define_insn "*movdi_1_rex64_nointerunit"
2003 [(set (match_operand:DI 0 "nonimmediate_operand"
2004 "=r,r ,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2005 (match_operand:DI 1 "general_operand"
2006 "Z,rem,i,re,n ,*y ,*y,m ,*Y ,*Y,m"))]
2007 "TARGET_64BIT
2008 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2009 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2010 {
2011 switch (get_attr_type (insn))
2012 {
2013 case TYPE_SSEMOV:
2014 if (get_attr_mode (insn) == MODE_TI)
2015 return "movdqa\t{%1, %0|%0, %1}";
2016 /* FALLTHRU */
2017 case TYPE_MMXMOV:
2018 return "movq\t{%1, %0|%0, %1}";
2019 case TYPE_MULTI:
2020 return "#";
2021 case TYPE_LEA:
2022 return "lea{q}\t{%a1, %0|%0, %a1}";
2023 default:
2024 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2025 abort ();
2026 if (get_attr_mode (insn) == MODE_SI)
2027 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2028 else if (which_alternative == 2)
2029 return "movabs{q}\t{%1, %0|%0, %1}";
2030 else
2031 return "mov{q}\t{%1, %0|%0, %1}";
2032 }
2033 }
2034 [(set (attr "type")
2035 (cond [(eq_attr "alternative" "5,6,7")
2036 (const_string "mmxmov")
2037 (eq_attr "alternative" "8,9,10")
2038 (const_string "ssemov")
2039 (eq_attr "alternative" "4")
2040 (const_string "multi")
2041 (and (ne (symbol_ref "flag_pic") (const_int 0))
2042 (match_operand:DI 1 "symbolic_operand" ""))
2043 (const_string "lea")
2044 ]
2045 (const_string "imov")))
2046 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2047 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2048 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2049
2050 ;; Stores and loads of ax to arbitrary constant address.
2051 ;; We fake an second form of instruction to force reload to load address
2052 ;; into register when rax is not available
2053 (define_insn "*movabsdi_1_rex64"
2054 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2055 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2056 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2057 "@
2058 movabs{q}\t{%1, %P0|%P0, %1}
2059 mov{q}\t{%1, %a0|%a0, %1}"
2060 [(set_attr "type" "imov")
2061 (set_attr "modrm" "0,*")
2062 (set_attr "length_address" "8,0")
2063 (set_attr "length_immediate" "0,*")
2064 (set_attr "memory" "store")
2065 (set_attr "mode" "DI")])
2066
2067 (define_insn "*movabsdi_2_rex64"
2068 [(set (match_operand:DI 0 "register_operand" "=a,r")
2069 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2070 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2071 "@
2072 movabs{q}\t{%P1, %0|%0, %P1}
2073 mov{q}\t{%a1, %0|%0, %a1}"
2074 [(set_attr "type" "imov")
2075 (set_attr "modrm" "0,*")
2076 (set_attr "length_address" "8,0")
2077 (set_attr "length_immediate" "0")
2078 (set_attr "memory" "load")
2079 (set_attr "mode" "DI")])
2080
2081 ;; Convert impossible stores of immediate to existing instructions.
2082 ;; First try to get scratch register and go through it. In case this
2083 ;; fails, move by 32bit parts.
2084 (define_peephole2
2085 [(match_scratch:DI 2 "r")
2086 (set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode)"
2090 [(set (match_dup 2) (match_dup 1))
2091 (set (match_dup 0) (match_dup 2))]
2092 "")
2093
2094 ;; We need to define this as both peepholer and splitter for case
2095 ;; peephole2 pass is not run.
2096 ;; "&& 1" is needed to keep it from matching the previous pattern.
2097 (define_peephole2
2098 [(set (match_operand:DI 0 "memory_operand" "")
2099 (match_operand:DI 1 "immediate_operand" ""))]
2100 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2101 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2102 [(set (match_dup 2) (match_dup 3))
2103 (set (match_dup 4) (match_dup 5))]
2104 "split_di (operands, 2, operands + 2, operands + 4);")
2105
2106 (define_split
2107 [(set (match_operand:DI 0 "memory_operand" "")
2108 (match_operand:DI 1 "immediate_operand" ""))]
2109 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2110 && !symbolic_operand (operands[1], DImode)
2111 && !x86_64_immediate_operand (operands[1], DImode)"
2112 [(set (match_dup 2) (match_dup 3))
2113 (set (match_dup 4) (match_dup 5))]
2114 "split_di (operands, 2, operands + 2, operands + 4);")
2115
2116 (define_insn "*swapdi_rex64"
2117 [(set (match_operand:DI 0 "register_operand" "+r")
2118 (match_operand:DI 1 "register_operand" "+r"))
2119 (set (match_dup 1)
2120 (match_dup 0))]
2121 "TARGET_64BIT"
2122 "xchg{q}\t%1, %0"
2123 [(set_attr "type" "imov")
2124 (set_attr "mode" "DI")
2125 (set_attr "pent_pair" "np")
2126 (set_attr "athlon_decode" "vector")])
2127
2128 (define_expand "movti"
2129 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2130 (match_operand:TI 1 "nonimmediate_operand" ""))]
2131 "TARGET_SSE || TARGET_64BIT"
2132 {
2133 if (TARGET_64BIT)
2134 ix86_expand_move (TImode, operands);
2135 else
2136 ix86_expand_vector_move (TImode, operands);
2137 DONE;
2138 })
2139
2140 (define_insn "*movti_internal"
2141 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2142 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2143 "TARGET_SSE && !TARGET_64BIT
2144 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2145 {
2146 switch (which_alternative)
2147 {
2148 case 0:
2149 if (get_attr_mode (insn) == MODE_V4SF)
2150 return "xorps\t%0, %0";
2151 else
2152 return "pxor\t%0, %0";
2153 case 1:
2154 case 2:
2155 if (get_attr_mode (insn) == MODE_V4SF)
2156 return "movaps\t{%1, %0|%0, %1}";
2157 else
2158 return "movdqa\t{%1, %0|%0, %1}";
2159 default:
2160 abort ();
2161 }
2162 }
2163 [(set_attr "type" "ssemov,ssemov,ssemov")
2164 (set (attr "mode")
2165 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2166 (const_string "V4SF")
2167
2168 (eq_attr "alternative" "0,1")
2169 (if_then_else
2170 (ne (symbol_ref "optimize_size")
2171 (const_int 0))
2172 (const_string "V4SF")
2173 (const_string "TI"))
2174 (eq_attr "alternative" "2")
2175 (if_then_else
2176 (ne (symbol_ref "optimize_size")
2177 (const_int 0))
2178 (const_string "V4SF")
2179 (const_string "TI"))]
2180 (const_string "TI")))])
2181
2182 (define_insn "*movti_rex64"
2183 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2184 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2185 "TARGET_64BIT
2186 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2187 {
2188 switch (which_alternative)
2189 {
2190 case 0:
2191 case 1:
2192 return "#";
2193 case 2:
2194 if (get_attr_mode (insn) == MODE_V4SF)
2195 return "xorps\t%0, %0";
2196 else
2197 return "pxor\t%0, %0";
2198 case 3:
2199 case 4:
2200 if (get_attr_mode (insn) == MODE_V4SF)
2201 return "movaps\t{%1, %0|%0, %1}";
2202 else
2203 return "movdqa\t{%1, %0|%0, %1}";
2204 default:
2205 abort ();
2206 }
2207 }
2208 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2209 (set (attr "mode")
2210 (cond [(eq_attr "alternative" "2,3")
2211 (if_then_else
2212 (ne (symbol_ref "optimize_size")
2213 (const_int 0))
2214 (const_string "V4SF")
2215 (const_string "TI"))
2216 (eq_attr "alternative" "4")
2217 (if_then_else
2218 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2219 (const_int 0))
2220 (ne (symbol_ref "optimize_size")
2221 (const_int 0)))
2222 (const_string "V4SF")
2223 (const_string "TI"))]
2224 (const_string "DI")))])
2225
2226 (define_split
2227 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2228 (match_operand:TI 1 "general_operand" ""))]
2229 "reload_completed && !SSE_REG_P (operands[0])
2230 && !SSE_REG_P (operands[1])"
2231 [(const_int 0)]
2232 "ix86_split_long_move (operands); DONE;")
2233
2234 (define_expand "movsf"
2235 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2236 (match_operand:SF 1 "general_operand" ""))]
2237 ""
2238 "ix86_expand_move (SFmode, operands); DONE;")
2239
2240 (define_insn "*pushsf"
2241 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2242 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2243 "!TARGET_64BIT"
2244 {
2245 switch (which_alternative)
2246 {
2247 case 1:
2248 return "push{l}\t%1";
2249
2250 default:
2251 /* This insn should be already split before reg-stack. */
2252 abort ();
2253 }
2254 }
2255 [(set_attr "type" "multi,push,multi")
2256 (set_attr "mode" "SF,SI,SF")])
2257
2258 (define_insn "*pushsf_rex64"
2259 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2260 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2261 "TARGET_64BIT"
2262 {
2263 switch (which_alternative)
2264 {
2265 case 1:
2266 return "push{q}\t%q1";
2267
2268 default:
2269 /* This insn should be already split before reg-stack. */
2270 abort ();
2271 }
2272 }
2273 [(set_attr "type" "multi,push,multi")
2274 (set_attr "mode" "SF,DI,SF")])
2275
2276 (define_split
2277 [(set (match_operand:SF 0 "push_operand" "")
2278 (match_operand:SF 1 "memory_operand" ""))]
2279 "reload_completed
2280 && GET_CODE (operands[1]) == MEM
2281 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2282 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2283 [(set (match_dup 0)
2284 (match_dup 1))]
2285 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2286
2287
2288 ;; %%% Kill this when call knows how to work this out.
2289 (define_split
2290 [(set (match_operand:SF 0 "push_operand" "")
2291 (match_operand:SF 1 "any_fp_register_operand" ""))]
2292 "!TARGET_64BIT"
2293 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2294 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2295
2296 (define_split
2297 [(set (match_operand:SF 0 "push_operand" "")
2298 (match_operand:SF 1 "any_fp_register_operand" ""))]
2299 "TARGET_64BIT"
2300 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2301 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2302
2303 (define_insn "*movsf_1"
2304 [(set (match_operand:SF 0 "nonimmediate_operand"
2305 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2306 (match_operand:SF 1 "general_operand"
2307 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2308 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2309 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2310 && (reload_in_progress || reload_completed
2311 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2312 || GET_CODE (operands[1]) != CONST_DOUBLE
2313 || memory_operand (operands[0], SFmode))"
2314 {
2315 switch (which_alternative)
2316 {
2317 case 0:
2318 return output_387_reg_move (insn, operands);
2319
2320 case 1:
2321 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2322 return "fstp%z0\t%y0";
2323 else
2324 return "fst%z0\t%y0";
2325
2326 case 2:
2327 return standard_80387_constant_opcode (operands[1]);
2328
2329 case 3:
2330 case 4:
2331 return "mov{l}\t{%1, %0|%0, %1}";
2332 case 5:
2333 if (get_attr_mode (insn) == MODE_TI)
2334 return "pxor\t%0, %0";
2335 else
2336 return "xorps\t%0, %0";
2337 case 6:
2338 if (get_attr_mode (insn) == MODE_V4SF)
2339 return "movaps\t{%1, %0|%0, %1}";
2340 else
2341 return "movss\t{%1, %0|%0, %1}";
2342 case 7:
2343 case 8:
2344 return "movss\t{%1, %0|%0, %1}";
2345
2346 case 9:
2347 case 10:
2348 return "movd\t{%1, %0|%0, %1}";
2349
2350 case 11:
2351 return "movq\t{%1, %0|%0, %1}";
2352
2353 default:
2354 abort();
2355 }
2356 }
2357 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2358 (set (attr "mode")
2359 (cond [(eq_attr "alternative" "3,4,9,10")
2360 (const_string "SI")
2361 (eq_attr "alternative" "5")
2362 (if_then_else
2363 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2364 (const_int 0))
2365 (ne (symbol_ref "TARGET_SSE2")
2366 (const_int 0)))
2367 (eq (symbol_ref "optimize_size")
2368 (const_int 0)))
2369 (const_string "TI")
2370 (const_string "V4SF"))
2371 /* For architectures resolving dependencies on
2372 whole SSE registers use APS move to break dependency
2373 chains, otherwise use short move to avoid extra work.
2374
2375 Do the same for architectures resolving dependencies on
2376 the parts. While in DF mode it is better to always handle
2377 just register parts, the SF mode is different due to lack
2378 of instructions to load just part of the register. It is
2379 better to maintain the whole registers in single format
2380 to avoid problems on using packed logical operations. */
2381 (eq_attr "alternative" "6")
2382 (if_then_else
2383 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2384 (const_int 0))
2385 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2386 (const_int 0)))
2387 (const_string "V4SF")
2388 (const_string "SF"))
2389 (eq_attr "alternative" "11")
2390 (const_string "DI")]
2391 (const_string "SF")))])
2392
2393 (define_insn "*movsf_1_nointerunit"
2394 [(set (match_operand:SF 0 "nonimmediate_operand"
2395 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!m,!*y")
2396 (match_operand:SF 1 "general_operand"
2397 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,m ,*y,*y"))]
2398 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2399 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2400 && (reload_in_progress || reload_completed
2401 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2402 || GET_CODE (operands[1]) != CONST_DOUBLE
2403 || memory_operand (operands[0], SFmode))"
2404 {
2405 switch (which_alternative)
2406 {
2407 case 0:
2408 return output_387_reg_move (insn, operands);
2409
2410 case 1:
2411 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2412 return "fstp%z0\t%y0";
2413 else
2414 return "fst%z0\t%y0";
2415
2416 case 2:
2417 return standard_80387_constant_opcode (operands[1]);
2418
2419 case 3:
2420 case 4:
2421 return "mov{l}\t{%1, %0|%0, %1}";
2422 case 5:
2423 if (get_attr_mode (insn) == MODE_TI)
2424 return "pxor\t%0, %0";
2425 else
2426 return "xorps\t%0, %0";
2427 case 6:
2428 if (get_attr_mode (insn) == MODE_V4SF)
2429 return "movaps\t{%1, %0|%0, %1}";
2430 else
2431 return "movss\t{%1, %0|%0, %1}";
2432 case 7:
2433 case 8:
2434 return "movss\t{%1, %0|%0, %1}";
2435
2436 case 9:
2437 case 10:
2438 return "movd\t{%1, %0|%0, %1}";
2439
2440 case 11:
2441 return "movq\t{%1, %0|%0, %1}";
2442
2443 default:
2444 abort();
2445 }
2446 }
2447 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2448 (set (attr "mode")
2449 (cond [(eq_attr "alternative" "3,4,9,10")
2450 (const_string "SI")
2451 (eq_attr "alternative" "5")
2452 (if_then_else
2453 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2454 (const_int 0))
2455 (ne (symbol_ref "TARGET_SSE2")
2456 (const_int 0)))
2457 (eq (symbol_ref "optimize_size")
2458 (const_int 0)))
2459 (const_string "TI")
2460 (const_string "V4SF"))
2461 /* For architectures resolving dependencies on
2462 whole SSE registers use APS move to break dependency
2463 chains, otherwise use short move to avoid extra work.
2464
2465 Do the same for architectures resolving dependencies on
2466 the parts. While in DF mode it is better to always handle
2467 just register parts, the SF mode is different due to lack
2468 of instructions to load just part of the register. It is
2469 better to maintain the whole registers in single format
2470 to avoid problems on using packed logical operations. */
2471 (eq_attr "alternative" "6")
2472 (if_then_else
2473 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2474 (const_int 0))
2475 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2476 (const_int 0)))
2477 (const_string "V4SF")
2478 (const_string "SF"))
2479 (eq_attr "alternative" "11")
2480 (const_string "DI")]
2481 (const_string "SF")))])
2482
2483 (define_insn "*swapsf"
2484 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2485 (match_operand:SF 1 "fp_register_operand" "+f"))
2486 (set (match_dup 1)
2487 (match_dup 0))]
2488 "reload_completed || TARGET_80387"
2489 {
2490 if (STACK_TOP_P (operands[0]))
2491 return "fxch\t%1";
2492 else
2493 return "fxch\t%0";
2494 }
2495 [(set_attr "type" "fxch")
2496 (set_attr "mode" "SF")])
2497
2498 (define_expand "movdf"
2499 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2500 (match_operand:DF 1 "general_operand" ""))]
2501 ""
2502 "ix86_expand_move (DFmode, operands); DONE;")
2503
2504 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2505 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2506 ;; On the average, pushdf using integers can be still shorter. Allow this
2507 ;; pattern for optimize_size too.
2508
2509 (define_insn "*pushdf_nointeger"
2510 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2511 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2512 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2513 {
2514 /* This insn should be already split before reg-stack. */
2515 abort ();
2516 }
2517 [(set_attr "type" "multi")
2518 (set_attr "mode" "DF,SI,SI,DF")])
2519
2520 (define_insn "*pushdf_integer"
2521 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2522 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2523 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2524 {
2525 /* This insn should be already split before reg-stack. */
2526 abort ();
2527 }
2528 [(set_attr "type" "multi")
2529 (set_attr "mode" "DF,SI,DF")])
2530
2531 ;; %%% Kill this when call knows how to work this out.
2532 (define_split
2533 [(set (match_operand:DF 0 "push_operand" "")
2534 (match_operand:DF 1 "any_fp_register_operand" ""))]
2535 "!TARGET_64BIT && reload_completed"
2536 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2537 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2538 "")
2539
2540 (define_split
2541 [(set (match_operand:DF 0 "push_operand" "")
2542 (match_operand:DF 1 "any_fp_register_operand" ""))]
2543 "TARGET_64BIT && reload_completed"
2544 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2545 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2546 "")
2547
2548 (define_split
2549 [(set (match_operand:DF 0 "push_operand" "")
2550 (match_operand:DF 1 "general_operand" ""))]
2551 "reload_completed"
2552 [(const_int 0)]
2553 "ix86_split_long_move (operands); DONE;")
2554
2555 ;; Moving is usually shorter when only FP registers are used. This separate
2556 ;; movdf pattern avoids the use of integer registers for FP operations
2557 ;; when optimizing for size.
2558
2559 (define_insn "*movdf_nointeger"
2560 [(set (match_operand:DF 0 "nonimmediate_operand"
2561 "=f#Y,m ,f#Y,*r ,o ,Y#f*x,Y#f*x,Y#f*x ,m ")
2562 (match_operand:DF 1 "general_operand"
2563 "fm#Y,f#Y,G ,*roF,F*r,C ,Y#f*x,HmY#f*x,Y#f*x"))]
2564 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2565 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2566 && (reload_in_progress || reload_completed
2567 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2568 || GET_CODE (operands[1]) != CONST_DOUBLE
2569 || memory_operand (operands[0], DFmode))"
2570 {
2571 switch (which_alternative)
2572 {
2573 case 0:
2574 return output_387_reg_move (insn, operands);
2575
2576 case 1:
2577 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2578 return "fstp%z0\t%y0";
2579 else
2580 return "fst%z0\t%y0";
2581
2582 case 2:
2583 return standard_80387_constant_opcode (operands[1]);
2584
2585 case 3:
2586 case 4:
2587 return "#";
2588 case 5:
2589 switch (get_attr_mode (insn))
2590 {
2591 case MODE_V4SF:
2592 return "xorps\t%0, %0";
2593 case MODE_V2DF:
2594 return "xorpd\t%0, %0";
2595 case MODE_TI:
2596 return "pxor\t%0, %0";
2597 default:
2598 abort ();
2599 }
2600 case 6:
2601 case 7:
2602 case 8:
2603 switch (get_attr_mode (insn))
2604 {
2605 case MODE_V4SF:
2606 return "movaps\t{%1, %0|%0, %1}";
2607 case MODE_V2DF:
2608 return "movapd\t{%1, %0|%0, %1}";
2609 case MODE_TI:
2610 return "movdqa\t{%1, %0|%0, %1}";
2611 case MODE_DI:
2612 return "movq\t{%1, %0|%0, %1}";
2613 case MODE_DF:
2614 return "movsd\t{%1, %0|%0, %1}";
2615 case MODE_V1DF:
2616 return "movlpd\t{%1, %0|%0, %1}";
2617 case MODE_V2SF:
2618 return "movlps\t{%1, %0|%0, %1}";
2619 default:
2620 abort ();
2621 }
2622
2623 default:
2624 abort();
2625 }
2626 }
2627 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2628 (set (attr "mode")
2629 (cond [(eq_attr "alternative" "0,1,2")
2630 (const_string "DF")
2631 (eq_attr "alternative" "3,4")
2632 (const_string "SI")
2633
2634 /* For SSE1, we have many fewer alternatives. */
2635 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2636 (cond [(eq_attr "alternative" "5,6")
2637 (const_string "V4SF")
2638 ]
2639 (const_string "V2SF"))
2640
2641 /* xorps is one byte shorter. */
2642 (eq_attr "alternative" "5")
2643 (cond [(ne (symbol_ref "optimize_size")
2644 (const_int 0))
2645 (const_string "V4SF")
2646 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2647 (const_int 0))
2648 (const_string "TI")
2649 ]
2650 (const_string "V2DF"))
2651
2652 /* For architectures resolving dependencies on
2653 whole SSE registers use APD move to break dependency
2654 chains, otherwise use short move to avoid extra work.
2655
2656 movaps encodes one byte shorter. */
2657 (eq_attr "alternative" "6")
2658 (cond
2659 [(ne (symbol_ref "optimize_size")
2660 (const_int 0))
2661 (const_string "V4SF")
2662 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2663 (const_int 0))
2664 (const_string "V2DF")
2665 ]
2666 (const_string "DF"))
2667 /* For architectures resolving dependencies on register
2668 parts we may avoid extra work to zero out upper part
2669 of register. */
2670 (eq_attr "alternative" "7")
2671 (if_then_else
2672 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2673 (const_int 0))
2674 (const_string "V1DF")
2675 (const_string "DF"))
2676 ]
2677 (const_string "DF")))])
2678
2679 (define_insn "*movdf_integer"
2680 [(set (match_operand:DF 0 "nonimmediate_operand"
2681 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y#rf*x,Y#rf*x,Y#rf*x,m")
2682 (match_operand:DF 1 "general_operand"
2683 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y#rf*x,m ,Y#rf*x"))]
2684 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2685 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2686 && (reload_in_progress || reload_completed
2687 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2688 || GET_CODE (operands[1]) != CONST_DOUBLE
2689 || memory_operand (operands[0], DFmode))"
2690 {
2691 switch (which_alternative)
2692 {
2693 case 0:
2694 return output_387_reg_move (insn, operands);
2695
2696 case 1:
2697 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2698 return "fstp%z0\t%y0";
2699 else
2700 return "fst%z0\t%y0";
2701
2702 case 2:
2703 return standard_80387_constant_opcode (operands[1]);
2704
2705 case 3:
2706 case 4:
2707 return "#";
2708
2709 case 5:
2710 switch (get_attr_mode (insn))
2711 {
2712 case MODE_V4SF:
2713 return "xorps\t%0, %0";
2714 case MODE_V2DF:
2715 return "xorpd\t%0, %0";
2716 case MODE_TI:
2717 return "pxor\t%0, %0";
2718 default:
2719 abort ();
2720 }
2721 case 6:
2722 case 7:
2723 case 8:
2724 switch (get_attr_mode (insn))
2725 {
2726 case MODE_V4SF:
2727 return "movaps\t{%1, %0|%0, %1}";
2728 case MODE_V2DF:
2729 return "movapd\t{%1, %0|%0, %1}";
2730 case MODE_TI:
2731 return "movdqa\t{%1, %0|%0, %1}";
2732 case MODE_DI:
2733 return "movq\t{%1, %0|%0, %1}";
2734 case MODE_DF:
2735 return "movsd\t{%1, %0|%0, %1}";
2736 case MODE_V1DF:
2737 return "movlpd\t{%1, %0|%0, %1}";
2738 case MODE_V2SF:
2739 return "movlps\t{%1, %0|%0, %1}";
2740 default:
2741 abort ();
2742 }
2743
2744 default:
2745 abort();
2746 }
2747 }
2748 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2749 (set (attr "mode")
2750 (cond [(eq_attr "alternative" "0,1,2")
2751 (const_string "DF")
2752 (eq_attr "alternative" "3,4")
2753 (const_string "SI")
2754
2755 /* For SSE1, we have many fewer alternatives. */
2756 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2757 (cond [(eq_attr "alternative" "5,6")
2758 (const_string "V4SF")
2759 ]
2760 (const_string "V2SF"))
2761
2762 /* xorps is one byte shorter. */
2763 (eq_attr "alternative" "5")
2764 (cond [(ne (symbol_ref "optimize_size")
2765 (const_int 0))
2766 (const_string "V4SF")
2767 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2768 (const_int 0))
2769 (const_string "TI")
2770 ]
2771 (const_string "V2DF"))
2772
2773 /* For architectures resolving dependencies on
2774 whole SSE registers use APD move to break dependency
2775 chains, otherwise use short move to avoid extra work.
2776
2777 movaps encodes one byte shorter. */
2778 (eq_attr "alternative" "6")
2779 (cond
2780 [(ne (symbol_ref "optimize_size")
2781 (const_int 0))
2782 (const_string "V4SF")
2783 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2784 (const_int 0))
2785 (const_string "V2DF")
2786 ]
2787 (const_string "DF"))
2788 /* For architectures resolving dependencies on register
2789 parts we may avoid extra work to zero out upper part
2790 of register. */
2791 (eq_attr "alternative" "7")
2792 (if_then_else
2793 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2794 (const_int 0))
2795 (const_string "V1DF")
2796 (const_string "DF"))
2797 ]
2798 (const_string "DF")))])
2799
2800 (define_split
2801 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2802 (match_operand:DF 1 "general_operand" ""))]
2803 "reload_completed
2804 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2805 && ! (ANY_FP_REG_P (operands[0]) ||
2806 (GET_CODE (operands[0]) == SUBREG
2807 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2808 && ! (ANY_FP_REG_P (operands[1]) ||
2809 (GET_CODE (operands[1]) == SUBREG
2810 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2811 [(const_int 0)]
2812 "ix86_split_long_move (operands); DONE;")
2813
2814 (define_insn "*swapdf"
2815 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2816 (match_operand:DF 1 "fp_register_operand" "+f"))
2817 (set (match_dup 1)
2818 (match_dup 0))]
2819 "reload_completed || TARGET_80387"
2820 {
2821 if (STACK_TOP_P (operands[0]))
2822 return "fxch\t%1";
2823 else
2824 return "fxch\t%0";
2825 }
2826 [(set_attr "type" "fxch")
2827 (set_attr "mode" "DF")])
2828
2829 (define_expand "movxf"
2830 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2831 (match_operand:XF 1 "general_operand" ""))]
2832 ""
2833 "ix86_expand_move (XFmode, operands); DONE;")
2834
2835 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2836 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2837 ;; Pushing using integer instructions is longer except for constants
2838 ;; and direct memory references.
2839 ;; (assuming that any given constant is pushed only once, but this ought to be
2840 ;; handled elsewhere).
2841
2842 (define_insn "*pushxf_nointeger"
2843 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2844 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2845 "optimize_size"
2846 {
2847 /* This insn should be already split before reg-stack. */
2848 abort ();
2849 }
2850 [(set_attr "type" "multi")
2851 (set_attr "mode" "XF,SI,SI")])
2852
2853 (define_insn "*pushxf_integer"
2854 [(set (match_operand:XF 0 "push_operand" "=<,<")
2855 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2856 "!optimize_size"
2857 {
2858 /* This insn should be already split before reg-stack. */
2859 abort ();
2860 }
2861 [(set_attr "type" "multi")
2862 (set_attr "mode" "XF,SI")])
2863
2864 (define_split
2865 [(set (match_operand 0 "push_operand" "")
2866 (match_operand 1 "general_operand" ""))]
2867 "reload_completed
2868 && (GET_MODE (operands[0]) == XFmode
2869 || GET_MODE (operands[0]) == DFmode)
2870 && !ANY_FP_REG_P (operands[1])"
2871 [(const_int 0)]
2872 "ix86_split_long_move (operands); DONE;")
2873
2874 (define_split
2875 [(set (match_operand:XF 0 "push_operand" "")
2876 (match_operand:XF 1 "any_fp_register_operand" ""))]
2877 "!TARGET_64BIT"
2878 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2879 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2880 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2881
2882 (define_split
2883 [(set (match_operand:XF 0 "push_operand" "")
2884 (match_operand:XF 1 "any_fp_register_operand" ""))]
2885 "TARGET_64BIT"
2886 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2887 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2888 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2889
2890 ;; Do not use integer registers when optimizing for size
2891 (define_insn "*movxf_nointeger"
2892 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2893 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2894 "optimize_size
2895 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2896 && (reload_in_progress || reload_completed
2897 || GET_CODE (operands[1]) != CONST_DOUBLE
2898 || memory_operand (operands[0], XFmode))"
2899 {
2900 switch (which_alternative)
2901 {
2902 case 0:
2903 return output_387_reg_move (insn, operands);
2904
2905 case 1:
2906 /* There is no non-popping store to memory for XFmode. So if
2907 we need one, follow the store with a load. */
2908 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2909 return "fstp%z0\t%y0\;fld%z0\t%y0";
2910 else
2911 return "fstp%z0\t%y0";
2912
2913 case 2:
2914 return standard_80387_constant_opcode (operands[1]);
2915
2916 case 3: case 4:
2917 return "#";
2918 }
2919 abort();
2920 }
2921 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2922 (set_attr "mode" "XF,XF,XF,SI,SI")])
2923
2924 (define_insn "*movxf_integer"
2925 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2926 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2927 "!optimize_size
2928 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2929 && (reload_in_progress || reload_completed
2930 || GET_CODE (operands[1]) != CONST_DOUBLE
2931 || memory_operand (operands[0], XFmode))"
2932 {
2933 switch (which_alternative)
2934 {
2935 case 0:
2936 return output_387_reg_move (insn, operands);
2937
2938 case 1:
2939 /* There is no non-popping store to memory for XFmode. So if
2940 we need one, follow the store with a load. */
2941 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2942 return "fstp%z0\t%y0\;fld%z0\t%y0";
2943 else
2944 return "fstp%z0\t%y0";
2945
2946 case 2:
2947 return standard_80387_constant_opcode (operands[1]);
2948
2949 case 3: case 4:
2950 return "#";
2951 }
2952 abort();
2953 }
2954 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2955 (set_attr "mode" "XF,XF,XF,SI,SI")])
2956
2957 (define_split
2958 [(set (match_operand 0 "nonimmediate_operand" "")
2959 (match_operand 1 "general_operand" ""))]
2960 "reload_completed
2961 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2962 && GET_MODE (operands[0]) == XFmode
2963 && ! (ANY_FP_REG_P (operands[0]) ||
2964 (GET_CODE (operands[0]) == SUBREG
2965 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2966 && ! (ANY_FP_REG_P (operands[1]) ||
2967 (GET_CODE (operands[1]) == SUBREG
2968 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2969 [(const_int 0)]
2970 "ix86_split_long_move (operands); DONE;")
2971
2972 (define_split
2973 [(set (match_operand 0 "register_operand" "")
2974 (match_operand 1 "memory_operand" ""))]
2975 "reload_completed
2976 && GET_CODE (operands[1]) == MEM
2977 && (GET_MODE (operands[0]) == XFmode
2978 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2979 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2980 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2981 [(set (match_dup 0) (match_dup 1))]
2982 {
2983 rtx c = get_pool_constant (XEXP (operands[1], 0));
2984 rtx r = operands[0];
2985
2986 if (GET_CODE (r) == SUBREG)
2987 r = SUBREG_REG (r);
2988
2989 if (SSE_REG_P (r))
2990 {
2991 if (!standard_sse_constant_p (c))
2992 FAIL;
2993 }
2994 else if (FP_REG_P (r))
2995 {
2996 if (!standard_80387_constant_p (c))
2997 FAIL;
2998 }
2999 else if (MMX_REG_P (r))
3000 FAIL;
3001
3002 operands[1] = c;
3003 })
3004
3005 (define_insn "swapxf"
3006 [(set (match_operand:XF 0 "register_operand" "+f")
3007 (match_operand:XF 1 "register_operand" "+f"))
3008 (set (match_dup 1)
3009 (match_dup 0))]
3010 "TARGET_80387"
3011 {
3012 if (STACK_TOP_P (operands[0]))
3013 return "fxch\t%1";
3014 else
3015 return "fxch\t%0";
3016 }
3017 [(set_attr "type" "fxch")
3018 (set_attr "mode" "XF")])
3019
3020 (define_expand "movtf"
3021 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3022 (match_operand:TF 1 "nonimmediate_operand" ""))]
3023 "TARGET_64BIT"
3024 {
3025 ix86_expand_move (TFmode, operands);
3026 DONE;
3027 })
3028
3029 (define_insn "*movtf_internal"
3030 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3031 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3032 "TARGET_64BIT
3033 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3034 {
3035 switch (which_alternative)
3036 {
3037 case 0:
3038 case 1:
3039 return "#";
3040 case 2:
3041 if (get_attr_mode (insn) == MODE_V4SF)
3042 return "xorps\t%0, %0";
3043 else
3044 return "pxor\t%0, %0";
3045 case 3:
3046 case 4:
3047 if (get_attr_mode (insn) == MODE_V4SF)
3048 return "movaps\t{%1, %0|%0, %1}";
3049 else
3050 return "movdqa\t{%1, %0|%0, %1}";
3051 default:
3052 abort ();
3053 }
3054 }
3055 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
3056 (set (attr "mode")
3057 (cond [(eq_attr "alternative" "2,3")
3058 (if_then_else
3059 (ne (symbol_ref "optimize_size")
3060 (const_int 0))
3061 (const_string "V4SF")
3062 (const_string "TI"))
3063 (eq_attr "alternative" "4")
3064 (if_then_else
3065 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3066 (const_int 0))
3067 (ne (symbol_ref "optimize_size")
3068 (const_int 0)))
3069 (const_string "V4SF")
3070 (const_string "TI"))]
3071 (const_string "DI")))])
3072
3073 (define_split
3074 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3075 (match_operand:TF 1 "general_operand" ""))]
3076 "reload_completed && !SSE_REG_P (operands[0])
3077 && !SSE_REG_P (operands[1])"
3078 [(const_int 0)]
3079 "ix86_split_long_move (operands); DONE;")
3080 \f
3081 ;; Zero extension instructions
3082
3083 (define_expand "zero_extendhisi2"
3084 [(set (match_operand:SI 0 "register_operand" "")
3085 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3086 ""
3087 {
3088 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3089 {
3090 operands[1] = force_reg (HImode, operands[1]);
3091 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3092 DONE;
3093 }
3094 })
3095
3096 (define_insn "zero_extendhisi2_and"
3097 [(set (match_operand:SI 0 "register_operand" "=r")
3098 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3099 (clobber (reg:CC FLAGS_REG))]
3100 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3101 "#"
3102 [(set_attr "type" "alu1")
3103 (set_attr "mode" "SI")])
3104
3105 (define_split
3106 [(set (match_operand:SI 0 "register_operand" "")
3107 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3108 (clobber (reg:CC FLAGS_REG))]
3109 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3110 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3111 (clobber (reg:CC FLAGS_REG))])]
3112 "")
3113
3114 (define_insn "*zero_extendhisi2_movzwl"
3115 [(set (match_operand:SI 0 "register_operand" "=r")
3116 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3117 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3118 "movz{wl|x}\t{%1, %0|%0, %1}"
3119 [(set_attr "type" "imovx")
3120 (set_attr "mode" "SI")])
3121
3122 (define_expand "zero_extendqihi2"
3123 [(parallel
3124 [(set (match_operand:HI 0 "register_operand" "")
3125 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3126 (clobber (reg:CC FLAGS_REG))])]
3127 ""
3128 "")
3129
3130 (define_insn "*zero_extendqihi2_and"
3131 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3132 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3133 (clobber (reg:CC FLAGS_REG))]
3134 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3135 "#"
3136 [(set_attr "type" "alu1")
3137 (set_attr "mode" "HI")])
3138
3139 (define_insn "*zero_extendqihi2_movzbw_and"
3140 [(set (match_operand:HI 0 "register_operand" "=r,r")
3141 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3142 (clobber (reg:CC FLAGS_REG))]
3143 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3144 "#"
3145 [(set_attr "type" "imovx,alu1")
3146 (set_attr "mode" "HI")])
3147
3148 (define_insn "*zero_extendqihi2_movzbw"
3149 [(set (match_operand:HI 0 "register_operand" "=r")
3150 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3151 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3152 "movz{bw|x}\t{%1, %0|%0, %1}"
3153 [(set_attr "type" "imovx")
3154 (set_attr "mode" "HI")])
3155
3156 ;; For the movzbw case strip only the clobber
3157 (define_split
3158 [(set (match_operand:HI 0 "register_operand" "")
3159 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3160 (clobber (reg:CC FLAGS_REG))]
3161 "reload_completed
3162 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3163 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3164 [(set (match_operand:HI 0 "register_operand" "")
3165 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3166
3167 ;; When source and destination does not overlap, clear destination
3168 ;; first and then do the movb
3169 (define_split
3170 [(set (match_operand:HI 0 "register_operand" "")
3171 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3172 (clobber (reg:CC FLAGS_REG))]
3173 "reload_completed
3174 && ANY_QI_REG_P (operands[0])
3175 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3176 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3177 [(set (match_dup 0) (const_int 0))
3178 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3179 "operands[2] = gen_lowpart (QImode, operands[0]);")
3180
3181 ;; Rest is handled by single and.
3182 (define_split
3183 [(set (match_operand:HI 0 "register_operand" "")
3184 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3185 (clobber (reg:CC FLAGS_REG))]
3186 "reload_completed
3187 && true_regnum (operands[0]) == true_regnum (operands[1])"
3188 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3189 (clobber (reg:CC FLAGS_REG))])]
3190 "")
3191
3192 (define_expand "zero_extendqisi2"
3193 [(parallel
3194 [(set (match_operand:SI 0 "register_operand" "")
3195 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3196 (clobber (reg:CC FLAGS_REG))])]
3197 ""
3198 "")
3199
3200 (define_insn "*zero_extendqisi2_and"
3201 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3202 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3203 (clobber (reg:CC FLAGS_REG))]
3204 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3205 "#"
3206 [(set_attr "type" "alu1")
3207 (set_attr "mode" "SI")])
3208
3209 (define_insn "*zero_extendqisi2_movzbw_and"
3210 [(set (match_operand:SI 0 "register_operand" "=r,r")
3211 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3212 (clobber (reg:CC FLAGS_REG))]
3213 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3214 "#"
3215 [(set_attr "type" "imovx,alu1")
3216 (set_attr "mode" "SI")])
3217
3218 (define_insn "*zero_extendqisi2_movzbw"
3219 [(set (match_operand:SI 0 "register_operand" "=r")
3220 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3221 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3222 "movz{bl|x}\t{%1, %0|%0, %1}"
3223 [(set_attr "type" "imovx")
3224 (set_attr "mode" "SI")])
3225
3226 ;; For the movzbl case strip only the clobber
3227 (define_split
3228 [(set (match_operand:SI 0 "register_operand" "")
3229 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3230 (clobber (reg:CC FLAGS_REG))]
3231 "reload_completed
3232 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3233 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3234 [(set (match_dup 0)
3235 (zero_extend:SI (match_dup 1)))])
3236
3237 ;; When source and destination does not overlap, clear destination
3238 ;; first and then do the movb
3239 (define_split
3240 [(set (match_operand:SI 0 "register_operand" "")
3241 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3242 (clobber (reg:CC FLAGS_REG))]
3243 "reload_completed
3244 && ANY_QI_REG_P (operands[0])
3245 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3246 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3247 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3248 [(set (match_dup 0) (const_int 0))
3249 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3250 "operands[2] = gen_lowpart (QImode, operands[0]);")
3251
3252 ;; Rest is handled by single and.
3253 (define_split
3254 [(set (match_operand:SI 0 "register_operand" "")
3255 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3256 (clobber (reg:CC FLAGS_REG))]
3257 "reload_completed
3258 && true_regnum (operands[0]) == true_regnum (operands[1])"
3259 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3260 (clobber (reg:CC FLAGS_REG))])]
3261 "")
3262
3263 ;; %%% Kill me once multi-word ops are sane.
3264 (define_expand "zero_extendsidi2"
3265 [(set (match_operand:DI 0 "register_operand" "=r")
3266 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3267 ""
3268 "if (!TARGET_64BIT)
3269 {
3270 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3271 DONE;
3272 }
3273 ")
3274
3275 (define_insn "zero_extendsidi2_32"
3276 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3277 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3278 (clobber (reg:CC FLAGS_REG))]
3279 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3280 "@
3281 #
3282 #
3283 #
3284 movd\t{%1, %0|%0, %1}
3285 movd\t{%1, %0|%0, %1}"
3286 [(set_attr "mode" "SI,SI,SI,DI,TI")
3287 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3288
3289 (define_insn "*zero_extendsidi2_32_1"
3290 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3291 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3292 (clobber (reg:CC FLAGS_REG))]
3293 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3294 "@
3295 #
3296 #
3297 #
3298 movd\t{%1, %0|%0, %1}
3299 movd\t{%1, %0|%0, %1}"
3300 [(set_attr "mode" "SI,SI,SI,DI,TI")
3301 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3302
3303 (define_insn "zero_extendsidi2_rex64"
3304 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3305 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3306 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3307 "@
3308 mov\t{%k1, %k0|%k0, %k1}
3309 #
3310 movd\t{%1, %0|%0, %1}
3311 movd\t{%1, %0|%0, %1}"
3312 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3313 (set_attr "mode" "SI,DI,DI,TI")])
3314
3315 (define_insn "*zero_extendsidi2_rex64_1"
3316 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3317 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3318 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3319 "@
3320 mov\t{%k1, %k0|%k0, %k1}
3321 #
3322 movd\t{%1, %0|%0, %1}
3323 movd\t{%1, %0|%0, %1}"
3324 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3325 (set_attr "mode" "SI,DI,SI,SI")])
3326
3327 (define_split
3328 [(set (match_operand:DI 0 "memory_operand" "")
3329 (zero_extend:DI (match_dup 0)))]
3330 "TARGET_64BIT"
3331 [(set (match_dup 4) (const_int 0))]
3332 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3333
3334 (define_split
3335 [(set (match_operand:DI 0 "register_operand" "")
3336 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3337 (clobber (reg:CC FLAGS_REG))]
3338 "!TARGET_64BIT && reload_completed
3339 && true_regnum (operands[0]) == true_regnum (operands[1])"
3340 [(set (match_dup 4) (const_int 0))]
3341 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3342
3343 (define_split
3344 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3345 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3346 (clobber (reg:CC FLAGS_REG))]
3347 "!TARGET_64BIT && reload_completed
3348 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3349 [(set (match_dup 3) (match_dup 1))
3350 (set (match_dup 4) (const_int 0))]
3351 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3352
3353 (define_insn "zero_extendhidi2"
3354 [(set (match_operand:DI 0 "register_operand" "=r,r")
3355 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3356 "TARGET_64BIT"
3357 "@
3358 movz{wl|x}\t{%1, %k0|%k0, %1}
3359 movz{wq|x}\t{%1, %0|%0, %1}"
3360 [(set_attr "type" "imovx")
3361 (set_attr "mode" "SI,DI")])
3362
3363 (define_insn "zero_extendqidi2"
3364 [(set (match_operand:DI 0 "register_operand" "=r,r")
3365 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3366 "TARGET_64BIT"
3367 "@
3368 movz{bl|x}\t{%1, %k0|%k0, %1}
3369 movz{bq|x}\t{%1, %0|%0, %1}"
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "SI,DI")])
3372 \f
3373 ;; Sign extension instructions
3374
3375 (define_expand "extendsidi2"
3376 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3377 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3378 (clobber (reg:CC FLAGS_REG))
3379 (clobber (match_scratch:SI 2 ""))])]
3380 ""
3381 {
3382 if (TARGET_64BIT)
3383 {
3384 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3385 DONE;
3386 }
3387 })
3388
3389 (define_insn "*extendsidi2_1"
3390 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3391 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3392 (clobber (reg:CC FLAGS_REG))
3393 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3394 "!TARGET_64BIT"
3395 "#")
3396
3397 (define_insn "extendsidi2_rex64"
3398 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3399 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3400 "TARGET_64BIT"
3401 "@
3402 {cltq|cdqe}
3403 movs{lq|x}\t{%1,%0|%0, %1}"
3404 [(set_attr "type" "imovx")
3405 (set_attr "mode" "DI")
3406 (set_attr "prefix_0f" "0")
3407 (set_attr "modrm" "0,1")])
3408
3409 (define_insn "extendhidi2"
3410 [(set (match_operand:DI 0 "register_operand" "=r")
3411 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3412 "TARGET_64BIT"
3413 "movs{wq|x}\t{%1,%0|%0, %1}"
3414 [(set_attr "type" "imovx")
3415 (set_attr "mode" "DI")])
3416
3417 (define_insn "extendqidi2"
3418 [(set (match_operand:DI 0 "register_operand" "=r")
3419 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3420 "TARGET_64BIT"
3421 "movs{bq|x}\t{%1,%0|%0, %1}"
3422 [(set_attr "type" "imovx")
3423 (set_attr "mode" "DI")])
3424
3425 ;; Extend to memory case when source register does die.
3426 (define_split
3427 [(set (match_operand:DI 0 "memory_operand" "")
3428 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3429 (clobber (reg:CC FLAGS_REG))
3430 (clobber (match_operand:SI 2 "register_operand" ""))]
3431 "(reload_completed
3432 && dead_or_set_p (insn, operands[1])
3433 && !reg_mentioned_p (operands[1], operands[0]))"
3434 [(set (match_dup 3) (match_dup 1))
3435 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3436 (clobber (reg:CC FLAGS_REG))])
3437 (set (match_dup 4) (match_dup 1))]
3438 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3439
3440 ;; Extend to memory case when source register does not die.
3441 (define_split
3442 [(set (match_operand:DI 0 "memory_operand" "")
3443 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3444 (clobber (reg:CC FLAGS_REG))
3445 (clobber (match_operand:SI 2 "register_operand" ""))]
3446 "reload_completed"
3447 [(const_int 0)]
3448 {
3449 split_di (&operands[0], 1, &operands[3], &operands[4]);
3450
3451 emit_move_insn (operands[3], operands[1]);
3452
3453 /* Generate a cltd if possible and doing so it profitable. */
3454 if (true_regnum (operands[1]) == 0
3455 && true_regnum (operands[2]) == 1
3456 && (optimize_size || TARGET_USE_CLTD))
3457 {
3458 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3459 }
3460 else
3461 {
3462 emit_move_insn (operands[2], operands[1]);
3463 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3464 }
3465 emit_move_insn (operands[4], operands[2]);
3466 DONE;
3467 })
3468
3469 ;; Extend to register case. Optimize case where source and destination
3470 ;; registers match and cases where we can use cltd.
3471 (define_split
3472 [(set (match_operand:DI 0 "register_operand" "")
3473 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3474 (clobber (reg:CC FLAGS_REG))
3475 (clobber (match_scratch:SI 2 ""))]
3476 "reload_completed"
3477 [(const_int 0)]
3478 {
3479 split_di (&operands[0], 1, &operands[3], &operands[4]);
3480
3481 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3482 emit_move_insn (operands[3], operands[1]);
3483
3484 /* Generate a cltd if possible and doing so it profitable. */
3485 if (true_regnum (operands[3]) == 0
3486 && (optimize_size || TARGET_USE_CLTD))
3487 {
3488 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3489 DONE;
3490 }
3491
3492 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3493 emit_move_insn (operands[4], operands[1]);
3494
3495 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3496 DONE;
3497 })
3498
3499 (define_insn "extendhisi2"
3500 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3501 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3502 ""
3503 {
3504 switch (get_attr_prefix_0f (insn))
3505 {
3506 case 0:
3507 return "{cwtl|cwde}";
3508 default:
3509 return "movs{wl|x}\t{%1,%0|%0, %1}";
3510 }
3511 }
3512 [(set_attr "type" "imovx")
3513 (set_attr "mode" "SI")
3514 (set (attr "prefix_0f")
3515 ;; movsx is short decodable while cwtl is vector decoded.
3516 (if_then_else (and (eq_attr "cpu" "!k6")
3517 (eq_attr "alternative" "0"))
3518 (const_string "0")
3519 (const_string "1")))
3520 (set (attr "modrm")
3521 (if_then_else (eq_attr "prefix_0f" "0")
3522 (const_string "0")
3523 (const_string "1")))])
3524
3525 (define_insn "*extendhisi2_zext"
3526 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3527 (zero_extend:DI
3528 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3529 "TARGET_64BIT"
3530 {
3531 switch (get_attr_prefix_0f (insn))
3532 {
3533 case 0:
3534 return "{cwtl|cwde}";
3535 default:
3536 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3537 }
3538 }
3539 [(set_attr "type" "imovx")
3540 (set_attr "mode" "SI")
3541 (set (attr "prefix_0f")
3542 ;; movsx is short decodable while cwtl is vector decoded.
3543 (if_then_else (and (eq_attr "cpu" "!k6")
3544 (eq_attr "alternative" "0"))
3545 (const_string "0")
3546 (const_string "1")))
3547 (set (attr "modrm")
3548 (if_then_else (eq_attr "prefix_0f" "0")
3549 (const_string "0")
3550 (const_string "1")))])
3551
3552 (define_insn "extendqihi2"
3553 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3554 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3555 ""
3556 {
3557 switch (get_attr_prefix_0f (insn))
3558 {
3559 case 0:
3560 return "{cbtw|cbw}";
3561 default:
3562 return "movs{bw|x}\t{%1,%0|%0, %1}";
3563 }
3564 }
3565 [(set_attr "type" "imovx")
3566 (set_attr "mode" "HI")
3567 (set (attr "prefix_0f")
3568 ;; movsx is short decodable while cwtl is vector decoded.
3569 (if_then_else (and (eq_attr "cpu" "!k6")
3570 (eq_attr "alternative" "0"))
3571 (const_string "0")
3572 (const_string "1")))
3573 (set (attr "modrm")
3574 (if_then_else (eq_attr "prefix_0f" "0")
3575 (const_string "0")
3576 (const_string "1")))])
3577
3578 (define_insn "extendqisi2"
3579 [(set (match_operand:SI 0 "register_operand" "=r")
3580 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3581 ""
3582 "movs{bl|x}\t{%1,%0|%0, %1}"
3583 [(set_attr "type" "imovx")
3584 (set_attr "mode" "SI")])
3585
3586 (define_insn "*extendqisi2_zext"
3587 [(set (match_operand:DI 0 "register_operand" "=r")
3588 (zero_extend:DI
3589 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3590 "TARGET_64BIT"
3591 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3592 [(set_attr "type" "imovx")
3593 (set_attr "mode" "SI")])
3594 \f
3595 ;; Conversions between float and double.
3596
3597 ;; These are all no-ops in the model used for the 80387. So just
3598 ;; emit moves.
3599
3600 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3601 (define_insn "*dummy_extendsfdf2"
3602 [(set (match_operand:DF 0 "push_operand" "=<")
3603 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3604 "0"
3605 "#")
3606
3607 (define_split
3608 [(set (match_operand:DF 0 "push_operand" "")
3609 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3610 "!TARGET_64BIT"
3611 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3612 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3613
3614 (define_split
3615 [(set (match_operand:DF 0 "push_operand" "")
3616 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3617 "TARGET_64BIT"
3618 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3619 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3620
3621 (define_insn "*dummy_extendsfxf2"
3622 [(set (match_operand:XF 0 "push_operand" "=<")
3623 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3624 "0"
3625 "#")
3626
3627 (define_split
3628 [(set (match_operand:XF 0 "push_operand" "")
3629 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3630 ""
3631 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3632 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3633 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3634
3635 (define_split
3636 [(set (match_operand:XF 0 "push_operand" "")
3637 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3638 "TARGET_64BIT"
3639 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3640 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3641 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3642
3643 (define_split
3644 [(set (match_operand:XF 0 "push_operand" "")
3645 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3646 ""
3647 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3648 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3649 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3650
3651 (define_split
3652 [(set (match_operand:XF 0 "push_operand" "")
3653 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3654 "TARGET_64BIT"
3655 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3656 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3657 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3658
3659 (define_expand "extendsfdf2"
3660 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3661 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3662 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3663 {
3664 /* ??? Needed for compress_float_constant since all fp constants
3665 are LEGITIMATE_CONSTANT_P. */
3666 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3667 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3668 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3669 operands[1] = force_reg (SFmode, operands[1]);
3670 })
3671
3672 (define_insn "*extendsfdf2_mixed"
3673 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3674 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3675 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3676 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3677 {
3678 switch (which_alternative)
3679 {
3680 case 0:
3681 return output_387_reg_move (insn, operands);
3682
3683 case 1:
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
3689 case 2:
3690 return "cvtss2sd\t{%1, %0|%0, %1}";
3691
3692 default:
3693 abort ();
3694 }
3695 }
3696 [(set_attr "type" "fmov,fmov,ssecvt")
3697 (set_attr "mode" "SF,XF,DF")])
3698
3699 (define_insn "*extendsfdf2_sse"
3700 [(set (match_operand:DF 0 "register_operand" "=Y")
3701 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3702 "TARGET_SSE2 && TARGET_SSE_MATH
3703 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3704 "cvtss2sd\t{%1, %0|%0, %1}"
3705 [(set_attr "type" "ssecvt")
3706 (set_attr "mode" "DF")])
3707
3708 (define_insn "*extendsfdf2_i387"
3709 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3710 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3711 "TARGET_80387
3712 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3713 {
3714 switch (which_alternative)
3715 {
3716 case 0:
3717 return output_387_reg_move (insn, operands);
3718
3719 case 1:
3720 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3721 return "fstp%z0\t%y0";
3722 else
3723 return "fst%z0\t%y0";
3724
3725 default:
3726 abort ();
3727 }
3728 }
3729 [(set_attr "type" "fmov")
3730 (set_attr "mode" "SF,XF")])
3731
3732 (define_expand "extendsfxf2"
3733 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3734 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3735 "TARGET_80387"
3736 {
3737 /* ??? Needed for compress_float_constant since all fp constants
3738 are LEGITIMATE_CONSTANT_P. */
3739 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3740 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3741 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3742 operands[1] = force_reg (SFmode, operands[1]);
3743 })
3744
3745 (define_insn "*extendsfxf2_i387"
3746 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3747 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3748 "TARGET_80387
3749 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3750 {
3751 switch (which_alternative)
3752 {
3753 case 0:
3754 return output_387_reg_move (insn, operands);
3755
3756 case 1:
3757 /* There is no non-popping store to memory for XFmode. So if
3758 we need one, follow the store with a load. */
3759 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3760 return "fstp%z0\t%y0";
3761 else
3762 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3763
3764 default:
3765 abort ();
3766 }
3767 }
3768 [(set_attr "type" "fmov")
3769 (set_attr "mode" "SF,XF")])
3770
3771 (define_expand "extenddfxf2"
3772 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3773 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3774 "TARGET_80387"
3775 {
3776 /* ??? Needed for compress_float_constant since all fp constants
3777 are LEGITIMATE_CONSTANT_P. */
3778 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3779 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3780 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3781 operands[1] = force_reg (DFmode, operands[1]);
3782 })
3783
3784 (define_insn "*extenddfxf2_i387"
3785 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3786 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3787 "TARGET_80387
3788 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3789 {
3790 switch (which_alternative)
3791 {
3792 case 0:
3793 return output_387_reg_move (insn, operands);
3794
3795 case 1:
3796 /* There is no non-popping store to memory for XFmode. So if
3797 we need one, follow the store with a load. */
3798 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3799 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3800 else
3801 return "fstp%z0\t%y0";
3802
3803 default:
3804 abort ();
3805 }
3806 }
3807 [(set_attr "type" "fmov")
3808 (set_attr "mode" "DF,XF")])
3809
3810 ;; %%% This seems bad bad news.
3811 ;; This cannot output into an f-reg because there is no way to be sure
3812 ;; of truncating in that case. Otherwise this is just like a simple move
3813 ;; insn. So we pretend we can output to a reg in order to get better
3814 ;; register preferencing, but we really use a stack slot.
3815
3816 ;; Conversion from DFmode to SFmode.
3817
3818 (define_expand "truncdfsf2"
3819 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3820 (float_truncate:SF
3821 (match_operand:DF 1 "nonimmediate_operand" "")))]
3822 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3823 {
3824 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3825 operands[1] = force_reg (DFmode, operands[1]);
3826
3827 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3828 ;
3829 else if (flag_unsafe_math_optimizations)
3830 ;
3831 else
3832 {
3833 rtx temp = assign_386_stack_local (SFmode, 0);
3834 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3835 DONE;
3836 }
3837 })
3838
3839 (define_expand "truncdfsf2_with_temp"
3840 [(parallel [(set (match_operand:SF 0 "" "")
3841 (float_truncate:SF (match_operand:DF 1 "" "")))
3842 (clobber (match_operand:SF 2 "" ""))])]
3843 "")
3844
3845 (define_insn "*truncdfsf_fast_mixed"
3846 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3847 (float_truncate:SF
3848 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3849 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3850 {
3851 switch (which_alternative)
3852 {
3853 case 0:
3854 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3855 return "fstp%z0\t%y0";
3856 else
3857 return "fst%z0\t%y0";
3858 case 1:
3859 return output_387_reg_move (insn, operands);
3860 case 2:
3861 return "cvtsd2ss\t{%1, %0|%0, %1}";
3862 default:
3863 abort ();
3864 }
3865 }
3866 [(set_attr "type" "fmov,fmov,ssecvt")
3867 (set_attr "mode" "SF")])
3868
3869 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3870 ;; because nothing we do here is unsafe.
3871 (define_insn "*truncdfsf_fast_sse"
3872 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3873 (float_truncate:SF
3874 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3875 "TARGET_SSE2 && TARGET_SSE_MATH"
3876 "cvtsd2ss\t{%1, %0|%0, %1}"
3877 [(set_attr "type" "ssecvt")
3878 (set_attr "mode" "SF")])
3879
3880 (define_insn "*truncdfsf_fast_i387"
3881 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3882 (float_truncate:SF
3883 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3884 "TARGET_80387 && flag_unsafe_math_optimizations"
3885 "* return output_387_reg_move (insn, operands);"
3886 [(set_attr "type" "fmov")
3887 (set_attr "mode" "SF")])
3888
3889 (define_insn "*truncdfsf_mixed"
3890 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3891 (float_truncate:SF
3892 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3893 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3894 "TARGET_MIX_SSE_I387"
3895 {
3896 switch (which_alternative)
3897 {
3898 case 0:
3899 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3900 return "fstp%z0\t%y0";
3901 else
3902 return "fst%z0\t%y0";
3903 case 1:
3904 return "#";
3905 case 2:
3906 return "cvtsd2ss\t{%1, %0|%0, %1}";
3907 default:
3908 abort ();
3909 }
3910 }
3911 [(set_attr "type" "fmov,multi,ssecvt")
3912 (set_attr "mode" "SF")])
3913
3914 (define_insn "*truncdfsf_i387"
3915 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3916 (float_truncate:SF
3917 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3918 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3919 "TARGET_80387"
3920 {
3921 switch (which_alternative)
3922 {
3923 case 0:
3924 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3925 return "fstp%z0\t%y0";
3926 else
3927 return "fst%z0\t%y0";
3928 case 1:
3929 return "#";
3930 default:
3931 abort ();
3932 }
3933 }
3934 [(set_attr "type" "fmov,multi")
3935 (set_attr "mode" "SF")])
3936
3937 (define_split
3938 [(set (match_operand:SF 0 "register_operand" "")
3939 (float_truncate:SF
3940 (match_operand:DF 1 "fp_register_operand" "")))
3941 (clobber (match_operand 2 "" ""))]
3942 "reload_completed"
3943 [(set (match_dup 2) (match_dup 1))
3944 (set (match_dup 0) (match_dup 2))]
3945 {
3946 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3947 })
3948
3949 ;; Conversion from XFmode to SFmode.
3950
3951 (define_expand "truncxfsf2"
3952 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3953 (float_truncate:SF
3954 (match_operand:XF 1 "register_operand" "")))
3955 (clobber (match_dup 2))])]
3956 "TARGET_80387"
3957 {
3958 if (flag_unsafe_math_optimizations)
3959 {
3960 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3961 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3962 if (reg != operands[0])
3963 emit_move_insn (operands[0], reg);
3964 DONE;
3965 }
3966 else
3967 operands[2] = assign_386_stack_local (SFmode, 0);
3968 })
3969
3970 (define_insn "*truncxfsf2_mixed"
3971 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3972 (float_truncate:SF
3973 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3974 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3975 "TARGET_MIX_SSE_I387"
3976 {
3977 switch (which_alternative)
3978 {
3979 case 0:
3980 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3981 return "fstp%z0\t%y0";
3982 else
3983 return "fst%z0\t%y0";
3984 default:
3985 abort();
3986 }
3987 }
3988 [(set_attr "type" "fmov,multi,multi,multi")
3989 (set_attr "mode" "SF")])
3990
3991 (define_insn "truncxfsf2_i387_noop"
3992 [(set (match_operand:SF 0 "register_operand" "=f")
3993 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3994 "TARGET_80387 && flag_unsafe_math_optimizations"
3995 {
3996 return output_387_reg_move (insn, operands);
3997 }
3998 [(set_attr "type" "fmov")
3999 (set_attr "mode" "SF")])
4000
4001 (define_insn "*truncxfsf2_i387"
4002 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
4003 (float_truncate:SF
4004 (match_operand:XF 1 "register_operand" "f,f,f")))
4005 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
4006 "TARGET_80387"
4007 {
4008 switch (which_alternative)
4009 {
4010 case 0:
4011 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4012 return "fstp%z0\t%y0";
4013 else
4014 return "fst%z0\t%y0";
4015 default:
4016 abort ();
4017 }
4018 }
4019 [(set_attr "type" "fmov,multi,multi")
4020 (set_attr "mode" "SF")])
4021
4022 (define_insn "*truncxfsf2_i387_1"
4023 [(set (match_operand:SF 0 "memory_operand" "=m")
4024 (float_truncate:SF
4025 (match_operand:XF 1 "register_operand" "f")))]
4026 "TARGET_80387"
4027 {
4028 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4029 return "fstp%z0\t%y0";
4030 else
4031 return "fst%z0\t%y0";
4032 }
4033 [(set_attr "type" "fmov")
4034 (set_attr "mode" "SF")])
4035
4036 (define_split
4037 [(set (match_operand:SF 0 "register_operand" "")
4038 (float_truncate:SF
4039 (match_operand:XF 1 "register_operand" "")))
4040 (clobber (match_operand:SF 2 "memory_operand" ""))]
4041 "TARGET_80387 && reload_completed"
4042 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4043 (set (match_dup 0) (match_dup 2))]
4044 "")
4045
4046 (define_split
4047 [(set (match_operand:SF 0 "memory_operand" "")
4048 (float_truncate:SF
4049 (match_operand:XF 1 "register_operand" "")))
4050 (clobber (match_operand:SF 2 "memory_operand" ""))]
4051 "TARGET_80387"
4052 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4053 "")
4054
4055 ;; Conversion from XFmode to DFmode.
4056
4057 (define_expand "truncxfdf2"
4058 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4059 (float_truncate:DF
4060 (match_operand:XF 1 "register_operand" "")))
4061 (clobber (match_dup 2))])]
4062 "TARGET_80387"
4063 {
4064 if (flag_unsafe_math_optimizations)
4065 {
4066 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4067 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4068 if (reg != operands[0])
4069 emit_move_insn (operands[0], reg);
4070 DONE;
4071 }
4072 else
4073 operands[2] = assign_386_stack_local (DFmode, 0);
4074 })
4075
4076 (define_insn "*truncxfdf2_mixed"
4077 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4078 (float_truncate:DF
4079 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4080 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4081 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4082 {
4083 switch (which_alternative)
4084 {
4085 case 0:
4086 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4087 return "fstp%z0\t%y0";
4088 else
4089 return "fst%z0\t%y0";
4090 default:
4091 abort();
4092 }
4093 abort ();
4094 }
4095 [(set_attr "type" "fmov,multi,multi,multi")
4096 (set_attr "mode" "DF")])
4097
4098 (define_insn "truncxfdf2_i387_noop"
4099 [(set (match_operand:DF 0 "register_operand" "=f")
4100 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4101 "TARGET_80387 && flag_unsafe_math_optimizations"
4102 {
4103 return output_387_reg_move (insn, operands);
4104 }
4105 [(set_attr "type" "fmov")
4106 (set_attr "mode" "DF")])
4107
4108 (define_insn "*truncxfdf2_i387"
4109 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
4110 (float_truncate:DF
4111 (match_operand:XF 1 "register_operand" "f,f,f")))
4112 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4113 "TARGET_80387"
4114 {
4115 switch (which_alternative)
4116 {
4117 case 0:
4118 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4119 return "fstp%z0\t%y0";
4120 else
4121 return "fst%z0\t%y0";
4122 default:
4123 abort ();
4124 }
4125 }
4126 [(set_attr "type" "fmov,multi,multi")
4127 (set_attr "mode" "DF")])
4128
4129 (define_insn "*truncxfdf2_i387_1"
4130 [(set (match_operand:DF 0 "memory_operand" "=m")
4131 (float_truncate:DF
4132 (match_operand:XF 1 "register_operand" "f")))]
4133 "TARGET_80387"
4134 {
4135 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4136 return "fstp%z0\t%y0";
4137 else
4138 return "fst%z0\t%y0";
4139 }
4140 [(set_attr "type" "fmov")
4141 (set_attr "mode" "DF")])
4142
4143 (define_split
4144 [(set (match_operand:DF 0 "register_operand" "")
4145 (float_truncate:DF
4146 (match_operand:XF 1 "register_operand" "")))
4147 (clobber (match_operand:DF 2 "memory_operand" ""))]
4148 "TARGET_80387 && reload_completed"
4149 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4150 (set (match_dup 0) (match_dup 2))]
4151 "")
4152
4153 (define_split
4154 [(set (match_operand:DF 0 "memory_operand" "")
4155 (float_truncate:DF
4156 (match_operand:XF 1 "register_operand" "")))
4157 (clobber (match_operand:DF 2 "memory_operand" ""))]
4158 "TARGET_80387"
4159 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4160 "")
4161 \f
4162 ;; %%% Break up all these bad boys.
4163
4164 ;; Signed conversion to DImode.
4165
4166 (define_expand "fix_truncxfdi2"
4167 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4168 (fix:DI (match_operand:XF 1 "register_operand" "")))
4169 (clobber (reg:CC FLAGS_REG))])]
4170 "TARGET_80387"
4171 "")
4172
4173 (define_expand "fix_truncdfdi2"
4174 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4175 (fix:DI (match_operand:DF 1 "register_operand" "")))
4176 (clobber (reg:CC FLAGS_REG))])]
4177 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2)"
4178 {
4179 if (TARGET_64BIT && TARGET_SSE2)
4180 {
4181 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4182 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4183 if (out != operands[0])
4184 emit_move_insn (operands[0], out);
4185 DONE;
4186 }
4187 })
4188
4189 (define_expand "fix_truncsfdi2"
4190 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4191 (fix:DI (match_operand:SF 1 "register_operand" "")))
4192 (clobber (reg:CC FLAGS_REG))])]
4193 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE)"
4194 {
4195 if (TARGET_64BIT && TARGET_SSE)
4196 {
4197 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4198 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4199 if (out != operands[0])
4200 emit_move_insn (operands[0], out);
4201 DONE;
4202 }
4203 })
4204
4205 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4206 ;; of the machinery.
4207 (define_insn_and_split "*fix_truncdi_i387"
4208 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4209 (fix:DI (match_operand 1 "register_operand" "f,f")))
4210 (clobber (reg:CC FLAGS_REG))]
4211 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4212 && !reload_completed && !reload_in_progress
4213 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4214 "#"
4215 "&& 1"
4216 [(const_int 0)]
4217 {
4218 ix86_optimize_mode_switching = 1;
4219 operands[2] = assign_386_stack_local (HImode, 1);
4220 operands[3] = assign_386_stack_local (HImode, 2);
4221 if (memory_operand (operands[0], VOIDmode))
4222 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4223 operands[2], operands[3]));
4224 else
4225 {
4226 operands[4] = assign_386_stack_local (DImode, 0);
4227 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4228 operands[2], operands[3],
4229 operands[4]));
4230 }
4231 DONE;
4232 }
4233 [(set_attr "type" "fistp")
4234 (set_attr "i387_cw" "trunc")
4235 (set_attr "mode" "DI")])
4236
4237 (define_insn "fix_truncdi_nomemory"
4238 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4239 (fix:DI (match_operand 1 "register_operand" "f,f")))
4240 (use (match_operand:HI 2 "memory_operand" "m,m"))
4241 (use (match_operand:HI 3 "memory_operand" "m,m"))
4242 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4243 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4244 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4245 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4246 "#"
4247 [(set_attr "type" "fistp")
4248 (set_attr "i387_cw" "trunc")
4249 (set_attr "mode" "DI")])
4250
4251 (define_insn "fix_truncdi_memory"
4252 [(set (match_operand:DI 0 "memory_operand" "=m")
4253 (fix:DI (match_operand 1 "register_operand" "f")))
4254 (use (match_operand:HI 2 "memory_operand" "m"))
4255 (use (match_operand:HI 3 "memory_operand" "m"))
4256 (clobber (match_scratch:DF 4 "=&1f"))]
4257 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4258 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4259 "* return output_fix_trunc (insn, operands);"
4260 [(set_attr "type" "fistp")
4261 (set_attr "i387_cw" "trunc")
4262 (set_attr "mode" "DI")])
4263
4264 (define_split
4265 [(set (match_operand:DI 0 "register_operand" "")
4266 (fix:DI (match_operand 1 "register_operand" "")))
4267 (use (match_operand:HI 2 "memory_operand" ""))
4268 (use (match_operand:HI 3 "memory_operand" ""))
4269 (clobber (match_operand:DI 4 "memory_operand" ""))
4270 (clobber (match_scratch 5 ""))]
4271 "reload_completed"
4272 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4273 (use (match_dup 2))
4274 (use (match_dup 3))
4275 (clobber (match_dup 5))])
4276 (set (match_dup 0) (match_dup 4))]
4277 "")
4278
4279 (define_split
4280 [(set (match_operand:DI 0 "memory_operand" "")
4281 (fix:DI (match_operand 1 "register_operand" "")))
4282 (use (match_operand:HI 2 "memory_operand" ""))
4283 (use (match_operand:HI 3 "memory_operand" ""))
4284 (clobber (match_operand:DI 4 "memory_operand" ""))
4285 (clobber (match_scratch 5 ""))]
4286 "reload_completed"
4287 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4288 (use (match_dup 2))
4289 (use (match_dup 3))
4290 (clobber (match_dup 5))])]
4291 "")
4292
4293 ;; When SSE available, it is always faster to use it!
4294 (define_insn "fix_truncsfdi_sse"
4295 [(set (match_operand:DI 0 "register_operand" "=r,r")
4296 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4297 "TARGET_64BIT && TARGET_SSE"
4298 "cvttss2si{q}\t{%1, %0|%0, %1}"
4299 [(set_attr "type" "sseicvt")
4300 (set_attr "mode" "SF")
4301 (set_attr "athlon_decode" "double,vector")])
4302
4303 ;; Avoid vector decoded form of the instruction.
4304 (define_peephole2
4305 [(match_scratch:SF 2 "x")
4306 (set (match_operand:DI 0 "register_operand" "")
4307 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4308 "TARGET_K8 && !optimize_size"
4309 [(set (match_dup 2) (match_dup 1))
4310 (set (match_dup 0) (fix:DI (match_dup 2)))]
4311 "")
4312
4313 (define_insn "fix_truncdfdi_sse"
4314 [(set (match_operand:DI 0 "register_operand" "=r,r")
4315 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4316 "TARGET_64BIT && TARGET_SSE2"
4317 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4318 [(set_attr "type" "sseicvt,sseicvt")
4319 (set_attr "mode" "DF")
4320 (set_attr "athlon_decode" "double,vector")])
4321
4322 ;; Avoid vector decoded form of the instruction.
4323 (define_peephole2
4324 [(match_scratch:DF 2 "Y")
4325 (set (match_operand:DI 0 "register_operand" "")
4326 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4327 "TARGET_K8 && !optimize_size"
4328 [(set (match_dup 2) (match_dup 1))
4329 (set (match_dup 0) (fix:DI (match_dup 2)))]
4330 "")
4331
4332 ;; Signed conversion to SImode.
4333
4334 (define_expand "fix_truncxfsi2"
4335 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4336 (fix:SI (match_operand:XF 1 "register_operand" "")))
4337 (clobber (reg:CC FLAGS_REG))])]
4338 "TARGET_80387"
4339 "")
4340
4341 (define_expand "fix_truncdfsi2"
4342 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4343 (fix:SI (match_operand:DF 1 "register_operand" "")))
4344 (clobber (reg:CC FLAGS_REG))])]
4345 "TARGET_80387 || TARGET_SSE2"
4346 {
4347 if (TARGET_SSE2)
4348 {
4349 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4350 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4351 if (out != operands[0])
4352 emit_move_insn (operands[0], out);
4353 DONE;
4354 }
4355 })
4356
4357 (define_expand "fix_truncsfsi2"
4358 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4359 (fix:SI (match_operand:SF 1 "register_operand" "")))
4360 (clobber (reg:CC FLAGS_REG))])]
4361 "TARGET_80387 || TARGET_SSE"
4362 {
4363 if (TARGET_SSE)
4364 {
4365 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4366 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4367 if (out != operands[0])
4368 emit_move_insn (operands[0], out);
4369 DONE;
4370 }
4371 })
4372
4373 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4374 ;; of the machinery.
4375 (define_insn_and_split "*fix_truncsi_i387"
4376 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4377 (fix:SI (match_operand 1 "register_operand" "f,f")))
4378 (clobber (reg:CC FLAGS_REG))]
4379 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4380 && !reload_completed && !reload_in_progress
4381 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4382 "#"
4383 "&& 1"
4384 [(const_int 0)]
4385 {
4386 ix86_optimize_mode_switching = 1;
4387 operands[2] = assign_386_stack_local (HImode, 1);
4388 operands[3] = assign_386_stack_local (HImode, 2);
4389 if (memory_operand (operands[0], VOIDmode))
4390 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4391 operands[2], operands[3]));
4392 else
4393 {
4394 operands[4] = assign_386_stack_local (SImode, 0);
4395 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4396 operands[2], operands[3],
4397 operands[4]));
4398 }
4399 DONE;
4400 }
4401 [(set_attr "type" "fistp")
4402 (set_attr "i387_cw" "trunc")
4403 (set_attr "mode" "SI")])
4404
4405 (define_insn "fix_truncsi_nomemory"
4406 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4407 (fix:SI (match_operand 1 "register_operand" "f,f")))
4408 (use (match_operand:HI 2 "memory_operand" "m,m"))
4409 (use (match_operand:HI 3 "memory_operand" "m,m"))
4410 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4411 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4412 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4413 "#"
4414 [(set_attr "type" "fistp")
4415 (set_attr "i387_cw" "trunc")
4416 (set_attr "mode" "SI")])
4417
4418 (define_insn "fix_truncsi_memory"
4419 [(set (match_operand:SI 0 "memory_operand" "=m")
4420 (fix:SI (match_operand 1 "register_operand" "f")))
4421 (use (match_operand:HI 2 "memory_operand" "m"))
4422 (use (match_operand:HI 3 "memory_operand" "m"))]
4423 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4424 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4425 "* return output_fix_trunc (insn, operands);"
4426 [(set_attr "type" "fistp")
4427 (set_attr "i387_cw" "trunc")
4428 (set_attr "mode" "SI")])
4429
4430 ;; When SSE available, it is always faster to use it!
4431 (define_insn "fix_truncsfsi_sse"
4432 [(set (match_operand:SI 0 "register_operand" "=r,r")
4433 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4434 "TARGET_SSE"
4435 "cvttss2si\t{%1, %0|%0, %1}"
4436 [(set_attr "type" "sseicvt")
4437 (set_attr "mode" "DF")
4438 (set_attr "athlon_decode" "double,vector")])
4439
4440 ;; Avoid vector decoded form of the instruction.
4441 (define_peephole2
4442 [(match_scratch:SF 2 "x")
4443 (set (match_operand:SI 0 "register_operand" "")
4444 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4445 "TARGET_K8 && !optimize_size"
4446 [(set (match_dup 2) (match_dup 1))
4447 (set (match_dup 0) (fix:SI (match_dup 2)))]
4448 "")
4449
4450 (define_insn "fix_truncdfsi_sse"
4451 [(set (match_operand:SI 0 "register_operand" "=r,r")
4452 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4453 "TARGET_SSE2"
4454 "cvttsd2si\t{%1, %0|%0, %1}"
4455 [(set_attr "type" "sseicvt")
4456 (set_attr "mode" "DF")
4457 (set_attr "athlon_decode" "double,vector")])
4458
4459 ;; Avoid vector decoded form of the instruction.
4460 (define_peephole2
4461 [(match_scratch:DF 2 "Y")
4462 (set (match_operand:SI 0 "register_operand" "")
4463 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4464 "TARGET_K8 && !optimize_size"
4465 [(set (match_dup 2) (match_dup 1))
4466 (set (match_dup 0) (fix:SI (match_dup 2)))]
4467 "")
4468
4469 (define_split
4470 [(set (match_operand:SI 0 "register_operand" "")
4471 (fix:SI (match_operand 1 "register_operand" "")))
4472 (use (match_operand:HI 2 "memory_operand" ""))
4473 (use (match_operand:HI 3 "memory_operand" ""))
4474 (clobber (match_operand:SI 4 "memory_operand" ""))]
4475 "reload_completed"
4476 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4477 (use (match_dup 2))
4478 (use (match_dup 3))])
4479 (set (match_dup 0) (match_dup 4))]
4480 "")
4481
4482 (define_split
4483 [(set (match_operand:SI 0 "memory_operand" "")
4484 (fix:SI (match_operand 1 "register_operand" "")))
4485 (use (match_operand:HI 2 "memory_operand" ""))
4486 (use (match_operand:HI 3 "memory_operand" ""))
4487 (clobber (match_operand:SI 4 "memory_operand" ""))]
4488 "reload_completed"
4489 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4490 (use (match_dup 2))
4491 (use (match_dup 3))])]
4492 "")
4493
4494 ;; Signed conversion to HImode.
4495
4496 (define_expand "fix_truncxfhi2"
4497 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4498 (fix:HI (match_operand:XF 1 "register_operand" "")))
4499 (clobber (reg:CC FLAGS_REG))])]
4500 "TARGET_80387"
4501 "")
4502
4503 (define_expand "fix_truncdfhi2"
4504 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4505 (fix:HI (match_operand:DF 1 "register_operand" "")))
4506 (clobber (reg:CC FLAGS_REG))])]
4507 "TARGET_80387 && !TARGET_SSE2"
4508 "")
4509
4510 (define_expand "fix_truncsfhi2"
4511 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4512 (fix:HI (match_operand:SF 1 "register_operand" "")))
4513 (clobber (reg:CC FLAGS_REG))])]
4514 "TARGET_80387 && !TARGET_SSE"
4515 "")
4516
4517 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4518 ;; of the machinery.
4519 (define_insn_and_split "*fix_trunchi_i387"
4520 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4521 (fix:HI (match_operand 1 "register_operand" "f,f")))
4522 (clobber (reg:CC FLAGS_REG))]
4523 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4524 && !reload_completed && !reload_in_progress
4525 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4526 "#"
4527 "&& 1"
4528 [(const_int 0)]
4529 {
4530 ix86_optimize_mode_switching = 1;
4531 operands[2] = assign_386_stack_local (HImode, 1);
4532 operands[3] = assign_386_stack_local (HImode, 2);
4533 if (memory_operand (operands[0], VOIDmode))
4534 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4535 operands[2], operands[3]));
4536 else
4537 {
4538 operands[4] = assign_386_stack_local (HImode, 0);
4539 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4540 operands[2], operands[3],
4541 operands[4]));
4542 }
4543 DONE;
4544 }
4545 [(set_attr "type" "fistp")
4546 (set_attr "i387_cw" "trunc")
4547 (set_attr "mode" "HI")])
4548
4549 (define_insn "fix_trunchi_nomemory"
4550 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4551 (fix:HI (match_operand 1 "register_operand" "f,f")))
4552 (use (match_operand:HI 2 "memory_operand" "m,m"))
4553 (use (match_operand:HI 3 "memory_operand" "m,m"))
4554 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4555 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4556 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4557 "#"
4558 [(set_attr "type" "fistp")
4559 (set_attr "i387_cw" "trunc")
4560 (set_attr "mode" "HI")])
4561
4562 (define_insn "fix_trunchi_memory"
4563 [(set (match_operand:HI 0 "memory_operand" "=m")
4564 (fix:HI (match_operand 1 "register_operand" "f")))
4565 (use (match_operand:HI 2 "memory_operand" "m"))
4566 (use (match_operand:HI 3 "memory_operand" "m"))]
4567 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4568 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4569 "* return output_fix_trunc (insn, operands);"
4570 [(set_attr "type" "fistp")
4571 (set_attr "i387_cw" "trunc")
4572 (set_attr "mode" "HI")])
4573
4574 (define_split
4575 [(set (match_operand:HI 0 "memory_operand" "")
4576 (fix:HI (match_operand 1 "register_operand" "")))
4577 (use (match_operand:HI 2 "memory_operand" ""))
4578 (use (match_operand:HI 3 "memory_operand" ""))
4579 (clobber (match_operand:HI 4 "memory_operand" ""))]
4580 "reload_completed"
4581 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4582 (use (match_dup 2))
4583 (use (match_dup 3))])]
4584 "")
4585
4586 (define_split
4587 [(set (match_operand:HI 0 "register_operand" "")
4588 (fix:HI (match_operand 1 "register_operand" "")))
4589 (use (match_operand:HI 2 "memory_operand" ""))
4590 (use (match_operand:HI 3 "memory_operand" ""))
4591 (clobber (match_operand:HI 4 "memory_operand" ""))]
4592 "reload_completed"
4593 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4594 (use (match_dup 2))
4595 (use (match_dup 3))
4596 (clobber (match_dup 4))])
4597 (set (match_dup 0) (match_dup 4))]
4598 "")
4599
4600 (define_insn "x86_fnstcw_1"
4601 [(set (match_operand:HI 0 "memory_operand" "=m")
4602 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4603 "TARGET_80387"
4604 "fnstcw\t%0"
4605 [(set_attr "length" "2")
4606 (set_attr "mode" "HI")
4607 (set_attr "unit" "i387")])
4608
4609 (define_insn "x86_fldcw_1"
4610 [(set (reg:HI FPSR_REG)
4611 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4612 "TARGET_80387"
4613 "fldcw\t%0"
4614 [(set_attr "length" "2")
4615 (set_attr "mode" "HI")
4616 (set_attr "unit" "i387")
4617 (set_attr "athlon_decode" "vector")])
4618 \f
4619 ;; Conversion between fixed point and floating point.
4620
4621 ;; Even though we only accept memory inputs, the backend _really_
4622 ;; wants to be able to do this between registers.
4623
4624 (define_expand "floathisf2"
4625 [(set (match_operand:SF 0 "register_operand" "")
4626 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4627 "TARGET_80387 || TARGET_SSE_MATH"
4628 {
4629 if (TARGET_SSE_MATH)
4630 {
4631 emit_insn (gen_floatsisf2 (operands[0],
4632 convert_to_mode (SImode, operands[1], 0)));
4633 DONE;
4634 }
4635 })
4636
4637 (define_insn "*floathisf2_i387"
4638 [(set (match_operand:SF 0 "register_operand" "=f,f")
4639 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4640 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4641 "@
4642 fild%z1\t%1
4643 #"
4644 [(set_attr "type" "fmov,multi")
4645 (set_attr "mode" "SF")
4646 (set_attr "fp_int_src" "true")])
4647
4648 (define_expand "floatsisf2"
4649 [(set (match_operand:SF 0 "register_operand" "")
4650 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4651 "TARGET_80387 || TARGET_SSE_MATH"
4652 "")
4653
4654 (define_insn "*floatsisf2_mixed"
4655 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4656 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4657 "TARGET_MIX_SSE_I387"
4658 "@
4659 fild%z1\t%1
4660 #
4661 cvtsi2ss\t{%1, %0|%0, %1}
4662 cvtsi2ss\t{%1, %0|%0, %1}"
4663 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4664 (set_attr "mode" "SF")
4665 (set_attr "athlon_decode" "*,*,vector,double")
4666 (set_attr "fp_int_src" "true")])
4667
4668 (define_insn "*floatsisf2_sse"
4669 [(set (match_operand:SF 0 "register_operand" "=x,x")
4670 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4671 "TARGET_SSE_MATH"
4672 "cvtsi2ss\t{%1, %0|%0, %1}"
4673 [(set_attr "type" "sseicvt")
4674 (set_attr "mode" "SF")
4675 (set_attr "athlon_decode" "vector,double")
4676 (set_attr "fp_int_src" "true")])
4677
4678 (define_insn "*floatsisf2_i387"
4679 [(set (match_operand:SF 0 "register_operand" "=f,f")
4680 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4681 "TARGET_80387"
4682 "@
4683 fild%z1\t%1
4684 #"
4685 [(set_attr "type" "fmov,multi")
4686 (set_attr "mode" "SF")
4687 (set_attr "fp_int_src" "true")])
4688
4689 (define_expand "floatdisf2"
4690 [(set (match_operand:SF 0 "register_operand" "")
4691 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4692 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4693 "")
4694
4695 (define_insn "*floatdisf2_mixed"
4696 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4697 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4698 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4699 "@
4700 fild%z1\t%1
4701 #
4702 cvtsi2ss{q}\t{%1, %0|%0, %1}
4703 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4704 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4705 (set_attr "mode" "SF")
4706 (set_attr "athlon_decode" "*,*,vector,double")
4707 (set_attr "fp_int_src" "true")])
4708
4709 (define_insn "*floatdisf2_sse"
4710 [(set (match_operand:SF 0 "register_operand" "=x,x")
4711 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4712 "TARGET_64BIT && TARGET_SSE_MATH"
4713 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4714 [(set_attr "type" "sseicvt")
4715 (set_attr "mode" "SF")
4716 (set_attr "athlon_decode" "vector,double")
4717 (set_attr "fp_int_src" "true")])
4718
4719 (define_insn "*floatdisf2_i387"
4720 [(set (match_operand:SF 0 "register_operand" "=f,f")
4721 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4722 "TARGET_80387"
4723 "@
4724 fild%z1\t%1
4725 #"
4726 [(set_attr "type" "fmov,multi")
4727 (set_attr "mode" "SF")
4728 (set_attr "fp_int_src" "true")])
4729
4730 (define_expand "floathidf2"
4731 [(set (match_operand:DF 0 "register_operand" "")
4732 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4733 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4734 {
4735 if (TARGET_SSE2 && TARGET_SSE_MATH)
4736 {
4737 emit_insn (gen_floatsidf2 (operands[0],
4738 convert_to_mode (SImode, operands[1], 0)));
4739 DONE;
4740 }
4741 })
4742
4743 (define_insn "*floathidf2_i387"
4744 [(set (match_operand:DF 0 "register_operand" "=f,f")
4745 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4746 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4747 "@
4748 fild%z1\t%1
4749 #"
4750 [(set_attr "type" "fmov,multi")
4751 (set_attr "mode" "DF")
4752 (set_attr "fp_int_src" "true")])
4753
4754 (define_expand "floatsidf2"
4755 [(set (match_operand:DF 0 "register_operand" "")
4756 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4757 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4758 "")
4759
4760 (define_insn "*floatsidf2_mixed"
4761 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4762 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4763 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4764 "@
4765 fild%z1\t%1
4766 #
4767 cvtsi2sd\t{%1, %0|%0, %1}
4768 cvtsi2sd\t{%1, %0|%0, %1}"
4769 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4770 (set_attr "mode" "DF")
4771 (set_attr "athlon_decode" "*,*,double,direct")
4772 (set_attr "fp_int_src" "true")])
4773
4774 (define_insn "*floatsidf2_sse"
4775 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4776 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4777 "TARGET_SSE2 && TARGET_SSE_MATH"
4778 "cvtsi2sd\t{%1, %0|%0, %1}"
4779 [(set_attr "type" "sseicvt")
4780 (set_attr "mode" "DF")
4781 (set_attr "athlon_decode" "double,direct")
4782 (set_attr "fp_int_src" "true")])
4783
4784 (define_insn "*floatsidf2_i387"
4785 [(set (match_operand:DF 0 "register_operand" "=f,f")
4786 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4787 "TARGET_80387"
4788 "@
4789 fild%z1\t%1
4790 #"
4791 [(set_attr "type" "fmov,multi")
4792 (set_attr "mode" "DF")
4793 (set_attr "fp_int_src" "true")])
4794
4795 (define_expand "floatdidf2"
4796 [(set (match_operand:DF 0 "register_operand" "")
4797 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4798 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4799 "")
4800
4801 (define_insn "*floatdidf2_mixed"
4802 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4803 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4804 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4805 "@
4806 fild%z1\t%1
4807 #
4808 cvtsi2sd{q}\t{%1, %0|%0, %1}
4809 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4810 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4811 (set_attr "mode" "DF")
4812 (set_attr "athlon_decode" "*,*,double,direct")
4813 (set_attr "fp_int_src" "true")])
4814
4815 (define_insn "*floatdidf2_sse"
4816 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4817 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4818 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4819 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4820 [(set_attr "type" "sseicvt")
4821 (set_attr "mode" "DF")
4822 (set_attr "athlon_decode" "double,direct")
4823 (set_attr "fp_int_src" "true")])
4824
4825 (define_insn "*floatdidf2_i387"
4826 [(set (match_operand:DF 0 "register_operand" "=f,f")
4827 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4828 "TARGET_80387"
4829 "@
4830 fild%z1\t%1
4831 #"
4832 [(set_attr "type" "fmov,multi")
4833 (set_attr "mode" "DF")
4834 (set_attr "fp_int_src" "true")])
4835
4836 (define_insn "floathixf2"
4837 [(set (match_operand:XF 0 "register_operand" "=f,f")
4838 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4839 "TARGET_80387"
4840 "@
4841 fild%z1\t%1
4842 #"
4843 [(set_attr "type" "fmov,multi")
4844 (set_attr "mode" "XF")
4845 (set_attr "fp_int_src" "true")])
4846
4847 (define_insn "floatsixf2"
4848 [(set (match_operand:XF 0 "register_operand" "=f,f")
4849 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4850 "TARGET_80387"
4851 "@
4852 fild%z1\t%1
4853 #"
4854 [(set_attr "type" "fmov,multi")
4855 (set_attr "mode" "XF")
4856 (set_attr "fp_int_src" "true")])
4857
4858 (define_insn "floatdixf2"
4859 [(set (match_operand:XF 0 "register_operand" "=f,f")
4860 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4861 "TARGET_80387"
4862 "@
4863 fild%z1\t%1
4864 #"
4865 [(set_attr "type" "fmov,multi")
4866 (set_attr "mode" "XF")
4867 (set_attr "fp_int_src" "true")])
4868
4869 ;; %%% Kill these when reload knows how to do it.
4870 (define_split
4871 [(set (match_operand 0 "fp_register_operand" "")
4872 (float (match_operand 1 "register_operand" "")))]
4873 "reload_completed
4874 && TARGET_80387
4875 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4876 [(const_int 0)]
4877 {
4878 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4879 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4880 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4881 ix86_free_from_memory (GET_MODE (operands[1]));
4882 DONE;
4883 })
4884
4885 (define_expand "floatunssisf2"
4886 [(use (match_operand:SF 0 "register_operand" ""))
4887 (use (match_operand:SI 1 "register_operand" ""))]
4888 "!TARGET_64BIT && TARGET_SSE_MATH"
4889 "x86_emit_floatuns (operands); DONE;")
4890
4891 (define_expand "floatunsdisf2"
4892 [(use (match_operand:SF 0 "register_operand" ""))
4893 (use (match_operand:DI 1 "register_operand" ""))]
4894 "TARGET_64BIT && TARGET_SSE_MATH"
4895 "x86_emit_floatuns (operands); DONE;")
4896
4897 (define_expand "floatunsdidf2"
4898 [(use (match_operand:DF 0 "register_operand" ""))
4899 (use (match_operand:DI 1 "register_operand" ""))]
4900 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4901 "x86_emit_floatuns (operands); DONE;")
4902 \f
4903 ;; SSE extract/set expanders
4904
4905 \f
4906 ;; Add instructions
4907
4908 ;; %%% splits for addsidi3
4909 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4910 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4911 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4912
4913 (define_expand "adddi3"
4914 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4915 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4916 (match_operand:DI 2 "x86_64_general_operand" "")))
4917 (clobber (reg:CC FLAGS_REG))]
4918 ""
4919 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4920
4921 (define_insn "*adddi3_1"
4922 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4923 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4924 (match_operand:DI 2 "general_operand" "roiF,riF")))
4925 (clobber (reg:CC FLAGS_REG))]
4926 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4927 "#")
4928
4929 (define_split
4930 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4931 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4932 (match_operand:DI 2 "general_operand" "")))
4933 (clobber (reg:CC FLAGS_REG))]
4934 "!TARGET_64BIT && reload_completed"
4935 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4936 UNSPEC_ADD_CARRY))
4937 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4938 (parallel [(set (match_dup 3)
4939 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4940 (match_dup 4))
4941 (match_dup 5)))
4942 (clobber (reg:CC FLAGS_REG))])]
4943 "split_di (operands+0, 1, operands+0, operands+3);
4944 split_di (operands+1, 1, operands+1, operands+4);
4945 split_di (operands+2, 1, operands+2, operands+5);")
4946
4947 (define_insn "adddi3_carry_rex64"
4948 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4949 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4950 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4951 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4952 (clobber (reg:CC FLAGS_REG))]
4953 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4954 "adc{q}\t{%2, %0|%0, %2}"
4955 [(set_attr "type" "alu")
4956 (set_attr "pent_pair" "pu")
4957 (set_attr "mode" "DI")])
4958
4959 (define_insn "*adddi3_cc_rex64"
4960 [(set (reg:CC FLAGS_REG)
4961 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4962 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4963 UNSPEC_ADD_CARRY))
4964 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4965 (plus:DI (match_dup 1) (match_dup 2)))]
4966 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4967 "add{q}\t{%2, %0|%0, %2}"
4968 [(set_attr "type" "alu")
4969 (set_attr "mode" "DI")])
4970
4971 (define_insn "addqi3_carry"
4972 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4973 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4974 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4975 (match_operand:QI 2 "general_operand" "qi,qm")))
4976 (clobber (reg:CC FLAGS_REG))]
4977 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4978 "adc{b}\t{%2, %0|%0, %2}"
4979 [(set_attr "type" "alu")
4980 (set_attr "pent_pair" "pu")
4981 (set_attr "mode" "QI")])
4982
4983 (define_insn "addhi3_carry"
4984 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4985 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4986 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4987 (match_operand:HI 2 "general_operand" "ri,rm")))
4988 (clobber (reg:CC FLAGS_REG))]
4989 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4990 "adc{w}\t{%2, %0|%0, %2}"
4991 [(set_attr "type" "alu")
4992 (set_attr "pent_pair" "pu")
4993 (set_attr "mode" "HI")])
4994
4995 (define_insn "addsi3_carry"
4996 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4997 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4998 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4999 (match_operand:SI 2 "general_operand" "ri,rm")))
5000 (clobber (reg:CC FLAGS_REG))]
5001 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5002 "adc{l}\t{%2, %0|%0, %2}"
5003 [(set_attr "type" "alu")
5004 (set_attr "pent_pair" "pu")
5005 (set_attr "mode" "SI")])
5006
5007 (define_insn "*addsi3_carry_zext"
5008 [(set (match_operand:DI 0 "register_operand" "=r")
5009 (zero_extend:DI
5010 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5011 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5012 (match_operand:SI 2 "general_operand" "rim"))))
5013 (clobber (reg:CC FLAGS_REG))]
5014 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5015 "adc{l}\t{%2, %k0|%k0, %2}"
5016 [(set_attr "type" "alu")
5017 (set_attr "pent_pair" "pu")
5018 (set_attr "mode" "SI")])
5019
5020 (define_insn "*addsi3_cc"
5021 [(set (reg:CC FLAGS_REG)
5022 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5023 (match_operand:SI 2 "general_operand" "ri,rm")]
5024 UNSPEC_ADD_CARRY))
5025 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5026 (plus:SI (match_dup 1) (match_dup 2)))]
5027 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5028 "add{l}\t{%2, %0|%0, %2}"
5029 [(set_attr "type" "alu")
5030 (set_attr "mode" "SI")])
5031
5032 (define_insn "addqi3_cc"
5033 [(set (reg:CC FLAGS_REG)
5034 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5035 (match_operand:QI 2 "general_operand" "qi,qm")]
5036 UNSPEC_ADD_CARRY))
5037 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5038 (plus:QI (match_dup 1) (match_dup 2)))]
5039 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5040 "add{b}\t{%2, %0|%0, %2}"
5041 [(set_attr "type" "alu")
5042 (set_attr "mode" "QI")])
5043
5044 (define_expand "addsi3"
5045 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5046 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5047 (match_operand:SI 2 "general_operand" "")))
5048 (clobber (reg:CC FLAGS_REG))])]
5049 ""
5050 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5051
5052 (define_insn "*lea_1"
5053 [(set (match_operand:SI 0 "register_operand" "=r")
5054 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5055 "!TARGET_64BIT"
5056 "lea{l}\t{%a1, %0|%0, %a1}"
5057 [(set_attr "type" "lea")
5058 (set_attr "mode" "SI")])
5059
5060 (define_insn "*lea_1_rex64"
5061 [(set (match_operand:SI 0 "register_operand" "=r")
5062 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5063 "TARGET_64BIT"
5064 "lea{l}\t{%a1, %0|%0, %a1}"
5065 [(set_attr "type" "lea")
5066 (set_attr "mode" "SI")])
5067
5068 (define_insn "*lea_1_zext"
5069 [(set (match_operand:DI 0 "register_operand" "=r")
5070 (zero_extend:DI
5071 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5072 "TARGET_64BIT"
5073 "lea{l}\t{%a1, %k0|%k0, %a1}"
5074 [(set_attr "type" "lea")
5075 (set_attr "mode" "SI")])
5076
5077 (define_insn "*lea_2_rex64"
5078 [(set (match_operand:DI 0 "register_operand" "=r")
5079 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5080 "TARGET_64BIT"
5081 "lea{q}\t{%a1, %0|%0, %a1}"
5082 [(set_attr "type" "lea")
5083 (set_attr "mode" "DI")])
5084
5085 ;; The lea patterns for non-Pmodes needs to be matched by several
5086 ;; insns converted to real lea by splitters.
5087
5088 (define_insn_and_split "*lea_general_1"
5089 [(set (match_operand 0 "register_operand" "=r")
5090 (plus (plus (match_operand 1 "index_register_operand" "l")
5091 (match_operand 2 "register_operand" "r"))
5092 (match_operand 3 "immediate_operand" "i")))]
5093 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5094 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5095 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5096 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5097 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5098 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5099 || GET_MODE (operands[3]) == VOIDmode)"
5100 "#"
5101 "&& reload_completed"
5102 [(const_int 0)]
5103 {
5104 rtx pat;
5105 operands[0] = gen_lowpart (SImode, operands[0]);
5106 operands[1] = gen_lowpart (Pmode, operands[1]);
5107 operands[2] = gen_lowpart (Pmode, operands[2]);
5108 operands[3] = gen_lowpart (Pmode, operands[3]);
5109 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5110 operands[3]);
5111 if (Pmode != SImode)
5112 pat = gen_rtx_SUBREG (SImode, pat, 0);
5113 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5114 DONE;
5115 }
5116 [(set_attr "type" "lea")
5117 (set_attr "mode" "SI")])
5118
5119 (define_insn_and_split "*lea_general_1_zext"
5120 [(set (match_operand:DI 0 "register_operand" "=r")
5121 (zero_extend:DI
5122 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5123 (match_operand:SI 2 "register_operand" "r"))
5124 (match_operand:SI 3 "immediate_operand" "i"))))]
5125 "TARGET_64BIT"
5126 "#"
5127 "&& reload_completed"
5128 [(set (match_dup 0)
5129 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5130 (match_dup 2))
5131 (match_dup 3)) 0)))]
5132 {
5133 operands[1] = gen_lowpart (Pmode, operands[1]);
5134 operands[2] = gen_lowpart (Pmode, operands[2]);
5135 operands[3] = gen_lowpart (Pmode, operands[3]);
5136 }
5137 [(set_attr "type" "lea")
5138 (set_attr "mode" "SI")])
5139
5140 (define_insn_and_split "*lea_general_2"
5141 [(set (match_operand 0 "register_operand" "=r")
5142 (plus (mult (match_operand 1 "index_register_operand" "l")
5143 (match_operand 2 "const248_operand" "i"))
5144 (match_operand 3 "nonmemory_operand" "ri")))]
5145 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5146 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5147 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5148 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5149 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5150 || GET_MODE (operands[3]) == VOIDmode)"
5151 "#"
5152 "&& reload_completed"
5153 [(const_int 0)]
5154 {
5155 rtx pat;
5156 operands[0] = gen_lowpart (SImode, operands[0]);
5157 operands[1] = gen_lowpart (Pmode, operands[1]);
5158 operands[3] = gen_lowpart (Pmode, operands[3]);
5159 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5160 operands[3]);
5161 if (Pmode != SImode)
5162 pat = gen_rtx_SUBREG (SImode, pat, 0);
5163 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5164 DONE;
5165 }
5166 [(set_attr "type" "lea")
5167 (set_attr "mode" "SI")])
5168
5169 (define_insn_and_split "*lea_general_2_zext"
5170 [(set (match_operand:DI 0 "register_operand" "=r")
5171 (zero_extend:DI
5172 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5173 (match_operand:SI 2 "const248_operand" "n"))
5174 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5175 "TARGET_64BIT"
5176 "#"
5177 "&& reload_completed"
5178 [(set (match_dup 0)
5179 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5180 (match_dup 2))
5181 (match_dup 3)) 0)))]
5182 {
5183 operands[1] = gen_lowpart (Pmode, operands[1]);
5184 operands[3] = gen_lowpart (Pmode, operands[3]);
5185 }
5186 [(set_attr "type" "lea")
5187 (set_attr "mode" "SI")])
5188
5189 (define_insn_and_split "*lea_general_3"
5190 [(set (match_operand 0 "register_operand" "=r")
5191 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5192 (match_operand 2 "const248_operand" "i"))
5193 (match_operand 3 "register_operand" "r"))
5194 (match_operand 4 "immediate_operand" "i")))]
5195 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5196 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5197 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5198 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5199 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5200 "#"
5201 "&& reload_completed"
5202 [(const_int 0)]
5203 {
5204 rtx pat;
5205 operands[0] = gen_lowpart (SImode, operands[0]);
5206 operands[1] = gen_lowpart (Pmode, operands[1]);
5207 operands[3] = gen_lowpart (Pmode, operands[3]);
5208 operands[4] = gen_lowpart (Pmode, operands[4]);
5209 pat = gen_rtx_PLUS (Pmode,
5210 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5211 operands[2]),
5212 operands[3]),
5213 operands[4]);
5214 if (Pmode != SImode)
5215 pat = gen_rtx_SUBREG (SImode, pat, 0);
5216 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5217 DONE;
5218 }
5219 [(set_attr "type" "lea")
5220 (set_attr "mode" "SI")])
5221
5222 (define_insn_and_split "*lea_general_3_zext"
5223 [(set (match_operand:DI 0 "register_operand" "=r")
5224 (zero_extend:DI
5225 (plus:SI (plus:SI (mult:SI
5226 (match_operand:SI 1 "index_register_operand" "l")
5227 (match_operand:SI 2 "const248_operand" "n"))
5228 (match_operand:SI 3 "register_operand" "r"))
5229 (match_operand:SI 4 "immediate_operand" "i"))))]
5230 "TARGET_64BIT"
5231 "#"
5232 "&& reload_completed"
5233 [(set (match_dup 0)
5234 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5235 (match_dup 2))
5236 (match_dup 3))
5237 (match_dup 4)) 0)))]
5238 {
5239 operands[1] = gen_lowpart (Pmode, operands[1]);
5240 operands[3] = gen_lowpart (Pmode, operands[3]);
5241 operands[4] = gen_lowpart (Pmode, operands[4]);
5242 }
5243 [(set_attr "type" "lea")
5244 (set_attr "mode" "SI")])
5245
5246 (define_insn "*adddi_1_rex64"
5247 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5248 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5249 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5250 (clobber (reg:CC FLAGS_REG))]
5251 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5252 {
5253 switch (get_attr_type (insn))
5254 {
5255 case TYPE_LEA:
5256 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5257 return "lea{q}\t{%a2, %0|%0, %a2}";
5258
5259 case TYPE_INCDEC:
5260 if (! rtx_equal_p (operands[0], operands[1]))
5261 abort ();
5262 if (operands[2] == const1_rtx)
5263 return "inc{q}\t%0";
5264 else if (operands[2] == constm1_rtx)
5265 return "dec{q}\t%0";
5266 else
5267 abort ();
5268
5269 default:
5270 if (! rtx_equal_p (operands[0], operands[1]))
5271 abort ();
5272
5273 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5274 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5275 if (GET_CODE (operands[2]) == CONST_INT
5276 /* Avoid overflows. */
5277 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5278 && (INTVAL (operands[2]) == 128
5279 || (INTVAL (operands[2]) < 0
5280 && INTVAL (operands[2]) != -128)))
5281 {
5282 operands[2] = GEN_INT (-INTVAL (operands[2]));
5283 return "sub{q}\t{%2, %0|%0, %2}";
5284 }
5285 return "add{q}\t{%2, %0|%0, %2}";
5286 }
5287 }
5288 [(set (attr "type")
5289 (cond [(eq_attr "alternative" "2")
5290 (const_string "lea")
5291 ; Current assemblers are broken and do not allow @GOTOFF in
5292 ; ought but a memory context.
5293 (match_operand:DI 2 "pic_symbolic_operand" "")
5294 (const_string "lea")
5295 (match_operand:DI 2 "incdec_operand" "")
5296 (const_string "incdec")
5297 ]
5298 (const_string "alu")))
5299 (set_attr "mode" "DI")])
5300
5301 ;; Convert lea to the lea pattern to avoid flags dependency.
5302 (define_split
5303 [(set (match_operand:DI 0 "register_operand" "")
5304 (plus:DI (match_operand:DI 1 "register_operand" "")
5305 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5306 (clobber (reg:CC FLAGS_REG))]
5307 "TARGET_64BIT && reload_completed
5308 && true_regnum (operands[0]) != true_regnum (operands[1])"
5309 [(set (match_dup 0)
5310 (plus:DI (match_dup 1)
5311 (match_dup 2)))]
5312 "")
5313
5314 (define_insn "*adddi_2_rex64"
5315 [(set (reg FLAGS_REG)
5316 (compare
5317 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5318 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5319 (const_int 0)))
5320 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5321 (plus:DI (match_dup 1) (match_dup 2)))]
5322 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5323 && ix86_binary_operator_ok (PLUS, DImode, operands)
5324 /* Current assemblers are broken and do not allow @GOTOFF in
5325 ought but a memory context. */
5326 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5327 {
5328 switch (get_attr_type (insn))
5329 {
5330 case TYPE_INCDEC:
5331 if (! rtx_equal_p (operands[0], operands[1]))
5332 abort ();
5333 if (operands[2] == const1_rtx)
5334 return "inc{q}\t%0";
5335 else if (operands[2] == constm1_rtx)
5336 return "dec{q}\t%0";
5337 else
5338 abort ();
5339
5340 default:
5341 if (! rtx_equal_p (operands[0], operands[1]))
5342 abort ();
5343 /* ???? We ought to handle there the 32bit case too
5344 - do we need new constraint? */
5345 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5346 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5347 if (GET_CODE (operands[2]) == CONST_INT
5348 /* Avoid overflows. */
5349 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5350 && (INTVAL (operands[2]) == 128
5351 || (INTVAL (operands[2]) < 0
5352 && INTVAL (operands[2]) != -128)))
5353 {
5354 operands[2] = GEN_INT (-INTVAL (operands[2]));
5355 return "sub{q}\t{%2, %0|%0, %2}";
5356 }
5357 return "add{q}\t{%2, %0|%0, %2}";
5358 }
5359 }
5360 [(set (attr "type")
5361 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5362 (const_string "incdec")
5363 (const_string "alu")))
5364 (set_attr "mode" "DI")])
5365
5366 (define_insn "*adddi_3_rex64"
5367 [(set (reg FLAGS_REG)
5368 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5369 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5370 (clobber (match_scratch:DI 0 "=r"))]
5371 "TARGET_64BIT
5372 && ix86_match_ccmode (insn, CCZmode)
5373 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5374 /* Current assemblers are broken and do not allow @GOTOFF in
5375 ought but a memory context. */
5376 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5377 {
5378 switch (get_attr_type (insn))
5379 {
5380 case TYPE_INCDEC:
5381 if (! rtx_equal_p (operands[0], operands[1]))
5382 abort ();
5383 if (operands[2] == const1_rtx)
5384 return "inc{q}\t%0";
5385 else if (operands[2] == constm1_rtx)
5386 return "dec{q}\t%0";
5387 else
5388 abort ();
5389
5390 default:
5391 if (! rtx_equal_p (operands[0], operands[1]))
5392 abort ();
5393 /* ???? We ought to handle there the 32bit case too
5394 - do we need new constraint? */
5395 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5396 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5397 if (GET_CODE (operands[2]) == CONST_INT
5398 /* Avoid overflows. */
5399 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5400 && (INTVAL (operands[2]) == 128
5401 || (INTVAL (operands[2]) < 0
5402 && INTVAL (operands[2]) != -128)))
5403 {
5404 operands[2] = GEN_INT (-INTVAL (operands[2]));
5405 return "sub{q}\t{%2, %0|%0, %2}";
5406 }
5407 return "add{q}\t{%2, %0|%0, %2}";
5408 }
5409 }
5410 [(set (attr "type")
5411 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5412 (const_string "incdec")
5413 (const_string "alu")))
5414 (set_attr "mode" "DI")])
5415
5416 ; For comparisons against 1, -1 and 128, we may generate better code
5417 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5418 ; is matched then. We can't accept general immediate, because for
5419 ; case of overflows, the result is messed up.
5420 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5421 ; when negated.
5422 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5423 ; only for comparisons not depending on it.
5424 (define_insn "*adddi_4_rex64"
5425 [(set (reg FLAGS_REG)
5426 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5427 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5428 (clobber (match_scratch:DI 0 "=rm"))]
5429 "TARGET_64BIT
5430 && ix86_match_ccmode (insn, CCGCmode)"
5431 {
5432 switch (get_attr_type (insn))
5433 {
5434 case TYPE_INCDEC:
5435 if (operands[2] == constm1_rtx)
5436 return "inc{q}\t%0";
5437 else if (operands[2] == const1_rtx)
5438 return "dec{q}\t%0";
5439 else
5440 abort();
5441
5442 default:
5443 if (! rtx_equal_p (operands[0], operands[1]))
5444 abort ();
5445 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5446 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5447 if ((INTVAL (operands[2]) == -128
5448 || (INTVAL (operands[2]) > 0
5449 && INTVAL (operands[2]) != 128))
5450 /* Avoid overflows. */
5451 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5452 return "sub{q}\t{%2, %0|%0, %2}";
5453 operands[2] = GEN_INT (-INTVAL (operands[2]));
5454 return "add{q}\t{%2, %0|%0, %2}";
5455 }
5456 }
5457 [(set (attr "type")
5458 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5459 (const_string "incdec")
5460 (const_string "alu")))
5461 (set_attr "mode" "DI")])
5462
5463 (define_insn "*adddi_5_rex64"
5464 [(set (reg FLAGS_REG)
5465 (compare
5466 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5467 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5468 (const_int 0)))
5469 (clobber (match_scratch:DI 0 "=r"))]
5470 "TARGET_64BIT
5471 && ix86_match_ccmode (insn, CCGOCmode)
5472 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5473 /* Current assemblers are broken and do not allow @GOTOFF in
5474 ought but a memory context. */
5475 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5476 {
5477 switch (get_attr_type (insn))
5478 {
5479 case TYPE_INCDEC:
5480 if (! rtx_equal_p (operands[0], operands[1]))
5481 abort ();
5482 if (operands[2] == const1_rtx)
5483 return "inc{q}\t%0";
5484 else if (operands[2] == constm1_rtx)
5485 return "dec{q}\t%0";
5486 else
5487 abort();
5488
5489 default:
5490 if (! rtx_equal_p (operands[0], operands[1]))
5491 abort ();
5492 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5493 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5494 if (GET_CODE (operands[2]) == CONST_INT
5495 /* Avoid overflows. */
5496 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5497 && (INTVAL (operands[2]) == 128
5498 || (INTVAL (operands[2]) < 0
5499 && INTVAL (operands[2]) != -128)))
5500 {
5501 operands[2] = GEN_INT (-INTVAL (operands[2]));
5502 return "sub{q}\t{%2, %0|%0, %2}";
5503 }
5504 return "add{q}\t{%2, %0|%0, %2}";
5505 }
5506 }
5507 [(set (attr "type")
5508 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5509 (const_string "incdec")
5510 (const_string "alu")))
5511 (set_attr "mode" "DI")])
5512
5513
5514 (define_insn "*addsi_1"
5515 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5516 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5517 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5518 (clobber (reg:CC FLAGS_REG))]
5519 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5520 {
5521 switch (get_attr_type (insn))
5522 {
5523 case TYPE_LEA:
5524 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5525 return "lea{l}\t{%a2, %0|%0, %a2}";
5526
5527 case TYPE_INCDEC:
5528 if (! rtx_equal_p (operands[0], operands[1]))
5529 abort ();
5530 if (operands[2] == const1_rtx)
5531 return "inc{l}\t%0";
5532 else if (operands[2] == constm1_rtx)
5533 return "dec{l}\t%0";
5534 else
5535 abort();
5536
5537 default:
5538 if (! rtx_equal_p (operands[0], operands[1]))
5539 abort ();
5540
5541 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5542 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5543 if (GET_CODE (operands[2]) == CONST_INT
5544 && (INTVAL (operands[2]) == 128
5545 || (INTVAL (operands[2]) < 0
5546 && INTVAL (operands[2]) != -128)))
5547 {
5548 operands[2] = GEN_INT (-INTVAL (operands[2]));
5549 return "sub{l}\t{%2, %0|%0, %2}";
5550 }
5551 return "add{l}\t{%2, %0|%0, %2}";
5552 }
5553 }
5554 [(set (attr "type")
5555 (cond [(eq_attr "alternative" "2")
5556 (const_string "lea")
5557 ; Current assemblers are broken and do not allow @GOTOFF in
5558 ; ought but a memory context.
5559 (match_operand:SI 2 "pic_symbolic_operand" "")
5560 (const_string "lea")
5561 (match_operand:SI 2 "incdec_operand" "")
5562 (const_string "incdec")
5563 ]
5564 (const_string "alu")))
5565 (set_attr "mode" "SI")])
5566
5567 ;; Convert lea to the lea pattern to avoid flags dependency.
5568 (define_split
5569 [(set (match_operand 0 "register_operand" "")
5570 (plus (match_operand 1 "register_operand" "")
5571 (match_operand 2 "nonmemory_operand" "")))
5572 (clobber (reg:CC FLAGS_REG))]
5573 "reload_completed
5574 && true_regnum (operands[0]) != true_regnum (operands[1])"
5575 [(const_int 0)]
5576 {
5577 rtx pat;
5578 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5579 may confuse gen_lowpart. */
5580 if (GET_MODE (operands[0]) != Pmode)
5581 {
5582 operands[1] = gen_lowpart (Pmode, operands[1]);
5583 operands[2] = gen_lowpart (Pmode, operands[2]);
5584 }
5585 operands[0] = gen_lowpart (SImode, operands[0]);
5586 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5587 if (Pmode != SImode)
5588 pat = gen_rtx_SUBREG (SImode, pat, 0);
5589 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5590 DONE;
5591 })
5592
5593 ;; It may seem that nonimmediate operand is proper one for operand 1.
5594 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5595 ;; we take care in ix86_binary_operator_ok to not allow two memory
5596 ;; operands so proper swapping will be done in reload. This allow
5597 ;; patterns constructed from addsi_1 to match.
5598 (define_insn "addsi_1_zext"
5599 [(set (match_operand:DI 0 "register_operand" "=r,r")
5600 (zero_extend:DI
5601 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5602 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5603 (clobber (reg:CC FLAGS_REG))]
5604 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5605 {
5606 switch (get_attr_type (insn))
5607 {
5608 case TYPE_LEA:
5609 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5610 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5611
5612 case TYPE_INCDEC:
5613 if (operands[2] == const1_rtx)
5614 return "inc{l}\t%k0";
5615 else if (operands[2] == constm1_rtx)
5616 return "dec{l}\t%k0";
5617 else
5618 abort();
5619
5620 default:
5621 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5622 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5623 if (GET_CODE (operands[2]) == CONST_INT
5624 && (INTVAL (operands[2]) == 128
5625 || (INTVAL (operands[2]) < 0
5626 && INTVAL (operands[2]) != -128)))
5627 {
5628 operands[2] = GEN_INT (-INTVAL (operands[2]));
5629 return "sub{l}\t{%2, %k0|%k0, %2}";
5630 }
5631 return "add{l}\t{%2, %k0|%k0, %2}";
5632 }
5633 }
5634 [(set (attr "type")
5635 (cond [(eq_attr "alternative" "1")
5636 (const_string "lea")
5637 ; Current assemblers are broken and do not allow @GOTOFF in
5638 ; ought but a memory context.
5639 (match_operand:SI 2 "pic_symbolic_operand" "")
5640 (const_string "lea")
5641 (match_operand:SI 2 "incdec_operand" "")
5642 (const_string "incdec")
5643 ]
5644 (const_string "alu")))
5645 (set_attr "mode" "SI")])
5646
5647 ;; Convert lea to the lea pattern to avoid flags dependency.
5648 (define_split
5649 [(set (match_operand:DI 0 "register_operand" "")
5650 (zero_extend:DI
5651 (plus:SI (match_operand:SI 1 "register_operand" "")
5652 (match_operand:SI 2 "nonmemory_operand" ""))))
5653 (clobber (reg:CC FLAGS_REG))]
5654 "TARGET_64BIT && reload_completed
5655 && true_regnum (operands[0]) != true_regnum (operands[1])"
5656 [(set (match_dup 0)
5657 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5658 {
5659 operands[1] = gen_lowpart (Pmode, operands[1]);
5660 operands[2] = gen_lowpart (Pmode, operands[2]);
5661 })
5662
5663 (define_insn "*addsi_2"
5664 [(set (reg FLAGS_REG)
5665 (compare
5666 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5667 (match_operand:SI 2 "general_operand" "rmni,rni"))
5668 (const_int 0)))
5669 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5670 (plus:SI (match_dup 1) (match_dup 2)))]
5671 "ix86_match_ccmode (insn, CCGOCmode)
5672 && ix86_binary_operator_ok (PLUS, SImode, operands)
5673 /* Current assemblers are broken and do not allow @GOTOFF in
5674 ought but a memory context. */
5675 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5676 {
5677 switch (get_attr_type (insn))
5678 {
5679 case TYPE_INCDEC:
5680 if (! rtx_equal_p (operands[0], operands[1]))
5681 abort ();
5682 if (operands[2] == const1_rtx)
5683 return "inc{l}\t%0";
5684 else if (operands[2] == constm1_rtx)
5685 return "dec{l}\t%0";
5686 else
5687 abort();
5688
5689 default:
5690 if (! rtx_equal_p (operands[0], operands[1]))
5691 abort ();
5692 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5693 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5694 if (GET_CODE (operands[2]) == CONST_INT
5695 && (INTVAL (operands[2]) == 128
5696 || (INTVAL (operands[2]) < 0
5697 && INTVAL (operands[2]) != -128)))
5698 {
5699 operands[2] = GEN_INT (-INTVAL (operands[2]));
5700 return "sub{l}\t{%2, %0|%0, %2}";
5701 }
5702 return "add{l}\t{%2, %0|%0, %2}";
5703 }
5704 }
5705 [(set (attr "type")
5706 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5707 (const_string "incdec")
5708 (const_string "alu")))
5709 (set_attr "mode" "SI")])
5710
5711 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5712 (define_insn "*addsi_2_zext"
5713 [(set (reg FLAGS_REG)
5714 (compare
5715 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5716 (match_operand:SI 2 "general_operand" "rmni"))
5717 (const_int 0)))
5718 (set (match_operand:DI 0 "register_operand" "=r")
5719 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5720 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5721 && ix86_binary_operator_ok (PLUS, SImode, operands)
5722 /* Current assemblers are broken and do not allow @GOTOFF in
5723 ought but a memory context. */
5724 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5725 {
5726 switch (get_attr_type (insn))
5727 {
5728 case TYPE_INCDEC:
5729 if (operands[2] == const1_rtx)
5730 return "inc{l}\t%k0";
5731 else if (operands[2] == constm1_rtx)
5732 return "dec{l}\t%k0";
5733 else
5734 abort();
5735
5736 default:
5737 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5738 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5739 if (GET_CODE (operands[2]) == CONST_INT
5740 && (INTVAL (operands[2]) == 128
5741 || (INTVAL (operands[2]) < 0
5742 && INTVAL (operands[2]) != -128)))
5743 {
5744 operands[2] = GEN_INT (-INTVAL (operands[2]));
5745 return "sub{l}\t{%2, %k0|%k0, %2}";
5746 }
5747 return "add{l}\t{%2, %k0|%k0, %2}";
5748 }
5749 }
5750 [(set (attr "type")
5751 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5752 (const_string "incdec")
5753 (const_string "alu")))
5754 (set_attr "mode" "SI")])
5755
5756 (define_insn "*addsi_3"
5757 [(set (reg FLAGS_REG)
5758 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5759 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5760 (clobber (match_scratch:SI 0 "=r"))]
5761 "ix86_match_ccmode (insn, CCZmode)
5762 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5763 /* Current assemblers are broken and do not allow @GOTOFF in
5764 ought but a memory context. */
5765 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5766 {
5767 switch (get_attr_type (insn))
5768 {
5769 case TYPE_INCDEC:
5770 if (! rtx_equal_p (operands[0], operands[1]))
5771 abort ();
5772 if (operands[2] == const1_rtx)
5773 return "inc{l}\t%0";
5774 else if (operands[2] == constm1_rtx)
5775 return "dec{l}\t%0";
5776 else
5777 abort();
5778
5779 default:
5780 if (! rtx_equal_p (operands[0], operands[1]))
5781 abort ();
5782 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5783 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5784 if (GET_CODE (operands[2]) == CONST_INT
5785 && (INTVAL (operands[2]) == 128
5786 || (INTVAL (operands[2]) < 0
5787 && INTVAL (operands[2]) != -128)))
5788 {
5789 operands[2] = GEN_INT (-INTVAL (operands[2]));
5790 return "sub{l}\t{%2, %0|%0, %2}";
5791 }
5792 return "add{l}\t{%2, %0|%0, %2}";
5793 }
5794 }
5795 [(set (attr "type")
5796 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5797 (const_string "incdec")
5798 (const_string "alu")))
5799 (set_attr "mode" "SI")])
5800
5801 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5802 (define_insn "*addsi_3_zext"
5803 [(set (reg FLAGS_REG)
5804 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5805 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5806 (set (match_operand:DI 0 "register_operand" "=r")
5807 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5808 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5809 && ix86_binary_operator_ok (PLUS, SImode, operands)
5810 /* Current assemblers are broken and do not allow @GOTOFF in
5811 ought but a memory context. */
5812 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5813 {
5814 switch (get_attr_type (insn))
5815 {
5816 case TYPE_INCDEC:
5817 if (operands[2] == const1_rtx)
5818 return "inc{l}\t%k0";
5819 else if (operands[2] == constm1_rtx)
5820 return "dec{l}\t%k0";
5821 else
5822 abort();
5823
5824 default:
5825 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5826 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5827 if (GET_CODE (operands[2]) == CONST_INT
5828 && (INTVAL (operands[2]) == 128
5829 || (INTVAL (operands[2]) < 0
5830 && INTVAL (operands[2]) != -128)))
5831 {
5832 operands[2] = GEN_INT (-INTVAL (operands[2]));
5833 return "sub{l}\t{%2, %k0|%k0, %2}";
5834 }
5835 return "add{l}\t{%2, %k0|%k0, %2}";
5836 }
5837 }
5838 [(set (attr "type")
5839 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5840 (const_string "incdec")
5841 (const_string "alu")))
5842 (set_attr "mode" "SI")])
5843
5844 ; For comparisons against 1, -1 and 128, we may generate better code
5845 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5846 ; is matched then. We can't accept general immediate, because for
5847 ; case of overflows, the result is messed up.
5848 ; This pattern also don't hold of 0x80000000, since the value overflows
5849 ; when negated.
5850 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5851 ; only for comparisons not depending on it.
5852 (define_insn "*addsi_4"
5853 [(set (reg FLAGS_REG)
5854 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5855 (match_operand:SI 2 "const_int_operand" "n")))
5856 (clobber (match_scratch:SI 0 "=rm"))]
5857 "ix86_match_ccmode (insn, CCGCmode)
5858 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5859 {
5860 switch (get_attr_type (insn))
5861 {
5862 case TYPE_INCDEC:
5863 if (operands[2] == constm1_rtx)
5864 return "inc{l}\t%0";
5865 else if (operands[2] == const1_rtx)
5866 return "dec{l}\t%0";
5867 else
5868 abort();
5869
5870 default:
5871 if (! rtx_equal_p (operands[0], operands[1]))
5872 abort ();
5873 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5875 if ((INTVAL (operands[2]) == -128
5876 || (INTVAL (operands[2]) > 0
5877 && INTVAL (operands[2]) != 128)))
5878 return "sub{l}\t{%2, %0|%0, %2}";
5879 operands[2] = GEN_INT (-INTVAL (operands[2]));
5880 return "add{l}\t{%2, %0|%0, %2}";
5881 }
5882 }
5883 [(set (attr "type")
5884 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5885 (const_string "incdec")
5886 (const_string "alu")))
5887 (set_attr "mode" "SI")])
5888
5889 (define_insn "*addsi_5"
5890 [(set (reg FLAGS_REG)
5891 (compare
5892 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5893 (match_operand:SI 2 "general_operand" "rmni"))
5894 (const_int 0)))
5895 (clobber (match_scratch:SI 0 "=r"))]
5896 "ix86_match_ccmode (insn, CCGOCmode)
5897 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5898 /* Current assemblers are broken and do not allow @GOTOFF in
5899 ought but a memory context. */
5900 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5901 {
5902 switch (get_attr_type (insn))
5903 {
5904 case TYPE_INCDEC:
5905 if (! rtx_equal_p (operands[0], operands[1]))
5906 abort ();
5907 if (operands[2] == const1_rtx)
5908 return "inc{l}\t%0";
5909 else if (operands[2] == constm1_rtx)
5910 return "dec{l}\t%0";
5911 else
5912 abort();
5913
5914 default:
5915 if (! rtx_equal_p (operands[0], operands[1]))
5916 abort ();
5917 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5918 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5919 if (GET_CODE (operands[2]) == CONST_INT
5920 && (INTVAL (operands[2]) == 128
5921 || (INTVAL (operands[2]) < 0
5922 && INTVAL (operands[2]) != -128)))
5923 {
5924 operands[2] = GEN_INT (-INTVAL (operands[2]));
5925 return "sub{l}\t{%2, %0|%0, %2}";
5926 }
5927 return "add{l}\t{%2, %0|%0, %2}";
5928 }
5929 }
5930 [(set (attr "type")
5931 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5932 (const_string "incdec")
5933 (const_string "alu")))
5934 (set_attr "mode" "SI")])
5935
5936 (define_expand "addhi3"
5937 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5938 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5939 (match_operand:HI 2 "general_operand" "")))
5940 (clobber (reg:CC FLAGS_REG))])]
5941 "TARGET_HIMODE_MATH"
5942 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5943
5944 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5945 ;; type optimizations enabled by define-splits. This is not important
5946 ;; for PII, and in fact harmful because of partial register stalls.
5947
5948 (define_insn "*addhi_1_lea"
5949 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5950 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5951 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5952 (clobber (reg:CC FLAGS_REG))]
5953 "!TARGET_PARTIAL_REG_STALL
5954 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5955 {
5956 switch (get_attr_type (insn))
5957 {
5958 case TYPE_LEA:
5959 return "#";
5960 case TYPE_INCDEC:
5961 if (operands[2] == const1_rtx)
5962 return "inc{w}\t%0";
5963 else if (operands[2] == constm1_rtx)
5964 return "dec{w}\t%0";
5965 abort();
5966
5967 default:
5968 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5969 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5970 if (GET_CODE (operands[2]) == CONST_INT
5971 && (INTVAL (operands[2]) == 128
5972 || (INTVAL (operands[2]) < 0
5973 && INTVAL (operands[2]) != -128)))
5974 {
5975 operands[2] = GEN_INT (-INTVAL (operands[2]));
5976 return "sub{w}\t{%2, %0|%0, %2}";
5977 }
5978 return "add{w}\t{%2, %0|%0, %2}";
5979 }
5980 }
5981 [(set (attr "type")
5982 (if_then_else (eq_attr "alternative" "2")
5983 (const_string "lea")
5984 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5985 (const_string "incdec")
5986 (const_string "alu"))))
5987 (set_attr "mode" "HI,HI,SI")])
5988
5989 (define_insn "*addhi_1"
5990 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5991 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5992 (match_operand:HI 2 "general_operand" "ri,rm")))
5993 (clobber (reg:CC FLAGS_REG))]
5994 "TARGET_PARTIAL_REG_STALL
5995 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5996 {
5997 switch (get_attr_type (insn))
5998 {
5999 case TYPE_INCDEC:
6000 if (operands[2] == const1_rtx)
6001 return "inc{w}\t%0";
6002 else if (operands[2] == constm1_rtx)
6003 return "dec{w}\t%0";
6004 abort();
6005
6006 default:
6007 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6008 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6009 if (GET_CODE (operands[2]) == CONST_INT
6010 && (INTVAL (operands[2]) == 128
6011 || (INTVAL (operands[2]) < 0
6012 && INTVAL (operands[2]) != -128)))
6013 {
6014 operands[2] = GEN_INT (-INTVAL (operands[2]));
6015 return "sub{w}\t{%2, %0|%0, %2}";
6016 }
6017 return "add{w}\t{%2, %0|%0, %2}";
6018 }
6019 }
6020 [(set (attr "type")
6021 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6022 (const_string "incdec")
6023 (const_string "alu")))
6024 (set_attr "mode" "HI")])
6025
6026 (define_insn "*addhi_2"
6027 [(set (reg FLAGS_REG)
6028 (compare
6029 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6030 (match_operand:HI 2 "general_operand" "rmni,rni"))
6031 (const_int 0)))
6032 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6033 (plus:HI (match_dup 1) (match_dup 2)))]
6034 "ix86_match_ccmode (insn, CCGOCmode)
6035 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6036 {
6037 switch (get_attr_type (insn))
6038 {
6039 case TYPE_INCDEC:
6040 if (operands[2] == const1_rtx)
6041 return "inc{w}\t%0";
6042 else if (operands[2] == constm1_rtx)
6043 return "dec{w}\t%0";
6044 abort();
6045
6046 default:
6047 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6048 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6049 if (GET_CODE (operands[2]) == CONST_INT
6050 && (INTVAL (operands[2]) == 128
6051 || (INTVAL (operands[2]) < 0
6052 && INTVAL (operands[2]) != -128)))
6053 {
6054 operands[2] = GEN_INT (-INTVAL (operands[2]));
6055 return "sub{w}\t{%2, %0|%0, %2}";
6056 }
6057 return "add{w}\t{%2, %0|%0, %2}";
6058 }
6059 }
6060 [(set (attr "type")
6061 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6062 (const_string "incdec")
6063 (const_string "alu")))
6064 (set_attr "mode" "HI")])
6065
6066 (define_insn "*addhi_3"
6067 [(set (reg FLAGS_REG)
6068 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6069 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6070 (clobber (match_scratch:HI 0 "=r"))]
6071 "ix86_match_ccmode (insn, CCZmode)
6072 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6073 {
6074 switch (get_attr_type (insn))
6075 {
6076 case TYPE_INCDEC:
6077 if (operands[2] == const1_rtx)
6078 return "inc{w}\t%0";
6079 else if (operands[2] == constm1_rtx)
6080 return "dec{w}\t%0";
6081 abort();
6082
6083 default:
6084 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6085 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6086 if (GET_CODE (operands[2]) == CONST_INT
6087 && (INTVAL (operands[2]) == 128
6088 || (INTVAL (operands[2]) < 0
6089 && INTVAL (operands[2]) != -128)))
6090 {
6091 operands[2] = GEN_INT (-INTVAL (operands[2]));
6092 return "sub{w}\t{%2, %0|%0, %2}";
6093 }
6094 return "add{w}\t{%2, %0|%0, %2}";
6095 }
6096 }
6097 [(set (attr "type")
6098 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6099 (const_string "incdec")
6100 (const_string "alu")))
6101 (set_attr "mode" "HI")])
6102
6103 ; See comments above addsi_4 for details.
6104 (define_insn "*addhi_4"
6105 [(set (reg FLAGS_REG)
6106 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6107 (match_operand:HI 2 "const_int_operand" "n")))
6108 (clobber (match_scratch:HI 0 "=rm"))]
6109 "ix86_match_ccmode (insn, CCGCmode)
6110 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6111 {
6112 switch (get_attr_type (insn))
6113 {
6114 case TYPE_INCDEC:
6115 if (operands[2] == constm1_rtx)
6116 return "inc{w}\t%0";
6117 else if (operands[2] == const1_rtx)
6118 return "dec{w}\t%0";
6119 else
6120 abort();
6121
6122 default:
6123 if (! rtx_equal_p (operands[0], operands[1]))
6124 abort ();
6125 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6126 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6127 if ((INTVAL (operands[2]) == -128
6128 || (INTVAL (operands[2]) > 0
6129 && INTVAL (operands[2]) != 128)))
6130 return "sub{w}\t{%2, %0|%0, %2}";
6131 operands[2] = GEN_INT (-INTVAL (operands[2]));
6132 return "add{w}\t{%2, %0|%0, %2}";
6133 }
6134 }
6135 [(set (attr "type")
6136 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6137 (const_string "incdec")
6138 (const_string "alu")))
6139 (set_attr "mode" "SI")])
6140
6141
6142 (define_insn "*addhi_5"
6143 [(set (reg FLAGS_REG)
6144 (compare
6145 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6146 (match_operand:HI 2 "general_operand" "rmni"))
6147 (const_int 0)))
6148 (clobber (match_scratch:HI 0 "=r"))]
6149 "ix86_match_ccmode (insn, CCGOCmode)
6150 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6151 {
6152 switch (get_attr_type (insn))
6153 {
6154 case TYPE_INCDEC:
6155 if (operands[2] == const1_rtx)
6156 return "inc{w}\t%0";
6157 else if (operands[2] == constm1_rtx)
6158 return "dec{w}\t%0";
6159 abort();
6160
6161 default:
6162 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6163 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6164 if (GET_CODE (operands[2]) == CONST_INT
6165 && (INTVAL (operands[2]) == 128
6166 || (INTVAL (operands[2]) < 0
6167 && INTVAL (operands[2]) != -128)))
6168 {
6169 operands[2] = GEN_INT (-INTVAL (operands[2]));
6170 return "sub{w}\t{%2, %0|%0, %2}";
6171 }
6172 return "add{w}\t{%2, %0|%0, %2}";
6173 }
6174 }
6175 [(set (attr "type")
6176 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6177 (const_string "incdec")
6178 (const_string "alu")))
6179 (set_attr "mode" "HI")])
6180
6181 (define_expand "addqi3"
6182 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6183 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6184 (match_operand:QI 2 "general_operand" "")))
6185 (clobber (reg:CC FLAGS_REG))])]
6186 "TARGET_QIMODE_MATH"
6187 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6188
6189 ;; %%% Potential partial reg stall on alternative 2. What to do?
6190 (define_insn "*addqi_1_lea"
6191 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6192 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6193 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6194 (clobber (reg:CC FLAGS_REG))]
6195 "!TARGET_PARTIAL_REG_STALL
6196 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6197 {
6198 int widen = (which_alternative == 2);
6199 switch (get_attr_type (insn))
6200 {
6201 case TYPE_LEA:
6202 return "#";
6203 case TYPE_INCDEC:
6204 if (operands[2] == const1_rtx)
6205 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6206 else if (operands[2] == constm1_rtx)
6207 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6208 abort();
6209
6210 default:
6211 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6212 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6213 if (GET_CODE (operands[2]) == CONST_INT
6214 && (INTVAL (operands[2]) == 128
6215 || (INTVAL (operands[2]) < 0
6216 && INTVAL (operands[2]) != -128)))
6217 {
6218 operands[2] = GEN_INT (-INTVAL (operands[2]));
6219 if (widen)
6220 return "sub{l}\t{%2, %k0|%k0, %2}";
6221 else
6222 return "sub{b}\t{%2, %0|%0, %2}";
6223 }
6224 if (widen)
6225 return "add{l}\t{%k2, %k0|%k0, %k2}";
6226 else
6227 return "add{b}\t{%2, %0|%0, %2}";
6228 }
6229 }
6230 [(set (attr "type")
6231 (if_then_else (eq_attr "alternative" "3")
6232 (const_string "lea")
6233 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6234 (const_string "incdec")
6235 (const_string "alu"))))
6236 (set_attr "mode" "QI,QI,SI,SI")])
6237
6238 (define_insn "*addqi_1"
6239 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6240 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6241 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6242 (clobber (reg:CC FLAGS_REG))]
6243 "TARGET_PARTIAL_REG_STALL
6244 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6245 {
6246 int widen = (which_alternative == 2);
6247 switch (get_attr_type (insn))
6248 {
6249 case TYPE_INCDEC:
6250 if (operands[2] == const1_rtx)
6251 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6252 else if (operands[2] == constm1_rtx)
6253 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6254 abort();
6255
6256 default:
6257 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6258 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6259 if (GET_CODE (operands[2]) == CONST_INT
6260 && (INTVAL (operands[2]) == 128
6261 || (INTVAL (operands[2]) < 0
6262 && INTVAL (operands[2]) != -128)))
6263 {
6264 operands[2] = GEN_INT (-INTVAL (operands[2]));
6265 if (widen)
6266 return "sub{l}\t{%2, %k0|%k0, %2}";
6267 else
6268 return "sub{b}\t{%2, %0|%0, %2}";
6269 }
6270 if (widen)
6271 return "add{l}\t{%k2, %k0|%k0, %k2}";
6272 else
6273 return "add{b}\t{%2, %0|%0, %2}";
6274 }
6275 }
6276 [(set (attr "type")
6277 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6278 (const_string "incdec")
6279 (const_string "alu")))
6280 (set_attr "mode" "QI,QI,SI")])
6281
6282 (define_insn "*addqi_1_slp"
6283 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6284 (plus:QI (match_dup 0)
6285 (match_operand:QI 1 "general_operand" "qn,qnm")))
6286 (clobber (reg:CC FLAGS_REG))]
6287 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6288 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6289 {
6290 switch (get_attr_type (insn))
6291 {
6292 case TYPE_INCDEC:
6293 if (operands[1] == const1_rtx)
6294 return "inc{b}\t%0";
6295 else if (operands[1] == constm1_rtx)
6296 return "dec{b}\t%0";
6297 abort();
6298
6299 default:
6300 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6301 if (GET_CODE (operands[1]) == CONST_INT
6302 && INTVAL (operands[1]) < 0)
6303 {
6304 operands[1] = GEN_INT (-INTVAL (operands[1]));
6305 return "sub{b}\t{%1, %0|%0, %1}";
6306 }
6307 return "add{b}\t{%1, %0|%0, %1}";
6308 }
6309 }
6310 [(set (attr "type")
6311 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6312 (const_string "incdec")
6313 (const_string "alu1")))
6314 (set (attr "memory")
6315 (if_then_else (match_operand 1 "memory_operand" "")
6316 (const_string "load")
6317 (const_string "none")))
6318 (set_attr "mode" "QI")])
6319
6320 (define_insn "*addqi_2"
6321 [(set (reg FLAGS_REG)
6322 (compare
6323 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6324 (match_operand:QI 2 "general_operand" "qmni,qni"))
6325 (const_int 0)))
6326 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6327 (plus:QI (match_dup 1) (match_dup 2)))]
6328 "ix86_match_ccmode (insn, CCGOCmode)
6329 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6330 {
6331 switch (get_attr_type (insn))
6332 {
6333 case TYPE_INCDEC:
6334 if (operands[2] == const1_rtx)
6335 return "inc{b}\t%0";
6336 else if (operands[2] == constm1_rtx
6337 || (GET_CODE (operands[2]) == CONST_INT
6338 && INTVAL (operands[2]) == 255))
6339 return "dec{b}\t%0";
6340 abort();
6341
6342 default:
6343 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6344 if (GET_CODE (operands[2]) == CONST_INT
6345 && INTVAL (operands[2]) < 0)
6346 {
6347 operands[2] = GEN_INT (-INTVAL (operands[2]));
6348 return "sub{b}\t{%2, %0|%0, %2}";
6349 }
6350 return "add{b}\t{%2, %0|%0, %2}";
6351 }
6352 }
6353 [(set (attr "type")
6354 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6355 (const_string "incdec")
6356 (const_string "alu")))
6357 (set_attr "mode" "QI")])
6358
6359 (define_insn "*addqi_3"
6360 [(set (reg FLAGS_REG)
6361 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6362 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6363 (clobber (match_scratch:QI 0 "=q"))]
6364 "ix86_match_ccmode (insn, CCZmode)
6365 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6366 {
6367 switch (get_attr_type (insn))
6368 {
6369 case TYPE_INCDEC:
6370 if (operands[2] == const1_rtx)
6371 return "inc{b}\t%0";
6372 else if (operands[2] == constm1_rtx
6373 || (GET_CODE (operands[2]) == CONST_INT
6374 && INTVAL (operands[2]) == 255))
6375 return "dec{b}\t%0";
6376 abort();
6377
6378 default:
6379 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6380 if (GET_CODE (operands[2]) == CONST_INT
6381 && INTVAL (operands[2]) < 0)
6382 {
6383 operands[2] = GEN_INT (-INTVAL (operands[2]));
6384 return "sub{b}\t{%2, %0|%0, %2}";
6385 }
6386 return "add{b}\t{%2, %0|%0, %2}";
6387 }
6388 }
6389 [(set (attr "type")
6390 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6391 (const_string "incdec")
6392 (const_string "alu")))
6393 (set_attr "mode" "QI")])
6394
6395 ; See comments above addsi_4 for details.
6396 (define_insn "*addqi_4"
6397 [(set (reg FLAGS_REG)
6398 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6399 (match_operand:QI 2 "const_int_operand" "n")))
6400 (clobber (match_scratch:QI 0 "=qm"))]
6401 "ix86_match_ccmode (insn, CCGCmode)
6402 && (INTVAL (operands[2]) & 0xff) != 0x80"
6403 {
6404 switch (get_attr_type (insn))
6405 {
6406 case TYPE_INCDEC:
6407 if (operands[2] == constm1_rtx
6408 || (GET_CODE (operands[2]) == CONST_INT
6409 && INTVAL (operands[2]) == 255))
6410 return "inc{b}\t%0";
6411 else if (operands[2] == const1_rtx)
6412 return "dec{b}\t%0";
6413 else
6414 abort();
6415
6416 default:
6417 if (! rtx_equal_p (operands[0], operands[1]))
6418 abort ();
6419 if (INTVAL (operands[2]) < 0)
6420 {
6421 operands[2] = GEN_INT (-INTVAL (operands[2]));
6422 return "add{b}\t{%2, %0|%0, %2}";
6423 }
6424 return "sub{b}\t{%2, %0|%0, %2}";
6425 }
6426 }
6427 [(set (attr "type")
6428 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6429 (const_string "incdec")
6430 (const_string "alu")))
6431 (set_attr "mode" "QI")])
6432
6433
6434 (define_insn "*addqi_5"
6435 [(set (reg FLAGS_REG)
6436 (compare
6437 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6438 (match_operand:QI 2 "general_operand" "qmni"))
6439 (const_int 0)))
6440 (clobber (match_scratch:QI 0 "=q"))]
6441 "ix86_match_ccmode (insn, CCGOCmode)
6442 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6443 {
6444 switch (get_attr_type (insn))
6445 {
6446 case TYPE_INCDEC:
6447 if (operands[2] == const1_rtx)
6448 return "inc{b}\t%0";
6449 else if (operands[2] == constm1_rtx
6450 || (GET_CODE (operands[2]) == CONST_INT
6451 && INTVAL (operands[2]) == 255))
6452 return "dec{b}\t%0";
6453 abort();
6454
6455 default:
6456 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6457 if (GET_CODE (operands[2]) == CONST_INT
6458 && INTVAL (operands[2]) < 0)
6459 {
6460 operands[2] = GEN_INT (-INTVAL (operands[2]));
6461 return "sub{b}\t{%2, %0|%0, %2}";
6462 }
6463 return "add{b}\t{%2, %0|%0, %2}";
6464 }
6465 }
6466 [(set (attr "type")
6467 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6468 (const_string "incdec")
6469 (const_string "alu")))
6470 (set_attr "mode" "QI")])
6471
6472
6473 (define_insn "addqi_ext_1"
6474 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6475 (const_int 8)
6476 (const_int 8))
6477 (plus:SI
6478 (zero_extract:SI
6479 (match_operand 1 "ext_register_operand" "0")
6480 (const_int 8)
6481 (const_int 8))
6482 (match_operand:QI 2 "general_operand" "Qmn")))
6483 (clobber (reg:CC FLAGS_REG))]
6484 "!TARGET_64BIT"
6485 {
6486 switch (get_attr_type (insn))
6487 {
6488 case TYPE_INCDEC:
6489 if (operands[2] == const1_rtx)
6490 return "inc{b}\t%h0";
6491 else if (operands[2] == constm1_rtx
6492 || (GET_CODE (operands[2]) == CONST_INT
6493 && INTVAL (operands[2]) == 255))
6494 return "dec{b}\t%h0";
6495 abort();
6496
6497 default:
6498 return "add{b}\t{%2, %h0|%h0, %2}";
6499 }
6500 }
6501 [(set (attr "type")
6502 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6503 (const_string "incdec")
6504 (const_string "alu")))
6505 (set_attr "mode" "QI")])
6506
6507 (define_insn "*addqi_ext_1_rex64"
6508 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6509 (const_int 8)
6510 (const_int 8))
6511 (plus:SI
6512 (zero_extract:SI
6513 (match_operand 1 "ext_register_operand" "0")
6514 (const_int 8)
6515 (const_int 8))
6516 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6517 (clobber (reg:CC FLAGS_REG))]
6518 "TARGET_64BIT"
6519 {
6520 switch (get_attr_type (insn))
6521 {
6522 case TYPE_INCDEC:
6523 if (operands[2] == const1_rtx)
6524 return "inc{b}\t%h0";
6525 else if (operands[2] == constm1_rtx
6526 || (GET_CODE (operands[2]) == CONST_INT
6527 && INTVAL (operands[2]) == 255))
6528 return "dec{b}\t%h0";
6529 abort();
6530
6531 default:
6532 return "add{b}\t{%2, %h0|%h0, %2}";
6533 }
6534 }
6535 [(set (attr "type")
6536 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6537 (const_string "incdec")
6538 (const_string "alu")))
6539 (set_attr "mode" "QI")])
6540
6541 (define_insn "*addqi_ext_2"
6542 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6543 (const_int 8)
6544 (const_int 8))
6545 (plus:SI
6546 (zero_extract:SI
6547 (match_operand 1 "ext_register_operand" "%0")
6548 (const_int 8)
6549 (const_int 8))
6550 (zero_extract:SI
6551 (match_operand 2 "ext_register_operand" "Q")
6552 (const_int 8)
6553 (const_int 8))))
6554 (clobber (reg:CC FLAGS_REG))]
6555 ""
6556 "add{b}\t{%h2, %h0|%h0, %h2}"
6557 [(set_attr "type" "alu")
6558 (set_attr "mode" "QI")])
6559
6560 ;; The patterns that match these are at the end of this file.
6561
6562 (define_expand "addxf3"
6563 [(set (match_operand:XF 0 "register_operand" "")
6564 (plus:XF (match_operand:XF 1 "register_operand" "")
6565 (match_operand:XF 2 "register_operand" "")))]
6566 "TARGET_80387"
6567 "")
6568
6569 (define_expand "adddf3"
6570 [(set (match_operand:DF 0 "register_operand" "")
6571 (plus:DF (match_operand:DF 1 "register_operand" "")
6572 (match_operand:DF 2 "nonimmediate_operand" "")))]
6573 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6574 "")
6575
6576 (define_expand "addsf3"
6577 [(set (match_operand:SF 0 "register_operand" "")
6578 (plus:SF (match_operand:SF 1 "register_operand" "")
6579 (match_operand:SF 2 "nonimmediate_operand" "")))]
6580 "TARGET_80387 || TARGET_SSE_MATH"
6581 "")
6582 \f
6583 ;; Subtract instructions
6584
6585 ;; %%% splits for subsidi3
6586
6587 (define_expand "subdi3"
6588 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6589 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6590 (match_operand:DI 2 "x86_64_general_operand" "")))
6591 (clobber (reg:CC FLAGS_REG))])]
6592 ""
6593 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6594
6595 (define_insn "*subdi3_1"
6596 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6597 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6598 (match_operand:DI 2 "general_operand" "roiF,riF")))
6599 (clobber (reg:CC FLAGS_REG))]
6600 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6601 "#")
6602
6603 (define_split
6604 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6605 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6606 (match_operand:DI 2 "general_operand" "")))
6607 (clobber (reg:CC FLAGS_REG))]
6608 "!TARGET_64BIT && reload_completed"
6609 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6610 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6611 (parallel [(set (match_dup 3)
6612 (minus:SI (match_dup 4)
6613 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6614 (match_dup 5))))
6615 (clobber (reg:CC FLAGS_REG))])]
6616 "split_di (operands+0, 1, operands+0, operands+3);
6617 split_di (operands+1, 1, operands+1, operands+4);
6618 split_di (operands+2, 1, operands+2, operands+5);")
6619
6620 (define_insn "subdi3_carry_rex64"
6621 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6622 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6623 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6624 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6625 (clobber (reg:CC FLAGS_REG))]
6626 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6627 "sbb{q}\t{%2, %0|%0, %2}"
6628 [(set_attr "type" "alu")
6629 (set_attr "pent_pair" "pu")
6630 (set_attr "mode" "DI")])
6631
6632 (define_insn "*subdi_1_rex64"
6633 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6634 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6635 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6636 (clobber (reg:CC FLAGS_REG))]
6637 "TARGET_64BIT && 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_2_rex64"
6643 [(set (reg FLAGS_REG)
6644 (compare
6645 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6646 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6647 (const_int 0)))
6648 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6649 (minus:DI (match_dup 1) (match_dup 2)))]
6650 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6651 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6652 "sub{q}\t{%2, %0|%0, %2}"
6653 [(set_attr "type" "alu")
6654 (set_attr "mode" "DI")])
6655
6656 (define_insn "*subdi_3_rex63"
6657 [(set (reg FLAGS_REG)
6658 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6659 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6660 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6661 (minus:DI (match_dup 1) (match_dup 2)))]
6662 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6663 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6664 "sub{q}\t{%2, %0|%0, %2}"
6665 [(set_attr "type" "alu")
6666 (set_attr "mode" "DI")])
6667
6668 (define_insn "subqi3_carry"
6669 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6670 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6671 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6672 (match_operand:QI 2 "general_operand" "qi,qm"))))
6673 (clobber (reg:CC FLAGS_REG))]
6674 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6675 "sbb{b}\t{%2, %0|%0, %2}"
6676 [(set_attr "type" "alu")
6677 (set_attr "pent_pair" "pu")
6678 (set_attr "mode" "QI")])
6679
6680 (define_insn "subhi3_carry"
6681 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6682 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6683 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6684 (match_operand:HI 2 "general_operand" "ri,rm"))))
6685 (clobber (reg:CC FLAGS_REG))]
6686 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6687 "sbb{w}\t{%2, %0|%0, %2}"
6688 [(set_attr "type" "alu")
6689 (set_attr "pent_pair" "pu")
6690 (set_attr "mode" "HI")])
6691
6692 (define_insn "subsi3_carry"
6693 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6694 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6695 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6696 (match_operand:SI 2 "general_operand" "ri,rm"))))
6697 (clobber (reg:CC FLAGS_REG))]
6698 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6699 "sbb{l}\t{%2, %0|%0, %2}"
6700 [(set_attr "type" "alu")
6701 (set_attr "pent_pair" "pu")
6702 (set_attr "mode" "SI")])
6703
6704 (define_insn "subsi3_carry_zext"
6705 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6706 (zero_extend:DI
6707 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6708 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6709 (match_operand:SI 2 "general_operand" "ri,rm")))))
6710 (clobber (reg:CC FLAGS_REG))]
6711 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6712 "sbb{l}\t{%2, %k0|%k0, %2}"
6713 [(set_attr "type" "alu")
6714 (set_attr "pent_pair" "pu")
6715 (set_attr "mode" "SI")])
6716
6717 (define_expand "subsi3"
6718 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6719 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6720 (match_operand:SI 2 "general_operand" "")))
6721 (clobber (reg:CC FLAGS_REG))])]
6722 ""
6723 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6724
6725 (define_insn "*subsi_1"
6726 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6727 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6728 (match_operand:SI 2 "general_operand" "ri,rm")))
6729 (clobber (reg:CC FLAGS_REG))]
6730 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6731 "sub{l}\t{%2, %0|%0, %2}"
6732 [(set_attr "type" "alu")
6733 (set_attr "mode" "SI")])
6734
6735 (define_insn "*subsi_1_zext"
6736 [(set (match_operand:DI 0 "register_operand" "=r")
6737 (zero_extend:DI
6738 (minus:SI (match_operand:SI 1 "register_operand" "0")
6739 (match_operand:SI 2 "general_operand" "rim"))))
6740 (clobber (reg:CC FLAGS_REG))]
6741 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6742 "sub{l}\t{%2, %k0|%k0, %2}"
6743 [(set_attr "type" "alu")
6744 (set_attr "mode" "SI")])
6745
6746 (define_insn "*subsi_2"
6747 [(set (reg FLAGS_REG)
6748 (compare
6749 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6750 (match_operand:SI 2 "general_operand" "ri,rm"))
6751 (const_int 0)))
6752 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6753 (minus:SI (match_dup 1) (match_dup 2)))]
6754 "ix86_match_ccmode (insn, CCGOCmode)
6755 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6756 "sub{l}\t{%2, %0|%0, %2}"
6757 [(set_attr "type" "alu")
6758 (set_attr "mode" "SI")])
6759
6760 (define_insn "*subsi_2_zext"
6761 [(set (reg FLAGS_REG)
6762 (compare
6763 (minus:SI (match_operand:SI 1 "register_operand" "0")
6764 (match_operand:SI 2 "general_operand" "rim"))
6765 (const_int 0)))
6766 (set (match_operand:DI 0 "register_operand" "=r")
6767 (zero_extend:DI
6768 (minus:SI (match_dup 1)
6769 (match_dup 2))))]
6770 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6771 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6772 "sub{l}\t{%2, %k0|%k0, %2}"
6773 [(set_attr "type" "alu")
6774 (set_attr "mode" "SI")])
6775
6776 (define_insn "*subsi_3"
6777 [(set (reg FLAGS_REG)
6778 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6779 (match_operand:SI 2 "general_operand" "ri,rm")))
6780 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6781 (minus:SI (match_dup 1) (match_dup 2)))]
6782 "ix86_match_ccmode (insn, CCmode)
6783 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6784 "sub{l}\t{%2, %0|%0, %2}"
6785 [(set_attr "type" "alu")
6786 (set_attr "mode" "SI")])
6787
6788 (define_insn "*subsi_3_zext"
6789 [(set (reg FLAGS_REG)
6790 (compare (match_operand:SI 1 "register_operand" "0")
6791 (match_operand:SI 2 "general_operand" "rim")))
6792 (set (match_operand:DI 0 "register_operand" "=r")
6793 (zero_extend:DI
6794 (minus:SI (match_dup 1)
6795 (match_dup 2))))]
6796 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6797 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6798 "sub{q}\t{%2, %0|%0, %2}"
6799 [(set_attr "type" "alu")
6800 (set_attr "mode" "DI")])
6801
6802 (define_expand "subhi3"
6803 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6804 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6805 (match_operand:HI 2 "general_operand" "")))
6806 (clobber (reg:CC FLAGS_REG))])]
6807 "TARGET_HIMODE_MATH"
6808 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6809
6810 (define_insn "*subhi_1"
6811 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6812 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6813 (match_operand:HI 2 "general_operand" "ri,rm")))
6814 (clobber (reg:CC FLAGS_REG))]
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_2"
6821 [(set (reg FLAGS_REG)
6822 (compare
6823 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6824 (match_operand:HI 2 "general_operand" "ri,rm"))
6825 (const_int 0)))
6826 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6827 (minus:HI (match_dup 1) (match_dup 2)))]
6828 "ix86_match_ccmode (insn, CCGOCmode)
6829 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6830 "sub{w}\t{%2, %0|%0, %2}"
6831 [(set_attr "type" "alu")
6832 (set_attr "mode" "HI")])
6833
6834 (define_insn "*subhi_3"
6835 [(set (reg FLAGS_REG)
6836 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6837 (match_operand:HI 2 "general_operand" "ri,rm")))
6838 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6839 (minus:HI (match_dup 1) (match_dup 2)))]
6840 "ix86_match_ccmode (insn, CCmode)
6841 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6842 "sub{w}\t{%2, %0|%0, %2}"
6843 [(set_attr "type" "alu")
6844 (set_attr "mode" "HI")])
6845
6846 (define_expand "subqi3"
6847 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6848 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6849 (match_operand:QI 2 "general_operand" "")))
6850 (clobber (reg:CC FLAGS_REG))])]
6851 "TARGET_QIMODE_MATH"
6852 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6853
6854 (define_insn "*subqi_1"
6855 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6856 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6857 (match_operand:QI 2 "general_operand" "qn,qmn")))
6858 (clobber (reg:CC FLAGS_REG))]
6859 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6860 "sub{b}\t{%2, %0|%0, %2}"
6861 [(set_attr "type" "alu")
6862 (set_attr "mode" "QI")])
6863
6864 (define_insn "*subqi_1_slp"
6865 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6866 (minus:QI (match_dup 0)
6867 (match_operand:QI 1 "general_operand" "qn,qmn")))
6868 (clobber (reg:CC FLAGS_REG))]
6869 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6870 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6871 "sub{b}\t{%1, %0|%0, %1}"
6872 [(set_attr "type" "alu1")
6873 (set_attr "mode" "QI")])
6874
6875 (define_insn "*subqi_2"
6876 [(set (reg FLAGS_REG)
6877 (compare
6878 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6879 (match_operand:QI 2 "general_operand" "qi,qm"))
6880 (const_int 0)))
6881 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6882 (minus:HI (match_dup 1) (match_dup 2)))]
6883 "ix86_match_ccmode (insn, CCGOCmode)
6884 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6885 "sub{b}\t{%2, %0|%0, %2}"
6886 [(set_attr "type" "alu")
6887 (set_attr "mode" "QI")])
6888
6889 (define_insn "*subqi_3"
6890 [(set (reg FLAGS_REG)
6891 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6892 (match_operand:QI 2 "general_operand" "qi,qm")))
6893 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6894 (minus:HI (match_dup 1) (match_dup 2)))]
6895 "ix86_match_ccmode (insn, CCmode)
6896 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6897 "sub{b}\t{%2, %0|%0, %2}"
6898 [(set_attr "type" "alu")
6899 (set_attr "mode" "QI")])
6900
6901 ;; The patterns that match these are at the end of this file.
6902
6903 (define_expand "subxf3"
6904 [(set (match_operand:XF 0 "register_operand" "")
6905 (minus:XF (match_operand:XF 1 "register_operand" "")
6906 (match_operand:XF 2 "register_operand" "")))]
6907 "TARGET_80387"
6908 "")
6909
6910 (define_expand "subdf3"
6911 [(set (match_operand:DF 0 "register_operand" "")
6912 (minus:DF (match_operand:DF 1 "register_operand" "")
6913 (match_operand:DF 2 "nonimmediate_operand" "")))]
6914 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6915 "")
6916
6917 (define_expand "subsf3"
6918 [(set (match_operand:SF 0 "register_operand" "")
6919 (minus:SF (match_operand:SF 1 "register_operand" "")
6920 (match_operand:SF 2 "nonimmediate_operand" "")))]
6921 "TARGET_80387 || TARGET_SSE_MATH"
6922 "")
6923 \f
6924 ;; Multiply instructions
6925
6926 (define_expand "muldi3"
6927 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6928 (mult:DI (match_operand:DI 1 "register_operand" "")
6929 (match_operand:DI 2 "x86_64_general_operand" "")))
6930 (clobber (reg:CC FLAGS_REG))])]
6931 "TARGET_64BIT"
6932 "")
6933
6934 (define_insn "*muldi3_1_rex64"
6935 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6936 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6937 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6938 (clobber (reg:CC FLAGS_REG))]
6939 "TARGET_64BIT
6940 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6941 "@
6942 imul{q}\t{%2, %1, %0|%0, %1, %2}
6943 imul{q}\t{%2, %1, %0|%0, %1, %2}
6944 imul{q}\t{%2, %0|%0, %2}"
6945 [(set_attr "type" "imul")
6946 (set_attr "prefix_0f" "0,0,1")
6947 (set (attr "athlon_decode")
6948 (cond [(eq_attr "cpu" "athlon")
6949 (const_string "vector")
6950 (eq_attr "alternative" "1")
6951 (const_string "vector")
6952 (and (eq_attr "alternative" "2")
6953 (match_operand 1 "memory_operand" ""))
6954 (const_string "vector")]
6955 (const_string "direct")))
6956 (set_attr "mode" "DI")])
6957
6958 (define_expand "mulsi3"
6959 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6960 (mult:SI (match_operand:SI 1 "register_operand" "")
6961 (match_operand:SI 2 "general_operand" "")))
6962 (clobber (reg:CC FLAGS_REG))])]
6963 ""
6964 "")
6965
6966 (define_insn "*mulsi3_1"
6967 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6968 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6969 (match_operand:SI 2 "general_operand" "K,i,mr")))
6970 (clobber (reg:CC FLAGS_REG))]
6971 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6972 "@
6973 imul{l}\t{%2, %1, %0|%0, %1, %2}
6974 imul{l}\t{%2, %1, %0|%0, %1, %2}
6975 imul{l}\t{%2, %0|%0, %2}"
6976 [(set_attr "type" "imul")
6977 (set_attr "prefix_0f" "0,0,1")
6978 (set (attr "athlon_decode")
6979 (cond [(eq_attr "cpu" "athlon")
6980 (const_string "vector")
6981 (eq_attr "alternative" "1")
6982 (const_string "vector")
6983 (and (eq_attr "alternative" "2")
6984 (match_operand 1 "memory_operand" ""))
6985 (const_string "vector")]
6986 (const_string "direct")))
6987 (set_attr "mode" "SI")])
6988
6989 (define_insn "*mulsi3_1_zext"
6990 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6991 (zero_extend:DI
6992 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6993 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6994 (clobber (reg:CC FLAGS_REG))]
6995 "TARGET_64BIT
6996 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6997 "@
6998 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6999 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7000 imul{l}\t{%2, %k0|%k0, %2}"
7001 [(set_attr "type" "imul")
7002 (set_attr "prefix_0f" "0,0,1")
7003 (set (attr "athlon_decode")
7004 (cond [(eq_attr "cpu" "athlon")
7005 (const_string "vector")
7006 (eq_attr "alternative" "1")
7007 (const_string "vector")
7008 (and (eq_attr "alternative" "2")
7009 (match_operand 1 "memory_operand" ""))
7010 (const_string "vector")]
7011 (const_string "direct")))
7012 (set_attr "mode" "SI")])
7013
7014 (define_expand "mulhi3"
7015 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7016 (mult:HI (match_operand:HI 1 "register_operand" "")
7017 (match_operand:HI 2 "general_operand" "")))
7018 (clobber (reg:CC FLAGS_REG))])]
7019 "TARGET_HIMODE_MATH"
7020 "")
7021
7022 (define_insn "*mulhi3_1"
7023 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7024 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7025 (match_operand:HI 2 "general_operand" "K,i,mr")))
7026 (clobber (reg:CC FLAGS_REG))]
7027 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7028 "@
7029 imul{w}\t{%2, %1, %0|%0, %1, %2}
7030 imul{w}\t{%2, %1, %0|%0, %1, %2}
7031 imul{w}\t{%2, %0|%0, %2}"
7032 [(set_attr "type" "imul")
7033 (set_attr "prefix_0f" "0,0,1")
7034 (set (attr "athlon_decode")
7035 (cond [(eq_attr "cpu" "athlon")
7036 (const_string "vector")
7037 (eq_attr "alternative" "1,2")
7038 (const_string "vector")]
7039 (const_string "direct")))
7040 (set_attr "mode" "HI")])
7041
7042 (define_expand "mulqi3"
7043 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7044 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7045 (match_operand:QI 2 "register_operand" "")))
7046 (clobber (reg:CC FLAGS_REG))])]
7047 "TARGET_QIMODE_MATH"
7048 "")
7049
7050 (define_insn "*mulqi3_1"
7051 [(set (match_operand:QI 0 "register_operand" "=a")
7052 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7053 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7054 (clobber (reg:CC FLAGS_REG))]
7055 "TARGET_QIMODE_MATH
7056 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7057 "mul{b}\t%2"
7058 [(set_attr "type" "imul")
7059 (set_attr "length_immediate" "0")
7060 (set (attr "athlon_decode")
7061 (if_then_else (eq_attr "cpu" "athlon")
7062 (const_string "vector")
7063 (const_string "direct")))
7064 (set_attr "mode" "QI")])
7065
7066 (define_expand "umulqihi3"
7067 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7068 (mult:HI (zero_extend:HI
7069 (match_operand:QI 1 "nonimmediate_operand" ""))
7070 (zero_extend:HI
7071 (match_operand:QI 2 "register_operand" ""))))
7072 (clobber (reg:CC FLAGS_REG))])]
7073 "TARGET_QIMODE_MATH"
7074 "")
7075
7076 (define_insn "*umulqihi3_1"
7077 [(set (match_operand:HI 0 "register_operand" "=a")
7078 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7079 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7080 (clobber (reg:CC FLAGS_REG))]
7081 "TARGET_QIMODE_MATH
7082 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7083 "mul{b}\t%2"
7084 [(set_attr "type" "imul")
7085 (set_attr "length_immediate" "0")
7086 (set (attr "athlon_decode")
7087 (if_then_else (eq_attr "cpu" "athlon")
7088 (const_string "vector")
7089 (const_string "direct")))
7090 (set_attr "mode" "QI")])
7091
7092 (define_expand "mulqihi3"
7093 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7094 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7095 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7096 (clobber (reg:CC FLAGS_REG))])]
7097 "TARGET_QIMODE_MATH"
7098 "")
7099
7100 (define_insn "*mulqihi3_insn"
7101 [(set (match_operand:HI 0 "register_operand" "=a")
7102 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7103 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7104 (clobber (reg:CC FLAGS_REG))]
7105 "TARGET_QIMODE_MATH
7106 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7107 "imul{b}\t%2"
7108 [(set_attr "type" "imul")
7109 (set_attr "length_immediate" "0")
7110 (set (attr "athlon_decode")
7111 (if_then_else (eq_attr "cpu" "athlon")
7112 (const_string "vector")
7113 (const_string "direct")))
7114 (set_attr "mode" "QI")])
7115
7116 (define_expand "umulditi3"
7117 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7118 (mult:TI (zero_extend:TI
7119 (match_operand:DI 1 "nonimmediate_operand" ""))
7120 (zero_extend:TI
7121 (match_operand:DI 2 "register_operand" ""))))
7122 (clobber (reg:CC FLAGS_REG))])]
7123 "TARGET_64BIT"
7124 "")
7125
7126 (define_insn "*umulditi3_insn"
7127 [(set (match_operand:TI 0 "register_operand" "=A")
7128 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7129 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7130 (clobber (reg:CC FLAGS_REG))]
7131 "TARGET_64BIT
7132 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7133 "mul{q}\t%2"
7134 [(set_attr "type" "imul")
7135 (set_attr "length_immediate" "0")
7136 (set (attr "athlon_decode")
7137 (if_then_else (eq_attr "cpu" "athlon")
7138 (const_string "vector")
7139 (const_string "double")))
7140 (set_attr "mode" "DI")])
7141
7142 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7143 (define_expand "umulsidi3"
7144 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7145 (mult:DI (zero_extend:DI
7146 (match_operand:SI 1 "nonimmediate_operand" ""))
7147 (zero_extend:DI
7148 (match_operand:SI 2 "register_operand" ""))))
7149 (clobber (reg:CC FLAGS_REG))])]
7150 "!TARGET_64BIT"
7151 "")
7152
7153 (define_insn "*umulsidi3_insn"
7154 [(set (match_operand:DI 0 "register_operand" "=A")
7155 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7156 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7157 (clobber (reg:CC FLAGS_REG))]
7158 "!TARGET_64BIT
7159 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7160 "mul{l}\t%2"
7161 [(set_attr "type" "imul")
7162 (set_attr "length_immediate" "0")
7163 (set (attr "athlon_decode")
7164 (if_then_else (eq_attr "cpu" "athlon")
7165 (const_string "vector")
7166 (const_string "double")))
7167 (set_attr "mode" "SI")])
7168
7169 (define_expand "mulditi3"
7170 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7171 (mult:TI (sign_extend:TI
7172 (match_operand:DI 1 "nonimmediate_operand" ""))
7173 (sign_extend:TI
7174 (match_operand:DI 2 "register_operand" ""))))
7175 (clobber (reg:CC FLAGS_REG))])]
7176 "TARGET_64BIT"
7177 "")
7178
7179 (define_insn "*mulditi3_insn"
7180 [(set (match_operand:TI 0 "register_operand" "=A")
7181 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7182 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7183 (clobber (reg:CC FLAGS_REG))]
7184 "TARGET_64BIT
7185 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7186 "imul{q}\t%2"
7187 [(set_attr "type" "imul")
7188 (set_attr "length_immediate" "0")
7189 (set (attr "athlon_decode")
7190 (if_then_else (eq_attr "cpu" "athlon")
7191 (const_string "vector")
7192 (const_string "double")))
7193 (set_attr "mode" "DI")])
7194
7195 (define_expand "mulsidi3"
7196 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7197 (mult:DI (sign_extend:DI
7198 (match_operand:SI 1 "nonimmediate_operand" ""))
7199 (sign_extend:DI
7200 (match_operand:SI 2 "register_operand" ""))))
7201 (clobber (reg:CC FLAGS_REG))])]
7202 "!TARGET_64BIT"
7203 "")
7204
7205 (define_insn "*mulsidi3_insn"
7206 [(set (match_operand:DI 0 "register_operand" "=A")
7207 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7208 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7209 (clobber (reg:CC FLAGS_REG))]
7210 "!TARGET_64BIT
7211 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7212 "imul{l}\t%2"
7213 [(set_attr "type" "imul")
7214 (set_attr "length_immediate" "0")
7215 (set (attr "athlon_decode")
7216 (if_then_else (eq_attr "cpu" "athlon")
7217 (const_string "vector")
7218 (const_string "double")))
7219 (set_attr "mode" "SI")])
7220
7221 (define_expand "umuldi3_highpart"
7222 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7223 (truncate:DI
7224 (lshiftrt:TI
7225 (mult:TI (zero_extend:TI
7226 (match_operand:DI 1 "nonimmediate_operand" ""))
7227 (zero_extend:TI
7228 (match_operand:DI 2 "register_operand" "")))
7229 (const_int 64))))
7230 (clobber (match_scratch:DI 3 ""))
7231 (clobber (reg:CC FLAGS_REG))])]
7232 "TARGET_64BIT"
7233 "")
7234
7235 (define_insn "*umuldi3_highpart_rex64"
7236 [(set (match_operand:DI 0 "register_operand" "=d")
7237 (truncate:DI
7238 (lshiftrt:TI
7239 (mult:TI (zero_extend:TI
7240 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7241 (zero_extend:TI
7242 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7243 (const_int 64))))
7244 (clobber (match_scratch:DI 3 "=1"))
7245 (clobber (reg:CC FLAGS_REG))]
7246 "TARGET_64BIT
7247 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7248 "mul{q}\t%2"
7249 [(set_attr "type" "imul")
7250 (set_attr "length_immediate" "0")
7251 (set (attr "athlon_decode")
7252 (if_then_else (eq_attr "cpu" "athlon")
7253 (const_string "vector")
7254 (const_string "double")))
7255 (set_attr "mode" "DI")])
7256
7257 (define_expand "umulsi3_highpart"
7258 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7259 (truncate:SI
7260 (lshiftrt:DI
7261 (mult:DI (zero_extend:DI
7262 (match_operand:SI 1 "nonimmediate_operand" ""))
7263 (zero_extend:DI
7264 (match_operand:SI 2 "register_operand" "")))
7265 (const_int 32))))
7266 (clobber (match_scratch:SI 3 ""))
7267 (clobber (reg:CC FLAGS_REG))])]
7268 ""
7269 "")
7270
7271 (define_insn "*umulsi3_highpart_insn"
7272 [(set (match_operand:SI 0 "register_operand" "=d")
7273 (truncate:SI
7274 (lshiftrt:DI
7275 (mult:DI (zero_extend:DI
7276 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7277 (zero_extend:DI
7278 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7279 (const_int 32))))
7280 (clobber (match_scratch:SI 3 "=1"))
7281 (clobber (reg:CC FLAGS_REG))]
7282 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7283 "mul{l}\t%2"
7284 [(set_attr "type" "imul")
7285 (set_attr "length_immediate" "0")
7286 (set (attr "athlon_decode")
7287 (if_then_else (eq_attr "cpu" "athlon")
7288 (const_string "vector")
7289 (const_string "double")))
7290 (set_attr "mode" "SI")])
7291
7292 (define_insn "*umulsi3_highpart_zext"
7293 [(set (match_operand:DI 0 "register_operand" "=d")
7294 (zero_extend:DI (truncate:SI
7295 (lshiftrt:DI
7296 (mult:DI (zero_extend:DI
7297 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7298 (zero_extend:DI
7299 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7300 (const_int 32)))))
7301 (clobber (match_scratch:SI 3 "=1"))
7302 (clobber (reg:CC FLAGS_REG))]
7303 "TARGET_64BIT
7304 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7305 "mul{l}\t%2"
7306 [(set_attr "type" "imul")
7307 (set_attr "length_immediate" "0")
7308 (set (attr "athlon_decode")
7309 (if_then_else (eq_attr "cpu" "athlon")
7310 (const_string "vector")
7311 (const_string "double")))
7312 (set_attr "mode" "SI")])
7313
7314 (define_expand "smuldi3_highpart"
7315 [(parallel [(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" ""))
7320 (sign_extend:TI
7321 (match_operand:DI 2 "register_operand" "")))
7322 (const_int 64))))
7323 (clobber (match_scratch:DI 3 ""))
7324 (clobber (reg:CC FLAGS_REG))])]
7325 "TARGET_64BIT"
7326 "")
7327
7328 (define_insn "*smuldi3_highpart_rex64"
7329 [(set (match_operand:DI 0 "register_operand" "=d")
7330 (truncate:DI
7331 (lshiftrt:TI
7332 (mult:TI (sign_extend:TI
7333 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7334 (sign_extend:TI
7335 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7336 (const_int 64))))
7337 (clobber (match_scratch:DI 3 "=1"))
7338 (clobber (reg:CC FLAGS_REG))]
7339 "TARGET_64BIT
7340 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7341 "imul{q}\t%2"
7342 [(set_attr "type" "imul")
7343 (set (attr "athlon_decode")
7344 (if_then_else (eq_attr "cpu" "athlon")
7345 (const_string "vector")
7346 (const_string "double")))
7347 (set_attr "mode" "DI")])
7348
7349 (define_expand "smulsi3_highpart"
7350 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7351 (truncate:SI
7352 (lshiftrt:DI
7353 (mult:DI (sign_extend:DI
7354 (match_operand:SI 1 "nonimmediate_operand" ""))
7355 (sign_extend:DI
7356 (match_operand:SI 2 "register_operand" "")))
7357 (const_int 32))))
7358 (clobber (match_scratch:SI 3 ""))
7359 (clobber (reg:CC FLAGS_REG))])]
7360 ""
7361 "")
7362
7363 (define_insn "*smulsi3_highpart_insn"
7364 [(set (match_operand:SI 0 "register_operand" "=d")
7365 (truncate:SI
7366 (lshiftrt:DI
7367 (mult:DI (sign_extend:DI
7368 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7369 (sign_extend:DI
7370 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7371 (const_int 32))))
7372 (clobber (match_scratch:SI 3 "=1"))
7373 (clobber (reg:CC FLAGS_REG))]
7374 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7375 "imul{l}\t%2"
7376 [(set_attr "type" "imul")
7377 (set (attr "athlon_decode")
7378 (if_then_else (eq_attr "cpu" "athlon")
7379 (const_string "vector")
7380 (const_string "double")))
7381 (set_attr "mode" "SI")])
7382
7383 (define_insn "*smulsi3_highpart_zext"
7384 [(set (match_operand:DI 0 "register_operand" "=d")
7385 (zero_extend:DI (truncate:SI
7386 (lshiftrt:DI
7387 (mult:DI (sign_extend:DI
7388 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7389 (sign_extend:DI
7390 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7391 (const_int 32)))))
7392 (clobber (match_scratch:SI 3 "=1"))
7393 (clobber (reg:CC FLAGS_REG))]
7394 "TARGET_64BIT
7395 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7396 "imul{l}\t%2"
7397 [(set_attr "type" "imul")
7398 (set (attr "athlon_decode")
7399 (if_then_else (eq_attr "cpu" "athlon")
7400 (const_string "vector")
7401 (const_string "double")))
7402 (set_attr "mode" "SI")])
7403
7404 ;; The patterns that match these are at the end of this file.
7405
7406 (define_expand "mulxf3"
7407 [(set (match_operand:XF 0 "register_operand" "")
7408 (mult:XF (match_operand:XF 1 "register_operand" "")
7409 (match_operand:XF 2 "register_operand" "")))]
7410 "TARGET_80387"
7411 "")
7412
7413 (define_expand "muldf3"
7414 [(set (match_operand:DF 0 "register_operand" "")
7415 (mult:DF (match_operand:DF 1 "register_operand" "")
7416 (match_operand:DF 2 "nonimmediate_operand" "")))]
7417 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7418 "")
7419
7420 (define_expand "mulsf3"
7421 [(set (match_operand:SF 0 "register_operand" "")
7422 (mult:SF (match_operand:SF 1 "register_operand" "")
7423 (match_operand:SF 2 "nonimmediate_operand" "")))]
7424 "TARGET_80387 || TARGET_SSE_MATH"
7425 "")
7426 \f
7427 ;; Divide instructions
7428
7429 (define_insn "divqi3"
7430 [(set (match_operand:QI 0 "register_operand" "=a")
7431 (div:QI (match_operand:HI 1 "register_operand" "0")
7432 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7433 (clobber (reg:CC FLAGS_REG))]
7434 "TARGET_QIMODE_MATH"
7435 "idiv{b}\t%2"
7436 [(set_attr "type" "idiv")
7437 (set_attr "mode" "QI")])
7438
7439 (define_insn "udivqi3"
7440 [(set (match_operand:QI 0 "register_operand" "=a")
7441 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7442 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7443 (clobber (reg:CC FLAGS_REG))]
7444 "TARGET_QIMODE_MATH"
7445 "div{b}\t%2"
7446 [(set_attr "type" "idiv")
7447 (set_attr "mode" "QI")])
7448
7449 ;; The patterns that match these are at the end of this file.
7450
7451 (define_expand "divxf3"
7452 [(set (match_operand:XF 0 "register_operand" "")
7453 (div:XF (match_operand:XF 1 "register_operand" "")
7454 (match_operand:XF 2 "register_operand" "")))]
7455 "TARGET_80387"
7456 "")
7457
7458 (define_expand "divdf3"
7459 [(set (match_operand:DF 0 "register_operand" "")
7460 (div:DF (match_operand:DF 1 "register_operand" "")
7461 (match_operand:DF 2 "nonimmediate_operand" "")))]
7462 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7463 "")
7464
7465 (define_expand "divsf3"
7466 [(set (match_operand:SF 0 "register_operand" "")
7467 (div:SF (match_operand:SF 1 "register_operand" "")
7468 (match_operand:SF 2 "nonimmediate_operand" "")))]
7469 "TARGET_80387 || TARGET_SSE_MATH"
7470 "")
7471 \f
7472 ;; Remainder instructions.
7473
7474 (define_expand "divmoddi4"
7475 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7476 (div:DI (match_operand:DI 1 "register_operand" "")
7477 (match_operand:DI 2 "nonimmediate_operand" "")))
7478 (set (match_operand:DI 3 "register_operand" "")
7479 (mod:DI (match_dup 1) (match_dup 2)))
7480 (clobber (reg:CC FLAGS_REG))])]
7481 "TARGET_64BIT"
7482 "")
7483
7484 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7485 ;; Penalize eax case slightly because it results in worse scheduling
7486 ;; of code.
7487 (define_insn "*divmoddi4_nocltd_rex64"
7488 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7489 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7490 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7491 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7492 (mod:DI (match_dup 2) (match_dup 3)))
7493 (clobber (reg:CC FLAGS_REG))]
7494 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7495 "#"
7496 [(set_attr "type" "multi")])
7497
7498 (define_insn "*divmoddi4_cltd_rex64"
7499 [(set (match_operand:DI 0 "register_operand" "=a")
7500 (div:DI (match_operand:DI 2 "register_operand" "a")
7501 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7502 (set (match_operand:DI 1 "register_operand" "=&d")
7503 (mod:DI (match_dup 2) (match_dup 3)))
7504 (clobber (reg:CC FLAGS_REG))]
7505 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7506 "#"
7507 [(set_attr "type" "multi")])
7508
7509 (define_insn "*divmoddi_noext_rex64"
7510 [(set (match_operand:DI 0 "register_operand" "=a")
7511 (div:DI (match_operand:DI 1 "register_operand" "0")
7512 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7513 (set (match_operand:DI 3 "register_operand" "=d")
7514 (mod:DI (match_dup 1) (match_dup 2)))
7515 (use (match_operand:DI 4 "register_operand" "3"))
7516 (clobber (reg:CC FLAGS_REG))]
7517 "TARGET_64BIT"
7518 "idiv{q}\t%2"
7519 [(set_attr "type" "idiv")
7520 (set_attr "mode" "DI")])
7521
7522 (define_split
7523 [(set (match_operand:DI 0 "register_operand" "")
7524 (div:DI (match_operand:DI 1 "register_operand" "")
7525 (match_operand:DI 2 "nonimmediate_operand" "")))
7526 (set (match_operand:DI 3 "register_operand" "")
7527 (mod:DI (match_dup 1) (match_dup 2)))
7528 (clobber (reg:CC FLAGS_REG))]
7529 "TARGET_64BIT && reload_completed"
7530 [(parallel [(set (match_dup 3)
7531 (ashiftrt:DI (match_dup 4) (const_int 63)))
7532 (clobber (reg:CC FLAGS_REG))])
7533 (parallel [(set (match_dup 0)
7534 (div:DI (reg:DI 0) (match_dup 2)))
7535 (set (match_dup 3)
7536 (mod:DI (reg:DI 0) (match_dup 2)))
7537 (use (match_dup 3))
7538 (clobber (reg:CC FLAGS_REG))])]
7539 {
7540 /* Avoid use of cltd in favor of a mov+shift. */
7541 if (!TARGET_USE_CLTD && !optimize_size)
7542 {
7543 if (true_regnum (operands[1]))
7544 emit_move_insn (operands[0], operands[1]);
7545 else
7546 emit_move_insn (operands[3], operands[1]);
7547 operands[4] = operands[3];
7548 }
7549 else
7550 {
7551 if (true_regnum (operands[1]))
7552 abort();
7553 operands[4] = operands[1];
7554 }
7555 })
7556
7557
7558 (define_expand "divmodsi4"
7559 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7560 (div:SI (match_operand:SI 1 "register_operand" "")
7561 (match_operand:SI 2 "nonimmediate_operand" "")))
7562 (set (match_operand:SI 3 "register_operand" "")
7563 (mod:SI (match_dup 1) (match_dup 2)))
7564 (clobber (reg:CC FLAGS_REG))])]
7565 ""
7566 "")
7567
7568 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7569 ;; Penalize eax case slightly because it results in worse scheduling
7570 ;; of code.
7571 (define_insn "*divmodsi4_nocltd"
7572 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7573 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7574 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7575 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7576 (mod:SI (match_dup 2) (match_dup 3)))
7577 (clobber (reg:CC FLAGS_REG))]
7578 "!optimize_size && !TARGET_USE_CLTD"
7579 "#"
7580 [(set_attr "type" "multi")])
7581
7582 (define_insn "*divmodsi4_cltd"
7583 [(set (match_operand:SI 0 "register_operand" "=a")
7584 (div:SI (match_operand:SI 2 "register_operand" "a")
7585 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7586 (set (match_operand:SI 1 "register_operand" "=&d")
7587 (mod:SI (match_dup 2) (match_dup 3)))
7588 (clobber (reg:CC FLAGS_REG))]
7589 "optimize_size || TARGET_USE_CLTD"
7590 "#"
7591 [(set_attr "type" "multi")])
7592
7593 (define_insn "*divmodsi_noext"
7594 [(set (match_operand:SI 0 "register_operand" "=a")
7595 (div:SI (match_operand:SI 1 "register_operand" "0")
7596 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7597 (set (match_operand:SI 3 "register_operand" "=d")
7598 (mod:SI (match_dup 1) (match_dup 2)))
7599 (use (match_operand:SI 4 "register_operand" "3"))
7600 (clobber (reg:CC FLAGS_REG))]
7601 ""
7602 "idiv{l}\t%2"
7603 [(set_attr "type" "idiv")
7604 (set_attr "mode" "SI")])
7605
7606 (define_split
7607 [(set (match_operand:SI 0 "register_operand" "")
7608 (div:SI (match_operand:SI 1 "register_operand" "")
7609 (match_operand:SI 2 "nonimmediate_operand" "")))
7610 (set (match_operand:SI 3 "register_operand" "")
7611 (mod:SI (match_dup 1) (match_dup 2)))
7612 (clobber (reg:CC FLAGS_REG))]
7613 "reload_completed"
7614 [(parallel [(set (match_dup 3)
7615 (ashiftrt:SI (match_dup 4) (const_int 31)))
7616 (clobber (reg:CC FLAGS_REG))])
7617 (parallel [(set (match_dup 0)
7618 (div:SI (reg:SI 0) (match_dup 2)))
7619 (set (match_dup 3)
7620 (mod:SI (reg:SI 0) (match_dup 2)))
7621 (use (match_dup 3))
7622 (clobber (reg:CC FLAGS_REG))])]
7623 {
7624 /* Avoid use of cltd in favor of a mov+shift. */
7625 if (!TARGET_USE_CLTD && !optimize_size)
7626 {
7627 if (true_regnum (operands[1]))
7628 emit_move_insn (operands[0], operands[1]);
7629 else
7630 emit_move_insn (operands[3], operands[1]);
7631 operands[4] = operands[3];
7632 }
7633 else
7634 {
7635 if (true_regnum (operands[1]))
7636 abort();
7637 operands[4] = operands[1];
7638 }
7639 })
7640 ;; %%% Split me.
7641 (define_insn "divmodhi4"
7642 [(set (match_operand:HI 0 "register_operand" "=a")
7643 (div:HI (match_operand:HI 1 "register_operand" "0")
7644 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7645 (set (match_operand:HI 3 "register_operand" "=&d")
7646 (mod:HI (match_dup 1) (match_dup 2)))
7647 (clobber (reg:CC FLAGS_REG))]
7648 "TARGET_HIMODE_MATH"
7649 "cwtd\;idiv{w}\t%2"
7650 [(set_attr "type" "multi")
7651 (set_attr "length_immediate" "0")
7652 (set_attr "mode" "SI")])
7653
7654 (define_insn "udivmoddi4"
7655 [(set (match_operand:DI 0 "register_operand" "=a")
7656 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7657 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7658 (set (match_operand:DI 3 "register_operand" "=&d")
7659 (umod:DI (match_dup 1) (match_dup 2)))
7660 (clobber (reg:CC FLAGS_REG))]
7661 "TARGET_64BIT"
7662 "xor{q}\t%3, %3\;div{q}\t%2"
7663 [(set_attr "type" "multi")
7664 (set_attr "length_immediate" "0")
7665 (set_attr "mode" "DI")])
7666
7667 (define_insn "*udivmoddi4_noext"
7668 [(set (match_operand:DI 0 "register_operand" "=a")
7669 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7670 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7671 (set (match_operand:DI 3 "register_operand" "=d")
7672 (umod:DI (match_dup 1) (match_dup 2)))
7673 (use (match_dup 3))
7674 (clobber (reg:CC FLAGS_REG))]
7675 "TARGET_64BIT"
7676 "div{q}\t%2"
7677 [(set_attr "type" "idiv")
7678 (set_attr "mode" "DI")])
7679
7680 (define_split
7681 [(set (match_operand:DI 0 "register_operand" "")
7682 (udiv:DI (match_operand:DI 1 "register_operand" "")
7683 (match_operand:DI 2 "nonimmediate_operand" "")))
7684 (set (match_operand:DI 3 "register_operand" "")
7685 (umod:DI (match_dup 1) (match_dup 2)))
7686 (clobber (reg:CC FLAGS_REG))]
7687 "TARGET_64BIT && reload_completed"
7688 [(set (match_dup 3) (const_int 0))
7689 (parallel [(set (match_dup 0)
7690 (udiv:DI (match_dup 1) (match_dup 2)))
7691 (set (match_dup 3)
7692 (umod:DI (match_dup 1) (match_dup 2)))
7693 (use (match_dup 3))
7694 (clobber (reg:CC FLAGS_REG))])]
7695 "")
7696
7697 (define_insn "udivmodsi4"
7698 [(set (match_operand:SI 0 "register_operand" "=a")
7699 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7700 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7701 (set (match_operand:SI 3 "register_operand" "=&d")
7702 (umod:SI (match_dup 1) (match_dup 2)))
7703 (clobber (reg:CC FLAGS_REG))]
7704 ""
7705 "xor{l}\t%3, %3\;div{l}\t%2"
7706 [(set_attr "type" "multi")
7707 (set_attr "length_immediate" "0")
7708 (set_attr "mode" "SI")])
7709
7710 (define_insn "*udivmodsi4_noext"
7711 [(set (match_operand:SI 0 "register_operand" "=a")
7712 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7713 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7714 (set (match_operand:SI 3 "register_operand" "=d")
7715 (umod:SI (match_dup 1) (match_dup 2)))
7716 (use (match_dup 3))
7717 (clobber (reg:CC FLAGS_REG))]
7718 ""
7719 "div{l}\t%2"
7720 [(set_attr "type" "idiv")
7721 (set_attr "mode" "SI")])
7722
7723 (define_split
7724 [(set (match_operand:SI 0 "register_operand" "")
7725 (udiv:SI (match_operand:SI 1 "register_operand" "")
7726 (match_operand:SI 2 "nonimmediate_operand" "")))
7727 (set (match_operand:SI 3 "register_operand" "")
7728 (umod:SI (match_dup 1) (match_dup 2)))
7729 (clobber (reg:CC FLAGS_REG))]
7730 "reload_completed"
7731 [(set (match_dup 3) (const_int 0))
7732 (parallel [(set (match_dup 0)
7733 (udiv:SI (match_dup 1) (match_dup 2)))
7734 (set (match_dup 3)
7735 (umod:SI (match_dup 1) (match_dup 2)))
7736 (use (match_dup 3))
7737 (clobber (reg:CC FLAGS_REG))])]
7738 "")
7739
7740 (define_expand "udivmodhi4"
7741 [(set (match_dup 4) (const_int 0))
7742 (parallel [(set (match_operand:HI 0 "register_operand" "")
7743 (udiv:HI (match_operand:HI 1 "register_operand" "")
7744 (match_operand:HI 2 "nonimmediate_operand" "")))
7745 (set (match_operand:HI 3 "register_operand" "")
7746 (umod:HI (match_dup 1) (match_dup 2)))
7747 (use (match_dup 4))
7748 (clobber (reg:CC FLAGS_REG))])]
7749 "TARGET_HIMODE_MATH"
7750 "operands[4] = gen_reg_rtx (HImode);")
7751
7752 (define_insn "*udivmodhi_noext"
7753 [(set (match_operand:HI 0 "register_operand" "=a")
7754 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7755 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7756 (set (match_operand:HI 3 "register_operand" "=d")
7757 (umod:HI (match_dup 1) (match_dup 2)))
7758 (use (match_operand:HI 4 "register_operand" "3"))
7759 (clobber (reg:CC FLAGS_REG))]
7760 ""
7761 "div{w}\t%2"
7762 [(set_attr "type" "idiv")
7763 (set_attr "mode" "HI")])
7764
7765 ;; We cannot use div/idiv for double division, because it causes
7766 ;; "division by zero" on the overflow and that's not what we expect
7767 ;; from truncate. Because true (non truncating) double division is
7768 ;; never generated, we can't create this insn anyway.
7769 ;
7770 ;(define_insn ""
7771 ; [(set (match_operand:SI 0 "register_operand" "=a")
7772 ; (truncate:SI
7773 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7774 ; (zero_extend:DI
7775 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7776 ; (set (match_operand:SI 3 "register_operand" "=d")
7777 ; (truncate:SI
7778 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7779 ; (clobber (reg:CC FLAGS_REG))]
7780 ; ""
7781 ; "div{l}\t{%2, %0|%0, %2}"
7782 ; [(set_attr "type" "idiv")])
7783 \f
7784 ;;- Logical AND instructions
7785
7786 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7787 ;; Note that this excludes ah.
7788
7789 (define_insn "*testdi_1_rex64"
7790 [(set (reg FLAGS_REG)
7791 (compare
7792 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7793 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7794 (const_int 0)))]
7795 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7796 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7797 "@
7798 test{l}\t{%k1, %k0|%k0, %k1}
7799 test{l}\t{%k1, %k0|%k0, %k1}
7800 test{q}\t{%1, %0|%0, %1}
7801 test{q}\t{%1, %0|%0, %1}
7802 test{q}\t{%1, %0|%0, %1}"
7803 [(set_attr "type" "test")
7804 (set_attr "modrm" "0,1,0,1,1")
7805 (set_attr "mode" "SI,SI,DI,DI,DI")
7806 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7807
7808 (define_insn "testsi_1"
7809 [(set (reg FLAGS_REG)
7810 (compare
7811 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7812 (match_operand:SI 1 "general_operand" "in,in,rin"))
7813 (const_int 0)))]
7814 "ix86_match_ccmode (insn, CCNOmode)
7815 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7816 "test{l}\t{%1, %0|%0, %1}"
7817 [(set_attr "type" "test")
7818 (set_attr "modrm" "0,1,1")
7819 (set_attr "mode" "SI")
7820 (set_attr "pent_pair" "uv,np,uv")])
7821
7822 (define_expand "testsi_ccno_1"
7823 [(set (reg:CCNO FLAGS_REG)
7824 (compare:CCNO
7825 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7826 (match_operand:SI 1 "nonmemory_operand" ""))
7827 (const_int 0)))]
7828 ""
7829 "")
7830
7831 (define_insn "*testhi_1"
7832 [(set (reg FLAGS_REG)
7833 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7834 (match_operand:HI 1 "general_operand" "n,n,rn"))
7835 (const_int 0)))]
7836 "ix86_match_ccmode (insn, CCNOmode)
7837 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7838 "test{w}\t{%1, %0|%0, %1}"
7839 [(set_attr "type" "test")
7840 (set_attr "modrm" "0,1,1")
7841 (set_attr "mode" "HI")
7842 (set_attr "pent_pair" "uv,np,uv")])
7843
7844 (define_expand "testqi_ccz_1"
7845 [(set (reg:CCZ FLAGS_REG)
7846 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7847 (match_operand:QI 1 "nonmemory_operand" ""))
7848 (const_int 0)))]
7849 ""
7850 "")
7851
7852 (define_insn "*testqi_1_maybe_si"
7853 [(set (reg FLAGS_REG)
7854 (compare
7855 (and:QI
7856 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7857 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7858 (const_int 0)))]
7859 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7860 && ix86_match_ccmode (insn,
7861 GET_CODE (operands[1]) == CONST_INT
7862 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7863 {
7864 if (which_alternative == 3)
7865 {
7866 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7867 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7868 return "test{l}\t{%1, %k0|%k0, %1}";
7869 }
7870 return "test{b}\t{%1, %0|%0, %1}";
7871 }
7872 [(set_attr "type" "test")
7873 (set_attr "modrm" "0,1,1,1")
7874 (set_attr "mode" "QI,QI,QI,SI")
7875 (set_attr "pent_pair" "uv,np,uv,np")])
7876
7877 (define_insn "*testqi_1"
7878 [(set (reg FLAGS_REG)
7879 (compare
7880 (and:QI
7881 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7882 (match_operand:QI 1 "general_operand" "n,n,qn"))
7883 (const_int 0)))]
7884 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7885 && ix86_match_ccmode (insn, CCNOmode)"
7886 "test{b}\t{%1, %0|%0, %1}"
7887 [(set_attr "type" "test")
7888 (set_attr "modrm" "0,1,1")
7889 (set_attr "mode" "QI")
7890 (set_attr "pent_pair" "uv,np,uv")])
7891
7892 (define_expand "testqi_ext_ccno_0"
7893 [(set (reg:CCNO FLAGS_REG)
7894 (compare:CCNO
7895 (and:SI
7896 (zero_extract:SI
7897 (match_operand 0 "ext_register_operand" "")
7898 (const_int 8)
7899 (const_int 8))
7900 (match_operand 1 "const_int_operand" ""))
7901 (const_int 0)))]
7902 ""
7903 "")
7904
7905 (define_insn "*testqi_ext_0"
7906 [(set (reg FLAGS_REG)
7907 (compare
7908 (and:SI
7909 (zero_extract:SI
7910 (match_operand 0 "ext_register_operand" "Q")
7911 (const_int 8)
7912 (const_int 8))
7913 (match_operand 1 "const_int_operand" "n"))
7914 (const_int 0)))]
7915 "ix86_match_ccmode (insn, CCNOmode)"
7916 "test{b}\t{%1, %h0|%h0, %1}"
7917 [(set_attr "type" "test")
7918 (set_attr "mode" "QI")
7919 (set_attr "length_immediate" "1")
7920 (set_attr "pent_pair" "np")])
7921
7922 (define_insn "*testqi_ext_1"
7923 [(set (reg FLAGS_REG)
7924 (compare
7925 (and:SI
7926 (zero_extract:SI
7927 (match_operand 0 "ext_register_operand" "Q")
7928 (const_int 8)
7929 (const_int 8))
7930 (zero_extend:SI
7931 (match_operand:QI 1 "general_operand" "Qm")))
7932 (const_int 0)))]
7933 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7934 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7935 "test{b}\t{%1, %h0|%h0, %1}"
7936 [(set_attr "type" "test")
7937 (set_attr "mode" "QI")])
7938
7939 (define_insn "*testqi_ext_1_rex64"
7940 [(set (reg FLAGS_REG)
7941 (compare
7942 (and:SI
7943 (zero_extract:SI
7944 (match_operand 0 "ext_register_operand" "Q")
7945 (const_int 8)
7946 (const_int 8))
7947 (zero_extend:SI
7948 (match_operand:QI 1 "register_operand" "Q")))
7949 (const_int 0)))]
7950 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7951 "test{b}\t{%1, %h0|%h0, %1}"
7952 [(set_attr "type" "test")
7953 (set_attr "mode" "QI")])
7954
7955 (define_insn "*testqi_ext_2"
7956 [(set (reg FLAGS_REG)
7957 (compare
7958 (and:SI
7959 (zero_extract:SI
7960 (match_operand 0 "ext_register_operand" "Q")
7961 (const_int 8)
7962 (const_int 8))
7963 (zero_extract:SI
7964 (match_operand 1 "ext_register_operand" "Q")
7965 (const_int 8)
7966 (const_int 8)))
7967 (const_int 0)))]
7968 "ix86_match_ccmode (insn, CCNOmode)"
7969 "test{b}\t{%h1, %h0|%h0, %h1}"
7970 [(set_attr "type" "test")
7971 (set_attr "mode" "QI")])
7972
7973 ;; Combine likes to form bit extractions for some tests. Humor it.
7974 (define_insn "*testqi_ext_3"
7975 [(set (reg FLAGS_REG)
7976 (compare (zero_extract:SI
7977 (match_operand 0 "nonimmediate_operand" "rm")
7978 (match_operand:SI 1 "const_int_operand" "")
7979 (match_operand:SI 2 "const_int_operand" ""))
7980 (const_int 0)))]
7981 "ix86_match_ccmode (insn, CCNOmode)
7982 && (GET_MODE (operands[0]) == SImode
7983 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7984 || GET_MODE (operands[0]) == HImode
7985 || GET_MODE (operands[0]) == QImode)"
7986 "#")
7987
7988 (define_insn "*testqi_ext_3_rex64"
7989 [(set (reg FLAGS_REG)
7990 (compare (zero_extract:DI
7991 (match_operand 0 "nonimmediate_operand" "rm")
7992 (match_operand:DI 1 "const_int_operand" "")
7993 (match_operand:DI 2 "const_int_operand" ""))
7994 (const_int 0)))]
7995 "TARGET_64BIT
7996 && ix86_match_ccmode (insn, CCNOmode)
7997 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7998 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7999 /* Ensure that resulting mask is zero or sign extended operand. */
8000 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8001 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8002 && INTVAL (operands[1]) > 32))
8003 && (GET_MODE (operands[0]) == SImode
8004 || GET_MODE (operands[0]) == DImode
8005 || GET_MODE (operands[0]) == HImode
8006 || GET_MODE (operands[0]) == QImode)"
8007 "#")
8008
8009 (define_split
8010 [(set (match_operand 0 "flags_reg_operand" "")
8011 (match_operator 1 "compare_operator"
8012 [(zero_extract
8013 (match_operand 2 "nonimmediate_operand" "")
8014 (match_operand 3 "const_int_operand" "")
8015 (match_operand 4 "const_int_operand" ""))
8016 (const_int 0)]))]
8017 "ix86_match_ccmode (insn, CCNOmode)"
8018 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8019 {
8020 rtx val = operands[2];
8021 HOST_WIDE_INT len = INTVAL (operands[3]);
8022 HOST_WIDE_INT pos = INTVAL (operands[4]);
8023 HOST_WIDE_INT mask;
8024 enum machine_mode mode, submode;
8025
8026 mode = GET_MODE (val);
8027 if (GET_CODE (val) == MEM)
8028 {
8029 /* ??? Combine likes to put non-volatile mem extractions in QImode
8030 no matter the size of the test. So find a mode that works. */
8031 if (! MEM_VOLATILE_P (val))
8032 {
8033 mode = smallest_mode_for_size (pos + len, MODE_INT);
8034 val = adjust_address (val, mode, 0);
8035 }
8036 }
8037 else if (GET_CODE (val) == SUBREG
8038 && (submode = GET_MODE (SUBREG_REG (val)),
8039 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8040 && pos + len <= GET_MODE_BITSIZE (submode))
8041 {
8042 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8043 mode = submode;
8044 val = SUBREG_REG (val);
8045 }
8046 else if (mode == HImode && pos + len <= 8)
8047 {
8048 /* Small HImode tests can be converted to QImode. */
8049 mode = QImode;
8050 val = gen_lowpart (QImode, val);
8051 }
8052
8053 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8054 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8055
8056 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8057 })
8058
8059 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8060 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8061 ;; this is relatively important trick.
8062 ;; Do the conversion only post-reload to avoid limiting of the register class
8063 ;; to QI regs.
8064 (define_split
8065 [(set (match_operand 0 "flags_reg_operand" "")
8066 (match_operator 1 "compare_operator"
8067 [(and (match_operand 2 "register_operand" "")
8068 (match_operand 3 "const_int_operand" ""))
8069 (const_int 0)]))]
8070 "reload_completed
8071 && QI_REG_P (operands[2])
8072 && GET_MODE (operands[2]) != QImode
8073 && ((ix86_match_ccmode (insn, CCZmode)
8074 && !(INTVAL (operands[3]) & ~(255 << 8)))
8075 || (ix86_match_ccmode (insn, CCNOmode)
8076 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8077 [(set (match_dup 0)
8078 (match_op_dup 1
8079 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8080 (match_dup 3))
8081 (const_int 0)]))]
8082 "operands[2] = gen_lowpart (SImode, operands[2]);
8083 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8084
8085 (define_split
8086 [(set (match_operand 0 "flags_reg_operand" "")
8087 (match_operator 1 "compare_operator"
8088 [(and (match_operand 2 "nonimmediate_operand" "")
8089 (match_operand 3 "const_int_operand" ""))
8090 (const_int 0)]))]
8091 "reload_completed
8092 && GET_MODE (operands[2]) != QImode
8093 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8094 && ((ix86_match_ccmode (insn, CCZmode)
8095 && !(INTVAL (operands[3]) & ~255))
8096 || (ix86_match_ccmode (insn, CCNOmode)
8097 && !(INTVAL (operands[3]) & ~127)))"
8098 [(set (match_dup 0)
8099 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8100 (const_int 0)]))]
8101 "operands[2] = gen_lowpart (QImode, operands[2]);
8102 operands[3] = gen_lowpart (QImode, operands[3]);")
8103
8104
8105 ;; %%% This used to optimize known byte-wide and operations to memory,
8106 ;; and sometimes to QImode registers. If this is considered useful,
8107 ;; it should be done with splitters.
8108
8109 (define_expand "anddi3"
8110 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8111 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8112 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8113 (clobber (reg:CC FLAGS_REG))]
8114 "TARGET_64BIT"
8115 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8116
8117 (define_insn "*anddi_1_rex64"
8118 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8119 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8120 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8121 (clobber (reg:CC FLAGS_REG))]
8122 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8123 {
8124 switch (get_attr_type (insn))
8125 {
8126 case TYPE_IMOVX:
8127 {
8128 enum machine_mode mode;
8129
8130 if (GET_CODE (operands[2]) != CONST_INT)
8131 abort ();
8132 if (INTVAL (operands[2]) == 0xff)
8133 mode = QImode;
8134 else if (INTVAL (operands[2]) == 0xffff)
8135 mode = HImode;
8136 else
8137 abort ();
8138
8139 operands[1] = gen_lowpart (mode, operands[1]);
8140 if (mode == QImode)
8141 return "movz{bq|x}\t{%1,%0|%0, %1}";
8142 else
8143 return "movz{wq|x}\t{%1,%0|%0, %1}";
8144 }
8145
8146 default:
8147 if (! rtx_equal_p (operands[0], operands[1]))
8148 abort ();
8149 if (get_attr_mode (insn) == MODE_SI)
8150 return "and{l}\t{%k2, %k0|%k0, %k2}";
8151 else
8152 return "and{q}\t{%2, %0|%0, %2}";
8153 }
8154 }
8155 [(set_attr "type" "alu,alu,alu,imovx")
8156 (set_attr "length_immediate" "*,*,*,0")
8157 (set_attr "mode" "SI,DI,DI,DI")])
8158
8159 (define_insn "*anddi_2"
8160 [(set (reg FLAGS_REG)
8161 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8162 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8163 (const_int 0)))
8164 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8165 (and:DI (match_dup 1) (match_dup 2)))]
8166 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8167 && ix86_binary_operator_ok (AND, DImode, operands)"
8168 "@
8169 and{l}\t{%k2, %k0|%k0, %k2}
8170 and{q}\t{%2, %0|%0, %2}
8171 and{q}\t{%2, %0|%0, %2}"
8172 [(set_attr "type" "alu")
8173 (set_attr "mode" "SI,DI,DI")])
8174
8175 (define_expand "andsi3"
8176 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8177 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8178 (match_operand:SI 2 "general_operand" "")))
8179 (clobber (reg:CC FLAGS_REG))]
8180 ""
8181 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8182
8183 (define_insn "*andsi_1"
8184 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8185 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8186 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8187 (clobber (reg:CC FLAGS_REG))]
8188 "ix86_binary_operator_ok (AND, SImode, operands)"
8189 {
8190 switch (get_attr_type (insn))
8191 {
8192 case TYPE_IMOVX:
8193 {
8194 enum machine_mode mode;
8195
8196 if (GET_CODE (operands[2]) != CONST_INT)
8197 abort ();
8198 if (INTVAL (operands[2]) == 0xff)
8199 mode = QImode;
8200 else if (INTVAL (operands[2]) == 0xffff)
8201 mode = HImode;
8202 else
8203 abort ();
8204
8205 operands[1] = gen_lowpart (mode, operands[1]);
8206 if (mode == QImode)
8207 return "movz{bl|x}\t{%1,%0|%0, %1}";
8208 else
8209 return "movz{wl|x}\t{%1,%0|%0, %1}";
8210 }
8211
8212 default:
8213 if (! rtx_equal_p (operands[0], operands[1]))
8214 abort ();
8215 return "and{l}\t{%2, %0|%0, %2}";
8216 }
8217 }
8218 [(set_attr "type" "alu,alu,imovx")
8219 (set_attr "length_immediate" "*,*,0")
8220 (set_attr "mode" "SI")])
8221
8222 (define_split
8223 [(set (match_operand 0 "register_operand" "")
8224 (and (match_dup 0)
8225 (const_int -65536)))
8226 (clobber (reg:CC FLAGS_REG))]
8227 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8228 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8229 "operands[1] = gen_lowpart (HImode, operands[0]);")
8230
8231 (define_split
8232 [(set (match_operand 0 "ext_register_operand" "")
8233 (and (match_dup 0)
8234 (const_int -256)))
8235 (clobber (reg:CC FLAGS_REG))]
8236 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8237 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8238 "operands[1] = gen_lowpart (QImode, operands[0]);")
8239
8240 (define_split
8241 [(set (match_operand 0 "ext_register_operand" "")
8242 (and (match_dup 0)
8243 (const_int -65281)))
8244 (clobber (reg:CC FLAGS_REG))]
8245 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8246 [(parallel [(set (zero_extract:SI (match_dup 0)
8247 (const_int 8)
8248 (const_int 8))
8249 (xor:SI
8250 (zero_extract:SI (match_dup 0)
8251 (const_int 8)
8252 (const_int 8))
8253 (zero_extract:SI (match_dup 0)
8254 (const_int 8)
8255 (const_int 8))))
8256 (clobber (reg:CC FLAGS_REG))])]
8257 "operands[0] = gen_lowpart (SImode, operands[0]);")
8258
8259 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8260 (define_insn "*andsi_1_zext"
8261 [(set (match_operand:DI 0 "register_operand" "=r")
8262 (zero_extend:DI
8263 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8264 (match_operand:SI 2 "general_operand" "rim"))))
8265 (clobber (reg:CC FLAGS_REG))]
8266 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8267 "and{l}\t{%2, %k0|%k0, %2}"
8268 [(set_attr "type" "alu")
8269 (set_attr "mode" "SI")])
8270
8271 (define_insn "*andsi_2"
8272 [(set (reg FLAGS_REG)
8273 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8274 (match_operand:SI 2 "general_operand" "rim,ri"))
8275 (const_int 0)))
8276 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8277 (and:SI (match_dup 1) (match_dup 2)))]
8278 "ix86_match_ccmode (insn, CCNOmode)
8279 && ix86_binary_operator_ok (AND, SImode, operands)"
8280 "and{l}\t{%2, %0|%0, %2}"
8281 [(set_attr "type" "alu")
8282 (set_attr "mode" "SI")])
8283
8284 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8285 (define_insn "*andsi_2_zext"
8286 [(set (reg FLAGS_REG)
8287 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8288 (match_operand:SI 2 "general_operand" "rim"))
8289 (const_int 0)))
8290 (set (match_operand:DI 0 "register_operand" "=r")
8291 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8292 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8293 && ix86_binary_operator_ok (AND, SImode, operands)"
8294 "and{l}\t{%2, %k0|%k0, %2}"
8295 [(set_attr "type" "alu")
8296 (set_attr "mode" "SI")])
8297
8298 (define_expand "andhi3"
8299 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8300 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8301 (match_operand:HI 2 "general_operand" "")))
8302 (clobber (reg:CC FLAGS_REG))]
8303 "TARGET_HIMODE_MATH"
8304 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8305
8306 (define_insn "*andhi_1"
8307 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8308 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8309 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8310 (clobber (reg:CC FLAGS_REG))]
8311 "ix86_binary_operator_ok (AND, HImode, operands)"
8312 {
8313 switch (get_attr_type (insn))
8314 {
8315 case TYPE_IMOVX:
8316 if (GET_CODE (operands[2]) != CONST_INT)
8317 abort ();
8318 if (INTVAL (operands[2]) == 0xff)
8319 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8320 abort ();
8321
8322 default:
8323 if (! rtx_equal_p (operands[0], operands[1]))
8324 abort ();
8325
8326 return "and{w}\t{%2, %0|%0, %2}";
8327 }
8328 }
8329 [(set_attr "type" "alu,alu,imovx")
8330 (set_attr "length_immediate" "*,*,0")
8331 (set_attr "mode" "HI,HI,SI")])
8332
8333 (define_insn "*andhi_2"
8334 [(set (reg FLAGS_REG)
8335 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8336 (match_operand:HI 2 "general_operand" "rim,ri"))
8337 (const_int 0)))
8338 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8339 (and:HI (match_dup 1) (match_dup 2)))]
8340 "ix86_match_ccmode (insn, CCNOmode)
8341 && ix86_binary_operator_ok (AND, HImode, operands)"
8342 "and{w}\t{%2, %0|%0, %2}"
8343 [(set_attr "type" "alu")
8344 (set_attr "mode" "HI")])
8345
8346 (define_expand "andqi3"
8347 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8348 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8349 (match_operand:QI 2 "general_operand" "")))
8350 (clobber (reg:CC FLAGS_REG))]
8351 "TARGET_QIMODE_MATH"
8352 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8353
8354 ;; %%% Potential partial reg stall on alternative 2. What to do?
8355 (define_insn "*andqi_1"
8356 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8357 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8358 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8359 (clobber (reg:CC FLAGS_REG))]
8360 "ix86_binary_operator_ok (AND, QImode, operands)"
8361 "@
8362 and{b}\t{%2, %0|%0, %2}
8363 and{b}\t{%2, %0|%0, %2}
8364 and{l}\t{%k2, %k0|%k0, %k2}"
8365 [(set_attr "type" "alu")
8366 (set_attr "mode" "QI,QI,SI")])
8367
8368 (define_insn "*andqi_1_slp"
8369 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8370 (and:QI (match_dup 0)
8371 (match_operand:QI 1 "general_operand" "qi,qmi")))
8372 (clobber (reg:CC FLAGS_REG))]
8373 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8374 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8375 "and{b}\t{%1, %0|%0, %1}"
8376 [(set_attr "type" "alu1")
8377 (set_attr "mode" "QI")])
8378
8379 (define_insn "*andqi_2_maybe_si"
8380 [(set (reg FLAGS_REG)
8381 (compare (and:QI
8382 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8383 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8384 (const_int 0)))
8385 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8386 (and:QI (match_dup 1) (match_dup 2)))]
8387 "ix86_binary_operator_ok (AND, QImode, operands)
8388 && ix86_match_ccmode (insn,
8389 GET_CODE (operands[2]) == CONST_INT
8390 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8391 {
8392 if (which_alternative == 2)
8393 {
8394 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8395 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8396 return "and{l}\t{%2, %k0|%k0, %2}";
8397 }
8398 return "and{b}\t{%2, %0|%0, %2}";
8399 }
8400 [(set_attr "type" "alu")
8401 (set_attr "mode" "QI,QI,SI")])
8402
8403 (define_insn "*andqi_2"
8404 [(set (reg FLAGS_REG)
8405 (compare (and:QI
8406 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8407 (match_operand:QI 2 "general_operand" "qim,qi"))
8408 (const_int 0)))
8409 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8410 (and:QI (match_dup 1) (match_dup 2)))]
8411 "ix86_match_ccmode (insn, CCNOmode)
8412 && ix86_binary_operator_ok (AND, QImode, operands)"
8413 "and{b}\t{%2, %0|%0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "QI")])
8416
8417 (define_insn "*andqi_2_slp"
8418 [(set (reg FLAGS_REG)
8419 (compare (and:QI
8420 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8421 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8422 (const_int 0)))
8423 (set (strict_low_part (match_dup 0))
8424 (and:QI (match_dup 0) (match_dup 1)))]
8425 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8426 && ix86_match_ccmode (insn, CCNOmode)
8427 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8428 "and{b}\t{%1, %0|%0, %1}"
8429 [(set_attr "type" "alu1")
8430 (set_attr "mode" "QI")])
8431
8432 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8433 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8434 ;; for a QImode operand, which of course failed.
8435
8436 (define_insn "andqi_ext_0"
8437 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8438 (const_int 8)
8439 (const_int 8))
8440 (and:SI
8441 (zero_extract:SI
8442 (match_operand 1 "ext_register_operand" "0")
8443 (const_int 8)
8444 (const_int 8))
8445 (match_operand 2 "const_int_operand" "n")))
8446 (clobber (reg:CC FLAGS_REG))]
8447 ""
8448 "and{b}\t{%2, %h0|%h0, %2}"
8449 [(set_attr "type" "alu")
8450 (set_attr "length_immediate" "1")
8451 (set_attr "mode" "QI")])
8452
8453 ;; Generated by peephole translating test to and. This shows up
8454 ;; often in fp comparisons.
8455
8456 (define_insn "*andqi_ext_0_cc"
8457 [(set (reg FLAGS_REG)
8458 (compare
8459 (and:SI
8460 (zero_extract:SI
8461 (match_operand 1 "ext_register_operand" "0")
8462 (const_int 8)
8463 (const_int 8))
8464 (match_operand 2 "const_int_operand" "n"))
8465 (const_int 0)))
8466 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8467 (const_int 8)
8468 (const_int 8))
8469 (and:SI
8470 (zero_extract:SI
8471 (match_dup 1)
8472 (const_int 8)
8473 (const_int 8))
8474 (match_dup 2)))]
8475 "ix86_match_ccmode (insn, CCNOmode)"
8476 "and{b}\t{%2, %h0|%h0, %2}"
8477 [(set_attr "type" "alu")
8478 (set_attr "length_immediate" "1")
8479 (set_attr "mode" "QI")])
8480
8481 (define_insn "*andqi_ext_1"
8482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8483 (const_int 8)
8484 (const_int 8))
8485 (and:SI
8486 (zero_extract:SI
8487 (match_operand 1 "ext_register_operand" "0")
8488 (const_int 8)
8489 (const_int 8))
8490 (zero_extend:SI
8491 (match_operand:QI 2 "general_operand" "Qm"))))
8492 (clobber (reg:CC FLAGS_REG))]
8493 "!TARGET_64BIT"
8494 "and{b}\t{%2, %h0|%h0, %2}"
8495 [(set_attr "type" "alu")
8496 (set_attr "length_immediate" "0")
8497 (set_attr "mode" "QI")])
8498
8499 (define_insn "*andqi_ext_1_rex64"
8500 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8501 (const_int 8)
8502 (const_int 8))
8503 (and:SI
8504 (zero_extract:SI
8505 (match_operand 1 "ext_register_operand" "0")
8506 (const_int 8)
8507 (const_int 8))
8508 (zero_extend:SI
8509 (match_operand 2 "ext_register_operand" "Q"))))
8510 (clobber (reg:CC FLAGS_REG))]
8511 "TARGET_64BIT"
8512 "and{b}\t{%2, %h0|%h0, %2}"
8513 [(set_attr "type" "alu")
8514 (set_attr "length_immediate" "0")
8515 (set_attr "mode" "QI")])
8516
8517 (define_insn "*andqi_ext_2"
8518 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8519 (const_int 8)
8520 (const_int 8))
8521 (and:SI
8522 (zero_extract:SI
8523 (match_operand 1 "ext_register_operand" "%0")
8524 (const_int 8)
8525 (const_int 8))
8526 (zero_extract:SI
8527 (match_operand 2 "ext_register_operand" "Q")
8528 (const_int 8)
8529 (const_int 8))))
8530 (clobber (reg:CC FLAGS_REG))]
8531 ""
8532 "and{b}\t{%h2, %h0|%h0, %h2}"
8533 [(set_attr "type" "alu")
8534 (set_attr "length_immediate" "0")
8535 (set_attr "mode" "QI")])
8536
8537 ;; Convert wide AND instructions with immediate operand to shorter QImode
8538 ;; equivalents when possible.
8539 ;; Don't do the splitting with memory operands, since it introduces risk
8540 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8541 ;; for size, but that can (should?) be handled by generic code instead.
8542 (define_split
8543 [(set (match_operand 0 "register_operand" "")
8544 (and (match_operand 1 "register_operand" "")
8545 (match_operand 2 "const_int_operand" "")))
8546 (clobber (reg:CC FLAGS_REG))]
8547 "reload_completed
8548 && QI_REG_P (operands[0])
8549 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8550 && !(~INTVAL (operands[2]) & ~(255 << 8))
8551 && GET_MODE (operands[0]) != QImode"
8552 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8553 (and:SI (zero_extract:SI (match_dup 1)
8554 (const_int 8) (const_int 8))
8555 (match_dup 2)))
8556 (clobber (reg:CC FLAGS_REG))])]
8557 "operands[0] = gen_lowpart (SImode, operands[0]);
8558 operands[1] = gen_lowpart (SImode, operands[1]);
8559 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8560
8561 ;; Since AND can be encoded with sign extended immediate, this is only
8562 ;; profitable when 7th bit is not set.
8563 (define_split
8564 [(set (match_operand 0 "register_operand" "")
8565 (and (match_operand 1 "general_operand" "")
8566 (match_operand 2 "const_int_operand" "")))
8567 (clobber (reg:CC FLAGS_REG))]
8568 "reload_completed
8569 && ANY_QI_REG_P (operands[0])
8570 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8571 && !(~INTVAL (operands[2]) & ~255)
8572 && !(INTVAL (operands[2]) & 128)
8573 && GET_MODE (operands[0]) != QImode"
8574 [(parallel [(set (strict_low_part (match_dup 0))
8575 (and:QI (match_dup 1)
8576 (match_dup 2)))
8577 (clobber (reg:CC FLAGS_REG))])]
8578 "operands[0] = gen_lowpart (QImode, operands[0]);
8579 operands[1] = gen_lowpart (QImode, operands[1]);
8580 operands[2] = gen_lowpart (QImode, operands[2]);")
8581 \f
8582 ;; Logical inclusive OR instructions
8583
8584 ;; %%% This used to optimize known byte-wide and operations to memory.
8585 ;; If this is considered useful, it should be done with splitters.
8586
8587 (define_expand "iordi3"
8588 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8589 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8590 (match_operand:DI 2 "x86_64_general_operand" "")))
8591 (clobber (reg:CC FLAGS_REG))]
8592 "TARGET_64BIT"
8593 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8594
8595 (define_insn "*iordi_1_rex64"
8596 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8597 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8598 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8599 (clobber (reg:CC FLAGS_REG))]
8600 "TARGET_64BIT
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_2_rex64"
8607 [(set (reg FLAGS_REG)
8608 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8609 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8610 (const_int 0)))
8611 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8612 (ior:DI (match_dup 1) (match_dup 2)))]
8613 "TARGET_64BIT
8614 && ix86_match_ccmode (insn, CCNOmode)
8615 && ix86_binary_operator_ok (IOR, DImode, operands)"
8616 "or{q}\t{%2, %0|%0, %2}"
8617 [(set_attr "type" "alu")
8618 (set_attr "mode" "DI")])
8619
8620 (define_insn "*iordi_3_rex64"
8621 [(set (reg FLAGS_REG)
8622 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8623 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8624 (const_int 0)))
8625 (clobber (match_scratch:DI 0 "=r"))]
8626 "TARGET_64BIT
8627 && ix86_match_ccmode (insn, CCNOmode)
8628 && ix86_binary_operator_ok (IOR, DImode, operands)"
8629 "or{q}\t{%2, %0|%0, %2}"
8630 [(set_attr "type" "alu")
8631 (set_attr "mode" "DI")])
8632
8633
8634 (define_expand "iorsi3"
8635 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8636 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8637 (match_operand:SI 2 "general_operand" "")))
8638 (clobber (reg:CC FLAGS_REG))]
8639 ""
8640 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8641
8642 (define_insn "*iorsi_1"
8643 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8644 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8645 (match_operand:SI 2 "general_operand" "ri,rmi")))
8646 (clobber (reg:CC FLAGS_REG))]
8647 "ix86_binary_operator_ok (IOR, SImode, operands)"
8648 "or{l}\t{%2, %0|%0, %2}"
8649 [(set_attr "type" "alu")
8650 (set_attr "mode" "SI")])
8651
8652 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8653 (define_insn "*iorsi_1_zext"
8654 [(set (match_operand:DI 0 "register_operand" "=rm")
8655 (zero_extend:DI
8656 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8657 (match_operand:SI 2 "general_operand" "rim"))))
8658 (clobber (reg:CC FLAGS_REG))]
8659 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8660 "or{l}\t{%2, %k0|%k0, %2}"
8661 [(set_attr "type" "alu")
8662 (set_attr "mode" "SI")])
8663
8664 (define_insn "*iorsi_1_zext_imm"
8665 [(set (match_operand:DI 0 "register_operand" "=rm")
8666 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8667 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8668 (clobber (reg:CC FLAGS_REG))]
8669 "TARGET_64BIT"
8670 "or{l}\t{%2, %k0|%k0, %2}"
8671 [(set_attr "type" "alu")
8672 (set_attr "mode" "SI")])
8673
8674 (define_insn "*iorsi_2"
8675 [(set (reg FLAGS_REG)
8676 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8677 (match_operand:SI 2 "general_operand" "rim,ri"))
8678 (const_int 0)))
8679 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8680 (ior:SI (match_dup 1) (match_dup 2)))]
8681 "ix86_match_ccmode (insn, CCNOmode)
8682 && ix86_binary_operator_ok (IOR, SImode, operands)"
8683 "or{l}\t{%2, %0|%0, %2}"
8684 [(set_attr "type" "alu")
8685 (set_attr "mode" "SI")])
8686
8687 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8688 ;; ??? Special case for immediate operand is missing - it is tricky.
8689 (define_insn "*iorsi_2_zext"
8690 [(set (reg FLAGS_REG)
8691 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8692 (match_operand:SI 2 "general_operand" "rim"))
8693 (const_int 0)))
8694 (set (match_operand:DI 0 "register_operand" "=r")
8695 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8696 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8697 && ix86_binary_operator_ok (IOR, SImode, operands)"
8698 "or{l}\t{%2, %k0|%k0, %2}"
8699 [(set_attr "type" "alu")
8700 (set_attr "mode" "SI")])
8701
8702 (define_insn "*iorsi_2_zext_imm"
8703 [(set (reg FLAGS_REG)
8704 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8705 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8706 (const_int 0)))
8707 (set (match_operand:DI 0 "register_operand" "=r")
8708 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8709 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8710 && ix86_binary_operator_ok (IOR, SImode, operands)"
8711 "or{l}\t{%2, %k0|%k0, %2}"
8712 [(set_attr "type" "alu")
8713 (set_attr "mode" "SI")])
8714
8715 (define_insn "*iorsi_3"
8716 [(set (reg FLAGS_REG)
8717 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8718 (match_operand:SI 2 "general_operand" "rim"))
8719 (const_int 0)))
8720 (clobber (match_scratch:SI 0 "=r"))]
8721 "ix86_match_ccmode (insn, CCNOmode)
8722 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8723 "or{l}\t{%2, %0|%0, %2}"
8724 [(set_attr "type" "alu")
8725 (set_attr "mode" "SI")])
8726
8727 (define_expand "iorhi3"
8728 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8729 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8730 (match_operand:HI 2 "general_operand" "")))
8731 (clobber (reg:CC FLAGS_REG))]
8732 "TARGET_HIMODE_MATH"
8733 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8734
8735 (define_insn "*iorhi_1"
8736 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8737 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8738 (match_operand:HI 2 "general_operand" "rmi,ri")))
8739 (clobber (reg:CC FLAGS_REG))]
8740 "ix86_binary_operator_ok (IOR, HImode, operands)"
8741 "or{w}\t{%2, %0|%0, %2}"
8742 [(set_attr "type" "alu")
8743 (set_attr "mode" "HI")])
8744
8745 (define_insn "*iorhi_2"
8746 [(set (reg FLAGS_REG)
8747 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8748 (match_operand:HI 2 "general_operand" "rim,ri"))
8749 (const_int 0)))
8750 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8751 (ior:HI (match_dup 1) (match_dup 2)))]
8752 "ix86_match_ccmode (insn, CCNOmode)
8753 && ix86_binary_operator_ok (IOR, HImode, operands)"
8754 "or{w}\t{%2, %0|%0, %2}"
8755 [(set_attr "type" "alu")
8756 (set_attr "mode" "HI")])
8757
8758 (define_insn "*iorhi_3"
8759 [(set (reg FLAGS_REG)
8760 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8761 (match_operand:HI 2 "general_operand" "rim"))
8762 (const_int 0)))
8763 (clobber (match_scratch:HI 0 "=r"))]
8764 "ix86_match_ccmode (insn, CCNOmode)
8765 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8766 "or{w}\t{%2, %0|%0, %2}"
8767 [(set_attr "type" "alu")
8768 (set_attr "mode" "HI")])
8769
8770 (define_expand "iorqi3"
8771 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8772 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8773 (match_operand:QI 2 "general_operand" "")))
8774 (clobber (reg:CC FLAGS_REG))]
8775 "TARGET_QIMODE_MATH"
8776 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8777
8778 ;; %%% Potential partial reg stall on alternative 2. What to do?
8779 (define_insn "*iorqi_1"
8780 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8781 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8782 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8783 (clobber (reg:CC FLAGS_REG))]
8784 "ix86_binary_operator_ok (IOR, QImode, operands)"
8785 "@
8786 or{b}\t{%2, %0|%0, %2}
8787 or{b}\t{%2, %0|%0, %2}
8788 or{l}\t{%k2, %k0|%k0, %k2}"
8789 [(set_attr "type" "alu")
8790 (set_attr "mode" "QI,QI,SI")])
8791
8792 (define_insn "*iorqi_1_slp"
8793 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8794 (ior:QI (match_dup 0)
8795 (match_operand:QI 1 "general_operand" "qmi,qi")))
8796 (clobber (reg:CC FLAGS_REG))]
8797 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8798 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8799 "or{b}\t{%1, %0|%0, %1}"
8800 [(set_attr "type" "alu1")
8801 (set_attr "mode" "QI")])
8802
8803 (define_insn "*iorqi_2"
8804 [(set (reg FLAGS_REG)
8805 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8806 (match_operand:QI 2 "general_operand" "qim,qi"))
8807 (const_int 0)))
8808 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8809 (ior:QI (match_dup 1) (match_dup 2)))]
8810 "ix86_match_ccmode (insn, CCNOmode)
8811 && ix86_binary_operator_ok (IOR, QImode, operands)"
8812 "or{b}\t{%2, %0|%0, %2}"
8813 [(set_attr "type" "alu")
8814 (set_attr "mode" "QI")])
8815
8816 (define_insn "*iorqi_2_slp"
8817 [(set (reg FLAGS_REG)
8818 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8819 (match_operand:QI 1 "general_operand" "qim,qi"))
8820 (const_int 0)))
8821 (set (strict_low_part (match_dup 0))
8822 (ior:QI (match_dup 0) (match_dup 1)))]
8823 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8824 && ix86_match_ccmode (insn, CCNOmode)
8825 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8826 "or{b}\t{%1, %0|%0, %1}"
8827 [(set_attr "type" "alu1")
8828 (set_attr "mode" "QI")])
8829
8830 (define_insn "*iorqi_3"
8831 [(set (reg FLAGS_REG)
8832 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8833 (match_operand:QI 2 "general_operand" "qim"))
8834 (const_int 0)))
8835 (clobber (match_scratch:QI 0 "=q"))]
8836 "ix86_match_ccmode (insn, CCNOmode)
8837 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8838 "or{b}\t{%2, %0|%0, %2}"
8839 [(set_attr "type" "alu")
8840 (set_attr "mode" "QI")])
8841
8842 (define_insn "iorqi_ext_0"
8843 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8844 (const_int 8)
8845 (const_int 8))
8846 (ior:SI
8847 (zero_extract:SI
8848 (match_operand 1 "ext_register_operand" "0")
8849 (const_int 8)
8850 (const_int 8))
8851 (match_operand 2 "const_int_operand" "n")))
8852 (clobber (reg:CC FLAGS_REG))]
8853 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8854 "or{b}\t{%2, %h0|%h0, %2}"
8855 [(set_attr "type" "alu")
8856 (set_attr "length_immediate" "1")
8857 (set_attr "mode" "QI")])
8858
8859 (define_insn "*iorqi_ext_1"
8860 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8861 (const_int 8)
8862 (const_int 8))
8863 (ior:SI
8864 (zero_extract:SI
8865 (match_operand 1 "ext_register_operand" "0")
8866 (const_int 8)
8867 (const_int 8))
8868 (zero_extend:SI
8869 (match_operand:QI 2 "general_operand" "Qm"))))
8870 (clobber (reg:CC FLAGS_REG))]
8871 "!TARGET_64BIT
8872 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8873 "or{b}\t{%2, %h0|%h0, %2}"
8874 [(set_attr "type" "alu")
8875 (set_attr "length_immediate" "0")
8876 (set_attr "mode" "QI")])
8877
8878 (define_insn "*iorqi_ext_1_rex64"
8879 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8880 (const_int 8)
8881 (const_int 8))
8882 (ior:SI
8883 (zero_extract:SI
8884 (match_operand 1 "ext_register_operand" "0")
8885 (const_int 8)
8886 (const_int 8))
8887 (zero_extend:SI
8888 (match_operand 2 "ext_register_operand" "Q"))))
8889 (clobber (reg:CC FLAGS_REG))]
8890 "TARGET_64BIT
8891 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8892 "or{b}\t{%2, %h0|%h0, %2}"
8893 [(set_attr "type" "alu")
8894 (set_attr "length_immediate" "0")
8895 (set_attr "mode" "QI")])
8896
8897 (define_insn "*iorqi_ext_2"
8898 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8899 (const_int 8)
8900 (const_int 8))
8901 (ior:SI
8902 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8903 (const_int 8)
8904 (const_int 8))
8905 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8906 (const_int 8)
8907 (const_int 8))))
8908 (clobber (reg:CC FLAGS_REG))]
8909 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8910 "ior{b}\t{%h2, %h0|%h0, %h2}"
8911 [(set_attr "type" "alu")
8912 (set_attr "length_immediate" "0")
8913 (set_attr "mode" "QI")])
8914
8915 (define_split
8916 [(set (match_operand 0 "register_operand" "")
8917 (ior (match_operand 1 "register_operand" "")
8918 (match_operand 2 "const_int_operand" "")))
8919 (clobber (reg:CC FLAGS_REG))]
8920 "reload_completed
8921 && QI_REG_P (operands[0])
8922 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8923 && !(INTVAL (operands[2]) & ~(255 << 8))
8924 && GET_MODE (operands[0]) != QImode"
8925 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8926 (ior:SI (zero_extract:SI (match_dup 1)
8927 (const_int 8) (const_int 8))
8928 (match_dup 2)))
8929 (clobber (reg:CC FLAGS_REG))])]
8930 "operands[0] = gen_lowpart (SImode, operands[0]);
8931 operands[1] = gen_lowpart (SImode, operands[1]);
8932 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8933
8934 ;; Since OR can be encoded with sign extended immediate, this is only
8935 ;; profitable when 7th bit is set.
8936 (define_split
8937 [(set (match_operand 0 "register_operand" "")
8938 (ior (match_operand 1 "general_operand" "")
8939 (match_operand 2 "const_int_operand" "")))
8940 (clobber (reg:CC FLAGS_REG))]
8941 "reload_completed
8942 && ANY_QI_REG_P (operands[0])
8943 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8944 && !(INTVAL (operands[2]) & ~255)
8945 && (INTVAL (operands[2]) & 128)
8946 && GET_MODE (operands[0]) != QImode"
8947 [(parallel [(set (strict_low_part (match_dup 0))
8948 (ior:QI (match_dup 1)
8949 (match_dup 2)))
8950 (clobber (reg:CC FLAGS_REG))])]
8951 "operands[0] = gen_lowpart (QImode, operands[0]);
8952 operands[1] = gen_lowpart (QImode, operands[1]);
8953 operands[2] = gen_lowpart (QImode, operands[2]);")
8954 \f
8955 ;; Logical XOR instructions
8956
8957 ;; %%% This used to optimize known byte-wide and operations to memory.
8958 ;; If this is considered useful, it should be done with splitters.
8959
8960 (define_expand "xordi3"
8961 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8962 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8963 (match_operand:DI 2 "x86_64_general_operand" "")))
8964 (clobber (reg:CC FLAGS_REG))]
8965 "TARGET_64BIT"
8966 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8967
8968 (define_insn "*xordi_1_rex64"
8969 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8970 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8971 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8972 (clobber (reg:CC FLAGS_REG))]
8973 "TARGET_64BIT
8974 && ix86_binary_operator_ok (XOR, DImode, operands)"
8975 "@
8976 xor{q}\t{%2, %0|%0, %2}
8977 xor{q}\t{%2, %0|%0, %2}"
8978 [(set_attr "type" "alu")
8979 (set_attr "mode" "DI,DI")])
8980
8981 (define_insn "*xordi_2_rex64"
8982 [(set (reg FLAGS_REG)
8983 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8984 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8985 (const_int 0)))
8986 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8987 (xor:DI (match_dup 1) (match_dup 2)))]
8988 "TARGET_64BIT
8989 && ix86_match_ccmode (insn, CCNOmode)
8990 && ix86_binary_operator_ok (XOR, DImode, operands)"
8991 "@
8992 xor{q}\t{%2, %0|%0, %2}
8993 xor{q}\t{%2, %0|%0, %2}"
8994 [(set_attr "type" "alu")
8995 (set_attr "mode" "DI,DI")])
8996
8997 (define_insn "*xordi_3_rex64"
8998 [(set (reg FLAGS_REG)
8999 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9000 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9001 (const_int 0)))
9002 (clobber (match_scratch:DI 0 "=r"))]
9003 "TARGET_64BIT
9004 && ix86_match_ccmode (insn, CCNOmode)
9005 && ix86_binary_operator_ok (XOR, DImode, operands)"
9006 "xor{q}\t{%2, %0|%0, %2}"
9007 [(set_attr "type" "alu")
9008 (set_attr "mode" "DI")])
9009
9010 (define_expand "xorsi3"
9011 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9012 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9013 (match_operand:SI 2 "general_operand" "")))
9014 (clobber (reg:CC FLAGS_REG))]
9015 ""
9016 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9017
9018 (define_insn "*xorsi_1"
9019 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9020 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9021 (match_operand:SI 2 "general_operand" "ri,rm")))
9022 (clobber (reg:CC FLAGS_REG))]
9023 "ix86_binary_operator_ok (XOR, SImode, operands)"
9024 "xor{l}\t{%2, %0|%0, %2}"
9025 [(set_attr "type" "alu")
9026 (set_attr "mode" "SI")])
9027
9028 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9029 ;; Add speccase for immediates
9030 (define_insn "*xorsi_1_zext"
9031 [(set (match_operand:DI 0 "register_operand" "=r")
9032 (zero_extend:DI
9033 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9034 (match_operand:SI 2 "general_operand" "rim"))))
9035 (clobber (reg:CC FLAGS_REG))]
9036 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9037 "xor{l}\t{%2, %k0|%k0, %2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "mode" "SI")])
9040
9041 (define_insn "*xorsi_1_zext_imm"
9042 [(set (match_operand:DI 0 "register_operand" "=r")
9043 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9044 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9045 (clobber (reg:CC FLAGS_REG))]
9046 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9047 "xor{l}\t{%2, %k0|%k0, %2}"
9048 [(set_attr "type" "alu")
9049 (set_attr "mode" "SI")])
9050
9051 (define_insn "*xorsi_2"
9052 [(set (reg FLAGS_REG)
9053 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9054 (match_operand:SI 2 "general_operand" "rim,ri"))
9055 (const_int 0)))
9056 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9057 (xor:SI (match_dup 1) (match_dup 2)))]
9058 "ix86_match_ccmode (insn, CCNOmode)
9059 && ix86_binary_operator_ok (XOR, SImode, operands)"
9060 "xor{l}\t{%2, %0|%0, %2}"
9061 [(set_attr "type" "alu")
9062 (set_attr "mode" "SI")])
9063
9064 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9065 ;; ??? Special case for immediate operand is missing - it is tricky.
9066 (define_insn "*xorsi_2_zext"
9067 [(set (reg FLAGS_REG)
9068 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9069 (match_operand:SI 2 "general_operand" "rim"))
9070 (const_int 0)))
9071 (set (match_operand:DI 0 "register_operand" "=r")
9072 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9073 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9074 && ix86_binary_operator_ok (XOR, SImode, operands)"
9075 "xor{l}\t{%2, %k0|%k0, %2}"
9076 [(set_attr "type" "alu")
9077 (set_attr "mode" "SI")])
9078
9079 (define_insn "*xorsi_2_zext_imm"
9080 [(set (reg FLAGS_REG)
9081 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9082 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9083 (const_int 0)))
9084 (set (match_operand:DI 0 "register_operand" "=r")
9085 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9086 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9087 && ix86_binary_operator_ok (XOR, SImode, operands)"
9088 "xor{l}\t{%2, %k0|%k0, %2}"
9089 [(set_attr "type" "alu")
9090 (set_attr "mode" "SI")])
9091
9092 (define_insn "*xorsi_3"
9093 [(set (reg FLAGS_REG)
9094 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9095 (match_operand:SI 2 "general_operand" "rim"))
9096 (const_int 0)))
9097 (clobber (match_scratch:SI 0 "=r"))]
9098 "ix86_match_ccmode (insn, CCNOmode)
9099 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9100 "xor{l}\t{%2, %0|%0, %2}"
9101 [(set_attr "type" "alu")
9102 (set_attr "mode" "SI")])
9103
9104 (define_expand "xorhi3"
9105 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9106 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9107 (match_operand:HI 2 "general_operand" "")))
9108 (clobber (reg:CC FLAGS_REG))]
9109 "TARGET_HIMODE_MATH"
9110 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9111
9112 (define_insn "*xorhi_1"
9113 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9114 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9115 (match_operand:HI 2 "general_operand" "rmi,ri")))
9116 (clobber (reg:CC FLAGS_REG))]
9117 "ix86_binary_operator_ok (XOR, HImode, operands)"
9118 "xor{w}\t{%2, %0|%0, %2}"
9119 [(set_attr "type" "alu")
9120 (set_attr "mode" "HI")])
9121
9122 (define_insn "*xorhi_2"
9123 [(set (reg FLAGS_REG)
9124 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9125 (match_operand:HI 2 "general_operand" "rim,ri"))
9126 (const_int 0)))
9127 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9128 (xor:HI (match_dup 1) (match_dup 2)))]
9129 "ix86_match_ccmode (insn, CCNOmode)
9130 && ix86_binary_operator_ok (XOR, HImode, operands)"
9131 "xor{w}\t{%2, %0|%0, %2}"
9132 [(set_attr "type" "alu")
9133 (set_attr "mode" "HI")])
9134
9135 (define_insn "*xorhi_3"
9136 [(set (reg FLAGS_REG)
9137 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9138 (match_operand:HI 2 "general_operand" "rim"))
9139 (const_int 0)))
9140 (clobber (match_scratch:HI 0 "=r"))]
9141 "ix86_match_ccmode (insn, CCNOmode)
9142 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9143 "xor{w}\t{%2, %0|%0, %2}"
9144 [(set_attr "type" "alu")
9145 (set_attr "mode" "HI")])
9146
9147 (define_expand "xorqi3"
9148 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9149 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9150 (match_operand:QI 2 "general_operand" "")))
9151 (clobber (reg:CC FLAGS_REG))]
9152 "TARGET_QIMODE_MATH"
9153 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9154
9155 ;; %%% Potential partial reg stall on alternative 2. What to do?
9156 (define_insn "*xorqi_1"
9157 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9158 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9159 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9160 (clobber (reg:CC FLAGS_REG))]
9161 "ix86_binary_operator_ok (XOR, QImode, operands)"
9162 "@
9163 xor{b}\t{%2, %0|%0, %2}
9164 xor{b}\t{%2, %0|%0, %2}
9165 xor{l}\t{%k2, %k0|%k0, %k2}"
9166 [(set_attr "type" "alu")
9167 (set_attr "mode" "QI,QI,SI")])
9168
9169 (define_insn "*xorqi_1_slp"
9170 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9171 (xor:QI (match_dup 0)
9172 (match_operand:QI 1 "general_operand" "qi,qmi")))
9173 (clobber (reg:CC FLAGS_REG))]
9174 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9175 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9176 "xor{b}\t{%1, %0|%0, %1}"
9177 [(set_attr "type" "alu1")
9178 (set_attr "mode" "QI")])
9179
9180 (define_insn "xorqi_ext_0"
9181 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9182 (const_int 8)
9183 (const_int 8))
9184 (xor:SI
9185 (zero_extract:SI
9186 (match_operand 1 "ext_register_operand" "0")
9187 (const_int 8)
9188 (const_int 8))
9189 (match_operand 2 "const_int_operand" "n")))
9190 (clobber (reg:CC FLAGS_REG))]
9191 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9192 "xor{b}\t{%2, %h0|%h0, %2}"
9193 [(set_attr "type" "alu")
9194 (set_attr "length_immediate" "1")
9195 (set_attr "mode" "QI")])
9196
9197 (define_insn "*xorqi_ext_1"
9198 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9199 (const_int 8)
9200 (const_int 8))
9201 (xor:SI
9202 (zero_extract:SI
9203 (match_operand 1 "ext_register_operand" "0")
9204 (const_int 8)
9205 (const_int 8))
9206 (zero_extend:SI
9207 (match_operand:QI 2 "general_operand" "Qm"))))
9208 (clobber (reg:CC FLAGS_REG))]
9209 "!TARGET_64BIT
9210 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9211 "xor{b}\t{%2, %h0|%h0, %2}"
9212 [(set_attr "type" "alu")
9213 (set_attr "length_immediate" "0")
9214 (set_attr "mode" "QI")])
9215
9216 (define_insn "*xorqi_ext_1_rex64"
9217 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9218 (const_int 8)
9219 (const_int 8))
9220 (xor:SI
9221 (zero_extract:SI
9222 (match_operand 1 "ext_register_operand" "0")
9223 (const_int 8)
9224 (const_int 8))
9225 (zero_extend:SI
9226 (match_operand 2 "ext_register_operand" "Q"))))
9227 (clobber (reg:CC FLAGS_REG))]
9228 "TARGET_64BIT
9229 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9230 "xor{b}\t{%2, %h0|%h0, %2}"
9231 [(set_attr "type" "alu")
9232 (set_attr "length_immediate" "0")
9233 (set_attr "mode" "QI")])
9234
9235 (define_insn "*xorqi_ext_2"
9236 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9237 (const_int 8)
9238 (const_int 8))
9239 (xor:SI
9240 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9241 (const_int 8)
9242 (const_int 8))
9243 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9244 (const_int 8)
9245 (const_int 8))))
9246 (clobber (reg:CC FLAGS_REG))]
9247 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9248 "xor{b}\t{%h2, %h0|%h0, %h2}"
9249 [(set_attr "type" "alu")
9250 (set_attr "length_immediate" "0")
9251 (set_attr "mode" "QI")])
9252
9253 (define_insn "*xorqi_cc_1"
9254 [(set (reg FLAGS_REG)
9255 (compare
9256 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9257 (match_operand:QI 2 "general_operand" "qim,qi"))
9258 (const_int 0)))
9259 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9260 (xor:QI (match_dup 1) (match_dup 2)))]
9261 "ix86_match_ccmode (insn, CCNOmode)
9262 && ix86_binary_operator_ok (XOR, QImode, operands)"
9263 "xor{b}\t{%2, %0|%0, %2}"
9264 [(set_attr "type" "alu")
9265 (set_attr "mode" "QI")])
9266
9267 (define_insn "*xorqi_2_slp"
9268 [(set (reg FLAGS_REG)
9269 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9270 (match_operand:QI 1 "general_operand" "qim,qi"))
9271 (const_int 0)))
9272 (set (strict_low_part (match_dup 0))
9273 (xor:QI (match_dup 0) (match_dup 1)))]
9274 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9275 && ix86_match_ccmode (insn, CCNOmode)
9276 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9277 "xor{b}\t{%1, %0|%0, %1}"
9278 [(set_attr "type" "alu1")
9279 (set_attr "mode" "QI")])
9280
9281 (define_insn "*xorqi_cc_2"
9282 [(set (reg FLAGS_REG)
9283 (compare
9284 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9285 (match_operand:QI 2 "general_operand" "qim"))
9286 (const_int 0)))
9287 (clobber (match_scratch:QI 0 "=q"))]
9288 "ix86_match_ccmode (insn, CCNOmode)
9289 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9290 "xor{b}\t{%2, %0|%0, %2}"
9291 [(set_attr "type" "alu")
9292 (set_attr "mode" "QI")])
9293
9294 (define_insn "*xorqi_cc_ext_1"
9295 [(set (reg FLAGS_REG)
9296 (compare
9297 (xor:SI
9298 (zero_extract:SI
9299 (match_operand 1 "ext_register_operand" "0")
9300 (const_int 8)
9301 (const_int 8))
9302 (match_operand:QI 2 "general_operand" "qmn"))
9303 (const_int 0)))
9304 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9305 (const_int 8)
9306 (const_int 8))
9307 (xor:SI
9308 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9309 (match_dup 2)))]
9310 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9311 "xor{b}\t{%2, %h0|%h0, %2}"
9312 [(set_attr "type" "alu")
9313 (set_attr "mode" "QI")])
9314
9315 (define_insn "*xorqi_cc_ext_1_rex64"
9316 [(set (reg FLAGS_REG)
9317 (compare
9318 (xor:SI
9319 (zero_extract:SI
9320 (match_operand 1 "ext_register_operand" "0")
9321 (const_int 8)
9322 (const_int 8))
9323 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9324 (const_int 0)))
9325 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9326 (const_int 8)
9327 (const_int 8))
9328 (xor:SI
9329 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9330 (match_dup 2)))]
9331 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9332 "xor{b}\t{%2, %h0|%h0, %2}"
9333 [(set_attr "type" "alu")
9334 (set_attr "mode" "QI")])
9335
9336 (define_expand "xorqi_cc_ext_1"
9337 [(parallel [
9338 (set (reg:CCNO FLAGS_REG)
9339 (compare:CCNO
9340 (xor:SI
9341 (zero_extract:SI
9342 (match_operand 1 "ext_register_operand" "")
9343 (const_int 8)
9344 (const_int 8))
9345 (match_operand:QI 2 "general_operand" ""))
9346 (const_int 0)))
9347 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9348 (const_int 8)
9349 (const_int 8))
9350 (xor:SI
9351 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9352 (match_dup 2)))])]
9353 ""
9354 "")
9355
9356 (define_split
9357 [(set (match_operand 0 "register_operand" "")
9358 (xor (match_operand 1 "register_operand" "")
9359 (match_operand 2 "const_int_operand" "")))
9360 (clobber (reg:CC FLAGS_REG))]
9361 "reload_completed
9362 && QI_REG_P (operands[0])
9363 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9364 && !(INTVAL (operands[2]) & ~(255 << 8))
9365 && GET_MODE (operands[0]) != QImode"
9366 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9367 (xor:SI (zero_extract:SI (match_dup 1)
9368 (const_int 8) (const_int 8))
9369 (match_dup 2)))
9370 (clobber (reg:CC FLAGS_REG))])]
9371 "operands[0] = gen_lowpart (SImode, operands[0]);
9372 operands[1] = gen_lowpart (SImode, operands[1]);
9373 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9374
9375 ;; Since XOR can be encoded with sign extended immediate, this is only
9376 ;; profitable when 7th bit is set.
9377 (define_split
9378 [(set (match_operand 0 "register_operand" "")
9379 (xor (match_operand 1 "general_operand" "")
9380 (match_operand 2 "const_int_operand" "")))
9381 (clobber (reg:CC FLAGS_REG))]
9382 "reload_completed
9383 && ANY_QI_REG_P (operands[0])
9384 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9385 && !(INTVAL (operands[2]) & ~255)
9386 && (INTVAL (operands[2]) & 128)
9387 && GET_MODE (operands[0]) != QImode"
9388 [(parallel [(set (strict_low_part (match_dup 0))
9389 (xor:QI (match_dup 1)
9390 (match_dup 2)))
9391 (clobber (reg:CC FLAGS_REG))])]
9392 "operands[0] = gen_lowpart (QImode, operands[0]);
9393 operands[1] = gen_lowpart (QImode, operands[1]);
9394 operands[2] = gen_lowpart (QImode, operands[2]);")
9395 \f
9396 ;; Negation instructions
9397
9398 (define_expand "negdi2"
9399 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9400 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9401 (clobber (reg:CC FLAGS_REG))])]
9402 ""
9403 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9404
9405 (define_insn "*negdi2_1"
9406 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9407 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9408 (clobber (reg:CC FLAGS_REG))]
9409 "!TARGET_64BIT
9410 && ix86_unary_operator_ok (NEG, DImode, operands)"
9411 "#")
9412
9413 (define_split
9414 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9415 (neg:DI (match_operand:DI 1 "general_operand" "")))
9416 (clobber (reg:CC FLAGS_REG))]
9417 "!TARGET_64BIT && reload_completed"
9418 [(parallel
9419 [(set (reg:CCZ FLAGS_REG)
9420 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9421 (set (match_dup 0) (neg:SI (match_dup 2)))])
9422 (parallel
9423 [(set (match_dup 1)
9424 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9425 (match_dup 3))
9426 (const_int 0)))
9427 (clobber (reg:CC FLAGS_REG))])
9428 (parallel
9429 [(set (match_dup 1)
9430 (neg:SI (match_dup 1)))
9431 (clobber (reg:CC FLAGS_REG))])]
9432 "split_di (operands+1, 1, operands+2, operands+3);
9433 split_di (operands+0, 1, operands+0, operands+1);")
9434
9435 (define_insn "*negdi2_1_rex64"
9436 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9437 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9438 (clobber (reg:CC FLAGS_REG))]
9439 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9440 "neg{q}\t%0"
9441 [(set_attr "type" "negnot")
9442 (set_attr "mode" "DI")])
9443
9444 ;; The problem with neg is that it does not perform (compare x 0),
9445 ;; it really performs (compare 0 x), which leaves us with the zero
9446 ;; flag being the only useful item.
9447
9448 (define_insn "*negdi2_cmpz_rex64"
9449 [(set (reg:CCZ FLAGS_REG)
9450 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9451 (const_int 0)))
9452 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9453 (neg:DI (match_dup 1)))]
9454 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9455 "neg{q}\t%0"
9456 [(set_attr "type" "negnot")
9457 (set_attr "mode" "DI")])
9458
9459
9460 (define_expand "negsi2"
9461 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9462 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9463 (clobber (reg:CC FLAGS_REG))])]
9464 ""
9465 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9466
9467 (define_insn "*negsi2_1"
9468 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9469 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9470 (clobber (reg:CC FLAGS_REG))]
9471 "ix86_unary_operator_ok (NEG, SImode, operands)"
9472 "neg{l}\t%0"
9473 [(set_attr "type" "negnot")
9474 (set_attr "mode" "SI")])
9475
9476 ;; Combine is quite creative about this pattern.
9477 (define_insn "*negsi2_1_zext"
9478 [(set (match_operand:DI 0 "register_operand" "=r")
9479 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9480 (const_int 32)))
9481 (const_int 32)))
9482 (clobber (reg:CC FLAGS_REG))]
9483 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9484 "neg{l}\t%k0"
9485 [(set_attr "type" "negnot")
9486 (set_attr "mode" "SI")])
9487
9488 ;; The problem with neg is that it does not perform (compare x 0),
9489 ;; it really performs (compare 0 x), which leaves us with the zero
9490 ;; flag being the only useful item.
9491
9492 (define_insn "*negsi2_cmpz"
9493 [(set (reg:CCZ FLAGS_REG)
9494 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9495 (const_int 0)))
9496 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9497 (neg:SI (match_dup 1)))]
9498 "ix86_unary_operator_ok (NEG, SImode, operands)"
9499 "neg{l}\t%0"
9500 [(set_attr "type" "negnot")
9501 (set_attr "mode" "SI")])
9502
9503 (define_insn "*negsi2_cmpz_zext"
9504 [(set (reg:CCZ FLAGS_REG)
9505 (compare:CCZ (lshiftrt:DI
9506 (neg:DI (ashift:DI
9507 (match_operand:DI 1 "register_operand" "0")
9508 (const_int 32)))
9509 (const_int 32))
9510 (const_int 0)))
9511 (set (match_operand:DI 0 "register_operand" "=r")
9512 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9513 (const_int 32)))
9514 (const_int 32)))]
9515 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9516 "neg{l}\t%k0"
9517 [(set_attr "type" "negnot")
9518 (set_attr "mode" "SI")])
9519
9520 (define_expand "neghi2"
9521 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9522 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9523 (clobber (reg:CC FLAGS_REG))])]
9524 "TARGET_HIMODE_MATH"
9525 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9526
9527 (define_insn "*neghi2_1"
9528 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9529 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9530 (clobber (reg:CC FLAGS_REG))]
9531 "ix86_unary_operator_ok (NEG, HImode, operands)"
9532 "neg{w}\t%0"
9533 [(set_attr "type" "negnot")
9534 (set_attr "mode" "HI")])
9535
9536 (define_insn "*neghi2_cmpz"
9537 [(set (reg:CCZ FLAGS_REG)
9538 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9539 (const_int 0)))
9540 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9541 (neg:HI (match_dup 1)))]
9542 "ix86_unary_operator_ok (NEG, HImode, operands)"
9543 "neg{w}\t%0"
9544 [(set_attr "type" "negnot")
9545 (set_attr "mode" "HI")])
9546
9547 (define_expand "negqi2"
9548 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9549 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9550 (clobber (reg:CC FLAGS_REG))])]
9551 "TARGET_QIMODE_MATH"
9552 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9553
9554 (define_insn "*negqi2_1"
9555 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9556 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9557 (clobber (reg:CC FLAGS_REG))]
9558 "ix86_unary_operator_ok (NEG, QImode, operands)"
9559 "neg{b}\t%0"
9560 [(set_attr "type" "negnot")
9561 (set_attr "mode" "QI")])
9562
9563 (define_insn "*negqi2_cmpz"
9564 [(set (reg:CCZ FLAGS_REG)
9565 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9566 (const_int 0)))
9567 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9568 (neg:QI (match_dup 1)))]
9569 "ix86_unary_operator_ok (NEG, QImode, operands)"
9570 "neg{b}\t%0"
9571 [(set_attr "type" "negnot")
9572 (set_attr "mode" "QI")])
9573
9574 ;; Changing of sign for FP values is doable using integer unit too.
9575
9576 (define_expand "negsf2"
9577 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9578 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9579 "TARGET_80387 || TARGET_SSE_MATH"
9580 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9581
9582 (define_expand "abssf2"
9583 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9584 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9585 "TARGET_80387 || TARGET_SSE_MATH"
9586 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9587
9588 (define_insn "*absnegsf2_mixed"
9589 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9590 (match_operator:SF 3 "absneg_operator"
9591 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#fr,0 ,0")]))
9592 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9593 (clobber (reg:CC FLAGS_REG))]
9594 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9595 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9596 "#")
9597
9598 (define_insn "*absnegsf2_sse"
9599 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#r,x#r,rm#x")
9600 (match_operator:SF 3 "absneg_operator"
9601 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#r,0")]))
9602 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X"))
9603 (clobber (reg:CC FLAGS_REG))]
9604 "TARGET_SSE_MATH
9605 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9606 "#")
9607
9608 (define_insn "*absnegsf2_i387"
9609 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9610 (match_operator:SF 3 "absneg_operator"
9611 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9612 (use (match_operand 2 "" ""))
9613 (clobber (reg:CC FLAGS_REG))]
9614 "TARGET_80387 && !TARGET_SSE_MATH
9615 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9616 "#")
9617
9618 (define_expand "negdf2"
9619 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9620 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9621 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9622 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9623
9624 (define_expand "absdf2"
9625 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9626 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9627 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9628 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9629
9630 (define_insn "*absnegdf2_mixed"
9631 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9632 (match_operator:DF 3 "absneg_operator"
9633 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#fr,0 ,0")]))
9634 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9635 (clobber (reg:CC FLAGS_REG))]
9636 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9637 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9638 "#")
9639
9640 (define_insn "*absnegdf2_sse"
9641 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#r,Y#r,rm#Y")
9642 (match_operator:DF 3 "absneg_operator"
9643 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#r,0")]))
9644 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X"))
9645 (clobber (reg:CC FLAGS_REG))]
9646 "TARGET_SSE2 && TARGET_SSE_MATH
9647 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9648 "#")
9649
9650 (define_insn "*absnegdf2_i387"
9651 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9652 (match_operator:DF 3 "absneg_operator"
9653 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9654 (use (match_operand 2 "" ""))
9655 (clobber (reg:CC FLAGS_REG))]
9656 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9657 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9658 "#")
9659
9660 (define_expand "negxf2"
9661 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9662 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9663 "TARGET_80387"
9664 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9665
9666 (define_expand "absxf2"
9667 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9668 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9669 "TARGET_80387"
9670 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9671
9672 (define_insn "*absnegxf2_i387"
9673 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9674 (match_operator:XF 3 "absneg_operator"
9675 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9676 (use (match_operand 2 "" ""))
9677 (clobber (reg:CC FLAGS_REG))]
9678 "TARGET_80387
9679 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9680 "#")
9681
9682 ;; Splitters for fp abs and neg.
9683
9684 (define_split
9685 [(set (match_operand 0 "fp_register_operand" "")
9686 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9687 (use (match_operand 2 "" ""))
9688 (clobber (reg:CC FLAGS_REG))]
9689 "reload_completed"
9690 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9691
9692 (define_split
9693 [(set (match_operand 0 "register_operand" "")
9694 (match_operator 3 "absneg_operator"
9695 [(match_operand 1 "register_operand" "")]))
9696 (use (match_operand 2 "nonimmediate_operand" ""))
9697 (clobber (reg:CC FLAGS_REG))]
9698 "reload_completed && SSE_REG_P (operands[0])"
9699 [(set (match_dup 0) (match_dup 3))]
9700 {
9701 enum machine_mode mode = GET_MODE (operands[0]);
9702 enum machine_mode vmode = GET_MODE (operands[2]);
9703 rtx tmp;
9704
9705 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9706 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9707 if (operands_match_p (operands[0], operands[2]))
9708 {
9709 tmp = operands[1];
9710 operands[1] = operands[2];
9711 operands[2] = tmp;
9712 }
9713 if (GET_CODE (operands[3]) == ABS)
9714 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9715 else
9716 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9717 operands[3] = tmp;
9718 })
9719
9720 (define_split
9721 [(set (match_operand:SF 0 "register_operand" "")
9722 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9723 (use (match_operand:V4SF 2 "" ""))
9724 (clobber (reg:CC FLAGS_REG))]
9725 "reload_completed"
9726 [(parallel [(set (match_dup 0) (match_dup 1))
9727 (clobber (reg:CC FLAGS_REG))])]
9728 {
9729 rtx tmp;
9730 operands[0] = gen_lowpart (SImode, operands[0]);
9731 if (GET_CODE (operands[1]) == ABS)
9732 {
9733 tmp = gen_int_mode (0x7fffffff, SImode);
9734 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9735 }
9736 else
9737 {
9738 tmp = gen_int_mode (0x80000000, SImode);
9739 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9740 }
9741 operands[1] = tmp;
9742 })
9743
9744 (define_split
9745 [(set (match_operand:DF 0 "register_operand" "")
9746 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9747 (use (match_operand 2 "" ""))
9748 (clobber (reg:CC FLAGS_REG))]
9749 "reload_completed"
9750 [(parallel [(set (match_dup 0) (match_dup 1))
9751 (clobber (reg:CC FLAGS_REG))])]
9752 {
9753 rtx tmp;
9754 if (TARGET_64BIT)
9755 {
9756 tmp = gen_lowpart (DImode, operands[0]);
9757 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9758 operands[0] = tmp;
9759
9760 if (GET_CODE (operands[1]) == ABS)
9761 tmp = const0_rtx;
9762 else
9763 tmp = gen_rtx_NOT (DImode, tmp);
9764 }
9765 else
9766 {
9767 operands[0] = gen_highpart (SImode, operands[0]);
9768 if (GET_CODE (operands[1]) == ABS)
9769 {
9770 tmp = gen_int_mode (0x7fffffff, SImode);
9771 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9772 }
9773 else
9774 {
9775 tmp = gen_int_mode (0x80000000, SImode);
9776 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9777 }
9778 }
9779 operands[1] = tmp;
9780 })
9781
9782 (define_split
9783 [(set (match_operand:XF 0 "register_operand" "")
9784 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9785 (use (match_operand 2 "" ""))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "reload_completed"
9788 [(parallel [(set (match_dup 0) (match_dup 1))
9789 (clobber (reg:CC FLAGS_REG))])]
9790 {
9791 rtx tmp;
9792 operands[0] = gen_rtx_REG (SImode,
9793 true_regnum (operands[0])
9794 + (TARGET_64BIT ? 1 : 2));
9795 if (GET_CODE (operands[1]) == ABS)
9796 {
9797 tmp = GEN_INT (0x7fff);
9798 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9799 }
9800 else
9801 {
9802 tmp = GEN_INT (0x8000);
9803 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9804 }
9805 operands[1] = tmp;
9806 })
9807
9808 (define_split
9809 [(set (match_operand 0 "memory_operand" "")
9810 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9811 (use (match_operand 2 "" ""))
9812 (clobber (reg:CC FLAGS_REG))]
9813 "reload_completed"
9814 [(parallel [(set (match_dup 0) (match_dup 1))
9815 (clobber (reg:CC FLAGS_REG))])]
9816 {
9817 enum machine_mode mode = GET_MODE (operands[0]);
9818 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9819 rtx tmp;
9820
9821 operands[0] = adjust_address (operands[0], QImode, size - 1);
9822 if (GET_CODE (operands[1]) == ABS)
9823 {
9824 tmp = gen_int_mode (0x7f, QImode);
9825 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9826 }
9827 else
9828 {
9829 tmp = gen_int_mode (0x80, QImode);
9830 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9831 }
9832 operands[1] = tmp;
9833 })
9834
9835 ;; Conditionalize these after reload. If they match before reload, we
9836 ;; lose the clobber and ability to use integer instructions.
9837
9838 (define_insn "*negsf2_1"
9839 [(set (match_operand:SF 0 "register_operand" "=f")
9840 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9841 "TARGET_80387 && reload_completed"
9842 "fchs"
9843 [(set_attr "type" "fsgn")
9844 (set_attr "mode" "SF")])
9845
9846 (define_insn "*negdf2_1"
9847 [(set (match_operand:DF 0 "register_operand" "=f")
9848 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9849 "TARGET_80387 && reload_completed"
9850 "fchs"
9851 [(set_attr "type" "fsgn")
9852 (set_attr "mode" "DF")])
9853
9854 (define_insn "*negxf2_1"
9855 [(set (match_operand:XF 0 "register_operand" "=f")
9856 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9857 "TARGET_80387 && reload_completed"
9858 "fchs"
9859 [(set_attr "type" "fsgn")
9860 (set_attr "mode" "XF")])
9861
9862 (define_insn "*abssf2_1"
9863 [(set (match_operand:SF 0 "register_operand" "=f")
9864 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9865 "TARGET_80387 && reload_completed"
9866 "fabs"
9867 [(set_attr "type" "fsgn")
9868 (set_attr "mode" "SF")])
9869
9870 (define_insn "*absdf2_1"
9871 [(set (match_operand:DF 0 "register_operand" "=f")
9872 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9873 "TARGET_80387 && reload_completed"
9874 "fabs"
9875 [(set_attr "type" "fsgn")
9876 (set_attr "mode" "DF")])
9877
9878 (define_insn "*absxf2_1"
9879 [(set (match_operand:XF 0 "register_operand" "=f")
9880 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9881 "TARGET_80387 && reload_completed"
9882 "fabs"
9883 [(set_attr "type" "fsgn")
9884 (set_attr "mode" "DF")])
9885
9886 (define_insn "*negextendsfdf2"
9887 [(set (match_operand:DF 0 "register_operand" "=f")
9888 (neg:DF (float_extend:DF
9889 (match_operand:SF 1 "register_operand" "0"))))]
9890 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9891 "fchs"
9892 [(set_attr "type" "fsgn")
9893 (set_attr "mode" "DF")])
9894
9895 (define_insn "*negextenddfxf2"
9896 [(set (match_operand:XF 0 "register_operand" "=f")
9897 (neg:XF (float_extend:XF
9898 (match_operand:DF 1 "register_operand" "0"))))]
9899 "TARGET_80387"
9900 "fchs"
9901 [(set_attr "type" "fsgn")
9902 (set_attr "mode" "XF")])
9903
9904 (define_insn "*negextendsfxf2"
9905 [(set (match_operand:XF 0 "register_operand" "=f")
9906 (neg:XF (float_extend:XF
9907 (match_operand:SF 1 "register_operand" "0"))))]
9908 "TARGET_80387"
9909 "fchs"
9910 [(set_attr "type" "fsgn")
9911 (set_attr "mode" "XF")])
9912
9913 (define_insn "*absextendsfdf2"
9914 [(set (match_operand:DF 0 "register_operand" "=f")
9915 (abs:DF (float_extend:DF
9916 (match_operand:SF 1 "register_operand" "0"))))]
9917 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9918 "fabs"
9919 [(set_attr "type" "fsgn")
9920 (set_attr "mode" "DF")])
9921
9922 (define_insn "*absextenddfxf2"
9923 [(set (match_operand:XF 0 "register_operand" "=f")
9924 (abs:XF (float_extend:XF
9925 (match_operand:DF 1 "register_operand" "0"))))]
9926 "TARGET_80387"
9927 "fabs"
9928 [(set_attr "type" "fsgn")
9929 (set_attr "mode" "XF")])
9930
9931 (define_insn "*absextendsfxf2"
9932 [(set (match_operand:XF 0 "register_operand" "=f")
9933 (abs:XF (float_extend:XF
9934 (match_operand:SF 1 "register_operand" "0"))))]
9935 "TARGET_80387"
9936 "fabs"
9937 [(set_attr "type" "fsgn")
9938 (set_attr "mode" "XF")])
9939 \f
9940 ;; One complement instructions
9941
9942 (define_expand "one_cmpldi2"
9943 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9944 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9945 "TARGET_64BIT"
9946 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9947
9948 (define_insn "*one_cmpldi2_1_rex64"
9949 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9950 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9951 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9952 "not{q}\t%0"
9953 [(set_attr "type" "negnot")
9954 (set_attr "mode" "DI")])
9955
9956 (define_insn "*one_cmpldi2_2_rex64"
9957 [(set (reg FLAGS_REG)
9958 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9959 (const_int 0)))
9960 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9961 (not:DI (match_dup 1)))]
9962 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9963 && ix86_unary_operator_ok (NOT, DImode, operands)"
9964 "#"
9965 [(set_attr "type" "alu1")
9966 (set_attr "mode" "DI")])
9967
9968 (define_split
9969 [(set (match_operand 0 "flags_reg_operand" "")
9970 (match_operator 2 "compare_operator"
9971 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9972 (const_int 0)]))
9973 (set (match_operand:DI 1 "nonimmediate_operand" "")
9974 (not:DI (match_dup 3)))]
9975 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9976 [(parallel [(set (match_dup 0)
9977 (match_op_dup 2
9978 [(xor:DI (match_dup 3) (const_int -1))
9979 (const_int 0)]))
9980 (set (match_dup 1)
9981 (xor:DI (match_dup 3) (const_int -1)))])]
9982 "")
9983
9984 (define_expand "one_cmplsi2"
9985 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9986 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9987 ""
9988 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9989
9990 (define_insn "*one_cmplsi2_1"
9991 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9992 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9993 "ix86_unary_operator_ok (NOT, SImode, operands)"
9994 "not{l}\t%0"
9995 [(set_attr "type" "negnot")
9996 (set_attr "mode" "SI")])
9997
9998 ;; ??? Currently never generated - xor is used instead.
9999 (define_insn "*one_cmplsi2_1_zext"
10000 [(set (match_operand:DI 0 "register_operand" "=r")
10001 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10002 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10003 "not{l}\t%k0"
10004 [(set_attr "type" "negnot")
10005 (set_attr "mode" "SI")])
10006
10007 (define_insn "*one_cmplsi2_2"
10008 [(set (reg FLAGS_REG)
10009 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10010 (const_int 0)))
10011 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10012 (not:SI (match_dup 1)))]
10013 "ix86_match_ccmode (insn, CCNOmode)
10014 && ix86_unary_operator_ok (NOT, SImode, operands)"
10015 "#"
10016 [(set_attr "type" "alu1")
10017 (set_attr "mode" "SI")])
10018
10019 (define_split
10020 [(set (match_operand 0 "flags_reg_operand" "")
10021 (match_operator 2 "compare_operator"
10022 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10023 (const_int 0)]))
10024 (set (match_operand:SI 1 "nonimmediate_operand" "")
10025 (not:SI (match_dup 3)))]
10026 "ix86_match_ccmode (insn, CCNOmode)"
10027 [(parallel [(set (match_dup 0)
10028 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10029 (const_int 0)]))
10030 (set (match_dup 1)
10031 (xor:SI (match_dup 3) (const_int -1)))])]
10032 "")
10033
10034 ;; ??? Currently never generated - xor is used instead.
10035 (define_insn "*one_cmplsi2_2_zext"
10036 [(set (reg FLAGS_REG)
10037 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10038 (const_int 0)))
10039 (set (match_operand:DI 0 "register_operand" "=r")
10040 (zero_extend:DI (not:SI (match_dup 1))))]
10041 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10042 && ix86_unary_operator_ok (NOT, SImode, operands)"
10043 "#"
10044 [(set_attr "type" "alu1")
10045 (set_attr "mode" "SI")])
10046
10047 (define_split
10048 [(set (match_operand 0 "flags_reg_operand" "")
10049 (match_operator 2 "compare_operator"
10050 [(not:SI (match_operand:SI 3 "register_operand" ""))
10051 (const_int 0)]))
10052 (set (match_operand:DI 1 "register_operand" "")
10053 (zero_extend:DI (not:SI (match_dup 3))))]
10054 "ix86_match_ccmode (insn, CCNOmode)"
10055 [(parallel [(set (match_dup 0)
10056 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10057 (const_int 0)]))
10058 (set (match_dup 1)
10059 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10060 "")
10061
10062 (define_expand "one_cmplhi2"
10063 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10064 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10065 "TARGET_HIMODE_MATH"
10066 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10067
10068 (define_insn "*one_cmplhi2_1"
10069 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10070 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10071 "ix86_unary_operator_ok (NOT, HImode, operands)"
10072 "not{w}\t%0"
10073 [(set_attr "type" "negnot")
10074 (set_attr "mode" "HI")])
10075
10076 (define_insn "*one_cmplhi2_2"
10077 [(set (reg FLAGS_REG)
10078 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10079 (const_int 0)))
10080 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10081 (not:HI (match_dup 1)))]
10082 "ix86_match_ccmode (insn, CCNOmode)
10083 && ix86_unary_operator_ok (NEG, HImode, operands)"
10084 "#"
10085 [(set_attr "type" "alu1")
10086 (set_attr "mode" "HI")])
10087
10088 (define_split
10089 [(set (match_operand 0 "flags_reg_operand" "")
10090 (match_operator 2 "compare_operator"
10091 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10092 (const_int 0)]))
10093 (set (match_operand:HI 1 "nonimmediate_operand" "")
10094 (not:HI (match_dup 3)))]
10095 "ix86_match_ccmode (insn, CCNOmode)"
10096 [(parallel [(set (match_dup 0)
10097 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10098 (const_int 0)]))
10099 (set (match_dup 1)
10100 (xor:HI (match_dup 3) (const_int -1)))])]
10101 "")
10102
10103 ;; %%% Potential partial reg stall on alternative 1. What to do?
10104 (define_expand "one_cmplqi2"
10105 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10106 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10107 "TARGET_QIMODE_MATH"
10108 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10109
10110 (define_insn "*one_cmplqi2_1"
10111 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10112 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10113 "ix86_unary_operator_ok (NOT, QImode, operands)"
10114 "@
10115 not{b}\t%0
10116 not{l}\t%k0"
10117 [(set_attr "type" "negnot")
10118 (set_attr "mode" "QI,SI")])
10119
10120 (define_insn "*one_cmplqi2_2"
10121 [(set (reg FLAGS_REG)
10122 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10123 (const_int 0)))
10124 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10125 (not:QI (match_dup 1)))]
10126 "ix86_match_ccmode (insn, CCNOmode)
10127 && ix86_unary_operator_ok (NOT, QImode, operands)"
10128 "#"
10129 [(set_attr "type" "alu1")
10130 (set_attr "mode" "QI")])
10131
10132 (define_split
10133 [(set (match_operand 0 "flags_reg_operand" "")
10134 (match_operator 2 "compare_operator"
10135 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10136 (const_int 0)]))
10137 (set (match_operand:QI 1 "nonimmediate_operand" "")
10138 (not:QI (match_dup 3)))]
10139 "ix86_match_ccmode (insn, CCNOmode)"
10140 [(parallel [(set (match_dup 0)
10141 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10142 (const_int 0)]))
10143 (set (match_dup 1)
10144 (xor:QI (match_dup 3) (const_int -1)))])]
10145 "")
10146 \f
10147 ;; Arithmetic shift instructions
10148
10149 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10150 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10151 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10152 ;; from the assembler input.
10153 ;;
10154 ;; This instruction shifts the target reg/mem as usual, but instead of
10155 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10156 ;; is a left shift double, bits are taken from the high order bits of
10157 ;; reg, else if the insn is a shift right double, bits are taken from the
10158 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10159 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10160 ;;
10161 ;; Since sh[lr]d does not change the `reg' operand, that is done
10162 ;; separately, making all shifts emit pairs of shift double and normal
10163 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10164 ;; support a 63 bit shift, each shift where the count is in a reg expands
10165 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10166 ;;
10167 ;; If the shift count is a constant, we need never emit more than one
10168 ;; shift pair, instead using moves and sign extension for counts greater
10169 ;; than 31.
10170
10171 (define_expand "ashldi3"
10172 [(set (match_operand:DI 0 "shiftdi_operand" "")
10173 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10174 (match_operand:QI 2 "nonmemory_operand" "")))]
10175 ""
10176 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10177
10178 (define_insn "*ashldi3_1_rex64"
10179 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10180 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10181 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10182 (clobber (reg:CC FLAGS_REG))]
10183 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10184 {
10185 switch (get_attr_type (insn))
10186 {
10187 case TYPE_ALU:
10188 if (operands[2] != const1_rtx)
10189 abort ();
10190 if (!rtx_equal_p (operands[0], operands[1]))
10191 abort ();
10192 return "add{q}\t{%0, %0|%0, %0}";
10193
10194 case TYPE_LEA:
10195 if (GET_CODE (operands[2]) != CONST_INT
10196 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10197 abort ();
10198 operands[1] = gen_rtx_MULT (DImode, operands[1],
10199 GEN_INT (1 << INTVAL (operands[2])));
10200 return "lea{q}\t{%a1, %0|%0, %a1}";
10201
10202 default:
10203 if (REG_P (operands[2]))
10204 return "sal{q}\t{%b2, %0|%0, %b2}";
10205 else if (operands[2] == const1_rtx
10206 && (TARGET_SHIFT1 || optimize_size))
10207 return "sal{q}\t%0";
10208 else
10209 return "sal{q}\t{%2, %0|%0, %2}";
10210 }
10211 }
10212 [(set (attr "type")
10213 (cond [(eq_attr "alternative" "1")
10214 (const_string "lea")
10215 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10216 (const_int 0))
10217 (match_operand 0 "register_operand" ""))
10218 (match_operand 2 "const1_operand" ""))
10219 (const_string "alu")
10220 ]
10221 (const_string "ishift")))
10222 (set_attr "mode" "DI")])
10223
10224 ;; Convert lea to the lea pattern to avoid flags dependency.
10225 (define_split
10226 [(set (match_operand:DI 0 "register_operand" "")
10227 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10228 (match_operand:QI 2 "immediate_operand" "")))
10229 (clobber (reg:CC FLAGS_REG))]
10230 "TARGET_64BIT && reload_completed
10231 && true_regnum (operands[0]) != true_regnum (operands[1])"
10232 [(set (match_dup 0)
10233 (mult:DI (match_dup 1)
10234 (match_dup 2)))]
10235 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10236
10237 ;; This pattern can't accept a variable shift count, since shifts by
10238 ;; zero don't affect the flags. We assume that shifts by constant
10239 ;; zero are optimized away.
10240 (define_insn "*ashldi3_cmp_rex64"
10241 [(set (reg FLAGS_REG)
10242 (compare
10243 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10244 (match_operand:QI 2 "immediate_operand" "e"))
10245 (const_int 0)))
10246 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10247 (ashift:DI (match_dup 1) (match_dup 2)))]
10248 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10249 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10250 {
10251 switch (get_attr_type (insn))
10252 {
10253 case TYPE_ALU:
10254 if (operands[2] != const1_rtx)
10255 abort ();
10256 return "add{q}\t{%0, %0|%0, %0}";
10257
10258 default:
10259 if (REG_P (operands[2]))
10260 return "sal{q}\t{%b2, %0|%0, %b2}";
10261 else if (operands[2] == const1_rtx
10262 && (TARGET_SHIFT1 || optimize_size))
10263 return "sal{q}\t%0";
10264 else
10265 return "sal{q}\t{%2, %0|%0, %2}";
10266 }
10267 }
10268 [(set (attr "type")
10269 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10270 (const_int 0))
10271 (match_operand 0 "register_operand" ""))
10272 (match_operand 2 "const1_operand" ""))
10273 (const_string "alu")
10274 ]
10275 (const_string "ishift")))
10276 (set_attr "mode" "DI")])
10277
10278 (define_insn "*ashldi3_1"
10279 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10280 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10281 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10282 (clobber (reg:CC FLAGS_REG))]
10283 "!TARGET_64BIT"
10284 "#"
10285 [(set_attr "type" "multi")])
10286
10287 ;; By default we don't ask for a scratch register, because when DImode
10288 ;; values are manipulated, registers are already at a premium. But if
10289 ;; we have one handy, we won't turn it away.
10290 (define_peephole2
10291 [(match_scratch:SI 3 "r")
10292 (parallel [(set (match_operand:DI 0 "register_operand" "")
10293 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10294 (match_operand:QI 2 "nonmemory_operand" "")))
10295 (clobber (reg:CC FLAGS_REG))])
10296 (match_dup 3)]
10297 "!TARGET_64BIT && TARGET_CMOVE"
10298 [(const_int 0)]
10299 "ix86_split_ashldi (operands, operands[3]); DONE;")
10300
10301 (define_split
10302 [(set (match_operand:DI 0 "register_operand" "")
10303 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10304 (match_operand:QI 2 "nonmemory_operand" "")))
10305 (clobber (reg:CC FLAGS_REG))]
10306 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10307 [(const_int 0)]
10308 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10309
10310 (define_insn "x86_shld_1"
10311 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10312 (ior:SI (ashift:SI (match_dup 0)
10313 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10314 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10315 (minus:QI (const_int 32) (match_dup 2)))))
10316 (clobber (reg:CC FLAGS_REG))]
10317 ""
10318 "@
10319 shld{l}\t{%2, %1, %0|%0, %1, %2}
10320 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10321 [(set_attr "type" "ishift")
10322 (set_attr "prefix_0f" "1")
10323 (set_attr "mode" "SI")
10324 (set_attr "pent_pair" "np")
10325 (set_attr "athlon_decode" "vector")])
10326
10327 (define_expand "x86_shift_adj_1"
10328 [(set (reg:CCZ FLAGS_REG)
10329 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10330 (const_int 32))
10331 (const_int 0)))
10332 (set (match_operand:SI 0 "register_operand" "")
10333 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10334 (match_operand:SI 1 "register_operand" "")
10335 (match_dup 0)))
10336 (set (match_dup 1)
10337 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10338 (match_operand:SI 3 "register_operand" "r")
10339 (match_dup 1)))]
10340 "TARGET_CMOVE"
10341 "")
10342
10343 (define_expand "x86_shift_adj_2"
10344 [(use (match_operand:SI 0 "register_operand" ""))
10345 (use (match_operand:SI 1 "register_operand" ""))
10346 (use (match_operand:QI 2 "register_operand" ""))]
10347 ""
10348 {
10349 rtx label = gen_label_rtx ();
10350 rtx tmp;
10351
10352 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10353
10354 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10355 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10356 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10357 gen_rtx_LABEL_REF (VOIDmode, label),
10358 pc_rtx);
10359 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10360 JUMP_LABEL (tmp) = label;
10361
10362 emit_move_insn (operands[0], operands[1]);
10363 ix86_expand_clear (operands[1]);
10364
10365 emit_label (label);
10366 LABEL_NUSES (label) = 1;
10367
10368 DONE;
10369 })
10370
10371 (define_expand "ashlsi3"
10372 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10373 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10374 (match_operand:QI 2 "nonmemory_operand" "")))
10375 (clobber (reg:CC FLAGS_REG))]
10376 ""
10377 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10378
10379 (define_insn "*ashlsi3_1"
10380 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10381 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10382 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10383 (clobber (reg:CC FLAGS_REG))]
10384 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10385 {
10386 switch (get_attr_type (insn))
10387 {
10388 case TYPE_ALU:
10389 if (operands[2] != const1_rtx)
10390 abort ();
10391 if (!rtx_equal_p (operands[0], operands[1]))
10392 abort ();
10393 return "add{l}\t{%0, %0|%0, %0}";
10394
10395 case TYPE_LEA:
10396 return "#";
10397
10398 default:
10399 if (REG_P (operands[2]))
10400 return "sal{l}\t{%b2, %0|%0, %b2}";
10401 else if (operands[2] == const1_rtx
10402 && (TARGET_SHIFT1 || optimize_size))
10403 return "sal{l}\t%0";
10404 else
10405 return "sal{l}\t{%2, %0|%0, %2}";
10406 }
10407 }
10408 [(set (attr "type")
10409 (cond [(eq_attr "alternative" "1")
10410 (const_string "lea")
10411 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10412 (const_int 0))
10413 (match_operand 0 "register_operand" ""))
10414 (match_operand 2 "const1_operand" ""))
10415 (const_string "alu")
10416 ]
10417 (const_string "ishift")))
10418 (set_attr "mode" "SI")])
10419
10420 ;; Convert lea to the lea pattern to avoid flags dependency.
10421 (define_split
10422 [(set (match_operand 0 "register_operand" "")
10423 (ashift (match_operand 1 "index_register_operand" "")
10424 (match_operand:QI 2 "const_int_operand" "")))
10425 (clobber (reg:CC FLAGS_REG))]
10426 "reload_completed
10427 && true_regnum (operands[0]) != true_regnum (operands[1])
10428 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10429 [(const_int 0)]
10430 {
10431 rtx pat;
10432 enum machine_mode mode = GET_MODE (operands[0]);
10433
10434 if (GET_MODE_SIZE (mode) < 4)
10435 operands[0] = gen_lowpart (SImode, operands[0]);
10436 if (mode != Pmode)
10437 operands[1] = gen_lowpart (Pmode, operands[1]);
10438 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10439
10440 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10441 if (Pmode != SImode)
10442 pat = gen_rtx_SUBREG (SImode, pat, 0);
10443 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10444 DONE;
10445 })
10446
10447 ;; Rare case of shifting RSP is handled by generating move and shift
10448 (define_split
10449 [(set (match_operand 0 "register_operand" "")
10450 (ashift (match_operand 1 "register_operand" "")
10451 (match_operand:QI 2 "const_int_operand" "")))
10452 (clobber (reg:CC FLAGS_REG))]
10453 "reload_completed
10454 && true_regnum (operands[0]) != true_regnum (operands[1])"
10455 [(const_int 0)]
10456 {
10457 rtx pat, clob;
10458 emit_move_insn (operands[1], operands[0]);
10459 pat = gen_rtx_SET (VOIDmode, operands[0],
10460 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10461 operands[0], operands[2]));
10462 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10463 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10464 DONE;
10465 })
10466
10467 (define_insn "*ashlsi3_1_zext"
10468 [(set (match_operand:DI 0 "register_operand" "=r,r")
10469 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10470 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10471 (clobber (reg:CC FLAGS_REG))]
10472 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10473 {
10474 switch (get_attr_type (insn))
10475 {
10476 case TYPE_ALU:
10477 if (operands[2] != const1_rtx)
10478 abort ();
10479 return "add{l}\t{%k0, %k0|%k0, %k0}";
10480
10481 case TYPE_LEA:
10482 return "#";
10483
10484 default:
10485 if (REG_P (operands[2]))
10486 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10487 else if (operands[2] == const1_rtx
10488 && (TARGET_SHIFT1 || optimize_size))
10489 return "sal{l}\t%k0";
10490 else
10491 return "sal{l}\t{%2, %k0|%k0, %2}";
10492 }
10493 }
10494 [(set (attr "type")
10495 (cond [(eq_attr "alternative" "1")
10496 (const_string "lea")
10497 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10498 (const_int 0))
10499 (match_operand 2 "const1_operand" ""))
10500 (const_string "alu")
10501 ]
10502 (const_string "ishift")))
10503 (set_attr "mode" "SI")])
10504
10505 ;; Convert lea to the lea pattern to avoid flags dependency.
10506 (define_split
10507 [(set (match_operand:DI 0 "register_operand" "")
10508 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10509 (match_operand:QI 2 "const_int_operand" ""))))
10510 (clobber (reg:CC FLAGS_REG))]
10511 "TARGET_64BIT && reload_completed
10512 && true_regnum (operands[0]) != true_regnum (operands[1])"
10513 [(set (match_dup 0) (zero_extend:DI
10514 (subreg:SI (mult:SI (match_dup 1)
10515 (match_dup 2)) 0)))]
10516 {
10517 operands[1] = gen_lowpart (Pmode, operands[1]);
10518 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10519 })
10520
10521 ;; This pattern can't accept a variable shift count, since shifts by
10522 ;; zero don't affect the flags. We assume that shifts by constant
10523 ;; zero are optimized away.
10524 (define_insn "*ashlsi3_cmp"
10525 [(set (reg FLAGS_REG)
10526 (compare
10527 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10528 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10529 (const_int 0)))
10530 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10531 (ashift:SI (match_dup 1) (match_dup 2)))]
10532 "ix86_match_ccmode (insn, CCGOCmode)
10533 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10534 {
10535 switch (get_attr_type (insn))
10536 {
10537 case TYPE_ALU:
10538 if (operands[2] != const1_rtx)
10539 abort ();
10540 return "add{l}\t{%0, %0|%0, %0}";
10541
10542 default:
10543 if (REG_P (operands[2]))
10544 return "sal{l}\t{%b2, %0|%0, %b2}";
10545 else if (operands[2] == const1_rtx
10546 && (TARGET_SHIFT1 || optimize_size))
10547 return "sal{l}\t%0";
10548 else
10549 return "sal{l}\t{%2, %0|%0, %2}";
10550 }
10551 }
10552 [(set (attr "type")
10553 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10554 (const_int 0))
10555 (match_operand 0 "register_operand" ""))
10556 (match_operand 2 "const1_operand" ""))
10557 (const_string "alu")
10558 ]
10559 (const_string "ishift")))
10560 (set_attr "mode" "SI")])
10561
10562 (define_insn "*ashlsi3_cmp_zext"
10563 [(set (reg FLAGS_REG)
10564 (compare
10565 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10566 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10567 (const_int 0)))
10568 (set (match_operand:DI 0 "register_operand" "=r")
10569 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10570 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10571 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10572 {
10573 switch (get_attr_type (insn))
10574 {
10575 case TYPE_ALU:
10576 if (operands[2] != const1_rtx)
10577 abort ();
10578 return "add{l}\t{%k0, %k0|%k0, %k0}";
10579
10580 default:
10581 if (REG_P (operands[2]))
10582 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10583 else if (operands[2] == const1_rtx
10584 && (TARGET_SHIFT1 || optimize_size))
10585 return "sal{l}\t%k0";
10586 else
10587 return "sal{l}\t{%2, %k0|%k0, %2}";
10588 }
10589 }
10590 [(set (attr "type")
10591 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10592 (const_int 0))
10593 (match_operand 2 "const1_operand" ""))
10594 (const_string "alu")
10595 ]
10596 (const_string "ishift")))
10597 (set_attr "mode" "SI")])
10598
10599 (define_expand "ashlhi3"
10600 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10601 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10602 (match_operand:QI 2 "nonmemory_operand" "")))
10603 (clobber (reg:CC FLAGS_REG))]
10604 "TARGET_HIMODE_MATH"
10605 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10606
10607 (define_insn "*ashlhi3_1_lea"
10608 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10609 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10610 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10611 (clobber (reg:CC FLAGS_REG))]
10612 "!TARGET_PARTIAL_REG_STALL
10613 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10614 {
10615 switch (get_attr_type (insn))
10616 {
10617 case TYPE_LEA:
10618 return "#";
10619 case TYPE_ALU:
10620 if (operands[2] != const1_rtx)
10621 abort ();
10622 return "add{w}\t{%0, %0|%0, %0}";
10623
10624 default:
10625 if (REG_P (operands[2]))
10626 return "sal{w}\t{%b2, %0|%0, %b2}";
10627 else if (operands[2] == const1_rtx
10628 && (TARGET_SHIFT1 || optimize_size))
10629 return "sal{w}\t%0";
10630 else
10631 return "sal{w}\t{%2, %0|%0, %2}";
10632 }
10633 }
10634 [(set (attr "type")
10635 (cond [(eq_attr "alternative" "1")
10636 (const_string "lea")
10637 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10638 (const_int 0))
10639 (match_operand 0 "register_operand" ""))
10640 (match_operand 2 "const1_operand" ""))
10641 (const_string "alu")
10642 ]
10643 (const_string "ishift")))
10644 (set_attr "mode" "HI,SI")])
10645
10646 (define_insn "*ashlhi3_1"
10647 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10648 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10649 (match_operand:QI 2 "nonmemory_operand" "cI")))
10650 (clobber (reg:CC FLAGS_REG))]
10651 "TARGET_PARTIAL_REG_STALL
10652 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10653 {
10654 switch (get_attr_type (insn))
10655 {
10656 case TYPE_ALU:
10657 if (operands[2] != const1_rtx)
10658 abort ();
10659 return "add{w}\t{%0, %0|%0, %0}";
10660
10661 default:
10662 if (REG_P (operands[2]))
10663 return "sal{w}\t{%b2, %0|%0, %b2}";
10664 else if (operands[2] == const1_rtx
10665 && (TARGET_SHIFT1 || optimize_size))
10666 return "sal{w}\t%0";
10667 else
10668 return "sal{w}\t{%2, %0|%0, %2}";
10669 }
10670 }
10671 [(set (attr "type")
10672 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10673 (const_int 0))
10674 (match_operand 0 "register_operand" ""))
10675 (match_operand 2 "const1_operand" ""))
10676 (const_string "alu")
10677 ]
10678 (const_string "ishift")))
10679 (set_attr "mode" "HI")])
10680
10681 ;; This pattern can't accept a variable shift count, since shifts by
10682 ;; zero don't affect the flags. We assume that shifts by constant
10683 ;; zero are optimized away.
10684 (define_insn "*ashlhi3_cmp"
10685 [(set (reg FLAGS_REG)
10686 (compare
10687 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10688 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10689 (const_int 0)))
10690 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10691 (ashift:HI (match_dup 1) (match_dup 2)))]
10692 "ix86_match_ccmode (insn, CCGOCmode)
10693 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10694 {
10695 switch (get_attr_type (insn))
10696 {
10697 case TYPE_ALU:
10698 if (operands[2] != const1_rtx)
10699 abort ();
10700 return "add{w}\t{%0, %0|%0, %0}";
10701
10702 default:
10703 if (REG_P (operands[2]))
10704 return "sal{w}\t{%b2, %0|%0, %b2}";
10705 else if (operands[2] == const1_rtx
10706 && (TARGET_SHIFT1 || optimize_size))
10707 return "sal{w}\t%0";
10708 else
10709 return "sal{w}\t{%2, %0|%0, %2}";
10710 }
10711 }
10712 [(set (attr "type")
10713 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10714 (const_int 0))
10715 (match_operand 0 "register_operand" ""))
10716 (match_operand 2 "const1_operand" ""))
10717 (const_string "alu")
10718 ]
10719 (const_string "ishift")))
10720 (set_attr "mode" "HI")])
10721
10722 (define_expand "ashlqi3"
10723 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10724 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10725 (match_operand:QI 2 "nonmemory_operand" "")))
10726 (clobber (reg:CC FLAGS_REG))]
10727 "TARGET_QIMODE_MATH"
10728 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10729
10730 ;; %%% Potential partial reg stall on alternative 2. What to do?
10731
10732 (define_insn "*ashlqi3_1_lea"
10733 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10734 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10735 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10736 (clobber (reg:CC FLAGS_REG))]
10737 "!TARGET_PARTIAL_REG_STALL
10738 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10739 {
10740 switch (get_attr_type (insn))
10741 {
10742 case TYPE_LEA:
10743 return "#";
10744 case TYPE_ALU:
10745 if (operands[2] != const1_rtx)
10746 abort ();
10747 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10748 return "add{l}\t{%k0, %k0|%k0, %k0}";
10749 else
10750 return "add{b}\t{%0, %0|%0, %0}";
10751
10752 default:
10753 if (REG_P (operands[2]))
10754 {
10755 if (get_attr_mode (insn) == MODE_SI)
10756 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10757 else
10758 return "sal{b}\t{%b2, %0|%0, %b2}";
10759 }
10760 else if (operands[2] == const1_rtx
10761 && (TARGET_SHIFT1 || optimize_size))
10762 {
10763 if (get_attr_mode (insn) == MODE_SI)
10764 return "sal{l}\t%0";
10765 else
10766 return "sal{b}\t%0";
10767 }
10768 else
10769 {
10770 if (get_attr_mode (insn) == MODE_SI)
10771 return "sal{l}\t{%2, %k0|%k0, %2}";
10772 else
10773 return "sal{b}\t{%2, %0|%0, %2}";
10774 }
10775 }
10776 }
10777 [(set (attr "type")
10778 (cond [(eq_attr "alternative" "2")
10779 (const_string "lea")
10780 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10781 (const_int 0))
10782 (match_operand 0 "register_operand" ""))
10783 (match_operand 2 "const1_operand" ""))
10784 (const_string "alu")
10785 ]
10786 (const_string "ishift")))
10787 (set_attr "mode" "QI,SI,SI")])
10788
10789 (define_insn "*ashlqi3_1"
10790 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10791 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10792 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10793 (clobber (reg:CC FLAGS_REG))]
10794 "TARGET_PARTIAL_REG_STALL
10795 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10796 {
10797 switch (get_attr_type (insn))
10798 {
10799 case TYPE_ALU:
10800 if (operands[2] != const1_rtx)
10801 abort ();
10802 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10803 return "add{l}\t{%k0, %k0|%k0, %k0}";
10804 else
10805 return "add{b}\t{%0, %0|%0, %0}";
10806
10807 default:
10808 if (REG_P (operands[2]))
10809 {
10810 if (get_attr_mode (insn) == MODE_SI)
10811 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10812 else
10813 return "sal{b}\t{%b2, %0|%0, %b2}";
10814 }
10815 else if (operands[2] == const1_rtx
10816 && (TARGET_SHIFT1 || optimize_size))
10817 {
10818 if (get_attr_mode (insn) == MODE_SI)
10819 return "sal{l}\t%0";
10820 else
10821 return "sal{b}\t%0";
10822 }
10823 else
10824 {
10825 if (get_attr_mode (insn) == MODE_SI)
10826 return "sal{l}\t{%2, %k0|%k0, %2}";
10827 else
10828 return "sal{b}\t{%2, %0|%0, %2}";
10829 }
10830 }
10831 }
10832 [(set (attr "type")
10833 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10834 (const_int 0))
10835 (match_operand 0 "register_operand" ""))
10836 (match_operand 2 "const1_operand" ""))
10837 (const_string "alu")
10838 ]
10839 (const_string "ishift")))
10840 (set_attr "mode" "QI,SI")])
10841
10842 ;; This pattern can't accept a variable shift count, since shifts by
10843 ;; zero don't affect the flags. We assume that shifts by constant
10844 ;; zero are optimized away.
10845 (define_insn "*ashlqi3_cmp"
10846 [(set (reg FLAGS_REG)
10847 (compare
10848 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10849 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10850 (const_int 0)))
10851 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10852 (ashift:QI (match_dup 1) (match_dup 2)))]
10853 "ix86_match_ccmode (insn, CCGOCmode)
10854 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10855 {
10856 switch (get_attr_type (insn))
10857 {
10858 case TYPE_ALU:
10859 if (operands[2] != const1_rtx)
10860 abort ();
10861 return "add{b}\t{%0, %0|%0, %0}";
10862
10863 default:
10864 if (REG_P (operands[2]))
10865 return "sal{b}\t{%b2, %0|%0, %b2}";
10866 else if (operands[2] == const1_rtx
10867 && (TARGET_SHIFT1 || optimize_size))
10868 return "sal{b}\t%0";
10869 else
10870 return "sal{b}\t{%2, %0|%0, %2}";
10871 }
10872 }
10873 [(set (attr "type")
10874 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10875 (const_int 0))
10876 (match_operand 0 "register_operand" ""))
10877 (match_operand 2 "const1_operand" ""))
10878 (const_string "alu")
10879 ]
10880 (const_string "ishift")))
10881 (set_attr "mode" "QI")])
10882
10883 ;; See comment above `ashldi3' about how this works.
10884
10885 (define_expand "ashrdi3"
10886 [(set (match_operand:DI 0 "shiftdi_operand" "")
10887 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10888 (match_operand:QI 2 "nonmemory_operand" "")))]
10889 ""
10890 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10891
10892 (define_insn "*ashrdi3_63_rex64"
10893 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10894 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10895 (match_operand:DI 2 "const_int_operand" "i,i")))
10896 (clobber (reg:CC FLAGS_REG))]
10897 "TARGET_64BIT && INTVAL (operands[2]) == 63
10898 && (TARGET_USE_CLTD || optimize_size)
10899 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10900 "@
10901 {cqto|cqo}
10902 sar{q}\t{%2, %0|%0, %2}"
10903 [(set_attr "type" "imovx,ishift")
10904 (set_attr "prefix_0f" "0,*")
10905 (set_attr "length_immediate" "0,*")
10906 (set_attr "modrm" "0,1")
10907 (set_attr "mode" "DI")])
10908
10909 (define_insn "*ashrdi3_1_one_bit_rex64"
10910 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10911 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10912 (match_operand:QI 2 "const1_operand" "")))
10913 (clobber (reg:CC FLAGS_REG))]
10914 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10915 && (TARGET_SHIFT1 || optimize_size)"
10916 "sar{q}\t%0"
10917 [(set_attr "type" "ishift")
10918 (set (attr "length")
10919 (if_then_else (match_operand:DI 0 "register_operand" "")
10920 (const_string "2")
10921 (const_string "*")))])
10922
10923 (define_insn "*ashrdi3_1_rex64"
10924 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10925 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10926 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10927 (clobber (reg:CC FLAGS_REG))]
10928 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10929 "@
10930 sar{q}\t{%2, %0|%0, %2}
10931 sar{q}\t{%b2, %0|%0, %b2}"
10932 [(set_attr "type" "ishift")
10933 (set_attr "mode" "DI")])
10934
10935 ;; This pattern can't accept a variable shift count, since shifts by
10936 ;; zero don't affect the flags. We assume that shifts by constant
10937 ;; zero are optimized away.
10938 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10939 [(set (reg FLAGS_REG)
10940 (compare
10941 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10942 (match_operand:QI 2 "const1_operand" ""))
10943 (const_int 0)))
10944 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10945 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10946 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10947 && (TARGET_SHIFT1 || optimize_size)
10948 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10949 "sar{q}\t%0"
10950 [(set_attr "type" "ishift")
10951 (set (attr "length")
10952 (if_then_else (match_operand:DI 0 "register_operand" "")
10953 (const_string "2")
10954 (const_string "*")))])
10955
10956 ;; This pattern can't accept a variable shift count, since shifts by
10957 ;; zero don't affect the flags. We assume that shifts by constant
10958 ;; zero are optimized away.
10959 (define_insn "*ashrdi3_cmp_rex64"
10960 [(set (reg FLAGS_REG)
10961 (compare
10962 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10963 (match_operand:QI 2 "const_int_operand" "n"))
10964 (const_int 0)))
10965 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10966 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10967 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10968 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10969 "sar{q}\t{%2, %0|%0, %2}"
10970 [(set_attr "type" "ishift")
10971 (set_attr "mode" "DI")])
10972
10973 (define_insn "*ashrdi3_1"
10974 [(set (match_operand:DI 0 "register_operand" "=r")
10975 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10976 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10977 (clobber (reg:CC FLAGS_REG))]
10978 "!TARGET_64BIT"
10979 "#"
10980 [(set_attr "type" "multi")])
10981
10982 ;; By default we don't ask for a scratch register, because when DImode
10983 ;; values are manipulated, registers are already at a premium. But if
10984 ;; we have one handy, we won't turn it away.
10985 (define_peephole2
10986 [(match_scratch:SI 3 "r")
10987 (parallel [(set (match_operand:DI 0 "register_operand" "")
10988 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10989 (match_operand:QI 2 "nonmemory_operand" "")))
10990 (clobber (reg:CC FLAGS_REG))])
10991 (match_dup 3)]
10992 "!TARGET_64BIT && TARGET_CMOVE"
10993 [(const_int 0)]
10994 "ix86_split_ashrdi (operands, operands[3]); DONE;")
10995
10996 (define_split
10997 [(set (match_operand:DI 0 "register_operand" "")
10998 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10999 (match_operand:QI 2 "nonmemory_operand" "")))
11000 (clobber (reg:CC FLAGS_REG))]
11001 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11002 [(const_int 0)]
11003 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11004
11005 (define_insn "x86_shrd_1"
11006 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11007 (ior:SI (ashiftrt:SI (match_dup 0)
11008 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11009 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11010 (minus:QI (const_int 32) (match_dup 2)))))
11011 (clobber (reg:CC FLAGS_REG))]
11012 ""
11013 "@
11014 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11015 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11016 [(set_attr "type" "ishift")
11017 (set_attr "prefix_0f" "1")
11018 (set_attr "pent_pair" "np")
11019 (set_attr "mode" "SI")])
11020
11021 (define_expand "x86_shift_adj_3"
11022 [(use (match_operand:SI 0 "register_operand" ""))
11023 (use (match_operand:SI 1 "register_operand" ""))
11024 (use (match_operand:QI 2 "register_operand" ""))]
11025 ""
11026 {
11027 rtx label = gen_label_rtx ();
11028 rtx tmp;
11029
11030 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11031
11032 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11033 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11034 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11035 gen_rtx_LABEL_REF (VOIDmode, label),
11036 pc_rtx);
11037 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11038 JUMP_LABEL (tmp) = label;
11039
11040 emit_move_insn (operands[0], operands[1]);
11041 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11042
11043 emit_label (label);
11044 LABEL_NUSES (label) = 1;
11045
11046 DONE;
11047 })
11048
11049 (define_insn "ashrsi3_31"
11050 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11051 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11052 (match_operand:SI 2 "const_int_operand" "i,i")))
11053 (clobber (reg:CC FLAGS_REG))]
11054 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11055 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11056 "@
11057 {cltd|cdq}
11058 sar{l}\t{%2, %0|%0, %2}"
11059 [(set_attr "type" "imovx,ishift")
11060 (set_attr "prefix_0f" "0,*")
11061 (set_attr "length_immediate" "0,*")
11062 (set_attr "modrm" "0,1")
11063 (set_attr "mode" "SI")])
11064
11065 (define_insn "*ashrsi3_31_zext"
11066 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11067 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11068 (match_operand:SI 2 "const_int_operand" "i,i"))))
11069 (clobber (reg:CC FLAGS_REG))]
11070 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11071 && INTVAL (operands[2]) == 31
11072 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11073 "@
11074 {cltd|cdq}
11075 sar{l}\t{%2, %k0|%k0, %2}"
11076 [(set_attr "type" "imovx,ishift")
11077 (set_attr "prefix_0f" "0,*")
11078 (set_attr "length_immediate" "0,*")
11079 (set_attr "modrm" "0,1")
11080 (set_attr "mode" "SI")])
11081
11082 (define_expand "ashrsi3"
11083 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11084 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11085 (match_operand:QI 2 "nonmemory_operand" "")))
11086 (clobber (reg:CC FLAGS_REG))]
11087 ""
11088 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11089
11090 (define_insn "*ashrsi3_1_one_bit"
11091 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11092 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11093 (match_operand:QI 2 "const1_operand" "")))
11094 (clobber (reg:CC FLAGS_REG))]
11095 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11096 && (TARGET_SHIFT1 || optimize_size)"
11097 "sar{l}\t%0"
11098 [(set_attr "type" "ishift")
11099 (set (attr "length")
11100 (if_then_else (match_operand:SI 0 "register_operand" "")
11101 (const_string "2")
11102 (const_string "*")))])
11103
11104 (define_insn "*ashrsi3_1_one_bit_zext"
11105 [(set (match_operand:DI 0 "register_operand" "=r")
11106 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11107 (match_operand:QI 2 "const1_operand" ""))))
11108 (clobber (reg:CC FLAGS_REG))]
11109 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11110 && (TARGET_SHIFT1 || optimize_size)"
11111 "sar{l}\t%k0"
11112 [(set_attr "type" "ishift")
11113 (set_attr "length" "2")])
11114
11115 (define_insn "*ashrsi3_1"
11116 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11117 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11118 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11119 (clobber (reg:CC FLAGS_REG))]
11120 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11121 "@
11122 sar{l}\t{%2, %0|%0, %2}
11123 sar{l}\t{%b2, %0|%0, %b2}"
11124 [(set_attr "type" "ishift")
11125 (set_attr "mode" "SI")])
11126
11127 (define_insn "*ashrsi3_1_zext"
11128 [(set (match_operand:DI 0 "register_operand" "=r,r")
11129 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11130 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11131 (clobber (reg:CC FLAGS_REG))]
11132 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11133 "@
11134 sar{l}\t{%2, %k0|%k0, %2}
11135 sar{l}\t{%b2, %k0|%k0, %b2}"
11136 [(set_attr "type" "ishift")
11137 (set_attr "mode" "SI")])
11138
11139 ;; This pattern can't accept a variable shift count, since shifts by
11140 ;; zero don't affect the flags. We assume that shifts by constant
11141 ;; zero are optimized away.
11142 (define_insn "*ashrsi3_one_bit_cmp"
11143 [(set (reg FLAGS_REG)
11144 (compare
11145 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11146 (match_operand:QI 2 "const1_operand" ""))
11147 (const_int 0)))
11148 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11149 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11150 "ix86_match_ccmode (insn, CCGOCmode)
11151 && (TARGET_SHIFT1 || optimize_size)
11152 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11153 "sar{l}\t%0"
11154 [(set_attr "type" "ishift")
11155 (set (attr "length")
11156 (if_then_else (match_operand:SI 0 "register_operand" "")
11157 (const_string "2")
11158 (const_string "*")))])
11159
11160 (define_insn "*ashrsi3_one_bit_cmp_zext"
11161 [(set (reg FLAGS_REG)
11162 (compare
11163 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11164 (match_operand:QI 2 "const1_operand" ""))
11165 (const_int 0)))
11166 (set (match_operand:DI 0 "register_operand" "=r")
11167 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11168 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11169 && (TARGET_SHIFT1 || optimize_size)
11170 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11171 "sar{l}\t%k0"
11172 [(set_attr "type" "ishift")
11173 (set_attr "length" "2")])
11174
11175 ;; This pattern can't accept a variable shift count, since shifts by
11176 ;; zero don't affect the flags. We assume that shifts by constant
11177 ;; zero are optimized away.
11178 (define_insn "*ashrsi3_cmp"
11179 [(set (reg FLAGS_REG)
11180 (compare
11181 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11182 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11183 (const_int 0)))
11184 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11185 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11186 "ix86_match_ccmode (insn, CCGOCmode)
11187 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11188 "sar{l}\t{%2, %0|%0, %2}"
11189 [(set_attr "type" "ishift")
11190 (set_attr "mode" "SI")])
11191
11192 (define_insn "*ashrsi3_cmp_zext"
11193 [(set (reg FLAGS_REG)
11194 (compare
11195 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11196 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11197 (const_int 0)))
11198 (set (match_operand:DI 0 "register_operand" "=r")
11199 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11200 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11201 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11202 "sar{l}\t{%2, %k0|%k0, %2}"
11203 [(set_attr "type" "ishift")
11204 (set_attr "mode" "SI")])
11205
11206 (define_expand "ashrhi3"
11207 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11208 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11209 (match_operand:QI 2 "nonmemory_operand" "")))
11210 (clobber (reg:CC FLAGS_REG))]
11211 "TARGET_HIMODE_MATH"
11212 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11213
11214 (define_insn "*ashrhi3_1_one_bit"
11215 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11216 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11217 (match_operand:QI 2 "const1_operand" "")))
11218 (clobber (reg:CC FLAGS_REG))]
11219 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11220 && (TARGET_SHIFT1 || optimize_size)"
11221 "sar{w}\t%0"
11222 [(set_attr "type" "ishift")
11223 (set (attr "length")
11224 (if_then_else (match_operand 0 "register_operand" "")
11225 (const_string "2")
11226 (const_string "*")))])
11227
11228 (define_insn "*ashrhi3_1"
11229 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11230 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11231 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11232 (clobber (reg:CC FLAGS_REG))]
11233 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11234 "@
11235 sar{w}\t{%2, %0|%0, %2}
11236 sar{w}\t{%b2, %0|%0, %b2}"
11237 [(set_attr "type" "ishift")
11238 (set_attr "mode" "HI")])
11239
11240 ;; This pattern can't accept a variable shift count, since shifts by
11241 ;; zero don't affect the flags. We assume that shifts by constant
11242 ;; zero are optimized away.
11243 (define_insn "*ashrhi3_one_bit_cmp"
11244 [(set (reg FLAGS_REG)
11245 (compare
11246 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11247 (match_operand:QI 2 "const1_operand" ""))
11248 (const_int 0)))
11249 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11250 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11251 "ix86_match_ccmode (insn, CCGOCmode)
11252 && (TARGET_SHIFT1 || optimize_size)
11253 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11254 "sar{w}\t%0"
11255 [(set_attr "type" "ishift")
11256 (set (attr "length")
11257 (if_then_else (match_operand 0 "register_operand" "")
11258 (const_string "2")
11259 (const_string "*")))])
11260
11261 ;; This pattern can't accept a variable shift count, since shifts by
11262 ;; zero don't affect the flags. We assume that shifts by constant
11263 ;; zero are optimized away.
11264 (define_insn "*ashrhi3_cmp"
11265 [(set (reg FLAGS_REG)
11266 (compare
11267 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11268 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11269 (const_int 0)))
11270 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11271 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11272 "ix86_match_ccmode (insn, CCGOCmode)
11273 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11274 "sar{w}\t{%2, %0|%0, %2}"
11275 [(set_attr "type" "ishift")
11276 (set_attr "mode" "HI")])
11277
11278 (define_expand "ashrqi3"
11279 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11280 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11281 (match_operand:QI 2 "nonmemory_operand" "")))
11282 (clobber (reg:CC FLAGS_REG))]
11283 "TARGET_QIMODE_MATH"
11284 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11285
11286 (define_insn "*ashrqi3_1_one_bit"
11287 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11288 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11289 (match_operand:QI 2 "const1_operand" "")))
11290 (clobber (reg:CC FLAGS_REG))]
11291 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11292 && (TARGET_SHIFT1 || optimize_size)"
11293 "sar{b}\t%0"
11294 [(set_attr "type" "ishift")
11295 (set (attr "length")
11296 (if_then_else (match_operand 0 "register_operand" "")
11297 (const_string "2")
11298 (const_string "*")))])
11299
11300 (define_insn "*ashrqi3_1_one_bit_slp"
11301 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11302 (ashiftrt:QI (match_dup 0)
11303 (match_operand:QI 1 "const1_operand" "")))
11304 (clobber (reg:CC FLAGS_REG))]
11305 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11306 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11307 && (TARGET_SHIFT1 || optimize_size)"
11308 "sar{b}\t%0"
11309 [(set_attr "type" "ishift1")
11310 (set (attr "length")
11311 (if_then_else (match_operand 0 "register_operand" "")
11312 (const_string "2")
11313 (const_string "*")))])
11314
11315 (define_insn "*ashrqi3_1"
11316 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11317 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11318 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11319 (clobber (reg:CC FLAGS_REG))]
11320 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11321 "@
11322 sar{b}\t{%2, %0|%0, %2}
11323 sar{b}\t{%b2, %0|%0, %b2}"
11324 [(set_attr "type" "ishift")
11325 (set_attr "mode" "QI")])
11326
11327 (define_insn "*ashrqi3_1_slp"
11328 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11329 (ashiftrt:QI (match_dup 0)
11330 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11331 (clobber (reg:CC FLAGS_REG))]
11332 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11333 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11334 "@
11335 sar{b}\t{%1, %0|%0, %1}
11336 sar{b}\t{%b1, %0|%0, %b1}"
11337 [(set_attr "type" "ishift1")
11338 (set_attr "mode" "QI")])
11339
11340 ;; This pattern can't accept a variable shift count, since shifts by
11341 ;; zero don't affect the flags. We assume that shifts by constant
11342 ;; zero are optimized away.
11343 (define_insn "*ashrqi3_one_bit_cmp"
11344 [(set (reg FLAGS_REG)
11345 (compare
11346 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11347 (match_operand:QI 2 "const1_operand" "I"))
11348 (const_int 0)))
11349 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11350 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11351 "ix86_match_ccmode (insn, CCGOCmode)
11352 && (TARGET_SHIFT1 || optimize_size)
11353 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11354 "sar{b}\t%0"
11355 [(set_attr "type" "ishift")
11356 (set (attr "length")
11357 (if_then_else (match_operand 0 "register_operand" "")
11358 (const_string "2")
11359 (const_string "*")))])
11360
11361 ;; This pattern can't accept a variable shift count, since shifts by
11362 ;; zero don't affect the flags. We assume that shifts by constant
11363 ;; zero are optimized away.
11364 (define_insn "*ashrqi3_cmp"
11365 [(set (reg FLAGS_REG)
11366 (compare
11367 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11368 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11369 (const_int 0)))
11370 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11371 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11372 "ix86_match_ccmode (insn, CCGOCmode)
11373 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11374 "sar{b}\t{%2, %0|%0, %2}"
11375 [(set_attr "type" "ishift")
11376 (set_attr "mode" "QI")])
11377 \f
11378 ;; Logical shift instructions
11379
11380 ;; See comment above `ashldi3' about how this works.
11381
11382 (define_expand "lshrdi3"
11383 [(set (match_operand:DI 0 "shiftdi_operand" "")
11384 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11385 (match_operand:QI 2 "nonmemory_operand" "")))]
11386 ""
11387 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11388
11389 (define_insn "*lshrdi3_1_one_bit_rex64"
11390 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11391 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11392 (match_operand:QI 2 "const1_operand" "")))
11393 (clobber (reg:CC FLAGS_REG))]
11394 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11395 && (TARGET_SHIFT1 || optimize_size)"
11396 "shr{q}\t%0"
11397 [(set_attr "type" "ishift")
11398 (set (attr "length")
11399 (if_then_else (match_operand:DI 0 "register_operand" "")
11400 (const_string "2")
11401 (const_string "*")))])
11402
11403 (define_insn "*lshrdi3_1_rex64"
11404 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11405 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11406 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11407 (clobber (reg:CC FLAGS_REG))]
11408 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11409 "@
11410 shr{q}\t{%2, %0|%0, %2}
11411 shr{q}\t{%b2, %0|%0, %b2}"
11412 [(set_attr "type" "ishift")
11413 (set_attr "mode" "DI")])
11414
11415 ;; This pattern can't accept a variable shift count, since shifts by
11416 ;; zero don't affect the flags. We assume that shifts by constant
11417 ;; zero are optimized away.
11418 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11419 [(set (reg FLAGS_REG)
11420 (compare
11421 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11422 (match_operand:QI 2 "const1_operand" ""))
11423 (const_int 0)))
11424 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11425 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11426 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11427 && (TARGET_SHIFT1 || optimize_size)
11428 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11429 "shr{q}\t%0"
11430 [(set_attr "type" "ishift")
11431 (set (attr "length")
11432 (if_then_else (match_operand:DI 0 "register_operand" "")
11433 (const_string "2")
11434 (const_string "*")))])
11435
11436 ;; This pattern can't accept a variable shift count, since shifts by
11437 ;; zero don't affect the flags. We assume that shifts by constant
11438 ;; zero are optimized away.
11439 (define_insn "*lshrdi3_cmp_rex64"
11440 [(set (reg FLAGS_REG)
11441 (compare
11442 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11443 (match_operand:QI 2 "const_int_operand" "e"))
11444 (const_int 0)))
11445 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11446 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11447 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11448 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11449 "shr{q}\t{%2, %0|%0, %2}"
11450 [(set_attr "type" "ishift")
11451 (set_attr "mode" "DI")])
11452
11453 (define_insn "*lshrdi3_1"
11454 [(set (match_operand:DI 0 "register_operand" "=r")
11455 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11456 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11457 (clobber (reg:CC FLAGS_REG))]
11458 "!TARGET_64BIT"
11459 "#"
11460 [(set_attr "type" "multi")])
11461
11462 ;; By default we don't ask for a scratch register, because when DImode
11463 ;; values are manipulated, registers are already at a premium. But if
11464 ;; we have one handy, we won't turn it away.
11465 (define_peephole2
11466 [(match_scratch:SI 3 "r")
11467 (parallel [(set (match_operand:DI 0 "register_operand" "")
11468 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11469 (match_operand:QI 2 "nonmemory_operand" "")))
11470 (clobber (reg:CC FLAGS_REG))])
11471 (match_dup 3)]
11472 "!TARGET_64BIT && TARGET_CMOVE"
11473 [(const_int 0)]
11474 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11475
11476 (define_split
11477 [(set (match_operand:DI 0 "register_operand" "")
11478 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11479 (match_operand:QI 2 "nonmemory_operand" "")))
11480 (clobber (reg:CC FLAGS_REG))]
11481 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11482 [(const_int 0)]
11483 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11484
11485 (define_expand "lshrsi3"
11486 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11487 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11488 (match_operand:QI 2 "nonmemory_operand" "")))
11489 (clobber (reg:CC FLAGS_REG))]
11490 ""
11491 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11492
11493 (define_insn "*lshrsi3_1_one_bit"
11494 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11495 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11496 (match_operand:QI 2 "const1_operand" "")))
11497 (clobber (reg:CC FLAGS_REG))]
11498 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11499 && (TARGET_SHIFT1 || optimize_size)"
11500 "shr{l}\t%0"
11501 [(set_attr "type" "ishift")
11502 (set (attr "length")
11503 (if_then_else (match_operand:SI 0 "register_operand" "")
11504 (const_string "2")
11505 (const_string "*")))])
11506
11507 (define_insn "*lshrsi3_1_one_bit_zext"
11508 [(set (match_operand:DI 0 "register_operand" "=r")
11509 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11510 (match_operand:QI 2 "const1_operand" "")))
11511 (clobber (reg:CC FLAGS_REG))]
11512 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11513 && (TARGET_SHIFT1 || optimize_size)"
11514 "shr{l}\t%k0"
11515 [(set_attr "type" "ishift")
11516 (set_attr "length" "2")])
11517
11518 (define_insn "*lshrsi3_1"
11519 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11520 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11521 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11522 (clobber (reg:CC FLAGS_REG))]
11523 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11524 "@
11525 shr{l}\t{%2, %0|%0, %2}
11526 shr{l}\t{%b2, %0|%0, %b2}"
11527 [(set_attr "type" "ishift")
11528 (set_attr "mode" "SI")])
11529
11530 (define_insn "*lshrsi3_1_zext"
11531 [(set (match_operand:DI 0 "register_operand" "=r,r")
11532 (zero_extend:DI
11533 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11534 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11535 (clobber (reg:CC FLAGS_REG))]
11536 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11537 "@
11538 shr{l}\t{%2, %k0|%k0, %2}
11539 shr{l}\t{%b2, %k0|%k0, %b2}"
11540 [(set_attr "type" "ishift")
11541 (set_attr "mode" "SI")])
11542
11543 ;; This pattern can't accept a variable shift count, since shifts by
11544 ;; zero don't affect the flags. We assume that shifts by constant
11545 ;; zero are optimized away.
11546 (define_insn "*lshrsi3_one_bit_cmp"
11547 [(set (reg FLAGS_REG)
11548 (compare
11549 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11550 (match_operand:QI 2 "const1_operand" ""))
11551 (const_int 0)))
11552 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11553 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11554 "ix86_match_ccmode (insn, CCGOCmode)
11555 && (TARGET_SHIFT1 || optimize_size)
11556 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11557 "shr{l}\t%0"
11558 [(set_attr "type" "ishift")
11559 (set (attr "length")
11560 (if_then_else (match_operand:SI 0 "register_operand" "")
11561 (const_string "2")
11562 (const_string "*")))])
11563
11564 (define_insn "*lshrsi3_cmp_one_bit_zext"
11565 [(set (reg FLAGS_REG)
11566 (compare
11567 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11568 (match_operand:QI 2 "const1_operand" ""))
11569 (const_int 0)))
11570 (set (match_operand:DI 0 "register_operand" "=r")
11571 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11572 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11573 && (TARGET_SHIFT1 || optimize_size)
11574 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11575 "shr{l}\t%k0"
11576 [(set_attr "type" "ishift")
11577 (set_attr "length" "2")])
11578
11579 ;; This pattern can't accept a variable shift count, since shifts by
11580 ;; zero don't affect the flags. We assume that shifts by constant
11581 ;; zero are optimized away.
11582 (define_insn "*lshrsi3_cmp"
11583 [(set (reg FLAGS_REG)
11584 (compare
11585 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11586 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11587 (const_int 0)))
11588 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11589 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11590 "ix86_match_ccmode (insn, CCGOCmode)
11591 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11592 "shr{l}\t{%2, %0|%0, %2}"
11593 [(set_attr "type" "ishift")
11594 (set_attr "mode" "SI")])
11595
11596 (define_insn "*lshrsi3_cmp_zext"
11597 [(set (reg FLAGS_REG)
11598 (compare
11599 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11600 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11601 (const_int 0)))
11602 (set (match_operand:DI 0 "register_operand" "=r")
11603 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11604 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11605 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11606 "shr{l}\t{%2, %k0|%k0, %2}"
11607 [(set_attr "type" "ishift")
11608 (set_attr "mode" "SI")])
11609
11610 (define_expand "lshrhi3"
11611 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11612 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11613 (match_operand:QI 2 "nonmemory_operand" "")))
11614 (clobber (reg:CC FLAGS_REG))]
11615 "TARGET_HIMODE_MATH"
11616 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11617
11618 (define_insn "*lshrhi3_1_one_bit"
11619 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11620 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11621 (match_operand:QI 2 "const1_operand" "")))
11622 (clobber (reg:CC FLAGS_REG))]
11623 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11624 && (TARGET_SHIFT1 || optimize_size)"
11625 "shr{w}\t%0"
11626 [(set_attr "type" "ishift")
11627 (set (attr "length")
11628 (if_then_else (match_operand 0 "register_operand" "")
11629 (const_string "2")
11630 (const_string "*")))])
11631
11632 (define_insn "*lshrhi3_1"
11633 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11634 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11635 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11636 (clobber (reg:CC FLAGS_REG))]
11637 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11638 "@
11639 shr{w}\t{%2, %0|%0, %2}
11640 shr{w}\t{%b2, %0|%0, %b2}"
11641 [(set_attr "type" "ishift")
11642 (set_attr "mode" "HI")])
11643
11644 ;; This pattern can't accept a variable shift count, since shifts by
11645 ;; zero don't affect the flags. We assume that shifts by constant
11646 ;; zero are optimized away.
11647 (define_insn "*lshrhi3_one_bit_cmp"
11648 [(set (reg FLAGS_REG)
11649 (compare
11650 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11651 (match_operand:QI 2 "const1_operand" ""))
11652 (const_int 0)))
11653 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11654 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11655 "ix86_match_ccmode (insn, CCGOCmode)
11656 && (TARGET_SHIFT1 || optimize_size)
11657 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11658 "shr{w}\t%0"
11659 [(set_attr "type" "ishift")
11660 (set (attr "length")
11661 (if_then_else (match_operand:SI 0 "register_operand" "")
11662 (const_string "2")
11663 (const_string "*")))])
11664
11665 ;; This pattern can't accept a variable shift count, since shifts by
11666 ;; zero don't affect the flags. We assume that shifts by constant
11667 ;; zero are optimized away.
11668 (define_insn "*lshrhi3_cmp"
11669 [(set (reg FLAGS_REG)
11670 (compare
11671 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11672 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11673 (const_int 0)))
11674 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11675 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11676 "ix86_match_ccmode (insn, CCGOCmode)
11677 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11678 "shr{w}\t{%2, %0|%0, %2}"
11679 [(set_attr "type" "ishift")
11680 (set_attr "mode" "HI")])
11681
11682 (define_expand "lshrqi3"
11683 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11684 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11685 (match_operand:QI 2 "nonmemory_operand" "")))
11686 (clobber (reg:CC FLAGS_REG))]
11687 "TARGET_QIMODE_MATH"
11688 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11689
11690 (define_insn "*lshrqi3_1_one_bit"
11691 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11692 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11693 (match_operand:QI 2 "const1_operand" "")))
11694 (clobber (reg:CC FLAGS_REG))]
11695 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11696 && (TARGET_SHIFT1 || optimize_size)"
11697 "shr{b}\t%0"
11698 [(set_attr "type" "ishift")
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_one_bit_slp"
11705 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11706 (lshiftrt:QI (match_dup 0)
11707 (match_operand:QI 1 "const1_operand" "")))
11708 (clobber (reg:CC FLAGS_REG))]
11709 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11710 && (TARGET_SHIFT1 || optimize_size)"
11711 "shr{b}\t%0"
11712 [(set_attr "type" "ishift1")
11713 (set (attr "length")
11714 (if_then_else (match_operand 0 "register_operand" "")
11715 (const_string "2")
11716 (const_string "*")))])
11717
11718 (define_insn "*lshrqi3_1"
11719 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11720 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11721 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11722 (clobber (reg:CC FLAGS_REG))]
11723 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11724 "@
11725 shr{b}\t{%2, %0|%0, %2}
11726 shr{b}\t{%b2, %0|%0, %b2}"
11727 [(set_attr "type" "ishift")
11728 (set_attr "mode" "QI")])
11729
11730 (define_insn "*lshrqi3_1_slp"
11731 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11732 (lshiftrt:QI (match_dup 0)
11733 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11734 (clobber (reg:CC FLAGS_REG))]
11735 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11736 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11737 "@
11738 shr{b}\t{%1, %0|%0, %1}
11739 shr{b}\t{%b1, %0|%0, %b1}"
11740 [(set_attr "type" "ishift1")
11741 (set_attr "mode" "QI")])
11742
11743 ;; This pattern can't accept a variable shift count, since shifts by
11744 ;; zero don't affect the flags. We assume that shifts by constant
11745 ;; zero are optimized away.
11746 (define_insn "*lshrqi2_one_bit_cmp"
11747 [(set (reg FLAGS_REG)
11748 (compare
11749 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11750 (match_operand:QI 2 "const1_operand" ""))
11751 (const_int 0)))
11752 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11753 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11754 "ix86_match_ccmode (insn, CCGOCmode)
11755 && (TARGET_SHIFT1 || optimize_size)
11756 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11757 "shr{b}\t%0"
11758 [(set_attr "type" "ishift")
11759 (set (attr "length")
11760 (if_then_else (match_operand:SI 0 "register_operand" "")
11761 (const_string "2")
11762 (const_string "*")))])
11763
11764 ;; This pattern can't accept a variable shift count, since shifts by
11765 ;; zero don't affect the flags. We assume that shifts by constant
11766 ;; zero are optimized away.
11767 (define_insn "*lshrqi2_cmp"
11768 [(set (reg FLAGS_REG)
11769 (compare
11770 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11771 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11772 (const_int 0)))
11773 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11774 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11775 "ix86_match_ccmode (insn, CCGOCmode)
11776 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11777 "shr{b}\t{%2, %0|%0, %2}"
11778 [(set_attr "type" "ishift")
11779 (set_attr "mode" "QI")])
11780 \f
11781 ;; Rotate instructions
11782
11783 (define_expand "rotldi3"
11784 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11785 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11786 (match_operand:QI 2 "nonmemory_operand" "")))
11787 (clobber (reg:CC FLAGS_REG))]
11788 "TARGET_64BIT"
11789 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11790
11791 (define_insn "*rotlsi3_1_one_bit_rex64"
11792 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11793 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11794 (match_operand:QI 2 "const1_operand" "")))
11795 (clobber (reg:CC FLAGS_REG))]
11796 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11797 && (TARGET_SHIFT1 || optimize_size)"
11798 "rol{q}\t%0"
11799 [(set_attr "type" "rotate")
11800 (set (attr "length")
11801 (if_then_else (match_operand:DI 0 "register_operand" "")
11802 (const_string "2")
11803 (const_string "*")))])
11804
11805 (define_insn "*rotldi3_1_rex64"
11806 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11807 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11808 (match_operand:QI 2 "nonmemory_operand" "e,c")))
11809 (clobber (reg:CC FLAGS_REG))]
11810 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11811 "@
11812 rol{q}\t{%2, %0|%0, %2}
11813 rol{q}\t{%b2, %0|%0, %b2}"
11814 [(set_attr "type" "rotate")
11815 (set_attr "mode" "DI")])
11816
11817 (define_expand "rotlsi3"
11818 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11819 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11820 (match_operand:QI 2 "nonmemory_operand" "")))
11821 (clobber (reg:CC FLAGS_REG))]
11822 ""
11823 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11824
11825 (define_insn "*rotlsi3_1_one_bit"
11826 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11827 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11828 (match_operand:QI 2 "const1_operand" "")))
11829 (clobber (reg:CC FLAGS_REG))]
11830 "ix86_binary_operator_ok (ROTATE, SImode, operands)
11831 && (TARGET_SHIFT1 || optimize_size)"
11832 "rol{l}\t%0"
11833 [(set_attr "type" "rotate")
11834 (set (attr "length")
11835 (if_then_else (match_operand:SI 0 "register_operand" "")
11836 (const_string "2")
11837 (const_string "*")))])
11838
11839 (define_insn "*rotlsi3_1_one_bit_zext"
11840 [(set (match_operand:DI 0 "register_operand" "=r")
11841 (zero_extend:DI
11842 (rotate:SI (match_operand:SI 1 "register_operand" "0")
11843 (match_operand:QI 2 "const1_operand" ""))))
11844 (clobber (reg:CC FLAGS_REG))]
11845 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11846 && (TARGET_SHIFT1 || optimize_size)"
11847 "rol{l}\t%k0"
11848 [(set_attr "type" "rotate")
11849 (set_attr "length" "2")])
11850
11851 (define_insn "*rotlsi3_1"
11852 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11853 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11854 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11855 (clobber (reg:CC FLAGS_REG))]
11856 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11857 "@
11858 rol{l}\t{%2, %0|%0, %2}
11859 rol{l}\t{%b2, %0|%0, %b2}"
11860 [(set_attr "type" "rotate")
11861 (set_attr "mode" "SI")])
11862
11863 (define_insn "*rotlsi3_1_zext"
11864 [(set (match_operand:DI 0 "register_operand" "=r,r")
11865 (zero_extend:DI
11866 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11867 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11868 (clobber (reg:CC FLAGS_REG))]
11869 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11870 "@
11871 rol{l}\t{%2, %k0|%k0, %2}
11872 rol{l}\t{%b2, %k0|%k0, %b2}"
11873 [(set_attr "type" "rotate")
11874 (set_attr "mode" "SI")])
11875
11876 (define_expand "rotlhi3"
11877 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11878 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11879 (match_operand:QI 2 "nonmemory_operand" "")))
11880 (clobber (reg:CC FLAGS_REG))]
11881 "TARGET_HIMODE_MATH"
11882 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11883
11884 (define_insn "*rotlhi3_1_one_bit"
11885 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11886 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11887 (match_operand:QI 2 "const1_operand" "")))
11888 (clobber (reg:CC FLAGS_REG))]
11889 "ix86_binary_operator_ok (ROTATE, HImode, operands)
11890 && (TARGET_SHIFT1 || optimize_size)"
11891 "rol{w}\t%0"
11892 [(set_attr "type" "rotate")
11893 (set (attr "length")
11894 (if_then_else (match_operand 0 "register_operand" "")
11895 (const_string "2")
11896 (const_string "*")))])
11897
11898 (define_insn "*rotlhi3_1"
11899 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11900 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11901 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11902 (clobber (reg:CC FLAGS_REG))]
11903 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11904 "@
11905 rol{w}\t{%2, %0|%0, %2}
11906 rol{w}\t{%b2, %0|%0, %b2}"
11907 [(set_attr "type" "rotate")
11908 (set_attr "mode" "HI")])
11909
11910 (define_expand "rotlqi3"
11911 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11912 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11913 (match_operand:QI 2 "nonmemory_operand" "")))
11914 (clobber (reg:CC FLAGS_REG))]
11915 "TARGET_QIMODE_MATH"
11916 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11917
11918 (define_insn "*rotlqi3_1_one_bit_slp"
11919 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11920 (rotate:QI (match_dup 0)
11921 (match_operand:QI 1 "const1_operand" "")))
11922 (clobber (reg:CC FLAGS_REG))]
11923 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11924 && (TARGET_SHIFT1 || optimize_size)"
11925 "rol{b}\t%0"
11926 [(set_attr "type" "rotate1")
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_one_bit"
11933 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11934 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11935 (match_operand:QI 2 "const1_operand" "")))
11936 (clobber (reg:CC FLAGS_REG))]
11937 "ix86_binary_operator_ok (ROTATE, QImode, operands)
11938 && (TARGET_SHIFT1 || optimize_size)"
11939 "rol{b}\t%0"
11940 [(set_attr "type" "rotate")
11941 (set (attr "length")
11942 (if_then_else (match_operand 0 "register_operand" "")
11943 (const_string "2")
11944 (const_string "*")))])
11945
11946 (define_insn "*rotlqi3_1_slp"
11947 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11948 (rotate:QI (match_dup 0)
11949 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11950 (clobber (reg:CC FLAGS_REG))]
11951 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11952 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11953 "@
11954 rol{b}\t{%1, %0|%0, %1}
11955 rol{b}\t{%b1, %0|%0, %b1}"
11956 [(set_attr "type" "rotate1")
11957 (set_attr "mode" "QI")])
11958
11959 (define_insn "*rotlqi3_1"
11960 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11961 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11962 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11963 (clobber (reg:CC FLAGS_REG))]
11964 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11965 "@
11966 rol{b}\t{%2, %0|%0, %2}
11967 rol{b}\t{%b2, %0|%0, %b2}"
11968 [(set_attr "type" "rotate")
11969 (set_attr "mode" "QI")])
11970
11971 (define_expand "rotrdi3"
11972 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11973 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11974 (match_operand:QI 2 "nonmemory_operand" "")))
11975 (clobber (reg:CC FLAGS_REG))]
11976 "TARGET_64BIT"
11977 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11978
11979 (define_insn "*rotrdi3_1_one_bit_rex64"
11980 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11981 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11982 (match_operand:QI 2 "const1_operand" "")))
11983 (clobber (reg:CC FLAGS_REG))]
11984 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11985 && (TARGET_SHIFT1 || optimize_size)"
11986 "ror{q}\t%0"
11987 [(set_attr "type" "rotate")
11988 (set (attr "length")
11989 (if_then_else (match_operand:DI 0 "register_operand" "")
11990 (const_string "2")
11991 (const_string "*")))])
11992
11993 (define_insn "*rotrdi3_1_rex64"
11994 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11995 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11996 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11997 (clobber (reg:CC FLAGS_REG))]
11998 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11999 "@
12000 ror{q}\t{%2, %0|%0, %2}
12001 ror{q}\t{%b2, %0|%0, %b2}"
12002 [(set_attr "type" "rotate")
12003 (set_attr "mode" "DI")])
12004
12005 (define_expand "rotrsi3"
12006 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12007 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12008 (match_operand:QI 2 "nonmemory_operand" "")))
12009 (clobber (reg:CC FLAGS_REG))]
12010 ""
12011 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12012
12013 (define_insn "*rotrsi3_1_one_bit"
12014 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12015 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12016 (match_operand:QI 2 "const1_operand" "")))
12017 (clobber (reg:CC FLAGS_REG))]
12018 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12019 && (TARGET_SHIFT1 || optimize_size)"
12020 "ror{l}\t%0"
12021 [(set_attr "type" "rotate")
12022 (set (attr "length")
12023 (if_then_else (match_operand:SI 0 "register_operand" "")
12024 (const_string "2")
12025 (const_string "*")))])
12026
12027 (define_insn "*rotrsi3_1_one_bit_zext"
12028 [(set (match_operand:DI 0 "register_operand" "=r")
12029 (zero_extend:DI
12030 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12031 (match_operand:QI 2 "const1_operand" ""))))
12032 (clobber (reg:CC FLAGS_REG))]
12033 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12034 && (TARGET_SHIFT1 || optimize_size)"
12035 "ror{l}\t%k0"
12036 [(set_attr "type" "rotate")
12037 (set (attr "length")
12038 (if_then_else (match_operand:SI 0 "register_operand" "")
12039 (const_string "2")
12040 (const_string "*")))])
12041
12042 (define_insn "*rotrsi3_1"
12043 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12044 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12045 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12046 (clobber (reg:CC FLAGS_REG))]
12047 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12048 "@
12049 ror{l}\t{%2, %0|%0, %2}
12050 ror{l}\t{%b2, %0|%0, %b2}"
12051 [(set_attr "type" "rotate")
12052 (set_attr "mode" "SI")])
12053
12054 (define_insn "*rotrsi3_1_zext"
12055 [(set (match_operand:DI 0 "register_operand" "=r,r")
12056 (zero_extend:DI
12057 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12058 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12059 (clobber (reg:CC FLAGS_REG))]
12060 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12061 "@
12062 ror{l}\t{%2, %k0|%k0, %2}
12063 ror{l}\t{%b2, %k0|%k0, %b2}"
12064 [(set_attr "type" "rotate")
12065 (set_attr "mode" "SI")])
12066
12067 (define_expand "rotrhi3"
12068 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12069 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12070 (match_operand:QI 2 "nonmemory_operand" "")))
12071 (clobber (reg:CC FLAGS_REG))]
12072 "TARGET_HIMODE_MATH"
12073 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12074
12075 (define_insn "*rotrhi3_one_bit"
12076 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12077 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12078 (match_operand:QI 2 "const1_operand" "")))
12079 (clobber (reg:CC FLAGS_REG))]
12080 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12081 && (TARGET_SHIFT1 || optimize_size)"
12082 "ror{w}\t%0"
12083 [(set_attr "type" "rotate")
12084 (set (attr "length")
12085 (if_then_else (match_operand 0 "register_operand" "")
12086 (const_string "2")
12087 (const_string "*")))])
12088
12089 (define_insn "*rotrhi3"
12090 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12091 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12092 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12093 (clobber (reg:CC FLAGS_REG))]
12094 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12095 "@
12096 ror{w}\t{%2, %0|%0, %2}
12097 ror{w}\t{%b2, %0|%0, %b2}"
12098 [(set_attr "type" "rotate")
12099 (set_attr "mode" "HI")])
12100
12101 (define_expand "rotrqi3"
12102 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12103 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12104 (match_operand:QI 2 "nonmemory_operand" "")))
12105 (clobber (reg:CC FLAGS_REG))]
12106 "TARGET_QIMODE_MATH"
12107 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12108
12109 (define_insn "*rotrqi3_1_one_bit"
12110 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12111 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12112 (match_operand:QI 2 "const1_operand" "")))
12113 (clobber (reg:CC FLAGS_REG))]
12114 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12115 && (TARGET_SHIFT1 || optimize_size)"
12116 "ror{b}\t%0"
12117 [(set_attr "type" "rotate")
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_one_bit_slp"
12124 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12125 (rotatert:QI (match_dup 0)
12126 (match_operand:QI 1 "const1_operand" "")))
12127 (clobber (reg:CC FLAGS_REG))]
12128 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12129 && (TARGET_SHIFT1 || optimize_size)"
12130 "ror{b}\t%0"
12131 [(set_attr "type" "rotate1")
12132 (set (attr "length")
12133 (if_then_else (match_operand 0 "register_operand" "")
12134 (const_string "2")
12135 (const_string "*")))])
12136
12137 (define_insn "*rotrqi3_1"
12138 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12139 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12140 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12141 (clobber (reg:CC FLAGS_REG))]
12142 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12143 "@
12144 ror{b}\t{%2, %0|%0, %2}
12145 ror{b}\t{%b2, %0|%0, %b2}"
12146 [(set_attr "type" "rotate")
12147 (set_attr "mode" "QI")])
12148
12149 (define_insn "*rotrqi3_1_slp"
12150 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12151 (rotatert:QI (match_dup 0)
12152 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12153 (clobber (reg:CC FLAGS_REG))]
12154 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12155 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12156 "@
12157 ror{b}\t{%1, %0|%0, %1}
12158 ror{b}\t{%b1, %0|%0, %b1}"
12159 [(set_attr "type" "rotate1")
12160 (set_attr "mode" "QI")])
12161 \f
12162 ;; Bit set / bit test instructions
12163
12164 (define_expand "extv"
12165 [(set (match_operand:SI 0 "register_operand" "")
12166 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12167 (match_operand:SI 2 "immediate_operand" "")
12168 (match_operand:SI 3 "immediate_operand" "")))]
12169 ""
12170 {
12171 /* Handle extractions from %ah et al. */
12172 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12173 FAIL;
12174
12175 /* From mips.md: extract_bit_field doesn't verify that our source
12176 matches the predicate, so check it again here. */
12177 if (! ext_register_operand (operands[1], VOIDmode))
12178 FAIL;
12179 })
12180
12181 (define_expand "extzv"
12182 [(set (match_operand:SI 0 "register_operand" "")
12183 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12184 (match_operand:SI 2 "immediate_operand" "")
12185 (match_operand:SI 3 "immediate_operand" "")))]
12186 ""
12187 {
12188 /* Handle extractions from %ah et al. */
12189 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12190 FAIL;
12191
12192 /* From mips.md: extract_bit_field doesn't verify that our source
12193 matches the predicate, so check it again here. */
12194 if (! ext_register_operand (operands[1], VOIDmode))
12195 FAIL;
12196 })
12197
12198 (define_expand "insv"
12199 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12200 (match_operand 1 "immediate_operand" "")
12201 (match_operand 2 "immediate_operand" ""))
12202 (match_operand 3 "register_operand" ""))]
12203 ""
12204 {
12205 /* Handle extractions from %ah et al. */
12206 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12207 FAIL;
12208
12209 /* From mips.md: insert_bit_field doesn't verify that our source
12210 matches the predicate, so check it again here. */
12211 if (! ext_register_operand (operands[0], VOIDmode))
12212 FAIL;
12213
12214 if (TARGET_64BIT)
12215 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12216 else
12217 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12218
12219 DONE;
12220 })
12221
12222 ;; %%% bts, btr, btc, bt.
12223 ;; In general these instructions are *slow* when applied to memory,
12224 ;; since they enforce atomic operation. When applied to registers,
12225 ;; it depends on the cpu implementation. They're never faster than
12226 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12227 ;; no point. But in 64-bit, we can't hold the relevant immediates
12228 ;; within the instruction itself, so operating on bits in the high
12229 ;; 32-bits of a register becomes easier.
12230 ;;
12231 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12232 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12233 ;; negdf respectively, so they can never be disabled entirely.
12234
12235 (define_insn "*btsq"
12236 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12237 (const_int 1)
12238 (match_operand:DI 1 "const_0_to_63_operand" ""))
12239 (const_int 1))
12240 (clobber (reg:CC FLAGS_REG))]
12241 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12242 "bts{q} %1,%0"
12243 [(set_attr "type" "alu1")])
12244
12245 (define_insn "*btrq"
12246 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12247 (const_int 1)
12248 (match_operand:DI 1 "const_0_to_63_operand" ""))
12249 (const_int 0))
12250 (clobber (reg:CC FLAGS_REG))]
12251 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12252 "btr{q} %1,%0"
12253 [(set_attr "type" "alu1")])
12254
12255 (define_insn "*btcq"
12256 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12257 (const_int 1)
12258 (match_operand:DI 1 "const_0_to_63_operand" ""))
12259 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12260 (clobber (reg:CC FLAGS_REG))]
12261 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12262 "btc{q} %1,%0"
12263 [(set_attr "type" "alu1")])
12264
12265 ;; Allow Nocona to avoid these instructions if a register is available.
12266
12267 (define_peephole2
12268 [(match_scratch:DI 2 "r")
12269 (parallel [(set (zero_extract:DI
12270 (match_operand:DI 0 "register_operand" "")
12271 (const_int 1)
12272 (match_operand:DI 1 "const_0_to_63_operand" ""))
12273 (const_int 1))
12274 (clobber (reg:CC FLAGS_REG))])]
12275 "TARGET_64BIT && !TARGET_USE_BT"
12276 [(const_int 0)]
12277 {
12278 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12279 rtx op1;
12280
12281 if (HOST_BITS_PER_WIDE_INT >= 64)
12282 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12283 else if (i < HOST_BITS_PER_WIDE_INT)
12284 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12285 else
12286 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12287
12288 op1 = immed_double_const (lo, hi, DImode);
12289 if (i >= 31)
12290 {
12291 emit_move_insn (operands[2], op1);
12292 op1 = operands[2];
12293 }
12294
12295 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12296 DONE;
12297 })
12298
12299 (define_peephole2
12300 [(match_scratch:DI 2 "r")
12301 (parallel [(set (zero_extract:DI
12302 (match_operand:DI 0 "register_operand" "")
12303 (const_int 1)
12304 (match_operand:DI 1 "const_0_to_63_operand" ""))
12305 (const_int 0))
12306 (clobber (reg:CC FLAGS_REG))])]
12307 "TARGET_64BIT && !TARGET_USE_BT"
12308 [(const_int 0)]
12309 {
12310 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12311 rtx op1;
12312
12313 if (HOST_BITS_PER_WIDE_INT >= 64)
12314 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12315 else if (i < HOST_BITS_PER_WIDE_INT)
12316 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12317 else
12318 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12319
12320 op1 = immed_double_const (~lo, ~hi, DImode);
12321 if (i >= 32)
12322 {
12323 emit_move_insn (operands[2], op1);
12324 op1 = operands[2];
12325 }
12326
12327 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12328 DONE;
12329 })
12330
12331 (define_peephole2
12332 [(match_scratch:DI 2 "r")
12333 (parallel [(set (zero_extract:DI
12334 (match_operand:DI 0 "register_operand" "")
12335 (const_int 1)
12336 (match_operand:DI 1 "const_0_to_63_operand" ""))
12337 (not:DI (zero_extract:DI
12338 (match_dup 0) (const_int 1) (match_dup 1))))
12339 (clobber (reg:CC FLAGS_REG))])]
12340 "TARGET_64BIT && !TARGET_USE_BT"
12341 [(const_int 0)]
12342 {
12343 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12344 rtx op1;
12345
12346 if (HOST_BITS_PER_WIDE_INT >= 64)
12347 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12348 else if (i < HOST_BITS_PER_WIDE_INT)
12349 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12350 else
12351 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12352
12353 op1 = immed_double_const (lo, hi, DImode);
12354 if (i >= 31)
12355 {
12356 emit_move_insn (operands[2], op1);
12357 op1 = operands[2];
12358 }
12359
12360 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12361 DONE;
12362 })
12363 \f
12364 ;; Store-flag instructions.
12365
12366 ;; For all sCOND expanders, also expand the compare or test insn that
12367 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12368
12369 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12370 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12371 ;; way, which can later delete the movzx if only QImode is needed.
12372
12373 (define_expand "seq"
12374 [(set (match_operand:QI 0 "register_operand" "")
12375 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12376 ""
12377 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12378
12379 (define_expand "sne"
12380 [(set (match_operand:QI 0 "register_operand" "")
12381 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12382 ""
12383 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12384
12385 (define_expand "sgt"
12386 [(set (match_operand:QI 0 "register_operand" "")
12387 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12388 ""
12389 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12390
12391 (define_expand "sgtu"
12392 [(set (match_operand:QI 0 "register_operand" "")
12393 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12394 ""
12395 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12396
12397 (define_expand "slt"
12398 [(set (match_operand:QI 0 "register_operand" "")
12399 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12400 ""
12401 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12402
12403 (define_expand "sltu"
12404 [(set (match_operand:QI 0 "register_operand" "")
12405 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12406 ""
12407 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12408
12409 (define_expand "sge"
12410 [(set (match_operand:QI 0 "register_operand" "")
12411 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12412 ""
12413 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12414
12415 (define_expand "sgeu"
12416 [(set (match_operand:QI 0 "register_operand" "")
12417 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12418 ""
12419 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12420
12421 (define_expand "sle"
12422 [(set (match_operand:QI 0 "register_operand" "")
12423 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12424 ""
12425 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12426
12427 (define_expand "sleu"
12428 [(set (match_operand:QI 0 "register_operand" "")
12429 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12430 ""
12431 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12432
12433 (define_expand "sunordered"
12434 [(set (match_operand:QI 0 "register_operand" "")
12435 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12436 "TARGET_80387 || TARGET_SSE"
12437 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12438
12439 (define_expand "sordered"
12440 [(set (match_operand:QI 0 "register_operand" "")
12441 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12442 "TARGET_80387"
12443 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12444
12445 (define_expand "suneq"
12446 [(set (match_operand:QI 0 "register_operand" "")
12447 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12448 "TARGET_80387 || TARGET_SSE"
12449 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12450
12451 (define_expand "sunge"
12452 [(set (match_operand:QI 0 "register_operand" "")
12453 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12454 "TARGET_80387 || TARGET_SSE"
12455 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12456
12457 (define_expand "sungt"
12458 [(set (match_operand:QI 0 "register_operand" "")
12459 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12460 "TARGET_80387 || TARGET_SSE"
12461 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12462
12463 (define_expand "sunle"
12464 [(set (match_operand:QI 0 "register_operand" "")
12465 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12466 "TARGET_80387 || TARGET_SSE"
12467 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12468
12469 (define_expand "sunlt"
12470 [(set (match_operand:QI 0 "register_operand" "")
12471 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12472 "TARGET_80387 || TARGET_SSE"
12473 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12474
12475 (define_expand "sltgt"
12476 [(set (match_operand:QI 0 "register_operand" "")
12477 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12478 "TARGET_80387 || TARGET_SSE"
12479 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12480
12481 (define_insn "*setcc_1"
12482 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12483 (match_operator:QI 1 "ix86_comparison_operator"
12484 [(reg FLAGS_REG) (const_int 0)]))]
12485 ""
12486 "set%C1\t%0"
12487 [(set_attr "type" "setcc")
12488 (set_attr "mode" "QI")])
12489
12490 (define_insn "*setcc_2"
12491 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12492 (match_operator:QI 1 "ix86_comparison_operator"
12493 [(reg FLAGS_REG) (const_int 0)]))]
12494 ""
12495 "set%C1\t%0"
12496 [(set_attr "type" "setcc")
12497 (set_attr "mode" "QI")])
12498
12499 ;; In general it is not safe to assume too much about CCmode registers,
12500 ;; so simplify-rtx stops when it sees a second one. Under certain
12501 ;; conditions this is safe on x86, so help combine not create
12502 ;;
12503 ;; seta %al
12504 ;; testb %al, %al
12505 ;; sete %al
12506
12507 (define_split
12508 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12509 (ne:QI (match_operator 1 "ix86_comparison_operator"
12510 [(reg FLAGS_REG) (const_int 0)])
12511 (const_int 0)))]
12512 ""
12513 [(set (match_dup 0) (match_dup 1))]
12514 {
12515 PUT_MODE (operands[1], QImode);
12516 })
12517
12518 (define_split
12519 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12520 (ne:QI (match_operator 1 "ix86_comparison_operator"
12521 [(reg FLAGS_REG) (const_int 0)])
12522 (const_int 0)))]
12523 ""
12524 [(set (match_dup 0) (match_dup 1))]
12525 {
12526 PUT_MODE (operands[1], QImode);
12527 })
12528
12529 (define_split
12530 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12531 (eq:QI (match_operator 1 "ix86_comparison_operator"
12532 [(reg FLAGS_REG) (const_int 0)])
12533 (const_int 0)))]
12534 ""
12535 [(set (match_dup 0) (match_dup 1))]
12536 {
12537 rtx new_op1 = copy_rtx (operands[1]);
12538 operands[1] = new_op1;
12539 PUT_MODE (new_op1, QImode);
12540 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12541 GET_MODE (XEXP (new_op1, 0))));
12542
12543 /* Make sure that (a) the CCmode we have for the flags is strong
12544 enough for the reversed compare or (b) we have a valid FP compare. */
12545 if (! ix86_comparison_operator (new_op1, VOIDmode))
12546 FAIL;
12547 })
12548
12549 (define_split
12550 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12551 (eq:QI (match_operator 1 "ix86_comparison_operator"
12552 [(reg FLAGS_REG) (const_int 0)])
12553 (const_int 0)))]
12554 ""
12555 [(set (match_dup 0) (match_dup 1))]
12556 {
12557 rtx new_op1 = copy_rtx (operands[1]);
12558 operands[1] = new_op1;
12559 PUT_MODE (new_op1, QImode);
12560 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12561 GET_MODE (XEXP (new_op1, 0))));
12562
12563 /* Make sure that (a) the CCmode we have for the flags is strong
12564 enough for the reversed compare or (b) we have a valid FP compare. */
12565 if (! ix86_comparison_operator (new_op1, VOIDmode))
12566 FAIL;
12567 })
12568
12569 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12570 ;; subsequent logical operations are used to imitate conditional moves.
12571 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12572 ;; it directly. Further holding this value in pseudo register might bring
12573 ;; problem in implicit normalization in spill code.
12574 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12575 ;; instructions after reload by splitting the conditional move patterns.
12576
12577 (define_insn "*sse_setccsf"
12578 [(set (match_operand:SF 0 "register_operand" "=x")
12579 (match_operator:SF 1 "sse_comparison_operator"
12580 [(match_operand:SF 2 "register_operand" "0")
12581 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12582 "TARGET_SSE && reload_completed"
12583 "cmp%D1ss\t{%3, %0|%0, %3}"
12584 [(set_attr "type" "ssecmp")
12585 (set_attr "mode" "SF")])
12586
12587 (define_insn "*sse_setccdf"
12588 [(set (match_operand:DF 0 "register_operand" "=Y")
12589 (match_operator:DF 1 "sse_comparison_operator"
12590 [(match_operand:DF 2 "register_operand" "0")
12591 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12592 "TARGET_SSE2 && reload_completed"
12593 "cmp%D1sd\t{%3, %0|%0, %3}"
12594 [(set_attr "type" "ssecmp")
12595 (set_attr "mode" "DF")])
12596 \f
12597 ;; Basic conditional jump instructions.
12598 ;; We ignore the overflow flag for signed branch instructions.
12599
12600 ;; For all bCOND expanders, also expand the compare or test insn that
12601 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12602
12603 (define_expand "beq"
12604 [(set (pc)
12605 (if_then_else (match_dup 1)
12606 (label_ref (match_operand 0 "" ""))
12607 (pc)))]
12608 ""
12609 "ix86_expand_branch (EQ, operands[0]); DONE;")
12610
12611 (define_expand "bne"
12612 [(set (pc)
12613 (if_then_else (match_dup 1)
12614 (label_ref (match_operand 0 "" ""))
12615 (pc)))]
12616 ""
12617 "ix86_expand_branch (NE, operands[0]); DONE;")
12618
12619 (define_expand "bgt"
12620 [(set (pc)
12621 (if_then_else (match_dup 1)
12622 (label_ref (match_operand 0 "" ""))
12623 (pc)))]
12624 ""
12625 "ix86_expand_branch (GT, operands[0]); DONE;")
12626
12627 (define_expand "bgtu"
12628 [(set (pc)
12629 (if_then_else (match_dup 1)
12630 (label_ref (match_operand 0 "" ""))
12631 (pc)))]
12632 ""
12633 "ix86_expand_branch (GTU, operands[0]); DONE;")
12634
12635 (define_expand "blt"
12636 [(set (pc)
12637 (if_then_else (match_dup 1)
12638 (label_ref (match_operand 0 "" ""))
12639 (pc)))]
12640 ""
12641 "ix86_expand_branch (LT, operands[0]); DONE;")
12642
12643 (define_expand "bltu"
12644 [(set (pc)
12645 (if_then_else (match_dup 1)
12646 (label_ref (match_operand 0 "" ""))
12647 (pc)))]
12648 ""
12649 "ix86_expand_branch (LTU, operands[0]); DONE;")
12650
12651 (define_expand "bge"
12652 [(set (pc)
12653 (if_then_else (match_dup 1)
12654 (label_ref (match_operand 0 "" ""))
12655 (pc)))]
12656 ""
12657 "ix86_expand_branch (GE, operands[0]); DONE;")
12658
12659 (define_expand "bgeu"
12660 [(set (pc)
12661 (if_then_else (match_dup 1)
12662 (label_ref (match_operand 0 "" ""))
12663 (pc)))]
12664 ""
12665 "ix86_expand_branch (GEU, operands[0]); DONE;")
12666
12667 (define_expand "ble"
12668 [(set (pc)
12669 (if_then_else (match_dup 1)
12670 (label_ref (match_operand 0 "" ""))
12671 (pc)))]
12672 ""
12673 "ix86_expand_branch (LE, operands[0]); DONE;")
12674
12675 (define_expand "bleu"
12676 [(set (pc)
12677 (if_then_else (match_dup 1)
12678 (label_ref (match_operand 0 "" ""))
12679 (pc)))]
12680 ""
12681 "ix86_expand_branch (LEU, operands[0]); DONE;")
12682
12683 (define_expand "bunordered"
12684 [(set (pc)
12685 (if_then_else (match_dup 1)
12686 (label_ref (match_operand 0 "" ""))
12687 (pc)))]
12688 "TARGET_80387 || TARGET_SSE_MATH"
12689 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12690
12691 (define_expand "bordered"
12692 [(set (pc)
12693 (if_then_else (match_dup 1)
12694 (label_ref (match_operand 0 "" ""))
12695 (pc)))]
12696 "TARGET_80387 || TARGET_SSE_MATH"
12697 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12698
12699 (define_expand "buneq"
12700 [(set (pc)
12701 (if_then_else (match_dup 1)
12702 (label_ref (match_operand 0 "" ""))
12703 (pc)))]
12704 "TARGET_80387 || TARGET_SSE_MATH"
12705 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12706
12707 (define_expand "bunge"
12708 [(set (pc)
12709 (if_then_else (match_dup 1)
12710 (label_ref (match_operand 0 "" ""))
12711 (pc)))]
12712 "TARGET_80387 || TARGET_SSE_MATH"
12713 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12714
12715 (define_expand "bungt"
12716 [(set (pc)
12717 (if_then_else (match_dup 1)
12718 (label_ref (match_operand 0 "" ""))
12719 (pc)))]
12720 "TARGET_80387 || TARGET_SSE_MATH"
12721 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12722
12723 (define_expand "bunle"
12724 [(set (pc)
12725 (if_then_else (match_dup 1)
12726 (label_ref (match_operand 0 "" ""))
12727 (pc)))]
12728 "TARGET_80387 || TARGET_SSE_MATH"
12729 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12730
12731 (define_expand "bunlt"
12732 [(set (pc)
12733 (if_then_else (match_dup 1)
12734 (label_ref (match_operand 0 "" ""))
12735 (pc)))]
12736 "TARGET_80387 || TARGET_SSE_MATH"
12737 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12738
12739 (define_expand "bltgt"
12740 [(set (pc)
12741 (if_then_else (match_dup 1)
12742 (label_ref (match_operand 0 "" ""))
12743 (pc)))]
12744 "TARGET_80387 || TARGET_SSE_MATH"
12745 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12746
12747 (define_insn "*jcc_1"
12748 [(set (pc)
12749 (if_then_else (match_operator 1 "ix86_comparison_operator"
12750 [(reg FLAGS_REG) (const_int 0)])
12751 (label_ref (match_operand 0 "" ""))
12752 (pc)))]
12753 ""
12754 "%+j%C1\t%l0"
12755 [(set_attr "type" "ibr")
12756 (set_attr "modrm" "0")
12757 (set (attr "length")
12758 (if_then_else (and (ge (minus (match_dup 0) (pc))
12759 (const_int -126))
12760 (lt (minus (match_dup 0) (pc))
12761 (const_int 128)))
12762 (const_int 2)
12763 (const_int 6)))])
12764
12765 (define_insn "*jcc_2"
12766 [(set (pc)
12767 (if_then_else (match_operator 1 "ix86_comparison_operator"
12768 [(reg FLAGS_REG) (const_int 0)])
12769 (pc)
12770 (label_ref (match_operand 0 "" ""))))]
12771 ""
12772 "%+j%c1\t%l0"
12773 [(set_attr "type" "ibr")
12774 (set_attr "modrm" "0")
12775 (set (attr "length")
12776 (if_then_else (and (ge (minus (match_dup 0) (pc))
12777 (const_int -126))
12778 (lt (minus (match_dup 0) (pc))
12779 (const_int 128)))
12780 (const_int 2)
12781 (const_int 6)))])
12782
12783 ;; In general it is not safe to assume too much about CCmode registers,
12784 ;; so simplify-rtx stops when it sees a second one. Under certain
12785 ;; conditions this is safe on x86, so help combine not create
12786 ;;
12787 ;; seta %al
12788 ;; testb %al, %al
12789 ;; je Lfoo
12790
12791 (define_split
12792 [(set (pc)
12793 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12794 [(reg FLAGS_REG) (const_int 0)])
12795 (const_int 0))
12796 (label_ref (match_operand 1 "" ""))
12797 (pc)))]
12798 ""
12799 [(set (pc)
12800 (if_then_else (match_dup 0)
12801 (label_ref (match_dup 1))
12802 (pc)))]
12803 {
12804 PUT_MODE (operands[0], VOIDmode);
12805 })
12806
12807 (define_split
12808 [(set (pc)
12809 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12810 [(reg FLAGS_REG) (const_int 0)])
12811 (const_int 0))
12812 (label_ref (match_operand 1 "" ""))
12813 (pc)))]
12814 ""
12815 [(set (pc)
12816 (if_then_else (match_dup 0)
12817 (label_ref (match_dup 1))
12818 (pc)))]
12819 {
12820 rtx new_op0 = copy_rtx (operands[0]);
12821 operands[0] = new_op0;
12822 PUT_MODE (new_op0, VOIDmode);
12823 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12824 GET_MODE (XEXP (new_op0, 0))));
12825
12826 /* Make sure that (a) the CCmode we have for the flags is strong
12827 enough for the reversed compare or (b) we have a valid FP compare. */
12828 if (! ix86_comparison_operator (new_op0, VOIDmode))
12829 FAIL;
12830 })
12831
12832 ;; Define combination compare-and-branch fp compare instructions to use
12833 ;; during early optimization. Splitting the operation apart early makes
12834 ;; for bad code when we want to reverse the operation.
12835
12836 (define_insn "*fp_jcc_1_mixed"
12837 [(set (pc)
12838 (if_then_else (match_operator 0 "comparison_operator"
12839 [(match_operand 1 "register_operand" "f#x,x#f")
12840 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12841 (label_ref (match_operand 3 "" ""))
12842 (pc)))
12843 (clobber (reg:CCFP FPSR_REG))
12844 (clobber (reg:CCFP FLAGS_REG))]
12845 "TARGET_MIX_SSE_I387
12846 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12847 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12848 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12849 "#")
12850
12851 (define_insn "*fp_jcc_1_sse"
12852 [(set (pc)
12853 (if_then_else (match_operator 0 "comparison_operator"
12854 [(match_operand 1 "register_operand" "x")
12855 (match_operand 2 "nonimmediate_operand" "xm")])
12856 (label_ref (match_operand 3 "" ""))
12857 (pc)))
12858 (clobber (reg:CCFP FPSR_REG))
12859 (clobber (reg:CCFP FLAGS_REG))]
12860 "TARGET_SSE_MATH
12861 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12862 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12863 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12864 "#")
12865
12866 (define_insn "*fp_jcc_1_387"
12867 [(set (pc)
12868 (if_then_else (match_operator 0 "comparison_operator"
12869 [(match_operand 1 "register_operand" "f")
12870 (match_operand 2 "register_operand" "f")])
12871 (label_ref (match_operand 3 "" ""))
12872 (pc)))
12873 (clobber (reg:CCFP FPSR_REG))
12874 (clobber (reg:CCFP FLAGS_REG))]
12875 "TARGET_CMOVE && TARGET_80387
12876 && FLOAT_MODE_P (GET_MODE (operands[1]))
12877 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12878 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12879 "#")
12880
12881 (define_insn "*fp_jcc_2_mixed"
12882 [(set (pc)
12883 (if_then_else (match_operator 0 "comparison_operator"
12884 [(match_operand 1 "register_operand" "f#x,x#f")
12885 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12886 (pc)
12887 (label_ref (match_operand 3 "" ""))))
12888 (clobber (reg:CCFP FPSR_REG))
12889 (clobber (reg:CCFP FLAGS_REG))]
12890 "TARGET_MIX_SSE_I387
12891 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12892 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12893 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12894 "#")
12895
12896 (define_insn "*fp_jcc_2_sse"
12897 [(set (pc)
12898 (if_then_else (match_operator 0 "comparison_operator"
12899 [(match_operand 1 "register_operand" "x")
12900 (match_operand 2 "nonimmediate_operand" "xm")])
12901 (pc)
12902 (label_ref (match_operand 3 "" ""))))
12903 (clobber (reg:CCFP FPSR_REG))
12904 (clobber (reg:CCFP FLAGS_REG))]
12905 "TARGET_SSE_MATH
12906 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12907 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12908 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12909 "#")
12910
12911 (define_insn "*fp_jcc_2_387"
12912 [(set (pc)
12913 (if_then_else (match_operator 0 "comparison_operator"
12914 [(match_operand 1 "register_operand" "f")
12915 (match_operand 2 "register_operand" "f")])
12916 (pc)
12917 (label_ref (match_operand 3 "" ""))))
12918 (clobber (reg:CCFP FPSR_REG))
12919 (clobber (reg:CCFP FLAGS_REG))]
12920 "TARGET_CMOVE && TARGET_80387
12921 && FLOAT_MODE_P (GET_MODE (operands[1]))
12922 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12923 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12924 "#")
12925
12926 (define_insn "*fp_jcc_3_387"
12927 [(set (pc)
12928 (if_then_else (match_operator 0 "comparison_operator"
12929 [(match_operand 1 "register_operand" "f")
12930 (match_operand 2 "nonimmediate_operand" "fm")])
12931 (label_ref (match_operand 3 "" ""))
12932 (pc)))
12933 (clobber (reg:CCFP FPSR_REG))
12934 (clobber (reg:CCFP FLAGS_REG))
12935 (clobber (match_scratch:HI 4 "=a"))]
12936 "TARGET_80387
12937 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12938 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12939 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12940 && SELECT_CC_MODE (GET_CODE (operands[0]),
12941 operands[1], operands[2]) == CCFPmode
12942 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12943 "#")
12944
12945 (define_insn "*fp_jcc_4_387"
12946 [(set (pc)
12947 (if_then_else (match_operator 0 "comparison_operator"
12948 [(match_operand 1 "register_operand" "f")
12949 (match_operand 2 "nonimmediate_operand" "fm")])
12950 (pc)
12951 (label_ref (match_operand 3 "" ""))))
12952 (clobber (reg:CCFP FPSR_REG))
12953 (clobber (reg:CCFP FLAGS_REG))
12954 (clobber (match_scratch:HI 4 "=a"))]
12955 "TARGET_80387
12956 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12957 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12958 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12959 && SELECT_CC_MODE (GET_CODE (operands[0]),
12960 operands[1], operands[2]) == CCFPmode
12961 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12962 "#")
12963
12964 (define_insn "*fp_jcc_5_387"
12965 [(set (pc)
12966 (if_then_else (match_operator 0 "comparison_operator"
12967 [(match_operand 1 "register_operand" "f")
12968 (match_operand 2 "register_operand" "f")])
12969 (label_ref (match_operand 3 "" ""))
12970 (pc)))
12971 (clobber (reg:CCFP FPSR_REG))
12972 (clobber (reg:CCFP FLAGS_REG))
12973 (clobber (match_scratch:HI 4 "=a"))]
12974 "TARGET_80387
12975 && FLOAT_MODE_P (GET_MODE (operands[1]))
12976 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12977 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12978 "#")
12979
12980 (define_insn "*fp_jcc_6_387"
12981 [(set (pc)
12982 (if_then_else (match_operator 0 "comparison_operator"
12983 [(match_operand 1 "register_operand" "f")
12984 (match_operand 2 "register_operand" "f")])
12985 (pc)
12986 (label_ref (match_operand 3 "" ""))))
12987 (clobber (reg:CCFP FPSR_REG))
12988 (clobber (reg:CCFP FLAGS_REG))
12989 (clobber (match_scratch:HI 4 "=a"))]
12990 "TARGET_80387
12991 && FLOAT_MODE_P (GET_MODE (operands[1]))
12992 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12993 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12994 "#")
12995
12996 (define_insn "*fp_jcc_7_387"
12997 [(set (pc)
12998 (if_then_else (match_operator 0 "comparison_operator"
12999 [(match_operand 1 "register_operand" "f")
13000 (match_operand 2 "const_double_operand" "C")])
13001 (label_ref (match_operand 3 "" ""))
13002 (pc)))
13003 (clobber (reg:CCFP FPSR_REG))
13004 (clobber (reg:CCFP FLAGS_REG))
13005 (clobber (match_scratch:HI 4 "=a"))]
13006 "TARGET_80387
13007 && FLOAT_MODE_P (GET_MODE (operands[1]))
13008 && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13009 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13010 && SELECT_CC_MODE (GET_CODE (operands[0]),
13011 operands[1], operands[2]) == CCFPmode
13012 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13013 "#")
13014
13015 ;; The order of operands in *fp_jcc_8 is forced by combine in
13016 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13017 ;; with a precedence over other operators and is always put in the first
13018 ;; place. Swap condition and operands to match ficom instruction.
13019
13020 (define_insn "*fp_jcc_8_387"
13021 [(set (pc)
13022 (if_then_else (match_operator 0 "comparison_operator"
13023 [(match_operator 1 "float_operator"
13024 [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13025 (match_operand 3 "register_operand" "f,f")])
13026 (label_ref (match_operand 4 "" ""))
13027 (pc)))
13028 (clobber (reg:CCFP FPSR_REG))
13029 (clobber (reg:CCFP FLAGS_REG))
13030 (clobber (match_scratch:HI 5 "=a,a"))]
13031 "TARGET_80387 && TARGET_USE_FIOP
13032 && FLOAT_MODE_P (GET_MODE (operands[3]))
13033 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13034 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13035 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13036 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13037 "#")
13038
13039 (define_split
13040 [(set (pc)
13041 (if_then_else (match_operator 0 "comparison_operator"
13042 [(match_operand 1 "register_operand" "")
13043 (match_operand 2 "nonimmediate_operand" "")])
13044 (match_operand 3 "" "")
13045 (match_operand 4 "" "")))
13046 (clobber (reg:CCFP FPSR_REG))
13047 (clobber (reg:CCFP FLAGS_REG))]
13048 "reload_completed"
13049 [(const_int 0)]
13050 {
13051 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13052 operands[3], operands[4], NULL_RTX, NULL_RTX);
13053 DONE;
13054 })
13055
13056 (define_split
13057 [(set (pc)
13058 (if_then_else (match_operator 0 "comparison_operator"
13059 [(match_operand 1 "register_operand" "")
13060 (match_operand 2 "general_operand" "")])
13061 (match_operand 3 "" "")
13062 (match_operand 4 "" "")))
13063 (clobber (reg:CCFP FPSR_REG))
13064 (clobber (reg:CCFP FLAGS_REG))
13065 (clobber (match_scratch:HI 5 "=a"))]
13066 "reload_completed"
13067 [(const_int 0)]
13068 {
13069 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13070 operands[3], operands[4], operands[5], NULL_RTX);
13071 DONE;
13072 })
13073
13074 (define_split
13075 [(set (pc)
13076 (if_then_else (match_operator 0 "comparison_operator"
13077 [(match_operator 1 "float_operator"
13078 [(match_operand:SI 2 "memory_operand" "")])
13079 (match_operand 3 "register_operand" "")])
13080 (match_operand 4 "" "")
13081 (match_operand 5 "" "")))
13082 (clobber (reg:CCFP FPSR_REG))
13083 (clobber (reg:CCFP FLAGS_REG))
13084 (clobber (match_scratch:HI 6 "=a"))]
13085 "reload_completed"
13086 [(const_int 0)]
13087 {
13088 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13089 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13090 operands[3], operands[7],
13091 operands[4], operands[5], operands[6], NULL_RTX);
13092 DONE;
13093 })
13094
13095 ;; %%% Kill this when reload knows how to do it.
13096 (define_split
13097 [(set (pc)
13098 (if_then_else (match_operator 0 "comparison_operator"
13099 [(match_operator 1 "float_operator"
13100 [(match_operand:SI 2 "register_operand" "")])
13101 (match_operand 3 "register_operand" "")])
13102 (match_operand 4 "" "")
13103 (match_operand 5 "" "")))
13104 (clobber (reg:CCFP FPSR_REG))
13105 (clobber (reg:CCFP FLAGS_REG))
13106 (clobber (match_scratch:HI 6 "=a"))]
13107 "reload_completed"
13108 [(const_int 0)]
13109 {
13110 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13111 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13112 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13113 operands[3], operands[7],
13114 operands[4], operands[5], operands[6], operands[2]);
13115 DONE;
13116 })
13117 \f
13118 ;; Unconditional and other jump instructions
13119
13120 (define_insn "jump"
13121 [(set (pc)
13122 (label_ref (match_operand 0 "" "")))]
13123 ""
13124 "jmp\t%l0"
13125 [(set_attr "type" "ibr")
13126 (set (attr "length")
13127 (if_then_else (and (ge (minus (match_dup 0) (pc))
13128 (const_int -126))
13129 (lt (minus (match_dup 0) (pc))
13130 (const_int 128)))
13131 (const_int 2)
13132 (const_int 5)))
13133 (set_attr "modrm" "0")])
13134
13135 (define_expand "indirect_jump"
13136 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13137 ""
13138 "")
13139
13140 (define_insn "*indirect_jump"
13141 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13142 "!TARGET_64BIT"
13143 "jmp\t%A0"
13144 [(set_attr "type" "ibr")
13145 (set_attr "length_immediate" "0")])
13146
13147 (define_insn "*indirect_jump_rtx64"
13148 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13149 "TARGET_64BIT"
13150 "jmp\t%A0"
13151 [(set_attr "type" "ibr")
13152 (set_attr "length_immediate" "0")])
13153
13154 (define_expand "tablejump"
13155 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13156 (use (label_ref (match_operand 1 "" "")))])]
13157 ""
13158 {
13159 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13160 relative. Convert the relative address to an absolute address. */
13161 if (flag_pic)
13162 {
13163 rtx op0, op1;
13164 enum rtx_code code;
13165
13166 if (TARGET_64BIT)
13167 {
13168 code = PLUS;
13169 op0 = operands[0];
13170 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13171 }
13172 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13173 {
13174 code = PLUS;
13175 op0 = operands[0];
13176 op1 = pic_offset_table_rtx;
13177 }
13178 else
13179 {
13180 code = MINUS;
13181 op0 = pic_offset_table_rtx;
13182 op1 = operands[0];
13183 }
13184
13185 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13186 OPTAB_DIRECT);
13187 }
13188 })
13189
13190 (define_insn "*tablejump_1"
13191 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13192 (use (label_ref (match_operand 1 "" "")))]
13193 "!TARGET_64BIT"
13194 "jmp\t%A0"
13195 [(set_attr "type" "ibr")
13196 (set_attr "length_immediate" "0")])
13197
13198 (define_insn "*tablejump_1_rtx64"
13199 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13200 (use (label_ref (match_operand 1 "" "")))]
13201 "TARGET_64BIT"
13202 "jmp\t%A0"
13203 [(set_attr "type" "ibr")
13204 (set_attr "length_immediate" "0")])
13205 \f
13206 ;; Loop instruction
13207 ;;
13208 ;; This is all complicated by the fact that since this is a jump insn
13209 ;; we must handle our own reloads.
13210
13211 (define_expand "doloop_end"
13212 [(use (match_operand 0 "" "")) ; loop pseudo
13213 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13214 (use (match_operand 2 "" "")) ; max iterations
13215 (use (match_operand 3 "" "")) ; loop level
13216 (use (match_operand 4 "" ""))] ; label
13217 "!TARGET_64BIT && TARGET_USE_LOOP"
13218 "
13219 {
13220 /* Only use cloop on innermost loops. */
13221 if (INTVAL (operands[3]) > 1)
13222 FAIL;
13223 if (GET_MODE (operands[0]) != SImode)
13224 FAIL;
13225 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13226 operands[0]));
13227 DONE;
13228 }")
13229
13230 (define_insn "doloop_end_internal"
13231 [(set (pc)
13232 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13233 (const_int 1))
13234 (label_ref (match_operand 0 "" ""))
13235 (pc)))
13236 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13237 (plus:SI (match_dup 1)
13238 (const_int -1)))
13239 (clobber (match_scratch:SI 3 "=X,X,r"))
13240 (clobber (reg:CC FLAGS_REG))]
13241 "!TARGET_64BIT && TARGET_USE_LOOP
13242 && (reload_in_progress || reload_completed
13243 || register_operand (operands[2], VOIDmode))"
13244 {
13245 if (which_alternative != 0)
13246 return "#";
13247 if (get_attr_length (insn) == 2)
13248 return "%+loop\t%l0";
13249 else
13250 return "dec{l}\t%1\;%+jne\t%l0";
13251 }
13252 [(set (attr "length")
13253 (if_then_else (and (eq_attr "alternative" "0")
13254 (and (ge (minus (match_dup 0) (pc))
13255 (const_int -126))
13256 (lt (minus (match_dup 0) (pc))
13257 (const_int 128))))
13258 (const_int 2)
13259 (const_int 16)))
13260 ;; We don't know the type before shorten branches. Optimistically expect
13261 ;; the loop instruction to match.
13262 (set (attr "type") (const_string "ibr"))])
13263
13264 (define_split
13265 [(set (pc)
13266 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13267 (const_int 1))
13268 (match_operand 0 "" "")
13269 (pc)))
13270 (set (match_dup 1)
13271 (plus:SI (match_dup 1)
13272 (const_int -1)))
13273 (clobber (match_scratch:SI 2 ""))
13274 (clobber (reg:CC FLAGS_REG))]
13275 "!TARGET_64BIT && TARGET_USE_LOOP
13276 && reload_completed
13277 && REGNO (operands[1]) != 2"
13278 [(parallel [(set (reg:CCZ FLAGS_REG)
13279 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13280 (const_int 0)))
13281 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13282 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13283 (match_dup 0)
13284 (pc)))]
13285 "")
13286
13287 (define_split
13288 [(set (pc)
13289 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13290 (const_int 1))
13291 (match_operand 0 "" "")
13292 (pc)))
13293 (set (match_operand:SI 2 "nonimmediate_operand" "")
13294 (plus:SI (match_dup 1)
13295 (const_int -1)))
13296 (clobber (match_scratch:SI 3 ""))
13297 (clobber (reg:CC FLAGS_REG))]
13298 "!TARGET_64BIT && TARGET_USE_LOOP
13299 && reload_completed
13300 && (! REG_P (operands[2])
13301 || ! rtx_equal_p (operands[1], operands[2]))"
13302 [(set (match_dup 3) (match_dup 1))
13303 (parallel [(set (reg:CCZ FLAGS_REG)
13304 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13305 (const_int 0)))
13306 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13307 (set (match_dup 2) (match_dup 3))
13308 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13309 (match_dup 0)
13310 (pc)))]
13311 "")
13312
13313 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13314
13315 (define_peephole2
13316 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13317 (set (match_operand:QI 1 "register_operand" "")
13318 (match_operator:QI 2 "ix86_comparison_operator"
13319 [(reg FLAGS_REG) (const_int 0)]))
13320 (set (match_operand 3 "q_regs_operand" "")
13321 (zero_extend (match_dup 1)))]
13322 "(peep2_reg_dead_p (3, operands[1])
13323 || operands_match_p (operands[1], operands[3]))
13324 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13325 [(set (match_dup 4) (match_dup 0))
13326 (set (strict_low_part (match_dup 5))
13327 (match_dup 2))]
13328 {
13329 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13330 operands[5] = gen_lowpart (QImode, operands[3]);
13331 ix86_expand_clear (operands[3]);
13332 })
13333
13334 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13335
13336 (define_peephole2
13337 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13338 (set (match_operand:QI 1 "register_operand" "")
13339 (match_operator:QI 2 "ix86_comparison_operator"
13340 [(reg FLAGS_REG) (const_int 0)]))
13341 (parallel [(set (match_operand 3 "q_regs_operand" "")
13342 (zero_extend (match_dup 1)))
13343 (clobber (reg:CC FLAGS_REG))])]
13344 "(peep2_reg_dead_p (3, operands[1])
13345 || operands_match_p (operands[1], operands[3]))
13346 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13347 [(set (match_dup 4) (match_dup 0))
13348 (set (strict_low_part (match_dup 5))
13349 (match_dup 2))]
13350 {
13351 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13352 operands[5] = gen_lowpart (QImode, operands[3]);
13353 ix86_expand_clear (operands[3]);
13354 })
13355 \f
13356 ;; Call instructions.
13357
13358 ;; The predicates normally associated with named expanders are not properly
13359 ;; checked for calls. This is a bug in the generic code, but it isn't that
13360 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13361
13362 ;; Call subroutine returning no value.
13363
13364 (define_expand "call_pop"
13365 [(parallel [(call (match_operand:QI 0 "" "")
13366 (match_operand:SI 1 "" ""))
13367 (set (reg:SI SP_REG)
13368 (plus:SI (reg:SI SP_REG)
13369 (match_operand:SI 3 "" "")))])]
13370 "!TARGET_64BIT"
13371 {
13372 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13373 DONE;
13374 })
13375
13376 (define_insn "*call_pop_0"
13377 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13378 (match_operand:SI 1 "" ""))
13379 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13380 (match_operand:SI 2 "immediate_operand" "")))]
13381 "!TARGET_64BIT"
13382 {
13383 if (SIBLING_CALL_P (insn))
13384 return "jmp\t%P0";
13385 else
13386 return "call\t%P0";
13387 }
13388 [(set_attr "type" "call")])
13389
13390 (define_insn "*call_pop_1"
13391 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13392 (match_operand:SI 1 "" ""))
13393 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13394 (match_operand:SI 2 "immediate_operand" "i")))]
13395 "!TARGET_64BIT"
13396 {
13397 if (constant_call_address_operand (operands[0], Pmode))
13398 {
13399 if (SIBLING_CALL_P (insn))
13400 return "jmp\t%P0";
13401 else
13402 return "call\t%P0";
13403 }
13404 if (SIBLING_CALL_P (insn))
13405 return "jmp\t%A0";
13406 else
13407 return "call\t%A0";
13408 }
13409 [(set_attr "type" "call")])
13410
13411 (define_expand "call"
13412 [(call (match_operand:QI 0 "" "")
13413 (match_operand 1 "" ""))
13414 (use (match_operand 2 "" ""))]
13415 ""
13416 {
13417 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13418 DONE;
13419 })
13420
13421 (define_expand "sibcall"
13422 [(call (match_operand:QI 0 "" "")
13423 (match_operand 1 "" ""))
13424 (use (match_operand 2 "" ""))]
13425 ""
13426 {
13427 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13428 DONE;
13429 })
13430
13431 (define_insn "*call_0"
13432 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13433 (match_operand 1 "" ""))]
13434 ""
13435 {
13436 if (SIBLING_CALL_P (insn))
13437 return "jmp\t%P0";
13438 else
13439 return "call\t%P0";
13440 }
13441 [(set_attr "type" "call")])
13442
13443 (define_insn "*call_1"
13444 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13445 (match_operand 1 "" ""))]
13446 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13447 {
13448 if (constant_call_address_operand (operands[0], Pmode))
13449 return "call\t%P0";
13450 return "call\t%A0";
13451 }
13452 [(set_attr "type" "call")])
13453
13454 (define_insn "*sibcall_1"
13455 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13456 (match_operand 1 "" ""))]
13457 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13458 {
13459 if (constant_call_address_operand (operands[0], Pmode))
13460 return "jmp\t%P0";
13461 return "jmp\t%A0";
13462 }
13463 [(set_attr "type" "call")])
13464
13465 (define_insn "*call_1_rex64"
13466 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13467 (match_operand 1 "" ""))]
13468 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13469 {
13470 if (constant_call_address_operand (operands[0], Pmode))
13471 return "call\t%P0";
13472 return "call\t%A0";
13473 }
13474 [(set_attr "type" "call")])
13475
13476 (define_insn "*sibcall_1_rex64"
13477 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13478 (match_operand 1 "" ""))]
13479 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13480 "jmp\t%P0"
13481 [(set_attr "type" "call")])
13482
13483 (define_insn "*sibcall_1_rex64_v"
13484 [(call (mem:QI (reg:DI 40))
13485 (match_operand 0 "" ""))]
13486 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13487 "jmp\t*%%r11"
13488 [(set_attr "type" "call")])
13489
13490
13491 ;; Call subroutine, returning value in operand 0
13492
13493 (define_expand "call_value_pop"
13494 [(parallel [(set (match_operand 0 "" "")
13495 (call (match_operand:QI 1 "" "")
13496 (match_operand:SI 2 "" "")))
13497 (set (reg:SI SP_REG)
13498 (plus:SI (reg:SI SP_REG)
13499 (match_operand:SI 4 "" "")))])]
13500 "!TARGET_64BIT"
13501 {
13502 ix86_expand_call (operands[0], operands[1], operands[2],
13503 operands[3], operands[4], 0);
13504 DONE;
13505 })
13506
13507 (define_expand "call_value"
13508 [(set (match_operand 0 "" "")
13509 (call (match_operand:QI 1 "" "")
13510 (match_operand:SI 2 "" "")))
13511 (use (match_operand:SI 3 "" ""))]
13512 ;; Operand 2 not used on the i386.
13513 ""
13514 {
13515 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13516 DONE;
13517 })
13518
13519 (define_expand "sibcall_value"
13520 [(set (match_operand 0 "" "")
13521 (call (match_operand:QI 1 "" "")
13522 (match_operand:SI 2 "" "")))
13523 (use (match_operand:SI 3 "" ""))]
13524 ;; Operand 2 not used on the i386.
13525 ""
13526 {
13527 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13528 DONE;
13529 })
13530
13531 ;; Call subroutine returning any type.
13532
13533 (define_expand "untyped_call"
13534 [(parallel [(call (match_operand 0 "" "")
13535 (const_int 0))
13536 (match_operand 1 "" "")
13537 (match_operand 2 "" "")])]
13538 ""
13539 {
13540 int i;
13541
13542 /* In order to give reg-stack an easier job in validating two
13543 coprocessor registers as containing a possible return value,
13544 simply pretend the untyped call returns a complex long double
13545 value. */
13546
13547 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13548 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13549 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13550 NULL, 0);
13551
13552 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13553 {
13554 rtx set = XVECEXP (operands[2], 0, i);
13555 emit_move_insn (SET_DEST (set), SET_SRC (set));
13556 }
13557
13558 /* The optimizer does not know that the call sets the function value
13559 registers we stored in the result block. We avoid problems by
13560 claiming that all hard registers are used and clobbered at this
13561 point. */
13562 emit_insn (gen_blockage (const0_rtx));
13563
13564 DONE;
13565 })
13566 \f
13567 ;; Prologue and epilogue instructions
13568
13569 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13570 ;; all of memory. This blocks insns from being moved across this point.
13571
13572 (define_insn "blockage"
13573 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13574 ""
13575 ""
13576 [(set_attr "length" "0")])
13577
13578 ;; Insn emitted into the body of a function to return from a function.
13579 ;; This is only done if the function's epilogue is known to be simple.
13580 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13581
13582 (define_expand "return"
13583 [(return)]
13584 "ix86_can_use_return_insn_p ()"
13585 {
13586 if (current_function_pops_args)
13587 {
13588 rtx popc = GEN_INT (current_function_pops_args);
13589 emit_jump_insn (gen_return_pop_internal (popc));
13590 DONE;
13591 }
13592 })
13593
13594 (define_insn "return_internal"
13595 [(return)]
13596 "reload_completed"
13597 "ret"
13598 [(set_attr "length" "1")
13599 (set_attr "length_immediate" "0")
13600 (set_attr "modrm" "0")])
13601
13602 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13603 ;; instruction Athlon and K8 have.
13604
13605 (define_insn "return_internal_long"
13606 [(return)
13607 (unspec [(const_int 0)] UNSPEC_REP)]
13608 "reload_completed"
13609 "rep {;} ret"
13610 [(set_attr "length" "1")
13611 (set_attr "length_immediate" "0")
13612 (set_attr "prefix_rep" "1")
13613 (set_attr "modrm" "0")])
13614
13615 (define_insn "return_pop_internal"
13616 [(return)
13617 (use (match_operand:SI 0 "const_int_operand" ""))]
13618 "reload_completed"
13619 "ret\t%0"
13620 [(set_attr "length" "3")
13621 (set_attr "length_immediate" "2")
13622 (set_attr "modrm" "0")])
13623
13624 (define_insn "return_indirect_internal"
13625 [(return)
13626 (use (match_operand:SI 0 "register_operand" "r"))]
13627 "reload_completed"
13628 "jmp\t%A0"
13629 [(set_attr "type" "ibr")
13630 (set_attr "length_immediate" "0")])
13631
13632 (define_insn "nop"
13633 [(const_int 0)]
13634 ""
13635 "nop"
13636 [(set_attr "length" "1")
13637 (set_attr "length_immediate" "0")
13638 (set_attr "modrm" "0")])
13639
13640 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13641 ;; branch prediction penalty for the third jump in a 16-byte
13642 ;; block on K8.
13643
13644 (define_insn "align"
13645 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13646 ""
13647 {
13648 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13649 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13650 #else
13651 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13652 The align insn is used to avoid 3 jump instructions in the row to improve
13653 branch prediction and the benefits hardly outweight the cost of extra 8
13654 nops on the average inserted by full alignment pseudo operation. */
13655 #endif
13656 return "";
13657 }
13658 [(set_attr "length" "16")])
13659
13660 (define_expand "prologue"
13661 [(const_int 1)]
13662 ""
13663 "ix86_expand_prologue (); DONE;")
13664
13665 (define_insn "set_got"
13666 [(set (match_operand:SI 0 "register_operand" "=r")
13667 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13668 (clobber (reg:CC FLAGS_REG))]
13669 "!TARGET_64BIT"
13670 { return output_set_got (operands[0]); }
13671 [(set_attr "type" "multi")
13672 (set_attr "length" "12")])
13673
13674 (define_expand "epilogue"
13675 [(const_int 1)]
13676 ""
13677 "ix86_expand_epilogue (1); DONE;")
13678
13679 (define_expand "sibcall_epilogue"
13680 [(const_int 1)]
13681 ""
13682 "ix86_expand_epilogue (0); DONE;")
13683
13684 (define_expand "eh_return"
13685 [(use (match_operand 0 "register_operand" ""))]
13686 ""
13687 {
13688 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13689
13690 /* Tricky bit: we write the address of the handler to which we will
13691 be returning into someone else's stack frame, one word below the
13692 stack address we wish to restore. */
13693 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13694 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13695 tmp = gen_rtx_MEM (Pmode, tmp);
13696 emit_move_insn (tmp, ra);
13697
13698 if (Pmode == SImode)
13699 emit_jump_insn (gen_eh_return_si (sa));
13700 else
13701 emit_jump_insn (gen_eh_return_di (sa));
13702 emit_barrier ();
13703 DONE;
13704 })
13705
13706 (define_insn_and_split "eh_return_si"
13707 [(set (pc)
13708 (unspec [(match_operand:SI 0 "register_operand" "c")]
13709 UNSPEC_EH_RETURN))]
13710 "!TARGET_64BIT"
13711 "#"
13712 "reload_completed"
13713 [(const_int 1)]
13714 "ix86_expand_epilogue (2); DONE;")
13715
13716 (define_insn_and_split "eh_return_di"
13717 [(set (pc)
13718 (unspec [(match_operand:DI 0 "register_operand" "c")]
13719 UNSPEC_EH_RETURN))]
13720 "TARGET_64BIT"
13721 "#"
13722 "reload_completed"
13723 [(const_int 1)]
13724 "ix86_expand_epilogue (2); DONE;")
13725
13726 (define_insn "leave"
13727 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13728 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13729 (clobber (mem:BLK (scratch)))]
13730 "!TARGET_64BIT"
13731 "leave"
13732 [(set_attr "type" "leave")])
13733
13734 (define_insn "leave_rex64"
13735 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13736 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13737 (clobber (mem:BLK (scratch)))]
13738 "TARGET_64BIT"
13739 "leave"
13740 [(set_attr "type" "leave")])
13741 \f
13742 (define_expand "ffssi2"
13743 [(parallel
13744 [(set (match_operand:SI 0 "register_operand" "")
13745 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13746 (clobber (match_scratch:SI 2 ""))
13747 (clobber (reg:CC FLAGS_REG))])]
13748 ""
13749 "")
13750
13751 (define_insn_and_split "*ffs_cmove"
13752 [(set (match_operand:SI 0 "register_operand" "=r")
13753 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13754 (clobber (match_scratch:SI 2 "=&r"))
13755 (clobber (reg:CC FLAGS_REG))]
13756 "TARGET_CMOVE"
13757 "#"
13758 "&& reload_completed"
13759 [(set (match_dup 2) (const_int -1))
13760 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13761 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13762 (set (match_dup 0) (if_then_else:SI
13763 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13764 (match_dup 2)
13765 (match_dup 0)))
13766 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13767 (clobber (reg:CC FLAGS_REG))])]
13768 "")
13769
13770 (define_insn_and_split "*ffs_no_cmove"
13771 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13772 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13773 (clobber (match_scratch:SI 2 "=&q"))
13774 (clobber (reg:CC FLAGS_REG))]
13775 ""
13776 "#"
13777 "reload_completed"
13778 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13779 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13780 (set (strict_low_part (match_dup 3))
13781 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13782 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13783 (clobber (reg:CC FLAGS_REG))])
13784 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13785 (clobber (reg:CC FLAGS_REG))])
13786 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13787 (clobber (reg:CC FLAGS_REG))])]
13788 {
13789 operands[3] = gen_lowpart (QImode, operands[2]);
13790 ix86_expand_clear (operands[2]);
13791 })
13792
13793 (define_insn "*ffssi_1"
13794 [(set (reg:CCZ FLAGS_REG)
13795 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13796 (const_int 0)))
13797 (set (match_operand:SI 0 "register_operand" "=r")
13798 (ctz:SI (match_dup 1)))]
13799 ""
13800 "bsf{l}\t{%1, %0|%0, %1}"
13801 [(set_attr "prefix_0f" "1")])
13802
13803 (define_expand "ffsdi2"
13804 [(parallel
13805 [(set (match_operand:DI 0 "register_operand" "")
13806 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13807 (clobber (match_scratch:DI 2 ""))
13808 (clobber (reg:CC FLAGS_REG))])]
13809 "TARGET_64BIT && TARGET_CMOVE"
13810 "")
13811
13812 (define_insn_and_split "*ffs_rex64"
13813 [(set (match_operand:DI 0 "register_operand" "=r")
13814 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13815 (clobber (match_scratch:DI 2 "=&r"))
13816 (clobber (reg:CC FLAGS_REG))]
13817 "TARGET_64BIT && TARGET_CMOVE"
13818 "#"
13819 "&& reload_completed"
13820 [(set (match_dup 2) (const_int -1))
13821 (parallel [(set (reg:CCZ FLAGS_REG)
13822 (compare:CCZ (match_dup 1) (const_int 0)))
13823 (set (match_dup 0) (ctz:DI (match_dup 1)))])
13824 (set (match_dup 0) (if_then_else:DI
13825 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13826 (match_dup 2)
13827 (match_dup 0)))
13828 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13829 (clobber (reg:CC FLAGS_REG))])]
13830 "")
13831
13832 (define_insn "*ffsdi_1"
13833 [(set (reg:CCZ FLAGS_REG)
13834 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13835 (const_int 0)))
13836 (set (match_operand:DI 0 "register_operand" "=r")
13837 (ctz:DI (match_dup 1)))]
13838 "TARGET_64BIT"
13839 "bsf{q}\t{%1, %0|%0, %1}"
13840 [(set_attr "prefix_0f" "1")])
13841
13842 (define_insn "ctzsi2"
13843 [(set (match_operand:SI 0 "register_operand" "=r")
13844 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13845 (clobber (reg:CC FLAGS_REG))]
13846 ""
13847 "bsf{l}\t{%1, %0|%0, %1}"
13848 [(set_attr "prefix_0f" "1")])
13849
13850 (define_insn "ctzdi2"
13851 [(set (match_operand:DI 0 "register_operand" "=r")
13852 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13853 (clobber (reg:CC FLAGS_REG))]
13854 "TARGET_64BIT"
13855 "bsf{q}\t{%1, %0|%0, %1}"
13856 [(set_attr "prefix_0f" "1")])
13857
13858 (define_expand "clzsi2"
13859 [(parallel
13860 [(set (match_operand:SI 0 "register_operand" "")
13861 (minus:SI (const_int 31)
13862 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13863 (clobber (reg:CC FLAGS_REG))])
13864 (parallel
13865 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13866 (clobber (reg:CC FLAGS_REG))])]
13867 ""
13868 "")
13869
13870 (define_insn "*bsr"
13871 [(set (match_operand:SI 0 "register_operand" "=r")
13872 (minus:SI (const_int 31)
13873 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13874 (clobber (reg:CC FLAGS_REG))]
13875 ""
13876 "bsr{l}\t{%1, %0|%0, %1}"
13877 [(set_attr "prefix_0f" "1")])
13878
13879 (define_expand "clzdi2"
13880 [(parallel
13881 [(set (match_operand:DI 0 "register_operand" "")
13882 (minus:DI (const_int 63)
13883 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13884 (clobber (reg:CC FLAGS_REG))])
13885 (parallel
13886 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13887 (clobber (reg:CC FLAGS_REG))])]
13888 "TARGET_64BIT"
13889 "")
13890
13891 (define_insn "*bsr_rex64"
13892 [(set (match_operand:DI 0 "register_operand" "=r")
13893 (minus:DI (const_int 63)
13894 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13895 (clobber (reg:CC FLAGS_REG))]
13896 "TARGET_64BIT"
13897 "bsr{q}\t{%1, %0|%0, %1}"
13898 [(set_attr "prefix_0f" "1")])
13899 \f
13900 ;; Thread-local storage patterns for ELF.
13901 ;;
13902 ;; Note that these code sequences must appear exactly as shown
13903 ;; in order to allow linker relaxation.
13904
13905 (define_insn "*tls_global_dynamic_32_gnu"
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_GNU_TLS"
13915 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13916 [(set_attr "type" "multi")
13917 (set_attr "length" "12")])
13918
13919 (define_insn "*tls_global_dynamic_32_sun"
13920 [(set (match_operand:SI 0 "register_operand" "=a")
13921 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13922 (match_operand:SI 2 "tls_symbolic_operand" "")
13923 (match_operand:SI 3 "call_insn_operand" "")]
13924 UNSPEC_TLS_GD))
13925 (clobber (match_scratch:SI 4 "=d"))
13926 (clobber (match_scratch:SI 5 "=c"))
13927 (clobber (reg:CC FLAGS_REG))]
13928 "!TARGET_64BIT && TARGET_SUN_TLS"
13929 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13930 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13931 [(set_attr "type" "multi")
13932 (set_attr "length" "14")])
13933
13934 (define_expand "tls_global_dynamic_32"
13935 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13936 (unspec:SI
13937 [(match_dup 2)
13938 (match_operand:SI 1 "tls_symbolic_operand" "")
13939 (match_dup 3)]
13940 UNSPEC_TLS_GD))
13941 (clobber (match_scratch:SI 4 ""))
13942 (clobber (match_scratch:SI 5 ""))
13943 (clobber (reg:CC FLAGS_REG))])]
13944 ""
13945 {
13946 if (flag_pic)
13947 operands[2] = pic_offset_table_rtx;
13948 else
13949 {
13950 operands[2] = gen_reg_rtx (Pmode);
13951 emit_insn (gen_set_got (operands[2]));
13952 }
13953 operands[3] = ix86_tls_get_addr ();
13954 })
13955
13956 (define_insn "*tls_global_dynamic_64"
13957 [(set (match_operand:DI 0 "register_operand" "=a")
13958 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13959 (match_operand:DI 3 "" "")))
13960 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13961 UNSPEC_TLS_GD)]
13962 "TARGET_64BIT"
13963 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13964 [(set_attr "type" "multi")
13965 (set_attr "length" "16")])
13966
13967 (define_expand "tls_global_dynamic_64"
13968 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13969 (call (mem:QI (match_dup 2)) (const_int 0)))
13970 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13971 UNSPEC_TLS_GD)])]
13972 ""
13973 {
13974 operands[2] = ix86_tls_get_addr ();
13975 })
13976
13977 (define_insn "*tls_local_dynamic_base_32_gnu"
13978 [(set (match_operand:SI 0 "register_operand" "=a")
13979 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13980 (match_operand:SI 2 "call_insn_operand" "")]
13981 UNSPEC_TLS_LD_BASE))
13982 (clobber (match_scratch:SI 3 "=d"))
13983 (clobber (match_scratch:SI 4 "=c"))
13984 (clobber (reg:CC FLAGS_REG))]
13985 "!TARGET_64BIT && TARGET_GNU_TLS"
13986 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13987 [(set_attr "type" "multi")
13988 (set_attr "length" "11")])
13989
13990 (define_insn "*tls_local_dynamic_base_32_sun"
13991 [(set (match_operand:SI 0 "register_operand" "=a")
13992 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13993 (match_operand:SI 2 "call_insn_operand" "")]
13994 UNSPEC_TLS_LD_BASE))
13995 (clobber (match_scratch:SI 3 "=d"))
13996 (clobber (match_scratch:SI 4 "=c"))
13997 (clobber (reg:CC FLAGS_REG))]
13998 "!TARGET_64BIT && TARGET_SUN_TLS"
13999 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14000 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14001 [(set_attr "type" "multi")
14002 (set_attr "length" "13")])
14003
14004 (define_expand "tls_local_dynamic_base_32"
14005 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14006 (unspec:SI [(match_dup 1) (match_dup 2)]
14007 UNSPEC_TLS_LD_BASE))
14008 (clobber (match_scratch:SI 3 ""))
14009 (clobber (match_scratch:SI 4 ""))
14010 (clobber (reg:CC FLAGS_REG))])]
14011 ""
14012 {
14013 if (flag_pic)
14014 operands[1] = pic_offset_table_rtx;
14015 else
14016 {
14017 operands[1] = gen_reg_rtx (Pmode);
14018 emit_insn (gen_set_got (operands[1]));
14019 }
14020 operands[2] = ix86_tls_get_addr ();
14021 })
14022
14023 (define_insn "*tls_local_dynamic_base_64"
14024 [(set (match_operand:DI 0 "register_operand" "=a")
14025 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14026 (match_operand:DI 2 "" "")))
14027 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14028 "TARGET_64BIT"
14029 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14030 [(set_attr "type" "multi")
14031 (set_attr "length" "12")])
14032
14033 (define_expand "tls_local_dynamic_base_64"
14034 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14035 (call (mem:QI (match_dup 1)) (const_int 0)))
14036 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14037 ""
14038 {
14039 operands[1] = ix86_tls_get_addr ();
14040 })
14041
14042 ;; Local dynamic of a single variable is a lose. Show combine how
14043 ;; to convert that back to global dynamic.
14044
14045 (define_insn_and_split "*tls_local_dynamic_32_once"
14046 [(set (match_operand:SI 0 "register_operand" "=a")
14047 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14048 (match_operand:SI 2 "call_insn_operand" "")]
14049 UNSPEC_TLS_LD_BASE)
14050 (const:SI (unspec:SI
14051 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14052 UNSPEC_DTPOFF))))
14053 (clobber (match_scratch:SI 4 "=d"))
14054 (clobber (match_scratch:SI 5 "=c"))
14055 (clobber (reg:CC FLAGS_REG))]
14056 ""
14057 "#"
14058 ""
14059 [(parallel [(set (match_dup 0)
14060 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14061 UNSPEC_TLS_GD))
14062 (clobber (match_dup 4))
14063 (clobber (match_dup 5))
14064 (clobber (reg:CC FLAGS_REG))])]
14065 "")
14066
14067 ;; Load and add the thread base pointer from %gs:0.
14068
14069 (define_insn "*load_tp_si"
14070 [(set (match_operand:SI 0 "register_operand" "=r")
14071 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14072 "!TARGET_64BIT"
14073 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14074 [(set_attr "type" "imov")
14075 (set_attr "modrm" "0")
14076 (set_attr "length" "7")
14077 (set_attr "memory" "load")
14078 (set_attr "imm_disp" "false")])
14079
14080 (define_insn "*add_tp_si"
14081 [(set (match_operand:SI 0 "register_operand" "=r")
14082 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14083 (match_operand:SI 1 "register_operand" "0")))
14084 (clobber (reg:CC FLAGS_REG))]
14085 "!TARGET_64BIT"
14086 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14087 [(set_attr "type" "alu")
14088 (set_attr "modrm" "0")
14089 (set_attr "length" "7")
14090 (set_attr "memory" "load")
14091 (set_attr "imm_disp" "false")])
14092
14093 (define_insn "*load_tp_di"
14094 [(set (match_operand:DI 0 "register_operand" "=r")
14095 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14096 "TARGET_64BIT"
14097 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14098 [(set_attr "type" "imov")
14099 (set_attr "modrm" "0")
14100 (set_attr "length" "7")
14101 (set_attr "memory" "load")
14102 (set_attr "imm_disp" "false")])
14103
14104 (define_insn "*add_tp_di"
14105 [(set (match_operand:DI 0 "register_operand" "=r")
14106 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14107 (match_operand:DI 1 "register_operand" "0")))
14108 (clobber (reg:CC FLAGS_REG))]
14109 "TARGET_64BIT"
14110 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14111 [(set_attr "type" "alu")
14112 (set_attr "modrm" "0")
14113 (set_attr "length" "7")
14114 (set_attr "memory" "load")
14115 (set_attr "imm_disp" "false")])
14116 \f
14117 ;; These patterns match the binary 387 instructions for addM3, subM3,
14118 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14119 ;; SFmode. The first is the normal insn, the second the same insn but
14120 ;; with one operand a conversion, and the third the same insn but with
14121 ;; the other operand a conversion. The conversion may be SFmode or
14122 ;; SImode if the target mode DFmode, but only SImode if the target mode
14123 ;; is SFmode.
14124
14125 ;; Gcc is slightly more smart about handling normal two address instructions
14126 ;; so use special patterns for add and mull.
14127
14128 (define_insn "*fop_sf_comm_mixed"
14129 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14130 (match_operator:SF 3 "binary_fp_operator"
14131 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14132 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14133 "TARGET_MIX_SSE_I387
14134 && COMMUTATIVE_ARITH_P (operands[3])
14135 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14136 "* return output_387_binary_op (insn, operands);"
14137 [(set (attr "type")
14138 (if_then_else (eq_attr "alternative" "1")
14139 (if_then_else (match_operand:SF 3 "mult_operator" "")
14140 (const_string "ssemul")
14141 (const_string "sseadd"))
14142 (if_then_else (match_operand:SF 3 "mult_operator" "")
14143 (const_string "fmul")
14144 (const_string "fop"))))
14145 (set_attr "mode" "SF")])
14146
14147 (define_insn "*fop_sf_comm_sse"
14148 [(set (match_operand:SF 0 "register_operand" "=x")
14149 (match_operator:SF 3 "binary_fp_operator"
14150 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14151 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14152 "TARGET_SSE_MATH
14153 && COMMUTATIVE_ARITH_P (operands[3])
14154 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14155 "* return output_387_binary_op (insn, operands);"
14156 [(set (attr "type")
14157 (if_then_else (match_operand:SF 3 "mult_operator" "")
14158 (const_string "ssemul")
14159 (const_string "sseadd")))
14160 (set_attr "mode" "SF")])
14161
14162 (define_insn "*fop_sf_comm_i387"
14163 [(set (match_operand:SF 0 "register_operand" "=f")
14164 (match_operator:SF 3 "binary_fp_operator"
14165 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14166 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14167 "TARGET_80387
14168 && COMMUTATIVE_ARITH_P (operands[3])
14169 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14170 "* return output_387_binary_op (insn, operands);"
14171 [(set (attr "type")
14172 (if_then_else (match_operand:SF 3 "mult_operator" "")
14173 (const_string "fmul")
14174 (const_string "fop")))
14175 (set_attr "mode" "SF")])
14176
14177 (define_insn "*fop_sf_1_mixed"
14178 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14179 (match_operator:SF 3 "binary_fp_operator"
14180 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14181 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14182 "TARGET_MIX_SSE_I387
14183 && !COMMUTATIVE_ARITH_P (operands[3])
14184 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14185 "* return output_387_binary_op (insn, operands);"
14186 [(set (attr "type")
14187 (cond [(and (eq_attr "alternative" "2")
14188 (match_operand:SF 3 "mult_operator" ""))
14189 (const_string "ssemul")
14190 (and (eq_attr "alternative" "2")
14191 (match_operand:SF 3 "div_operator" ""))
14192 (const_string "ssediv")
14193 (eq_attr "alternative" "2")
14194 (const_string "sseadd")
14195 (match_operand:SF 3 "mult_operator" "")
14196 (const_string "fmul")
14197 (match_operand:SF 3 "div_operator" "")
14198 (const_string "fdiv")
14199 ]
14200 (const_string "fop")))
14201 (set_attr "mode" "SF")])
14202
14203 (define_insn "*fop_sf_1_sse"
14204 [(set (match_operand:SF 0 "register_operand" "=x")
14205 (match_operator:SF 3 "binary_fp_operator"
14206 [(match_operand:SF 1 "register_operand" "0")
14207 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14208 "TARGET_SSE_MATH
14209 && !COMMUTATIVE_ARITH_P (operands[3])"
14210 "* return output_387_binary_op (insn, operands);"
14211 [(set (attr "type")
14212 (cond [(match_operand:SF 3 "mult_operator" "")
14213 (const_string "ssemul")
14214 (match_operand:SF 3 "div_operator" "")
14215 (const_string "ssediv")
14216 ]
14217 (const_string "sseadd")))
14218 (set_attr "mode" "SF")])
14219
14220 ;; This pattern is not fully shadowed by the pattern above.
14221 (define_insn "*fop_sf_1_i387"
14222 [(set (match_operand:SF 0 "register_operand" "=f,f")
14223 (match_operator:SF 3 "binary_fp_operator"
14224 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14225 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14226 "TARGET_80387 && !TARGET_SSE_MATH
14227 && !COMMUTATIVE_ARITH_P (operands[3])
14228 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14229 "* return output_387_binary_op (insn, operands);"
14230 [(set (attr "type")
14231 (cond [(match_operand:SF 3 "mult_operator" "")
14232 (const_string "fmul")
14233 (match_operand:SF 3 "div_operator" "")
14234 (const_string "fdiv")
14235 ]
14236 (const_string "fop")))
14237 (set_attr "mode" "SF")])
14238
14239
14240 ;; ??? Add SSE splitters for these!
14241 (define_insn "*fop_sf_2_i387"
14242 [(set (match_operand:SF 0 "register_operand" "=f,f")
14243 (match_operator:SF 3 "binary_fp_operator"
14244 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14245 (match_operand:SF 2 "register_operand" "0,0")]))]
14246 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14247 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14248 [(set (attr "type")
14249 (cond [(match_operand:SF 3 "mult_operator" "")
14250 (const_string "fmul")
14251 (match_operand:SF 3 "div_operator" "")
14252 (const_string "fdiv")
14253 ]
14254 (const_string "fop")))
14255 (set_attr "fp_int_src" "true")
14256 (set_attr "mode" "SI")])
14257
14258 (define_insn "*fop_sf_3_i387"
14259 [(set (match_operand:SF 0 "register_operand" "=f,f")
14260 (match_operator:SF 3 "binary_fp_operator"
14261 [(match_operand:SF 1 "register_operand" "0,0")
14262 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14263 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14264 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14265 [(set (attr "type")
14266 (cond [(match_operand:SF 3 "mult_operator" "")
14267 (const_string "fmul")
14268 (match_operand:SF 3 "div_operator" "")
14269 (const_string "fdiv")
14270 ]
14271 (const_string "fop")))
14272 (set_attr "fp_int_src" "true")
14273 (set_attr "mode" "SI")])
14274
14275 (define_insn "*fop_df_comm_mixed"
14276 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14277 (match_operator:DF 3 "binary_fp_operator"
14278 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14279 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14280 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14281 && COMMUTATIVE_ARITH_P (operands[3])
14282 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14283 "* return output_387_binary_op (insn, operands);"
14284 [(set (attr "type")
14285 (if_then_else (eq_attr "alternative" "1")
14286 (if_then_else (match_operand:SF 3 "mult_operator" "")
14287 (const_string "ssemul")
14288 (const_string "sseadd"))
14289 (if_then_else (match_operand:SF 3 "mult_operator" "")
14290 (const_string "fmul")
14291 (const_string "fop"))))
14292 (set_attr "mode" "DF")])
14293
14294 (define_insn "*fop_df_comm_sse"
14295 [(set (match_operand:DF 0 "register_operand" "=Y")
14296 (match_operator:DF 3 "binary_fp_operator"
14297 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14298 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14299 "TARGET_SSE2 && TARGET_SSE_MATH
14300 && COMMUTATIVE_ARITH_P (operands[3])
14301 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14302 "* return output_387_binary_op (insn, operands);"
14303 [(set (attr "type")
14304 (if_then_else (match_operand:SF 3 "mult_operator" "")
14305 (const_string "ssemul")
14306 (const_string "sseadd")))
14307 (set_attr "mode" "DF")])
14308
14309 (define_insn "*fop_df_comm_i387"
14310 [(set (match_operand:DF 0 "register_operand" "=f")
14311 (match_operator:DF 3 "binary_fp_operator"
14312 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14313 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14314 "TARGET_80387
14315 && COMMUTATIVE_ARITH_P (operands[3])
14316 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14317 "* return output_387_binary_op (insn, operands);"
14318 [(set (attr "type")
14319 (if_then_else (match_operand:SF 3 "mult_operator" "")
14320 (const_string "fmul")
14321 (const_string "fop")))
14322 (set_attr "mode" "DF")])
14323
14324 (define_insn "*fop_df_1_mixed"
14325 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14326 (match_operator:DF 3 "binary_fp_operator"
14327 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14328 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14329 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14330 && !COMMUTATIVE_ARITH_P (operands[3])
14331 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14332 "* return output_387_binary_op (insn, operands);"
14333 [(set (attr "type")
14334 (cond [(and (eq_attr "alternative" "2")
14335 (match_operand:SF 3 "mult_operator" ""))
14336 (const_string "ssemul")
14337 (and (eq_attr "alternative" "2")
14338 (match_operand:SF 3 "div_operator" ""))
14339 (const_string "ssediv")
14340 (eq_attr "alternative" "2")
14341 (const_string "sseadd")
14342 (match_operand:DF 3 "mult_operator" "")
14343 (const_string "fmul")
14344 (match_operand:DF 3 "div_operator" "")
14345 (const_string "fdiv")
14346 ]
14347 (const_string "fop")))
14348 (set_attr "mode" "DF")])
14349
14350 (define_insn "*fop_df_1_sse"
14351 [(set (match_operand:DF 0 "register_operand" "=Y")
14352 (match_operator:DF 3 "binary_fp_operator"
14353 [(match_operand:DF 1 "register_operand" "0")
14354 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14355 "TARGET_SSE2 && TARGET_SSE_MATH
14356 && !COMMUTATIVE_ARITH_P (operands[3])"
14357 "* return output_387_binary_op (insn, operands);"
14358 [(set_attr "mode" "DF")
14359 (set (attr "type")
14360 (cond [(match_operand:SF 3 "mult_operator" "")
14361 (const_string "ssemul")
14362 (match_operand:SF 3 "div_operator" "")
14363 (const_string "ssediv")
14364 ]
14365 (const_string "sseadd")))])
14366
14367 ;; This pattern is not fully shadowed by the pattern above.
14368 (define_insn "*fop_df_1_i387"
14369 [(set (match_operand:DF 0 "register_operand" "=f,f")
14370 (match_operator:DF 3 "binary_fp_operator"
14371 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14372 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14373 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14374 && !COMMUTATIVE_ARITH_P (operands[3])
14375 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14376 "* return output_387_binary_op (insn, operands);"
14377 [(set (attr "type")
14378 (cond [(match_operand:DF 3 "mult_operator" "")
14379 (const_string "fmul")
14380 (match_operand:DF 3 "div_operator" "")
14381 (const_string "fdiv")
14382 ]
14383 (const_string "fop")))
14384 (set_attr "mode" "DF")])
14385
14386 ;; ??? Add SSE splitters for these!
14387 (define_insn "*fop_df_2_i387"
14388 [(set (match_operand:DF 0 "register_operand" "=f,f")
14389 (match_operator:DF 3 "binary_fp_operator"
14390 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14391 (match_operand:DF 2 "register_operand" "0,0")]))]
14392 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14393 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14394 [(set (attr "type")
14395 (cond [(match_operand:DF 3 "mult_operator" "")
14396 (const_string "fmul")
14397 (match_operand:DF 3 "div_operator" "")
14398 (const_string "fdiv")
14399 ]
14400 (const_string "fop")))
14401 (set_attr "fp_int_src" "true")
14402 (set_attr "mode" "SI")])
14403
14404 (define_insn "*fop_df_3_i387"
14405 [(set (match_operand:DF 0 "register_operand" "=f,f")
14406 (match_operator:DF 3 "binary_fp_operator"
14407 [(match_operand:DF 1 "register_operand" "0,0")
14408 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14409 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14410 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14411 [(set (attr "type")
14412 (cond [(match_operand:DF 3 "mult_operator" "")
14413 (const_string "fmul")
14414 (match_operand:DF 3 "div_operator" "")
14415 (const_string "fdiv")
14416 ]
14417 (const_string "fop")))
14418 (set_attr "fp_int_src" "true")
14419 (set_attr "mode" "SI")])
14420
14421 (define_insn "*fop_df_4_i387"
14422 [(set (match_operand:DF 0 "register_operand" "=f,f")
14423 (match_operator:DF 3 "binary_fp_operator"
14424 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14425 (match_operand:DF 2 "register_operand" "0,f")]))]
14426 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14427 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14428 "* return output_387_binary_op (insn, operands);"
14429 [(set (attr "type")
14430 (cond [(match_operand:DF 3 "mult_operator" "")
14431 (const_string "fmul")
14432 (match_operand:DF 3 "div_operator" "")
14433 (const_string "fdiv")
14434 ]
14435 (const_string "fop")))
14436 (set_attr "mode" "SF")])
14437
14438 (define_insn "*fop_df_5_i387"
14439 [(set (match_operand:DF 0 "register_operand" "=f,f")
14440 (match_operator:DF 3 "binary_fp_operator"
14441 [(match_operand:DF 1 "register_operand" "0,f")
14442 (float_extend:DF
14443 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14444 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14445 "* return output_387_binary_op (insn, operands);"
14446 [(set (attr "type")
14447 (cond [(match_operand:DF 3 "mult_operator" "")
14448 (const_string "fmul")
14449 (match_operand:DF 3 "div_operator" "")
14450 (const_string "fdiv")
14451 ]
14452 (const_string "fop")))
14453 (set_attr "mode" "SF")])
14454
14455 (define_insn "*fop_df_6_i387"
14456 [(set (match_operand:DF 0 "register_operand" "=f,f")
14457 (match_operator:DF 3 "binary_fp_operator"
14458 [(float_extend:DF
14459 (match_operand:SF 1 "register_operand" "0,f"))
14460 (float_extend:DF
14461 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14462 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14463 "* return output_387_binary_op (insn, operands);"
14464 [(set (attr "type")
14465 (cond [(match_operand:DF 3 "mult_operator" "")
14466 (const_string "fmul")
14467 (match_operand:DF 3 "div_operator" "")
14468 (const_string "fdiv")
14469 ]
14470 (const_string "fop")))
14471 (set_attr "mode" "SF")])
14472
14473 (define_insn "*fop_xf_comm_i387"
14474 [(set (match_operand:XF 0 "register_operand" "=f")
14475 (match_operator:XF 3 "binary_fp_operator"
14476 [(match_operand:XF 1 "register_operand" "%0")
14477 (match_operand:XF 2 "register_operand" "f")]))]
14478 "TARGET_80387
14479 && COMMUTATIVE_ARITH_P (operands[3])"
14480 "* return output_387_binary_op (insn, operands);"
14481 [(set (attr "type")
14482 (if_then_else (match_operand:XF 3 "mult_operator" "")
14483 (const_string "fmul")
14484 (const_string "fop")))
14485 (set_attr "mode" "XF")])
14486
14487 (define_insn "*fop_xf_1_i387"
14488 [(set (match_operand:XF 0 "register_operand" "=f,f")
14489 (match_operator:XF 3 "binary_fp_operator"
14490 [(match_operand:XF 1 "register_operand" "0,f")
14491 (match_operand:XF 2 "register_operand" "f,0")]))]
14492 "TARGET_80387
14493 && !COMMUTATIVE_ARITH_P (operands[3])"
14494 "* return output_387_binary_op (insn, operands);"
14495 [(set (attr "type")
14496 (cond [(match_operand:XF 3 "mult_operator" "")
14497 (const_string "fmul")
14498 (match_operand:XF 3 "div_operator" "")
14499 (const_string "fdiv")
14500 ]
14501 (const_string "fop")))
14502 (set_attr "mode" "XF")])
14503
14504 (define_insn "*fop_xf_2_i387"
14505 [(set (match_operand:XF 0 "register_operand" "=f,f")
14506 (match_operator:XF 3 "binary_fp_operator"
14507 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14508 (match_operand:XF 2 "register_operand" "0,0")]))]
14509 "TARGET_80387 && TARGET_USE_FIOP"
14510 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14511 [(set (attr "type")
14512 (cond [(match_operand:XF 3 "mult_operator" "")
14513 (const_string "fmul")
14514 (match_operand:XF 3 "div_operator" "")
14515 (const_string "fdiv")
14516 ]
14517 (const_string "fop")))
14518 (set_attr "fp_int_src" "true")
14519 (set_attr "mode" "SI")])
14520
14521 (define_insn "*fop_xf_3_i387"
14522 [(set (match_operand:XF 0 "register_operand" "=f,f")
14523 (match_operator:XF 3 "binary_fp_operator"
14524 [(match_operand:XF 1 "register_operand" "0,0")
14525 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14526 "TARGET_80387 && TARGET_USE_FIOP"
14527 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14528 [(set (attr "type")
14529 (cond [(match_operand:XF 3 "mult_operator" "")
14530 (const_string "fmul")
14531 (match_operand:XF 3 "div_operator" "")
14532 (const_string "fdiv")
14533 ]
14534 (const_string "fop")))
14535 (set_attr "fp_int_src" "true")
14536 (set_attr "mode" "SI")])
14537
14538 (define_insn "*fop_xf_4_i387"
14539 [(set (match_operand:XF 0 "register_operand" "=f,f")
14540 (match_operator:XF 3 "binary_fp_operator"
14541 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14542 (match_operand:XF 2 "register_operand" "0,f")]))]
14543 "TARGET_80387"
14544 "* return output_387_binary_op (insn, operands);"
14545 [(set (attr "type")
14546 (cond [(match_operand:XF 3 "mult_operator" "")
14547 (const_string "fmul")
14548 (match_operand:XF 3 "div_operator" "")
14549 (const_string "fdiv")
14550 ]
14551 (const_string "fop")))
14552 (set_attr "mode" "SF")])
14553
14554 (define_insn "*fop_xf_5_i387"
14555 [(set (match_operand:XF 0 "register_operand" "=f,f")
14556 (match_operator:XF 3 "binary_fp_operator"
14557 [(match_operand:XF 1 "register_operand" "0,f")
14558 (float_extend:XF
14559 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14560 "TARGET_80387"
14561 "* return output_387_binary_op (insn, operands);"
14562 [(set (attr "type")
14563 (cond [(match_operand:XF 3 "mult_operator" "")
14564 (const_string "fmul")
14565 (match_operand:XF 3 "div_operator" "")
14566 (const_string "fdiv")
14567 ]
14568 (const_string "fop")))
14569 (set_attr "mode" "SF")])
14570
14571 (define_insn "*fop_xf_6_i387"
14572 [(set (match_operand:XF 0 "register_operand" "=f,f")
14573 (match_operator:XF 3 "binary_fp_operator"
14574 [(float_extend:XF
14575 (match_operand 1 "register_operand" "0,f"))
14576 (float_extend:XF
14577 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14578 "TARGET_80387"
14579 "* return output_387_binary_op (insn, operands);"
14580 [(set (attr "type")
14581 (cond [(match_operand:XF 3 "mult_operator" "")
14582 (const_string "fmul")
14583 (match_operand:XF 3 "div_operator" "")
14584 (const_string "fdiv")
14585 ]
14586 (const_string "fop")))
14587 (set_attr "mode" "SF")])
14588
14589 (define_split
14590 [(set (match_operand 0 "register_operand" "")
14591 (match_operator 3 "binary_fp_operator"
14592 [(float (match_operand:SI 1 "register_operand" ""))
14593 (match_operand 2 "register_operand" "")]))]
14594 "TARGET_80387 && reload_completed
14595 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14596 [(const_int 0)]
14597 {
14598 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14599 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14600 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14601 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14602 GET_MODE (operands[3]),
14603 operands[4],
14604 operands[2])));
14605 ix86_free_from_memory (GET_MODE (operands[1]));
14606 DONE;
14607 })
14608
14609 (define_split
14610 [(set (match_operand 0 "register_operand" "")
14611 (match_operator 3 "binary_fp_operator"
14612 [(match_operand 1 "register_operand" "")
14613 (float (match_operand:SI 2 "register_operand" ""))]))]
14614 "TARGET_80387 && reload_completed
14615 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14616 [(const_int 0)]
14617 {
14618 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14619 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14620 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14621 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14622 GET_MODE (operands[3]),
14623 operands[1],
14624 operands[4])));
14625 ix86_free_from_memory (GET_MODE (operands[2]));
14626 DONE;
14627 })
14628 \f
14629 ;; FPU special functions.
14630
14631 (define_expand "sqrtsf2"
14632 [(set (match_operand:SF 0 "register_operand" "")
14633 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14634 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14635 {
14636 if (!TARGET_SSE_MATH)
14637 operands[1] = force_reg (SFmode, operands[1]);
14638 })
14639
14640 (define_insn "*sqrtsf2_mixed"
14641 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14642 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14643 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14644 "@
14645 fsqrt
14646 sqrtss\t{%1, %0|%0, %1}"
14647 [(set_attr "type" "fpspc,sse")
14648 (set_attr "mode" "SF,SF")
14649 (set_attr "athlon_decode" "direct,*")])
14650
14651 (define_insn "*sqrtsf2_sse"
14652 [(set (match_operand:SF 0 "register_operand" "=x")
14653 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14654 "TARGET_SSE_MATH"
14655 "sqrtss\t{%1, %0|%0, %1}"
14656 [(set_attr "type" "sse")
14657 (set_attr "mode" "SF")
14658 (set_attr "athlon_decode" "*")])
14659
14660 (define_insn "*sqrtsf2_i387"
14661 [(set (match_operand:SF 0 "register_operand" "=f")
14662 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14663 "TARGET_USE_FANCY_MATH_387"
14664 "fsqrt"
14665 [(set_attr "type" "fpspc")
14666 (set_attr "mode" "SF")
14667 (set_attr "athlon_decode" "direct")])
14668
14669 (define_expand "sqrtdf2"
14670 [(set (match_operand:DF 0 "register_operand" "")
14671 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14672 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14673 {
14674 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14675 operands[1] = force_reg (DFmode, operands[1]);
14676 })
14677
14678 (define_insn "*sqrtdf2_mixed"
14679 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14680 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14681 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14682 "@
14683 fsqrt
14684 sqrtsd\t{%1, %0|%0, %1}"
14685 [(set_attr "type" "fpspc,sse")
14686 (set_attr "mode" "DF,DF")
14687 (set_attr "athlon_decode" "direct,*")])
14688
14689 (define_insn "*sqrtdf2_sse"
14690 [(set (match_operand:DF 0 "register_operand" "=Y")
14691 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14692 "TARGET_SSE2 && TARGET_SSE_MATH"
14693 "sqrtsd\t{%1, %0|%0, %1}"
14694 [(set_attr "type" "sse")
14695 (set_attr "mode" "DF")
14696 (set_attr "athlon_decode" "*")])
14697
14698 (define_insn "*sqrtdf2_i387"
14699 [(set (match_operand:DF 0 "register_operand" "=f")
14700 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14701 "TARGET_USE_FANCY_MATH_387"
14702 "fsqrt"
14703 [(set_attr "type" "fpspc")
14704 (set_attr "mode" "DF")
14705 (set_attr "athlon_decode" "direct")])
14706
14707 (define_insn "*sqrtextendsfdf2_i387"
14708 [(set (match_operand:DF 0 "register_operand" "=f")
14709 (sqrt:DF (float_extend:DF
14710 (match_operand:SF 1 "register_operand" "0"))))]
14711 "TARGET_USE_FANCY_MATH_387
14712 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14713 "fsqrt"
14714 [(set_attr "type" "fpspc")
14715 (set_attr "mode" "DF")
14716 (set_attr "athlon_decode" "direct")])
14717
14718 (define_insn "sqrtxf2"
14719 [(set (match_operand:XF 0 "register_operand" "=f")
14720 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14721 "TARGET_USE_FANCY_MATH_387
14722 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14723 "fsqrt"
14724 [(set_attr "type" "fpspc")
14725 (set_attr "mode" "XF")
14726 (set_attr "athlon_decode" "direct")])
14727
14728 (define_insn "*sqrtextendsfxf2_i387"
14729 [(set (match_operand:XF 0 "register_operand" "=f")
14730 (sqrt:XF (float_extend:XF
14731 (match_operand:SF 1 "register_operand" "0"))))]
14732 "TARGET_USE_FANCY_MATH_387"
14733 "fsqrt"
14734 [(set_attr "type" "fpspc")
14735 (set_attr "mode" "XF")
14736 (set_attr "athlon_decode" "direct")])
14737
14738 (define_insn "*sqrtextenddfxf2_i387"
14739 [(set (match_operand:XF 0 "register_operand" "=f")
14740 (sqrt:XF (float_extend:XF
14741 (match_operand:DF 1 "register_operand" "0"))))]
14742 "TARGET_USE_FANCY_MATH_387"
14743 "fsqrt"
14744 [(set_attr "type" "fpspc")
14745 (set_attr "mode" "XF")
14746 (set_attr "athlon_decode" "direct")])
14747
14748 (define_insn "fpremxf4"
14749 [(set (match_operand:XF 0 "register_operand" "=f")
14750 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14751 (match_operand:XF 3 "register_operand" "1")]
14752 UNSPEC_FPREM_F))
14753 (set (match_operand:XF 1 "register_operand" "=u")
14754 (unspec:XF [(match_dup 2) (match_dup 3)]
14755 UNSPEC_FPREM_U))
14756 (set (reg:CCFP FPSR_REG)
14757 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14758 "TARGET_USE_FANCY_MATH_387
14759 && flag_unsafe_math_optimizations"
14760 "fprem"
14761 [(set_attr "type" "fpspc")
14762 (set_attr "mode" "XF")])
14763
14764 (define_expand "fmodsf3"
14765 [(use (match_operand:SF 0 "register_operand" ""))
14766 (use (match_operand:SF 1 "register_operand" ""))
14767 (use (match_operand:SF 2 "register_operand" ""))]
14768 "TARGET_USE_FANCY_MATH_387
14769 && flag_unsafe_math_optimizations"
14770 {
14771 rtx label = gen_label_rtx ();
14772
14773 rtx op1 = gen_reg_rtx (XFmode);
14774 rtx op2 = gen_reg_rtx (XFmode);
14775
14776 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14777 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14778
14779 emit_label (label);
14780
14781 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14782 ix86_emit_fp_unordered_jump (label);
14783
14784 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14785 DONE;
14786 })
14787
14788 (define_expand "fmoddf3"
14789 [(use (match_operand:DF 0 "register_operand" ""))
14790 (use (match_operand:DF 1 "register_operand" ""))
14791 (use (match_operand:DF 2 "register_operand" ""))]
14792 "TARGET_USE_FANCY_MATH_387
14793 && flag_unsafe_math_optimizations"
14794 {
14795 rtx label = gen_label_rtx ();
14796
14797 rtx op1 = gen_reg_rtx (XFmode);
14798 rtx op2 = gen_reg_rtx (XFmode);
14799
14800 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14801 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14802
14803 emit_label (label);
14804
14805 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14806 ix86_emit_fp_unordered_jump (label);
14807
14808 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14809 DONE;
14810 })
14811
14812 (define_expand "fmodxf3"
14813 [(use (match_operand:XF 0 "register_operand" ""))
14814 (use (match_operand:XF 1 "register_operand" ""))
14815 (use (match_operand:XF 2 "register_operand" ""))]
14816 "TARGET_USE_FANCY_MATH_387
14817 && flag_unsafe_math_optimizations"
14818 {
14819 rtx label = gen_label_rtx ();
14820
14821 emit_label (label);
14822
14823 emit_insn (gen_fpremxf4 (operands[1], operands[2],
14824 operands[1], operands[2]));
14825 ix86_emit_fp_unordered_jump (label);
14826
14827 emit_move_insn (operands[0], operands[1]);
14828 DONE;
14829 })
14830
14831 (define_insn "fprem1xf4"
14832 [(set (match_operand:XF 0 "register_operand" "=f")
14833 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14834 (match_operand:XF 3 "register_operand" "1")]
14835 UNSPEC_FPREM1_F))
14836 (set (match_operand:XF 1 "register_operand" "=u")
14837 (unspec:XF [(match_dup 2) (match_dup 3)]
14838 UNSPEC_FPREM1_U))
14839 (set (reg:CCFP FPSR_REG)
14840 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14841 "TARGET_USE_FANCY_MATH_387
14842 && flag_unsafe_math_optimizations"
14843 "fprem1"
14844 [(set_attr "type" "fpspc")
14845 (set_attr "mode" "XF")])
14846
14847 (define_expand "dremsf3"
14848 [(use (match_operand:SF 0 "register_operand" ""))
14849 (use (match_operand:SF 1 "register_operand" ""))
14850 (use (match_operand:SF 2 "register_operand" ""))]
14851 "TARGET_USE_FANCY_MATH_387
14852 && flag_unsafe_math_optimizations"
14853 {
14854 rtx label = gen_label_rtx ();
14855
14856 rtx op1 = gen_reg_rtx (XFmode);
14857 rtx op2 = gen_reg_rtx (XFmode);
14858
14859 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14860 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14861
14862 emit_label (label);
14863
14864 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14865 ix86_emit_fp_unordered_jump (label);
14866
14867 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14868 DONE;
14869 })
14870
14871 (define_expand "dremdf3"
14872 [(use (match_operand:DF 0 "register_operand" ""))
14873 (use (match_operand:DF 1 "register_operand" ""))
14874 (use (match_operand:DF 2 "register_operand" ""))]
14875 "TARGET_USE_FANCY_MATH_387
14876 && flag_unsafe_math_optimizations"
14877 {
14878 rtx label = gen_label_rtx ();
14879
14880 rtx op1 = gen_reg_rtx (XFmode);
14881 rtx op2 = gen_reg_rtx (XFmode);
14882
14883 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14884 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14885
14886 emit_label (label);
14887
14888 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14889 ix86_emit_fp_unordered_jump (label);
14890
14891 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14892 DONE;
14893 })
14894
14895 (define_expand "dremxf3"
14896 [(use (match_operand:XF 0 "register_operand" ""))
14897 (use (match_operand:XF 1 "register_operand" ""))
14898 (use (match_operand:XF 2 "register_operand" ""))]
14899 "TARGET_USE_FANCY_MATH_387
14900 && flag_unsafe_math_optimizations"
14901 {
14902 rtx label = gen_label_rtx ();
14903
14904 emit_label (label);
14905
14906 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14907 operands[1], operands[2]));
14908 ix86_emit_fp_unordered_jump (label);
14909
14910 emit_move_insn (operands[0], operands[1]);
14911 DONE;
14912 })
14913
14914 (define_insn "*sindf2"
14915 [(set (match_operand:DF 0 "register_operand" "=f")
14916 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14917 "TARGET_USE_FANCY_MATH_387
14918 && flag_unsafe_math_optimizations"
14919 "fsin"
14920 [(set_attr "type" "fpspc")
14921 (set_attr "mode" "DF")])
14922
14923 (define_insn "*sinsf2"
14924 [(set (match_operand:SF 0 "register_operand" "=f")
14925 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14926 "TARGET_USE_FANCY_MATH_387
14927 && flag_unsafe_math_optimizations"
14928 "fsin"
14929 [(set_attr "type" "fpspc")
14930 (set_attr "mode" "SF")])
14931
14932 (define_insn "*sinextendsfdf2"
14933 [(set (match_operand:DF 0 "register_operand" "=f")
14934 (unspec:DF [(float_extend:DF
14935 (match_operand:SF 1 "register_operand" "0"))]
14936 UNSPEC_SIN))]
14937 "TARGET_USE_FANCY_MATH_387
14938 && flag_unsafe_math_optimizations"
14939 "fsin"
14940 [(set_attr "type" "fpspc")
14941 (set_attr "mode" "DF")])
14942
14943 (define_insn "*sinxf2"
14944 [(set (match_operand:XF 0 "register_operand" "=f")
14945 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14946 "TARGET_USE_FANCY_MATH_387
14947 && flag_unsafe_math_optimizations"
14948 "fsin"
14949 [(set_attr "type" "fpspc")
14950 (set_attr "mode" "XF")])
14951
14952 (define_insn "*cosdf2"
14953 [(set (match_operand:DF 0 "register_operand" "=f")
14954 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14955 "TARGET_USE_FANCY_MATH_387
14956 && flag_unsafe_math_optimizations"
14957 "fcos"
14958 [(set_attr "type" "fpspc")
14959 (set_attr "mode" "DF")])
14960
14961 (define_insn "*cossf2"
14962 [(set (match_operand:SF 0 "register_operand" "=f")
14963 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14964 "TARGET_USE_FANCY_MATH_387
14965 && flag_unsafe_math_optimizations"
14966 "fcos"
14967 [(set_attr "type" "fpspc")
14968 (set_attr "mode" "SF")])
14969
14970 (define_insn "*cosextendsfdf2"
14971 [(set (match_operand:DF 0 "register_operand" "=f")
14972 (unspec:DF [(float_extend:DF
14973 (match_operand:SF 1 "register_operand" "0"))]
14974 UNSPEC_COS))]
14975 "TARGET_USE_FANCY_MATH_387
14976 && flag_unsafe_math_optimizations"
14977 "fcos"
14978 [(set_attr "type" "fpspc")
14979 (set_attr "mode" "DF")])
14980
14981 (define_insn "*cosxf2"
14982 [(set (match_operand:XF 0 "register_operand" "=f")
14983 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14984 "TARGET_USE_FANCY_MATH_387
14985 && flag_unsafe_math_optimizations"
14986 "fcos"
14987 [(set_attr "type" "fpspc")
14988 (set_attr "mode" "XF")])
14989
14990 ;; With sincos pattern defined, sin and cos builtin function will be
14991 ;; expanded to sincos pattern with one of its outputs left unused.
14992 ;; Cse pass will detected, if two sincos patterns can be combined,
14993 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14994 ;; depending on the unused output.
14995
14996 (define_insn "sincosdf3"
14997 [(set (match_operand:DF 0 "register_operand" "=f")
14998 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14999 UNSPEC_SINCOS_COS))
15000 (set (match_operand:DF 1 "register_operand" "=u")
15001 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15002 "TARGET_USE_FANCY_MATH_387
15003 && flag_unsafe_math_optimizations"
15004 "fsincos"
15005 [(set_attr "type" "fpspc")
15006 (set_attr "mode" "DF")])
15007
15008 (define_split
15009 [(set (match_operand:DF 0 "register_operand" "")
15010 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15011 UNSPEC_SINCOS_COS))
15012 (set (match_operand:DF 1 "register_operand" "")
15013 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15014 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15015 && !reload_completed && !reload_in_progress"
15016 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15017 "")
15018
15019 (define_split
15020 [(set (match_operand:DF 0 "register_operand" "")
15021 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15022 UNSPEC_SINCOS_COS))
15023 (set (match_operand:DF 1 "register_operand" "")
15024 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15025 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15026 && !reload_completed && !reload_in_progress"
15027 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15028 "")
15029
15030 (define_insn "sincossf3"
15031 [(set (match_operand:SF 0 "register_operand" "=f")
15032 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15033 UNSPEC_SINCOS_COS))
15034 (set (match_operand:SF 1 "register_operand" "=u")
15035 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15036 "TARGET_USE_FANCY_MATH_387
15037 && flag_unsafe_math_optimizations"
15038 "fsincos"
15039 [(set_attr "type" "fpspc")
15040 (set_attr "mode" "SF")])
15041
15042 (define_split
15043 [(set (match_operand:SF 0 "register_operand" "")
15044 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15045 UNSPEC_SINCOS_COS))
15046 (set (match_operand:SF 1 "register_operand" "")
15047 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15048 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15049 && !reload_completed && !reload_in_progress"
15050 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15051 "")
15052
15053 (define_split
15054 [(set (match_operand:SF 0 "register_operand" "")
15055 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15056 UNSPEC_SINCOS_COS))
15057 (set (match_operand:SF 1 "register_operand" "")
15058 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15059 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15060 && !reload_completed && !reload_in_progress"
15061 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15062 "")
15063
15064 (define_insn "*sincosextendsfdf3"
15065 [(set (match_operand:DF 0 "register_operand" "=f")
15066 (unspec:DF [(float_extend:DF
15067 (match_operand:SF 2 "register_operand" "0"))]
15068 UNSPEC_SINCOS_COS))
15069 (set (match_operand:DF 1 "register_operand" "=u")
15070 (unspec:DF [(float_extend:DF
15071 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15072 "TARGET_USE_FANCY_MATH_387
15073 && flag_unsafe_math_optimizations"
15074 "fsincos"
15075 [(set_attr "type" "fpspc")
15076 (set_attr "mode" "DF")])
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[0]))
15087 && !reload_completed && !reload_in_progress"
15088 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15089 (match_dup 2))] UNSPEC_SIN))]
15090 "")
15091
15092 (define_split
15093 [(set (match_operand:DF 0 "register_operand" "")
15094 (unspec:DF [(float_extend:DF
15095 (match_operand:SF 2 "register_operand" ""))]
15096 UNSPEC_SINCOS_COS))
15097 (set (match_operand:DF 1 "register_operand" "")
15098 (unspec:DF [(float_extend:DF
15099 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15100 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15101 && !reload_completed && !reload_in_progress"
15102 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15103 (match_dup 2))] UNSPEC_COS))]
15104 "")
15105
15106 (define_insn "sincosxf3"
15107 [(set (match_operand:XF 0 "register_operand" "=f")
15108 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15109 UNSPEC_SINCOS_COS))
15110 (set (match_operand:XF 1 "register_operand" "=u")
15111 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15112 "TARGET_USE_FANCY_MATH_387
15113 && flag_unsafe_math_optimizations"
15114 "fsincos"
15115 [(set_attr "type" "fpspc")
15116 (set_attr "mode" "XF")])
15117
15118 (define_split
15119 [(set (match_operand:XF 0 "register_operand" "")
15120 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15121 UNSPEC_SINCOS_COS))
15122 (set (match_operand:XF 1 "register_operand" "")
15123 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15124 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15125 && !reload_completed && !reload_in_progress"
15126 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15127 "")
15128
15129 (define_split
15130 [(set (match_operand:XF 0 "register_operand" "")
15131 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15132 UNSPEC_SINCOS_COS))
15133 (set (match_operand:XF 1 "register_operand" "")
15134 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15135 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15136 && !reload_completed && !reload_in_progress"
15137 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15138 "")
15139
15140 (define_insn "*tandf3_1"
15141 [(set (match_operand:DF 0 "register_operand" "=f")
15142 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15143 UNSPEC_TAN_ONE))
15144 (set (match_operand:DF 1 "register_operand" "=u")
15145 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15146 "TARGET_USE_FANCY_MATH_387
15147 && flag_unsafe_math_optimizations"
15148 "fptan"
15149 [(set_attr "type" "fpspc")
15150 (set_attr "mode" "DF")])
15151
15152 ;; optimize sequence: fptan
15153 ;; fstp %st(0)
15154 ;; fld1
15155 ;; into fptan insn.
15156
15157 (define_peephole2
15158 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15159 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15160 UNSPEC_TAN_ONE))
15161 (set (match_operand:DF 1 "register_operand" "")
15162 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15163 (set (match_dup 0)
15164 (match_operand:DF 3 "immediate_operand" ""))]
15165 "standard_80387_constant_p (operands[3]) == 2"
15166 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15167 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15168 "")
15169
15170 (define_expand "tandf2"
15171 [(parallel [(set (match_dup 2)
15172 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15173 UNSPEC_TAN_ONE))
15174 (set (match_operand:DF 0 "register_operand" "")
15175 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15176 "TARGET_USE_FANCY_MATH_387
15177 && flag_unsafe_math_optimizations"
15178 {
15179 operands[2] = gen_reg_rtx (DFmode);
15180 })
15181
15182 (define_insn "*tansf3_1"
15183 [(set (match_operand:SF 0 "register_operand" "=f")
15184 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15185 UNSPEC_TAN_ONE))
15186 (set (match_operand:SF 1 "register_operand" "=u")
15187 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15188 "TARGET_USE_FANCY_MATH_387
15189 && flag_unsafe_math_optimizations"
15190 "fptan"
15191 [(set_attr "type" "fpspc")
15192 (set_attr "mode" "SF")])
15193
15194 ;; optimize sequence: fptan
15195 ;; fstp %st(0)
15196 ;; fld1
15197 ;; into fptan insn.
15198
15199 (define_peephole2
15200 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15201 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15202 UNSPEC_TAN_ONE))
15203 (set (match_operand:SF 1 "register_operand" "")
15204 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15205 (set (match_dup 0)
15206 (match_operand:SF 3 "immediate_operand" ""))]
15207 "standard_80387_constant_p (operands[3]) == 2"
15208 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15209 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15210 "")
15211
15212 (define_expand "tansf2"
15213 [(parallel [(set (match_dup 2)
15214 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15215 UNSPEC_TAN_ONE))
15216 (set (match_operand:SF 0 "register_operand" "")
15217 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15218 "TARGET_USE_FANCY_MATH_387
15219 && flag_unsafe_math_optimizations"
15220 {
15221 operands[2] = gen_reg_rtx (SFmode);
15222 })
15223
15224 (define_insn "*tanxf3_1"
15225 [(set (match_operand:XF 0 "register_operand" "=f")
15226 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15227 UNSPEC_TAN_ONE))
15228 (set (match_operand:XF 1 "register_operand" "=u")
15229 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15230 "TARGET_USE_FANCY_MATH_387
15231 && flag_unsafe_math_optimizations"
15232 "fptan"
15233 [(set_attr "type" "fpspc")
15234 (set_attr "mode" "XF")])
15235
15236 ;; optimize sequence: fptan
15237 ;; fstp %st(0)
15238 ;; fld1
15239 ;; into fptan insn.
15240
15241 (define_peephole2
15242 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15243 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15244 UNSPEC_TAN_ONE))
15245 (set (match_operand:XF 1 "register_operand" "")
15246 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15247 (set (match_dup 0)
15248 (match_operand:XF 3 "immediate_operand" ""))]
15249 "standard_80387_constant_p (operands[3]) == 2"
15250 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15251 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15252 "")
15253
15254 (define_expand "tanxf2"
15255 [(parallel [(set (match_dup 2)
15256 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15257 UNSPEC_TAN_ONE))
15258 (set (match_operand:XF 0 "register_operand" "")
15259 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15260 "TARGET_USE_FANCY_MATH_387
15261 && flag_unsafe_math_optimizations"
15262 {
15263 operands[2] = gen_reg_rtx (XFmode);
15264 })
15265
15266 (define_insn "atan2df3_1"
15267 [(set (match_operand:DF 0 "register_operand" "=f")
15268 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15269 (match_operand:DF 1 "register_operand" "u")]
15270 UNSPEC_FPATAN))
15271 (clobber (match_scratch:DF 3 "=1"))]
15272 "TARGET_USE_FANCY_MATH_387
15273 && flag_unsafe_math_optimizations"
15274 "fpatan"
15275 [(set_attr "type" "fpspc")
15276 (set_attr "mode" "DF")])
15277
15278 (define_expand "atan2df3"
15279 [(use (match_operand:DF 0 "register_operand" "=f"))
15280 (use (match_operand:DF 2 "register_operand" "0"))
15281 (use (match_operand:DF 1 "register_operand" "u"))]
15282 "TARGET_USE_FANCY_MATH_387
15283 && flag_unsafe_math_optimizations"
15284 {
15285 rtx copy = gen_reg_rtx (DFmode);
15286 emit_move_insn (copy, operands[1]);
15287 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15288 DONE;
15289 })
15290
15291 (define_expand "atandf2"
15292 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15293 (unspec:DF [(match_dup 2)
15294 (match_operand:DF 1 "register_operand" "")]
15295 UNSPEC_FPATAN))
15296 (clobber (match_scratch:DF 3 ""))])]
15297 "TARGET_USE_FANCY_MATH_387
15298 && flag_unsafe_math_optimizations"
15299 {
15300 operands[2] = gen_reg_rtx (DFmode);
15301 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15302 })
15303
15304 (define_insn "atan2sf3_1"
15305 [(set (match_operand:SF 0 "register_operand" "=f")
15306 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15307 (match_operand:SF 1 "register_operand" "u")]
15308 UNSPEC_FPATAN))
15309 (clobber (match_scratch:SF 3 "=1"))]
15310 "TARGET_USE_FANCY_MATH_387
15311 && flag_unsafe_math_optimizations"
15312 "fpatan"
15313 [(set_attr "type" "fpspc")
15314 (set_attr "mode" "SF")])
15315
15316 (define_expand "atan2sf3"
15317 [(use (match_operand:SF 0 "register_operand" "=f"))
15318 (use (match_operand:SF 2 "register_operand" "0"))
15319 (use (match_operand:SF 1 "register_operand" "u"))]
15320 "TARGET_USE_FANCY_MATH_387
15321 && flag_unsafe_math_optimizations"
15322 {
15323 rtx copy = gen_reg_rtx (SFmode);
15324 emit_move_insn (copy, operands[1]);
15325 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15326 DONE;
15327 })
15328
15329 (define_expand "atansf2"
15330 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15331 (unspec:SF [(match_dup 2)
15332 (match_operand:SF 1 "register_operand" "")]
15333 UNSPEC_FPATAN))
15334 (clobber (match_scratch:SF 3 ""))])]
15335 "TARGET_USE_FANCY_MATH_387
15336 && flag_unsafe_math_optimizations"
15337 {
15338 operands[2] = gen_reg_rtx (SFmode);
15339 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15340 })
15341
15342 (define_insn "atan2xf3_1"
15343 [(set (match_operand:XF 0 "register_operand" "=f")
15344 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15345 (match_operand:XF 1 "register_operand" "u")]
15346 UNSPEC_FPATAN))
15347 (clobber (match_scratch:XF 3 "=1"))]
15348 "TARGET_USE_FANCY_MATH_387
15349 && flag_unsafe_math_optimizations"
15350 "fpatan"
15351 [(set_attr "type" "fpspc")
15352 (set_attr "mode" "XF")])
15353
15354 (define_expand "atan2xf3"
15355 [(use (match_operand:XF 0 "register_operand" "=f"))
15356 (use (match_operand:XF 2 "register_operand" "0"))
15357 (use (match_operand:XF 1 "register_operand" "u"))]
15358 "TARGET_USE_FANCY_MATH_387
15359 && flag_unsafe_math_optimizations"
15360 {
15361 rtx copy = gen_reg_rtx (XFmode);
15362 emit_move_insn (copy, operands[1]);
15363 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15364 DONE;
15365 })
15366
15367 (define_expand "atanxf2"
15368 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15369 (unspec:XF [(match_dup 2)
15370 (match_operand:XF 1 "register_operand" "")]
15371 UNSPEC_FPATAN))
15372 (clobber (match_scratch:XF 3 ""))])]
15373 "TARGET_USE_FANCY_MATH_387
15374 && flag_unsafe_math_optimizations"
15375 {
15376 operands[2] = gen_reg_rtx (XFmode);
15377 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15378 })
15379
15380 (define_expand "asindf2"
15381 [(set (match_dup 2)
15382 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15383 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15384 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15385 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15386 (parallel [(set (match_dup 7)
15387 (unspec:XF [(match_dup 6) (match_dup 2)]
15388 UNSPEC_FPATAN))
15389 (clobber (match_scratch:XF 8 ""))])
15390 (set (match_operand:DF 0 "register_operand" "")
15391 (float_truncate:DF (match_dup 7)))]
15392 "TARGET_USE_FANCY_MATH_387
15393 && flag_unsafe_math_optimizations"
15394 {
15395 int i;
15396
15397 for (i=2; i<8; i++)
15398 operands[i] = gen_reg_rtx (XFmode);
15399
15400 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15401 })
15402
15403 (define_expand "asinsf2"
15404 [(set (match_dup 2)
15405 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15406 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15407 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15408 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15409 (parallel [(set (match_dup 7)
15410 (unspec:XF [(match_dup 6) (match_dup 2)]
15411 UNSPEC_FPATAN))
15412 (clobber (match_scratch:XF 8 ""))])
15413 (set (match_operand:SF 0 "register_operand" "")
15414 (float_truncate:SF (match_dup 7)))]
15415 "TARGET_USE_FANCY_MATH_387
15416 && flag_unsafe_math_optimizations"
15417 {
15418 int i;
15419
15420 for (i=2; i<8; i++)
15421 operands[i] = gen_reg_rtx (XFmode);
15422
15423 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15424 })
15425
15426 (define_expand "asinxf2"
15427 [(set (match_dup 2)
15428 (mult:XF (match_operand:XF 1 "register_operand" "")
15429 (match_dup 1)))
15430 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15431 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15432 (parallel [(set (match_operand:XF 0 "register_operand" "")
15433 (unspec:XF [(match_dup 5) (match_dup 1)]
15434 UNSPEC_FPATAN))
15435 (clobber (match_scratch:XF 6 ""))])]
15436 "TARGET_USE_FANCY_MATH_387
15437 && flag_unsafe_math_optimizations"
15438 {
15439 int i;
15440
15441 for (i=2; i<6; i++)
15442 operands[i] = gen_reg_rtx (XFmode);
15443
15444 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15445 })
15446
15447 (define_expand "acosdf2"
15448 [(set (match_dup 2)
15449 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15450 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15451 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15452 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15453 (parallel [(set (match_dup 7)
15454 (unspec:XF [(match_dup 2) (match_dup 6)]
15455 UNSPEC_FPATAN))
15456 (clobber (match_scratch:XF 8 ""))])
15457 (set (match_operand:DF 0 "register_operand" "")
15458 (float_truncate:DF (match_dup 7)))]
15459 "TARGET_USE_FANCY_MATH_387
15460 && flag_unsafe_math_optimizations"
15461 {
15462 int i;
15463
15464 for (i=2; i<8; i++)
15465 operands[i] = gen_reg_rtx (XFmode);
15466
15467 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15468 })
15469
15470 (define_expand "acossf2"
15471 [(set (match_dup 2)
15472 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15473 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15474 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15475 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15476 (parallel [(set (match_dup 7)
15477 (unspec:XF [(match_dup 2) (match_dup 6)]
15478 UNSPEC_FPATAN))
15479 (clobber (match_scratch:XF 8 ""))])
15480 (set (match_operand:SF 0 "register_operand" "")
15481 (float_truncate:SF (match_dup 7)))]
15482 "TARGET_USE_FANCY_MATH_387
15483 && flag_unsafe_math_optimizations"
15484 {
15485 int i;
15486
15487 for (i=2; i<8; i++)
15488 operands[i] = gen_reg_rtx (XFmode);
15489
15490 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15491 })
15492
15493 (define_expand "acosxf2"
15494 [(set (match_dup 2)
15495 (mult:XF (match_operand:XF 1 "register_operand" "")
15496 (match_dup 1)))
15497 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15498 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15499 (parallel [(set (match_operand:XF 0 "register_operand" "")
15500 (unspec:XF [(match_dup 1) (match_dup 5)]
15501 UNSPEC_FPATAN))
15502 (clobber (match_scratch:XF 6 ""))])]
15503 "TARGET_USE_FANCY_MATH_387
15504 && flag_unsafe_math_optimizations"
15505 {
15506 int i;
15507
15508 for (i=2; i<6; i++)
15509 operands[i] = gen_reg_rtx (XFmode);
15510
15511 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15512 })
15513
15514 (define_insn "fyl2x_xf3"
15515 [(set (match_operand:XF 0 "register_operand" "=f")
15516 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15517 (match_operand:XF 1 "register_operand" "u")]
15518 UNSPEC_FYL2X))
15519 (clobber (match_scratch:XF 3 "=1"))]
15520 "TARGET_USE_FANCY_MATH_387
15521 && flag_unsafe_math_optimizations"
15522 "fyl2x"
15523 [(set_attr "type" "fpspc")
15524 (set_attr "mode" "XF")])
15525
15526 (define_expand "logsf2"
15527 [(set (match_dup 2)
15528 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15529 (parallel [(set (match_dup 4)
15530 (unspec:XF [(match_dup 2)
15531 (match_dup 3)] UNSPEC_FYL2X))
15532 (clobber (match_scratch:XF 5 ""))])
15533 (set (match_operand:SF 0 "register_operand" "")
15534 (float_truncate:SF (match_dup 4)))]
15535 "TARGET_USE_FANCY_MATH_387
15536 && flag_unsafe_math_optimizations"
15537 {
15538 rtx temp;
15539
15540 operands[2] = gen_reg_rtx (XFmode);
15541 operands[3] = gen_reg_rtx (XFmode);
15542 operands[4] = gen_reg_rtx (XFmode);
15543
15544 temp = standard_80387_constant_rtx (4); /* fldln2 */
15545 emit_move_insn (operands[3], temp);
15546 })
15547
15548 (define_expand "logdf2"
15549 [(set (match_dup 2)
15550 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15551 (parallel [(set (match_dup 4)
15552 (unspec:XF [(match_dup 2)
15553 (match_dup 3)] UNSPEC_FYL2X))
15554 (clobber (match_scratch:XF 5 ""))])
15555 (set (match_operand:DF 0 "register_operand" "")
15556 (float_truncate:DF (match_dup 4)))]
15557 "TARGET_USE_FANCY_MATH_387
15558 && flag_unsafe_math_optimizations"
15559 {
15560 rtx temp;
15561
15562 operands[2] = gen_reg_rtx (XFmode);
15563 operands[3] = gen_reg_rtx (XFmode);
15564 operands[4] = gen_reg_rtx (XFmode);
15565
15566 temp = standard_80387_constant_rtx (4); /* fldln2 */
15567 emit_move_insn (operands[3], temp);
15568 })
15569
15570 (define_expand "logxf2"
15571 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15572 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15573 (match_dup 2)] UNSPEC_FYL2X))
15574 (clobber (match_scratch:XF 3 ""))])]
15575 "TARGET_USE_FANCY_MATH_387
15576 && flag_unsafe_math_optimizations"
15577 {
15578 rtx temp;
15579
15580 operands[2] = gen_reg_rtx (XFmode);
15581 temp = standard_80387_constant_rtx (4); /* fldln2 */
15582 emit_move_insn (operands[2], temp);
15583 })
15584
15585 (define_expand "log10sf2"
15586 [(set (match_dup 2)
15587 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15588 (parallel [(set (match_dup 4)
15589 (unspec:XF [(match_dup 2)
15590 (match_dup 3)] UNSPEC_FYL2X))
15591 (clobber (match_scratch:XF 5 ""))])
15592 (set (match_operand:SF 0 "register_operand" "")
15593 (float_truncate:SF (match_dup 4)))]
15594 "TARGET_USE_FANCY_MATH_387
15595 && flag_unsafe_math_optimizations"
15596 {
15597 rtx temp;
15598
15599 operands[2] = gen_reg_rtx (XFmode);
15600 operands[3] = gen_reg_rtx (XFmode);
15601 operands[4] = gen_reg_rtx (XFmode);
15602
15603 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15604 emit_move_insn (operands[3], temp);
15605 })
15606
15607 (define_expand "log10df2"
15608 [(set (match_dup 2)
15609 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15610 (parallel [(set (match_dup 4)
15611 (unspec:XF [(match_dup 2)
15612 (match_dup 3)] UNSPEC_FYL2X))
15613 (clobber (match_scratch:XF 5 ""))])
15614 (set (match_operand:DF 0 "register_operand" "")
15615 (float_truncate:DF (match_dup 4)))]
15616 "TARGET_USE_FANCY_MATH_387
15617 && flag_unsafe_math_optimizations"
15618 {
15619 rtx temp;
15620
15621 operands[2] = gen_reg_rtx (XFmode);
15622 operands[3] = gen_reg_rtx (XFmode);
15623 operands[4] = gen_reg_rtx (XFmode);
15624
15625 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15626 emit_move_insn (operands[3], temp);
15627 })
15628
15629 (define_expand "log10xf2"
15630 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15631 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15632 (match_dup 2)] UNSPEC_FYL2X))
15633 (clobber (match_scratch:XF 3 ""))])]
15634 "TARGET_USE_FANCY_MATH_387
15635 && flag_unsafe_math_optimizations"
15636 {
15637 rtx temp;
15638
15639 operands[2] = gen_reg_rtx (XFmode);
15640 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15641 emit_move_insn (operands[2], temp);
15642 })
15643
15644 (define_expand "log2sf2"
15645 [(set (match_dup 2)
15646 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15647 (parallel [(set (match_dup 4)
15648 (unspec:XF [(match_dup 2)
15649 (match_dup 3)] UNSPEC_FYL2X))
15650 (clobber (match_scratch:XF 5 ""))])
15651 (set (match_operand:SF 0 "register_operand" "")
15652 (float_truncate:SF (match_dup 4)))]
15653 "TARGET_USE_FANCY_MATH_387
15654 && flag_unsafe_math_optimizations"
15655 {
15656 operands[2] = gen_reg_rtx (XFmode);
15657 operands[3] = gen_reg_rtx (XFmode);
15658 operands[4] = gen_reg_rtx (XFmode);
15659
15660 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15661 })
15662
15663 (define_expand "log2df2"
15664 [(set (match_dup 2)
15665 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15666 (parallel [(set (match_dup 4)
15667 (unspec:XF [(match_dup 2)
15668 (match_dup 3)] UNSPEC_FYL2X))
15669 (clobber (match_scratch:XF 5 ""))])
15670 (set (match_operand:DF 0 "register_operand" "")
15671 (float_truncate:DF (match_dup 4)))]
15672 "TARGET_USE_FANCY_MATH_387
15673 && flag_unsafe_math_optimizations"
15674 {
15675 operands[2] = gen_reg_rtx (XFmode);
15676 operands[3] = gen_reg_rtx (XFmode);
15677 operands[4] = gen_reg_rtx (XFmode);
15678
15679 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15680 })
15681
15682 (define_expand "log2xf2"
15683 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15684 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15685 (match_dup 2)] UNSPEC_FYL2X))
15686 (clobber (match_scratch:XF 3 ""))])]
15687 "TARGET_USE_FANCY_MATH_387
15688 && flag_unsafe_math_optimizations"
15689 {
15690 operands[2] = gen_reg_rtx (XFmode);
15691 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15692 })
15693
15694 (define_insn "fyl2xp1_xf3"
15695 [(set (match_operand:XF 0 "register_operand" "=f")
15696 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15697 (match_operand:XF 1 "register_operand" "u")]
15698 UNSPEC_FYL2XP1))
15699 (clobber (match_scratch:XF 3 "=1"))]
15700 "TARGET_USE_FANCY_MATH_387
15701 && flag_unsafe_math_optimizations"
15702 "fyl2xp1"
15703 [(set_attr "type" "fpspc")
15704 (set_attr "mode" "XF")])
15705
15706 (define_expand "log1psf2"
15707 [(use (match_operand:SF 0 "register_operand" ""))
15708 (use (match_operand:SF 1 "register_operand" ""))]
15709 "TARGET_USE_FANCY_MATH_387
15710 && flag_unsafe_math_optimizations"
15711 {
15712 rtx op0 = gen_reg_rtx (XFmode);
15713 rtx op1 = gen_reg_rtx (XFmode);
15714
15715 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15716 ix86_emit_i387_log1p (op0, op1);
15717 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15718 DONE;
15719 })
15720
15721 (define_expand "log1pdf2"
15722 [(use (match_operand:DF 0 "register_operand" ""))
15723 (use (match_operand:DF 1 "register_operand" ""))]
15724 "TARGET_USE_FANCY_MATH_387
15725 && flag_unsafe_math_optimizations"
15726 {
15727 rtx op0 = gen_reg_rtx (XFmode);
15728 rtx op1 = gen_reg_rtx (XFmode);
15729
15730 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15731 ix86_emit_i387_log1p (op0, op1);
15732 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15733 DONE;
15734 })
15735
15736 (define_expand "log1pxf2"
15737 [(use (match_operand:XF 0 "register_operand" ""))
15738 (use (match_operand:XF 1 "register_operand" ""))]
15739 "TARGET_USE_FANCY_MATH_387
15740 && flag_unsafe_math_optimizations"
15741 {
15742 ix86_emit_i387_log1p (operands[0], operands[1]);
15743 DONE;
15744 })
15745
15746 (define_insn "*fxtractxf3"
15747 [(set (match_operand:XF 0 "register_operand" "=f")
15748 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15749 UNSPEC_XTRACT_FRACT))
15750 (set (match_operand:XF 1 "register_operand" "=u")
15751 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15752 "TARGET_USE_FANCY_MATH_387
15753 && flag_unsafe_math_optimizations"
15754 "fxtract"
15755 [(set_attr "type" "fpspc")
15756 (set_attr "mode" "XF")])
15757
15758 (define_expand "logbsf2"
15759 [(set (match_dup 2)
15760 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15761 (parallel [(set (match_dup 3)
15762 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15763 (set (match_dup 4)
15764 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15765 (set (match_operand:SF 0 "register_operand" "")
15766 (float_truncate:SF (match_dup 4)))]
15767 "TARGET_USE_FANCY_MATH_387
15768 && flag_unsafe_math_optimizations"
15769 {
15770 operands[2] = gen_reg_rtx (XFmode);
15771 operands[3] = gen_reg_rtx (XFmode);
15772 operands[4] = gen_reg_rtx (XFmode);
15773 })
15774
15775 (define_expand "logbdf2"
15776 [(set (match_dup 2)
15777 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15778 (parallel [(set (match_dup 3)
15779 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15780 (set (match_dup 4)
15781 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15782 (set (match_operand:DF 0 "register_operand" "")
15783 (float_truncate:DF (match_dup 4)))]
15784 "TARGET_USE_FANCY_MATH_387
15785 && flag_unsafe_math_optimizations"
15786 {
15787 operands[2] = gen_reg_rtx (XFmode);
15788 operands[3] = gen_reg_rtx (XFmode);
15789 operands[4] = gen_reg_rtx (XFmode);
15790 })
15791
15792 (define_expand "logbxf2"
15793 [(parallel [(set (match_dup 2)
15794 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15795 UNSPEC_XTRACT_FRACT))
15796 (set (match_operand:XF 0 "register_operand" "")
15797 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15798 "TARGET_USE_FANCY_MATH_387
15799 && flag_unsafe_math_optimizations"
15800 {
15801 operands[2] = gen_reg_rtx (XFmode);
15802 })
15803
15804 (define_expand "ilogbsi2"
15805 [(parallel [(set (match_dup 2)
15806 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15807 UNSPEC_XTRACT_FRACT))
15808 (set (match_operand:XF 3 "register_operand" "")
15809 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15810 (parallel [(set (match_operand:SI 0 "register_operand" "")
15811 (fix:SI (match_dup 3)))
15812 (clobber (reg:CC FLAGS_REG))])]
15813 "TARGET_USE_FANCY_MATH_387
15814 && flag_unsafe_math_optimizations"
15815 {
15816 operands[2] = gen_reg_rtx (XFmode);
15817 operands[3] = gen_reg_rtx (XFmode);
15818 })
15819
15820 (define_insn "*f2xm1xf2"
15821 [(set (match_operand:XF 0 "register_operand" "=f")
15822 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15823 UNSPEC_F2XM1))]
15824 "TARGET_USE_FANCY_MATH_387
15825 && flag_unsafe_math_optimizations"
15826 "f2xm1"
15827 [(set_attr "type" "fpspc")
15828 (set_attr "mode" "XF")])
15829
15830 (define_insn "*fscalexf4"
15831 [(set (match_operand:XF 0 "register_operand" "=f")
15832 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15833 (match_operand:XF 3 "register_operand" "1")]
15834 UNSPEC_FSCALE_FRACT))
15835 (set (match_operand:XF 1 "register_operand" "=u")
15836 (unspec:XF [(match_dup 2) (match_dup 3)]
15837 UNSPEC_FSCALE_EXP))]
15838 "TARGET_USE_FANCY_MATH_387
15839 && flag_unsafe_math_optimizations"
15840 "fscale"
15841 [(set_attr "type" "fpspc")
15842 (set_attr "mode" "XF")])
15843
15844 (define_expand "expsf2"
15845 [(set (match_dup 2)
15846 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15847 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15848 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15849 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15850 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15851 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15852 (parallel [(set (match_dup 10)
15853 (unspec:XF [(match_dup 9) (match_dup 5)]
15854 UNSPEC_FSCALE_FRACT))
15855 (set (match_dup 11)
15856 (unspec:XF [(match_dup 9) (match_dup 5)]
15857 UNSPEC_FSCALE_EXP))])
15858 (set (match_operand:SF 0 "register_operand" "")
15859 (float_truncate:SF (match_dup 10)))]
15860 "TARGET_USE_FANCY_MATH_387
15861 && flag_unsafe_math_optimizations"
15862 {
15863 rtx temp;
15864 int i;
15865
15866 for (i=2; i<12; i++)
15867 operands[i] = gen_reg_rtx (XFmode);
15868 temp = standard_80387_constant_rtx (5); /* fldl2e */
15869 emit_move_insn (operands[3], temp);
15870 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15871 })
15872
15873 (define_expand "expdf2"
15874 [(set (match_dup 2)
15875 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15876 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15877 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15878 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15879 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15880 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15881 (parallel [(set (match_dup 10)
15882 (unspec:XF [(match_dup 9) (match_dup 5)]
15883 UNSPEC_FSCALE_FRACT))
15884 (set (match_dup 11)
15885 (unspec:XF [(match_dup 9) (match_dup 5)]
15886 UNSPEC_FSCALE_EXP))])
15887 (set (match_operand:DF 0 "register_operand" "")
15888 (float_truncate:DF (match_dup 10)))]
15889 "TARGET_USE_FANCY_MATH_387
15890 && flag_unsafe_math_optimizations"
15891 {
15892 rtx temp;
15893 int i;
15894
15895 for (i=2; i<12; i++)
15896 operands[i] = gen_reg_rtx (XFmode);
15897 temp = standard_80387_constant_rtx (5); /* fldl2e */
15898 emit_move_insn (operands[3], temp);
15899 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15900 })
15901
15902 (define_expand "expxf2"
15903 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15904 (match_dup 2)))
15905 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15906 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15907 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15908 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15909 (parallel [(set (match_operand:XF 0 "register_operand" "")
15910 (unspec:XF [(match_dup 8) (match_dup 4)]
15911 UNSPEC_FSCALE_FRACT))
15912 (set (match_dup 9)
15913 (unspec:XF [(match_dup 8) (match_dup 4)]
15914 UNSPEC_FSCALE_EXP))])]
15915 "TARGET_USE_FANCY_MATH_387
15916 && flag_unsafe_math_optimizations"
15917 {
15918 rtx temp;
15919 int i;
15920
15921 for (i=2; i<10; i++)
15922 operands[i] = gen_reg_rtx (XFmode);
15923 temp = standard_80387_constant_rtx (5); /* fldl2e */
15924 emit_move_insn (operands[2], temp);
15925 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15926 })
15927
15928 (define_expand "exp10sf2"
15929 [(set (match_dup 2)
15930 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15931 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15932 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15933 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15934 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15935 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15936 (parallel [(set (match_dup 10)
15937 (unspec:XF [(match_dup 9) (match_dup 5)]
15938 UNSPEC_FSCALE_FRACT))
15939 (set (match_dup 11)
15940 (unspec:XF [(match_dup 9) (match_dup 5)]
15941 UNSPEC_FSCALE_EXP))])
15942 (set (match_operand:SF 0 "register_operand" "")
15943 (float_truncate:SF (match_dup 10)))]
15944 "TARGET_USE_FANCY_MATH_387
15945 && flag_unsafe_math_optimizations"
15946 {
15947 rtx temp;
15948 int i;
15949
15950 for (i=2; i<12; i++)
15951 operands[i] = gen_reg_rtx (XFmode);
15952 temp = standard_80387_constant_rtx (6); /* fldl2t */
15953 emit_move_insn (operands[3], temp);
15954 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15955 })
15956
15957 (define_expand "exp10df2"
15958 [(set (match_dup 2)
15959 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15960 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15961 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15962 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15963 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15964 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15965 (parallel [(set (match_dup 10)
15966 (unspec:XF [(match_dup 9) (match_dup 5)]
15967 UNSPEC_FSCALE_FRACT))
15968 (set (match_dup 11)
15969 (unspec:XF [(match_dup 9) (match_dup 5)]
15970 UNSPEC_FSCALE_EXP))])
15971 (set (match_operand:DF 0 "register_operand" "")
15972 (float_truncate:DF (match_dup 10)))]
15973 "TARGET_USE_FANCY_MATH_387
15974 && flag_unsafe_math_optimizations"
15975 {
15976 rtx temp;
15977 int i;
15978
15979 for (i=2; i<12; i++)
15980 operands[i] = gen_reg_rtx (XFmode);
15981 temp = standard_80387_constant_rtx (6); /* fldl2t */
15982 emit_move_insn (operands[3], temp);
15983 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15984 })
15985
15986 (define_expand "exp10xf2"
15987 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15988 (match_dup 2)))
15989 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15990 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15991 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15992 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15993 (parallel [(set (match_operand:XF 0 "register_operand" "")
15994 (unspec:XF [(match_dup 8) (match_dup 4)]
15995 UNSPEC_FSCALE_FRACT))
15996 (set (match_dup 9)
15997 (unspec:XF [(match_dup 8) (match_dup 4)]
15998 UNSPEC_FSCALE_EXP))])]
15999 "TARGET_USE_FANCY_MATH_387
16000 && flag_unsafe_math_optimizations"
16001 {
16002 rtx temp;
16003 int i;
16004
16005 for (i=2; i<10; i++)
16006 operands[i] = gen_reg_rtx (XFmode);
16007 temp = standard_80387_constant_rtx (6); /* fldl2t */
16008 emit_move_insn (operands[2], temp);
16009 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16010 })
16011
16012 (define_expand "exp2sf2"
16013 [(set (match_dup 2)
16014 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16015 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16016 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16017 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16018 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16019 (parallel [(set (match_dup 8)
16020 (unspec:XF [(match_dup 7) (match_dup 3)]
16021 UNSPEC_FSCALE_FRACT))
16022 (set (match_dup 9)
16023 (unspec:XF [(match_dup 7) (match_dup 3)]
16024 UNSPEC_FSCALE_EXP))])
16025 (set (match_operand:SF 0 "register_operand" "")
16026 (float_truncate:SF (match_dup 8)))]
16027 "TARGET_USE_FANCY_MATH_387
16028 && flag_unsafe_math_optimizations"
16029 {
16030 int i;
16031
16032 for (i=2; i<10; i++)
16033 operands[i] = gen_reg_rtx (XFmode);
16034 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16035 })
16036
16037 (define_expand "exp2df2"
16038 [(set (match_dup 2)
16039 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16040 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16041 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16042 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16043 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16044 (parallel [(set (match_dup 8)
16045 (unspec:XF [(match_dup 7) (match_dup 3)]
16046 UNSPEC_FSCALE_FRACT))
16047 (set (match_dup 9)
16048 (unspec:XF [(match_dup 7) (match_dup 3)]
16049 UNSPEC_FSCALE_EXP))])
16050 (set (match_operand:DF 0 "register_operand" "")
16051 (float_truncate:DF (match_dup 8)))]
16052 "TARGET_USE_FANCY_MATH_387
16053 && flag_unsafe_math_optimizations"
16054 {
16055 int i;
16056
16057 for (i=2; i<10; i++)
16058 operands[i] = gen_reg_rtx (XFmode);
16059 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16060 })
16061
16062 (define_expand "exp2xf2"
16063 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16064 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16065 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16066 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16067 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16068 (parallel [(set (match_operand:XF 0 "register_operand" "")
16069 (unspec:XF [(match_dup 7) (match_dup 3)]
16070 UNSPEC_FSCALE_FRACT))
16071 (set (match_dup 8)
16072 (unspec:XF [(match_dup 7) (match_dup 3)]
16073 UNSPEC_FSCALE_EXP))])]
16074 "TARGET_USE_FANCY_MATH_387
16075 && flag_unsafe_math_optimizations"
16076 {
16077 int i;
16078
16079 for (i=2; i<9; i++)
16080 operands[i] = gen_reg_rtx (XFmode);
16081 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16082 })
16083
16084 (define_expand "expm1df2"
16085 [(set (match_dup 2)
16086 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16087 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16088 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16089 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16090 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16091 (parallel [(set (match_dup 8)
16092 (unspec:XF [(match_dup 7) (match_dup 5)]
16093 UNSPEC_FSCALE_FRACT))
16094 (set (match_dup 9)
16095 (unspec:XF [(match_dup 7) (match_dup 5)]
16096 UNSPEC_FSCALE_EXP))])
16097 (parallel [(set (match_dup 11)
16098 (unspec:XF [(match_dup 10) (match_dup 9)]
16099 UNSPEC_FSCALE_FRACT))
16100 (set (match_dup 12)
16101 (unspec:XF [(match_dup 10) (match_dup 9)]
16102 UNSPEC_FSCALE_EXP))])
16103 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16104 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16105 (set (match_operand:DF 0 "register_operand" "")
16106 (float_truncate:DF (match_dup 14)))]
16107 "TARGET_USE_FANCY_MATH_387
16108 && flag_unsafe_math_optimizations"
16109 {
16110 rtx temp;
16111 int i;
16112
16113 for (i=2; i<15; i++)
16114 operands[i] = gen_reg_rtx (XFmode);
16115 temp = standard_80387_constant_rtx (5); /* fldl2e */
16116 emit_move_insn (operands[3], temp);
16117 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16118 })
16119
16120 (define_expand "expm1sf2"
16121 [(set (match_dup 2)
16122 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16123 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16124 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16125 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16126 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16127 (parallel [(set (match_dup 8)
16128 (unspec:XF [(match_dup 7) (match_dup 5)]
16129 UNSPEC_FSCALE_FRACT))
16130 (set (match_dup 9)
16131 (unspec:XF [(match_dup 7) (match_dup 5)]
16132 UNSPEC_FSCALE_EXP))])
16133 (parallel [(set (match_dup 11)
16134 (unspec:XF [(match_dup 10) (match_dup 9)]
16135 UNSPEC_FSCALE_FRACT))
16136 (set (match_dup 12)
16137 (unspec:XF [(match_dup 10) (match_dup 9)]
16138 UNSPEC_FSCALE_EXP))])
16139 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16140 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16141 (set (match_operand:SF 0 "register_operand" "")
16142 (float_truncate:SF (match_dup 14)))]
16143 "TARGET_USE_FANCY_MATH_387
16144 && flag_unsafe_math_optimizations"
16145 {
16146 rtx temp;
16147 int i;
16148
16149 for (i=2; i<15; i++)
16150 operands[i] = gen_reg_rtx (XFmode);
16151 temp = standard_80387_constant_rtx (5); /* fldl2e */
16152 emit_move_insn (operands[3], temp);
16153 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16154 })
16155
16156 (define_expand "expm1xf2"
16157 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16158 (match_dup 2)))
16159 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16160 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16161 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16162 (parallel [(set (match_dup 7)
16163 (unspec:XF [(match_dup 6) (match_dup 4)]
16164 UNSPEC_FSCALE_FRACT))
16165 (set (match_dup 8)
16166 (unspec:XF [(match_dup 6) (match_dup 4)]
16167 UNSPEC_FSCALE_EXP))])
16168 (parallel [(set (match_dup 10)
16169 (unspec:XF [(match_dup 9) (match_dup 8)]
16170 UNSPEC_FSCALE_FRACT))
16171 (set (match_dup 11)
16172 (unspec:XF [(match_dup 9) (match_dup 8)]
16173 UNSPEC_FSCALE_EXP))])
16174 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16175 (set (match_operand:XF 0 "register_operand" "")
16176 (plus:XF (match_dup 12) (match_dup 7)))]
16177 "TARGET_USE_FANCY_MATH_387
16178 && flag_unsafe_math_optimizations"
16179 {
16180 rtx temp;
16181 int i;
16182
16183 for (i=2; i<13; i++)
16184 operands[i] = gen_reg_rtx (XFmode);
16185 temp = standard_80387_constant_rtx (5); /* fldl2e */
16186 emit_move_insn (operands[2], temp);
16187 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16188 })
16189 \f
16190
16191 (define_insn "frndintxf2"
16192 [(set (match_operand:XF 0 "register_operand" "=f")
16193 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16194 UNSPEC_FRNDINT))]
16195 "TARGET_USE_FANCY_MATH_387
16196 && flag_unsafe_math_optimizations"
16197 "frndint"
16198 [(set_attr "type" "fpspc")
16199 (set_attr "mode" "XF")])
16200
16201 (define_expand "rintdf2"
16202 [(use (match_operand:DF 0 "register_operand" ""))
16203 (use (match_operand:DF 1 "register_operand" ""))]
16204 "TARGET_USE_FANCY_MATH_387
16205 && flag_unsafe_math_optimizations"
16206 {
16207 rtx op0 = gen_reg_rtx (XFmode);
16208 rtx op1 = gen_reg_rtx (XFmode);
16209
16210 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16211 emit_insn (gen_frndintxf2 (op0, op1));
16212
16213 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16214 DONE;
16215 })
16216
16217 (define_expand "rintsf2"
16218 [(use (match_operand:SF 0 "register_operand" ""))
16219 (use (match_operand:SF 1 "register_operand" ""))]
16220 "TARGET_USE_FANCY_MATH_387
16221 && flag_unsafe_math_optimizations"
16222 {
16223 rtx op0 = gen_reg_rtx (XFmode);
16224 rtx op1 = gen_reg_rtx (XFmode);
16225
16226 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16227 emit_insn (gen_frndintxf2 (op0, op1));
16228
16229 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16230 DONE;
16231 })
16232
16233 (define_expand "rintxf2"
16234 [(use (match_operand:XF 0 "register_operand" ""))
16235 (use (match_operand:XF 1 "register_operand" ""))]
16236 "TARGET_USE_FANCY_MATH_387
16237 && flag_unsafe_math_optimizations"
16238 {
16239 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16240 DONE;
16241 })
16242
16243 (define_insn "frndintxf2_floor"
16244 [(set (match_operand:XF 0 "register_operand" "=f")
16245 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16246 UNSPEC_FRNDINT_FLOOR))
16247 (use (match_operand:HI 2 "memory_operand" "m"))
16248 (use (match_operand:HI 3 "memory_operand" "m"))]
16249 "TARGET_USE_FANCY_MATH_387
16250 && flag_unsafe_math_optimizations"
16251 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16252 [(set_attr "type" "frndint")
16253 (set_attr "i387_cw" "floor")
16254 (set_attr "mode" "XF")])
16255
16256 (define_expand "floordf2"
16257 [(use (match_operand:DF 0 "register_operand" ""))
16258 (use (match_operand:DF 1 "register_operand" ""))]
16259 "TARGET_USE_FANCY_MATH_387
16260 && flag_unsafe_math_optimizations"
16261 {
16262 rtx op0 = gen_reg_rtx (XFmode);
16263 rtx op1 = gen_reg_rtx (XFmode);
16264 rtx op2 = assign_386_stack_local (HImode, 1);
16265 rtx op3 = assign_386_stack_local (HImode, 2);
16266
16267 ix86_optimize_mode_switching = 1;
16268
16269 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16270 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16271
16272 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16273 DONE;
16274 })
16275
16276 (define_expand "floorsf2"
16277 [(use (match_operand:SF 0 "register_operand" ""))
16278 (use (match_operand:SF 1 "register_operand" ""))]
16279 "TARGET_USE_FANCY_MATH_387
16280 && flag_unsafe_math_optimizations"
16281 {
16282 rtx op0 = gen_reg_rtx (XFmode);
16283 rtx op1 = gen_reg_rtx (XFmode);
16284 rtx op2 = assign_386_stack_local (HImode, 1);
16285 rtx op3 = assign_386_stack_local (HImode, 2);
16286
16287 ix86_optimize_mode_switching = 1;
16288
16289 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16290 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16291
16292 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16293 DONE;
16294 })
16295
16296 (define_expand "floorxf2"
16297 [(use (match_operand:XF 0 "register_operand" ""))
16298 (use (match_operand:XF 1 "register_operand" ""))]
16299 "TARGET_USE_FANCY_MATH_387
16300 && flag_unsafe_math_optimizations"
16301 {
16302 rtx op2 = assign_386_stack_local (HImode, 1);
16303 rtx op3 = assign_386_stack_local (HImode, 2);
16304
16305 ix86_optimize_mode_switching = 1;
16306
16307 emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16308 DONE;
16309 })
16310
16311 (define_insn "frndintxf2_ceil"
16312 [(set (match_operand:XF 0 "register_operand" "=f")
16313 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16314 UNSPEC_FRNDINT_CEIL))
16315 (use (match_operand:HI 2 "memory_operand" "m"))
16316 (use (match_operand:HI 3 "memory_operand" "m"))]
16317 "TARGET_USE_FANCY_MATH_387
16318 && flag_unsafe_math_optimizations"
16319 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16320 [(set_attr "type" "frndint")
16321 (set_attr "i387_cw" "ceil")
16322 (set_attr "mode" "XF")])
16323
16324 (define_expand "ceildf2"
16325 [(use (match_operand:DF 0 "register_operand" ""))
16326 (use (match_operand:DF 1 "register_operand" ""))]
16327 "TARGET_USE_FANCY_MATH_387
16328 && flag_unsafe_math_optimizations"
16329 {
16330 rtx op0 = gen_reg_rtx (XFmode);
16331 rtx op1 = gen_reg_rtx (XFmode);
16332 rtx op2 = assign_386_stack_local (HImode, 1);
16333 rtx op3 = assign_386_stack_local (HImode, 2);
16334
16335 ix86_optimize_mode_switching = 1;
16336
16337 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16338 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16339
16340 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16341 DONE;
16342 })
16343
16344 (define_expand "ceilsf2"
16345 [(use (match_operand:SF 0 "register_operand" ""))
16346 (use (match_operand:SF 1 "register_operand" ""))]
16347 "TARGET_USE_FANCY_MATH_387
16348 && flag_unsafe_math_optimizations"
16349 {
16350 rtx op0 = gen_reg_rtx (XFmode);
16351 rtx op1 = gen_reg_rtx (XFmode);
16352 rtx op2 = assign_386_stack_local (HImode, 1);
16353 rtx op3 = assign_386_stack_local (HImode, 2);
16354
16355 ix86_optimize_mode_switching = 1;
16356
16357 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16358 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16359
16360 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16361 DONE;
16362 })
16363
16364 (define_expand "ceilxf2"
16365 [(use (match_operand:XF 0 "register_operand" ""))
16366 (use (match_operand:XF 1 "register_operand" ""))]
16367 "TARGET_USE_FANCY_MATH_387
16368 && flag_unsafe_math_optimizations"
16369 {
16370 rtx op2 = assign_386_stack_local (HImode, 1);
16371 rtx op3 = assign_386_stack_local (HImode, 2);
16372
16373 ix86_optimize_mode_switching = 1;
16374
16375 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16376 DONE;
16377 })
16378
16379 (define_insn "frndintxf2_trunc"
16380 [(set (match_operand:XF 0 "register_operand" "=f")
16381 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16382 UNSPEC_FRNDINT_TRUNC))
16383 (use (match_operand:HI 2 "memory_operand" "m"))
16384 (use (match_operand:HI 3 "memory_operand" "m"))]
16385 "TARGET_USE_FANCY_MATH_387
16386 && flag_unsafe_math_optimizations"
16387 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16388 [(set_attr "type" "frndint")
16389 (set_attr "i387_cw" "trunc")
16390 (set_attr "mode" "XF")])
16391
16392 (define_expand "btruncdf2"
16393 [(use (match_operand:DF 0 "register_operand" ""))
16394 (use (match_operand:DF 1 "register_operand" ""))]
16395 "TARGET_USE_FANCY_MATH_387
16396 && flag_unsafe_math_optimizations"
16397 {
16398 rtx op0 = gen_reg_rtx (XFmode);
16399 rtx op1 = gen_reg_rtx (XFmode);
16400 rtx op2 = assign_386_stack_local (HImode, 1);
16401 rtx op3 = assign_386_stack_local (HImode, 2);
16402
16403 ix86_optimize_mode_switching = 1;
16404
16405 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16406 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16407
16408 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16409 DONE;
16410 })
16411
16412 (define_expand "btruncsf2"
16413 [(use (match_operand:SF 0 "register_operand" ""))
16414 (use (match_operand:SF 1 "register_operand" ""))]
16415 "TARGET_USE_FANCY_MATH_387
16416 && flag_unsafe_math_optimizations"
16417 {
16418 rtx op0 = gen_reg_rtx (XFmode);
16419 rtx op1 = gen_reg_rtx (XFmode);
16420 rtx op2 = assign_386_stack_local (HImode, 1);
16421 rtx op3 = assign_386_stack_local (HImode, 2);
16422
16423 ix86_optimize_mode_switching = 1;
16424
16425 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16426 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16427
16428 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16429 DONE;
16430 })
16431
16432 (define_expand "btruncxf2"
16433 [(use (match_operand:XF 0 "register_operand" ""))
16434 (use (match_operand:XF 1 "register_operand" ""))]
16435 "TARGET_USE_FANCY_MATH_387
16436 && flag_unsafe_math_optimizations"
16437 {
16438 rtx op2 = assign_386_stack_local (HImode, 1);
16439 rtx op3 = assign_386_stack_local (HImode, 2);
16440
16441 ix86_optimize_mode_switching = 1;
16442
16443 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16444 DONE;
16445 })
16446
16447 (define_insn "frndintxf2_mask_pm"
16448 [(set (match_operand:XF 0 "register_operand" "=f")
16449 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16450 UNSPEC_FRNDINT_MASK_PM))
16451 (use (match_operand:HI 2 "memory_operand" "m"))
16452 (use (match_operand:HI 3 "memory_operand" "m"))]
16453 "TARGET_USE_FANCY_MATH_387
16454 && flag_unsafe_math_optimizations"
16455 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16456 [(set_attr "type" "frndint")
16457 (set_attr "i387_cw" "mask_pm")
16458 (set_attr "mode" "XF")])
16459
16460 (define_expand "nearbyintdf2"
16461 [(use (match_operand:DF 0 "register_operand" ""))
16462 (use (match_operand:DF 1 "register_operand" ""))]
16463 "TARGET_USE_FANCY_MATH_387
16464 && flag_unsafe_math_optimizations"
16465 {
16466 rtx op0 = gen_reg_rtx (XFmode);
16467 rtx op1 = gen_reg_rtx (XFmode);
16468 rtx op2 = assign_386_stack_local (HImode, 1);
16469 rtx op3 = assign_386_stack_local (HImode, 2);
16470
16471 ix86_optimize_mode_switching = 1;
16472
16473 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16474 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16475
16476 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16477 DONE;
16478 })
16479
16480 (define_expand "nearbyintsf2"
16481 [(use (match_operand:SF 0 "register_operand" ""))
16482 (use (match_operand:SF 1 "register_operand" ""))]
16483 "TARGET_USE_FANCY_MATH_387
16484 && flag_unsafe_math_optimizations"
16485 {
16486 rtx op0 = gen_reg_rtx (XFmode);
16487 rtx op1 = gen_reg_rtx (XFmode);
16488 rtx op2 = assign_386_stack_local (HImode, 1);
16489 rtx op3 = assign_386_stack_local (HImode, 2);
16490
16491 ix86_optimize_mode_switching = 1;
16492
16493 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16494 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16495
16496 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16497 DONE;
16498 })
16499
16500 (define_expand "nearbyintxf2"
16501 [(use (match_operand:XF 0 "register_operand" ""))
16502 (use (match_operand:XF 1 "register_operand" ""))]
16503 "TARGET_USE_FANCY_MATH_387
16504 && flag_unsafe_math_optimizations"
16505 {
16506 rtx op2 = assign_386_stack_local (HImode, 1);
16507 rtx op3 = assign_386_stack_local (HImode, 2);
16508
16509 ix86_optimize_mode_switching = 1;
16510
16511 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16512 op2, op3));
16513 DONE;
16514 })
16515
16516 \f
16517 ;; Block operation instructions
16518
16519 (define_insn "cld"
16520 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16521 ""
16522 "cld"
16523 [(set_attr "type" "cld")])
16524
16525 (define_expand "movmemsi"
16526 [(use (match_operand:BLK 0 "memory_operand" ""))
16527 (use (match_operand:BLK 1 "memory_operand" ""))
16528 (use (match_operand:SI 2 "nonmemory_operand" ""))
16529 (use (match_operand:SI 3 "const_int_operand" ""))]
16530 "! optimize_size"
16531 {
16532 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16533 DONE;
16534 else
16535 FAIL;
16536 })
16537
16538 (define_expand "movmemdi"
16539 [(use (match_operand:BLK 0 "memory_operand" ""))
16540 (use (match_operand:BLK 1 "memory_operand" ""))
16541 (use (match_operand:DI 2 "nonmemory_operand" ""))
16542 (use (match_operand:DI 3 "const_int_operand" ""))]
16543 "TARGET_64BIT"
16544 {
16545 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16546 DONE;
16547 else
16548 FAIL;
16549 })
16550
16551 ;; Most CPUs don't like single string operations
16552 ;; Handle this case here to simplify previous expander.
16553
16554 (define_expand "strmov"
16555 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16556 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16557 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16558 (clobber (reg:CC FLAGS_REG))])
16559 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16560 (clobber (reg:CC FLAGS_REG))])]
16561 ""
16562 {
16563 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16564
16565 /* If .md ever supports :P for Pmode, these can be directly
16566 in the pattern above. */
16567 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16568 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16569
16570 if (TARGET_SINGLE_STRINGOP || optimize_size)
16571 {
16572 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16573 operands[2], operands[3],
16574 operands[5], operands[6]));
16575 DONE;
16576 }
16577
16578 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16579 })
16580
16581 (define_expand "strmov_singleop"
16582 [(parallel [(set (match_operand 1 "memory_operand" "")
16583 (match_operand 3 "memory_operand" ""))
16584 (set (match_operand 0 "register_operand" "")
16585 (match_operand 4 "" ""))
16586 (set (match_operand 2 "register_operand" "")
16587 (match_operand 5 "" ""))
16588 (use (reg:SI DIRFLAG_REG))])]
16589 "TARGET_SINGLE_STRINGOP || optimize_size"
16590 "")
16591
16592 (define_insn "*strmovdi_rex_1"
16593 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16594 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16595 (set (match_operand:DI 0 "register_operand" "=D")
16596 (plus:DI (match_dup 2)
16597 (const_int 8)))
16598 (set (match_operand:DI 1 "register_operand" "=S")
16599 (plus:DI (match_dup 3)
16600 (const_int 8)))
16601 (use (reg:SI DIRFLAG_REG))]
16602 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16603 "movsq"
16604 [(set_attr "type" "str")
16605 (set_attr "mode" "DI")
16606 (set_attr "memory" "both")])
16607
16608 (define_insn "*strmovsi_1"
16609 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16610 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16611 (set (match_operand:SI 0 "register_operand" "=D")
16612 (plus:SI (match_dup 2)
16613 (const_int 4)))
16614 (set (match_operand:SI 1 "register_operand" "=S")
16615 (plus:SI (match_dup 3)
16616 (const_int 4)))
16617 (use (reg:SI DIRFLAG_REG))]
16618 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16619 "{movsl|movsd}"
16620 [(set_attr "type" "str")
16621 (set_attr "mode" "SI")
16622 (set_attr "memory" "both")])
16623
16624 (define_insn "*strmovsi_rex_1"
16625 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16626 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16627 (set (match_operand:DI 0 "register_operand" "=D")
16628 (plus:DI (match_dup 2)
16629 (const_int 4)))
16630 (set (match_operand:DI 1 "register_operand" "=S")
16631 (plus:DI (match_dup 3)
16632 (const_int 4)))
16633 (use (reg:SI DIRFLAG_REG))]
16634 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16635 "{movsl|movsd}"
16636 [(set_attr "type" "str")
16637 (set_attr "mode" "SI")
16638 (set_attr "memory" "both")])
16639
16640 (define_insn "*strmovhi_1"
16641 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16642 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16643 (set (match_operand:SI 0 "register_operand" "=D")
16644 (plus:SI (match_dup 2)
16645 (const_int 2)))
16646 (set (match_operand:SI 1 "register_operand" "=S")
16647 (plus:SI (match_dup 3)
16648 (const_int 2)))
16649 (use (reg:SI DIRFLAG_REG))]
16650 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16651 "movsw"
16652 [(set_attr "type" "str")
16653 (set_attr "memory" "both")
16654 (set_attr "mode" "HI")])
16655
16656 (define_insn "*strmovhi_rex_1"
16657 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16658 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16659 (set (match_operand:DI 0 "register_operand" "=D")
16660 (plus:DI (match_dup 2)
16661 (const_int 2)))
16662 (set (match_operand:DI 1 "register_operand" "=S")
16663 (plus:DI (match_dup 3)
16664 (const_int 2)))
16665 (use (reg:SI DIRFLAG_REG))]
16666 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16667 "movsw"
16668 [(set_attr "type" "str")
16669 (set_attr "memory" "both")
16670 (set_attr "mode" "HI")])
16671
16672 (define_insn "*strmovqi_1"
16673 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16674 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16675 (set (match_operand:SI 0 "register_operand" "=D")
16676 (plus:SI (match_dup 2)
16677 (const_int 1)))
16678 (set (match_operand:SI 1 "register_operand" "=S")
16679 (plus:SI (match_dup 3)
16680 (const_int 1)))
16681 (use (reg:SI DIRFLAG_REG))]
16682 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16683 "movsb"
16684 [(set_attr "type" "str")
16685 (set_attr "memory" "both")
16686 (set_attr "mode" "QI")])
16687
16688 (define_insn "*strmovqi_rex_1"
16689 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16690 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16691 (set (match_operand:DI 0 "register_operand" "=D")
16692 (plus:DI (match_dup 2)
16693 (const_int 1)))
16694 (set (match_operand:DI 1 "register_operand" "=S")
16695 (plus:DI (match_dup 3)
16696 (const_int 1)))
16697 (use (reg:SI DIRFLAG_REG))]
16698 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16699 "movsb"
16700 [(set_attr "type" "str")
16701 (set_attr "memory" "both")
16702 (set_attr "mode" "QI")])
16703
16704 (define_expand "rep_mov"
16705 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16706 (set (match_operand 0 "register_operand" "")
16707 (match_operand 5 "" ""))
16708 (set (match_operand 2 "register_operand" "")
16709 (match_operand 6 "" ""))
16710 (set (match_operand 1 "memory_operand" "")
16711 (match_operand 3 "memory_operand" ""))
16712 (use (match_dup 4))
16713 (use (reg:SI DIRFLAG_REG))])]
16714 ""
16715 "")
16716
16717 (define_insn "*rep_movdi_rex64"
16718 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16719 (set (match_operand:DI 0 "register_operand" "=D")
16720 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16721 (const_int 3))
16722 (match_operand:DI 3 "register_operand" "0")))
16723 (set (match_operand:DI 1 "register_operand" "=S")
16724 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16725 (match_operand:DI 4 "register_operand" "1")))
16726 (set (mem:BLK (match_dup 3))
16727 (mem:BLK (match_dup 4)))
16728 (use (match_dup 5))
16729 (use (reg:SI DIRFLAG_REG))]
16730 "TARGET_64BIT"
16731 "{rep\;movsq|rep movsq}"
16732 [(set_attr "type" "str")
16733 (set_attr "prefix_rep" "1")
16734 (set_attr "memory" "both")
16735 (set_attr "mode" "DI")])
16736
16737 (define_insn "*rep_movsi"
16738 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16739 (set (match_operand:SI 0 "register_operand" "=D")
16740 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16741 (const_int 2))
16742 (match_operand:SI 3 "register_operand" "0")))
16743 (set (match_operand:SI 1 "register_operand" "=S")
16744 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16745 (match_operand:SI 4 "register_operand" "1")))
16746 (set (mem:BLK (match_dup 3))
16747 (mem:BLK (match_dup 4)))
16748 (use (match_dup 5))
16749 (use (reg:SI DIRFLAG_REG))]
16750 "!TARGET_64BIT"
16751 "{rep\;movsl|rep movsd}"
16752 [(set_attr "type" "str")
16753 (set_attr "prefix_rep" "1")
16754 (set_attr "memory" "both")
16755 (set_attr "mode" "SI")])
16756
16757 (define_insn "*rep_movsi_rex64"
16758 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16759 (set (match_operand:DI 0 "register_operand" "=D")
16760 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16761 (const_int 2))
16762 (match_operand:DI 3 "register_operand" "0")))
16763 (set (match_operand:DI 1 "register_operand" "=S")
16764 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16765 (match_operand:DI 4 "register_operand" "1")))
16766 (set (mem:BLK (match_dup 3))
16767 (mem:BLK (match_dup 4)))
16768 (use (match_dup 5))
16769 (use (reg:SI DIRFLAG_REG))]
16770 "TARGET_64BIT"
16771 "{rep\;movsl|rep movsd}"
16772 [(set_attr "type" "str")
16773 (set_attr "prefix_rep" "1")
16774 (set_attr "memory" "both")
16775 (set_attr "mode" "SI")])
16776
16777 (define_insn "*rep_movqi"
16778 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16779 (set (match_operand:SI 0 "register_operand" "=D")
16780 (plus:SI (match_operand:SI 3 "register_operand" "0")
16781 (match_operand:SI 5 "register_operand" "2")))
16782 (set (match_operand:SI 1 "register_operand" "=S")
16783 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16784 (set (mem:BLK (match_dup 3))
16785 (mem:BLK (match_dup 4)))
16786 (use (match_dup 5))
16787 (use (reg:SI DIRFLAG_REG))]
16788 "!TARGET_64BIT"
16789 "{rep\;movsb|rep movsb}"
16790 [(set_attr "type" "str")
16791 (set_attr "prefix_rep" "1")
16792 (set_attr "memory" "both")
16793 (set_attr "mode" "SI")])
16794
16795 (define_insn "*rep_movqi_rex64"
16796 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16797 (set (match_operand:DI 0 "register_operand" "=D")
16798 (plus:DI (match_operand:DI 3 "register_operand" "0")
16799 (match_operand:DI 5 "register_operand" "2")))
16800 (set (match_operand:DI 1 "register_operand" "=S")
16801 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16802 (set (mem:BLK (match_dup 3))
16803 (mem:BLK (match_dup 4)))
16804 (use (match_dup 5))
16805 (use (reg:SI DIRFLAG_REG))]
16806 "TARGET_64BIT"
16807 "{rep\;movsb|rep movsb}"
16808 [(set_attr "type" "str")
16809 (set_attr "prefix_rep" "1")
16810 (set_attr "memory" "both")
16811 (set_attr "mode" "SI")])
16812
16813 (define_expand "clrmemsi"
16814 [(use (match_operand:BLK 0 "memory_operand" ""))
16815 (use (match_operand:SI 1 "nonmemory_operand" ""))
16816 (use (match_operand 2 "const_int_operand" ""))]
16817 ""
16818 {
16819 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16820 DONE;
16821 else
16822 FAIL;
16823 })
16824
16825 (define_expand "clrmemdi"
16826 [(use (match_operand:BLK 0 "memory_operand" ""))
16827 (use (match_operand:DI 1 "nonmemory_operand" ""))
16828 (use (match_operand 2 "const_int_operand" ""))]
16829 "TARGET_64BIT"
16830 {
16831 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16832 DONE;
16833 else
16834 FAIL;
16835 })
16836
16837 ;; Most CPUs don't like single string operations
16838 ;; Handle this case here to simplify previous expander.
16839
16840 (define_expand "strset"
16841 [(set (match_operand 1 "memory_operand" "")
16842 (match_operand 2 "register_operand" ""))
16843 (parallel [(set (match_operand 0 "register_operand" "")
16844 (match_dup 3))
16845 (clobber (reg:CC FLAGS_REG))])]
16846 ""
16847 {
16848 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16849 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16850
16851 /* If .md ever supports :P for Pmode, this can be directly
16852 in the pattern above. */
16853 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16854 GEN_INT (GET_MODE_SIZE (GET_MODE
16855 (operands[2]))));
16856 if (TARGET_SINGLE_STRINGOP || optimize_size)
16857 {
16858 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16859 operands[3]));
16860 DONE;
16861 }
16862 })
16863
16864 (define_expand "strset_singleop"
16865 [(parallel [(set (match_operand 1 "memory_operand" "")
16866 (match_operand 2 "register_operand" ""))
16867 (set (match_operand 0 "register_operand" "")
16868 (match_operand 3 "" ""))
16869 (use (reg:SI DIRFLAG_REG))])]
16870 "TARGET_SINGLE_STRINGOP || optimize_size"
16871 "")
16872
16873 (define_insn "*strsetdi_rex_1"
16874 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16875 (match_operand:DI 2 "register_operand" "a"))
16876 (set (match_operand:DI 0 "register_operand" "=D")
16877 (plus:DI (match_dup 1)
16878 (const_int 8)))
16879 (use (reg:SI DIRFLAG_REG))]
16880 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16881 "stosq"
16882 [(set_attr "type" "str")
16883 (set_attr "memory" "store")
16884 (set_attr "mode" "DI")])
16885
16886 (define_insn "*strsetsi_1"
16887 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16888 (match_operand:SI 2 "register_operand" "a"))
16889 (set (match_operand:SI 0 "register_operand" "=D")
16890 (plus:SI (match_dup 1)
16891 (const_int 4)))
16892 (use (reg:SI DIRFLAG_REG))]
16893 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16894 "{stosl|stosd}"
16895 [(set_attr "type" "str")
16896 (set_attr "memory" "store")
16897 (set_attr "mode" "SI")])
16898
16899 (define_insn "*strsetsi_rex_1"
16900 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16901 (match_operand:SI 2 "register_operand" "a"))
16902 (set (match_operand:DI 0 "register_operand" "=D")
16903 (plus:DI (match_dup 1)
16904 (const_int 4)))
16905 (use (reg:SI DIRFLAG_REG))]
16906 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16907 "{stosl|stosd}"
16908 [(set_attr "type" "str")
16909 (set_attr "memory" "store")
16910 (set_attr "mode" "SI")])
16911
16912 (define_insn "*strsethi_1"
16913 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16914 (match_operand:HI 2 "register_operand" "a"))
16915 (set (match_operand:SI 0 "register_operand" "=D")
16916 (plus:SI (match_dup 1)
16917 (const_int 2)))
16918 (use (reg:SI DIRFLAG_REG))]
16919 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16920 "stosw"
16921 [(set_attr "type" "str")
16922 (set_attr "memory" "store")
16923 (set_attr "mode" "HI")])
16924
16925 (define_insn "*strsethi_rex_1"
16926 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16927 (match_operand:HI 2 "register_operand" "a"))
16928 (set (match_operand:DI 0 "register_operand" "=D")
16929 (plus:DI (match_dup 1)
16930 (const_int 2)))
16931 (use (reg:SI DIRFLAG_REG))]
16932 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16933 "stosw"
16934 [(set_attr "type" "str")
16935 (set_attr "memory" "store")
16936 (set_attr "mode" "HI")])
16937
16938 (define_insn "*strsetqi_1"
16939 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16940 (match_operand:QI 2 "register_operand" "a"))
16941 (set (match_operand:SI 0 "register_operand" "=D")
16942 (plus:SI (match_dup 1)
16943 (const_int 1)))
16944 (use (reg:SI DIRFLAG_REG))]
16945 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16946 "stosb"
16947 [(set_attr "type" "str")
16948 (set_attr "memory" "store")
16949 (set_attr "mode" "QI")])
16950
16951 (define_insn "*strsetqi_rex_1"
16952 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16953 (match_operand:QI 2 "register_operand" "a"))
16954 (set (match_operand:DI 0 "register_operand" "=D")
16955 (plus:DI (match_dup 1)
16956 (const_int 1)))
16957 (use (reg:SI DIRFLAG_REG))]
16958 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16959 "stosb"
16960 [(set_attr "type" "str")
16961 (set_attr "memory" "store")
16962 (set_attr "mode" "QI")])
16963
16964 (define_expand "rep_stos"
16965 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16966 (set (match_operand 0 "register_operand" "")
16967 (match_operand 4 "" ""))
16968 (set (match_operand 2 "memory_operand" "") (const_int 0))
16969 (use (match_operand 3 "register_operand" ""))
16970 (use (match_dup 1))
16971 (use (reg:SI DIRFLAG_REG))])]
16972 ""
16973 "")
16974
16975 (define_insn "*rep_stosdi_rex64"
16976 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16977 (set (match_operand:DI 0 "register_operand" "=D")
16978 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16979 (const_int 3))
16980 (match_operand:DI 3 "register_operand" "0")))
16981 (set (mem:BLK (match_dup 3))
16982 (const_int 0))
16983 (use (match_operand:DI 2 "register_operand" "a"))
16984 (use (match_dup 4))
16985 (use (reg:SI DIRFLAG_REG))]
16986 "TARGET_64BIT"
16987 "{rep\;stosq|rep stosq}"
16988 [(set_attr "type" "str")
16989 (set_attr "prefix_rep" "1")
16990 (set_attr "memory" "store")
16991 (set_attr "mode" "DI")])
16992
16993 (define_insn "*rep_stossi"
16994 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16995 (set (match_operand:SI 0 "register_operand" "=D")
16996 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16997 (const_int 2))
16998 (match_operand:SI 3 "register_operand" "0")))
16999 (set (mem:BLK (match_dup 3))
17000 (const_int 0))
17001 (use (match_operand:SI 2 "register_operand" "a"))
17002 (use (match_dup 4))
17003 (use (reg:SI DIRFLAG_REG))]
17004 "!TARGET_64BIT"
17005 "{rep\;stosl|rep stosd}"
17006 [(set_attr "type" "str")
17007 (set_attr "prefix_rep" "1")
17008 (set_attr "memory" "store")
17009 (set_attr "mode" "SI")])
17010
17011 (define_insn "*rep_stossi_rex64"
17012 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17013 (set (match_operand:DI 0 "register_operand" "=D")
17014 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17015 (const_int 2))
17016 (match_operand:DI 3 "register_operand" "0")))
17017 (set (mem:BLK (match_dup 3))
17018 (const_int 0))
17019 (use (match_operand:SI 2 "register_operand" "a"))
17020 (use (match_dup 4))
17021 (use (reg:SI DIRFLAG_REG))]
17022 "TARGET_64BIT"
17023 "{rep\;stosl|rep stosd}"
17024 [(set_attr "type" "str")
17025 (set_attr "prefix_rep" "1")
17026 (set_attr "memory" "store")
17027 (set_attr "mode" "SI")])
17028
17029 (define_insn "*rep_stosqi"
17030 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17031 (set (match_operand:SI 0 "register_operand" "=D")
17032 (plus:SI (match_operand:SI 3 "register_operand" "0")
17033 (match_operand:SI 4 "register_operand" "1")))
17034 (set (mem:BLK (match_dup 3))
17035 (const_int 0))
17036 (use (match_operand:QI 2 "register_operand" "a"))
17037 (use (match_dup 4))
17038 (use (reg:SI DIRFLAG_REG))]
17039 "!TARGET_64BIT"
17040 "{rep\;stosb|rep stosb}"
17041 [(set_attr "type" "str")
17042 (set_attr "prefix_rep" "1")
17043 (set_attr "memory" "store")
17044 (set_attr "mode" "QI")])
17045
17046 (define_insn "*rep_stosqi_rex64"
17047 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17048 (set (match_operand:DI 0 "register_operand" "=D")
17049 (plus:DI (match_operand:DI 3 "register_operand" "0")
17050 (match_operand:DI 4 "register_operand" "1")))
17051 (set (mem:BLK (match_dup 3))
17052 (const_int 0))
17053 (use (match_operand:QI 2 "register_operand" "a"))
17054 (use (match_dup 4))
17055 (use (reg:SI DIRFLAG_REG))]
17056 "TARGET_64BIT"
17057 "{rep\;stosb|rep stosb}"
17058 [(set_attr "type" "str")
17059 (set_attr "prefix_rep" "1")
17060 (set_attr "memory" "store")
17061 (set_attr "mode" "QI")])
17062
17063 (define_expand "cmpstrsi"
17064 [(set (match_operand:SI 0 "register_operand" "")
17065 (compare:SI (match_operand:BLK 1 "general_operand" "")
17066 (match_operand:BLK 2 "general_operand" "")))
17067 (use (match_operand 3 "general_operand" ""))
17068 (use (match_operand 4 "immediate_operand" ""))]
17069 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17070 {
17071 rtx addr1, addr2, out, outlow, count, countreg, align;
17072
17073 /* Can't use this if the user has appropriated esi or edi. */
17074 if (global_regs[4] || global_regs[5])
17075 FAIL;
17076
17077 out = operands[0];
17078 if (GET_CODE (out) != REG)
17079 out = gen_reg_rtx (SImode);
17080
17081 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17082 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17083 if (addr1 != XEXP (operands[1], 0))
17084 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17085 if (addr2 != XEXP (operands[2], 0))
17086 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17087
17088 count = operands[3];
17089 countreg = ix86_zero_extend_to_Pmode (count);
17090
17091 /* %%% Iff we are testing strict equality, we can use known alignment
17092 to good advantage. This may be possible with combine, particularly
17093 once cc0 is dead. */
17094 align = operands[4];
17095
17096 emit_insn (gen_cld ());
17097 if (GET_CODE (count) == CONST_INT)
17098 {
17099 if (INTVAL (count) == 0)
17100 {
17101 emit_move_insn (operands[0], const0_rtx);
17102 DONE;
17103 }
17104 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17105 operands[1], operands[2]));
17106 }
17107 else
17108 {
17109 if (TARGET_64BIT)
17110 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17111 else
17112 emit_insn (gen_cmpsi_1 (countreg, countreg));
17113 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17114 operands[1], operands[2]));
17115 }
17116
17117 outlow = gen_lowpart (QImode, out);
17118 emit_insn (gen_cmpintqi (outlow));
17119 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17120
17121 if (operands[0] != out)
17122 emit_move_insn (operands[0], out);
17123
17124 DONE;
17125 })
17126
17127 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17128
17129 (define_expand "cmpintqi"
17130 [(set (match_dup 1)
17131 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17132 (set (match_dup 2)
17133 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17134 (parallel [(set (match_operand:QI 0 "register_operand" "")
17135 (minus:QI (match_dup 1)
17136 (match_dup 2)))
17137 (clobber (reg:CC FLAGS_REG))])]
17138 ""
17139 "operands[1] = gen_reg_rtx (QImode);
17140 operands[2] = gen_reg_rtx (QImode);")
17141
17142 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17143 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17144
17145 (define_expand "cmpstrqi_nz_1"
17146 [(parallel [(set (reg:CC FLAGS_REG)
17147 (compare:CC (match_operand 4 "memory_operand" "")
17148 (match_operand 5 "memory_operand" "")))
17149 (use (match_operand 2 "register_operand" ""))
17150 (use (match_operand:SI 3 "immediate_operand" ""))
17151 (use (reg:SI DIRFLAG_REG))
17152 (clobber (match_operand 0 "register_operand" ""))
17153 (clobber (match_operand 1 "register_operand" ""))
17154 (clobber (match_dup 2))])]
17155 ""
17156 "")
17157
17158 (define_insn "*cmpstrqi_nz_1"
17159 [(set (reg:CC FLAGS_REG)
17160 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17161 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17162 (use (match_operand:SI 6 "register_operand" "2"))
17163 (use (match_operand:SI 3 "immediate_operand" "i"))
17164 (use (reg:SI DIRFLAG_REG))
17165 (clobber (match_operand:SI 0 "register_operand" "=S"))
17166 (clobber (match_operand:SI 1 "register_operand" "=D"))
17167 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17168 "!TARGET_64BIT"
17169 "repz{\;| }cmpsb"
17170 [(set_attr "type" "str")
17171 (set_attr "mode" "QI")
17172 (set_attr "prefix_rep" "1")])
17173
17174 (define_insn "*cmpstrqi_nz_rex_1"
17175 [(set (reg:CC FLAGS_REG)
17176 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17177 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17178 (use (match_operand:DI 6 "register_operand" "2"))
17179 (use (match_operand:SI 3 "immediate_operand" "i"))
17180 (use (reg:SI DIRFLAG_REG))
17181 (clobber (match_operand:DI 0 "register_operand" "=S"))
17182 (clobber (match_operand:DI 1 "register_operand" "=D"))
17183 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17184 "TARGET_64BIT"
17185 "repz{\;| }cmpsb"
17186 [(set_attr "type" "str")
17187 (set_attr "mode" "QI")
17188 (set_attr "prefix_rep" "1")])
17189
17190 ;; The same, but the count is not known to not be zero.
17191
17192 (define_expand "cmpstrqi_1"
17193 [(parallel [(set (reg:CC FLAGS_REG)
17194 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17195 (const_int 0))
17196 (compare:CC (match_operand 4 "memory_operand" "")
17197 (match_operand 5 "memory_operand" ""))
17198 (const_int 0)))
17199 (use (match_operand:SI 3 "immediate_operand" ""))
17200 (use (reg:CC FLAGS_REG))
17201 (use (reg:SI DIRFLAG_REG))
17202 (clobber (match_operand 0 "register_operand" ""))
17203 (clobber (match_operand 1 "register_operand" ""))
17204 (clobber (match_dup 2))])]
17205 ""
17206 "")
17207
17208 (define_insn "*cmpstrqi_1"
17209 [(set (reg:CC FLAGS_REG)
17210 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17211 (const_int 0))
17212 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17213 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17214 (const_int 0)))
17215 (use (match_operand:SI 3 "immediate_operand" "i"))
17216 (use (reg:CC FLAGS_REG))
17217 (use (reg:SI DIRFLAG_REG))
17218 (clobber (match_operand:SI 0 "register_operand" "=S"))
17219 (clobber (match_operand:SI 1 "register_operand" "=D"))
17220 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17221 "!TARGET_64BIT"
17222 "repz{\;| }cmpsb"
17223 [(set_attr "type" "str")
17224 (set_attr "mode" "QI")
17225 (set_attr "prefix_rep" "1")])
17226
17227 (define_insn "*cmpstrqi_rex_1"
17228 [(set (reg:CC FLAGS_REG)
17229 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17230 (const_int 0))
17231 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17232 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17233 (const_int 0)))
17234 (use (match_operand:SI 3 "immediate_operand" "i"))
17235 (use (reg:CC FLAGS_REG))
17236 (use (reg:SI DIRFLAG_REG))
17237 (clobber (match_operand:DI 0 "register_operand" "=S"))
17238 (clobber (match_operand:DI 1 "register_operand" "=D"))
17239 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17240 "TARGET_64BIT"
17241 "repz{\;| }cmpsb"
17242 [(set_attr "type" "str")
17243 (set_attr "mode" "QI")
17244 (set_attr "prefix_rep" "1")])
17245
17246 (define_expand "strlensi"
17247 [(set (match_operand:SI 0 "register_operand" "")
17248 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17249 (match_operand:QI 2 "immediate_operand" "")
17250 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17251 ""
17252 {
17253 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17254 DONE;
17255 else
17256 FAIL;
17257 })
17258
17259 (define_expand "strlendi"
17260 [(set (match_operand:DI 0 "register_operand" "")
17261 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17262 (match_operand:QI 2 "immediate_operand" "")
17263 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17264 ""
17265 {
17266 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17267 DONE;
17268 else
17269 FAIL;
17270 })
17271
17272 (define_expand "strlenqi_1"
17273 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17274 (use (reg:SI DIRFLAG_REG))
17275 (clobber (match_operand 1 "register_operand" ""))
17276 (clobber (reg:CC FLAGS_REG))])]
17277 ""
17278 "")
17279
17280 (define_insn "*strlenqi_1"
17281 [(set (match_operand:SI 0 "register_operand" "=&c")
17282 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17283 (match_operand:QI 2 "register_operand" "a")
17284 (match_operand:SI 3 "immediate_operand" "i")
17285 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17286 (use (reg:SI DIRFLAG_REG))
17287 (clobber (match_operand:SI 1 "register_operand" "=D"))
17288 (clobber (reg:CC FLAGS_REG))]
17289 "!TARGET_64BIT"
17290 "repnz{\;| }scasb"
17291 [(set_attr "type" "str")
17292 (set_attr "mode" "QI")
17293 (set_attr "prefix_rep" "1")])
17294
17295 (define_insn "*strlenqi_rex_1"
17296 [(set (match_operand:DI 0 "register_operand" "=&c")
17297 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17298 (match_operand:QI 2 "register_operand" "a")
17299 (match_operand:DI 3 "immediate_operand" "i")
17300 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17301 (use (reg:SI DIRFLAG_REG))
17302 (clobber (match_operand:DI 1 "register_operand" "=D"))
17303 (clobber (reg:CC FLAGS_REG))]
17304 "TARGET_64BIT"
17305 "repnz{\;| }scasb"
17306 [(set_attr "type" "str")
17307 (set_attr "mode" "QI")
17308 (set_attr "prefix_rep" "1")])
17309
17310 ;; Peephole optimizations to clean up after cmpstr*. This should be
17311 ;; handled in combine, but it is not currently up to the task.
17312 ;; When used for their truth value, the cmpstr* expanders generate
17313 ;; code like this:
17314 ;;
17315 ;; repz cmpsb
17316 ;; seta %al
17317 ;; setb %dl
17318 ;; cmpb %al, %dl
17319 ;; jcc label
17320 ;;
17321 ;; The intermediate three instructions are unnecessary.
17322
17323 ;; This one handles cmpstr*_nz_1...
17324 (define_peephole2
17325 [(parallel[
17326 (set (reg:CC FLAGS_REG)
17327 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17328 (mem:BLK (match_operand 5 "register_operand" ""))))
17329 (use (match_operand 6 "register_operand" ""))
17330 (use (match_operand:SI 3 "immediate_operand" ""))
17331 (use (reg:SI DIRFLAG_REG))
17332 (clobber (match_operand 0 "register_operand" ""))
17333 (clobber (match_operand 1 "register_operand" ""))
17334 (clobber (match_operand 2 "register_operand" ""))])
17335 (set (match_operand:QI 7 "register_operand" "")
17336 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17337 (set (match_operand:QI 8 "register_operand" "")
17338 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17339 (set (reg FLAGS_REG)
17340 (compare (match_dup 7) (match_dup 8)))
17341 ]
17342 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17343 [(parallel[
17344 (set (reg:CC FLAGS_REG)
17345 (compare:CC (mem:BLK (match_dup 4))
17346 (mem:BLK (match_dup 5))))
17347 (use (match_dup 6))
17348 (use (match_dup 3))
17349 (use (reg:SI DIRFLAG_REG))
17350 (clobber (match_dup 0))
17351 (clobber (match_dup 1))
17352 (clobber (match_dup 2))])]
17353 "")
17354
17355 ;; ...and this one handles cmpstr*_1.
17356 (define_peephole2
17357 [(parallel[
17358 (set (reg:CC FLAGS_REG)
17359 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17360 (const_int 0))
17361 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17362 (mem:BLK (match_operand 5 "register_operand" "")))
17363 (const_int 0)))
17364 (use (match_operand:SI 3 "immediate_operand" ""))
17365 (use (reg:CC FLAGS_REG))
17366 (use (reg:SI DIRFLAG_REG))
17367 (clobber (match_operand 0 "register_operand" ""))
17368 (clobber (match_operand 1 "register_operand" ""))
17369 (clobber (match_operand 2 "register_operand" ""))])
17370 (set (match_operand:QI 7 "register_operand" "")
17371 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17372 (set (match_operand:QI 8 "register_operand" "")
17373 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17374 (set (reg FLAGS_REG)
17375 (compare (match_dup 7) (match_dup 8)))
17376 ]
17377 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17378 [(parallel[
17379 (set (reg:CC FLAGS_REG)
17380 (if_then_else:CC (ne (match_dup 6)
17381 (const_int 0))
17382 (compare:CC (mem:BLK (match_dup 4))
17383 (mem:BLK (match_dup 5)))
17384 (const_int 0)))
17385 (use (match_dup 3))
17386 (use (reg:CC FLAGS_REG))
17387 (use (reg:SI DIRFLAG_REG))
17388 (clobber (match_dup 0))
17389 (clobber (match_dup 1))
17390 (clobber (match_dup 2))])]
17391 "")
17392
17393
17394 \f
17395 ;; Conditional move instructions.
17396
17397 (define_expand "movdicc"
17398 [(set (match_operand:DI 0 "register_operand" "")
17399 (if_then_else:DI (match_operand 1 "comparison_operator" "")
17400 (match_operand:DI 2 "general_operand" "")
17401 (match_operand:DI 3 "general_operand" "")))]
17402 "TARGET_64BIT"
17403 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17404
17405 (define_insn "x86_movdicc_0_m1_rex64"
17406 [(set (match_operand:DI 0 "register_operand" "=r")
17407 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17408 (const_int -1)
17409 (const_int 0)))
17410 (clobber (reg:CC FLAGS_REG))]
17411 "TARGET_64BIT"
17412 "sbb{q}\t%0, %0"
17413 ; Since we don't have the proper number of operands for an alu insn,
17414 ; fill in all the blanks.
17415 [(set_attr "type" "alu")
17416 (set_attr "pent_pair" "pu")
17417 (set_attr "memory" "none")
17418 (set_attr "imm_disp" "false")
17419 (set_attr "mode" "DI")
17420 (set_attr "length_immediate" "0")])
17421
17422 (define_insn "*movdicc_c_rex64"
17423 [(set (match_operand:DI 0 "register_operand" "=r,r")
17424 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17425 [(reg FLAGS_REG) (const_int 0)])
17426 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17427 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17428 "TARGET_64BIT && TARGET_CMOVE
17429 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17430 "@
17431 cmov%O2%C1\t{%2, %0|%0, %2}
17432 cmov%O2%c1\t{%3, %0|%0, %3}"
17433 [(set_attr "type" "icmov")
17434 (set_attr "mode" "DI")])
17435
17436 (define_expand "movsicc"
17437 [(set (match_operand:SI 0 "register_operand" "")
17438 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17439 (match_operand:SI 2 "general_operand" "")
17440 (match_operand:SI 3 "general_operand" "")))]
17441 ""
17442 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17443
17444 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17445 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17446 ;; So just document what we're doing explicitly.
17447
17448 (define_insn "x86_movsicc_0_m1"
17449 [(set (match_operand:SI 0 "register_operand" "=r")
17450 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17451 (const_int -1)
17452 (const_int 0)))
17453 (clobber (reg:CC FLAGS_REG))]
17454 ""
17455 "sbb{l}\t%0, %0"
17456 ; Since we don't have the proper number of operands for an alu insn,
17457 ; fill in all the blanks.
17458 [(set_attr "type" "alu")
17459 (set_attr "pent_pair" "pu")
17460 (set_attr "memory" "none")
17461 (set_attr "imm_disp" "false")
17462 (set_attr "mode" "SI")
17463 (set_attr "length_immediate" "0")])
17464
17465 (define_insn "*movsicc_noc"
17466 [(set (match_operand:SI 0 "register_operand" "=r,r")
17467 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17468 [(reg FLAGS_REG) (const_int 0)])
17469 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17470 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17471 "TARGET_CMOVE
17472 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17473 "@
17474 cmov%O2%C1\t{%2, %0|%0, %2}
17475 cmov%O2%c1\t{%3, %0|%0, %3}"
17476 [(set_attr "type" "icmov")
17477 (set_attr "mode" "SI")])
17478
17479 (define_expand "movhicc"
17480 [(set (match_operand:HI 0 "register_operand" "")
17481 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17482 (match_operand:HI 2 "general_operand" "")
17483 (match_operand:HI 3 "general_operand" "")))]
17484 "TARGET_HIMODE_MATH"
17485 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17486
17487 (define_insn "*movhicc_noc"
17488 [(set (match_operand:HI 0 "register_operand" "=r,r")
17489 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17490 [(reg FLAGS_REG) (const_int 0)])
17491 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17492 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17493 "TARGET_CMOVE
17494 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17495 "@
17496 cmov%O2%C1\t{%2, %0|%0, %2}
17497 cmov%O2%c1\t{%3, %0|%0, %3}"
17498 [(set_attr "type" "icmov")
17499 (set_attr "mode" "HI")])
17500
17501 (define_expand "movqicc"
17502 [(set (match_operand:QI 0 "register_operand" "")
17503 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17504 (match_operand:QI 2 "general_operand" "")
17505 (match_operand:QI 3 "general_operand" "")))]
17506 "TARGET_QIMODE_MATH"
17507 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17508
17509 (define_insn_and_split "*movqicc_noc"
17510 [(set (match_operand:QI 0 "register_operand" "=r,r")
17511 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17512 [(match_operand 4 "flags_reg_operand" "")
17513 (const_int 0)])
17514 (match_operand:QI 2 "register_operand" "r,0")
17515 (match_operand:QI 3 "register_operand" "0,r")))]
17516 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17517 "#"
17518 "&& reload_completed"
17519 [(set (match_dup 0)
17520 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17521 (match_dup 2)
17522 (match_dup 3)))]
17523 "operands[0] = gen_lowpart (SImode, operands[0]);
17524 operands[2] = gen_lowpart (SImode, operands[2]);
17525 operands[3] = gen_lowpart (SImode, operands[3]);"
17526 [(set_attr "type" "icmov")
17527 (set_attr "mode" "SI")])
17528
17529 (define_expand "movsfcc"
17530 [(set (match_operand:SF 0 "register_operand" "")
17531 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17532 (match_operand:SF 2 "register_operand" "")
17533 (match_operand:SF 3 "register_operand" "")))]
17534 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17535 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17536
17537 ;; These versions of min/max are aware of the instruction's behaviour
17538 ;; wrt -0.0 and NaN inputs. If we don't care about either, then we
17539 ;; should have used the smin/smax expanders in the first place.
17540 (define_insn "*movsfcc_1_sse_min"
17541 [(set (match_operand:SF 0 "register_operand" "=x")
17542 (if_then_else:SF
17543 (lt:SF (match_operand:SF 1 "register_operand" "0")
17544 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17545 (match_dup 1)
17546 (match_dup 2)))]
17547 "TARGET_SSE_MATH"
17548 "minss\t{%2, %0|%0, %2}"
17549 [(set_attr "type" "sseadd")
17550 (set_attr "mode" "SF")])
17551
17552 (define_insn "*movsfcc_1_sse_max"
17553 [(set (match_operand:SF 0 "register_operand" "=x")
17554 (if_then_else:SF
17555 (lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm")
17556 (match_operand:SF 1 "register_operand" "0"))
17557 (match_dup 1)
17558 (match_dup 2)))]
17559 "TARGET_SSE_MATH"
17560 "maxss\t{%2, %0|%0, %2}"
17561 [(set_attr "type" "sseadd")
17562 (set_attr "mode" "SF")])
17563
17564 (define_insn_and_split "*movsfcc_1_sse"
17565 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
17566 (if_then_else:SF
17567 (match_operator:SF 4 "sse_comparison_operator"
17568 [(match_operand:SF 5 "register_operand" "0,0,0")
17569 (match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")])
17570 (match_operand:SF 2 "reg_or_0_operand" "C,x,1")
17571 (match_operand:SF 3 "reg_or_0_operand" "x,C,x")))
17572 (clobber (match_scratch:V4SF 1 "=X,X,x"))]
17573 "TARGET_SSE_MATH"
17574 "#"
17575 "&& reload_completed"
17576 [(const_int 0)]
17577 {
17578 ix86_split_sse_movcc (operands);
17579 DONE;
17580 })
17581
17582 (define_insn "*movsfcc_1_387"
17583 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17584 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17585 [(reg FLAGS_REG) (const_int 0)])
17586 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17587 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17588 "TARGET_80387 && TARGET_CMOVE
17589 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17590 "@
17591 fcmov%F1\t{%2, %0|%0, %2}
17592 fcmov%f1\t{%3, %0|%0, %3}
17593 cmov%O2%C1\t{%2, %0|%0, %2}
17594 cmov%O2%c1\t{%3, %0|%0, %3}"
17595 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17596 (set_attr "mode" "SF,SF,SI,SI")])
17597
17598 (define_expand "movdfcc"
17599 [(set (match_operand:DF 0 "register_operand" "")
17600 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17601 (match_operand:DF 2 "register_operand" "")
17602 (match_operand:DF 3 "register_operand" "")))]
17603 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17604 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17605
17606 ;; These versions of min/max are aware of the instruction's behaviour
17607 ;; wrt -0.0 and NaN inputs. If we don't care about either, then we
17608 ;; should have used the smin/smax expanders in the first place.
17609 (define_insn "*movdfcc_1_sse_min"
17610 [(set (match_operand:DF 0 "register_operand" "=x")
17611 (if_then_else:DF
17612 (lt:DF (match_operand:DF 1 "register_operand" "0")
17613 (match_operand:DF 2 "nonimmediate_operand" "xm"))
17614 (match_dup 1)
17615 (match_dup 2)))]
17616 "TARGET_SSE2 && TARGET_SSE_MATH"
17617 "minsd\t{%2, %0|%0, %2}"
17618 [(set_attr "type" "sseadd")
17619 (set_attr "mode" "DF")])
17620
17621 (define_insn "*movdfcc_1_sse_max"
17622 [(set (match_operand:DF 0 "register_operand" "=x")
17623 (if_then_else:DF
17624 (lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm")
17625 (match_operand:DF 1 "register_operand" "0"))
17626 (match_dup 1)
17627 (match_dup 2)))]
17628 "TARGET_SSE2 && TARGET_SSE_MATH"
17629 "maxsd\t{%2, %0|%0, %2}"
17630 [(set_attr "type" "sseadd")
17631 (set_attr "mode" "DF")])
17632
17633 (define_insn_and_split "*movdfcc_1_sse"
17634 [(set (match_operand:DF 0 "register_operand" "=x,x,x")
17635 (if_then_else:DF
17636 (match_operator:DF 4 "sse_comparison_operator"
17637 [(match_operand:DF 5 "register_operand" "0,0,0")
17638 (match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")])
17639 (match_operand:DF 2 "reg_or_0_operand" "C,x,1")
17640 (match_operand:DF 3 "reg_or_0_operand" "x,C,x")))
17641 (clobber (match_scratch:V2DF 1 "=X,X,x"))]
17642 "TARGET_SSE2 && TARGET_SSE_MATH"
17643 "#"
17644 "&& reload_completed"
17645 [(const_int 0)]
17646 {
17647 ix86_split_sse_movcc (operands);
17648 DONE;
17649 })
17650
17651 (define_insn "*movdfcc_1"
17652 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17653 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17654 [(reg FLAGS_REG) (const_int 0)])
17655 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17656 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17657 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17658 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17659 "@
17660 fcmov%F1\t{%2, %0|%0, %2}
17661 fcmov%f1\t{%3, %0|%0, %3}
17662 #
17663 #"
17664 [(set_attr "type" "fcmov,fcmov,multi,multi")
17665 (set_attr "mode" "DF")])
17666
17667 (define_insn "*movdfcc_1_rex64"
17668 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17669 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17670 [(reg FLAGS_REG) (const_int 0)])
17671 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17672 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17673 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17674 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17675 "@
17676 fcmov%F1\t{%2, %0|%0, %2}
17677 fcmov%f1\t{%3, %0|%0, %3}
17678 cmov%O2%C1\t{%2, %0|%0, %2}
17679 cmov%O2%c1\t{%3, %0|%0, %3}"
17680 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17681 (set_attr "mode" "DF")])
17682
17683 (define_split
17684 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17685 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17686 [(match_operand 4 "flags_reg_operand" "")
17687 (const_int 0)])
17688 (match_operand:DF 2 "nonimmediate_operand" "")
17689 (match_operand:DF 3 "nonimmediate_operand" "")))]
17690 "!TARGET_64BIT && reload_completed"
17691 [(set (match_dup 2)
17692 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17693 (match_dup 5)
17694 (match_dup 7)))
17695 (set (match_dup 3)
17696 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17697 (match_dup 6)
17698 (match_dup 8)))]
17699 "split_di (operands+2, 1, operands+5, operands+6);
17700 split_di (operands+3, 1, operands+7, operands+8);
17701 split_di (operands, 1, operands+2, operands+3);")
17702
17703 (define_expand "movxfcc"
17704 [(set (match_operand:XF 0 "register_operand" "")
17705 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17706 (match_operand:XF 2 "register_operand" "")
17707 (match_operand:XF 3 "register_operand" "")))]
17708 "TARGET_80387 && TARGET_CMOVE"
17709 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17710
17711 (define_insn "*movxfcc_1"
17712 [(set (match_operand:XF 0 "register_operand" "=f,f")
17713 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17714 [(reg FLAGS_REG) (const_int 0)])
17715 (match_operand:XF 2 "register_operand" "f,0")
17716 (match_operand:XF 3 "register_operand" "0,f")))]
17717 "TARGET_80387 && TARGET_CMOVE"
17718 "@
17719 fcmov%F1\t{%2, %0|%0, %2}
17720 fcmov%f1\t{%3, %0|%0, %3}"
17721 [(set_attr "type" "fcmov")
17722 (set_attr "mode" "XF")])
17723
17724 ;; These versions of the min/max patterns are intentionally ignorant of
17725 ;; their behaviour wrt -0.0 and NaN (via the commutative operand mark).
17726 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17727 ;; are undefined in this condition, we're certain this is correct.
17728
17729 (define_insn "sminsf3"
17730 [(set (match_operand:SF 0 "register_operand" "=x")
17731 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17732 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17733 "TARGET_SSE_MATH"
17734 "minss\t{%2, %0|%0, %2}"
17735 [(set_attr "type" "sseadd")
17736 (set_attr "mode" "SF")])
17737
17738 (define_insn "smaxsf3"
17739 [(set (match_operand:SF 0 "register_operand" "=x")
17740 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17741 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17742 "TARGET_SSE_MATH"
17743 "minss\t{%2, %0|%0, %2}"
17744 [(set_attr "type" "sseadd")
17745 (set_attr "mode" "SF")])
17746
17747 (define_insn "smindf3"
17748 [(set (match_operand:DF 0 "register_operand" "=x")
17749 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17750 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17751 "TARGET_SSE2 && TARGET_SSE_MATH"
17752 "minsd\t{%2, %0|%0, %2}"
17753 [(set_attr "type" "sseadd")
17754 (set_attr "mode" "DF")])
17755
17756 (define_insn "smaxdf3"
17757 [(set (match_operand:DF 0 "register_operand" "=x")
17758 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17759 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17760 "TARGET_SSE2 && TARGET_SSE_MATH"
17761 "maxsd\t{%2, %0|%0, %2}"
17762 [(set_attr "type" "sseadd")
17763 (set_attr "mode" "DF")])
17764
17765 ;; Conditional addition patterns
17766 (define_expand "addqicc"
17767 [(match_operand:QI 0 "register_operand" "")
17768 (match_operand 1 "comparison_operator" "")
17769 (match_operand:QI 2 "register_operand" "")
17770 (match_operand:QI 3 "const_int_operand" "")]
17771 ""
17772 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17773
17774 (define_expand "addhicc"
17775 [(match_operand:HI 0 "register_operand" "")
17776 (match_operand 1 "comparison_operator" "")
17777 (match_operand:HI 2 "register_operand" "")
17778 (match_operand:HI 3 "const_int_operand" "")]
17779 ""
17780 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17781
17782 (define_expand "addsicc"
17783 [(match_operand:SI 0 "register_operand" "")
17784 (match_operand 1 "comparison_operator" "")
17785 (match_operand:SI 2 "register_operand" "")
17786 (match_operand:SI 3 "const_int_operand" "")]
17787 ""
17788 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17789
17790 (define_expand "adddicc"
17791 [(match_operand:DI 0 "register_operand" "")
17792 (match_operand 1 "comparison_operator" "")
17793 (match_operand:DI 2 "register_operand" "")
17794 (match_operand:DI 3 "const_int_operand" "")]
17795 "TARGET_64BIT"
17796 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17797
17798 \f
17799 ;; Misc patterns (?)
17800
17801 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17802 ;; Otherwise there will be nothing to keep
17803 ;;
17804 ;; [(set (reg ebp) (reg esp))]
17805 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17806 ;; (clobber (eflags)]
17807 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17808 ;;
17809 ;; in proper program order.
17810 (define_insn "pro_epilogue_adjust_stack_1"
17811 [(set (match_operand:SI 0 "register_operand" "=r,r")
17812 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17813 (match_operand:SI 2 "immediate_operand" "i,i")))
17814 (clobber (reg:CC FLAGS_REG))
17815 (clobber (mem:BLK (scratch)))]
17816 "!TARGET_64BIT"
17817 {
17818 switch (get_attr_type (insn))
17819 {
17820 case TYPE_IMOV:
17821 return "mov{l}\t{%1, %0|%0, %1}";
17822
17823 case TYPE_ALU:
17824 if (GET_CODE (operands[2]) == CONST_INT
17825 && (INTVAL (operands[2]) == 128
17826 || (INTVAL (operands[2]) < 0
17827 && INTVAL (operands[2]) != -128)))
17828 {
17829 operands[2] = GEN_INT (-INTVAL (operands[2]));
17830 return "sub{l}\t{%2, %0|%0, %2}";
17831 }
17832 return "add{l}\t{%2, %0|%0, %2}";
17833
17834 case TYPE_LEA:
17835 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17836 return "lea{l}\t{%a2, %0|%0, %a2}";
17837
17838 default:
17839 abort ();
17840 }
17841 }
17842 [(set (attr "type")
17843 (cond [(eq_attr "alternative" "0")
17844 (const_string "alu")
17845 (match_operand:SI 2 "const0_operand" "")
17846 (const_string "imov")
17847 ]
17848 (const_string "lea")))
17849 (set_attr "mode" "SI")])
17850
17851 (define_insn "pro_epilogue_adjust_stack_rex64"
17852 [(set (match_operand:DI 0 "register_operand" "=r,r")
17853 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17854 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17855 (clobber (reg:CC FLAGS_REG))
17856 (clobber (mem:BLK (scratch)))]
17857 "TARGET_64BIT"
17858 {
17859 switch (get_attr_type (insn))
17860 {
17861 case TYPE_IMOV:
17862 return "mov{q}\t{%1, %0|%0, %1}";
17863
17864 case TYPE_ALU:
17865 if (GET_CODE (operands[2]) == CONST_INT
17866 /* Avoid overflows. */
17867 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17868 && (INTVAL (operands[2]) == 128
17869 || (INTVAL (operands[2]) < 0
17870 && INTVAL (operands[2]) != -128)))
17871 {
17872 operands[2] = GEN_INT (-INTVAL (operands[2]));
17873 return "sub{q}\t{%2, %0|%0, %2}";
17874 }
17875 return "add{q}\t{%2, %0|%0, %2}";
17876
17877 case TYPE_LEA:
17878 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17879 return "lea{q}\t{%a2, %0|%0, %a2}";
17880
17881 default:
17882 abort ();
17883 }
17884 }
17885 [(set (attr "type")
17886 (cond [(eq_attr "alternative" "0")
17887 (const_string "alu")
17888 (match_operand:DI 2 "const0_operand" "")
17889 (const_string "imov")
17890 ]
17891 (const_string "lea")))
17892 (set_attr "mode" "DI")])
17893
17894 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17895 [(set (match_operand:DI 0 "register_operand" "=r,r")
17896 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17897 (match_operand:DI 3 "immediate_operand" "i,i")))
17898 (use (match_operand:DI 2 "register_operand" "r,r"))
17899 (clobber (reg:CC FLAGS_REG))
17900 (clobber (mem:BLK (scratch)))]
17901 "TARGET_64BIT"
17902 {
17903 switch (get_attr_type (insn))
17904 {
17905 case TYPE_ALU:
17906 return "add{q}\t{%2, %0|%0, %2}";
17907
17908 case TYPE_LEA:
17909 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17910 return "lea{q}\t{%a2, %0|%0, %a2}";
17911
17912 default:
17913 abort ();
17914 }
17915 }
17916 [(set_attr "type" "alu,lea")
17917 (set_attr "mode" "DI")])
17918
17919 (define_expand "allocate_stack_worker"
17920 [(match_operand:SI 0 "register_operand" "")]
17921 "TARGET_STACK_PROBE"
17922 {
17923 if (reload_completed)
17924 {
17925 if (TARGET_64BIT)
17926 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17927 else
17928 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17929 }
17930 else
17931 {
17932 if (TARGET_64BIT)
17933 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17934 else
17935 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17936 }
17937 DONE;
17938 })
17939
17940 (define_insn "allocate_stack_worker_1"
17941 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17942 UNSPECV_STACK_PROBE)
17943 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
17944 (clobber (match_scratch:SI 1 "=0"))
17945 (clobber (reg:CC FLAGS_REG))]
17946 "!TARGET_64BIT && TARGET_STACK_PROBE"
17947 "call\t__alloca"
17948 [(set_attr "type" "multi")
17949 (set_attr "length" "5")])
17950
17951 (define_expand "allocate_stack_worker_postreload"
17952 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17953 UNSPECV_STACK_PROBE)
17954 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
17955 (clobber (match_dup 0))
17956 (clobber (reg:CC FLAGS_REG))])]
17957 ""
17958 "")
17959
17960 (define_insn "allocate_stack_worker_rex64"
17961 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17962 UNSPECV_STACK_PROBE)
17963 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
17964 (clobber (match_scratch:DI 1 "=0"))
17965 (clobber (reg:CC FLAGS_REG))]
17966 "TARGET_64BIT && TARGET_STACK_PROBE"
17967 "call\t__alloca"
17968 [(set_attr "type" "multi")
17969 (set_attr "length" "5")])
17970
17971 (define_expand "allocate_stack_worker_rex64_postreload"
17972 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17973 UNSPECV_STACK_PROBE)
17974 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
17975 (clobber (match_dup 0))
17976 (clobber (reg:CC FLAGS_REG))])]
17977 ""
17978 "")
17979
17980 (define_expand "allocate_stack"
17981 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17982 (minus:SI (reg:SI SP_REG)
17983 (match_operand:SI 1 "general_operand" "")))
17984 (clobber (reg:CC FLAGS_REG))])
17985 (parallel [(set (reg:SI SP_REG)
17986 (minus:SI (reg:SI SP_REG) (match_dup 1)))
17987 (clobber (reg:CC FLAGS_REG))])]
17988 "TARGET_STACK_PROBE"
17989 {
17990 #ifdef CHECK_STACK_LIMIT
17991 if (GET_CODE (operands[1]) == CONST_INT
17992 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17993 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17994 operands[1]));
17995 else
17996 #endif
17997 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17998 operands[1])));
17999
18000 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18001 DONE;
18002 })
18003
18004 (define_expand "builtin_setjmp_receiver"
18005 [(label_ref (match_operand 0 "" ""))]
18006 "!TARGET_64BIT && flag_pic"
18007 {
18008 emit_insn (gen_set_got (pic_offset_table_rtx));
18009 DONE;
18010 })
18011 \f
18012 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18013
18014 (define_split
18015 [(set (match_operand 0 "register_operand" "")
18016 (match_operator 3 "promotable_binary_operator"
18017 [(match_operand 1 "register_operand" "")
18018 (match_operand 2 "aligned_operand" "")]))
18019 (clobber (reg:CC FLAGS_REG))]
18020 "! TARGET_PARTIAL_REG_STALL && reload_completed
18021 && ((GET_MODE (operands[0]) == HImode
18022 && ((!optimize_size && !TARGET_FAST_PREFIX)
18023 || GET_CODE (operands[2]) != CONST_INT
18024 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18025 || (GET_MODE (operands[0]) == QImode
18026 && (TARGET_PROMOTE_QImode || optimize_size)))"
18027 [(parallel [(set (match_dup 0)
18028 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18029 (clobber (reg:CC FLAGS_REG))])]
18030 "operands[0] = gen_lowpart (SImode, operands[0]);
18031 operands[1] = gen_lowpart (SImode, operands[1]);
18032 if (GET_CODE (operands[3]) != ASHIFT)
18033 operands[2] = gen_lowpart (SImode, operands[2]);
18034 PUT_MODE (operands[3], SImode);")
18035
18036 ; Promote the QImode tests, as i386 has encoding of the AND
18037 ; instruction with 32-bit sign-extended immediate and thus the
18038 ; instruction size is unchanged, except in the %eax case for
18039 ; which it is increased by one byte, hence the ! optimize_size.
18040 (define_split
18041 [(set (match_operand 0 "flags_reg_operand" "")
18042 (match_operator 2 "compare_operator"
18043 [(and (match_operand 3 "aligned_operand" "")
18044 (match_operand 4 "const_int_operand" ""))
18045 (const_int 0)]))
18046 (set (match_operand 1 "register_operand" "")
18047 (and (match_dup 3) (match_dup 4)))]
18048 "! TARGET_PARTIAL_REG_STALL && reload_completed
18049 /* Ensure that the operand will remain sign-extended immediate. */
18050 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18051 && ! optimize_size
18052 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18053 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18054 [(parallel [(set (match_dup 0)
18055 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18056 (const_int 0)]))
18057 (set (match_dup 1)
18058 (and:SI (match_dup 3) (match_dup 4)))])]
18059 {
18060 operands[4]
18061 = gen_int_mode (INTVAL (operands[4])
18062 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18063 operands[1] = gen_lowpart (SImode, operands[1]);
18064 operands[3] = gen_lowpart (SImode, operands[3]);
18065 })
18066
18067 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18068 ; the TEST instruction with 32-bit sign-extended immediate and thus
18069 ; the instruction size would at least double, which is not what we
18070 ; want even with ! optimize_size.
18071 (define_split
18072 [(set (match_operand 0 "flags_reg_operand" "")
18073 (match_operator 1 "compare_operator"
18074 [(and (match_operand:HI 2 "aligned_operand" "")
18075 (match_operand:HI 3 "const_int_operand" ""))
18076 (const_int 0)]))]
18077 "! TARGET_PARTIAL_REG_STALL && reload_completed
18078 /* Ensure that the operand will remain sign-extended immediate. */
18079 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18080 && ! TARGET_FAST_PREFIX
18081 && ! optimize_size"
18082 [(set (match_dup 0)
18083 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18084 (const_int 0)]))]
18085 {
18086 operands[3]
18087 = gen_int_mode (INTVAL (operands[3])
18088 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18089 operands[2] = gen_lowpart (SImode, operands[2]);
18090 })
18091
18092 (define_split
18093 [(set (match_operand 0 "register_operand" "")
18094 (neg (match_operand 1 "register_operand" "")))
18095 (clobber (reg:CC FLAGS_REG))]
18096 "! TARGET_PARTIAL_REG_STALL && reload_completed
18097 && (GET_MODE (operands[0]) == HImode
18098 || (GET_MODE (operands[0]) == QImode
18099 && (TARGET_PROMOTE_QImode || optimize_size)))"
18100 [(parallel [(set (match_dup 0)
18101 (neg:SI (match_dup 1)))
18102 (clobber (reg:CC FLAGS_REG))])]
18103 "operands[0] = gen_lowpart (SImode, operands[0]);
18104 operands[1] = gen_lowpart (SImode, operands[1]);")
18105
18106 (define_split
18107 [(set (match_operand 0 "register_operand" "")
18108 (not (match_operand 1 "register_operand" "")))]
18109 "! TARGET_PARTIAL_REG_STALL && reload_completed
18110 && (GET_MODE (operands[0]) == HImode
18111 || (GET_MODE (operands[0]) == QImode
18112 && (TARGET_PROMOTE_QImode || optimize_size)))"
18113 [(set (match_dup 0)
18114 (not:SI (match_dup 1)))]
18115 "operands[0] = gen_lowpart (SImode, operands[0]);
18116 operands[1] = gen_lowpart (SImode, operands[1]);")
18117
18118 (define_split
18119 [(set (match_operand 0 "register_operand" "")
18120 (if_then_else (match_operator 1 "comparison_operator"
18121 [(reg FLAGS_REG) (const_int 0)])
18122 (match_operand 2 "register_operand" "")
18123 (match_operand 3 "register_operand" "")))]
18124 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18125 && (GET_MODE (operands[0]) == HImode
18126 || (GET_MODE (operands[0]) == QImode
18127 && (TARGET_PROMOTE_QImode || optimize_size)))"
18128 [(set (match_dup 0)
18129 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18130 "operands[0] = gen_lowpart (SImode, operands[0]);
18131 operands[2] = gen_lowpart (SImode, operands[2]);
18132 operands[3] = gen_lowpart (SImode, operands[3]);")
18133
18134 \f
18135 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18136 ;; transform a complex memory operation into two memory to register operations.
18137
18138 ;; Don't push memory operands
18139 (define_peephole2
18140 [(set (match_operand:SI 0 "push_operand" "")
18141 (match_operand:SI 1 "memory_operand" ""))
18142 (match_scratch:SI 2 "r")]
18143 "! optimize_size && ! TARGET_PUSH_MEMORY"
18144 [(set (match_dup 2) (match_dup 1))
18145 (set (match_dup 0) (match_dup 2))]
18146 "")
18147
18148 (define_peephole2
18149 [(set (match_operand:DI 0 "push_operand" "")
18150 (match_operand:DI 1 "memory_operand" ""))
18151 (match_scratch:DI 2 "r")]
18152 "! optimize_size && ! TARGET_PUSH_MEMORY"
18153 [(set (match_dup 2) (match_dup 1))
18154 (set (match_dup 0) (match_dup 2))]
18155 "")
18156
18157 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18158 ;; SImode pushes.
18159 (define_peephole2
18160 [(set (match_operand:SF 0 "push_operand" "")
18161 (match_operand:SF 1 "memory_operand" ""))
18162 (match_scratch:SF 2 "r")]
18163 "! optimize_size && ! TARGET_PUSH_MEMORY"
18164 [(set (match_dup 2) (match_dup 1))
18165 (set (match_dup 0) (match_dup 2))]
18166 "")
18167
18168 (define_peephole2
18169 [(set (match_operand:HI 0 "push_operand" "")
18170 (match_operand:HI 1 "memory_operand" ""))
18171 (match_scratch:HI 2 "r")]
18172 "! optimize_size && ! TARGET_PUSH_MEMORY"
18173 [(set (match_dup 2) (match_dup 1))
18174 (set (match_dup 0) (match_dup 2))]
18175 "")
18176
18177 (define_peephole2
18178 [(set (match_operand:QI 0 "push_operand" "")
18179 (match_operand:QI 1 "memory_operand" ""))
18180 (match_scratch:QI 2 "q")]
18181 "! optimize_size && ! TARGET_PUSH_MEMORY"
18182 [(set (match_dup 2) (match_dup 1))
18183 (set (match_dup 0) (match_dup 2))]
18184 "")
18185
18186 ;; Don't move an immediate directly to memory when the instruction
18187 ;; gets too big.
18188 (define_peephole2
18189 [(match_scratch:SI 1 "r")
18190 (set (match_operand:SI 0 "memory_operand" "")
18191 (const_int 0))]
18192 "! optimize_size
18193 && ! TARGET_USE_MOV0
18194 && TARGET_SPLIT_LONG_MOVES
18195 && get_attr_length (insn) >= ix86_cost->large_insn
18196 && peep2_regno_dead_p (0, FLAGS_REG)"
18197 [(parallel [(set (match_dup 1) (const_int 0))
18198 (clobber (reg:CC FLAGS_REG))])
18199 (set (match_dup 0) (match_dup 1))]
18200 "")
18201
18202 (define_peephole2
18203 [(match_scratch:HI 1 "r")
18204 (set (match_operand:HI 0 "memory_operand" "")
18205 (const_int 0))]
18206 "! optimize_size
18207 && ! TARGET_USE_MOV0
18208 && TARGET_SPLIT_LONG_MOVES
18209 && get_attr_length (insn) >= ix86_cost->large_insn
18210 && peep2_regno_dead_p (0, FLAGS_REG)"
18211 [(parallel [(set (match_dup 2) (const_int 0))
18212 (clobber (reg:CC FLAGS_REG))])
18213 (set (match_dup 0) (match_dup 1))]
18214 "operands[2] = gen_lowpart (SImode, operands[1]);")
18215
18216 (define_peephole2
18217 [(match_scratch:QI 1 "q")
18218 (set (match_operand:QI 0 "memory_operand" "")
18219 (const_int 0))]
18220 "! optimize_size
18221 && ! TARGET_USE_MOV0
18222 && TARGET_SPLIT_LONG_MOVES
18223 && get_attr_length (insn) >= ix86_cost->large_insn
18224 && peep2_regno_dead_p (0, FLAGS_REG)"
18225 [(parallel [(set (match_dup 2) (const_int 0))
18226 (clobber (reg:CC FLAGS_REG))])
18227 (set (match_dup 0) (match_dup 1))]
18228 "operands[2] = gen_lowpart (SImode, operands[1]);")
18229
18230 (define_peephole2
18231 [(match_scratch:SI 2 "r")
18232 (set (match_operand:SI 0 "memory_operand" "")
18233 (match_operand:SI 1 "immediate_operand" ""))]
18234 "! optimize_size
18235 && get_attr_length (insn) >= ix86_cost->large_insn
18236 && TARGET_SPLIT_LONG_MOVES"
18237 [(set (match_dup 2) (match_dup 1))
18238 (set (match_dup 0) (match_dup 2))]
18239 "")
18240
18241 (define_peephole2
18242 [(match_scratch:HI 2 "r")
18243 (set (match_operand:HI 0 "memory_operand" "")
18244 (match_operand:HI 1 "immediate_operand" ""))]
18245 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18246 && TARGET_SPLIT_LONG_MOVES"
18247 [(set (match_dup 2) (match_dup 1))
18248 (set (match_dup 0) (match_dup 2))]
18249 "")
18250
18251 (define_peephole2
18252 [(match_scratch:QI 2 "q")
18253 (set (match_operand:QI 0 "memory_operand" "")
18254 (match_operand:QI 1 "immediate_operand" ""))]
18255 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18256 && TARGET_SPLIT_LONG_MOVES"
18257 [(set (match_dup 2) (match_dup 1))
18258 (set (match_dup 0) (match_dup 2))]
18259 "")
18260
18261 ;; Don't compare memory with zero, load and use a test instead.
18262 (define_peephole2
18263 [(set (match_operand 0 "flags_reg_operand" "")
18264 (match_operator 1 "compare_operator"
18265 [(match_operand:SI 2 "memory_operand" "")
18266 (const_int 0)]))
18267 (match_scratch:SI 3 "r")]
18268 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18269 [(set (match_dup 3) (match_dup 2))
18270 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18271 "")
18272
18273 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18274 ;; Don't split NOTs with a displacement operand, because resulting XOR
18275 ;; will not be pairable anyway.
18276 ;;
18277 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18278 ;; represented using a modRM byte. The XOR replacement is long decoded,
18279 ;; so this split helps here as well.
18280 ;;
18281 ;; Note: Can't do this as a regular split because we can't get proper
18282 ;; lifetime information then.
18283
18284 (define_peephole2
18285 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18286 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18287 "!optimize_size
18288 && peep2_regno_dead_p (0, FLAGS_REG)
18289 && ((TARGET_PENTIUM
18290 && (GET_CODE (operands[0]) != MEM
18291 || !memory_displacement_operand (operands[0], SImode)))
18292 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18293 [(parallel [(set (match_dup 0)
18294 (xor:SI (match_dup 1) (const_int -1)))
18295 (clobber (reg:CC FLAGS_REG))])]
18296 "")
18297
18298 (define_peephole2
18299 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18300 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18301 "!optimize_size
18302 && peep2_regno_dead_p (0, FLAGS_REG)
18303 && ((TARGET_PENTIUM
18304 && (GET_CODE (operands[0]) != MEM
18305 || !memory_displacement_operand (operands[0], HImode)))
18306 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18307 [(parallel [(set (match_dup 0)
18308 (xor:HI (match_dup 1) (const_int -1)))
18309 (clobber (reg:CC FLAGS_REG))])]
18310 "")
18311
18312 (define_peephole2
18313 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18314 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18315 "!optimize_size
18316 && peep2_regno_dead_p (0, FLAGS_REG)
18317 && ((TARGET_PENTIUM
18318 && (GET_CODE (operands[0]) != MEM
18319 || !memory_displacement_operand (operands[0], QImode)))
18320 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18321 [(parallel [(set (match_dup 0)
18322 (xor:QI (match_dup 1) (const_int -1)))
18323 (clobber (reg:CC FLAGS_REG))])]
18324 "")
18325
18326 ;; Non pairable "test imm, reg" instructions can be translated to
18327 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18328 ;; byte opcode instead of two, have a short form for byte operands),
18329 ;; so do it for other CPUs as well. Given that the value was dead,
18330 ;; this should not create any new dependencies. Pass on the sub-word
18331 ;; versions if we're concerned about partial register stalls.
18332
18333 (define_peephole2
18334 [(set (match_operand 0 "flags_reg_operand" "")
18335 (match_operator 1 "compare_operator"
18336 [(and:SI (match_operand:SI 2 "register_operand" "")
18337 (match_operand:SI 3 "immediate_operand" ""))
18338 (const_int 0)]))]
18339 "ix86_match_ccmode (insn, CCNOmode)
18340 && (true_regnum (operands[2]) != 0
18341 || (GET_CODE (operands[3]) == CONST_INT
18342 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18343 && peep2_reg_dead_p (1, operands[2])"
18344 [(parallel
18345 [(set (match_dup 0)
18346 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18347 (const_int 0)]))
18348 (set (match_dup 2)
18349 (and:SI (match_dup 2) (match_dup 3)))])]
18350 "")
18351
18352 ;; We don't need to handle HImode case, because it will be promoted to SImode
18353 ;; on ! TARGET_PARTIAL_REG_STALL
18354
18355 (define_peephole2
18356 [(set (match_operand 0 "flags_reg_operand" "")
18357 (match_operator 1 "compare_operator"
18358 [(and:QI (match_operand:QI 2 "register_operand" "")
18359 (match_operand:QI 3 "immediate_operand" ""))
18360 (const_int 0)]))]
18361 "! TARGET_PARTIAL_REG_STALL
18362 && ix86_match_ccmode (insn, CCNOmode)
18363 && true_regnum (operands[2]) != 0
18364 && peep2_reg_dead_p (1, operands[2])"
18365 [(parallel
18366 [(set (match_dup 0)
18367 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18368 (const_int 0)]))
18369 (set (match_dup 2)
18370 (and:QI (match_dup 2) (match_dup 3)))])]
18371 "")
18372
18373 (define_peephole2
18374 [(set (match_operand 0 "flags_reg_operand" "")
18375 (match_operator 1 "compare_operator"
18376 [(and:SI
18377 (zero_extract:SI
18378 (match_operand 2 "ext_register_operand" "")
18379 (const_int 8)
18380 (const_int 8))
18381 (match_operand 3 "const_int_operand" ""))
18382 (const_int 0)]))]
18383 "! TARGET_PARTIAL_REG_STALL
18384 && ix86_match_ccmode (insn, CCNOmode)
18385 && true_regnum (operands[2]) != 0
18386 && peep2_reg_dead_p (1, operands[2])"
18387 [(parallel [(set (match_dup 0)
18388 (match_op_dup 1
18389 [(and:SI
18390 (zero_extract:SI
18391 (match_dup 2)
18392 (const_int 8)
18393 (const_int 8))
18394 (match_dup 3))
18395 (const_int 0)]))
18396 (set (zero_extract:SI (match_dup 2)
18397 (const_int 8)
18398 (const_int 8))
18399 (and:SI
18400 (zero_extract:SI
18401 (match_dup 2)
18402 (const_int 8)
18403 (const_int 8))
18404 (match_dup 3)))])]
18405 "")
18406
18407 ;; Don't do logical operations with memory inputs.
18408 (define_peephole2
18409 [(match_scratch:SI 2 "r")
18410 (parallel [(set (match_operand:SI 0 "register_operand" "")
18411 (match_operator:SI 3 "arith_or_logical_operator"
18412 [(match_dup 0)
18413 (match_operand:SI 1 "memory_operand" "")]))
18414 (clobber (reg:CC FLAGS_REG))])]
18415 "! optimize_size && ! TARGET_READ_MODIFY"
18416 [(set (match_dup 2) (match_dup 1))
18417 (parallel [(set (match_dup 0)
18418 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18419 (clobber (reg:CC FLAGS_REG))])]
18420 "")
18421
18422 (define_peephole2
18423 [(match_scratch:SI 2 "r")
18424 (parallel [(set (match_operand:SI 0 "register_operand" "")
18425 (match_operator:SI 3 "arith_or_logical_operator"
18426 [(match_operand:SI 1 "memory_operand" "")
18427 (match_dup 0)]))
18428 (clobber (reg:CC FLAGS_REG))])]
18429 "! optimize_size && ! TARGET_READ_MODIFY"
18430 [(set (match_dup 2) (match_dup 1))
18431 (parallel [(set (match_dup 0)
18432 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18433 (clobber (reg:CC FLAGS_REG))])]
18434 "")
18435
18436 ; Don't do logical operations with memory outputs
18437 ;
18438 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18439 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18440 ; the same decoder scheduling characteristics as the original.
18441
18442 (define_peephole2
18443 [(match_scratch:SI 2 "r")
18444 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18445 (match_operator:SI 3 "arith_or_logical_operator"
18446 [(match_dup 0)
18447 (match_operand:SI 1 "nonmemory_operand" "")]))
18448 (clobber (reg:CC FLAGS_REG))])]
18449 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18450 [(set (match_dup 2) (match_dup 0))
18451 (parallel [(set (match_dup 2)
18452 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18453 (clobber (reg:CC FLAGS_REG))])
18454 (set (match_dup 0) (match_dup 2))]
18455 "")
18456
18457 (define_peephole2
18458 [(match_scratch:SI 2 "r")
18459 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18460 (match_operator:SI 3 "arith_or_logical_operator"
18461 [(match_operand:SI 1 "nonmemory_operand" "")
18462 (match_dup 0)]))
18463 (clobber (reg:CC FLAGS_REG))])]
18464 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18465 [(set (match_dup 2) (match_dup 0))
18466 (parallel [(set (match_dup 2)
18467 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18468 (clobber (reg:CC FLAGS_REG))])
18469 (set (match_dup 0) (match_dup 2))]
18470 "")
18471
18472 ;; Attempt to always use XOR for zeroing registers.
18473 (define_peephole2
18474 [(set (match_operand 0 "register_operand" "")
18475 (const_int 0))]
18476 "(GET_MODE (operands[0]) == QImode
18477 || GET_MODE (operands[0]) == HImode
18478 || GET_MODE (operands[0]) == SImode
18479 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18480 && (! TARGET_USE_MOV0 || optimize_size)
18481 && peep2_regno_dead_p (0, FLAGS_REG)"
18482 [(parallel [(set (match_dup 0) (const_int 0))
18483 (clobber (reg:CC FLAGS_REG))])]
18484 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18485 operands[0]);")
18486
18487 (define_peephole2
18488 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18489 (const_int 0))]
18490 "(GET_MODE (operands[0]) == QImode
18491 || GET_MODE (operands[0]) == HImode)
18492 && (! TARGET_USE_MOV0 || optimize_size)
18493 && peep2_regno_dead_p (0, FLAGS_REG)"
18494 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18495 (clobber (reg:CC FLAGS_REG))])])
18496
18497 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18498 (define_peephole2
18499 [(set (match_operand 0 "register_operand" "")
18500 (const_int -1))]
18501 "(GET_MODE (operands[0]) == HImode
18502 || GET_MODE (operands[0]) == SImode
18503 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18504 && (optimize_size || TARGET_PENTIUM)
18505 && peep2_regno_dead_p (0, FLAGS_REG)"
18506 [(parallel [(set (match_dup 0) (const_int -1))
18507 (clobber (reg:CC FLAGS_REG))])]
18508 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18509 operands[0]);")
18510
18511 ;; Attempt to convert simple leas to adds. These can be created by
18512 ;; move expanders.
18513 (define_peephole2
18514 [(set (match_operand:SI 0 "register_operand" "")
18515 (plus:SI (match_dup 0)
18516 (match_operand:SI 1 "nonmemory_operand" "")))]
18517 "peep2_regno_dead_p (0, FLAGS_REG)"
18518 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18519 (clobber (reg:CC FLAGS_REG))])]
18520 "")
18521
18522 (define_peephole2
18523 [(set (match_operand:SI 0 "register_operand" "")
18524 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18525 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18526 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18527 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18528 (clobber (reg:CC FLAGS_REG))])]
18529 "operands[2] = gen_lowpart (SImode, operands[2]);")
18530
18531 (define_peephole2
18532 [(set (match_operand:DI 0 "register_operand" "")
18533 (plus:DI (match_dup 0)
18534 (match_operand:DI 1 "x86_64_general_operand" "")))]
18535 "peep2_regno_dead_p (0, FLAGS_REG)"
18536 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18537 (clobber (reg:CC FLAGS_REG))])]
18538 "")
18539
18540 (define_peephole2
18541 [(set (match_operand:SI 0 "register_operand" "")
18542 (mult:SI (match_dup 0)
18543 (match_operand:SI 1 "const_int_operand" "")))]
18544 "exact_log2 (INTVAL (operands[1])) >= 0
18545 && peep2_regno_dead_p (0, FLAGS_REG)"
18546 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18547 (clobber (reg:CC FLAGS_REG))])]
18548 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18549
18550 (define_peephole2
18551 [(set (match_operand:DI 0 "register_operand" "")
18552 (mult:DI (match_dup 0)
18553 (match_operand:DI 1 "const_int_operand" "")))]
18554 "exact_log2 (INTVAL (operands[1])) >= 0
18555 && peep2_regno_dead_p (0, FLAGS_REG)"
18556 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18557 (clobber (reg:CC FLAGS_REG))])]
18558 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18559
18560 (define_peephole2
18561 [(set (match_operand:SI 0 "register_operand" "")
18562 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18563 (match_operand:DI 2 "const_int_operand" "")) 0))]
18564 "exact_log2 (INTVAL (operands[2])) >= 0
18565 && REGNO (operands[0]) == REGNO (operands[1])
18566 && peep2_regno_dead_p (0, FLAGS_REG)"
18567 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18568 (clobber (reg:CC FLAGS_REG))])]
18569 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18570
18571 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18572 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18573 ;; many CPUs it is also faster, since special hardware to avoid esp
18574 ;; dependencies is present.
18575
18576 ;; While some of these conversions may be done using splitters, we use peepholes
18577 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18578
18579 ;; Convert prologue esp subtractions to push.
18580 ;; We need register to push. In order to keep verify_flow_info happy we have
18581 ;; two choices
18582 ;; - use scratch and clobber it in order to avoid dependencies
18583 ;; - use already live register
18584 ;; We can't use the second way right now, since there is no reliable way how to
18585 ;; verify that given register is live. First choice will also most likely in
18586 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18587 ;; call clobbered registers are dead. We may want to use base pointer as an
18588 ;; alternative when no register is available later.
18589
18590 (define_peephole2
18591 [(match_scratch:SI 0 "r")
18592 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18593 (clobber (reg:CC FLAGS_REG))
18594 (clobber (mem:BLK (scratch)))])]
18595 "optimize_size || !TARGET_SUB_ESP_4"
18596 [(clobber (match_dup 0))
18597 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18598 (clobber (mem:BLK (scratch)))])])
18599
18600 (define_peephole2
18601 [(match_scratch:SI 0 "r")
18602 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18603 (clobber (reg:CC FLAGS_REG))
18604 (clobber (mem:BLK (scratch)))])]
18605 "optimize_size || !TARGET_SUB_ESP_8"
18606 [(clobber (match_dup 0))
18607 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18608 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18609 (clobber (mem:BLK (scratch)))])])
18610
18611 ;; Convert esp subtractions to push.
18612 (define_peephole2
18613 [(match_scratch:SI 0 "r")
18614 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18615 (clobber (reg:CC FLAGS_REG))])]
18616 "optimize_size || !TARGET_SUB_ESP_4"
18617 [(clobber (match_dup 0))
18618 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18619
18620 (define_peephole2
18621 [(match_scratch:SI 0 "r")
18622 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18623 (clobber (reg:CC FLAGS_REG))])]
18624 "optimize_size || !TARGET_SUB_ESP_8"
18625 [(clobber (match_dup 0))
18626 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18627 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18628
18629 ;; Convert epilogue deallocator to pop.
18630 (define_peephole2
18631 [(match_scratch:SI 0 "r")
18632 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18633 (clobber (reg:CC FLAGS_REG))
18634 (clobber (mem:BLK (scratch)))])]
18635 "optimize_size || !TARGET_ADD_ESP_4"
18636 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18637 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18638 (clobber (mem:BLK (scratch)))])]
18639 "")
18640
18641 ;; Two pops case is tricky, since pop causes dependency on destination register.
18642 ;; We use two registers if available.
18643 (define_peephole2
18644 [(match_scratch:SI 0 "r")
18645 (match_scratch:SI 1 "r")
18646 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18647 (clobber (reg:CC FLAGS_REG))
18648 (clobber (mem:BLK (scratch)))])]
18649 "optimize_size || !TARGET_ADD_ESP_8"
18650 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18651 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18652 (clobber (mem:BLK (scratch)))])
18653 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18654 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18655 "")
18656
18657 (define_peephole2
18658 [(match_scratch:SI 0 "r")
18659 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18660 (clobber (reg:CC FLAGS_REG))
18661 (clobber (mem:BLK (scratch)))])]
18662 "optimize_size"
18663 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18664 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18665 (clobber (mem:BLK (scratch)))])
18666 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18667 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18668 "")
18669
18670 ;; Convert esp additions to pop.
18671 (define_peephole2
18672 [(match_scratch:SI 0 "r")
18673 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18674 (clobber (reg:CC FLAGS_REG))])]
18675 ""
18676 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18677 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18678 "")
18679
18680 ;; Two pops case is tricky, since pop causes dependency on destination register.
18681 ;; We use two registers if available.
18682 (define_peephole2
18683 [(match_scratch:SI 0 "r")
18684 (match_scratch:SI 1 "r")
18685 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18686 (clobber (reg:CC FLAGS_REG))])]
18687 ""
18688 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18689 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18690 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18691 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18692 "")
18693
18694 (define_peephole2
18695 [(match_scratch:SI 0 "r")
18696 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18697 (clobber (reg:CC FLAGS_REG))])]
18698 "optimize_size"
18699 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18700 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18701 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18702 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18703 "")
18704 \f
18705 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18706 ;; required and register dies. Similarly for 128 to plus -128.
18707 (define_peephole2
18708 [(set (match_operand 0 "flags_reg_operand" "")
18709 (match_operator 1 "compare_operator"
18710 [(match_operand 2 "register_operand" "")
18711 (match_operand 3 "const_int_operand" "")]))]
18712 "(INTVAL (operands[3]) == -1
18713 || INTVAL (operands[3]) == 1
18714 || INTVAL (operands[3]) == 128)
18715 && ix86_match_ccmode (insn, CCGCmode)
18716 && peep2_reg_dead_p (1, operands[2])"
18717 [(parallel [(set (match_dup 0)
18718 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18719 (clobber (match_dup 2))])]
18720 "")
18721 \f
18722 (define_peephole2
18723 [(match_scratch:DI 0 "r")
18724 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18725 (clobber (reg:CC FLAGS_REG))
18726 (clobber (mem:BLK (scratch)))])]
18727 "optimize_size || !TARGET_SUB_ESP_4"
18728 [(clobber (match_dup 0))
18729 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18730 (clobber (mem:BLK (scratch)))])])
18731
18732 (define_peephole2
18733 [(match_scratch:DI 0 "r")
18734 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18735 (clobber (reg:CC FLAGS_REG))
18736 (clobber (mem:BLK (scratch)))])]
18737 "optimize_size || !TARGET_SUB_ESP_8"
18738 [(clobber (match_dup 0))
18739 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18740 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18741 (clobber (mem:BLK (scratch)))])])
18742
18743 ;; Convert esp subtractions to push.
18744 (define_peephole2
18745 [(match_scratch:DI 0 "r")
18746 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18747 (clobber (reg:CC FLAGS_REG))])]
18748 "optimize_size || !TARGET_SUB_ESP_4"
18749 [(clobber (match_dup 0))
18750 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18751
18752 (define_peephole2
18753 [(match_scratch:DI 0 "r")
18754 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18755 (clobber (reg:CC FLAGS_REG))])]
18756 "optimize_size || !TARGET_SUB_ESP_8"
18757 [(clobber (match_dup 0))
18758 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18759 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18760
18761 ;; Convert epilogue deallocator to pop.
18762 (define_peephole2
18763 [(match_scratch:DI 0 "r")
18764 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18765 (clobber (reg:CC FLAGS_REG))
18766 (clobber (mem:BLK (scratch)))])]
18767 "optimize_size || !TARGET_ADD_ESP_4"
18768 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18769 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18770 (clobber (mem:BLK (scratch)))])]
18771 "")
18772
18773 ;; Two pops case is tricky, since pop causes dependency on destination register.
18774 ;; We use two registers if available.
18775 (define_peephole2
18776 [(match_scratch:DI 0 "r")
18777 (match_scratch:DI 1 "r")
18778 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18779 (clobber (reg:CC FLAGS_REG))
18780 (clobber (mem:BLK (scratch)))])]
18781 "optimize_size || !TARGET_ADD_ESP_8"
18782 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18783 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18784 (clobber (mem:BLK (scratch)))])
18785 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18786 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18787 "")
18788
18789 (define_peephole2
18790 [(match_scratch:DI 0 "r")
18791 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18792 (clobber (reg:CC FLAGS_REG))
18793 (clobber (mem:BLK (scratch)))])]
18794 "optimize_size"
18795 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18796 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18797 (clobber (mem:BLK (scratch)))])
18798 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18799 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18800 "")
18801
18802 ;; Convert esp additions to pop.
18803 (define_peephole2
18804 [(match_scratch:DI 0 "r")
18805 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18806 (clobber (reg:CC FLAGS_REG))])]
18807 ""
18808 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18809 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18810 "")
18811
18812 ;; Two pops case is tricky, since pop causes dependency on destination register.
18813 ;; We use two registers if available.
18814 (define_peephole2
18815 [(match_scratch:DI 0 "r")
18816 (match_scratch:DI 1 "r")
18817 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18818 (clobber (reg:CC FLAGS_REG))])]
18819 ""
18820 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18821 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18822 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18823 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18824 "")
18825
18826 (define_peephole2
18827 [(match_scratch:DI 0 "r")
18828 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18829 (clobber (reg:CC FLAGS_REG))])]
18830 "optimize_size"
18831 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18832 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18833 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18834 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18835 "")
18836 \f
18837 ;; Convert imul by three, five and nine into lea
18838 (define_peephole2
18839 [(parallel
18840 [(set (match_operand:SI 0 "register_operand" "")
18841 (mult:SI (match_operand:SI 1 "register_operand" "")
18842 (match_operand:SI 2 "const_int_operand" "")))
18843 (clobber (reg:CC FLAGS_REG))])]
18844 "INTVAL (operands[2]) == 3
18845 || INTVAL (operands[2]) == 5
18846 || INTVAL (operands[2]) == 9"
18847 [(set (match_dup 0)
18848 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18849 (match_dup 1)))]
18850 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18851
18852 (define_peephole2
18853 [(parallel
18854 [(set (match_operand:SI 0 "register_operand" "")
18855 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18856 (match_operand:SI 2 "const_int_operand" "")))
18857 (clobber (reg:CC FLAGS_REG))])]
18858 "!optimize_size
18859 && (INTVAL (operands[2]) == 3
18860 || INTVAL (operands[2]) == 5
18861 || INTVAL (operands[2]) == 9)"
18862 [(set (match_dup 0) (match_dup 1))
18863 (set (match_dup 0)
18864 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18865 (match_dup 0)))]
18866 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18867
18868 (define_peephole2
18869 [(parallel
18870 [(set (match_operand:DI 0 "register_operand" "")
18871 (mult:DI (match_operand:DI 1 "register_operand" "")
18872 (match_operand:DI 2 "const_int_operand" "")))
18873 (clobber (reg:CC FLAGS_REG))])]
18874 "TARGET_64BIT
18875 && (INTVAL (operands[2]) == 3
18876 || INTVAL (operands[2]) == 5
18877 || INTVAL (operands[2]) == 9)"
18878 [(set (match_dup 0)
18879 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18880 (match_dup 1)))]
18881 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18882
18883 (define_peephole2
18884 [(parallel
18885 [(set (match_operand:DI 0 "register_operand" "")
18886 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18887 (match_operand:DI 2 "const_int_operand" "")))
18888 (clobber (reg:CC FLAGS_REG))])]
18889 "TARGET_64BIT
18890 && !optimize_size
18891 && (INTVAL (operands[2]) == 3
18892 || INTVAL (operands[2]) == 5
18893 || INTVAL (operands[2]) == 9)"
18894 [(set (match_dup 0) (match_dup 1))
18895 (set (match_dup 0)
18896 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18897 (match_dup 0)))]
18898 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18899
18900 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18901 ;; imul $32bit_imm, reg, reg is direct decoded.
18902 (define_peephole2
18903 [(match_scratch:DI 3 "r")
18904 (parallel [(set (match_operand:DI 0 "register_operand" "")
18905 (mult:DI (match_operand:DI 1 "memory_operand" "")
18906 (match_operand:DI 2 "immediate_operand" "")))
18907 (clobber (reg:CC FLAGS_REG))])]
18908 "TARGET_K8 && !optimize_size
18909 && (GET_CODE (operands[2]) != CONST_INT
18910 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18911 [(set (match_dup 3) (match_dup 1))
18912 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18913 (clobber (reg:CC FLAGS_REG))])]
18914 "")
18915
18916 (define_peephole2
18917 [(match_scratch:SI 3 "r")
18918 (parallel [(set (match_operand:SI 0 "register_operand" "")
18919 (mult:SI (match_operand:SI 1 "memory_operand" "")
18920 (match_operand:SI 2 "immediate_operand" "")))
18921 (clobber (reg:CC FLAGS_REG))])]
18922 "TARGET_K8 && !optimize_size
18923 && (GET_CODE (operands[2]) != CONST_INT
18924 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18925 [(set (match_dup 3) (match_dup 1))
18926 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18927 (clobber (reg:CC FLAGS_REG))])]
18928 "")
18929
18930 (define_peephole2
18931 [(match_scratch:SI 3 "r")
18932 (parallel [(set (match_operand:DI 0 "register_operand" "")
18933 (zero_extend:DI
18934 (mult:SI (match_operand:SI 1 "memory_operand" "")
18935 (match_operand:SI 2 "immediate_operand" ""))))
18936 (clobber (reg:CC FLAGS_REG))])]
18937 "TARGET_K8 && !optimize_size
18938 && (GET_CODE (operands[2]) != CONST_INT
18939 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18940 [(set (match_dup 3) (match_dup 1))
18941 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18942 (clobber (reg:CC FLAGS_REG))])]
18943 "")
18944
18945 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18946 ;; Convert it into imul reg, reg
18947 ;; It would be better to force assembler to encode instruction using long
18948 ;; immediate, but there is apparently no way to do so.
18949 (define_peephole2
18950 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18951 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18952 (match_operand:DI 2 "const_int_operand" "")))
18953 (clobber (reg:CC FLAGS_REG))])
18954 (match_scratch:DI 3 "r")]
18955 "TARGET_K8 && !optimize_size
18956 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18957 [(set (match_dup 3) (match_dup 2))
18958 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18959 (clobber (reg:CC FLAGS_REG))])]
18960 {
18961 if (!rtx_equal_p (operands[0], operands[1]))
18962 emit_move_insn (operands[0], operands[1]);
18963 })
18964
18965 (define_peephole2
18966 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18967 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18968 (match_operand:SI 2 "const_int_operand" "")))
18969 (clobber (reg:CC FLAGS_REG))])
18970 (match_scratch:SI 3 "r")]
18971 "TARGET_K8 && !optimize_size
18972 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18973 [(set (match_dup 3) (match_dup 2))
18974 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18975 (clobber (reg:CC FLAGS_REG))])]
18976 {
18977 if (!rtx_equal_p (operands[0], operands[1]))
18978 emit_move_insn (operands[0], operands[1]);
18979 })
18980
18981 (define_peephole2
18982 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18983 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18984 (match_operand:HI 2 "immediate_operand" "")))
18985 (clobber (reg:CC FLAGS_REG))])
18986 (match_scratch:HI 3 "r")]
18987 "TARGET_K8 && !optimize_size"
18988 [(set (match_dup 3) (match_dup 2))
18989 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18990 (clobber (reg:CC FLAGS_REG))])]
18991 {
18992 if (!rtx_equal_p (operands[0], operands[1]))
18993 emit_move_insn (operands[0], operands[1]);
18994 })
18995 \f
18996 ;; Call-value patterns last so that the wildcard operand does not
18997 ;; disrupt insn-recog's switch tables.
18998
18999 (define_insn "*call_value_pop_0"
19000 [(set (match_operand 0 "" "")
19001 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19002 (match_operand:SI 2 "" "")))
19003 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19004 (match_operand:SI 3 "immediate_operand" "")))]
19005 "!TARGET_64BIT"
19006 {
19007 if (SIBLING_CALL_P (insn))
19008 return "jmp\t%P1";
19009 else
19010 return "call\t%P1";
19011 }
19012 [(set_attr "type" "callv")])
19013
19014 (define_insn "*call_value_pop_1"
19015 [(set (match_operand 0 "" "")
19016 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19017 (match_operand:SI 2 "" "")))
19018 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19019 (match_operand:SI 3 "immediate_operand" "i")))]
19020 "!TARGET_64BIT"
19021 {
19022 if (constant_call_address_operand (operands[1], Pmode))
19023 {
19024 if (SIBLING_CALL_P (insn))
19025 return "jmp\t%P1";
19026 else
19027 return "call\t%P1";
19028 }
19029 if (SIBLING_CALL_P (insn))
19030 return "jmp\t%A1";
19031 else
19032 return "call\t%A1";
19033 }
19034 [(set_attr "type" "callv")])
19035
19036 (define_insn "*call_value_0"
19037 [(set (match_operand 0 "" "")
19038 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19039 (match_operand:SI 2 "" "")))]
19040 "!TARGET_64BIT"
19041 {
19042 if (SIBLING_CALL_P (insn))
19043 return "jmp\t%P1";
19044 else
19045 return "call\t%P1";
19046 }
19047 [(set_attr "type" "callv")])
19048
19049 (define_insn "*call_value_0_rex64"
19050 [(set (match_operand 0 "" "")
19051 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19052 (match_operand:DI 2 "const_int_operand" "")))]
19053 "TARGET_64BIT"
19054 {
19055 if (SIBLING_CALL_P (insn))
19056 return "jmp\t%P1";
19057 else
19058 return "call\t%P1";
19059 }
19060 [(set_attr "type" "callv")])
19061
19062 (define_insn "*call_value_1"
19063 [(set (match_operand 0 "" "")
19064 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19065 (match_operand:SI 2 "" "")))]
19066 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19067 {
19068 if (constant_call_address_operand (operands[1], Pmode))
19069 return "call\t%P1";
19070 return "call\t%A1";
19071 }
19072 [(set_attr "type" "callv")])
19073
19074 (define_insn "*sibcall_value_1"
19075 [(set (match_operand 0 "" "")
19076 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19077 (match_operand:SI 2 "" "")))]
19078 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19079 {
19080 if (constant_call_address_operand (operands[1], Pmode))
19081 return "jmp\t%P1";
19082 return "jmp\t%A1";
19083 }
19084 [(set_attr "type" "callv")])
19085
19086 (define_insn "*call_value_1_rex64"
19087 [(set (match_operand 0 "" "")
19088 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19089 (match_operand:DI 2 "" "")))]
19090 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19091 {
19092 if (constant_call_address_operand (operands[1], Pmode))
19093 return "call\t%P1";
19094 return "call\t%A1";
19095 }
19096 [(set_attr "type" "callv")])
19097
19098 (define_insn "*sibcall_value_1_rex64"
19099 [(set (match_operand 0 "" "")
19100 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19101 (match_operand:DI 2 "" "")))]
19102 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19103 "jmp\t%P1"
19104 [(set_attr "type" "callv")])
19105
19106 (define_insn "*sibcall_value_1_rex64_v"
19107 [(set (match_operand 0 "" "")
19108 (call (mem:QI (reg:DI 40))
19109 (match_operand:DI 1 "" "")))]
19110 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19111 "jmp\t*%%r11"
19112 [(set_attr "type" "callv")])
19113 \f
19114 (define_insn "trap"
19115 [(trap_if (const_int 1) (const_int 5))]
19116 ""
19117 "int\t$5")
19118
19119 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19120 ;;; for the sake of bounds checking. By emitting bounds checks as
19121 ;;; conditional traps rather than as conditional jumps around
19122 ;;; unconditional traps we avoid introducing spurious basic-block
19123 ;;; boundaries and facilitate elimination of redundant checks. In
19124 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19125 ;;; interrupt 5.
19126 ;;;
19127 ;;; FIXME: Static branch prediction rules for ix86 are such that
19128 ;;; forward conditional branches predict as untaken. As implemented
19129 ;;; below, pseudo conditional traps violate that rule. We should use
19130 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19131 ;;; section loaded at the end of the text segment and branch forward
19132 ;;; there on bounds-failure, and then jump back immediately (in case
19133 ;;; the system chooses to ignore bounds violations, or to report
19134 ;;; violations and continue execution).
19135
19136 (define_expand "conditional_trap"
19137 [(trap_if (match_operator 0 "comparison_operator"
19138 [(match_dup 2) (const_int 0)])
19139 (match_operand 1 "const_int_operand" ""))]
19140 ""
19141 {
19142 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19143 ix86_expand_compare (GET_CODE (operands[0]),
19144 NULL, NULL),
19145 operands[1]));
19146 DONE;
19147 })
19148
19149 (define_insn "*conditional_trap_1"
19150 [(trap_if (match_operator 0 "comparison_operator"
19151 [(reg FLAGS_REG) (const_int 0)])
19152 (match_operand 1 "const_int_operand" ""))]
19153 ""
19154 {
19155 operands[2] = gen_label_rtx ();
19156 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19157 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19158 CODE_LABEL_NUMBER (operands[2]));
19159 RET;
19160 })
19161
19162 (define_expand "sse_prologue_save"
19163 [(parallel [(set (match_operand:BLK 0 "" "")
19164 (unspec:BLK [(reg:DI 21)
19165 (reg:DI 22)
19166 (reg:DI 23)
19167 (reg:DI 24)
19168 (reg:DI 25)
19169 (reg:DI 26)
19170 (reg:DI 27)
19171 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19172 (use (match_operand:DI 1 "register_operand" ""))
19173 (use (match_operand:DI 2 "immediate_operand" ""))
19174 (use (label_ref:DI (match_operand 3 "" "")))])]
19175 "TARGET_64BIT"
19176 "")
19177
19178 (define_insn "*sse_prologue_save_insn"
19179 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19180 (match_operand:DI 4 "const_int_operand" "n")))
19181 (unspec:BLK [(reg:DI 21)
19182 (reg:DI 22)
19183 (reg:DI 23)
19184 (reg:DI 24)
19185 (reg:DI 25)
19186 (reg:DI 26)
19187 (reg:DI 27)
19188 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19189 (use (match_operand:DI 1 "register_operand" "r"))
19190 (use (match_operand:DI 2 "const_int_operand" "i"))
19191 (use (label_ref:DI (match_operand 3 "" "X")))]
19192 "TARGET_64BIT
19193 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19194 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19195 "*
19196 {
19197 int i;
19198 operands[0] = gen_rtx_MEM (Pmode,
19199 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19200 output_asm_insn (\"jmp\\t%A1\", operands);
19201 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19202 {
19203 operands[4] = adjust_address (operands[0], DImode, i*16);
19204 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19205 PUT_MODE (operands[4], TImode);
19206 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19207 output_asm_insn (\"rex\", operands);
19208 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19209 }
19210 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19211 CODE_LABEL_NUMBER (operands[3]));
19212 RET;
19213 }
19214 "
19215 [(set_attr "type" "other")
19216 (set_attr "length_immediate" "0")
19217 (set_attr "length_address" "0")
19218 (set_attr "length" "135")
19219 (set_attr "memory" "store")
19220 (set_attr "modrm" "0")
19221 (set_attr "mode" "DI")])
19222
19223 (define_expand "prefetch"
19224 [(prefetch (match_operand 0 "address_operand" "")
19225 (match_operand:SI 1 "const_int_operand" "")
19226 (match_operand:SI 2 "const_int_operand" ""))]
19227 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19228 {
19229 int rw = INTVAL (operands[1]);
19230 int locality = INTVAL (operands[2]);
19231
19232 if (rw != 0 && rw != 1)
19233 abort ();
19234 if (locality < 0 || locality > 3)
19235 abort ();
19236 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19237 abort ();
19238
19239 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19240 suported by SSE counterpart or the SSE prefetch is not available
19241 (K6 machines). Otherwise use SSE prefetch as it allows specifying
19242 of locality. */
19243 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19244 operands[2] = GEN_INT (3);
19245 else
19246 operands[1] = const0_rtx;
19247 })
19248
19249 (define_insn "*prefetch_sse"
19250 [(prefetch (match_operand:SI 0 "address_operand" "p")
19251 (const_int 0)
19252 (match_operand:SI 1 "const_int_operand" ""))]
19253 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19254 {
19255 static const char * const patterns[4] = {
19256 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19257 };
19258
19259 int locality = INTVAL (operands[1]);
19260 if (locality < 0 || locality > 3)
19261 abort ();
19262
19263 return patterns[locality];
19264 }
19265 [(set_attr "type" "sse")
19266 (set_attr "memory" "none")])
19267
19268 (define_insn "*prefetch_sse_rex"
19269 [(prefetch (match_operand:DI 0 "address_operand" "p")
19270 (const_int 0)
19271 (match_operand:SI 1 "const_int_operand" ""))]
19272 "TARGET_PREFETCH_SSE && TARGET_64BIT"
19273 {
19274 static const char * const patterns[4] = {
19275 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19276 };
19277
19278 int locality = INTVAL (operands[1]);
19279 if (locality < 0 || locality > 3)
19280 abort ();
19281
19282 return patterns[locality];
19283 }
19284 [(set_attr "type" "sse")
19285 (set_attr "memory" "none")])
19286
19287 (define_insn "*prefetch_3dnow"
19288 [(prefetch (match_operand:SI 0 "address_operand" "p")
19289 (match_operand:SI 1 "const_int_operand" "n")
19290 (const_int 3))]
19291 "TARGET_3DNOW && !TARGET_64BIT"
19292 {
19293 if (INTVAL (operands[1]) == 0)
19294 return "prefetch\t%a0";
19295 else
19296 return "prefetchw\t%a0";
19297 }
19298 [(set_attr "type" "mmx")
19299 (set_attr "memory" "none")])
19300
19301 (define_insn "*prefetch_3dnow_rex"
19302 [(prefetch (match_operand:DI 0 "address_operand" "p")
19303 (match_operand:SI 1 "const_int_operand" "n")
19304 (const_int 3))]
19305 "TARGET_3DNOW && TARGET_64BIT"
19306 {
19307 if (INTVAL (operands[1]) == 0)
19308 return "prefetch\t%a0";
19309 else
19310 return "prefetchw\t%a0";
19311 }
19312 [(set_attr "type" "mmx")
19313 (set_attr "memory" "none")])
19314
19315 (include "sse.md")
19316 (include "mmx.md")
This page took 0.866567 seconds and 4 git commands to generate.