OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc1/] [gcc/] [config/] [i386/] [i386.md] - Blame information for rev 338

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 282 jeremybenn
;; GCC machine description for IA-32 and x86-64.
2
;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3
;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
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 3, 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 COPYING3.  If not see
22
;; .  */
23
;;
24
;; The original PO technology requires these to be ordered by speed,
25
;; so that assigner will pick the fastest.
26
;;
27
;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28
;;
29
;; The special asm out single letter directives following a '%' are:
30
;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31
;; C -- print opcode suffix for set/cmov insn.
32
;; c -- like C, but print reversed condition
33
;; E,e -- likewise, but for compare-and-branch fused insn.
34
;; F,f -- likewise, but for floating-point.
35
;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36
;;      otherwise nothing
37
;; R -- print the prefix for register names.
38
;; z -- print the opcode suffix for the size of the current operand.
39
;; Z -- likewise, with special suffixes for x87 instructions.
40
;; * -- print a star (in certain assembler syntax)
41
;; A -- print an absolute memory reference.
42
;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43
;; s -- print a shift double count, followed by the assemblers argument
44
;;      delimiter.
45
;; b -- print the QImode name of the register for the indicated operand.
46
;;      %b0 would print %al if operands[0] is reg 0.
47
;; w --  likewise, print the HImode name of the register.
48
;; k --  likewise, print the SImode name of the register.
49
;; q --  likewise, print the DImode name of the register.
50
;; x --  likewise, print the V4SFmode name of the register.
51
;; t --  likewise, print the V8SFmode name of the register.
52
;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53
;; y -- print "st(0)" instead of "st" as a register.
54
;; d -- print duplicated register operand for AVX instruction.
55
;; D -- print condition for SSE cmp instruction.
56
;; P -- if PIC, print an @PLT suffix.
57
;; X -- don't print any sort of PIC '@' suffix for a symbol.
58
;; & -- print some in-use local-dynamic symbol name.
59
;; H -- print a memory address offset by 8; used for sse high-parts
60
;; Y -- print condition for XOP pcom* instruction.
61
;; + -- print a branch hint as 'cs' or 'ds' prefix
62
;; ; -- print a semicolon (after prefixes due to bug in older gas).
63
 
64
;; UNSPEC usage:
65
 
66
(define_constants
67
  [; Relocation specifiers
68
   (UNSPEC_GOT                  0)
69
   (UNSPEC_GOTOFF               1)
70
   (UNSPEC_GOTPCREL             2)
71
   (UNSPEC_GOTTPOFF             3)
72
   (UNSPEC_TPOFF                4)
73
   (UNSPEC_NTPOFF               5)
74
   (UNSPEC_DTPOFF               6)
75
   (UNSPEC_GOTNTPOFF            7)
76
   (UNSPEC_INDNTPOFF            8)
77
   (UNSPEC_PLTOFF               9)
78
   (UNSPEC_MACHOPIC_OFFSET      10)
79
 
80
   ; Prologue support
81
   (UNSPEC_STACK_ALLOC          11)
82
   (UNSPEC_SET_GOT              12)
83
   (UNSPEC_SSE_PROLOGUE_SAVE    13)
84
   (UNSPEC_REG_SAVE             14)
85
   (UNSPEC_DEF_CFA              15)
86
   (UNSPEC_SET_RIP              16)
87
   (UNSPEC_SET_GOT_OFFSET       17)
88
   (UNSPEC_MEMORY_BLOCKAGE      18)
89
 
90
   ; TLS support
91
   (UNSPEC_TP                   20)
92
   (UNSPEC_TLS_GD               21)
93
   (UNSPEC_TLS_LD_BASE          22)
94
   (UNSPEC_TLSDESC              23)
95
 
96
   ; Other random patterns
97
   (UNSPEC_SCAS                 30)
98
   (UNSPEC_FNSTSW               31)
99
   (UNSPEC_SAHF                 32)
100
   (UNSPEC_PARITY               33)
101
   (UNSPEC_FSTCW                34)
102
   (UNSPEC_ADD_CARRY            35)
103
   (UNSPEC_FLDCW                36)
104
   (UNSPEC_REP                  37)
105
   (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
106
   (UNSPEC_TRUNC_NOOP           39)
107
 
108
   ; For SSE/MMX support:
109
   (UNSPEC_FIX_NOTRUNC          40)
110
   (UNSPEC_MASKMOV              41)
111
   (UNSPEC_MOVMSK               42)
112
   (UNSPEC_MOVNT                43)
113
   (UNSPEC_MOVU                 44)
114
   (UNSPEC_RCP                  45)
115
   (UNSPEC_RSQRT                46)
116
   (UNSPEC_SFENCE               47)
117
   (UNSPEC_PFRCP                49)
118
   (UNSPEC_PFRCPIT1             40)
119
   (UNSPEC_PFRCPIT2             41)
120
   (UNSPEC_PFRSQRT              42)
121
   (UNSPEC_PFRSQIT1             43)
122
   (UNSPEC_MFENCE               44)
123
   (UNSPEC_LFENCE               45)
124
   (UNSPEC_PSADBW               46)
125
   (UNSPEC_LDDQU                47)
126
   (UNSPEC_MS_TO_SYSV_CALL      48)
127
 
128
   ; Generic math support
129
   (UNSPEC_COPYSIGN             50)
130
   (UNSPEC_IEEE_MIN             51)     ; not commutative
131
   (UNSPEC_IEEE_MAX             52)     ; not commutative
132
 
133
   ; x87 Floating point
134
   (UNSPEC_SIN                  60)
135
   (UNSPEC_COS                  61)
136
   (UNSPEC_FPATAN               62)
137
   (UNSPEC_FYL2X                63)
138
   (UNSPEC_FYL2XP1              64)
139
   (UNSPEC_FRNDINT              65)
140
   (UNSPEC_FIST                 66)
141
   (UNSPEC_F2XM1                67)
142
   (UNSPEC_TAN                  68)
143
   (UNSPEC_FXAM                 69)
144
 
145
   ; x87 Rounding
146
   (UNSPEC_FRNDINT_FLOOR        70)
147
   (UNSPEC_FRNDINT_CEIL         71)
148
   (UNSPEC_FRNDINT_TRUNC        72)
149
   (UNSPEC_FRNDINT_MASK_PM      73)
150
   (UNSPEC_FIST_FLOOR           74)
151
   (UNSPEC_FIST_CEIL            75)
152
 
153
   ; x87 Double output FP
154
   (UNSPEC_SINCOS_COS           80)
155
   (UNSPEC_SINCOS_SIN           81)
156
   (UNSPEC_XTRACT_FRACT         84)
157
   (UNSPEC_XTRACT_EXP           85)
158
   (UNSPEC_FSCALE_FRACT         86)
159
   (UNSPEC_FSCALE_EXP           87)
160
   (UNSPEC_FPREM_F              88)
161
   (UNSPEC_FPREM_U              89)
162
   (UNSPEC_FPREM1_F             90)
163
   (UNSPEC_FPREM1_U             91)
164
 
165
   (UNSPEC_C2_FLAG              95)
166
   (UNSPEC_FXAM_MEM             96)
167
 
168
   ; SSP patterns
169
   (UNSPEC_SP_SET               100)
170
   (UNSPEC_SP_TEST              101)
171
   (UNSPEC_SP_TLS_SET           102)
172
   (UNSPEC_SP_TLS_TEST          103)
173
 
174
   ; SSSE3
175
   (UNSPEC_PSHUFB               120)
176
   (UNSPEC_PSIGN                121)
177
   (UNSPEC_PALIGNR              122)
178
 
179
   ; For SSE4A support
180
   (UNSPEC_EXTRQI               130)
181
   (UNSPEC_EXTRQ                131)
182
   (UNSPEC_INSERTQI             132)
183
   (UNSPEC_INSERTQ              133)
184
 
185
   ; For SSE4.1 support
186
   (UNSPEC_BLENDV               134)
187
   (UNSPEC_INSERTPS             135)
188
   (UNSPEC_DP                   136)
189
   (UNSPEC_MOVNTDQA             137)
190
   (UNSPEC_MPSADBW              138)
191
   (UNSPEC_PHMINPOSUW           139)
192
   (UNSPEC_PTEST                140)
193
   (UNSPEC_ROUND                141)
194
 
195
   ; For SSE4.2 support
196
   (UNSPEC_CRC32                143)
197
   (UNSPEC_PCMPESTR             144)
198
   (UNSPEC_PCMPISTR             145)
199
 
200
   ; For FMA4 support
201
   (UNSPEC_FMA4_INTRINSIC       150)
202
   (UNSPEC_FMA4_FMADDSUB        151)
203
   (UNSPEC_FMA4_FMSUBADD        152)
204
   (UNSPEC_XOP_UNSIGNED_CMP     151)
205
   (UNSPEC_XOP_TRUEFALSE        152)
206
   (UNSPEC_XOP_PERMUTE          153)
207
   (UNSPEC_FRCZ                 154)
208
 
209
   ; For AES support
210
   (UNSPEC_AESENC               159)
211
   (UNSPEC_AESENCLAST           160)
212
   (UNSPEC_AESDEC               161)
213
   (UNSPEC_AESDECLAST           162)
214
   (UNSPEC_AESIMC               163)
215
   (UNSPEC_AESKEYGENASSIST      164)
216
 
217
   ; For PCLMUL support
218
   (UNSPEC_PCLMUL               165)
219
 
220
   ; For AVX support
221
   (UNSPEC_PCMP                 166)
222
   (UNSPEC_VPERMIL              167)
223
   (UNSPEC_VPERMIL2             168)
224
   (UNSPEC_VPERMIL2F128         169)
225
   (UNSPEC_MASKLOAD             170)
226
   (UNSPEC_MASKSTORE            171)
227
   (UNSPEC_CAST                 172)
228
   (UNSPEC_VTESTP               173)
229
  ])
230
 
231
(define_constants
232
  [(UNSPECV_BLOCKAGE            0)
233
   (UNSPECV_STACK_PROBE         1)
234
   (UNSPECV_EMMS                2)
235
   (UNSPECV_LDMXCSR             3)
236
   (UNSPECV_STMXCSR             4)
237
   (UNSPECV_FEMMS               5)
238
   (UNSPECV_CLFLUSH             6)
239
   (UNSPECV_ALIGN               7)
240
   (UNSPECV_MONITOR             8)
241
   (UNSPECV_MWAIT               9)
242
   (UNSPECV_CMPXCHG             10)
243
   (UNSPECV_XCHG                12)
244
   (UNSPECV_LOCK                13)
245
   (UNSPECV_PROLOGUE_USE        14)
246
   (UNSPECV_CLD                 15)
247
   (UNSPECV_VZEROALL            16)
248
   (UNSPECV_VZEROUPPER          17)
249
   (UNSPECV_RDTSC               18)
250
   (UNSPECV_RDTSCP              19)
251
   (UNSPECV_RDPMC               20)
252
   (UNSPECV_VSWAPMOV            21)
253
   (UNSPECV_LLWP_INTRINSIC      22)
254
   (UNSPECV_SLWP_INTRINSIC      23)
255
   (UNSPECV_LWPVAL_INTRINSIC    24)
256
   (UNSPECV_LWPINS_INTRINSIC    25)
257
  ])
258
 
259
;; Constants to represent pcomtrue/pcomfalse variants
260
(define_constants
261
  [(PCOM_FALSE                  0)
262
   (PCOM_TRUE                   1)
263
   (COM_FALSE_S                 2)
264
   (COM_FALSE_P                 3)
265
   (COM_TRUE_S                  4)
266
   (COM_TRUE_P                  5)
267
  ])
268
 
269
;; Constants used in the XOP pperm instruction
270
(define_constants
271
  [(PPERM_SRC                   0x00)   /* copy source */
272
   (PPERM_INVERT                0x20)   /* invert source */
273
   (PPERM_REVERSE               0x40)   /* bit reverse source */
274
   (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
275
   (PPERM_ZERO                  0x80)   /* all 0's */
276
   (PPERM_ONES                  0xa0)   /* all 1's */
277
   (PPERM_SIGN                  0xc0)   /* propagate sign bit */
278
   (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
279
   (PPERM_SRC1                  0x00)   /* use first source byte */
280
   (PPERM_SRC2                  0x10)   /* use second source byte */
281
   ])
282
 
283
;; Registers by name.
284
(define_constants
285
  [(AX_REG                       0)
286
   (DX_REG                       1)
287
   (CX_REG                       2)
288
   (BX_REG                       3)
289
   (SI_REG                       4)
290
   (DI_REG                       5)
291
   (BP_REG                       6)
292
   (SP_REG                       7)
293
   (ST0_REG                      8)
294
   (ST1_REG                      9)
295
   (ST2_REG                     10)
296
   (ST3_REG                     11)
297
   (ST4_REG                     12)
298
   (ST5_REG                     13)
299
   (ST6_REG                     14)
300
   (ST7_REG                     15)
301
   (FLAGS_REG                   17)
302
   (FPSR_REG                    18)
303
   (FPCR_REG                    19)
304
   (XMM0_REG                    21)
305
   (XMM1_REG                    22)
306
   (XMM2_REG                    23)
307
   (XMM3_REG                    24)
308
   (XMM4_REG                    25)
309
   (XMM5_REG                    26)
310
   (XMM6_REG                    27)
311
   (XMM7_REG                    28)
312
   (MM0_REG                     29)
313
   (MM1_REG                     30)
314
   (MM2_REG                     31)
315
   (MM3_REG                     32)
316
   (MM4_REG                     33)
317
   (MM5_REG                     34)
318
   (MM6_REG                     35)
319
   (MM7_REG                     36)
320
   (R8_REG                      37)
321
   (R9_REG                      38)
322
   (R10_REG                     39)
323
   (R11_REG                     40)
324
   (R12_REG                     41)
325
   (R13_REG                     42)
326
   (XMM8_REG                    45)
327
   (XMM9_REG                    46)
328
   (XMM10_REG                   47)
329
   (XMM11_REG                   48)
330
   (XMM12_REG                   49)
331
   (XMM13_REG                   50)
332
   (XMM14_REG                   51)
333
   (XMM15_REG                   52)
334
  ])
335
 
336
;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
337
;; from i386.c.
338
 
339
;; In C guard expressions, put expressions which may be compile-time
340
;; constants first.  This allows for better optimization.  For
341
;; example, write "TARGET_64BIT && reload_completed", not
342
;; "reload_completed && TARGET_64BIT".
343
 
344
 
345
;; Processor type.
346
(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
347
                    generic64,amdfam10"
348
  (const (symbol_ref "ix86_schedule")))
349
 
350
;; A basic instruction type.  Refinements due to arguments to be
351
;; provided in other attributes.
352
(define_attr "type"
353
  "other,multi,
354
   alu,alu1,negnot,imov,imovx,lea,
355
   incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
356
   icmp,test,ibr,setcc,icmov,
357
   push,pop,call,callv,leave,
358
   str,bitmanip,
359
   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
360
   sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
361
   sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
362
   ssemuladd,sse4arg,lwp,
363
   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
364
  (const_string "other"))
365
 
366
;; Main data type used by the insn
367
(define_attr "mode"
368
  "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
369
  (const_string "unknown"))
370
 
371
;; The CPU unit operations uses.
372
(define_attr "unit" "integer,i387,sse,mmx,unknown"
373
  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
374
           (const_string "i387")
375
         (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
376
                          sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
377
                          ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
378
           (const_string "sse")
379
         (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
380
           (const_string "mmx")
381
         (eq_attr "type" "other")
382
           (const_string "unknown")]
383
         (const_string "integer")))
384
 
385
;; The (bounding maximum) length of an instruction immediate.
386
(define_attr "length_immediate" ""
387
  (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
388
                          bitmanip")
389
           (const_int 0)
390
         (eq_attr "unit" "i387,sse,mmx")
391
           (const_int 0)
392
         (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
393
                          imul,icmp,push,pop")
394
           (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
395
         (eq_attr "type" "imov,test")
396
           (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
397
         (eq_attr "type" "call")
398
           (if_then_else (match_operand 0 "constant_call_address_operand" "")
399
             (const_int 4)
400
             (const_int 0))
401
         (eq_attr "type" "callv")
402
           (if_then_else (match_operand 1 "constant_call_address_operand" "")
403
             (const_int 4)
404
             (const_int 0))
405
         ;; We don't know the size before shorten_branches.  Expect
406
         ;; the instruction to fit for better scheduling.
407
         (eq_attr "type" "ibr")
408
           (const_int 1)
409
         ]
410
         (symbol_ref "/* Update immediate_length and other attributes! */
411
                      gcc_unreachable (),1")))
412
 
413
;; The (bounding maximum) length of an instruction address.
414
(define_attr "length_address" ""
415
  (cond [(eq_attr "type" "str,other,multi,fxch")
416
           (const_int 0)
417
         (and (eq_attr "type" "call")
418
              (match_operand 0 "constant_call_address_operand" ""))
419
             (const_int 0)
420
         (and (eq_attr "type" "callv")
421
              (match_operand 1 "constant_call_address_operand" ""))
422
             (const_int 0)
423
         ]
424
         (symbol_ref "ix86_attr_length_address_default (insn)")))
425
 
426
;; Set when length prefix is used.
427
(define_attr "prefix_data16" ""
428
  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
429
           (const_int 0)
430
         (eq_attr "mode" "HI")
431
           (const_int 1)
432
         (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
433
           (const_int 1)
434
        ]
435
        (const_int 0)))
436
 
437
;; Set when string REP prefix is used.
438
(define_attr "prefix_rep" ""
439
  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
440
           (const_int 0)
441
         (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
442
           (const_int 1)
443
        ]
444
        (const_int 0)))
445
 
446
;; Set when 0f opcode prefix is used.
447
(define_attr "prefix_0f" ""
448
  (if_then_else
449
    (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
450
         (eq_attr "unit" "sse,mmx"))
451
    (const_int 1)
452
    (const_int 0)))
453
 
454
;; Set when REX opcode prefix is used.
455
(define_attr "prefix_rex" ""
456
  (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
457
           (const_int 0)
458
         (and (eq_attr "mode" "DI")
459
              (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
460
                   (eq_attr "unit" "!mmx")))
461
           (const_int 1)
462
         (and (eq_attr "mode" "QI")
463
              (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
464
                  (const_int 0)))
465
           (const_int 1)
466
         (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
467
             (const_int 0))
468
           (const_int 1)
469
         (and (eq_attr "type" "imovx")
470
              (match_operand:QI 1 "ext_QIreg_operand" ""))
471
           (const_int 1)
472
        ]
473
        (const_int 0)))
474
 
475
;; There are also additional prefixes in 3DNOW, SSSE3.
476
;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
477
;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
478
;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
479
(define_attr "prefix_extra" ""
480
  (cond [(eq_attr "type" "ssemuladd,sse4arg")
481
           (const_int 2)
482
         (eq_attr "type" "sseiadd1,ssecvt1")
483
           (const_int 1)
484
        ]
485
        (const_int 0)))
486
 
487
;; Prefix used: original, VEX or maybe VEX.
488
(define_attr "prefix" "orig,vex,maybe_vex"
489
  (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
490
    (const_string "vex")
491
    (const_string "orig")))
492
 
493
;; VEX W bit is used.
494
(define_attr "prefix_vex_w" "" (const_int 0))
495
 
496
;; The length of VEX prefix
497
;; Only instructions with 0f prefix can have 2 byte VEX prefix,
498
;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
499
;; still prefix_0f 1, with prefix_extra 1.
500
(define_attr "length_vex" ""
501
  (if_then_else (and (eq_attr "prefix_0f" "1")
502
                     (eq_attr "prefix_extra" "0"))
503
    (if_then_else (eq_attr "prefix_vex_w" "1")
504
      (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
505
      (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
506
    (if_then_else (eq_attr "prefix_vex_w" "1")
507
      (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
508
      (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
509
 
510
;; Set when modrm byte is used.
511
(define_attr "modrm" ""
512
  (cond [(eq_attr "type" "str,leave")
513
           (const_int 0)
514
         (eq_attr "unit" "i387")
515
           (const_int 0)
516
         (and (eq_attr "type" "incdec")
517
              (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
518
                   (ior (match_operand:SI 1 "register_operand" "")
519
                        (match_operand:HI 1 "register_operand" ""))))
520
           (const_int 0)
521
         (and (eq_attr "type" "push")
522
              (not (match_operand 1 "memory_operand" "")))
523
           (const_int 0)
524
         (and (eq_attr "type" "pop")
525
              (not (match_operand 0 "memory_operand" "")))
526
           (const_int 0)
527
         (and (eq_attr "type" "imov")
528
              (and (not (eq_attr "mode" "DI"))
529
                   (ior (and (match_operand 0 "register_operand" "")
530
                             (match_operand 1 "immediate_operand" ""))
531
                        (ior (and (match_operand 0 "ax_reg_operand" "")
532
                                  (match_operand 1 "memory_displacement_only_operand" ""))
533
                             (and (match_operand 0 "memory_displacement_only_operand" "")
534
                                  (match_operand 1 "ax_reg_operand" ""))))))
535
           (const_int 0)
536
         (and (eq_attr "type" "call")
537
              (match_operand 0 "constant_call_address_operand" ""))
538
             (const_int 0)
539
         (and (eq_attr "type" "callv")
540
              (match_operand 1 "constant_call_address_operand" ""))
541
             (const_int 0)
542
         (and (eq_attr "type" "alu,alu1,icmp,test")
543
              (match_operand 0 "ax_reg_operand" ""))
544
             (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
545
         ]
546
         (const_int 1)))
547
 
548
;; The (bounding maximum) length of an instruction in bytes.
549
;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
550
;; Later we may want to split them and compute proper length as for
551
;; other insns.
552
(define_attr "length" ""
553
  (cond [(eq_attr "type" "other,multi,fistp,frndint")
554
           (const_int 16)
555
         (eq_attr "type" "fcmp")
556
           (const_int 4)
557
         (eq_attr "unit" "i387")
558
           (plus (const_int 2)
559
                 (plus (attr "prefix_data16")
560
                       (attr "length_address")))
561
         (ior (eq_attr "prefix" "vex")
562
              (and (eq_attr "prefix" "maybe_vex")
563
                    (ne (symbol_ref "TARGET_AVX") (const_int 0))))
564
           (plus (attr "length_vex")
565
                 (plus (attr "length_immediate")
566
                       (plus (attr "modrm")
567
                             (attr "length_address"))))]
568
         (plus (plus (attr "modrm")
569
                     (plus (attr "prefix_0f")
570
                           (plus (attr "prefix_rex")
571
                                 (plus (attr "prefix_extra")
572
                                       (const_int 1)))))
573
               (plus (attr "prefix_rep")
574
                     (plus (attr "prefix_data16")
575
                           (plus (attr "length_immediate")
576
                                 (attr "length_address")))))))
577
 
578
;; The `memory' attribute is `none' if no memory is referenced, `load' or
579
;; `store' if there is a simple memory reference therein, or `unknown'
580
;; if the instruction is complex.
581
 
582
(define_attr "memory" "none,load,store,both,unknown"
583
  (cond [(eq_attr "type" "other,multi,str,lwp")
584
           (const_string "unknown")
585
         (eq_attr "type" "lea,fcmov,fpspc")
586
           (const_string "none")
587
         (eq_attr "type" "fistp,leave")
588
           (const_string "both")
589
         (eq_attr "type" "frndint")
590
           (const_string "load")
591
         (eq_attr "type" "push")
592
           (if_then_else (match_operand 1 "memory_operand" "")
593
             (const_string "both")
594
             (const_string "store"))
595
         (eq_attr "type" "pop")
596
           (if_then_else (match_operand 0 "memory_operand" "")
597
             (const_string "both")
598
             (const_string "load"))
599
         (eq_attr "type" "setcc")
600
           (if_then_else (match_operand 0 "memory_operand" "")
601
             (const_string "store")
602
             (const_string "none"))
603
         (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
604
           (if_then_else (ior (match_operand 0 "memory_operand" "")
605
                              (match_operand 1 "memory_operand" ""))
606
             (const_string "load")
607
             (const_string "none"))
608
         (eq_attr "type" "ibr")
609
           (if_then_else (match_operand 0 "memory_operand" "")
610
             (const_string "load")
611
             (const_string "none"))
612
         (eq_attr "type" "call")
613
           (if_then_else (match_operand 0 "constant_call_address_operand" "")
614
             (const_string "none")
615
             (const_string "load"))
616
         (eq_attr "type" "callv")
617
           (if_then_else (match_operand 1 "constant_call_address_operand" "")
618
             (const_string "none")
619
             (const_string "load"))
620
         (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
621
              (match_operand 1 "memory_operand" ""))
622
           (const_string "both")
623
         (and (match_operand 0 "memory_operand" "")
624
              (match_operand 1 "memory_operand" ""))
625
           (const_string "both")
626
         (match_operand 0 "memory_operand" "")
627
           (const_string "store")
628
         (match_operand 1 "memory_operand" "")
629
           (const_string "load")
630
         (and (eq_attr "type"
631
                 "!alu1,negnot,ishift1,
632
                   imov,imovx,icmp,test,bitmanip,
633
                   fmov,fcmp,fsgn,
634
                   sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
635
                   sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
636
              (match_operand 2 "memory_operand" ""))
637
           (const_string "load")
638
         (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
639
              (match_operand 3 "memory_operand" ""))
640
           (const_string "load")
641
        ]
642
        (const_string "none")))
643
 
644
;; Indicates if an instruction has both an immediate and a displacement.
645
 
646
(define_attr "imm_disp" "false,true,unknown"
647
  (cond [(eq_attr "type" "other,multi")
648
           (const_string "unknown")
649
         (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
650
              (and (match_operand 0 "memory_displacement_operand" "")
651
                   (match_operand 1 "immediate_operand" "")))
652
           (const_string "true")
653
         (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
654
              (and (match_operand 0 "memory_displacement_operand" "")
655
                   (match_operand 2 "immediate_operand" "")))
656
           (const_string "true")
657
        ]
658
        (const_string "false")))
659
 
660
;; Indicates if an FP operation has an integer source.
661
 
662
(define_attr "fp_int_src" "false,true"
663
  (const_string "false"))
664
 
665
;; Defines rounding mode of an FP operation.
666
 
667
(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
668
  (const_string "any"))
669
 
670
;; Define attribute to classify add/sub insns that consumes carry flag (CF)
671
(define_attr "use_carry" "0,1" (const_string "0"))
672
 
673
;; Define attribute to indicate unaligned ssemov insns
674
(define_attr "movu" "0,1" (const_string "0"))
675
 
676
;; Describe a user's asm statement.
677
(define_asm_attributes
678
  [(set_attr "length" "128")
679
   (set_attr "type" "multi")])
680
 
681
;; All integer comparison codes.
682
(define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
683
 
684
;; All floating-point comparison codes.
685
(define_code_iterator fp_cond [unordered ordered
686
                               uneq unge ungt unle unlt ltgt])
687
 
688
(define_code_iterator plusminus [plus minus])
689
 
690
(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
691
 
692
;; Base name for define_insn
693
(define_code_attr plusminus_insn
694
  [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
695
   (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
696
 
697
;; Base name for insn mnemonic.
698
(define_code_attr plusminus_mnemonic
699
  [(plus "add") (ss_plus "adds") (us_plus "addus")
700
   (minus "sub") (ss_minus "subs") (us_minus "subus")])
701
(define_code_attr plusminus_carry_mnemonic
702
  [(plus "adc") (minus "sbb")])
703
 
704
;; Mark commutative operators as such in constraints.
705
(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
706
                        (minus "") (ss_minus "") (us_minus "")])
707
 
708
;; Mapping of signed max and min
709
(define_code_iterator smaxmin [smax smin])
710
 
711
;; Mapping of unsigned max and min
712
(define_code_iterator umaxmin [umax umin])
713
 
714
;; Mapping of signed/unsigned max and min
715
(define_code_iterator maxmin [smax smin umax umin])
716
 
717
;; Base name for integer and FP insn mnemonic
718
(define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
719
                                 (umax "maxu") (umin "minu")])
720
(define_code_attr maxminfprefix [(smax "max") (smin "min")])
721
 
722
;; Mapping of logic operators
723
(define_code_iterator any_logic [and ior xor])
724
(define_code_iterator any_or [ior xor])
725
 
726
;; Base name for insn mnemonic.
727
(define_code_attr logicprefix [(and "and") (ior "or") (xor "xor")])
728
 
729
;; Mapping of abs neg operators
730
(define_code_iterator absneg [abs neg])
731
 
732
;; Base name for x87 insn mnemonic.
733
(define_code_attr absnegprefix [(abs "abs") (neg "chs")])
734
 
735
;; Used in signed and unsigned widening multiplications.
736
(define_code_iterator any_extend [sign_extend zero_extend])
737
 
738
;; Various insn prefixes for signed and unsigned operations.
739
(define_code_attr u [(sign_extend "") (zero_extend "u")
740
                     (div "") (udiv "u")])
741
(define_code_attr s [(sign_extend "s") (zero_extend "u")])
742
 
743
;; Used in signed and unsigned divisions.
744
(define_code_iterator any_div [div udiv])
745
 
746
;; Instruction prefix for signed and unsigned operations.
747
(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
748
                             (div "i") (udiv "")])
749
 
750
;; All single word integer modes.
751
(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
752
 
753
;; Single word integer modes without DImode.
754
(define_mode_iterator SWI124 [QI HI SI])
755
 
756
;; Single word integer modes without QImode.
757
(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
758
 
759
;; Single word integer modes without QImode and HImode.
760
(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
761
 
762
;; All math-dependant single and double word integer modes.
763
(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
764
                             (HI "TARGET_HIMODE_MATH")
765
                             SI DI (TI "TARGET_64BIT")])
766
 
767
;; Math-dependant single word integer modes.
768
(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
769
                            (HI "TARGET_HIMODE_MATH")
770
                            SI (DI "TARGET_64BIT")])
771
 
772
;; Math-dependant single word integer modes without QImode.
773
(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
774
                               SI (DI "TARGET_64BIT")])
775
 
776
;; Half mode for double word integer modes.
777
(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
778
                            (DI "TARGET_64BIT")])
779
 
780
;; Double word integer modes.
781
(define_mode_attr DWI [(SI "DI") (DI "TI")])
782
(define_mode_attr dwi [(SI "di") (DI "ti")])
783
 
784
;; Instruction suffix for integer modes.
785
(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
786
 
787
;; Register class for integer modes.
788
(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
789
 
790
;; Immediate operand constraint for integer modes.
791
(define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
792
 
793
;; General operand constraint for word modes.
794
(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
795
 
796
;; Immediate operand constraint for double integer modes.
797
(define_mode_attr di [(SI "iF") (DI "e")])
798
 
799
;; General operand predicate for integer modes.
800
(define_mode_attr general_operand
801
        [(QI "general_operand")
802
         (HI "general_operand")
803
         (SI "general_operand")
804
         (DI "x86_64_general_operand")
805
         (TI "x86_64_general_operand")])
806
 
807
;; General sign/zero extend operand predicate for integer modes.
808
(define_mode_attr general_szext_operand
809
        [(QI "general_operand")
810
         (HI "general_operand")
811
         (SI "general_operand")
812
         (DI "x86_64_szext_general_operand")])
813
 
814
;; SSE and x87 SFmode and DFmode floating point modes
815
(define_mode_iterator MODEF [SF DF])
816
 
817
;; All x87 floating point modes
818
(define_mode_iterator X87MODEF [SF DF XF])
819
 
820
;; All integer modes handled by x87 fisttp operator.
821
(define_mode_iterator X87MODEI [HI SI DI])
822
 
823
;; All integer modes handled by integer x87 operators.
824
(define_mode_iterator X87MODEI12 [HI SI])
825
 
826
;; All integer modes handled by SSE cvtts?2si* operators.
827
(define_mode_iterator SSEMODEI24 [SI DI])
828
 
829
;; SSE asm suffix for floating point modes
830
(define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
831
 
832
;; SSE vector mode corresponding to a scalar mode
833
(define_mode_attr ssevecmode
834
  [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
835
 
836
;; Instruction suffix for REX 64bit operators.
837
(define_mode_attr rex64suffix [(SI "") (DI "{q}")])
838
 
839
;; This mode iterator allows :P to be used for patterns that operate on
840
;; pointer-sized quantities.  Exactly one of the two alternatives will match.
841
(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
842
 
843
;; Scheduling descriptions
844
 
845
(include "pentium.md")
846
(include "ppro.md")
847
(include "k6.md")
848
(include "athlon.md")
849
(include "geode.md")
850
(include "atom.md")
851
 
852
 
853
;; Operand and operator predicates and constraints
854
 
855
(include "predicates.md")
856
(include "constraints.md")
857
 
858
 
859
;; Compare and branch/compare and store instructions.
860
 
861
(define_expand "cbranch4"
862
  [(set (reg:CC FLAGS_REG)
863
        (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
864
                    (match_operand:SDWIM 2 "" "")))
865
   (set (pc) (if_then_else
866
               (match_operator 0 "comparison_operator"
867
                [(reg:CC FLAGS_REG) (const_int 0)])
868
               (label_ref (match_operand 3 "" ""))
869
               (pc)))]
870
  ""
871
{
872
  if (MEM_P (operands[1]) && MEM_P (operands[2]))
873
    operands[1] = force_reg (mode, operands[1]);
874
  ix86_compare_op0 = operands[1];
875
  ix86_compare_op1 = operands[2];
876
  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
877
  DONE;
878
})
879
 
880
(define_expand "cstore4"
881
  [(set (reg:CC FLAGS_REG)
882
        (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
883
                    (match_operand:SWIM 3 "" "")))
884
   (set (match_operand:QI 0 "register_operand" "")
885
        (match_operator 1 "comparison_operator"
886
          [(reg:CC FLAGS_REG) (const_int 0)]))]
887
  ""
888
{
889
  if (MEM_P (operands[2]) && MEM_P (operands[3]))
890
    operands[2] = force_reg (mode, operands[2]);
891
  ix86_compare_op0 = operands[2];
892
  ix86_compare_op1 = operands[3];
893
  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
894
  DONE;
895
})
896
 
897
(define_expand "cmp_1"
898
  [(set (reg:CC FLAGS_REG)
899
        (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
900
                    (match_operand:SWI48 1 "" "")))]
901
  ""
902
  "")
903
 
904
(define_insn "*cmp_ccno_1"
905
  [(set (reg FLAGS_REG)
906
        (compare (match_operand:SWI 0 "nonimmediate_operand" ",?m")
907
                 (match_operand:SWI 1 "const0_operand" "")))]
908
  "ix86_match_ccmode (insn, CCNOmode)"
909
  "@
910
   test{}\t%0, %0
911
   cmp{}\t{%1, %0|%0, %1}"
912
  [(set_attr "type" "test,icmp")
913
   (set_attr "length_immediate" "0,1")
914
   (set_attr "mode" "")])
915
 
916
(define_insn "*cmp_1"
917
  [(set (reg FLAGS_REG)
918
        (compare (match_operand:SWI 0 "nonimmediate_operand" "m,")
919
                 (match_operand:SWI 1 "" ",m")))]
920
  "ix86_match_ccmode (insn, CCmode)"
921
  "cmp{}\t{%1, %0|%0, %1}"
922
  [(set_attr "type" "icmp")
923
   (set_attr "mode" "")])
924
 
925
(define_insn "*cmp_minus_1"
926
  [(set (reg FLAGS_REG)
927
        (compare
928
          (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "m,")
929
                     (match_operand:SWI 1 "" ",m"))
930
          (const_int 0)))]
931
  "ix86_match_ccmode (insn, CCGOCmode)"
932
  "cmp{}\t{%1, %0|%0, %1}"
933
  [(set_attr "type" "icmp")
934
   (set_attr "mode" "")])
935
 
936
(define_insn "*cmpqi_ext_1"
937
  [(set (reg FLAGS_REG)
938
        (compare
939
          (match_operand:QI 0 "general_operand" "Qm")
940
          (subreg:QI
941
            (zero_extract:SI
942
              (match_operand 1 "ext_register_operand" "Q")
943
              (const_int 8)
944
              (const_int 8)) 0)))]
945
  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
946
  "cmp{b}\t{%h1, %0|%0, %h1}"
947
  [(set_attr "type" "icmp")
948
   (set_attr "mode" "QI")])
949
 
950
(define_insn "*cmpqi_ext_1_rex64"
951
  [(set (reg FLAGS_REG)
952
        (compare
953
          (match_operand:QI 0 "register_operand" "Q")
954
          (subreg:QI
955
            (zero_extract:SI
956
              (match_operand 1 "ext_register_operand" "Q")
957
              (const_int 8)
958
              (const_int 8)) 0)))]
959
  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
960
  "cmp{b}\t{%h1, %0|%0, %h1}"
961
  [(set_attr "type" "icmp")
962
   (set_attr "mode" "QI")])
963
 
964
(define_insn "*cmpqi_ext_2"
965
  [(set (reg FLAGS_REG)
966
        (compare
967
          (subreg:QI
968
            (zero_extract:SI
969
              (match_operand 0 "ext_register_operand" "Q")
970
              (const_int 8)
971
              (const_int 8)) 0)
972
          (match_operand:QI 1 "const0_operand" "")))]
973
  "ix86_match_ccmode (insn, CCNOmode)"
974
  "test{b}\t%h0, %h0"
975
  [(set_attr "type" "test")
976
   (set_attr "length_immediate" "0")
977
   (set_attr "mode" "QI")])
978
 
979
(define_expand "cmpqi_ext_3"
980
  [(set (reg:CC FLAGS_REG)
981
        (compare:CC
982
          (subreg:QI
983
            (zero_extract:SI
984
              (match_operand 0 "ext_register_operand" "")
985
              (const_int 8)
986
              (const_int 8)) 0)
987
          (match_operand:QI 1 "immediate_operand" "")))]
988
  ""
989
  "")
990
 
991
(define_insn "*cmpqi_ext_3_insn"
992
  [(set (reg FLAGS_REG)
993
        (compare
994
          (subreg:QI
995
            (zero_extract:SI
996
              (match_operand 0 "ext_register_operand" "Q")
997
              (const_int 8)
998
              (const_int 8)) 0)
999
          (match_operand:QI 1 "general_operand" "Qmn")))]
1000
  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1001
  "cmp{b}\t{%1, %h0|%h0, %1}"
1002
  [(set_attr "type" "icmp")
1003
   (set_attr "modrm" "1")
1004
   (set_attr "mode" "QI")])
1005
 
1006
(define_insn "*cmpqi_ext_3_insn_rex64"
1007
  [(set (reg FLAGS_REG)
1008
        (compare
1009
          (subreg:QI
1010
            (zero_extract:SI
1011
              (match_operand 0 "ext_register_operand" "Q")
1012
              (const_int 8)
1013
              (const_int 8)) 0)
1014
          (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1015
  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1016
  "cmp{b}\t{%1, %h0|%h0, %1}"
1017
  [(set_attr "type" "icmp")
1018
   (set_attr "modrm" "1")
1019
   (set_attr "mode" "QI")])
1020
 
1021
(define_insn "*cmpqi_ext_4"
1022
  [(set (reg FLAGS_REG)
1023
        (compare
1024
          (subreg:QI
1025
            (zero_extract:SI
1026
              (match_operand 0 "ext_register_operand" "Q")
1027
              (const_int 8)
1028
              (const_int 8)) 0)
1029
          (subreg:QI
1030
            (zero_extract:SI
1031
              (match_operand 1 "ext_register_operand" "Q")
1032
              (const_int 8)
1033
              (const_int 8)) 0)))]
1034
  "ix86_match_ccmode (insn, CCmode)"
1035
  "cmp{b}\t{%h1, %h0|%h0, %h1}"
1036
  [(set_attr "type" "icmp")
1037
   (set_attr "mode" "QI")])
1038
 
1039
;; These implement float point compares.
1040
;; %%% See if we can get away with VOIDmode operands on the actual insns,
1041
;; which would allow mix and match FP modes on the compares.  Which is what
1042
;; the old patterns did, but with many more of them.
1043
 
1044
(define_expand "cbranchxf4"
1045
  [(set (reg:CC FLAGS_REG)
1046
        (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1047
                    (match_operand:XF 2 "nonmemory_operand" "")))
1048
   (set (pc) (if_then_else
1049
              (match_operator 0 "ix86_fp_comparison_operator"
1050
               [(reg:CC FLAGS_REG)
1051
                (const_int 0)])
1052
              (label_ref (match_operand 3 "" ""))
1053
              (pc)))]
1054
  "TARGET_80387"
1055
{
1056
  ix86_compare_op0 = operands[1];
1057
  ix86_compare_op1 = operands[2];
1058
  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1059
  DONE;
1060
})
1061
 
1062
(define_expand "cstorexf4"
1063
  [(set (reg:CC FLAGS_REG)
1064
        (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1065
                    (match_operand:XF 3 "nonmemory_operand" "")))
1066
   (set (match_operand:QI 0 "register_operand" "")
1067
              (match_operator 1 "ix86_fp_comparison_operator"
1068
               [(reg:CC FLAGS_REG)
1069
                (const_int 0)]))]
1070
  "TARGET_80387"
1071
{
1072
  ix86_compare_op0 = operands[2];
1073
  ix86_compare_op1 = operands[3];
1074
  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1075
  DONE;
1076
})
1077
 
1078
(define_expand "cbranch4"
1079
  [(set (reg:CC FLAGS_REG)
1080
        (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1081
                    (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1082
   (set (pc) (if_then_else
1083
              (match_operator 0 "ix86_fp_comparison_operator"
1084
               [(reg:CC FLAGS_REG)
1085
                (const_int 0)])
1086
              (label_ref (match_operand 3 "" ""))
1087
              (pc)))]
1088
  "TARGET_80387 || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
1089
{
1090
  ix86_compare_op0 = operands[1];
1091
  ix86_compare_op1 = operands[2];
1092
  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1093
  DONE;
1094
})
1095
 
1096
(define_expand "cstore4"
1097
  [(set (reg:CC FLAGS_REG)
1098
        (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1099
                    (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1100
   (set (match_operand:QI 0 "register_operand" "")
1101
              (match_operator 1 "ix86_fp_comparison_operator"
1102
               [(reg:CC FLAGS_REG)
1103
                (const_int 0)]))]
1104
  "TARGET_80387 || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
1105
{
1106
  ix86_compare_op0 = operands[2];
1107
  ix86_compare_op1 = operands[3];
1108
  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1109
  DONE;
1110
})
1111
 
1112
(define_expand "cbranchcc4"
1113
  [(set (pc) (if_then_else
1114
              (match_operator 0 "comparison_operator"
1115
               [(match_operand 1 "flags_reg_operand" "")
1116
                (match_operand 2 "const0_operand" "")])
1117
              (label_ref (match_operand 3 "" ""))
1118
              (pc)))]
1119
  ""
1120
{
1121
  ix86_compare_op0 = operands[1];
1122
  ix86_compare_op1 = operands[2];
1123
  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1124
  DONE;
1125
})
1126
 
1127
(define_expand "cstorecc4"
1128
  [(set (match_operand:QI 0 "register_operand" "")
1129
              (match_operator 1 "comparison_operator"
1130
               [(match_operand 2 "flags_reg_operand" "")
1131
                (match_operand 3 "const0_operand" "")]))]
1132
  ""
1133
{
1134
  ix86_compare_op0 = operands[2];
1135
  ix86_compare_op1 = operands[3];
1136
  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1137
  DONE;
1138
})
1139
 
1140
 
1141
;; FP compares, step 1:
1142
;; Set the FP condition codes.
1143
;;
1144
;; CCFPmode     compare with exceptions
1145
;; CCFPUmode    compare with no exceptions
1146
 
1147
;; We may not use "#" to split and emit these, since the REG_DEAD notes
1148
;; used to manage the reg stack popping would not be preserved.
1149
 
1150
(define_insn "*cmpfp_0"
1151
  [(set (match_operand:HI 0 "register_operand" "=a")
1152
        (unspec:HI
1153
          [(compare:CCFP
1154
             (match_operand 1 "register_operand" "f")
1155
             (match_operand 2 "const0_operand" ""))]
1156
        UNSPEC_FNSTSW))]
1157
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1158
   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1159
  "* return output_fp_compare (insn, operands, 0, 0);"
1160
  [(set_attr "type" "multi")
1161
   (set_attr "unit" "i387")
1162
   (set (attr "mode")
1163
     (cond [(match_operand:SF 1 "" "")
1164
              (const_string "SF")
1165
            (match_operand:DF 1 "" "")
1166
              (const_string "DF")
1167
           ]
1168
           (const_string "XF")))])
1169
 
1170
(define_insn_and_split "*cmpfp_0_cc"
1171
  [(set (reg:CCFP FLAGS_REG)
1172
        (compare:CCFP
1173
          (match_operand 1 "register_operand" "f")
1174
          (match_operand 2 "const0_operand" "")))
1175
   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1176
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1177
   && TARGET_SAHF && !TARGET_CMOVE
1178
   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1179
  "#"
1180
  "&& reload_completed"
1181
  [(set (match_dup 0)
1182
        (unspec:HI
1183
          [(compare:CCFP (match_dup 1)(match_dup 2))]
1184
        UNSPEC_FNSTSW))
1185
   (set (reg:CC FLAGS_REG)
1186
        (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1187
  ""
1188
  [(set_attr "type" "multi")
1189
   (set_attr "unit" "i387")
1190
   (set (attr "mode")
1191
     (cond [(match_operand:SF 1 "" "")
1192
              (const_string "SF")
1193
            (match_operand:DF 1 "" "")
1194
              (const_string "DF")
1195
           ]
1196
           (const_string "XF")))])
1197
 
1198
(define_insn "*cmpfp_xf"
1199
  [(set (match_operand:HI 0 "register_operand" "=a")
1200
        (unspec:HI
1201
          [(compare:CCFP
1202
             (match_operand:XF 1 "register_operand" "f")
1203
             (match_operand:XF 2 "register_operand" "f"))]
1204
          UNSPEC_FNSTSW))]
1205
  "TARGET_80387"
1206
  "* return output_fp_compare (insn, operands, 0, 0);"
1207
  [(set_attr "type" "multi")
1208
   (set_attr "unit" "i387")
1209
   (set_attr "mode" "XF")])
1210
 
1211
(define_insn_and_split "*cmpfp_xf_cc"
1212
  [(set (reg:CCFP FLAGS_REG)
1213
        (compare:CCFP
1214
          (match_operand:XF 1 "register_operand" "f")
1215
          (match_operand:XF 2 "register_operand" "f")))
1216
   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1217
  "TARGET_80387
1218
   && TARGET_SAHF && !TARGET_CMOVE"
1219
  "#"
1220
  "&& reload_completed"
1221
  [(set (match_dup 0)
1222
        (unspec:HI
1223
          [(compare:CCFP (match_dup 1)(match_dup 2))]
1224
        UNSPEC_FNSTSW))
1225
   (set (reg:CC FLAGS_REG)
1226
        (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1227
  ""
1228
  [(set_attr "type" "multi")
1229
   (set_attr "unit" "i387")
1230
   (set_attr "mode" "XF")])
1231
 
1232
(define_insn "*cmpfp_"
1233
  [(set (match_operand:HI 0 "register_operand" "=a")
1234
        (unspec:HI
1235
          [(compare:CCFP
1236
             (match_operand:MODEF 1 "register_operand" "f")
1237
             (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1238
          UNSPEC_FNSTSW))]
1239
  "TARGET_80387"
1240
  "* return output_fp_compare (insn, operands, 0, 0);"
1241
  [(set_attr "type" "multi")
1242
   (set_attr "unit" "i387")
1243
   (set_attr "mode" "")])
1244
 
1245
(define_insn_and_split "*cmpfp__cc"
1246
  [(set (reg:CCFP FLAGS_REG)
1247
        (compare:CCFP
1248
          (match_operand:MODEF 1 "register_operand" "f")
1249
          (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1250
   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1251
  "TARGET_80387
1252
   && TARGET_SAHF && !TARGET_CMOVE"
1253
  "#"
1254
  "&& reload_completed"
1255
  [(set (match_dup 0)
1256
        (unspec:HI
1257
          [(compare:CCFP (match_dup 1)(match_dup 2))]
1258
        UNSPEC_FNSTSW))
1259
   (set (reg:CC FLAGS_REG)
1260
        (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1261
  ""
1262
  [(set_attr "type" "multi")
1263
   (set_attr "unit" "i387")
1264
   (set_attr "mode" "")])
1265
 
1266
(define_insn "*cmpfp_u"
1267
  [(set (match_operand:HI 0 "register_operand" "=a")
1268
        (unspec:HI
1269
          [(compare:CCFPU
1270
             (match_operand 1 "register_operand" "f")
1271
             (match_operand 2 "register_operand" "f"))]
1272
          UNSPEC_FNSTSW))]
1273
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1274
   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1275
  "* return output_fp_compare (insn, operands, 0, 1);"
1276
  [(set_attr "type" "multi")
1277
   (set_attr "unit" "i387")
1278
   (set (attr "mode")
1279
     (cond [(match_operand:SF 1 "" "")
1280
              (const_string "SF")
1281
            (match_operand:DF 1 "" "")
1282
              (const_string "DF")
1283
           ]
1284
           (const_string "XF")))])
1285
 
1286
(define_insn_and_split "*cmpfp_u_cc"
1287
  [(set (reg:CCFPU FLAGS_REG)
1288
        (compare:CCFPU
1289
          (match_operand 1 "register_operand" "f")
1290
          (match_operand 2 "register_operand" "f")))
1291
   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1292
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1293
   && TARGET_SAHF && !TARGET_CMOVE
1294
   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1295
  "#"
1296
  "&& reload_completed"
1297
  [(set (match_dup 0)
1298
        (unspec:HI
1299
          [(compare:CCFPU (match_dup 1)(match_dup 2))]
1300
        UNSPEC_FNSTSW))
1301
   (set (reg:CC FLAGS_REG)
1302
        (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1303
  ""
1304
  [(set_attr "type" "multi")
1305
   (set_attr "unit" "i387")
1306
   (set (attr "mode")
1307
     (cond [(match_operand:SF 1 "" "")
1308
              (const_string "SF")
1309
            (match_operand:DF 1 "" "")
1310
              (const_string "DF")
1311
           ]
1312
           (const_string "XF")))])
1313
 
1314
(define_insn "*cmpfp_"
1315
  [(set (match_operand:HI 0 "register_operand" "=a")
1316
        (unspec:HI
1317
          [(compare:CCFP
1318
             (match_operand 1 "register_operand" "f")
1319
             (match_operator 3 "float_operator"
1320
               [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1321
          UNSPEC_FNSTSW))]
1322
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1323
   && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))
1324
   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1325
  "* return output_fp_compare (insn, operands, 0, 0);"
1326
  [(set_attr "type" "multi")
1327
   (set_attr "unit" "i387")
1328
   (set_attr "fp_int_src" "true")
1329
   (set_attr "mode" "")])
1330
 
1331
(define_insn_and_split "*cmpfp__cc"
1332
  [(set (reg:CCFP FLAGS_REG)
1333
        (compare:CCFP
1334
          (match_operand 1 "register_operand" "f")
1335
          (match_operator 3 "float_operator"
1336
            [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1337
   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1338
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1339
   && TARGET_SAHF && !TARGET_CMOVE
1340
   && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))
1341
   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1342
  "#"
1343
  "&& reload_completed"
1344
  [(set (match_dup 0)
1345
        (unspec:HI
1346
          [(compare:CCFP
1347
             (match_dup 1)
1348
             (match_op_dup 3 [(match_dup 2)]))]
1349
        UNSPEC_FNSTSW))
1350
   (set (reg:CC FLAGS_REG)
1351
        (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1352
  ""
1353
  [(set_attr "type" "multi")
1354
   (set_attr "unit" "i387")
1355
   (set_attr "fp_int_src" "true")
1356
   (set_attr "mode" "")])
1357
 
1358
;; FP compares, step 2
1359
;; Move the fpsw to ax.
1360
 
1361
(define_insn "x86_fnstsw_1"
1362
  [(set (match_operand:HI 0 "register_operand" "=a")
1363
        (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1364
  "TARGET_80387"
1365
  "fnstsw\t%0"
1366
  [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1367
   (set_attr "mode" "SI")
1368
   (set_attr "unit" "i387")])
1369
 
1370
;; FP compares, step 3
1371
;; Get ax into flags, general case.
1372
 
1373
(define_insn "x86_sahf_1"
1374
  [(set (reg:CC FLAGS_REG)
1375
        (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1376
                   UNSPEC_SAHF))]
1377
  "TARGET_SAHF"
1378
{
1379
#ifndef HAVE_AS_IX86_SAHF
1380
  if (TARGET_64BIT)
1381
    return ASM_BYTE "0x9e";
1382
  else
1383
#endif
1384
  return "sahf";
1385
}
1386
  [(set_attr "length" "1")
1387
   (set_attr "athlon_decode" "vector")
1388
   (set_attr "amdfam10_decode" "direct")
1389
   (set_attr "mode" "SI")])
1390
 
1391
;; Pentium Pro can do steps 1 through 3 in one go.
1392
;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1393
(define_insn "*cmpfp_i_mixed"
1394
  [(set (reg:CCFP FLAGS_REG)
1395
        (compare:CCFP (match_operand 0 "register_operand" "f,x")
1396
                      (match_operand 1 "nonimmediate_operand" "f,xm")))]
1397
  "TARGET_MIX_SSE_I387
1398
   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1399
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1400
  "* return output_fp_compare (insn, operands, 1, 0);"
1401
  [(set_attr "type" "fcmp,ssecomi")
1402
   (set_attr "prefix" "orig,maybe_vex")
1403
   (set (attr "mode")
1404
     (if_then_else (match_operand:SF 1 "" "")
1405
        (const_string "SF")
1406
        (const_string "DF")))
1407
   (set (attr "prefix_rep")
1408
        (if_then_else (eq_attr "type" "ssecomi")
1409
                      (const_string "0")
1410
                      (const_string "*")))
1411
   (set (attr "prefix_data16")
1412
        (cond [(eq_attr "type" "fcmp")
1413
                 (const_string "*")
1414
               (eq_attr "mode" "DF")
1415
                 (const_string "1")
1416
              ]
1417
              (const_string "0")))
1418
   (set_attr "athlon_decode" "vector")
1419
   (set_attr "amdfam10_decode" "direct")])
1420
 
1421
(define_insn "*cmpfp_i_sse"
1422
  [(set (reg:CCFP FLAGS_REG)
1423
        (compare:CCFP (match_operand 0 "register_operand" "x")
1424
                      (match_operand 1 "nonimmediate_operand" "xm")))]
1425
  "TARGET_SSE_MATH
1426
   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1427
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1428
  "* return output_fp_compare (insn, operands, 1, 0);"
1429
  [(set_attr "type" "ssecomi")
1430
   (set_attr "prefix" "maybe_vex")
1431
   (set (attr "mode")
1432
     (if_then_else (match_operand:SF 1 "" "")
1433
        (const_string "SF")
1434
        (const_string "DF")))
1435
   (set_attr "prefix_rep" "0")
1436
   (set (attr "prefix_data16")
1437
        (if_then_else (eq_attr "mode" "DF")
1438
                      (const_string "1")
1439
                      (const_string "0")))
1440
   (set_attr "athlon_decode" "vector")
1441
   (set_attr "amdfam10_decode" "direct")])
1442
 
1443
(define_insn "*cmpfp_i_i387"
1444
  [(set (reg:CCFP FLAGS_REG)
1445
        (compare:CCFP (match_operand 0 "register_operand" "f")
1446
                      (match_operand 1 "register_operand" "f")))]
1447
  "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1448
   && TARGET_CMOVE
1449
   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1450
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1451
  "* return output_fp_compare (insn, operands, 1, 0);"
1452
  [(set_attr "type" "fcmp")
1453
   (set (attr "mode")
1454
     (cond [(match_operand:SF 1 "" "")
1455
              (const_string "SF")
1456
            (match_operand:DF 1 "" "")
1457
              (const_string "DF")
1458
           ]
1459
           (const_string "XF")))
1460
   (set_attr "athlon_decode" "vector")
1461
   (set_attr "amdfam10_decode" "direct")])
1462
 
1463
(define_insn "*cmpfp_iu_mixed"
1464
  [(set (reg:CCFPU FLAGS_REG)
1465
        (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1466
                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1467
  "TARGET_MIX_SSE_I387
1468
   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1469
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1470
  "* return output_fp_compare (insn, operands, 1, 1);"
1471
  [(set_attr "type" "fcmp,ssecomi")
1472
   (set_attr "prefix" "orig,maybe_vex")
1473
   (set (attr "mode")
1474
     (if_then_else (match_operand:SF 1 "" "")
1475
        (const_string "SF")
1476
        (const_string "DF")))
1477
   (set (attr "prefix_rep")
1478
        (if_then_else (eq_attr "type" "ssecomi")
1479
                      (const_string "0")
1480
                      (const_string "*")))
1481
   (set (attr "prefix_data16")
1482
        (cond [(eq_attr "type" "fcmp")
1483
                 (const_string "*")
1484
               (eq_attr "mode" "DF")
1485
                 (const_string "1")
1486
              ]
1487
              (const_string "0")))
1488
   (set_attr "athlon_decode" "vector")
1489
   (set_attr "amdfam10_decode" "direct")])
1490
 
1491
(define_insn "*cmpfp_iu_sse"
1492
  [(set (reg:CCFPU FLAGS_REG)
1493
        (compare:CCFPU (match_operand 0 "register_operand" "x")
1494
                       (match_operand 1 "nonimmediate_operand" "xm")))]
1495
  "TARGET_SSE_MATH
1496
   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1497
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1498
  "* return output_fp_compare (insn, operands, 1, 1);"
1499
  [(set_attr "type" "ssecomi")
1500
   (set_attr "prefix" "maybe_vex")
1501
   (set (attr "mode")
1502
     (if_then_else (match_operand:SF 1 "" "")
1503
        (const_string "SF")
1504
        (const_string "DF")))
1505
   (set_attr "prefix_rep" "0")
1506
   (set (attr "prefix_data16")
1507
        (if_then_else (eq_attr "mode" "DF")
1508
                      (const_string "1")
1509
                      (const_string "0")))
1510
   (set_attr "athlon_decode" "vector")
1511
   (set_attr "amdfam10_decode" "direct")])
1512
 
1513
(define_insn "*cmpfp_iu_387"
1514
  [(set (reg:CCFPU FLAGS_REG)
1515
        (compare:CCFPU (match_operand 0 "register_operand" "f")
1516
                       (match_operand 1 "register_operand" "f")))]
1517
  "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1518
   && TARGET_CMOVE
1519
   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1520
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1521
  "* return output_fp_compare (insn, operands, 1, 1);"
1522
  [(set_attr "type" "fcmp")
1523
   (set (attr "mode")
1524
     (cond [(match_operand:SF 1 "" "")
1525
              (const_string "SF")
1526
            (match_operand:DF 1 "" "")
1527
              (const_string "DF")
1528
           ]
1529
           (const_string "XF")))
1530
   (set_attr "athlon_decode" "vector")
1531
   (set_attr "amdfam10_decode" "direct")])
1532
 
1533
;; Move instructions.
1534
 
1535
;; General case of fullword move.
1536
 
1537
(define_expand "movsi"
1538
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1539
        (match_operand:SI 1 "general_operand" ""))]
1540
  ""
1541
  "ix86_expand_move (SImode, operands); DONE;")
1542
 
1543
;; Push/pop instructions.  They are separate since autoinc/dec is not a
1544
;; general_operand.
1545
;;
1546
;; %%% We don't use a post-inc memory reference because x86 is not a
1547
;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1548
;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1549
;; targets without our curiosities, and it is just as easy to represent
1550
;; this differently.
1551
 
1552
(define_insn "*pushsi2"
1553
  [(set (match_operand:SI 0 "push_operand" "=<")
1554
        (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1555
  "!TARGET_64BIT"
1556
  "push{l}\t%1"
1557
  [(set_attr "type" "push")
1558
   (set_attr "mode" "SI")])
1559
 
1560
;; For 64BIT abi we always round up to 8 bytes.
1561
(define_insn "*pushsi2_rex64"
1562
  [(set (match_operand:SI 0 "push_operand" "=X")
1563
        (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1564
  "TARGET_64BIT"
1565
  "push{q}\t%q1"
1566
  [(set_attr "type" "push")
1567
   (set_attr "mode" "SI")])
1568
 
1569
(define_insn "*pushsi2_prologue"
1570
  [(set (match_operand:SI 0 "push_operand" "=<")
1571
        (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1572
   (clobber (mem:BLK (scratch)))]
1573
  "!TARGET_64BIT"
1574
  "push{l}\t%1"
1575
  [(set_attr "type" "push")
1576
   (set_attr "mode" "SI")])
1577
 
1578
(define_insn "*popsi1_epilogue"
1579
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1580
        (mem:SI (reg:SI SP_REG)))
1581
   (set (reg:SI SP_REG)
1582
        (plus:SI (reg:SI SP_REG) (const_int 4)))
1583
   (clobber (mem:BLK (scratch)))]
1584
  "!TARGET_64BIT"
1585
  "pop{l}\t%0"
1586
  [(set_attr "type" "pop")
1587
   (set_attr "mode" "SI")])
1588
 
1589
(define_insn "popsi1"
1590
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1591
        (mem:SI (reg:SI SP_REG)))
1592
   (set (reg:SI SP_REG)
1593
        (plus:SI (reg:SI SP_REG) (const_int 4)))]
1594
  "!TARGET_64BIT"
1595
  "pop{l}\t%0"
1596
  [(set_attr "type" "pop")
1597
   (set_attr "mode" "SI")])
1598
 
1599
(define_insn "*movsi_xor"
1600
  [(set (match_operand:SI 0 "register_operand" "=r")
1601
        (match_operand:SI 1 "const0_operand" ""))
1602
   (clobber (reg:CC FLAGS_REG))]
1603
  "reload_completed"
1604
  "xor{l}\t%0, %0"
1605
  [(set_attr "type" "alu1")
1606
   (set_attr "mode" "SI")
1607
   (set_attr "length_immediate" "0")])
1608
 
1609
(define_insn "*movsi_or"
1610
  [(set (match_operand:SI 0 "register_operand" "=r")
1611
        (match_operand:SI 1 "immediate_operand" "i"))
1612
   (clobber (reg:CC FLAGS_REG))]
1613
  "reload_completed
1614
   && operands[1] == constm1_rtx"
1615
{
1616
  operands[1] = constm1_rtx;
1617
  return "or{l}\t{%1, %0|%0, %1}";
1618
}
1619
  [(set_attr "type" "alu1")
1620
   (set_attr "mode" "SI")
1621
   (set_attr "length_immediate" "1")])
1622
 
1623
(define_insn "*movsi_1"
1624
  [(set (match_operand:SI 0 "nonimmediate_operand"
1625
                        "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1626
        (match_operand:SI 1 "general_operand"
1627
                        "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1628
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1629
{
1630
  switch (get_attr_type (insn))
1631
    {
1632
    case TYPE_SSELOG1:
1633
      if (get_attr_mode (insn) == MODE_TI)
1634
        return "%vpxor\t%0, %d0";
1635
      return "%vxorps\t%0, %d0";
1636
 
1637
    case TYPE_SSEMOV:
1638
      switch (get_attr_mode (insn))
1639
        {
1640
        case MODE_TI:
1641
          return "%vmovdqa\t{%1, %0|%0, %1}";
1642
        case MODE_V4SF:
1643
          return "%vmovaps\t{%1, %0|%0, %1}";
1644
        case MODE_SI:
1645
          return "%vmovd\t{%1, %0|%0, %1}";
1646
        case MODE_SF:
1647
          return "%vmovss\t{%1, %0|%0, %1}";
1648
        default:
1649
          gcc_unreachable ();
1650
        }
1651
 
1652
    case TYPE_MMX:
1653
      return "pxor\t%0, %0";
1654
 
1655
    case TYPE_MMXMOV:
1656
      if (get_attr_mode (insn) == MODE_DI)
1657
        return "movq\t{%1, %0|%0, %1}";
1658
      return "movd\t{%1, %0|%0, %1}";
1659
 
1660
    case TYPE_LEA:
1661
      return "lea{l}\t{%a1, %0|%0, %a1}";
1662
 
1663
    default:
1664
      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1665
      return "mov{l}\t{%1, %0|%0, %1}";
1666
    }
1667
}
1668
  [(set (attr "type")
1669
     (cond [(eq_attr "alternative" "2")
1670
              (const_string "mmx")
1671
            (eq_attr "alternative" "3,4,5")
1672
              (const_string "mmxmov")
1673
            (eq_attr "alternative" "6")
1674
              (const_string "sselog1")
1675
            (eq_attr "alternative" "7,8,9,10,11")
1676
              (const_string "ssemov")
1677
            (match_operand:DI 1 "pic_32bit_operand" "")
1678
              (const_string "lea")
1679
           ]
1680
           (const_string "imov")))
1681
   (set (attr "prefix")
1682
     (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1683
       (const_string "orig")
1684
       (const_string "maybe_vex")))
1685
   (set (attr "prefix_data16")
1686
     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1687
       (const_string "1")
1688
       (const_string "*")))
1689
   (set (attr "mode")
1690
     (cond [(eq_attr "alternative" "2,3")
1691
              (const_string "DI")
1692
            (eq_attr "alternative" "6,7")
1693
              (if_then_else
1694
                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1695
                (const_string "V4SF")
1696
                (const_string "TI"))
1697
            (and (eq_attr "alternative" "8,9,10,11")
1698
                 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1699
              (const_string "SF")
1700
           ]
1701
           (const_string "SI")))])
1702
 
1703
;; Stores and loads of ax to arbitrary constant address.
1704
;; We fake an second form of instruction to force reload to load address
1705
;; into register when rax is not available
1706
(define_insn "*movabssi_1_rex64"
1707
  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1708
        (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1709
  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1710
  "@
1711
   movabs{l}\t{%1, %P0|%P0, %1}
1712
   mov{l}\t{%1, %a0|%a0, %1}"
1713
  [(set_attr "type" "imov")
1714
   (set_attr "modrm" "0,*")
1715
   (set_attr "length_address" "8,0")
1716
   (set_attr "length_immediate" "0,*")
1717
   (set_attr "memory" "store")
1718
   (set_attr "mode" "SI")])
1719
 
1720
(define_insn "*movabssi_2_rex64"
1721
  [(set (match_operand:SI 0 "register_operand" "=a,r")
1722
        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1723
  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1724
  "@
1725
   movabs{l}\t{%P1, %0|%0, %P1}
1726
   mov{l}\t{%a1, %0|%0, %a1}"
1727
  [(set_attr "type" "imov")
1728
   (set_attr "modrm" "0,*")
1729
   (set_attr "length_address" "8,0")
1730
   (set_attr "length_immediate" "0")
1731
   (set_attr "memory" "load")
1732
   (set_attr "mode" "SI")])
1733
 
1734
(define_insn "*swapsi"
1735
  [(set (match_operand:SI 0 "register_operand" "+r")
1736
        (match_operand:SI 1 "register_operand" "+r"))
1737
   (set (match_dup 1)
1738
        (match_dup 0))]
1739
  ""
1740
  "xchg{l}\t%1, %0"
1741
  [(set_attr "type" "imov")
1742
   (set_attr "mode" "SI")
1743
   (set_attr "pent_pair" "np")
1744
   (set_attr "athlon_decode" "vector")
1745
   (set_attr "amdfam10_decode" "double")])
1746
 
1747
(define_expand "movhi"
1748
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1749
        (match_operand:HI 1 "general_operand" ""))]
1750
  ""
1751
  "ix86_expand_move (HImode, operands); DONE;")
1752
 
1753
(define_insn "*pushhi2"
1754
  [(set (match_operand:HI 0 "push_operand" "=X")
1755
        (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1756
  "!TARGET_64BIT"
1757
  "push{l}\t%k1"
1758
  [(set_attr "type" "push")
1759
   (set_attr "mode" "SI")])
1760
 
1761
;; For 64BIT abi we always round up to 8 bytes.
1762
(define_insn "*pushhi2_rex64"
1763
  [(set (match_operand:HI 0 "push_operand" "=X")
1764
        (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1765
  "TARGET_64BIT"
1766
  "push{q}\t%q1"
1767
  [(set_attr "type" "push")
1768
   (set_attr "mode" "DI")])
1769
 
1770
(define_insn "*movhi_1"
1771
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1772
        (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1773
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1774
{
1775
  switch (get_attr_type (insn))
1776
    {
1777
    case TYPE_IMOVX:
1778
      /* movzwl is faster than movw on p2 due to partial word stalls,
1779
         though not as fast as an aligned movl.  */
1780
      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1781
    default:
1782
      if (get_attr_mode (insn) == MODE_SI)
1783
        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1784
      else
1785
        return "mov{w}\t{%1, %0|%0, %1}";
1786
    }
1787
}
1788
  [(set (attr "type")
1789
     (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1790
              (const_string "imov")
1791
            (and (eq_attr "alternative" "0")
1792
                 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1793
                          (const_int 0))
1794
                      (eq (symbol_ref "TARGET_HIMODE_MATH")
1795
                          (const_int 0))))
1796
              (const_string "imov")
1797
            (and (eq_attr "alternative" "1,2")
1798
                 (match_operand:HI 1 "aligned_operand" ""))
1799
              (const_string "imov")
1800
            (and (ne (symbol_ref "TARGET_MOVX")
1801
                     (const_int 0))
1802
                 (eq_attr "alternative" "0,2"))
1803
              (const_string "imovx")
1804
           ]
1805
           (const_string "imov")))
1806
    (set (attr "mode")
1807
      (cond [(eq_attr "type" "imovx")
1808
               (const_string "SI")
1809
             (and (eq_attr "alternative" "1,2")
1810
                  (match_operand:HI 1 "aligned_operand" ""))
1811
               (const_string "SI")
1812
             (and (eq_attr "alternative" "0")
1813
                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1814
                           (const_int 0))
1815
                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1816
                           (const_int 0))))
1817
               (const_string "SI")
1818
            ]
1819
            (const_string "HI")))])
1820
 
1821
;; Stores and loads of ax to arbitrary constant address.
1822
;; We fake an second form of instruction to force reload to load address
1823
;; into register when rax is not available
1824
(define_insn "*movabshi_1_rex64"
1825
  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1826
        (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1827
  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1828
  "@
1829
   movabs{w}\t{%1, %P0|%P0, %1}
1830
   mov{w}\t{%1, %a0|%a0, %1}"
1831
  [(set_attr "type" "imov")
1832
   (set_attr "modrm" "0,*")
1833
   (set_attr "length_address" "8,0")
1834
   (set_attr "length_immediate" "0,*")
1835
   (set_attr "memory" "store")
1836
   (set_attr "mode" "HI")])
1837
 
1838
(define_insn "*movabshi_2_rex64"
1839
  [(set (match_operand:HI 0 "register_operand" "=a,r")
1840
        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1841
  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1842
  "@
1843
   movabs{w}\t{%P1, %0|%0, %P1}
1844
   mov{w}\t{%a1, %0|%0, %a1}"
1845
  [(set_attr "type" "imov")
1846
   (set_attr "modrm" "0,*")
1847
   (set_attr "length_address" "8,0")
1848
   (set_attr "length_immediate" "0")
1849
   (set_attr "memory" "load")
1850
   (set_attr "mode" "HI")])
1851
 
1852
(define_insn "*swaphi_1"
1853
  [(set (match_operand:HI 0 "register_operand" "+r")
1854
        (match_operand:HI 1 "register_operand" "+r"))
1855
   (set (match_dup 1)
1856
        (match_dup 0))]
1857
  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1858
  "xchg{l}\t%k1, %k0"
1859
  [(set_attr "type" "imov")
1860
   (set_attr "mode" "SI")
1861
   (set_attr "pent_pair" "np")
1862
   (set_attr "athlon_decode" "vector")
1863
   (set_attr "amdfam10_decode" "double")])
1864
 
1865
;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1866
(define_insn "*swaphi_2"
1867
  [(set (match_operand:HI 0 "register_operand" "+r")
1868
        (match_operand:HI 1 "register_operand" "+r"))
1869
   (set (match_dup 1)
1870
        (match_dup 0))]
1871
  "TARGET_PARTIAL_REG_STALL"
1872
  "xchg{w}\t%1, %0"
1873
  [(set_attr "type" "imov")
1874
   (set_attr "mode" "HI")
1875
   (set_attr "pent_pair" "np")
1876
   (set_attr "athlon_decode" "vector")])
1877
 
1878
(define_expand "movstricthi"
1879
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1880
        (match_operand:HI 1 "general_operand" ""))]
1881
  ""
1882
{
1883
  if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1884
    FAIL;
1885
  /* Don't generate memory->memory moves, go through a register */
1886
  if (MEM_P (operands[0]) && MEM_P (operands[1]))
1887
    operands[1] = force_reg (HImode, operands[1]);
1888
})
1889
 
1890
(define_insn "*movstricthi_1"
1891
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1892
        (match_operand:HI 1 "general_operand" "rn,m"))]
1893
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1894
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1895
  "mov{w}\t{%1, %0|%0, %1}"
1896
  [(set_attr "type" "imov")
1897
   (set_attr "mode" "HI")])
1898
 
1899
(define_insn "*movstricthi_xor"
1900
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1901
        (match_operand:HI 1 "const0_operand" ""))
1902
   (clobber (reg:CC FLAGS_REG))]
1903
  "reload_completed"
1904
  "xor{w}\t%0, %0"
1905
  [(set_attr "type" "alu1")
1906
   (set_attr "mode" "HI")
1907
   (set_attr "length_immediate" "0")])
1908
 
1909
(define_expand "movqi"
1910
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1911
        (match_operand:QI 1 "general_operand" ""))]
1912
  ""
1913
  "ix86_expand_move (QImode, operands); DONE;")
1914
 
1915
;; emit_push_insn when it calls move_by_pieces requires an insn to
1916
;; "push a byte".  But actually we use pushl, which has the effect
1917
;; of rounding the amount pushed up to a word.
1918
 
1919
(define_insn "*pushqi2"
1920
  [(set (match_operand:QI 0 "push_operand" "=X")
1921
        (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1922
  "!TARGET_64BIT"
1923
  "push{l}\t%k1"
1924
  [(set_attr "type" "push")
1925
   (set_attr "mode" "SI")])
1926
 
1927
;; For 64BIT abi we always round up to 8 bytes.
1928
(define_insn "*pushqi2_rex64"
1929
  [(set (match_operand:QI 0 "push_operand" "=X")
1930
        (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1931
  "TARGET_64BIT"
1932
  "push{q}\t%q1"
1933
  [(set_attr "type" "push")
1934
   (set_attr "mode" "DI")])
1935
 
1936
;; Situation is quite tricky about when to choose full sized (SImode) move
1937
;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1938
;; partial register dependency machines (such as AMD Athlon), where QImode
1939
;; moves issue extra dependency and for partial register stalls machines
1940
;; that don't use QImode patterns (and QImode move cause stall on the next
1941
;; instruction).
1942
;;
1943
;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1944
;; register stall machines with, where we use QImode instructions, since
1945
;; partial register stall can be caused there.  Then we use movzx.
1946
(define_insn "*movqi_1"
1947
  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1948
        (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1949
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1950
{
1951
  switch (get_attr_type (insn))
1952
    {
1953
    case TYPE_IMOVX:
1954
      gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1955
      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1956
    default:
1957
      if (get_attr_mode (insn) == MODE_SI)
1958
        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1959
      else
1960
        return "mov{b}\t{%1, %0|%0, %1}";
1961
    }
1962
}
1963
  [(set (attr "type")
1964
     (cond [(and (eq_attr "alternative" "5")
1965
                 (not (match_operand:QI 1 "aligned_operand" "")))
1966
              (const_string "imovx")
1967
            (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1968
              (const_string "imov")
1969
            (and (eq_attr "alternative" "3")
1970
                 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1971
                          (const_int 0))
1972
                      (eq (symbol_ref "TARGET_QIMODE_MATH")
1973
                          (const_int 0))))
1974
              (const_string "imov")
1975
            (eq_attr "alternative" "3,5")
1976
              (const_string "imovx")
1977
            (and (ne (symbol_ref "TARGET_MOVX")
1978
                     (const_int 0))
1979
                 (eq_attr "alternative" "2"))
1980
              (const_string "imovx")
1981
           ]
1982
           (const_string "imov")))
1983
   (set (attr "mode")
1984
      (cond [(eq_attr "alternative" "3,4,5")
1985
               (const_string "SI")
1986
             (eq_attr "alternative" "6")
1987
               (const_string "QI")
1988
             (eq_attr "type" "imovx")
1989
               (const_string "SI")
1990
             (and (eq_attr "type" "imov")
1991
                  (and (eq_attr "alternative" "0,1")
1992
                       (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1993
                                (const_int 0))
1994
                            (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1995
                                     (const_int 0))
1996
                                 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1997
                                     (const_int 0))))))
1998
               (const_string "SI")
1999
             ;; Avoid partial register stalls when not using QImode arithmetic
2000
             (and (eq_attr "type" "imov")
2001
                  (and (eq_attr "alternative" "0,1")
2002
                       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2003
                                (const_int 0))
2004
                            (eq (symbol_ref "TARGET_QIMODE_MATH")
2005
                                (const_int 0)))))
2006
               (const_string "SI")
2007
           ]
2008
           (const_string "QI")))])
2009
 
2010
(define_insn "*swapqi_1"
2011
  [(set (match_operand:QI 0 "register_operand" "+r")
2012
        (match_operand:QI 1 "register_operand" "+r"))
2013
   (set (match_dup 1)
2014
        (match_dup 0))]
2015
  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2016
  "xchg{l}\t%k1, %k0"
2017
  [(set_attr "type" "imov")
2018
   (set_attr "mode" "SI")
2019
   (set_attr "pent_pair" "np")
2020
   (set_attr "athlon_decode" "vector")
2021
   (set_attr "amdfam10_decode" "vector")])
2022
 
2023
;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2024
(define_insn "*swapqi_2"
2025
  [(set (match_operand:QI 0 "register_operand" "+q")
2026
        (match_operand:QI 1 "register_operand" "+q"))
2027
   (set (match_dup 1)
2028
        (match_dup 0))]
2029
  "TARGET_PARTIAL_REG_STALL"
2030
  "xchg{b}\t%1, %0"
2031
  [(set_attr "type" "imov")
2032
   (set_attr "mode" "QI")
2033
   (set_attr "pent_pair" "np")
2034
   (set_attr "athlon_decode" "vector")])
2035
 
2036
(define_expand "movstrictqi"
2037
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2038
        (match_operand:QI 1 "general_operand" ""))]
2039
  ""
2040
{
2041
  if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2042
    FAIL;
2043
  /* Don't generate memory->memory moves, go through a register.  */
2044
  if (MEM_P (operands[0]) && MEM_P (operands[1]))
2045
    operands[1] = force_reg (QImode, operands[1]);
2046
})
2047
 
2048
(define_insn "*movstrictqi_1"
2049
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2050
        (match_operand:QI 1 "general_operand" "*qn,m"))]
2051
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2052
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2053
  "mov{b}\t{%1, %0|%0, %1}"
2054
  [(set_attr "type" "imov")
2055
   (set_attr "mode" "QI")])
2056
 
2057
(define_insn "*movstrictqi_xor"
2058
  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2059
        (match_operand:QI 1 "const0_operand" ""))
2060
   (clobber (reg:CC FLAGS_REG))]
2061
  "reload_completed"
2062
  "xor{b}\t%0, %0"
2063
  [(set_attr "type" "alu1")
2064
   (set_attr "mode" "QI")
2065
   (set_attr "length_immediate" "0")])
2066
 
2067
(define_insn "*movsi_extv_1"
2068
  [(set (match_operand:SI 0 "register_operand" "=R")
2069
        (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2070
                         (const_int 8)
2071
                         (const_int 8)))]
2072
  ""
2073
  "movs{bl|x}\t{%h1, %0|%0, %h1}"
2074
  [(set_attr "type" "imovx")
2075
   (set_attr "mode" "SI")])
2076
 
2077
(define_insn "*movhi_extv_1"
2078
  [(set (match_operand:HI 0 "register_operand" "=R")
2079
        (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2080
                         (const_int 8)
2081
                         (const_int 8)))]
2082
  ""
2083
  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2084
  [(set_attr "type" "imovx")
2085
   (set_attr "mode" "SI")])
2086
 
2087
(define_insn "*movqi_extv_1"
2088
  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2089
        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2090
                         (const_int 8)
2091
                         (const_int 8)))]
2092
  "!TARGET_64BIT"
2093
{
2094
  switch (get_attr_type (insn))
2095
    {
2096
    case TYPE_IMOVX:
2097
      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2098
    default:
2099
      return "mov{b}\t{%h1, %0|%0, %h1}";
2100
    }
2101
}
2102
  [(set (attr "type")
2103
     (if_then_else (and (match_operand:QI 0 "register_operand" "")
2104
                        (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2105
                             (ne (symbol_ref "TARGET_MOVX")
2106
                                 (const_int 0))))
2107
        (const_string "imovx")
2108
        (const_string "imov")))
2109
   (set (attr "mode")
2110
     (if_then_else (eq_attr "type" "imovx")
2111
        (const_string "SI")
2112
        (const_string "QI")))])
2113
 
2114
(define_insn "*movqi_extv_1_rex64"
2115
  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2116
        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2117
                         (const_int 8)
2118
                         (const_int 8)))]
2119
  "TARGET_64BIT"
2120
{
2121
  switch (get_attr_type (insn))
2122
    {
2123
    case TYPE_IMOVX:
2124
      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2125
    default:
2126
      return "mov{b}\t{%h1, %0|%0, %h1}";
2127
    }
2128
}
2129
  [(set (attr "type")
2130
     (if_then_else (and (match_operand:QI 0 "register_operand" "")
2131
                        (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2132
                             (ne (symbol_ref "TARGET_MOVX")
2133
                                 (const_int 0))))
2134
        (const_string "imovx")
2135
        (const_string "imov")))
2136
   (set (attr "mode")
2137
     (if_then_else (eq_attr "type" "imovx")
2138
        (const_string "SI")
2139
        (const_string "QI")))])
2140
 
2141
;; Stores and loads of ax to arbitrary constant address.
2142
;; We fake an second form of instruction to force reload to load address
2143
;; into register when rax is not available
2144
(define_insn "*movabsqi_1_rex64"
2145
  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2146
        (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2147
  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2148
  "@
2149
   movabs{b}\t{%1, %P0|%P0, %1}
2150
   mov{b}\t{%1, %a0|%a0, %1}"
2151
  [(set_attr "type" "imov")
2152
   (set_attr "modrm" "0,*")
2153
   (set_attr "length_address" "8,0")
2154
   (set_attr "length_immediate" "0,*")
2155
   (set_attr "memory" "store")
2156
   (set_attr "mode" "QI")])
2157
 
2158
(define_insn "*movabsqi_2_rex64"
2159
  [(set (match_operand:QI 0 "register_operand" "=a,r")
2160
        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2161
  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2162
  "@
2163
   movabs{b}\t{%P1, %0|%0, %P1}
2164
   mov{b}\t{%a1, %0|%0, %a1}"
2165
  [(set_attr "type" "imov")
2166
   (set_attr "modrm" "0,*")
2167
   (set_attr "length_address" "8,0")
2168
   (set_attr "length_immediate" "0")
2169
   (set_attr "memory" "load")
2170
   (set_attr "mode" "QI")])
2171
 
2172
(define_insn "*movdi_extzv_1"
2173
  [(set (match_operand:DI 0 "register_operand" "=R")
2174
        (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2175
                         (const_int 8)
2176
                         (const_int 8)))]
2177
  "TARGET_64BIT"
2178
  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2179
  [(set_attr "type" "imovx")
2180
   (set_attr "mode" "SI")])
2181
 
2182
(define_insn "*movsi_extzv_1"
2183
  [(set (match_operand:SI 0 "register_operand" "=R")
2184
        (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2185
                         (const_int 8)
2186
                         (const_int 8)))]
2187
  ""
2188
  "movz{bl|x}\t{%h1, %0|%0, %h1}"
2189
  [(set_attr "type" "imovx")
2190
   (set_attr "mode" "SI")])
2191
 
2192
(define_insn "*movqi_extzv_2"
2193
  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2194
        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2195
                                    (const_int 8)
2196
                                    (const_int 8)) 0))]
2197
  "!TARGET_64BIT"
2198
{
2199
  switch (get_attr_type (insn))
2200
    {
2201
    case TYPE_IMOVX:
2202
      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2203
    default:
2204
      return "mov{b}\t{%h1, %0|%0, %h1}";
2205
    }
2206
}
2207
  [(set (attr "type")
2208
     (if_then_else (and (match_operand:QI 0 "register_operand" "")
2209
                        (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2210
                             (ne (symbol_ref "TARGET_MOVX")
2211
                                 (const_int 0))))
2212
        (const_string "imovx")
2213
        (const_string "imov")))
2214
   (set (attr "mode")
2215
     (if_then_else (eq_attr "type" "imovx")
2216
        (const_string "SI")
2217
        (const_string "QI")))])
2218
 
2219
(define_insn "*movqi_extzv_2_rex64"
2220
  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2221
        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2222
                                    (const_int 8)
2223
                                    (const_int 8)) 0))]
2224
  "TARGET_64BIT"
2225
{
2226
  switch (get_attr_type (insn))
2227
    {
2228
    case TYPE_IMOVX:
2229
      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2230
    default:
2231
      return "mov{b}\t{%h1, %0|%0, %h1}";
2232
    }
2233
}
2234
  [(set (attr "type")
2235
     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2236
                        (ne (symbol_ref "TARGET_MOVX")
2237
                            (const_int 0)))
2238
        (const_string "imovx")
2239
        (const_string "imov")))
2240
   (set (attr "mode")
2241
     (if_then_else (eq_attr "type" "imovx")
2242
        (const_string "SI")
2243
        (const_string "QI")))])
2244
 
2245
(define_insn "movsi_insv_1"
2246
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2247
                         (const_int 8)
2248
                         (const_int 8))
2249
        (match_operand:SI 1 "general_operand" "Qmn"))]
2250
  "!TARGET_64BIT"
2251
  "mov{b}\t{%b1, %h0|%h0, %b1}"
2252
  [(set_attr "type" "imov")
2253
   (set_attr "mode" "QI")])
2254
 
2255
(define_insn "*movsi_insv_1_rex64"
2256
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2257
                         (const_int 8)
2258
                         (const_int 8))
2259
        (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2260
  "TARGET_64BIT"
2261
  "mov{b}\t{%b1, %h0|%h0, %b1}"
2262
  [(set_attr "type" "imov")
2263
   (set_attr "mode" "QI")])
2264
 
2265
(define_insn "movdi_insv_1_rex64"
2266
  [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2267
                         (const_int 8)
2268
                         (const_int 8))
2269
        (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2270
  "TARGET_64BIT"
2271
  "mov{b}\t{%b1, %h0|%h0, %b1}"
2272
  [(set_attr "type" "imov")
2273
   (set_attr "mode" "QI")])
2274
 
2275
(define_insn "*movqi_insv_2"
2276
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2277
                         (const_int 8)
2278
                         (const_int 8))
2279
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2280
                     (const_int 8)))]
2281
  ""
2282
  "mov{b}\t{%h1, %h0|%h0, %h1}"
2283
  [(set_attr "type" "imov")
2284
   (set_attr "mode" "QI")])
2285
 
2286
(define_expand "movdi"
2287
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
2288
        (match_operand:DI 1 "general_operand" ""))]
2289
  ""
2290
  "ix86_expand_move (DImode, operands); DONE;")
2291
 
2292
(define_insn "*pushdi"
2293
  [(set (match_operand:DI 0 "push_operand" "=<")
2294
        (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2295
  "!TARGET_64BIT"
2296
  "#")
2297
 
2298
(define_insn "*pushdi2_rex64"
2299
  [(set (match_operand:DI 0 "push_operand" "=<,!<")
2300
        (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2301
  "TARGET_64BIT"
2302
  "@
2303
   push{q}\t%1
2304
   #"
2305
  [(set_attr "type" "push,multi")
2306
   (set_attr "mode" "DI")])
2307
 
2308
;; Convert impossible pushes of immediate to existing instructions.
2309
;; First try to get scratch register and go through it.  In case this
2310
;; fails, push sign extended lower part first and then overwrite
2311
;; upper part by 32bit move.
2312
(define_peephole2
2313
  [(match_scratch:DI 2 "r")
2314
   (set (match_operand:DI 0 "push_operand" "")
2315
        (match_operand:DI 1 "immediate_operand" ""))]
2316
  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2317
   && !x86_64_immediate_operand (operands[1], DImode)"
2318
  [(set (match_dup 2) (match_dup 1))
2319
   (set (match_dup 0) (match_dup 2))]
2320
  "")
2321
 
2322
;; We need to define this as both peepholer and splitter for case
2323
;; peephole2 pass is not run.
2324
;; "&& 1" is needed to keep it from matching the previous pattern.
2325
(define_peephole2
2326
  [(set (match_operand:DI 0 "push_operand" "")
2327
        (match_operand:DI 1 "immediate_operand" ""))]
2328
  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2329
   && !x86_64_immediate_operand (operands[1], DImode) && 1"
2330
  [(set (match_dup 0) (match_dup 1))
2331
   (set (match_dup 2) (match_dup 3))]
2332
  "split_di (&operands[1], 1, &operands[2], &operands[3]);
2333
   operands[1] = gen_lowpart (DImode, operands[2]);
2334
   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2335
                                                    GEN_INT (4)));
2336
  ")
2337
 
2338
(define_split
2339
  [(set (match_operand:DI 0 "push_operand" "")
2340
        (match_operand:DI 1 "immediate_operand" ""))]
2341
  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2342
                    ? epilogue_completed : reload_completed)
2343
   && !symbolic_operand (operands[1], DImode)
2344
   && !x86_64_immediate_operand (operands[1], DImode)"
2345
  [(set (match_dup 0) (match_dup 1))
2346
   (set (match_dup 2) (match_dup 3))]
2347
  "split_di (&operands[1], 1, &operands[2], &operands[3]);
2348
   operands[1] = gen_lowpart (DImode, operands[2]);
2349
   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2350
                                                    GEN_INT (4)));
2351
  ")
2352
 
2353
(define_insn "*pushdi2_prologue_rex64"
2354
  [(set (match_operand:DI 0 "push_operand" "=<")
2355
        (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2356
   (clobber (mem:BLK (scratch)))]
2357
  "TARGET_64BIT"
2358
  "push{q}\t%1"
2359
  [(set_attr "type" "push")
2360
   (set_attr "mode" "DI")])
2361
 
2362
(define_insn "*popdi1_epilogue_rex64"
2363
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2364
        (mem:DI (reg:DI SP_REG)))
2365
   (set (reg:DI SP_REG)
2366
        (plus:DI (reg:DI SP_REG) (const_int 8)))
2367
   (clobber (mem:BLK (scratch)))]
2368
  "TARGET_64BIT"
2369
  "pop{q}\t%0"
2370
  [(set_attr "type" "pop")
2371
   (set_attr "mode" "DI")])
2372
 
2373
(define_insn "popdi1"
2374
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2375
        (mem:DI (reg:DI SP_REG)))
2376
   (set (reg:DI SP_REG)
2377
        (plus:DI (reg:DI SP_REG) (const_int 8)))]
2378
  "TARGET_64BIT"
2379
  "pop{q}\t%0"
2380
  [(set_attr "type" "pop")
2381
   (set_attr "mode" "DI")])
2382
 
2383
(define_insn "*movdi_xor_rex64"
2384
  [(set (match_operand:DI 0 "register_operand" "=r")
2385
        (match_operand:DI 1 "const0_operand" ""))
2386
   (clobber (reg:CC FLAGS_REG))]
2387
  "TARGET_64BIT
2388
   && reload_completed"
2389
  "xor{l}\t%k0, %k0";
2390
  [(set_attr "type" "alu1")
2391
   (set_attr "mode" "SI")
2392
   (set_attr "length_immediate" "0")])
2393
 
2394
(define_insn "*movdi_or_rex64"
2395
  [(set (match_operand:DI 0 "register_operand" "=r")
2396
        (match_operand:DI 1 "const_int_operand" "i"))
2397
   (clobber (reg:CC FLAGS_REG))]
2398
  "TARGET_64BIT
2399
   && reload_completed
2400
   && operands[1] == constm1_rtx"
2401
{
2402
  operands[1] = constm1_rtx;
2403
  return "or{q}\t{%1, %0|%0, %1}";
2404
}
2405
  [(set_attr "type" "alu1")
2406
   (set_attr "mode" "DI")
2407
   (set_attr "length_immediate" "1")])
2408
 
2409
(define_insn "*movdi_2"
2410
  [(set (match_operand:DI 0 "nonimmediate_operand"
2411
                        "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2412
        (match_operand:DI 1 "general_operand"
2413
                        "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2414
  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2415
  "@
2416
   #
2417
   #
2418
   pxor\t%0, %0
2419
   movq\t{%1, %0|%0, %1}
2420
   movq\t{%1, %0|%0, %1}
2421
   %vpxor\t%0, %d0
2422
   %vmovq\t{%1, %0|%0, %1}
2423
   %vmovdqa\t{%1, %0|%0, %1}
2424
   %vmovq\t{%1, %0|%0, %1}
2425
   xorps\t%0, %0
2426
   movlps\t{%1, %0|%0, %1}
2427
   movaps\t{%1, %0|%0, %1}
2428
   movlps\t{%1, %0|%0, %1}"
2429
  [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2430
   (set (attr "prefix")
2431
     (if_then_else (eq_attr "alternative" "5,6,7,8")
2432
       (const_string "vex")
2433
       (const_string "orig")))
2434
   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2435
 
2436
(define_split
2437
  [(set (match_operand:DI 0 "push_operand" "")
2438
        (match_operand:DI 1 "general_operand" ""))]
2439
  "!TARGET_64BIT && reload_completed
2440
   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2441
  [(const_int 0)]
2442
  "ix86_split_long_move (operands); DONE;")
2443
 
2444
;; %%% This multiword shite has got to go.
2445
(define_split
2446
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
2447
        (match_operand:DI 1 "general_operand" ""))]
2448
  "!TARGET_64BIT && reload_completed
2449
   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2450
   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2451
  [(const_int 0)]
2452
  "ix86_split_long_move (operands); DONE;")
2453
 
2454
(define_insn "*movdi_1_rex64"
2455
  [(set (match_operand:DI 0 "nonimmediate_operand"
2456
          "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2457
        (match_operand:DI 1 "general_operand"
2458
          "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2459
  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2460
{
2461
  switch (get_attr_type (insn))
2462
    {
2463
    case TYPE_SSECVT:
2464
      if (SSE_REG_P (operands[0]))
2465
        return "movq2dq\t{%1, %0|%0, %1}";
2466
      else
2467
        return "movdq2q\t{%1, %0|%0, %1}";
2468
 
2469
    case TYPE_SSEMOV:
2470
      if (TARGET_AVX)
2471
        {
2472
          if (get_attr_mode (insn) == MODE_TI)
2473
            return "vmovdqa\t{%1, %0|%0, %1}";
2474
          else
2475
            return "vmovq\t{%1, %0|%0, %1}";
2476
        }
2477
 
2478
      if (get_attr_mode (insn) == MODE_TI)
2479
        return "movdqa\t{%1, %0|%0, %1}";
2480
      /* FALLTHRU */
2481
 
2482
    case TYPE_MMXMOV:
2483
      /* Moves from and into integer register is done using movd
2484
         opcode with REX prefix.  */
2485
      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2486
        return "movd\t{%1, %0|%0, %1}";
2487
      return "movq\t{%1, %0|%0, %1}";
2488
 
2489
    case TYPE_SSELOG1:
2490
      return "%vpxor\t%0, %d0";
2491
 
2492
    case TYPE_MMX:
2493
      return "pxor\t%0, %0";
2494
 
2495
    case TYPE_MULTI:
2496
      return "#";
2497
 
2498
    case TYPE_LEA:
2499
      return "lea{q}\t{%a1, %0|%0, %a1}";
2500
 
2501
    default:
2502
      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2503
      if (get_attr_mode (insn) == MODE_SI)
2504
        return "mov{l}\t{%k1, %k0|%k0, %k1}";
2505
      else if (which_alternative == 2)
2506
        return "movabs{q}\t{%1, %0|%0, %1}";
2507
      else
2508
        return "mov{q}\t{%1, %0|%0, %1}";
2509
    }
2510
}
2511
  [(set (attr "type")
2512
     (cond [(eq_attr "alternative" "5")
2513
              (const_string "mmx")
2514
            (eq_attr "alternative" "6,7,8,9,10")
2515
              (const_string "mmxmov")
2516
            (eq_attr "alternative" "11")
2517
              (const_string "sselog1")
2518
            (eq_attr "alternative" "12,13,14,15,16")
2519
              (const_string "ssemov")
2520
            (eq_attr "alternative" "17,18")
2521
              (const_string "ssecvt")
2522
            (eq_attr "alternative" "4")
2523
              (const_string "multi")
2524
            (match_operand:DI 1 "pic_32bit_operand" "")
2525
              (const_string "lea")
2526
           ]
2527
           (const_string "imov")))
2528
   (set (attr "modrm")
2529
     (if_then_else
2530
       (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2531
         (const_string "0")
2532
         (const_string "*")))
2533
   (set (attr "length_immediate")
2534
     (if_then_else
2535
       (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2536
         (const_string "8")
2537
         (const_string "*")))
2538
   (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2539
   (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2540
   (set (attr "prefix")
2541
     (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2542
       (const_string "maybe_vex")
2543
       (const_string "orig")))
2544
   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2545
 
2546
;; Stores and loads of ax to arbitrary constant address.
2547
;; We fake an second form of instruction to force reload to load address
2548
;; into register when rax is not available
2549
(define_insn "*movabsdi_1_rex64"
2550
  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2551
        (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2552
  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2553
  "@
2554
   movabs{q}\t{%1, %P0|%P0, %1}
2555
   mov{q}\t{%1, %a0|%a0, %1}"
2556
  [(set_attr "type" "imov")
2557
   (set_attr "modrm" "0,*")
2558
   (set_attr "length_address" "8,0")
2559
   (set_attr "length_immediate" "0,*")
2560
   (set_attr "memory" "store")
2561
   (set_attr "mode" "DI")])
2562
 
2563
(define_insn "*movabsdi_2_rex64"
2564
  [(set (match_operand:DI 0 "register_operand" "=a,r")
2565
        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2566
  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2567
  "@
2568
   movabs{q}\t{%P1, %0|%0, %P1}
2569
   mov{q}\t{%a1, %0|%0, %a1}"
2570
  [(set_attr "type" "imov")
2571
   (set_attr "modrm" "0,*")
2572
   (set_attr "length_address" "8,0")
2573
   (set_attr "length_immediate" "0")
2574
   (set_attr "memory" "load")
2575
   (set_attr "mode" "DI")])
2576
 
2577
;; Convert impossible stores of immediate to existing instructions.
2578
;; First try to get scratch register and go through it.  In case this
2579
;; fails, move by 32bit parts.
2580
(define_peephole2
2581
  [(match_scratch:DI 2 "r")
2582
   (set (match_operand:DI 0 "memory_operand" "")
2583
        (match_operand:DI 1 "immediate_operand" ""))]
2584
  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2585
   && !x86_64_immediate_operand (operands[1], DImode)"
2586
  [(set (match_dup 2) (match_dup 1))
2587
   (set (match_dup 0) (match_dup 2))]
2588
  "")
2589
 
2590
;; We need to define this as both peepholer and splitter for case
2591
;; peephole2 pass is not run.
2592
;; "&& 1" is needed to keep it from matching the previous pattern.
2593
(define_peephole2
2594
  [(set (match_operand:DI 0 "memory_operand" "")
2595
        (match_operand:DI 1 "immediate_operand" ""))]
2596
  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2597
   && !x86_64_immediate_operand (operands[1], DImode) && 1"
2598
  [(set (match_dup 2) (match_dup 3))
2599
   (set (match_dup 4) (match_dup 5))]
2600
  "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2601
 
2602
(define_split
2603
  [(set (match_operand:DI 0 "memory_operand" "")
2604
        (match_operand:DI 1 "immediate_operand" ""))]
2605
  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2606
                    ? epilogue_completed : reload_completed)
2607
   && !symbolic_operand (operands[1], DImode)
2608
   && !x86_64_immediate_operand (operands[1], DImode)"
2609
  [(set (match_dup 2) (match_dup 3))
2610
   (set (match_dup 4) (match_dup 5))]
2611
  "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2612
 
2613
(define_insn "*swapdi_rex64"
2614
  [(set (match_operand:DI 0 "register_operand" "+r")
2615
        (match_operand:DI 1 "register_operand" "+r"))
2616
   (set (match_dup 1)
2617
        (match_dup 0))]
2618
  "TARGET_64BIT"
2619
  "xchg{q}\t%1, %0"
2620
  [(set_attr "type" "imov")
2621
   (set_attr "mode" "DI")
2622
   (set_attr "pent_pair" "np")
2623
   (set_attr "athlon_decode" "vector")
2624
   (set_attr "amdfam10_decode" "double")])
2625
 
2626
(define_expand "movoi"
2627
  [(set (match_operand:OI 0 "nonimmediate_operand" "")
2628
        (match_operand:OI 1 "general_operand" ""))]
2629
  "TARGET_AVX"
2630
  "ix86_expand_move (OImode, operands); DONE;")
2631
 
2632
(define_insn "*movoi_internal"
2633
  [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2634
        (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2635
  "TARGET_AVX
2636
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2637
{
2638
  switch (which_alternative)
2639
    {
2640
    case 0:
2641
      return "vxorps\t%0, %0, %0";
2642
    case 1:
2643
    case 2:
2644
      if (misaligned_operand (operands[0], OImode)
2645
          || misaligned_operand (operands[1], OImode))
2646
        return "vmovdqu\t{%1, %0|%0, %1}";
2647
      else
2648
        return "vmovdqa\t{%1, %0|%0, %1}";
2649
    default:
2650
      gcc_unreachable ();
2651
    }
2652
}
2653
  [(set_attr "type" "sselog1,ssemov,ssemov")
2654
   (set_attr "prefix" "vex")
2655
   (set_attr "mode" "OI")])
2656
 
2657
(define_expand "movti"
2658
  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2659
        (match_operand:TI 1 "nonimmediate_operand" ""))]
2660
  "TARGET_SSE || TARGET_64BIT"
2661
{
2662
  if (TARGET_64BIT)
2663
    ix86_expand_move (TImode, operands);
2664
  else if (push_operand (operands[0], TImode))
2665
    ix86_expand_push (TImode, operands[1]);
2666
  else
2667
    ix86_expand_vector_move (TImode, operands);
2668
  DONE;
2669
})
2670
 
2671
(define_insn "*movti_internal"
2672
  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2673
        (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2674
  "TARGET_SSE && !TARGET_64BIT
2675
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2676
{
2677
  switch (which_alternative)
2678
    {
2679
    case 0:
2680
      if (get_attr_mode (insn) == MODE_V4SF)
2681
        return "%vxorps\t%0, %d0";
2682
      else
2683
        return "%vpxor\t%0, %d0";
2684
    case 1:
2685
    case 2:
2686
      /* TDmode values are passed as TImode on the stack.  Moving them
2687
         to stack may result in unaligned memory access.  */
2688
      if (misaligned_operand (operands[0], TImode)
2689
          || misaligned_operand (operands[1], TImode))
2690
        {
2691
          if (get_attr_mode (insn) == MODE_V4SF)
2692
            return "%vmovups\t{%1, %0|%0, %1}";
2693
         else
2694
           return "%vmovdqu\t{%1, %0|%0, %1}";
2695
        }
2696
      else
2697
        {
2698
          if (get_attr_mode (insn) == MODE_V4SF)
2699
            return "%vmovaps\t{%1, %0|%0, %1}";
2700
         else
2701
           return "%vmovdqa\t{%1, %0|%0, %1}";
2702
        }
2703
    default:
2704
      gcc_unreachable ();
2705
    }
2706
}
2707
  [(set_attr "type" "sselog1,ssemov,ssemov")
2708
   (set_attr "prefix" "maybe_vex")
2709
   (set (attr "mode")
2710
        (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2711
                    (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2712
                 (const_string "V4SF")
2713
               (and (eq_attr "alternative" "2")
2714
                    (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2715
                        (const_int 0)))
2716
                 (const_string "V4SF")]
2717
              (const_string "TI")))])
2718
 
2719
(define_insn "*movti_rex64"
2720
  [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2721
        (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2722
  "TARGET_64BIT
2723
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2724
{
2725
  switch (which_alternative)
2726
    {
2727
    case 0:
2728
    case 1:
2729
      return "#";
2730
    case 2:
2731
      if (get_attr_mode (insn) == MODE_V4SF)
2732
        return "%vxorps\t%0, %d0";
2733
      else
2734
        return "%vpxor\t%0, %d0";
2735
    case 3:
2736
    case 4:
2737
      /* TDmode values are passed as TImode on the stack.  Moving them
2738
         to stack may result in unaligned memory access.  */
2739
      if (misaligned_operand (operands[0], TImode)
2740
          || misaligned_operand (operands[1], TImode))
2741
        {
2742
          if (get_attr_mode (insn) == MODE_V4SF)
2743
            return "%vmovups\t{%1, %0|%0, %1}";
2744
         else
2745
           return "%vmovdqu\t{%1, %0|%0, %1}";
2746
        }
2747
      else
2748
        {
2749
          if (get_attr_mode (insn) == MODE_V4SF)
2750
            return "%vmovaps\t{%1, %0|%0, %1}";
2751
         else
2752
           return "%vmovdqa\t{%1, %0|%0, %1}";
2753
        }
2754
    default:
2755
      gcc_unreachable ();
2756
    }
2757
}
2758
  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2759
   (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2760
   (set (attr "mode")
2761
        (cond [(eq_attr "alternative" "2,3")
2762
                 (if_then_else
2763
                   (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2764
                       (const_int 0))
2765
                   (const_string "V4SF")
2766
                   (const_string "TI"))
2767
               (eq_attr "alternative" "4")
2768
                 (if_then_else
2769
                   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2770
                            (const_int 0))
2771
                        (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2772
                            (const_int 0)))
2773
                   (const_string "V4SF")
2774
                   (const_string "TI"))]
2775
               (const_string "DI")))])
2776
 
2777
(define_split
2778
  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2779
        (match_operand:TI 1 "general_operand" ""))]
2780
  "reload_completed && !SSE_REG_P (operands[0])
2781
   && !SSE_REG_P (operands[1])"
2782
  [(const_int 0)]
2783
  "ix86_split_long_move (operands); DONE;")
2784
 
2785
;; This expands to what emit_move_complex would generate if we didn't
2786
;; have a movti pattern.  Having this avoids problems with reload on
2787
;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2788
;; to have around all the time.
2789
(define_expand "movcdi"
2790
  [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2791
        (match_operand:CDI 1 "general_operand" ""))]
2792
  ""
2793
{
2794
  if (push_operand (operands[0], CDImode))
2795
    emit_move_complex_push (CDImode, operands[0], operands[1]);
2796
  else
2797
    emit_move_complex_parts (operands[0], operands[1]);
2798
  DONE;
2799
})
2800
 
2801
(define_expand "movsf"
2802
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
2803
        (match_operand:SF 1 "general_operand" ""))]
2804
  ""
2805
  "ix86_expand_move (SFmode, operands); DONE;")
2806
 
2807
(define_insn "*pushsf"
2808
  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2809
        (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2810
  "!TARGET_64BIT"
2811
{
2812
  /* Anything else should be already split before reg-stack.  */
2813
  gcc_assert (which_alternative == 1);
2814
  return "push{l}\t%1";
2815
}
2816
  [(set_attr "type" "multi,push,multi")
2817
   (set_attr "unit" "i387,*,*")
2818
   (set_attr "mode" "SF,SI,SF")])
2819
 
2820
(define_insn "*pushsf_rex64"
2821
  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2822
        (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2823
  "TARGET_64BIT"
2824
{
2825
  /* Anything else should be already split before reg-stack.  */
2826
  gcc_assert (which_alternative == 1);
2827
  return "push{q}\t%q1";
2828
}
2829
  [(set_attr "type" "multi,push,multi")
2830
   (set_attr "unit" "i387,*,*")
2831
   (set_attr "mode" "SF,DI,SF")])
2832
 
2833
(define_split
2834
  [(set (match_operand:SF 0 "push_operand" "")
2835
        (match_operand:SF 1 "memory_operand" ""))]
2836
  "reload_completed
2837
   && MEM_P (operands[1])
2838
   && (operands[2] = find_constant_src (insn))"
2839
  [(set (match_dup 0)
2840
        (match_dup 2))])
2841
 
2842
;; %%% Kill this when call knows how to work this out.
2843
(define_split
2844
  [(set (match_operand:SF 0 "push_operand" "")
2845
        (match_operand:SF 1 "any_fp_register_operand" ""))]
2846
  "!TARGET_64BIT"
2847
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2848
   (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2849
 
2850
(define_split
2851
  [(set (match_operand:SF 0 "push_operand" "")
2852
        (match_operand:SF 1 "any_fp_register_operand" ""))]
2853
  "TARGET_64BIT"
2854
  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2855
   (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2856
 
2857
(define_insn "*movsf_1"
2858
  [(set (match_operand:SF 0 "nonimmediate_operand"
2859
          "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2860
        (match_operand:SF 1 "general_operand"
2861
          "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2862
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2863
   && (reload_in_progress || reload_completed
2864
       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2865
       || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2866
           && standard_80387_constant_p (operands[1]))
2867
       || GET_CODE (operands[1]) != CONST_DOUBLE
2868
       || memory_operand (operands[0], SFmode))"
2869
{
2870
  switch (which_alternative)
2871
    {
2872
    case 0:
2873
    case 1:
2874
      return output_387_reg_move (insn, operands);
2875
 
2876
    case 2:
2877
      return standard_80387_constant_opcode (operands[1]);
2878
 
2879
    case 3:
2880
    case 4:
2881
      return "mov{l}\t{%1, %0|%0, %1}";
2882
    case 5:
2883
      if (get_attr_mode (insn) == MODE_TI)
2884
        return "%vpxor\t%0, %d0";
2885
      else
2886
        return "%vxorps\t%0, %d0";
2887
    case 6:
2888
      if (get_attr_mode (insn) == MODE_V4SF)
2889
        return "%vmovaps\t{%1, %0|%0, %1}";
2890
      else
2891
        return "%vmovss\t{%1, %d0|%d0, %1}";
2892
    case 7:
2893
      if (TARGET_AVX)
2894
        return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2895
                                   : "vmovss\t{%1, %0|%0, %1}";
2896
      else
2897
        return "movss\t{%1, %0|%0, %1}";
2898
    case 8:
2899
      return "%vmovss\t{%1, %0|%0, %1}";
2900
 
2901
    case 9: case 10: case 14: case 15:
2902
      return "movd\t{%1, %0|%0, %1}";
2903
    case 12: case 13:
2904
      return "%vmovd\t{%1, %0|%0, %1}";
2905
 
2906
    case 11:
2907
      return "movq\t{%1, %0|%0, %1}";
2908
 
2909
    default:
2910
      gcc_unreachable ();
2911
    }
2912
}
2913
  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2914
   (set (attr "prefix")
2915
     (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2916
       (const_string "maybe_vex")
2917
       (const_string "orig")))
2918
   (set (attr "mode")
2919
        (cond [(eq_attr "alternative" "3,4,9,10")
2920
                 (const_string "SI")
2921
               (eq_attr "alternative" "5")
2922
                 (if_then_else
2923
                   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2924
                                 (const_int 0))
2925
                             (ne (symbol_ref "TARGET_SSE2")
2926
                                 (const_int 0)))
2927
                        (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2928
                            (const_int 0)))
2929
                   (const_string "TI")
2930
                   (const_string "V4SF"))
2931
               /* For architectures resolving dependencies on
2932
                  whole SSE registers use APS move to break dependency
2933
                  chains, otherwise use short move to avoid extra work.
2934
 
2935
                  Do the same for architectures resolving dependencies on
2936
                  the parts.  While in DF mode it is better to always handle
2937
                  just register parts, the SF mode is different due to lack
2938
                  of instructions to load just part of the register.  It is
2939
                  better to maintain the whole registers in single format
2940
                  to avoid problems on using packed logical operations.  */
2941
               (eq_attr "alternative" "6")
2942
                 (if_then_else
2943
                   (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2944
                            (const_int 0))
2945
                        (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2946
                            (const_int 0)))
2947
                   (const_string "V4SF")
2948
                   (const_string "SF"))
2949
               (eq_attr "alternative" "11")
2950
                 (const_string "DI")]
2951
               (const_string "SF")))])
2952
 
2953
(define_insn "*swapsf"
2954
  [(set (match_operand:SF 0 "fp_register_operand" "+f")
2955
        (match_operand:SF 1 "fp_register_operand" "+f"))
2956
   (set (match_dup 1)
2957
        (match_dup 0))]
2958
  "reload_completed || TARGET_80387"
2959
{
2960
  if (STACK_TOP_P (operands[0]))
2961
    return "fxch\t%1";
2962
  else
2963
    return "fxch\t%0";
2964
}
2965
  [(set_attr "type" "fxch")
2966
   (set_attr "mode" "SF")])
2967
 
2968
(define_expand "movdf"
2969
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2970
        (match_operand:DF 1 "general_operand" ""))]
2971
  ""
2972
  "ix86_expand_move (DFmode, operands); DONE;")
2973
 
2974
;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2975
;; Size of pushdf using integer instructions is 2+2*memory operand size
2976
;; On the average, pushdf using integers can be still shorter.  Allow this
2977
;; pattern for optimize_size too.
2978
 
2979
(define_insn "*pushdf_nointeger"
2980
  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2981
        (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2982
  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2983
{
2984
  /* This insn should be already split before reg-stack.  */
2985
  gcc_unreachable ();
2986
}
2987
  [(set_attr "type" "multi")
2988
   (set_attr "unit" "i387,*,*,*")
2989
   (set_attr "mode" "DF,SI,SI,DF")])
2990
 
2991
(define_insn "*pushdf_integer"
2992
  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2993
        (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2994
  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2995
{
2996
  /* This insn should be already split before reg-stack.  */
2997
  gcc_unreachable ();
2998
}
2999
  [(set_attr "type" "multi")
3000
   (set_attr "unit" "i387,*,*")
3001
   (set_attr "mode" "DF,SI,DF")])
3002
 
3003
;; %%% Kill this when call knows how to work this out.
3004
(define_split
3005
  [(set (match_operand:DF 0 "push_operand" "")
3006
        (match_operand:DF 1 "any_fp_register_operand" ""))]
3007
  "reload_completed"
3008
  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3009
   (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3010
  "")
3011
 
3012
(define_split
3013
  [(set (match_operand:DF 0 "push_operand" "")
3014
        (match_operand:DF 1 "general_operand" ""))]
3015
  "reload_completed"
3016
  [(const_int 0)]
3017
  "ix86_split_long_move (operands); DONE;")
3018
 
3019
;; Moving is usually shorter when only FP registers are used. This separate
3020
;; movdf pattern avoids the use of integer registers for FP operations
3021
;; when optimizing for size.
3022
 
3023
(define_insn "*movdf_nointeger"
3024
  [(set (match_operand:DF 0 "nonimmediate_operand"
3025
                        "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3026
        (match_operand:DF 1 "general_operand"
3027
                        "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3028
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3029
   && ((optimize_function_for_size_p (cfun)
3030
       || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3031
   && (reload_in_progress || reload_completed
3032
       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3033
       || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3034
           && optimize_function_for_size_p (cfun)
3035
           && !memory_operand (operands[0], DFmode)
3036
           && standard_80387_constant_p (operands[1]))
3037
       || GET_CODE (operands[1]) != CONST_DOUBLE
3038
       || ((optimize_function_for_size_p (cfun)
3039
            || !TARGET_MEMORY_MISMATCH_STALL
3040
            || reload_in_progress || reload_completed)
3041
           && memory_operand (operands[0], DFmode)))"
3042
{
3043
  switch (which_alternative)
3044
    {
3045
    case 0:
3046
    case 1:
3047
      return output_387_reg_move (insn, operands);
3048
 
3049
    case 2:
3050
      return standard_80387_constant_opcode (operands[1]);
3051
 
3052
    case 3:
3053
    case 4:
3054
      return "#";
3055
    case 5:
3056
      switch (get_attr_mode (insn))
3057
        {
3058
        case MODE_V4SF:
3059
          return "%vxorps\t%0, %d0";
3060
        case MODE_V2DF:
3061
          return "%vxorpd\t%0, %d0";
3062
        case MODE_TI:
3063
          return "%vpxor\t%0, %d0";
3064
        default:
3065
          gcc_unreachable ();
3066
        }
3067
    case 6:
3068
    case 7:
3069
    case 8:
3070
      switch (get_attr_mode (insn))
3071
        {
3072
        case MODE_V4SF:
3073
          return "%vmovaps\t{%1, %0|%0, %1}";
3074
        case MODE_V2DF:
3075
          return "%vmovapd\t{%1, %0|%0, %1}";
3076
        case MODE_TI:
3077
          return "%vmovdqa\t{%1, %0|%0, %1}";
3078
        case MODE_DI:
3079
          return "%vmovq\t{%1, %0|%0, %1}";
3080
        case MODE_DF:
3081
          if (TARGET_AVX)
3082
            {
3083
              if (REG_P (operands[0]) && REG_P (operands[1]))
3084
                return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3085
              else
3086
                return "vmovsd\t{%1, %0|%0, %1}";
3087
            }
3088
          else
3089
            return "movsd\t{%1, %0|%0, %1}";
3090
        case MODE_V1DF:
3091
          if (TARGET_AVX)
3092
            {
3093
              if (REG_P (operands[0]))
3094
                return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3095
              else
3096
                return "vmovlpd\t{%1, %0|%0, %1}";
3097
            }
3098
          else
3099
            return "movlpd\t{%1, %0|%0, %1}";
3100
        case MODE_V2SF:
3101
          if (TARGET_AVX)
3102
            {
3103
              if (REG_P (operands[0]))
3104
                return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3105
              else
3106
                return "vmovlps\t{%1, %0|%0, %1}";
3107
            }
3108
          else
3109
            return "movlps\t{%1, %0|%0, %1}";
3110
        default:
3111
          gcc_unreachable ();
3112
        }
3113
 
3114
    default:
3115
      gcc_unreachable ();
3116
    }
3117
}
3118
  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3119
   (set (attr "prefix")
3120
     (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3121
       (const_string "orig")
3122
       (const_string "maybe_vex")))
3123
   (set (attr "prefix_data16")
3124
     (if_then_else (eq_attr "mode" "V1DF")
3125
       (const_string "1")
3126
       (const_string "*")))
3127
   (set (attr "mode")
3128
        (cond [(eq_attr "alternative" "0,1,2")
3129
                 (const_string "DF")
3130
               (eq_attr "alternative" "3,4")
3131
                 (const_string "SI")
3132
 
3133
               /* For SSE1, we have many fewer alternatives.  */
3134
               (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3135
                 (cond [(eq_attr "alternative" "5,6")
3136
                          (const_string "V4SF")
3137
                       ]
3138
                   (const_string "V2SF"))
3139
 
3140
               /* xorps is one byte shorter.  */
3141
               (eq_attr "alternative" "5")
3142
                 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3143
                            (const_int 0))
3144
                          (const_string "V4SF")
3145
                        (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3146
                            (const_int 0))
3147
                          (const_string "TI")
3148
                       ]
3149
                       (const_string "V2DF"))
3150
 
3151
               /* For architectures resolving dependencies on
3152
                  whole SSE registers use APD move to break dependency
3153
                  chains, otherwise use short move to avoid extra work.
3154
 
3155
                  movaps encodes one byte shorter.  */
3156
               (eq_attr "alternative" "6")
3157
                 (cond
3158
                   [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3159
                        (const_int 0))
3160
                      (const_string "V4SF")
3161
                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3162
                        (const_int 0))
3163
                      (const_string "V2DF")
3164
                   ]
3165
                   (const_string "DF"))
3166
               /* For architectures resolving dependencies on register
3167
                  parts we may avoid extra work to zero out upper part
3168
                  of register.  */
3169
               (eq_attr "alternative" "7")
3170
                 (if_then_else
3171
                   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3172
                       (const_int 0))
3173
                   (const_string "V1DF")
3174
                   (const_string "DF"))
3175
              ]
3176
              (const_string "DF")))])
3177
 
3178
(define_insn "*movdf_integer_rex64"
3179
  [(set (match_operand:DF 0 "nonimmediate_operand"
3180
                "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3181
        (match_operand:DF 1 "general_operand"
3182
                "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3183
  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3184
   && (reload_in_progress || reload_completed
3185
       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3186
       || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3187
           && optimize_function_for_size_p (cfun)
3188
           && standard_80387_constant_p (operands[1]))
3189
       || GET_CODE (operands[1]) != CONST_DOUBLE
3190
       || memory_operand (operands[0], DFmode))"
3191
{
3192
  switch (which_alternative)
3193
    {
3194
    case 0:
3195
    case 1:
3196
      return output_387_reg_move (insn, operands);
3197
 
3198
    case 2:
3199
      return standard_80387_constant_opcode (operands[1]);
3200
 
3201
    case 3:
3202
    case 4:
3203
      return "#";
3204
 
3205
    case 5:
3206
      switch (get_attr_mode (insn))
3207
        {
3208
        case MODE_V4SF:
3209
          return "%vxorps\t%0, %d0";
3210
        case MODE_V2DF:
3211
          return "%vxorpd\t%0, %d0";
3212
        case MODE_TI:
3213
          return "%vpxor\t%0, %d0";
3214
        default:
3215
          gcc_unreachable ();
3216
        }
3217
    case 6:
3218
    case 7:
3219
    case 8:
3220
      switch (get_attr_mode (insn))
3221
        {
3222
        case MODE_V4SF:
3223
          return "%vmovaps\t{%1, %0|%0, %1}";
3224
        case MODE_V2DF:
3225
          return "%vmovapd\t{%1, %0|%0, %1}";
3226
        case MODE_TI:
3227
          return "%vmovdqa\t{%1, %0|%0, %1}";
3228
        case MODE_DI:
3229
          return "%vmovq\t{%1, %0|%0, %1}";
3230
        case MODE_DF:
3231
          if (TARGET_AVX)
3232
            {
3233
              if (REG_P (operands[0]) && REG_P (operands[1]))
3234
                return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3235
              else
3236
                return "vmovsd\t{%1, %0|%0, %1}";
3237
            }
3238
          else
3239
            return "movsd\t{%1, %0|%0, %1}";
3240
        case MODE_V1DF:
3241
          return "%vmovlpd\t{%1, %d0|%d0, %1}";
3242
        case MODE_V2SF:
3243
          return "%vmovlps\t{%1, %d0|%d0, %1}";
3244
        default:
3245
          gcc_unreachable ();
3246
        }
3247
 
3248
    case 9:
3249
    case 10:
3250
    return "%vmovd\t{%1, %0|%0, %1}";
3251
 
3252
    default:
3253
      gcc_unreachable();
3254
    }
3255
}
3256
  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3257
   (set (attr "prefix")
3258
     (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3259
       (const_string "orig")
3260
       (const_string "maybe_vex")))
3261
   (set (attr "prefix_data16")
3262
     (if_then_else (eq_attr "mode" "V1DF")
3263
       (const_string "1")
3264
       (const_string "*")))
3265
   (set (attr "mode")
3266
        (cond [(eq_attr "alternative" "0,1,2")
3267
                 (const_string "DF")
3268
               (eq_attr "alternative" "3,4,9,10")
3269
                 (const_string "DI")
3270
 
3271
               /* For SSE1, we have many fewer alternatives.  */
3272
               (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3273
                 (cond [(eq_attr "alternative" "5,6")
3274
                          (const_string "V4SF")
3275
                       ]
3276
                   (const_string "V2SF"))
3277
 
3278
               /* xorps is one byte shorter.  */
3279
               (eq_attr "alternative" "5")
3280
                 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3281
                            (const_int 0))
3282
                          (const_string "V4SF")
3283
                        (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3284
                            (const_int 0))
3285
                          (const_string "TI")
3286
                       ]
3287
                       (const_string "V2DF"))
3288
 
3289
               /* For architectures resolving dependencies on
3290
                  whole SSE registers use APD move to break dependency
3291
                  chains, otherwise use short move to avoid extra work.
3292
 
3293
                  movaps encodes one byte shorter.  */
3294
               (eq_attr "alternative" "6")
3295
                 (cond
3296
                   [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3297
                        (const_int 0))
3298
                      (const_string "V4SF")
3299
                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3300
                        (const_int 0))
3301
                      (const_string "V2DF")
3302
                   ]
3303
                   (const_string "DF"))
3304
               /* For architectures resolving dependencies on register
3305
                  parts we may avoid extra work to zero out upper part
3306
                  of register.  */
3307
               (eq_attr "alternative" "7")
3308
                 (if_then_else
3309
                   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3310
                       (const_int 0))
3311
                   (const_string "V1DF")
3312
                   (const_string "DF"))
3313
              ]
3314
              (const_string "DF")))])
3315
 
3316
(define_insn "*movdf_integer"
3317
  [(set (match_operand:DF 0 "nonimmediate_operand"
3318
                "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3319
        (match_operand:DF 1 "general_operand"
3320
                "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3321
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3322
   && optimize_function_for_speed_p (cfun)
3323
   && TARGET_INTEGER_DFMODE_MOVES
3324
   && (reload_in_progress || reload_completed
3325
       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3326
       || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3327
           && optimize_function_for_size_p (cfun)
3328
           && standard_80387_constant_p (operands[1]))
3329
       || GET_CODE (operands[1]) != CONST_DOUBLE
3330
       || memory_operand (operands[0], DFmode))"
3331
{
3332
  switch (which_alternative)
3333
    {
3334
    case 0:
3335
    case 1:
3336
      return output_387_reg_move (insn, operands);
3337
 
3338
    case 2:
3339
      return standard_80387_constant_opcode (operands[1]);
3340
 
3341
    case 3:
3342
    case 4:
3343
      return "#";
3344
 
3345
    case 5:
3346
      switch (get_attr_mode (insn))
3347
        {
3348
        case MODE_V4SF:
3349
          return "xorps\t%0, %0";
3350
        case MODE_V2DF:
3351
          return "xorpd\t%0, %0";
3352
        case MODE_TI:
3353
          return "pxor\t%0, %0";
3354
        default:
3355
          gcc_unreachable ();
3356
        }
3357
    case 6:
3358
    case 7:
3359
    case 8:
3360
      switch (get_attr_mode (insn))
3361
        {
3362
        case MODE_V4SF:
3363
          return "movaps\t{%1, %0|%0, %1}";
3364
        case MODE_V2DF:
3365
          return "movapd\t{%1, %0|%0, %1}";
3366
        case MODE_TI:
3367
          return "movdqa\t{%1, %0|%0, %1}";
3368
        case MODE_DI:
3369
          return "movq\t{%1, %0|%0, %1}";
3370
        case MODE_DF:
3371
          return "movsd\t{%1, %0|%0, %1}";
3372
        case MODE_V1DF:
3373
          return "movlpd\t{%1, %0|%0, %1}";
3374
        case MODE_V2SF:
3375
          return "movlps\t{%1, %0|%0, %1}";
3376
        default:
3377
          gcc_unreachable ();
3378
        }
3379
 
3380
    default:
3381
      gcc_unreachable();
3382
    }
3383
}
3384
  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3385
   (set (attr "prefix_data16")
3386
     (if_then_else (eq_attr "mode" "V1DF")
3387
       (const_string "1")
3388
       (const_string "*")))
3389
   (set (attr "mode")
3390
        (cond [(eq_attr "alternative" "0,1,2")
3391
                 (const_string "DF")
3392
               (eq_attr "alternative" "3,4")
3393
                 (const_string "SI")
3394
 
3395
               /* For SSE1, we have many fewer alternatives.  */
3396
               (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3397
                 (cond [(eq_attr "alternative" "5,6")
3398
                          (const_string "V4SF")
3399
                       ]
3400
                   (const_string "V2SF"))
3401
 
3402
               /* xorps is one byte shorter.  */
3403
               (eq_attr "alternative" "5")
3404
                 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3405
                            (const_int 0))
3406
                          (const_string "V4SF")
3407
                        (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3408
                            (const_int 0))
3409
                          (const_string "TI")
3410
                       ]
3411
                       (const_string "V2DF"))
3412
 
3413
               /* For architectures resolving dependencies on
3414
                  whole SSE registers use APD move to break dependency
3415
                  chains, otherwise use short move to avoid extra work.
3416
 
3417
                  movaps encodes one byte shorter.  */
3418
               (eq_attr "alternative" "6")
3419
                 (cond
3420
                   [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3421
                        (const_int 0))
3422
                      (const_string "V4SF")
3423
                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3424
                        (const_int 0))
3425
                      (const_string "V2DF")
3426
                   ]
3427
                   (const_string "DF"))
3428
               /* For architectures resolving dependencies on register
3429
                  parts we may avoid extra work to zero out upper part
3430
                  of register.  */
3431
               (eq_attr "alternative" "7")
3432
                 (if_then_else
3433
                   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3434
                       (const_int 0))
3435
                   (const_string "V1DF")
3436
                   (const_string "DF"))
3437
              ]
3438
              (const_string "DF")))])
3439
 
3440
(define_split
3441
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3442
        (match_operand:DF 1 "general_operand" ""))]
3443
  "reload_completed
3444
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3445
   && ! (ANY_FP_REG_P (operands[0]) ||
3446
         (GET_CODE (operands[0]) == SUBREG
3447
          && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3448
   && ! (ANY_FP_REG_P (operands[1]) ||
3449
         (GET_CODE (operands[1]) == SUBREG
3450
          && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3451
  [(const_int 0)]
3452
  "ix86_split_long_move (operands); DONE;")
3453
 
3454
(define_insn "*swapdf"
3455
  [(set (match_operand:DF 0 "fp_register_operand" "+f")
3456
        (match_operand:DF 1 "fp_register_operand" "+f"))
3457
   (set (match_dup 1)
3458
        (match_dup 0))]
3459
  "reload_completed || TARGET_80387"
3460
{
3461
  if (STACK_TOP_P (operands[0]))
3462
    return "fxch\t%1";
3463
  else
3464
    return "fxch\t%0";
3465
}
3466
  [(set_attr "type" "fxch")
3467
   (set_attr "mode" "DF")])
3468
 
3469
(define_expand "movxf"
3470
  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3471
        (match_operand:XF 1 "general_operand" ""))]
3472
  ""
3473
  "ix86_expand_move (XFmode, operands); DONE;")
3474
 
3475
;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3476
;; Size of pushdf using integer instructions is 3+3*memory operand size
3477
;; Pushing using integer instructions is longer except for constants
3478
;; and direct memory references.
3479
;; (assuming that any given constant is pushed only once, but this ought to be
3480
;;  handled elsewhere).
3481
 
3482
(define_insn "*pushxf_nointeger"
3483
  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3484
        (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3485
  "optimize_function_for_size_p (cfun)"
3486
{
3487
  /* This insn should be already split before reg-stack.  */
3488
  gcc_unreachable ();
3489
}
3490
  [(set_attr "type" "multi")
3491
   (set_attr "unit" "i387,*,*")
3492
   (set_attr "mode" "XF,SI,SI")])
3493
 
3494
(define_insn "*pushxf_integer"
3495
  [(set (match_operand:XF 0 "push_operand" "=<,<")
3496
        (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3497
  "optimize_function_for_speed_p (cfun)"
3498
{
3499
  /* This insn should be already split before reg-stack.  */
3500
  gcc_unreachable ();
3501
}
3502
  [(set_attr "type" "multi")
3503
   (set_attr "unit" "i387,*")
3504
   (set_attr "mode" "XF,SI")])
3505
 
3506
(define_split
3507
  [(set (match_operand 0 "push_operand" "")
3508
        (match_operand 1 "general_operand" ""))]
3509
  "reload_completed
3510
   && (GET_MODE (operands[0]) == XFmode
3511
       || GET_MODE (operands[0]) == DFmode)
3512
   && !ANY_FP_REG_P (operands[1])"
3513
  [(const_int 0)]
3514
  "ix86_split_long_move (operands); DONE;")
3515
 
3516
(define_split
3517
  [(set (match_operand:XF 0 "push_operand" "")
3518
        (match_operand:XF 1 "any_fp_register_operand" ""))]
3519
  ""
3520
  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3521
   (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3522
  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3523
 
3524
;; Do not use integer registers when optimizing for size
3525
(define_insn "*movxf_nointeger"
3526
  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3527
        (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3528
  "optimize_function_for_size_p (cfun)
3529
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3530
   && (reload_in_progress || reload_completed
3531
       || standard_80387_constant_p (operands[1])
3532
       || GET_CODE (operands[1]) != CONST_DOUBLE
3533
       || memory_operand (operands[0], XFmode))"
3534
{
3535
  switch (which_alternative)
3536
    {
3537
    case 0:
3538
    case 1:
3539
      return output_387_reg_move (insn, operands);
3540
 
3541
    case 2:
3542
      return standard_80387_constant_opcode (operands[1]);
3543
 
3544
    case 3: case 4:
3545
      return "#";
3546
    default:
3547
      gcc_unreachable ();
3548
    }
3549
}
3550
  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3551
   (set_attr "mode" "XF,XF,XF,SI,SI")])
3552
 
3553
(define_insn "*movxf_integer"
3554
  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3555
        (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3556
  "optimize_function_for_speed_p (cfun)
3557
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3558
   && (reload_in_progress || reload_completed
3559
       || GET_CODE (operands[1]) != CONST_DOUBLE
3560
       || memory_operand (operands[0], XFmode))"
3561
{
3562
  switch (which_alternative)
3563
    {
3564
    case 0:
3565
    case 1:
3566
      return output_387_reg_move (insn, operands);
3567
 
3568
    case 2:
3569
      return standard_80387_constant_opcode (operands[1]);
3570
 
3571
    case 3: case 4:
3572
      return "#";
3573
 
3574
    default:
3575
      gcc_unreachable ();
3576
    }
3577
}
3578
  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3579
   (set_attr "mode" "XF,XF,XF,SI,SI")])
3580
 
3581
(define_expand "movtf"
3582
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
3583
        (match_operand:TF 1 "nonimmediate_operand" ""))]
3584
  "TARGET_SSE2"
3585
{
3586
  ix86_expand_move (TFmode, operands);
3587
  DONE;
3588
})
3589
 
3590
(define_insn "*movtf_internal"
3591
  [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3592
        (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3593
  "TARGET_SSE2
3594
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3595
{
3596
  switch (which_alternative)
3597
    {
3598
    case 0:
3599
    case 1:
3600
      if (get_attr_mode (insn) == MODE_V4SF)
3601
        return "%vmovaps\t{%1, %0|%0, %1}";
3602
      else
3603
        return "%vmovdqa\t{%1, %0|%0, %1}";
3604
    case 2:
3605
      if (get_attr_mode (insn) == MODE_V4SF)
3606
        return "%vxorps\t%0, %d0";
3607
      else
3608
        return "%vpxor\t%0, %d0";
3609
    case 3:
3610
    case 4:
3611
        return "#";
3612
    default:
3613
      gcc_unreachable ();
3614
    }
3615
}
3616
  [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3617
   (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3618
   (set (attr "mode")
3619
        (cond [(eq_attr "alternative" "0,2")
3620
                 (if_then_else
3621
                   (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3622
                       (const_int 0))
3623
                   (const_string "V4SF")
3624
                   (const_string "TI"))
3625
               (eq_attr "alternative" "1")
3626
                 (if_then_else
3627
                   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3628
                            (const_int 0))
3629
                        (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3630
                            (const_int 0)))
3631
                   (const_string "V4SF")
3632
                   (const_string "TI"))]
3633
               (const_string "DI")))])
3634
 
3635
(define_insn "*pushtf_sse"
3636
  [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3637
        (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3638
  "TARGET_SSE2"
3639
{
3640
  /* This insn should be already split before reg-stack.  */
3641
  gcc_unreachable ();
3642
}
3643
  [(set_attr "type" "multi")
3644
   (set_attr "unit" "sse,*,*")
3645
   (set_attr "mode" "TF,SI,SI")])
3646
 
3647
(define_split
3648
  [(set (match_operand:TF 0 "push_operand" "")
3649
        (match_operand:TF 1 "general_operand" ""))]
3650
  "TARGET_SSE2 && reload_completed
3651
   && !SSE_REG_P (operands[1])"
3652
  [(const_int 0)]
3653
  "ix86_split_long_move (operands); DONE;")
3654
 
3655
(define_split
3656
  [(set (match_operand:TF 0 "push_operand" "")
3657
        (match_operand:TF 1 "any_fp_register_operand" ""))]
3658
  "TARGET_SSE2"
3659
  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3660
   (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3661
  "")
3662
 
3663
(define_split
3664
  [(set (match_operand 0 "nonimmediate_operand" "")
3665
        (match_operand 1 "general_operand" ""))]
3666
  "reload_completed
3667
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3668
   && GET_MODE (operands[0]) == XFmode
3669
   && ! (ANY_FP_REG_P (operands[0]) ||
3670
         (GET_CODE (operands[0]) == SUBREG
3671
          && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3672
   && ! (ANY_FP_REG_P (operands[1]) ||
3673
         (GET_CODE (operands[1]) == SUBREG
3674
          && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3675
  [(const_int 0)]
3676
  "ix86_split_long_move (operands); DONE;")
3677
 
3678
(define_split
3679
  [(set (match_operand 0 "register_operand" "")
3680
        (match_operand 1 "memory_operand" ""))]
3681
  "reload_completed
3682
   && MEM_P (operands[1])
3683
   && (GET_MODE (operands[0]) == TFmode
3684
       || GET_MODE (operands[0]) == XFmode
3685
       || GET_MODE (operands[0]) == SFmode
3686
       || GET_MODE (operands[0]) == DFmode)
3687
   && (operands[2] = find_constant_src (insn))"
3688
  [(set (match_dup 0) (match_dup 2))]
3689
{
3690
  rtx c = operands[2];
3691
  rtx r = operands[0];
3692
 
3693
  if (GET_CODE (r) == SUBREG)
3694
    r = SUBREG_REG (r);
3695
 
3696
  if (SSE_REG_P (r))
3697
    {
3698
      if (!standard_sse_constant_p (c))
3699
        FAIL;
3700
    }
3701
  else if (FP_REG_P (r))
3702
    {
3703
      if (!standard_80387_constant_p (c))
3704
        FAIL;
3705
    }
3706
  else if (MMX_REG_P (r))
3707
    FAIL;
3708
})
3709
 
3710
(define_split
3711
  [(set (match_operand 0 "register_operand" "")
3712
        (float_extend (match_operand 1 "memory_operand" "")))]
3713
  "reload_completed
3714
   && MEM_P (operands[1])
3715
   && (GET_MODE (operands[0]) == TFmode
3716
       || GET_MODE (operands[0]) == XFmode
3717
       || GET_MODE (operands[0]) == SFmode
3718
       || GET_MODE (operands[0]) == DFmode)
3719
   && (operands[2] = find_constant_src (insn))"
3720
  [(set (match_dup 0) (match_dup 2))]
3721
{
3722
  rtx c = operands[2];
3723
  rtx r = operands[0];
3724
 
3725
  if (GET_CODE (r) == SUBREG)
3726
    r = SUBREG_REG (r);
3727
 
3728
  if (SSE_REG_P (r))
3729
    {
3730
      if (!standard_sse_constant_p (c))
3731
        FAIL;
3732
    }
3733
  else if (FP_REG_P (r))
3734
    {
3735
      if (!standard_80387_constant_p (c))
3736
        FAIL;
3737
    }
3738
  else if (MMX_REG_P (r))
3739
    FAIL;
3740
})
3741
 
3742
(define_insn "swapxf"
3743
  [(set (match_operand:XF 0 "register_operand" "+f")
3744
        (match_operand:XF 1 "register_operand" "+f"))
3745
   (set (match_dup 1)
3746
        (match_dup 0))]
3747
  "TARGET_80387"
3748
{
3749
  if (STACK_TOP_P (operands[0]))
3750
    return "fxch\t%1";
3751
  else
3752
    return "fxch\t%0";
3753
}
3754
  [(set_attr "type" "fxch")
3755
   (set_attr "mode" "XF")])
3756
 
3757
;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3758
(define_split
3759
  [(set (match_operand:X87MODEF 0 "register_operand" "")
3760
        (match_operand:X87MODEF 1 "immediate_operand" ""))]
3761
  "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3762
   && (standard_80387_constant_p (operands[1]) == 8
3763
       || standard_80387_constant_p (operands[1]) == 9)"
3764
  [(set (match_dup 0)(match_dup 1))
3765
   (set (match_dup 0)
3766
        (neg:X87MODEF (match_dup 0)))]
3767
{
3768
  REAL_VALUE_TYPE r;
3769
 
3770
  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3771
  if (real_isnegzero (&r))
3772
    operands[1] = CONST0_RTX (mode);
3773
  else
3774
    operands[1] = CONST1_RTX (mode);
3775
})
3776
 
3777
(define_split
3778
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
3779
        (match_operand:TF 1 "general_operand" ""))]
3780
  "reload_completed
3781
   && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3782
  [(const_int 0)]
3783
  "ix86_split_long_move (operands); DONE;")
3784
 
3785
;; Zero extension instructions
3786
 
3787
(define_expand "zero_extendhisi2"
3788
  [(set (match_operand:SI 0 "register_operand" "")
3789
     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3790
  ""
3791
{
3792
  if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3793
    {
3794
      operands[1] = force_reg (HImode, operands[1]);
3795
      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3796
      DONE;
3797
    }
3798
})
3799
 
3800
(define_insn "zero_extendhisi2_and"
3801
  [(set (match_operand:SI 0 "register_operand" "=r")
3802
     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3803
   (clobber (reg:CC FLAGS_REG))]
3804
  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3805
  "#"
3806
  [(set_attr "type" "alu1")
3807
   (set_attr "mode" "SI")])
3808
 
3809
(define_split
3810
  [(set (match_operand:SI 0 "register_operand" "")
3811
        (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3812
   (clobber (reg:CC FLAGS_REG))]
3813
  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3814
   && optimize_function_for_speed_p (cfun)"
3815
  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3816
              (clobber (reg:CC FLAGS_REG))])]
3817
  "")
3818
 
3819
(define_insn "*zero_extendhisi2_movzwl"
3820
  [(set (match_operand:SI 0 "register_operand" "=r")
3821
     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3822
  "!TARGET_ZERO_EXTEND_WITH_AND
3823
   || optimize_function_for_size_p (cfun)"
3824
  "movz{wl|x}\t{%1, %0|%0, %1}"
3825
  [(set_attr "type" "imovx")
3826
   (set_attr "mode" "SI")])
3827
 
3828
(define_expand "zero_extendqihi2"
3829
  [(parallel
3830
    [(set (match_operand:HI 0 "register_operand" "")
3831
       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3832
     (clobber (reg:CC FLAGS_REG))])]
3833
  ""
3834
  "")
3835
 
3836
(define_insn "*zero_extendqihi2_and"
3837
  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3838
     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3839
   (clobber (reg:CC FLAGS_REG))]
3840
  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3841
  "#"
3842
  [(set_attr "type" "alu1")
3843
   (set_attr "mode" "HI")])
3844
 
3845
(define_insn "*zero_extendqihi2_movzbw_and"
3846
  [(set (match_operand:HI 0 "register_operand" "=r,r")
3847
     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3848
   (clobber (reg:CC FLAGS_REG))]
3849
  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3850
  "#"
3851
  [(set_attr "type" "imovx,alu1")
3852
   (set_attr "mode" "HI")])
3853
 
3854
; zero extend to SImode here to avoid partial register stalls
3855
(define_insn "*zero_extendqihi2_movzbl"
3856
  [(set (match_operand:HI 0 "register_operand" "=r")
3857
     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3858
  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3859
   && reload_completed"
3860
  "movz{bl|x}\t{%1, %k0|%k0, %1}"
3861
  [(set_attr "type" "imovx")
3862
   (set_attr "mode" "SI")])
3863
 
3864
;; For the movzbw case strip only the clobber
3865
(define_split
3866
  [(set (match_operand:HI 0 "register_operand" "")
3867
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3868
   (clobber (reg:CC FLAGS_REG))]
3869
  "reload_completed
3870
   && (!TARGET_ZERO_EXTEND_WITH_AND
3871
       || optimize_function_for_size_p (cfun))
3872
   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3873
  [(set (match_operand:HI 0 "register_operand" "")
3874
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3875
 
3876
;; When source and destination does not overlap, clear destination
3877
;; first and then do the movb
3878
(define_split
3879
  [(set (match_operand:HI 0 "register_operand" "")
3880
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3881
   (clobber (reg:CC FLAGS_REG))]
3882
  "reload_completed
3883
   && ANY_QI_REG_P (operands[0])
3884
   && (TARGET_ZERO_EXTEND_WITH_AND
3885
       && optimize_function_for_speed_p (cfun))
3886
   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3887
  [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3888
{
3889
  operands[2] = gen_lowpart (QImode, operands[0]);
3890
  ix86_expand_clear (operands[0]);
3891
})
3892
 
3893
;; Rest is handled by single and.
3894
(define_split
3895
  [(set (match_operand:HI 0 "register_operand" "")
3896
        (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3897
   (clobber (reg:CC FLAGS_REG))]
3898
  "reload_completed
3899
   && true_regnum (operands[0]) == true_regnum (operands[1])"
3900
  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3901
              (clobber (reg:CC FLAGS_REG))])]
3902
  "")
3903
 
3904
(define_expand "zero_extendqisi2"
3905
  [(parallel
3906
    [(set (match_operand:SI 0 "register_operand" "")
3907
       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3908
     (clobber (reg:CC FLAGS_REG))])]
3909
  ""
3910
  "")
3911
 
3912
(define_insn "*zero_extendqisi2_and"
3913
  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3914
     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3915
   (clobber (reg:CC FLAGS_REG))]
3916
  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3917
  "#"
3918
  [(set_attr "type" "alu1")
3919
   (set_attr "mode" "SI")])
3920
 
3921
(define_insn "*zero_extendqisi2_movzbl_and"
3922
  [(set (match_operand:SI 0 "register_operand" "=r,r")
3923
     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3924
   (clobber (reg:CC FLAGS_REG))]
3925
  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3926
  "#"
3927
  [(set_attr "type" "imovx,alu1")
3928
   (set_attr "mode" "SI")])
3929
 
3930
(define_insn "*zero_extendqisi2_movzbl"
3931
  [(set (match_operand:SI 0 "register_operand" "=r")
3932
     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3933
  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3934
   && reload_completed"
3935
  "movz{bl|x}\t{%1, %0|%0, %1}"
3936
  [(set_attr "type" "imovx")
3937
   (set_attr "mode" "SI")])
3938
 
3939
;; For the movzbl case strip only the clobber
3940
(define_split
3941
  [(set (match_operand:SI 0 "register_operand" "")
3942
        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3943
   (clobber (reg:CC FLAGS_REG))]
3944
  "reload_completed
3945
   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3946
   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3947
  [(set (match_dup 0)
3948
        (zero_extend:SI (match_dup 1)))])
3949
 
3950
;; When source and destination does not overlap, clear destination
3951
;; first and then do the movb
3952
(define_split
3953
  [(set (match_operand:SI 0 "register_operand" "")
3954
        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3955
   (clobber (reg:CC FLAGS_REG))]
3956
  "reload_completed
3957
   && ANY_QI_REG_P (operands[0])
3958
   && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3959
   && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3960
   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3961
  [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3962
{
3963
  operands[2] = gen_lowpart (QImode, operands[0]);
3964
  ix86_expand_clear (operands[0]);
3965
})
3966
 
3967
;; Rest is handled by single and.
3968
(define_split
3969
  [(set (match_operand:SI 0 "register_operand" "")
3970
        (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3971
   (clobber (reg:CC FLAGS_REG))]
3972
  "reload_completed
3973
   && true_regnum (operands[0]) == true_regnum (operands[1])"
3974
  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3975
              (clobber (reg:CC FLAGS_REG))])]
3976
  "")
3977
 
3978
;; %%% Kill me once multi-word ops are sane.
3979
(define_expand "zero_extendsidi2"
3980
  [(set (match_operand:DI 0 "register_operand" "")
3981
     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3982
  ""
3983
{
3984
  if (!TARGET_64BIT)
3985
    {
3986
      emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3987
      DONE;
3988
    }
3989
})
3990
 
3991
(define_insn "zero_extendsidi2_32"
3992
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3993
        (zero_extend:DI
3994
         (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3995
   (clobber (reg:CC FLAGS_REG))]
3996
  "!TARGET_64BIT"
3997
  "@
3998
   #
3999
   #
4000
   #
4001
   movd\t{%1, %0|%0, %1}
4002
   movd\t{%1, %0|%0, %1}
4003
   %vmovd\t{%1, %0|%0, %1}
4004
   %vmovd\t{%1, %0|%0, %1}"
4005
  [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4006
   (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4007
   (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4008
 
4009
(define_insn "zero_extendsidi2_rex64"
4010
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4011
     (zero_extend:DI
4012
       (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4013
  "TARGET_64BIT"
4014
  "@
4015
   mov\t{%k1, %k0|%k0, %k1}
4016
   #
4017
   movd\t{%1, %0|%0, %1}
4018
   movd\t{%1, %0|%0, %1}
4019
   %vmovd\t{%1, %0|%0, %1}
4020
   %vmovd\t{%1, %0|%0, %1}"
4021
  [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4022
   (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4023
   (set_attr "prefix_0f" "0,*,*,*,*,*")
4024
   (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4025
 
4026
(define_split
4027
  [(set (match_operand:DI 0 "memory_operand" "")
4028
     (zero_extend:DI (match_dup 0)))]
4029
  "TARGET_64BIT"
4030
  [(set (match_dup 4) (const_int 0))]
4031
  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4032
 
4033
(define_split
4034
  [(set (match_operand:DI 0 "register_operand" "")
4035
        (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4036
   (clobber (reg:CC FLAGS_REG))]
4037
  "!TARGET_64BIT && reload_completed
4038
   && true_regnum (operands[0]) == true_regnum (operands[1])"
4039
  [(set (match_dup 4) (const_int 0))]
4040
  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4041
 
4042
(define_split
4043
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4044
        (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4045
   (clobber (reg:CC FLAGS_REG))]
4046
  "!TARGET_64BIT && reload_completed
4047
   && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4048
  [(set (match_dup 3) (match_dup 1))
4049
   (set (match_dup 4) (const_int 0))]
4050
  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4051
 
4052
(define_insn "zero_extendhidi2"
4053
  [(set (match_operand:DI 0 "register_operand" "=r")
4054
     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4055
  "TARGET_64BIT"
4056
  "movz{wl|x}\t{%1, %k0|%k0, %1}"
4057
  [(set_attr "type" "imovx")
4058
   (set_attr "mode" "SI")])
4059
 
4060
(define_insn "zero_extendqidi2"
4061
  [(set (match_operand:DI 0 "register_operand" "=r")
4062
     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4063
  "TARGET_64BIT"
4064
  "movz{bl|x}\t{%1, %k0|%k0, %1}"
4065
  [(set_attr "type" "imovx")
4066
   (set_attr "mode" "SI")])
4067
 
4068
;; Sign extension instructions
4069
 
4070
(define_expand "extendsidi2"
4071
  [(parallel [(set (match_operand:DI 0 "register_operand" "")
4072
                   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4073
              (clobber (reg:CC FLAGS_REG))
4074
              (clobber (match_scratch:SI 2 ""))])]
4075
  ""
4076
{
4077
  if (TARGET_64BIT)
4078
    {
4079
      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4080
      DONE;
4081
    }
4082
})
4083
 
4084
(define_insn "*extendsidi2_1"
4085
  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4086
        (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4087
   (clobber (reg:CC FLAGS_REG))
4088
   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4089
  "!TARGET_64BIT"
4090
  "#")
4091
 
4092
(define_insn "extendsidi2_rex64"
4093
  [(set (match_operand:DI 0 "register_operand" "=*a,r")
4094
        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4095
  "TARGET_64BIT"
4096
  "@
4097
   {cltq|cdqe}
4098
   movs{lq|x}\t{%1, %0|%0, %1}"
4099
  [(set_attr "type" "imovx")
4100
   (set_attr "mode" "DI")
4101
   (set_attr "prefix_0f" "0")
4102
   (set_attr "modrm" "0,1")])
4103
 
4104
(define_insn "extendhidi2"
4105
  [(set (match_operand:DI 0 "register_operand" "=r")
4106
        (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4107
  "TARGET_64BIT"
4108
  "movs{wq|x}\t{%1, %0|%0, %1}"
4109
  [(set_attr "type" "imovx")
4110
   (set_attr "mode" "DI")])
4111
 
4112
(define_insn "extendqidi2"
4113
  [(set (match_operand:DI 0 "register_operand" "=r")
4114
        (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4115
  "TARGET_64BIT"
4116
  "movs{bq|x}\t{%1, %0|%0, %1}"
4117
   [(set_attr "type" "imovx")
4118
    (set_attr "mode" "DI")])
4119
 
4120
;; Extend to memory case when source register does die.
4121
(define_split
4122
  [(set (match_operand:DI 0 "memory_operand" "")
4123
        (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4124
   (clobber (reg:CC FLAGS_REG))
4125
   (clobber (match_operand:SI 2 "register_operand" ""))]
4126
  "(reload_completed
4127
    && dead_or_set_p (insn, operands[1])
4128
    && !reg_mentioned_p (operands[1], operands[0]))"
4129
  [(set (match_dup 3) (match_dup 1))
4130
   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4131
              (clobber (reg:CC FLAGS_REG))])
4132
   (set (match_dup 4) (match_dup 1))]
4133
  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4134
 
4135
;; Extend to memory case when source register does not die.
4136
(define_split
4137
  [(set (match_operand:DI 0 "memory_operand" "")
4138
        (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4139
   (clobber (reg:CC FLAGS_REG))
4140
   (clobber (match_operand:SI 2 "register_operand" ""))]
4141
  "reload_completed"
4142
  [(const_int 0)]
4143
{
4144
  split_di (&operands[0], 1, &operands[3], &operands[4]);
4145
 
4146
  emit_move_insn (operands[3], operands[1]);
4147
 
4148
  /* Generate a cltd if possible and doing so it profitable.  */
4149
  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4150
      && true_regnum (operands[1]) == AX_REG
4151
      && true_regnum (operands[2]) == DX_REG)
4152
    {
4153
      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4154
    }
4155
  else
4156
    {
4157
      emit_move_insn (operands[2], operands[1]);
4158
      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4159
    }
4160
  emit_move_insn (operands[4], operands[2]);
4161
  DONE;
4162
})
4163
 
4164
;; Extend to register case.  Optimize case where source and destination
4165
;; registers match and cases where we can use cltd.
4166
(define_split
4167
  [(set (match_operand:DI 0 "register_operand" "")
4168
        (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4169
   (clobber (reg:CC FLAGS_REG))
4170
   (clobber (match_scratch:SI 2 ""))]
4171
  "reload_completed"
4172
  [(const_int 0)]
4173
{
4174
  split_di (&operands[0], 1, &operands[3], &operands[4]);
4175
 
4176
  if (true_regnum (operands[3]) != true_regnum (operands[1]))
4177
    emit_move_insn (operands[3], operands[1]);
4178
 
4179
  /* Generate a cltd if possible and doing so it profitable.  */
4180
  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4181
      && true_regnum (operands[3]) == AX_REG)
4182
    {
4183
      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4184
      DONE;
4185
    }
4186
 
4187
  if (true_regnum (operands[4]) != true_regnum (operands[1]))
4188
    emit_move_insn (operands[4], operands[1]);
4189
 
4190
  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4191
  DONE;
4192
})
4193
 
4194
(define_insn "extendhisi2"
4195
  [(set (match_operand:SI 0 "register_operand" "=*a,r")
4196
        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4197
  ""
4198
{
4199
  switch (get_attr_prefix_0f (insn))
4200
    {
4201
    case 0:
4202
      return "{cwtl|cwde}";
4203
    default:
4204
      return "movs{wl|x}\t{%1, %0|%0, %1}";
4205
    }
4206
}
4207
  [(set_attr "type" "imovx")
4208
   (set_attr "mode" "SI")
4209
   (set (attr "prefix_0f")
4210
     ;; movsx is short decodable while cwtl is vector decoded.
4211
     (if_then_else (and (eq_attr "cpu" "!k6")
4212
                        (eq_attr "alternative" "0"))
4213
        (const_string "0")
4214
        (const_string "1")))
4215
   (set (attr "modrm")
4216
     (if_then_else (eq_attr "prefix_0f" "0")
4217
        (const_string "0")
4218
        (const_string "1")))])
4219
 
4220
(define_insn "*extendhisi2_zext"
4221
  [(set (match_operand:DI 0 "register_operand" "=*a,r")
4222
        (zero_extend:DI
4223
          (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4224
  "TARGET_64BIT"
4225
{
4226
  switch (get_attr_prefix_0f (insn))
4227
    {
4228
    case 0:
4229
      return "{cwtl|cwde}";
4230
    default:
4231
      return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4232
    }
4233
}
4234
  [(set_attr "type" "imovx")
4235
   (set_attr "mode" "SI")
4236
   (set (attr "prefix_0f")
4237
     ;; movsx is short decodable while cwtl is vector decoded.
4238
     (if_then_else (and (eq_attr "cpu" "!k6")
4239
                        (eq_attr "alternative" "0"))
4240
        (const_string "0")
4241
        (const_string "1")))
4242
   (set (attr "modrm")
4243
     (if_then_else (eq_attr "prefix_0f" "0")
4244
        (const_string "0")
4245
        (const_string "1")))])
4246
 
4247
(define_insn "extendqihi2"
4248
  [(set (match_operand:HI 0 "register_operand" "=*a,r")
4249
        (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4250
  ""
4251
{
4252
  switch (get_attr_prefix_0f (insn))
4253
    {
4254
    case 0:
4255
      return "{cbtw|cbw}";
4256
    default:
4257
      return "movs{bw|x}\t{%1, %0|%0, %1}";
4258
    }
4259
}
4260
  [(set_attr "type" "imovx")
4261
   (set_attr "mode" "HI")
4262
   (set (attr "prefix_0f")
4263
     ;; movsx is short decodable while cwtl is vector decoded.
4264
     (if_then_else (and (eq_attr "cpu" "!k6")
4265
                        (eq_attr "alternative" "0"))
4266
        (const_string "0")
4267
        (const_string "1")))
4268
   (set (attr "modrm")
4269
     (if_then_else (eq_attr "prefix_0f" "0")
4270
        (const_string "0")
4271
        (const_string "1")))])
4272
 
4273
(define_insn "extendqisi2"
4274
  [(set (match_operand:SI 0 "register_operand" "=r")
4275
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4276
  ""
4277
  "movs{bl|x}\t{%1, %0|%0, %1}"
4278
   [(set_attr "type" "imovx")
4279
    (set_attr "mode" "SI")])
4280
 
4281
(define_insn "*extendqisi2_zext"
4282
  [(set (match_operand:DI 0 "register_operand" "=r")
4283
        (zero_extend:DI
4284
          (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4285
  "TARGET_64BIT"
4286
  "movs{bl|x}\t{%1, %k0|%k0, %1}"
4287
   [(set_attr "type" "imovx")
4288
    (set_attr "mode" "SI")])
4289
 
4290
;; Conversions between float and double.
4291
 
4292
;; These are all no-ops in the model used for the 80387.  So just
4293
;; emit moves.
4294
 
4295
;; %%% Kill these when call knows how to work out a DFmode push earlier.
4296
(define_insn "*dummy_extendsfdf2"
4297
  [(set (match_operand:DF 0 "push_operand" "=<")
4298
        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4299
  "0"
4300
  "#")
4301
 
4302
(define_split
4303
  [(set (match_operand:DF 0 "push_operand" "")
4304
        (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4305
  ""
4306
  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4307
   (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4308
 
4309
(define_insn "*dummy_extendsfxf2"
4310
  [(set (match_operand:XF 0 "push_operand" "=<")
4311
        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4312
  "0"
4313
  "#")
4314
 
4315
(define_split
4316
  [(set (match_operand:XF 0 "push_operand" "")
4317
        (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4318
  ""
4319
  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4320
   (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4321
  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4322
 
4323
(define_split
4324
  [(set (match_operand:XF 0 "push_operand" "")
4325
        (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4326
  ""
4327
  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4328
   (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4329
  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4330
 
4331
(define_expand "extendsfdf2"
4332
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
4333
        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4334
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4335
{
4336
  /* ??? Needed for compress_float_constant since all fp constants
4337
     are LEGITIMATE_CONSTANT_P.  */
4338
  if (GET_CODE (operands[1]) == CONST_DOUBLE)
4339
    {
4340
      if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4341
          && standard_80387_constant_p (operands[1]) > 0)
4342
        {
4343
          operands[1] = simplify_const_unary_operation
4344
            (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4345
          emit_move_insn_1 (operands[0], operands[1]);
4346
          DONE;
4347
        }
4348
      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4349
    }
4350
})
4351
 
4352
/* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4353
   cvtss2sd:
4354
      unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4355
      cvtps2pd xmm2,xmm1
4356
   We do the conversion post reload to avoid producing of 128bit spills
4357
   that might lead to ICE on 32bit target.  The sequence unlikely combine
4358
   anyway.  */
4359
(define_split
4360
  [(set (match_operand:DF 0 "register_operand" "")
4361
        (float_extend:DF
4362
          (match_operand:SF 1 "nonimmediate_operand" "")))]
4363
  "TARGET_USE_VECTOR_FP_CONVERTS
4364
   && optimize_insn_for_speed_p ()
4365
   && reload_completed && SSE_REG_P (operands[0])"
4366
   [(set (match_dup 2)
4367
         (float_extend:V2DF
4368
           (vec_select:V2SF
4369
             (match_dup 3)
4370
             (parallel [(const_int 0) (const_int 1)]))))]
4371
{
4372
  operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4373
  operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4374
  /* Use movss for loading from memory, unpcklps reg, reg for registers.
4375
     Try to avoid move when unpacking can be done in source.  */
4376
  if (REG_P (operands[1]))
4377
    {
4378
      /* If it is unsafe to overwrite upper half of source, we need
4379
         to move to destination and unpack there.  */
4380
      if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4381
           || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4382
          && true_regnum (operands[0]) != true_regnum (operands[1]))
4383
        {
4384
          rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4385
          emit_move_insn (tmp, operands[1]);
4386
        }
4387
      else
4388
        operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4389
      emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4390
                                             operands[3]));
4391
    }
4392
  else
4393
    emit_insn (gen_vec_setv4sf_0 (operands[3],
4394
                                  CONST0_RTX (V4SFmode), operands[1]));
4395
})
4396
 
4397
(define_insn "*extendsfdf2_mixed"
4398
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4399
        (float_extend:DF
4400
          (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4401
  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4402
{
4403
  switch (which_alternative)
4404
    {
4405
    case 0:
4406
    case 1:
4407
      return output_387_reg_move (insn, operands);
4408
 
4409
    case 2:
4410
      return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4411
 
4412
    default:
4413
      gcc_unreachable ();
4414
    }
4415
}
4416
  [(set_attr "type" "fmov,fmov,ssecvt")
4417
   (set_attr "prefix" "orig,orig,maybe_vex")
4418
   (set_attr "mode" "SF,XF,DF")])
4419
 
4420
(define_insn "*extendsfdf2_sse"
4421
  [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4422
        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4423
  "TARGET_SSE2 && TARGET_SSE_MATH"
4424
  "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4425
  [(set_attr "type" "ssecvt")
4426
   (set_attr "prefix" "maybe_vex")
4427
   (set_attr "mode" "DF")])
4428
 
4429
(define_insn "*extendsfdf2_i387"
4430
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4431
        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4432
  "TARGET_80387"
4433
  "* return output_387_reg_move (insn, operands);"
4434
  [(set_attr "type" "fmov")
4435
   (set_attr "mode" "SF,XF")])
4436
 
4437
(define_expand "extendxf2"
4438
  [(set (match_operand:XF 0 "nonimmediate_operand" "")
4439
        (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4440
  "TARGET_80387"
4441
{
4442
  /* ??? Needed for compress_float_constant since all fp constants
4443
     are LEGITIMATE_CONSTANT_P.  */
4444
  if (GET_CODE (operands[1]) == CONST_DOUBLE)
4445
    {
4446
      if (standard_80387_constant_p (operands[1]) > 0)
4447
        {
4448
          operands[1] = simplify_const_unary_operation
4449
            (FLOAT_EXTEND, XFmode, operands[1], mode);
4450
          emit_move_insn_1 (operands[0], operands[1]);
4451
          DONE;
4452
        }
4453
      operands[1] = validize_mem (force_const_mem (mode, operands[1]));
4454
    }
4455
})
4456
 
4457
(define_insn "*extendxf2_i387"
4458
  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4459
        (float_extend:XF
4460
          (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4461
  "TARGET_80387"
4462
  "* return output_387_reg_move (insn, operands);"
4463
  [(set_attr "type" "fmov")
4464
   (set_attr "mode" ",XF")])
4465
 
4466
;; %%% This seems bad bad news.
4467
;; This cannot output into an f-reg because there is no way to be sure
4468
;; of truncating in that case.  Otherwise this is just like a simple move
4469
;; insn.  So we pretend we can output to a reg in order to get better
4470
;; register preferencing, but we really use a stack slot.
4471
 
4472
;; Conversion from DFmode to SFmode.
4473
 
4474
(define_expand "truncdfsf2"
4475
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
4476
        (float_truncate:SF
4477
          (match_operand:DF 1 "nonimmediate_operand" "")))]
4478
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4479
{
4480
  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4481
    ;
4482
  else if (flag_unsafe_math_optimizations)
4483
    ;
4484
  else
4485
    {
4486
      enum ix86_stack_slot slot = (virtuals_instantiated
4487
                                   ? SLOT_TEMP
4488
                                   : SLOT_VIRTUAL);
4489
      rtx temp = assign_386_stack_local (SFmode, slot);
4490
      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4491
      DONE;
4492
    }
4493
})
4494
 
4495
/* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4496
   cvtsd2ss:
4497
      unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4498
      cvtpd2ps xmm2,xmm1
4499
   We do the conversion post reload to avoid producing of 128bit spills
4500
   that might lead to ICE on 32bit target.  The sequence unlikely combine
4501
   anyway.  */
4502
(define_split
4503
  [(set (match_operand:SF 0 "register_operand" "")
4504
        (float_truncate:SF
4505
          (match_operand:DF 1 "nonimmediate_operand" "")))]
4506
  "TARGET_USE_VECTOR_FP_CONVERTS
4507
   && optimize_insn_for_speed_p ()
4508
   && reload_completed && SSE_REG_P (operands[0])"
4509
   [(set (match_dup 2)
4510
         (vec_concat:V4SF
4511
           (float_truncate:V2SF
4512
             (match_dup 4))
4513
           (match_dup 3)))]
4514
{
4515
  operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4516
  operands[3] = CONST0_RTX (V2SFmode);
4517
  operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4518
  /* Use movsd for loading from memory, unpcklpd for registers.
4519
     Try to avoid move when unpacking can be done in source, or SSE3
4520
     movddup is available.  */
4521
  if (REG_P (operands[1]))
4522
    {
4523
      if (!TARGET_SSE3
4524
          && true_regnum (operands[0]) != true_regnum (operands[1])
4525
          && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4526
              || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4527
        {
4528
          rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4529
          emit_move_insn (tmp, operands[1]);
4530
          operands[1] = tmp;
4531
        }
4532
      else if (!TARGET_SSE3)
4533
        operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4534
      emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4535
    }
4536
  else
4537
    emit_insn (gen_sse2_loadlpd (operands[4],
4538
                                 CONST0_RTX (V2DFmode), operands[1]));
4539
})
4540
 
4541
(define_expand "truncdfsf2_with_temp"
4542
  [(parallel [(set (match_operand:SF 0 "" "")
4543
                   (float_truncate:SF (match_operand:DF 1 "" "")))
4544
              (clobber (match_operand:SF 2 "" ""))])]
4545
  "")
4546
 
4547
(define_insn "*truncdfsf_fast_mixed"
4548
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4549
        (float_truncate:SF
4550
          (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4551
  "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4552
{
4553
  switch (which_alternative)
4554
    {
4555
    case 0:
4556
      return output_387_reg_move (insn, operands);
4557
    case 1:
4558
      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4559
    default:
4560
      gcc_unreachable ();
4561
    }
4562
}
4563
  [(set_attr "type" "fmov,ssecvt")
4564
   (set_attr "prefix" "orig,maybe_vex")
4565
   (set_attr "mode" "SF")])
4566
 
4567
;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4568
;; because nothing we do here is unsafe.
4569
(define_insn "*truncdfsf_fast_sse"
4570
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4571
        (float_truncate:SF
4572
          (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4573
  "TARGET_SSE2 && TARGET_SSE_MATH"
4574
  "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4575
  [(set_attr "type" "ssecvt")
4576
   (set_attr "prefix" "maybe_vex")
4577
   (set_attr "mode" "SF")])
4578
 
4579
(define_insn "*truncdfsf_fast_i387"
4580
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4581
        (float_truncate:SF
4582
          (match_operand:DF 1 "nonimmediate_operand" "f")))]
4583
  "TARGET_80387 && flag_unsafe_math_optimizations"
4584
  "* return output_387_reg_move (insn, operands);"
4585
  [(set_attr "type" "fmov")
4586
   (set_attr "mode" "SF")])
4587
 
4588
(define_insn "*truncdfsf_mixed"
4589
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4590
        (float_truncate:SF
4591
          (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4592
   (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4593
  "TARGET_MIX_SSE_I387"
4594
{
4595
  switch (which_alternative)
4596
    {
4597
    case 0:
4598
      return output_387_reg_move (insn, operands);
4599
    case 1:
4600
      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4601
 
4602
    default:
4603
      return "#";
4604
    }
4605
}
4606
  [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4607
   (set_attr "unit" "*,*,i387,i387,i387")
4608
   (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4609
   (set_attr "mode" "SF")])
4610
 
4611
(define_insn "*truncdfsf_i387"
4612
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4613
        (float_truncate:SF
4614
          (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4615
   (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4616
  "TARGET_80387"
4617
{
4618
  switch (which_alternative)
4619
    {
4620
    case 0:
4621
      return output_387_reg_move (insn, operands);
4622
 
4623
    default:
4624
      return "#";
4625
    }
4626
}
4627
  [(set_attr "type" "fmov,multi,multi,multi")
4628
   (set_attr "unit" "*,i387,i387,i387")
4629
   (set_attr "mode" "SF")])
4630
 
4631
(define_insn "*truncdfsf2_i387_1"
4632
  [(set (match_operand:SF 0 "memory_operand" "=m")
4633
        (float_truncate:SF
4634
          (match_operand:DF 1 "register_operand" "f")))]
4635
  "TARGET_80387
4636
   && !(TARGET_SSE2 && TARGET_SSE_MATH)
4637
   && !TARGET_MIX_SSE_I387"
4638
  "* return output_387_reg_move (insn, operands);"
4639
  [(set_attr "type" "fmov")
4640
   (set_attr "mode" "SF")])
4641
 
4642
(define_split
4643
  [(set (match_operand:SF 0 "register_operand" "")
4644
        (float_truncate:SF
4645
         (match_operand:DF 1 "fp_register_operand" "")))
4646
   (clobber (match_operand 2 "" ""))]
4647
  "reload_completed"
4648
  [(set (match_dup 2) (match_dup 1))
4649
   (set (match_dup 0) (match_dup 2))]
4650
{
4651
  operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4652
})
4653
 
4654
;; Conversion from XFmode to {SF,DF}mode
4655
 
4656
(define_expand "truncxf2"
4657
  [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4658
                   (float_truncate:MODEF
4659
                     (match_operand:XF 1 "register_operand" "")))
4660
              (clobber (match_dup 2))])]
4661
  "TARGET_80387"
4662
{
4663
  if (flag_unsafe_math_optimizations)
4664
    {
4665
      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (mode);
4666
      emit_insn (gen_truncxf2_i387_noop (reg, operands[1]));
4667
      if (reg != operands[0])
4668
        emit_move_insn (operands[0], reg);
4669
      DONE;
4670
    }
4671
  else
4672
    {
4673
     enum ix86_stack_slot slot = (virtuals_instantiated
4674
                                  ? SLOT_TEMP
4675
                                  : SLOT_VIRTUAL);
4676
      operands[2] = assign_386_stack_local (mode, slot);
4677
    }
4678
})
4679
 
4680
(define_insn "*truncxfsf2_mixed"
4681
  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4682
        (float_truncate:SF
4683
          (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4684
   (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4685
  "TARGET_80387"
4686
{
4687
  gcc_assert (!which_alternative);
4688
  return output_387_reg_move (insn, operands);
4689
}
4690
  [(set_attr "type" "fmov,multi,multi,multi")
4691
   (set_attr "unit" "*,i387,i387,i387")
4692
   (set_attr "mode" "SF")])
4693
 
4694
(define_insn "*truncxfdf2_mixed"
4695
  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4696
        (float_truncate:DF
4697
          (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4698
   (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4699
  "TARGET_80387"
4700
{
4701
  gcc_assert (!which_alternative);
4702
  return output_387_reg_move (insn, operands);
4703
}
4704
  [(set_attr "type" "fmov,multi,multi,multi")
4705
   (set_attr "unit" "*,i387,i387,i387")
4706
   (set_attr "mode" "DF")])
4707
 
4708
(define_insn "truncxf2_i387_noop"
4709
  [(set (match_operand:MODEF 0 "register_operand" "=f")
4710
        (float_truncate:MODEF
4711
          (match_operand:XF 1 "register_operand" "f")))]
4712
  "TARGET_80387 && flag_unsafe_math_optimizations"
4713
  "* return output_387_reg_move (insn, operands);"
4714
  [(set_attr "type" "fmov")
4715
   (set_attr "mode" "")])
4716
 
4717
(define_insn "*truncxf2_i387"
4718
  [(set (match_operand:MODEF 0 "memory_operand" "=m")
4719
        (float_truncate:MODEF
4720
          (match_operand:XF 1 "register_operand" "f")))]
4721
  "TARGET_80387"
4722
  "* return output_387_reg_move (insn, operands);"
4723
  [(set_attr "type" "fmov")
4724
   (set_attr "mode" "")])
4725
 
4726
(define_split
4727
  [(set (match_operand:MODEF 0 "register_operand" "")
4728
        (float_truncate:MODEF
4729
          (match_operand:XF 1 "register_operand" "")))
4730
   (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4731
  "TARGET_80387 && reload_completed"
4732
  [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4733
   (set (match_dup 0) (match_dup 2))]
4734
  "")
4735
 
4736
(define_split
4737
  [(set (match_operand:MODEF 0 "memory_operand" "")
4738
        (float_truncate:MODEF
4739
          (match_operand:XF 1 "register_operand" "")))
4740
   (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4741
  "TARGET_80387"
4742
  [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4743
  "")
4744
 
4745
;; Signed conversion to DImode.
4746
 
4747
(define_expand "fix_truncxfdi2"
4748
  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4749
                   (fix:DI (match_operand:XF 1 "register_operand" "")))
4750
              (clobber (reg:CC FLAGS_REG))])]
4751
  "TARGET_80387"
4752
{
4753
  if (TARGET_FISTTP)
4754
   {
4755
     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4756
     DONE;
4757
   }
4758
})
4759
 
4760
(define_expand "fix_truncdi2"
4761
  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4762
                   (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4763
              (clobber (reg:CC FLAGS_REG))])]
4764
  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (mode))"
4765
{
4766
  if (TARGET_FISTTP
4767
      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))
4768
   {
4769
     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4770
     DONE;
4771
   }
4772
  if (TARGET_64BIT && SSE_FLOAT_MODE_P (mode))
4773
   {
4774
     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4775
     emit_insn (gen_fix_truncdi_sse (out, operands[1]));
4776
     if (out != operands[0])
4777
        emit_move_insn (operands[0], out);
4778
     DONE;
4779
   }
4780
})
4781
 
4782
;; Signed conversion to SImode.
4783
 
4784
(define_expand "fix_truncxfsi2"
4785
  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4786
                   (fix:SI (match_operand:XF 1 "register_operand" "")))
4787
              (clobber (reg:CC FLAGS_REG))])]
4788
  "TARGET_80387"
4789
{
4790
  if (TARGET_FISTTP)
4791
   {
4792
     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4793
     DONE;
4794
   }
4795
})
4796
 
4797
(define_expand "fix_truncsi2"
4798
  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4799
                   (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4800
              (clobber (reg:CC FLAGS_REG))])]
4801
  "TARGET_80387 || SSE_FLOAT_MODE_P (mode)"
4802
{
4803
  if (TARGET_FISTTP
4804
      && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))
4805
   {
4806
     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4807
     DONE;
4808
   }
4809
  if (SSE_FLOAT_MODE_P (mode))
4810
   {
4811
     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4812
     emit_insn (gen_fix_truncsi_sse (out, operands[1]));
4813
     if (out != operands[0])
4814
        emit_move_insn (operands[0], out);
4815
     DONE;
4816
   }
4817
})
4818
 
4819
;; Signed conversion to HImode.
4820
 
4821
(define_expand "fix_trunchi2"
4822
  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4823
                   (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4824
              (clobber (reg:CC FLAGS_REG))])]
4825
  "TARGET_80387
4826
   && !(SSE_FLOAT_MODE_P (mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4827
{
4828
  if (TARGET_FISTTP)
4829
   {
4830
     emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4831
     DONE;
4832
   }
4833
})
4834
 
4835
;; Unsigned conversion to SImode.
4836
 
4837
(define_expand "fixuns_truncsi2"
4838
  [(parallel
4839
    [(set (match_operand:SI 0 "register_operand" "")
4840
          (unsigned_fix:SI
4841
            (match_operand:MODEF 1 "nonimmediate_operand" "")))
4842
     (use (match_dup 2))
4843
     (clobber (match_scratch: 3 ""))
4844
     (clobber (match_scratch: 4 ""))])]
4845
  "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4846
{
4847
  enum machine_mode mode = mode;
4848
  enum machine_mode vecmode = mode;
4849
  REAL_VALUE_TYPE TWO31r;
4850
  rtx two31;
4851
 
4852
  if (optimize_insn_for_size_p ())
4853
    FAIL;
4854
 
4855
  real_ldexp (&TWO31r, &dconst1, 31);
4856
  two31 = const_double_from_real_value (TWO31r, mode);
4857
  two31 = ix86_build_const_vector (mode, true, two31);
4858
  operands[2] = force_reg (vecmode, two31);
4859
})
4860
 
4861
(define_insn_and_split "*fixuns_trunc_1"
4862
  [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4863
        (unsigned_fix:SI
4864
          (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4865
   (use (match_operand: 4  "nonimmediate_operand" "m,x"))
4866
   (clobber (match_scratch: 1 "=x,&x"))
4867
   (clobber (match_scratch: 2 "=x,x"))]
4868
  "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4869
   && optimize_function_for_speed_p (cfun)"
4870
  "#"
4871
  "&& reload_completed"
4872
  [(const_int 0)]
4873
{
4874
  ix86_split_convert_uns_si_sse (operands);
4875
  DONE;
4876
})
4877
 
4878
;; Unsigned conversion to HImode.
4879
;; Without these patterns, we'll try the unsigned SI conversion which
4880
;; is complex for SSE, rather than the signed SI conversion, which isn't.
4881
 
4882
(define_expand "fixuns_trunchi2"
4883
  [(set (match_dup 2)
4884
        (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4885
   (set (match_operand:HI 0 "nonimmediate_operand" "")
4886
        (subreg:HI (match_dup 2) 0))]
4887
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
4888
  "operands[2] = gen_reg_rtx (SImode);")
4889
 
4890
;; When SSE is available, it is always faster to use it!
4891
(define_insn "fix_truncdi_sse"
4892
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4893
        (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4894
  "TARGET_64BIT && SSE_FLOAT_MODE_P (mode)
4895
   && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4896
  "%vcvtts2si{q}\t{%1, %0|%0, %1}"
4897
  [(set_attr "type" "sseicvt")
4898
   (set_attr "prefix" "maybe_vex")
4899
   (set_attr "prefix_rex" "1")
4900
   (set_attr "mode" "")
4901
   (set_attr "athlon_decode" "double,vector")
4902
   (set_attr "amdfam10_decode" "double,double")])
4903
 
4904
(define_insn "fix_truncsi_sse"
4905
  [(set (match_operand:SI 0 "register_operand" "=r,r")
4906
        (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4907
  "SSE_FLOAT_MODE_P (mode)
4908
   && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4909
  "%vcvtts2si\t{%1, %0|%0, %1}"
4910
  [(set_attr "type" "sseicvt")
4911
   (set_attr "prefix" "maybe_vex")
4912
   (set_attr "mode" "")
4913
   (set_attr "athlon_decode" "double,vector")
4914
   (set_attr "amdfam10_decode" "double,double")])
4915
 
4916
;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4917
(define_peephole2
4918
  [(set (match_operand:MODEF 0 "register_operand" "")
4919
        (match_operand:MODEF 1 "memory_operand" ""))
4920
   (set (match_operand:SSEMODEI24 2 "register_operand" "")
4921
        (fix:SSEMODEI24 (match_dup 0)))]
4922
  "TARGET_SHORTEN_X87_SSE
4923
   && peep2_reg_dead_p (2, operands[0])"
4924
  [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4925
  "")
4926
 
4927
;; Avoid vector decoded forms of the instruction.
4928
(define_peephole2
4929
  [(match_scratch:DF 2 "Y2")
4930
   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4931
        (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4932
  "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4933
  [(set (match_dup 2) (match_dup 1))
4934
   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4935
  "")
4936
 
4937
(define_peephole2
4938
  [(match_scratch:SF 2 "x")
4939
   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4940
        (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4941
  "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4942
  [(set (match_dup 2) (match_dup 1))
4943
   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4944
  "")
4945
 
4946
(define_insn_and_split "fix_trunc_fisttp_i387_1"
4947
  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4948
        (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4949
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4950
   && TARGET_FISTTP
4951
   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4952
         && (TARGET_64BIT || mode != DImode))
4953
        && TARGET_SSE_MATH)
4954
   && can_create_pseudo_p ()"
4955
  "#"
4956
  "&& 1"
4957
  [(const_int 0)]
4958
{
4959
  if (memory_operand (operands[0], VOIDmode))
4960
    emit_insn (gen_fix_trunc_i387_fisttp (operands[0], operands[1]));
4961
  else
4962
    {
4963
      operands[2] = assign_386_stack_local (mode, SLOT_TEMP);
4964
      emit_insn (gen_fix_trunc_i387_fisttp_with_temp (operands[0],
4965
                                                            operands[1],
4966
                                                            operands[2]));
4967
    }
4968
  DONE;
4969
}
4970
  [(set_attr "type" "fisttp")
4971
   (set_attr "mode" "")])
4972
 
4973
(define_insn "fix_trunc_i387_fisttp"
4974
  [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4975
        (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4976
   (clobber (match_scratch:XF 2 "=&1f"))]
4977
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4978
   && TARGET_FISTTP
4979
   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4980
         && (TARGET_64BIT || mode != DImode))
4981
        && TARGET_SSE_MATH)"
4982
  "* return output_fix_trunc (insn, operands, 1);"
4983
  [(set_attr "type" "fisttp")
4984
   (set_attr "mode" "")])
4985
 
4986
(define_insn "fix_trunc_i387_fisttp_with_temp"
4987
  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4988
        (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4989
   (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4990
   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4991
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4992
   && TARGET_FISTTP
4993
   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4994
        && (TARGET_64BIT || mode != DImode))
4995
        && TARGET_SSE_MATH)"
4996
  "#"
4997
  [(set_attr "type" "fisttp")
4998
   (set_attr "mode" "")])
4999
 
5000
(define_split
5001
  [(set (match_operand:X87MODEI 0 "register_operand" "")
5002
        (fix:X87MODEI (match_operand 1 "register_operand" "")))
5003
   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5004
   (clobber (match_scratch 3 ""))]
5005
  "reload_completed"
5006
  [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5007
              (clobber (match_dup 3))])
5008
   (set (match_dup 0) (match_dup 2))]
5009
  "")
5010
 
5011
(define_split
5012
  [(set (match_operand:X87MODEI 0 "memory_operand" "")
5013
        (fix:X87MODEI (match_operand 1 "register_operand" "")))
5014
   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5015
   (clobber (match_scratch 3 ""))]
5016
  "reload_completed"
5017
  [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5018
              (clobber (match_dup 3))])]
5019
  "")
5020
 
5021
;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5022
;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5023
;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5024
;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5025
;; function in i386.c.
5026
(define_insn_and_split "*fix_trunc_i387_1"
5027
  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5028
        (fix:X87MODEI (match_operand 1 "register_operand" "")))
5029
   (clobber (reg:CC FLAGS_REG))]
5030
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5031
   && !TARGET_FISTTP
5032
   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5033
         && (TARGET_64BIT || mode != DImode))
5034
   && can_create_pseudo_p ()"
5035
  "#"
5036
  "&& 1"
5037
  [(const_int 0)]
5038
{
5039
  ix86_optimize_mode_switching[I387_TRUNC] = 1;
5040
 
5041
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5042
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5043
  if (memory_operand (operands[0], VOIDmode))
5044
    emit_insn (gen_fix_trunc_i387 (operands[0], operands[1],
5045
                                         operands[2], operands[3]));
5046
  else
5047
    {
5048
      operands[4] = assign_386_stack_local (mode, SLOT_TEMP);
5049
      emit_insn (gen_fix_trunc_i387_with_temp (operands[0], operands[1],
5050
                                                     operands[2], operands[3],
5051
                                                     operands[4]));
5052
    }
5053
  DONE;
5054
}
5055
  [(set_attr "type" "fistp")
5056
   (set_attr "i387_cw" "trunc")
5057
   (set_attr "mode" "")])
5058
 
5059
(define_insn "fix_truncdi_i387"
5060
  [(set (match_operand:DI 0 "memory_operand" "=m")
5061
        (fix:DI (match_operand 1 "register_operand" "f")))
5062
   (use (match_operand:HI 2 "memory_operand" "m"))
5063
   (use (match_operand:HI 3 "memory_operand" "m"))
5064
   (clobber (match_scratch:XF 4 "=&1f"))]
5065
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5066
   && !TARGET_FISTTP
5067
   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5068
  "* return output_fix_trunc (insn, operands, 0);"
5069
  [(set_attr "type" "fistp")
5070
   (set_attr "i387_cw" "trunc")
5071
   (set_attr "mode" "DI")])
5072
 
5073
(define_insn "fix_truncdi_i387_with_temp"
5074
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5075
        (fix:DI (match_operand 1 "register_operand" "f,f")))
5076
   (use (match_operand:HI 2 "memory_operand" "m,m"))
5077
   (use (match_operand:HI 3 "memory_operand" "m,m"))
5078
   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5079
   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5080
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5081
   && !TARGET_FISTTP
5082
   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5083
  "#"
5084
  [(set_attr "type" "fistp")
5085
   (set_attr "i387_cw" "trunc")
5086
   (set_attr "mode" "DI")])
5087
 
5088
(define_split
5089
  [(set (match_operand:DI 0 "register_operand" "")
5090
        (fix:DI (match_operand 1 "register_operand" "")))
5091
   (use (match_operand:HI 2 "memory_operand" ""))
5092
   (use (match_operand:HI 3 "memory_operand" ""))
5093
   (clobber (match_operand:DI 4 "memory_operand" ""))
5094
   (clobber (match_scratch 5 ""))]
5095
  "reload_completed"
5096
  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5097
              (use (match_dup 2))
5098
              (use (match_dup 3))
5099
              (clobber (match_dup 5))])
5100
   (set (match_dup 0) (match_dup 4))]
5101
  "")
5102
 
5103
(define_split
5104
  [(set (match_operand:DI 0 "memory_operand" "")
5105
        (fix:DI (match_operand 1 "register_operand" "")))
5106
   (use (match_operand:HI 2 "memory_operand" ""))
5107
   (use (match_operand:HI 3 "memory_operand" ""))
5108
   (clobber (match_operand:DI 4 "memory_operand" ""))
5109
   (clobber (match_scratch 5 ""))]
5110
  "reload_completed"
5111
  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5112
              (use (match_dup 2))
5113
              (use (match_dup 3))
5114
              (clobber (match_dup 5))])]
5115
  "")
5116
 
5117
(define_insn "fix_trunc_i387"
5118
  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5119
        (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5120
   (use (match_operand:HI 2 "memory_operand" "m"))
5121
   (use (match_operand:HI 3 "memory_operand" "m"))]
5122
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5123
   && !TARGET_FISTTP
5124
   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5125
  "* return output_fix_trunc (insn, operands, 0);"
5126
  [(set_attr "type" "fistp")
5127
   (set_attr "i387_cw" "trunc")
5128
   (set_attr "mode" "")])
5129
 
5130
(define_insn "fix_trunc_i387_with_temp"
5131
  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5132
        (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5133
   (use (match_operand:HI 2 "memory_operand" "m,m"))
5134
   (use (match_operand:HI 3 "memory_operand" "m,m"))
5135
   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5136
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5137
   && !TARGET_FISTTP
5138
   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5139
  "#"
5140
  [(set_attr "type" "fistp")
5141
   (set_attr "i387_cw" "trunc")
5142
   (set_attr "mode" "")])
5143
 
5144
(define_split
5145
  [(set (match_operand:X87MODEI12 0 "register_operand" "")
5146
        (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5147
   (use (match_operand:HI 2 "memory_operand" ""))
5148
   (use (match_operand:HI 3 "memory_operand" ""))
5149
   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5150
  "reload_completed"
5151
  [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5152
              (use (match_dup 2))
5153
              (use (match_dup 3))])
5154
   (set (match_dup 0) (match_dup 4))]
5155
  "")
5156
 
5157
(define_split
5158
  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5159
        (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5160
   (use (match_operand:HI 2 "memory_operand" ""))
5161
   (use (match_operand:HI 3 "memory_operand" ""))
5162
   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5163
  "reload_completed"
5164
  [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5165
              (use (match_dup 2))
5166
              (use (match_dup 3))])]
5167
  "")
5168
 
5169
(define_insn "x86_fnstcw_1"
5170
  [(set (match_operand:HI 0 "memory_operand" "=m")
5171
        (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5172
  "TARGET_80387"
5173
  "fnstcw\t%0"
5174
  [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5175
   (set_attr "mode" "HI")
5176
   (set_attr "unit" "i387")])
5177
 
5178
(define_insn "x86_fldcw_1"
5179
  [(set (reg:HI FPCR_REG)
5180
        (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5181
  "TARGET_80387"
5182
  "fldcw\t%0"
5183
  [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5184
   (set_attr "mode" "HI")
5185
   (set_attr "unit" "i387")
5186
   (set_attr "athlon_decode" "vector")
5187
   (set_attr "amdfam10_decode" "vector")])
5188
 
5189
;; Conversion between fixed point and floating point.
5190
 
5191
;; Even though we only accept memory inputs, the backend _really_
5192
;; wants to be able to do this between registers.
5193
 
5194
(define_expand "floathi2"
5195
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5196
        (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5197
  "TARGET_80387
5198
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
5199
       || TARGET_MIX_SSE_I387)"
5200
  "")
5201
 
5202
;; Pre-reload splitter to add memory clobber to the pattern.
5203
(define_insn_and_split "*floathi2_1"
5204
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5205
        (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5206
  "TARGET_80387
5207
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
5208
       || TARGET_MIX_SSE_I387)
5209
   && can_create_pseudo_p ()"
5210
  "#"
5211
  "&& 1"
5212
  [(parallel [(set (match_dup 0)
5213
              (float:X87MODEF (match_dup 1)))
5214
   (clobber (match_dup 2))])]
5215
  "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5216
 
5217
(define_insn "*floathi2_i387_with_temp"
5218
  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5219
        (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5220
  (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5221
  "TARGET_80387
5222
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
5223
       || TARGET_MIX_SSE_I387)"
5224
  "#"
5225
  [(set_attr "type" "fmov,multi")
5226
   (set_attr "mode" "")
5227
   (set_attr "unit" "*,i387")
5228
   (set_attr "fp_int_src" "true")])
5229
 
5230
(define_insn "*floathi2_i387"
5231
  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5232
        (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5233
  "TARGET_80387
5234
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
5235
       || TARGET_MIX_SSE_I387)"
5236
  "fild%Z1\t%1"
5237
  [(set_attr "type" "fmov")
5238
   (set_attr "mode" "")
5239
   (set_attr "fp_int_src" "true")])
5240
 
5241
(define_split
5242
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5243
        (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5244
   (clobber (match_operand:HI 2 "memory_operand" ""))]
5245
  "TARGET_80387
5246
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
5247
       || TARGET_MIX_SSE_I387)
5248
   && reload_completed"
5249
  [(set (match_dup 2) (match_dup 1))
5250
   (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5251
  "")
5252
 
5253
(define_split
5254
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5255
        (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5256
   (clobber (match_operand:HI 2 "memory_operand" ""))]
5257
   "TARGET_80387
5258
    && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
5259
        || TARGET_MIX_SSE_I387)
5260
    && reload_completed"
5261
  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5262
  "")
5263
 
5264
(define_expand "float2"
5265
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5266
        (float:X87MODEF
5267
          (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5268
  "TARGET_80387
5269
   || ((mode != DImode || TARGET_64BIT)
5270
       && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
5271
{
5272
  if (!((mode != DImode || TARGET_64BIT)
5273
        && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
5274
      && !X87_ENABLE_FLOAT (mode, mode))
5275
    {
5276
      rtx reg = gen_reg_rtx (XFmode);
5277
      rtx insn;
5278
 
5279
      emit_insn (gen_floatxf2 (reg, operands[1]));
5280
 
5281
      if (mode == SFmode)
5282
        insn = gen_truncxfsf2 (operands[0], reg);
5283
      else if (mode == DFmode)
5284
        insn = gen_truncxfdf2 (operands[0], reg);
5285
      else
5286
        gcc_unreachable ();
5287
 
5288
      emit_insn (insn);
5289
      DONE;
5290
    }
5291
})
5292
 
5293
;; Pre-reload splitter to add memory clobber to the pattern.
5294
(define_insn_and_split "*float2_1"
5295
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5296
        (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5297
  "((TARGET_80387
5298
     && X87_ENABLE_FLOAT (mode, mode)
5299
     && (!((mode != DImode || TARGET_64BIT)
5300
           && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
5301
         || TARGET_MIX_SSE_I387))
5302
    || ((mode != DImode || TARGET_64BIT)
5303
        && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
5304
        && ((mode == SImode
5305
             && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5306
             && optimize_function_for_speed_p (cfun)
5307
             && flag_trapping_math)
5308
            || !(TARGET_INTER_UNIT_CONVERSIONS
5309
                 || optimize_function_for_size_p (cfun)))))
5310
   && can_create_pseudo_p ()"
5311
  "#"
5312
  "&& 1"
5313
  [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5314
              (clobber (match_dup 2))])]
5315
{
5316
  operands[2] = assign_386_stack_local (mode, SLOT_TEMP);
5317
 
5318
  /* Avoid store forwarding (partial memory) stall penalty
5319
     by passing DImode value through XMM registers.  */
5320
  if (mode == DImode && !TARGET_64BIT
5321
      && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5322
      && optimize_function_for_speed_p (cfun))
5323
    {
5324
      emit_insn (gen_floatdi2_i387_with_xmm (operands[0],
5325
                                                            operands[1],
5326
                                                            operands[2]));
5327
      DONE;
5328
    }
5329
})
5330
 
5331
(define_insn "*floatsi2_vector_mixed_with_temp"
5332
  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5333
        (float:MODEF
5334
          (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5335
   (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5336
  "TARGET_SSE2 && TARGET_MIX_SSE_I387
5337
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5338
  "#"
5339
  [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5340
   (set_attr "mode" ",,,,")
5341
   (set_attr "unit" "*,i387,*,*,*")
5342
   (set_attr "athlon_decode" "*,*,double,direct,double")
5343
   (set_attr "amdfam10_decode" "*,*,vector,double,double")
5344
   (set_attr "fp_int_src" "true")])
5345
 
5346
(define_insn "*floatsi2_vector_mixed"
5347
  [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5348
        (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5349
  "TARGET_SSE2 && TARGET_MIX_SSE_I387
5350
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5351
  "@
5352
   fild%Z1\t%1
5353
   #"
5354
  [(set_attr "type" "fmov,sseicvt")
5355
   (set_attr "mode" ",")
5356
   (set_attr "unit" "i387,*")
5357
   (set_attr "athlon_decode" "*,direct")
5358
   (set_attr "amdfam10_decode" "*,double")
5359
   (set_attr "fp_int_src" "true")])
5360
 
5361
(define_insn "*float2_mixed_with_temp"
5362
  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5363
        (float:MODEF
5364
          (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5365
  (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5366
  "(mode != DImode || TARGET_64BIT)
5367
   && SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387"
5368
  "#"
5369
  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5370
   (set_attr "mode" "")
5371
   (set_attr "unit" "*,i387,*,*")
5372
   (set_attr "athlon_decode" "*,*,double,direct")
5373
   (set_attr "amdfam10_decode" "*,*,vector,double")
5374
   (set_attr "fp_int_src" "true")])
5375
 
5376
(define_split
5377
  [(set (match_operand:MODEF 0 "register_operand" "")
5378
        (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5379
   (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5380
  "(mode != DImode || TARGET_64BIT)
5381
   && SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
5382
   && TARGET_INTER_UNIT_CONVERSIONS
5383
   && reload_completed
5384
   && (SSE_REG_P (operands[0])
5385
       || (GET_CODE (operands[0]) == SUBREG
5386
           && SSE_REG_P (operands[0])))"
5387
  [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5388
  "")
5389
 
5390
(define_split
5391
  [(set (match_operand:MODEF 0 "register_operand" "")
5392
        (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5393
   (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5394
  "(mode != DImode || TARGET_64BIT)
5395
   && SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
5396
   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5397
   && reload_completed
5398
   && (SSE_REG_P (operands[0])
5399
       || (GET_CODE (operands[0]) == SUBREG
5400
           && SSE_REG_P (operands[0])))"
5401
  [(set (match_dup 2) (match_dup 1))
5402
   (set (match_dup 0) (float:MODEF (match_dup 2)))]
5403
  "")
5404
 
5405
(define_insn "*float2_mixed_interunit"
5406
  [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5407
        (float:MODEF
5408
          (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5409
  "(mode != DImode || TARGET_64BIT)
5410
   && SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
5411
   && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5412
  "@
5413
   fild%Z1\t%1
5414
   %vcvtsi2s\t{%1, %d0|%d0, %1}
5415
   %vcvtsi2s\t{%1, %d0|%d0, %1}"
5416
  [(set_attr "type" "fmov,sseicvt,sseicvt")
5417
   (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5418
   (set_attr "mode" "")
5419
   (set (attr "prefix_rex")
5420
     (if_then_else
5421
       (and (eq_attr "prefix" "maybe_vex")
5422
            (ne (symbol_ref "mode == DImode") (const_int 0)))
5423
       (const_string "1")
5424
       (const_string "*")))
5425
   (set_attr "unit" "i387,*,*")
5426
   (set_attr "athlon_decode" "*,double,direct")
5427
   (set_attr "amdfam10_decode" "*,vector,double")
5428
   (set_attr "fp_int_src" "true")])
5429
 
5430
(define_insn "*float2_mixed_nointerunit"
5431
  [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5432
        (float:MODEF
5433
          (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5434
  "(mode != DImode || TARGET_64BIT)
5435
   && SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
5436
   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5437
  "@
5438
   fild%Z1\t%1
5439
   %vcvtsi2s\t{%1, %d0|%d0, %1}"
5440
  [(set_attr "type" "fmov,sseicvt")
5441
   (set_attr "prefix" "orig,maybe_vex")
5442
   (set_attr "mode" "")
5443
   (set (attr "prefix_rex")
5444
     (if_then_else
5445
       (and (eq_attr "prefix" "maybe_vex")
5446
            (ne (symbol_ref "mode == DImode") (const_int 0)))
5447
       (const_string "1")
5448
       (const_string "*")))
5449
   (set_attr "athlon_decode" "*,direct")
5450
   (set_attr "amdfam10_decode" "*,double")
5451
   (set_attr "fp_int_src" "true")])
5452
 
5453
(define_insn "*floatsi2_vector_sse_with_temp"
5454
  [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5455
        (float:MODEF
5456
          (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5457
   (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5458
  "TARGET_SSE2 && TARGET_SSE_MATH
5459
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5460
  "#"
5461
  [(set_attr "type" "sseicvt")
5462
   (set_attr "mode" ",,")
5463
   (set_attr "athlon_decode" "double,direct,double")
5464
   (set_attr "amdfam10_decode" "vector,double,double")
5465
   (set_attr "fp_int_src" "true")])
5466
 
5467
(define_insn "*floatsi2_vector_sse"
5468
  [(set (match_operand:MODEF 0 "register_operand" "=x")
5469
        (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5470
  "TARGET_SSE2 && TARGET_SSE_MATH
5471
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5472
  "#"
5473
  [(set_attr "type" "sseicvt")
5474
   (set_attr "mode" "")
5475
   (set_attr "athlon_decode" "direct")
5476
   (set_attr "amdfam10_decode" "double")
5477
   (set_attr "fp_int_src" "true")])
5478
 
5479
(define_split
5480
  [(set (match_operand:MODEF 0 "register_operand" "")
5481
        (float:MODEF (match_operand:SI 1 "register_operand" "")))
5482
   (clobber (match_operand:SI 2 "memory_operand" ""))]
5483
  "TARGET_SSE2 && TARGET_SSE_MATH
5484
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5485
   && reload_completed
5486
   && (SSE_REG_P (operands[0])
5487
       || (GET_CODE (operands[0]) == SUBREG
5488
           && SSE_REG_P (operands[0])))"
5489
  [(const_int 0)]
5490
{
5491
  rtx op1 = operands[1];
5492
 
5493
  operands[3] = simplify_gen_subreg (mode, operands[0],
5494
                                     mode, 0);
5495
  if (GET_CODE (op1) == SUBREG)
5496
    op1 = SUBREG_REG (op1);
5497
 
5498
  if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5499
    {
5500
      operands[4] = simplify_gen_subreg (V4SImode, operands[0], mode, 0);
5501
      emit_insn (gen_sse2_loadld (operands[4],
5502
                                  CONST0_RTX (V4SImode), operands[1]));
5503
    }
5504
  /* We can ignore possible trapping value in the
5505
     high part of SSE register for non-trapping math. */
5506
  else if (SSE_REG_P (op1) && !flag_trapping_math)
5507
    operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5508
  else
5509
    {
5510
      operands[4] = simplify_gen_subreg (V4SImode, operands[0], mode, 0);
5511
      emit_move_insn (operands[2], operands[1]);
5512
      emit_insn (gen_sse2_loadld (operands[4],
5513
                                  CONST0_RTX (V4SImode), operands[2]));
5514
    }
5515
  emit_insn
5516
    (gen_sse2_cvtdq2p (operands[3], operands[4]));
5517
  DONE;
5518
})
5519
 
5520
(define_split
5521
  [(set (match_operand:MODEF 0 "register_operand" "")
5522
        (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5523
   (clobber (match_operand:SI 2 "memory_operand" ""))]
5524
  "TARGET_SSE2 && TARGET_SSE_MATH
5525
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5526
   && reload_completed
5527
   && (SSE_REG_P (operands[0])
5528
       || (GET_CODE (operands[0]) == SUBREG
5529
           && SSE_REG_P (operands[0])))"
5530
  [(const_int 0)]
5531
{
5532
  operands[3] = simplify_gen_subreg (mode, operands[0],
5533
                                     mode, 0);
5534
  operands[4] = simplify_gen_subreg (V4SImode, operands[0], mode, 0);
5535
 
5536
  emit_insn (gen_sse2_loadld (operands[4],
5537
                              CONST0_RTX (V4SImode), operands[1]));
5538
  emit_insn
5539
    (gen_sse2_cvtdq2p (operands[3], operands[4]));
5540
  DONE;
5541
})
5542
 
5543
(define_split
5544
  [(set (match_operand:MODEF 0 "register_operand" "")
5545
        (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5546
  "TARGET_SSE2 && TARGET_SSE_MATH
5547
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5548
   && reload_completed
5549
   && (SSE_REG_P (operands[0])
5550
       || (GET_CODE (operands[0]) == SUBREG
5551
           && SSE_REG_P (operands[0])))"
5552
  [(const_int 0)]
5553
{
5554
  rtx op1 = operands[1];
5555
 
5556
  operands[3] = simplify_gen_subreg (mode, operands[0],
5557
                                     mode, 0);
5558
  if (GET_CODE (op1) == SUBREG)
5559
    op1 = SUBREG_REG (op1);
5560
 
5561
  if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5562
    {
5563
      operands[4] = simplify_gen_subreg (V4SImode, operands[0], mode, 0);
5564
      emit_insn (gen_sse2_loadld (operands[4],
5565
                                  CONST0_RTX (V4SImode), operands[1]));
5566
    }
5567
  /* We can ignore possible trapping value in the
5568
     high part of SSE register for non-trapping math. */
5569
  else if (SSE_REG_P (op1) && !flag_trapping_math)
5570
    operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5571
  else
5572
    gcc_unreachable ();
5573
  emit_insn
5574
    (gen_sse2_cvtdq2p (operands[3], operands[4]));
5575
  DONE;
5576
})
5577
 
5578
(define_split
5579
  [(set (match_operand:MODEF 0 "register_operand" "")
5580
        (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5581
  "TARGET_SSE2 && TARGET_SSE_MATH
5582
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5583
   && reload_completed
5584
   && (SSE_REG_P (operands[0])
5585
       || (GET_CODE (operands[0]) == SUBREG
5586
           && SSE_REG_P (operands[0])))"
5587
  [(const_int 0)]
5588
{
5589
  operands[3] = simplify_gen_subreg (mode, operands[0],
5590
                                     mode, 0);
5591
  operands[4] = simplify_gen_subreg (V4SImode, operands[0], mode, 0);
5592
 
5593
  emit_insn (gen_sse2_loadld (operands[4],
5594
                              CONST0_RTX (V4SImode), operands[1]));
5595
  emit_insn
5596
    (gen_sse2_cvtdq2p (operands[3], operands[4]));
5597
  DONE;
5598
})
5599
 
5600
(define_insn "*float2_sse_with_temp"
5601
  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5602
        (float:MODEF
5603
          (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5604
  (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5605
  "(mode != DImode || TARGET_64BIT)
5606
   && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
5607
  "#"
5608
  [(set_attr "type" "sseicvt")
5609
   (set_attr "mode" "")
5610
   (set_attr "athlon_decode" "double,direct")
5611
   (set_attr "amdfam10_decode" "vector,double")
5612
   (set_attr "fp_int_src" "true")])
5613
 
5614
(define_insn "*float2_sse_interunit"
5615
  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5616
        (float:MODEF
5617
          (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5618
  "(mode != DImode || TARGET_64BIT)
5619
   && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
5620
   && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5621
  "%vcvtsi2s\t{%1, %d0|%d0, %1}"
5622
  [(set_attr "type" "sseicvt")
5623
   (set_attr "prefix" "maybe_vex")
5624
   (set_attr "mode" "")
5625
   (set (attr "prefix_rex")
5626
     (if_then_else
5627
       (and (eq_attr "prefix" "maybe_vex")
5628
            (ne (symbol_ref "mode == DImode") (const_int 0)))
5629
       (const_string "1")
5630
       (const_string "*")))
5631
   (set_attr "athlon_decode" "double,direct")
5632
   (set_attr "amdfam10_decode" "vector,double")
5633
   (set_attr "fp_int_src" "true")])
5634
 
5635
(define_split
5636
  [(set (match_operand:MODEF 0 "register_operand" "")
5637
        (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5638
   (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5639
  "(mode != DImode || TARGET_64BIT)
5640
   && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
5641
   && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5642
   && reload_completed
5643
   && (SSE_REG_P (operands[0])
5644
       || (GET_CODE (operands[0]) == SUBREG
5645
           && SSE_REG_P (operands[0])))"
5646
  [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5647
  "")
5648
 
5649
(define_insn "*float2_sse_nointerunit"
5650
  [(set (match_operand:MODEF 0 "register_operand" "=x")
5651
        (float:MODEF
5652
          (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5653
  "(mode != DImode || TARGET_64BIT)
5654
   && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
5655
   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5656
  "%vcvtsi2s\t{%1, %d0|%d0, %1}"
5657
  [(set_attr "type" "sseicvt")
5658
   (set_attr "prefix" "maybe_vex")
5659
   (set_attr "mode" "")
5660
   (set (attr "prefix_rex")
5661
     (if_then_else
5662
       (and (eq_attr "prefix" "maybe_vex")
5663
            (ne (symbol_ref "mode == DImode") (const_int 0)))
5664
       (const_string "1")
5665
       (const_string "*")))
5666
   (set_attr "athlon_decode" "direct")
5667
   (set_attr "amdfam10_decode" "double")
5668
   (set_attr "fp_int_src" "true")])
5669
 
5670
(define_split
5671
  [(set (match_operand:MODEF 0 "register_operand" "")
5672
        (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5673
   (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5674
  "(mode != DImode || TARGET_64BIT)
5675
   && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
5676
   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5677
   && reload_completed
5678
   && (SSE_REG_P (operands[0])
5679
       || (GET_CODE (operands[0]) == SUBREG
5680
           && SSE_REG_P (operands[0])))"
5681
  [(set (match_dup 2) (match_dup 1))
5682
   (set (match_dup 0) (float:MODEF (match_dup 2)))]
5683
  "")
5684
 
5685
(define_split
5686
  [(set (match_operand:MODEF 0 "register_operand" "")
5687
        (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5688
   (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5689
  "(mode != DImode || TARGET_64BIT)
5690
   && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
5691
   && reload_completed
5692
   && (SSE_REG_P (operands[0])
5693
       || (GET_CODE (operands[0]) == SUBREG
5694
           && SSE_REG_P (operands[0])))"
5695
  [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5696
  "")
5697
 
5698
(define_insn "*float2_i387_with_temp"
5699
  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5700
        (float:X87MODEF
5701
          (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5702
  (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5703
  "TARGET_80387
5704
   && X87_ENABLE_FLOAT (mode, mode)"
5705
  "@
5706
   fild%Z1\t%1
5707
   #"
5708
  [(set_attr "type" "fmov,multi")
5709
   (set_attr "mode" "")
5710
   (set_attr "unit" "*,i387")
5711
   (set_attr "fp_int_src" "true")])
5712
 
5713
(define_insn "*float2_i387"
5714
  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5715
        (float:X87MODEF
5716
          (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5717
  "TARGET_80387
5718
   && X87_ENABLE_FLOAT (mode, mode)"
5719
  "fild%Z1\t%1"
5720
  [(set_attr "type" "fmov")
5721
   (set_attr "mode" "")
5722
   (set_attr "fp_int_src" "true")])
5723
 
5724
(define_split
5725
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5726
        (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5727
   (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5728
  "TARGET_80387
5729
   && X87_ENABLE_FLOAT (mode, mode)
5730
   && reload_completed
5731
   && FP_REG_P (operands[0])"
5732
  [(set (match_dup 2) (match_dup 1))
5733
   (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5734
  "")
5735
 
5736
(define_split
5737
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5738
        (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5739
   (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5740
  "TARGET_80387
5741
   && X87_ENABLE_FLOAT (mode, mode)
5742
   && reload_completed
5743
   && FP_REG_P (operands[0])"
5744
  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5745
  "")
5746
 
5747
;; Avoid store forwarding (partial memory) stall penalty
5748
;; by passing DImode value through XMM registers.  */
5749
 
5750
(define_insn "floatdi2_i387_with_xmm"
5751
  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5752
        (float:X87MODEF
5753
          (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5754
   (clobber (match_scratch:V4SI 3 "=X,x"))
5755
   (clobber (match_scratch:V4SI 4 "=X,x"))
5756
   (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5757
  "TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5758
   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5759
   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5760
  "#"
5761
  [(set_attr "type" "multi")
5762
   (set_attr "mode" "")
5763
   (set_attr "unit" "i387")
5764
   (set_attr "fp_int_src" "true")])
5765
 
5766
(define_split
5767
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5768
        (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5769
   (clobber (match_scratch:V4SI 3 ""))
5770
   (clobber (match_scratch:V4SI 4 ""))
5771
   (clobber (match_operand:DI 2 "memory_operand" ""))]
5772
  "TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5773
   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5774
   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5775
   && reload_completed
5776
   && FP_REG_P (operands[0])"
5777
  [(set (match_dup 2) (match_dup 3))
5778
   (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5779
{
5780
  /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5781
     Assemble the 64-bit DImode value in an xmm register.  */
5782
  emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5783
                              gen_rtx_SUBREG (SImode, operands[1], 0)));
5784
  emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5785
                              gen_rtx_SUBREG (SImode, operands[1], 4)));
5786
  emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5787
                                         operands[4]));
5788
 
5789
  operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5790
})
5791
 
5792
(define_split
5793
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5794
        (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5795
   (clobber (match_scratch:V4SI 3 ""))
5796
   (clobber (match_scratch:V4SI 4 ""))
5797
   (clobber (match_operand:DI 2 "memory_operand" ""))]
5798
  "TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5799
   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5800
   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5801
   && reload_completed
5802
   && FP_REG_P (operands[0])"
5803
  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5804
  "")
5805
 
5806
;; Avoid store forwarding (partial memory) stall penalty by extending
5807
;; SImode value to DImode through XMM register instead of pushing two
5808
;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5809
;; targets benefit from this optimization. Also note that fild
5810
;; loads from memory only.
5811
 
5812
(define_insn "*floatunssi2_1"
5813
  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5814
        (unsigned_float:X87MODEF
5815
          (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5816
   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5817
   (clobber (match_scratch:SI 3 "=X,x"))]
5818
  "!TARGET_64BIT
5819
   && TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5820
   && TARGET_SSE"
5821
  "#"
5822
  [(set_attr "type" "multi")
5823
   (set_attr "mode" "")])
5824
 
5825
(define_split
5826
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5827
        (unsigned_float:X87MODEF
5828
          (match_operand:SI 1 "register_operand" "")))
5829
   (clobber (match_operand:DI 2 "memory_operand" ""))
5830
   (clobber (match_scratch:SI 3 ""))]
5831
  "!TARGET_64BIT
5832
   && TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5833
   && TARGET_SSE
5834
   && reload_completed"
5835
  [(set (match_dup 2) (match_dup 1))
5836
   (set (match_dup 0)
5837
        (float:X87MODEF (match_dup 2)))]
5838
  "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5839
 
5840
(define_split
5841
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5842
        (unsigned_float:X87MODEF
5843
          (match_operand:SI 1 "memory_operand" "")))
5844
   (clobber (match_operand:DI 2 "memory_operand" ""))
5845
   (clobber (match_scratch:SI 3 ""))]
5846
  "!TARGET_64BIT
5847
   && TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5848
   && TARGET_SSE
5849
   && reload_completed"
5850
  [(set (match_dup 2) (match_dup 3))
5851
   (set (match_dup 0)
5852
        (float:X87MODEF (match_dup 2)))]
5853
{
5854
  emit_move_insn (operands[3], operands[1]);
5855
  operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5856
})
5857
 
5858
(define_expand "floatunssi2"
5859
  [(parallel
5860
     [(set (match_operand:X87MODEF 0 "register_operand" "")
5861
           (unsigned_float:X87MODEF
5862
             (match_operand:SI 1 "nonimmediate_operand" "")))
5863
      (clobber (match_dup 2))
5864
      (clobber (match_scratch:SI 3 ""))])]
5865
  "!TARGET_64BIT
5866
   && ((TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5867
        && TARGET_SSE)
5868
       || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))"
5869
{
5870
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
5871
    {
5872
      ix86_expand_convert_uns_si_sse (operands[0], operands[1]);
5873
      DONE;
5874
    }
5875
  else
5876
    {
5877
      enum ix86_stack_slot slot = (virtuals_instantiated
5878
                                   ? SLOT_TEMP
5879
                                   : SLOT_VIRTUAL);
5880
      operands[2] = assign_386_stack_local (DImode, slot);
5881
    }
5882
})
5883
 
5884
(define_expand "floatunsdisf2"
5885
  [(use (match_operand:SF 0 "register_operand" ""))
5886
   (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5887
  "TARGET_64BIT && TARGET_SSE_MATH"
5888
  "x86_emit_floatuns (operands); DONE;")
5889
 
5890
(define_expand "floatunsdidf2"
5891
  [(use (match_operand:DF 0 "register_operand" ""))
5892
   (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5893
  "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5894
   && TARGET_SSE2 && TARGET_SSE_MATH"
5895
{
5896
  if (TARGET_64BIT)
5897
    x86_emit_floatuns (operands);
5898
  else
5899
    ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5900
  DONE;
5901
})
5902
 
5903
;; Add instructions
5904
 
5905
(define_expand "add3"
5906
  [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5907
        (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5908
                    (match_operand:SDWIM 2 "" "")))]
5909
  ""
5910
  "ix86_expand_binary_operator (PLUS, mode, operands); DONE;")
5911
 
5912
(define_insn_and_split "*add3_doubleword"
5913
  [(set (match_operand: 0 "nonimmediate_operand" "=r,o")
5914
        (plus:
5915
          (match_operand: 1 "nonimmediate_operand" "%0,0")
5916
          (match_operand: 2 "" "ro,r")))
5917
   (clobber (reg:CC FLAGS_REG))]
5918
  "ix86_binary_operator_ok (PLUS, mode, operands)"
5919
  "#"
5920
  "reload_completed"
5921
  [(parallel [(set (reg:CC FLAGS_REG)
5922
                   (unspec:CC [(match_dup 1) (match_dup 2)]
5923
                              UNSPEC_ADD_CARRY))
5924
              (set (match_dup 0)
5925
                   (plus:DWIH (match_dup 1) (match_dup 2)))])
5926
   (parallel [(set (match_dup 3)
5927
                   (plus:DWIH
5928
                     (match_dup 4)
5929
                     (plus:DWIH
5930
                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5931
                       (match_dup 5))))
5932
              (clobber (reg:CC FLAGS_REG))])]
5933
  "split_ (&operands[0], 3, &operands[0], &operands[3]);")
5934
 
5935
(define_insn "*add3_cc"
5936
  [(set (reg:CC FLAGS_REG)
5937
        (unspec:CC
5938
          [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5939
           (match_operand:SWI48 2 "" "r,rm")]
5940
          UNSPEC_ADD_CARRY))
5941
   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5942
        (plus:SWI48 (match_dup 1) (match_dup 2)))]
5943
  "ix86_binary_operator_ok (PLUS, mode, operands)"
5944
  "add{}\t{%2, %0|%0, %2}"
5945
  [(set_attr "type" "alu")
5946
   (set_attr "mode" "")])
5947
 
5948
(define_insn "addqi3_cc"
5949
  [(set (reg:CC FLAGS_REG)
5950
        (unspec:CC
5951
          [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5952
           (match_operand:QI 2 "general_operand" "qn,qm")]
5953
          UNSPEC_ADD_CARRY))
5954
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5955
        (plus:QI (match_dup 1) (match_dup 2)))]
5956
  "ix86_binary_operator_ok (PLUS, QImode, operands)"
5957
  "add{b}\t{%2, %0|%0, %2}"
5958
  [(set_attr "type" "alu")
5959
   (set_attr "mode" "QI")])
5960
 
5961
(define_insn "*lea_1"
5962
  [(set (match_operand:DWIH 0 "register_operand" "=r")
5963
        (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5964
  ""
5965
  "lea{}\t{%a1, %0|%0, %a1}"
5966
  [(set_attr "type" "lea")
5967
   (set_attr "mode" "")])
5968
 
5969
(define_insn "*lea_2"
5970
  [(set (match_operand:SI 0 "register_operand" "=r")
5971
        (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5972
  "TARGET_64BIT"
5973
  "lea{l}\t{%a1, %0|%0, %a1}"
5974
  [(set_attr "type" "lea")
5975
   (set_attr "mode" "SI")])
5976
 
5977
(define_insn "*lea_2_zext"
5978
  [(set (match_operand:DI 0 "register_operand" "=r")
5979
        (zero_extend:DI
5980
          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5981
  "TARGET_64BIT"
5982
  "lea{l}\t{%a1, %k0|%k0, %a1}"
5983
  [(set_attr "type" "lea")
5984
   (set_attr "mode" "SI")])
5985
 
5986
(define_insn "*add_1"
5987
  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5988
        (plus:SWI48
5989
          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5990
          (match_operand:SWI48 2 "" ",r,0,l")))
5991
   (clobber (reg:CC FLAGS_REG))]
5992
  "ix86_binary_operator_ok (PLUS, mode, operands)"
5993
{
5994
  switch (get_attr_type (insn))
5995
    {
5996
    case TYPE_LEA:
5997
      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5998
      return "lea{}\t{%a2, %0|%0, %a2}";
5999
 
6000
    case TYPE_INCDEC:
6001
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6002
      if (operands[2] == const1_rtx)
6003
        return "inc{}\t%0";
6004
      else
6005
        {
6006
          gcc_assert (operands[2] == constm1_rtx);
6007
          return "dec{}\t%0";
6008
        }
6009
 
6010
    default:
6011
      /* Use add as much as possible to replace lea for AGU optimization. */
6012
      if (which_alternative == 2 && TARGET_OPT_AGU)
6013
        return "add{}\t{%1, %0|%0, %1}";
6014
 
6015
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6016
 
6017
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6018
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6019
      if (CONST_INT_P (operands[2])
6020
          /* Avoid overflows.  */
6021
          && (mode != DImode
6022
              || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6023
          && (INTVAL (operands[2]) == 128
6024
              || (INTVAL (operands[2]) < 0
6025
                  && INTVAL (operands[2]) != -128)))
6026
        {
6027
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6028
          return "sub{}\t{%2, %0|%0, %2}";
6029
        }
6030
      return "add{}\t{%2, %0|%0, %2}";
6031
    }
6032
}
6033
  [(set (attr "type")
6034
     (cond [(and (eq_attr "alternative" "2")
6035
                 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6036
              (const_string "lea")
6037
            (eq_attr "alternative" "3")
6038
              (const_string "lea")
6039
            ; Current assemblers are broken and do not allow @GOTOFF in
6040
            ; ought but a memory context.
6041
            (match_operand:SWI48 2 "pic_symbolic_operand" "")
6042
              (const_string "lea")
6043
            (match_operand:SWI48 2 "incdec_operand" "")
6044
              (const_string "incdec")
6045
           ]
6046
           (const_string "alu")))
6047
   (set (attr "length_immediate")
6048
      (if_then_else
6049
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6050
        (const_string "1")
6051
        (const_string "*")))
6052
   (set_attr "mode" "")])
6053
 
6054
;; It may seem that nonimmediate operand is proper one for operand 1.
6055
;; The addsi_1 pattern allows nonimmediate operand at that place and
6056
;; we take care in ix86_binary_operator_ok to not allow two memory
6057
;; operands so proper swapping will be done in reload.  This allow
6058
;; patterns constructed from addsi_1 to match.
6059
 
6060
(define_insn "*addsi_1_zext"
6061
  [(set (match_operand:DI 0 "register_operand" "=r,r")
6062
        (zero_extend:DI
6063
          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6064
                   (match_operand:SI 2 "general_operand" "g,li"))))
6065
   (clobber (reg:CC FLAGS_REG))]
6066
  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6067
{
6068
  switch (get_attr_type (insn))
6069
    {
6070
    case TYPE_LEA:
6071
      operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6072
      return "lea{l}\t{%a2, %k0|%k0, %a2}";
6073
 
6074
    case TYPE_INCDEC:
6075
      if (operands[2] == const1_rtx)
6076
        return "inc{l}\t%k0";
6077
      else
6078
        {
6079
          gcc_assert (operands[2] == constm1_rtx);
6080
          return "dec{l}\t%k0";
6081
        }
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 (CONST_INT_P (operands[2])
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{l}\t{%2, %k0|%k0, %2}";
6093
        }
6094
      return "add{l}\t{%2, %k0|%k0, %2}";
6095
    }
6096
}
6097
  [(set (attr "type")
6098
     (cond [(eq_attr "alternative" "1")
6099
              (const_string "lea")
6100
            ; Current assemblers are broken and do not allow @GOTOFF in
6101
            ; ought but a memory context.
6102
            (match_operand:SI 2 "pic_symbolic_operand" "")
6103
              (const_string "lea")
6104
            (match_operand:SI 2 "incdec_operand" "")
6105
              (const_string "incdec")
6106
           ]
6107
           (const_string "alu")))
6108
   (set (attr "length_immediate")
6109
      (if_then_else
6110
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6111
        (const_string "1")
6112
        (const_string "*")))
6113
   (set_attr "mode" "SI")])
6114
 
6115
(define_insn "*addhi_1"
6116
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6117
        (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6118
                 (match_operand:HI 2 "general_operand" "rn,rm")))
6119
   (clobber (reg:CC FLAGS_REG))]
6120
  "TARGET_PARTIAL_REG_STALL
6121
   && ix86_binary_operator_ok (PLUS, HImode, operands)"
6122
{
6123
  switch (get_attr_type (insn))
6124
    {
6125
    case TYPE_INCDEC:
6126
      if (operands[2] == const1_rtx)
6127
        return "inc{w}\t%0";
6128
      else
6129
        {
6130
          gcc_assert (operands[2] == constm1_rtx);
6131
          return "dec{w}\t%0";
6132
        }
6133
 
6134
    default:
6135
      /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6136
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6137
      if (CONST_INT_P (operands[2])
6138
          && (INTVAL (operands[2]) == 128
6139
              || (INTVAL (operands[2]) < 0
6140
                  && INTVAL (operands[2]) != -128)))
6141
        {
6142
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6143
          return "sub{w}\t{%2, %0|%0, %2}";
6144
        }
6145
      return "add{w}\t{%2, %0|%0, %2}";
6146
    }
6147
}
6148
  [(set (attr "type")
6149
     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6150
        (const_string "incdec")
6151
        (const_string "alu")))
6152
   (set (attr "length_immediate")
6153
      (if_then_else
6154
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6155
        (const_string "1")
6156
        (const_string "*")))
6157
   (set_attr "mode" "HI")])
6158
 
6159
;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6160
;; type optimizations enabled by define-splits.  This is not important
6161
;; for PII, and in fact harmful because of partial register stalls.
6162
 
6163
(define_insn "*addhi_1_lea"
6164
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6165
        (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6166
                 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6167
   (clobber (reg:CC FLAGS_REG))]
6168
  "!TARGET_PARTIAL_REG_STALL
6169
   && ix86_binary_operator_ok (PLUS, HImode, operands)"
6170
{
6171
  switch (get_attr_type (insn))
6172
    {
6173
    case TYPE_LEA:
6174
      return "#";
6175
    case TYPE_INCDEC:
6176
      if (operands[2] == const1_rtx)
6177
        return "inc{w}\t%0";
6178
      else
6179
        {
6180
          gcc_assert (operands[2] == constm1_rtx);
6181
          return "dec{w}\t%0";
6182
        }
6183
 
6184
    default:
6185
      /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6186
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6187
      if (CONST_INT_P (operands[2])
6188
          && (INTVAL (operands[2]) == 128
6189
              || (INTVAL (operands[2]) < 0
6190
                  && INTVAL (operands[2]) != -128)))
6191
        {
6192
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6193
          return "sub{w}\t{%2, %0|%0, %2}";
6194
        }
6195
      return "add{w}\t{%2, %0|%0, %2}";
6196
    }
6197
}
6198
  [(set (attr "type")
6199
     (if_then_else (eq_attr "alternative" "2")
6200
        (const_string "lea")
6201
        (if_then_else (match_operand:HI 2 "incdec_operand" "")
6202
           (const_string "incdec")
6203
           (const_string "alu"))))
6204
   (set (attr "length_immediate")
6205
      (if_then_else
6206
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6207
        (const_string "1")
6208
        (const_string "*")))
6209
   (set_attr "mode" "HI,HI,SI")])
6210
 
6211
(define_insn "*addqi_1"
6212
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6213
        (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6214
                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6215
   (clobber (reg:CC FLAGS_REG))]
6216
  "TARGET_PARTIAL_REG_STALL
6217
   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6218
{
6219
  int widen = (which_alternative == 2);
6220
  switch (get_attr_type (insn))
6221
    {
6222
    case TYPE_INCDEC:
6223
      if (operands[2] == const1_rtx)
6224
        return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6225
      else
6226
        {
6227
          gcc_assert (operands[2] == constm1_rtx);
6228
          return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6229
        }
6230
 
6231
    default:
6232
      /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6233
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6234
      if (CONST_INT_P (operands[2])
6235
          && (INTVAL (operands[2]) == 128
6236
              || (INTVAL (operands[2]) < 0
6237
                  && INTVAL (operands[2]) != -128)))
6238
        {
6239
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6240
          if (widen)
6241
            return "sub{l}\t{%2, %k0|%k0, %2}";
6242
          else
6243
            return "sub{b}\t{%2, %0|%0, %2}";
6244
        }
6245
      if (widen)
6246
        return "add{l}\t{%k2, %k0|%k0, %k2}";
6247
      else
6248
        return "add{b}\t{%2, %0|%0, %2}";
6249
    }
6250
}
6251
  [(set (attr "type")
6252
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6253
        (const_string "incdec")
6254
        (const_string "alu")))
6255
   (set (attr "length_immediate")
6256
      (if_then_else
6257
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6258
        (const_string "1")
6259
        (const_string "*")))
6260
   (set_attr "mode" "QI,QI,SI")])
6261
 
6262
;; %%% Potential partial reg stall on alternative 2.  What to do?
6263
(define_insn "*addqi_1_lea"
6264
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6265
        (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6266
                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6267
   (clobber (reg:CC FLAGS_REG))]
6268
  "!TARGET_PARTIAL_REG_STALL
6269
   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6270
{
6271
  int widen = (which_alternative == 2);
6272
  switch (get_attr_type (insn))
6273
    {
6274
    case TYPE_LEA:
6275
      return "#";
6276
    case TYPE_INCDEC:
6277
      if (operands[2] == const1_rtx)
6278
        return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6279
      else
6280
        {
6281
          gcc_assert (operands[2] == constm1_rtx);
6282
          return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6283
        }
6284
 
6285
    default:
6286
      /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6287
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6288
      if (CONST_INT_P (operands[2])
6289
          && (INTVAL (operands[2]) == 128
6290
              || (INTVAL (operands[2]) < 0
6291
                  && INTVAL (operands[2]) != -128)))
6292
        {
6293
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6294
          if (widen)
6295
            return "sub{l}\t{%2, %k0|%k0, %2}";
6296
          else
6297
            return "sub{b}\t{%2, %0|%0, %2}";
6298
        }
6299
      if (widen)
6300
        return "add{l}\t{%k2, %k0|%k0, %k2}";
6301
      else
6302
        return "add{b}\t{%2, %0|%0, %2}";
6303
    }
6304
}
6305
  [(set (attr "type")
6306
     (if_then_else (eq_attr "alternative" "3")
6307
        (const_string "lea")
6308
        (if_then_else (match_operand:QI 2 "incdec_operand" "")
6309
           (const_string "incdec")
6310
           (const_string "alu"))))
6311
   (set (attr "length_immediate")
6312
      (if_then_else
6313
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6314
        (const_string "1")
6315
        (const_string "*")))
6316
   (set_attr "mode" "QI,QI,SI,SI")])
6317
 
6318
(define_insn "*addqi_1_slp"
6319
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6320
        (plus:QI (match_dup 0)
6321
                 (match_operand:QI 1 "general_operand" "qn,qnm")))
6322
   (clobber (reg:CC FLAGS_REG))]
6323
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6324
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6325
{
6326
  switch (get_attr_type (insn))
6327
    {
6328
    case TYPE_INCDEC:
6329
      if (operands[1] == const1_rtx)
6330
        return "inc{b}\t%0";
6331
      else
6332
        {
6333
          gcc_assert (operands[1] == constm1_rtx);
6334
          return "dec{b}\t%0";
6335
        }
6336
 
6337
    default:
6338
      /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6339
      if (CONST_INT_P (operands[1])
6340
          && INTVAL (operands[1]) < 0)
6341
        {
6342
          operands[1] = GEN_INT (-INTVAL (operands[1]));
6343
          return "sub{b}\t{%1, %0|%0, %1}";
6344
        }
6345
      return "add{b}\t{%1, %0|%0, %1}";
6346
    }
6347
}
6348
  [(set (attr "type")
6349
     (if_then_else (match_operand:QI 1 "incdec_operand" "")
6350
        (const_string "incdec")
6351
        (const_string "alu1")))
6352
   (set (attr "memory")
6353
     (if_then_else (match_operand 1 "memory_operand" "")
6354
        (const_string "load")
6355
        (const_string "none")))
6356
   (set_attr "mode" "QI")])
6357
 
6358
(define_insn "*add_2"
6359
  [(set (reg FLAGS_REG)
6360
        (compare
6361
          (plus:SWI48
6362
            (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6363
            (match_operand:SWI48 2 "" ",r"))
6364
          (const_int 0)))
6365
   (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6366
        (plus:SWI48 (match_dup 1) (match_dup 2)))]
6367
  "ix86_match_ccmode (insn, CCGOCmode)
6368
   && ix86_binary_operator_ok (PLUS, mode, operands)
6369
   /* Current assemblers are broken and do not allow @GOTOFF in
6370
      ought but a memory context.  */
6371
   && ! pic_symbolic_operand (operands[2], VOIDmode)"
6372
{
6373
  switch (get_attr_type (insn))
6374
    {
6375
    case TYPE_INCDEC:
6376
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6377
      if (operands[2] == const1_rtx)
6378
        return "inc{}\t%0";
6379
      else
6380
        {
6381
          gcc_assert (operands[2] == constm1_rtx);
6382
          return "dec{}\t%0";
6383
        }
6384
 
6385
    default:
6386
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6387
      /* ???? In DImode, we ought to handle there the 32bit case too
6388
         - do we need new constraint?  */
6389
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6390
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6391
      if (CONST_INT_P (operands[2])
6392
          /* Avoid overflows.  */
6393
          && (mode != DImode
6394
              || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6395
          && (INTVAL (operands[2]) == 128
6396
              || (INTVAL (operands[2]) < 0
6397
                  && INTVAL (operands[2]) != -128)))
6398
        {
6399
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6400
          return "sub{}\t{%2, %0|%0, %2}";
6401
        }
6402
      return "add{}\t{%2, %0|%0, %2}";
6403
    }
6404
}
6405
  [(set (attr "type")
6406
     (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6407
        (const_string "incdec")
6408
        (const_string "alu")))
6409
   (set (attr "length_immediate")
6410
      (if_then_else
6411
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6412
        (const_string "1")
6413
        (const_string "*")))
6414
   (set_attr "mode" "")])
6415
 
6416
;; See comment for addsi_1_zext why we do use nonimmediate_operand
6417
(define_insn "*addsi_2_zext"
6418
  [(set (reg FLAGS_REG)
6419
        (compare
6420
          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6421
                   (match_operand:SI 2 "general_operand" "g"))
6422
          (const_int 0)))
6423
   (set (match_operand:DI 0 "register_operand" "=r")
6424
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6425
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6426
   && ix86_binary_operator_ok (PLUS, SImode, operands)
6427
   /* Current assemblers are broken and do not allow @GOTOFF in
6428
      ought but a memory context.  */
6429
   && ! pic_symbolic_operand (operands[2], VOIDmode)"
6430
{
6431
  switch (get_attr_type (insn))
6432
    {
6433
    case TYPE_INCDEC:
6434
      if (operands[2] == const1_rtx)
6435
        return "inc{l}\t%k0";
6436
      else
6437
        {
6438
          gcc_assert (operands[2] == constm1_rtx);
6439
          return "dec{l}\t%k0";
6440
        }
6441
 
6442
    default:
6443
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6444
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6445
      if (CONST_INT_P (operands[2])
6446
          && (INTVAL (operands[2]) == 128
6447
              || (INTVAL (operands[2]) < 0
6448
                  && INTVAL (operands[2]) != -128)))
6449
        {
6450
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6451
          return "sub{l}\t{%2, %k0|%k0, %2}";
6452
        }
6453
      return "add{l}\t{%2, %k0|%k0, %2}";
6454
    }
6455
}
6456
  [(set (attr "type")
6457
     (if_then_else (match_operand:SI 2 "incdec_operand" "")
6458
        (const_string "incdec")
6459
        (const_string "alu")))
6460
   (set (attr "length_immediate")
6461
      (if_then_else
6462
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6463
        (const_string "1")
6464
        (const_string "*")))
6465
   (set_attr "mode" "SI")])
6466
 
6467
(define_insn "*addhi_2"
6468
  [(set (reg FLAGS_REG)
6469
        (compare
6470
          (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6471
                   (match_operand:HI 2 "general_operand" "rmn,rn"))
6472
          (const_int 0)))
6473
   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6474
        (plus:HI (match_dup 1) (match_dup 2)))]
6475
  "ix86_match_ccmode (insn, CCGOCmode)
6476
   && ix86_binary_operator_ok (PLUS, HImode, operands)"
6477
{
6478
  switch (get_attr_type (insn))
6479
    {
6480
    case TYPE_INCDEC:
6481
      if (operands[2] == const1_rtx)
6482
        return "inc{w}\t%0";
6483
      else
6484
        {
6485
          gcc_assert (operands[2] == constm1_rtx);
6486
          return "dec{w}\t%0";
6487
        }
6488
 
6489
    default:
6490
      /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6491
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6492
      if (CONST_INT_P (operands[2])
6493
          && (INTVAL (operands[2]) == 128
6494
              || (INTVAL (operands[2]) < 0
6495
                  && INTVAL (operands[2]) != -128)))
6496
        {
6497
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6498
          return "sub{w}\t{%2, %0|%0, %2}";
6499
        }
6500
      return "add{w}\t{%2, %0|%0, %2}";
6501
    }
6502
}
6503
  [(set (attr "type")
6504
     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6505
        (const_string "incdec")
6506
        (const_string "alu")))
6507
   (set (attr "length_immediate")
6508
      (if_then_else
6509
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6510
        (const_string "1")
6511
        (const_string "*")))
6512
   (set_attr "mode" "HI")])
6513
 
6514
(define_insn "*addqi_2"
6515
  [(set (reg FLAGS_REG)
6516
        (compare
6517
          (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6518
                   (match_operand:QI 2 "general_operand" "qmn,qn"))
6519
          (const_int 0)))
6520
   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6521
        (plus:QI (match_dup 1) (match_dup 2)))]
6522
  "ix86_match_ccmode (insn, CCGOCmode)
6523
   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6524
{
6525
  switch (get_attr_type (insn))
6526
    {
6527
    case TYPE_INCDEC:
6528
      if (operands[2] == const1_rtx)
6529
        return "inc{b}\t%0";
6530
      else
6531
        {
6532
          gcc_assert (operands[2] == constm1_rtx
6533
                      || (CONST_INT_P (operands[2])
6534
                          && INTVAL (operands[2]) == 255));
6535
          return "dec{b}\t%0";
6536
        }
6537
 
6538
    default:
6539
      /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6540
      if (CONST_INT_P (operands[2])
6541
          && INTVAL (operands[2]) < 0)
6542
        {
6543
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6544
          return "sub{b}\t{%2, %0|%0, %2}";
6545
        }
6546
      return "add{b}\t{%2, %0|%0, %2}";
6547
    }
6548
}
6549
  [(set (attr "type")
6550
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6551
        (const_string "incdec")
6552
        (const_string "alu")))
6553
   (set_attr "mode" "QI")])
6554
 
6555
(define_insn "*add_3"
6556
  [(set (reg FLAGS_REG)
6557
        (compare
6558
          (neg:SWI48 (match_operand:SWI48 2 "" ""))
6559
          (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6560
   (clobber (match_scratch:SWI48 0 "=r"))]
6561
  "ix86_match_ccmode (insn, CCZmode)
6562
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6563
   /* Current assemblers are broken and do not allow @GOTOFF in
6564
      ought but a memory context.  */
6565
   && ! pic_symbolic_operand (operands[2], VOIDmode)"
6566
{
6567
  switch (get_attr_type (insn))
6568
    {
6569
    case TYPE_INCDEC:
6570
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6571
      if (operands[2] == const1_rtx)
6572
        return "inc{}\t%0";
6573
      else
6574
        {
6575
          gcc_assert (operands[2] == constm1_rtx);
6576
          return "dec{}\t%0";
6577
        }
6578
 
6579
    default:
6580
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6581
      /* ???? In DImode, we ought to handle there the 32bit case too
6582
         - do we need new constraint?  */
6583
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6584
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6585
      if (CONST_INT_P (operands[2])
6586
          /* Avoid overflows.  */
6587
          && (mode != DImode
6588
              || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6589
          && (INTVAL (operands[2]) == 128
6590
              || (INTVAL (operands[2]) < 0
6591
                  && INTVAL (operands[2]) != -128)))
6592
        {
6593
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6594
          return "sub{}\t{%2, %0|%0, %2}";
6595
        }
6596
      return "add{}\t{%2, %0|%0, %2}";
6597
    }
6598
}
6599
  [(set (attr "type")
6600
     (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6601
        (const_string "incdec")
6602
        (const_string "alu")))
6603
   (set (attr "length_immediate")
6604
      (if_then_else
6605
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6606
        (const_string "1")
6607
        (const_string "*")))
6608
   (set_attr "mode" "")])
6609
 
6610
;; See comment for addsi_1_zext why we do use nonimmediate_operand
6611
(define_insn "*addsi_3_zext"
6612
  [(set (reg FLAGS_REG)
6613
        (compare
6614
          (neg:SI (match_operand:SI 2 "general_operand" "g"))
6615
          (match_operand:SI 1 "nonimmediate_operand" "%0")))
6616
   (set (match_operand:DI 0 "register_operand" "=r")
6617
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6618
  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6619
   && ix86_binary_operator_ok (PLUS, SImode, operands)
6620
   /* Current assemblers are broken and do not allow @GOTOFF in
6621
      ought but a memory context.  */
6622
   && ! pic_symbolic_operand (operands[2], VOIDmode)"
6623
{
6624
  switch (get_attr_type (insn))
6625
    {
6626
    case TYPE_INCDEC:
6627
      if (operands[2] == const1_rtx)
6628
        return "inc{l}\t%k0";
6629
      else
6630
        {
6631
          gcc_assert (operands[2] == constm1_rtx);
6632
          return "dec{l}\t%k0";
6633
        }
6634
 
6635
    default:
6636
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6637
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6638
      if (CONST_INT_P (operands[2])
6639
          && (INTVAL (operands[2]) == 128
6640
              || (INTVAL (operands[2]) < 0
6641
                  && INTVAL (operands[2]) != -128)))
6642
        {
6643
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6644
          return "sub{l}\t{%2, %k0|%k0, %2}";
6645
        }
6646
      return "add{l}\t{%2, %k0|%k0, %2}";
6647
    }
6648
}
6649
  [(set (attr "type")
6650
     (if_then_else (match_operand:SI 2 "incdec_operand" "")
6651
        (const_string "incdec")
6652
        (const_string "alu")))
6653
   (set (attr "length_immediate")
6654
      (if_then_else
6655
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6656
        (const_string "1")
6657
        (const_string "*")))
6658
   (set_attr "mode" "SI")])
6659
 
6660
(define_insn "*addhi_3"
6661
  [(set (reg FLAGS_REG)
6662
        (compare
6663
          (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6664
          (match_operand:HI 1 "nonimmediate_operand" "%0")))
6665
   (clobber (match_scratch:HI 0 "=r"))]
6666
  "ix86_match_ccmode (insn, CCZmode)
6667
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6668
{
6669
  switch (get_attr_type (insn))
6670
    {
6671
    case TYPE_INCDEC:
6672
      if (operands[2] == const1_rtx)
6673
        return "inc{w}\t%0";
6674
      else
6675
        {
6676
          gcc_assert (operands[2] == constm1_rtx);
6677
          return "dec{w}\t%0";
6678
        }
6679
 
6680
    default:
6681
      /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6682
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6683
      if (CONST_INT_P (operands[2])
6684
          && (INTVAL (operands[2]) == 128
6685
              || (INTVAL (operands[2]) < 0
6686
                  && INTVAL (operands[2]) != -128)))
6687
        {
6688
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6689
          return "sub{w}\t{%2, %0|%0, %2}";
6690
        }
6691
      return "add{w}\t{%2, %0|%0, %2}";
6692
    }
6693
}
6694
  [(set (attr "type")
6695
     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6696
        (const_string "incdec")
6697
        (const_string "alu")))
6698
   (set (attr "length_immediate")
6699
      (if_then_else
6700
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6701
        (const_string "1")
6702
        (const_string "*")))
6703
   (set_attr "mode" "HI")])
6704
 
6705
(define_insn "*addqi_3"
6706
  [(set (reg FLAGS_REG)
6707
        (compare
6708
          (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6709
          (match_operand:QI 1 "nonimmediate_operand" "%0")))
6710
   (clobber (match_scratch:QI 0 "=q"))]
6711
  "ix86_match_ccmode (insn, CCZmode)
6712
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6713
{
6714
  switch (get_attr_type (insn))
6715
    {
6716
    case TYPE_INCDEC:
6717
      if (operands[2] == const1_rtx)
6718
        return "inc{b}\t%0";
6719
      else
6720
        {
6721
          gcc_assert (operands[2] == constm1_rtx
6722
                      || (CONST_INT_P (operands[2])
6723
                          && INTVAL (operands[2]) == 255));
6724
          return "dec{b}\t%0";
6725
        }
6726
 
6727
    default:
6728
      /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6729
      if (CONST_INT_P (operands[2])
6730
          && INTVAL (operands[2]) < 0)
6731
        {
6732
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6733
          return "sub{b}\t{%2, %0|%0, %2}";
6734
        }
6735
      return "add{b}\t{%2, %0|%0, %2}";
6736
    }
6737
}
6738
  [(set (attr "type")
6739
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6740
        (const_string "incdec")
6741
        (const_string "alu")))
6742
   (set_attr "mode" "QI")])
6743
 
6744
; For comparisons against 1, -1 and 128, we may generate better code
6745
; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6746
; is matched then.  We can't accept general immediate, because for
6747
; case of overflows,  the result is messed up.
6748
; This pattern also don't hold of 0x8000000000000000, since the value
6749
; overflows when negated.
6750
; Also carry flag is reversed compared to cmp, so this conversion is valid
6751
; only for comparisons not depending on it.
6752
 
6753
(define_insn "*adddi_4"
6754
  [(set (reg FLAGS_REG)
6755
        (compare
6756
          (match_operand:DI 1 "nonimmediate_operand" "0")
6757
          (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6758
   (clobber (match_scratch:DI 0 "=rm"))]
6759
  "TARGET_64BIT
6760
   && ix86_match_ccmode (insn, CCGCmode)"
6761
{
6762
  switch (get_attr_type (insn))
6763
    {
6764
    case TYPE_INCDEC:
6765
      if (operands[2] == constm1_rtx)
6766
        return "inc{q}\t%0";
6767
      else
6768
        {
6769
          gcc_assert (operands[2] == const1_rtx);
6770
          return "dec{q}\t%0";
6771
        }
6772
 
6773
    default:
6774
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6775
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6776
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6777
      if ((INTVAL (operands[2]) == -128
6778
           || (INTVAL (operands[2]) > 0
6779
               && INTVAL (operands[2]) != 128))
6780
          /* Avoid overflows.  */
6781
          && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6782
        return "sub{q}\t{%2, %0|%0, %2}";
6783
      operands[2] = GEN_INT (-INTVAL (operands[2]));
6784
      return "add{q}\t{%2, %0|%0, %2}";
6785
    }
6786
}
6787
  [(set (attr "type")
6788
     (if_then_else (match_operand:DI 2 "incdec_operand" "")
6789
        (const_string "incdec")
6790
        (const_string "alu")))
6791
   (set (attr "length_immediate")
6792
      (if_then_else
6793
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6794
        (const_string "1")
6795
        (const_string "*")))
6796
   (set_attr "mode" "DI")])
6797
 
6798
; For comparisons against 1, -1 and 128, we may generate better code
6799
; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6800
; is matched then.  We can't accept general immediate, because for
6801
; case of overflows,  the result is messed up.
6802
; This pattern also don't hold of 0x80000000, since the value overflows
6803
; when negated.
6804
; Also carry flag is reversed compared to cmp, so this conversion is valid
6805
; only for comparisons not depending on it.
6806
 
6807
(define_insn "*addsi_4"
6808
  [(set (reg FLAGS_REG)
6809
        (compare
6810
          (match_operand:SI 1 "nonimmediate_operand" "0")
6811
          (match_operand:SI 2 "const_int_operand" "n")))
6812
   (clobber (match_scratch:SI 0 "=rm"))]
6813
  "ix86_match_ccmode (insn, CCGCmode)
6814
   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6815
{
6816
  switch (get_attr_type (insn))
6817
    {
6818
    case TYPE_INCDEC:
6819
      if (operands[2] == constm1_rtx)
6820
        return "inc{l}\t%0";
6821
      else
6822
        {
6823
          gcc_assert (operands[2] == const1_rtx);
6824
          return "dec{l}\t%0";
6825
        }
6826
 
6827
    default:
6828
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6829
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6830
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6831
      if ((INTVAL (operands[2]) == -128
6832
           || (INTVAL (operands[2]) > 0
6833
               && INTVAL (operands[2]) != 128)))
6834
        return "sub{l}\t{%2, %0|%0, %2}";
6835
      operands[2] = GEN_INT (-INTVAL (operands[2]));
6836
      return "add{l}\t{%2, %0|%0, %2}";
6837
    }
6838
}
6839
  [(set (attr "type")
6840
     (if_then_else (match_operand:SI 2 "incdec_operand" "")
6841
        (const_string "incdec")
6842
        (const_string "alu")))
6843
   (set (attr "length_immediate")
6844
      (if_then_else
6845
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6846
        (const_string "1")
6847
        (const_string "*")))
6848
   (set_attr "mode" "SI")])
6849
 
6850
; See comments above addsi_4 for details.
6851
 
6852
(define_insn "*addhi_4"
6853
  [(set (reg FLAGS_REG)
6854
        (compare
6855
          (match_operand:HI 1 "nonimmediate_operand" "0")
6856
          (match_operand:HI 2 "const_int_operand" "n")))
6857
   (clobber (match_scratch:HI 0 "=rm"))]
6858
  "ix86_match_ccmode (insn, CCGCmode)
6859
   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6860
{
6861
  switch (get_attr_type (insn))
6862
    {
6863
    case TYPE_INCDEC:
6864
      if (operands[2] == constm1_rtx)
6865
        return "inc{w}\t%0";
6866
      else
6867
        {
6868
          gcc_assert (operands[2] == const1_rtx);
6869
          return "dec{w}\t%0";
6870
        }
6871
 
6872
    default:
6873
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6874
      /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6875
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6876
      if ((INTVAL (operands[2]) == -128
6877
           || (INTVAL (operands[2]) > 0
6878
               && INTVAL (operands[2]) != 128)))
6879
        return "sub{w}\t{%2, %0|%0, %2}";
6880
      operands[2] = GEN_INT (-INTVAL (operands[2]));
6881
      return "add{w}\t{%2, %0|%0, %2}";
6882
    }
6883
}
6884
  [(set (attr "type")
6885
     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6886
        (const_string "incdec")
6887
        (const_string "alu")))
6888
   (set (attr "length_immediate")
6889
      (if_then_else
6890
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6891
        (const_string "1")
6892
        (const_string "*")))
6893
   (set_attr "mode" "HI")])
6894
 
6895
; See comments above addsi_4 for details.
6896
 
6897
(define_insn "*addqi_4"
6898
  [(set (reg FLAGS_REG)
6899
        (compare
6900
          (match_operand:QI 1 "nonimmediate_operand" "0")
6901
          (match_operand:QI 2 "const_int_operand" "n")))
6902
   (clobber (match_scratch:QI 0 "=qm"))]
6903
  "ix86_match_ccmode (insn, CCGCmode)
6904
   && (INTVAL (operands[2]) & 0xff) != 0x80"
6905
{
6906
  switch (get_attr_type (insn))
6907
    {
6908
    case TYPE_INCDEC:
6909
      if (operands[2] == constm1_rtx
6910
          || (CONST_INT_P (operands[2])
6911
              && INTVAL (operands[2]) == 255))
6912
        return "inc{b}\t%0";
6913
      else
6914
        {
6915
          gcc_assert (operands[2] == const1_rtx);
6916
          return "dec{b}\t%0";
6917
        }
6918
 
6919
    default:
6920
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6921
      if (INTVAL (operands[2]) < 0)
6922
        {
6923
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6924
          return "add{b}\t{%2, %0|%0, %2}";
6925
        }
6926
      return "sub{b}\t{%2, %0|%0, %2}";
6927
    }
6928
}
6929
  [(set (attr "type")
6930
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6931
        (const_string "incdec")
6932
        (const_string "alu")))
6933
   (set_attr "mode" "QI")])
6934
 
6935
(define_insn "*add_5"
6936
  [(set (reg FLAGS_REG)
6937
        (compare
6938
          (plus:SWI48
6939
            (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6940
            (match_operand:SWI48 2 "" ""))
6941
          (const_int 0)))
6942
   (clobber (match_scratch:SWI48 0 "=r"))]
6943
  "ix86_match_ccmode (insn, CCGOCmode)
6944
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6945
   /* Current assemblers are broken and do not allow @GOTOFF in
6946
      ought but a memory context.  */
6947
   && ! pic_symbolic_operand (operands[2], VOIDmode)"
6948
{
6949
  switch (get_attr_type (insn))
6950
    {
6951
    case TYPE_INCDEC:
6952
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6953
      if (operands[2] == const1_rtx)
6954
        return "inc{}\t%0";
6955
      else
6956
        {
6957
          gcc_assert (operands[2] == constm1_rtx);
6958
          return "dec{}\t%0";
6959
        }
6960
 
6961
    default:
6962
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6963
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6964
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6965
      if (CONST_INT_P (operands[2])
6966
          /* Avoid overflows.  */
6967
          && (mode != DImode
6968
              || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6969
          && (INTVAL (operands[2]) == 128
6970
              || (INTVAL (operands[2]) < 0
6971
                  && INTVAL (operands[2]) != -128)))
6972
        {
6973
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6974
          return "sub{}\t{%2, %0|%0, %2}";
6975
        }
6976
      return "add{}\t{%2, %0|%0, %2}";
6977
    }
6978
}
6979
  [(set (attr "type")
6980
     (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6981
        (const_string "incdec")
6982
        (const_string "alu")))
6983
   (set (attr "length_immediate")
6984
      (if_then_else
6985
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6986
        (const_string "1")
6987
        (const_string "*")))
6988
   (set_attr "mode" "")])
6989
 
6990
(define_insn "*addhi_5"
6991
  [(set (reg FLAGS_REG)
6992
        (compare
6993
          (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6994
                   (match_operand:HI 2 "general_operand" "rmn"))
6995
          (const_int 0)))
6996
   (clobber (match_scratch:HI 0 "=r"))]
6997
  "ix86_match_ccmode (insn, CCGOCmode)
6998
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6999
{
7000
  switch (get_attr_type (insn))
7001
    {
7002
    case TYPE_INCDEC:
7003
      if (operands[2] == const1_rtx)
7004
        return "inc{w}\t%0";
7005
      else
7006
        {
7007
          gcc_assert (operands[2] == constm1_rtx);
7008
          return "dec{w}\t%0";
7009
        }
7010
 
7011
    default:
7012
      /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7013
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7014
      if (CONST_INT_P (operands[2])
7015
          && (INTVAL (operands[2]) == 128
7016
              || (INTVAL (operands[2]) < 0
7017
                  && INTVAL (operands[2]) != -128)))
7018
        {
7019
          operands[2] = GEN_INT (-INTVAL (operands[2]));
7020
          return "sub{w}\t{%2, %0|%0, %2}";
7021
        }
7022
      return "add{w}\t{%2, %0|%0, %2}";
7023
    }
7024
}
7025
  [(set (attr "type")
7026
     (if_then_else (match_operand:HI 2 "incdec_operand" "")
7027
        (const_string "incdec")
7028
        (const_string "alu")))
7029
   (set (attr "length_immediate")
7030
      (if_then_else
7031
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7032
        (const_string "1")
7033
        (const_string "*")))
7034
   (set_attr "mode" "HI")])
7035
 
7036
(define_insn "*addqi_5"
7037
  [(set (reg FLAGS_REG)
7038
        (compare
7039
          (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7040
                   (match_operand:QI 2 "general_operand" "qmn"))
7041
          (const_int 0)))
7042
   (clobber (match_scratch:QI 0 "=q"))]
7043
  "ix86_match_ccmode (insn, CCGOCmode)
7044
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7045
{
7046
  switch (get_attr_type (insn))
7047
    {
7048
    case TYPE_INCDEC:
7049
      if (operands[2] == const1_rtx)
7050
        return "inc{b}\t%0";
7051
      else
7052
        {
7053
          gcc_assert (operands[2] == constm1_rtx
7054
                      || (CONST_INT_P (operands[2])
7055
                          && INTVAL (operands[2]) == 255));
7056
          return "dec{b}\t%0";
7057
        }
7058
 
7059
    default:
7060
      /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
7061
      if (CONST_INT_P (operands[2])
7062
          && INTVAL (operands[2]) < 0)
7063
        {
7064
          operands[2] = GEN_INT (-INTVAL (operands[2]));
7065
          return "sub{b}\t{%2, %0|%0, %2}";
7066
        }
7067
      return "add{b}\t{%2, %0|%0, %2}";
7068
    }
7069
}
7070
  [(set (attr "type")
7071
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
7072
        (const_string "incdec")
7073
        (const_string "alu")))
7074
   (set_attr "mode" "QI")])
7075
 
7076
(define_insn "*addqi_ext_1_rex64"
7077
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7078
                         (const_int 8)
7079
                         (const_int 8))
7080
        (plus:SI
7081
          (zero_extract:SI
7082
            (match_operand 1 "ext_register_operand" "0")
7083
            (const_int 8)
7084
            (const_int 8))
7085
          (match_operand:QI 2 "nonmemory_operand" "Qn")))
7086
   (clobber (reg:CC FLAGS_REG))]
7087
  "TARGET_64BIT"
7088
{
7089
  switch (get_attr_type (insn))
7090
    {
7091
    case TYPE_INCDEC:
7092
      if (operands[2] == const1_rtx)
7093
        return "inc{b}\t%h0";
7094
      else
7095
        {
7096
          gcc_assert (operands[2] == constm1_rtx
7097
                      || (CONST_INT_P (operands[2])
7098
                          && INTVAL (operands[2]) == 255));
7099
          return "dec{b}\t%h0";
7100
        }
7101
 
7102
    default:
7103
      return "add{b}\t{%2, %h0|%h0, %2}";
7104
    }
7105
}
7106
  [(set (attr "type")
7107
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
7108
        (const_string "incdec")
7109
        (const_string "alu")))
7110
   (set_attr "modrm" "1")
7111
   (set_attr "mode" "QI")])
7112
 
7113
(define_insn "addqi_ext_1"
7114
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7115
                         (const_int 8)
7116
                         (const_int 8))
7117
        (plus:SI
7118
          (zero_extract:SI
7119
            (match_operand 1 "ext_register_operand" "0")
7120
            (const_int 8)
7121
            (const_int 8))
7122
          (match_operand:QI 2 "general_operand" "Qmn")))
7123
   (clobber (reg:CC FLAGS_REG))]
7124
  "!TARGET_64BIT"
7125
{
7126
  switch (get_attr_type (insn))
7127
    {
7128
    case TYPE_INCDEC:
7129
      if (operands[2] == const1_rtx)
7130
        return "inc{b}\t%h0";
7131
      else
7132
        {
7133
          gcc_assert (operands[2] == constm1_rtx
7134
                      || (CONST_INT_P (operands[2])
7135
                          && INTVAL (operands[2]) == 255));
7136
          return "dec{b}\t%h0";
7137
        }
7138
 
7139
    default:
7140
      return "add{b}\t{%2, %h0|%h0, %2}";
7141
    }
7142
}
7143
  [(set (attr "type")
7144
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
7145
        (const_string "incdec")
7146
        (const_string "alu")))
7147
   (set_attr "modrm" "1")
7148
   (set_attr "mode" "QI")])
7149
 
7150
(define_insn "*addqi_ext_2"
7151
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7152
                         (const_int 8)
7153
                         (const_int 8))
7154
        (plus:SI
7155
          (zero_extract:SI
7156
            (match_operand 1 "ext_register_operand" "%0")
7157
            (const_int 8)
7158
            (const_int 8))
7159
          (zero_extract:SI
7160
            (match_operand 2 "ext_register_operand" "Q")
7161
            (const_int 8)
7162
            (const_int 8))))
7163
   (clobber (reg:CC FLAGS_REG))]
7164
  ""
7165
  "add{b}\t{%h2, %h0|%h0, %h2}"
7166
  [(set_attr "type" "alu")
7167
   (set_attr "mode" "QI")])
7168
 
7169
;; The lea patterns for non-Pmodes needs to be matched by
7170
;; several insns converted to real lea by splitters.
7171
 
7172
(define_insn_and_split "*lea_general_1"
7173
  [(set (match_operand 0 "register_operand" "=r")
7174
        (plus (plus (match_operand 1 "index_register_operand" "l")
7175
                    (match_operand 2 "register_operand" "r"))
7176
              (match_operand 3 "immediate_operand" "i")))]
7177
  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7178
    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7179
   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7180
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
7181
   && GET_MODE (operands[0]) == GET_MODE (operands[2])
7182
   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7183
       || GET_MODE (operands[3]) == VOIDmode)"
7184
  "#"
7185
  "&& reload_completed"
7186
  [(const_int 0)]
7187
{
7188
  rtx pat;
7189
  operands[0] = gen_lowpart (SImode, operands[0]);
7190
  operands[1] = gen_lowpart (Pmode, operands[1]);
7191
  operands[2] = gen_lowpart (Pmode, operands[2]);
7192
  operands[3] = gen_lowpart (Pmode, operands[3]);
7193
  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7194
                      operands[3]);
7195
  if (Pmode != SImode)
7196
    pat = gen_rtx_SUBREG (SImode, pat, 0);
7197
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7198
  DONE;
7199
}
7200
  [(set_attr "type" "lea")
7201
   (set_attr "mode" "SI")])
7202
 
7203
(define_insn_and_split "*lea_general_1_zext"
7204
  [(set (match_operand:DI 0 "register_operand" "=r")
7205
        (zero_extend:DI
7206
          (plus:SI (plus:SI
7207
                     (match_operand:SI 1 "index_register_operand" "l")
7208
                     (match_operand:SI 2 "register_operand" "r"))
7209
                   (match_operand:SI 3 "immediate_operand" "i"))))]
7210
  "TARGET_64BIT"
7211
  "#"
7212
  "&& reload_completed"
7213
  [(set (match_dup 0)
7214
        (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7215
                                                     (match_dup 2))
7216
                                            (match_dup 3)) 0)))]
7217
{
7218
  operands[1] = gen_lowpart (Pmode, operands[1]);
7219
  operands[2] = gen_lowpart (Pmode, operands[2]);
7220
  operands[3] = gen_lowpart (Pmode, operands[3]);
7221
}
7222
  [(set_attr "type" "lea")
7223
   (set_attr "mode" "SI")])
7224
 
7225
(define_insn_and_split "*lea_general_2"
7226
  [(set (match_operand 0 "register_operand" "=r")
7227
        (plus (mult (match_operand 1 "index_register_operand" "l")
7228
                    (match_operand 2 "const248_operand" "i"))
7229
              (match_operand 3 "nonmemory_operand" "ri")))]
7230
  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7231
    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7232
   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7233
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
7234
   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7235
       || GET_MODE (operands[3]) == VOIDmode)"
7236
  "#"
7237
  "&& reload_completed"
7238
  [(const_int 0)]
7239
{
7240
  rtx pat;
7241
  operands[0] = gen_lowpart (SImode, operands[0]);
7242
  operands[1] = gen_lowpart (Pmode, operands[1]);
7243
  operands[3] = gen_lowpart (Pmode, operands[3]);
7244
  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7245
                      operands[3]);
7246
  if (Pmode != SImode)
7247
    pat = gen_rtx_SUBREG (SImode, pat, 0);
7248
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7249
  DONE;
7250
}
7251
  [(set_attr "type" "lea")
7252
   (set_attr "mode" "SI")])
7253
 
7254
(define_insn_and_split "*lea_general_2_zext"
7255
  [(set (match_operand:DI 0 "register_operand" "=r")
7256
        (zero_extend:DI
7257
          (plus:SI (mult:SI
7258
                     (match_operand:SI 1 "index_register_operand" "l")
7259
                     (match_operand:SI 2 "const248_operand" "n"))
7260
                   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7261
  "TARGET_64BIT"
7262
  "#"
7263
  "&& reload_completed"
7264
  [(set (match_dup 0)
7265
        (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7266
                                                     (match_dup 2))
7267
                                            (match_dup 3)) 0)))]
7268
{
7269
  operands[1] = gen_lowpart (Pmode, operands[1]);
7270
  operands[3] = gen_lowpart (Pmode, operands[3]);
7271
}
7272
  [(set_attr "type" "lea")
7273
   (set_attr "mode" "SI")])
7274
 
7275
(define_insn_and_split "*lea_general_3"
7276
  [(set (match_operand 0 "register_operand" "=r")
7277
        (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7278
                          (match_operand 2 "const248_operand" "i"))
7279
                    (match_operand 3 "register_operand" "r"))
7280
              (match_operand 4 "immediate_operand" "i")))]
7281
  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7282
    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7283
   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7284
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
7285
   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7286
  "#"
7287
  "&& reload_completed"
7288
  [(const_int 0)]
7289
{
7290
  rtx pat;
7291
  operands[0] = gen_lowpart (SImode, operands[0]);
7292
  operands[1] = gen_lowpart (Pmode, operands[1]);
7293
  operands[3] = gen_lowpart (Pmode, operands[3]);
7294
  operands[4] = gen_lowpart (Pmode, operands[4]);
7295
  pat = gen_rtx_PLUS (Pmode,
7296
                      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7297
                                                         operands[2]),
7298
                                    operands[3]),
7299
                      operands[4]);
7300
  if (Pmode != SImode)
7301
    pat = gen_rtx_SUBREG (SImode, pat, 0);
7302
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7303
  DONE;
7304
}
7305
  [(set_attr "type" "lea")
7306
   (set_attr "mode" "SI")])
7307
 
7308
(define_insn_and_split "*lea_general_3_zext"
7309
  [(set (match_operand:DI 0 "register_operand" "=r")
7310
        (zero_extend:DI
7311
          (plus:SI (plus:SI
7312
                     (mult:SI
7313
                       (match_operand:SI 1 "index_register_operand" "l")
7314
                       (match_operand:SI 2 "const248_operand" "n"))
7315
                     (match_operand:SI 3 "register_operand" "r"))
7316
                   (match_operand:SI 4 "immediate_operand" "i"))))]
7317
  "TARGET_64BIT"
7318
  "#"
7319
  "&& reload_completed"
7320
  [(set (match_dup 0)
7321
        (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7322
                                                              (match_dup 2))
7323
                                                     (match_dup 3))
7324
                                            (match_dup 4)) 0)))]
7325
{
7326
  operands[1] = gen_lowpart (Pmode, operands[1]);
7327
  operands[3] = gen_lowpart (Pmode, operands[3]);
7328
  operands[4] = gen_lowpart (Pmode, operands[4]);
7329
}
7330
  [(set_attr "type" "lea")
7331
   (set_attr "mode" "SI")])
7332
 
7333
;; Convert lea to the lea pattern to avoid flags dependency.
7334
(define_split
7335
  [(set (match_operand:DI 0 "register_operand" "")
7336
        (plus:DI (match_operand:DI 1 "register_operand" "")
7337
                 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7338
   (clobber (reg:CC FLAGS_REG))]
7339
  "TARGET_64BIT && reload_completed
7340
   && ix86_lea_for_add_ok (PLUS, insn, operands)"
7341
  [(set (match_dup 0)
7342
        (plus:DI (match_dup 1)
7343
                 (match_dup 2)))]
7344
  "")
7345
 
7346
;; Convert lea to the lea pattern to avoid flags dependency.
7347
(define_split
7348
  [(set (match_operand 0 "register_operand" "")
7349
        (plus (match_operand 1 "register_operand" "")
7350
              (match_operand 2 "nonmemory_operand" "")))
7351
   (clobber (reg:CC FLAGS_REG))]
7352
  "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7353
  [(const_int 0)]
7354
{
7355
  rtx pat;
7356
  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7357
     may confuse gen_lowpart.  */
7358
  if (GET_MODE (operands[0]) != Pmode)
7359
    {
7360
      operands[1] = gen_lowpart (Pmode, operands[1]);
7361
      operands[2] = gen_lowpart (Pmode, operands[2]);
7362
    }
7363
  operands[0] = gen_lowpart (SImode, operands[0]);
7364
  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7365
  if (Pmode != SImode)
7366
    pat = gen_rtx_SUBREG (SImode, pat, 0);
7367
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7368
  DONE;
7369
})
7370
 
7371
;; Convert lea to the lea pattern to avoid flags dependency.
7372
(define_split
7373
  [(set (match_operand:DI 0 "register_operand" "")
7374
        (zero_extend:DI
7375
          (plus:SI (match_operand:SI 1 "register_operand" "")
7376
                   (match_operand:SI 2 "nonmemory_operand" ""))))
7377
   (clobber (reg:CC FLAGS_REG))]
7378
  "TARGET_64BIT && reload_completed
7379
   && true_regnum (operands[0]) != true_regnum (operands[1])"
7380
  [(set (match_dup 0)
7381
        (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7382
{
7383
  operands[1] = gen_lowpart (Pmode, operands[1]);
7384
  operands[2] = gen_lowpart (Pmode, operands[2]);
7385
})
7386
 
7387
;; Subtract instructions
7388
 
7389
(define_expand "sub3"
7390
  [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7391
        (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7392
                     (match_operand:SDWIM 2 "" "")))]
7393
  ""
7394
  "ix86_expand_binary_operator (MINUS, mode, operands); DONE;")
7395
 
7396
(define_insn_and_split "*sub3_doubleword"
7397
  [(set (match_operand: 0 "nonimmediate_operand" "=r,o")
7398
        (minus:
7399
          (match_operand: 1 "nonimmediate_operand" "0,0")
7400
          (match_operand: 2 "" "ro,r")))
7401
   (clobber (reg:CC FLAGS_REG))]
7402
  "ix86_binary_operator_ok (MINUS, mode, operands)"
7403
  "#"
7404
  "reload_completed"
7405
  [(parallel [(set (reg:CC FLAGS_REG)
7406
                   (compare:CC (match_dup 1) (match_dup 2)))
7407
              (set (match_dup 0)
7408
                   (minus:DWIH (match_dup 1) (match_dup 2)))])
7409
   (parallel [(set (match_dup 3)
7410
                   (minus:DWIH
7411
                     (match_dup 4)
7412
                     (plus:DWIH
7413
                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7414
                       (match_dup 5))))
7415
              (clobber (reg:CC FLAGS_REG))])]
7416
  "split_ (&operands[0], 3, &operands[0], &operands[3]);")
7417
 
7418
(define_insn "*sub_1"
7419
  [(set (match_operand:SWI 0 "nonimmediate_operand" "=m,")
7420
        (minus:SWI
7421
          (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7422
          (match_operand:SWI 2 "" ",m")))
7423
   (clobber (reg:CC FLAGS_REG))]
7424
  "ix86_binary_operator_ok (MINUS, mode, operands)"
7425
  "sub{}\t{%2, %0|%0, %2}"
7426
  [(set_attr "type" "alu")
7427
   (set_attr "mode" "")])
7428
 
7429
(define_insn "*subsi_1_zext"
7430
  [(set (match_operand:DI 0 "register_operand" "=r")
7431
        (zero_extend:DI
7432
          (minus:SI (match_operand:SI 1 "register_operand" "0")
7433
                    (match_operand:SI 2 "general_operand" "g"))))
7434
   (clobber (reg:CC FLAGS_REG))]
7435
  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7436
  "sub{l}\t{%2, %k0|%k0, %2}"
7437
  [(set_attr "type" "alu")
7438
   (set_attr "mode" "SI")])
7439
 
7440
(define_insn "*subqi_1_slp"
7441
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7442
        (minus:QI (match_dup 0)
7443
                  (match_operand:QI 1 "general_operand" "qn,qm")))
7444
   (clobber (reg:CC FLAGS_REG))]
7445
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7446
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7447
  "sub{b}\t{%1, %0|%0, %1}"
7448
  [(set_attr "type" "alu1")
7449
   (set_attr "mode" "QI")])
7450
 
7451
(define_insn "*sub_2"
7452
  [(set (reg FLAGS_REG)
7453
        (compare
7454
          (minus:SWI
7455
            (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7456
            (match_operand:SWI 2 "" ",m"))
7457
          (const_int 0)))
7458
   (set (match_operand:SWI 0 "nonimmediate_operand" "=m,")
7459
        (minus:SWI (match_dup 1) (match_dup 2)))]
7460
  "ix86_match_ccmode (insn, CCGOCmode)
7461
   && ix86_binary_operator_ok (MINUS, mode, operands)"
7462
  "sub{}\t{%2, %0|%0, %2}"
7463
  [(set_attr "type" "alu")
7464
   (set_attr "mode" "")])
7465
 
7466
(define_insn "*subsi_2_zext"
7467
  [(set (reg FLAGS_REG)
7468
        (compare
7469
          (minus:SI (match_operand:SI 1 "register_operand" "0")
7470
                    (match_operand:SI 2 "general_operand" "g"))
7471
          (const_int 0)))
7472
   (set (match_operand:DI 0 "register_operand" "=r")
7473
        (zero_extend:DI
7474
          (minus:SI (match_dup 1)
7475
                    (match_dup 2))))]
7476
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7477
   && ix86_binary_operator_ok (MINUS, SImode, operands)"
7478
  "sub{l}\t{%2, %k0|%k0, %2}"
7479
  [(set_attr "type" "alu")
7480
   (set_attr "mode" "SI")])
7481
 
7482
(define_insn "*sub_3"
7483
  [(set (reg FLAGS_REG)
7484
        (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7485
                 (match_operand:SWI 2 "" ",m")))
7486
   (set (match_operand:SWI 0 "nonimmediate_operand" "=m,")
7487
        (minus:SWI (match_dup 1) (match_dup 2)))]
7488
  "ix86_match_ccmode (insn, CCmode)
7489
   && ix86_binary_operator_ok (MINUS, mode, operands)"
7490
  "sub{}\t{%2, %0|%0, %2}"
7491
  [(set_attr "type" "alu")
7492
   (set_attr "mode" "")])
7493
 
7494
(define_insn "*subsi_3_zext"
7495
  [(set (reg FLAGS_REG)
7496
        (compare (match_operand:SI 1 "register_operand" "0")
7497
                 (match_operand:SI 2 "general_operand" "g")))
7498
   (set (match_operand:DI 0 "register_operand" "=r")
7499
        (zero_extend:DI
7500
          (minus:SI (match_dup 1)
7501
                    (match_dup 2))))]
7502
  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7503
   && ix86_binary_operator_ok (MINUS, SImode, operands)"
7504
  "sub{l}\t{%2, %1|%1, %2}"
7505
  [(set_attr "type" "alu")
7506
   (set_attr "mode" "SI")])
7507
 
7508
;; Add with carry and subtract with borrow
7509
 
7510
(define_expand "3_carry"
7511
  [(parallel
7512
    [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7513
          (plusminus:SWI
7514
            (match_operand:SWI 1 "nonimmediate_operand" "")
7515
            (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7516
                       [(match_operand 3 "flags_reg_operand" "")
7517
                        (const_int 0)])
7518
                      (match_operand:SWI 2 "" ""))))
7519
     (clobber (reg:CC FLAGS_REG))])]
7520
  "ix86_binary_operator_ok (, mode, operands)"
7521
  "")
7522
 
7523
(define_insn "*3_carry"
7524
  [(set (match_operand:SWI 0 "nonimmediate_operand" "=m,")
7525
        (plusminus:SWI
7526
          (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7527
          (plus:SWI
7528
            (match_operator 3 "ix86_carry_flag_operator"
7529
             [(reg FLAGS_REG) (const_int 0)])
7530
            (match_operand:SWI 2 "" ",m"))))
7531
   (clobber (reg:CC FLAGS_REG))]
7532
  "ix86_binary_operator_ok (PLUS, mode, operands)"
7533
  "{}\t{%2, %0|%0, %2}"
7534
  [(set_attr "type" "alu")
7535
   (set_attr "use_carry" "1")
7536
   (set_attr "pent_pair" "pu")
7537
   (set_attr "mode" "")])
7538
 
7539
(define_insn "*addsi3_carry_zext"
7540
  [(set (match_operand:DI 0 "register_operand" "=r")
7541
        (zero_extend:DI
7542
          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7543
                   (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7544
                             [(reg FLAGS_REG) (const_int 0)])
7545
                            (match_operand:SI 2 "general_operand" "g")))))
7546
   (clobber (reg:CC FLAGS_REG))]
7547
  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7548
  "adc{l}\t{%2, %k0|%k0, %2}"
7549
  [(set_attr "type" "alu")
7550
   (set_attr "use_carry" "1")
7551
   (set_attr "pent_pair" "pu")
7552
   (set_attr "mode" "SI")])
7553
 
7554
(define_insn "*subsi3_carry_zext"
7555
  [(set (match_operand:DI 0 "register_operand" "=r")
7556
        (zero_extend:DI
7557
          (minus:SI (match_operand:SI 1 "register_operand" "0")
7558
                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7559
                              [(reg FLAGS_REG) (const_int 0)])
7560
                             (match_operand:SI 2 "general_operand" "g")))))
7561
   (clobber (reg:CC FLAGS_REG))]
7562
  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7563
  "sbb{l}\t{%2, %k0|%k0, %2}"
7564
  [(set_attr "type" "alu")
7565
   (set_attr "pent_pair" "pu")
7566
   (set_attr "mode" "SI")])
7567
 
7568
;; Overflow setting add and subtract instructions
7569
 
7570
(define_insn "*add3_cconly_overflow"
7571
  [(set (reg:CCC FLAGS_REG)
7572
        (compare:CCC
7573
          (plus:SWI
7574
            (match_operand:SWI 1 "nonimmediate_operand" "%0")
7575
            (match_operand:SWI 2 "" "m"))
7576
          (match_dup 1)))
7577
   (clobber (match_scratch:SWI 0 "="))]
7578
  "ix86_binary_operator_ok (PLUS, mode, operands)"
7579
  "add{}\t{%2, %0|%0, %2}"
7580
  [(set_attr "type" "alu")
7581
   (set_attr "mode" "")])
7582
 
7583
(define_insn "*sub3_cconly_overflow"
7584
  [(set (reg:CCC FLAGS_REG)
7585
        (compare:CCC
7586
          (minus:SWI
7587
            (match_operand:SWI 0 "nonimmediate_operand" "m,")
7588
            (match_operand:SWI 1 "" ",m"))
7589
          (match_dup 0)))]
7590
  ""
7591
  "cmp{}\t{%1, %0|%0, %1}"
7592
  [(set_attr "type" "icmp")
7593
   (set_attr "mode" "")])
7594
 
7595
(define_insn "*3_cc_overflow"
7596
  [(set (reg:CCC FLAGS_REG)
7597
        (compare:CCC
7598
            (plusminus:SWI
7599
                (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7600
                (match_operand:SWI 2 "" ",m"))
7601
            (match_dup 1)))
7602
   (set (match_operand:SWI 0 "nonimmediate_operand" "=m,")
7603
        (plusminus:SWI (match_dup 1) (match_dup 2)))]
7604
  "ix86_binary_operator_ok (, mode, operands)"
7605
  "{}\t{%2, %0|%0, %2}"
7606
  [(set_attr "type" "alu")
7607
   (set_attr "mode" "")])
7608
 
7609
(define_insn "*si3_zext_cc_overflow"
7610
  [(set (reg:CCC FLAGS_REG)
7611
        (compare:CCC
7612
          (plusminus:SI
7613
            (match_operand:SI 1 "nonimmediate_operand" "0")
7614
            (match_operand:SI 2 "general_operand" "g"))
7615
          (match_dup 1)))
7616
   (set (match_operand:DI 0 "register_operand" "=r")
7617
        (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7618
  "TARGET_64BIT && ix86_binary_operator_ok (, SImode, operands)"
7619
  "{l}\t{%2, %k0|%k0, %2}"
7620
  [(set_attr "type" "alu")
7621
   (set_attr "mode" "SI")])
7622
 
7623
;; The patterns that match these are at the end of this file.
7624
 
7625
(define_expand "xf3"
7626
  [(set (match_operand:XF 0 "register_operand" "")
7627
        (plusminus:XF
7628
          (match_operand:XF 1 "register_operand" "")
7629
          (match_operand:XF 2 "register_operand" "")))]
7630
  "TARGET_80387"
7631
  "")
7632
 
7633
(define_expand "3"
7634
  [(set (match_operand:MODEF 0 "register_operand" "")
7635
        (plusminus:MODEF
7636
          (match_operand:MODEF 1 "register_operand" "")
7637
          (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7638
  "(TARGET_80387 && X87_ENABLE_ARITH (mode))
7639
    || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
7640
  "")
7641
 
7642
;; Multiply instructions
7643
 
7644
(define_expand "mul3"
7645
  [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7646
                   (mult:SWIM248
7647
                     (match_operand:SWIM248 1 "register_operand" "")
7648
                     (match_operand:SWIM248 2 "" "")))
7649
              (clobber (reg:CC FLAGS_REG))])]
7650
  ""
7651
  "")
7652
 
7653
(define_expand "mulqi3"
7654
  [(parallel [(set (match_operand:QI 0 "register_operand" "")
7655
                   (mult:QI
7656
                     (match_operand:QI 1 "register_operand" "")
7657
                     (match_operand:QI 2 "nonimmediate_operand" "")))
7658
              (clobber (reg:CC FLAGS_REG))])]
7659
  "TARGET_QIMODE_MATH"
7660
  "")
7661
 
7662
;; On AMDFAM10
7663
;; IMUL reg32/64, reg32/64, imm8        Direct
7664
;; IMUL reg32/64, mem32/64, imm8        VectorPath
7665
;; IMUL reg32/64, reg32/64, imm32       Direct
7666
;; IMUL reg32/64, mem32/64, imm32       VectorPath
7667
;; IMUL reg32/64, reg32/64              Direct
7668
;; IMUL reg32/64, mem32/64              Direct
7669
 
7670
(define_insn "*mul3_1"
7671
  [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7672
        (mult:SWI48
7673
          (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7674
          (match_operand:SWI48 2 "" "K,,mr")))
7675
   (clobber (reg:CC FLAGS_REG))]
7676
  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7677
  "@
7678
   imul{}\t{%2, %1, %0|%0, %1, %2}
7679
   imul{}\t{%2, %1, %0|%0, %1, %2}
7680
   imul{}\t{%2, %0|%0, %2}"
7681
  [(set_attr "type" "imul")
7682
   (set_attr "prefix_0f" "0,0,1")
7683
   (set (attr "athlon_decode")
7684
        (cond [(eq_attr "cpu" "athlon")
7685
                  (const_string "vector")
7686
               (eq_attr "alternative" "1")
7687
                  (const_string "vector")
7688
               (and (eq_attr "alternative" "2")
7689
                    (match_operand 1 "memory_operand" ""))
7690
                  (const_string "vector")]
7691
              (const_string "direct")))
7692
   (set (attr "amdfam10_decode")
7693
        (cond [(and (eq_attr "alternative" "0,1")
7694
                    (match_operand 1 "memory_operand" ""))
7695
                  (const_string "vector")]
7696
              (const_string "direct")))
7697
   (set_attr "mode" "")])
7698
 
7699
(define_insn "*mulsi3_1_zext"
7700
  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7701
        (zero_extend:DI
7702
          (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7703
                   (match_operand:SI 2 "general_operand" "K,i,mr"))))
7704
   (clobber (reg:CC FLAGS_REG))]
7705
  "TARGET_64BIT
7706
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7707
  "@
7708
   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7709
   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7710
   imul{l}\t{%2, %k0|%k0, %2}"
7711
  [(set_attr "type" "imul")
7712
   (set_attr "prefix_0f" "0,0,1")
7713
   (set (attr "athlon_decode")
7714
        (cond [(eq_attr "cpu" "athlon")
7715
                  (const_string "vector")
7716
               (eq_attr "alternative" "1")
7717
                  (const_string "vector")
7718
               (and (eq_attr "alternative" "2")
7719
                    (match_operand 1 "memory_operand" ""))
7720
                  (const_string "vector")]
7721
              (const_string "direct")))
7722
   (set (attr "amdfam10_decode")
7723
        (cond [(and (eq_attr "alternative" "0,1")
7724
                    (match_operand 1 "memory_operand" ""))
7725
                  (const_string "vector")]
7726
              (const_string "direct")))
7727
   (set_attr "mode" "SI")])
7728
 
7729
;; On AMDFAM10
7730
;; IMUL reg16, reg16, imm8      VectorPath
7731
;; IMUL reg16, mem16, imm8      VectorPath
7732
;; IMUL reg16, reg16, imm16     VectorPath
7733
;; IMUL reg16, mem16, imm16     VectorPath
7734
;; IMUL reg16, reg16            Direct
7735
;; IMUL reg16, mem16            Direct
7736
 
7737
(define_insn "*mulhi3_1"
7738
  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7739
        (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7740
                 (match_operand:HI 2 "general_operand" "K,n,mr")))
7741
   (clobber (reg:CC FLAGS_REG))]
7742
  "TARGET_HIMODE_MATH
7743
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7744
  "@
7745
   imul{w}\t{%2, %1, %0|%0, %1, %2}
7746
   imul{w}\t{%2, %1, %0|%0, %1, %2}
7747
   imul{w}\t{%2, %0|%0, %2}"
7748
  [(set_attr "type" "imul")
7749
   (set_attr "prefix_0f" "0,0,1")
7750
   (set (attr "athlon_decode")
7751
        (cond [(eq_attr "cpu" "athlon")
7752
                  (const_string "vector")
7753
               (eq_attr "alternative" "1,2")
7754
                  (const_string "vector")]
7755
              (const_string "direct")))
7756
   (set (attr "amdfam10_decode")
7757
        (cond [(eq_attr "alternative" "0,1")
7758
                  (const_string "vector")]
7759
              (const_string "direct")))
7760
   (set_attr "mode" "HI")])
7761
 
7762
;;On AMDFAM10
7763
;; MUL reg8     Direct
7764
;; MUL mem8     Direct
7765
 
7766
(define_insn "*mulqi3_1"
7767
  [(set (match_operand:QI 0 "register_operand" "=a")
7768
        (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7769
                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7770
   (clobber (reg:CC FLAGS_REG))]
7771
  "TARGET_QIMODE_MATH
7772
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7773
  "mul{b}\t%2"
7774
  [(set_attr "type" "imul")
7775
   (set_attr "length_immediate" "0")
7776
   (set (attr "athlon_decode")
7777
     (if_then_else (eq_attr "cpu" "athlon")
7778
        (const_string "vector")
7779
        (const_string "direct")))
7780
   (set_attr "amdfam10_decode" "direct")
7781
   (set_attr "mode" "QI")])
7782
 
7783
(define_expand "mul3"
7784
  [(parallel [(set (match_operand: 0 "register_operand" "")
7785
                   (mult:
7786
                     (any_extend:
7787
                       (match_operand:DWIH 1 "nonimmediate_operand" ""))
7788
                     (any_extend:
7789
                       (match_operand:DWIH 2 "register_operand" ""))))
7790
              (clobber (reg:CC FLAGS_REG))])]
7791
  ""
7792
  "")
7793
 
7794
(define_expand "mulqihi3"
7795
  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7796
                   (mult:HI
7797
                     (any_extend:HI
7798
                       (match_operand:QI 1 "nonimmediate_operand" ""))
7799
                     (any_extend:HI
7800
                       (match_operand:QI 2 "register_operand" ""))))
7801
              (clobber (reg:CC FLAGS_REG))])]
7802
  "TARGET_QIMODE_MATH"
7803
  "")
7804
 
7805
(define_insn "*mul3_1"
7806
  [(set (match_operand: 0 "register_operand" "=A")
7807
        (mult:
7808
          (any_extend:
7809
            (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7810
          (any_extend:
7811
            (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7812
   (clobber (reg:CC FLAGS_REG))]
7813
  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7814
  "mul{}\t%2"
7815
  [(set_attr "type" "imul")
7816
   (set_attr "length_immediate" "0")
7817
   (set (attr "athlon_decode")
7818
     (if_then_else (eq_attr "cpu" "athlon")
7819
        (const_string "vector")
7820
        (const_string "double")))
7821
   (set_attr "amdfam10_decode" "double")
7822
   (set_attr "mode" "")])
7823
 
7824
(define_insn "*mulqihi3_1"
7825
  [(set (match_operand:HI 0 "register_operand" "=a")
7826
        (mult:HI
7827
          (any_extend:HI
7828
            (match_operand:QI 1 "nonimmediate_operand" "%0"))
7829
          (any_extend:HI
7830
            (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7831
   (clobber (reg:CC FLAGS_REG))]
7832
  "TARGET_QIMODE_MATH
7833
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7834
  "mul{b}\t%2"
7835
  [(set_attr "type" "imul")
7836
   (set_attr "length_immediate" "0")
7837
   (set (attr "athlon_decode")
7838
     (if_then_else (eq_attr "cpu" "athlon")
7839
        (const_string "vector")
7840
        (const_string "direct")))
7841
   (set_attr "amdfam10_decode" "direct")
7842
   (set_attr "mode" "QI")])
7843
 
7844
(define_expand "mul3_highpart"
7845
  [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7846
                   (truncate:SWI48
7847
                     (lshiftrt:
7848
                       (mult:
7849
                         (any_extend:
7850
                           (match_operand:SWI48 1 "nonimmediate_operand" ""))
7851
                         (any_extend:
7852
                           (match_operand:SWI48 2 "register_operand" "")))
7853
                       (match_dup 4))))
7854
              (clobber (match_scratch:SWI48 3 ""))
7855
              (clobber (reg:CC FLAGS_REG))])]
7856
  ""
7857
  "operands[4] = GEN_INT (GET_MODE_BITSIZE (mode));")
7858
 
7859
(define_insn "*muldi3_highpart_1"
7860
  [(set (match_operand:DI 0 "register_operand" "=d")
7861
        (truncate:DI
7862
          (lshiftrt:TI
7863
            (mult:TI
7864
              (any_extend:TI
7865
                (match_operand:DI 1 "nonimmediate_operand" "%a"))
7866
              (any_extend:TI
7867
                (match_operand:DI 2 "nonimmediate_operand" "rm")))
7868
            (const_int 64))))
7869
   (clobber (match_scratch:DI 3 "=1"))
7870
   (clobber (reg:CC FLAGS_REG))]
7871
  "TARGET_64BIT
7872
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7873
  "mul{q}\t%2"
7874
  [(set_attr "type" "imul")
7875
   (set_attr "length_immediate" "0")
7876
   (set (attr "athlon_decode")
7877
     (if_then_else (eq_attr "cpu" "athlon")
7878
        (const_string "vector")
7879
        (const_string "double")))
7880
   (set_attr "amdfam10_decode" "double")
7881
   (set_attr "mode" "DI")])
7882
 
7883
(define_insn "*mulsi3_highpart_1"
7884
  [(set (match_operand:SI 0 "register_operand" "=d")
7885
        (truncate:SI
7886
          (lshiftrt:DI
7887
            (mult:DI
7888
              (any_extend:DI
7889
                (match_operand:SI 1 "nonimmediate_operand" "%a"))
7890
              (any_extend:DI
7891
                (match_operand:SI 2 "nonimmediate_operand" "rm")))
7892
            (const_int 32))))
7893
   (clobber (match_scratch:SI 3 "=1"))
7894
   (clobber (reg:CC FLAGS_REG))]
7895
  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7896
  "mul{l}\t%2"
7897
  [(set_attr "type" "imul")
7898
   (set_attr "length_immediate" "0")
7899
   (set (attr "athlon_decode")
7900
     (if_then_else (eq_attr "cpu" "athlon")
7901
        (const_string "vector")
7902
        (const_string "double")))
7903
   (set_attr "amdfam10_decode" "double")
7904
   (set_attr "mode" "SI")])
7905
 
7906
(define_insn "*mulsi3_highpart_zext"
7907
  [(set (match_operand:DI 0 "register_operand" "=d")
7908
        (zero_extend:DI (truncate:SI
7909
          (lshiftrt:DI
7910
            (mult:DI (any_extend:DI
7911
                       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7912
                     (any_extend:DI
7913
                       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7914
            (const_int 32)))))
7915
   (clobber (match_scratch:SI 3 "=1"))
7916
   (clobber (reg:CC FLAGS_REG))]
7917
  "TARGET_64BIT
7918
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7919
  "mul{l}\t%2"
7920
  [(set_attr "type" "imul")
7921
   (set_attr "length_immediate" "0")
7922
   (set (attr "athlon_decode")
7923
     (if_then_else (eq_attr "cpu" "athlon")
7924
        (const_string "vector")
7925
        (const_string "double")))
7926
   (set_attr "amdfam10_decode" "double")
7927
   (set_attr "mode" "SI")])
7928
 
7929
;; The patterns that match these are at the end of this file.
7930
 
7931
(define_expand "mulxf3"
7932
  [(set (match_operand:XF 0 "register_operand" "")
7933
        (mult:XF (match_operand:XF 1 "register_operand" "")
7934
                 (match_operand:XF 2 "register_operand" "")))]
7935
  "TARGET_80387"
7936
  "")
7937
 
7938
(define_expand "mul3"
7939
  [(set (match_operand:MODEF 0 "register_operand" "")
7940
        (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7941
                    (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7942
  "(TARGET_80387 && X87_ENABLE_ARITH (mode))
7943
    || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
7944
  "")
7945
 
7946
;; Divide instructions
7947
 
7948
(define_insn "divqi3"
7949
  [(set (match_operand:QI 0 "register_operand" "=a")
7950
        (any_div:QI
7951
          (match_operand:HI 1 "register_operand" "0")
7952
          (match_operand:QI 2 "nonimmediate_operand" "qm")))
7953
   (clobber (reg:CC FLAGS_REG))]
7954
  "TARGET_QIMODE_MATH"
7955
  "div{b}\t%2"
7956
  [(set_attr "type" "idiv")
7957
   (set_attr "mode" "QI")])
7958
 
7959
;; The patterns that match these are at the end of this file.
7960
 
7961
(define_expand "divxf3"
7962
  [(set (match_operand:XF 0 "register_operand" "")
7963
        (div:XF (match_operand:XF 1 "register_operand" "")
7964
                (match_operand:XF 2 "register_operand" "")))]
7965
  "TARGET_80387"
7966
  "")
7967
 
7968
(define_expand "divdf3"
7969
  [(set (match_operand:DF 0 "register_operand" "")
7970
        (div:DF (match_operand:DF 1 "register_operand" "")
7971
                (match_operand:DF 2 "nonimmediate_operand" "")))]
7972
   "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7973
    || (TARGET_SSE2 && TARGET_SSE_MATH)"
7974
   "")
7975
 
7976
(define_expand "divsf3"
7977
  [(set (match_operand:SF 0 "register_operand" "")
7978
        (div:SF (match_operand:SF 1 "register_operand" "")
7979
                (match_operand:SF 2 "nonimmediate_operand" "")))]
7980
  "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7981
    || TARGET_SSE_MATH"
7982
{
7983
  if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7984
      && flag_finite_math_only && !flag_trapping_math
7985
      && flag_unsafe_math_optimizations)
7986
    {
7987
      ix86_emit_swdivsf (operands[0], operands[1],
7988
                         operands[2], SFmode);
7989
      DONE;
7990
    }
7991
})
7992
 
7993
;; Divmod instructions.
7994
 
7995
(define_expand "divmod4"
7996
  [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7997
                   (div:SWIM248
7998
                     (match_operand:SWIM248 1 "register_operand" "")
7999
                     (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8000
              (set (match_operand:SWIM248 3 "register_operand" "")
8001
                   (mod:SWIM248 (match_dup 1) (match_dup 2)))
8002
              (clobber (reg:CC FLAGS_REG))])]
8003
  ""
8004
  "")
8005
 
8006
(define_insn_and_split "*divmod4"
8007
  [(set (match_operand:SWIM248 0 "register_operand" "=a")
8008
        (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8009
                    (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8010
   (set (match_operand:SWIM248 1 "register_operand" "=&d")
8011
        (mod:SWIM248 (match_dup 2) (match_dup 3)))
8012
   (clobber (reg:CC FLAGS_REG))]
8013
  ""
8014
  "#"
8015
  "reload_completed"
8016
  [(parallel [(set (match_dup 1)
8017
                   (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8018
              (clobber (reg:CC FLAGS_REG))])
8019
   (parallel [(set (match_dup 0)
8020
                   (div:SWIM248 (match_dup 2) (match_dup 3)))
8021
              (set (match_dup 1)
8022
                   (mod:SWIM248 (match_dup 2) (match_dup 3)))
8023
              (use (match_dup 1))
8024
              (clobber (reg:CC FLAGS_REG))])]
8025
{
8026
  operands[5] = GEN_INT (GET_MODE_BITSIZE (mode) - 1);
8027
 
8028
  if (mode != HImode
8029
      && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8030
    operands[4] = operands[2];
8031
  else
8032
    {
8033
      /* Avoid use of cltd in favor of a mov+shift.  */
8034
      emit_move_insn (operands[1], operands[2]);
8035
      operands[4] = operands[1];
8036
    }
8037
}
8038
  [(set_attr "type" "multi")
8039
   (set_attr "mode" "")])
8040
 
8041
(define_insn "*divmod4_noext"
8042
  [(set (match_operand:SWIM248 0 "register_operand" "=a")
8043
        (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8044
                    (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8045
   (set (match_operand:SWIM248 1 "register_operand" "=d")
8046
        (mod:SWIM248 (match_dup 2) (match_dup 3)))
8047
   (use (match_operand:SWIM248 4 "register_operand" "1"))
8048
   (clobber (reg:CC FLAGS_REG))]
8049
  ""
8050
  "idiv{}\t%3"
8051
  [(set_attr "type" "idiv")
8052
   (set_attr "mode" "")])
8053
 
8054
(define_expand "udivmod4"
8055
  [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8056
                   (udiv:SWIM248
8057
                     (match_operand:SWIM248 1 "register_operand" "")
8058
                     (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8059
              (set (match_operand:SWIM248 3 "register_operand" "")
8060
                   (umod:SWIM248 (match_dup 1) (match_dup 2)))
8061
              (clobber (reg:CC FLAGS_REG))])]
8062
  ""
8063
  "")
8064
 
8065
(define_insn_and_split "*udivmod4"
8066
  [(set (match_operand:SWIM248 0 "register_operand" "=a")
8067
        (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8068
                      (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8069
   (set (match_operand:SWIM248 1 "register_operand" "=&d")
8070
        (umod:SWIM248 (match_dup 2) (match_dup 3)))
8071
   (clobber (reg:CC FLAGS_REG))]
8072
  ""
8073
  "#"
8074
  "reload_completed"
8075
  [(set (match_dup 1) (const_int 0))
8076
   (parallel [(set (match_dup 0)
8077
                   (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8078
              (set (match_dup 1)
8079
                   (umod:SWIM248 (match_dup 2) (match_dup 3)))
8080
              (use (match_dup 1))
8081
              (clobber (reg:CC FLAGS_REG))])]
8082
  ""
8083
  [(set_attr "type" "multi")
8084
   (set_attr "mode" "")])
8085
 
8086
(define_insn "*udivmod4_noext"
8087
  [(set (match_operand:SWIM248 0 "register_operand" "=a")
8088
        (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8089
                      (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8090
   (set (match_operand:SWIM248 1 "register_operand" "=d")
8091
        (umod:SWIM248 (match_dup 2) (match_dup 3)))
8092
   (use (match_operand:SWIM248 4 "register_operand" "1"))
8093
   (clobber (reg:CC FLAGS_REG))]
8094
  ""
8095
  "div{}\t%3"
8096
  [(set_attr "type" "idiv")
8097
   (set_attr "mode" "")])
8098
 
8099
;; We cannot use div/idiv for double division, because it causes
8100
;; "division by zero" on the overflow and that's not what we expect
8101
;; from truncate.  Because true (non truncating) double division is
8102
;; never generated, we can't create this insn anyway.
8103
;
8104
;(define_insn ""
8105
;  [(set (match_operand:SI 0 "register_operand" "=a")
8106
;       (truncate:SI
8107
;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8108
;                  (zero_extend:DI
8109
;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8110
;   (set (match_operand:SI 3 "register_operand" "=d")
8111
;       (truncate:SI
8112
;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8113
;   (clobber (reg:CC FLAGS_REG))]
8114
;  ""
8115
;  "div{l}\t{%2, %0|%0, %2}"
8116
;  [(set_attr "type" "idiv")])
8117
 
8118
;;- Logical AND instructions
8119
 
8120
;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8121
;; Note that this excludes ah.
8122
 
8123
(define_expand "testsi_ccno_1"
8124
  [(set (reg:CCNO FLAGS_REG)
8125
        (compare:CCNO
8126
          (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8127
                  (match_operand:SI 1 "nonmemory_operand" ""))
8128
          (const_int 0)))]
8129
  ""
8130
  "")
8131
 
8132
(define_expand "testqi_ccz_1"
8133
  [(set (reg:CCZ FLAGS_REG)
8134
        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8135
                             (match_operand:QI 1 "nonmemory_operand" ""))
8136
                 (const_int 0)))]
8137
  ""
8138
  "")
8139
 
8140
(define_insn "*testdi_1"
8141
  [(set (reg FLAGS_REG)
8142
        (compare
8143
         (and:DI
8144
          (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8145
          (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8146
         (const_int 0)))]
8147
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8148
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8149
  "@
8150
   test{l}\t{%k1, %k0|%k0, %k1}
8151
   test{l}\t{%k1, %k0|%k0, %k1}
8152
   test{q}\t{%1, %0|%0, %1}
8153
   test{q}\t{%1, %0|%0, %1}
8154
   test{q}\t{%1, %0|%0, %1}"
8155
  [(set_attr "type" "test")
8156
   (set_attr "modrm" "0,1,0,1,1")
8157
   (set_attr "mode" "SI,SI,DI,DI,DI")])
8158
 
8159
(define_insn "*testqi_1_maybe_si"
8160
  [(set (reg FLAGS_REG)
8161
        (compare
8162
          (and:QI
8163
            (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8164
            (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8165
          (const_int 0)))]
8166
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8167
    && ix86_match_ccmode (insn,
8168
                         CONST_INT_P (operands[1])
8169
                         && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8170
{
8171
  if (which_alternative == 3)
8172
    {
8173
      if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8174
        operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8175
      return "test{l}\t{%1, %k0|%k0, %1}";
8176
    }
8177
  return "test{b}\t{%1, %0|%0, %1}";
8178
}
8179
  [(set_attr "type" "test")
8180
   (set_attr "modrm" "0,1,1,1")
8181
   (set_attr "mode" "QI,QI,QI,SI")
8182
   (set_attr "pent_pair" "uv,np,uv,np")])
8183
 
8184
(define_insn "*test_1"
8185
  [(set (reg FLAGS_REG)
8186
        (compare
8187
         (and:SWI124
8188
          (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,,m")
8189
          (match_operand:SWI124 1 "general_operand" ",,"))
8190
         (const_int 0)))]
8191
  "ix86_match_ccmode (insn, CCNOmode)
8192
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8193
  "test{}\t{%1, %0|%0, %1}"
8194
  [(set_attr "type" "test")
8195
   (set_attr "modrm" "0,1,1")
8196
   (set_attr "mode" "")
8197
   (set_attr "pent_pair" "uv,np,uv")])
8198
 
8199
(define_expand "testqi_ext_ccno_0"
8200
  [(set (reg:CCNO FLAGS_REG)
8201
        (compare:CCNO
8202
          (and:SI
8203
            (zero_extract:SI
8204
              (match_operand 0 "ext_register_operand" "")
8205
              (const_int 8)
8206
              (const_int 8))
8207
            (match_operand 1 "const_int_operand" ""))
8208
          (const_int 0)))]
8209
  ""
8210
  "")
8211
 
8212
(define_insn "*testqi_ext_0"
8213
  [(set (reg FLAGS_REG)
8214
        (compare
8215
          (and:SI
8216
            (zero_extract:SI
8217
              (match_operand 0 "ext_register_operand" "Q")
8218
              (const_int 8)
8219
              (const_int 8))
8220
            (match_operand 1 "const_int_operand" "n"))
8221
          (const_int 0)))]
8222
  "ix86_match_ccmode (insn, CCNOmode)"
8223
  "test{b}\t{%1, %h0|%h0, %1}"
8224
  [(set_attr "type" "test")
8225
   (set_attr "mode" "QI")
8226
   (set_attr "length_immediate" "1")
8227
   (set_attr "modrm" "1")
8228
   (set_attr "pent_pair" "np")])
8229
 
8230
(define_insn "*testqi_ext_1_rex64"
8231
  [(set (reg FLAGS_REG)
8232
        (compare
8233
          (and:SI
8234
            (zero_extract:SI
8235
              (match_operand 0 "ext_register_operand" "Q")
8236
              (const_int 8)
8237
              (const_int 8))
8238
            (zero_extend:SI
8239
              (match_operand:QI 1 "register_operand" "Q")))
8240
          (const_int 0)))]
8241
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8242
  "test{b}\t{%1, %h0|%h0, %1}"
8243
  [(set_attr "type" "test")
8244
   (set_attr "mode" "QI")])
8245
 
8246
(define_insn "*testqi_ext_1"
8247
  [(set (reg FLAGS_REG)
8248
        (compare
8249
          (and:SI
8250
            (zero_extract:SI
8251
              (match_operand 0 "ext_register_operand" "Q")
8252
              (const_int 8)
8253
              (const_int 8))
8254
            (zero_extend:SI
8255
              (match_operand:QI 1 "general_operand" "Qm")))
8256
          (const_int 0)))]
8257
  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8258
  "test{b}\t{%1, %h0|%h0, %1}"
8259
  [(set_attr "type" "test")
8260
   (set_attr "mode" "QI")])
8261
 
8262
(define_insn "*testqi_ext_2"
8263
  [(set (reg FLAGS_REG)
8264
        (compare
8265
          (and:SI
8266
            (zero_extract:SI
8267
              (match_operand 0 "ext_register_operand" "Q")
8268
              (const_int 8)
8269
              (const_int 8))
8270
            (zero_extract:SI
8271
              (match_operand 1 "ext_register_operand" "Q")
8272
              (const_int 8)
8273
              (const_int 8)))
8274
          (const_int 0)))]
8275
  "ix86_match_ccmode (insn, CCNOmode)"
8276
  "test{b}\t{%h1, %h0|%h0, %h1}"
8277
  [(set_attr "type" "test")
8278
   (set_attr "mode" "QI")])
8279
 
8280
(define_insn "*testqi_ext_3_rex64"
8281
  [(set (reg FLAGS_REG)
8282
        (compare (zero_extract:DI
8283
                   (match_operand 0 "nonimmediate_operand" "rm")
8284
                   (match_operand:DI 1 "const_int_operand" "")
8285
                   (match_operand:DI 2 "const_int_operand" ""))
8286
                 (const_int 0)))]
8287
  "TARGET_64BIT
8288
   && ix86_match_ccmode (insn, CCNOmode)
8289
   && INTVAL (operands[1]) > 0
8290
   && INTVAL (operands[2]) >= 0
8291
   /* Ensure that resulting mask is zero or sign extended operand.  */
8292
   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8293
       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8294
           && INTVAL (operands[1]) > 32))
8295
   && (GET_MODE (operands[0]) == SImode
8296
       || GET_MODE (operands[0]) == DImode
8297
       || GET_MODE (operands[0]) == HImode
8298
       || GET_MODE (operands[0]) == QImode)"
8299
  "#")
8300
 
8301
;; Combine likes to form bit extractions for some tests.  Humor it.
8302
(define_insn "*testqi_ext_3"
8303
  [(set (reg FLAGS_REG)
8304
        (compare (zero_extract:SI
8305
                   (match_operand 0 "nonimmediate_operand" "rm")
8306
                   (match_operand:SI 1 "const_int_operand" "")
8307
                   (match_operand:SI 2 "const_int_operand" ""))
8308
                 (const_int 0)))]
8309
  "ix86_match_ccmode (insn, CCNOmode)
8310
   && INTVAL (operands[1]) > 0
8311
   && INTVAL (operands[2]) >= 0
8312
   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8313
   && (GET_MODE (operands[0]) == SImode
8314
       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8315
       || GET_MODE (operands[0]) == HImode
8316
       || GET_MODE (operands[0]) == QImode)"
8317
  "#")
8318
 
8319
(define_split
8320
  [(set (match_operand 0 "flags_reg_operand" "")
8321
        (match_operator 1 "compare_operator"
8322
          [(zero_extract
8323
             (match_operand 2 "nonimmediate_operand" "")
8324
             (match_operand 3 "const_int_operand" "")
8325
             (match_operand 4 "const_int_operand" ""))
8326
           (const_int 0)]))]
8327
  "ix86_match_ccmode (insn, CCNOmode)"
8328
  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8329
{
8330
  rtx val = operands[2];
8331
  HOST_WIDE_INT len = INTVAL (operands[3]);
8332
  HOST_WIDE_INT pos = INTVAL (operands[4]);
8333
  HOST_WIDE_INT mask;
8334
  enum machine_mode mode, submode;
8335
 
8336
  mode = GET_MODE (val);
8337
  if (MEM_P (val))
8338
    {
8339
      /* ??? Combine likes to put non-volatile mem extractions in QImode
8340
         no matter the size of the test.  So find a mode that works.  */
8341
      if (! MEM_VOLATILE_P (val))
8342
        {
8343
          mode = smallest_mode_for_size (pos + len, MODE_INT);
8344
          val = adjust_address (val, mode, 0);
8345
        }
8346
    }
8347
  else if (GET_CODE (val) == SUBREG
8348
           && (submode = GET_MODE (SUBREG_REG (val)),
8349
               GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8350
           && pos + len <= GET_MODE_BITSIZE (submode)
8351
           && GET_MODE_CLASS (submode) == MODE_INT)
8352
    {
8353
      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8354
      mode = submode;
8355
      val = SUBREG_REG (val);
8356
    }
8357
  else if (mode == HImode && pos + len <= 8)
8358
    {
8359
      /* Small HImode tests can be converted to QImode.  */
8360
      mode = QImode;
8361
      val = gen_lowpart (QImode, val);
8362
    }
8363
 
8364
  if (len == HOST_BITS_PER_WIDE_INT)
8365
    mask = -1;
8366
  else
8367
    mask = ((HOST_WIDE_INT)1 << len) - 1;
8368
  mask <<= pos;
8369
 
8370
  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8371
})
8372
 
8373
;; Convert HImode/SImode test instructions with immediate to QImode ones.
8374
;; i386 does not allow to encode test with 8bit sign extended immediate, so
8375
;; this is relatively important trick.
8376
;; Do the conversion only post-reload to avoid limiting of the register class
8377
;; to QI regs.
8378
(define_split
8379
  [(set (match_operand 0 "flags_reg_operand" "")
8380
        (match_operator 1 "compare_operator"
8381
          [(and (match_operand 2 "register_operand" "")
8382
                (match_operand 3 "const_int_operand" ""))
8383
           (const_int 0)]))]
8384
   "reload_completed
8385
    && QI_REG_P (operands[2])
8386
    && GET_MODE (operands[2]) != QImode
8387
    && ((ix86_match_ccmode (insn, CCZmode)
8388
         && !(INTVAL (operands[3]) & ~(255 << 8)))
8389
        || (ix86_match_ccmode (insn, CCNOmode)
8390
            && !(INTVAL (operands[3]) & ~(127 << 8))))"
8391
  [(set (match_dup 0)
8392
        (match_op_dup 1
8393
          [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8394
                   (match_dup 3))
8395
           (const_int 0)]))]
8396
  "operands[2] = gen_lowpart (SImode, operands[2]);
8397
   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8398
 
8399
(define_split
8400
  [(set (match_operand 0 "flags_reg_operand" "")
8401
        (match_operator 1 "compare_operator"
8402
          [(and (match_operand 2 "nonimmediate_operand" "")
8403
                (match_operand 3 "const_int_operand" ""))
8404
           (const_int 0)]))]
8405
   "reload_completed
8406
    && GET_MODE (operands[2]) != QImode
8407
    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8408
    && ((ix86_match_ccmode (insn, CCZmode)
8409
         && !(INTVAL (operands[3]) & ~255))
8410
        || (ix86_match_ccmode (insn, CCNOmode)
8411
            && !(INTVAL (operands[3]) & ~127)))"
8412
  [(set (match_dup 0)
8413
        (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8414
                         (const_int 0)]))]
8415
  "operands[2] = gen_lowpart (QImode, operands[2]);
8416
   operands[3] = gen_lowpart (QImode, operands[3]);")
8417
 
8418
;; %%% This used to optimize known byte-wide and operations to memory,
8419
;; and sometimes to QImode registers.  If this is considered useful,
8420
;; it should be done with splitters.
8421
 
8422
(define_expand "and3"
8423
  [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8424
        (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8425
                  (match_operand:SWIM 2 "" "")))]
8426
  ""
8427
  "ix86_expand_binary_operator (AND, mode, operands); DONE;")
8428
 
8429
(define_insn "*anddi_1"
8430
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8431
        (and:DI
8432
         (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8433
         (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8434
   (clobber (reg:CC FLAGS_REG))]
8435
  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8436
{
8437
  switch (get_attr_type (insn))
8438
    {
8439
    case TYPE_IMOVX:
8440
      {
8441
        enum machine_mode mode;
8442
 
8443
        gcc_assert (CONST_INT_P (operands[2]));
8444
        if (INTVAL (operands[2]) == 0xff)
8445
          mode = QImode;
8446
        else
8447
          {
8448
            gcc_assert (INTVAL (operands[2]) == 0xffff);
8449
            mode = HImode;
8450
          }
8451
 
8452
        operands[1] = gen_lowpart (mode, operands[1]);
8453
        if (mode == QImode)
8454
          return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8455
        else
8456
          return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8457
      }
8458
 
8459
    default:
8460
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8461
      if (get_attr_mode (insn) == MODE_SI)
8462
        return "and{l}\t{%k2, %k0|%k0, %k2}";
8463
      else
8464
        return "and{q}\t{%2, %0|%0, %2}";
8465
    }
8466
}
8467
  [(set_attr "type" "alu,alu,alu,imovx")
8468
   (set_attr "length_immediate" "*,*,*,0")
8469
   (set (attr "prefix_rex")
8470
     (if_then_else
8471
       (and (eq_attr "type" "imovx")
8472
            (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8473
                 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8474
       (const_string "1")
8475
       (const_string "*")))
8476
   (set_attr "mode" "SI,DI,DI,SI")])
8477
 
8478
(define_insn "*andsi_1"
8479
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8480
        (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8481
                (match_operand:SI 2 "general_operand" "ri,rm,L")))
8482
   (clobber (reg:CC FLAGS_REG))]
8483
  "ix86_binary_operator_ok (AND, SImode, operands)"
8484
{
8485
  switch (get_attr_type (insn))
8486
    {
8487
    case TYPE_IMOVX:
8488
      {
8489
        enum machine_mode mode;
8490
 
8491
        gcc_assert (CONST_INT_P (operands[2]));
8492
        if (INTVAL (operands[2]) == 0xff)
8493
          mode = QImode;
8494
        else
8495
          {
8496
            gcc_assert (INTVAL (operands[2]) == 0xffff);
8497
            mode = HImode;
8498
          }
8499
 
8500
        operands[1] = gen_lowpart (mode, operands[1]);
8501
        if (mode == QImode)
8502
          return "movz{bl|x}\t{%1, %0|%0, %1}";
8503
        else
8504
          return "movz{wl|x}\t{%1, %0|%0, %1}";
8505
      }
8506
 
8507
    default:
8508
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8509
      return "and{l}\t{%2, %0|%0, %2}";
8510
    }
8511
}
8512
  [(set_attr "type" "alu,alu,imovx")
8513
   (set (attr "prefix_rex")
8514
     (if_then_else
8515
       (and (eq_attr "type" "imovx")
8516
            (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8517
                 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8518
       (const_string "1")
8519
       (const_string "*")))
8520
   (set_attr "length_immediate" "*,*,0")
8521
   (set_attr "mode" "SI")])
8522
 
8523
;; See comment for addsi_1_zext why we do use nonimmediate_operand
8524
(define_insn "*andsi_1_zext"
8525
  [(set (match_operand:DI 0 "register_operand" "=r")
8526
        (zero_extend:DI
8527
          (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8528
                  (match_operand:SI 2 "general_operand" "g"))))
8529
   (clobber (reg:CC FLAGS_REG))]
8530
  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8531
  "and{l}\t{%2, %k0|%k0, %2}"
8532
  [(set_attr "type" "alu")
8533
   (set_attr "mode" "SI")])
8534
 
8535
(define_insn "*andhi_1"
8536
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8537
        (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8538
                (match_operand:HI 2 "general_operand" "rn,rm,L")))
8539
   (clobber (reg:CC FLAGS_REG))]
8540
  "ix86_binary_operator_ok (AND, HImode, operands)"
8541
{
8542
  switch (get_attr_type (insn))
8543
    {
8544
    case TYPE_IMOVX:
8545
      gcc_assert (CONST_INT_P (operands[2]));
8546
      gcc_assert (INTVAL (operands[2]) == 0xff);
8547
      return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8548
 
8549
    default:
8550
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8551
 
8552
      return "and{w}\t{%2, %0|%0, %2}";
8553
    }
8554
}
8555
  [(set_attr "type" "alu,alu,imovx")
8556
   (set_attr "length_immediate" "*,*,0")
8557
   (set (attr "prefix_rex")
8558
     (if_then_else
8559
       (and (eq_attr "type" "imovx")
8560
            (match_operand 1 "ext_QIreg_nomode_operand" ""))
8561
       (const_string "1")
8562
       (const_string "*")))
8563
   (set_attr "mode" "HI,HI,SI")])
8564
 
8565
;; %%% Potential partial reg stall on alternative 2.  What to do?
8566
(define_insn "*andqi_1"
8567
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8568
        (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8569
                (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8570
   (clobber (reg:CC FLAGS_REG))]
8571
  "ix86_binary_operator_ok (AND, QImode, operands)"
8572
  "@
8573
   and{b}\t{%2, %0|%0, %2}
8574
   and{b}\t{%2, %0|%0, %2}
8575
   and{l}\t{%k2, %k0|%k0, %k2}"
8576
  [(set_attr "type" "alu")
8577
   (set_attr "mode" "QI,QI,SI")])
8578
 
8579
(define_insn "*andqi_1_slp"
8580
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8581
        (and:QI (match_dup 0)
8582
                (match_operand:QI 1 "general_operand" "qn,qmn")))
8583
   (clobber (reg:CC FLAGS_REG))]
8584
  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8585
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8586
  "and{b}\t{%1, %0|%0, %1}"
8587
  [(set_attr "type" "alu1")
8588
   (set_attr "mode" "QI")])
8589
 
8590
(define_split
8591
  [(set (match_operand 0 "register_operand" "")
8592
        (and (match_dup 0)
8593
             (const_int -65536)))
8594
   (clobber (reg:CC FLAGS_REG))]
8595
  "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8596
    || optimize_function_for_size_p (cfun)"
8597
  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8598
  "operands[1] = gen_lowpart (HImode, operands[0]);")
8599
 
8600
(define_split
8601
  [(set (match_operand 0 "ext_register_operand" "")
8602
        (and (match_dup 0)
8603
             (const_int -256)))
8604
   (clobber (reg:CC FLAGS_REG))]
8605
  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8606
   && reload_completed"
8607
  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8608
  "operands[1] = gen_lowpart (QImode, operands[0]);")
8609
 
8610
(define_split
8611
  [(set (match_operand 0 "ext_register_operand" "")
8612
        (and (match_dup 0)
8613
             (const_int -65281)))
8614
   (clobber (reg:CC FLAGS_REG))]
8615
  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8616
   && reload_completed"
8617
  [(parallel [(set (zero_extract:SI (match_dup 0)
8618
                                    (const_int 8)
8619
                                    (const_int 8))
8620
                   (xor:SI
8621
                     (zero_extract:SI (match_dup 0)
8622
                                      (const_int 8)
8623
                                      (const_int 8))
8624
                     (zero_extract:SI (match_dup 0)
8625
                                      (const_int 8)
8626
                                      (const_int 8))))
8627
              (clobber (reg:CC FLAGS_REG))])]
8628
  "operands[0] = gen_lowpart (SImode, operands[0]);")
8629
 
8630
(define_insn "*anddi_2"
8631
  [(set (reg FLAGS_REG)
8632
        (compare
8633
         (and:DI
8634
          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8635
          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8636
         (const_int 0)))
8637
   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8638
        (and:DI (match_dup 1) (match_dup 2)))]
8639
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8640
   && ix86_binary_operator_ok (AND, DImode, operands)"
8641
  "@
8642
   and{l}\t{%k2, %k0|%k0, %k2}
8643
   and{q}\t{%2, %0|%0, %2}
8644
   and{q}\t{%2, %0|%0, %2}"
8645
  [(set_attr "type" "alu")
8646
   (set_attr "mode" "SI,DI,DI")])
8647
 
8648
(define_insn "*andqi_2_maybe_si"
8649
  [(set (reg FLAGS_REG)
8650
        (compare (and:QI
8651
                  (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8652
                  (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8653
                 (const_int 0)))
8654
   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8655
        (and:QI (match_dup 1) (match_dup 2)))]
8656
  "ix86_binary_operator_ok (AND, QImode, operands)
8657
   && ix86_match_ccmode (insn,
8658
                         CONST_INT_P (operands[2])
8659
                         && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8660
{
8661
  if (which_alternative == 2)
8662
    {
8663
      if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8664
        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8665
      return "and{l}\t{%2, %k0|%k0, %2}";
8666
    }
8667
  return "and{b}\t{%2, %0|%0, %2}";
8668
}
8669
  [(set_attr "type" "alu")
8670
   (set_attr "mode" "QI,QI,SI")])
8671
 
8672
(define_insn "*and_2"
8673
  [(set (reg FLAGS_REG)
8674
        (compare (and:SWI124
8675
                  (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8676
                  (match_operand:SWI124 2 "general_operand" ","))
8677
                 (const_int 0)))
8678
   (set (match_operand:SWI124 0 "nonimmediate_operand" "=,m")
8679
        (and:SWI124 (match_dup 1) (match_dup 2)))]
8680
  "ix86_match_ccmode (insn, CCNOmode)
8681
   && ix86_binary_operator_ok (AND, mode, operands)"
8682
  "and{}\t{%2, %0|%0, %2}"
8683
  [(set_attr "type" "alu")
8684
   (set_attr "mode" "")])
8685
 
8686
;; See comment for addsi_1_zext why we do use nonimmediate_operand
8687
(define_insn "*andsi_2_zext"
8688
  [(set (reg FLAGS_REG)
8689
        (compare (and:SI
8690
                  (match_operand:SI 1 "nonimmediate_operand" "%0")
8691
                  (match_operand:SI 2 "general_operand" "g"))
8692
                 (const_int 0)))
8693
   (set (match_operand:DI 0 "register_operand" "=r")
8694
        (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8695
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8696
   && ix86_binary_operator_ok (AND, SImode, operands)"
8697
  "and{l}\t{%2, %k0|%k0, %2}"
8698
  [(set_attr "type" "alu")
8699
   (set_attr "mode" "SI")])
8700
 
8701
(define_insn "*andqi_2_slp"
8702
  [(set (reg FLAGS_REG)
8703
        (compare (and:QI
8704
                   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8705
                   (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8706
                 (const_int 0)))
8707
   (set (strict_low_part (match_dup 0))
8708
        (and:QI (match_dup 0) (match_dup 1)))]
8709
  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8710
   && ix86_match_ccmode (insn, CCNOmode)
8711
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8712
  "and{b}\t{%1, %0|%0, %1}"
8713
  [(set_attr "type" "alu1")
8714
   (set_attr "mode" "QI")])
8715
 
8716
;; ??? A bug in recog prevents it from recognizing a const_int as an
8717
;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8718
;; for a QImode operand, which of course failed.
8719
(define_insn "andqi_ext_0"
8720
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8721
                         (const_int 8)
8722
                         (const_int 8))
8723
        (and:SI
8724
          (zero_extract:SI
8725
            (match_operand 1 "ext_register_operand" "0")
8726
            (const_int 8)
8727
            (const_int 8))
8728
          (match_operand 2 "const_int_operand" "n")))
8729
   (clobber (reg:CC FLAGS_REG))]
8730
  ""
8731
  "and{b}\t{%2, %h0|%h0, %2}"
8732
  [(set_attr "type" "alu")
8733
   (set_attr "length_immediate" "1")
8734
   (set_attr "modrm" "1")
8735
   (set_attr "mode" "QI")])
8736
 
8737
;; Generated by peephole translating test to and.  This shows up
8738
;; often in fp comparisons.
8739
(define_insn "*andqi_ext_0_cc"
8740
  [(set (reg FLAGS_REG)
8741
        (compare
8742
          (and:SI
8743
            (zero_extract:SI
8744
              (match_operand 1 "ext_register_operand" "0")
8745
              (const_int 8)
8746
              (const_int 8))
8747
            (match_operand 2 "const_int_operand" "n"))
8748
          (const_int 0)))
8749
   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8750
                         (const_int 8)
8751
                         (const_int 8))
8752
        (and:SI
8753
          (zero_extract:SI
8754
            (match_dup 1)
8755
            (const_int 8)
8756
            (const_int 8))
8757
          (match_dup 2)))]
8758
  "ix86_match_ccmode (insn, CCNOmode)"
8759
  "and{b}\t{%2, %h0|%h0, %2}"
8760
  [(set_attr "type" "alu")
8761
   (set_attr "length_immediate" "1")
8762
   (set_attr "modrm" "1")
8763
   (set_attr "mode" "QI")])
8764
 
8765
(define_insn "*andqi_ext_1_rex64"
8766
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8767
                         (const_int 8)
8768
                         (const_int 8))
8769
        (and:SI
8770
          (zero_extract:SI
8771
            (match_operand 1 "ext_register_operand" "0")
8772
            (const_int 8)
8773
            (const_int 8))
8774
          (zero_extend:SI
8775
            (match_operand 2 "ext_register_operand" "Q"))))
8776
   (clobber (reg:CC FLAGS_REG))]
8777
  "TARGET_64BIT"
8778
  "and{b}\t{%2, %h0|%h0, %2}"
8779
  [(set_attr "type" "alu")
8780
   (set_attr "length_immediate" "0")
8781
   (set_attr "mode" "QI")])
8782
 
8783
(define_insn "*andqi_ext_1"
8784
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8785
                         (const_int 8)
8786
                         (const_int 8))
8787
        (and:SI
8788
          (zero_extract:SI
8789
            (match_operand 1 "ext_register_operand" "0")
8790
            (const_int 8)
8791
            (const_int 8))
8792
          (zero_extend:SI
8793
            (match_operand:QI 2 "general_operand" "Qm"))))
8794
   (clobber (reg:CC FLAGS_REG))]
8795
  "!TARGET_64BIT"
8796
  "and{b}\t{%2, %h0|%h0, %2}"
8797
  [(set_attr "type" "alu")
8798
   (set_attr "length_immediate" "0")
8799
   (set_attr "mode" "QI")])
8800
 
8801
(define_insn "*andqi_ext_2"
8802
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8803
                         (const_int 8)
8804
                         (const_int 8))
8805
        (and:SI
8806
          (zero_extract:SI
8807
            (match_operand 1 "ext_register_operand" "%0")
8808
            (const_int 8)
8809
            (const_int 8))
8810
          (zero_extract:SI
8811
            (match_operand 2 "ext_register_operand" "Q")
8812
            (const_int 8)
8813
            (const_int 8))))
8814
   (clobber (reg:CC FLAGS_REG))]
8815
  ""
8816
  "and{b}\t{%h2, %h0|%h0, %h2}"
8817
  [(set_attr "type" "alu")
8818
   (set_attr "length_immediate" "0")
8819
   (set_attr "mode" "QI")])
8820
 
8821
;; Convert wide AND instructions with immediate operand to shorter QImode
8822
;; equivalents when possible.
8823
;; Don't do the splitting with memory operands, since it introduces risk
8824
;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8825
;; for size, but that can (should?) be handled by generic code instead.
8826
(define_split
8827
  [(set (match_operand 0 "register_operand" "")
8828
        (and (match_operand 1 "register_operand" "")
8829
             (match_operand 2 "const_int_operand" "")))
8830
   (clobber (reg:CC FLAGS_REG))]
8831
   "reload_completed
8832
    && QI_REG_P (operands[0])
8833
    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8834
    && !(~INTVAL (operands[2]) & ~(255 << 8))
8835
    && GET_MODE (operands[0]) != QImode"
8836
  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8837
                   (and:SI (zero_extract:SI (match_dup 1)
8838
                                            (const_int 8) (const_int 8))
8839
                           (match_dup 2)))
8840
              (clobber (reg:CC FLAGS_REG))])]
8841
  "operands[0] = gen_lowpart (SImode, operands[0]);
8842
   operands[1] = gen_lowpart (SImode, operands[1]);
8843
   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8844
 
8845
;; Since AND can be encoded with sign extended immediate, this is only
8846
;; profitable when 7th bit is not set.
8847
(define_split
8848
  [(set (match_operand 0 "register_operand" "")
8849
        (and (match_operand 1 "general_operand" "")
8850
             (match_operand 2 "const_int_operand" "")))
8851
   (clobber (reg:CC FLAGS_REG))]
8852
   "reload_completed
8853
    && ANY_QI_REG_P (operands[0])
8854
    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8855
    && !(~INTVAL (operands[2]) & ~255)
8856
    && !(INTVAL (operands[2]) & 128)
8857
    && GET_MODE (operands[0]) != QImode"
8858
  [(parallel [(set (strict_low_part (match_dup 0))
8859
                   (and:QI (match_dup 1)
8860
                           (match_dup 2)))
8861
              (clobber (reg:CC FLAGS_REG))])]
8862
  "operands[0] = gen_lowpart (QImode, operands[0]);
8863
   operands[1] = gen_lowpart (QImode, operands[1]);
8864
   operands[2] = gen_lowpart (QImode, operands[2]);")
8865
 
8866
;; Logical inclusive and exclusive OR instructions
8867
 
8868
;; %%% This used to optimize known byte-wide and operations to memory.
8869
;; If this is considered useful, it should be done with splitters.
8870
 
8871
(define_expand "3"
8872
  [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8873
        (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8874
                     (match_operand:SWIM 2 "" "")))]
8875
  ""
8876
  "ix86_expand_binary_operator (, mode, operands); DONE;")
8877
 
8878
(define_insn "*_1"
8879
  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8880
        (any_or:SWI248
8881
         (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8882
         (match_operand:SWI248 2 "" ",r")))
8883
   (clobber (reg:CC FLAGS_REG))]
8884
  "ix86_binary_operator_ok (, mode, operands)"
8885
  "{}\t{%2, %0|%0, %2}"
8886
  [(set_attr "type" "alu")
8887
   (set_attr "mode" "")])
8888
 
8889
;; %%% Potential partial reg stall on alternative 2.  What to do?
8890
(define_insn "*qi_1"
8891
  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8892
        (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8893
                   (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8894
   (clobber (reg:CC FLAGS_REG))]
8895
  "ix86_binary_operator_ok (, QImode, operands)"
8896
  "@
8897
   {b}\t{%2, %0|%0, %2}
8898
   {b}\t{%2, %0|%0, %2}
8899
   {l}\t{%k2, %k0|%k0, %k2}"
8900
  [(set_attr "type" "alu")
8901
   (set_attr "mode" "QI,QI,SI")])
8902
 
8903
;; See comment for addsi_1_zext why we do use nonimmediate_operand
8904
(define_insn "*si_1_zext"
8905
  [(set (match_operand:DI 0 "register_operand" "=r")
8906
        (zero_extend:DI
8907
         (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8908
                    (match_operand:SI 2 "general_operand" "g"))))
8909
   (clobber (reg:CC FLAGS_REG))]
8910
  "TARGET_64BIT && ix86_binary_operator_ok (, SImode, operands)"
8911
  "{l}\t{%2, %k0|%k0, %2}"
8912
  [(set_attr "type" "alu")
8913
   (set_attr "mode" "SI")])
8914
 
8915
(define_insn "*si_1_zext_imm"
8916
  [(set (match_operand:DI 0 "register_operand" "=r")
8917
        (any_or:DI
8918
         (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8919
         (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8920
   (clobber (reg:CC FLAGS_REG))]
8921
  "TARGET_64BIT && ix86_binary_operator_ok (, SImode, operands)"
8922
  "{l}\t{%2, %k0|%k0, %2}"
8923
  [(set_attr "type" "alu")
8924
   (set_attr "mode" "SI")])
8925
 
8926
(define_insn "*qi_1_slp"
8927
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8928
        (any_or:QI (match_dup 0)
8929
                   (match_operand:QI 1 "general_operand" "qmn,qn")))
8930
   (clobber (reg:CC FLAGS_REG))]
8931
  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8932
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8933
  "{b}\t{%1, %0|%0, %1}"
8934
  [(set_attr "type" "alu1")
8935
   (set_attr "mode" "QI")])
8936
 
8937
(define_insn "*_2"
8938
  [(set (reg FLAGS_REG)
8939
        (compare (any_or:SWI
8940
                  (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8941
                  (match_operand:SWI 2 "" ","))
8942
                 (const_int 0)))
8943
   (set (match_operand:SWI 0 "nonimmediate_operand" "=,m")
8944
        (any_or:SWI (match_dup 1) (match_dup 2)))]
8945
  "ix86_match_ccmode (insn, CCNOmode)
8946
   && ix86_binary_operator_ok (, mode, operands)"
8947
  "{}\t{%2, %0|%0, %2}"
8948
  [(set_attr "type" "alu")
8949
   (set_attr "mode" "")])
8950
 
8951
;; See comment for addsi_1_zext why we do use nonimmediate_operand
8952
;; ??? Special case for immediate operand is missing - it is tricky.
8953
(define_insn "*si_2_zext"
8954
  [(set (reg FLAGS_REG)
8955
        (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956
                            (match_operand:SI 2 "general_operand" "g"))
8957
                 (const_int 0)))
8958
   (set (match_operand:DI 0 "register_operand" "=r")
8959
        (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8960
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8961
   && ix86_binary_operator_ok (, SImode, operands)"
8962
  "{l}\t{%2, %k0|%k0, %2}"
8963
  [(set_attr "type" "alu")
8964
   (set_attr "mode" "SI")])
8965
 
8966
(define_insn "*si_2_zext_imm"
8967
  [(set (reg FLAGS_REG)
8968
        (compare (any_or:SI
8969
                  (match_operand:SI 1 "nonimmediate_operand" "%0")
8970
                  (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8971
                 (const_int 0)))
8972
   (set (match_operand:DI 0 "register_operand" "=r")
8973
        (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8974
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8975
   && ix86_binary_operator_ok (, SImode, operands)"
8976
  "{l}\t{%2, %k0|%k0, %2}"
8977
  [(set_attr "type" "alu")
8978
   (set_attr "mode" "SI")])
8979
 
8980
(define_insn "*qi_2_slp"
8981
  [(set (reg FLAGS_REG)
8982
        (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8983
                            (match_operand:QI 1 "general_operand" "qmn,qn"))
8984
                 (const_int 0)))
8985
   (set (strict_low_part (match_dup 0))
8986
        (any_or:QI (match_dup 0) (match_dup 1)))]
8987
  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8988
   && ix86_match_ccmode (insn, CCNOmode)
8989
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8990
  "{b}\t{%1, %0|%0, %1}"
8991
  [(set_attr "type" "alu1")
8992
   (set_attr "mode" "QI")])
8993
 
8994
(define_insn "*_3"
8995
  [(set (reg FLAGS_REG)
8996
        (compare (any_or:SWI
8997
                  (match_operand:SWI 1 "nonimmediate_operand" "%0")
8998
                  (match_operand:SWI 2 "" ""))
8999
                 (const_int 0)))
9000
   (clobber (match_scratch:SWI 0 "="))]
9001
  "ix86_match_ccmode (insn, CCNOmode)
9002
   && ix86_binary_operator_ok (, mode, operands)"
9003
  "{}\t{%2, %0|%0, %2}"
9004
  [(set_attr "type" "alu")
9005
   (set_attr "mode" "")])
9006
 
9007
(define_insn "*qi_ext_0"
9008
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9009
                         (const_int 8)
9010
                         (const_int 8))
9011
        (any_or:SI
9012
          (zero_extract:SI
9013
            (match_operand 1 "ext_register_operand" "0")
9014
            (const_int 8)
9015
            (const_int 8))
9016
          (match_operand 2 "const_int_operand" "n")))
9017
   (clobber (reg:CC FLAGS_REG))]
9018
  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9019
  "{b}\t{%2, %h0|%h0, %2}"
9020
  [(set_attr "type" "alu")
9021
   (set_attr "length_immediate" "1")
9022
   (set_attr "modrm" "1")
9023
   (set_attr "mode" "QI")])
9024
 
9025
(define_insn "*qi_ext_1_rex64"
9026
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9027
                         (const_int 8)
9028
                         (const_int 8))
9029
        (any_or:SI
9030
          (zero_extract:SI
9031
            (match_operand 1 "ext_register_operand" "0")
9032
            (const_int 8)
9033
            (const_int 8))
9034
          (zero_extend:SI
9035
            (match_operand 2 "ext_register_operand" "Q"))))
9036
   (clobber (reg:CC FLAGS_REG))]
9037
  "TARGET_64BIT
9038
   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9039
  "{b}\t{%2, %h0|%h0, %2}"
9040
  [(set_attr "type" "alu")
9041
   (set_attr "length_immediate" "0")
9042
   (set_attr "mode" "QI")])
9043
 
9044
(define_insn "*qi_ext_1"
9045
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9046
                         (const_int 8)
9047
                         (const_int 8))
9048
        (any_or:SI
9049
          (zero_extract:SI
9050
            (match_operand 1 "ext_register_operand" "0")
9051
            (const_int 8)
9052
            (const_int 8))
9053
          (zero_extend:SI
9054
            (match_operand:QI 2 "general_operand" "Qm"))))
9055
   (clobber (reg:CC FLAGS_REG))]
9056
  "!TARGET_64BIT
9057
   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9058
  "{b}\t{%2, %h0|%h0, %2}"
9059
  [(set_attr "type" "alu")
9060
   (set_attr "length_immediate" "0")
9061
   (set_attr "mode" "QI")])
9062
 
9063
(define_insn "*qi_ext_2"
9064
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9065
                         (const_int 8)
9066
                         (const_int 8))
9067
        (any_or:SI
9068
          (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9069
                           (const_int 8)
9070
                           (const_int 8))
9071
          (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9072
                           (const_int 8)
9073
                           (const_int 8))))
9074
   (clobber (reg:CC FLAGS_REG))]
9075
  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9076
  "{b}\t{%h2, %h0|%h0, %h2}"
9077
  [(set_attr "type" "alu")
9078
   (set_attr "length_immediate" "0")
9079
   (set_attr "mode" "QI")])
9080
 
9081
(define_split
9082
  [(set (match_operand 0 "register_operand" "")
9083
        (any_or (match_operand 1 "register_operand" "")
9084
                (match_operand 2 "const_int_operand" "")))
9085
   (clobber (reg:CC FLAGS_REG))]
9086
   "reload_completed
9087
    && QI_REG_P (operands[0])
9088
    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9089
    && !(INTVAL (operands[2]) & ~(255 << 8))
9090
    && GET_MODE (operands[0]) != QImode"
9091
  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9092
                   (any_or:SI (zero_extract:SI (match_dup 1)
9093
                                               (const_int 8) (const_int 8))
9094
                              (match_dup 2)))
9095
              (clobber (reg:CC FLAGS_REG))])]
9096
  "operands[0] = gen_lowpart (SImode, operands[0]);
9097
   operands[1] = gen_lowpart (SImode, operands[1]);
9098
   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9099
 
9100
;; Since OR can be encoded with sign extended immediate, this is only
9101
;; profitable when 7th bit is set.
9102
(define_split
9103
  [(set (match_operand 0 "register_operand" "")
9104
        (any_or (match_operand 1 "general_operand" "")
9105
                (match_operand 2 "const_int_operand" "")))
9106
   (clobber (reg:CC FLAGS_REG))]
9107
   "reload_completed
9108
    && ANY_QI_REG_P (operands[0])
9109
    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9110
    && !(INTVAL (operands[2]) & ~255)
9111
    && (INTVAL (operands[2]) & 128)
9112
    && GET_MODE (operands[0]) != QImode"
9113
  [(parallel [(set (strict_low_part (match_dup 0))
9114
                   (any_or:QI (match_dup 1)
9115
                              (match_dup 2)))
9116
              (clobber (reg:CC FLAGS_REG))])]
9117
  "operands[0] = gen_lowpart (QImode, operands[0]);
9118
   operands[1] = gen_lowpart (QImode, operands[1]);
9119
   operands[2] = gen_lowpart (QImode, operands[2]);")
9120
 
9121
(define_expand "xorqi_cc_ext_1"
9122
  [(parallel [
9123
     (set (reg:CCNO FLAGS_REG)
9124
          (compare:CCNO
9125
            (xor:SI
9126
              (zero_extract:SI
9127
                (match_operand 1 "ext_register_operand" "")
9128
                (const_int 8)
9129
                (const_int 8))
9130
              (match_operand:QI 2 "general_operand" ""))
9131
            (const_int 0)))
9132
     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9133
                           (const_int 8)
9134
                           (const_int 8))
9135
          (xor:SI
9136
            (zero_extract:SI
9137
             (match_dup 1)
9138
             (const_int 8)
9139
             (const_int 8))
9140
            (match_dup 2)))])]
9141
  ""
9142
  "")
9143
 
9144
(define_insn "*xorqi_cc_ext_1_rex64"
9145
  [(set (reg FLAGS_REG)
9146
        (compare
9147
          (xor:SI
9148
            (zero_extract:SI
9149
              (match_operand 1 "ext_register_operand" "0")
9150
              (const_int 8)
9151
              (const_int 8))
9152
            (match_operand:QI 2 "nonmemory_operand" "Qn"))
9153
          (const_int 0)))
9154
   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9155
                         (const_int 8)
9156
                         (const_int 8))
9157
        (xor:SI
9158
          (zero_extract:SI
9159
           (match_dup 1)
9160
           (const_int 8)
9161
           (const_int 8))
9162
          (match_dup 2)))]
9163
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9164
  "xor{b}\t{%2, %h0|%h0, %2}"
9165
  [(set_attr "type" "alu")
9166
   (set_attr "modrm" "1")
9167
   (set_attr "mode" "QI")])
9168
 
9169
(define_insn "*xorqi_cc_ext_1"
9170
  [(set (reg FLAGS_REG)
9171
        (compare
9172
          (xor:SI
9173
            (zero_extract:SI
9174
              (match_operand 1 "ext_register_operand" "0")
9175
              (const_int 8)
9176
              (const_int 8))
9177
            (match_operand:QI 2 "general_operand" "qmn"))
9178
          (const_int 0)))
9179
   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9180
                         (const_int 8)
9181
                         (const_int 8))
9182
        (xor:SI
9183
          (zero_extract:SI
9184
           (match_dup 1)
9185
           (const_int 8)
9186
           (const_int 8))
9187
          (match_dup 2)))]
9188
  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9189
  "xor{b}\t{%2, %h0|%h0, %2}"
9190
  [(set_attr "type" "alu")
9191
   (set_attr "modrm" "1")
9192
   (set_attr "mode" "QI")])
9193
 
9194
;; Negation instructions
9195
 
9196
(define_expand "neg2"
9197
  [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9198
        (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9199
  ""
9200
  "ix86_expand_unary_operator (NEG, mode, operands); DONE;")
9201
 
9202
(define_insn_and_split "*neg2_doubleword"
9203
  [(set (match_operand: 0 "nonimmediate_operand" "=ro")
9204
        (neg: (match_operand: 1 "nonimmediate_operand" "0")))
9205
   (clobber (reg:CC FLAGS_REG))]
9206
  "ix86_unary_operator_ok (NEG, mode, operands)"
9207
  "#"
9208
  "reload_completed"
9209
  [(parallel
9210
    [(set (reg:CCZ FLAGS_REG)
9211
          (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9212
     (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9213
   (parallel
9214
    [(set (match_dup 2)
9215
          (plus:DWIH (match_dup 3)
9216
                     (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9217
                                (const_int 0))))
9218
     (clobber (reg:CC FLAGS_REG))])
9219
   (parallel
9220
    [(set (match_dup 2)
9221
          (neg:DWIH (match_dup 2)))
9222
     (clobber (reg:CC FLAGS_REG))])]
9223
  "split_ (&operands[0], 2, &operands[0], &operands[2]);")
9224
 
9225
(define_insn "*neg2_1"
9226
  [(set (match_operand:SWI 0 "nonimmediate_operand" "=m")
9227
        (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9228
   (clobber (reg:CC FLAGS_REG))]
9229
  "ix86_unary_operator_ok (NEG, mode, operands)"
9230
  "neg{}\t%0"
9231
  [(set_attr "type" "negnot")
9232
   (set_attr "mode" "")])
9233
 
9234
;; Combine is quite creative about this pattern.
9235
(define_insn "*negsi2_1_zext"
9236
  [(set (match_operand:DI 0 "register_operand" "=r")
9237
        (lshiftrt:DI
9238
          (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9239
                             (const_int 32)))
9240
        (const_int 32)))
9241
   (clobber (reg:CC FLAGS_REG))]
9242
  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9243
  "neg{l}\t%k0"
9244
  [(set_attr "type" "negnot")
9245
   (set_attr "mode" "SI")])
9246
 
9247
;; The problem with neg is that it does not perform (compare x 0),
9248
;; it really performs (compare 0 x), which leaves us with the zero
9249
;; flag being the only useful item.
9250
 
9251
(define_insn "*neg2_cmpz"
9252
  [(set (reg:CCZ FLAGS_REG)
9253
        (compare:CCZ
9254
          (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9255
                   (const_int 0)))
9256
   (set (match_operand:SWI 0 "nonimmediate_operand" "=m")
9257
        (neg:SWI (match_dup 1)))]
9258
  "ix86_unary_operator_ok (NEG, mode, operands)"
9259
  "neg{}\t%0"
9260
  [(set_attr "type" "negnot")
9261
   (set_attr "mode" "")])
9262
 
9263
(define_insn "*negsi2_cmpz_zext"
9264
  [(set (reg:CCZ FLAGS_REG)
9265
        (compare:CCZ
9266
          (lshiftrt:DI
9267
            (neg:DI (ashift:DI
9268
                      (match_operand:DI 1 "register_operand" "0")
9269
                      (const_int 32)))
9270
            (const_int 32))
9271
          (const_int 0)))
9272
   (set (match_operand:DI 0 "register_operand" "=r")
9273
        (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9274
                                        (const_int 32)))
9275
                     (const_int 32)))]
9276
  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9277
  "neg{l}\t%k0"
9278
  [(set_attr "type" "negnot")
9279
   (set_attr "mode" "SI")])
9280
 
9281
;; Changing of sign for FP values is doable using integer unit too.
9282
 
9283
(define_expand "2"
9284
  [(set (match_operand:X87MODEF 0 "register_operand" "")
9285
        (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9286
  "TARGET_80387 || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
9287
  "ix86_expand_fp_absneg_operator (, mode, operands); DONE;")
9288
 
9289
(define_insn "*absneg2_mixed"
9290
  [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9291
        (match_operator:MODEF 3 "absneg_operator"
9292
          [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9293
   (use (match_operand: 2 "nonimmediate_operand" "xm,0,X,X"))
9294
   (clobber (reg:CC FLAGS_REG))]
9295
  "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (mode)"
9296
  "#")
9297
 
9298
(define_insn "*absneg2_sse"
9299
  [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9300
        (match_operator:MODEF 3 "absneg_operator"
9301
          [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9302
   (use (match_operand: 2 "register_operand" "xm,0,X"))
9303
   (clobber (reg:CC FLAGS_REG))]
9304
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
9305
  "#")
9306
 
9307
(define_insn "*absneg2_i387"
9308
  [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9309
        (match_operator:X87MODEF 3 "absneg_operator"
9310
          [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9311
   (use (match_operand 2 "" ""))
9312
   (clobber (reg:CC FLAGS_REG))]
9313
  "TARGET_80387 && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
9314
  "#")
9315
 
9316
(define_expand "tf2"
9317
  [(set (match_operand:TF 0 "register_operand" "")
9318
        (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9319
  "TARGET_SSE2"
9320
  "ix86_expand_fp_absneg_operator (, TFmode, operands); DONE;")
9321
 
9322
(define_insn "*absnegtf2_sse"
9323
  [(set (match_operand:TF 0 "register_operand" "=x,x")
9324
        (match_operator:TF 3 "absneg_operator"
9325
          [(match_operand:TF 1 "register_operand" "0,x")]))
9326
   (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9327
   (clobber (reg:CC FLAGS_REG))]
9328
  "TARGET_SSE2"
9329
  "#")
9330
 
9331
;; Splitters for fp abs and neg.
9332
 
9333
(define_split
9334
  [(set (match_operand 0 "fp_register_operand" "")
9335
        (match_operator 1 "absneg_operator" [(match_dup 0)]))
9336
   (use (match_operand 2 "" ""))
9337
   (clobber (reg:CC FLAGS_REG))]
9338
  "reload_completed"
9339
  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9340
 
9341
(define_split
9342
  [(set (match_operand 0 "register_operand" "")
9343
        (match_operator 3 "absneg_operator"
9344
          [(match_operand 1 "register_operand" "")]))
9345
   (use (match_operand 2 "nonimmediate_operand" ""))
9346
   (clobber (reg:CC FLAGS_REG))]
9347
  "reload_completed && SSE_REG_P (operands[0])"
9348
  [(set (match_dup 0) (match_dup 3))]
9349
{
9350
  enum machine_mode mode = GET_MODE (operands[0]);
9351
  enum machine_mode vmode = GET_MODE (operands[2]);
9352
  rtx tmp;
9353
 
9354
  operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9355
  operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9356
  if (operands_match_p (operands[0], operands[2]))
9357
    {
9358
      tmp = operands[1];
9359
      operands[1] = operands[2];
9360
      operands[2] = tmp;
9361
    }
9362
  if (GET_CODE (operands[3]) == ABS)
9363
    tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9364
  else
9365
    tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9366
  operands[3] = tmp;
9367
})
9368
 
9369
(define_split
9370
  [(set (match_operand:SF 0 "register_operand" "")
9371
        (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9372
   (use (match_operand:V4SF 2 "" ""))
9373
   (clobber (reg:CC FLAGS_REG))]
9374
  "reload_completed"
9375
  [(parallel [(set (match_dup 0) (match_dup 1))
9376
              (clobber (reg:CC FLAGS_REG))])]
9377
{
9378
  rtx tmp;
9379
  operands[0] = gen_lowpart (SImode, operands[0]);
9380
  if (GET_CODE (operands[1]) == ABS)
9381
    {
9382
      tmp = gen_int_mode (0x7fffffff, SImode);
9383
      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9384
    }
9385
  else
9386
    {
9387
      tmp = gen_int_mode (0x80000000, SImode);
9388
      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9389
    }
9390
  operands[1] = tmp;
9391
})
9392
 
9393
(define_split
9394
  [(set (match_operand:DF 0 "register_operand" "")
9395
        (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9396
   (use (match_operand 2 "" ""))
9397
   (clobber (reg:CC FLAGS_REG))]
9398
  "reload_completed"
9399
  [(parallel [(set (match_dup 0) (match_dup 1))
9400
              (clobber (reg:CC FLAGS_REG))])]
9401
{
9402
  rtx tmp;
9403
  if (TARGET_64BIT)
9404
    {
9405
      tmp = gen_lowpart (DImode, operands[0]);
9406
      tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9407
      operands[0] = tmp;
9408
 
9409
      if (GET_CODE (operands[1]) == ABS)
9410
        tmp = const0_rtx;
9411
      else
9412
        tmp = gen_rtx_NOT (DImode, tmp);
9413
    }
9414
  else
9415
    {
9416
      operands[0] = gen_highpart (SImode, operands[0]);
9417
      if (GET_CODE (operands[1]) == ABS)
9418
        {
9419
          tmp = gen_int_mode (0x7fffffff, SImode);
9420
          tmp = gen_rtx_AND (SImode, operands[0], tmp);
9421
        }
9422
      else
9423
        {
9424
          tmp = gen_int_mode (0x80000000, SImode);
9425
          tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9426
        }
9427
    }
9428
  operands[1] = tmp;
9429
})
9430
 
9431
(define_split
9432
  [(set (match_operand:XF 0 "register_operand" "")
9433
        (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9434
   (use (match_operand 2 "" ""))
9435
   (clobber (reg:CC FLAGS_REG))]
9436
  "reload_completed"
9437
  [(parallel [(set (match_dup 0) (match_dup 1))
9438
              (clobber (reg:CC FLAGS_REG))])]
9439
{
9440
  rtx tmp;
9441
  operands[0] = gen_rtx_REG (SImode,
9442
                             true_regnum (operands[0])
9443
                             + (TARGET_64BIT ? 1 : 2));
9444
  if (GET_CODE (operands[1]) == ABS)
9445
    {
9446
      tmp = GEN_INT (0x7fff);
9447
      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9448
    }
9449
  else
9450
    {
9451
      tmp = GEN_INT (0x8000);
9452
      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9453
    }
9454
  operands[1] = tmp;
9455
})
9456
 
9457
;; Conditionalize these after reload. If they match before reload, we
9458
;; lose the clobber and ability to use integer instructions.
9459
 
9460
(define_insn "*2_1"
9461
  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9462
        (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9463
  "TARGET_80387
9464
   && (reload_completed
9465
       || !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))"
9466
  "f"
9467
  [(set_attr "type" "fsgn")
9468
   (set_attr "mode" "")])
9469
 
9470
(define_insn "*extendsfdf2"
9471
  [(set (match_operand:DF 0 "register_operand" "=f")
9472
        (absneg:DF (float_extend:DF
9473
                     (match_operand:SF 1 "register_operand" "0"))))]
9474
  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9475
  "f"
9476
  [(set_attr "type" "fsgn")
9477
   (set_attr "mode" "DF")])
9478
 
9479
(define_insn "*extendsfxf2"
9480
  [(set (match_operand:XF 0 "register_operand" "=f")
9481
        (absneg:XF (float_extend:XF
9482
                     (match_operand:SF 1 "register_operand" "0"))))]
9483
  "TARGET_80387"
9484
  "f"
9485
  [(set_attr "type" "fsgn")
9486
   (set_attr "mode" "XF")])
9487
 
9488
(define_insn "*extenddfxf2"
9489
  [(set (match_operand:XF 0 "register_operand" "=f")
9490
        (absneg:XF (float_extend:XF
9491
                      (match_operand:DF 1 "register_operand" "0"))))]
9492
  "TARGET_80387"
9493
  "f"
9494
  [(set_attr "type" "fsgn")
9495
   (set_attr "mode" "XF")])
9496
 
9497
;; Copysign instructions
9498
 
9499
(define_mode_iterator CSGNMODE [SF DF TF])
9500
(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9501
 
9502
(define_expand "copysign3"
9503
  [(match_operand:CSGNMODE 0 "register_operand" "")
9504
   (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9505
   (match_operand:CSGNMODE 2 "register_operand" "")]
9506
  "(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
9507
   || (TARGET_SSE2 && (mode == TFmode))"
9508
{
9509
  ix86_expand_copysign (operands);
9510
  DONE;
9511
})
9512
 
9513
(define_insn_and_split "copysign3_const"
9514
  [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9515
        (unspec:CSGNMODE
9516
          [(match_operand: 1 "vector_move_operand" "xmC")
9517
           (match_operand:CSGNMODE 2 "register_operand" "0")
9518
           (match_operand: 3 "nonimmediate_operand" "xm")]
9519
          UNSPEC_COPYSIGN))]
9520
  "(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
9521
   || (TARGET_SSE2 && (mode == TFmode))"
9522
  "#"
9523
  "&& reload_completed"
9524
  [(const_int 0)]
9525
{
9526
  ix86_split_copysign_const (operands);
9527
  DONE;
9528
})
9529
 
9530
(define_insn "copysign3_var"
9531
  [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9532
        (unspec:CSGNMODE
9533
          [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9534
           (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9535
           (match_operand: 4 "nonimmediate_operand" "X,xm,xm,0,0")
9536
           (match_operand: 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9537
          UNSPEC_COPYSIGN))
9538
   (clobber (match_scratch: 1 "=x,x,x,x,x"))]
9539
  "(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
9540
   || (TARGET_SSE2 && (mode == TFmode))"
9541
  "#")
9542
 
9543
(define_split
9544
  [(set (match_operand:CSGNMODE 0 "register_operand" "")
9545
        (unspec:CSGNMODE
9546
          [(match_operand:CSGNMODE 2 "register_operand" "")
9547
           (match_operand:CSGNMODE 3 "register_operand" "")
9548
           (match_operand: 4 "" "")
9549
           (match_operand: 5 "" "")]
9550
          UNSPEC_COPYSIGN))
9551
   (clobber (match_scratch: 1 ""))]
9552
  "((SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
9553
    || (TARGET_SSE2 && (mode == TFmode)))
9554
   && reload_completed"
9555
  [(const_int 0)]
9556
{
9557
  ix86_split_copysign_var (operands);
9558
  DONE;
9559
})
9560
 
9561
;; One complement instructions
9562
 
9563
(define_expand "one_cmpl2"
9564
  [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9565
        (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9566
  ""
9567
  "ix86_expand_unary_operator (NOT, mode, operands); DONE;")
9568
 
9569
(define_insn "*one_cmpl2_1"
9570
  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9571
        (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9572
  "ix86_unary_operator_ok (NOT, mode, operands)"
9573
  "not{}\t%0"
9574
  [(set_attr "type" "negnot")
9575
   (set_attr "mode" "")])
9576
 
9577
;; %%% Potential partial reg stall on alternative 1.  What to do?
9578
(define_insn "*one_cmplqi2_1"
9579
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9580
        (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9581
  "ix86_unary_operator_ok (NOT, QImode, operands)"
9582
  "@
9583
   not{b}\t%0
9584
   not{l}\t%k0"
9585
  [(set_attr "type" "negnot")
9586
   (set_attr "mode" "QI,SI")])
9587
 
9588
;; ??? Currently never generated - xor is used instead.
9589
(define_insn "*one_cmplsi2_1_zext"
9590
  [(set (match_operand:DI 0 "register_operand" "=r")
9591
        (zero_extend:DI
9592
          (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9593
  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9594
  "not{l}\t%k0"
9595
  [(set_attr "type" "negnot")
9596
   (set_attr "mode" "SI")])
9597
 
9598
(define_insn "*one_cmpl2_2"
9599
  [(set (reg FLAGS_REG)
9600
        (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9601
                 (const_int 0)))
9602
   (set (match_operand:SWI 0 "nonimmediate_operand" "=m")
9603
        (not:SWI (match_dup 1)))]
9604
  "ix86_match_ccmode (insn, CCNOmode)
9605
   && ix86_unary_operator_ok (NOT, mode, operands)"
9606
  "#"
9607
  [(set_attr "type" "alu1")
9608
   (set_attr "mode" "")])
9609
 
9610
(define_split
9611
  [(set (match_operand 0 "flags_reg_operand" "")
9612
        (match_operator 2 "compare_operator"
9613
          [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9614
           (const_int 0)]))
9615
   (set (match_operand:SWI 1 "nonimmediate_operand" "")
9616
        (not:SWI (match_dup 3)))]
9617
  "ix86_match_ccmode (insn, CCNOmode)"
9618
  [(parallel [(set (match_dup 0)
9619
                   (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9620
                                    (const_int 0)]))
9621
              (set (match_dup 1)
9622
                   (xor:SWI (match_dup 3) (const_int -1)))])]
9623
  "")
9624
 
9625
;; ??? Currently never generated - xor is used instead.
9626
(define_insn "*one_cmplsi2_2_zext"
9627
  [(set (reg FLAGS_REG)
9628
        (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9629
                 (const_int 0)))
9630
   (set (match_operand:DI 0 "register_operand" "=r")
9631
        (zero_extend:DI (not:SI (match_dup 1))))]
9632
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9633
   && ix86_unary_operator_ok (NOT, SImode, operands)"
9634
  "#"
9635
  [(set_attr "type" "alu1")
9636
   (set_attr "mode" "SI")])
9637
 
9638
(define_split
9639
  [(set (match_operand 0 "flags_reg_operand" "")
9640
        (match_operator 2 "compare_operator"
9641
          [(not:SI (match_operand:SI 3 "register_operand" ""))
9642
           (const_int 0)]))
9643
   (set (match_operand:DI 1 "register_operand" "")
9644
        (zero_extend:DI (not:SI (match_dup 3))))]
9645
  "ix86_match_ccmode (insn, CCNOmode)"
9646
  [(parallel [(set (match_dup 0)
9647
                   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9648
                                    (const_int 0)]))
9649
              (set (match_dup 1)
9650
                   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9651
  "")
9652
 
9653
;; Arithmetic shift instructions
9654
 
9655
;; DImode shifts are implemented using the i386 "shift double" opcode,
9656
;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9657
;; is variable, then the count is in %cl and the "imm" operand is dropped
9658
;; from the assembler input.
9659
;;
9660
;; This instruction shifts the target reg/mem as usual, but instead of
9661
;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9662
;; is a left shift double, bits are taken from the high order bits of
9663
;; reg, else if the insn is a shift right double, bits are taken from the
9664
;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9665
;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9666
;;
9667
;; Since sh[lr]d does not change the `reg' operand, that is done
9668
;; separately, making all shifts emit pairs of shift double and normal
9669
;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9670
;; support a 63 bit shift, each shift where the count is in a reg expands
9671
;; to a pair of shifts, a branch, a shift by 32 and a label.
9672
;;
9673
;; If the shift count is a constant, we need never emit more than one
9674
;; shift pair, instead using moves and sign extension for counts greater
9675
;; than 31.
9676
 
9677
(define_expand "ashlti3"
9678
  [(set (match_operand:TI 0 "register_operand" "")
9679
        (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
9680
                   (match_operand:QI 2 "nonmemory_operand" "")))]
9681
  "TARGET_64BIT"
9682
  "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
9683
 
9684
(define_insn "*ashlti3_1"
9685
  [(set (match_operand:TI 0 "register_operand" "=&r,r")
9686
        (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
9687
                   (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
9688
   (clobber (reg:CC FLAGS_REG))]
9689
  "TARGET_64BIT"
9690
  "#"
9691
  [(set_attr "type" "multi")])
9692
 
9693
(define_peephole2
9694
  [(match_scratch:DI 3 "r")
9695
   (parallel [(set (match_operand:TI 0 "register_operand" "")
9696
                   (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9697
                              (match_operand:QI 2 "nonmemory_operand" "")))
9698
              (clobber (reg:CC FLAGS_REG))])
9699
   (match_dup 3)]
9700
  "TARGET_64BIT"
9701
  [(const_int 0)]
9702
  "ix86_split_ashl (operands, operands[3], TImode); DONE;")
9703
 
9704
(define_split
9705
  [(set (match_operand:TI 0 "register_operand" "")
9706
        (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9707
                   (match_operand:QI 2 "nonmemory_operand" "")))
9708
   (clobber (reg:CC FLAGS_REG))]
9709
  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9710
                    ? epilogue_completed : reload_completed)"
9711
  [(const_int 0)]
9712
  "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
9713
 
9714
(define_insn "x86_64_shld"
9715
  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9716
        (ior:DI (ashift:DI (match_dup 0)
9717
                  (match_operand:QI 2 "nonmemory_operand" "Jc"))
9718
                (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9719
                  (minus:QI (const_int 64) (match_dup 2)))))
9720
   (clobber (reg:CC FLAGS_REG))]
9721
  "TARGET_64BIT"
9722
  "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9723
  [(set_attr "type" "ishift")
9724
   (set_attr "prefix_0f" "1")
9725
   (set_attr "mode" "DI")
9726
   (set_attr "athlon_decode" "vector")
9727
   (set_attr "amdfam10_decode" "vector")])
9728
 
9729
(define_expand "x86_64_shift_adj_1"
9730
  [(set (reg:CCZ FLAGS_REG)
9731
        (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9732
                             (const_int 64))
9733
                     (const_int 0)))
9734
   (set (match_operand:DI 0 "register_operand" "")
9735
        (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9736
                         (match_operand:DI 1 "register_operand" "")
9737
                         (match_dup 0)))
9738
   (set (match_dup 1)
9739
        (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9740
                         (match_operand:DI 3 "register_operand" "r")
9741
                         (match_dup 1)))]
9742
  "TARGET_64BIT"
9743
  "")
9744
 
9745
(define_expand "x86_64_shift_adj_2"
9746
  [(use (match_operand:DI 0 "register_operand" ""))
9747
   (use (match_operand:DI 1 "register_operand" ""))
9748
   (use (match_operand:QI 2 "register_operand" ""))]
9749
  "TARGET_64BIT"
9750
{
9751
  rtx label = gen_label_rtx ();
9752
  rtx tmp;
9753
 
9754
  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
9755
 
9756
  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9757
  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9758
  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9759
                              gen_rtx_LABEL_REF (VOIDmode, label),
9760
                              pc_rtx);
9761
  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9762
  JUMP_LABEL (tmp) = label;
9763
 
9764
  emit_move_insn (operands[0], operands[1]);
9765
  ix86_expand_clear (operands[1]);
9766
 
9767
  emit_label (label);
9768
  LABEL_NUSES (label) = 1;
9769
 
9770
  DONE;
9771
})
9772
 
9773
(define_expand "ashldi3"
9774
  [(set (match_operand:DI 0 "shiftdi_operand" "")
9775
        (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
9776
                   (match_operand:QI 2 "nonmemory_operand" "")))]
9777
  ""
9778
  "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
9779
 
9780
(define_insn "*ashldi3_1_rex64"
9781
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9782
        (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
9783
                   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
9784
   (clobber (reg:CC FLAGS_REG))]
9785
  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9786
{
9787
  switch (get_attr_type (insn))
9788
    {
9789
    case TYPE_ALU:
9790
      gcc_assert (operands[2] == const1_rtx);
9791
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
9792
      return "add{q}\t%0, %0";
9793
 
9794
    case TYPE_LEA:
9795
      gcc_assert (CONST_INT_P (operands[2]));
9796
      gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
9797
      operands[1] = gen_rtx_MULT (DImode, operands[1],
9798
                                  GEN_INT (1 << INTVAL (operands[2])));
9799
      return "lea{q}\t{%a1, %0|%0, %a1}";
9800
 
9801
    default:
9802
      if (REG_P (operands[2]))
9803
        return "sal{q}\t{%b2, %0|%0, %b2}";
9804
      else if (operands[2] == const1_rtx
9805
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9806
        return "sal{q}\t%0";
9807
      else
9808
        return "sal{q}\t{%2, %0|%0, %2}";
9809
    }
9810
}
9811
  [(set (attr "type")
9812
     (cond [(eq_attr "alternative" "1")
9813
              (const_string "lea")
9814
            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9815
                          (const_int 0))
9816
                      (match_operand 0 "register_operand" ""))
9817
                 (match_operand 2 "const1_operand" ""))
9818
              (const_string "alu")
9819
           ]
9820
           (const_string "ishift")))
9821
   (set (attr "length_immediate")
9822
     (if_then_else
9823
       (ior (eq_attr "type" "alu")
9824
            (and (eq_attr "type" "ishift")
9825
                 (and (match_operand 2 "const1_operand" "")
9826
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9827
                          (const_int 0)))))
9828
       (const_string "0")
9829
       (const_string "*")))
9830
   (set_attr "mode" "DI")])
9831
 
9832
;; Convert lea to the lea pattern to avoid flags dependency.
9833
(define_split
9834
  [(set (match_operand:DI 0 "register_operand" "")
9835
        (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9836
                   (match_operand:QI 2 "immediate_operand" "")))
9837
   (clobber (reg:CC FLAGS_REG))]
9838
  "TARGET_64BIT && reload_completed
9839
   && true_regnum (operands[0]) != true_regnum (operands[1])"
9840
  [(set (match_dup 0)
9841
        (mult:DI (match_dup 1)
9842
                 (match_dup 2)))]
9843
  "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9844
 
9845
;; This pattern can't accept a variable shift count, since shifts by
9846
;; zero don't affect the flags.  We assume that shifts by constant
9847
;; zero are optimized away.
9848
(define_insn "*ashldi3_cmp_rex64"
9849
  [(set (reg FLAGS_REG)
9850
        (compare
9851
          (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9852
                     (match_operand:QI 2 "const_1_to_63_operand" "J"))
9853
          (const_int 0)))
9854
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9855
        (ashift:DI (match_dup 1) (match_dup 2)))]
9856
  "TARGET_64BIT
9857
   && (optimize_function_for_size_p (cfun)
9858
       || !TARGET_PARTIAL_FLAG_REG_STALL
9859
       || (operands[2] == const1_rtx
9860
           && (TARGET_SHIFT1
9861
               || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9862
   && ix86_match_ccmode (insn, CCGOCmode)
9863
   && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9864
{
9865
  switch (get_attr_type (insn))
9866
    {
9867
    case TYPE_ALU:
9868
      gcc_assert (operands[2] == const1_rtx);
9869
      return "add{q}\t%0, %0";
9870
 
9871
    default:
9872
      if (REG_P (operands[2]))
9873
        return "sal{q}\t{%b2, %0|%0, %b2}";
9874
      else if (operands[2] == const1_rtx
9875
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9876
        return "sal{q}\t%0";
9877
      else
9878
        return "sal{q}\t{%2, %0|%0, %2}";
9879
    }
9880
}
9881
  [(set (attr "type")
9882
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9883
                          (const_int 0))
9884
                      (match_operand 0 "register_operand" ""))
9885
                 (match_operand 2 "const1_operand" ""))
9886
              (const_string "alu")
9887
           ]
9888
           (const_string "ishift")))
9889
   (set (attr "length_immediate")
9890
     (if_then_else
9891
       (ior (eq_attr "type" "alu")
9892
            (and (eq_attr "type" "ishift")
9893
                 (and (match_operand 2 "const1_operand" "")
9894
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9895
                          (const_int 0)))))
9896
       (const_string "0")
9897
       (const_string "*")))
9898
   (set_attr "mode" "DI")])
9899
 
9900
(define_insn "*ashldi3_cconly_rex64"
9901
  [(set (reg FLAGS_REG)
9902
        (compare
9903
          (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9904
                     (match_operand:QI 2 "const_1_to_63_operand" "J"))
9905
          (const_int 0)))
9906
   (clobber (match_scratch:DI 0 "=r"))]
9907
  "TARGET_64BIT
9908
   && (optimize_function_for_size_p (cfun)
9909
       || !TARGET_PARTIAL_FLAG_REG_STALL
9910
       || (operands[2] == const1_rtx
9911
           && (TARGET_SHIFT1
9912
               || TARGET_DOUBLE_WITH_ADD)))
9913
   && ix86_match_ccmode (insn, CCGOCmode)
9914
   && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9915
{
9916
  switch (get_attr_type (insn))
9917
    {
9918
    case TYPE_ALU:
9919
      gcc_assert (operands[2] == const1_rtx);
9920
      return "add{q}\t%0, %0";
9921
 
9922
    default:
9923
      if (REG_P (operands[2]))
9924
        return "sal{q}\t{%b2, %0|%0, %b2}";
9925
      else if (operands[2] == const1_rtx
9926
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9927
        return "sal{q}\t%0";
9928
      else
9929
        return "sal{q}\t{%2, %0|%0, %2}";
9930
    }
9931
}
9932
  [(set (attr "type")
9933
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9934
                          (const_int 0))
9935
                      (match_operand 0 "register_operand" ""))
9936
                 (match_operand 2 "const1_operand" ""))
9937
              (const_string "alu")
9938
           ]
9939
           (const_string "ishift")))
9940
   (set (attr "length_immediate")
9941
     (if_then_else
9942
       (ior (eq_attr "type" "alu")
9943
            (and (eq_attr "type" "ishift")
9944
                 (and (match_operand 2 "const1_operand" "")
9945
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9946
                          (const_int 0)))))
9947
       (const_string "0")
9948
       (const_string "*")))
9949
   (set_attr "mode" "DI")])
9950
 
9951
(define_insn "*ashldi3_1"
9952
  [(set (match_operand:DI 0 "register_operand" "=&r,r")
9953
        (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
9954
                   (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
9955
   (clobber (reg:CC FLAGS_REG))]
9956
  "!TARGET_64BIT"
9957
  "#"
9958
  [(set_attr "type" "multi")])
9959
 
9960
;; By default we don't ask for a scratch register, because when DImode
9961
;; values are manipulated, registers are already at a premium.  But if
9962
;; we have one handy, we won't turn it away.
9963
(define_peephole2
9964
  [(match_scratch:SI 3 "r")
9965
   (parallel [(set (match_operand:DI 0 "register_operand" "")
9966
                   (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9967
                              (match_operand:QI 2 "nonmemory_operand" "")))
9968
              (clobber (reg:CC FLAGS_REG))])
9969
   (match_dup 3)]
9970
  "!TARGET_64BIT && TARGET_CMOVE"
9971
  [(const_int 0)]
9972
  "ix86_split_ashl (operands, operands[3], DImode); DONE;")
9973
 
9974
(define_split
9975
  [(set (match_operand:DI 0 "register_operand" "")
9976
        (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9977
                   (match_operand:QI 2 "nonmemory_operand" "")))
9978
   (clobber (reg:CC FLAGS_REG))]
9979
  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9980
                     ? epilogue_completed : reload_completed)"
9981
  [(const_int 0)]
9982
  "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
9983
 
9984
(define_insn "x86_shld"
9985
  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9986
        (ior:SI (ashift:SI (match_dup 0)
9987
                  (match_operand:QI 2 "nonmemory_operand" "Ic"))
9988
                (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9989
                  (minus:QI (const_int 32) (match_dup 2)))))
9990
   (clobber (reg:CC FLAGS_REG))]
9991
  ""
9992
  "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9993
  [(set_attr "type" "ishift")
9994
   (set_attr "prefix_0f" "1")
9995
   (set_attr "mode" "SI")
9996
   (set_attr "pent_pair" "np")
9997
   (set_attr "athlon_decode" "vector")
9998
   (set_attr "amdfam10_decode" "vector")])
9999
 
10000
(define_expand "x86_shift_adj_1"
10001
  [(set (reg:CCZ FLAGS_REG)
10002
        (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10003
                             (const_int 32))
10004
                     (const_int 0)))
10005
   (set (match_operand:SI 0 "register_operand" "")
10006
        (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10007
                         (match_operand:SI 1 "register_operand" "")
10008
                         (match_dup 0)))
10009
   (set (match_dup 1)
10010
        (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10011
                         (match_operand:SI 3 "register_operand" "r")
10012
                         (match_dup 1)))]
10013
  "TARGET_CMOVE"
10014
  "")
10015
 
10016
(define_expand "x86_shift_adj_2"
10017
  [(use (match_operand:SI 0 "register_operand" ""))
10018
   (use (match_operand:SI 1 "register_operand" ""))
10019
   (use (match_operand:QI 2 "register_operand" ""))]
10020
  ""
10021
{
10022
  rtx label = gen_label_rtx ();
10023
  rtx tmp;
10024
 
10025
  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10026
 
10027
  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10028
  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10029
  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10030
                              gen_rtx_LABEL_REF (VOIDmode, label),
10031
                              pc_rtx);
10032
  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10033
  JUMP_LABEL (tmp) = label;
10034
 
10035
  emit_move_insn (operands[0], operands[1]);
10036
  ix86_expand_clear (operands[1]);
10037
 
10038
  emit_label (label);
10039
  LABEL_NUSES (label) = 1;
10040
 
10041
  DONE;
10042
})
10043
 
10044
(define_expand "ashlsi3"
10045
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10046
        (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10047
                   (match_operand:QI 2 "nonmemory_operand" "")))]
10048
  ""
10049
  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10050
 
10051
(define_insn "*ashlsi3_1"
10052
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10053
        (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10054
                   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10055
   (clobber (reg:CC FLAGS_REG))]
10056
  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10057
{
10058
  switch (get_attr_type (insn))
10059
    {
10060
    case TYPE_ALU:
10061
      gcc_assert (operands[2] == const1_rtx);
10062
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10063
      return "add{l}\t%0, %0";
10064
 
10065
    case TYPE_LEA:
10066
      return "#";
10067
 
10068
    default:
10069
      if (REG_P (operands[2]))
10070
        return "sal{l}\t{%b2, %0|%0, %b2}";
10071
      else if (operands[2] == const1_rtx
10072
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10073
        return "sal{l}\t%0";
10074
      else
10075
        return "sal{l}\t{%2, %0|%0, %2}";
10076
    }
10077
}
10078
  [(set (attr "type")
10079
     (cond [(eq_attr "alternative" "1")
10080
              (const_string "lea")
10081
            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10082
                          (const_int 0))
10083
                      (match_operand 0 "register_operand" ""))
10084
                 (match_operand 2 "const1_operand" ""))
10085
              (const_string "alu")
10086
           ]
10087
           (const_string "ishift")))
10088
   (set (attr "length_immediate")
10089
     (if_then_else
10090
       (ior (eq_attr "type" "alu")
10091
            (and (eq_attr "type" "ishift")
10092
                 (and (match_operand 2 "const1_operand" "")
10093
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10094
                          (const_int 0)))))
10095
       (const_string "0")
10096
       (const_string "*")))
10097
   (set_attr "mode" "SI")])
10098
 
10099
;; Convert lea to the lea pattern to avoid flags dependency.
10100
(define_split
10101
  [(set (match_operand 0 "register_operand" "")
10102
        (ashift (match_operand 1 "index_register_operand" "")
10103
                (match_operand:QI 2 "const_int_operand" "")))
10104
   (clobber (reg:CC FLAGS_REG))]
10105
  "reload_completed
10106
   && true_regnum (operands[0]) != true_regnum (operands[1])
10107
   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10108
  [(const_int 0)]
10109
{
10110
  rtx pat;
10111
  enum machine_mode mode = GET_MODE (operands[0]);
10112
 
10113
  if (GET_MODE_SIZE (mode) < 4)
10114
    operands[0] = gen_lowpart (SImode, operands[0]);
10115
  if (mode != Pmode)
10116
    operands[1] = gen_lowpart (Pmode, operands[1]);
10117
  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10118
 
10119
  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10120
  if (Pmode != SImode)
10121
    pat = gen_rtx_SUBREG (SImode, pat, 0);
10122
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10123
  DONE;
10124
})
10125
 
10126
;; Rare case of shifting RSP is handled by generating move and shift
10127
(define_split
10128
  [(set (match_operand 0 "register_operand" "")
10129
        (ashift (match_operand 1 "register_operand" "")
10130
                (match_operand:QI 2 "const_int_operand" "")))
10131
   (clobber (reg:CC FLAGS_REG))]
10132
  "reload_completed
10133
   && true_regnum (operands[0]) != true_regnum (operands[1])"
10134
  [(const_int 0)]
10135
{
10136
  rtx pat, clob;
10137
  emit_move_insn (operands[0], operands[1]);
10138
  pat = gen_rtx_SET (VOIDmode, operands[0],
10139
                     gen_rtx_ASHIFT (GET_MODE (operands[0]),
10140
                                     operands[0], operands[2]));
10141
  clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10142
  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10143
  DONE;
10144
})
10145
 
10146
(define_insn "*ashlsi3_1_zext"
10147
  [(set (match_operand:DI 0 "register_operand" "=r,r")
10148
        (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10149
                        (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10150
   (clobber (reg:CC FLAGS_REG))]
10151
  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10152
{
10153
  switch (get_attr_type (insn))
10154
    {
10155
    case TYPE_ALU:
10156
      gcc_assert (operands[2] == const1_rtx);
10157
      return "add{l}\t%k0, %k0";
10158
 
10159
    case TYPE_LEA:
10160
      return "#";
10161
 
10162
    default:
10163
      if (REG_P (operands[2]))
10164
        return "sal{l}\t{%b2, %k0|%k0, %b2}";
10165
      else if (operands[2] == const1_rtx
10166
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10167
        return "sal{l}\t%k0";
10168
      else
10169
        return "sal{l}\t{%2, %k0|%k0, %2}";
10170
    }
10171
}
10172
  [(set (attr "type")
10173
     (cond [(eq_attr "alternative" "1")
10174
              (const_string "lea")
10175
            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10176
                     (const_int 0))
10177
                 (match_operand 2 "const1_operand" ""))
10178
              (const_string "alu")
10179
           ]
10180
           (const_string "ishift")))
10181
   (set (attr "length_immediate")
10182
     (if_then_else
10183
       (ior (eq_attr "type" "alu")
10184
            (and (eq_attr "type" "ishift")
10185
                 (and (match_operand 2 "const1_operand" "")
10186
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10187
                          (const_int 0)))))
10188
       (const_string "0")
10189
       (const_string "*")))
10190
   (set_attr "mode" "SI")])
10191
 
10192
;; Convert lea to the lea pattern to avoid flags dependency.
10193
(define_split
10194
  [(set (match_operand:DI 0 "register_operand" "")
10195
        (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10196
                                (match_operand:QI 2 "const_int_operand" ""))))
10197
   (clobber (reg:CC FLAGS_REG))]
10198
  "TARGET_64BIT && reload_completed
10199
   && true_regnum (operands[0]) != true_regnum (operands[1])"
10200
  [(set (match_dup 0) (zero_extend:DI
10201
                        (subreg:SI (mult:DI (match_dup 1)
10202
                                            (match_dup 2)) 0)))]
10203
{
10204
  operands[1] = gen_lowpart (Pmode, operands[1]);
10205
  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10206
})
10207
 
10208
;; This pattern can't accept a variable shift count, since shifts by
10209
;; zero don't affect the flags.  We assume that shifts by constant
10210
;; zero are optimized away.
10211
(define_insn "*ashlsi3_cmp"
10212
  [(set (reg FLAGS_REG)
10213
        (compare
10214
          (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10215
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10216
          (const_int 0)))
10217
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10218
        (ashift:SI (match_dup 1) (match_dup 2)))]
10219
   "(optimize_function_for_size_p (cfun)
10220
     || !TARGET_PARTIAL_FLAG_REG_STALL
10221
     || (operands[2] == const1_rtx
10222
         && (TARGET_SHIFT1
10223
             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10224
   && ix86_match_ccmode (insn, CCGOCmode)
10225
   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10226
{
10227
  switch (get_attr_type (insn))
10228
    {
10229
    case TYPE_ALU:
10230
      gcc_assert (operands[2] == const1_rtx);
10231
      return "add{l}\t%0, %0";
10232
 
10233
    default:
10234
      if (REG_P (operands[2]))
10235
        return "sal{l}\t{%b2, %0|%0, %b2}";
10236
      else if (operands[2] == const1_rtx
10237
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10238
        return "sal{l}\t%0";
10239
      else
10240
        return "sal{l}\t{%2, %0|%0, %2}";
10241
    }
10242
}
10243
  [(set (attr "type")
10244
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10245
                          (const_int 0))
10246
                      (match_operand 0 "register_operand" ""))
10247
                 (match_operand 2 "const1_operand" ""))
10248
              (const_string "alu")
10249
           ]
10250
           (const_string "ishift")))
10251
   (set (attr "length_immediate")
10252
     (if_then_else
10253
       (ior (eq_attr "type" "alu")
10254
            (and (eq_attr "type" "ishift")
10255
                 (and (match_operand 2 "const1_operand" "")
10256
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10257
                          (const_int 0)))))
10258
       (const_string "0")
10259
       (const_string "*")))
10260
   (set_attr "mode" "SI")])
10261
 
10262
(define_insn "*ashlsi3_cconly"
10263
  [(set (reg FLAGS_REG)
10264
        (compare
10265
          (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10266
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10267
          (const_int 0)))
10268
   (clobber (match_scratch:SI 0 "=r"))]
10269
  "(optimize_function_for_size_p (cfun)
10270
    || !TARGET_PARTIAL_FLAG_REG_STALL
10271
    || (operands[2] == const1_rtx
10272
        && (TARGET_SHIFT1
10273
            || TARGET_DOUBLE_WITH_ADD)))
10274
   && ix86_match_ccmode (insn, CCGOCmode)
10275
   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10276
{
10277
  switch (get_attr_type (insn))
10278
    {
10279
    case TYPE_ALU:
10280
      gcc_assert (operands[2] == const1_rtx);
10281
      return "add{l}\t%0, %0";
10282
 
10283
    default:
10284
      if (REG_P (operands[2]))
10285
        return "sal{l}\t{%b2, %0|%0, %b2}";
10286
      else if (operands[2] == const1_rtx
10287
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10288
        return "sal{l}\t%0";
10289
      else
10290
        return "sal{l}\t{%2, %0|%0, %2}";
10291
    }
10292
}
10293
  [(set (attr "type")
10294
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10295
                          (const_int 0))
10296
                      (match_operand 0 "register_operand" ""))
10297
                 (match_operand 2 "const1_operand" ""))
10298
              (const_string "alu")
10299
           ]
10300
           (const_string "ishift")))
10301
   (set (attr "length_immediate")
10302
     (if_then_else
10303
       (ior (eq_attr "type" "alu")
10304
            (and (eq_attr "type" "ishift")
10305
                 (and (match_operand 2 "const1_operand" "")
10306
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10307
                          (const_int 0)))))
10308
       (const_string "0")
10309
       (const_string "*")))
10310
   (set_attr "mode" "SI")])
10311
 
10312
(define_insn "*ashlsi3_cmp_zext"
10313
  [(set (reg FLAGS_REG)
10314
        (compare
10315
          (ashift:SI (match_operand:SI 1 "register_operand" "0")
10316
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10317
          (const_int 0)))
10318
   (set (match_operand:DI 0 "register_operand" "=r")
10319
        (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10320
  "TARGET_64BIT
10321
   && (optimize_function_for_size_p (cfun)
10322
       || !TARGET_PARTIAL_FLAG_REG_STALL
10323
       || (operands[2] == const1_rtx
10324
           && (TARGET_SHIFT1
10325
               || TARGET_DOUBLE_WITH_ADD)))
10326
   && ix86_match_ccmode (insn, CCGOCmode)
10327
   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10328
{
10329
  switch (get_attr_type (insn))
10330
    {
10331
    case TYPE_ALU:
10332
      gcc_assert (operands[2] == const1_rtx);
10333
      return "add{l}\t%k0, %k0";
10334
 
10335
    default:
10336
      if (REG_P (operands[2]))
10337
        return "sal{l}\t{%b2, %k0|%k0, %b2}";
10338
      else if (operands[2] == const1_rtx
10339
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10340
        return "sal{l}\t%k0";
10341
      else
10342
        return "sal{l}\t{%2, %k0|%k0, %2}";
10343
    }
10344
}
10345
  [(set (attr "type")
10346
     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10347
                     (const_int 0))
10348
                 (match_operand 2 "const1_operand" ""))
10349
              (const_string "alu")
10350
           ]
10351
           (const_string "ishift")))
10352
   (set (attr "length_immediate")
10353
     (if_then_else
10354
       (ior (eq_attr "type" "alu")
10355
            (and (eq_attr "type" "ishift")
10356
                 (and (match_operand 2 "const1_operand" "")
10357
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10358
                          (const_int 0)))))
10359
       (const_string "0")
10360
       (const_string "*")))
10361
   (set_attr "mode" "SI")])
10362
 
10363
(define_expand "ashlhi3"
10364
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10365
        (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10366
                   (match_operand:QI 2 "nonmemory_operand" "")))]
10367
  "TARGET_HIMODE_MATH"
10368
  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10369
 
10370
(define_insn "*ashlhi3_1_lea"
10371
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10372
        (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10373
                   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10374
   (clobber (reg:CC FLAGS_REG))]
10375
  "!TARGET_PARTIAL_REG_STALL
10376
   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10377
{
10378
  switch (get_attr_type (insn))
10379
    {
10380
    case TYPE_LEA:
10381
      return "#";
10382
    case TYPE_ALU:
10383
      gcc_assert (operands[2] == const1_rtx);
10384
      return "add{w}\t%0, %0";
10385
 
10386
    default:
10387
      if (REG_P (operands[2]))
10388
        return "sal{w}\t{%b2, %0|%0, %b2}";
10389
      else if (operands[2] == const1_rtx
10390
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10391
        return "sal{w}\t%0";
10392
      else
10393
        return "sal{w}\t{%2, %0|%0, %2}";
10394
    }
10395
}
10396
  [(set (attr "type")
10397
     (cond [(eq_attr "alternative" "1")
10398
              (const_string "lea")
10399
            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10400
                          (const_int 0))
10401
                      (match_operand 0 "register_operand" ""))
10402
                 (match_operand 2 "const1_operand" ""))
10403
              (const_string "alu")
10404
           ]
10405
           (const_string "ishift")))
10406
   (set (attr "length_immediate")
10407
     (if_then_else
10408
       (ior (eq_attr "type" "alu")
10409
            (and (eq_attr "type" "ishift")
10410
                 (and (match_operand 2 "const1_operand" "")
10411
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10412
                          (const_int 0)))))
10413
       (const_string "0")
10414
       (const_string "*")))
10415
   (set_attr "mode" "HI,SI")])
10416
 
10417
(define_insn "*ashlhi3_1"
10418
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10419
        (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10420
                   (match_operand:QI 2 "nonmemory_operand" "cI")))
10421
   (clobber (reg:CC FLAGS_REG))]
10422
  "TARGET_PARTIAL_REG_STALL
10423
   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10424
{
10425
  switch (get_attr_type (insn))
10426
    {
10427
    case TYPE_ALU:
10428
      gcc_assert (operands[2] == const1_rtx);
10429
      return "add{w}\t%0, %0";
10430
 
10431
    default:
10432
      if (REG_P (operands[2]))
10433
        return "sal{w}\t{%b2, %0|%0, %b2}";
10434
      else if (operands[2] == const1_rtx
10435
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10436
        return "sal{w}\t%0";
10437
      else
10438
        return "sal{w}\t{%2, %0|%0, %2}";
10439
    }
10440
}
10441
  [(set (attr "type")
10442
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10443
                          (const_int 0))
10444
                      (match_operand 0 "register_operand" ""))
10445
                 (match_operand 2 "const1_operand" ""))
10446
              (const_string "alu")
10447
           ]
10448
           (const_string "ishift")))
10449
   (set (attr "length_immediate")
10450
     (if_then_else
10451
       (ior (eq_attr "type" "alu")
10452
            (and (eq_attr "type" "ishift")
10453
                 (and (match_operand 2 "const1_operand" "")
10454
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10455
                          (const_int 0)))))
10456
       (const_string "0")
10457
       (const_string "*")))
10458
   (set_attr "mode" "HI")])
10459
 
10460
;; This pattern can't accept a variable shift count, since shifts by
10461
;; zero don't affect the flags.  We assume that shifts by constant
10462
;; zero are optimized away.
10463
(define_insn "*ashlhi3_cmp"
10464
  [(set (reg FLAGS_REG)
10465
        (compare
10466
          (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10467
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10468
          (const_int 0)))
10469
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10470
        (ashift:HI (match_dup 1) (match_dup 2)))]
10471
  "(optimize_function_for_size_p (cfun)
10472
    || !TARGET_PARTIAL_FLAG_REG_STALL
10473
    || (operands[2] == const1_rtx
10474
        && (TARGET_SHIFT1
10475
            || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10476
   && ix86_match_ccmode (insn, CCGOCmode)
10477
   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10478
{
10479
  switch (get_attr_type (insn))
10480
    {
10481
    case TYPE_ALU:
10482
      gcc_assert (operands[2] == const1_rtx);
10483
      return "add{w}\t%0, %0";
10484
 
10485
    default:
10486
      if (REG_P (operands[2]))
10487
        return "sal{w}\t{%b2, %0|%0, %b2}";
10488
      else if (operands[2] == const1_rtx
10489
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10490
        return "sal{w}\t%0";
10491
      else
10492
        return "sal{w}\t{%2, %0|%0, %2}";
10493
    }
10494
}
10495
  [(set (attr "type")
10496
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10497
                          (const_int 0))
10498
                      (match_operand 0 "register_operand" ""))
10499
                 (match_operand 2 "const1_operand" ""))
10500
              (const_string "alu")
10501
           ]
10502
           (const_string "ishift")))
10503
   (set (attr "length_immediate")
10504
     (if_then_else
10505
       (ior (eq_attr "type" "alu")
10506
            (and (eq_attr "type" "ishift")
10507
                 (and (match_operand 2 "const1_operand" "")
10508
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10509
                          (const_int 0)))))
10510
       (const_string "0")
10511
       (const_string "*")))
10512
   (set_attr "mode" "HI")])
10513
 
10514
(define_insn "*ashlhi3_cconly"
10515
  [(set (reg FLAGS_REG)
10516
        (compare
10517
          (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10518
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10519
          (const_int 0)))
10520
   (clobber (match_scratch:HI 0 "=r"))]
10521
  "(optimize_function_for_size_p (cfun)
10522
    || !TARGET_PARTIAL_FLAG_REG_STALL
10523
    || (operands[2] == const1_rtx
10524
        && (TARGET_SHIFT1
10525
            || TARGET_DOUBLE_WITH_ADD)))
10526
   && ix86_match_ccmode (insn, CCGOCmode)
10527
   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10528
{
10529
  switch (get_attr_type (insn))
10530
    {
10531
    case TYPE_ALU:
10532
      gcc_assert (operands[2] == const1_rtx);
10533
      return "add{w}\t%0, %0";
10534
 
10535
    default:
10536
      if (REG_P (operands[2]))
10537
        return "sal{w}\t{%b2, %0|%0, %b2}";
10538
      else if (operands[2] == const1_rtx
10539
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10540
        return "sal{w}\t%0";
10541
      else
10542
        return "sal{w}\t{%2, %0|%0, %2}";
10543
    }
10544
}
10545
  [(set (attr "type")
10546
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10547
                          (const_int 0))
10548
                      (match_operand 0 "register_operand" ""))
10549
                 (match_operand 2 "const1_operand" ""))
10550
              (const_string "alu")
10551
           ]
10552
           (const_string "ishift")))
10553
   (set (attr "length_immediate")
10554
     (if_then_else
10555
       (ior (eq_attr "type" "alu")
10556
            (and (eq_attr "type" "ishift")
10557
                 (and (match_operand 2 "const1_operand" "")
10558
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10559
                          (const_int 0)))))
10560
       (const_string "0")
10561
       (const_string "*")))
10562
   (set_attr "mode" "HI")])
10563
 
10564
(define_expand "ashlqi3"
10565
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10566
        (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10567
                   (match_operand:QI 2 "nonmemory_operand" "")))]
10568
  "TARGET_QIMODE_MATH"
10569
  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10570
 
10571
;; %%% Potential partial reg stall on alternative 2.  What to do?
10572
 
10573
(define_insn "*ashlqi3_1_lea"
10574
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10575
        (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10576
                   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10577
   (clobber (reg:CC FLAGS_REG))]
10578
  "!TARGET_PARTIAL_REG_STALL
10579
   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10580
{
10581
  switch (get_attr_type (insn))
10582
    {
10583
    case TYPE_LEA:
10584
      return "#";
10585
    case TYPE_ALU:
10586
      gcc_assert (operands[2] == const1_rtx);
10587
      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10588
        return "add{l}\t%k0, %k0";
10589
      else
10590
        return "add{b}\t%0, %0";
10591
 
10592
    default:
10593
      if (REG_P (operands[2]))
10594
        {
10595
          if (get_attr_mode (insn) == MODE_SI)
10596
            return "sal{l}\t{%b2, %k0|%k0, %b2}";
10597
          else
10598
            return "sal{b}\t{%b2, %0|%0, %b2}";
10599
        }
10600
      else if (operands[2] == const1_rtx
10601
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10602
        {
10603
          if (get_attr_mode (insn) == MODE_SI)
10604
            return "sal{l}\t%0";
10605
          else
10606
            return "sal{b}\t%0";
10607
        }
10608
      else
10609
        {
10610
          if (get_attr_mode (insn) == MODE_SI)
10611
            return "sal{l}\t{%2, %k0|%k0, %2}";
10612
          else
10613
            return "sal{b}\t{%2, %0|%0, %2}";
10614
        }
10615
    }
10616
}
10617
  [(set (attr "type")
10618
     (cond [(eq_attr "alternative" "2")
10619
              (const_string "lea")
10620
            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10621
                          (const_int 0))
10622
                      (match_operand 0 "register_operand" ""))
10623
                 (match_operand 2 "const1_operand" ""))
10624
              (const_string "alu")
10625
           ]
10626
           (const_string "ishift")))
10627
   (set (attr "length_immediate")
10628
     (if_then_else
10629
       (ior (eq_attr "type" "alu")
10630
            (and (eq_attr "type" "ishift")
10631
                 (and (match_operand 2 "const1_operand" "")
10632
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10633
                          (const_int 0)))))
10634
       (const_string "0")
10635
       (const_string "*")))
10636
   (set_attr "mode" "QI,SI,SI")])
10637
 
10638
(define_insn "*ashlqi3_1"
10639
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10640
        (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10641
                   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10642
   (clobber (reg:CC FLAGS_REG))]
10643
  "TARGET_PARTIAL_REG_STALL
10644
   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10645
{
10646
  switch (get_attr_type (insn))
10647
    {
10648
    case TYPE_ALU:
10649
      gcc_assert (operands[2] == const1_rtx);
10650
      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10651
        return "add{l}\t%k0, %k0";
10652
      else
10653
        return "add{b}\t%0, %0";
10654
 
10655
    default:
10656
      if (REG_P (operands[2]))
10657
        {
10658
          if (get_attr_mode (insn) == MODE_SI)
10659
            return "sal{l}\t{%b2, %k0|%k0, %b2}";
10660
          else
10661
            return "sal{b}\t{%b2, %0|%0, %b2}";
10662
        }
10663
      else if (operands[2] == const1_rtx
10664
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10665
        {
10666
          if (get_attr_mode (insn) == MODE_SI)
10667
            return "sal{l}\t%0";
10668
          else
10669
            return "sal{b}\t%0";
10670
        }
10671
      else
10672
        {
10673
          if (get_attr_mode (insn) == MODE_SI)
10674
            return "sal{l}\t{%2, %k0|%k0, %2}";
10675
          else
10676
            return "sal{b}\t{%2, %0|%0, %2}";
10677
        }
10678
    }
10679
}
10680
  [(set (attr "type")
10681
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10682
                          (const_int 0))
10683
                      (match_operand 0 "register_operand" ""))
10684
                 (match_operand 2 "const1_operand" ""))
10685
              (const_string "alu")
10686
           ]
10687
           (const_string "ishift")))
10688
   (set (attr "length_immediate")
10689
     (if_then_else
10690
       (ior (eq_attr "type" "alu")
10691
            (and (eq_attr "type" "ishift")
10692
                 (and (match_operand 2 "const1_operand" "")
10693
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10694
                          (const_int 0)))))
10695
       (const_string "0")
10696
       (const_string "*")))
10697
   (set_attr "mode" "QI,SI")])
10698
 
10699
;; This pattern can't accept a variable shift count, since shifts by
10700
;; zero don't affect the flags.  We assume that shifts by constant
10701
;; zero are optimized away.
10702
(define_insn "*ashlqi3_cmp"
10703
  [(set (reg FLAGS_REG)
10704
        (compare
10705
          (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10706
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10707
          (const_int 0)))
10708
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10709
        (ashift:QI (match_dup 1) (match_dup 2)))]
10710
  "(optimize_function_for_size_p (cfun)
10711
    || !TARGET_PARTIAL_FLAG_REG_STALL
10712
    || (operands[2] == const1_rtx
10713
        && (TARGET_SHIFT1
10714
            || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10715
   && ix86_match_ccmode (insn, CCGOCmode)
10716
   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10717
{
10718
  switch (get_attr_type (insn))
10719
    {
10720
    case TYPE_ALU:
10721
      gcc_assert (operands[2] == const1_rtx);
10722
      return "add{b}\t%0, %0";
10723
 
10724
    default:
10725
      if (REG_P (operands[2]))
10726
        return "sal{b}\t{%b2, %0|%0, %b2}";
10727
      else if (operands[2] == const1_rtx
10728
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10729
        return "sal{b}\t%0";
10730
      else
10731
        return "sal{b}\t{%2, %0|%0, %2}";
10732
    }
10733
}
10734
  [(set (attr "type")
10735
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10736
                          (const_int 0))
10737
                      (match_operand 0 "register_operand" ""))
10738
                 (match_operand 2 "const1_operand" ""))
10739
              (const_string "alu")
10740
           ]
10741
           (const_string "ishift")))
10742
   (set (attr "length_immediate")
10743
     (if_then_else
10744
       (ior (eq_attr "type" "alu")
10745
            (and (eq_attr "type" "ishift")
10746
                 (and (match_operand 2 "const1_operand" "")
10747
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10748
                          (const_int 0)))))
10749
       (const_string "0")
10750
       (const_string "*")))
10751
   (set_attr "mode" "QI")])
10752
 
10753
(define_insn "*ashlqi3_cconly"
10754
  [(set (reg FLAGS_REG)
10755
        (compare
10756
          (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10757
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10758
          (const_int 0)))
10759
   (clobber (match_scratch:QI 0 "=q"))]
10760
  "(optimize_function_for_size_p (cfun)
10761
    || !TARGET_PARTIAL_FLAG_REG_STALL
10762
    || (operands[2] == const1_rtx
10763
        && (TARGET_SHIFT1
10764
            || TARGET_DOUBLE_WITH_ADD)))
10765
   && ix86_match_ccmode (insn, CCGOCmode)
10766
   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10767
{
10768
  switch (get_attr_type (insn))
10769
    {
10770
    case TYPE_ALU:
10771
      gcc_assert (operands[2] == const1_rtx);
10772
      return "add{b}\t%0, %0";
10773
 
10774
    default:
10775
      if (REG_P (operands[2]))
10776
        return "sal{b}\t{%b2, %0|%0, %b2}";
10777
      else if (operands[2] == const1_rtx
10778
               && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10779
        return "sal{b}\t%0";
10780
      else
10781
        return "sal{b}\t{%2, %0|%0, %2}";
10782
    }
10783
}
10784
  [(set (attr "type")
10785
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10786
                          (const_int 0))
10787
                      (match_operand 0 "register_operand" ""))
10788
                 (match_operand 2 "const1_operand" ""))
10789
              (const_string "alu")
10790
           ]
10791
           (const_string "ishift")))
10792
   (set (attr "length_immediate")
10793
     (if_then_else
10794
       (ior (eq_attr "type" "alu")
10795
            (and (eq_attr "type" "ishift")
10796
                 (and (match_operand 2 "const1_operand" "")
10797
                      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10798
                          (const_int 0)))))
10799
       (const_string "0")
10800
       (const_string "*")))
10801
   (set_attr "mode" "QI")])
10802
 
10803
;; See comment above `ashldi3' about how this works.
10804
 
10805
(define_expand "ashrti3"
10806
  [(set (match_operand:TI 0 "register_operand" "")
10807
        (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10808
                     (match_operand:QI 2 "nonmemory_operand" "")))]
10809
  "TARGET_64BIT"
10810
  "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
10811
 
10812
(define_insn "*ashrti3_1"
10813
  [(set (match_operand:TI 0 "register_operand" "=r")
10814
        (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
10815
                     (match_operand:QI 2 "nonmemory_operand" "Oc")))
10816
   (clobber (reg:CC FLAGS_REG))]
10817
  "TARGET_64BIT"
10818
  "#"
10819
  [(set_attr "type" "multi")])
10820
 
10821
(define_peephole2
10822
  [(match_scratch:DI 3 "r")
10823
   (parallel [(set (match_operand:TI 0 "register_operand" "")
10824
                   (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10825
                                (match_operand:QI 2 "nonmemory_operand" "")))
10826
              (clobber (reg:CC FLAGS_REG))])
10827
   (match_dup 3)]
10828
  "TARGET_64BIT"
10829
  [(const_int 0)]
10830
  "ix86_split_ashr (operands, operands[3], TImode); DONE;")
10831
 
10832
(define_split
10833
  [(set (match_operand:TI 0 "register_operand" "")
10834
        (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10835
                     (match_operand:QI 2 "nonmemory_operand" "")))
10836
   (clobber (reg:CC FLAGS_REG))]
10837
  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10838
                    ? epilogue_completed : reload_completed)"
10839
  [(const_int 0)]
10840
  "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
10841
 
10842
(define_insn "x86_64_shrd"
10843
  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10844
        (ior:DI (ashiftrt:DI (match_dup 0)
10845
                  (match_operand:QI 2 "nonmemory_operand" "Jc"))
10846
                (ashift:DI (match_operand:DI 1 "register_operand" "r")
10847
                  (minus:QI (const_int 64) (match_dup 2)))))
10848
   (clobber (reg:CC FLAGS_REG))]
10849
  "TARGET_64BIT"
10850
  "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10851
  [(set_attr "type" "ishift")
10852
   (set_attr "prefix_0f" "1")
10853
   (set_attr "mode" "DI")
10854
   (set_attr "athlon_decode" "vector")
10855
   (set_attr "amdfam10_decode" "vector")])
10856
 
10857
(define_expand "ashrdi3"
10858
  [(set (match_operand:DI 0 "shiftdi_operand" "")
10859
        (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10860
                     (match_operand:QI 2 "nonmemory_operand" "")))]
10861
  ""
10862
  "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10863
 
10864
(define_expand "x86_64_shift_adj_3"
10865
  [(use (match_operand:DI 0 "register_operand" ""))
10866
   (use (match_operand:DI 1 "register_operand" ""))
10867
   (use (match_operand:QI 2 "register_operand" ""))]
10868
  ""
10869
{
10870
  rtx label = gen_label_rtx ();
10871
  rtx tmp;
10872
 
10873
  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10874
 
10875
  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10876
  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10877
  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10878
                              gen_rtx_LABEL_REF (VOIDmode, label),
10879
                              pc_rtx);
10880
  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10881
  JUMP_LABEL (tmp) = label;
10882
 
10883
  emit_move_insn (operands[0], operands[1]);
10884
  emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
10885
 
10886
  emit_label (label);
10887
  LABEL_NUSES (label) = 1;
10888
 
10889
  DONE;
10890
})
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_function_for_size_p (cfun))
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
10915
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10916
   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10917
  "sar{q}\t%0"
10918
  [(set_attr "type" "ishift")
10919
   (set_attr "length_immediate" "0")
10920
   (set_attr "mode" "DI")])
10921
 
10922
(define_insn "*ashrdi3_1_rex64"
10923
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10924
        (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10925
                     (match_operand:QI 2 "nonmemory_operand" "J,c")))
10926
   (clobber (reg:CC FLAGS_REG))]
10927
  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10928
  "@
10929
   sar{q}\t{%2, %0|%0, %2}
10930
   sar{q}\t{%b2, %0|%0, %b2}"
10931
  [(set_attr "type" "ishift")
10932
   (set_attr "mode" "DI")])
10933
 
10934
;; This pattern can't accept a variable shift count, since shifts by
10935
;; zero don't affect the flags.  We assume that shifts by constant
10936
;; zero are optimized away.
10937
(define_insn "*ashrdi3_one_bit_cmp_rex64"
10938
  [(set (reg FLAGS_REG)
10939
        (compare
10940
          (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10941
                       (match_operand:QI 2 "const1_operand" ""))
10942
          (const_int 0)))
10943
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10944
        (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10945
  "TARGET_64BIT
10946
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10947
   && ix86_match_ccmode (insn, CCGOCmode)
10948
   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10949
  "sar{q}\t%0"
10950
  [(set_attr "type" "ishift")
10951
   (set_attr "length_immediate" "0")
10952
   (set_attr "mode" "DI")])
10953
 
10954
(define_insn "*ashrdi3_one_bit_cconly_rex64"
10955
  [(set (reg FLAGS_REG)
10956
        (compare
10957
          (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10958
                       (match_operand:QI 2 "const1_operand" ""))
10959
          (const_int 0)))
10960
   (clobber (match_scratch:DI 0 "=r"))]
10961
  "TARGET_64BIT
10962
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10963
   && ix86_match_ccmode (insn, CCGOCmode)
10964
   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10965
  "sar{q}\t%0"
10966
  [(set_attr "type" "ishift")
10967
   (set_attr "length_immediate" "0")
10968
   (set_attr "mode" "DI")])
10969
 
10970
;; This pattern can't accept a variable shift count, since shifts by
10971
;; zero don't affect the flags.  We assume that shifts by constant
10972
;; zero are optimized away.
10973
(define_insn "*ashrdi3_cmp_rex64"
10974
  [(set (reg FLAGS_REG)
10975
        (compare
10976
          (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10977
                       (match_operand:QI 2 "const_1_to_63_operand" "J"))
10978
          (const_int 0)))
10979
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10980
        (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10981
  "TARGET_64BIT
10982
   && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10983
   && ix86_match_ccmode (insn, CCGOCmode)
10984
   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10985
  "sar{q}\t{%2, %0|%0, %2}"
10986
  [(set_attr "type" "ishift")
10987
   (set_attr "mode" "DI")])
10988
 
10989
(define_insn "*ashrdi3_cconly_rex64"
10990
  [(set (reg FLAGS_REG)
10991
        (compare
10992
          (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10993
                       (match_operand:QI 2 "const_1_to_63_operand" "J"))
10994
          (const_int 0)))
10995
   (clobber (match_scratch:DI 0 "=r"))]
10996
  "TARGET_64BIT
10997
   && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10998
   && ix86_match_ccmode (insn, CCGOCmode)
10999
   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11000
  "sar{q}\t{%2, %0|%0, %2}"
11001
  [(set_attr "type" "ishift")
11002
   (set_attr "mode" "DI")])
11003
 
11004
(define_insn "*ashrdi3_1"
11005
  [(set (match_operand:DI 0 "register_operand" "=r")
11006
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11007
                     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11008
   (clobber (reg:CC FLAGS_REG))]
11009
  "!TARGET_64BIT"
11010
  "#"
11011
  [(set_attr "type" "multi")])
11012
 
11013
;; By default we don't ask for a scratch register, because when DImode
11014
;; values are manipulated, registers are already at a premium.  But if
11015
;; we have one handy, we won't turn it away.
11016
(define_peephole2
11017
  [(match_scratch:SI 3 "r")
11018
   (parallel [(set (match_operand:DI 0 "register_operand" "")
11019
                   (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11020
                                (match_operand:QI 2 "nonmemory_operand" "")))
11021
              (clobber (reg:CC FLAGS_REG))])
11022
   (match_dup 3)]
11023
  "!TARGET_64BIT && TARGET_CMOVE"
11024
  [(const_int 0)]
11025
  "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11026
 
11027
(define_split
11028
  [(set (match_operand:DI 0 "register_operand" "")
11029
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11030
                     (match_operand:QI 2 "nonmemory_operand" "")))
11031
   (clobber (reg:CC FLAGS_REG))]
11032
  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11033
                     ? epilogue_completed : reload_completed)"
11034
  [(const_int 0)]
11035
  "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11036
 
11037
(define_insn "x86_shrd"
11038
  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11039
        (ior:SI (ashiftrt:SI (match_dup 0)
11040
                  (match_operand:QI 2 "nonmemory_operand" "Ic"))
11041
                (ashift:SI (match_operand:SI 1 "register_operand" "r")
11042
                  (minus:QI (const_int 32) (match_dup 2)))))
11043
   (clobber (reg:CC FLAGS_REG))]
11044
  ""
11045
  "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11046
  [(set_attr "type" "ishift")
11047
   (set_attr "prefix_0f" "1")
11048
   (set_attr "pent_pair" "np")
11049
   (set_attr "mode" "SI")])
11050
 
11051
(define_expand "x86_shift_adj_3"
11052
  [(use (match_operand:SI 0 "register_operand" ""))
11053
   (use (match_operand:SI 1 "register_operand" ""))
11054
   (use (match_operand:QI 2 "register_operand" ""))]
11055
  ""
11056
{
11057
  rtx label = gen_label_rtx ();
11058
  rtx tmp;
11059
 
11060
  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11061
 
11062
  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11063
  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11064
  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11065
                              gen_rtx_LABEL_REF (VOIDmode, label),
11066
                              pc_rtx);
11067
  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11068
  JUMP_LABEL (tmp) = label;
11069
 
11070
  emit_move_insn (operands[0], operands[1]);
11071
  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11072
 
11073
  emit_label (label);
11074
  LABEL_NUSES (label) = 1;
11075
 
11076
  DONE;
11077
})
11078
 
11079
(define_expand "ashrsi3_31"
11080
  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11081
                   (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11082
                                (match_operand:SI 2 "const_int_operand" "i,i")))
11083
              (clobber (reg:CC FLAGS_REG))])]
11084
  "")
11085
 
11086
(define_insn "*ashrsi3_31"
11087
  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11088
        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11089
                     (match_operand:SI 2 "const_int_operand" "i,i")))
11090
   (clobber (reg:CC FLAGS_REG))]
11091
  "INTVAL (operands[2]) == 31
11092
   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11093
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11094
  "@
11095
   {cltd|cdq}
11096
   sar{l}\t{%2, %0|%0, %2}"
11097
  [(set_attr "type" "imovx,ishift")
11098
   (set_attr "prefix_0f" "0,*")
11099
   (set_attr "length_immediate" "0,*")
11100
   (set_attr "modrm" "0,1")
11101
   (set_attr "mode" "SI")])
11102
 
11103
(define_insn "*ashrsi3_31_zext"
11104
  [(set (match_operand:DI 0 "register_operand" "=*d,r")
11105
        (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11106
                                     (match_operand:SI 2 "const_int_operand" "i,i"))))
11107
   (clobber (reg:CC FLAGS_REG))]
11108
  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11109
   && INTVAL (operands[2]) == 31
11110
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11111
  "@
11112
   {cltd|cdq}
11113
   sar{l}\t{%2, %k0|%k0, %2}"
11114
  [(set_attr "type" "imovx,ishift")
11115
   (set_attr "prefix_0f" "0,*")
11116
   (set_attr "length_immediate" "0,*")
11117
   (set_attr "modrm" "0,1")
11118
   (set_attr "mode" "SI")])
11119
 
11120
(define_expand "ashrsi3"
11121
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
11122
        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11123
                     (match_operand:QI 2 "nonmemory_operand" "")))]
11124
  ""
11125
  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11126
 
11127
(define_insn "*ashrsi3_1_one_bit"
11128
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11129
        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11130
                     (match_operand:QI 2 "const1_operand" "")))
11131
   (clobber (reg:CC FLAGS_REG))]
11132
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11133
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11134
  "sar{l}\t%0"
11135
  [(set_attr "type" "ishift")
11136
   (set_attr "length_immediate" "0")
11137
   (set_attr "mode" "SI")])
11138
 
11139
(define_insn "*ashrsi3_1_one_bit_zext"
11140
  [(set (match_operand:DI 0 "register_operand" "=r")
11141
        (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11142
                                     (match_operand:QI 2 "const1_operand" ""))))
11143
   (clobber (reg:CC FLAGS_REG))]
11144
  "TARGET_64BIT
11145
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11146
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11147
  "sar{l}\t%k0"
11148
  [(set_attr "type" "ishift")
11149
   (set_attr "length_immediate" "0")
11150
   (set_attr "mode" "SI")])
11151
 
11152
(define_insn "*ashrsi3_1"
11153
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11154
        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11155
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11156
   (clobber (reg:CC FLAGS_REG))]
11157
  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11158
  "@
11159
   sar{l}\t{%2, %0|%0, %2}
11160
   sar{l}\t{%b2, %0|%0, %b2}"
11161
  [(set_attr "type" "ishift")
11162
   (set_attr "mode" "SI")])
11163
 
11164
(define_insn "*ashrsi3_1_zext"
11165
  [(set (match_operand:DI 0 "register_operand" "=r,r")
11166
        (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11167
                                     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11168
   (clobber (reg:CC FLAGS_REG))]
11169
  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11170
  "@
11171
   sar{l}\t{%2, %k0|%k0, %2}
11172
   sar{l}\t{%b2, %k0|%k0, %b2}"
11173
  [(set_attr "type" "ishift")
11174
   (set_attr "mode" "SI")])
11175
 
11176
;; This pattern can't accept a variable shift count, since shifts by
11177
;; zero don't affect the flags.  We assume that shifts by constant
11178
;; zero are optimized away.
11179
(define_insn "*ashrsi3_one_bit_cmp"
11180
  [(set (reg FLAGS_REG)
11181
        (compare
11182
          (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11183
                       (match_operand:QI 2 "const1_operand" ""))
11184
          (const_int 0)))
11185
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11186
        (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11187
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11188
   && ix86_match_ccmode (insn, CCGOCmode)
11189
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11190
  "sar{l}\t%0"
11191
  [(set_attr "type" "ishift")
11192
   (set_attr "length_immediate" "0")
11193
   (set_attr "mode" "SI")])
11194
 
11195
(define_insn "*ashrsi3_one_bit_cconly"
11196
  [(set (reg FLAGS_REG)
11197
        (compare
11198
          (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11199
                       (match_operand:QI 2 "const1_operand" ""))
11200
          (const_int 0)))
11201
   (clobber (match_scratch:SI 0 "=r"))]
11202
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11203
   && ix86_match_ccmode (insn, CCGOCmode)
11204
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11205
  "sar{l}\t%0"
11206
  [(set_attr "type" "ishift")
11207
   (set_attr "length_immediate" "0")
11208
   (set_attr "mode" "SI")])
11209
 
11210
(define_insn "*ashrsi3_one_bit_cmp_zext"
11211
  [(set (reg FLAGS_REG)
11212
        (compare
11213
          (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11214
                       (match_operand:QI 2 "const1_operand" ""))
11215
          (const_int 0)))
11216
   (set (match_operand:DI 0 "register_operand" "=r")
11217
        (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11218
  "TARGET_64BIT
11219
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11220
   && ix86_match_ccmode (insn, CCmode)
11221
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11222
  "sar{l}\t%k0"
11223
  [(set_attr "type" "ishift")
11224
   (set_attr "length_immediate" "0")
11225
   (set_attr "mode" "SI")])
11226
 
11227
;; This pattern can't accept a variable shift count, since shifts by
11228
;; zero don't affect the flags.  We assume that shifts by constant
11229
;; zero are optimized away.
11230
(define_insn "*ashrsi3_cmp"
11231
  [(set (reg FLAGS_REG)
11232
        (compare
11233
          (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11234
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11235
          (const_int 0)))
11236
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11237
        (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11238
  "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11239
   && ix86_match_ccmode (insn, CCGOCmode)
11240
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11241
  "sar{l}\t{%2, %0|%0, %2}"
11242
  [(set_attr "type" "ishift")
11243
   (set_attr "mode" "SI")])
11244
 
11245
(define_insn "*ashrsi3_cconly"
11246
  [(set (reg FLAGS_REG)
11247
        (compare
11248
          (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11249
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11250
          (const_int 0)))
11251
   (clobber (match_scratch:SI 0 "=r"))]
11252
  "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11253
   && ix86_match_ccmode (insn, CCGOCmode)
11254
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11255
  "sar{l}\t{%2, %0|%0, %2}"
11256
  [(set_attr "type" "ishift")
11257
   (set_attr "mode" "SI")])
11258
 
11259
(define_insn "*ashrsi3_cmp_zext"
11260
  [(set (reg FLAGS_REG)
11261
        (compare
11262
          (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11263
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11264
          (const_int 0)))
11265
   (set (match_operand:DI 0 "register_operand" "=r")
11266
        (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11267
  "TARGET_64BIT
11268
   && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11269
   && ix86_match_ccmode (insn, CCGOCmode)
11270
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11271
  "sar{l}\t{%2, %k0|%k0, %2}"
11272
  [(set_attr "type" "ishift")
11273
   (set_attr "mode" "SI")])
11274
 
11275
(define_expand "ashrhi3"
11276
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11277
        (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11278
                     (match_operand:QI 2 "nonmemory_operand" "")))]
11279
  "TARGET_HIMODE_MATH"
11280
  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11281
 
11282
(define_insn "*ashrhi3_1_one_bit"
11283
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11284
        (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11285
                     (match_operand:QI 2 "const1_operand" "")))
11286
   (clobber (reg:CC FLAGS_REG))]
11287
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11288
   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11289
  "sar{w}\t%0"
11290
  [(set_attr "type" "ishift")
11291
   (set_attr "length_immediate" "0")
11292
   (set_attr "mode" "HI")])
11293
 
11294
(define_insn "*ashrhi3_1"
11295
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11296
        (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11297
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11298
   (clobber (reg:CC FLAGS_REG))]
11299
  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11300
  "@
11301
   sar{w}\t{%2, %0|%0, %2}
11302
   sar{w}\t{%b2, %0|%0, %b2}"
11303
  [(set_attr "type" "ishift")
11304
   (set_attr "mode" "HI")])
11305
 
11306
;; This pattern can't accept a variable shift count, since shifts by
11307
;; zero don't affect the flags.  We assume that shifts by constant
11308
;; zero are optimized away.
11309
(define_insn "*ashrhi3_one_bit_cmp"
11310
  [(set (reg FLAGS_REG)
11311
        (compare
11312
          (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11313
                       (match_operand:QI 2 "const1_operand" ""))
11314
          (const_int 0)))
11315
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11316
        (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11317
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11318
   && ix86_match_ccmode (insn, CCGOCmode)
11319
   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11320
  "sar{w}\t%0"
11321
  [(set_attr "type" "ishift")
11322
   (set_attr "length_immediate" "0")
11323
   (set_attr "mode" "HI")])
11324
 
11325
(define_insn "*ashrhi3_one_bit_cconly"
11326
  [(set (reg FLAGS_REG)
11327
        (compare
11328
          (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11329
                       (match_operand:QI 2 "const1_operand" ""))
11330
          (const_int 0)))
11331
   (clobber (match_scratch:HI 0 "=r"))]
11332
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11333
   && ix86_match_ccmode (insn, CCGOCmode)
11334
   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11335
  "sar{w}\t%0"
11336
  [(set_attr "type" "ishift")
11337
   (set_attr "length_immediate" "0")
11338
   (set_attr "mode" "HI")])
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 "*ashrhi3_cmp"
11344
  [(set (reg FLAGS_REG)
11345
        (compare
11346
          (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11347
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11348
          (const_int 0)))
11349
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11350
        (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11351
  "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11352
   && ix86_match_ccmode (insn, CCGOCmode)
11353
   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11354
  "sar{w}\t{%2, %0|%0, %2}"
11355
  [(set_attr "type" "ishift")
11356
   (set_attr "mode" "HI")])
11357
 
11358
(define_insn "*ashrhi3_cconly"
11359
  [(set (reg FLAGS_REG)
11360
        (compare
11361
          (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11362
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11363
          (const_int 0)))
11364
   (clobber (match_scratch:HI 0 "=r"))]
11365
  "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11366
   && ix86_match_ccmode (insn, CCGOCmode)
11367
   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11368
  "sar{w}\t{%2, %0|%0, %2}"
11369
  [(set_attr "type" "ishift")
11370
   (set_attr "mode" "HI")])
11371
 
11372
(define_expand "ashrqi3"
11373
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11374
        (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11375
                     (match_operand:QI 2 "nonmemory_operand" "")))]
11376
  "TARGET_QIMODE_MATH"
11377
  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11378
 
11379
(define_insn "*ashrqi3_1_one_bit"
11380
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11381
        (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11382
                     (match_operand:QI 2 "const1_operand" "")))
11383
   (clobber (reg:CC FLAGS_REG))]
11384
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11385
   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11386
  "sar{b}\t%0"
11387
  [(set_attr "type" "ishift")
11388
   (set_attr "length_immediate" "0")
11389
   (set_attr "mode" "QI")])
11390
 
11391
(define_insn "*ashrqi3_1_one_bit_slp"
11392
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11393
        (ashiftrt:QI (match_dup 0)
11394
                     (match_operand:QI 1 "const1_operand" "")))
11395
   (clobber (reg:CC FLAGS_REG))]
11396
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11397
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11398
   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11399
  "sar{b}\t%0"
11400
  [(set_attr "type" "ishift1")
11401
   (set_attr "length_immediate" "0")
11402
   (set_attr "mode" "QI")])
11403
 
11404
(define_insn "*ashrqi3_1"
11405
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11406
        (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11407
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11408
   (clobber (reg:CC FLAGS_REG))]
11409
  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11410
  "@
11411
   sar{b}\t{%2, %0|%0, %2}
11412
   sar{b}\t{%b2, %0|%0, %b2}"
11413
  [(set_attr "type" "ishift")
11414
   (set_attr "mode" "QI")])
11415
 
11416
(define_insn "*ashrqi3_1_slp"
11417
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11418
        (ashiftrt:QI (match_dup 0)
11419
                     (match_operand:QI 1 "nonmemory_operand" "I,c")))
11420
   (clobber (reg:CC FLAGS_REG))]
11421
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11422
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11423
  "@
11424
   sar{b}\t{%1, %0|%0, %1}
11425
   sar{b}\t{%b1, %0|%0, %b1}"
11426
  [(set_attr "type" "ishift1")
11427
   (set_attr "mode" "QI")])
11428
 
11429
;; This pattern can't accept a variable shift count, since shifts by
11430
;; zero don't affect the flags.  We assume that shifts by constant
11431
;; zero are optimized away.
11432
(define_insn "*ashrqi3_one_bit_cmp"
11433
  [(set (reg FLAGS_REG)
11434
        (compare
11435
          (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11436
                       (match_operand:QI 2 "const1_operand" "I"))
11437
          (const_int 0)))
11438
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11439
        (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11440
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11441
   && ix86_match_ccmode (insn, CCGOCmode)
11442
   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11443
  "sar{b}\t%0"
11444
  [(set_attr "type" "ishift")
11445
   (set_attr "length_immediate" "0")
11446
   (set_attr "mode" "QI")])
11447
 
11448
(define_insn "*ashrqi3_one_bit_cconly"
11449
  [(set (reg FLAGS_REG)
11450
        (compare
11451
          (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11452
                       (match_operand:QI 2 "const1_operand" ""))
11453
          (const_int 0)))
11454
   (clobber (match_scratch:QI 0 "=q"))]
11455
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11456
   && ix86_match_ccmode (insn, CCGOCmode)
11457
   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11458
  "sar{b}\t%0"
11459
  [(set_attr "type" "ishift")
11460
   (set_attr "length_immediate" "0")
11461
   (set_attr "mode" "QI")])
11462
 
11463
;; This pattern can't accept a variable shift count, since shifts by
11464
;; zero don't affect the flags.  We assume that shifts by constant
11465
;; zero are optimized away.
11466
(define_insn "*ashrqi3_cmp"
11467
  [(set (reg FLAGS_REG)
11468
        (compare
11469
          (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11470
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11471
          (const_int 0)))
11472
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11473
        (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11474
  "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11475
   && ix86_match_ccmode (insn, CCGOCmode)
11476
   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11477
  "sar{b}\t{%2, %0|%0, %2}"
11478
  [(set_attr "type" "ishift")
11479
   (set_attr "mode" "QI")])
11480
 
11481
(define_insn "*ashrqi3_cconly"
11482
  [(set (reg FLAGS_REG)
11483
        (compare
11484
          (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11485
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11486
          (const_int 0)))
11487
   (clobber (match_scratch:QI 0 "=q"))]
11488
  "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11489
   && ix86_match_ccmode (insn, CCGOCmode)
11490
   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11491
  "sar{b}\t{%2, %0|%0, %2}"
11492
  [(set_attr "type" "ishift")
11493
   (set_attr "mode" "QI")])
11494
 
11495
 
11496
;; Logical shift instructions
11497
 
11498
;; See comment above `ashldi3' about how this works.
11499
 
11500
(define_expand "lshrti3"
11501
  [(set (match_operand:TI 0 "register_operand" "")
11502
        (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11503
                     (match_operand:QI 2 "nonmemory_operand" "")))]
11504
  "TARGET_64BIT"
11505
  "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
11506
 
11507
(define_insn "*lshrti3_1"
11508
  [(set (match_operand:TI 0 "register_operand" "=r")
11509
        (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11510
                     (match_operand:QI 2 "nonmemory_operand" "Oc")))
11511
   (clobber (reg:CC FLAGS_REG))]
11512
  "TARGET_64BIT"
11513
  "#"
11514
  [(set_attr "type" "multi")])
11515
 
11516
(define_peephole2
11517
  [(match_scratch:DI 3 "r")
11518
   (parallel [(set (match_operand:TI 0 "register_operand" "")
11519
                   (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11520
                                (match_operand:QI 2 "nonmemory_operand" "")))
11521
              (clobber (reg:CC FLAGS_REG))])
11522
   (match_dup 3)]
11523
  "TARGET_64BIT"
11524
  [(const_int 0)]
11525
  "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11526
 
11527
(define_split
11528
  [(set (match_operand:TI 0 "register_operand" "")
11529
        (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11530
                     (match_operand:QI 2 "nonmemory_operand" "")))
11531
   (clobber (reg:CC FLAGS_REG))]
11532
  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11533
                    ? epilogue_completed : reload_completed)"
11534
  [(const_int 0)]
11535
  "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11536
 
11537
(define_expand "lshrdi3"
11538
  [(set (match_operand:DI 0 "shiftdi_operand" "")
11539
        (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11540
                     (match_operand:QI 2 "nonmemory_operand" "")))]
11541
  ""
11542
  "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11543
 
11544
(define_insn "*lshrdi3_1_one_bit_rex64"
11545
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11546
        (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11547
                     (match_operand:QI 2 "const1_operand" "")))
11548
   (clobber (reg:CC FLAGS_REG))]
11549
  "TARGET_64BIT
11550
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11551
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11552
  "shr{q}\t%0"
11553
  [(set_attr "type" "ishift")
11554
   (set_attr "length_immediate" "0")
11555
   (set_attr "mode" "DI")])
11556
 
11557
(define_insn "*lshrdi3_1_rex64"
11558
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11559
        (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11560
                     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11561
   (clobber (reg:CC FLAGS_REG))]
11562
  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11563
  "@
11564
   shr{q}\t{%2, %0|%0, %2}
11565
   shr{q}\t{%b2, %0|%0, %b2}"
11566
  [(set_attr "type" "ishift")
11567
   (set_attr "mode" "DI")])
11568
 
11569
;; This pattern can't accept a variable shift count, since shifts by
11570
;; zero don't affect the flags.  We assume that shifts by constant
11571
;; zero are optimized away.
11572
(define_insn "*lshrdi3_cmp_one_bit_rex64"
11573
  [(set (reg FLAGS_REG)
11574
        (compare
11575
          (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11576
                       (match_operand:QI 2 "const1_operand" ""))
11577
          (const_int 0)))
11578
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11579
        (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11580
  "TARGET_64BIT
11581
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11582
   && ix86_match_ccmode (insn, CCGOCmode)
11583
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11584
  "shr{q}\t%0"
11585
  [(set_attr "type" "ishift")
11586
   (set_attr "length_immediate" "0")
11587
   (set_attr "mode" "DI")])
11588
 
11589
(define_insn "*lshrdi3_cconly_one_bit_rex64"
11590
  [(set (reg FLAGS_REG)
11591
        (compare
11592
          (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11593
                       (match_operand:QI 2 "const1_operand" ""))
11594
          (const_int 0)))
11595
   (clobber (match_scratch:DI 0 "=r"))]
11596
  "TARGET_64BIT
11597
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11598
   && ix86_match_ccmode (insn, CCGOCmode)
11599
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11600
  "shr{q}\t%0"
11601
  [(set_attr "type" "ishift")
11602
   (set_attr "length_immediate" "0")
11603
   (set_attr "mode" "DI")])
11604
 
11605
;; This pattern can't accept a variable shift count, since shifts by
11606
;; zero don't affect the flags.  We assume that shifts by constant
11607
;; zero are optimized away.
11608
(define_insn "*lshrdi3_cmp_rex64"
11609
  [(set (reg FLAGS_REG)
11610
        (compare
11611
          (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11612
                       (match_operand:QI 2 "const_1_to_63_operand" "J"))
11613
          (const_int 0)))
11614
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11615
        (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11616
  "TARGET_64BIT
11617
   && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11618
   && ix86_match_ccmode (insn, CCGOCmode)
11619
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11620
  "shr{q}\t{%2, %0|%0, %2}"
11621
  [(set_attr "type" "ishift")
11622
   (set_attr "mode" "DI")])
11623
 
11624
(define_insn "*lshrdi3_cconly_rex64"
11625
  [(set (reg FLAGS_REG)
11626
        (compare
11627
          (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11628
                       (match_operand:QI 2 "const_1_to_63_operand" "J"))
11629
          (const_int 0)))
11630
   (clobber (match_scratch:DI 0 "=r"))]
11631
  "TARGET_64BIT
11632
   && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11633
   && ix86_match_ccmode (insn, CCGOCmode)
11634
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11635
  "shr{q}\t{%2, %0|%0, %2}"
11636
  [(set_attr "type" "ishift")
11637
   (set_attr "mode" "DI")])
11638
 
11639
(define_insn "*lshrdi3_1"
11640
  [(set (match_operand:DI 0 "register_operand" "=r")
11641
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11642
                     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11643
   (clobber (reg:CC FLAGS_REG))]
11644
  "!TARGET_64BIT"
11645
  "#"
11646
  [(set_attr "type" "multi")])
11647
 
11648
;; By default we don't ask for a scratch register, because when DImode
11649
;; values are manipulated, registers are already at a premium.  But if
11650
;; we have one handy, we won't turn it away.
11651
(define_peephole2
11652
  [(match_scratch:SI 3 "r")
11653
   (parallel [(set (match_operand:DI 0 "register_operand" "")
11654
                   (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11655
                                (match_operand:QI 2 "nonmemory_operand" "")))
11656
              (clobber (reg:CC FLAGS_REG))])
11657
   (match_dup 3)]
11658
  "!TARGET_64BIT && TARGET_CMOVE"
11659
  [(const_int 0)]
11660
  "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11661
 
11662
(define_split
11663
  [(set (match_operand:DI 0 "register_operand" "")
11664
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11665
                     (match_operand:QI 2 "nonmemory_operand" "")))
11666
   (clobber (reg:CC FLAGS_REG))]
11667
  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11668
                     ? epilogue_completed : reload_completed)"
11669
  [(const_int 0)]
11670
  "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11671
 
11672
(define_expand "lshrsi3"
11673
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
11674
        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11675
                     (match_operand:QI 2 "nonmemory_operand" "")))]
11676
  ""
11677
  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11678
 
11679
(define_insn "*lshrsi3_1_one_bit"
11680
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11681
        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11682
                     (match_operand:QI 2 "const1_operand" "")))
11683
   (clobber (reg:CC FLAGS_REG))]
11684
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11685
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11686
  "shr{l}\t%0"
11687
  [(set_attr "type" "ishift")
11688
   (set_attr "length_immediate" "0")
11689
   (set_attr "mode" "SI")])
11690
 
11691
(define_insn "*lshrsi3_1_one_bit_zext"
11692
  [(set (match_operand:DI 0 "register_operand" "=r")
11693
        (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11694
                     (match_operand:QI 2 "const1_operand" "")))
11695
   (clobber (reg:CC FLAGS_REG))]
11696
  "TARGET_64BIT
11697
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11698
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11699
  "shr{l}\t%k0"
11700
  [(set_attr "type" "ishift")
11701
   (set_attr "length_immediate" "0")
11702
   (set_attr "mode" "SI")])
11703
 
11704
(define_insn "*lshrsi3_1"
11705
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11706
        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11707
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11708
   (clobber (reg:CC FLAGS_REG))]
11709
  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11710
  "@
11711
   shr{l}\t{%2, %0|%0, %2}
11712
   shr{l}\t{%b2, %0|%0, %b2}"
11713
  [(set_attr "type" "ishift")
11714
   (set_attr "mode" "SI")])
11715
 
11716
(define_insn "*lshrsi3_1_zext"
11717
  [(set (match_operand:DI 0 "register_operand" "=r,r")
11718
        (zero_extend:DI
11719
          (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11720
                       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11721
   (clobber (reg:CC FLAGS_REG))]
11722
  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11723
  "@
11724
   shr{l}\t{%2, %k0|%k0, %2}
11725
   shr{l}\t{%b2, %k0|%k0, %b2}"
11726
  [(set_attr "type" "ishift")
11727
   (set_attr "mode" "SI")])
11728
 
11729
;; This pattern can't accept a variable shift count, since shifts by
11730
;; zero don't affect the flags.  We assume that shifts by constant
11731
;; zero are optimized away.
11732
(define_insn "*lshrsi3_one_bit_cmp"
11733
  [(set (reg FLAGS_REG)
11734
        (compare
11735
          (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11736
                       (match_operand:QI 2 "const1_operand" ""))
11737
          (const_int 0)))
11738
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11739
        (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11740
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11741
   && ix86_match_ccmode (insn, CCGOCmode)
11742
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11743
  "shr{l}\t%0"
11744
  [(set_attr "type" "ishift")
11745
   (set_attr "length_immediate" "0")
11746
   (set_attr "mode" "SI")])
11747
 
11748
(define_insn "*lshrsi3_one_bit_cconly"
11749
  [(set (reg FLAGS_REG)
11750
        (compare
11751
          (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11752
                       (match_operand:QI 2 "const1_operand" ""))
11753
          (const_int 0)))
11754
   (clobber (match_scratch:SI 0 "=r"))]
11755
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11756
   && ix86_match_ccmode (insn, CCGOCmode)
11757
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11758
  "shr{l}\t%0"
11759
  [(set_attr "type" "ishift")
11760
   (set_attr "length_immediate" "0")
11761
   (set_attr "mode" "SI")])
11762
 
11763
(define_insn "*lshrsi3_cmp_one_bit_zext"
11764
  [(set (reg FLAGS_REG)
11765
        (compare
11766
          (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11767
                       (match_operand:QI 2 "const1_operand" ""))
11768
          (const_int 0)))
11769
   (set (match_operand:DI 0 "register_operand" "=r")
11770
        (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11771
  "TARGET_64BIT
11772
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11773
   && ix86_match_ccmode (insn, CCGOCmode)
11774
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11775
  "shr{l}\t%k0"
11776
  [(set_attr "type" "ishift")
11777
   (set_attr "length_immediate" "0")
11778
   (set_attr "mode" "SI")])
11779
 
11780
;; This pattern can't accept a variable shift count, since shifts by
11781
;; zero don't affect the flags.  We assume that shifts by constant
11782
;; zero are optimized away.
11783
(define_insn "*lshrsi3_cmp"
11784
  [(set (reg FLAGS_REG)
11785
        (compare
11786
          (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11787
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11788
          (const_int 0)))
11789
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11790
        (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11791
  "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11792
   && ix86_match_ccmode (insn, CCGOCmode)
11793
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11794
  "shr{l}\t{%2, %0|%0, %2}"
11795
  [(set_attr "type" "ishift")
11796
   (set_attr "mode" "SI")])
11797
 
11798
(define_insn "*lshrsi3_cconly"
11799
  [(set (reg FLAGS_REG)
11800
      (compare
11801
        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11802
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11803
        (const_int 0)))
11804
   (clobber (match_scratch:SI 0 "=r"))]
11805
  "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11806
   && ix86_match_ccmode (insn, CCGOCmode)
11807
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11808
  "shr{l}\t{%2, %0|%0, %2}"
11809
  [(set_attr "type" "ishift")
11810
   (set_attr "mode" "SI")])
11811
 
11812
(define_insn "*lshrsi3_cmp_zext"
11813
  [(set (reg FLAGS_REG)
11814
        (compare
11815
          (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11816
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11817
          (const_int 0)))
11818
   (set (match_operand:DI 0 "register_operand" "=r")
11819
        (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11820
  "TARGET_64BIT
11821
   && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11822
   && ix86_match_ccmode (insn, CCGOCmode)
11823
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11824
  "shr{l}\t{%2, %k0|%k0, %2}"
11825
  [(set_attr "type" "ishift")
11826
   (set_attr "mode" "SI")])
11827
 
11828
(define_expand "lshrhi3"
11829
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11830
        (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11831
                     (match_operand:QI 2 "nonmemory_operand" "")))]
11832
  "TARGET_HIMODE_MATH"
11833
  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11834
 
11835
(define_insn "*lshrhi3_1_one_bit"
11836
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11837
        (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11838
                     (match_operand:QI 2 "const1_operand" "")))
11839
   (clobber (reg:CC FLAGS_REG))]
11840
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11841
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11842
  "shr{w}\t%0"
11843
  [(set_attr "type" "ishift")
11844
   (set_attr "length_immediate" "0")
11845
   (set_attr "mode" "HI")])
11846
 
11847
(define_insn "*lshrhi3_1"
11848
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11849
        (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11850
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11851
   (clobber (reg:CC FLAGS_REG))]
11852
  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11853
  "@
11854
   shr{w}\t{%2, %0|%0, %2}
11855
   shr{w}\t{%b2, %0|%0, %b2}"
11856
  [(set_attr "type" "ishift")
11857
   (set_attr "mode" "HI")])
11858
 
11859
;; This pattern can't accept a variable shift count, since shifts by
11860
;; zero don't affect the flags.  We assume that shifts by constant
11861
;; zero are optimized away.
11862
(define_insn "*lshrhi3_one_bit_cmp"
11863
  [(set (reg FLAGS_REG)
11864
        (compare
11865
          (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11866
                       (match_operand:QI 2 "const1_operand" ""))
11867
          (const_int 0)))
11868
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11869
        (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11870
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11871
   && ix86_match_ccmode (insn, CCGOCmode)
11872
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11873
  "shr{w}\t%0"
11874
  [(set_attr "type" "ishift")
11875
   (set_attr "length_immediate" "0")
11876
   (set_attr "mode" "HI")])
11877
 
11878
(define_insn "*lshrhi3_one_bit_cconly"
11879
  [(set (reg FLAGS_REG)
11880
        (compare
11881
          (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11882
                       (match_operand:QI 2 "const1_operand" ""))
11883
          (const_int 0)))
11884
   (clobber (match_scratch:HI 0 "=r"))]
11885
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11886
   && ix86_match_ccmode (insn, CCGOCmode)
11887
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11888
  "shr{w}\t%0"
11889
  [(set_attr "type" "ishift")
11890
   (set_attr "length_immediate" "0")
11891
   (set_attr "mode" "HI")])
11892
 
11893
;; This pattern can't accept a variable shift count, since shifts by
11894
;; zero don't affect the flags.  We assume that shifts by constant
11895
;; zero are optimized away.
11896
(define_insn "*lshrhi3_cmp"
11897
  [(set (reg FLAGS_REG)
11898
        (compare
11899
          (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11900
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11901
          (const_int 0)))
11902
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11903
        (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11904
  "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11905
   && ix86_match_ccmode (insn, CCGOCmode)
11906
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11907
  "shr{w}\t{%2, %0|%0, %2}"
11908
  [(set_attr "type" "ishift")
11909
   (set_attr "mode" "HI")])
11910
 
11911
(define_insn "*lshrhi3_cconly"
11912
  [(set (reg FLAGS_REG)
11913
        (compare
11914
          (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11915
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11916
          (const_int 0)))
11917
   (clobber (match_scratch:HI 0 "=r"))]
11918
  "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11919
   && ix86_match_ccmode (insn, CCGOCmode)
11920
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11921
  "shr{w}\t{%2, %0|%0, %2}"
11922
  [(set_attr "type" "ishift")
11923
   (set_attr "mode" "HI")])
11924
 
11925
(define_expand "lshrqi3"
11926
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11927
        (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11928
                     (match_operand:QI 2 "nonmemory_operand" "")))]
11929
  "TARGET_QIMODE_MATH"
11930
  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11931
 
11932
(define_insn "*lshrqi3_1_one_bit"
11933
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11934
        (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11935
                     (match_operand:QI 2 "const1_operand" "")))
11936
   (clobber (reg:CC FLAGS_REG))]
11937
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11938
   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11939
  "shr{b}\t%0"
11940
  [(set_attr "type" "ishift")
11941
   (set_attr "length_immediate" "0")
11942
   (set_attr "mode" "QI")])
11943
 
11944
(define_insn "*lshrqi3_1_one_bit_slp"
11945
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11946
        (lshiftrt:QI (match_dup 0)
11947
                     (match_operand:QI 1 "const1_operand" "")))
11948
   (clobber (reg:CC FLAGS_REG))]
11949
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11950
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11951
  "shr{b}\t%0"
11952
  [(set_attr "type" "ishift1")
11953
   (set_attr "length_immediate" "0")
11954
   (set_attr "mode" "QI")])
11955
 
11956
(define_insn "*lshrqi3_1"
11957
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11958
        (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11959
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11960
   (clobber (reg:CC FLAGS_REG))]
11961
  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11962
  "@
11963
   shr{b}\t{%2, %0|%0, %2}
11964
   shr{b}\t{%b2, %0|%0, %b2}"
11965
  [(set_attr "type" "ishift")
11966
   (set_attr "mode" "QI")])
11967
 
11968
(define_insn "*lshrqi3_1_slp"
11969
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11970
        (lshiftrt:QI (match_dup 0)
11971
                     (match_operand:QI 1 "nonmemory_operand" "I,c")))
11972
   (clobber (reg:CC FLAGS_REG))]
11973
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11974
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11975
  "@
11976
   shr{b}\t{%1, %0|%0, %1}
11977
   shr{b}\t{%b1, %0|%0, %b1}"
11978
  [(set_attr "type" "ishift1")
11979
   (set_attr "mode" "QI")])
11980
 
11981
;; This pattern can't accept a variable shift count, since shifts by
11982
;; zero don't affect the flags.  We assume that shifts by constant
11983
;; zero are optimized away.
11984
(define_insn "*lshrqi2_one_bit_cmp"
11985
  [(set (reg FLAGS_REG)
11986
        (compare
11987
          (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11988
                       (match_operand:QI 2 "const1_operand" ""))
11989
          (const_int 0)))
11990
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11991
        (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11992
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11993
   && ix86_match_ccmode (insn, CCGOCmode)
11994
   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11995
  "shr{b}\t%0"
11996
  [(set_attr "type" "ishift")
11997
   (set_attr "length_immediate" "0")
11998
   (set_attr "mode" "QI")])
11999
 
12000
(define_insn "*lshrqi2_one_bit_cconly"
12001
  [(set (reg FLAGS_REG)
12002
        (compare
12003
          (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12004
                       (match_operand:QI 2 "const1_operand" ""))
12005
          (const_int 0)))
12006
   (clobber (match_scratch:QI 0 "=q"))]
12007
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12008
   && ix86_match_ccmode (insn, CCGOCmode)
12009
   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12010
  "shr{b}\t%0"
12011
  [(set_attr "type" "ishift")
12012
   (set_attr "length_immediate" "0")
12013
   (set_attr "mode" "QI")])
12014
 
12015
;; This pattern can't accept a variable shift count, since shifts by
12016
;; zero don't affect the flags.  We assume that shifts by constant
12017
;; zero are optimized away.
12018
(define_insn "*lshrqi2_cmp"
12019
  [(set (reg FLAGS_REG)
12020
        (compare
12021
          (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12022
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12023
          (const_int 0)))
12024
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12025
        (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12026
  "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12027
   && ix86_match_ccmode (insn, CCGOCmode)
12028
   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12029
  "shr{b}\t{%2, %0|%0, %2}"
12030
  [(set_attr "type" "ishift")
12031
   (set_attr "mode" "QI")])
12032
 
12033
(define_insn "*lshrqi2_cconly"
12034
  [(set (reg FLAGS_REG)
12035
        (compare
12036
          (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12037
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12038
          (const_int 0)))
12039
   (clobber (match_scratch:QI 0 "=q"))]
12040
  "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12041
   && ix86_match_ccmode (insn, CCGOCmode)
12042
   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12043
  "shr{b}\t{%2, %0|%0, %2}"
12044
  [(set_attr "type" "ishift")
12045
   (set_attr "mode" "QI")])
12046
 
12047
;; Rotate instructions
12048
 
12049
(define_expand "rotldi3"
12050
  [(set (match_operand:DI 0 "shiftdi_operand" "")
12051
        (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12052
                   (match_operand:QI 2 "nonmemory_operand" "")))]
12053
 ""
12054
{
12055
  if (TARGET_64BIT)
12056
    {
12057
      ix86_expand_binary_operator (ROTATE, DImode, operands);
12058
      DONE;
12059
    }
12060
  if (!const_1_to_31_operand (operands[2], VOIDmode))
12061
    FAIL;
12062
  emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12063
  DONE;
12064
})
12065
 
12066
;; Implement rotation using two double-precision shift instructions
12067
;; and a scratch register.
12068
(define_insn_and_split "ix86_rotldi3"
12069
 [(set (match_operand:DI 0 "register_operand" "=r")
12070
       (rotate:DI (match_operand:DI 1 "register_operand" "0")
12071
                  (match_operand:QI 2 "const_1_to_31_operand" "I")))
12072
  (clobber (reg:CC FLAGS_REG))
12073
  (clobber (match_scratch:SI 3 "=&r"))]
12074
 "!TARGET_64BIT"
12075
 ""
12076
 "&& reload_completed"
12077
 [(set (match_dup 3) (match_dup 4))
12078
  (parallel
12079
   [(set (match_dup 4)
12080
         (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12081
                 (lshiftrt:SI (match_dup 5)
12082
                              (minus:QI (const_int 32) (match_dup 2)))))
12083
    (clobber (reg:CC FLAGS_REG))])
12084
  (parallel
12085
   [(set (match_dup 5)
12086
         (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12087
                 (lshiftrt:SI (match_dup 3)
12088
                              (minus:QI (const_int 32) (match_dup 2)))))
12089
    (clobber (reg:CC FLAGS_REG))])]
12090
 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12091
 
12092
(define_insn "*rotlsi3_1_one_bit_rex64"
12093
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12094
        (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12095
                   (match_operand:QI 2 "const1_operand" "")))
12096
   (clobber (reg:CC FLAGS_REG))]
12097
  "TARGET_64BIT
12098
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12099
   && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12100
  "rol{q}\t%0"
12101
  [(set_attr "type" "rotate")
12102
   (set_attr "length_immediate" "0")
12103
   (set_attr "mode" "DI")])
12104
 
12105
(define_insn "*rotldi3_1_rex64"
12106
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12107
        (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12108
                   (match_operand:QI 2 "nonmemory_operand" "e,c")))
12109
   (clobber (reg:CC FLAGS_REG))]
12110
  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12111
  "@
12112
   rol{q}\t{%2, %0|%0, %2}
12113
   rol{q}\t{%b2, %0|%0, %b2}"
12114
  [(set_attr "type" "rotate")
12115
   (set_attr "mode" "DI")])
12116
 
12117
(define_expand "rotlsi3"
12118
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12119
        (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12120
                   (match_operand:QI 2 "nonmemory_operand" "")))]
12121
  ""
12122
  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12123
 
12124
(define_insn "*rotlsi3_1_one_bit"
12125
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12126
        (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12127
                   (match_operand:QI 2 "const1_operand" "")))
12128
   (clobber (reg:CC FLAGS_REG))]
12129
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12130
   && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12131
  "rol{l}\t%0"
12132
  [(set_attr "type" "rotate")
12133
   (set_attr "length_immediate" "0")
12134
   (set_attr "mode" "SI")])
12135
 
12136
(define_insn "*rotlsi3_1_one_bit_zext"
12137
  [(set (match_operand:DI 0 "register_operand" "=r")
12138
        (zero_extend:DI
12139
          (rotate:SI (match_operand:SI 1 "register_operand" "0")
12140
                     (match_operand:QI 2 "const1_operand" ""))))
12141
   (clobber (reg:CC FLAGS_REG))]
12142
  "TARGET_64BIT
12143
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12144
   && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12145
  "rol{l}\t%k0"
12146
  [(set_attr "type" "rotate")
12147
   (set_attr "length_immediate" "0")
12148
   (set_attr "mode" "SI")])
12149
 
12150
(define_insn "*rotlsi3_1"
12151
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12152
        (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12153
                   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12154
   (clobber (reg:CC FLAGS_REG))]
12155
  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12156
  "@
12157
   rol{l}\t{%2, %0|%0, %2}
12158
   rol{l}\t{%b2, %0|%0, %b2}"
12159
  [(set_attr "type" "rotate")
12160
   (set_attr "mode" "SI")])
12161
 
12162
(define_insn "*rotlsi3_1_zext"
12163
  [(set (match_operand:DI 0 "register_operand" "=r,r")
12164
        (zero_extend:DI
12165
          (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12166
                     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12167
   (clobber (reg:CC FLAGS_REG))]
12168
  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12169
  "@
12170
   rol{l}\t{%2, %k0|%k0, %2}
12171
   rol{l}\t{%b2, %k0|%k0, %b2}"
12172
  [(set_attr "type" "rotate")
12173
   (set_attr "mode" "SI")])
12174
 
12175
(define_expand "rotlhi3"
12176
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12177
        (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12178
                   (match_operand:QI 2 "nonmemory_operand" "")))]
12179
  "TARGET_HIMODE_MATH"
12180
  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12181
 
12182
(define_insn "*rotlhi3_1_one_bit"
12183
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12184
        (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12185
                   (match_operand:QI 2 "const1_operand" "")))
12186
   (clobber (reg:CC FLAGS_REG))]
12187
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12188
   && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12189
  "rol{w}\t%0"
12190
  [(set_attr "type" "rotate")
12191
   (set_attr "length_immediate" "0")
12192
   (set_attr "mode" "HI")])
12193
 
12194
(define_insn "*rotlhi3_1"
12195
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12196
        (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12197
                   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12198
   (clobber (reg:CC FLAGS_REG))]
12199
  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12200
  "@
12201
   rol{w}\t{%2, %0|%0, %2}
12202
   rol{w}\t{%b2, %0|%0, %b2}"
12203
  [(set_attr "type" "rotate")
12204
   (set_attr "mode" "HI")])
12205
 
12206
(define_split
12207
 [(set (match_operand:HI 0 "register_operand" "")
12208
       (rotate:HI (match_dup 0) (const_int 8)))
12209
  (clobber (reg:CC FLAGS_REG))]
12210
 "reload_completed"
12211
 [(parallel [(set (strict_low_part (match_dup 0))
12212
                  (bswap:HI (match_dup 0)))
12213
             (clobber (reg:CC FLAGS_REG))])]
12214
 "")
12215
 
12216
(define_expand "rotlqi3"
12217
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12218
        (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12219
                   (match_operand:QI 2 "nonmemory_operand" "")))]
12220
  "TARGET_QIMODE_MATH"
12221
  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12222
 
12223
(define_insn "*rotlqi3_1_one_bit_slp"
12224
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12225
        (rotate:QI (match_dup 0)
12226
                   (match_operand:QI 1 "const1_operand" "")))
12227
   (clobber (reg:CC FLAGS_REG))]
12228
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12229
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12230
  "rol{b}\t%0"
12231
  [(set_attr "type" "rotate1")
12232
   (set_attr "length_immediate" "0")
12233
   (set_attr "mode" "QI")])
12234
 
12235
(define_insn "*rotlqi3_1_one_bit"
12236
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12237
        (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12238
                   (match_operand:QI 2 "const1_operand" "")))
12239
   (clobber (reg:CC FLAGS_REG))]
12240
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12241
   && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12242
  "rol{b}\t%0"
12243
  [(set_attr "type" "rotate")
12244
   (set_attr "length_immediate" "0")
12245
   (set_attr "mode" "QI")])
12246
 
12247
(define_insn "*rotlqi3_1_slp"
12248
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12249
        (rotate:QI (match_dup 0)
12250
                   (match_operand:QI 1 "nonmemory_operand" "I,c")))
12251
   (clobber (reg:CC FLAGS_REG))]
12252
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12253
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12254
  "@
12255
   rol{b}\t{%1, %0|%0, %1}
12256
   rol{b}\t{%b1, %0|%0, %b1}"
12257
  [(set_attr "type" "rotate1")
12258
   (set_attr "mode" "QI")])
12259
 
12260
(define_insn "*rotlqi3_1"
12261
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12262
        (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12263
                   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12264
   (clobber (reg:CC FLAGS_REG))]
12265
  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12266
  "@
12267
   rol{b}\t{%2, %0|%0, %2}
12268
   rol{b}\t{%b2, %0|%0, %b2}"
12269
  [(set_attr "type" "rotate")
12270
   (set_attr "mode" "QI")])
12271
 
12272
(define_expand "rotrdi3"
12273
  [(set (match_operand:DI 0 "shiftdi_operand" "")
12274
        (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12275
                   (match_operand:QI 2 "nonmemory_operand" "")))]
12276
 ""
12277
{
12278
  if (TARGET_64BIT)
12279
    {
12280
      ix86_expand_binary_operator (ROTATERT, DImode, operands);
12281
      DONE;
12282
    }
12283
  if (!const_1_to_31_operand (operands[2], VOIDmode))
12284
    FAIL;
12285
  emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12286
  DONE;
12287
})
12288
 
12289
;; Implement rotation using two double-precision shift instructions
12290
;; and a scratch register.
12291
(define_insn_and_split "ix86_rotrdi3"
12292
 [(set (match_operand:DI 0 "register_operand" "=r")
12293
       (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12294
                    (match_operand:QI 2 "const_1_to_31_operand" "I")))
12295
  (clobber (reg:CC FLAGS_REG))
12296
  (clobber (match_scratch:SI 3 "=&r"))]
12297
 "!TARGET_64BIT"
12298
 ""
12299
 "&& reload_completed"
12300
 [(set (match_dup 3) (match_dup 4))
12301
  (parallel
12302
   [(set (match_dup 4)
12303
         (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12304
                 (ashift:SI (match_dup 5)
12305
                            (minus:QI (const_int 32) (match_dup 2)))))
12306
    (clobber (reg:CC FLAGS_REG))])
12307
  (parallel
12308
   [(set (match_dup 5)
12309
         (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12310
                 (ashift:SI (match_dup 3)
12311
                            (minus:QI (const_int 32) (match_dup 2)))))
12312
    (clobber (reg:CC FLAGS_REG))])]
12313
 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12314
 
12315
(define_insn "*rotrdi3_1_one_bit_rex64"
12316
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12317
        (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12318
                     (match_operand:QI 2 "const1_operand" "")))
12319
   (clobber (reg:CC FLAGS_REG))]
12320
  "TARGET_64BIT
12321
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12322
   && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12323
  "ror{q}\t%0"
12324
  [(set_attr "type" "rotate")
12325
   (set_attr "length_immediate" "0")
12326
   (set_attr "mode" "DI")])
12327
 
12328
(define_insn "*rotrdi3_1_rex64"
12329
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12330
        (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12331
                     (match_operand:QI 2 "nonmemory_operand" "J,c")))
12332
   (clobber (reg:CC FLAGS_REG))]
12333
  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12334
  "@
12335
   ror{q}\t{%2, %0|%0, %2}
12336
   ror{q}\t{%b2, %0|%0, %b2}"
12337
  [(set_attr "type" "rotate")
12338
   (set_attr "mode" "DI")])
12339
 
12340
(define_expand "rotrsi3"
12341
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12342
        (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12343
                     (match_operand:QI 2 "nonmemory_operand" "")))]
12344
  ""
12345
  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12346
 
12347
(define_insn "*rotrsi3_1_one_bit"
12348
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12349
        (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12350
                     (match_operand:QI 2 "const1_operand" "")))
12351
   (clobber (reg:CC FLAGS_REG))]
12352
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12353
   && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12354
  "ror{l}\t%0"
12355
  [(set_attr "type" "rotate")
12356
   (set_attr "length_immediate" "0")
12357
   (set_attr "mode" "SI")])
12358
 
12359
(define_insn "*rotrsi3_1_one_bit_zext"
12360
  [(set (match_operand:DI 0 "register_operand" "=r")
12361
        (zero_extend:DI
12362
          (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12363
                       (match_operand:QI 2 "const1_operand" ""))))
12364
   (clobber (reg:CC FLAGS_REG))]
12365
  "TARGET_64BIT
12366
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12367
   && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12368
  "ror{l}\t%k0"
12369
  [(set_attr "type" "rotate")
12370
   (set_attr "length_immediate" "0")
12371
   (set_attr "mode" "SI")])
12372
 
12373
(define_insn "*rotrsi3_1"
12374
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12375
        (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12376
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12377
   (clobber (reg:CC FLAGS_REG))]
12378
  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12379
  "@
12380
   ror{l}\t{%2, %0|%0, %2}
12381
   ror{l}\t{%b2, %0|%0, %b2}"
12382
  [(set_attr "type" "rotate")
12383
   (set_attr "mode" "SI")])
12384
 
12385
(define_insn "*rotrsi3_1_zext"
12386
  [(set (match_operand:DI 0 "register_operand" "=r,r")
12387
        (zero_extend:DI
12388
          (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12389
                       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12390
   (clobber (reg:CC FLAGS_REG))]
12391
  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12392
  "@
12393
   ror{l}\t{%2, %k0|%k0, %2}
12394
   ror{l}\t{%b2, %k0|%k0, %b2}"
12395
  [(set_attr "type" "rotate")
12396
   (set_attr "mode" "SI")])
12397
 
12398
(define_expand "rotrhi3"
12399
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12400
        (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12401
                     (match_operand:QI 2 "nonmemory_operand" "")))]
12402
  "TARGET_HIMODE_MATH"
12403
  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12404
 
12405
(define_insn "*rotrhi3_one_bit"
12406
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12407
        (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12408
                     (match_operand:QI 2 "const1_operand" "")))
12409
   (clobber (reg:CC FLAGS_REG))]
12410
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12411
   && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12412
  "ror{w}\t%0"
12413
  [(set_attr "type" "rotate")
12414
   (set_attr "length_immediate" "0")
12415
   (set_attr "mode" "HI")])
12416
 
12417
(define_insn "*rotrhi3_1"
12418
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12419
        (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12420
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12421
   (clobber (reg:CC FLAGS_REG))]
12422
  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12423
  "@
12424
   ror{w}\t{%2, %0|%0, %2}
12425
   ror{w}\t{%b2, %0|%0, %b2}"
12426
  [(set_attr "type" "rotate")
12427
   (set_attr "mode" "HI")])
12428
 
12429
(define_split
12430
 [(set (match_operand:HI 0 "register_operand" "")
12431
       (rotatert:HI (match_dup 0) (const_int 8)))
12432
  (clobber (reg:CC FLAGS_REG))]
12433
 "reload_completed"
12434
 [(parallel [(set (strict_low_part (match_dup 0))
12435
                  (bswap:HI (match_dup 0)))
12436
             (clobber (reg:CC FLAGS_REG))])]
12437
 "")
12438
 
12439
(define_expand "rotrqi3"
12440
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12441
        (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12442
                     (match_operand:QI 2 "nonmemory_operand" "")))]
12443
  "TARGET_QIMODE_MATH"
12444
  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12445
 
12446
(define_insn "*rotrqi3_1_one_bit"
12447
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12448
        (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12449
                     (match_operand:QI 2 "const1_operand" "")))
12450
   (clobber (reg:CC FLAGS_REG))]
12451
  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12452
   && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12453
  "ror{b}\t%0"
12454
  [(set_attr "type" "rotate")
12455
   (set_attr "length_immediate" "0")
12456
   (set_attr "mode" "QI")])
12457
 
12458
(define_insn "*rotrqi3_1_one_bit_slp"
12459
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12460
        (rotatert:QI (match_dup 0)
12461
                     (match_operand:QI 1 "const1_operand" "")))
12462
   (clobber (reg:CC FLAGS_REG))]
12463
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12464
   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12465
  "ror{b}\t%0"
12466
  [(set_attr "type" "rotate1")
12467
   (set_attr "length_immediate" "0")
12468
   (set_attr "mode" "QI")])
12469
 
12470
(define_insn "*rotrqi3_1"
12471
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12472
        (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12473
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12474
   (clobber (reg:CC FLAGS_REG))]
12475
  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12476
  "@
12477
   ror{b}\t{%2, %0|%0, %2}
12478
   ror{b}\t{%b2, %0|%0, %b2}"
12479
  [(set_attr "type" "rotate")
12480
   (set_attr "mode" "QI")])
12481
 
12482
(define_insn "*rotrqi3_1_slp"
12483
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12484
        (rotatert:QI (match_dup 0)
12485
                     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12486
   (clobber (reg:CC FLAGS_REG))]
12487
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12488
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12489
  "@
12490
   ror{b}\t{%1, %0|%0, %1}
12491
   ror{b}\t{%b1, %0|%0, %b1}"
12492
  [(set_attr "type" "rotate1")
12493
   (set_attr "mode" "QI")])
12494
 
12495
;; Bit set / bit test instructions
12496
 
12497
(define_expand "extv"
12498
  [(set (match_operand:SI 0 "register_operand" "")
12499
        (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12500
                         (match_operand:SI 2 "const8_operand" "")
12501
                         (match_operand:SI 3 "const8_operand" "")))]
12502
  ""
12503
{
12504
  /* Handle extractions from %ah et al.  */
12505
  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12506
    FAIL;
12507
 
12508
  /* From mips.md: extract_bit_field doesn't verify that our source
12509
     matches the predicate, so check it again here.  */
12510
  if (! ext_register_operand (operands[1], VOIDmode))
12511
    FAIL;
12512
})
12513
 
12514
(define_expand "extzv"
12515
  [(set (match_operand:SI 0 "register_operand" "")
12516
        (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12517
                         (match_operand:SI 2 "const8_operand" "")
12518
                         (match_operand:SI 3 "const8_operand" "")))]
12519
  ""
12520
{
12521
  /* Handle extractions from %ah et al.  */
12522
  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12523
    FAIL;
12524
 
12525
  /* From mips.md: extract_bit_field doesn't verify that our source
12526
     matches the predicate, so check it again here.  */
12527
  if (! ext_register_operand (operands[1], VOIDmode))
12528
    FAIL;
12529
})
12530
 
12531
(define_expand "insv"
12532
  [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12533
                      (match_operand 1 "const8_operand" "")
12534
                      (match_operand 2 "const8_operand" ""))
12535
        (match_operand 3 "register_operand" ""))]
12536
  ""
12537
{
12538
  /* Handle insertions to %ah et al.  */
12539
  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12540
    FAIL;
12541
 
12542
  /* From mips.md: insert_bit_field doesn't verify that our source
12543
     matches the predicate, so check it again here.  */
12544
  if (! ext_register_operand (operands[0], VOIDmode))
12545
    FAIL;
12546
 
12547
  if (TARGET_64BIT)
12548
    emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12549
  else
12550
    emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12551
 
12552
  DONE;
12553
})
12554
 
12555
;; %%% bts, btr, btc, bt.
12556
;; In general these instructions are *slow* when applied to memory,
12557
;; since they enforce atomic operation.  When applied to registers,
12558
;; it depends on the cpu implementation.  They're never faster than
12559
;; the corresponding and/ior/xor operations, so with 32-bit there's
12560
;; no point.  But in 64-bit, we can't hold the relevant immediates
12561
;; within the instruction itself, so operating on bits in the high
12562
;; 32-bits of a register becomes easier.
12563
;;
12564
;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12565
;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12566
;; negdf respectively, so they can never be disabled entirely.
12567
 
12568
(define_insn "*btsq"
12569
  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12570
                         (const_int 1)
12571
                         (match_operand:DI 1 "const_0_to_63_operand" ""))
12572
        (const_int 1))
12573
   (clobber (reg:CC FLAGS_REG))]
12574
  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12575
  "bts{q}\t{%1, %0|%0, %1}"
12576
  [(set_attr "type" "alu1")
12577
   (set_attr "prefix_0f" "1")
12578
   (set_attr "mode" "DI")])
12579
 
12580
(define_insn "*btrq"
12581
  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12582
                         (const_int 1)
12583
                         (match_operand:DI 1 "const_0_to_63_operand" ""))
12584
        (const_int 0))
12585
   (clobber (reg:CC FLAGS_REG))]
12586
  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12587
  "btr{q}\t{%1, %0|%0, %1}"
12588
  [(set_attr "type" "alu1")
12589
   (set_attr "prefix_0f" "1")
12590
   (set_attr "mode" "DI")])
12591
 
12592
(define_insn "*btcq"
12593
  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12594
                         (const_int 1)
12595
                         (match_operand:DI 1 "const_0_to_63_operand" ""))
12596
        (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12597
   (clobber (reg:CC FLAGS_REG))]
12598
  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12599
  "btc{q}\t{%1, %0|%0, %1}"
12600
  [(set_attr "type" "alu1")
12601
   (set_attr "prefix_0f" "1")
12602
   (set_attr "mode" "DI")])
12603
 
12604
;; Allow Nocona to avoid these instructions if a register is available.
12605
 
12606
(define_peephole2
12607
  [(match_scratch:DI 2 "r")
12608
   (parallel [(set (zero_extract:DI
12609
                     (match_operand:DI 0 "register_operand" "")
12610
                     (const_int 1)
12611
                     (match_operand:DI 1 "const_0_to_63_operand" ""))
12612
                   (const_int 1))
12613
              (clobber (reg:CC FLAGS_REG))])]
12614
  "TARGET_64BIT && !TARGET_USE_BT"
12615
  [(const_int 0)]
12616
{
12617
  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12618
  rtx op1;
12619
 
12620
  if (HOST_BITS_PER_WIDE_INT >= 64)
12621
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
12622
  else if (i < HOST_BITS_PER_WIDE_INT)
12623
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
12624
  else
12625
    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12626
 
12627
  op1 = immed_double_const (lo, hi, DImode);
12628
  if (i >= 31)
12629
    {
12630
      emit_move_insn (operands[2], op1);
12631
      op1 = operands[2];
12632
    }
12633
 
12634
  emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12635
  DONE;
12636
})
12637
 
12638
(define_peephole2
12639
  [(match_scratch:DI 2 "r")
12640
   (parallel [(set (zero_extract:DI
12641
                     (match_operand:DI 0 "register_operand" "")
12642
                     (const_int 1)
12643
                     (match_operand:DI 1 "const_0_to_63_operand" ""))
12644
                   (const_int 0))
12645
              (clobber (reg:CC FLAGS_REG))])]
12646
  "TARGET_64BIT && !TARGET_USE_BT"
12647
  [(const_int 0)]
12648
{
12649
  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12650
  rtx op1;
12651
 
12652
  if (HOST_BITS_PER_WIDE_INT >= 64)
12653
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
12654
  else if (i < HOST_BITS_PER_WIDE_INT)
12655
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
12656
  else
12657
    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12658
 
12659
  op1 = immed_double_const (~lo, ~hi, DImode);
12660
  if (i >= 32)
12661
    {
12662
      emit_move_insn (operands[2], op1);
12663
      op1 = operands[2];
12664
    }
12665
 
12666
  emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12667
  DONE;
12668
})
12669
 
12670
(define_peephole2
12671
  [(match_scratch:DI 2 "r")
12672
   (parallel [(set (zero_extract:DI
12673
                     (match_operand:DI 0 "register_operand" "")
12674
                     (const_int 1)
12675
                     (match_operand:DI 1 "const_0_to_63_operand" ""))
12676
              (not:DI (zero_extract:DI
12677
                        (match_dup 0) (const_int 1) (match_dup 1))))
12678
              (clobber (reg:CC FLAGS_REG))])]
12679
  "TARGET_64BIT && !TARGET_USE_BT"
12680
  [(const_int 0)]
12681
{
12682
  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12683
  rtx op1;
12684
 
12685
  if (HOST_BITS_PER_WIDE_INT >= 64)
12686
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
12687
  else if (i < HOST_BITS_PER_WIDE_INT)
12688
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
12689
  else
12690
    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12691
 
12692
  op1 = immed_double_const (lo, hi, DImode);
12693
  if (i >= 31)
12694
    {
12695
      emit_move_insn (operands[2], op1);
12696
      op1 = operands[2];
12697
    }
12698
 
12699
  emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12700
  DONE;
12701
})
12702
 
12703
(define_insn "*btdi_rex64"
12704
  [(set (reg:CCC FLAGS_REG)
12705
        (compare:CCC
12706
          (zero_extract:DI
12707
            (match_operand:DI 0 "register_operand" "r")
12708
            (const_int 1)
12709
            (match_operand:DI 1 "nonmemory_operand" "rN"))
12710
          (const_int 0)))]
12711
  "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12712
  "bt{q}\t{%1, %0|%0, %1}"
12713
  [(set_attr "type" "alu1")
12714
   (set_attr "prefix_0f" "1")
12715
   (set_attr "mode" "DI")])
12716
 
12717
(define_insn "*btsi"
12718
  [(set (reg:CCC FLAGS_REG)
12719
        (compare:CCC
12720
          (zero_extract:SI
12721
            (match_operand:SI 0 "register_operand" "r")
12722
            (const_int 1)
12723
            (match_operand:SI 1 "nonmemory_operand" "rN"))
12724
          (const_int 0)))]
12725
  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12726
  "bt{l}\t{%1, %0|%0, %1}"
12727
  [(set_attr "type" "alu1")
12728
   (set_attr "prefix_0f" "1")
12729
   (set_attr "mode" "SI")])
12730
 
12731
;; Store-flag instructions.
12732
 
12733
;; For all sCOND expanders, also expand the compare or test insn that
12734
;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12735
 
12736
(define_insn_and_split "*setcc_di_1"
12737
  [(set (match_operand:DI 0 "register_operand" "=q")
12738
        (match_operator:DI 1 "ix86_comparison_operator"
12739
          [(reg FLAGS_REG) (const_int 0)]))]
12740
  "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12741
  "#"
12742
  "&& reload_completed"
12743
  [(set (match_dup 2) (match_dup 1))
12744
   (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12745
{
12746
  PUT_MODE (operands[1], QImode);
12747
  operands[2] = gen_lowpart (QImode, operands[0]);
12748
})
12749
 
12750
(define_insn_and_split "*setcc_si_1_and"
12751
  [(set (match_operand:SI 0 "register_operand" "=q")
12752
        (match_operator:SI 1 "ix86_comparison_operator"
12753
          [(reg FLAGS_REG) (const_int 0)]))
12754
   (clobber (reg:CC FLAGS_REG))]
12755
  "!TARGET_PARTIAL_REG_STALL
12756
   && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12757
  "#"
12758
  "&& reload_completed"
12759
  [(set (match_dup 2) (match_dup 1))
12760
   (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12761
              (clobber (reg:CC FLAGS_REG))])]
12762
{
12763
  PUT_MODE (operands[1], QImode);
12764
  operands[2] = gen_lowpart (QImode, operands[0]);
12765
})
12766
 
12767
(define_insn_and_split "*setcc_si_1_movzbl"
12768
  [(set (match_operand:SI 0 "register_operand" "=q")
12769
        (match_operator:SI 1 "ix86_comparison_operator"
12770
          [(reg FLAGS_REG) (const_int 0)]))]
12771
  "!TARGET_PARTIAL_REG_STALL
12772
   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12773
  "#"
12774
  "&& reload_completed"
12775
  [(set (match_dup 2) (match_dup 1))
12776
   (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12777
{
12778
  PUT_MODE (operands[1], QImode);
12779
  operands[2] = gen_lowpart (QImode, operands[0]);
12780
})
12781
 
12782
(define_insn "*setcc_qi"
12783
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12784
        (match_operator:QI 1 "ix86_comparison_operator"
12785
          [(reg FLAGS_REG) (const_int 0)]))]
12786
  ""
12787
  "set%C1\t%0"
12788
  [(set_attr "type" "setcc")
12789
   (set_attr "mode" "QI")])
12790
 
12791
(define_insn "*setcc_qi_slp"
12792
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12793
        (match_operator:QI 1 "ix86_comparison_operator"
12794
          [(reg FLAGS_REG) (const_int 0)]))]
12795
  ""
12796
  "set%C1\t%0"
12797
  [(set_attr "type" "setcc")
12798
   (set_attr "mode" "QI")])
12799
 
12800
;; In general it is not safe to assume too much about CCmode registers,
12801
;; so simplify-rtx stops when it sees a second one.  Under certain
12802
;; conditions this is safe on x86, so help combine not create
12803
;;
12804
;;      seta    %al
12805
;;      testb   %al, %al
12806
;;      sete    %al
12807
 
12808
(define_split
12809
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12810
        (ne:QI (match_operator 1 "ix86_comparison_operator"
12811
                 [(reg FLAGS_REG) (const_int 0)])
12812
            (const_int 0)))]
12813
  ""
12814
  [(set (match_dup 0) (match_dup 1))]
12815
{
12816
  PUT_MODE (operands[1], QImode);
12817
})
12818
 
12819
(define_split
12820
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12821
        (ne:QI (match_operator 1 "ix86_comparison_operator"
12822
                 [(reg FLAGS_REG) (const_int 0)])
12823
            (const_int 0)))]
12824
  ""
12825
  [(set (match_dup 0) (match_dup 1))]
12826
{
12827
  PUT_MODE (operands[1], QImode);
12828
})
12829
 
12830
(define_split
12831
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12832
        (eq:QI (match_operator 1 "ix86_comparison_operator"
12833
                 [(reg FLAGS_REG) (const_int 0)])
12834
            (const_int 0)))]
12835
  ""
12836
  [(set (match_dup 0) (match_dup 1))]
12837
{
12838
  rtx new_op1 = copy_rtx (operands[1]);
12839
  operands[1] = new_op1;
12840
  PUT_MODE (new_op1, QImode);
12841
  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12842
                                             GET_MODE (XEXP (new_op1, 0))));
12843
 
12844
  /* Make sure that (a) the CCmode we have for the flags is strong
12845
     enough for the reversed compare or (b) we have a valid FP compare.  */
12846
  if (! ix86_comparison_operator (new_op1, VOIDmode))
12847
    FAIL;
12848
})
12849
 
12850
(define_split
12851
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12852
        (eq:QI (match_operator 1 "ix86_comparison_operator"
12853
                 [(reg FLAGS_REG) (const_int 0)])
12854
            (const_int 0)))]
12855
  ""
12856
  [(set (match_dup 0) (match_dup 1))]
12857
{
12858
  rtx new_op1 = copy_rtx (operands[1]);
12859
  operands[1] = new_op1;
12860
  PUT_MODE (new_op1, QImode);
12861
  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12862
                                             GET_MODE (XEXP (new_op1, 0))));
12863
 
12864
  /* Make sure that (a) the CCmode we have for the flags is strong
12865
     enough for the reversed compare or (b) we have a valid FP compare.  */
12866
  if (! ix86_comparison_operator (new_op1, VOIDmode))
12867
    FAIL;
12868
})
12869
 
12870
;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12871
;; subsequent logical operations are used to imitate conditional moves.
12872
;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12873
;; it directly.
12874
 
12875
(define_insn "*avx_setcc"
12876
  [(set (match_operand:MODEF 0 "register_operand" "=x")
12877
        (match_operator:MODEF 1 "avx_comparison_float_operator"
12878
          [(match_operand:MODEF 2 "register_operand" "x")
12879
           (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12880
  "TARGET_AVX"
12881
  "vcmp%D1s\t{%3, %2, %0|%0, %2, %3}"
12882
  [(set_attr "type" "ssecmp")
12883
   (set_attr "prefix" "vex")
12884
   (set_attr "length_immediate" "1")
12885
   (set_attr "mode" "")])
12886
 
12887
(define_insn "*sse_setcc"
12888
  [(set (match_operand:MODEF 0 "register_operand" "=x")
12889
        (match_operator:MODEF 1 "sse_comparison_operator"
12890
          [(match_operand:MODEF 2 "register_operand" "0")
12891
           (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12892
  "SSE_FLOAT_MODE_P (mode)"
12893
  "cmp%D1s\t{%3, %0|%0, %3}"
12894
  [(set_attr "type" "ssecmp")
12895
   (set_attr "length_immediate" "1")
12896
   (set_attr "mode" "")])
12897
 
12898
;; Basic conditional jump instructions.
12899
;; We ignore the overflow flag for signed branch instructions.
12900
 
12901
(define_insn "*jcc_1"
12902
  [(set (pc)
12903
        (if_then_else (match_operator 1 "ix86_comparison_operator"
12904
                                      [(reg FLAGS_REG) (const_int 0)])
12905
                      (label_ref (match_operand 0 "" ""))
12906
                      (pc)))]
12907
  ""
12908
  "%+j%C1\t%l0"
12909
  [(set_attr "type" "ibr")
12910
   (set_attr "modrm" "0")
12911
   (set (attr "length")
12912
           (if_then_else (and (ge (minus (match_dup 0) (pc))
12913
                                  (const_int -126))
12914
                              (lt (minus (match_dup 0) (pc))
12915
                                  (const_int 128)))
12916
             (const_int 2)
12917
             (const_int 6)))])
12918
 
12919
(define_insn "*jcc_2"
12920
  [(set (pc)
12921
        (if_then_else (match_operator 1 "ix86_comparison_operator"
12922
                                      [(reg FLAGS_REG) (const_int 0)])
12923
                      (pc)
12924
                      (label_ref (match_operand 0 "" ""))))]
12925
  ""
12926
  "%+j%c1\t%l0"
12927
  [(set_attr "type" "ibr")
12928
   (set_attr "modrm" "0")
12929
   (set (attr "length")
12930
           (if_then_else (and (ge (minus (match_dup 0) (pc))
12931
                                  (const_int -126))
12932
                              (lt (minus (match_dup 0) (pc))
12933
                                  (const_int 128)))
12934
             (const_int 2)
12935
             (const_int 6)))])
12936
 
12937
;; In general it is not safe to assume too much about CCmode registers,
12938
;; so simplify-rtx stops when it sees a second one.  Under certain
12939
;; conditions this is safe on x86, so help combine not create
12940
;;
12941
;;      seta    %al
12942
;;      testb   %al, %al
12943
;;      je      Lfoo
12944
 
12945
(define_split
12946
  [(set (pc)
12947
        (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12948
                                      [(reg FLAGS_REG) (const_int 0)])
12949
                          (const_int 0))
12950
                      (label_ref (match_operand 1 "" ""))
12951
                      (pc)))]
12952
  ""
12953
  [(set (pc)
12954
        (if_then_else (match_dup 0)
12955
                      (label_ref (match_dup 1))
12956
                      (pc)))]
12957
{
12958
  PUT_MODE (operands[0], VOIDmode);
12959
})
12960
 
12961
(define_split
12962
  [(set (pc)
12963
        (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12964
                                      [(reg FLAGS_REG) (const_int 0)])
12965
                          (const_int 0))
12966
                      (label_ref (match_operand 1 "" ""))
12967
                      (pc)))]
12968
  ""
12969
  [(set (pc)
12970
        (if_then_else (match_dup 0)
12971
                      (label_ref (match_dup 1))
12972
                      (pc)))]
12973
{
12974
  rtx new_op0 = copy_rtx (operands[0]);
12975
  operands[0] = new_op0;
12976
  PUT_MODE (new_op0, VOIDmode);
12977
  PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12978
                                             GET_MODE (XEXP (new_op0, 0))));
12979
 
12980
  /* Make sure that (a) the CCmode we have for the flags is strong
12981
     enough for the reversed compare or (b) we have a valid FP compare.  */
12982
  if (! ix86_comparison_operator (new_op0, VOIDmode))
12983
    FAIL;
12984
})
12985
 
12986
;; zero_extend in SImode is correct, since this is what combine pass
12987
;; generates from shift insn with QImode operand.  Actually, the mode of
12988
;; operand 2 (bit offset operand) doesn't matter since bt insn takes
12989
;; appropriate modulo of the bit offset value.
12990
 
12991
(define_insn_and_split "*jcc_btdi_rex64"
12992
  [(set (pc)
12993
        (if_then_else (match_operator 0 "bt_comparison_operator"
12994
                        [(zero_extract:DI
12995
                           (match_operand:DI 1 "register_operand" "r")
12996
                           (const_int 1)
12997
                           (zero_extend:SI
12998
                             (match_operand:QI 2 "register_operand" "r")))
12999
                         (const_int 0)])
13000
                      (label_ref (match_operand 3 "" ""))
13001
                      (pc)))
13002
   (clobber (reg:CC FLAGS_REG))]
13003
  "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13004
  "#"
13005
  "&& 1"
13006
  [(set (reg:CCC FLAGS_REG)
13007
        (compare:CCC
13008
          (zero_extract:DI
13009
            (match_dup 1)
13010
            (const_int 1)
13011
            (match_dup 2))
13012
          (const_int 0)))
13013
   (set (pc)
13014
        (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13015
                      (label_ref (match_dup 3))
13016
                      (pc)))]
13017
{
13018
  operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13019
 
13020
  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13021
})
13022
 
13023
;; avoid useless masking of bit offset operand
13024
(define_insn_and_split "*jcc_btdi_mask_rex64"
13025
  [(set (pc)
13026
        (if_then_else (match_operator 0 "bt_comparison_operator"
13027
                        [(zero_extract:DI
13028
                           (match_operand:DI 1 "register_operand" "r")
13029
                           (const_int 1)
13030
                           (and:SI
13031
                             (match_operand:SI 2 "register_operand" "r")
13032
                             (match_operand:SI 3 "const_int_operand" "n")))])
13033
                      (label_ref (match_operand 4 "" ""))
13034
                      (pc)))
13035
   (clobber (reg:CC FLAGS_REG))]
13036
  "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13037
   && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13038
  "#"
13039
  "&& 1"
13040
  [(set (reg:CCC FLAGS_REG)
13041
        (compare:CCC
13042
          (zero_extract:DI
13043
            (match_dup 1)
13044
            (const_int 1)
13045
            (match_dup 2))
13046
          (const_int 0)))
13047
   (set (pc)
13048
        (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13049
                      (label_ref (match_dup 4))
13050
                      (pc)))]
13051
{
13052
  operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13053
 
13054
  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13055
})
13056
 
13057
(define_insn_and_split "*jcc_btsi"
13058
  [(set (pc)
13059
        (if_then_else (match_operator 0 "bt_comparison_operator"
13060
                        [(zero_extract:SI
13061
                           (match_operand:SI 1 "register_operand" "r")
13062
                           (const_int 1)
13063
                           (zero_extend:SI
13064
                             (match_operand:QI 2 "register_operand" "r")))
13065
                         (const_int 0)])
13066
                      (label_ref (match_operand 3 "" ""))
13067
                      (pc)))
13068
   (clobber (reg:CC FLAGS_REG))]
13069
  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13070
  "#"
13071
  "&& 1"
13072
  [(set (reg:CCC FLAGS_REG)
13073
        (compare:CCC
13074
          (zero_extract:SI
13075
            (match_dup 1)
13076
            (const_int 1)
13077
            (match_dup 2))
13078
          (const_int 0)))
13079
   (set (pc)
13080
        (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13081
                      (label_ref (match_dup 3))
13082
                      (pc)))]
13083
{
13084
  operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13085
 
13086
  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13087
})
13088
 
13089
;; avoid useless masking of bit offset operand
13090
(define_insn_and_split "*jcc_btsi_mask"
13091
  [(set (pc)
13092
        (if_then_else (match_operator 0 "bt_comparison_operator"
13093
                        [(zero_extract:SI
13094
                           (match_operand:SI 1 "register_operand" "r")
13095
                           (const_int 1)
13096
                           (and:SI
13097
                             (match_operand:SI 2 "register_operand" "r")
13098
                             (match_operand:SI 3 "const_int_operand" "n")))])
13099
                      (label_ref (match_operand 4 "" ""))
13100
                      (pc)))
13101
   (clobber (reg:CC FLAGS_REG))]
13102
  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13103
   && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13104
  "#"
13105
  "&& 1"
13106
  [(set (reg:CCC FLAGS_REG)
13107
        (compare:CCC
13108
          (zero_extract:SI
13109
            (match_dup 1)
13110
            (const_int 1)
13111
            (match_dup 2))
13112
          (const_int 0)))
13113
   (set (pc)
13114
        (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13115
                      (label_ref (match_dup 4))
13116
                      (pc)))]
13117
  "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13118
 
13119
(define_insn_and_split "*jcc_btsi_1"
13120
  [(set (pc)
13121
        (if_then_else (match_operator 0 "bt_comparison_operator"
13122
                        [(and:SI
13123
                           (lshiftrt:SI
13124
                             (match_operand:SI 1 "register_operand" "r")
13125
                             (match_operand:QI 2 "register_operand" "r"))
13126
                           (const_int 1))
13127
                         (const_int 0)])
13128
                      (label_ref (match_operand 3 "" ""))
13129
                      (pc)))
13130
   (clobber (reg:CC FLAGS_REG))]
13131
  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13132
  "#"
13133
  "&& 1"
13134
  [(set (reg:CCC FLAGS_REG)
13135
        (compare:CCC
13136
          (zero_extract:SI
13137
            (match_dup 1)
13138
            (const_int 1)
13139
            (match_dup 2))
13140
          (const_int 0)))
13141
   (set (pc)
13142
        (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13143
                      (label_ref (match_dup 3))
13144
                      (pc)))]
13145
{
13146
  operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13147
 
13148
  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13149
})
13150
 
13151
;; avoid useless masking of bit offset operand
13152
(define_insn_and_split "*jcc_btsi_mask_1"
13153
  [(set (pc)
13154
        (if_then_else
13155
          (match_operator 0 "bt_comparison_operator"
13156
            [(and:SI
13157
               (lshiftrt:SI
13158
                 (match_operand:SI 1 "register_operand" "r")
13159
                 (subreg:QI
13160
                   (and:SI
13161
                     (match_operand:SI 2 "register_operand" "r")
13162
                     (match_operand:SI 3 "const_int_operand" "n")) 0))
13163
               (const_int 1))
13164
             (const_int 0)])
13165
          (label_ref (match_operand 4 "" ""))
13166
          (pc)))
13167
   (clobber (reg:CC FLAGS_REG))]
13168
  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13169
   && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13170
  "#"
13171
  "&& 1"
13172
  [(set (reg:CCC FLAGS_REG)
13173
        (compare:CCC
13174
          (zero_extract:SI
13175
            (match_dup 1)
13176
            (const_int 1)
13177
            (match_dup 2))
13178
          (const_int 0)))
13179
   (set (pc)
13180
        (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13181
                      (label_ref (match_dup 4))
13182
                      (pc)))]
13183
  "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13184
 
13185
;; Define combination compare-and-branch fp compare instructions to help
13186
;; combine.
13187
 
13188
(define_insn "*fp_jcc_1_387"
13189
  [(set (pc)
13190
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13191
                        [(match_operand 1 "register_operand" "f")
13192
                         (match_operand 2 "nonimmediate_operand" "fm")])
13193
          (label_ref (match_operand 3 "" ""))
13194
          (pc)))
13195
   (clobber (reg:CCFP FPSR_REG))
13196
   (clobber (reg:CCFP FLAGS_REG))
13197
   (clobber (match_scratch:HI 4 "=a"))]
13198
  "TARGET_80387
13199
   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13200
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13201
   && SELECT_CC_MODE (GET_CODE (operands[0]),
13202
                      operands[1], operands[2]) == CCFPmode
13203
   && !TARGET_CMOVE"
13204
  "#")
13205
 
13206
(define_insn "*fp_jcc_1r_387"
13207
  [(set (pc)
13208
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13209
                        [(match_operand 1 "register_operand" "f")
13210
                         (match_operand 2 "nonimmediate_operand" "fm")])
13211
          (pc)
13212
          (label_ref (match_operand 3 "" ""))))
13213
   (clobber (reg:CCFP FPSR_REG))
13214
   (clobber (reg:CCFP FLAGS_REG))
13215
   (clobber (match_scratch:HI 4 "=a"))]
13216
  "TARGET_80387
13217
   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13218
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13219
   && SELECT_CC_MODE (GET_CODE (operands[0]),
13220
                      operands[1], operands[2]) == CCFPmode
13221
   && !TARGET_CMOVE"
13222
  "#")
13223
 
13224
(define_insn "*fp_jcc_2_387"
13225
  [(set (pc)
13226
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13227
                        [(match_operand 1 "register_operand" "f")
13228
                         (match_operand 2 "register_operand" "f")])
13229
          (label_ref (match_operand 3 "" ""))
13230
          (pc)))
13231
   (clobber (reg:CCFP FPSR_REG))
13232
   (clobber (reg:CCFP FLAGS_REG))
13233
   (clobber (match_scratch:HI 4 "=a"))]
13234
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13235
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13236
   && !TARGET_CMOVE"
13237
  "#")
13238
 
13239
(define_insn "*fp_jcc_2r_387"
13240
  [(set (pc)
13241
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13242
                        [(match_operand 1 "register_operand" "f")
13243
                         (match_operand 2 "register_operand" "f")])
13244
          (pc)
13245
          (label_ref (match_operand 3 "" ""))))
13246
   (clobber (reg:CCFP FPSR_REG))
13247
   (clobber (reg:CCFP FLAGS_REG))
13248
   (clobber (match_scratch:HI 4 "=a"))]
13249
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13250
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13251
   && !TARGET_CMOVE"
13252
  "#")
13253
 
13254
(define_insn "*fp_jcc_3_387"
13255
  [(set (pc)
13256
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13257
                        [(match_operand 1 "register_operand" "f")
13258
                         (match_operand 2 "const0_operand" "")])
13259
          (label_ref (match_operand 3 "" ""))
13260
          (pc)))
13261
   (clobber (reg:CCFP FPSR_REG))
13262
   (clobber (reg:CCFP FLAGS_REG))
13263
   (clobber (match_scratch:HI 4 "=a"))]
13264
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13265
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13266
   && SELECT_CC_MODE (GET_CODE (operands[0]),
13267
                      operands[1], operands[2]) == CCFPmode
13268
   && !TARGET_CMOVE"
13269
  "#")
13270
 
13271
(define_split
13272
  [(set (pc)
13273
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13274
                        [(match_operand 1 "register_operand" "")
13275
                         (match_operand 2 "nonimmediate_operand" "")])
13276
          (match_operand 3 "" "")
13277
          (match_operand 4 "" "")))
13278
   (clobber (reg:CCFP FPSR_REG))
13279
   (clobber (reg:CCFP FLAGS_REG))]
13280
  "reload_completed"
13281
  [(const_int 0)]
13282
{
13283
  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13284
                        operands[3], operands[4], NULL_RTX, NULL_RTX);
13285
  DONE;
13286
})
13287
 
13288
(define_split
13289
  [(set (pc)
13290
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13291
                        [(match_operand 1 "register_operand" "")
13292
                         (match_operand 2 "general_operand" "")])
13293
          (match_operand 3 "" "")
13294
          (match_operand 4 "" "")))
13295
   (clobber (reg:CCFP FPSR_REG))
13296
   (clobber (reg:CCFP FLAGS_REG))
13297
   (clobber (match_scratch:HI 5 "=a"))]
13298
  "reload_completed"
13299
  [(const_int 0)]
13300
{
13301
  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13302
                        operands[3], operands[4], operands[5], NULL_RTX);
13303
  DONE;
13304
})
13305
 
13306
;; The order of operands in *fp_jcc_4_387 is forced by combine in
13307
;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13308
;; with a precedence over other operators and is always put in the first
13309
;; place. Swap condition and operands to match ficom instruction.
13310
 
13311
(define_insn "*fp_jcc_4__387"
13312
  [(set (pc)
13313
        (if_then_else
13314
          (match_operator 0 "ix86_swapped_fp_comparison_operator"
13315
            [(match_operator 1 "float_operator"
13316
              [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13317
             (match_operand 3 "register_operand" "f,f")])
13318
          (label_ref (match_operand 4 "" ""))
13319
          (pc)))
13320
   (clobber (reg:CCFP FPSR_REG))
13321
   (clobber (reg:CCFP FLAGS_REG))
13322
   (clobber (match_scratch:HI 5 "=a,a"))]
13323
  "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13324
   && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))
13325
   && GET_MODE (operands[1]) == GET_MODE (operands[3])
13326
   && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13327
   && !TARGET_CMOVE"
13328
  "#")
13329
 
13330
(define_split
13331
  [(set (pc)
13332
        (if_then_else
13333
          (match_operator 0 "ix86_swapped_fp_comparison_operator"
13334
            [(match_operator 1 "float_operator"
13335
              [(match_operand:X87MODEI12 2 "memory_operand" "")])
13336
             (match_operand 3 "register_operand" "")])
13337
          (match_operand 4 "" "")
13338
          (match_operand 5 "" "")))
13339
   (clobber (reg:CCFP FPSR_REG))
13340
   (clobber (reg:CCFP FLAGS_REG))
13341
   (clobber (match_scratch:HI 6 "=a"))]
13342
  "reload_completed"
13343
  [(const_int 0)]
13344
{
13345
  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13346
  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13347
                        operands[3], operands[7],
13348
                        operands[4], operands[5], operands[6], NULL_RTX);
13349
  DONE;
13350
})
13351
 
13352
;; %%% Kill this when reload knows how to do it.
13353
(define_split
13354
  [(set (pc)
13355
        (if_then_else
13356
          (match_operator 0 "ix86_swapped_fp_comparison_operator"
13357
            [(match_operator 1 "float_operator"
13358
              [(match_operand:X87MODEI12 2 "register_operand" "")])
13359
             (match_operand 3 "register_operand" "")])
13360
          (match_operand 4 "" "")
13361
          (match_operand 5 "" "")))
13362
   (clobber (reg:CCFP FPSR_REG))
13363
   (clobber (reg:CCFP FLAGS_REG))
13364
   (clobber (match_scratch:HI 6 "=a"))]
13365
  "reload_completed"
13366
  [(const_int 0)]
13367
{
13368
  operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13369
  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13370
  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13371
                        operands[3], operands[7],
13372
                        operands[4], operands[5], operands[6], operands[2]);
13373
  DONE;
13374
})
13375
 
13376
;; Unconditional and other jump instructions
13377
 
13378
(define_insn "jump"
13379
  [(set (pc)
13380
        (label_ref (match_operand 0 "" "")))]
13381
  ""
13382
  "jmp\t%l0"
13383
  [(set_attr "type" "ibr")
13384
   (set (attr "length")
13385
           (if_then_else (and (ge (minus (match_dup 0) (pc))
13386
                                  (const_int -126))
13387
                              (lt (minus (match_dup 0) (pc))
13388
                                  (const_int 128)))
13389
             (const_int 2)
13390
             (const_int 5)))
13391
   (set_attr "modrm" "0")])
13392
 
13393
(define_expand "indirect_jump"
13394
  [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13395
  ""
13396
  "")
13397
 
13398
(define_insn "*indirect_jump"
13399
  [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
13400
  ""
13401
  "jmp\t%A0"
13402
  [(set_attr "type" "ibr")
13403
   (set_attr "length_immediate" "0")])
13404
 
13405
(define_expand "tablejump"
13406
  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
13407
              (use (label_ref (match_operand 1 "" "")))])]
13408
  ""
13409
{
13410
  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13411
     relative.  Convert the relative address to an absolute address.  */
13412
  if (flag_pic)
13413
    {
13414
      rtx op0, op1;
13415
      enum rtx_code code;
13416
 
13417
      /* We can't use @GOTOFF for text labels on VxWorks;
13418
         see gotoff_operand.  */
13419
      if (TARGET_64BIT || TARGET_VXWORKS_RTP)
13420
        {
13421
          code = PLUS;
13422
          op0 = operands[0];
13423
          op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13424
        }
13425
      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13426
        {
13427
          code = PLUS;
13428
          op0 = operands[0];
13429
          op1 = pic_offset_table_rtx;
13430
        }
13431
      else
13432
        {
13433
          code = MINUS;
13434
          op0 = pic_offset_table_rtx;
13435
          op1 = operands[0];
13436
        }
13437
 
13438
      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13439
                                         OPTAB_DIRECT);
13440
    }
13441
})
13442
 
13443
(define_insn "*tablejump_1"
13444
  [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
13445
   (use (label_ref (match_operand 1 "" "")))]
13446
  ""
13447
  "jmp\t%A0"
13448
  [(set_attr "type" "ibr")
13449
   (set_attr "length_immediate" "0")])
13450
 
13451
;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13452
 
13453
(define_peephole2
13454
  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13455
   (set (match_operand:QI 1 "register_operand" "")
13456
        (match_operator:QI 2 "ix86_comparison_operator"
13457
          [(reg FLAGS_REG) (const_int 0)]))
13458
   (set (match_operand 3 "q_regs_operand" "")
13459
        (zero_extend (match_dup 1)))]
13460
  "(peep2_reg_dead_p (3, operands[1])
13461
    || operands_match_p (operands[1], operands[3]))
13462
   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13463
  [(set (match_dup 4) (match_dup 0))
13464
   (set (strict_low_part (match_dup 5))
13465
        (match_dup 2))]
13466
{
13467
  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13468
  operands[5] = gen_lowpart (QImode, operands[3]);
13469
  ix86_expand_clear (operands[3]);
13470
})
13471
 
13472
;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13473
 
13474
(define_peephole2
13475
  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13476
   (set (match_operand:QI 1 "register_operand" "")
13477
        (match_operator:QI 2 "ix86_comparison_operator"
13478
          [(reg FLAGS_REG) (const_int 0)]))
13479
   (parallel [(set (match_operand 3 "q_regs_operand" "")
13480
                   (zero_extend (match_dup 1)))
13481
              (clobber (reg:CC FLAGS_REG))])]
13482
  "(peep2_reg_dead_p (3, operands[1])
13483
    || operands_match_p (operands[1], operands[3]))
13484
   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13485
  [(set (match_dup 4) (match_dup 0))
13486
   (set (strict_low_part (match_dup 5))
13487
        (match_dup 2))]
13488
{
13489
  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13490
  operands[5] = gen_lowpart (QImode, operands[3]);
13491
  ix86_expand_clear (operands[3]);
13492
})
13493
 
13494
;; Call instructions.
13495
 
13496
;; The predicates normally associated with named expanders are not properly
13497
;; checked for calls.  This is a bug in the generic code, but it isn't that
13498
;; easy to fix.  Ignore it for now and be prepared to fix things up.
13499
 
13500
;; P6 processors will jump to the address after the decrement when %esp
13501
;; is used as a call operand, so they will execute return address as a code.
13502
;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
13503
 
13504
;; Call subroutine returning no value.
13505
 
13506
(define_expand "call_pop"
13507
  [(parallel [(call (match_operand:QI 0 "" "")
13508
                    (match_operand:SI 1 "" ""))
13509
              (set (reg:SI SP_REG)
13510
                   (plus:SI (reg:SI SP_REG)
13511
                            (match_operand:SI 3 "" "")))])]
13512
  "!TARGET_64BIT"
13513
{
13514
  ix86_expand_call (NULL, operands[0], operands[1],
13515
                    operands[2], operands[3], 0);
13516
  DONE;
13517
})
13518
 
13519
(define_insn "*call_pop_0"
13520
  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13521
         (match_operand:SI 1 "" ""))
13522
   (set (reg:SI SP_REG)
13523
        (plus:SI (reg:SI SP_REG)
13524
                 (match_operand:SI 2 "immediate_operand" "")))]
13525
  "!TARGET_64BIT"
13526
{
13527
  if (SIBLING_CALL_P (insn))
13528
    return "jmp\t%P0";
13529
  else
13530
    return "call\t%P0";
13531
}
13532
  [(set_attr "type" "call")])
13533
 
13534
(define_insn "*call_pop_1"
13535
  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13536
         (match_operand:SI 1 "" ""))
13537
   (set (reg:SI SP_REG)
13538
        (plus:SI (reg:SI SP_REG)
13539
                 (match_operand:SI 2 "immediate_operand" "i")))]
13540
  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13541
{
13542
  if (constant_call_address_operand (operands[0], Pmode))
13543
    return "call\t%P0";
13544
  return "call\t%A0";
13545
}
13546
  [(set_attr "type" "call")])
13547
 
13548
(define_insn "*sibcall_pop_1"
13549
  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13550
         (match_operand:SI 1 "" ""))
13551
   (set (reg:SI SP_REG)
13552
        (plus:SI (reg:SI SP_REG)
13553
                 (match_operand:SI 2 "immediate_operand" "i,i")))]
13554
  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13555
  "@
13556
   jmp\t%P0
13557
   jmp\t%A0"
13558
  [(set_attr "type" "call")])
13559
 
13560
(define_expand "call"
13561
  [(call (match_operand:QI 0 "" "")
13562
         (match_operand 1 "" ""))
13563
   (use (match_operand 2 "" ""))]
13564
  ""
13565
{
13566
  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13567
  DONE;
13568
})
13569
 
13570
(define_expand "sibcall"
13571
  [(call (match_operand:QI 0 "" "")
13572
         (match_operand 1 "" ""))
13573
   (use (match_operand 2 "" ""))]
13574
  ""
13575
{
13576
  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13577
  DONE;
13578
})
13579
 
13580
(define_insn "*call_0"
13581
  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13582
         (match_operand 1 "" ""))]
13583
  ""
13584
{
13585
  if (SIBLING_CALL_P (insn))
13586
    return "jmp\t%P0";
13587
  else
13588
    return "call\t%P0";
13589
}
13590
  [(set_attr "type" "call")])
13591
 
13592
(define_insn "*call_1"
13593
  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13594
         (match_operand 1 "" ""))]
13595
  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13596
{
13597
  if (constant_call_address_operand (operands[0], Pmode))
13598
    return "call\t%P0";
13599
  return "call\t%A0";
13600
}
13601
  [(set_attr "type" "call")])
13602
 
13603
(define_insn "*sibcall_1"
13604
  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13605
         (match_operand 1 "" ""))]
13606
  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13607
  "@
13608
   jmp\t%P0
13609
   jmp\t%A0"
13610
  [(set_attr "type" "call")])
13611
 
13612
(define_insn "*call_1_rex64"
13613
  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13614
         (match_operand 1 "" ""))]
13615
  "TARGET_64BIT && !SIBLING_CALL_P (insn)
13616
   && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
13617
{
13618
  if (constant_call_address_operand (operands[0], Pmode))
13619
    return "call\t%P0";
13620
  return "call\t%A0";
13621
}
13622
  [(set_attr "type" "call")])
13623
 
13624
(define_insn "*call_1_rex64_ms_sysv"
13625
  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13626
         (match_operand 1 "" ""))
13627
   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
13628
   (clobber (reg:TI XMM6_REG))
13629
   (clobber (reg:TI XMM7_REG))
13630
   (clobber (reg:TI XMM8_REG))
13631
   (clobber (reg:TI XMM9_REG))
13632
   (clobber (reg:TI XMM10_REG))
13633
   (clobber (reg:TI XMM11_REG))
13634
   (clobber (reg:TI XMM12_REG))
13635
   (clobber (reg:TI XMM13_REG))
13636
   (clobber (reg:TI XMM14_REG))
13637
   (clobber (reg:TI XMM15_REG))
13638
   (clobber (reg:DI SI_REG))
13639
   (clobber (reg:DI DI_REG))]
13640
  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13641
{
13642
  if (constant_call_address_operand (operands[0], Pmode))
13643
    return "call\t%P0";
13644
  return "call\t%A0";
13645
}
13646
  [(set_attr "type" "call")])
13647
 
13648
(define_insn "*call_1_rex64_large"
13649
  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
13650
         (match_operand 1 "" ""))]
13651
  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13652
  "call\t%A0"
13653
  [(set_attr "type" "call")])
13654
 
13655
(define_insn "*sibcall_1_rex64"
13656
  [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
13657
         (match_operand 1 "" ""))]
13658
  "TARGET_64BIT && SIBLING_CALL_P (insn)"
13659
  "@
13660
   jmp\t%P0
13661
   jmp\t%A0"
13662
  [(set_attr "type" "call")])
13663
 
13664
;; Call subroutine, returning value in operand 0
13665
(define_expand "call_value_pop"
13666
  [(parallel [(set (match_operand 0 "" "")
13667
                   (call (match_operand:QI 1 "" "")
13668
                         (match_operand:SI 2 "" "")))
13669
              (set (reg:SI SP_REG)
13670
                   (plus:SI (reg:SI SP_REG)
13671
                            (match_operand:SI 4 "" "")))])]
13672
  "!TARGET_64BIT"
13673
{
13674
  ix86_expand_call (operands[0], operands[1], operands[2],
13675
                    operands[3], operands[4], 0);
13676
  DONE;
13677
})
13678
 
13679
(define_expand "call_value"
13680
  [(set (match_operand 0 "" "")
13681
        (call (match_operand:QI 1 "" "")
13682
              (match_operand:SI 2 "" "")))
13683
   (use (match_operand:SI 3 "" ""))]
13684
  ;; Operand 3 is not used on the i386.
13685
  ""
13686
{
13687
  ix86_expand_call (operands[0], operands[1], operands[2],
13688
                    operands[3], NULL, 0);
13689
  DONE;
13690
})
13691
 
13692
(define_expand "sibcall_value"
13693
  [(set (match_operand 0 "" "")
13694
        (call (match_operand:QI 1 "" "")
13695
              (match_operand:SI 2 "" "")))
13696
   (use (match_operand:SI 3 "" ""))]
13697
  ;; Operand 3 is not used on the i386.
13698
  ""
13699
{
13700
  ix86_expand_call (operands[0], operands[1], operands[2],
13701
                    operands[3], NULL, 1);
13702
  DONE;
13703
})
13704
 
13705
;; Call subroutine returning any type.
13706
 
13707
(define_expand "untyped_call"
13708
  [(parallel [(call (match_operand 0 "" "")
13709
                    (const_int 0))
13710
              (match_operand 1 "" "")
13711
              (match_operand 2 "" "")])]
13712
  ""
13713
{
13714
  int i;
13715
 
13716
  /* In order to give reg-stack an easier job in validating two
13717
     coprocessor registers as containing a possible return value,
13718
     simply pretend the untyped call returns a complex long double
13719
     value.
13720
 
13721
     We can't use SSE_REGPARM_MAX here since callee is unprototyped
13722
     and should have the default ABI.  */
13723
 
13724
  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13725
                     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13726
                    operands[0], const0_rtx,
13727
                    GEN_INT ((TARGET_64BIT
13728
                              ? (ix86_abi == SYSV_ABI
13729
                                 ? X86_64_SSE_REGPARM_MAX
13730
                                 : X86_64_MS_SSE_REGPARM_MAX)
13731
                              : X86_32_SSE_REGPARM_MAX)
13732
                             - 1),
13733
                    NULL, 0);
13734
 
13735
  for (i = 0; i < XVECLEN (operands[2], 0); i++)
13736
    {
13737
      rtx set = XVECEXP (operands[2], 0, i);
13738
      emit_move_insn (SET_DEST (set), SET_SRC (set));
13739
    }
13740
 
13741
  /* The optimizer does not know that the call sets the function value
13742
     registers we stored in the result block.  We avoid problems by
13743
     claiming that all hard registers are used and clobbered at this
13744
     point.  */
13745
  emit_insn (gen_blockage ());
13746
 
13747
  DONE;
13748
})
13749
 
13750
;; Prologue and epilogue instructions
13751
 
13752
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13753
;; all of memory.  This blocks insns from being moved across this point.
13754
 
13755
(define_insn "blockage"
13756
  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13757
  ""
13758
  ""
13759
  [(set_attr "length" "0")])
13760
 
13761
;; Do not schedule instructions accessing memory across this point.
13762
 
13763
(define_expand "memory_blockage"
13764
  [(set (match_dup 0)
13765
        (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13766
  ""
13767
{
13768
  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13769
  MEM_VOLATILE_P (operands[0]) = 1;
13770
})
13771
 
13772
(define_insn "*memory_blockage"
13773
  [(set (match_operand:BLK 0 "" "")
13774
        (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13775
  ""
13776
  ""
13777
  [(set_attr "length" "0")])
13778
 
13779
;; As USE insns aren't meaningful after reload, this is used instead
13780
;; to prevent deleting instructions setting registers for PIC code
13781
(define_insn "prologue_use"
13782
  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
13783
  ""
13784
  ""
13785
  [(set_attr "length" "0")])
13786
 
13787
;; Insn emitted into the body of a function to return from a function.
13788
;; This is only done if the function's epilogue is known to be simple.
13789
;; See comments for ix86_can_use_return_insn_p in i386.c.
13790
 
13791
(define_expand "return"
13792
  [(return)]
13793
  "ix86_can_use_return_insn_p ()"
13794
{
13795
  if (crtl->args.pops_args)
13796
    {
13797
      rtx popc = GEN_INT (crtl->args.pops_args);
13798
      emit_jump_insn (gen_return_pop_internal (popc));
13799
      DONE;
13800
    }
13801
})
13802
 
13803
(define_insn "return_internal"
13804
  [(return)]
13805
  "reload_completed"
13806
  "ret"
13807
  [(set_attr "length" "1")
13808
   (set_attr "atom_unit" "jeu")
13809
   (set_attr "length_immediate" "0")
13810
   (set_attr "modrm" "0")])
13811
 
13812
;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13813
;; instruction Athlon and K8 have.
13814
 
13815
(define_insn "return_internal_long"
13816
  [(return)
13817
   (unspec [(const_int 0)] UNSPEC_REP)]
13818
  "reload_completed"
13819
  "rep\;ret"
13820
  [(set_attr "length" "2")
13821
   (set_attr "atom_unit" "jeu")
13822
   (set_attr "length_immediate" "0")
13823
   (set_attr "prefix_rep" "1")
13824
   (set_attr "modrm" "0")])
13825
 
13826
(define_insn "return_pop_internal"
13827
  [(return)
13828
   (use (match_operand:SI 0 "const_int_operand" ""))]
13829
  "reload_completed"
13830
  "ret\t%0"
13831
  [(set_attr "length" "3")
13832
   (set_attr "atom_unit" "jeu")
13833
   (set_attr "length_immediate" "2")
13834
   (set_attr "modrm" "0")])
13835
 
13836
(define_insn "return_indirect_internal"
13837
  [(return)
13838
   (use (match_operand:SI 0 "register_operand" "r"))]
13839
  "reload_completed"
13840
  "jmp\t%A0"
13841
  [(set_attr "type" "ibr")
13842
   (set_attr "length_immediate" "0")])
13843
 
13844
(define_insn "nop"
13845
  [(const_int 0)]
13846
  ""
13847
  "nop"
13848
  [(set_attr "length" "1")
13849
   (set_attr "length_immediate" "0")
13850
   (set_attr "modrm" "0")])
13851
 
13852
(define_insn "vswapmov"
13853
  [(set (match_operand:SI 0 "register_operand" "=r")
13854
        (match_operand:SI 1 "register_operand" "r"))
13855
   (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
13856
  ""
13857
  "movl.s\t{%1, %0|%0, %1}"
13858
  [(set_attr "length" "2")
13859
   (set_attr "length_immediate" "0")
13860
   (set_attr "modrm" "0")])
13861
 
13862
;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
13863
;; branch prediction penalty for the third jump in a 16-byte
13864
;; block on K8.
13865
 
13866
(define_insn "pad"
13867
  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13868
  ""
13869
{
13870
#ifdef ASM_OUTPUT_MAX_SKIP_PAD
13871
  ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13872
#else
13873
  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13874
     The align insn is used to avoid 3 jump instructions in the row to improve
13875
     branch prediction and the benefits hardly outweigh the cost of extra 8
13876
     nops on the average inserted by full alignment pseudo operation.  */
13877
#endif
13878
  return "";
13879
}
13880
  [(set_attr "length" "16")])
13881
 
13882
(define_expand "prologue"
13883
  [(const_int 0)]
13884
  ""
13885
  "ix86_expand_prologue (); DONE;")
13886
 
13887
(define_insn "set_got"
13888
  [(set (match_operand:SI 0 "register_operand" "=r")
13889
        (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13890
   (clobber (reg:CC FLAGS_REG))]
13891
  "!TARGET_64BIT"
13892
  { return output_set_got (operands[0], NULL_RTX); }
13893
  [(set_attr "type" "multi")
13894
   (set_attr "length" "12")])
13895
 
13896
(define_insn "set_got_labelled"
13897
  [(set (match_operand:SI 0 "register_operand" "=r")
13898
        (unspec:SI [(label_ref (match_operand 1 "" ""))]
13899
         UNSPEC_SET_GOT))
13900
   (clobber (reg:CC FLAGS_REG))]
13901
  "!TARGET_64BIT"
13902
  { return output_set_got (operands[0], operands[1]); }
13903
  [(set_attr "type" "multi")
13904
   (set_attr "length" "12")])
13905
 
13906
(define_insn "set_got_rex64"
13907
  [(set (match_operand:DI 0 "register_operand" "=r")
13908
        (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13909
  "TARGET_64BIT"
13910
  "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13911
  [(set_attr "type" "lea")
13912
   (set_attr "length_address" "4")
13913
   (set_attr "mode" "DI")])
13914
 
13915
(define_insn "set_rip_rex64"
13916
  [(set (match_operand:DI 0 "register_operand" "=r")
13917
        (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
13918
  "TARGET_64BIT"
13919
  "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13920
  [(set_attr "type" "lea")
13921
   (set_attr "length_address" "4")
13922
   (set_attr "mode" "DI")])
13923
 
13924
(define_insn "set_got_offset_rex64"
13925
  [(set (match_operand:DI 0 "register_operand" "=r")
13926
        (unspec:DI
13927
          [(label_ref (match_operand 1 "" ""))]
13928
          UNSPEC_SET_GOT_OFFSET))]
13929
  "TARGET_64BIT"
13930
  "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13931
  [(set_attr "type" "imov")
13932
   (set_attr "length_immediate" "0")
13933
   (set_attr "length_address" "8")
13934
   (set_attr "mode" "DI")])
13935
 
13936
(define_expand "epilogue"
13937
  [(const_int 0)]
13938
  ""
13939
  "ix86_expand_epilogue (1); DONE;")
13940
 
13941
(define_expand "sibcall_epilogue"
13942
  [(const_int 0)]
13943
  ""
13944
  "ix86_expand_epilogue (0); DONE;")
13945
 
13946
(define_expand "eh_return"
13947
  [(use (match_operand 0 "register_operand" ""))]
13948
  ""
13949
{
13950
  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13951
 
13952
  /* Tricky bit: we write the address of the handler to which we will
13953
     be returning into someone else's stack frame, one word below the
13954
     stack address we wish to restore.  */
13955
  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13956
  tmp = plus_constant (tmp, -UNITS_PER_WORD);
13957
  tmp = gen_rtx_MEM (Pmode, tmp);
13958
  emit_move_insn (tmp, ra);
13959
 
13960
  emit_jump_insn (gen_eh_return_internal ());
13961
  emit_barrier ();
13962
  DONE;
13963
})
13964
 
13965
(define_insn_and_split "eh_return_internal"
13966
  [(eh_return)]
13967
  ""
13968
  "#"
13969
  "epilogue_completed"
13970
  [(const_int 0)]
13971
  "ix86_expand_epilogue (2); DONE;")
13972
 
13973
(define_insn "leave"
13974
  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13975
   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13976
   (clobber (mem:BLK (scratch)))]
13977
  "!TARGET_64BIT"
13978
  "leave"
13979
  [(set_attr "type" "leave")])
13980
 
13981
(define_insn "leave_rex64"
13982
  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13983
   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13984
   (clobber (mem:BLK (scratch)))]
13985
  "TARGET_64BIT"
13986
  "leave"
13987
  [(set_attr "type" "leave")])
13988
 
13989
(define_expand "ffssi2"
13990
  [(parallel
13991
     [(set (match_operand:SI 0 "register_operand" "")
13992
           (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13993
      (clobber (match_scratch:SI 2 ""))
13994
      (clobber (reg:CC FLAGS_REG))])]
13995
  ""
13996
{
13997
  if (TARGET_CMOVE)
13998
    {
13999
      emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14000
      DONE;
14001
    }
14002
})
14003
 
14004
(define_expand "ffs_cmove"
14005
  [(set (match_dup 2) (const_int -1))
14006
   (parallel [(set (reg:CCZ FLAGS_REG)
14007
                   (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14008
                                (const_int 0)))
14009
              (set (match_operand:SI 0 "register_operand" "")
14010
                   (ctz:SI (match_dup 1)))])
14011
   (set (match_dup 0) (if_then_else:SI
14012
                        (eq (reg:CCZ FLAGS_REG) (const_int 0))
14013
                        (match_dup 2)
14014
                        (match_dup 0)))
14015
   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14016
              (clobber (reg:CC FLAGS_REG))])]
14017
  "TARGET_CMOVE"
14018
  "operands[2] = gen_reg_rtx (SImode);")
14019
 
14020
(define_insn_and_split "*ffs_no_cmove"
14021
  [(set (match_operand:SI 0 "register_operand" "=r")
14022
        (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14023
   (clobber (match_scratch:SI 2 "=&q"))
14024
   (clobber (reg:CC FLAGS_REG))]
14025
  "!TARGET_CMOVE"
14026
  "#"
14027
  "&& reload_completed"
14028
  [(parallel [(set (reg:CCZ FLAGS_REG)
14029
                   (compare:CCZ (match_dup 1) (const_int 0)))
14030
              (set (match_dup 0) (ctz:SI (match_dup 1)))])
14031
   (set (strict_low_part (match_dup 3))
14032
        (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14033
   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14034
              (clobber (reg:CC FLAGS_REG))])
14035
   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14036
              (clobber (reg:CC FLAGS_REG))])
14037
   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14038
              (clobber (reg:CC FLAGS_REG))])]
14039
{
14040
  operands[3] = gen_lowpart (QImode, operands[2]);
14041
  ix86_expand_clear (operands[2]);
14042
})
14043
 
14044
(define_insn "*ffssi_1"
14045
  [(set (reg:CCZ FLAGS_REG)
14046
        (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14047
                     (const_int 0)))
14048
   (set (match_operand:SI 0 "register_operand" "=r")
14049
        (ctz:SI (match_dup 1)))]
14050
  ""
14051
  "bsf{l}\t{%1, %0|%0, %1}"
14052
  [(set_attr "type" "alu1")
14053
   (set_attr "prefix_0f" "1")
14054
   (set_attr "mode" "SI")])
14055
 
14056
(define_expand "ffsdi2"
14057
  [(set (match_dup 2) (const_int -1))
14058
   (parallel [(set (reg:CCZ FLAGS_REG)
14059
                   (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14060
                                (const_int 0)))
14061
              (set (match_operand:DI 0 "register_operand" "")
14062
                   (ctz:DI (match_dup 1)))])
14063
   (set (match_dup 0) (if_then_else:DI
14064
                        (eq (reg:CCZ FLAGS_REG) (const_int 0))
14065
                        (match_dup 2)
14066
                        (match_dup 0)))
14067
   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14068
              (clobber (reg:CC FLAGS_REG))])]
14069
  "TARGET_64BIT"
14070
  "operands[2] = gen_reg_rtx (DImode);")
14071
 
14072
(define_insn "*ffsdi_1"
14073
  [(set (reg:CCZ FLAGS_REG)
14074
        (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14075
                     (const_int 0)))
14076
   (set (match_operand:DI 0 "register_operand" "=r")
14077
        (ctz:DI (match_dup 1)))]
14078
  "TARGET_64BIT"
14079
  "bsf{q}\t{%1, %0|%0, %1}"
14080
  [(set_attr "type" "alu1")
14081
   (set_attr "prefix_0f" "1")
14082
   (set_attr "mode" "DI")])
14083
 
14084
(define_insn "ctzsi2"
14085
  [(set (match_operand:SI 0 "register_operand" "=r")
14086
        (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14087
   (clobber (reg:CC FLAGS_REG))]
14088
  ""
14089
  "bsf{l}\t{%1, %0|%0, %1}"
14090
  [(set_attr "type" "alu1")
14091
   (set_attr "prefix_0f" "1")
14092
   (set_attr "mode" "SI")])
14093
 
14094
(define_insn "ctzdi2"
14095
  [(set (match_operand:DI 0 "register_operand" "=r")
14096
        (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14097
   (clobber (reg:CC FLAGS_REG))]
14098
  "TARGET_64BIT"
14099
  "bsf{q}\t{%1, %0|%0, %1}"
14100
  [(set_attr "type" "alu1")
14101
   (set_attr "prefix_0f" "1")
14102
   (set_attr "mode" "DI")])
14103
 
14104
(define_expand "clzsi2"
14105
  [(parallel
14106
     [(set (match_operand:SI 0 "register_operand" "")
14107
           (minus:SI (const_int 31)
14108
                     (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14109
      (clobber (reg:CC FLAGS_REG))])
14110
   (parallel
14111
     [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14112
      (clobber (reg:CC FLAGS_REG))])]
14113
  ""
14114
{
14115
  if (TARGET_ABM)
14116
    {
14117
      emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14118
      DONE;
14119
    }
14120
})
14121
 
14122
(define_insn "clzsi2_abm"
14123
  [(set (match_operand:SI 0 "register_operand" "=r")
14124
        (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14125
   (clobber (reg:CC FLAGS_REG))]
14126
  "TARGET_ABM"
14127
  "lzcnt{l}\t{%1, %0|%0, %1}"
14128
  [(set_attr "prefix_rep" "1")
14129
   (set_attr "type" "bitmanip")
14130
   (set_attr "mode" "SI")])
14131
 
14132
(define_insn "bsr"
14133
  [(set (match_operand:SI 0 "register_operand" "=r")
14134
        (minus:SI (const_int 31)
14135
                  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14136
   (clobber (reg:CC FLAGS_REG))]
14137
  ""
14138
  "bsr{l}\t{%1, %0|%0, %1}"
14139
  [(set_attr "type" "alu1")
14140
   (set_attr "prefix_0f" "1")
14141
   (set_attr "mode" "SI")])
14142
 
14143
(define_insn "popcount2"
14144
  [(set (match_operand:SWI248 0 "register_operand" "=r")
14145
        (popcount:SWI248
14146
          (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14147
   (clobber (reg:CC FLAGS_REG))]
14148
  "TARGET_POPCNT"
14149
{
14150
#if TARGET_MACHO
14151
  return "popcnt\t{%1, %0|%0, %1}";
14152
#else
14153
  return "popcnt{}\t{%1, %0|%0, %1}";
14154
#endif
14155
}
14156
  [(set_attr "prefix_rep" "1")
14157
   (set_attr "type" "bitmanip")
14158
   (set_attr "mode" "")])
14159
 
14160
(define_insn "*popcount2_cmp"
14161
  [(set (reg FLAGS_REG)
14162
        (compare
14163
          (popcount:SWI248
14164
            (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14165
          (const_int 0)))
14166
   (set (match_operand:SWI248 0 "register_operand" "=r")
14167
        (popcount:SWI248 (match_dup 1)))]
14168
  "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14169
{
14170
#if TARGET_MACHO
14171
  return "popcnt\t{%1, %0|%0, %1}";
14172
#else
14173
  return "popcnt{}\t{%1, %0|%0, %1}";
14174
#endif
14175
}
14176
  [(set_attr "prefix_rep" "1")
14177
   (set_attr "type" "bitmanip")
14178
   (set_attr "mode" "")])
14179
 
14180
(define_insn "*popcountsi2_cmp_zext"
14181
  [(set (reg FLAGS_REG)
14182
        (compare
14183
          (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14184
          (const_int 0)))
14185
   (set (match_operand:DI 0 "register_operand" "=r")
14186
        (zero_extend:DI (popcount:SI (match_dup 1))))]
14187
  "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14188
{
14189
#if TARGET_MACHO
14190
  return "popcnt\t{%1, %0|%0, %1}";
14191
#else
14192
  return "popcnt{l}\t{%1, %0|%0, %1}";
14193
#endif
14194
}
14195
  [(set_attr "prefix_rep" "1")
14196
   (set_attr "type" "bitmanip")
14197
   (set_attr "mode" "SI")])
14198
 
14199
(define_expand "bswapsi2"
14200
  [(set (match_operand:SI 0 "register_operand" "")
14201
        (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14202
  ""
14203
{
14204
  if (!(TARGET_BSWAP || TARGET_MOVBE))
14205
    {
14206
      rtx x = operands[0];
14207
 
14208
      emit_move_insn (x, operands[1]);
14209
      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14210
      emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14211
      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14212
      DONE;
14213
    }
14214
})
14215
 
14216
(define_insn "*bswapsi_movbe"
14217
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14218
        (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14219
  "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14220
  "@
14221
    bswap\t%0
14222
    movbe\t{%1, %0|%0, %1}
14223
    movbe\t{%1, %0|%0, %1}"
14224
  [(set_attr "type" "*,imov,imov")
14225
   (set_attr "modrm" "*,1,1")
14226
   (set_attr "prefix_0f" "1")
14227
   (set_attr "prefix_extra" "*,1,1")
14228
   (set_attr "length" "2,*,*")
14229
   (set_attr "mode" "SI")])
14230
 
14231
(define_insn "*bswapsi_1"
14232
  [(set (match_operand:SI 0 "register_operand" "=r")
14233
        (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14234
  "TARGET_BSWAP"
14235
  "bswap\t%0"
14236
  [(set_attr "prefix_0f" "1")
14237
   (set_attr "length" "2")])
14238
 
14239
(define_insn "*bswaphi_lowpart_1"
14240
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14241
        (bswap:HI (match_dup 0)))
14242
   (clobber (reg:CC FLAGS_REG))]
14243
  "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14244
  "@
14245
    xchg{b}\t{%h0, %b0|%b0, %h0}
14246
    rol{w}\t{$8, %0|%0, 8}"
14247
  [(set_attr "length" "2,4")
14248
   (set_attr "mode" "QI,HI")])
14249
 
14250
(define_insn "bswaphi_lowpart"
14251
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14252
        (bswap:HI (match_dup 0)))
14253
   (clobber (reg:CC FLAGS_REG))]
14254
  ""
14255
  "rol{w}\t{$8, %0|%0, 8}"
14256
  [(set_attr "length" "4")
14257
   (set_attr "mode" "HI")])
14258
 
14259
(define_expand "bswapdi2"
14260
  [(set (match_operand:DI 0 "register_operand" "")
14261
        (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14262
  "TARGET_64BIT"
14263
  "")
14264
 
14265
(define_insn "*bswapdi_movbe"
14266
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14267
        (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14268
  "TARGET_64BIT && TARGET_MOVBE
14269
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14270
  "@
14271
    bswap\t%0
14272
    movbe\t{%1, %0|%0, %1}
14273
    movbe\t{%1, %0|%0, %1}"
14274
  [(set_attr "type" "*,imov,imov")
14275
   (set_attr "modrm" "*,1,1")
14276
   (set_attr "prefix_0f" "1")
14277
   (set_attr "prefix_extra" "*,1,1")
14278
   (set_attr "length" "3,*,*")
14279
   (set_attr "mode" "DI")])
14280
 
14281
(define_insn "*bswapdi_1"
14282
  [(set (match_operand:DI 0 "register_operand" "=r")
14283
        (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14284
  "TARGET_64BIT"
14285
  "bswap\t%0"
14286
  [(set_attr "prefix_0f" "1")
14287
   (set_attr "length" "3")])
14288
 
14289
(define_expand "clzdi2"
14290
  [(parallel
14291
     [(set (match_operand:DI 0 "register_operand" "")
14292
           (minus:DI (const_int 63)
14293
                     (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14294
      (clobber (reg:CC FLAGS_REG))])
14295
   (parallel
14296
     [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14297
      (clobber (reg:CC FLAGS_REG))])]
14298
  "TARGET_64BIT"
14299
{
14300
  if (TARGET_ABM)
14301
    {
14302
      emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14303
      DONE;
14304
    }
14305
})
14306
 
14307
(define_insn "clzdi2_abm"
14308
  [(set (match_operand:DI 0 "register_operand" "=r")
14309
        (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14310
   (clobber (reg:CC FLAGS_REG))]
14311
  "TARGET_64BIT && TARGET_ABM"
14312
  "lzcnt{q}\t{%1, %0|%0, %1}"
14313
  [(set_attr "prefix_rep" "1")
14314
   (set_attr "type" "bitmanip")
14315
   (set_attr "mode" "DI")])
14316
 
14317
(define_insn "bsr_rex64"
14318
  [(set (match_operand:DI 0 "register_operand" "=r")
14319
        (minus:DI (const_int 63)
14320
                  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14321
   (clobber (reg:CC FLAGS_REG))]
14322
  "TARGET_64BIT"
14323
  "bsr{q}\t{%1, %0|%0, %1}"
14324
  [(set_attr "type" "alu1")
14325
   (set_attr "prefix_0f" "1")
14326
   (set_attr "mode" "DI")])
14327
 
14328
(define_expand "clzhi2"
14329
  [(parallel
14330
     [(set (match_operand:HI 0 "register_operand" "")
14331
           (minus:HI (const_int 15)
14332
                     (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14333
      (clobber (reg:CC FLAGS_REG))])
14334
   (parallel
14335
     [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14336
      (clobber (reg:CC FLAGS_REG))])]
14337
  ""
14338
{
14339
  if (TARGET_ABM)
14340
    {
14341
      emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14342
      DONE;
14343
    }
14344
})
14345
 
14346
(define_insn "clzhi2_abm"
14347
  [(set (match_operand:HI 0 "register_operand" "=r")
14348
        (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14349
   (clobber (reg:CC FLAGS_REG))]
14350
  "TARGET_ABM"
14351
  "lzcnt{w}\t{%1, %0|%0, %1}"
14352
  [(set_attr "prefix_rep" "1")
14353
   (set_attr "type" "bitmanip")
14354
   (set_attr "mode" "HI")])
14355
 
14356
(define_insn "*bsrhi"
14357
  [(set (match_operand:HI 0 "register_operand" "=r")
14358
        (minus:HI (const_int 15)
14359
                  (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14360
   (clobber (reg:CC FLAGS_REG))]
14361
  ""
14362
  "bsr{w}\t{%1, %0|%0, %1}"
14363
  [(set_attr "type" "alu1")
14364
   (set_attr "prefix_0f" "1")
14365
   (set_attr "mode" "HI")])
14366
 
14367
(define_expand "paritydi2"
14368
  [(set (match_operand:DI 0 "register_operand" "")
14369
        (parity:DI (match_operand:DI 1 "register_operand" "")))]
14370
  "! TARGET_POPCNT"
14371
{
14372
  rtx scratch = gen_reg_rtx (QImode);
14373
  rtx cond;
14374
 
14375
  emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14376
                                NULL_RTX, operands[1]));
14377
 
14378
  cond = gen_rtx_fmt_ee (ORDERED, QImode,
14379
                         gen_rtx_REG (CCmode, FLAGS_REG),
14380
                         const0_rtx);
14381
  emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14382
 
14383
  if (TARGET_64BIT)
14384
    emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14385
  else
14386
    {
14387
      rtx tmp = gen_reg_rtx (SImode);
14388
 
14389
      emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14390
      emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14391
    }
14392
  DONE;
14393
})
14394
 
14395
(define_insn_and_split "paritydi2_cmp"
14396
  [(set (reg:CC FLAGS_REG)
14397
        (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14398
                   UNSPEC_PARITY))
14399
   (clobber (match_scratch:DI 0 "=r"))
14400
   (clobber (match_scratch:SI 1 "=&r"))
14401
   (clobber (match_scratch:HI 2 "=Q"))]
14402
  "! TARGET_POPCNT"
14403
  "#"
14404
  "&& reload_completed"
14405
  [(parallel
14406
     [(set (match_dup 1)
14407
           (xor:SI (match_dup 1) (match_dup 4)))
14408
      (clobber (reg:CC FLAGS_REG))])
14409
   (parallel
14410
     [(set (reg:CC FLAGS_REG)
14411
           (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14412
      (clobber (match_dup 1))
14413
      (clobber (match_dup 2))])]
14414
{
14415
  operands[4] = gen_lowpart (SImode, operands[3]);
14416
 
14417
  if (TARGET_64BIT)
14418
    {
14419
      emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14420
      emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14421
    }
14422
  else
14423
    operands[1] = gen_highpart (SImode, operands[3]);
14424
})
14425
 
14426
(define_expand "paritysi2"
14427
  [(set (match_operand:SI 0 "register_operand" "")
14428
        (parity:SI (match_operand:SI 1 "register_operand" "")))]
14429
  "! TARGET_POPCNT"
14430
{
14431
  rtx scratch = gen_reg_rtx (QImode);
14432
  rtx cond;
14433
 
14434
  emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14435
 
14436
  cond = gen_rtx_fmt_ee (ORDERED, QImode,
14437
                         gen_rtx_REG (CCmode, FLAGS_REG),
14438
                         const0_rtx);
14439
  emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14440
 
14441
  emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14442
  DONE;
14443
})
14444
 
14445
(define_insn_and_split "paritysi2_cmp"
14446
  [(set (reg:CC FLAGS_REG)
14447
        (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14448
                   UNSPEC_PARITY))
14449
   (clobber (match_scratch:SI 0 "=r"))
14450
   (clobber (match_scratch:HI 1 "=&Q"))]
14451
  "! TARGET_POPCNT"
14452
  "#"
14453
  "&& reload_completed"
14454
  [(parallel
14455
     [(set (match_dup 1)
14456
           (xor:HI (match_dup 1) (match_dup 3)))
14457
      (clobber (reg:CC FLAGS_REG))])
14458
   (parallel
14459
     [(set (reg:CC FLAGS_REG)
14460
           (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14461
      (clobber (match_dup 1))])]
14462
{
14463
  operands[3] = gen_lowpart (HImode, operands[2]);
14464
 
14465
  emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14466
  emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14467
})
14468
 
14469
(define_insn "*parityhi2_cmp"
14470
  [(set (reg:CC FLAGS_REG)
14471
        (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14472
                   UNSPEC_PARITY))
14473
   (clobber (match_scratch:HI 0 "=Q"))]
14474
  "! TARGET_POPCNT"
14475
  "xor{b}\t{%h0, %b0|%b0, %h0}"
14476
  [(set_attr "length" "2")
14477
   (set_attr "mode" "HI")])
14478
 
14479
;; Thread-local storage patterns for ELF.
14480
;;
14481
;; Note that these code sequences must appear exactly as shown
14482
;; in order to allow linker relaxation.
14483
 
14484
(define_insn "*tls_global_dynamic_32_gnu"
14485
  [(set (match_operand:SI 0 "register_operand" "=a")
14486
        (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14487
                    (match_operand:SI 2 "tls_symbolic_operand" "")
14488
                    (match_operand:SI 3 "call_insn_operand" "")]
14489
                    UNSPEC_TLS_GD))
14490
   (clobber (match_scratch:SI 4 "=d"))
14491
   (clobber (match_scratch:SI 5 "=c"))
14492
   (clobber (reg:CC FLAGS_REG))]
14493
  "!TARGET_64BIT && TARGET_GNU_TLS"
14494
  "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
14495
  [(set_attr "type" "multi")
14496
   (set_attr "length" "12")])
14497
 
14498
(define_expand "tls_global_dynamic_32"
14499
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14500
                   (unspec:SI
14501
                    [(match_dup 2)
14502
                     (match_operand:SI 1 "tls_symbolic_operand" "")
14503
                     (match_dup 3)]
14504
                    UNSPEC_TLS_GD))
14505
              (clobber (match_scratch:SI 4 ""))
14506
              (clobber (match_scratch:SI 5 ""))
14507
              (clobber (reg:CC FLAGS_REG))])]
14508
  ""
14509
{
14510
  if (flag_pic)
14511
    operands[2] = pic_offset_table_rtx;
14512
  else
14513
    {
14514
      operands[2] = gen_reg_rtx (Pmode);
14515
      emit_insn (gen_set_got (operands[2]));
14516
    }
14517
  if (TARGET_GNU2_TLS)
14518
    {
14519
       emit_insn (gen_tls_dynamic_gnu2_32
14520
                  (operands[0], operands[1], operands[2]));
14521
       DONE;
14522
    }
14523
  operands[3] = ix86_tls_get_addr ();
14524
})
14525
 
14526
(define_insn "*tls_global_dynamic_64"
14527
  [(set (match_operand:DI 0 "register_operand" "=a")
14528
        (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14529
                 (match_operand:DI 3 "" "")))
14530
   (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14531
              UNSPEC_TLS_GD)]
14532
  "TARGET_64BIT"
14533
  { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
14534
  [(set_attr "type" "multi")
14535
   (set_attr "length" "16")])
14536
 
14537
(define_expand "tls_global_dynamic_64"
14538
  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14539
                   (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14540
              (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14541
                         UNSPEC_TLS_GD)])]
14542
  ""
14543
{
14544
  if (TARGET_GNU2_TLS)
14545
    {
14546
       emit_insn (gen_tls_dynamic_gnu2_64
14547
                  (operands[0], operands[1]));
14548
       DONE;
14549
    }
14550
  operands[2] = ix86_tls_get_addr ();
14551
})
14552
 
14553
(define_insn "*tls_local_dynamic_base_32_gnu"
14554
  [(set (match_operand:SI 0 "register_operand" "=a")
14555
        (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14556
                    (match_operand:SI 2 "call_insn_operand" "")]
14557
                   UNSPEC_TLS_LD_BASE))
14558
   (clobber (match_scratch:SI 3 "=d"))
14559
   (clobber (match_scratch:SI 4 "=c"))
14560
   (clobber (reg:CC FLAGS_REG))]
14561
  "!TARGET_64BIT && TARGET_GNU_TLS"
14562
  "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
14563
  [(set_attr "type" "multi")
14564
   (set_attr "length" "11")])
14565
 
14566
(define_expand "tls_local_dynamic_base_32"
14567
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14568
                   (unspec:SI [(match_dup 1) (match_dup 2)]
14569
                              UNSPEC_TLS_LD_BASE))
14570
              (clobber (match_scratch:SI 3 ""))
14571
              (clobber (match_scratch:SI 4 ""))
14572
              (clobber (reg:CC FLAGS_REG))])]
14573
  ""
14574
{
14575
  if (flag_pic)
14576
    operands[1] = pic_offset_table_rtx;
14577
  else
14578
    {
14579
      operands[1] = gen_reg_rtx (Pmode);
14580
      emit_insn (gen_set_got (operands[1]));
14581
    }
14582
  if (TARGET_GNU2_TLS)
14583
    {
14584
       emit_insn (gen_tls_dynamic_gnu2_32
14585
                  (operands[0], ix86_tls_module_base (), operands[1]));
14586
       DONE;
14587
    }
14588
  operands[2] = ix86_tls_get_addr ();
14589
})
14590
 
14591
(define_insn "*tls_local_dynamic_base_64"
14592
  [(set (match_operand:DI 0 "register_operand" "=a")
14593
        (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14594
                 (match_operand:DI 2 "" "")))
14595
   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14596
  "TARGET_64BIT"
14597
  "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
14598
  [(set_attr "type" "multi")
14599
   (set_attr "length" "12")])
14600
 
14601
(define_expand "tls_local_dynamic_base_64"
14602
  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14603
                   (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14604
              (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14605
  ""
14606
{
14607
  if (TARGET_GNU2_TLS)
14608
    {
14609
       emit_insn (gen_tls_dynamic_gnu2_64
14610
                  (operands[0], ix86_tls_module_base ()));
14611
       DONE;
14612
    }
14613
  operands[1] = ix86_tls_get_addr ();
14614
})
14615
 
14616
;; Local dynamic of a single variable is a lose.  Show combine how
14617
;; to convert that back to global dynamic.
14618
 
14619
(define_insn_and_split "*tls_local_dynamic_32_once"
14620
  [(set (match_operand:SI 0 "register_operand" "=a")
14621
        (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14622
                             (match_operand:SI 2 "call_insn_operand" "")]
14623
                            UNSPEC_TLS_LD_BASE)
14624
                 (const:SI (unspec:SI
14625
                            [(match_operand:SI 3 "tls_symbolic_operand" "")]
14626
                            UNSPEC_DTPOFF))))
14627
   (clobber (match_scratch:SI 4 "=d"))
14628
   (clobber (match_scratch:SI 5 "=c"))
14629
   (clobber (reg:CC FLAGS_REG))]
14630
  ""
14631
  "#"
14632
  ""
14633
  [(parallel [(set (match_dup 0)
14634
                   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14635
                              UNSPEC_TLS_GD))
14636
              (clobber (match_dup 4))
14637
              (clobber (match_dup 5))
14638
              (clobber (reg:CC FLAGS_REG))])]
14639
  "")
14640
 
14641
;; Load and add the thread base pointer from %gs:0.
14642
 
14643
(define_insn "*load_tp_si"
14644
  [(set (match_operand:SI 0 "register_operand" "=r")
14645
        (unspec:SI [(const_int 0)] UNSPEC_TP))]
14646
  "!TARGET_64BIT"
14647
  "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14648
  [(set_attr "type" "imov")
14649
   (set_attr "modrm" "0")
14650
   (set_attr "length" "7")
14651
   (set_attr "memory" "load")
14652
   (set_attr "imm_disp" "false")])
14653
 
14654
(define_insn "*add_tp_si"
14655
  [(set (match_operand:SI 0 "register_operand" "=r")
14656
        (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14657
                 (match_operand:SI 1 "register_operand" "0")))
14658
   (clobber (reg:CC FLAGS_REG))]
14659
  "!TARGET_64BIT"
14660
  "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14661
  [(set_attr "type" "alu")
14662
   (set_attr "modrm" "0")
14663
   (set_attr "length" "7")
14664
   (set_attr "memory" "load")
14665
   (set_attr "imm_disp" "false")])
14666
 
14667
(define_insn "*load_tp_di"
14668
  [(set (match_operand:DI 0 "register_operand" "=r")
14669
        (unspec:DI [(const_int 0)] UNSPEC_TP))]
14670
  "TARGET_64BIT"
14671
  "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14672
  [(set_attr "type" "imov")
14673
   (set_attr "modrm" "0")
14674
   (set_attr "length" "7")
14675
   (set_attr "memory" "load")
14676
   (set_attr "imm_disp" "false")])
14677
 
14678
(define_insn "*add_tp_di"
14679
  [(set (match_operand:DI 0 "register_operand" "=r")
14680
        (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14681
                 (match_operand:DI 1 "register_operand" "0")))
14682
   (clobber (reg:CC FLAGS_REG))]
14683
  "TARGET_64BIT"
14684
  "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14685
  [(set_attr "type" "alu")
14686
   (set_attr "modrm" "0")
14687
   (set_attr "length" "7")
14688
   (set_attr "memory" "load")
14689
   (set_attr "imm_disp" "false")])
14690
 
14691
;; GNU2 TLS patterns can be split.
14692
 
14693
(define_expand "tls_dynamic_gnu2_32"
14694
  [(set (match_dup 3)
14695
        (plus:SI (match_operand:SI 2 "register_operand" "")
14696
                 (const:SI
14697
                  (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14698
                             UNSPEC_TLSDESC))))
14699
   (parallel
14700
    [(set (match_operand:SI 0 "register_operand" "")
14701
          (unspec:SI [(match_dup 1) (match_dup 3)
14702
                      (match_dup 2) (reg:SI SP_REG)]
14703
                      UNSPEC_TLSDESC))
14704
     (clobber (reg:CC FLAGS_REG))])]
14705
  "!TARGET_64BIT && TARGET_GNU2_TLS"
14706
{
14707
  operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14708
  ix86_tls_descriptor_calls_expanded_in_cfun = true;
14709
})
14710
 
14711
(define_insn "*tls_dynamic_lea_32"
14712
  [(set (match_operand:SI 0 "register_operand" "=r")
14713
        (plus:SI (match_operand:SI 1 "register_operand" "b")
14714
                 (const:SI
14715
                  (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14716
                              UNSPEC_TLSDESC))))]
14717
  "!TARGET_64BIT && TARGET_GNU2_TLS"
14718
  "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14719
  [(set_attr "type" "lea")
14720
   (set_attr "mode" "SI")
14721
   (set_attr "length" "6")
14722
   (set_attr "length_address" "4")])
14723
 
14724
(define_insn "*tls_dynamic_call_32"
14725
  [(set (match_operand:SI 0 "register_operand" "=a")
14726
        (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14727
                    (match_operand:SI 2 "register_operand" "0")
14728
                    ;; we have to make sure %ebx still points to the GOT
14729
                    (match_operand:SI 3 "register_operand" "b")
14730
                    (reg:SI SP_REG)]
14731
                   UNSPEC_TLSDESC))
14732
   (clobber (reg:CC FLAGS_REG))]
14733
  "!TARGET_64BIT && TARGET_GNU2_TLS"
14734
  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14735
  [(set_attr "type" "call")
14736
   (set_attr "length" "2")
14737
   (set_attr "length_address" "0")])
14738
 
14739
(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14740
  [(set (match_operand:SI 0 "register_operand" "=&a")
14741
        (plus:SI
14742
         (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14743
                     (match_operand:SI 4 "" "")
14744
                     (match_operand:SI 2 "register_operand" "b")
14745
                     (reg:SI SP_REG)]
14746
                    UNSPEC_TLSDESC)
14747
         (const:SI (unspec:SI
14748
                    [(match_operand:SI 1 "tls_symbolic_operand" "")]
14749
                    UNSPEC_DTPOFF))))
14750
   (clobber (reg:CC FLAGS_REG))]
14751
  "!TARGET_64BIT && TARGET_GNU2_TLS"
14752
  "#"
14753
  ""
14754
  [(set (match_dup 0) (match_dup 5))]
14755
{
14756
  operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14757
  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14758
})
14759
 
14760
(define_expand "tls_dynamic_gnu2_64"
14761
  [(set (match_dup 2)
14762
        (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14763
                   UNSPEC_TLSDESC))
14764
   (parallel
14765
    [(set (match_operand:DI 0 "register_operand" "")
14766
          (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14767
                     UNSPEC_TLSDESC))
14768
     (clobber (reg:CC FLAGS_REG))])]
14769
  "TARGET_64BIT && TARGET_GNU2_TLS"
14770
{
14771
  operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14772
  ix86_tls_descriptor_calls_expanded_in_cfun = true;
14773
})
14774
 
14775
(define_insn "*tls_dynamic_lea_64"
14776
  [(set (match_operand:DI 0 "register_operand" "=r")
14777
        (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14778
                   UNSPEC_TLSDESC))]
14779
  "TARGET_64BIT && TARGET_GNU2_TLS"
14780
  "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
14781
  [(set_attr "type" "lea")
14782
   (set_attr "mode" "DI")
14783
   (set_attr "length" "7")
14784
   (set_attr "length_address" "4")])
14785
 
14786
(define_insn "*tls_dynamic_call_64"
14787
  [(set (match_operand:DI 0 "register_operand" "=a")
14788
        (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14789
                    (match_operand:DI 2 "register_operand" "0")
14790
                    (reg:DI SP_REG)]
14791
                   UNSPEC_TLSDESC))
14792
   (clobber (reg:CC FLAGS_REG))]
14793
  "TARGET_64BIT && TARGET_GNU2_TLS"
14794
  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14795
  [(set_attr "type" "call")
14796
   (set_attr "length" "2")
14797
   (set_attr "length_address" "0")])
14798
 
14799
(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14800
  [(set (match_operand:DI 0 "register_operand" "=&a")
14801
        (plus:DI
14802
         (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14803
                     (match_operand:DI 3 "" "")
14804
                     (reg:DI SP_REG)]
14805
                    UNSPEC_TLSDESC)
14806
         (const:DI (unspec:DI
14807
                    [(match_operand:DI 1 "tls_symbolic_operand" "")]
14808
                    UNSPEC_DTPOFF))))
14809
   (clobber (reg:CC FLAGS_REG))]
14810
  "TARGET_64BIT && TARGET_GNU2_TLS"
14811
  "#"
14812
  ""
14813
  [(set (match_dup 0) (match_dup 4))]
14814
{
14815
  operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14816
  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14817
})
14818
 
14819
;;
14820
 
14821
;; These patterns match the binary 387 instructions for addM3, subM3,
14822
;; mulM3 and divM3.  There are three patterns for each of DFmode and
14823
;; SFmode.  The first is the normal insn, the second the same insn but
14824
;; with one operand a conversion, and the third the same insn but with
14825
;; the other operand a conversion.  The conversion may be SFmode or
14826
;; SImode if the target mode DFmode, but only SImode if the target mode
14827
;; is SFmode.
14828
 
14829
;; Gcc is slightly more smart about handling normal two address instructions
14830
;; so use special patterns for add and mull.
14831
 
14832
(define_insn "*fop__comm_mixed_avx"
14833
  [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14834
        (match_operator:MODEF 3 "binary_fp_operator"
14835
          [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
14836
           (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14837
  "AVX_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
14838
   && COMMUTATIVE_ARITH_P (operands[3])
14839
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14840
  "* return output_387_binary_op (insn, operands);"
14841
  [(set (attr "type")
14842
        (if_then_else (eq_attr "alternative" "1")
14843
           (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14844
              (const_string "ssemul")
14845
              (const_string "sseadd"))
14846
           (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14847
              (const_string "fmul")
14848
              (const_string "fop"))))
14849
   (set_attr "prefix" "orig,maybe_vex")
14850
   (set_attr "mode" "")])
14851
 
14852
(define_insn "*fop__comm_mixed"
14853
  [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14854
        (match_operator:MODEF 3 "binary_fp_operator"
14855
          [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
14856
           (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14857
  "SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
14858
   && COMMUTATIVE_ARITH_P (operands[3])
14859
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14860
  "* return output_387_binary_op (insn, operands);"
14861
  [(set (attr "type")
14862
        (if_then_else (eq_attr "alternative" "1")
14863
           (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14864
              (const_string "ssemul")
14865
              (const_string "sseadd"))
14866
           (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14867
              (const_string "fmul")
14868
              (const_string "fop"))))
14869
   (set_attr "mode" "")])
14870
 
14871
(define_insn "*fop__comm_avx"
14872
  [(set (match_operand:MODEF 0 "register_operand" "=x")
14873
        (match_operator:MODEF 3 "binary_fp_operator"
14874
          [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
14875
           (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14876
  "AVX_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
14877
   && COMMUTATIVE_ARITH_P (operands[3])
14878
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14879
  "* return output_387_binary_op (insn, operands);"
14880
  [(set (attr "type")
14881
        (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14882
           (const_string "ssemul")
14883
           (const_string "sseadd")))
14884
   (set_attr "prefix" "vex")
14885
   (set_attr "mode" "")])
14886
 
14887
(define_insn "*fop__comm_sse"
14888
  [(set (match_operand:MODEF 0 "register_operand" "=x")
14889
        (match_operator:MODEF 3 "binary_fp_operator"
14890
          [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14891
           (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14892
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
14893
   && COMMUTATIVE_ARITH_P (operands[3])
14894
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14895
  "* return output_387_binary_op (insn, operands);"
14896
  [(set (attr "type")
14897
        (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14898
           (const_string "ssemul")
14899
           (const_string "sseadd")))
14900
   (set_attr "mode" "")])
14901
 
14902
(define_insn "*fop__comm_i387"
14903
  [(set (match_operand:MODEF 0 "register_operand" "=f")
14904
        (match_operator:MODEF 3 "binary_fp_operator"
14905
          [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14906
           (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
14907
  "TARGET_80387 && X87_ENABLE_ARITH (mode)
14908
   && COMMUTATIVE_ARITH_P (operands[3])
14909
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14910
  "* return output_387_binary_op (insn, operands);"
14911
  [(set (attr "type")
14912
        (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14913
           (const_string "fmul")
14914
           (const_string "fop")))
14915
   (set_attr "mode" "")])
14916
 
14917
(define_insn "*fop__1_mixed_avx"
14918
  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14919
        (match_operator:MODEF 3 "binary_fp_operator"
14920
          [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
14921
           (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14922
  "AVX_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
14923
   && !COMMUTATIVE_ARITH_P (operands[3])
14924
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14925
  "* return output_387_binary_op (insn, operands);"
14926
  [(set (attr "type")
14927
        (cond [(and (eq_attr "alternative" "2")
14928
                    (match_operand:MODEF 3 "mult_operator" ""))
14929
                 (const_string "ssemul")
14930
               (and (eq_attr "alternative" "2")
14931
                    (match_operand:MODEF 3 "div_operator" ""))
14932
                 (const_string "ssediv")
14933
               (eq_attr "alternative" "2")
14934
                 (const_string "sseadd")
14935
               (match_operand:MODEF 3 "mult_operator" "")
14936
                 (const_string "fmul")
14937
               (match_operand:MODEF 3 "div_operator" "")
14938
                 (const_string "fdiv")
14939
              ]
14940
              (const_string "fop")))
14941
   (set_attr "prefix" "orig,orig,maybe_vex")
14942
   (set_attr "mode" "")])
14943
 
14944
(define_insn "*fop__1_mixed"
14945
  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14946
        (match_operator:MODEF 3 "binary_fp_operator"
14947
          [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
14948
           (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14949
  "SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
14950
   && !COMMUTATIVE_ARITH_P (operands[3])
14951
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14952
  "* return output_387_binary_op (insn, operands);"
14953
  [(set (attr "type")
14954
        (cond [(and (eq_attr "alternative" "2")
14955
                    (match_operand:MODEF 3 "mult_operator" ""))
14956
                 (const_string "ssemul")
14957
               (and (eq_attr "alternative" "2")
14958
                    (match_operand:MODEF 3 "div_operator" ""))
14959
                 (const_string "ssediv")
14960
               (eq_attr "alternative" "2")
14961
                 (const_string "sseadd")
14962
               (match_operand:MODEF 3 "mult_operator" "")
14963
                 (const_string "fmul")
14964
               (match_operand:MODEF 3 "div_operator" "")
14965
                 (const_string "fdiv")
14966
              ]
14967
              (const_string "fop")))
14968
   (set_attr "mode" "")])
14969
 
14970
(define_insn "*rcpsf2_sse"
14971
  [(set (match_operand:SF 0 "register_operand" "=x")
14972
        (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14973
                   UNSPEC_RCP))]
14974
  "TARGET_SSE_MATH"
14975
  "%vrcpss\t{%1, %d0|%d0, %1}"
14976
  [(set_attr "type" "sse")
14977
   (set_attr "atom_sse_attr" "rcp")
14978
   (set_attr "prefix" "maybe_vex")
14979
   (set_attr "mode" "SF")])
14980
 
14981
(define_insn "*fop__1_avx"
14982
  [(set (match_operand:MODEF 0 "register_operand" "=x")
14983
        (match_operator:MODEF 3 "binary_fp_operator"
14984
          [(match_operand:MODEF 1 "register_operand" "x")
14985
           (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14986
  "AVX_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
14987
   && !COMMUTATIVE_ARITH_P (operands[3])"
14988
  "* return output_387_binary_op (insn, operands);"
14989
  [(set (attr "type")
14990
        (cond [(match_operand:MODEF 3 "mult_operator" "")
14991
                 (const_string "ssemul")
14992
               (match_operand:MODEF 3 "div_operator" "")
14993
                 (const_string "ssediv")
14994
              ]
14995
              (const_string "sseadd")))
14996
   (set_attr "prefix" "vex")
14997
   (set_attr "mode" "")])
14998
 
14999
(define_insn "*fop__1_sse"
15000
  [(set (match_operand:MODEF 0 "register_operand" "=x")
15001
        (match_operator:MODEF 3 "binary_fp_operator"
15002
          [(match_operand:MODEF 1 "register_operand" "0")
15003
           (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15004
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
15005
   && !COMMUTATIVE_ARITH_P (operands[3])"
15006
  "* return output_387_binary_op (insn, operands);"
15007
  [(set (attr "type")
15008
        (cond [(match_operand:MODEF 3 "mult_operator" "")
15009
                 (const_string "ssemul")
15010
               (match_operand:MODEF 3 "div_operator" "")
15011
                 (const_string "ssediv")
15012
              ]
15013
              (const_string "sseadd")))
15014
   (set_attr "mode" "")])
15015
 
15016
;; This pattern is not fully shadowed by the pattern above.
15017
(define_insn "*fop__1_i387"
15018
  [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15019
        (match_operator:MODEF 3 "binary_fp_operator"
15020
          [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15021
           (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15022
  "TARGET_80387 && X87_ENABLE_ARITH (mode)
15023
   && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15024
   && !COMMUTATIVE_ARITH_P (operands[3])
15025
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15026
  "* return output_387_binary_op (insn, operands);"
15027
  [(set (attr "type")
15028
        (cond [(match_operand:MODEF 3 "mult_operator" "")
15029
                 (const_string "fmul")
15030
               (match_operand:MODEF 3 "div_operator" "")
15031
                 (const_string "fdiv")
15032
              ]
15033
              (const_string "fop")))
15034
   (set_attr "mode" "")])
15035
 
15036
;; ??? Add SSE splitters for these!
15037
(define_insn "*fop__2_i387"
15038
  [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15039
        (match_operator:MODEF 3 "binary_fp_operator"
15040
          [(float:MODEF
15041
             (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15042
           (match_operand:MODEF 2 "register_operand" "0,0")]))]
15043
  "TARGET_80387 && X87_ENABLE_FLOAT (mode, mode)
15044
   && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15045
   && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))"
15046
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15047
  [(set (attr "type")
15048
        (cond [(match_operand:MODEF 3 "mult_operator" "")
15049
                 (const_string "fmul")
15050
               (match_operand:MODEF 3 "div_operator" "")
15051
                 (const_string "fdiv")
15052
              ]
15053
              (const_string "fop")))
15054
   (set_attr "fp_int_src" "true")
15055
   (set_attr "mode" "")])
15056
 
15057
(define_insn "*fop__3_i387"
15058
  [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15059
        (match_operator:MODEF 3 "binary_fp_operator"
15060
          [(match_operand:MODEF 1 "register_operand" "0,0")
15061
           (float:MODEF
15062
             (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15063
  "TARGET_80387 && X87_ENABLE_FLOAT (mode, mode)
15064
   && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15065
   && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))"
15066
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15067
  [(set (attr "type")
15068
        (cond [(match_operand:MODEF 3 "mult_operator" "")
15069
                 (const_string "fmul")
15070
               (match_operand:MODEF 3 "div_operator" "")
15071
                 (const_string "fdiv")
15072
              ]
15073
              (const_string "fop")))
15074
   (set_attr "fp_int_src" "true")
15075
   (set_attr "mode" "")])
15076
 
15077
(define_insn "*fop_df_4_i387"
15078
  [(set (match_operand:DF 0 "register_operand" "=f,f")
15079
        (match_operator:DF 3 "binary_fp_operator"
15080
           [(float_extend:DF
15081
             (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15082
            (match_operand:DF 2 "register_operand" "0,f")]))]
15083
  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15084
   && !(TARGET_SSE2 && TARGET_SSE_MATH)
15085
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15086
  "* return output_387_binary_op (insn, operands);"
15087
  [(set (attr "type")
15088
        (cond [(match_operand:DF 3 "mult_operator" "")
15089
                 (const_string "fmul")
15090
               (match_operand:DF 3 "div_operator" "")
15091
                 (const_string "fdiv")
15092
              ]
15093
              (const_string "fop")))
15094
   (set_attr "mode" "SF")])
15095
 
15096
(define_insn "*fop_df_5_i387"
15097
  [(set (match_operand:DF 0 "register_operand" "=f,f")
15098
        (match_operator:DF 3 "binary_fp_operator"
15099
          [(match_operand:DF 1 "register_operand" "0,f")
15100
           (float_extend:DF
15101
            (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15102
  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15103
   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15104
  "* return output_387_binary_op (insn, operands);"
15105
  [(set (attr "type")
15106
        (cond [(match_operand:DF 3 "mult_operator" "")
15107
                 (const_string "fmul")
15108
               (match_operand:DF 3 "div_operator" "")
15109
                 (const_string "fdiv")
15110
              ]
15111
              (const_string "fop")))
15112
   (set_attr "mode" "SF")])
15113
 
15114
(define_insn "*fop_df_6_i387"
15115
  [(set (match_operand:DF 0 "register_operand" "=f,f")
15116
        (match_operator:DF 3 "binary_fp_operator"
15117
          [(float_extend:DF
15118
            (match_operand:SF 1 "register_operand" "0,f"))
15119
           (float_extend:DF
15120
            (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15121
  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15122
   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15123
  "* return output_387_binary_op (insn, operands);"
15124
  [(set (attr "type")
15125
        (cond [(match_operand:DF 3 "mult_operator" "")
15126
                 (const_string "fmul")
15127
               (match_operand:DF 3 "div_operator" "")
15128
                 (const_string "fdiv")
15129
              ]
15130
              (const_string "fop")))
15131
   (set_attr "mode" "SF")])
15132
 
15133
(define_insn "*fop_xf_comm_i387"
15134
  [(set (match_operand:XF 0 "register_operand" "=f")
15135
        (match_operator:XF 3 "binary_fp_operator"
15136
                        [(match_operand:XF 1 "register_operand" "%0")
15137
                         (match_operand:XF 2 "register_operand" "f")]))]
15138
  "TARGET_80387
15139
   && COMMUTATIVE_ARITH_P (operands[3])"
15140
  "* return output_387_binary_op (insn, operands);"
15141
  [(set (attr "type")
15142
        (if_then_else (match_operand:XF 3 "mult_operator" "")
15143
           (const_string "fmul")
15144
           (const_string "fop")))
15145
   (set_attr "mode" "XF")])
15146
 
15147
(define_insn "*fop_xf_1_i387"
15148
  [(set (match_operand:XF 0 "register_operand" "=f,f")
15149
        (match_operator:XF 3 "binary_fp_operator"
15150
                        [(match_operand:XF 1 "register_operand" "0,f")
15151
                         (match_operand:XF 2 "register_operand" "f,0")]))]
15152
  "TARGET_80387
15153
   && !COMMUTATIVE_ARITH_P (operands[3])"
15154
  "* return output_387_binary_op (insn, operands);"
15155
  [(set (attr "type")
15156
        (cond [(match_operand:XF 3 "mult_operator" "")
15157
                 (const_string "fmul")
15158
               (match_operand:XF 3 "div_operator" "")
15159
                 (const_string "fdiv")
15160
              ]
15161
              (const_string "fop")))
15162
   (set_attr "mode" "XF")])
15163
 
15164
(define_insn "*fop_xf_2_i387"
15165
  [(set (match_operand:XF 0 "register_operand" "=f,f")
15166
        (match_operator:XF 3 "binary_fp_operator"
15167
          [(float:XF
15168
             (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15169
           (match_operand:XF 2 "register_operand" "0,0")]))]
15170
  "TARGET_80387 && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))"
15171
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15172
  [(set (attr "type")
15173
        (cond [(match_operand:XF 3 "mult_operator" "")
15174
                 (const_string "fmul")
15175
               (match_operand:XF 3 "div_operator" "")
15176
                 (const_string "fdiv")
15177
              ]
15178
              (const_string "fop")))
15179
   (set_attr "fp_int_src" "true")
15180
   (set_attr "mode" "")])
15181
 
15182
(define_insn "*fop_xf_3_i387"
15183
  [(set (match_operand:XF 0 "register_operand" "=f,f")
15184
        (match_operator:XF 3 "binary_fp_operator"
15185
          [(match_operand:XF 1 "register_operand" "0,0")
15186
           (float:XF
15187
             (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15188
  "TARGET_80387 && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))"
15189
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15190
  [(set (attr "type")
15191
        (cond [(match_operand:XF 3 "mult_operator" "")
15192
                 (const_string "fmul")
15193
               (match_operand:XF 3 "div_operator" "")
15194
                 (const_string "fdiv")
15195
              ]
15196
              (const_string "fop")))
15197
   (set_attr "fp_int_src" "true")
15198
   (set_attr "mode" "")])
15199
 
15200
(define_insn "*fop_xf_4_i387"
15201
  [(set (match_operand:XF 0 "register_operand" "=f,f")
15202
        (match_operator:XF 3 "binary_fp_operator"
15203
           [(float_extend:XF
15204
              (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15205
            (match_operand:XF 2 "register_operand" "0,f")]))]
15206
  "TARGET_80387"
15207
  "* return output_387_binary_op (insn, operands);"
15208
  [(set (attr "type")
15209
        (cond [(match_operand:XF 3 "mult_operator" "")
15210
                 (const_string "fmul")
15211
               (match_operand:XF 3 "div_operator" "")
15212
                 (const_string "fdiv")
15213
              ]
15214
              (const_string "fop")))
15215
   (set_attr "mode" "")])
15216
 
15217
(define_insn "*fop_xf_5_i387"
15218
  [(set (match_operand:XF 0 "register_operand" "=f,f")
15219
        (match_operator:XF 3 "binary_fp_operator"
15220
          [(match_operand:XF 1 "register_operand" "0,f")
15221
           (float_extend:XF
15222
             (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15223
  "TARGET_80387"
15224
  "* return output_387_binary_op (insn, operands);"
15225
  [(set (attr "type")
15226
        (cond [(match_operand:XF 3 "mult_operator" "")
15227
                 (const_string "fmul")
15228
               (match_operand:XF 3 "div_operator" "")
15229
                 (const_string "fdiv")
15230
              ]
15231
              (const_string "fop")))
15232
   (set_attr "mode" "")])
15233
 
15234
(define_insn "*fop_xf_6_i387"
15235
  [(set (match_operand:XF 0 "register_operand" "=f,f")
15236
        (match_operator:XF 3 "binary_fp_operator"
15237
          [(float_extend:XF
15238
             (match_operand:MODEF 1 "register_operand" "0,f"))
15239
           (float_extend:XF
15240
             (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15241
  "TARGET_80387"
15242
  "* return output_387_binary_op (insn, operands);"
15243
  [(set (attr "type")
15244
        (cond [(match_operand:XF 3 "mult_operator" "")
15245
                 (const_string "fmul")
15246
               (match_operand:XF 3 "div_operator" "")
15247
                 (const_string "fdiv")
15248
              ]
15249
              (const_string "fop")))
15250
   (set_attr "mode" "")])
15251
 
15252
(define_split
15253
  [(set (match_operand 0 "register_operand" "")
15254
        (match_operator 3 "binary_fp_operator"
15255
           [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15256
            (match_operand 2 "register_operand" "")]))]
15257
  "reload_completed
15258
   && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15259
   && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15260
  [(const_int 0)]
15261
{
15262
  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15263
  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15264
  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15265
                          gen_rtx_fmt_ee (GET_CODE (operands[3]),
15266
                                          GET_MODE (operands[3]),
15267
                                          operands[4],
15268
                                          operands[2])));
15269
  ix86_free_from_memory (GET_MODE (operands[1]));
15270
  DONE;
15271
})
15272
 
15273
(define_split
15274
  [(set (match_operand 0 "register_operand" "")
15275
        (match_operator 3 "binary_fp_operator"
15276
           [(match_operand 1 "register_operand" "")
15277
            (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15278
  "reload_completed
15279
   && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15280
   && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15281
  [(const_int 0)]
15282
{
15283
  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15284
  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15285
  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15286
                          gen_rtx_fmt_ee (GET_CODE (operands[3]),
15287
                                          GET_MODE (operands[3]),
15288
                                          operands[1],
15289
                                          operands[4])));
15290
  ix86_free_from_memory (GET_MODE (operands[2]));
15291
  DONE;
15292
})
15293
 
15294
;; FPU special functions.
15295
 
15296
;; This pattern implements a no-op XFmode truncation for
15297
;; all fancy i386 XFmode math functions.
15298
 
15299
(define_insn "truncxf2_i387_noop_unspec"
15300
  [(set (match_operand:MODEF 0 "register_operand" "=f")
15301
        (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15302
        UNSPEC_TRUNC_NOOP))]
15303
  "TARGET_USE_FANCY_MATH_387"
15304
  "* return output_387_reg_move (insn, operands);"
15305
  [(set_attr "type" "fmov")
15306
   (set_attr "mode" "")])
15307
 
15308
(define_insn "sqrtxf2"
15309
  [(set (match_operand:XF 0 "register_operand" "=f")
15310
        (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15311
  "TARGET_USE_FANCY_MATH_387"
15312
  "fsqrt"
15313
  [(set_attr "type" "fpspc")
15314
   (set_attr "mode" "XF")
15315
   (set_attr "athlon_decode" "direct")
15316
   (set_attr "amdfam10_decode" "direct")])
15317
 
15318
(define_insn "sqrt_extendxf2_i387"
15319
  [(set (match_operand:XF 0 "register_operand" "=f")
15320
        (sqrt:XF
15321
          (float_extend:XF
15322
            (match_operand:MODEF 1 "register_operand" "0"))))]
15323
  "TARGET_USE_FANCY_MATH_387"
15324
  "fsqrt"
15325
  [(set_attr "type" "fpspc")
15326
   (set_attr "mode" "XF")
15327
   (set_attr "athlon_decode" "direct")
15328
   (set_attr "amdfam10_decode" "direct")])
15329
 
15330
(define_insn "*rsqrtsf2_sse"
15331
  [(set (match_operand:SF 0 "register_operand" "=x")
15332
        (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15333
                   UNSPEC_RSQRT))]
15334
  "TARGET_SSE_MATH"
15335
  "%vrsqrtss\t{%1, %d0|%d0, %1}"
15336
  [(set_attr "type" "sse")
15337
   (set_attr "atom_sse_attr" "rcp")
15338
   (set_attr "prefix" "maybe_vex")
15339
   (set_attr "mode" "SF")])
15340
 
15341
(define_expand "rsqrtsf2"
15342
  [(set (match_operand:SF 0 "register_operand" "")
15343
        (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15344
                   UNSPEC_RSQRT))]
15345
  "TARGET_SSE_MATH"
15346
{
15347
  ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15348
  DONE;
15349
})
15350
 
15351
(define_insn "*sqrt2_sse"
15352
  [(set (match_operand:MODEF 0 "register_operand" "=x")
15353
        (sqrt:MODEF
15354
          (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15355
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
15356
  "%vsqrts\t{%1, %d0|%d0, %1}"
15357
  [(set_attr "type" "sse")
15358
   (set_attr "atom_sse_attr" "sqrt")
15359
   (set_attr "prefix" "maybe_vex")
15360
   (set_attr "mode" "")
15361
   (set_attr "athlon_decode" "*")
15362
   (set_attr "amdfam10_decode" "*")])
15363
 
15364
(define_expand "sqrt2"
15365
  [(set (match_operand:MODEF 0 "register_operand" "")
15366
        (sqrt:MODEF
15367
          (match_operand:MODEF 1 "nonimmediate_operand" "")))]
15368
  "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (mode))
15369
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
15370
{
15371
  if (mode == SFmode
15372
      && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
15373
      && flag_finite_math_only && !flag_trapping_math
15374
      && flag_unsafe_math_optimizations)
15375
    {
15376
      ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15377
      DONE;
15378
    }
15379
 
15380
  if (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))
15381
    {
15382
      rtx op0 = gen_reg_rtx (XFmode);
15383
      rtx op1 = force_reg (mode, operands[1]);
15384
 
15385
      emit_insn (gen_sqrt_extendxf2_i387 (op0, op1));
15386
      emit_insn (gen_truncxf2_i387_noop_unspec (operands[0], op0));
15387
      DONE;
15388
   }
15389
})
15390
 
15391
(define_insn "fpremxf4_i387"
15392
  [(set (match_operand:XF 0 "register_operand" "=f")
15393
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15394
                    (match_operand:XF 3 "register_operand" "1")]
15395
                   UNSPEC_FPREM_F))
15396
   (set (match_operand:XF 1 "register_operand" "=u")
15397
        (unspec:XF [(match_dup 2) (match_dup 3)]
15398
                   UNSPEC_FPREM_U))
15399
   (set (reg:CCFP FPSR_REG)
15400
        (unspec:CCFP [(match_dup 2) (match_dup 3)]
15401
                     UNSPEC_C2_FLAG))]
15402
  "TARGET_USE_FANCY_MATH_387"
15403
  "fprem"
15404
  [(set_attr "type" "fpspc")
15405
   (set_attr "mode" "XF")])
15406
 
15407
(define_expand "fmodxf3"
15408
  [(use (match_operand:XF 0 "register_operand" ""))
15409
   (use (match_operand:XF 1 "general_operand" ""))
15410
   (use (match_operand:XF 2 "general_operand" ""))]
15411
  "TARGET_USE_FANCY_MATH_387"
15412
{
15413
  rtx label = gen_label_rtx ();
15414
 
15415
  rtx op1 = gen_reg_rtx (XFmode);
15416
  rtx op2 = gen_reg_rtx (XFmode);
15417
 
15418
  emit_move_insn (op2, operands[2]);
15419
  emit_move_insn (op1, operands[1]);
15420
 
15421
  emit_label (label);
15422
  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15423
  ix86_emit_fp_unordered_jump (label);
15424
  LABEL_NUSES (label) = 1;
15425
 
15426
  emit_move_insn (operands[0], op1);
15427
  DONE;
15428
})
15429
 
15430
(define_expand "fmod3"
15431
  [(use (match_operand:MODEF 0 "register_operand" ""))
15432
   (use (match_operand:MODEF 1 "general_operand" ""))
15433
   (use (match_operand:MODEF 2 "general_operand" ""))]
15434
  "TARGET_USE_FANCY_MATH_387"
15435
{
15436
  rtx label = gen_label_rtx ();
15437
 
15438
  rtx op1 = gen_reg_rtx (XFmode);
15439
  rtx op2 = gen_reg_rtx (XFmode);
15440
 
15441
  emit_insn (gen_extendxf2 (op2, operands[2]));
15442
  emit_insn (gen_extendxf2 (op1, operands[1]));
15443
 
15444
  emit_label (label);
15445
  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15446
  ix86_emit_fp_unordered_jump (label);
15447
  LABEL_NUSES (label) = 1;
15448
 
15449
  /* Truncate the result properly for strict SSE math.  */
15450
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
15451
      && !TARGET_MIX_SSE_I387)
15452
    emit_insn (gen_truncxf2 (operands[0], op1));
15453
  else
15454
    emit_insn (gen_truncxf2_i387_noop_unspec (operands[0], op1));
15455
 
15456
  DONE;
15457
})
15458
 
15459
(define_insn "fprem1xf4_i387"
15460
  [(set (match_operand:XF 0 "register_operand" "=f")
15461
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15462
                    (match_operand:XF 3 "register_operand" "1")]
15463
                   UNSPEC_FPREM1_F))
15464
   (set (match_operand:XF 1 "register_operand" "=u")
15465
        (unspec:XF [(match_dup 2) (match_dup 3)]
15466
                   UNSPEC_FPREM1_U))
15467
   (set (reg:CCFP FPSR_REG)
15468
        (unspec:CCFP [(match_dup 2) (match_dup 3)]
15469
                     UNSPEC_C2_FLAG))]
15470
  "TARGET_USE_FANCY_MATH_387"
15471
  "fprem1"
15472
  [(set_attr "type" "fpspc")
15473
   (set_attr "mode" "XF")])
15474
 
15475
(define_expand "remainderxf3"
15476
  [(use (match_operand:XF 0 "register_operand" ""))
15477
   (use (match_operand:XF 1 "general_operand" ""))
15478
   (use (match_operand:XF 2 "general_operand" ""))]
15479
  "TARGET_USE_FANCY_MATH_387"
15480
{
15481
  rtx label = gen_label_rtx ();
15482
 
15483
  rtx op1 = gen_reg_rtx (XFmode);
15484
  rtx op2 = gen_reg_rtx (XFmode);
15485
 
15486
  emit_move_insn (op2, operands[2]);
15487
  emit_move_insn (op1, operands[1]);
15488
 
15489
  emit_label (label);
15490
  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15491
  ix86_emit_fp_unordered_jump (label);
15492
  LABEL_NUSES (label) = 1;
15493
 
15494
  emit_move_insn (operands[0], op1);
15495
  DONE;
15496
})
15497
 
15498
(define_expand "remainder3"
15499
  [(use (match_operand:MODEF 0 "register_operand" ""))
15500
   (use (match_operand:MODEF 1 "general_operand" ""))
15501
   (use (match_operand:MODEF 2 "general_operand" ""))]
15502
  "TARGET_USE_FANCY_MATH_387"
15503
{
15504
  rtx label = gen_label_rtx ();
15505
 
15506
  rtx op1 = gen_reg_rtx (XFmode);
15507
  rtx op2 = gen_reg_rtx (XFmode);
15508
 
15509
  emit_insn (gen_extendxf2 (op2, operands[2]));
15510
  emit_insn (gen_extendxf2 (op1, operands[1]));
15511
 
15512
  emit_label (label);
15513
 
15514
  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15515
  ix86_emit_fp_unordered_jump (label);
15516
  LABEL_NUSES (label) = 1;
15517
 
15518
  /* Truncate the result properly for strict SSE math.  */
15519
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
15520
      && !TARGET_MIX_SSE_I387)
15521
    emit_insn (gen_truncxf2 (operands[0], op1));
15522
  else
15523
    emit_insn (gen_truncxf2_i387_noop_unspec (operands[0], op1));
15524
 
15525
  DONE;
15526
})
15527
 
15528
(define_insn "*sinxf2_i387"
15529
  [(set (match_operand:XF 0 "register_operand" "=f")
15530
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15531
  "TARGET_USE_FANCY_MATH_387
15532
   && flag_unsafe_math_optimizations"
15533
  "fsin"
15534
  [(set_attr "type" "fpspc")
15535
   (set_attr "mode" "XF")])
15536
 
15537
(define_insn "*sin_extendxf2_i387"
15538
  [(set (match_operand:XF 0 "register_operand" "=f")
15539
        (unspec:XF [(float_extend:XF
15540
                      (match_operand:MODEF 1 "register_operand" "0"))]
15541
                   UNSPEC_SIN))]
15542
  "TARGET_USE_FANCY_MATH_387
15543
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15544
       || TARGET_MIX_SSE_I387)
15545
   && flag_unsafe_math_optimizations"
15546
  "fsin"
15547
  [(set_attr "type" "fpspc")
15548
   (set_attr "mode" "XF")])
15549
 
15550
(define_insn "*cosxf2_i387"
15551
  [(set (match_operand:XF 0 "register_operand" "=f")
15552
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15553
  "TARGET_USE_FANCY_MATH_387
15554
   && flag_unsafe_math_optimizations"
15555
  "fcos"
15556
  [(set_attr "type" "fpspc")
15557
   (set_attr "mode" "XF")])
15558
 
15559
(define_insn "*cos_extendxf2_i387"
15560
  [(set (match_operand:XF 0 "register_operand" "=f")
15561
        (unspec:XF [(float_extend:XF
15562
                      (match_operand:MODEF 1 "register_operand" "0"))]
15563
                   UNSPEC_COS))]
15564
  "TARGET_USE_FANCY_MATH_387
15565
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15566
       || TARGET_MIX_SSE_I387)
15567
   && flag_unsafe_math_optimizations"
15568
  "fcos"
15569
  [(set_attr "type" "fpspc")
15570
   (set_attr "mode" "XF")])
15571
 
15572
;; When sincos pattern is defined, sin and cos builtin functions will be
15573
;; expanded to sincos pattern with one of its outputs left unused.
15574
;; CSE pass will figure out if two sincos patterns can be combined,
15575
;; otherwise sincos pattern will be split back to sin or cos pattern,
15576
;; depending on the unused output.
15577
 
15578
(define_insn "sincosxf3"
15579
  [(set (match_operand:XF 0 "register_operand" "=f")
15580
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15581
                   UNSPEC_SINCOS_COS))
15582
   (set (match_operand:XF 1 "register_operand" "=u")
15583
        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15584
  "TARGET_USE_FANCY_MATH_387
15585
   && flag_unsafe_math_optimizations"
15586
  "fsincos"
15587
  [(set_attr "type" "fpspc")
15588
   (set_attr "mode" "XF")])
15589
 
15590
(define_split
15591
  [(set (match_operand:XF 0 "register_operand" "")
15592
        (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15593
                   UNSPEC_SINCOS_COS))
15594
   (set (match_operand:XF 1 "register_operand" "")
15595
        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15596
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15597
   && !(reload_completed || reload_in_progress)"
15598
  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15599
  "")
15600
 
15601
(define_split
15602
  [(set (match_operand:XF 0 "register_operand" "")
15603
        (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15604
                   UNSPEC_SINCOS_COS))
15605
   (set (match_operand:XF 1 "register_operand" "")
15606
        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15607
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15608
   && !(reload_completed || reload_in_progress)"
15609
  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15610
  "")
15611
 
15612
(define_insn "sincos_extendxf3_i387"
15613
  [(set (match_operand:XF 0 "register_operand" "=f")
15614
        (unspec:XF [(float_extend:XF
15615
                      (match_operand:MODEF 2 "register_operand" "0"))]
15616
                   UNSPEC_SINCOS_COS))
15617
   (set (match_operand:XF 1 "register_operand" "=u")
15618
        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15619
  "TARGET_USE_FANCY_MATH_387
15620
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15621
       || TARGET_MIX_SSE_I387)
15622
   && flag_unsafe_math_optimizations"
15623
  "fsincos"
15624
  [(set_attr "type" "fpspc")
15625
   (set_attr "mode" "XF")])
15626
 
15627
(define_split
15628
  [(set (match_operand:XF 0 "register_operand" "")
15629
        (unspec:XF [(float_extend:XF
15630
                      (match_operand:MODEF 2 "register_operand" ""))]
15631
                   UNSPEC_SINCOS_COS))
15632
   (set (match_operand:XF 1 "register_operand" "")
15633
        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15634
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15635
   && !(reload_completed || reload_in_progress)"
15636
  [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15637
  "")
15638
 
15639
(define_split
15640
  [(set (match_operand:XF 0 "register_operand" "")
15641
        (unspec:XF [(float_extend:XF
15642
                      (match_operand:MODEF 2 "register_operand" ""))]
15643
                   UNSPEC_SINCOS_COS))
15644
   (set (match_operand:XF 1 "register_operand" "")
15645
        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15646
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15647
   && !(reload_completed || reload_in_progress)"
15648
  [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15649
  "")
15650
 
15651
(define_expand "sincos3"
15652
  [(use (match_operand:MODEF 0 "register_operand" ""))
15653
   (use (match_operand:MODEF 1 "register_operand" ""))
15654
   (use (match_operand:MODEF 2 "register_operand" ""))]
15655
  "TARGET_USE_FANCY_MATH_387
15656
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15657
       || TARGET_MIX_SSE_I387)
15658
   && flag_unsafe_math_optimizations"
15659
{
15660
  rtx op0 = gen_reg_rtx (XFmode);
15661
  rtx op1 = gen_reg_rtx (XFmode);
15662
 
15663
  emit_insn (gen_sincos_extendxf3_i387 (op0, op1, operands[2]));
15664
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
15665
  emit_insn (gen_truncxf2_i387_noop (operands[1], op1));
15666
  DONE;
15667
})
15668
 
15669
(define_insn "fptanxf4_i387"
15670
  [(set (match_operand:XF 0 "register_operand" "=f")
15671
        (match_operand:XF 3 "const_double_operand" "F"))
15672
   (set (match_operand:XF 1 "register_operand" "=u")
15673
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15674
                   UNSPEC_TAN))]
15675
  "TARGET_USE_FANCY_MATH_387
15676
   && flag_unsafe_math_optimizations
15677
   && standard_80387_constant_p (operands[3]) == 2"
15678
  "fptan"
15679
  [(set_attr "type" "fpspc")
15680
   (set_attr "mode" "XF")])
15681
 
15682
(define_insn "fptan_extendxf4_i387"
15683
  [(set (match_operand:MODEF 0 "register_operand" "=f")
15684
        (match_operand:MODEF 3 "const_double_operand" "F"))
15685
   (set (match_operand:XF 1 "register_operand" "=u")
15686
        (unspec:XF [(float_extend:XF
15687
                      (match_operand:MODEF 2 "register_operand" "0"))]
15688
                   UNSPEC_TAN))]
15689
  "TARGET_USE_FANCY_MATH_387
15690
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15691
       || TARGET_MIX_SSE_I387)
15692
   && flag_unsafe_math_optimizations
15693
   && standard_80387_constant_p (operands[3]) == 2"
15694
  "fptan"
15695
  [(set_attr "type" "fpspc")
15696
   (set_attr "mode" "XF")])
15697
 
15698
(define_expand "tanxf2"
15699
  [(use (match_operand:XF 0 "register_operand" ""))
15700
   (use (match_operand:XF 1 "register_operand" ""))]
15701
  "TARGET_USE_FANCY_MATH_387
15702
   && flag_unsafe_math_optimizations"
15703
{
15704
  rtx one = gen_reg_rtx (XFmode);
15705
  rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15706
 
15707
  emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15708
  DONE;
15709
})
15710
 
15711
(define_expand "tan2"
15712
  [(use (match_operand:MODEF 0 "register_operand" ""))
15713
   (use (match_operand:MODEF 1 "register_operand" ""))]
15714
  "TARGET_USE_FANCY_MATH_387
15715
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15716
       || TARGET_MIX_SSE_I387)
15717
   && flag_unsafe_math_optimizations"
15718
{
15719
  rtx op0 = gen_reg_rtx (XFmode);
15720
 
15721
  rtx one = gen_reg_rtx (mode);
15722
  rtx op2 = CONST1_RTX (mode); /* fld1 */
15723
 
15724
  emit_insn (gen_fptan_extendxf4_i387 (one, op0,
15725
                                             operands[1], op2));
15726
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
15727
  DONE;
15728
})
15729
 
15730
(define_insn "*fpatanxf3_i387"
15731
  [(set (match_operand:XF 0 "register_operand" "=f")
15732
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15733
                    (match_operand:XF 2 "register_operand" "u")]
15734
                   UNSPEC_FPATAN))
15735
   (clobber (match_scratch:XF 3 "=2"))]
15736
  "TARGET_USE_FANCY_MATH_387
15737
   && flag_unsafe_math_optimizations"
15738
  "fpatan"
15739
  [(set_attr "type" "fpspc")
15740
   (set_attr "mode" "XF")])
15741
 
15742
(define_insn "fpatan_extendxf3_i387"
15743
  [(set (match_operand:XF 0 "register_operand" "=f")
15744
        (unspec:XF [(float_extend:XF
15745
                      (match_operand:MODEF 1 "register_operand" "0"))
15746
                    (float_extend:XF
15747
                      (match_operand:MODEF 2 "register_operand" "u"))]
15748
                   UNSPEC_FPATAN))
15749
   (clobber (match_scratch:XF 3 "=2"))]
15750
  "TARGET_USE_FANCY_MATH_387
15751
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15752
       || TARGET_MIX_SSE_I387)
15753
   && flag_unsafe_math_optimizations"
15754
  "fpatan"
15755
  [(set_attr "type" "fpspc")
15756
   (set_attr "mode" "XF")])
15757
 
15758
(define_expand "atan2xf3"
15759
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
15760
                   (unspec:XF [(match_operand:XF 2 "register_operand" "")
15761
                               (match_operand:XF 1 "register_operand" "")]
15762
                              UNSPEC_FPATAN))
15763
              (clobber (match_scratch:XF 3 ""))])]
15764
  "TARGET_USE_FANCY_MATH_387
15765
   && flag_unsafe_math_optimizations"
15766
  "")
15767
 
15768
(define_expand "atan23"
15769
  [(use (match_operand:MODEF 0 "register_operand" ""))
15770
   (use (match_operand:MODEF 1 "register_operand" ""))
15771
   (use (match_operand:MODEF 2 "register_operand" ""))]
15772
  "TARGET_USE_FANCY_MATH_387
15773
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15774
       || TARGET_MIX_SSE_I387)
15775
   && flag_unsafe_math_optimizations"
15776
{
15777
  rtx op0 = gen_reg_rtx (XFmode);
15778
 
15779
  emit_insn (gen_fpatan_extendxf3_i387 (op0, operands[2], operands[1]));
15780
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
15781
  DONE;
15782
})
15783
 
15784
(define_expand "atanxf2"
15785
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
15786
                   (unspec:XF [(match_dup 2)
15787
                               (match_operand:XF 1 "register_operand" "")]
15788
                              UNSPEC_FPATAN))
15789
              (clobber (match_scratch:XF 3 ""))])]
15790
  "TARGET_USE_FANCY_MATH_387
15791
   && flag_unsafe_math_optimizations"
15792
{
15793
  operands[2] = gen_reg_rtx (XFmode);
15794
  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15795
})
15796
 
15797
(define_expand "atan2"
15798
  [(use (match_operand:MODEF 0 "register_operand" ""))
15799
   (use (match_operand:MODEF 1 "register_operand" ""))]
15800
  "TARGET_USE_FANCY_MATH_387
15801
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15802
       || TARGET_MIX_SSE_I387)
15803
   && flag_unsafe_math_optimizations"
15804
{
15805
  rtx op0 = gen_reg_rtx (XFmode);
15806
 
15807
  rtx op2 = gen_reg_rtx (mode);
15808
  emit_move_insn (op2, CONST1_RTX (mode));  /* fld1 */
15809
 
15810
  emit_insn (gen_fpatan_extendxf3_i387 (op0, op2, operands[1]));
15811
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
15812
  DONE;
15813
})
15814
 
15815
(define_expand "asinxf2"
15816
  [(set (match_dup 2)
15817
        (mult:XF (match_operand:XF 1 "register_operand" "")
15818
                 (match_dup 1)))
15819
   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15820
   (set (match_dup 5) (sqrt:XF (match_dup 4)))
15821
   (parallel [(set (match_operand:XF 0 "register_operand" "")
15822
                   (unspec:XF [(match_dup 5) (match_dup 1)]
15823
                              UNSPEC_FPATAN))
15824
              (clobber (match_scratch:XF 6 ""))])]
15825
  "TARGET_USE_FANCY_MATH_387
15826
   && flag_unsafe_math_optimizations"
15827
{
15828
  int i;
15829
 
15830
  if (optimize_insn_for_size_p ())
15831
    FAIL;
15832
 
15833
  for (i = 2; i < 6; i++)
15834
    operands[i] = gen_reg_rtx (XFmode);
15835
 
15836
  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15837
})
15838
 
15839
(define_expand "asin2"
15840
  [(use (match_operand:MODEF 0 "register_operand" ""))
15841
   (use (match_operand:MODEF 1 "general_operand" ""))]
15842
 "TARGET_USE_FANCY_MATH_387
15843
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15844
       || TARGET_MIX_SSE_I387)
15845
   && flag_unsafe_math_optimizations"
15846
{
15847
  rtx op0 = gen_reg_rtx (XFmode);
15848
  rtx op1 = gen_reg_rtx (XFmode);
15849
 
15850
  if (optimize_insn_for_size_p ())
15851
    FAIL;
15852
 
15853
  emit_insn (gen_extendxf2 (op1, operands[1]));
15854
  emit_insn (gen_asinxf2 (op0, op1));
15855
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
15856
  DONE;
15857
})
15858
 
15859
(define_expand "acosxf2"
15860
  [(set (match_dup 2)
15861
        (mult:XF (match_operand:XF 1 "register_operand" "")
15862
                 (match_dup 1)))
15863
   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15864
   (set (match_dup 5) (sqrt:XF (match_dup 4)))
15865
   (parallel [(set (match_operand:XF 0 "register_operand" "")
15866
                   (unspec:XF [(match_dup 1) (match_dup 5)]
15867
                              UNSPEC_FPATAN))
15868
              (clobber (match_scratch:XF 6 ""))])]
15869
  "TARGET_USE_FANCY_MATH_387
15870
   && flag_unsafe_math_optimizations"
15871
{
15872
  int i;
15873
 
15874
  if (optimize_insn_for_size_p ())
15875
    FAIL;
15876
 
15877
  for (i = 2; i < 6; i++)
15878
    operands[i] = gen_reg_rtx (XFmode);
15879
 
15880
  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15881
})
15882
 
15883
(define_expand "acos2"
15884
  [(use (match_operand:MODEF 0 "register_operand" ""))
15885
   (use (match_operand:MODEF 1 "general_operand" ""))]
15886
 "TARGET_USE_FANCY_MATH_387
15887
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15888
       || TARGET_MIX_SSE_I387)
15889
   && flag_unsafe_math_optimizations"
15890
{
15891
  rtx op0 = gen_reg_rtx (XFmode);
15892
  rtx op1 = gen_reg_rtx (XFmode);
15893
 
15894
  if (optimize_insn_for_size_p ())
15895
    FAIL;
15896
 
15897
  emit_insn (gen_extendxf2 (op1, operands[1]));
15898
  emit_insn (gen_acosxf2 (op0, op1));
15899
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
15900
  DONE;
15901
})
15902
 
15903
(define_insn "fyl2xxf3_i387"
15904
  [(set (match_operand:XF 0 "register_operand" "=f")
15905
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15906
                    (match_operand:XF 2 "register_operand" "u")]
15907
                   UNSPEC_FYL2X))
15908
   (clobber (match_scratch:XF 3 "=2"))]
15909
  "TARGET_USE_FANCY_MATH_387
15910
   && flag_unsafe_math_optimizations"
15911
  "fyl2x"
15912
  [(set_attr "type" "fpspc")
15913
   (set_attr "mode" "XF")])
15914
 
15915
(define_insn "fyl2x_extendxf3_i387"
15916
  [(set (match_operand:XF 0 "register_operand" "=f")
15917
        (unspec:XF [(float_extend:XF
15918
                      (match_operand:MODEF 1 "register_operand" "0"))
15919
                    (match_operand:XF 2 "register_operand" "u")]
15920
                   UNSPEC_FYL2X))
15921
   (clobber (match_scratch:XF 3 "=2"))]
15922
  "TARGET_USE_FANCY_MATH_387
15923
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15924
       || TARGET_MIX_SSE_I387)
15925
   && flag_unsafe_math_optimizations"
15926
  "fyl2x"
15927
  [(set_attr "type" "fpspc")
15928
   (set_attr "mode" "XF")])
15929
 
15930
(define_expand "logxf2"
15931
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
15932
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
15933
                               (match_dup 2)] UNSPEC_FYL2X))
15934
              (clobber (match_scratch:XF 3 ""))])]
15935
  "TARGET_USE_FANCY_MATH_387
15936
   && flag_unsafe_math_optimizations"
15937
{
15938
  operands[2] = gen_reg_rtx (XFmode);
15939
  emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15940
})
15941
 
15942
(define_expand "log2"
15943
  [(use (match_operand:MODEF 0 "register_operand" ""))
15944
   (use (match_operand:MODEF 1 "register_operand" ""))]
15945
  "TARGET_USE_FANCY_MATH_387
15946
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15947
       || TARGET_MIX_SSE_I387)
15948
   && flag_unsafe_math_optimizations"
15949
{
15950
  rtx op0 = gen_reg_rtx (XFmode);
15951
 
15952
  rtx op2 = gen_reg_rtx (XFmode);
15953
  emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15954
 
15955
  emit_insn (gen_fyl2x_extendxf3_i387 (op0, operands[1], op2));
15956
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
15957
  DONE;
15958
})
15959
 
15960
(define_expand "log10xf2"
15961
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
15962
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
15963
                               (match_dup 2)] UNSPEC_FYL2X))
15964
              (clobber (match_scratch:XF 3 ""))])]
15965
  "TARGET_USE_FANCY_MATH_387
15966
   && flag_unsafe_math_optimizations"
15967
{
15968
  operands[2] = gen_reg_rtx (XFmode);
15969
  emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15970
})
15971
 
15972
(define_expand "log102"
15973
  [(use (match_operand:MODEF 0 "register_operand" ""))
15974
   (use (match_operand:MODEF 1 "register_operand" ""))]
15975
  "TARGET_USE_FANCY_MATH_387
15976
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15977
       || TARGET_MIX_SSE_I387)
15978
   && flag_unsafe_math_optimizations"
15979
{
15980
  rtx op0 = gen_reg_rtx (XFmode);
15981
 
15982
  rtx op2 = gen_reg_rtx (XFmode);
15983
  emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15984
 
15985
  emit_insn (gen_fyl2x_extendxf3_i387 (op0, operands[1], op2));
15986
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
15987
  DONE;
15988
})
15989
 
15990
(define_expand "log2xf2"
15991
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
15992
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
15993
                               (match_dup 2)] UNSPEC_FYL2X))
15994
              (clobber (match_scratch:XF 3 ""))])]
15995
  "TARGET_USE_FANCY_MATH_387
15996
   && flag_unsafe_math_optimizations"
15997
{
15998
  operands[2] = gen_reg_rtx (XFmode);
15999
  emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16000
})
16001
 
16002
(define_expand "log22"
16003
  [(use (match_operand:MODEF 0 "register_operand" ""))
16004
   (use (match_operand:MODEF 1 "register_operand" ""))]
16005
  "TARGET_USE_FANCY_MATH_387
16006
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16007
       || TARGET_MIX_SSE_I387)
16008
   && flag_unsafe_math_optimizations"
16009
{
16010
  rtx op0 = gen_reg_rtx (XFmode);
16011
 
16012
  rtx op2 = gen_reg_rtx (XFmode);
16013
  emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16014
 
16015
  emit_insn (gen_fyl2x_extendxf3_i387 (op0, operands[1], op2));
16016
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
16017
  DONE;
16018
})
16019
 
16020
(define_insn "fyl2xp1xf3_i387"
16021
  [(set (match_operand:XF 0 "register_operand" "=f")
16022
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16023
                    (match_operand:XF 2 "register_operand" "u")]
16024
                   UNSPEC_FYL2XP1))
16025
   (clobber (match_scratch:XF 3 "=2"))]
16026
  "TARGET_USE_FANCY_MATH_387
16027
   && flag_unsafe_math_optimizations"
16028
  "fyl2xp1"
16029
  [(set_attr "type" "fpspc")
16030
   (set_attr "mode" "XF")])
16031
 
16032
(define_insn "fyl2xp1_extendxf3_i387"
16033
  [(set (match_operand:XF 0 "register_operand" "=f")
16034
        (unspec:XF [(float_extend:XF
16035
                      (match_operand:MODEF 1 "register_operand" "0"))
16036
                    (match_operand:XF 2 "register_operand" "u")]
16037
                   UNSPEC_FYL2XP1))
16038
   (clobber (match_scratch:XF 3 "=2"))]
16039
  "TARGET_USE_FANCY_MATH_387
16040
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16041
       || TARGET_MIX_SSE_I387)
16042
   && flag_unsafe_math_optimizations"
16043
  "fyl2xp1"
16044
  [(set_attr "type" "fpspc")
16045
   (set_attr "mode" "XF")])
16046
 
16047
(define_expand "log1pxf2"
16048
  [(use (match_operand:XF 0 "register_operand" ""))
16049
   (use (match_operand:XF 1 "register_operand" ""))]
16050
  "TARGET_USE_FANCY_MATH_387
16051
   && flag_unsafe_math_optimizations"
16052
{
16053
  if (optimize_insn_for_size_p ())
16054
    FAIL;
16055
 
16056
  ix86_emit_i387_log1p (operands[0], operands[1]);
16057
  DONE;
16058
})
16059
 
16060
(define_expand "log1p2"
16061
  [(use (match_operand:MODEF 0 "register_operand" ""))
16062
   (use (match_operand:MODEF 1 "register_operand" ""))]
16063
  "TARGET_USE_FANCY_MATH_387
16064
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16065
       || TARGET_MIX_SSE_I387)
16066
   && flag_unsafe_math_optimizations"
16067
{
16068
  rtx op0;
16069
 
16070
  if (optimize_insn_for_size_p ())
16071
    FAIL;
16072
 
16073
  op0 = gen_reg_rtx (XFmode);
16074
 
16075
  operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16076
 
16077
  ix86_emit_i387_log1p (op0, operands[1]);
16078
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
16079
  DONE;
16080
})
16081
 
16082
(define_insn "fxtractxf3_i387"
16083
  [(set (match_operand:XF 0 "register_operand" "=f")
16084
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16085
                   UNSPEC_XTRACT_FRACT))
16086
   (set (match_operand:XF 1 "register_operand" "=u")
16087
        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16088
  "TARGET_USE_FANCY_MATH_387
16089
   && flag_unsafe_math_optimizations"
16090
  "fxtract"
16091
  [(set_attr "type" "fpspc")
16092
   (set_attr "mode" "XF")])
16093
 
16094
(define_insn "fxtract_extendxf3_i387"
16095
  [(set (match_operand:XF 0 "register_operand" "=f")
16096
        (unspec:XF [(float_extend:XF
16097
                      (match_operand:MODEF 2 "register_operand" "0"))]
16098
                   UNSPEC_XTRACT_FRACT))
16099
   (set (match_operand:XF 1 "register_operand" "=u")
16100
        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16101
  "TARGET_USE_FANCY_MATH_387
16102
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16103
       || TARGET_MIX_SSE_I387)
16104
   && flag_unsafe_math_optimizations"
16105
  "fxtract"
16106
  [(set_attr "type" "fpspc")
16107
   (set_attr "mode" "XF")])
16108
 
16109
(define_expand "logbxf2"
16110
  [(parallel [(set (match_dup 2)
16111
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16112
                              UNSPEC_XTRACT_FRACT))
16113
              (set (match_operand:XF 0 "register_operand" "")
16114
                   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16115
  "TARGET_USE_FANCY_MATH_387
16116
   && flag_unsafe_math_optimizations"
16117
{
16118
  operands[2] = gen_reg_rtx (XFmode);
16119
})
16120
 
16121
(define_expand "logb2"
16122
  [(use (match_operand:MODEF 0 "register_operand" ""))
16123
   (use (match_operand:MODEF 1 "register_operand" ""))]
16124
  "TARGET_USE_FANCY_MATH_387
16125
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16126
       || TARGET_MIX_SSE_I387)
16127
   && flag_unsafe_math_optimizations"
16128
{
16129
  rtx op0 = gen_reg_rtx (XFmode);
16130
  rtx op1 = gen_reg_rtx (XFmode);
16131
 
16132
  emit_insn (gen_fxtract_extendxf3_i387 (op0, op1, operands[1]));
16133
  emit_insn (gen_truncxf2_i387_noop (operands[0], op1));
16134
  DONE;
16135
})
16136
 
16137
(define_expand "ilogbxf2"
16138
  [(use (match_operand:SI 0 "register_operand" ""))
16139
   (use (match_operand:XF 1 "register_operand" ""))]
16140
  "TARGET_USE_FANCY_MATH_387
16141
   && flag_unsafe_math_optimizations"
16142
{
16143
  rtx op0, op1;
16144
 
16145
  if (optimize_insn_for_size_p ())
16146
    FAIL;
16147
 
16148
  op0 = gen_reg_rtx (XFmode);
16149
  op1 = gen_reg_rtx (XFmode);
16150
 
16151
  emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16152
  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16153
  DONE;
16154
})
16155
 
16156
(define_expand "ilogb2"
16157
  [(use (match_operand:SI 0 "register_operand" ""))
16158
   (use (match_operand:MODEF 1 "register_operand" ""))]
16159
  "TARGET_USE_FANCY_MATH_387
16160
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16161
       || TARGET_MIX_SSE_I387)
16162
   && flag_unsafe_math_optimizations"
16163
{
16164
  rtx op0, op1;
16165
 
16166
  if (optimize_insn_for_size_p ())
16167
    FAIL;
16168
 
16169
  op0 = gen_reg_rtx (XFmode);
16170
  op1 = gen_reg_rtx (XFmode);
16171
 
16172
  emit_insn (gen_fxtract_extendxf3_i387 (op0, op1, operands[1]));
16173
  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16174
  DONE;
16175
})
16176
 
16177
(define_insn "*f2xm1xf2_i387"
16178
  [(set (match_operand:XF 0 "register_operand" "=f")
16179
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16180
                   UNSPEC_F2XM1))]
16181
  "TARGET_USE_FANCY_MATH_387
16182
   && flag_unsafe_math_optimizations"
16183
  "f2xm1"
16184
  [(set_attr "type" "fpspc")
16185
   (set_attr "mode" "XF")])
16186
 
16187
(define_insn "*fscalexf4_i387"
16188
  [(set (match_operand:XF 0 "register_operand" "=f")
16189
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16190
                    (match_operand:XF 3 "register_operand" "1")]
16191
                   UNSPEC_FSCALE_FRACT))
16192
   (set (match_operand:XF 1 "register_operand" "=u")
16193
        (unspec:XF [(match_dup 2) (match_dup 3)]
16194
                   UNSPEC_FSCALE_EXP))]
16195
  "TARGET_USE_FANCY_MATH_387
16196
   && flag_unsafe_math_optimizations"
16197
  "fscale"
16198
  [(set_attr "type" "fpspc")
16199
   (set_attr "mode" "XF")])
16200
 
16201
(define_expand "expNcorexf3"
16202
  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16203
                               (match_operand:XF 2 "register_operand" "")))
16204
   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16205
   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16206
   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16207
   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16208
   (parallel [(set (match_operand:XF 0 "register_operand" "")
16209
                   (unspec:XF [(match_dup 8) (match_dup 4)]
16210
                              UNSPEC_FSCALE_FRACT))
16211
              (set (match_dup 9)
16212
                   (unspec:XF [(match_dup 8) (match_dup 4)]
16213
                              UNSPEC_FSCALE_EXP))])]
16214
  "TARGET_USE_FANCY_MATH_387
16215
   && flag_unsafe_math_optimizations"
16216
{
16217
  int i;
16218
 
16219
  if (optimize_insn_for_size_p ())
16220
    FAIL;
16221
 
16222
  for (i = 3; i < 10; i++)
16223
    operands[i] = gen_reg_rtx (XFmode);
16224
 
16225
  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16226
})
16227
 
16228
(define_expand "expxf2"
16229
  [(use (match_operand:XF 0 "register_operand" ""))
16230
   (use (match_operand:XF 1 "register_operand" ""))]
16231
  "TARGET_USE_FANCY_MATH_387
16232
   && flag_unsafe_math_optimizations"
16233
{
16234
  rtx op2;
16235
 
16236
  if (optimize_insn_for_size_p ())
16237
    FAIL;
16238
 
16239
  op2 = gen_reg_rtx (XFmode);
16240
  emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16241
 
16242
  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16243
  DONE;
16244
})
16245
 
16246
(define_expand "exp2"
16247
  [(use (match_operand:MODEF 0 "register_operand" ""))
16248
   (use (match_operand:MODEF 1 "general_operand" ""))]
16249
 "TARGET_USE_FANCY_MATH_387
16250
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16251
       || TARGET_MIX_SSE_I387)
16252
   && flag_unsafe_math_optimizations"
16253
{
16254
  rtx op0, op1;
16255
 
16256
  if (optimize_insn_for_size_p ())
16257
    FAIL;
16258
 
16259
  op0 = gen_reg_rtx (XFmode);
16260
  op1 = gen_reg_rtx (XFmode);
16261
 
16262
  emit_insn (gen_extendxf2 (op1, operands[1]));
16263
  emit_insn (gen_expxf2 (op0, op1));
16264
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
16265
  DONE;
16266
})
16267
 
16268
(define_expand "exp10xf2"
16269
  [(use (match_operand:XF 0 "register_operand" ""))
16270
   (use (match_operand:XF 1 "register_operand" ""))]
16271
  "TARGET_USE_FANCY_MATH_387
16272
   && flag_unsafe_math_optimizations"
16273
{
16274
  rtx op2;
16275
 
16276
  if (optimize_insn_for_size_p ())
16277
    FAIL;
16278
 
16279
  op2 = gen_reg_rtx (XFmode);
16280
  emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16281
 
16282
  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16283
  DONE;
16284
})
16285
 
16286
(define_expand "exp102"
16287
  [(use (match_operand:MODEF 0 "register_operand" ""))
16288
   (use (match_operand:MODEF 1 "general_operand" ""))]
16289
 "TARGET_USE_FANCY_MATH_387
16290
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16291
       || TARGET_MIX_SSE_I387)
16292
   && flag_unsafe_math_optimizations"
16293
{
16294
  rtx op0, op1;
16295
 
16296
  if (optimize_insn_for_size_p ())
16297
    FAIL;
16298
 
16299
  op0 = gen_reg_rtx (XFmode);
16300
  op1 = gen_reg_rtx (XFmode);
16301
 
16302
  emit_insn (gen_extendxf2 (op1, operands[1]));
16303
  emit_insn (gen_exp10xf2 (op0, op1));
16304
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
16305
  DONE;
16306
})
16307
 
16308
(define_expand "exp2xf2"
16309
  [(use (match_operand:XF 0 "register_operand" ""))
16310
   (use (match_operand:XF 1 "register_operand" ""))]
16311
  "TARGET_USE_FANCY_MATH_387
16312
   && flag_unsafe_math_optimizations"
16313
{
16314
  rtx op2;
16315
 
16316
  if (optimize_insn_for_size_p ())
16317
    FAIL;
16318
 
16319
  op2 = gen_reg_rtx (XFmode);
16320
  emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16321
 
16322
  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16323
  DONE;
16324
})
16325
 
16326
(define_expand "exp22"
16327
  [(use (match_operand:MODEF 0 "register_operand" ""))
16328
   (use (match_operand:MODEF 1 "general_operand" ""))]
16329
 "TARGET_USE_FANCY_MATH_387
16330
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16331
       || TARGET_MIX_SSE_I387)
16332
   && flag_unsafe_math_optimizations"
16333
{
16334
  rtx op0, op1;
16335
 
16336
  if (optimize_insn_for_size_p ())
16337
    FAIL;
16338
 
16339
  op0 = gen_reg_rtx (XFmode);
16340
  op1 = gen_reg_rtx (XFmode);
16341
 
16342
  emit_insn (gen_extendxf2 (op1, operands[1]));
16343
  emit_insn (gen_exp2xf2 (op0, op1));
16344
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
16345
  DONE;
16346
})
16347
 
16348
(define_expand "expm1xf2"
16349
  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16350
                               (match_dup 2)))
16351
   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16352
   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16353
   (set (match_dup 9) (float_extend:XF (match_dup 13)))
16354
   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16355
   (parallel [(set (match_dup 7)
16356
                   (unspec:XF [(match_dup 6) (match_dup 4)]
16357
                              UNSPEC_FSCALE_FRACT))
16358
              (set (match_dup 8)
16359
                   (unspec:XF [(match_dup 6) (match_dup 4)]
16360
                              UNSPEC_FSCALE_EXP))])
16361
   (parallel [(set (match_dup 10)
16362
                   (unspec:XF [(match_dup 9) (match_dup 8)]
16363
                              UNSPEC_FSCALE_FRACT))
16364
              (set (match_dup 11)
16365
                   (unspec:XF [(match_dup 9) (match_dup 8)]
16366
                              UNSPEC_FSCALE_EXP))])
16367
   (set (match_dup 12) (minus:XF (match_dup 10)
16368
                                 (float_extend:XF (match_dup 13))))
16369
   (set (match_operand:XF 0 "register_operand" "")
16370
        (plus:XF (match_dup 12) (match_dup 7)))]
16371
  "TARGET_USE_FANCY_MATH_387
16372
   && flag_unsafe_math_optimizations"
16373
{
16374
  int i;
16375
 
16376
  if (optimize_insn_for_size_p ())
16377
    FAIL;
16378
 
16379
  for (i = 2; i < 13; i++)
16380
    operands[i] = gen_reg_rtx (XFmode);
16381
 
16382
  operands[13]
16383
    = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16384
 
16385
  emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16386
})
16387
 
16388
(define_expand "expm12"
16389
  [(use (match_operand:MODEF 0 "register_operand" ""))
16390
   (use (match_operand:MODEF 1 "general_operand" ""))]
16391
 "TARGET_USE_FANCY_MATH_387
16392
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16393
       || TARGET_MIX_SSE_I387)
16394
   && flag_unsafe_math_optimizations"
16395
{
16396
  rtx op0, op1;
16397
 
16398
  if (optimize_insn_for_size_p ())
16399
    FAIL;
16400
 
16401
  op0 = gen_reg_rtx (XFmode);
16402
  op1 = gen_reg_rtx (XFmode);
16403
 
16404
  emit_insn (gen_extendxf2 (op1, operands[1]));
16405
  emit_insn (gen_expm1xf2 (op0, op1));
16406
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
16407
  DONE;
16408
})
16409
 
16410
(define_expand "ldexpxf3"
16411
  [(set (match_dup 3)
16412
        (float:XF (match_operand:SI 2 "register_operand" "")))
16413
   (parallel [(set (match_operand:XF 0 " register_operand" "")
16414
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16415
                               (match_dup 3)]
16416
                              UNSPEC_FSCALE_FRACT))
16417
              (set (match_dup 4)
16418
                   (unspec:XF [(match_dup 1) (match_dup 3)]
16419
                              UNSPEC_FSCALE_EXP))])]
16420
  "TARGET_USE_FANCY_MATH_387
16421
   && flag_unsafe_math_optimizations"
16422
{
16423
  if (optimize_insn_for_size_p ())
16424
    FAIL;
16425
 
16426
  operands[3] = gen_reg_rtx (XFmode);
16427
  operands[4] = gen_reg_rtx (XFmode);
16428
})
16429
 
16430
(define_expand "ldexp3"
16431
  [(use (match_operand:MODEF 0 "register_operand" ""))
16432
   (use (match_operand:MODEF 1 "general_operand" ""))
16433
   (use (match_operand:SI 2 "register_operand" ""))]
16434
 "TARGET_USE_FANCY_MATH_387
16435
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16436
       || TARGET_MIX_SSE_I387)
16437
   && flag_unsafe_math_optimizations"
16438
{
16439
  rtx op0, op1;
16440
 
16441
  if (optimize_insn_for_size_p ())
16442
    FAIL;
16443
 
16444
  op0 = gen_reg_rtx (XFmode);
16445
  op1 = gen_reg_rtx (XFmode);
16446
 
16447
  emit_insn (gen_extendxf2 (op1, operands[1]));
16448
  emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16449
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
16450
  DONE;
16451
})
16452
 
16453
(define_expand "scalbxf3"
16454
  [(parallel [(set (match_operand:XF 0 " register_operand" "")
16455
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16456
                               (match_operand:XF 2 "register_operand" "")]
16457
                              UNSPEC_FSCALE_FRACT))
16458
              (set (match_dup 3)
16459
                   (unspec:XF [(match_dup 1) (match_dup 2)]
16460
                              UNSPEC_FSCALE_EXP))])]
16461
  "TARGET_USE_FANCY_MATH_387
16462
   && flag_unsafe_math_optimizations"
16463
{
16464
  if (optimize_insn_for_size_p ())
16465
    FAIL;
16466
 
16467
  operands[3] = gen_reg_rtx (XFmode);
16468
})
16469
 
16470
(define_expand "scalb3"
16471
  [(use (match_operand:MODEF 0 "register_operand" ""))
16472
   (use (match_operand:MODEF 1 "general_operand" ""))
16473
   (use (match_operand:MODEF 2 "general_operand" ""))]
16474
 "TARGET_USE_FANCY_MATH_387
16475
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16476
       || TARGET_MIX_SSE_I387)
16477
   && flag_unsafe_math_optimizations"
16478
{
16479
  rtx op0, op1, op2;
16480
 
16481
  if (optimize_insn_for_size_p ())
16482
    FAIL;
16483
 
16484
  op0 = gen_reg_rtx (XFmode);
16485
  op1 = gen_reg_rtx (XFmode);
16486
  op2 = gen_reg_rtx (XFmode);
16487
 
16488
  emit_insn (gen_extendxf2 (op1, operands[1]));
16489
  emit_insn (gen_extendxf2 (op2, operands[2]));
16490
  emit_insn (gen_scalbxf3 (op0, op1, op2));
16491
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
16492
  DONE;
16493
})
16494
 
16495
(define_expand "significandxf2"
16496
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16497
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16498
                              UNSPEC_XTRACT_FRACT))
16499
              (set (match_dup 2)
16500
                   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16501
  "TARGET_USE_FANCY_MATH_387
16502
   && flag_unsafe_math_optimizations"
16503
{
16504
  operands[2] = gen_reg_rtx (XFmode);
16505
})
16506
 
16507
(define_expand "significand2"
16508
  [(use (match_operand:MODEF 0 "register_operand" ""))
16509
   (use (match_operand:MODEF 1 "register_operand" ""))]
16510
  "TARGET_USE_FANCY_MATH_387
16511
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16512
       || TARGET_MIX_SSE_I387)
16513
   && flag_unsafe_math_optimizations"
16514
{
16515
  rtx op0 = gen_reg_rtx (XFmode);
16516
  rtx op1 = gen_reg_rtx (XFmode);
16517
 
16518
  emit_insn (gen_fxtract_extendxf3_i387 (op0, op1, operands[1]));
16519
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
16520
  DONE;
16521
})
16522
 
16523
 
16524
(define_insn "sse4_1_round2"
16525
  [(set (match_operand:MODEF 0 "register_operand" "=x")
16526
        (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
16527
                       (match_operand:SI 2 "const_0_to_15_operand" "n")]
16528
                      UNSPEC_ROUND))]
16529
  "TARGET_ROUND"
16530
  "%vrounds\t{%2, %1, %d0|%d0, %1, %2}"
16531
  [(set_attr "type" "ssecvt")
16532
   (set_attr "prefix_extra" "1")
16533
   (set_attr "prefix" "maybe_vex")
16534
   (set_attr "mode" "")])
16535
 
16536
(define_insn "rintxf2"
16537
  [(set (match_operand:XF 0 "register_operand" "=f")
16538
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16539
                   UNSPEC_FRNDINT))]
16540
  "TARGET_USE_FANCY_MATH_387
16541
   && flag_unsafe_math_optimizations"
16542
  "frndint"
16543
  [(set_attr "type" "fpspc")
16544
   (set_attr "mode" "XF")])
16545
 
16546
(define_expand "rint2"
16547
  [(use (match_operand:MODEF 0 "register_operand" ""))
16548
   (use (match_operand:MODEF 1 "register_operand" ""))]
16549
  "(TARGET_USE_FANCY_MATH_387
16550
    && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16551
        || TARGET_MIX_SSE_I387)
16552
    && flag_unsafe_math_optimizations)
16553
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
16554
       && !flag_trapping_math)"
16555
{
16556
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
16557
      && !flag_trapping_math)
16558
    {
16559
      if (!TARGET_ROUND && optimize_insn_for_size_p ())
16560
        FAIL;
16561
      if (TARGET_ROUND)
16562
        emit_insn (gen_sse4_1_round2
16563
                   (operands[0], operands[1], GEN_INT (0x04)));
16564
      else
16565
        ix86_expand_rint (operand0, operand1);
16566
    }
16567
  else
16568
    {
16569
      rtx op0 = gen_reg_rtx (XFmode);
16570
      rtx op1 = gen_reg_rtx (XFmode);
16571
 
16572
      emit_insn (gen_extendxf2 (op1, operands[1]));
16573
      emit_insn (gen_rintxf2 (op0, op1));
16574
 
16575
      emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
16576
    }
16577
  DONE;
16578
})
16579
 
16580
(define_expand "round2"
16581
  [(match_operand:MODEF 0 "register_operand" "")
16582
   (match_operand:MODEF 1 "nonimmediate_operand" "")]
16583
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
16584
   && !flag_trapping_math && !flag_rounding_math"
16585
{
16586
  if (optimize_insn_for_size_p ())
16587
    FAIL;
16588
  if (TARGET_64BIT || (mode != DFmode))
16589
    ix86_expand_round (operand0, operand1);
16590
  else
16591
    ix86_expand_rounddf_32 (operand0, operand1);
16592
  DONE;
16593
})
16594
 
16595
(define_insn_and_split "*fistdi2_1"
16596
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
16597
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16598
                   UNSPEC_FIST))]
16599
  "TARGET_USE_FANCY_MATH_387
16600
   && can_create_pseudo_p ()"
16601
  "#"
16602
  "&& 1"
16603
  [(const_int 0)]
16604
{
16605
  if (memory_operand (operands[0], VOIDmode))
16606
    emit_insn (gen_fistdi2 (operands[0], operands[1]));
16607
  else
16608
    {
16609
      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16610
      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16611
                                         operands[2]));
16612
    }
16613
  DONE;
16614
}
16615
  [(set_attr "type" "fpspc")
16616
   (set_attr "mode" "DI")])
16617
 
16618
(define_insn "fistdi2"
16619
  [(set (match_operand:DI 0 "memory_operand" "=m")
16620
        (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16621
                   UNSPEC_FIST))
16622
   (clobber (match_scratch:XF 2 "=&1f"))]
16623
  "TARGET_USE_FANCY_MATH_387"
16624
  "* return output_fix_trunc (insn, operands, 0);"
16625
  [(set_attr "type" "fpspc")
16626
   (set_attr "mode" "DI")])
16627
 
16628
(define_insn "fistdi2_with_temp"
16629
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16630
        (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16631
                   UNSPEC_FIST))
16632
   (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16633
   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16634
  "TARGET_USE_FANCY_MATH_387"
16635
  "#"
16636
  [(set_attr "type" "fpspc")
16637
   (set_attr "mode" "DI")])
16638
 
16639
(define_split
16640
  [(set (match_operand:DI 0 "register_operand" "")
16641
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16642
                   UNSPEC_FIST))
16643
   (clobber (match_operand:DI 2 "memory_operand" ""))
16644
   (clobber (match_scratch 3 ""))]
16645
  "reload_completed"
16646
  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16647
              (clobber (match_dup 3))])
16648
   (set (match_dup 0) (match_dup 2))]
16649
  "")
16650
 
16651
(define_split
16652
  [(set (match_operand:DI 0 "memory_operand" "")
16653
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16654
                   UNSPEC_FIST))
16655
   (clobber (match_operand:DI 2 "memory_operand" ""))
16656
   (clobber (match_scratch 3 ""))]
16657
  "reload_completed"
16658
  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16659
              (clobber (match_dup 3))])]
16660
  "")
16661
 
16662
(define_insn_and_split "*fist2_1"
16663
  [(set (match_operand:X87MODEI12 0 "register_operand" "")
16664
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16665
                           UNSPEC_FIST))]
16666
  "TARGET_USE_FANCY_MATH_387
16667
   && can_create_pseudo_p ()"
16668
  "#"
16669
  "&& 1"
16670
  [(const_int 0)]
16671
{
16672
  operands[2] = assign_386_stack_local (mode, SLOT_TEMP);
16673
  emit_insn (gen_fist2_with_temp (operands[0], operands[1],
16674
                                        operands[2]));
16675
  DONE;
16676
}
16677
  [(set_attr "type" "fpspc")
16678
   (set_attr "mode" "")])
16679
 
16680
(define_insn "fist2"
16681
  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16682
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16683
                           UNSPEC_FIST))]
16684
  "TARGET_USE_FANCY_MATH_387"
16685
  "* return output_fix_trunc (insn, operands, 0);"
16686
  [(set_attr "type" "fpspc")
16687
   (set_attr "mode" "")])
16688
 
16689
(define_insn "fist2_with_temp"
16690
  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16691
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16692
                           UNSPEC_FIST))
16693
   (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16694
  "TARGET_USE_FANCY_MATH_387"
16695
  "#"
16696
  [(set_attr "type" "fpspc")
16697
   (set_attr "mode" "")])
16698
 
16699
(define_split
16700
  [(set (match_operand:X87MODEI12 0 "register_operand" "")
16701
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16702
                           UNSPEC_FIST))
16703
   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16704
  "reload_completed"
16705
  [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
16706
   (set (match_dup 0) (match_dup 2))]
16707
  "")
16708
 
16709
(define_split
16710
  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16711
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16712
                           UNSPEC_FIST))
16713
   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16714
  "reload_completed"
16715
  [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
16716
  "")
16717
 
16718
(define_expand "lrintxf2"
16719
  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16720
     (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16721
                      UNSPEC_FIST))]
16722
  "TARGET_USE_FANCY_MATH_387"
16723
  "")
16724
 
16725
(define_expand "lrint2"
16726
  [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16727
     (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
16728
                        UNSPEC_FIX_NOTRUNC))]
16729
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
16730
   && ((mode != DImode) || TARGET_64BIT)"
16731
  "")
16732
 
16733
(define_expand "lround2"
16734
  [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16735
   (match_operand:MODEF 1 "register_operand" "")]
16736
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
16737
   && ((mode != DImode) || TARGET_64BIT)
16738
   && !flag_trapping_math && !flag_rounding_math"
16739
{
16740
  if (optimize_insn_for_size_p ())
16741
    FAIL;
16742
  ix86_expand_lround (operand0, operand1);
16743
  DONE;
16744
})
16745
 
16746
;; Rounding mode control word calculation could clobber FLAGS_REG.
16747
(define_insn_and_split "frndintxf2_floor"
16748
  [(set (match_operand:XF 0 "register_operand" "")
16749
        (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16750
         UNSPEC_FRNDINT_FLOOR))
16751
   (clobber (reg:CC FLAGS_REG))]
16752
  "TARGET_USE_FANCY_MATH_387
16753
   && flag_unsafe_math_optimizations
16754
   && can_create_pseudo_p ()"
16755
  "#"
16756
  "&& 1"
16757
  [(const_int 0)]
16758
{
16759
  ix86_optimize_mode_switching[I387_FLOOR] = 1;
16760
 
16761
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16762
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16763
 
16764
  emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16765
                                        operands[2], operands[3]));
16766
  DONE;
16767
}
16768
  [(set_attr "type" "frndint")
16769
   (set_attr "i387_cw" "floor")
16770
   (set_attr "mode" "XF")])
16771
 
16772
(define_insn "frndintxf2_floor_i387"
16773
  [(set (match_operand:XF 0 "register_operand" "=f")
16774
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16775
         UNSPEC_FRNDINT_FLOOR))
16776
   (use (match_operand:HI 2 "memory_operand" "m"))
16777
   (use (match_operand:HI 3 "memory_operand" "m"))]
16778
  "TARGET_USE_FANCY_MATH_387
16779
   && flag_unsafe_math_optimizations"
16780
  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16781
  [(set_attr "type" "frndint")
16782
   (set_attr "i387_cw" "floor")
16783
   (set_attr "mode" "XF")])
16784
 
16785
(define_expand "floorxf2"
16786
  [(use (match_operand:XF 0 "register_operand" ""))
16787
   (use (match_operand:XF 1 "register_operand" ""))]
16788
  "TARGET_USE_FANCY_MATH_387
16789
   && flag_unsafe_math_optimizations"
16790
{
16791
  if (optimize_insn_for_size_p ())
16792
    FAIL;
16793
  emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16794
  DONE;
16795
})
16796
 
16797
(define_expand "floor2"
16798
  [(use (match_operand:MODEF 0 "register_operand" ""))
16799
   (use (match_operand:MODEF 1 "register_operand" ""))]
16800
  "(TARGET_USE_FANCY_MATH_387
16801
    && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
16802
        || TARGET_MIX_SSE_I387)
16803
    && flag_unsafe_math_optimizations)
16804
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
16805
       && !flag_trapping_math)"
16806
{
16807
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
16808
      && !flag_trapping_math
16809
      && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16810
    {
16811
      if (!TARGET_ROUND && optimize_insn_for_size_p ())
16812
        FAIL;
16813
      if (TARGET_ROUND)
16814
        emit_insn (gen_sse4_1_round2
16815
                   (operands[0], operands[1], GEN_INT (0x01)));
16816
      else if (TARGET_64BIT || (mode != DFmode))
16817
        ix86_expand_floorceil (operand0, operand1, true);
16818
      else
16819
        ix86_expand_floorceildf_32 (operand0, operand1, true);
16820
    }
16821
  else
16822
    {
16823
      rtx op0, op1;
16824
 
16825
      if (optimize_insn_for_size_p ())
16826
        FAIL;
16827
 
16828
      op0 = gen_reg_rtx (XFmode);
16829
      op1 = gen_reg_rtx (XFmode);
16830
      emit_insn (gen_extendxf2 (op1, operands[1]));
16831
      emit_insn (gen_frndintxf2_floor (op0, op1));
16832
 
16833
      emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
16834
    }
16835
  DONE;
16836
})
16837
 
16838
(define_insn_and_split "*fist2_floor_1"
16839
  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16840
        (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16841
         UNSPEC_FIST_FLOOR))
16842
   (clobber (reg:CC FLAGS_REG))]
16843
  "TARGET_USE_FANCY_MATH_387
16844
   && flag_unsafe_math_optimizations
16845
   && can_create_pseudo_p ()"
16846
  "#"
16847
  "&& 1"
16848
  [(const_int 0)]
16849
{
16850
  ix86_optimize_mode_switching[I387_FLOOR] = 1;
16851
 
16852
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16853
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16854
  if (memory_operand (operands[0], VOIDmode))
16855
    emit_insn (gen_fist2_floor (operands[0], operands[1],
16856
                                      operands[2], operands[3]));
16857
  else
16858
    {
16859
      operands[4] = assign_386_stack_local (mode, SLOT_TEMP);
16860
      emit_insn (gen_fist2_floor_with_temp (operands[0], operands[1],
16861
                                                  operands[2], operands[3],
16862
                                                  operands[4]));
16863
    }
16864
  DONE;
16865
}
16866
  [(set_attr "type" "fistp")
16867
   (set_attr "i387_cw" "floor")
16868
   (set_attr "mode" "")])
16869
 
16870
(define_insn "fistdi2_floor"
16871
  [(set (match_operand:DI 0 "memory_operand" "=m")
16872
        (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16873
         UNSPEC_FIST_FLOOR))
16874
   (use (match_operand:HI 2 "memory_operand" "m"))
16875
   (use (match_operand:HI 3 "memory_operand" "m"))
16876
   (clobber (match_scratch:XF 4 "=&1f"))]
16877
  "TARGET_USE_FANCY_MATH_387
16878
   && flag_unsafe_math_optimizations"
16879
  "* return output_fix_trunc (insn, operands, 0);"
16880
  [(set_attr "type" "fistp")
16881
   (set_attr "i387_cw" "floor")
16882
   (set_attr "mode" "DI")])
16883
 
16884
(define_insn "fistdi2_floor_with_temp"
16885
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16886
        (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16887
         UNSPEC_FIST_FLOOR))
16888
   (use (match_operand:HI 2 "memory_operand" "m,m"))
16889
   (use (match_operand:HI 3 "memory_operand" "m,m"))
16890
   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16891
   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16892
  "TARGET_USE_FANCY_MATH_387
16893
   && flag_unsafe_math_optimizations"
16894
  "#"
16895
  [(set_attr "type" "fistp")
16896
   (set_attr "i387_cw" "floor")
16897
   (set_attr "mode" "DI")])
16898
 
16899
(define_split
16900
  [(set (match_operand:DI 0 "register_operand" "")
16901
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16902
         UNSPEC_FIST_FLOOR))
16903
   (use (match_operand:HI 2 "memory_operand" ""))
16904
   (use (match_operand:HI 3 "memory_operand" ""))
16905
   (clobber (match_operand:DI 4 "memory_operand" ""))
16906
   (clobber (match_scratch 5 ""))]
16907
  "reload_completed"
16908
  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16909
              (use (match_dup 2))
16910
              (use (match_dup 3))
16911
              (clobber (match_dup 5))])
16912
   (set (match_dup 0) (match_dup 4))]
16913
  "")
16914
 
16915
(define_split
16916
  [(set (match_operand:DI 0 "memory_operand" "")
16917
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16918
         UNSPEC_FIST_FLOOR))
16919
   (use (match_operand:HI 2 "memory_operand" ""))
16920
   (use (match_operand:HI 3 "memory_operand" ""))
16921
   (clobber (match_operand:DI 4 "memory_operand" ""))
16922
   (clobber (match_scratch 5 ""))]
16923
  "reload_completed"
16924
  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16925
              (use (match_dup 2))
16926
              (use (match_dup 3))
16927
              (clobber (match_dup 5))])]
16928
  "")
16929
 
16930
(define_insn "fist2_floor"
16931
  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16932
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16933
         UNSPEC_FIST_FLOOR))
16934
   (use (match_operand:HI 2 "memory_operand" "m"))
16935
   (use (match_operand:HI 3 "memory_operand" "m"))]
16936
  "TARGET_USE_FANCY_MATH_387
16937
   && flag_unsafe_math_optimizations"
16938
  "* return output_fix_trunc (insn, operands, 0);"
16939
  [(set_attr "type" "fistp")
16940
   (set_attr "i387_cw" "floor")
16941
   (set_attr "mode" "")])
16942
 
16943
(define_insn "fist2_floor_with_temp"
16944
  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16945
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16946
         UNSPEC_FIST_FLOOR))
16947
   (use (match_operand:HI 2 "memory_operand" "m,m"))
16948
   (use (match_operand:HI 3 "memory_operand" "m,m"))
16949
   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
16950
  "TARGET_USE_FANCY_MATH_387
16951
   && flag_unsafe_math_optimizations"
16952
  "#"
16953
  [(set_attr "type" "fistp")
16954
   (set_attr "i387_cw" "floor")
16955
   (set_attr "mode" "")])
16956
 
16957
(define_split
16958
  [(set (match_operand:X87MODEI12 0 "register_operand" "")
16959
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16960
         UNSPEC_FIST_FLOOR))
16961
   (use (match_operand:HI 2 "memory_operand" ""))
16962
   (use (match_operand:HI 3 "memory_operand" ""))
16963
   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16964
  "reload_completed"
16965
  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16966
                                  UNSPEC_FIST_FLOOR))
16967
              (use (match_dup 2))
16968
              (use (match_dup 3))])
16969
   (set (match_dup 0) (match_dup 4))]
16970
  "")
16971
 
16972
(define_split
16973
  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16974
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16975
         UNSPEC_FIST_FLOOR))
16976
   (use (match_operand:HI 2 "memory_operand" ""))
16977
   (use (match_operand:HI 3 "memory_operand" ""))
16978
   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16979
  "reload_completed"
16980
  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16981
                                  UNSPEC_FIST_FLOOR))
16982
              (use (match_dup 2))
16983
              (use (match_dup 3))])]
16984
  "")
16985
 
16986
(define_expand "lfloorxf2"
16987
  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16988
                   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16989
                    UNSPEC_FIST_FLOOR))
16990
              (clobber (reg:CC FLAGS_REG))])]
16991
  "TARGET_USE_FANCY_MATH_387
16992
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16993
   && flag_unsafe_math_optimizations"
16994
  "")
16995
 
16996
(define_expand "lfloor2"
16997
  [(match_operand:SWI48 0 "nonimmediate_operand" "")
16998
   (match_operand:MODEF 1 "register_operand" "")]
16999
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
17000
   && !flag_trapping_math"
17001
{
17002
  if (TARGET_64BIT && optimize_insn_for_size_p ())
17003
    FAIL;
17004
  ix86_expand_lfloorceil (operand0, operand1, true);
17005
  DONE;
17006
})
17007
 
17008
;; Rounding mode control word calculation could clobber FLAGS_REG.
17009
(define_insn_and_split "frndintxf2_ceil"
17010
  [(set (match_operand:XF 0 "register_operand" "")
17011
        (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17012
         UNSPEC_FRNDINT_CEIL))
17013
   (clobber (reg:CC FLAGS_REG))]
17014
  "TARGET_USE_FANCY_MATH_387
17015
   && flag_unsafe_math_optimizations
17016
   && can_create_pseudo_p ()"
17017
  "#"
17018
  "&& 1"
17019
  [(const_int 0)]
17020
{
17021
  ix86_optimize_mode_switching[I387_CEIL] = 1;
17022
 
17023
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17024
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17025
 
17026
  emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17027
                                       operands[2], operands[3]));
17028
  DONE;
17029
}
17030
  [(set_attr "type" "frndint")
17031
   (set_attr "i387_cw" "ceil")
17032
   (set_attr "mode" "XF")])
17033
 
17034
(define_insn "frndintxf2_ceil_i387"
17035
  [(set (match_operand:XF 0 "register_operand" "=f")
17036
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17037
         UNSPEC_FRNDINT_CEIL))
17038
   (use (match_operand:HI 2 "memory_operand" "m"))
17039
   (use (match_operand:HI 3 "memory_operand" "m"))]
17040
  "TARGET_USE_FANCY_MATH_387
17041
   && flag_unsafe_math_optimizations"
17042
  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17043
  [(set_attr "type" "frndint")
17044
   (set_attr "i387_cw" "ceil")
17045
   (set_attr "mode" "XF")])
17046
 
17047
(define_expand "ceilxf2"
17048
  [(use (match_operand:XF 0 "register_operand" ""))
17049
   (use (match_operand:XF 1 "register_operand" ""))]
17050
  "TARGET_USE_FANCY_MATH_387
17051
   && flag_unsafe_math_optimizations"
17052
{
17053
  if (optimize_insn_for_size_p ())
17054
    FAIL;
17055
  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17056
  DONE;
17057
})
17058
 
17059
(define_expand "ceil2"
17060
  [(use (match_operand:MODEF 0 "register_operand" ""))
17061
   (use (match_operand:MODEF 1 "register_operand" ""))]
17062
  "(TARGET_USE_FANCY_MATH_387
17063
    && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
17064
        || TARGET_MIX_SSE_I387)
17065
    && flag_unsafe_math_optimizations)
17066
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
17067
       && !flag_trapping_math)"
17068
{
17069
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
17070
      && !flag_trapping_math
17071
      && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17072
    {
17073
      if (TARGET_ROUND)
17074
        emit_insn (gen_sse4_1_round2
17075
                   (operands[0], operands[1], GEN_INT (0x02)));
17076
      else if (optimize_insn_for_size_p ())
17077
        FAIL;
17078
      else if (TARGET_64BIT || (mode != DFmode))
17079
        ix86_expand_floorceil (operand0, operand1, false);
17080
      else
17081
        ix86_expand_floorceildf_32 (operand0, operand1, false);
17082
    }
17083
  else
17084
    {
17085
      rtx op0, op1;
17086
 
17087
      if (optimize_insn_for_size_p ())
17088
        FAIL;
17089
 
17090
      op0 = gen_reg_rtx (XFmode);
17091
      op1 = gen_reg_rtx (XFmode);
17092
      emit_insn (gen_extendxf2 (op1, operands[1]));
17093
      emit_insn (gen_frndintxf2_ceil (op0, op1));
17094
 
17095
      emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
17096
    }
17097
  DONE;
17098
})
17099
 
17100
(define_insn_and_split "*fist2_ceil_1"
17101
  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17102
        (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17103
         UNSPEC_FIST_CEIL))
17104
   (clobber (reg:CC FLAGS_REG))]
17105
  "TARGET_USE_FANCY_MATH_387
17106
   && flag_unsafe_math_optimizations
17107
   && can_create_pseudo_p ()"
17108
  "#"
17109
  "&& 1"
17110
  [(const_int 0)]
17111
{
17112
  ix86_optimize_mode_switching[I387_CEIL] = 1;
17113
 
17114
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17115
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17116
  if (memory_operand (operands[0], VOIDmode))
17117
    emit_insn (gen_fist2_ceil (operands[0], operands[1],
17118
                                     operands[2], operands[3]));
17119
  else
17120
    {
17121
      operands[4] = assign_386_stack_local (mode, SLOT_TEMP);
17122
      emit_insn (gen_fist2_ceil_with_temp (operands[0], operands[1],
17123
                                                 operands[2], operands[3],
17124
                                                 operands[4]));
17125
    }
17126
  DONE;
17127
}
17128
  [(set_attr "type" "fistp")
17129
   (set_attr "i387_cw" "ceil")
17130
   (set_attr "mode" "")])
17131
 
17132
(define_insn "fistdi2_ceil"
17133
  [(set (match_operand:DI 0 "memory_operand" "=m")
17134
        (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17135
         UNSPEC_FIST_CEIL))
17136
   (use (match_operand:HI 2 "memory_operand" "m"))
17137
   (use (match_operand:HI 3 "memory_operand" "m"))
17138
   (clobber (match_scratch:XF 4 "=&1f"))]
17139
  "TARGET_USE_FANCY_MATH_387
17140
   && flag_unsafe_math_optimizations"
17141
  "* return output_fix_trunc (insn, operands, 0);"
17142
  [(set_attr "type" "fistp")
17143
   (set_attr "i387_cw" "ceil")
17144
   (set_attr "mode" "DI")])
17145
 
17146
(define_insn "fistdi2_ceil_with_temp"
17147
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17148
        (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17149
         UNSPEC_FIST_CEIL))
17150
   (use (match_operand:HI 2 "memory_operand" "m,m"))
17151
   (use (match_operand:HI 3 "memory_operand" "m,m"))
17152
   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17153
   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17154
  "TARGET_USE_FANCY_MATH_387
17155
   && flag_unsafe_math_optimizations"
17156
  "#"
17157
  [(set_attr "type" "fistp")
17158
   (set_attr "i387_cw" "ceil")
17159
   (set_attr "mode" "DI")])
17160
 
17161
(define_split
17162
  [(set (match_operand:DI 0 "register_operand" "")
17163
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17164
         UNSPEC_FIST_CEIL))
17165
   (use (match_operand:HI 2 "memory_operand" ""))
17166
   (use (match_operand:HI 3 "memory_operand" ""))
17167
   (clobber (match_operand:DI 4 "memory_operand" ""))
17168
   (clobber (match_scratch 5 ""))]
17169
  "reload_completed"
17170
  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17171
              (use (match_dup 2))
17172
              (use (match_dup 3))
17173
              (clobber (match_dup 5))])
17174
   (set (match_dup 0) (match_dup 4))]
17175
  "")
17176
 
17177
(define_split
17178
  [(set (match_operand:DI 0 "memory_operand" "")
17179
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17180
         UNSPEC_FIST_CEIL))
17181
   (use (match_operand:HI 2 "memory_operand" ""))
17182
   (use (match_operand:HI 3 "memory_operand" ""))
17183
   (clobber (match_operand:DI 4 "memory_operand" ""))
17184
   (clobber (match_scratch 5 ""))]
17185
  "reload_completed"
17186
  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17187
              (use (match_dup 2))
17188
              (use (match_dup 3))
17189
              (clobber (match_dup 5))])]
17190
  "")
17191
 
17192
(define_insn "fist2_ceil"
17193
  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17194
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17195
         UNSPEC_FIST_CEIL))
17196
   (use (match_operand:HI 2 "memory_operand" "m"))
17197
   (use (match_operand:HI 3 "memory_operand" "m"))]
17198
  "TARGET_USE_FANCY_MATH_387
17199
   && flag_unsafe_math_optimizations"
17200
  "* return output_fix_trunc (insn, operands, 0);"
17201
  [(set_attr "type" "fistp")
17202
   (set_attr "i387_cw" "ceil")
17203
   (set_attr "mode" "")])
17204
 
17205
(define_insn "fist2_ceil_with_temp"
17206
  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17207
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17208
         UNSPEC_FIST_CEIL))
17209
   (use (match_operand:HI 2 "memory_operand" "m,m"))
17210
   (use (match_operand:HI 3 "memory_operand" "m,m"))
17211
   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17212
  "TARGET_USE_FANCY_MATH_387
17213
   && flag_unsafe_math_optimizations"
17214
  "#"
17215
  [(set_attr "type" "fistp")
17216
   (set_attr "i387_cw" "ceil")
17217
   (set_attr "mode" "")])
17218
 
17219
(define_split
17220
  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17221
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17222
         UNSPEC_FIST_CEIL))
17223
   (use (match_operand:HI 2 "memory_operand" ""))
17224
   (use (match_operand:HI 3 "memory_operand" ""))
17225
   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17226
  "reload_completed"
17227
  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17228
                                  UNSPEC_FIST_CEIL))
17229
              (use (match_dup 2))
17230
              (use (match_dup 3))])
17231
   (set (match_dup 0) (match_dup 4))]
17232
  "")
17233
 
17234
(define_split
17235
  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17236
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17237
         UNSPEC_FIST_CEIL))
17238
   (use (match_operand:HI 2 "memory_operand" ""))
17239
   (use (match_operand:HI 3 "memory_operand" ""))
17240
   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17241
  "reload_completed"
17242
  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17243
                                  UNSPEC_FIST_CEIL))
17244
              (use (match_dup 2))
17245
              (use (match_dup 3))])]
17246
  "")
17247
 
17248
(define_expand "lceilxf2"
17249
  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17250
                   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17251
                    UNSPEC_FIST_CEIL))
17252
              (clobber (reg:CC FLAGS_REG))])]
17253
  "TARGET_USE_FANCY_MATH_387
17254
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17255
   && flag_unsafe_math_optimizations"
17256
  "")
17257
 
17258
(define_expand "lceil2"
17259
  [(match_operand:SWI48 0 "nonimmediate_operand" "")
17260
   (match_operand:MODEF 1 "register_operand" "")]
17261
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
17262
   && !flag_trapping_math"
17263
{
17264
  ix86_expand_lfloorceil (operand0, operand1, false);
17265
  DONE;
17266
})
17267
 
17268
;; Rounding mode control word calculation could clobber FLAGS_REG.
17269
(define_insn_and_split "frndintxf2_trunc"
17270
  [(set (match_operand:XF 0 "register_operand" "")
17271
        (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17272
         UNSPEC_FRNDINT_TRUNC))
17273
   (clobber (reg:CC FLAGS_REG))]
17274
  "TARGET_USE_FANCY_MATH_387
17275
   && flag_unsafe_math_optimizations
17276
   && can_create_pseudo_p ()"
17277
  "#"
17278
  "&& 1"
17279
  [(const_int 0)]
17280
{
17281
  ix86_optimize_mode_switching[I387_TRUNC] = 1;
17282
 
17283
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17284
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17285
 
17286
  emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17287
                                        operands[2], operands[3]));
17288
  DONE;
17289
}
17290
  [(set_attr "type" "frndint")
17291
   (set_attr "i387_cw" "trunc")
17292
   (set_attr "mode" "XF")])
17293
 
17294
(define_insn "frndintxf2_trunc_i387"
17295
  [(set (match_operand:XF 0 "register_operand" "=f")
17296
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17297
         UNSPEC_FRNDINT_TRUNC))
17298
   (use (match_operand:HI 2 "memory_operand" "m"))
17299
   (use (match_operand:HI 3 "memory_operand" "m"))]
17300
  "TARGET_USE_FANCY_MATH_387
17301
   && flag_unsafe_math_optimizations"
17302
  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17303
  [(set_attr "type" "frndint")
17304
   (set_attr "i387_cw" "trunc")
17305
   (set_attr "mode" "XF")])
17306
 
17307
(define_expand "btruncxf2"
17308
  [(use (match_operand:XF 0 "register_operand" ""))
17309
   (use (match_operand:XF 1 "register_operand" ""))]
17310
  "TARGET_USE_FANCY_MATH_387
17311
   && flag_unsafe_math_optimizations"
17312
{
17313
  if (optimize_insn_for_size_p ())
17314
    FAIL;
17315
  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17316
  DONE;
17317
})
17318
 
17319
(define_expand "btrunc2"
17320
  [(use (match_operand:MODEF 0 "register_operand" ""))
17321
   (use (match_operand:MODEF 1 "register_operand" ""))]
17322
  "(TARGET_USE_FANCY_MATH_387
17323
    && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
17324
        || TARGET_MIX_SSE_I387)
17325
    && flag_unsafe_math_optimizations)
17326
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
17327
       && !flag_trapping_math)"
17328
{
17329
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
17330
      && !flag_trapping_math
17331
      && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17332
    {
17333
      if (TARGET_ROUND)
17334
        emit_insn (gen_sse4_1_round2
17335
                   (operands[0], operands[1], GEN_INT (0x03)));
17336
      else if (optimize_insn_for_size_p ())
17337
        FAIL;
17338
      else if (TARGET_64BIT || (mode != DFmode))
17339
        ix86_expand_trunc (operand0, operand1);
17340
      else
17341
        ix86_expand_truncdf_32 (operand0, operand1);
17342
    }
17343
  else
17344
    {
17345
      rtx op0, op1;
17346
 
17347
      if (optimize_insn_for_size_p ())
17348
        FAIL;
17349
 
17350
      op0 = gen_reg_rtx (XFmode);
17351
      op1 = gen_reg_rtx (XFmode);
17352
      emit_insn (gen_extendxf2 (op1, operands[1]));
17353
      emit_insn (gen_frndintxf2_trunc (op0, op1));
17354
 
17355
      emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
17356
    }
17357
  DONE;
17358
})
17359
 
17360
;; Rounding mode control word calculation could clobber FLAGS_REG.
17361
(define_insn_and_split "frndintxf2_mask_pm"
17362
  [(set (match_operand:XF 0 "register_operand" "")
17363
        (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17364
         UNSPEC_FRNDINT_MASK_PM))
17365
   (clobber (reg:CC FLAGS_REG))]
17366
  "TARGET_USE_FANCY_MATH_387
17367
   && flag_unsafe_math_optimizations
17368
   && can_create_pseudo_p ()"
17369
  "#"
17370
  "&& 1"
17371
  [(const_int 0)]
17372
{
17373
  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17374
 
17375
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17376
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17377
 
17378
  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17379
                                          operands[2], operands[3]));
17380
  DONE;
17381
}
17382
  [(set_attr "type" "frndint")
17383
   (set_attr "i387_cw" "mask_pm")
17384
   (set_attr "mode" "XF")])
17385
 
17386
(define_insn "frndintxf2_mask_pm_i387"
17387
  [(set (match_operand:XF 0 "register_operand" "=f")
17388
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17389
         UNSPEC_FRNDINT_MASK_PM))
17390
   (use (match_operand:HI 2 "memory_operand" "m"))
17391
   (use (match_operand:HI 3 "memory_operand" "m"))]
17392
  "TARGET_USE_FANCY_MATH_387
17393
   && flag_unsafe_math_optimizations"
17394
  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17395
  [(set_attr "type" "frndint")
17396
   (set_attr "i387_cw" "mask_pm")
17397
   (set_attr "mode" "XF")])
17398
 
17399
(define_expand "nearbyintxf2"
17400
  [(use (match_operand:XF 0 "register_operand" ""))
17401
   (use (match_operand:XF 1 "register_operand" ""))]
17402
  "TARGET_USE_FANCY_MATH_387
17403
   && flag_unsafe_math_optimizations"
17404
{
17405
  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17406
 
17407
  DONE;
17408
})
17409
 
17410
(define_expand "nearbyint2"
17411
  [(use (match_operand:MODEF 0 "register_operand" ""))
17412
   (use (match_operand:MODEF 1 "register_operand" ""))]
17413
  "TARGET_USE_FANCY_MATH_387
17414
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
17415
       || TARGET_MIX_SSE_I387)
17416
   && flag_unsafe_math_optimizations"
17417
{
17418
  rtx op0 = gen_reg_rtx (XFmode);
17419
  rtx op1 = gen_reg_rtx (XFmode);
17420
 
17421
  emit_insn (gen_extendxf2 (op1, operands[1]));
17422
  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17423
 
17424
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
17425
  DONE;
17426
})
17427
 
17428
(define_insn "fxam2_i387"
17429
  [(set (match_operand:HI 0 "register_operand" "=a")
17430
        (unspec:HI
17431
          [(match_operand:X87MODEF 1 "register_operand" "f")]
17432
          UNSPEC_FXAM))]
17433
  "TARGET_USE_FANCY_MATH_387"
17434
  "fxam\n\tfnstsw\t%0"
17435
  [(set_attr "type" "multi")
17436
   (set_attr "length" "4")
17437
   (set_attr "unit" "i387")
17438
   (set_attr "mode" "")])
17439
 
17440
(define_insn_and_split "fxam2_i387_with_temp"
17441
  [(set (match_operand:HI 0 "register_operand" "")
17442
        (unspec:HI
17443
          [(match_operand:MODEF 1 "memory_operand" "")]
17444
          UNSPEC_FXAM_MEM))]
17445
  "TARGET_USE_FANCY_MATH_387
17446
   && can_create_pseudo_p ()"
17447
  "#"
17448
  "&& 1"
17449
  [(set (match_dup 2)(match_dup 1))
17450
   (set (match_dup 0)
17451
        (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17452
{
17453
  operands[2] = gen_reg_rtx (mode);
17454
 
17455
  MEM_VOLATILE_P (operands[1]) = 1;
17456
}
17457
  [(set_attr "type" "multi")
17458
   (set_attr "unit" "i387")
17459
   (set_attr "mode" "")])
17460
 
17461
(define_expand "isinfxf2"
17462
  [(use (match_operand:SI 0 "register_operand" ""))
17463
   (use (match_operand:XF 1 "register_operand" ""))]
17464
  "TARGET_USE_FANCY_MATH_387
17465
   && TARGET_C99_FUNCTIONS"
17466
{
17467
  rtx mask = GEN_INT (0x45);
17468
  rtx val = GEN_INT (0x05);
17469
 
17470
  rtx cond;
17471
 
17472
  rtx scratch = gen_reg_rtx (HImode);
17473
  rtx res = gen_reg_rtx (QImode);
17474
 
17475
  emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17476
 
17477
  emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17478
  emit_insn (gen_cmpqi_ext_3 (scratch, val));
17479
  cond = gen_rtx_fmt_ee (EQ, QImode,
17480
                         gen_rtx_REG (CCmode, FLAGS_REG),
17481
                         const0_rtx);
17482
  emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17483
  emit_insn (gen_zero_extendqisi2 (operands[0], res));
17484
  DONE;
17485
})
17486
 
17487
(define_expand "isinf2"
17488
  [(use (match_operand:SI 0 "register_operand" ""))
17489
   (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
17490
  "TARGET_USE_FANCY_MATH_387
17491
   && TARGET_C99_FUNCTIONS
17492
   && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
17493
{
17494
  rtx mask = GEN_INT (0x45);
17495
  rtx val = GEN_INT (0x05);
17496
 
17497
  rtx cond;
17498
 
17499
  rtx scratch = gen_reg_rtx (HImode);
17500
  rtx res = gen_reg_rtx (QImode);
17501
 
17502
  /* Remove excess precision by forcing value through memory. */
17503
  if (memory_operand (operands[1], VOIDmode))
17504
    emit_insn (gen_fxam2_i387_with_temp (scratch, operands[1]));
17505
  else
17506
    {
17507
      enum ix86_stack_slot slot = (virtuals_instantiated
17508
                                   ? SLOT_TEMP
17509
                                   : SLOT_VIRTUAL);
17510
      rtx temp = assign_386_stack_local (mode, slot);
17511
 
17512
      emit_move_insn (temp, operands[1]);
17513
      emit_insn (gen_fxam2_i387_with_temp (scratch, temp));
17514
    }
17515
 
17516
  emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17517
  emit_insn (gen_cmpqi_ext_3 (scratch, val));
17518
  cond = gen_rtx_fmt_ee (EQ, QImode,
17519
                         gen_rtx_REG (CCmode, FLAGS_REG),
17520
                         const0_rtx);
17521
  emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17522
  emit_insn (gen_zero_extendqisi2 (operands[0], res));
17523
  DONE;
17524
})
17525
 
17526
(define_expand "signbit2"
17527
  [(use (match_operand:SI 0 "register_operand" ""))
17528
   (use (match_operand:X87MODEF 1 "register_operand" ""))]
17529
  "TARGET_USE_FANCY_MATH_387
17530
   && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
17531
{
17532
  rtx mask = GEN_INT (0x0200);
17533
 
17534
  rtx scratch = gen_reg_rtx (HImode);
17535
 
17536
  emit_insn (gen_fxam2_i387 (scratch, operands[1]));
17537
  emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
17538
  DONE;
17539
})
17540
 
17541
;; Block operation instructions
17542
 
17543
(define_insn "cld"
17544
  [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17545
  ""
17546
  "cld"
17547
  [(set_attr "length" "1")
17548
   (set_attr "length_immediate" "0")
17549
   (set_attr "modrm" "0")])
17550
 
17551
(define_expand "movmemsi"
17552
  [(use (match_operand:BLK 0 "memory_operand" ""))
17553
   (use (match_operand:BLK 1 "memory_operand" ""))
17554
   (use (match_operand:SI 2 "nonmemory_operand" ""))
17555
   (use (match_operand:SI 3 "const_int_operand" ""))
17556
   (use (match_operand:SI 4 "const_int_operand" ""))
17557
   (use (match_operand:SI 5 "const_int_operand" ""))]
17558
  ""
17559
{
17560
 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17561
                         operands[4], operands[5]))
17562
   DONE;
17563
 else
17564
   FAIL;
17565
})
17566
 
17567
(define_expand "movmemdi"
17568
  [(use (match_operand:BLK 0 "memory_operand" ""))
17569
   (use (match_operand:BLK 1 "memory_operand" ""))
17570
   (use (match_operand:DI 2 "nonmemory_operand" ""))
17571
   (use (match_operand:DI 3 "const_int_operand" ""))
17572
   (use (match_operand:SI 4 "const_int_operand" ""))
17573
   (use (match_operand:SI 5 "const_int_operand" ""))]
17574
  "TARGET_64BIT"
17575
{
17576
 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17577
                         operands[4], operands[5]))
17578
   DONE;
17579
 else
17580
   FAIL;
17581
})
17582
 
17583
;; Most CPUs don't like single string operations
17584
;; Handle this case here to simplify previous expander.
17585
 
17586
(define_expand "strmov"
17587
  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17588
   (set (match_operand 1 "memory_operand" "") (match_dup 4))
17589
   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17590
              (clobber (reg:CC FLAGS_REG))])
17591
   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17592
              (clobber (reg:CC FLAGS_REG))])]
17593
  ""
17594
{
17595
  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17596
 
17597
  /* If .md ever supports :P for Pmode, these can be directly
17598
     in the pattern above.  */
17599
  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17600
  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17601
 
17602
  /* Can't use this if the user has appropriated esi or edi.  */
17603
  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17604
      && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17605
    {
17606
      emit_insn (gen_strmov_singleop (operands[0], operands[1],
17607
                                      operands[2], operands[3],
17608
                                      operands[5], operands[6]));
17609
      DONE;
17610
    }
17611
 
17612
  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17613
})
17614
 
17615
(define_expand "strmov_singleop"
17616
  [(parallel [(set (match_operand 1 "memory_operand" "")
17617
                   (match_operand 3 "memory_operand" ""))
17618
              (set (match_operand 0 "register_operand" "")
17619
                   (match_operand 4 "" ""))
17620
              (set (match_operand 2 "register_operand" "")
17621
                   (match_operand 5 "" ""))])]
17622
  ""
17623
  "ix86_current_function_needs_cld = 1;")
17624
 
17625
(define_insn "*strmovdi_rex_1"
17626
  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17627
        (mem:DI (match_operand:DI 3 "register_operand" "1")))
17628
   (set (match_operand:DI 0 "register_operand" "=D")
17629
        (plus:DI (match_dup 2)
17630
                 (const_int 8)))
17631
   (set (match_operand:DI 1 "register_operand" "=S")
17632
        (plus:DI (match_dup 3)
17633
                 (const_int 8)))]
17634
  "TARGET_64BIT"
17635
  "movsq"
17636
  [(set_attr "type" "str")
17637
   (set_attr "mode" "DI")
17638
   (set_attr "memory" "both")])
17639
 
17640
(define_insn "*strmovsi_1"
17641
  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17642
        (mem:SI (match_operand:SI 3 "register_operand" "1")))
17643
   (set (match_operand:SI 0 "register_operand" "=D")
17644
        (plus:SI (match_dup 2)
17645
                 (const_int 4)))
17646
   (set (match_operand:SI 1 "register_operand" "=S")
17647
        (plus:SI (match_dup 3)
17648
                 (const_int 4)))]
17649
  "!TARGET_64BIT"
17650
  "movs{l|d}"
17651
  [(set_attr "type" "str")
17652
   (set_attr "mode" "SI")
17653
   (set_attr "memory" "both")])
17654
 
17655
(define_insn "*strmovsi_rex_1"
17656
  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17657
        (mem:SI (match_operand:DI 3 "register_operand" "1")))
17658
   (set (match_operand:DI 0 "register_operand" "=D")
17659
        (plus:DI (match_dup 2)
17660
                 (const_int 4)))
17661
   (set (match_operand:DI 1 "register_operand" "=S")
17662
        (plus:DI (match_dup 3)
17663
                 (const_int 4)))]
17664
  "TARGET_64BIT"
17665
  "movs{l|d}"
17666
  [(set_attr "type" "str")
17667
   (set_attr "mode" "SI")
17668
   (set_attr "memory" "both")])
17669
 
17670
(define_insn "*strmovhi_1"
17671
  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17672
        (mem:HI (match_operand:SI 3 "register_operand" "1")))
17673
   (set (match_operand:SI 0 "register_operand" "=D")
17674
        (plus:SI (match_dup 2)
17675
                 (const_int 2)))
17676
   (set (match_operand:SI 1 "register_operand" "=S")
17677
        (plus:SI (match_dup 3)
17678
                 (const_int 2)))]
17679
  "!TARGET_64BIT"
17680
  "movsw"
17681
  [(set_attr "type" "str")
17682
   (set_attr "memory" "both")
17683
   (set_attr "mode" "HI")])
17684
 
17685
(define_insn "*strmovhi_rex_1"
17686
  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17687
        (mem:HI (match_operand:DI 3 "register_operand" "1")))
17688
   (set (match_operand:DI 0 "register_operand" "=D")
17689
        (plus:DI (match_dup 2)
17690
                 (const_int 2)))
17691
   (set (match_operand:DI 1 "register_operand" "=S")
17692
        (plus:DI (match_dup 3)
17693
                 (const_int 2)))]
17694
  "TARGET_64BIT"
17695
  "movsw"
17696
  [(set_attr "type" "str")
17697
   (set_attr "memory" "both")
17698
   (set_attr "mode" "HI")])
17699
 
17700
(define_insn "*strmovqi_1"
17701
  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17702
        (mem:QI (match_operand:SI 3 "register_operand" "1")))
17703
   (set (match_operand:SI 0 "register_operand" "=D")
17704
        (plus:SI (match_dup 2)
17705
                 (const_int 1)))
17706
   (set (match_operand:SI 1 "register_operand" "=S")
17707
        (plus:SI (match_dup 3)
17708
                 (const_int 1)))]
17709
  "!TARGET_64BIT"
17710
  "movsb"
17711
  [(set_attr "type" "str")
17712
   (set_attr "memory" "both")
17713
   (set_attr "mode" "QI")])
17714
 
17715
(define_insn "*strmovqi_rex_1"
17716
  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17717
        (mem:QI (match_operand:DI 3 "register_operand" "1")))
17718
   (set (match_operand:DI 0 "register_operand" "=D")
17719
        (plus:DI (match_dup 2)
17720
                 (const_int 1)))
17721
   (set (match_operand:DI 1 "register_operand" "=S")
17722
        (plus:DI (match_dup 3)
17723
                 (const_int 1)))]
17724
  "TARGET_64BIT"
17725
  "movsb"
17726
  [(set_attr "type" "str")
17727
   (set_attr "memory" "both")
17728
   (set_attr "prefix_rex" "0")
17729
   (set_attr "mode" "QI")])
17730
 
17731
(define_expand "rep_mov"
17732
  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17733
              (set (match_operand 0 "register_operand" "")
17734
                   (match_operand 5 "" ""))
17735
              (set (match_operand 2 "register_operand" "")
17736
                   (match_operand 6 "" ""))
17737
              (set (match_operand 1 "memory_operand" "")
17738
                   (match_operand 3 "memory_operand" ""))
17739
              (use (match_dup 4))])]
17740
  ""
17741
  "ix86_current_function_needs_cld = 1;")
17742
 
17743
(define_insn "*rep_movdi_rex64"
17744
  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17745
   (set (match_operand:DI 0 "register_operand" "=D")
17746
        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17747
                            (const_int 3))
17748
                 (match_operand:DI 3 "register_operand" "0")))
17749
   (set (match_operand:DI 1 "register_operand" "=S")
17750
        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17751
                 (match_operand:DI 4 "register_operand" "1")))
17752
   (set (mem:BLK (match_dup 3))
17753
        (mem:BLK (match_dup 4)))
17754
   (use (match_dup 5))]
17755
  "TARGET_64BIT"
17756
  "rep{%;} movsq"
17757
  [(set_attr "type" "str")
17758
   (set_attr "prefix_rep" "1")
17759
   (set_attr "memory" "both")
17760
   (set_attr "mode" "DI")])
17761
 
17762
(define_insn "*rep_movsi"
17763
  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17764
   (set (match_operand:SI 0 "register_operand" "=D")
17765
        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17766
                            (const_int 2))
17767
                 (match_operand:SI 3 "register_operand" "0")))
17768
   (set (match_operand:SI 1 "register_operand" "=S")
17769
        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17770
                 (match_operand:SI 4 "register_operand" "1")))
17771
   (set (mem:BLK (match_dup 3))
17772
        (mem:BLK (match_dup 4)))
17773
   (use (match_dup 5))]
17774
  "!TARGET_64BIT"
17775
  "rep{%;} movs{l|d}"
17776
  [(set_attr "type" "str")
17777
   (set_attr "prefix_rep" "1")
17778
   (set_attr "memory" "both")
17779
   (set_attr "mode" "SI")])
17780
 
17781
(define_insn "*rep_movsi_rex64"
17782
  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17783
   (set (match_operand:DI 0 "register_operand" "=D")
17784
        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17785
                            (const_int 2))
17786
                 (match_operand:DI 3 "register_operand" "0")))
17787
   (set (match_operand:DI 1 "register_operand" "=S")
17788
        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17789
                 (match_operand:DI 4 "register_operand" "1")))
17790
   (set (mem:BLK (match_dup 3))
17791
        (mem:BLK (match_dup 4)))
17792
   (use (match_dup 5))]
17793
  "TARGET_64BIT"
17794
  "rep{%;} movs{l|d}"
17795
  [(set_attr "type" "str")
17796
   (set_attr "prefix_rep" "1")
17797
   (set_attr "memory" "both")
17798
   (set_attr "mode" "SI")])
17799
 
17800
(define_insn "*rep_movqi"
17801
  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17802
   (set (match_operand:SI 0 "register_operand" "=D")
17803
        (plus:SI (match_operand:SI 3 "register_operand" "0")
17804
                 (match_operand:SI 5 "register_operand" "2")))
17805
   (set (match_operand:SI 1 "register_operand" "=S")
17806
        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17807
   (set (mem:BLK (match_dup 3))
17808
        (mem:BLK (match_dup 4)))
17809
   (use (match_dup 5))]
17810
  "!TARGET_64BIT"
17811
  "rep{%;} movsb"
17812
  [(set_attr "type" "str")
17813
   (set_attr "prefix_rep" "1")
17814
   (set_attr "memory" "both")
17815
   (set_attr "mode" "SI")])
17816
 
17817
(define_insn "*rep_movqi_rex64"
17818
  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17819
   (set (match_operand:DI 0 "register_operand" "=D")
17820
        (plus:DI (match_operand:DI 3 "register_operand" "0")
17821
                 (match_operand:DI 5 "register_operand" "2")))
17822
   (set (match_operand:DI 1 "register_operand" "=S")
17823
        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17824
   (set (mem:BLK (match_dup 3))
17825
        (mem:BLK (match_dup 4)))
17826
   (use (match_dup 5))]
17827
  "TARGET_64BIT"
17828
  "rep{%;} movsb"
17829
  [(set_attr "type" "str")
17830
   (set_attr "prefix_rep" "1")
17831
   (set_attr "memory" "both")
17832
   (set_attr "mode" "SI")])
17833
 
17834
(define_expand "setmemsi"
17835
   [(use (match_operand:BLK 0 "memory_operand" ""))
17836
    (use (match_operand:SI 1 "nonmemory_operand" ""))
17837
    (use (match_operand 2 "const_int_operand" ""))
17838
    (use (match_operand 3 "const_int_operand" ""))
17839
    (use (match_operand:SI 4 "const_int_operand" ""))
17840
    (use (match_operand:SI 5 "const_int_operand" ""))]
17841
  ""
17842
{
17843
 if (ix86_expand_setmem (operands[0], operands[1],
17844
                         operands[2], operands[3],
17845
                         operands[4], operands[5]))
17846
   DONE;
17847
 else
17848
   FAIL;
17849
})
17850
 
17851
(define_expand "setmemdi"
17852
   [(use (match_operand:BLK 0 "memory_operand" ""))
17853
    (use (match_operand:DI 1 "nonmemory_operand" ""))
17854
    (use (match_operand 2 "const_int_operand" ""))
17855
    (use (match_operand 3 "const_int_operand" ""))
17856
    (use (match_operand 4 "const_int_operand" ""))
17857
    (use (match_operand 5 "const_int_operand" ""))]
17858
  "TARGET_64BIT"
17859
{
17860
 if (ix86_expand_setmem (operands[0], operands[1],
17861
                         operands[2], operands[3],
17862
                         operands[4], operands[5]))
17863
   DONE;
17864
 else
17865
   FAIL;
17866
})
17867
 
17868
;; Most CPUs don't like single string operations
17869
;; Handle this case here to simplify previous expander.
17870
 
17871
(define_expand "strset"
17872
  [(set (match_operand 1 "memory_operand" "")
17873
        (match_operand 2 "register_operand" ""))
17874
   (parallel [(set (match_operand 0 "register_operand" "")
17875
                   (match_dup 3))
17876
              (clobber (reg:CC FLAGS_REG))])]
17877
  ""
17878
{
17879
  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17880
    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17881
 
17882
  /* If .md ever supports :P for Pmode, this can be directly
17883
     in the pattern above.  */
17884
  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17885
                              GEN_INT (GET_MODE_SIZE (GET_MODE
17886
                                                      (operands[2]))));
17887
  if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17888
    {
17889
      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17890
                                      operands[3]));
17891
      DONE;
17892
    }
17893
})
17894
 
17895
(define_expand "strset_singleop"
17896
  [(parallel [(set (match_operand 1 "memory_operand" "")
17897
                   (match_operand 2 "register_operand" ""))
17898
              (set (match_operand 0 "register_operand" "")
17899
                   (match_operand 3 "" ""))])]
17900
  ""
17901
  "ix86_current_function_needs_cld = 1;")
17902
 
17903
(define_insn "*strsetdi_rex_1"
17904
  [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17905
        (match_operand:DI 2 "register_operand" "a"))
17906
   (set (match_operand:DI 0 "register_operand" "=D")
17907
        (plus:DI (match_dup 1)
17908
                 (const_int 8)))]
17909
  "TARGET_64BIT"
17910
  "stosq"
17911
  [(set_attr "type" "str")
17912
   (set_attr "memory" "store")
17913
   (set_attr "mode" "DI")])
17914
 
17915
(define_insn "*strsetsi_1"
17916
  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17917
        (match_operand:SI 2 "register_operand" "a"))
17918
   (set (match_operand:SI 0 "register_operand" "=D")
17919
        (plus:SI (match_dup 1)
17920
                 (const_int 4)))]
17921
  "!TARGET_64BIT"
17922
  "stos{l|d}"
17923
  [(set_attr "type" "str")
17924
   (set_attr "memory" "store")
17925
   (set_attr "mode" "SI")])
17926
 
17927
(define_insn "*strsetsi_rex_1"
17928
  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17929
        (match_operand:SI 2 "register_operand" "a"))
17930
   (set (match_operand:DI 0 "register_operand" "=D")
17931
        (plus:DI (match_dup 1)
17932
                 (const_int 4)))]
17933
  "TARGET_64BIT"
17934
  "stos{l|d}"
17935
  [(set_attr "type" "str")
17936
   (set_attr "memory" "store")
17937
   (set_attr "mode" "SI")])
17938
 
17939
(define_insn "*strsethi_1"
17940
  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17941
        (match_operand:HI 2 "register_operand" "a"))
17942
   (set (match_operand:SI 0 "register_operand" "=D")
17943
        (plus:SI (match_dup 1)
17944
                 (const_int 2)))]
17945
  "!TARGET_64BIT"
17946
  "stosw"
17947
  [(set_attr "type" "str")
17948
   (set_attr "memory" "store")
17949
   (set_attr "mode" "HI")])
17950
 
17951
(define_insn "*strsethi_rex_1"
17952
  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17953
        (match_operand:HI 2 "register_operand" "a"))
17954
   (set (match_operand:DI 0 "register_operand" "=D")
17955
        (plus:DI (match_dup 1)
17956
                 (const_int 2)))]
17957
  "TARGET_64BIT"
17958
  "stosw"
17959
  [(set_attr "type" "str")
17960
   (set_attr "memory" "store")
17961
   (set_attr "mode" "HI")])
17962
 
17963
(define_insn "*strsetqi_1"
17964
  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17965
        (match_operand:QI 2 "register_operand" "a"))
17966
   (set (match_operand:SI 0 "register_operand" "=D")
17967
        (plus:SI (match_dup 1)
17968
                 (const_int 1)))]
17969
  "!TARGET_64BIT"
17970
  "stosb"
17971
  [(set_attr "type" "str")
17972
   (set_attr "memory" "store")
17973
   (set_attr "mode" "QI")])
17974
 
17975
(define_insn "*strsetqi_rex_1"
17976
  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17977
        (match_operand:QI 2 "register_operand" "a"))
17978
   (set (match_operand:DI 0 "register_operand" "=D")
17979
        (plus:DI (match_dup 1)
17980
                 (const_int 1)))]
17981
  "TARGET_64BIT"
17982
  "stosb"
17983
  [(set_attr "type" "str")
17984
   (set_attr "memory" "store")
17985
   (set_attr "prefix_rex" "0")
17986
   (set_attr "mode" "QI")])
17987
 
17988
(define_expand "rep_stos"
17989
  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17990
              (set (match_operand 0 "register_operand" "")
17991
                   (match_operand 4 "" ""))
17992
              (set (match_operand 2 "memory_operand" "") (const_int 0))
17993
              (use (match_operand 3 "register_operand" ""))
17994
              (use (match_dup 1))])]
17995
  ""
17996
  "ix86_current_function_needs_cld = 1;")
17997
 
17998
(define_insn "*rep_stosdi_rex64"
17999
  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18000
   (set (match_operand:DI 0 "register_operand" "=D")
18001
        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18002
                            (const_int 3))
18003
                 (match_operand:DI 3 "register_operand" "0")))
18004
   (set (mem:BLK (match_dup 3))
18005
        (const_int 0))
18006
   (use (match_operand:DI 2 "register_operand" "a"))
18007
   (use (match_dup 4))]
18008
  "TARGET_64BIT"
18009
  "rep{%;} stosq"
18010
  [(set_attr "type" "str")
18011
   (set_attr "prefix_rep" "1")
18012
   (set_attr "memory" "store")
18013
   (set_attr "mode" "DI")])
18014
 
18015
(define_insn "*rep_stossi"
18016
  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18017
   (set (match_operand:SI 0 "register_operand" "=D")
18018
        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18019
                            (const_int 2))
18020
                 (match_operand:SI 3 "register_operand" "0")))
18021
   (set (mem:BLK (match_dup 3))
18022
        (const_int 0))
18023
   (use (match_operand:SI 2 "register_operand" "a"))
18024
   (use (match_dup 4))]
18025
  "!TARGET_64BIT"
18026
  "rep{%;} stos{l|d}"
18027
  [(set_attr "type" "str")
18028
   (set_attr "prefix_rep" "1")
18029
   (set_attr "memory" "store")
18030
   (set_attr "mode" "SI")])
18031
 
18032
(define_insn "*rep_stossi_rex64"
18033
  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18034
   (set (match_operand:DI 0 "register_operand" "=D")
18035
        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18036
                            (const_int 2))
18037
                 (match_operand:DI 3 "register_operand" "0")))
18038
   (set (mem:BLK (match_dup 3))
18039
        (const_int 0))
18040
   (use (match_operand:SI 2 "register_operand" "a"))
18041
   (use (match_dup 4))]
18042
  "TARGET_64BIT"
18043
  "rep{%;} stos{l|d}"
18044
  [(set_attr "type" "str")
18045
   (set_attr "prefix_rep" "1")
18046
   (set_attr "memory" "store")
18047
   (set_attr "mode" "SI")])
18048
 
18049
(define_insn "*rep_stosqi"
18050
  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18051
   (set (match_operand:SI 0 "register_operand" "=D")
18052
        (plus:SI (match_operand:SI 3 "register_operand" "0")
18053
                 (match_operand:SI 4 "register_operand" "1")))
18054
   (set (mem:BLK (match_dup 3))
18055
        (const_int 0))
18056
   (use (match_operand:QI 2 "register_operand" "a"))
18057
   (use (match_dup 4))]
18058
  "!TARGET_64BIT"
18059
  "rep{%;} stosb"
18060
  [(set_attr "type" "str")
18061
   (set_attr "prefix_rep" "1")
18062
   (set_attr "memory" "store")
18063
   (set_attr "mode" "QI")])
18064
 
18065
(define_insn "*rep_stosqi_rex64"
18066
  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18067
   (set (match_operand:DI 0 "register_operand" "=D")
18068
        (plus:DI (match_operand:DI 3 "register_operand" "0")
18069
                 (match_operand:DI 4 "register_operand" "1")))
18070
   (set (mem:BLK (match_dup 3))
18071
        (const_int 0))
18072
   (use (match_operand:QI 2 "register_operand" "a"))
18073
   (use (match_dup 4))]
18074
  "TARGET_64BIT"
18075
  "rep{%;} stosb"
18076
  [(set_attr "type" "str")
18077
   (set_attr "prefix_rep" "1")
18078
   (set_attr "memory" "store")
18079
   (set_attr "prefix_rex" "0")
18080
   (set_attr "mode" "QI")])
18081
 
18082
(define_expand "cmpstrnsi"
18083
  [(set (match_operand:SI 0 "register_operand" "")
18084
        (compare:SI (match_operand:BLK 1 "general_operand" "")
18085
                    (match_operand:BLK 2 "general_operand" "")))
18086
   (use (match_operand 3 "general_operand" ""))
18087
   (use (match_operand 4 "immediate_operand" ""))]
18088
  ""
18089
{
18090
  rtx addr1, addr2, out, outlow, count, countreg, align;
18091
 
18092
  if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18093
    FAIL;
18094
 
18095
  /* Can't use this if the user has appropriated esi or edi.  */
18096
  if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18097
    FAIL;
18098
 
18099
  out = operands[0];
18100
  if (!REG_P (out))
18101
    out = gen_reg_rtx (SImode);
18102
 
18103
  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18104
  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18105
  if (addr1 != XEXP (operands[1], 0))
18106
    operands[1] = replace_equiv_address_nv (operands[1], addr1);
18107
  if (addr2 != XEXP (operands[2], 0))
18108
    operands[2] = replace_equiv_address_nv (operands[2], addr2);
18109
 
18110
  count = operands[3];
18111
  countreg = ix86_zero_extend_to_Pmode (count);
18112
 
18113
  /* %%% Iff we are testing strict equality, we can use known alignment
18114
     to good advantage.  This may be possible with combine, particularly
18115
     once cc0 is dead.  */
18116
  align = operands[4];
18117
 
18118
  if (CONST_INT_P (count))
18119
    {
18120
      if (INTVAL (count) == 0)
18121
        {
18122
          emit_move_insn (operands[0], const0_rtx);
18123
          DONE;
18124
        }
18125
      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18126
                                     operands[1], operands[2]));
18127
    }
18128
  else
18129
    {
18130
      rtx (*cmp_insn)(rtx, rtx);
18131
 
18132
      if (TARGET_64BIT)
18133
        cmp_insn = gen_cmpdi_1;
18134
      else
18135
        cmp_insn = gen_cmpsi_1;
18136
      emit_insn (cmp_insn (countreg, countreg));
18137
      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18138
                                  operands[1], operands[2]));
18139
    }
18140
 
18141
  outlow = gen_lowpart (QImode, out);
18142
  emit_insn (gen_cmpintqi (outlow));
18143
  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18144
 
18145
  if (operands[0] != out)
18146
    emit_move_insn (operands[0], out);
18147
 
18148
  DONE;
18149
})
18150
 
18151
;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18152
 
18153
(define_expand "cmpintqi"
18154
  [(set (match_dup 1)
18155
        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18156
   (set (match_dup 2)
18157
        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18158
   (parallel [(set (match_operand:QI 0 "register_operand" "")
18159
                   (minus:QI (match_dup 1)
18160
                             (match_dup 2)))
18161
              (clobber (reg:CC FLAGS_REG))])]
18162
  ""
18163
  "operands[1] = gen_reg_rtx (QImode);
18164
   operands[2] = gen_reg_rtx (QImode);")
18165
 
18166
;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18167
;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18168
 
18169
(define_expand "cmpstrnqi_nz_1"
18170
  [(parallel [(set (reg:CC FLAGS_REG)
18171
                   (compare:CC (match_operand 4 "memory_operand" "")
18172
                               (match_operand 5 "memory_operand" "")))
18173
              (use (match_operand 2 "register_operand" ""))
18174
              (use (match_operand:SI 3 "immediate_operand" ""))
18175
              (clobber (match_operand 0 "register_operand" ""))
18176
              (clobber (match_operand 1 "register_operand" ""))
18177
              (clobber (match_dup 2))])]
18178
  ""
18179
  "ix86_current_function_needs_cld = 1;")
18180
 
18181
(define_insn "*cmpstrnqi_nz_1"
18182
  [(set (reg:CC FLAGS_REG)
18183
        (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18184
                    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18185
   (use (match_operand:SI 6 "register_operand" "2"))
18186
   (use (match_operand:SI 3 "immediate_operand" "i"))
18187
   (clobber (match_operand:SI 0 "register_operand" "=S"))
18188
   (clobber (match_operand:SI 1 "register_operand" "=D"))
18189
   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18190
  "!TARGET_64BIT"
18191
  "repz{%;} cmpsb"
18192
  [(set_attr "type" "str")
18193
   (set_attr "mode" "QI")
18194
   (set_attr "prefix_rep" "1")])
18195
 
18196
(define_insn "*cmpstrnqi_nz_rex_1"
18197
  [(set (reg:CC FLAGS_REG)
18198
        (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18199
                    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18200
   (use (match_operand:DI 6 "register_operand" "2"))
18201
   (use (match_operand:SI 3 "immediate_operand" "i"))
18202
   (clobber (match_operand:DI 0 "register_operand" "=S"))
18203
   (clobber (match_operand:DI 1 "register_operand" "=D"))
18204
   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18205
  "TARGET_64BIT"
18206
  "repz{%;} cmpsb"
18207
  [(set_attr "type" "str")
18208
   (set_attr "mode" "QI")
18209
   (set_attr "prefix_rex" "0")
18210
   (set_attr "prefix_rep" "1")])
18211
 
18212
;; The same, but the count is not known to not be zero.
18213
 
18214
(define_expand "cmpstrnqi_1"
18215
  [(parallel [(set (reg:CC FLAGS_REG)
18216
                (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18217
                                     (const_int 0))
18218
                  (compare:CC (match_operand 4 "memory_operand" "")
18219
                              (match_operand 5 "memory_operand" ""))
18220
                  (const_int 0)))
18221
              (use (match_operand:SI 3 "immediate_operand" ""))
18222
              (use (reg:CC FLAGS_REG))
18223
              (clobber (match_operand 0 "register_operand" ""))
18224
              (clobber (match_operand 1 "register_operand" ""))
18225
              (clobber (match_dup 2))])]
18226
  ""
18227
  "ix86_current_function_needs_cld = 1;")
18228
 
18229
(define_insn "*cmpstrnqi_1"
18230
  [(set (reg:CC FLAGS_REG)
18231
        (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18232
                             (const_int 0))
18233
          (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18234
                      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18235
          (const_int 0)))
18236
   (use (match_operand:SI 3 "immediate_operand" "i"))
18237
   (use (reg:CC FLAGS_REG))
18238
   (clobber (match_operand:SI 0 "register_operand" "=S"))
18239
   (clobber (match_operand:SI 1 "register_operand" "=D"))
18240
   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18241
  "!TARGET_64BIT"
18242
  "repz{%;} cmpsb"
18243
  [(set_attr "type" "str")
18244
   (set_attr "mode" "QI")
18245
   (set_attr "prefix_rep" "1")])
18246
 
18247
(define_insn "*cmpstrnqi_rex_1"
18248
  [(set (reg:CC FLAGS_REG)
18249
        (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18250
                             (const_int 0))
18251
          (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18252
                      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18253
          (const_int 0)))
18254
   (use (match_operand:SI 3 "immediate_operand" "i"))
18255
   (use (reg:CC FLAGS_REG))
18256
   (clobber (match_operand:DI 0 "register_operand" "=S"))
18257
   (clobber (match_operand:DI 1 "register_operand" "=D"))
18258
   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18259
  "TARGET_64BIT"
18260
  "repz{%;} cmpsb"
18261
  [(set_attr "type" "str")
18262
   (set_attr "mode" "QI")
18263
   (set_attr "prefix_rex" "0")
18264
   (set_attr "prefix_rep" "1")])
18265
 
18266
(define_expand "strlensi"
18267
  [(set (match_operand:SI 0 "register_operand" "")
18268
        (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18269
                    (match_operand:QI 2 "immediate_operand" "")
18270
                    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18271
  ""
18272
{
18273
 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18274
   DONE;
18275
 else
18276
   FAIL;
18277
})
18278
 
18279
(define_expand "strlendi"
18280
  [(set (match_operand:DI 0 "register_operand" "")
18281
        (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18282
                    (match_operand:QI 2 "immediate_operand" "")
18283
                    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18284
  ""
18285
{
18286
 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18287
   DONE;
18288
 else
18289
   FAIL;
18290
})
18291
 
18292
(define_expand "strlenqi_1"
18293
  [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18294
              (clobber (match_operand 1 "register_operand" ""))
18295
              (clobber (reg:CC FLAGS_REG))])]
18296
  ""
18297
  "ix86_current_function_needs_cld = 1;")
18298
 
18299
(define_insn "*strlenqi_1"
18300
  [(set (match_operand:SI 0 "register_operand" "=&c")
18301
        (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18302
                    (match_operand:QI 2 "register_operand" "a")
18303
                    (match_operand:SI 3 "immediate_operand" "i")
18304
                    (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18305
   (clobber (match_operand:SI 1 "register_operand" "=D"))
18306
   (clobber (reg:CC FLAGS_REG))]
18307
  "!TARGET_64BIT"
18308
  "repnz{%;} scasb"
18309
  [(set_attr "type" "str")
18310
   (set_attr "mode" "QI")
18311
   (set_attr "prefix_rep" "1")])
18312
 
18313
(define_insn "*strlenqi_rex_1"
18314
  [(set (match_operand:DI 0 "register_operand" "=&c")
18315
        (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18316
                    (match_operand:QI 2 "register_operand" "a")
18317
                    (match_operand:DI 3 "immediate_operand" "i")
18318
                    (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18319
   (clobber (match_operand:DI 1 "register_operand" "=D"))
18320
   (clobber (reg:CC FLAGS_REG))]
18321
  "TARGET_64BIT"
18322
  "repnz{%;} scasb"
18323
  [(set_attr "type" "str")
18324
   (set_attr "mode" "QI")
18325
   (set_attr "prefix_rex" "0")
18326
   (set_attr "prefix_rep" "1")])
18327
 
18328
;; Peephole optimizations to clean up after cmpstrn*.  This should be
18329
;; handled in combine, but it is not currently up to the task.
18330
;; When used for their truth value, the cmpstrn* expanders generate
18331
;; code like this:
18332
;;
18333
;;   repz cmpsb
18334
;;   seta       %al
18335
;;   setb       %dl
18336
;;   cmpb       %al, %dl
18337
;;   jcc        label
18338
;;
18339
;; The intermediate three instructions are unnecessary.
18340
 
18341
;; This one handles cmpstrn*_nz_1...
18342
(define_peephole2
18343
  [(parallel[
18344
     (set (reg:CC FLAGS_REG)
18345
          (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18346
                      (mem:BLK (match_operand 5 "register_operand" ""))))
18347
     (use (match_operand 6 "register_operand" ""))
18348
     (use (match_operand:SI 3 "immediate_operand" ""))
18349
     (clobber (match_operand 0 "register_operand" ""))
18350
     (clobber (match_operand 1 "register_operand" ""))
18351
     (clobber (match_operand 2 "register_operand" ""))])
18352
   (set (match_operand:QI 7 "register_operand" "")
18353
        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18354
   (set (match_operand:QI 8 "register_operand" "")
18355
        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18356
   (set (reg FLAGS_REG)
18357
        (compare (match_dup 7) (match_dup 8)))
18358
  ]
18359
  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18360
  [(parallel[
18361
     (set (reg:CC FLAGS_REG)
18362
          (compare:CC (mem:BLK (match_dup 4))
18363
                      (mem:BLK (match_dup 5))))
18364
     (use (match_dup 6))
18365
     (use (match_dup 3))
18366
     (clobber (match_dup 0))
18367
     (clobber (match_dup 1))
18368
     (clobber (match_dup 2))])]
18369
  "")
18370
 
18371
;; ...and this one handles cmpstrn*_1.
18372
(define_peephole2
18373
  [(parallel[
18374
     (set (reg:CC FLAGS_REG)
18375
          (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18376
                               (const_int 0))
18377
            (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18378
                        (mem:BLK (match_operand 5 "register_operand" "")))
18379
            (const_int 0)))
18380
     (use (match_operand:SI 3 "immediate_operand" ""))
18381
     (use (reg:CC FLAGS_REG))
18382
     (clobber (match_operand 0 "register_operand" ""))
18383
     (clobber (match_operand 1 "register_operand" ""))
18384
     (clobber (match_operand 2 "register_operand" ""))])
18385
   (set (match_operand:QI 7 "register_operand" "")
18386
        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18387
   (set (match_operand:QI 8 "register_operand" "")
18388
        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18389
   (set (reg FLAGS_REG)
18390
        (compare (match_dup 7) (match_dup 8)))
18391
  ]
18392
  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18393
  [(parallel[
18394
     (set (reg:CC FLAGS_REG)
18395
          (if_then_else:CC (ne (match_dup 6)
18396
                               (const_int 0))
18397
            (compare:CC (mem:BLK (match_dup 4))
18398
                        (mem:BLK (match_dup 5)))
18399
            (const_int 0)))
18400
     (use (match_dup 3))
18401
     (use (reg:CC FLAGS_REG))
18402
     (clobber (match_dup 0))
18403
     (clobber (match_dup 1))
18404
     (clobber (match_dup 2))])]
18405
  "")
18406
 
18407
 
18408
 
18409
;; Conditional move instructions.
18410
 
18411
(define_expand "movcc"
18412
  [(set (match_operand:SWIM 0 "register_operand" "")
18413
        (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
18414
                           (match_operand:SWIM 2 "general_operand" "")
18415
                           (match_operand:SWIM 3 "general_operand" "")))]
18416
  ""
18417
  "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18418
 
18419
;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18420
;; the register first winds up with `sbbl $0,reg', which is also weird.
18421
;; So just document what we're doing explicitly.
18422
 
18423
(define_expand "x86_movcc_0_m1"
18424
  [(parallel
18425
    [(set (match_operand:SWI48 0 "register_operand" "")
18426
          (if_then_else:SWI48
18427
            (match_operator:SWI48 2 "ix86_carry_flag_operator"
18428
             [(match_operand 1 "flags_reg_operand" "")
18429
              (const_int 0)])
18430
            (const_int -1)
18431
            (const_int 0)))
18432
     (clobber (reg:CC FLAGS_REG))])]
18433
  ""
18434
  "")
18435
 
18436
(define_insn "*x86_movcc_0_m1"
18437
  [(set (match_operand:SWI48 0 "register_operand" "=r")
18438
        (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18439
                             [(reg FLAGS_REG) (const_int 0)])
18440
          (const_int -1)
18441
          (const_int 0)))
18442
   (clobber (reg:CC FLAGS_REG))]
18443
  ""
18444
  "sbb{}\t%0, %0"
18445
  ; Since we don't have the proper number of operands for an alu insn,
18446
  ; fill in all the blanks.
18447
  [(set_attr "type" "alu")
18448
   (set_attr "use_carry" "1")
18449
   (set_attr "pent_pair" "pu")
18450
   (set_attr "memory" "none")
18451
   (set_attr "imm_disp" "false")
18452
   (set_attr "mode" "")
18453
   (set_attr "length_immediate" "0")])
18454
 
18455
(define_insn "*x86_movcc_0_m1_se"
18456
  [(set (match_operand:SWI48 0 "register_operand" "=r")
18457
        (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18458
                             [(reg FLAGS_REG) (const_int 0)])
18459
                            (const_int 1)
18460
                            (const_int 0)))
18461
   (clobber (reg:CC FLAGS_REG))]
18462
  ""
18463
  "sbb{}\t%0, %0"
18464
  [(set_attr "type" "alu")
18465
   (set_attr "use_carry" "1")
18466
   (set_attr "pent_pair" "pu")
18467
   (set_attr "memory" "none")
18468
   (set_attr "imm_disp" "false")
18469
   (set_attr "mode" "")
18470
   (set_attr "length_immediate" "0")])
18471
 
18472
(define_insn "*x86_movcc_0_m1_neg"
18473
  [(set (match_operand:SWI48 0 "register_operand" "=r")
18474
        (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18475
                    [(reg FLAGS_REG) (const_int 0)])))]
18476
  ""
18477
  "sbb{}\t%0, %0"
18478
  [(set_attr "type" "alu")
18479
   (set_attr "use_carry" "1")
18480
   (set_attr "pent_pair" "pu")
18481
   (set_attr "memory" "none")
18482
   (set_attr "imm_disp" "false")
18483
   (set_attr "mode" "")
18484
   (set_attr "length_immediate" "0")])
18485
 
18486
(define_insn "*movcc_noc"
18487
  [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18488
        (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18489
                               [(reg FLAGS_REG) (const_int 0)])
18490
          (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18491
          (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18492
  "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18493
  "@
18494
   cmov%O2%C1\t{%2, %0|%0, %2}
18495
   cmov%O2%c1\t{%3, %0|%0, %3}"
18496
  [(set_attr "type" "icmov")
18497
   (set_attr "mode" "")])
18498
 
18499
(define_insn_and_split "*movqicc_noc"
18500
  [(set (match_operand:QI 0 "register_operand" "=r,r")
18501
        (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18502
                           [(match_operand 4 "flags_reg_operand" "")
18503
                            (const_int 0)])
18504
                      (match_operand:QI 2 "register_operand" "r,0")
18505
                      (match_operand:QI 3 "register_operand" "0,r")))]
18506
  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18507
  "#"
18508
  "&& reload_completed"
18509
  [(set (match_dup 0)
18510
        (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18511
                      (match_dup 2)
18512
                      (match_dup 3)))]
18513
  "operands[0] = gen_lowpart (SImode, operands[0]);
18514
   operands[2] = gen_lowpart (SImode, operands[2]);
18515
   operands[3] = gen_lowpart (SImode, operands[3]);"
18516
  [(set_attr "type" "icmov")
18517
   (set_attr "mode" "SI")])
18518
 
18519
(define_expand "movcc"
18520
  [(set (match_operand:X87MODEF 0 "register_operand" "")
18521
        (if_then_else:X87MODEF
18522
          (match_operand 1 "ix86_fp_comparison_operator" "")
18523
          (match_operand:X87MODEF 2 "register_operand" "")
18524
          (match_operand:X87MODEF 3 "register_operand" "")))]
18525
  "(TARGET_80387 && TARGET_CMOVE)
18526
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
18527
  "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18528
 
18529
(define_insn "*movsfcc_1_387"
18530
  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18531
        (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18532
                                [(reg FLAGS_REG) (const_int 0)])
18533
                      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18534
                      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18535
  "TARGET_80387 && TARGET_CMOVE
18536
   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18537
  "@
18538
   fcmov%F1\t{%2, %0|%0, %2}
18539
   fcmov%f1\t{%3, %0|%0, %3}
18540
   cmov%O2%C1\t{%2, %0|%0, %2}
18541
   cmov%O2%c1\t{%3, %0|%0, %3}"
18542
  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18543
   (set_attr "mode" "SF,SF,SI,SI")])
18544
 
18545
(define_insn "*movdfcc_1"
18546
  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18547
        (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18548
                                [(reg FLAGS_REG) (const_int 0)])
18549
                      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18550
                      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18551
  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18552
   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18553
  "@
18554
   fcmov%F1\t{%2, %0|%0, %2}
18555
   fcmov%f1\t{%3, %0|%0, %3}
18556
   #
18557
   #"
18558
  [(set_attr "type" "fcmov,fcmov,multi,multi")
18559
   (set_attr "mode" "DF")])
18560
 
18561
(define_insn "*movdfcc_1_rex64"
18562
  [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18563
        (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18564
                                [(reg FLAGS_REG) (const_int 0)])
18565
                      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18566
                      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18567
  "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18568
   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18569
  "@
18570
   fcmov%F1\t{%2, %0|%0, %2}
18571
   fcmov%f1\t{%3, %0|%0, %3}
18572
   cmov%O2%C1\t{%2, %0|%0, %2}
18573
   cmov%O2%c1\t{%3, %0|%0, %3}"
18574
  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18575
   (set_attr "mode" "DF")])
18576
 
18577
(define_split
18578
  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18579
        (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18580
                                [(match_operand 4 "flags_reg_operand" "")
18581
                                 (const_int 0)])
18582
                      (match_operand:DF 2 "nonimmediate_operand" "")
18583
                      (match_operand:DF 3 "nonimmediate_operand" "")))]
18584
  "!TARGET_64BIT && reload_completed"
18585
  [(set (match_dup 2)
18586
        (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18587
                      (match_dup 5)
18588
                      (match_dup 6)))
18589
   (set (match_dup 3)
18590
        (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18591
                      (match_dup 7)
18592
                      (match_dup 8)))]
18593
  "split_di (&operands[2], 2, &operands[5], &operands[7]);
18594
   split_di (&operands[0], 1, &operands[2], &operands[3]);")
18595
 
18596
(define_insn "*movxfcc_1"
18597
  [(set (match_operand:XF 0 "register_operand" "=f,f")
18598
        (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18599
                                [(reg FLAGS_REG) (const_int 0)])
18600
                      (match_operand:XF 2 "register_operand" "f,0")
18601
                      (match_operand:XF 3 "register_operand" "0,f")))]
18602
  "TARGET_80387 && TARGET_CMOVE"
18603
  "@
18604
   fcmov%F1\t{%2, %0|%0, %2}
18605
   fcmov%f1\t{%3, %0|%0, %3}"
18606
  [(set_attr "type" "fcmov")
18607
   (set_attr "mode" "XF")])
18608
 
18609
;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18610
;; the scalar versions to have only XMM registers as operands.
18611
 
18612
;; XOP conditional move
18613
(define_insn "*xop_pcmov_"
18614
  [(set (match_operand:MODEF 0 "register_operand" "=x")
18615
        (if_then_else:MODEF
18616
          (match_operand:MODEF 1 "register_operand" "x")
18617
          (match_operand:MODEF 2 "register_operand" "x")
18618
          (match_operand:MODEF 3 "register_operand" "x")))]
18619
  "TARGET_XOP"
18620
  "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18621
  [(set_attr "type" "sse4arg")])
18622
 
18623
;; These versions of the min/max patterns are intentionally ignorant of
18624
;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18625
;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18626
;; are undefined in this condition, we're certain this is correct.
18627
 
18628
(define_insn "*avx_3"
18629
  [(set (match_operand:MODEF 0 "register_operand" "=x")
18630
        (smaxmin:MODEF
18631
          (match_operand:MODEF 1 "nonimmediate_operand" "%x")
18632
          (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18633
  "AVX_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
18634
  "vs\t{%2, %1, %0|%0, %1, %2}"
18635
  [(set_attr "type" "sseadd")
18636
   (set_attr "prefix" "vex")
18637
   (set_attr "mode" "")])
18638
 
18639
(define_insn "3"
18640
  [(set (match_operand:MODEF 0 "register_operand" "=x")
18641
        (smaxmin:MODEF
18642
          (match_operand:MODEF 1 "nonimmediate_operand" "%0")
18643
          (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18644
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
18645
  "s\t{%2, %0|%0, %2}"
18646
  [(set_attr "type" "sseadd")
18647
   (set_attr "mode" "")])
18648
 
18649
;; These versions of the min/max patterns implement exactly the operations
18650
;;   min = (op1 < op2 ? op1 : op2)
18651
;;   max = (!(op1 < op2) ? op1 : op2)
18652
;; Their operands are not commutative, and thus they may be used in the
18653
;; presence of -0.0 and NaN.
18654
 
18655
(define_insn "*avx_ieee_smin3"
18656
  [(set (match_operand:MODEF 0 "register_operand" "=x")
18657
        (unspec:MODEF
18658
          [(match_operand:MODEF 1 "register_operand" "x")
18659
           (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18660
         UNSPEC_IEEE_MIN))]
18661
  "AVX_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
18662
  "vmins\t{%2, %1, %0|%0, %1, %2}"
18663
  [(set_attr "type" "sseadd")
18664
   (set_attr "prefix" "vex")
18665
   (set_attr "mode" "")])
18666
 
18667
(define_insn "*ieee_smin3"
18668
  [(set (match_operand:MODEF 0 "register_operand" "=x")
18669
        (unspec:MODEF
18670
          [(match_operand:MODEF 1 "register_operand" "0")
18671
           (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18672
         UNSPEC_IEEE_MIN))]
18673
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
18674
  "mins\t{%2, %0|%0, %2}"
18675
  [(set_attr "type" "sseadd")
18676
   (set_attr "mode" "")])
18677
 
18678
(define_insn "*avx_ieee_smax3"
18679
  [(set (match_operand:MODEF 0 "register_operand" "=x")
18680
        (unspec:MODEF
18681
          [(match_operand:MODEF 1 "register_operand" "0")
18682
           (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18683
         UNSPEC_IEEE_MAX))]
18684
  "AVX_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
18685
  "vmaxs\t{%2, %1, %0|%0, %1, %2}"
18686
  [(set_attr "type" "sseadd")
18687
   (set_attr "prefix" "vex")
18688
   (set_attr "mode" "")])
18689
 
18690
(define_insn "*ieee_smax3"
18691
  [(set (match_operand:MODEF 0 "register_operand" "=x")
18692
        (unspec:MODEF
18693
          [(match_operand:MODEF 1 "register_operand" "0")
18694
           (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18695
         UNSPEC_IEEE_MAX))]
18696
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
18697
  "maxs\t{%2, %0|%0, %2}"
18698
  [(set_attr "type" "sseadd")
18699
   (set_attr "mode" "")])
18700
 
18701
;; Make two stack loads independent:
18702
;;   fld aa              fld aa
18703
;;   fld %st(0)     ->   fld bb
18704
;;   fmul bb             fmul %st(1), %st
18705
;;
18706
;; Actually we only match the last two instructions for simplicity.
18707
(define_peephole2
18708
  [(set (match_operand 0 "fp_register_operand" "")
18709
        (match_operand 1 "fp_register_operand" ""))
18710
   (set (match_dup 0)
18711
        (match_operator 2 "binary_fp_operator"
18712
           [(match_dup 0)
18713
            (match_operand 3 "memory_operand" "")]))]
18714
  "REGNO (operands[0]) != REGNO (operands[1])"
18715
  [(set (match_dup 0) (match_dup 3))
18716
   (set (match_dup 0) (match_dup 4))]
18717
 
18718
  ;; The % modifier is not operational anymore in peephole2's, so we have to
18719
  ;; swap the operands manually in the case of addition and multiplication.
18720
  "if (COMMUTATIVE_ARITH_P (operands[2]))
18721
     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18722
                                 operands[0], operands[1]);
18723
   else
18724
     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18725
                                 operands[1], operands[0]);")
18726
 
18727
;; Conditional addition patterns
18728
(define_expand "addcc"
18729
  [(match_operand:SWI 0 "register_operand" "")
18730
   (match_operand 1 "comparison_operator" "")
18731
   (match_operand:SWI 2 "register_operand" "")
18732
   (match_operand:SWI 3 "const_int_operand" "")]
18733
  ""
18734
  "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18735
 
18736
 
18737
;; Misc patterns (?)
18738
 
18739
;; This pattern exists to put a dependency on all ebp-based memory accesses.
18740
;; Otherwise there will be nothing to keep
18741
;;
18742
;; [(set (reg ebp) (reg esp))]
18743
;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18744
;;  (clobber (eflags)]
18745
;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18746
;;
18747
;; in proper program order.
18748
(define_insn "pro_epilogue_adjust_stack_1"
18749
  [(set (match_operand:SI 0 "register_operand" "=r,r")
18750
        (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18751
                 (match_operand:SI 2 "immediate_operand" "i,i")))
18752
   (clobber (reg:CC FLAGS_REG))
18753
   (clobber (mem:BLK (scratch)))]
18754
  "!TARGET_64BIT"
18755
{
18756
  switch (get_attr_type (insn))
18757
    {
18758
    case TYPE_IMOV:
18759
      return "mov{l}\t{%1, %0|%0, %1}";
18760
 
18761
    case TYPE_ALU:
18762
      if (CONST_INT_P (operands[2])
18763
          && (INTVAL (operands[2]) == 128
18764
              || (INTVAL (operands[2]) < 0
18765
                  && INTVAL (operands[2]) != -128)))
18766
        {
18767
          operands[2] = GEN_INT (-INTVAL (operands[2]));
18768
          return "sub{l}\t{%2, %0|%0, %2}";
18769
        }
18770
      return "add{l}\t{%2, %0|%0, %2}";
18771
 
18772
    case TYPE_LEA:
18773
      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18774
      return "lea{l}\t{%a2, %0|%0, %a2}";
18775
 
18776
    default:
18777
      gcc_unreachable ();
18778
    }
18779
}
18780
  [(set (attr "type")
18781
        (cond [(and (eq_attr "alternative" "0")
18782
                    (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18783
                 (const_string "alu")
18784
               (match_operand:SI 2 "const0_operand" "")
18785
                 (const_string "imov")
18786
              ]
18787
              (const_string "lea")))
18788
   (set (attr "length_immediate")
18789
        (cond [(eq_attr "type" "imov")
18790
                 (const_string "0")
18791
               (and (eq_attr "type" "alu")
18792
                    (match_operand 2 "const128_operand" ""))
18793
                 (const_string "1")
18794
              ]
18795
              (const_string "*")))
18796
   (set_attr "mode" "SI")])
18797
 
18798
(define_insn "pro_epilogue_adjust_stack_rex64"
18799
  [(set (match_operand:DI 0 "register_operand" "=r,r")
18800
        (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18801
                 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18802
   (clobber (reg:CC FLAGS_REG))
18803
   (clobber (mem:BLK (scratch)))]
18804
  "TARGET_64BIT"
18805
{
18806
  switch (get_attr_type (insn))
18807
    {
18808
    case TYPE_IMOV:
18809
      return "mov{q}\t{%1, %0|%0, %1}";
18810
 
18811
    case TYPE_ALU:
18812
      if (CONST_INT_P (operands[2])
18813
          /* Avoid overflows.  */
18814
          && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18815
          && (INTVAL (operands[2]) == 128
18816
              || (INTVAL (operands[2]) < 0
18817
                  && INTVAL (operands[2]) != -128)))
18818
        {
18819
          operands[2] = GEN_INT (-INTVAL (operands[2]));
18820
          return "sub{q}\t{%2, %0|%0, %2}";
18821
        }
18822
      return "add{q}\t{%2, %0|%0, %2}";
18823
 
18824
    case TYPE_LEA:
18825
      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18826
      return "lea{q}\t{%a2, %0|%0, %a2}";
18827
 
18828
    default:
18829
      gcc_unreachable ();
18830
    }
18831
}
18832
  [(set (attr "type")
18833
        (cond [(and (eq_attr "alternative" "0")
18834
                    (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18835
                 (const_string "alu")
18836
               (match_operand:DI 2 "const0_operand" "")
18837
                 (const_string "imov")
18838
              ]
18839
              (const_string "lea")))
18840
   (set (attr "length_immediate")
18841
        (cond [(eq_attr "type" "imov")
18842
                 (const_string "0")
18843
               (and (eq_attr "type" "alu")
18844
                    (match_operand 2 "const128_operand" ""))
18845
                 (const_string "1")
18846
              ]
18847
              (const_string "*")))
18848
   (set_attr "mode" "DI")])
18849
 
18850
(define_insn "pro_epilogue_adjust_stack_rex64_2"
18851
  [(set (match_operand:DI 0 "register_operand" "=r,r")
18852
        (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18853
                 (match_operand:DI 3 "immediate_operand" "i,i")))
18854
   (use (match_operand:DI 2 "register_operand" "r,r"))
18855
   (clobber (reg:CC FLAGS_REG))
18856
   (clobber (mem:BLK (scratch)))]
18857
  "TARGET_64BIT"
18858
{
18859
  switch (get_attr_type (insn))
18860
    {
18861
    case TYPE_ALU:
18862
      return "add{q}\t{%2, %0|%0, %2}";
18863
 
18864
    case TYPE_LEA:
18865
      operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18866
      return "lea{q}\t{%a2, %0|%0, %a2}";
18867
 
18868
    default:
18869
      gcc_unreachable ();
18870
    }
18871
}
18872
  [(set_attr "type" "alu,lea")
18873
   (set_attr "mode" "DI")])
18874
 
18875
(define_insn "allocate_stack_worker_32"
18876
  [(set (match_operand:SI 0 "register_operand" "=a")
18877
        (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18878
                            UNSPECV_STACK_PROBE))
18879
   (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
18880
   (clobber (reg:CC FLAGS_REG))]
18881
  "!TARGET_64BIT && TARGET_STACK_PROBE"
18882
  "call\t___chkstk"
18883
  [(set_attr "type" "multi")
18884
   (set_attr "length" "5")])
18885
 
18886
(define_insn "allocate_stack_worker_64"
18887
  [(set (match_operand:DI 0 "register_operand" "=a")
18888
        (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
18889
                            UNSPECV_STACK_PROBE))
18890
   (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
18891
   (clobber (reg:DI R10_REG))
18892
   (clobber (reg:DI R11_REG))
18893
   (clobber (reg:CC FLAGS_REG))]
18894
  "TARGET_64BIT && TARGET_STACK_PROBE"
18895
  "call\t___chkstk"
18896
  [(set_attr "type" "multi")
18897
   (set_attr "length" "5")])
18898
 
18899
(define_expand "allocate_stack"
18900
  [(match_operand 0 "register_operand" "")
18901
   (match_operand 1 "general_operand" "")]
18902
  "TARGET_STACK_PROBE"
18903
{
18904
  rtx x;
18905
 
18906
#ifndef CHECK_STACK_LIMIT
18907
#define CHECK_STACK_LIMIT 0
18908
#endif
18909
 
18910
  if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18911
      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18912
    {
18913
      x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
18914
                               stack_pointer_rtx, 0, OPTAB_DIRECT);
18915
      if (x != stack_pointer_rtx)
18916
        emit_move_insn (stack_pointer_rtx, x);
18917
    }
18918
  else
18919
    {
18920
      x = copy_to_mode_reg (Pmode, operands[1]);
18921
      if (TARGET_64BIT)
18922
        x = gen_allocate_stack_worker_64 (x, x);
18923
      else
18924
        x = gen_allocate_stack_worker_32 (x, x);
18925
      emit_insn (x);
18926
    }
18927
 
18928
  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18929
  DONE;
18930
})
18931
 
18932
;; Use IOR for stack probes, this is shorter.
18933
(define_expand "probe_stack"
18934
  [(match_operand 0 "memory_operand" "")]
18935
  ""
18936
{
18937
  if (GET_MODE (operands[0]) == DImode)
18938
    emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
18939
  else
18940
    emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
18941
  DONE;
18942
})
18943
 
18944
(define_expand "builtin_setjmp_receiver"
18945
  [(label_ref (match_operand 0 "" ""))]
18946
  "!TARGET_64BIT && flag_pic"
18947
{
18948
#if TARGET_MACHO
18949
  if (TARGET_MACHO)
18950
    {
18951
      rtx xops[3];
18952
      rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18953
      rtx label_rtx = gen_label_rtx ();
18954
      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18955
      xops[0] = xops[1] = picreg;
18956
      xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18957
      ix86_expand_binary_operator (MINUS, SImode, xops);
18958
    }
18959
  else
18960
#endif
18961
    emit_insn (gen_set_got (pic_offset_table_rtx));
18962
  DONE;
18963
})
18964
 
18965
;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18966
 
18967
(define_split
18968
  [(set (match_operand 0 "register_operand" "")
18969
        (match_operator 3 "promotable_binary_operator"
18970
           [(match_operand 1 "register_operand" "")
18971
            (match_operand 2 "aligned_operand" "")]))
18972
   (clobber (reg:CC FLAGS_REG))]
18973
  "! TARGET_PARTIAL_REG_STALL && reload_completed
18974
   && ((GET_MODE (operands[0]) == HImode
18975
        && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18976
            /* ??? next two lines just !satisfies_constraint_K (...) */
18977
            || !CONST_INT_P (operands[2])
18978
            || satisfies_constraint_K (operands[2])))
18979
       || (GET_MODE (operands[0]) == QImode
18980
           && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18981
  [(parallel [(set (match_dup 0)
18982
                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18983
              (clobber (reg:CC FLAGS_REG))])]
18984
  "operands[0] = gen_lowpart (SImode, operands[0]);
18985
   operands[1] = gen_lowpart (SImode, operands[1]);
18986
   if (GET_CODE (operands[3]) != ASHIFT)
18987
     operands[2] = gen_lowpart (SImode, operands[2]);
18988
   PUT_MODE (operands[3], SImode);")
18989
 
18990
; Promote the QImode tests, as i386 has encoding of the AND
18991
; instruction with 32-bit sign-extended immediate and thus the
18992
; instruction size is unchanged, except in the %eax case for
18993
; which it is increased by one byte, hence the ! optimize_size.
18994
(define_split
18995
  [(set (match_operand 0 "flags_reg_operand" "")
18996
        (match_operator 2 "compare_operator"
18997
          [(and (match_operand 3 "aligned_operand" "")
18998
                (match_operand 4 "const_int_operand" ""))
18999
           (const_int 0)]))
19000
   (set (match_operand 1 "register_operand" "")
19001
        (and (match_dup 3) (match_dup 4)))]
19002
  "! TARGET_PARTIAL_REG_STALL && reload_completed
19003
   && optimize_insn_for_speed_p ()
19004
   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19005
       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19006
   /* Ensure that the operand will remain sign-extended immediate.  */
19007
   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19008
  [(parallel [(set (match_dup 0)
19009
                   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19010
                                    (const_int 0)]))
19011
              (set (match_dup 1)
19012
                   (and:SI (match_dup 3) (match_dup 4)))])]
19013
{
19014
  operands[4]
19015
    = gen_int_mode (INTVAL (operands[4])
19016
                    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19017
  operands[1] = gen_lowpart (SImode, operands[1]);
19018
  operands[3] = gen_lowpart (SImode, operands[3]);
19019
})
19020
 
19021
; Don't promote the QImode tests, as i386 doesn't have encoding of
19022
; the TEST instruction with 32-bit sign-extended immediate and thus
19023
; the instruction size would at least double, which is not what we
19024
; want even with ! optimize_size.
19025
(define_split
19026
  [(set (match_operand 0 "flags_reg_operand" "")
19027
        (match_operator 1 "compare_operator"
19028
          [(and (match_operand:HI 2 "aligned_operand" "")
19029
                (match_operand:HI 3 "const_int_operand" ""))
19030
           (const_int 0)]))]
19031
  "! TARGET_PARTIAL_REG_STALL && reload_completed
19032
   && ! TARGET_FAST_PREFIX
19033
   && optimize_insn_for_speed_p ()
19034
   /* Ensure that the operand will remain sign-extended immediate.  */
19035
   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19036
  [(set (match_dup 0)
19037
        (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19038
                         (const_int 0)]))]
19039
{
19040
  operands[3]
19041
    = gen_int_mode (INTVAL (operands[3])
19042
                    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19043
  operands[2] = gen_lowpart (SImode, operands[2]);
19044
})
19045
 
19046
(define_split
19047
  [(set (match_operand 0 "register_operand" "")
19048
        (neg (match_operand 1 "register_operand" "")))
19049
   (clobber (reg:CC FLAGS_REG))]
19050
  "! TARGET_PARTIAL_REG_STALL && reload_completed
19051
   && (GET_MODE (operands[0]) == HImode
19052
       || (GET_MODE (operands[0]) == QImode
19053
           && (TARGET_PROMOTE_QImode
19054
               || optimize_insn_for_size_p ())))"
19055
  [(parallel [(set (match_dup 0)
19056
                   (neg:SI (match_dup 1)))
19057
              (clobber (reg:CC FLAGS_REG))])]
19058
  "operands[0] = gen_lowpart (SImode, operands[0]);
19059
   operands[1] = gen_lowpart (SImode, operands[1]);")
19060
 
19061
(define_split
19062
  [(set (match_operand 0 "register_operand" "")
19063
        (not (match_operand 1 "register_operand" "")))]
19064
  "! TARGET_PARTIAL_REG_STALL && reload_completed
19065
   && (GET_MODE (operands[0]) == HImode
19066
       || (GET_MODE (operands[0]) == QImode
19067
           && (TARGET_PROMOTE_QImode
19068
               || optimize_insn_for_size_p ())))"
19069
  [(set (match_dup 0)
19070
        (not:SI (match_dup 1)))]
19071
  "operands[0] = gen_lowpart (SImode, operands[0]);
19072
   operands[1] = gen_lowpart (SImode, operands[1]);")
19073
 
19074
(define_split
19075
  [(set (match_operand 0 "register_operand" "")
19076
        (if_then_else (match_operator 1 "comparison_operator"
19077
                                [(reg FLAGS_REG) (const_int 0)])
19078
                      (match_operand 2 "register_operand" "")
19079
                      (match_operand 3 "register_operand" "")))]
19080
  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19081
   && (GET_MODE (operands[0]) == HImode
19082
       || (GET_MODE (operands[0]) == QImode
19083
           && (TARGET_PROMOTE_QImode
19084
               || optimize_insn_for_size_p ())))"
19085
  [(set (match_dup 0)
19086
        (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19087
  "operands[0] = gen_lowpart (SImode, operands[0]);
19088
   operands[2] = gen_lowpart (SImode, operands[2]);
19089
   operands[3] = gen_lowpart (SImode, operands[3]);")
19090
 
19091
 
19092
;; RTL Peephole optimizations, run before sched2.  These primarily look to
19093
;; transform a complex memory operation into two memory to register operations.
19094
 
19095
;; Don't push memory operands
19096
(define_peephole2
19097
  [(set (match_operand:SI 0 "push_operand" "")
19098
        (match_operand:SI 1 "memory_operand" ""))
19099
   (match_scratch:SI 2 "r")]
19100
  "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19101
   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19102
  [(set (match_dup 2) (match_dup 1))
19103
   (set (match_dup 0) (match_dup 2))]
19104
  "")
19105
 
19106
(define_peephole2
19107
  [(set (match_operand:DI 0 "push_operand" "")
19108
        (match_operand:DI 1 "memory_operand" ""))
19109
   (match_scratch:DI 2 "r")]
19110
  "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19111
   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19112
  [(set (match_dup 2) (match_dup 1))
19113
   (set (match_dup 0) (match_dup 2))]
19114
  "")
19115
 
19116
;; We need to handle SFmode only, because DFmode and XFmode is split to
19117
;; SImode pushes.
19118
(define_peephole2
19119
  [(set (match_operand:SF 0 "push_operand" "")
19120
        (match_operand:SF 1 "memory_operand" ""))
19121
   (match_scratch:SF 2 "r")]
19122
  "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19123
   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19124
  [(set (match_dup 2) (match_dup 1))
19125
   (set (match_dup 0) (match_dup 2))]
19126
  "")
19127
 
19128
(define_peephole2
19129
  [(set (match_operand:HI 0 "push_operand" "")
19130
        (match_operand:HI 1 "memory_operand" ""))
19131
   (match_scratch:HI 2 "r")]
19132
  "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19133
   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19134
  [(set (match_dup 2) (match_dup 1))
19135
   (set (match_dup 0) (match_dup 2))]
19136
  "")
19137
 
19138
(define_peephole2
19139
  [(set (match_operand:QI 0 "push_operand" "")
19140
        (match_operand:QI 1 "memory_operand" ""))
19141
   (match_scratch:QI 2 "q")]
19142
  "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19143
   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19144
  [(set (match_dup 2) (match_dup 1))
19145
   (set (match_dup 0) (match_dup 2))]
19146
  "")
19147
 
19148
;; Don't move an immediate directly to memory when the instruction
19149
;; gets too big.
19150
(define_peephole2
19151
  [(match_scratch:SI 1 "r")
19152
   (set (match_operand:SI 0 "memory_operand" "")
19153
        (const_int 0))]
19154
  "optimize_insn_for_speed_p ()
19155
   && ! TARGET_USE_MOV0
19156
   && TARGET_SPLIT_LONG_MOVES
19157
   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19158
   && peep2_regno_dead_p (0, FLAGS_REG)"
19159
  [(parallel [(set (match_dup 1) (const_int 0))
19160
              (clobber (reg:CC FLAGS_REG))])
19161
   (set (match_dup 0) (match_dup 1))]
19162
  "")
19163
 
19164
(define_peephole2
19165
  [(match_scratch:HI 1 "r")
19166
   (set (match_operand:HI 0 "memory_operand" "")
19167
        (const_int 0))]
19168
  "optimize_insn_for_speed_p ()
19169
   && ! TARGET_USE_MOV0
19170
   && TARGET_SPLIT_LONG_MOVES
19171
   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19172
   && peep2_regno_dead_p (0, FLAGS_REG)"
19173
  [(parallel [(set (match_dup 2) (const_int 0))
19174
              (clobber (reg:CC FLAGS_REG))])
19175
   (set (match_dup 0) (match_dup 1))]
19176
  "operands[2] = gen_lowpart (SImode, operands[1]);")
19177
 
19178
(define_peephole2
19179
  [(match_scratch:QI 1 "q")
19180
   (set (match_operand:QI 0 "memory_operand" "")
19181
        (const_int 0))]
19182
  "optimize_insn_for_speed_p ()
19183
   && ! TARGET_USE_MOV0
19184
   && TARGET_SPLIT_LONG_MOVES
19185
   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19186
   && peep2_regno_dead_p (0, FLAGS_REG)"
19187
  [(parallel [(set (match_dup 2) (const_int 0))
19188
              (clobber (reg:CC FLAGS_REG))])
19189
   (set (match_dup 0) (match_dup 1))]
19190
  "operands[2] = gen_lowpart (SImode, operands[1]);")
19191
 
19192
(define_peephole2
19193
  [(match_scratch:SI 2 "r")
19194
   (set (match_operand:SI 0 "memory_operand" "")
19195
        (match_operand:SI 1 "immediate_operand" ""))]
19196
  "optimize_insn_for_speed_p ()
19197
   && TARGET_SPLIT_LONG_MOVES
19198
   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19199
  [(set (match_dup 2) (match_dup 1))
19200
   (set (match_dup 0) (match_dup 2))]
19201
  "")
19202
 
19203
(define_peephole2
19204
  [(match_scratch:HI 2 "r")
19205
   (set (match_operand:HI 0 "memory_operand" "")
19206
        (match_operand:HI 1 "immediate_operand" ""))]
19207
  "optimize_insn_for_speed_p ()
19208
   && TARGET_SPLIT_LONG_MOVES
19209
   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19210
  [(set (match_dup 2) (match_dup 1))
19211
   (set (match_dup 0) (match_dup 2))]
19212
  "")
19213
 
19214
(define_peephole2
19215
  [(match_scratch:QI 2 "q")
19216
   (set (match_operand:QI 0 "memory_operand" "")
19217
        (match_operand:QI 1 "immediate_operand" ""))]
19218
  "optimize_insn_for_speed_p ()
19219
   && TARGET_SPLIT_LONG_MOVES
19220
   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19221
  [(set (match_dup 2) (match_dup 1))
19222
   (set (match_dup 0) (match_dup 2))]
19223
  "")
19224
 
19225
;; Don't compare memory with zero, load and use a test instead.
19226
(define_peephole2
19227
  [(set (match_operand 0 "flags_reg_operand" "")
19228
        (match_operator 1 "compare_operator"
19229
          [(match_operand:SI 2 "memory_operand" "")
19230
           (const_int 0)]))
19231
   (match_scratch:SI 3 "r")]
19232
  "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19233
  [(set (match_dup 3) (match_dup 2))
19234
   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19235
  "")
19236
 
19237
;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19238
;; Don't split NOTs with a displacement operand, because resulting XOR
19239
;; will not be pairable anyway.
19240
;;
19241
;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19242
;; represented using a modRM byte.  The XOR replacement is long decoded,
19243
;; so this split helps here as well.
19244
;;
19245
;; Note: Can't do this as a regular split because we can't get proper
19246
;; lifetime information then.
19247
 
19248
(define_peephole2
19249
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
19250
        (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19251
  "optimize_insn_for_speed_p ()
19252
   && ((TARGET_NOT_UNPAIRABLE
19253
        && (!MEM_P (operands[0])
19254
            || !memory_displacement_operand (operands[0], SImode)))
19255
       || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19256
   && peep2_regno_dead_p (0, FLAGS_REG)"
19257
  [(parallel [(set (match_dup 0)
19258
                   (xor:SI (match_dup 1) (const_int -1)))
19259
              (clobber (reg:CC FLAGS_REG))])]
19260
  "")
19261
 
19262
(define_peephole2
19263
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
19264
        (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19265
  "optimize_insn_for_speed_p ()
19266
   && ((TARGET_NOT_UNPAIRABLE
19267
        && (!MEM_P (operands[0])
19268
            || !memory_displacement_operand (operands[0], HImode)))
19269
       || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19270
   && peep2_regno_dead_p (0, FLAGS_REG)"
19271
  [(parallel [(set (match_dup 0)
19272
                   (xor:HI (match_dup 1) (const_int -1)))
19273
              (clobber (reg:CC FLAGS_REG))])]
19274
  "")
19275
 
19276
(define_peephole2
19277
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
19278
        (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19279
  "optimize_insn_for_speed_p ()
19280
   && ((TARGET_NOT_UNPAIRABLE
19281
        && (!MEM_P (operands[0])
19282
            || !memory_displacement_operand (operands[0], QImode)))
19283
       || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19284
   && peep2_regno_dead_p (0, FLAGS_REG)"
19285
  [(parallel [(set (match_dup 0)
19286
                   (xor:QI (match_dup 1) (const_int -1)))
19287
              (clobber (reg:CC FLAGS_REG))])]
19288
  "")
19289
 
19290
;; Non pairable "test imm, reg" instructions can be translated to
19291
;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19292
;; byte opcode instead of two, have a short form for byte operands),
19293
;; so do it for other CPUs as well.  Given that the value was dead,
19294
;; this should not create any new dependencies.  Pass on the sub-word
19295
;; versions if we're concerned about partial register stalls.
19296
 
19297
(define_peephole2
19298
  [(set (match_operand 0 "flags_reg_operand" "")
19299
        (match_operator 1 "compare_operator"
19300
          [(and:SI (match_operand:SI 2 "register_operand" "")
19301
                   (match_operand:SI 3 "immediate_operand" ""))
19302
           (const_int 0)]))]
19303
  "ix86_match_ccmode (insn, CCNOmode)
19304
   && (true_regnum (operands[2]) != AX_REG
19305
       || satisfies_constraint_K (operands[3]))
19306
   && peep2_reg_dead_p (1, operands[2])"
19307
  [(parallel
19308
     [(set (match_dup 0)
19309
           (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19310
                            (const_int 0)]))
19311
      (set (match_dup 2)
19312
           (and:SI (match_dup 2) (match_dup 3)))])]
19313
  "")
19314
 
19315
;; We don't need to handle HImode case, because it will be promoted to SImode
19316
;; on ! TARGET_PARTIAL_REG_STALL
19317
 
19318
(define_peephole2
19319
  [(set (match_operand 0 "flags_reg_operand" "")
19320
        (match_operator 1 "compare_operator"
19321
          [(and:QI (match_operand:QI 2 "register_operand" "")
19322
                   (match_operand:QI 3 "immediate_operand" ""))
19323
           (const_int 0)]))]
19324
  "! TARGET_PARTIAL_REG_STALL
19325
   && ix86_match_ccmode (insn, CCNOmode)
19326
   && true_regnum (operands[2]) != AX_REG
19327
   && peep2_reg_dead_p (1, operands[2])"
19328
  [(parallel
19329
     [(set (match_dup 0)
19330
           (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19331
                            (const_int 0)]))
19332
      (set (match_dup 2)
19333
           (and:QI (match_dup 2) (match_dup 3)))])]
19334
  "")
19335
 
19336
(define_peephole2
19337
  [(set (match_operand 0 "flags_reg_operand" "")
19338
        (match_operator 1 "compare_operator"
19339
          [(and:SI
19340
             (zero_extract:SI
19341
               (match_operand 2 "ext_register_operand" "")
19342
               (const_int 8)
19343
               (const_int 8))
19344
             (match_operand 3 "const_int_operand" ""))
19345
           (const_int 0)]))]
19346
  "! TARGET_PARTIAL_REG_STALL
19347
   && ix86_match_ccmode (insn, CCNOmode)
19348
   && true_regnum (operands[2]) != AX_REG
19349
   && peep2_reg_dead_p (1, operands[2])"
19350
  [(parallel [(set (match_dup 0)
19351
                   (match_op_dup 1
19352
                     [(and:SI
19353
                        (zero_extract:SI
19354
                          (match_dup 2)
19355
                          (const_int 8)
19356
                          (const_int 8))
19357
                        (match_dup 3))
19358
                      (const_int 0)]))
19359
              (set (zero_extract:SI (match_dup 2)
19360
                                    (const_int 8)
19361
                                    (const_int 8))
19362
                   (and:SI
19363
                     (zero_extract:SI
19364
                       (match_dup 2)
19365
                       (const_int 8)
19366
                       (const_int 8))
19367
                     (match_dup 3)))])]
19368
  "")
19369
 
19370
;; Don't do logical operations with memory inputs.
19371
(define_peephole2
19372
  [(match_scratch:SI 2 "r")
19373
   (parallel [(set (match_operand:SI 0 "register_operand" "")
19374
                   (match_operator:SI 3 "arith_or_logical_operator"
19375
                     [(match_dup 0)
19376
                      (match_operand:SI 1 "memory_operand" "")]))
19377
              (clobber (reg:CC FLAGS_REG))])]
19378
  "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19379
  [(set (match_dup 2) (match_dup 1))
19380
   (parallel [(set (match_dup 0)
19381
                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19382
              (clobber (reg:CC FLAGS_REG))])]
19383
  "")
19384
 
19385
(define_peephole2
19386
  [(match_scratch:SI 2 "r")
19387
   (parallel [(set (match_operand:SI 0 "register_operand" "")
19388
                   (match_operator:SI 3 "arith_or_logical_operator"
19389
                     [(match_operand:SI 1 "memory_operand" "")
19390
                      (match_dup 0)]))
19391
              (clobber (reg:CC FLAGS_REG))])]
19392
  "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19393
  [(set (match_dup 2) (match_dup 1))
19394
   (parallel [(set (match_dup 0)
19395
                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19396
              (clobber (reg:CC FLAGS_REG))])]
19397
  "")
19398
 
19399
;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
19400
;; refers to the destination of the load!
19401
 
19402
(define_peephole2
19403
  [(set (match_operand:SI 0 "register_operand" "")
19404
        (match_operand:SI 1 "register_operand" ""))
19405
   (parallel [(set (match_dup 0)
19406
                   (match_operator:SI 3 "commutative_operator"
19407
                     [(match_dup 0)
19408
                      (match_operand:SI 2 "memory_operand" "")]))
19409
              (clobber (reg:CC FLAGS_REG))])]
19410
  "REGNO (operands[0]) != REGNO (operands[1])
19411
   && GENERAL_REGNO_P (REGNO (operands[0]))
19412
   && GENERAL_REGNO_P (REGNO (operands[1]))"
19413
  [(set (match_dup 0) (match_dup 4))
19414
   (parallel [(set (match_dup 0)
19415
                   (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19416
              (clobber (reg:CC FLAGS_REG))])]
19417
  "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
19418
 
19419
(define_peephole2
19420
  [(set (match_operand 0 "register_operand" "")
19421
        (match_operand 1 "register_operand" ""))
19422
   (set (match_dup 0)
19423
                   (match_operator 3 "commutative_operator"
19424
                     [(match_dup 0)
19425
                      (match_operand 2 "memory_operand" "")]))]
19426
  "REGNO (operands[0]) != REGNO (operands[1])
19427
   && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
19428
       || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
19429
  [(set (match_dup 0) (match_dup 2))
19430
   (set (match_dup 0)
19431
        (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
19432
  "")
19433
 
19434
; Don't do logical operations with memory outputs
19435
;
19436
; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19437
; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19438
; the same decoder scheduling characteristics as the original.
19439
 
19440
(define_peephole2
19441
  [(match_scratch:SI 2 "r")
19442
   (parallel [(set (match_operand:SI 0 "memory_operand" "")
19443
                   (match_operator:SI 3 "arith_or_logical_operator"
19444
                     [(match_dup 0)
19445
                      (match_operand:SI 1 "nonmemory_operand" "")]))
19446
              (clobber (reg:CC FLAGS_REG))])]
19447
  "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19448
   /* Do not split stack checking probes.  */
19449
   && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19450
  [(set (match_dup 2) (match_dup 0))
19451
   (parallel [(set (match_dup 2)
19452
                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19453
              (clobber (reg:CC FLAGS_REG))])
19454
   (set (match_dup 0) (match_dup 2))]
19455
  "")
19456
 
19457
(define_peephole2
19458
  [(match_scratch:SI 2 "r")
19459
   (parallel [(set (match_operand:SI 0 "memory_operand" "")
19460
                   (match_operator:SI 3 "arith_or_logical_operator"
19461
                     [(match_operand:SI 1 "nonmemory_operand" "")
19462
                      (match_dup 0)]))
19463
              (clobber (reg:CC FLAGS_REG))])]
19464
  "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19465
   /* Do not split stack checking probes.  */
19466
   && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19467
  [(set (match_dup 2) (match_dup 0))
19468
   (parallel [(set (match_dup 2)
19469
                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19470
              (clobber (reg:CC FLAGS_REG))])
19471
   (set (match_dup 0) (match_dup 2))]
19472
  "")
19473
 
19474
;; Attempt to always use XOR for zeroing registers.
19475
(define_peephole2
19476
  [(set (match_operand 0 "register_operand" "")
19477
        (match_operand 1 "const0_operand" ""))]
19478
  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19479
   && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19480
   && GENERAL_REG_P (operands[0])
19481
   && peep2_regno_dead_p (0, FLAGS_REG)"
19482
  [(parallel [(set (match_dup 0) (const_int 0))
19483
              (clobber (reg:CC FLAGS_REG))])]
19484
{
19485
  operands[0] = gen_lowpart (word_mode, operands[0]);
19486
})
19487
 
19488
(define_peephole2
19489
  [(set (strict_low_part (match_operand 0 "register_operand" ""))
19490
        (const_int 0))]
19491
  "(GET_MODE (operands[0]) == QImode
19492
    || GET_MODE (operands[0]) == HImode)
19493
   && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19494
   && peep2_regno_dead_p (0, FLAGS_REG)"
19495
  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19496
              (clobber (reg:CC FLAGS_REG))])])
19497
 
19498
;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19499
(define_peephole2
19500
  [(set (match_operand 0 "register_operand" "")
19501
        (const_int -1))]
19502
  "(GET_MODE (operands[0]) == HImode
19503
    || GET_MODE (operands[0]) == SImode
19504
    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19505
   && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
19506
   && peep2_regno_dead_p (0, FLAGS_REG)"
19507
  [(parallel [(set (match_dup 0) (const_int -1))
19508
              (clobber (reg:CC FLAGS_REG))])]
19509
  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19510
                              operands[0]);")
19511
 
19512
;; Attempt to convert simple leas to adds. These can be created by
19513
;; move expanders.
19514
(define_peephole2
19515
  [(set (match_operand:SI 0 "register_operand" "")
19516
        (plus:SI (match_dup 0)
19517
                 (match_operand:SI 1 "nonmemory_operand" "")))]
19518
  "peep2_regno_dead_p (0, FLAGS_REG)"
19519
  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19520
              (clobber (reg:CC FLAGS_REG))])]
19521
  "")
19522
 
19523
(define_peephole2
19524
  [(set (match_operand:SI 0 "register_operand" "")
19525
        (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19526
                            (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19527
  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19528
  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19529
              (clobber (reg:CC FLAGS_REG))])]
19530
  "operands[2] = gen_lowpart (SImode, operands[2]);")
19531
 
19532
(define_peephole2
19533
  [(set (match_operand:DI 0 "register_operand" "")
19534
        (plus:DI (match_dup 0)
19535
                 (match_operand:DI 1 "x86_64_general_operand" "")))]
19536
  "peep2_regno_dead_p (0, FLAGS_REG)"
19537
  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19538
              (clobber (reg:CC FLAGS_REG))])]
19539
  "")
19540
 
19541
(define_peephole2
19542
  [(set (match_operand:SI 0 "register_operand" "")
19543
        (mult:SI (match_dup 0)
19544
                 (match_operand:SI 1 "const_int_operand" "")))]
19545
  "exact_log2 (INTVAL (operands[1])) >= 0
19546
   && peep2_regno_dead_p (0, FLAGS_REG)"
19547
  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19548
              (clobber (reg:CC FLAGS_REG))])]
19549
  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19550
 
19551
(define_peephole2
19552
  [(set (match_operand:DI 0 "register_operand" "")
19553
        (mult:DI (match_dup 0)
19554
                 (match_operand:DI 1 "const_int_operand" "")))]
19555
  "exact_log2 (INTVAL (operands[1])) >= 0
19556
   && peep2_regno_dead_p (0, FLAGS_REG)"
19557
  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19558
              (clobber (reg:CC FLAGS_REG))])]
19559
  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19560
 
19561
(define_peephole2
19562
  [(set (match_operand:SI 0 "register_operand" "")
19563
        (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19564
                   (match_operand:DI 2 "const_int_operand" "")) 0))]
19565
  "exact_log2 (INTVAL (operands[2])) >= 0
19566
   && REGNO (operands[0]) == REGNO (operands[1])
19567
   && peep2_regno_dead_p (0, FLAGS_REG)"
19568
  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19569
              (clobber (reg:CC FLAGS_REG))])]
19570
  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19571
 
19572
;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19573
;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19574
;; many CPUs it is also faster, since special hardware to avoid esp
19575
;; dependencies is present.
19576
 
19577
;; While some of these conversions may be done using splitters, we use peepholes
19578
;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19579
 
19580
;; Convert prologue esp subtractions to push.
19581
;; We need register to push.  In order to keep verify_flow_info happy we have
19582
;; two choices
19583
;; - use scratch and clobber it in order to avoid dependencies
19584
;; - use already live register
19585
;; We can't use the second way right now, since there is no reliable way how to
19586
;; verify that given register is live.  First choice will also most likely in
19587
;; fewer dependencies.  On the place of esp adjustments it is very likely that
19588
;; call clobbered registers are dead.  We may want to use base pointer as an
19589
;; alternative when no register is available later.
19590
 
19591
(define_peephole2
19592
  [(match_scratch:SI 0 "r")
19593
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19594
              (clobber (reg:CC FLAGS_REG))
19595
              (clobber (mem:BLK (scratch)))])]
19596
  "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19597
  [(clobber (match_dup 0))
19598
   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19599
              (clobber (mem:BLK (scratch)))])])
19600
 
19601
(define_peephole2
19602
  [(match_scratch:SI 0 "r")
19603
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19604
              (clobber (reg:CC FLAGS_REG))
19605
              (clobber (mem:BLK (scratch)))])]
19606
  "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19607
  [(clobber (match_dup 0))
19608
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19609
   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19610
              (clobber (mem:BLK (scratch)))])])
19611
 
19612
;; Convert esp subtractions to push.
19613
(define_peephole2
19614
  [(match_scratch:SI 0 "r")
19615
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19616
              (clobber (reg:CC FLAGS_REG))])]
19617
  "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19618
  [(clobber (match_dup 0))
19619
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19620
 
19621
(define_peephole2
19622
  [(match_scratch:SI 0 "r")
19623
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19624
              (clobber (reg:CC FLAGS_REG))])]
19625
  "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19626
  [(clobber (match_dup 0))
19627
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19628
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19629
 
19630
;; Convert epilogue deallocator to pop.
19631
(define_peephole2
19632
  [(match_scratch:SI 0 "r")
19633
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19634
              (clobber (reg:CC FLAGS_REG))
19635
              (clobber (mem:BLK (scratch)))])]
19636
  "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19637
  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19638
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19639
              (clobber (mem:BLK (scratch)))])]
19640
  "")
19641
 
19642
;; Two pops case is tricky, since pop causes dependency on destination register.
19643
;; We use two registers if available.
19644
(define_peephole2
19645
  [(match_scratch:SI 0 "r")
19646
   (match_scratch:SI 1 "r")
19647
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19648
              (clobber (reg:CC FLAGS_REG))
19649
              (clobber (mem:BLK (scratch)))])]
19650
  "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19651
  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19652
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19653
              (clobber (mem:BLK (scratch)))])
19654
   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19655
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19656
  "")
19657
 
19658
(define_peephole2
19659
  [(match_scratch:SI 0 "r")
19660
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19661
              (clobber (reg:CC FLAGS_REG))
19662
              (clobber (mem:BLK (scratch)))])]
19663
  "optimize_insn_for_size_p ()"
19664
  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19665
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19666
              (clobber (mem:BLK (scratch)))])
19667
   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19668
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19669
  "")
19670
 
19671
;; Convert esp additions to pop.
19672
(define_peephole2
19673
  [(match_scratch:SI 0 "r")
19674
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19675
              (clobber (reg:CC FLAGS_REG))])]
19676
  ""
19677
  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19678
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19679
  "")
19680
 
19681
;; Two pops case is tricky, since pop causes dependency on destination register.
19682
;; We use two registers if available.
19683
(define_peephole2
19684
  [(match_scratch:SI 0 "r")
19685
   (match_scratch:SI 1 "r")
19686
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19687
              (clobber (reg:CC FLAGS_REG))])]
19688
  ""
19689
  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19690
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19691
   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19692
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19693
  "")
19694
 
19695
(define_peephole2
19696
  [(match_scratch:SI 0 "r")
19697
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19698
              (clobber (reg:CC FLAGS_REG))])]
19699
  "optimize_insn_for_size_p ()"
19700
  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19701
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19702
   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19703
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19704
  "")
19705
 
19706
;; Convert compares with 1 to shorter inc/dec operations when CF is not
19707
;; required and register dies.  Similarly for 128 to -128.
19708
(define_peephole2
19709
  [(set (match_operand 0 "flags_reg_operand" "")
19710
        (match_operator 1 "compare_operator"
19711
          [(match_operand 2 "register_operand" "")
19712
           (match_operand 3 "const_int_operand" "")]))]
19713
  "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19714
     && incdec_operand (operands[3], GET_MODE (operands[3])))
19715
    || (!TARGET_FUSE_CMP_AND_BRANCH
19716
        && INTVAL (operands[3]) == 128))
19717
   && ix86_match_ccmode (insn, CCGCmode)
19718
   && peep2_reg_dead_p (1, operands[2])"
19719
  [(parallel [(set (match_dup 0)
19720
                   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19721
              (clobber (match_dup 2))])]
19722
  "")
19723
 
19724
(define_peephole2
19725
  [(match_scratch:DI 0 "r")
19726
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19727
              (clobber (reg:CC FLAGS_REG))
19728
              (clobber (mem:BLK (scratch)))])]
19729
  "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19730
  [(clobber (match_dup 0))
19731
   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19732
              (clobber (mem:BLK (scratch)))])])
19733
 
19734
(define_peephole2
19735
  [(match_scratch:DI 0 "r")
19736
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19737
              (clobber (reg:CC FLAGS_REG))
19738
              (clobber (mem:BLK (scratch)))])]
19739
  "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19740
  [(clobber (match_dup 0))
19741
   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19742
   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19743
              (clobber (mem:BLK (scratch)))])])
19744
 
19745
;; Convert esp subtractions to push.
19746
(define_peephole2
19747
  [(match_scratch:DI 0 "r")
19748
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19749
              (clobber (reg:CC FLAGS_REG))])]
19750
  "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19751
  [(clobber (match_dup 0))
19752
   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19753
 
19754
(define_peephole2
19755
  [(match_scratch:DI 0 "r")
19756
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19757
              (clobber (reg:CC FLAGS_REG))])]
19758
  "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19759
  [(clobber (match_dup 0))
19760
   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19761
   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19762
 
19763
;; Convert epilogue deallocator to pop.
19764
(define_peephole2
19765
  [(match_scratch:DI 0 "r")
19766
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19767
              (clobber (reg:CC FLAGS_REG))
19768
              (clobber (mem:BLK (scratch)))])]
19769
  "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19770
  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19771
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19772
              (clobber (mem:BLK (scratch)))])]
19773
  "")
19774
 
19775
;; Two pops case is tricky, since pop causes dependency on destination register.
19776
;; We use two registers if available.
19777
(define_peephole2
19778
  [(match_scratch:DI 0 "r")
19779
   (match_scratch:DI 1 "r")
19780
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19781
              (clobber (reg:CC FLAGS_REG))
19782
              (clobber (mem:BLK (scratch)))])]
19783
  "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19784
  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19785
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19786
              (clobber (mem:BLK (scratch)))])
19787
   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19788
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19789
  "")
19790
 
19791
(define_peephole2
19792
  [(match_scratch:DI 0 "r")
19793
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19794
              (clobber (reg:CC FLAGS_REG))
19795
              (clobber (mem:BLK (scratch)))])]
19796
  "optimize_insn_for_size_p ()"
19797
  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19798
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19799
              (clobber (mem:BLK (scratch)))])
19800
   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19801
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19802
  "")
19803
 
19804
;; Convert esp additions to pop.
19805
(define_peephole2
19806
  [(match_scratch:DI 0 "r")
19807
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19808
              (clobber (reg:CC FLAGS_REG))])]
19809
  ""
19810
  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19811
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19812
  "")
19813
 
19814
;; Two pops case is tricky, since pop causes dependency on destination register.
19815
;; We use two registers if available.
19816
(define_peephole2
19817
  [(match_scratch:DI 0 "r")
19818
   (match_scratch:DI 1 "r")
19819
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19820
              (clobber (reg:CC FLAGS_REG))])]
19821
  ""
19822
  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19823
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19824
   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19825
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19826
  "")
19827
 
19828
(define_peephole2
19829
  [(match_scratch:DI 0 "r")
19830
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19831
              (clobber (reg:CC FLAGS_REG))])]
19832
  "optimize_insn_for_size_p ()"
19833
  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19834
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19835
   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19836
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19837
  "")
19838
 
19839
;; Convert imul by three, five and nine into lea
19840
(define_peephole2
19841
  [(parallel
19842
    [(set (match_operand:SI 0 "register_operand" "")
19843
          (mult:SI (match_operand:SI 1 "register_operand" "")
19844
                   (match_operand:SI 2 "const_int_operand" "")))
19845
     (clobber (reg:CC FLAGS_REG))])]
19846
  "INTVAL (operands[2]) == 3
19847
   || INTVAL (operands[2]) == 5
19848
   || INTVAL (operands[2]) == 9"
19849
  [(set (match_dup 0)
19850
        (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19851
                 (match_dup 1)))]
19852
  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19853
 
19854
(define_peephole2
19855
  [(parallel
19856
    [(set (match_operand:SI 0 "register_operand" "")
19857
          (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19858
                   (match_operand:SI 2 "const_int_operand" "")))
19859
     (clobber (reg:CC FLAGS_REG))])]
19860
  "optimize_insn_for_speed_p ()
19861
   && (INTVAL (operands[2]) == 3
19862
       || INTVAL (operands[2]) == 5
19863
       || INTVAL (operands[2]) == 9)"
19864
  [(set (match_dup 0) (match_dup 1))
19865
   (set (match_dup 0)
19866
        (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19867
                 (match_dup 0)))]
19868
  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19869
 
19870
(define_peephole2
19871
  [(parallel
19872
    [(set (match_operand:DI 0 "register_operand" "")
19873
          (mult:DI (match_operand:DI 1 "register_operand" "")
19874
                   (match_operand:DI 2 "const_int_operand" "")))
19875
     (clobber (reg:CC FLAGS_REG))])]
19876
  "TARGET_64BIT
19877
   && (INTVAL (operands[2]) == 3
19878
       || INTVAL (operands[2]) == 5
19879
       || INTVAL (operands[2]) == 9)"
19880
  [(set (match_dup 0)
19881
        (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19882
                 (match_dup 1)))]
19883
  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19884
 
19885
(define_peephole2
19886
  [(parallel
19887
    [(set (match_operand:DI 0 "register_operand" "")
19888
          (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19889
                   (match_operand:DI 2 "const_int_operand" "")))
19890
     (clobber (reg:CC FLAGS_REG))])]
19891
  "TARGET_64BIT
19892
   && optimize_insn_for_speed_p ()
19893
   && (INTVAL (operands[2]) == 3
19894
       || INTVAL (operands[2]) == 5
19895
       || INTVAL (operands[2]) == 9)"
19896
  [(set (match_dup 0) (match_dup 1))
19897
   (set (match_dup 0)
19898
        (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19899
                 (match_dup 0)))]
19900
  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19901
 
19902
;; Imul $32bit_imm, mem, reg is vector decoded, while
19903
;; imul $32bit_imm, reg, reg is direct decoded.
19904
(define_peephole2
19905
  [(match_scratch:DI 3 "r")
19906
   (parallel [(set (match_operand:DI 0 "register_operand" "")
19907
                   (mult:DI (match_operand:DI 1 "memory_operand" "")
19908
                            (match_operand:DI 2 "immediate_operand" "")))
19909
              (clobber (reg:CC FLAGS_REG))])]
19910
  "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19911
   && !satisfies_constraint_K (operands[2])"
19912
  [(set (match_dup 3) (match_dup 1))
19913
   (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19914
              (clobber (reg:CC FLAGS_REG))])]
19915
"")
19916
 
19917
(define_peephole2
19918
  [(match_scratch:SI 3 "r")
19919
   (parallel [(set (match_operand:SI 0 "register_operand" "")
19920
                   (mult:SI (match_operand:SI 1 "memory_operand" "")
19921
                            (match_operand:SI 2 "immediate_operand" "")))
19922
              (clobber (reg:CC FLAGS_REG))])]
19923
  "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19924
   && !satisfies_constraint_K (operands[2])"
19925
  [(set (match_dup 3) (match_dup 1))
19926
   (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19927
              (clobber (reg:CC FLAGS_REG))])]
19928
"")
19929
 
19930
(define_peephole2
19931
  [(match_scratch:SI 3 "r")
19932
   (parallel [(set (match_operand:DI 0 "register_operand" "")
19933
                   (zero_extend:DI
19934
                     (mult:SI (match_operand:SI 1 "memory_operand" "")
19935
                              (match_operand:SI 2 "immediate_operand" ""))))
19936
              (clobber (reg:CC FLAGS_REG))])]
19937
  "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19938
   && !satisfies_constraint_K (operands[2])"
19939
  [(set (match_dup 3) (match_dup 1))
19940
   (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19941
              (clobber (reg:CC FLAGS_REG))])]
19942
"")
19943
 
19944
;; imul $8/16bit_imm, regmem, reg is vector decoded.
19945
;; Convert it into imul reg, reg
19946
;; It would be better to force assembler to encode instruction using long
19947
;; immediate, but there is apparently no way to do so.
19948
(define_peephole2
19949
  [(parallel [(set (match_operand:DI 0 "register_operand" "")
19950
                   (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19951
                            (match_operand:DI 2 "const_int_operand" "")))
19952
              (clobber (reg:CC FLAGS_REG))])
19953
   (match_scratch:DI 3 "r")]
19954
  "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19955
   && satisfies_constraint_K (operands[2])"
19956
  [(set (match_dup 3) (match_dup 2))
19957
   (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19958
              (clobber (reg:CC FLAGS_REG))])]
19959
{
19960
  if (!rtx_equal_p (operands[0], operands[1]))
19961
    emit_move_insn (operands[0], operands[1]);
19962
})
19963
 
19964
(define_peephole2
19965
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
19966
                   (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19967
                            (match_operand:SI 2 "const_int_operand" "")))
19968
              (clobber (reg:CC FLAGS_REG))])
19969
   (match_scratch:SI 3 "r")]
19970
  "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19971
   && satisfies_constraint_K (operands[2])"
19972
  [(set (match_dup 3) (match_dup 2))
19973
   (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19974
              (clobber (reg:CC FLAGS_REG))])]
19975
{
19976
  if (!rtx_equal_p (operands[0], operands[1]))
19977
    emit_move_insn (operands[0], operands[1]);
19978
})
19979
 
19980
(define_peephole2
19981
  [(parallel [(set (match_operand:HI 0 "register_operand" "")
19982
                   (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19983
                            (match_operand:HI 2 "immediate_operand" "")))
19984
              (clobber (reg:CC FLAGS_REG))])
19985
   (match_scratch:HI 3 "r")]
19986
  "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
19987
  [(set (match_dup 3) (match_dup 2))
19988
   (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19989
              (clobber (reg:CC FLAGS_REG))])]
19990
{
19991
  if (!rtx_equal_p (operands[0], operands[1]))
19992
    emit_move_insn (operands[0], operands[1]);
19993
})
19994
 
19995
;; After splitting up read-modify operations, array accesses with memory
19996
;; operands might end up in form:
19997
;;  sall    $2, %eax
19998
;;  movl    4(%esp), %edx
19999
;;  addl    %edx, %eax
20000
;; instead of pre-splitting:
20001
;;  sall    $2, %eax
20002
;;  addl    4(%esp), %eax
20003
;; Turn it into:
20004
;;  movl    4(%esp), %edx
20005
;;  leal    (%edx,%eax,4), %eax
20006
 
20007
(define_peephole2
20008
  [(parallel [(set (match_operand 0 "register_operand" "")
20009
                   (ashift (match_operand 1 "register_operand" "")
20010
                           (match_operand 2 "const_int_operand" "")))
20011
               (clobber (reg:CC FLAGS_REG))])
20012
   (set (match_operand 3 "register_operand")
20013
        (match_operand 4 "x86_64_general_operand" ""))
20014
   (parallel [(set (match_operand 5 "register_operand" "")
20015
                   (plus (match_operand 6 "register_operand" "")
20016
                         (match_operand 7 "register_operand" "")))
20017
                   (clobber (reg:CC FLAGS_REG))])]
20018
  "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20019
   /* Validate MODE for lea.  */
20020
   && ((!TARGET_PARTIAL_REG_STALL
20021
        && (GET_MODE (operands[0]) == QImode
20022
            || GET_MODE (operands[0]) == HImode))
20023
       || GET_MODE (operands[0]) == SImode
20024
       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20025
   /* We reorder load and the shift.  */
20026
   && !rtx_equal_p (operands[1], operands[3])
20027
   && !reg_overlap_mentioned_p (operands[0], operands[4])
20028
   /* Last PLUS must consist of operand 0 and 3.  */
20029
   && !rtx_equal_p (operands[0], operands[3])
20030
   && (rtx_equal_p (operands[3], operands[6])
20031
       || rtx_equal_p (operands[3], operands[7]))
20032
   && (rtx_equal_p (operands[0], operands[6])
20033
       || rtx_equal_p (operands[0], operands[7]))
20034
   /* The intermediate operand 0 must die or be same as output.  */
20035
   && (rtx_equal_p (operands[0], operands[5])
20036
       || peep2_reg_dead_p (3, operands[0]))"
20037
  [(set (match_dup 3) (match_dup 4))
20038
   (set (match_dup 0) (match_dup 1))]
20039
{
20040
  enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20041
  int scale = 1 << INTVAL (operands[2]);
20042
  rtx index = gen_lowpart (Pmode, operands[1]);
20043
  rtx base = gen_lowpart (Pmode, operands[3]);
20044
  rtx dest = gen_lowpart (mode, operands[5]);
20045
 
20046
  operands[1] = gen_rtx_PLUS (Pmode, base,
20047
                              gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20048
  if (mode != Pmode)
20049
    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20050
  operands[0] = dest;
20051
})
20052
 
20053
;; Call-value patterns last so that the wildcard operand does not
20054
;; disrupt insn-recog's switch tables.
20055
 
20056
(define_insn "*call_value_pop_0"
20057
  [(set (match_operand 0 "" "")
20058
        (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20059
              (match_operand:SI 2 "" "")))
20060
   (set (reg:SI SP_REG)
20061
        (plus:SI (reg:SI SP_REG)
20062
                 (match_operand:SI 3 "immediate_operand" "")))]
20063
  "!TARGET_64BIT"
20064
{
20065
  if (SIBLING_CALL_P (insn))
20066
    return "jmp\t%P1";
20067
  else
20068
    return "call\t%P1";
20069
}
20070
  [(set_attr "type" "callv")])
20071
 
20072
(define_insn "*call_value_pop_1"
20073
  [(set (match_operand 0 "" "")
20074
        (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20075
              (match_operand:SI 2 "" "")))
20076
   (set (reg:SI SP_REG)
20077
        (plus:SI (reg:SI SP_REG)
20078
                 (match_operand:SI 3 "immediate_operand" "i")))]
20079
  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20080
{
20081
  if (constant_call_address_operand (operands[1], Pmode))
20082
    return "call\t%P1";
20083
  return "call\t%A1";
20084
}
20085
  [(set_attr "type" "callv")])
20086
 
20087
(define_insn "*sibcall_value_pop_1"
20088
  [(set (match_operand 0 "" "")
20089
        (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20090
              (match_operand:SI 2 "" "")))
20091
   (set (reg:SI SP_REG)
20092
        (plus:SI (reg:SI SP_REG)
20093
                 (match_operand:SI 3 "immediate_operand" "i,i")))]
20094
  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20095
  "@
20096
   jmp\t%P1
20097
   jmp\t%A1"
20098
  [(set_attr "type" "callv")])
20099
 
20100
(define_insn "*call_value_0"
20101
  [(set (match_operand 0 "" "")
20102
        (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20103
              (match_operand:SI 2 "" "")))]
20104
  "!TARGET_64BIT"
20105
{
20106
  if (SIBLING_CALL_P (insn))
20107
    return "jmp\t%P1";
20108
  else
20109
    return "call\t%P1";
20110
}
20111
  [(set_attr "type" "callv")])
20112
 
20113
(define_insn "*call_value_0_rex64"
20114
  [(set (match_operand 0 "" "")
20115
        (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20116
              (match_operand:DI 2 "const_int_operand" "")))]
20117
  "TARGET_64BIT"
20118
{
20119
  if (SIBLING_CALL_P (insn))
20120
    return "jmp\t%P1";
20121
  else
20122
    return "call\t%P1";
20123
}
20124
  [(set_attr "type" "callv")])
20125
 
20126
(define_insn "*call_value_0_rex64_ms_sysv"
20127
  [(set (match_operand 0 "" "")
20128
        (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20129
              (match_operand:DI 2 "const_int_operand" "")))
20130
   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20131
   (clobber (reg:TI XMM6_REG))
20132
   (clobber (reg:TI XMM7_REG))
20133
   (clobber (reg:TI XMM8_REG))
20134
   (clobber (reg:TI XMM9_REG))
20135
   (clobber (reg:TI XMM10_REG))
20136
   (clobber (reg:TI XMM11_REG))
20137
   (clobber (reg:TI XMM12_REG))
20138
   (clobber (reg:TI XMM13_REG))
20139
   (clobber (reg:TI XMM14_REG))
20140
   (clobber (reg:TI XMM15_REG))
20141
   (clobber (reg:DI SI_REG))
20142
   (clobber (reg:DI DI_REG))]
20143
  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20144
{
20145
  if (SIBLING_CALL_P (insn))
20146
    return "jmp\t%P1";
20147
  else
20148
    return "call\t%P1";
20149
}
20150
  [(set_attr "type" "callv")])
20151
 
20152
(define_insn "*call_value_1"
20153
  [(set (match_operand 0 "" "")
20154
        (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20155
              (match_operand:SI 2 "" "")))]
20156
  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20157
{
20158
  if (constant_call_address_operand (operands[1], Pmode))
20159
    return "call\t%P1";
20160
  return "call\t%A1";
20161
}
20162
  [(set_attr "type" "callv")])
20163
 
20164
(define_insn "*sibcall_value_1"
20165
  [(set (match_operand 0 "" "")
20166
        (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20167
              (match_operand:SI 2 "" "")))]
20168
  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20169
  "@
20170
   jmp\t%P1
20171
   jmp\t%A1"
20172
  [(set_attr "type" "callv")])
20173
 
20174
(define_insn "*call_value_1_rex64"
20175
  [(set (match_operand 0 "" "")
20176
        (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20177
              (match_operand:DI 2 "" "")))]
20178
  "TARGET_64BIT && !SIBLING_CALL_P (insn)
20179
   && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20180
{
20181
  if (constant_call_address_operand (operands[1], Pmode))
20182
    return "call\t%P1";
20183
  return "call\t%A1";
20184
}
20185
  [(set_attr "type" "callv")])
20186
 
20187
(define_insn "*call_value_1_rex64_ms_sysv"
20188
  [(set (match_operand 0 "" "")
20189
        (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20190
              (match_operand:DI 2 "" "")))
20191
   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20192
   (clobber (reg:TI XMM6_REG))
20193
   (clobber (reg:TI XMM7_REG))
20194
   (clobber (reg:TI XMM8_REG))
20195
   (clobber (reg:TI XMM9_REG))
20196
   (clobber (reg:TI XMM10_REG))
20197
   (clobber (reg:TI XMM11_REG))
20198
   (clobber (reg:TI XMM12_REG))
20199
   (clobber (reg:TI XMM13_REG))
20200
   (clobber (reg:TI XMM14_REG))
20201
   (clobber (reg:TI XMM15_REG))
20202
   (clobber (reg:DI SI_REG))
20203
   (clobber (reg:DI DI_REG))]
20204
  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20205
{
20206
  if (constant_call_address_operand (operands[1], Pmode))
20207
    return "call\t%P1";
20208
  return "call\t%A1";
20209
}
20210
  [(set_attr "type" "callv")])
20211
 
20212
(define_insn "*call_value_1_rex64_large"
20213
  [(set (match_operand 0 "" "")
20214
        (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20215
              (match_operand:DI 2 "" "")))]
20216
  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20217
  "call\t%A1"
20218
  [(set_attr "type" "callv")])
20219
 
20220
(define_insn "*sibcall_value_1_rex64"
20221
  [(set (match_operand 0 "" "")
20222
        (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20223
              (match_operand:DI 2 "" "")))]
20224
  "TARGET_64BIT && SIBLING_CALL_P (insn)"
20225
  "@
20226
   jmp\t%P1
20227
   jmp\t%A1"
20228
  [(set_attr "type" "callv")])
20229
 
20230
;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20231
;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20232
;; caught for use by garbage collectors and the like.  Using an insn that
20233
;; maps to SIGILL makes it more likely the program will rightfully die.
20234
;; Keeping with tradition, "6" is in honor of #UD.
20235
(define_insn "trap"
20236
  [(trap_if (const_int 1) (const_int 6))]
20237
  ""
20238
  { return ASM_SHORT "0x0b0f"; }
20239
  [(set_attr "length" "2")])
20240
 
20241
(define_expand "sse_prologue_save"
20242
  [(parallel [(set (match_operand:BLK 0 "" "")
20243
                   (unspec:BLK [(reg:DI XMM0_REG)
20244
                                (reg:DI XMM1_REG)
20245
                                (reg:DI XMM2_REG)
20246
                                (reg:DI XMM3_REG)
20247
                                (reg:DI XMM4_REG)
20248
                                (reg:DI XMM5_REG)
20249
                                (reg:DI XMM6_REG)
20250
                                (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20251
              (use (match_operand:DI 1 "register_operand" ""))
20252
              (use (match_operand:DI 2 "immediate_operand" ""))
20253
              (use (label_ref:DI (match_operand 3 "" "")))])]
20254
  "TARGET_64BIT"
20255
  "")
20256
 
20257
(define_insn "*sse_prologue_save_insn"
20258
  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20259
                          (match_operand:DI 4 "const_int_operand" "n")))
20260
        (unspec:BLK [(reg:DI XMM0_REG)
20261
                     (reg:DI XMM1_REG)
20262
                     (reg:DI XMM2_REG)
20263
                     (reg:DI XMM3_REG)
20264
                     (reg:DI XMM4_REG)
20265
                     (reg:DI XMM5_REG)
20266
                     (reg:DI XMM6_REG)
20267
                     (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20268
   (use (match_operand:DI 1 "register_operand" "r"))
20269
   (use (match_operand:DI 2 "const_int_operand" "i"))
20270
   (use (label_ref:DI (match_operand 3 "" "X")))]
20271
  "TARGET_64BIT
20272
   && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20273
   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20274
{
20275
  int i;
20276
  operands[0] = gen_rtx_MEM (Pmode,
20277
                             gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20278
  /* VEX instruction with a REX prefix will #UD.  */
20279
  if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20280
    gcc_unreachable ();
20281
 
20282
  output_asm_insn ("jmp\t%A1", operands);
20283
  for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20284
    {
20285
      operands[4] = adjust_address (operands[0], DImode, i*16);
20286
      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20287
      PUT_MODE (operands[4], TImode);
20288
      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20289
        output_asm_insn ("rex", operands);
20290
      output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20291
    }
20292
  (*targetm.asm_out.internal_label) (asm_out_file, "L",
20293
                                     CODE_LABEL_NUMBER (operands[3]));
20294
  return "";
20295
}
20296
  [(set_attr "type" "other")
20297
   (set_attr "length_immediate" "0")
20298
   (set_attr "length_address" "0")
20299
   (set (attr "length")
20300
     (if_then_else
20301
       (eq (symbol_ref "TARGET_AVX") (const_int 0))
20302
       (const_string "34")
20303
       (const_string "42")))
20304
   (set_attr "memory" "store")
20305
   (set_attr "modrm" "0")
20306
   (set_attr "prefix" "maybe_vex")
20307
   (set_attr "mode" "DI")])
20308
 
20309
(define_expand "prefetch"
20310
  [(prefetch (match_operand 0 "address_operand" "")
20311
             (match_operand:SI 1 "const_int_operand" "")
20312
             (match_operand:SI 2 "const_int_operand" ""))]
20313
  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20314
{
20315
  int rw = INTVAL (operands[1]);
20316
  int locality = INTVAL (operands[2]);
20317
 
20318
  gcc_assert (rw == 0 || rw == 1);
20319
  gcc_assert (locality >= 0 && locality <= 3);
20320
  gcc_assert (GET_MODE (operands[0]) == Pmode
20321
              || GET_MODE (operands[0]) == VOIDmode);
20322
 
20323
  /* Use 3dNOW prefetch in case we are asking for write prefetch not
20324
     supported by SSE counterpart or the SSE prefetch is not available
20325
     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20326
     of locality.  */
20327
  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20328
    operands[2] = GEN_INT (3);
20329
  else
20330
    operands[1] = const0_rtx;
20331
})
20332
 
20333
(define_insn "*prefetch_sse"
20334
  [(prefetch (match_operand:SI 0 "address_operand" "p")
20335
             (const_int 0)
20336
             (match_operand:SI 1 "const_int_operand" ""))]
20337
  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20338
{
20339
  static const char * const patterns[4] = {
20340
   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20341
  };
20342
 
20343
  int locality = INTVAL (operands[1]);
20344
  gcc_assert (locality >= 0 && locality <= 3);
20345
 
20346
  return patterns[locality];
20347
}
20348
  [(set_attr "type" "sse")
20349
   (set_attr "atom_sse_attr" "prefetch")
20350
   (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20351
   (set_attr "memory" "none")])
20352
 
20353
(define_insn "*prefetch_sse_rex"
20354
  [(prefetch (match_operand:DI 0 "address_operand" "p")
20355
             (const_int 0)
20356
             (match_operand:SI 1 "const_int_operand" ""))]
20357
  "TARGET_PREFETCH_SSE && TARGET_64BIT"
20358
{
20359
  static const char * const patterns[4] = {
20360
   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20361
  };
20362
 
20363
  int locality = INTVAL (operands[1]);
20364
  gcc_assert (locality >= 0 && locality <= 3);
20365
 
20366
  return patterns[locality];
20367
}
20368
  [(set_attr "type" "sse")
20369
   (set_attr "atom_sse_attr" "prefetch")
20370
   (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20371
   (set_attr "memory" "none")])
20372
 
20373
(define_insn "*prefetch_3dnow"
20374
  [(prefetch (match_operand:SI 0 "address_operand" "p")
20375
             (match_operand:SI 1 "const_int_operand" "n")
20376
             (const_int 3))]
20377
  "TARGET_3DNOW && !TARGET_64BIT"
20378
{
20379
  if (INTVAL (operands[1]) == 0)
20380
    return "prefetch\t%a0";
20381
  else
20382
    return "prefetchw\t%a0";
20383
}
20384
  [(set_attr "type" "mmx")
20385
   (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20386
   (set_attr "memory" "none")])
20387
 
20388
(define_insn "*prefetch_3dnow_rex"
20389
  [(prefetch (match_operand:DI 0 "address_operand" "p")
20390
             (match_operand:SI 1 "const_int_operand" "n")
20391
             (const_int 3))]
20392
  "TARGET_3DNOW && TARGET_64BIT"
20393
{
20394
  if (INTVAL (operands[1]) == 0)
20395
    return "prefetch\t%a0";
20396
  else
20397
    return "prefetchw\t%a0";
20398
}
20399
  [(set_attr "type" "mmx")
20400
   (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20401
   (set_attr "memory" "none")])
20402
 
20403
(define_expand "stack_protect_set"
20404
  [(match_operand 0 "memory_operand" "")
20405
   (match_operand 1 "memory_operand" "")]
20406
  ""
20407
{
20408
#ifdef TARGET_THREAD_SSP_OFFSET
20409
  if (TARGET_64BIT)
20410
    emit_insn (gen_stack_tls_protect_set_di (operands[0],
20411
                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20412
  else
20413
    emit_insn (gen_stack_tls_protect_set_si (operands[0],
20414
                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20415
#else
20416
  if (TARGET_64BIT)
20417
    emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20418
  else
20419
    emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20420
#endif
20421
  DONE;
20422
})
20423
 
20424
(define_insn "stack_protect_set_si"
20425
  [(set (match_operand:SI 0 "memory_operand" "=m")
20426
        (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20427
   (set (match_scratch:SI 2 "=&r") (const_int 0))
20428
   (clobber (reg:CC FLAGS_REG))]
20429
  ""
20430
  "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20431
  [(set_attr "type" "multi")])
20432
 
20433
(define_insn "stack_protect_set_di"
20434
  [(set (match_operand:DI 0 "memory_operand" "=m")
20435
        (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20436
   (set (match_scratch:DI 2 "=&r") (const_int 0))
20437
   (clobber (reg:CC FLAGS_REG))]
20438
  "TARGET_64BIT"
20439
  "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20440
  [(set_attr "type" "multi")])
20441
 
20442
(define_insn "stack_tls_protect_set_si"
20443
  [(set (match_operand:SI 0 "memory_operand" "=m")
20444
        (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20445
   (set (match_scratch:SI 2 "=&r") (const_int 0))
20446
   (clobber (reg:CC FLAGS_REG))]
20447
  ""
20448
  "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20449
  [(set_attr "type" "multi")])
20450
 
20451
(define_insn "stack_tls_protect_set_di"
20452
  [(set (match_operand:DI 0 "memory_operand" "=m")
20453
        (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20454
   (set (match_scratch:DI 2 "=&r") (const_int 0))
20455
   (clobber (reg:CC FLAGS_REG))]
20456
  "TARGET_64BIT"
20457
  {
20458
     /* The kernel uses a different segment register for performance reasons; a
20459
        system call would not have to trash the userspace segment register,
20460
        which would be expensive */
20461
     if (ix86_cmodel != CM_KERNEL)
20462
        return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20463
     else
20464
        return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20465
  }
20466
  [(set_attr "type" "multi")])
20467
 
20468
(define_expand "stack_protect_test"
20469
  [(match_operand 0 "memory_operand" "")
20470
   (match_operand 1 "memory_operand" "")
20471
   (match_operand 2 "" "")]
20472
  ""
20473
{
20474
  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20475
 
20476
#ifdef TARGET_THREAD_SSP_OFFSET
20477
  if (TARGET_64BIT)
20478
    emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20479
                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20480
  else
20481
    emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20482
                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20483
#else
20484
  if (TARGET_64BIT)
20485
    emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20486
  else
20487
    emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20488
#endif
20489
 
20490
  emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20491
                                  flags, const0_rtx, operands[2]));
20492
  DONE;
20493
})
20494
 
20495
(define_insn "stack_protect_test_si"
20496
  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20497
        (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20498
                     (match_operand:SI 2 "memory_operand" "m")]
20499
                    UNSPEC_SP_TEST))
20500
   (clobber (match_scratch:SI 3 "=&r"))]
20501
  ""
20502
  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20503
  [(set_attr "type" "multi")])
20504
 
20505
(define_insn "stack_protect_test_di"
20506
  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20507
        (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20508
                     (match_operand:DI 2 "memory_operand" "m")]
20509
                    UNSPEC_SP_TEST))
20510
   (clobber (match_scratch:DI 3 "=&r"))]
20511
  "TARGET_64BIT"
20512
  "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20513
  [(set_attr "type" "multi")])
20514
 
20515
(define_insn "stack_tls_protect_test_si"
20516
  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20517
        (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20518
                     (match_operand:SI 2 "const_int_operand" "i")]
20519
                    UNSPEC_SP_TLS_TEST))
20520
   (clobber (match_scratch:SI 3 "=r"))]
20521
  ""
20522
  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
20523
  [(set_attr "type" "multi")])
20524
 
20525
(define_insn "stack_tls_protect_test_di"
20526
  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20527
        (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20528
                     (match_operand:DI 2 "const_int_operand" "i")]
20529
                    UNSPEC_SP_TLS_TEST))
20530
   (clobber (match_scratch:DI 3 "=r"))]
20531
  "TARGET_64BIT"
20532
  {
20533
     /* The kernel uses a different segment register for performance reasons; a
20534
        system call would not have to trash the userspace segment register,
20535
        which would be expensive */
20536
     if (ix86_cmodel != CM_KERNEL)
20537
        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
20538
     else
20539
        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
20540
  }
20541
  [(set_attr "type" "multi")])
20542
 
20543
(define_insn "sse4_2_crc32"
20544
  [(set (match_operand:SI 0 "register_operand" "=r")
20545
        (unspec:SI
20546
          [(match_operand:SI 1 "register_operand" "0")
20547
           (match_operand:SWI124 2 "nonimmediate_operand" "m")]
20548
          UNSPEC_CRC32))]
20549
  "TARGET_SSE4_2 || TARGET_CRC32"
20550
  "crc32{}\t{%2, %0|%0, %2}"
20551
  [(set_attr "type" "sselog1")
20552
   (set_attr "prefix_rep" "1")
20553
   (set_attr "prefix_extra" "1")
20554
   (set (attr "prefix_data16")
20555
     (if_then_else (match_operand:HI 2 "" "")
20556
       (const_string "1")
20557
       (const_string "*")))
20558
   (set (attr "prefix_rex")
20559
     (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
20560
       (const_string "1")
20561
       (const_string "*")))
20562
   (set_attr "mode" "SI")])
20563
 
20564
(define_insn "sse4_2_crc32di"
20565
  [(set (match_operand:DI 0 "register_operand" "=r")
20566
        (unspec:DI
20567
          [(match_operand:DI 1 "register_operand" "0")
20568
           (match_operand:DI 2 "nonimmediate_operand" "rm")]
20569
          UNSPEC_CRC32))]
20570
  "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20571
  "crc32{q}\t{%2, %0|%0, %2}"
20572
  [(set_attr "type" "sselog1")
20573
   (set_attr "prefix_rep" "1")
20574
   (set_attr "prefix_extra" "1")
20575
   (set_attr "mode" "DI")])
20576
 
20577
(define_expand "rdpmc"
20578
  [(match_operand:DI 0 "register_operand" "")
20579
   (match_operand:SI 1 "register_operand" "")]
20580
  ""
20581
{
20582
  rtx reg = gen_reg_rtx (DImode);
20583
  rtx si;
20584
 
20585
  /* Force operand 1 into ECX.  */
20586
  rtx ecx = gen_rtx_REG (SImode, CX_REG);
20587
  emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
20588
  si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
20589
                                UNSPECV_RDPMC);
20590
 
20591
  if (TARGET_64BIT)
20592
    {
20593
      rtvec vec = rtvec_alloc (2);
20594
      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20595
      rtx upper = gen_reg_rtx (DImode);
20596
      rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20597
                                        gen_rtvec (1, const0_rtx),
20598
                                        UNSPECV_RDPMC);
20599
      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
20600
      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20601
      emit_insn (load);
20602
      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20603
                                   NULL, 1, OPTAB_DIRECT);
20604
      reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20605
                                 OPTAB_DIRECT);
20606
    }
20607
  else
20608
    emit_insn (gen_rtx_SET (VOIDmode, reg, si));
20609
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20610
  DONE;
20611
})
20612
 
20613
(define_insn "*rdpmc"
20614
  [(set (match_operand:DI 0 "register_operand" "=A")
20615
        (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20616
                            UNSPECV_RDPMC))]
20617
  "!TARGET_64BIT"
20618
  "rdpmc"
20619
  [(set_attr "type" "other")
20620
   (set_attr "length" "2")])
20621
 
20622
(define_insn "*rdpmc_rex64"
20623
  [(set (match_operand:DI 0 "register_operand" "=a")
20624
        (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20625
                            UNSPECV_RDPMC))
20626
  (set (match_operand:DI 1 "register_operand" "=d")
20627
       (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
20628
  "TARGET_64BIT"
20629
  "rdpmc"
20630
  [(set_attr "type" "other")
20631
   (set_attr "length" "2")])
20632
 
20633
(define_expand "rdtsc"
20634
  [(set (match_operand:DI 0 "register_operand" "")
20635
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20636
  ""
20637
{
20638
  if (TARGET_64BIT)
20639
    {
20640
      rtvec vec = rtvec_alloc (2);
20641
      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20642
      rtx upper = gen_reg_rtx (DImode);
20643
      rtx lower = gen_reg_rtx (DImode);
20644
      rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
20645
                                         gen_rtvec (1, const0_rtx),
20646
                                         UNSPECV_RDTSC);
20647
      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
20648
      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
20649
      emit_insn (load);
20650
      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20651
                                   NULL, 1, OPTAB_DIRECT);
20652
      lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
20653
                                   OPTAB_DIRECT);
20654
      emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
20655
      DONE;
20656
    }
20657
})
20658
 
20659
(define_insn "*rdtsc"
20660
  [(set (match_operand:DI 0 "register_operand" "=A")
20661
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20662
  "!TARGET_64BIT"
20663
  "rdtsc"
20664
  [(set_attr "type" "other")
20665
   (set_attr "length" "2")])
20666
 
20667
(define_insn "*rdtsc_rex64"
20668
  [(set (match_operand:DI 0 "register_operand" "=a")
20669
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20670
   (set (match_operand:DI 1 "register_operand" "=d")
20671
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20672
  "TARGET_64BIT"
20673
  "rdtsc"
20674
  [(set_attr "type" "other")
20675
   (set_attr "length" "2")])
20676
 
20677
(define_expand "rdtscp"
20678
  [(match_operand:DI 0 "register_operand" "")
20679
   (match_operand:SI 1 "memory_operand" "")]
20680
  ""
20681
{
20682
  rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20683
                                    gen_rtvec (1, const0_rtx),
20684
                                    UNSPECV_RDTSCP);
20685
  rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
20686
                                    gen_rtvec (1, const0_rtx),
20687
                                    UNSPECV_RDTSCP);
20688
  rtx reg = gen_reg_rtx (DImode);
20689
  rtx tmp = gen_reg_rtx (SImode);
20690
 
20691
  if (TARGET_64BIT)
20692
    {
20693
      rtvec vec = rtvec_alloc (3);
20694
      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20695
      rtx upper = gen_reg_rtx (DImode);
20696
      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20697
      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20698
      RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
20699
      emit_insn (load);
20700
      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20701
                                   NULL, 1, OPTAB_DIRECT);
20702
      reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20703
                                 OPTAB_DIRECT);
20704
    }
20705
  else
20706
    {
20707
      rtvec vec = rtvec_alloc (2);
20708
      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20709
      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20710
      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
20711
      emit_insn (load);
20712
    }
20713
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20714
  emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
20715
  DONE;
20716
})
20717
 
20718
(define_insn "*rdtscp"
20719
  [(set (match_operand:DI 0 "register_operand" "=A")
20720
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20721
   (set (match_operand:SI 1 "register_operand" "=c")
20722
        (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20723
  "!TARGET_64BIT"
20724
  "rdtscp"
20725
  [(set_attr "type" "other")
20726
   (set_attr "length" "3")])
20727
 
20728
(define_insn "*rdtscp_rex64"
20729
  [(set (match_operand:DI 0 "register_operand" "=a")
20730
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20731
   (set (match_operand:DI 1 "register_operand" "=d")
20732
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20733
   (set (match_operand:SI 2 "register_operand" "=c")
20734
        (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20735
  "TARGET_64BIT"
20736
  "rdtscp"
20737
  [(set_attr "type" "other")
20738
   (set_attr "length" "3")])
20739
 
20740
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20741
;;
20742
;; LWP instructions
20743
;;
20744
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20745
 
20746
(define_expand "lwp_llwpcb"
20747
  [(unspec_volatile [(match_operand 0 "register_operand" "r")]
20748
                    UNSPECV_LLWP_INTRINSIC)]
20749
  "TARGET_LWP"
20750
  "")
20751
 
20752
(define_insn "*lwp_llwpcb1"
20753
  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20754
                    UNSPECV_LLWP_INTRINSIC)]
20755
  "TARGET_LWP"
20756
  "llwpcb\t%0"
20757
  [(set_attr "type" "lwp")
20758
   (set_attr "mode" "")
20759
   (set_attr "length" "5")])
20760
 
20761
(define_expand "lwp_slwpcb"
20762
  [(set (match_operand 0 "register_operand" "=r")
20763
        (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20764
  "TARGET_LWP"
20765
  {
20766
    if (TARGET_64BIT)
20767
      emit_insn (gen_lwp_slwpcbdi (operands[0]));
20768
    else
20769
      emit_insn (gen_lwp_slwpcbsi (operands[0]));
20770
    DONE;
20771
  })
20772
 
20773
(define_insn "lwp_slwpcb"
20774
  [(set (match_operand:P 0 "register_operand" "=r")
20775
        (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20776
  "TARGET_LWP"
20777
  "slwpcb\t%0"
20778
  [(set_attr "type" "lwp")
20779
   (set_attr "mode" "")
20780
   (set_attr "length" "5")])
20781
 
20782
(define_expand "lwp_lwpval3"
20783
  [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
20784
                     (match_operand:SI 2 "nonimmediate_operand" "rm")
20785
                     (match_operand:SI 3 "const_int_operand" "i")]
20786
                    UNSPECV_LWPVAL_INTRINSIC)]
20787
  "TARGET_LWP"
20788
  "/* Avoid unused variable warning.  */
20789
   (void) operand0;")
20790
 
20791
(define_insn "*lwp_lwpval3_1"
20792
  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20793
                     (match_operand:SI 1 "nonimmediate_operand" "rm")
20794
                     (match_operand:SI 2 "const_int_operand" "i")]
20795
                    UNSPECV_LWPVAL_INTRINSIC)]
20796
  "TARGET_LWP"
20797
  "lwpval\t{%2, %1, %0|%0, %1, %2}"
20798
  [(set_attr "type" "lwp")
20799
   (set_attr "mode" "")
20800
   (set (attr "length")
20801
        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20802
 
20803
(define_expand "lwp_lwpins3"
20804
  [(set (reg:CCC FLAGS_REG)
20805
        (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
20806
                              (match_operand:SI 2 "nonimmediate_operand" "rm")
20807
                              (match_operand:SI 3 "const_int_operand" "i")]
20808
                             UNSPECV_LWPINS_INTRINSIC))
20809
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
20810
        (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20811
  "TARGET_LWP"
20812
  "")
20813
 
20814
(define_insn "*lwp_lwpins3_1"
20815
  [(set (reg:CCC FLAGS_REG)
20816
        (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20817
                              (match_operand:SI 1 "nonimmediate_operand" "rm")
20818
                              (match_operand:SI 2 "const_int_operand" "i")]
20819
                             UNSPECV_LWPINS_INTRINSIC))]
20820
  "TARGET_LWP"
20821
  "lwpins\t{%2, %1, %0|%0, %1, %2}"
20822
  [(set_attr "type" "lwp")
20823
   (set_attr "mode" "")
20824
   (set (attr "length")
20825
        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20826
 
20827
(include "mmx.md")
20828
(include "sse.md")
20829
(include "sync.md")

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.