OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [i386/] [i386.md] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 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, 2011, 2012
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
;; F,f -- likewise, but for floating-point.
34
;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35
;;      otherwise nothing
36
;; R -- print the prefix for register names.
37
;; z -- print the opcode suffix for the size of the current operand.
38
;; Z -- likewise, with special suffixes for x87 instructions.
39
;; * -- print a star (in certain assembler syntax)
40
;; A -- print an absolute memory reference.
41
;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42
;; s -- print a shift double count, followed by the assemblers argument
43
;;      delimiter.
44
;; b -- print the QImode name of the register for the indicated operand.
45
;;      %b0 would print %al if operands[0] is reg 0.
46
;; w --  likewise, print the HImode name of the register.
47
;; k --  likewise, print the SImode name of the register.
48
;; q --  likewise, print the DImode name of the register.
49
;; x --  likewise, print the V4SFmode name of the register.
50
;; t --  likewise, print the V8SFmode name of the register.
51
;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52
;; y -- print "st(0)" instead of "st" as a register.
53
;; d -- print duplicated register operand for AVX instruction.
54
;; D -- print condition for SSE cmp instruction.
55
;; P -- if PIC, print an @PLT suffix.
56
;; p -- print raw symbol name.
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
;; @ -- print a segment register of thread base pointer load
64
 
65
(define_c_enum "unspec" [
66
  ;; Relocation specifiers
67
  UNSPEC_GOT
68
  UNSPEC_GOTOFF
69
  UNSPEC_GOTPCREL
70
  UNSPEC_GOTTPOFF
71
  UNSPEC_TPOFF
72
  UNSPEC_NTPOFF
73
  UNSPEC_DTPOFF
74
  UNSPEC_GOTNTPOFF
75
  UNSPEC_INDNTPOFF
76
  UNSPEC_PLTOFF
77
  UNSPEC_MACHOPIC_OFFSET
78
  UNSPEC_PCREL
79
 
80
  ;; Prologue support
81
  UNSPEC_STACK_ALLOC
82
  UNSPEC_SET_GOT
83
  UNSPEC_REG_SAVE
84
  UNSPEC_DEF_CFA
85
  UNSPEC_SET_RIP
86
  UNSPEC_SET_GOT_OFFSET
87
  UNSPEC_MEMORY_BLOCKAGE
88
  UNSPEC_STACK_CHECK
89
 
90
  ;; TLS support
91
  UNSPEC_TP
92
  UNSPEC_TLS_GD
93
  UNSPEC_TLS_LD_BASE
94
  UNSPEC_TLSDESC
95
  UNSPEC_TLS_IE_SUN
96
 
97
  ;; Other random patterns
98
  UNSPEC_SCAS
99
  UNSPEC_FNSTSW
100
  UNSPEC_SAHF
101
  UNSPEC_PARITY
102
  UNSPEC_FSTCW
103
  UNSPEC_ADD_CARRY
104
  UNSPEC_FLDCW
105
  UNSPEC_REP
106
  UNSPEC_LD_MPIC        ; load_macho_picbase
107
  UNSPEC_TRUNC_NOOP
108
  UNSPEC_DIV_ALREADY_SPLIT
109
  UNSPEC_MS_TO_SYSV_CALL
110
  UNSPEC_CALL_NEEDS_VZEROUPPER
111
  UNSPEC_PAUSE
112
 
113
  ;; For SSE/MMX support:
114
  UNSPEC_FIX_NOTRUNC
115
  UNSPEC_MASKMOV
116
  UNSPEC_MOVMSK
117
  UNSPEC_RCP
118
  UNSPEC_RSQRT
119
  UNSPEC_PSADBW
120
 
121
  ;; Generic math support
122
  UNSPEC_COPYSIGN
123
  UNSPEC_IEEE_MIN       ; not commutative
124
  UNSPEC_IEEE_MAX       ; not commutative
125
 
126
  ;; x87 Floating point
127
  UNSPEC_SIN
128
  UNSPEC_COS
129
  UNSPEC_FPATAN
130
  UNSPEC_FYL2X
131
  UNSPEC_FYL2XP1
132
  UNSPEC_FRNDINT
133
  UNSPEC_FIST
134
  UNSPEC_F2XM1
135
  UNSPEC_TAN
136
  UNSPEC_FXAM
137
 
138
  ;; x87 Rounding
139
  UNSPEC_FRNDINT_FLOOR
140
  UNSPEC_FRNDINT_CEIL
141
  UNSPEC_FRNDINT_TRUNC
142
  UNSPEC_FRNDINT_MASK_PM
143
  UNSPEC_FIST_FLOOR
144
  UNSPEC_FIST_CEIL
145
 
146
  ;; x87 Double output FP
147
  UNSPEC_SINCOS_COS
148
  UNSPEC_SINCOS_SIN
149
  UNSPEC_XTRACT_FRACT
150
  UNSPEC_XTRACT_EXP
151
  UNSPEC_FSCALE_FRACT
152
  UNSPEC_FSCALE_EXP
153
  UNSPEC_FPREM_F
154
  UNSPEC_FPREM_U
155
  UNSPEC_FPREM1_F
156
  UNSPEC_FPREM1_U
157
 
158
  UNSPEC_C2_FLAG
159
  UNSPEC_FXAM_MEM
160
 
161
  ;; SSP patterns
162
  UNSPEC_SP_SET
163
  UNSPEC_SP_TEST
164
  UNSPEC_SP_TLS_SET
165
  UNSPEC_SP_TLS_TEST
166
 
167
  ;; For ROUND support
168
  UNSPEC_ROUND
169
 
170
  ;; For CRC32 support
171
  UNSPEC_CRC32
172
 
173
  ;; For RDRAND support
174
  UNSPEC_RDRAND
175
 
176
  ;; For BMI support
177
  UNSPEC_BEXTR
178
 
179
  ;; For BMI2 support
180
  UNSPEC_PDEP
181
  UNSPEC_PEXT
182
])
183
 
184
(define_c_enum "unspecv" [
185
  UNSPECV_BLOCKAGE
186
  UNSPECV_STACK_PROBE
187
  UNSPECV_PROBE_STACK_RANGE
188
  UNSPECV_ALIGN
189
  UNSPECV_PROLOGUE_USE
190
  UNSPECV_SPLIT_STACK_RETURN
191
  UNSPECV_CLD
192
  UNSPECV_NOPS
193
  UNSPECV_RDTSC
194
  UNSPECV_RDTSCP
195
  UNSPECV_RDPMC
196
  UNSPECV_LLWP_INTRINSIC
197
  UNSPECV_SLWP_INTRINSIC
198
  UNSPECV_LWPVAL_INTRINSIC
199
  UNSPECV_LWPINS_INTRINSIC
200
  UNSPECV_RDFSBASE
201
  UNSPECV_RDGSBASE
202
  UNSPECV_WRFSBASE
203
  UNSPECV_WRGSBASE
204
])
205
 
206
;; Constants to represent rounding modes in the ROUND instruction
207
(define_constants
208
  [(ROUND_FLOOR                 0x1)
209
   (ROUND_CEIL                  0x2)
210
   (ROUND_TRUNC                 0x3)
211
   (ROUND_MXCSR                 0x4)
212
   (ROUND_NO_EXC                0x8)
213
  ])
214
 
215
;; Constants to represent pcomtrue/pcomfalse variants
216
(define_constants
217
  [(PCOM_FALSE                  0)
218
   (PCOM_TRUE                   1)
219
   (COM_FALSE_S                 2)
220
   (COM_FALSE_P                 3)
221
   (COM_TRUE_S                  4)
222
   (COM_TRUE_P                  5)
223
  ])
224
 
225
;; Constants used in the XOP pperm instruction
226
(define_constants
227
  [(PPERM_SRC                   0x00)   /* copy source */
228
   (PPERM_INVERT                0x20)   /* invert source */
229
   (PPERM_REVERSE               0x40)   /* bit reverse source */
230
   (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
231
   (PPERM_ZERO                  0x80)   /* all 0's */
232
   (PPERM_ONES                  0xa0)   /* all 1's */
233
   (PPERM_SIGN                  0xc0)   /* propagate sign bit */
234
   (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
235
   (PPERM_SRC1                  0x00)   /* use first source byte */
236
   (PPERM_SRC2                  0x10)   /* use second source byte */
237
   ])
238
 
239
;; Registers by name.
240
(define_constants
241
  [(AX_REG                       0)
242
   (DX_REG                       1)
243
   (CX_REG                       2)
244
   (BX_REG                       3)
245
   (SI_REG                       4)
246
   (DI_REG                       5)
247
   (BP_REG                       6)
248
   (SP_REG                       7)
249
   (ST0_REG                      8)
250
   (ST1_REG                      9)
251
   (ST2_REG                     10)
252
   (ST3_REG                     11)
253
   (ST4_REG                     12)
254
   (ST5_REG                     13)
255
   (ST6_REG                     14)
256
   (ST7_REG                     15)
257
   (FLAGS_REG                   17)
258
   (FPSR_REG                    18)
259
   (FPCR_REG                    19)
260
   (XMM0_REG                    21)
261
   (XMM1_REG                    22)
262
   (XMM2_REG                    23)
263
   (XMM3_REG                    24)
264
   (XMM4_REG                    25)
265
   (XMM5_REG                    26)
266
   (XMM6_REG                    27)
267
   (XMM7_REG                    28)
268
   (MM0_REG                     29)
269
   (MM1_REG                     30)
270
   (MM2_REG                     31)
271
   (MM3_REG                     32)
272
   (MM4_REG                     33)
273
   (MM5_REG                     34)
274
   (MM6_REG                     35)
275
   (MM7_REG                     36)
276
   (R8_REG                      37)
277
   (R9_REG                      38)
278
   (R10_REG                     39)
279
   (R11_REG                     40)
280
   (R12_REG                     41)
281
   (R13_REG                     42)
282
   (XMM8_REG                    45)
283
   (XMM9_REG                    46)
284
   (XMM10_REG                   47)
285
   (XMM11_REG                   48)
286
   (XMM12_REG                   49)
287
   (XMM13_REG                   50)
288
   (XMM14_REG                   51)
289
   (XMM15_REG                   52)
290
  ])
291
 
292
;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
293
;; from i386.c.
294
 
295
;; In C guard expressions, put expressions which may be compile-time
296
;; constants first.  This allows for better optimization.  For
297
;; example, write "TARGET_64BIT && reload_completed", not
298
;; "reload_completed && TARGET_64BIT".
299
 
300
 
301
;; Processor type.
302
(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
303
                    atom,generic64,amdfam10,bdver1,bdver2,btver1"
304
  (const (symbol_ref "ix86_schedule")))
305
 
306
;; A basic instruction type.  Refinements due to arguments to be
307
;; provided in other attributes.
308
(define_attr "type"
309
  "other,multi,
310
   alu,alu1,negnot,imov,imovx,lea,
311
   incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
312
   icmp,test,ibr,setcc,icmov,
313
   push,pop,call,callv,leave,
314
   str,bitmanip,
315
   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
316
   sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
317
   sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
318
   ssemuladd,sse4arg,lwp,
319
   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
320
  (const_string "other"))
321
 
322
;; Main data type used by the insn
323
(define_attr "mode"
324
  "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
325
  (const_string "unknown"))
326
 
327
;; The CPU unit operations uses.
328
(define_attr "unit" "integer,i387,sse,mmx,unknown"
329
  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
330
           (const_string "i387")
331
         (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
332
                          sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
333
                          ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
334
           (const_string "sse")
335
         (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
336
           (const_string "mmx")
337
         (eq_attr "type" "other")
338
           (const_string "unknown")]
339
         (const_string "integer")))
340
 
341
;; The (bounding maximum) length of an instruction immediate.
342
(define_attr "length_immediate" ""
343
  (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
344
                          bitmanip,imulx")
345
           (const_int 0)
346
         (eq_attr "unit" "i387,sse,mmx")
347
           (const_int 0)
348
         (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
349
                          rotate,rotatex,rotate1,imul,icmp,push,pop")
350
           (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
351
         (eq_attr "type" "imov,test")
352
           (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
353
         (eq_attr "type" "call")
354
           (if_then_else (match_operand 0 "constant_call_address_operand" "")
355
             (const_int 4)
356
             (const_int 0))
357
         (eq_attr "type" "callv")
358
           (if_then_else (match_operand 1 "constant_call_address_operand" "")
359
             (const_int 4)
360
             (const_int 0))
361
         ;; We don't know the size before shorten_branches.  Expect
362
         ;; the instruction to fit for better scheduling.
363
         (eq_attr "type" "ibr")
364
           (const_int 1)
365
         ]
366
         (symbol_ref "/* Update immediate_length and other attributes! */
367
                      gcc_unreachable (),1")))
368
 
369
;; The (bounding maximum) length of an instruction address.
370
(define_attr "length_address" ""
371
  (cond [(eq_attr "type" "str,other,multi,fxch")
372
           (const_int 0)
373
         (and (eq_attr "type" "call")
374
              (match_operand 0 "constant_call_address_operand" ""))
375
             (const_int 0)
376
         (and (eq_attr "type" "callv")
377
              (match_operand 1 "constant_call_address_operand" ""))
378
             (const_int 0)
379
         ]
380
         (symbol_ref "ix86_attr_length_address_default (insn)")))
381
 
382
;; Set when length prefix is used.
383
(define_attr "prefix_data16" ""
384
  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
385
           (const_int 0)
386
         (eq_attr "mode" "HI")
387
           (const_int 1)
388
         (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
389
           (const_int 1)
390
        ]
391
        (const_int 0)))
392
 
393
;; Set when string REP prefix is used.
394
(define_attr "prefix_rep" ""
395
  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
396
           (const_int 0)
397
         (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
398
           (const_int 1)
399
        ]
400
        (const_int 0)))
401
 
402
;; Set when 0f opcode prefix is used.
403
(define_attr "prefix_0f" ""
404
  (if_then_else
405
    (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
406
         (eq_attr "unit" "sse,mmx"))
407
    (const_int 1)
408
    (const_int 0)))
409
 
410
;; Set when REX opcode prefix is used.
411
(define_attr "prefix_rex" ""
412
  (cond [(not (match_test "TARGET_64BIT"))
413
           (const_int 0)
414
         (and (eq_attr "mode" "DI")
415
              (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
416
                   (eq_attr "unit" "!mmx")))
417
           (const_int 1)
418
         (and (eq_attr "mode" "QI")
419
              (match_test "x86_extended_QIreg_mentioned_p (insn)"))
420
           (const_int 1)
421
         (match_test "x86_extended_reg_mentioned_p (insn)")
422
           (const_int 1)
423
         (and (eq_attr "type" "imovx")
424
              (match_operand:QI 1 "ext_QIreg_operand" ""))
425
           (const_int 1)
426
        ]
427
        (const_int 0)))
428
 
429
;; There are also additional prefixes in 3DNOW, SSSE3.
430
;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
431
;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
432
;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
433
(define_attr "prefix_extra" ""
434
  (cond [(eq_attr "type" "ssemuladd,sse4arg")
435
           (const_int 2)
436
         (eq_attr "type" "sseiadd1,ssecvt1")
437
           (const_int 1)
438
        ]
439
        (const_int 0)))
440
 
441
;; Prefix used: original, VEX or maybe VEX.
442
(define_attr "prefix" "orig,vex,maybe_vex"
443
  (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
444
    (const_string "vex")
445
    (const_string "orig")))
446
 
447
;; VEX W bit is used.
448
(define_attr "prefix_vex_w" "" (const_int 0))
449
 
450
;; The length of VEX prefix
451
;; Only instructions with 0f prefix can have 2 byte VEX prefix,
452
;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
453
;; still prefix_0f 1, with prefix_extra 1.
454
(define_attr "length_vex" ""
455
  (if_then_else (and (eq_attr "prefix_0f" "1")
456
                     (eq_attr "prefix_extra" "0"))
457
    (if_then_else (eq_attr "prefix_vex_w" "1")
458
      (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
459
      (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
460
    (if_then_else (eq_attr "prefix_vex_w" "1")
461
      (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
462
      (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
463
 
464
;; Set when modrm byte is used.
465
(define_attr "modrm" ""
466
  (cond [(eq_attr "type" "str,leave")
467
           (const_int 0)
468
         (eq_attr "unit" "i387")
469
           (const_int 0)
470
         (and (eq_attr "type" "incdec")
471
              (and (not (match_test "TARGET_64BIT"))
472
                   (ior (match_operand:SI 1 "register_operand" "")
473
                        (match_operand:HI 1 "register_operand" ""))))
474
           (const_int 0)
475
         (and (eq_attr "type" "push")
476
              (not (match_operand 1 "memory_operand" "")))
477
           (const_int 0)
478
         (and (eq_attr "type" "pop")
479
              (not (match_operand 0 "memory_operand" "")))
480
           (const_int 0)
481
         (and (eq_attr "type" "imov")
482
              (and (not (eq_attr "mode" "DI"))
483
                   (ior (and (match_operand 0 "register_operand" "")
484
                             (match_operand 1 "immediate_operand" ""))
485
                        (ior (and (match_operand 0 "ax_reg_operand" "")
486
                                  (match_operand 1 "memory_displacement_only_operand" ""))
487
                             (and (match_operand 0 "memory_displacement_only_operand" "")
488
                                  (match_operand 1 "ax_reg_operand" ""))))))
489
           (const_int 0)
490
         (and (eq_attr "type" "call")
491
              (match_operand 0 "constant_call_address_operand" ""))
492
             (const_int 0)
493
         (and (eq_attr "type" "callv")
494
              (match_operand 1 "constant_call_address_operand" ""))
495
             (const_int 0)
496
         (and (eq_attr "type" "alu,alu1,icmp,test")
497
              (match_operand 0 "ax_reg_operand" ""))
498
             (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
499
         ]
500
         (const_int 1)))
501
 
502
;; The (bounding maximum) length of an instruction in bytes.
503
;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
504
;; Later we may want to split them and compute proper length as for
505
;; other insns.
506
(define_attr "length" ""
507
  (cond [(eq_attr "type" "other,multi,fistp,frndint")
508
           (const_int 16)
509
         (eq_attr "type" "fcmp")
510
           (const_int 4)
511
         (eq_attr "unit" "i387")
512
           (plus (const_int 2)
513
                 (plus (attr "prefix_data16")
514
                       (attr "length_address")))
515
         (ior (eq_attr "prefix" "vex")
516
              (and (eq_attr "prefix" "maybe_vex")
517
                   (match_test "TARGET_AVX")))
518
           (plus (attr "length_vex")
519
                 (plus (attr "length_immediate")
520
                       (plus (attr "modrm")
521
                             (attr "length_address"))))]
522
         (plus (plus (attr "modrm")
523
                     (plus (attr "prefix_0f")
524
                           (plus (attr "prefix_rex")
525
                                 (plus (attr "prefix_extra")
526
                                       (const_int 1)))))
527
               (plus (attr "prefix_rep")
528
                     (plus (attr "prefix_data16")
529
                           (plus (attr "length_immediate")
530
                                 (attr "length_address")))))))
531
 
532
;; The `memory' attribute is `none' if no memory is referenced, `load' or
533
;; `store' if there is a simple memory reference therein, or `unknown'
534
;; if the instruction is complex.
535
 
536
(define_attr "memory" "none,load,store,both,unknown"
537
  (cond [(eq_attr "type" "other,multi,str,lwp")
538
           (const_string "unknown")
539
         (eq_attr "type" "lea,fcmov,fpspc")
540
           (const_string "none")
541
         (eq_attr "type" "fistp,leave")
542
           (const_string "both")
543
         (eq_attr "type" "frndint")
544
           (const_string "load")
545
         (eq_attr "type" "push")
546
           (if_then_else (match_operand 1 "memory_operand" "")
547
             (const_string "both")
548
             (const_string "store"))
549
         (eq_attr "type" "pop")
550
           (if_then_else (match_operand 0 "memory_operand" "")
551
             (const_string "both")
552
             (const_string "load"))
553
         (eq_attr "type" "setcc")
554
           (if_then_else (match_operand 0 "memory_operand" "")
555
             (const_string "store")
556
             (const_string "none"))
557
         (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
558
           (if_then_else (ior (match_operand 0 "memory_operand" "")
559
                              (match_operand 1 "memory_operand" ""))
560
             (const_string "load")
561
             (const_string "none"))
562
         (eq_attr "type" "ibr")
563
           (if_then_else (match_operand 0 "memory_operand" "")
564
             (const_string "load")
565
             (const_string "none"))
566
         (eq_attr "type" "call")
567
           (if_then_else (match_operand 0 "constant_call_address_operand" "")
568
             (const_string "none")
569
             (const_string "load"))
570
         (eq_attr "type" "callv")
571
           (if_then_else (match_operand 1 "constant_call_address_operand" "")
572
             (const_string "none")
573
             (const_string "load"))
574
         (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
575
              (match_operand 1 "memory_operand" ""))
576
           (const_string "both")
577
         (and (match_operand 0 "memory_operand" "")
578
              (match_operand 1 "memory_operand" ""))
579
           (const_string "both")
580
         (match_operand 0 "memory_operand" "")
581
           (const_string "store")
582
         (match_operand 1 "memory_operand" "")
583
           (const_string "load")
584
         (and (eq_attr "type"
585
                 "!alu1,negnot,ishift1,
586
                   imov,imovx,icmp,test,bitmanip,
587
                   fmov,fcmp,fsgn,
588
                   sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
589
                   sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
590
              (match_operand 2 "memory_operand" ""))
591
           (const_string "load")
592
         (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
593
              (match_operand 3 "memory_operand" ""))
594
           (const_string "load")
595
        ]
596
        (const_string "none")))
597
 
598
;; Indicates if an instruction has both an immediate and a displacement.
599
 
600
(define_attr "imm_disp" "false,true,unknown"
601
  (cond [(eq_attr "type" "other,multi")
602
           (const_string "unknown")
603
         (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
604
              (and (match_operand 0 "memory_displacement_operand" "")
605
                   (match_operand 1 "immediate_operand" "")))
606
           (const_string "true")
607
         (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
608
              (and (match_operand 0 "memory_displacement_operand" "")
609
                   (match_operand 2 "immediate_operand" "")))
610
           (const_string "true")
611
        ]
612
        (const_string "false")))
613
 
614
;; Indicates if an FP operation has an integer source.
615
 
616
(define_attr "fp_int_src" "false,true"
617
  (const_string "false"))
618
 
619
;; Defines rounding mode of an FP operation.
620
 
621
(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
622
  (const_string "any"))
623
 
624
;; Define attribute to classify add/sub insns that consumes carry flag (CF)
625
(define_attr "use_carry" "0,1" (const_string "0"))
626
 
627
;; Define attribute to indicate unaligned ssemov insns
628
(define_attr "movu" "0,1" (const_string "0"))
629
 
630
;; Used to control the "enabled" attribute on a per-instruction basis.
631
(define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
632
  (const_string "base"))
633
 
634
(define_attr "enabled" ""
635
  (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
636
         (eq_attr "isa" "sse2_noavx")
637
           (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
638
         (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
639
         (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
640
         (eq_attr "isa" "sse4_noavx")
641
           (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
642
         (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
643
         (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
644
         (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
645
        ]
646
        (const_int 1)))
647
 
648
;; Describe a user's asm statement.
649
(define_asm_attributes
650
  [(set_attr "length" "128")
651
   (set_attr "type" "multi")])
652
 
653
(define_code_iterator plusminus [plus minus])
654
 
655
(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
656
 
657
;; Base name for define_insn
658
(define_code_attr plusminus_insn
659
  [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
660
   (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
661
 
662
;; Base name for insn mnemonic.
663
(define_code_attr plusminus_mnemonic
664
  [(plus "add") (ss_plus "adds") (us_plus "addus")
665
   (minus "sub") (ss_minus "subs") (us_minus "subus")])
666
(define_code_attr plusminus_carry_mnemonic
667
  [(plus "adc") (minus "sbb")])
668
 
669
;; Mark commutative operators as such in constraints.
670
(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
671
                        (minus "") (ss_minus "") (us_minus "")])
672
 
673
;; Mapping of max and min
674
(define_code_iterator maxmin [smax smin umax umin])
675
 
676
;; Mapping of signed max and min
677
(define_code_iterator smaxmin [smax smin])
678
 
679
;; Mapping of unsigned max and min
680
(define_code_iterator umaxmin [umax umin])
681
 
682
;; Base name for integer and FP insn mnemonic
683
(define_code_attr maxmin_int [(smax "maxs") (smin "mins")
684
                              (umax "maxu") (umin "minu")])
685
(define_code_attr maxmin_float [(smax "max") (smin "min")])
686
 
687
;; Mapping of logic operators
688
(define_code_iterator any_logic [and ior xor])
689
(define_code_iterator any_or [ior xor])
690
 
691
;; Base name for insn mnemonic.
692
(define_code_attr logic [(and "and") (ior "or") (xor "xor")])
693
 
694
;; Mapping of logic-shift operators
695
(define_code_iterator any_lshift [ashift lshiftrt])
696
 
697
;; Mapping of shift-right operators
698
(define_code_iterator any_shiftrt [lshiftrt ashiftrt])
699
 
700
;; Base name for define_insn
701
(define_code_attr shift_insn
702
  [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
703
 
704
;; Base name for insn mnemonic.
705
(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
706
(define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
707
 
708
;; Mapping of rotate operators
709
(define_code_iterator any_rotate [rotate rotatert])
710
 
711
;; Base name for define_insn
712
(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
713
 
714
;; Base name for insn mnemonic.
715
(define_code_attr rotate [(rotate "rol") (rotatert "ror")])
716
 
717
;; Mapping of abs neg operators
718
(define_code_iterator absneg [abs neg])
719
 
720
;; Base name for x87 insn mnemonic.
721
(define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
722
 
723
;; Used in signed and unsigned widening multiplications.
724
(define_code_iterator any_extend [sign_extend zero_extend])
725
 
726
;; Prefix for insn menmonic.
727
(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
728
 
729
;; Prefix for define_insn
730
(define_code_attr u [(sign_extend "") (zero_extend "u")])
731
(define_code_attr s [(sign_extend "s") (zero_extend "u")])
732
 
733
;; All integer modes.
734
(define_mode_iterator SWI1248x [QI HI SI DI])
735
 
736
;; All integer modes without QImode.
737
(define_mode_iterator SWI248x [HI SI DI])
738
 
739
;; All integer modes without QImode and HImode.
740
(define_mode_iterator SWI48x [SI DI])
741
 
742
;; All integer modes without SImode and DImode.
743
(define_mode_iterator SWI12 [QI HI])
744
 
745
;; All integer modes without DImode.
746
(define_mode_iterator SWI124 [QI HI SI])
747
 
748
;; All integer modes without QImode and DImode.
749
(define_mode_iterator SWI24 [HI SI])
750
 
751
;; Single word integer modes.
752
(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
753
 
754
;; Single word integer modes without QImode.
755
(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
756
 
757
;; Single word integer modes without QImode and HImode.
758
(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
759
 
760
;; All math-dependant single and double word integer modes.
761
(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
762
                             (HI "TARGET_HIMODE_MATH")
763
                             SI DI (TI "TARGET_64BIT")])
764
 
765
;; Math-dependant single word integer modes.
766
(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
767
                            (HI "TARGET_HIMODE_MATH")
768
                            SI (DI "TARGET_64BIT")])
769
 
770
;; Math-dependant integer modes without DImode.
771
(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
772
                               (HI "TARGET_HIMODE_MATH")
773
                               SI])
774
 
775
;; Math-dependant single word integer modes without QImode.
776
(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
777
                               SI (DI "TARGET_64BIT")])
778
 
779
;; Double word integer modes.
780
(define_mode_iterator DWI [(DI "!TARGET_64BIT")
781
                           (TI "TARGET_64BIT")])
782
 
783
;; Double word integer modes as mode attribute.
784
(define_mode_attr DWI [(SI "DI") (DI "TI")])
785
(define_mode_attr dwi [(SI "di") (DI "ti")])
786
 
787
;; Half mode for double word integer modes.
788
(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
789
                            (DI "TARGET_64BIT")])
790
 
791
;; Instruction suffix for integer modes.
792
(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
793
 
794
;; Pointer size prefix for integer modes (Intel asm dialect)
795
(define_mode_attr iptrsize [(QI "BYTE")
796
                            (HI "WORD")
797
                            (SI "DWORD")
798
                            (DI "QWORD")])
799
 
800
;; Register class for integer modes.
801
(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
802
 
803
;; Immediate operand constraint for integer modes.
804
(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
805
 
806
;; General operand constraint for word modes.
807
(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
808
 
809
;; Immediate operand constraint for double integer modes.
810
(define_mode_attr di [(SI "nF") (DI "e")])
811
 
812
;; Immediate operand constraint for shifts.
813
(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
814
 
815
;; General operand predicate for integer modes.
816
(define_mode_attr general_operand
817
        [(QI "general_operand")
818
         (HI "general_operand")
819
         (SI "x86_64_general_operand")
820
         (DI "x86_64_general_operand")
821
         (TI "x86_64_general_operand")])
822
 
823
;; General sign/zero extend operand predicate for integer modes.
824
(define_mode_attr general_szext_operand
825
        [(QI "general_operand")
826
         (HI "general_operand")
827
         (SI "x86_64_szext_general_operand")
828
         (DI "x86_64_szext_general_operand")])
829
 
830
;; Immediate operand predicate for integer modes.
831
(define_mode_attr immediate_operand
832
        [(QI "immediate_operand")
833
         (HI "immediate_operand")
834
         (SI "x86_64_immediate_operand")
835
         (DI "x86_64_immediate_operand")])
836
 
837
;; Nonmemory operand predicate for integer modes.
838
(define_mode_attr nonmemory_operand
839
        [(QI "nonmemory_operand")
840
         (HI "nonmemory_operand")
841
         (SI "x86_64_nonmemory_operand")
842
         (DI "x86_64_nonmemory_operand")])
843
 
844
;; Operand predicate for shifts.
845
(define_mode_attr shift_operand
846
        [(QI "nonimmediate_operand")
847
         (HI "nonimmediate_operand")
848
         (SI "nonimmediate_operand")
849
         (DI "shiftdi_operand")
850
         (TI "register_operand")])
851
 
852
;; Operand predicate for shift argument.
853
(define_mode_attr shift_immediate_operand
854
        [(QI "const_1_to_31_operand")
855
         (HI "const_1_to_31_operand")
856
         (SI "const_1_to_31_operand")
857
         (DI "const_1_to_63_operand")])
858
 
859
;; Input operand predicate for arithmetic left shifts.
860
(define_mode_attr ashl_input_operand
861
        [(QI "nonimmediate_operand")
862
         (HI "nonimmediate_operand")
863
         (SI "nonimmediate_operand")
864
         (DI "ashldi_input_operand")
865
         (TI "reg_or_pm1_operand")])
866
 
867
;; SSE and x87 SFmode and DFmode floating point modes
868
(define_mode_iterator MODEF [SF DF])
869
 
870
;; All x87 floating point modes
871
(define_mode_iterator X87MODEF [SF DF XF])
872
 
873
;; SSE instruction suffix for various modes
874
(define_mode_attr ssemodesuffix
875
  [(SF "ss") (DF "sd")
876
   (V8SF "ps") (V4DF "pd")
877
   (V4SF "ps") (V2DF "pd")
878
   (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
879
   (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
880
 
881
;; SSE vector suffix for floating point modes
882
(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
883
 
884
;; SSE vector mode corresponding to a scalar mode
885
(define_mode_attr ssevecmode
886
  [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
887
 
888
;; Instruction suffix for REX 64bit operators.
889
(define_mode_attr rex64suffix [(SI "") (DI "{q}")])
890
 
891
;; This mode iterator allows :P to be used for patterns that operate on
892
;; pointer-sized quantities.  Exactly one of the two alternatives will match.
893
(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
894
 
895
;; This mode iterator allows :PTR to be used for patterns that operate on
896
;; ptr_mode sized quantities.
897
(define_mode_iterator PTR
898
  [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
899
 
900
;; Scheduling descriptions
901
 
902
(include "pentium.md")
903
(include "ppro.md")
904
(include "k6.md")
905
(include "athlon.md")
906
(include "bdver1.md")
907
(include "geode.md")
908
(include "atom.md")
909
(include "core2.md")
910
 
911
 
912
;; Operand and operator predicates and constraints
913
 
914
(include "predicates.md")
915
(include "constraints.md")
916
 
917
 
918
;; Compare and branch/compare and store instructions.
919
 
920
(define_expand "cbranch4"
921
  [(set (reg:CC FLAGS_REG)
922
        (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
923
                    (match_operand:SDWIM 2 "" "")))
924
   (set (pc) (if_then_else
925
               (match_operator 0 "ordered_comparison_operator"
926
                [(reg:CC FLAGS_REG) (const_int 0)])
927
               (label_ref (match_operand 3 "" ""))
928
               (pc)))]
929
  ""
930
{
931
  if (MEM_P (operands[1]) && MEM_P (operands[2]))
932
    operands[1] = force_reg (mode, operands[1]);
933
  ix86_expand_branch (GET_CODE (operands[0]),
934
                      operands[1], operands[2], operands[3]);
935
  DONE;
936
})
937
 
938
(define_expand "cstore4"
939
  [(set (reg:CC FLAGS_REG)
940
        (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
941
                    (match_operand:SWIM 3 "" "")))
942
   (set (match_operand:QI 0 "register_operand" "")
943
        (match_operator 1 "ordered_comparison_operator"
944
          [(reg:CC FLAGS_REG) (const_int 0)]))]
945
  ""
946
{
947
  if (MEM_P (operands[2]) && MEM_P (operands[3]))
948
    operands[2] = force_reg (mode, operands[2]);
949
  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
950
                     operands[2], operands[3]);
951
  DONE;
952
})
953
 
954
(define_expand "cmp_1"
955
  [(set (reg:CC FLAGS_REG)
956
        (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
957
                    (match_operand:SWI48 1 "" "")))])
958
 
959
(define_insn "*cmp_ccno_1"
960
  [(set (reg FLAGS_REG)
961
        (compare (match_operand:SWI 0 "nonimmediate_operand" ",?m")
962
                 (match_operand:SWI 1 "const0_operand" "")))]
963
  "ix86_match_ccmode (insn, CCNOmode)"
964
  "@
965
   test{}\t%0, %0
966
   cmp{}\t{%1, %0|%0, %1}"
967
  [(set_attr "type" "test,icmp")
968
   (set_attr "length_immediate" "0,1")
969
   (set_attr "mode" "")])
970
 
971
(define_insn "*cmp_1"
972
  [(set (reg FLAGS_REG)
973
        (compare (match_operand:SWI 0 "nonimmediate_operand" "m,")
974
                 (match_operand:SWI 1 "" ",m")))]
975
  "ix86_match_ccmode (insn, CCmode)"
976
  "cmp{}\t{%1, %0|%0, %1}"
977
  [(set_attr "type" "icmp")
978
   (set_attr "mode" "")])
979
 
980
(define_insn "*cmp_minus_1"
981
  [(set (reg FLAGS_REG)
982
        (compare
983
          (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "m,")
984
                     (match_operand:SWI 1 "" ",m"))
985
          (const_int 0)))]
986
  "ix86_match_ccmode (insn, CCGOCmode)"
987
  "cmp{}\t{%1, %0|%0, %1}"
988
  [(set_attr "type" "icmp")
989
   (set_attr "mode" "")])
990
 
991
(define_insn "*cmpqi_ext_1"
992
  [(set (reg FLAGS_REG)
993
        (compare
994
          (match_operand:QI 0 "general_operand" "Qm")
995
          (subreg:QI
996
            (zero_extract:SI
997
              (match_operand 1 "ext_register_operand" "Q")
998
              (const_int 8)
999
              (const_int 8)) 0)))]
1000
  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1001
  "cmp{b}\t{%h1, %0|%0, %h1}"
1002
  [(set_attr "type" "icmp")
1003
   (set_attr "mode" "QI")])
1004
 
1005
(define_insn "*cmpqi_ext_1_rex64"
1006
  [(set (reg FLAGS_REG)
1007
        (compare
1008
          (match_operand:QI 0 "register_operand" "Q")
1009
          (subreg:QI
1010
            (zero_extract:SI
1011
              (match_operand 1 "ext_register_operand" "Q")
1012
              (const_int 8)
1013
              (const_int 8)) 0)))]
1014
  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1015
  "cmp{b}\t{%h1, %0|%0, %h1}"
1016
  [(set_attr "type" "icmp")
1017
   (set_attr "mode" "QI")])
1018
 
1019
(define_insn "*cmpqi_ext_2"
1020
  [(set (reg FLAGS_REG)
1021
        (compare
1022
          (subreg:QI
1023
            (zero_extract:SI
1024
              (match_operand 0 "ext_register_operand" "Q")
1025
              (const_int 8)
1026
              (const_int 8)) 0)
1027
          (match_operand:QI 1 "const0_operand" "")))]
1028
  "ix86_match_ccmode (insn, CCNOmode)"
1029
  "test{b}\t%h0, %h0"
1030
  [(set_attr "type" "test")
1031
   (set_attr "length_immediate" "0")
1032
   (set_attr "mode" "QI")])
1033
 
1034
(define_expand "cmpqi_ext_3"
1035
  [(set (reg:CC FLAGS_REG)
1036
        (compare:CC
1037
          (subreg:QI
1038
            (zero_extract:SI
1039
              (match_operand 0 "ext_register_operand" "")
1040
              (const_int 8)
1041
              (const_int 8)) 0)
1042
          (match_operand:QI 1 "immediate_operand" "")))])
1043
 
1044
(define_insn "*cmpqi_ext_3_insn"
1045
  [(set (reg FLAGS_REG)
1046
        (compare
1047
          (subreg:QI
1048
            (zero_extract:SI
1049
              (match_operand 0 "ext_register_operand" "Q")
1050
              (const_int 8)
1051
              (const_int 8)) 0)
1052
          (match_operand:QI 1 "general_operand" "Qmn")))]
1053
  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1054
  "cmp{b}\t{%1, %h0|%h0, %1}"
1055
  [(set_attr "type" "icmp")
1056
   (set_attr "modrm" "1")
1057
   (set_attr "mode" "QI")])
1058
 
1059
(define_insn "*cmpqi_ext_3_insn_rex64"
1060
  [(set (reg FLAGS_REG)
1061
        (compare
1062
          (subreg:QI
1063
            (zero_extract:SI
1064
              (match_operand 0 "ext_register_operand" "Q")
1065
              (const_int 8)
1066
              (const_int 8)) 0)
1067
          (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1068
  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1069
  "cmp{b}\t{%1, %h0|%h0, %1}"
1070
  [(set_attr "type" "icmp")
1071
   (set_attr "modrm" "1")
1072
   (set_attr "mode" "QI")])
1073
 
1074
(define_insn "*cmpqi_ext_4"
1075
  [(set (reg FLAGS_REG)
1076
        (compare
1077
          (subreg:QI
1078
            (zero_extract:SI
1079
              (match_operand 0 "ext_register_operand" "Q")
1080
              (const_int 8)
1081
              (const_int 8)) 0)
1082
          (subreg:QI
1083
            (zero_extract:SI
1084
              (match_operand 1 "ext_register_operand" "Q")
1085
              (const_int 8)
1086
              (const_int 8)) 0)))]
1087
  "ix86_match_ccmode (insn, CCmode)"
1088
  "cmp{b}\t{%h1, %h0|%h0, %h1}"
1089
  [(set_attr "type" "icmp")
1090
   (set_attr "mode" "QI")])
1091
 
1092
;; These implement float point compares.
1093
;; %%% See if we can get away with VOIDmode operands on the actual insns,
1094
;; which would allow mix and match FP modes on the compares.  Which is what
1095
;; the old patterns did, but with many more of them.
1096
 
1097
(define_expand "cbranchxf4"
1098
  [(set (reg:CC FLAGS_REG)
1099
        (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1100
                    (match_operand:XF 2 "nonmemory_operand" "")))
1101
   (set (pc) (if_then_else
1102
              (match_operator 0 "ix86_fp_comparison_operator"
1103
               [(reg:CC FLAGS_REG)
1104
                (const_int 0)])
1105
              (label_ref (match_operand 3 "" ""))
1106
              (pc)))]
1107
  "TARGET_80387"
1108
{
1109
  ix86_expand_branch (GET_CODE (operands[0]),
1110
                      operands[1], operands[2], operands[3]);
1111
  DONE;
1112
})
1113
 
1114
(define_expand "cstorexf4"
1115
  [(set (reg:CC FLAGS_REG)
1116
        (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1117
                    (match_operand:XF 3 "nonmemory_operand" "")))
1118
   (set (match_operand:QI 0 "register_operand" "")
1119
              (match_operator 1 "ix86_fp_comparison_operator"
1120
               [(reg:CC FLAGS_REG)
1121
                (const_int 0)]))]
1122
  "TARGET_80387"
1123
{
1124
  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1125
                     operands[2], operands[3]);
1126
  DONE;
1127
})
1128
 
1129
(define_expand "cbranch4"
1130
  [(set (reg:CC FLAGS_REG)
1131
        (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1132
                    (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1133
   (set (pc) (if_then_else
1134
              (match_operator 0 "ix86_fp_comparison_operator"
1135
               [(reg:CC FLAGS_REG)
1136
                (const_int 0)])
1137
              (label_ref (match_operand 3 "" ""))
1138
              (pc)))]
1139
  "TARGET_80387 || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
1140
{
1141
  ix86_expand_branch (GET_CODE (operands[0]),
1142
                      operands[1], operands[2], operands[3]);
1143
  DONE;
1144
})
1145
 
1146
(define_expand "cstore4"
1147
  [(set (reg:CC FLAGS_REG)
1148
        (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1149
                    (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1150
   (set (match_operand:QI 0 "register_operand" "")
1151
              (match_operator 1 "ix86_fp_comparison_operator"
1152
               [(reg:CC FLAGS_REG)
1153
                (const_int 0)]))]
1154
  "TARGET_80387 || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
1155
{
1156
  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1157
                     operands[2], operands[3]);
1158
  DONE;
1159
})
1160
 
1161
(define_expand "cbranchcc4"
1162
  [(set (pc) (if_then_else
1163
              (match_operator 0 "comparison_operator"
1164
               [(match_operand 1 "flags_reg_operand" "")
1165
                (match_operand 2 "const0_operand" "")])
1166
              (label_ref (match_operand 3 "" ""))
1167
              (pc)))]
1168
  ""
1169
{
1170
  ix86_expand_branch (GET_CODE (operands[0]),
1171
                      operands[1], operands[2], operands[3]);
1172
  DONE;
1173
})
1174
 
1175
(define_expand "cstorecc4"
1176
  [(set (match_operand:QI 0 "register_operand" "")
1177
              (match_operator 1 "comparison_operator"
1178
               [(match_operand 2 "flags_reg_operand" "")
1179
                (match_operand 3 "const0_operand" "")]))]
1180
  ""
1181
{
1182
  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1183
                     operands[2], operands[3]);
1184
  DONE;
1185
})
1186
 
1187
 
1188
;; FP compares, step 1:
1189
;; Set the FP condition codes.
1190
;;
1191
;; CCFPmode     compare with exceptions
1192
;; CCFPUmode    compare with no exceptions
1193
 
1194
;; We may not use "#" to split and emit these, since the REG_DEAD notes
1195
;; used to manage the reg stack popping would not be preserved.
1196
 
1197
(define_insn "*cmpfp_0"
1198
  [(set (match_operand:HI 0 "register_operand" "=a")
1199
        (unspec:HI
1200
          [(compare:CCFP
1201
             (match_operand 1 "register_operand" "f")
1202
             (match_operand 2 "const0_operand" ""))]
1203
        UNSPEC_FNSTSW))]
1204
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1205
   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1206
  "* return output_fp_compare (insn, operands, false, false);"
1207
  [(set_attr "type" "multi")
1208
   (set_attr "unit" "i387")
1209
   (set (attr "mode")
1210
     (cond [(match_operand:SF 1 "" "")
1211
              (const_string "SF")
1212
            (match_operand:DF 1 "" "")
1213
              (const_string "DF")
1214
           ]
1215
           (const_string "XF")))])
1216
 
1217
(define_insn_and_split "*cmpfp_0_cc"
1218
  [(set (reg:CCFP FLAGS_REG)
1219
        (compare:CCFP
1220
          (match_operand 1 "register_operand" "f")
1221
          (match_operand 2 "const0_operand" "")))
1222
   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1223
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1224
   && TARGET_SAHF && !TARGET_CMOVE
1225
   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1226
  "#"
1227
  "&& reload_completed"
1228
  [(set (match_dup 0)
1229
        (unspec:HI
1230
          [(compare:CCFP (match_dup 1)(match_dup 2))]
1231
        UNSPEC_FNSTSW))
1232
   (set (reg:CC FLAGS_REG)
1233
        (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1234
  ""
1235
  [(set_attr "type" "multi")
1236
   (set_attr "unit" "i387")
1237
   (set (attr "mode")
1238
     (cond [(match_operand:SF 1 "" "")
1239
              (const_string "SF")
1240
            (match_operand:DF 1 "" "")
1241
              (const_string "DF")
1242
           ]
1243
           (const_string "XF")))])
1244
 
1245
(define_insn "*cmpfp_xf"
1246
  [(set (match_operand:HI 0 "register_operand" "=a")
1247
        (unspec:HI
1248
          [(compare:CCFP
1249
             (match_operand:XF 1 "register_operand" "f")
1250
             (match_operand:XF 2 "register_operand" "f"))]
1251
          UNSPEC_FNSTSW))]
1252
  "TARGET_80387"
1253
  "* return output_fp_compare (insn, operands, false, false);"
1254
  [(set_attr "type" "multi")
1255
   (set_attr "unit" "i387")
1256
   (set_attr "mode" "XF")])
1257
 
1258
(define_insn_and_split "*cmpfp_xf_cc"
1259
  [(set (reg:CCFP FLAGS_REG)
1260
        (compare:CCFP
1261
          (match_operand:XF 1 "register_operand" "f")
1262
          (match_operand:XF 2 "register_operand" "f")))
1263
   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1264
  "TARGET_80387
1265
   && TARGET_SAHF && !TARGET_CMOVE"
1266
  "#"
1267
  "&& reload_completed"
1268
  [(set (match_dup 0)
1269
        (unspec:HI
1270
          [(compare:CCFP (match_dup 1)(match_dup 2))]
1271
        UNSPEC_FNSTSW))
1272
   (set (reg:CC FLAGS_REG)
1273
        (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1274
  ""
1275
  [(set_attr "type" "multi")
1276
   (set_attr "unit" "i387")
1277
   (set_attr "mode" "XF")])
1278
 
1279
(define_insn "*cmpfp_"
1280
  [(set (match_operand:HI 0 "register_operand" "=a")
1281
        (unspec:HI
1282
          [(compare:CCFP
1283
             (match_operand:MODEF 1 "register_operand" "f")
1284
             (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1285
          UNSPEC_FNSTSW))]
1286
  "TARGET_80387"
1287
  "* return output_fp_compare (insn, operands, false, false);"
1288
  [(set_attr "type" "multi")
1289
   (set_attr "unit" "i387")
1290
   (set_attr "mode" "")])
1291
 
1292
(define_insn_and_split "*cmpfp__cc"
1293
  [(set (reg:CCFP FLAGS_REG)
1294
        (compare:CCFP
1295
          (match_operand:MODEF 1 "register_operand" "f")
1296
          (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1297
   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1298
  "TARGET_80387
1299
   && TARGET_SAHF && !TARGET_CMOVE"
1300
  "#"
1301
  "&& reload_completed"
1302
  [(set (match_dup 0)
1303
        (unspec:HI
1304
          [(compare:CCFP (match_dup 1)(match_dup 2))]
1305
        UNSPEC_FNSTSW))
1306
   (set (reg:CC FLAGS_REG)
1307
        (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1308
  ""
1309
  [(set_attr "type" "multi")
1310
   (set_attr "unit" "i387")
1311
   (set_attr "mode" "")])
1312
 
1313
(define_insn "*cmpfp_u"
1314
  [(set (match_operand:HI 0 "register_operand" "=a")
1315
        (unspec:HI
1316
          [(compare:CCFPU
1317
             (match_operand 1 "register_operand" "f")
1318
             (match_operand 2 "register_operand" "f"))]
1319
          UNSPEC_FNSTSW))]
1320
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1321
   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1322
  "* return output_fp_compare (insn, operands, false, true);"
1323
  [(set_attr "type" "multi")
1324
   (set_attr "unit" "i387")
1325
   (set (attr "mode")
1326
     (cond [(match_operand:SF 1 "" "")
1327
              (const_string "SF")
1328
            (match_operand:DF 1 "" "")
1329
              (const_string "DF")
1330
           ]
1331
           (const_string "XF")))])
1332
 
1333
(define_insn_and_split "*cmpfp_u_cc"
1334
  [(set (reg:CCFPU FLAGS_REG)
1335
        (compare:CCFPU
1336
          (match_operand 1 "register_operand" "f")
1337
          (match_operand 2 "register_operand" "f")))
1338
   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1339
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1340
   && TARGET_SAHF && !TARGET_CMOVE
1341
   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1342
  "#"
1343
  "&& reload_completed"
1344
  [(set (match_dup 0)
1345
        (unspec:HI
1346
          [(compare:CCFPU (match_dup 1)(match_dup 2))]
1347
        UNSPEC_FNSTSW))
1348
   (set (reg:CC FLAGS_REG)
1349
        (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1350
  ""
1351
  [(set_attr "type" "multi")
1352
   (set_attr "unit" "i387")
1353
   (set (attr "mode")
1354
     (cond [(match_operand:SF 1 "" "")
1355
              (const_string "SF")
1356
            (match_operand:DF 1 "" "")
1357
              (const_string "DF")
1358
           ]
1359
           (const_string "XF")))])
1360
 
1361
(define_insn "*cmpfp_"
1362
  [(set (match_operand:HI 0 "register_operand" "=a")
1363
        (unspec:HI
1364
          [(compare:CCFP
1365
             (match_operand 1 "register_operand" "f")
1366
             (match_operator 3 "float_operator"
1367
               [(match_operand:SWI24 2 "memory_operand" "m")]))]
1368
          UNSPEC_FNSTSW))]
1369
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1370
   && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))
1371
   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1372
  "* return output_fp_compare (insn, operands, false, false);"
1373
  [(set_attr "type" "multi")
1374
   (set_attr "unit" "i387")
1375
   (set_attr "fp_int_src" "true")
1376
   (set_attr "mode" "")])
1377
 
1378
(define_insn_and_split "*cmpfp__cc"
1379
  [(set (reg:CCFP FLAGS_REG)
1380
        (compare:CCFP
1381
          (match_operand 1 "register_operand" "f")
1382
          (match_operator 3 "float_operator"
1383
            [(match_operand:SWI24 2 "memory_operand" "m")])))
1384
   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1385
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1386
   && TARGET_SAHF && !TARGET_CMOVE
1387
   && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))
1388
   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1389
  "#"
1390
  "&& reload_completed"
1391
  [(set (match_dup 0)
1392
        (unspec:HI
1393
          [(compare:CCFP
1394
             (match_dup 1)
1395
             (match_op_dup 3 [(match_dup 2)]))]
1396
        UNSPEC_FNSTSW))
1397
   (set (reg:CC FLAGS_REG)
1398
        (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1399
  ""
1400
  [(set_attr "type" "multi")
1401
   (set_attr "unit" "i387")
1402
   (set_attr "fp_int_src" "true")
1403
   (set_attr "mode" "")])
1404
 
1405
;; FP compares, step 2
1406
;; Move the fpsw to ax.
1407
 
1408
(define_insn "x86_fnstsw_1"
1409
  [(set (match_operand:HI 0 "register_operand" "=a")
1410
        (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1411
  "TARGET_80387"
1412
  "fnstsw\t%0"
1413
  [(set (attr "length")
1414
        (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1415
   (set_attr "mode" "SI")
1416
   (set_attr "unit" "i387")])
1417
 
1418
;; FP compares, step 3
1419
;; Get ax into flags, general case.
1420
 
1421
(define_insn "x86_sahf_1"
1422
  [(set (reg:CC FLAGS_REG)
1423
        (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1424
                   UNSPEC_SAHF))]
1425
  "TARGET_SAHF"
1426
{
1427
#ifndef HAVE_AS_IX86_SAHF
1428
  if (TARGET_64BIT)
1429
    return ASM_BYTE "0x9e";
1430
  else
1431
#endif
1432
  return "sahf";
1433
}
1434
  [(set_attr "length" "1")
1435
   (set_attr "athlon_decode" "vector")
1436
   (set_attr "amdfam10_decode" "direct")
1437
   (set_attr "bdver1_decode" "direct")
1438
   (set_attr "mode" "SI")])
1439
 
1440
;; Pentium Pro can do steps 1 through 3 in one go.
1441
;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1442
;; (these i387 instructions set flags directly)
1443
(define_insn "*cmpfp_i_mixed"
1444
  [(set (reg:CCFP FLAGS_REG)
1445
        (compare:CCFP (match_operand 0 "register_operand" "f,x")
1446
                      (match_operand 1 "nonimmediate_operand" "f,xm")))]
1447
  "TARGET_MIX_SSE_I387
1448
   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1449
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1450
  "* return output_fp_compare (insn, operands, true, false);"
1451
  [(set_attr "type" "fcmp,ssecomi")
1452
   (set_attr "prefix" "orig,maybe_vex")
1453
   (set (attr "mode")
1454
     (if_then_else (match_operand:SF 1 "" "")
1455
        (const_string "SF")
1456
        (const_string "DF")))
1457
   (set (attr "prefix_rep")
1458
        (if_then_else (eq_attr "type" "ssecomi")
1459
                      (const_string "0")
1460
                      (const_string "*")))
1461
   (set (attr "prefix_data16")
1462
        (cond [(eq_attr "type" "fcmp")
1463
                 (const_string "*")
1464
               (eq_attr "mode" "DF")
1465
                 (const_string "1")
1466
              ]
1467
              (const_string "0")))
1468
   (set_attr "athlon_decode" "vector")
1469
   (set_attr "amdfam10_decode" "direct")
1470
   (set_attr "bdver1_decode" "double")])
1471
 
1472
(define_insn "*cmpfp_i_sse"
1473
  [(set (reg:CCFP FLAGS_REG)
1474
        (compare:CCFP (match_operand 0 "register_operand" "x")
1475
                      (match_operand 1 "nonimmediate_operand" "xm")))]
1476
  "TARGET_SSE_MATH
1477
   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1478
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1479
  "* return output_fp_compare (insn, operands, true, false);"
1480
  [(set_attr "type" "ssecomi")
1481
   (set_attr "prefix" "maybe_vex")
1482
   (set (attr "mode")
1483
     (if_then_else (match_operand:SF 1 "" "")
1484
        (const_string "SF")
1485
        (const_string "DF")))
1486
   (set_attr "prefix_rep" "0")
1487
   (set (attr "prefix_data16")
1488
        (if_then_else (eq_attr "mode" "DF")
1489
                      (const_string "1")
1490
                      (const_string "0")))
1491
   (set_attr "athlon_decode" "vector")
1492
   (set_attr "amdfam10_decode" "direct")
1493
   (set_attr "bdver1_decode" "double")])
1494
 
1495
(define_insn "*cmpfp_i_i387"
1496
  [(set (reg:CCFP FLAGS_REG)
1497
        (compare:CCFP (match_operand 0 "register_operand" "f")
1498
                      (match_operand 1 "register_operand" "f")))]
1499
  "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1500
   && TARGET_CMOVE
1501
   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1502
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503
  "* return output_fp_compare (insn, operands, true, false);"
1504
  [(set_attr "type" "fcmp")
1505
   (set (attr "mode")
1506
     (cond [(match_operand:SF 1 "" "")
1507
              (const_string "SF")
1508
            (match_operand:DF 1 "" "")
1509
              (const_string "DF")
1510
           ]
1511
           (const_string "XF")))
1512
   (set_attr "athlon_decode" "vector")
1513
   (set_attr "amdfam10_decode" "direct")
1514
   (set_attr "bdver1_decode" "double")])
1515
 
1516
(define_insn "*cmpfp_iu_mixed"
1517
  [(set (reg:CCFPU FLAGS_REG)
1518
        (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1519
                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1520
  "TARGET_MIX_SSE_I387
1521
   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1522
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1523
  "* return output_fp_compare (insn, operands, true, true);"
1524
  [(set_attr "type" "fcmp,ssecomi")
1525
   (set_attr "prefix" "orig,maybe_vex")
1526
   (set (attr "mode")
1527
     (if_then_else (match_operand:SF 1 "" "")
1528
        (const_string "SF")
1529
        (const_string "DF")))
1530
   (set (attr "prefix_rep")
1531
        (if_then_else (eq_attr "type" "ssecomi")
1532
                      (const_string "0")
1533
                      (const_string "*")))
1534
   (set (attr "prefix_data16")
1535
        (cond [(eq_attr "type" "fcmp")
1536
                 (const_string "*")
1537
               (eq_attr "mode" "DF")
1538
                 (const_string "1")
1539
              ]
1540
              (const_string "0")))
1541
   (set_attr "athlon_decode" "vector")
1542
   (set_attr "amdfam10_decode" "direct")
1543
   (set_attr "bdver1_decode" "double")])
1544
 
1545
(define_insn "*cmpfp_iu_sse"
1546
  [(set (reg:CCFPU FLAGS_REG)
1547
        (compare:CCFPU (match_operand 0 "register_operand" "x")
1548
                       (match_operand 1 "nonimmediate_operand" "xm")))]
1549
  "TARGET_SSE_MATH
1550
   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1551
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1552
  "* return output_fp_compare (insn, operands, true, true);"
1553
  [(set_attr "type" "ssecomi")
1554
   (set_attr "prefix" "maybe_vex")
1555
   (set (attr "mode")
1556
     (if_then_else (match_operand:SF 1 "" "")
1557
        (const_string "SF")
1558
        (const_string "DF")))
1559
   (set_attr "prefix_rep" "0")
1560
   (set (attr "prefix_data16")
1561
        (if_then_else (eq_attr "mode" "DF")
1562
                      (const_string "1")
1563
                      (const_string "0")))
1564
   (set_attr "athlon_decode" "vector")
1565
   (set_attr "amdfam10_decode" "direct")
1566
   (set_attr "bdver1_decode" "double")])
1567
 
1568
(define_insn "*cmpfp_iu_387"
1569
  [(set (reg:CCFPU FLAGS_REG)
1570
        (compare:CCFPU (match_operand 0 "register_operand" "f")
1571
                       (match_operand 1 "register_operand" "f")))]
1572
  "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1573
   && TARGET_CMOVE
1574
   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1575
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576
  "* return output_fp_compare (insn, operands, true, true);"
1577
  [(set_attr "type" "fcmp")
1578
   (set (attr "mode")
1579
     (cond [(match_operand:SF 1 "" "")
1580
              (const_string "SF")
1581
            (match_operand:DF 1 "" "")
1582
              (const_string "DF")
1583
           ]
1584
           (const_string "XF")))
1585
   (set_attr "athlon_decode" "vector")
1586
   (set_attr "amdfam10_decode" "direct")
1587
   (set_attr "bdver1_decode" "direct")])
1588
 
1589
;; Push/pop instructions.
1590
 
1591
(define_insn "*push2"
1592
  [(set (match_operand:DWI 0 "push_operand" "=<")
1593
        (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1594
  ""
1595
  "#"
1596
  [(set_attr "type" "multi")
1597
   (set_attr "mode" "")])
1598
 
1599
(define_split
1600
  [(set (match_operand:TI 0 "push_operand" "")
1601
        (match_operand:TI 1 "general_operand" ""))]
1602
  "TARGET_64BIT && reload_completed
1603
   && !SSE_REG_P (operands[1])"
1604
  [(const_int 0)]
1605
  "ix86_split_long_move (operands); DONE;")
1606
 
1607
(define_insn "*pushdi2_rex64"
1608
  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1609
        (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1610
  "TARGET_64BIT"
1611
  "@
1612
   push{q}\t%1
1613
   #"
1614
  [(set_attr "type" "push,multi")
1615
   (set_attr "mode" "DI")])
1616
 
1617
;; Convert impossible pushes of immediate to existing instructions.
1618
;; First try to get scratch register and go through it.  In case this
1619
;; fails, push sign extended lower part first and then overwrite
1620
;; upper part by 32bit move.
1621
(define_peephole2
1622
  [(match_scratch:DI 2 "r")
1623
   (set (match_operand:DI 0 "push_operand" "")
1624
        (match_operand:DI 1 "immediate_operand" ""))]
1625
  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1626
   && !x86_64_immediate_operand (operands[1], DImode)"
1627
  [(set (match_dup 2) (match_dup 1))
1628
   (set (match_dup 0) (match_dup 2))])
1629
 
1630
;; We need to define this as both peepholer and splitter for case
1631
;; peephole2 pass is not run.
1632
;; "&& 1" is needed to keep it from matching the previous pattern.
1633
(define_peephole2
1634
  [(set (match_operand:DI 0 "push_operand" "")
1635
        (match_operand:DI 1 "immediate_operand" ""))]
1636
  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1637
   && !x86_64_immediate_operand (operands[1], DImode) && 1"
1638
  [(set (match_dup 0) (match_dup 1))
1639
   (set (match_dup 2) (match_dup 3))]
1640
{
1641
  split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1642
 
1643
  operands[1] = gen_lowpart (DImode, operands[2]);
1644
  operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1645
                                                   GEN_INT (4)));
1646
})
1647
 
1648
(define_split
1649
  [(set (match_operand:DI 0 "push_operand" "")
1650
        (match_operand:DI 1 "immediate_operand" ""))]
1651
  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1652
                    ? epilogue_completed : reload_completed)
1653
   && !symbolic_operand (operands[1], DImode)
1654
   && !x86_64_immediate_operand (operands[1], DImode)"
1655
  [(set (match_dup 0) (match_dup 1))
1656
   (set (match_dup 2) (match_dup 3))]
1657
{
1658
  split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1659
 
1660
  operands[1] = gen_lowpart (DImode, operands[2]);
1661
  operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1662
                                                   GEN_INT (4)));
1663
})
1664
 
1665
(define_split
1666
  [(set (match_operand:DI 0 "push_operand" "")
1667
        (match_operand:DI 1 "general_operand" ""))]
1668
  "!TARGET_64BIT && reload_completed
1669
   && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1670
  [(const_int 0)]
1671
  "ix86_split_long_move (operands); DONE;")
1672
 
1673
(define_insn "*pushsi2"
1674
  [(set (match_operand:SI 0 "push_operand" "=<")
1675
        (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1676
  "!TARGET_64BIT"
1677
  "push{l}\t%1"
1678
  [(set_attr "type" "push")
1679
   (set_attr "mode" "SI")])
1680
 
1681
;; emit_push_insn when it calls move_by_pieces requires an insn to
1682
;; "push a byte/word".  But actually we use pushl, which has the effect
1683
;; of rounding the amount pushed up to a word.
1684
 
1685
;; For TARGET_64BIT we always round up to 8 bytes.
1686
(define_insn "*push2_rex64"
1687
  [(set (match_operand:SWI124 0 "push_operand" "=X")
1688
        (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r"))]
1689
  "TARGET_64BIT"
1690
  "push{q}\t%q1"
1691
  [(set_attr "type" "push")
1692
   (set_attr "mode" "DI")])
1693
 
1694
(define_insn "*push2"
1695
  [(set (match_operand:SWI12 0 "push_operand" "=X")
1696
        (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1697
  "!TARGET_64BIT"
1698
  "push{l}\t%k1"
1699
  [(set_attr "type" "push")
1700
   (set_attr "mode" "SI")])
1701
 
1702
(define_insn "*push2_prologue"
1703
  [(set (match_operand:P 0 "push_operand" "=<")
1704
        (match_operand:P 1 "general_no_elim_operand" "r*m"))
1705
   (clobber (mem:BLK (scratch)))]
1706
  ""
1707
  "push{}\t%1"
1708
  [(set_attr "type" "push")
1709
   (set_attr "mode" "")])
1710
 
1711
(define_insn "*pop1"
1712
  [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1713
        (match_operand:P 1 "pop_operand" ">"))]
1714
  ""
1715
  "pop{}\t%0"
1716
  [(set_attr "type" "pop")
1717
   (set_attr "mode" "")])
1718
 
1719
(define_insn "*pop1_epilogue"
1720
  [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1721
        (match_operand:P 1 "pop_operand" ">"))
1722
   (clobber (mem:BLK (scratch)))]
1723
  ""
1724
  "pop{}\t%0"
1725
  [(set_attr "type" "pop")
1726
   (set_attr "mode" "")])
1727
 
1728
;; Move instructions.
1729
 
1730
(define_expand "movoi"
1731
  [(set (match_operand:OI 0 "nonimmediate_operand" "")
1732
        (match_operand:OI 1 "general_operand" ""))]
1733
  "TARGET_AVX"
1734
  "ix86_expand_move (OImode, operands); DONE;")
1735
 
1736
(define_expand "movti"
1737
  [(set (match_operand:TI 0 "nonimmediate_operand" "")
1738
        (match_operand:TI 1 "nonimmediate_operand" ""))]
1739
  "TARGET_64BIT || TARGET_SSE"
1740
{
1741
  if (TARGET_64BIT)
1742
    ix86_expand_move (TImode, operands);
1743
  else if (push_operand (operands[0], TImode))
1744
    ix86_expand_push (TImode, operands[1]);
1745
  else
1746
    ix86_expand_vector_move (TImode, operands);
1747
  DONE;
1748
})
1749
 
1750
;; This expands to what emit_move_complex would generate if we didn't
1751
;; have a movti pattern.  Having this avoids problems with reload on
1752
;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1753
;; to have around all the time.
1754
(define_expand "movcdi"
1755
  [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1756
        (match_operand:CDI 1 "general_operand" ""))]
1757
  ""
1758
{
1759
  if (push_operand (operands[0], CDImode))
1760
    emit_move_complex_push (CDImode, operands[0], operands[1]);
1761
  else
1762
    emit_move_complex_parts (operands[0], operands[1]);
1763
  DONE;
1764
})
1765
 
1766
(define_expand "mov"
1767
  [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1768
        (match_operand:SWI1248x 1 "general_operand" ""))]
1769
  ""
1770
  "ix86_expand_move (mode, operands); DONE;")
1771
 
1772
(define_insn "*mov_xor"
1773
  [(set (match_operand:SWI48 0 "register_operand" "=r")
1774
        (match_operand:SWI48 1 "const0_operand" ""))
1775
   (clobber (reg:CC FLAGS_REG))]
1776
  "reload_completed"
1777
  "xor{l}\t%k0, %k0"
1778
  [(set_attr "type" "alu1")
1779
   (set_attr "mode" "SI")
1780
   (set_attr "length_immediate" "0")])
1781
 
1782
(define_insn "*mov_or"
1783
  [(set (match_operand:SWI48 0 "register_operand" "=r")
1784
        (match_operand:SWI48 1 "const_int_operand" ""))
1785
   (clobber (reg:CC FLAGS_REG))]
1786
  "reload_completed
1787
   && operands[1] == constm1_rtx"
1788
  "or{}\t{%1, %0|%0, %1}"
1789
  [(set_attr "type" "alu1")
1790
   (set_attr "mode" "")
1791
   (set_attr "length_immediate" "1")])
1792
 
1793
(define_insn "*movoi_internal_avx"
1794
  [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1795
        (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1796
  "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1797
{
1798
  switch (which_alternative)
1799
    {
1800
    case 0:
1801
      return standard_sse_constant_opcode (insn, operands[1]);
1802
    case 1:
1803
    case 2:
1804
      if (misaligned_operand (operands[0], OImode)
1805
          || misaligned_operand (operands[1], OImode))
1806
        return "vmovdqu\t{%1, %0|%0, %1}";
1807
      else
1808
        return "vmovdqa\t{%1, %0|%0, %1}";
1809
    default:
1810
      gcc_unreachable ();
1811
    }
1812
}
1813
  [(set_attr "type" "sselog1,ssemov,ssemov")
1814
   (set_attr "prefix" "vex")
1815
   (set_attr "mode" "OI")])
1816
 
1817
(define_insn "*movti_internal_rex64"
1818
  [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1819
        (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1820
  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1821
{
1822
  switch (which_alternative)
1823
    {
1824
    case 0:
1825
    case 1:
1826
      return "#";
1827
    case 2:
1828
      return standard_sse_constant_opcode (insn, operands[1]);
1829
    case 3:
1830
    case 4:
1831
      /* TDmode values are passed as TImode on the stack.  Moving them
1832
         to stack may result in unaligned memory access.  */
1833
      if (misaligned_operand (operands[0], TImode)
1834
          || misaligned_operand (operands[1], TImode))
1835
        {
1836
          if (get_attr_mode (insn) == MODE_V4SF)
1837
            return "%vmovups\t{%1, %0|%0, %1}";
1838
          else
1839
            return "%vmovdqu\t{%1, %0|%0, %1}";
1840
        }
1841
      else
1842
        {
1843
          if (get_attr_mode (insn) == MODE_V4SF)
1844
            return "%vmovaps\t{%1, %0|%0, %1}";
1845
          else
1846
            return "%vmovdqa\t{%1, %0|%0, %1}";
1847
        }
1848
    default:
1849
      gcc_unreachable ();
1850
    }
1851
}
1852
  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1853
   (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1854
   (set (attr "mode")
1855
        (cond [(eq_attr "alternative" "2,3")
1856
                 (if_then_else
1857
                   (match_test "optimize_function_for_size_p (cfun)")
1858
                   (const_string "V4SF")
1859
                   (const_string "TI"))
1860
               (eq_attr "alternative" "4")
1861
                 (if_then_else
1862
                   (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1863
                        (match_test "optimize_function_for_size_p (cfun)"))
1864
                   (const_string "V4SF")
1865
                   (const_string "TI"))]
1866
               (const_string "DI")))])
1867
 
1868
(define_split
1869
  [(set (match_operand:TI 0 "nonimmediate_operand" "")
1870
        (match_operand:TI 1 "general_operand" ""))]
1871
  "reload_completed
1872
   && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1873
  [(const_int 0)]
1874
  "ix86_split_long_move (operands); DONE;")
1875
 
1876
(define_insn "*movti_internal_sse"
1877
  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1878
        (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1879
  "TARGET_SSE && !TARGET_64BIT
1880
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1881
{
1882
  switch (which_alternative)
1883
    {
1884
    case 0:
1885
      return standard_sse_constant_opcode (insn, operands[1]);
1886
    case 1:
1887
    case 2:
1888
      /* TDmode values are passed as TImode on the stack.  Moving them
1889
         to stack may result in unaligned memory access.  */
1890
      if (misaligned_operand (operands[0], TImode)
1891
          || misaligned_operand (operands[1], TImode))
1892
        {
1893
          if (get_attr_mode (insn) == MODE_V4SF)
1894
            return "%vmovups\t{%1, %0|%0, %1}";
1895
          else
1896
            return "%vmovdqu\t{%1, %0|%0, %1}";
1897
        }
1898
      else
1899
        {
1900
          if (get_attr_mode (insn) == MODE_V4SF)
1901
            return "%vmovaps\t{%1, %0|%0, %1}";
1902
          else
1903
            return "%vmovdqa\t{%1, %0|%0, %1}";
1904
        }
1905
    default:
1906
      gcc_unreachable ();
1907
    }
1908
}
1909
  [(set_attr "type" "sselog1,ssemov,ssemov")
1910
   (set_attr "prefix" "maybe_vex")
1911
   (set (attr "mode")
1912
        (cond [(ior (not (match_test "TARGET_SSE2"))
1913
                    (match_test "optimize_function_for_size_p (cfun)"))
1914
                 (const_string "V4SF")
1915
               (and (eq_attr "alternative" "2")
1916
                    (match_test "TARGET_SSE_TYPELESS_STORES"))
1917
                 (const_string "V4SF")]
1918
              (const_string "TI")))])
1919
 
1920
(define_insn "*movdi_internal_rex64"
1921
  [(set (match_operand:DI 0 "nonimmediate_operand"
1922
          "=r,r  ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1923
        (match_operand:DI 1 "general_operand"
1924
          "Z ,rem,i,re,n ,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1925
  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1926
{
1927
  switch (get_attr_type (insn))
1928
    {
1929
    case TYPE_SSECVT:
1930
      if (SSE_REG_P (operands[0]))
1931
        return "movq2dq\t{%1, %0|%0, %1}";
1932
      else
1933
        return "movdq2q\t{%1, %0|%0, %1}";
1934
 
1935
    case TYPE_SSEMOV:
1936
      if (get_attr_mode (insn) == MODE_TI)
1937
        return "%vmovdqa\t{%1, %0|%0, %1}";
1938
      /* Handle broken assemblers that require movd instead of movq.  */
1939
      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1940
        return "%vmovd\t{%1, %0|%0, %1}";
1941
      else
1942
        return "%vmovq\t{%1, %0|%0, %1}";
1943
 
1944
    case TYPE_MMXMOV:
1945
      /* Handle broken assemblers that require movd instead of movq.  */
1946
      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1947
        return "movd\t{%1, %0|%0, %1}";
1948
      else
1949
        return "movq\t{%1, %0|%0, %1}";
1950
 
1951
    case TYPE_SSELOG1:
1952
      return standard_sse_constant_opcode (insn, operands[1]);
1953
 
1954
    case TYPE_MMX:
1955
      return "pxor\t%0, %0";
1956
 
1957
    case TYPE_MULTI:
1958
      return "#";
1959
 
1960
    case TYPE_LEA:
1961
      return "lea{q}\t{%a1, %0|%0, %a1}";
1962
 
1963
    default:
1964
      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1965
      if (get_attr_mode (insn) == MODE_SI)
1966
        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1967
      else if (which_alternative == 2)
1968
        return "movabs{q}\t{%1, %0|%0, %1}";
1969
      else if (ix86_use_lea_for_mov (insn, operands))
1970
        return "lea{q}\t{%a1, %0|%0, %a1}";
1971
      else
1972
        return "mov{q}\t{%1, %0|%0, %1}";
1973
    }
1974
}
1975
  [(set (attr "type")
1976
     (cond [(eq_attr "alternative" "4")
1977
              (const_string "multi")
1978
            (eq_attr "alternative" "5")
1979
              (const_string "mmx")
1980
            (eq_attr "alternative" "6,7,8,9")
1981
              (const_string "mmxmov")
1982
            (eq_attr "alternative" "10")
1983
              (const_string "sselog1")
1984
            (eq_attr "alternative" "11,12,13,14,15")
1985
              (const_string "ssemov")
1986
            (eq_attr "alternative" "16,17")
1987
              (const_string "ssecvt")
1988
            (match_operand 1 "pic_32bit_operand" "")
1989
              (const_string "lea")
1990
           ]
1991
           (const_string "imov")))
1992
   (set (attr "modrm")
1993
     (if_then_else
1994
       (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1995
         (const_string "0")
1996
         (const_string "*")))
1997
   (set (attr "length_immediate")
1998
     (if_then_else
1999
       (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2000
         (const_string "8")
2001
         (const_string "*")))
2002
   (set (attr "prefix_rex")
2003
     (if_then_else (eq_attr "alternative" "8,9")
2004
       (const_string "1")
2005
       (const_string "*")))
2006
   (set (attr "prefix_data16")
2007
     (if_then_else (eq_attr "alternative" "11")
2008
       (const_string "1")
2009
       (const_string "*")))
2010
   (set (attr "prefix")
2011
     (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2012
       (const_string "maybe_vex")
2013
       (const_string "orig")))
2014
   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2015
 
2016
;; Reload patterns to support multi-word load/store
2017
;; with non-offsetable address.
2018
(define_expand "reload_noff_store"
2019
  [(parallel [(match_operand 0 "memory_operand" "=m")
2020
              (match_operand 1 "register_operand" "r")
2021
              (match_operand:DI 2 "register_operand" "=&r")])]
2022
  "TARGET_64BIT"
2023
{
2024
  rtx mem = operands[0];
2025
  rtx addr = XEXP (mem, 0);
2026
 
2027
  emit_move_insn (operands[2], addr);
2028
  mem = replace_equiv_address_nv (mem, operands[2]);
2029
 
2030
  emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2031
  DONE;
2032
})
2033
 
2034
(define_expand "reload_noff_load"
2035
  [(parallel [(match_operand 0 "register_operand" "=r")
2036
              (match_operand 1 "memory_operand" "m")
2037
              (match_operand:DI 2 "register_operand" "=r")])]
2038
  "TARGET_64BIT"
2039
{
2040
  rtx mem = operands[1];
2041
  rtx addr = XEXP (mem, 0);
2042
 
2043
  emit_move_insn (operands[2], addr);
2044
  mem = replace_equiv_address_nv (mem, operands[2]);
2045
 
2046
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2047
  DONE;
2048
})
2049
 
2050
;; Convert impossible stores of immediate to existing instructions.
2051
;; First try to get scratch register and go through it.  In case this
2052
;; fails, move by 32bit parts.
2053
(define_peephole2
2054
  [(match_scratch:DI 2 "r")
2055
   (set (match_operand:DI 0 "memory_operand" "")
2056
        (match_operand:DI 1 "immediate_operand" ""))]
2057
  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2058
   && !x86_64_immediate_operand (operands[1], DImode)"
2059
  [(set (match_dup 2) (match_dup 1))
2060
   (set (match_dup 0) (match_dup 2))])
2061
 
2062
;; We need to define this as both peepholer and splitter for case
2063
;; peephole2 pass is not run.
2064
;; "&& 1" is needed to keep it from matching the previous pattern.
2065
(define_peephole2
2066
  [(set (match_operand:DI 0 "memory_operand" "")
2067
        (match_operand:DI 1 "immediate_operand" ""))]
2068
  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2069
   && !x86_64_immediate_operand (operands[1], DImode) && 1"
2070
  [(set (match_dup 2) (match_dup 3))
2071
   (set (match_dup 4) (match_dup 5))]
2072
  "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2073
 
2074
(define_split
2075
  [(set (match_operand:DI 0 "memory_operand" "")
2076
        (match_operand:DI 1 "immediate_operand" ""))]
2077
  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2078
                    ? epilogue_completed : reload_completed)
2079
   && !symbolic_operand (operands[1], DImode)
2080
   && !x86_64_immediate_operand (operands[1], DImode)"
2081
  [(set (match_dup 2) (match_dup 3))
2082
   (set (match_dup 4) (match_dup 5))]
2083
  "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2084
 
2085
(define_insn "*movdi_internal"
2086
  [(set (match_operand:DI 0 "nonimmediate_operand"
2087
          "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2088
        (match_operand:DI 1 "general_operand"
2089
          "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2090
  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2091
{
2092
  switch (get_attr_type (insn))
2093
    {
2094
    case TYPE_SSECVT:
2095
      if (SSE_REG_P (operands[0]))
2096
        return "movq2dq\t{%1, %0|%0, %1}";
2097
      else
2098
        return "movdq2q\t{%1, %0|%0, %1}";
2099
 
2100
    case TYPE_SSEMOV:
2101
      switch (get_attr_mode (insn))
2102
        {
2103
        case MODE_TI:
2104
          return "%vmovdqa\t{%1, %0|%0, %1}";
2105
        case MODE_DI:
2106
           return "%vmovq\t{%1, %0|%0, %1}";
2107
        case MODE_V4SF:
2108
          return "movaps\t{%1, %0|%0, %1}";
2109
        case MODE_V2SF:
2110
          return "movlps\t{%1, %0|%0, %1}";
2111
        default:
2112
          gcc_unreachable ();
2113
        }
2114
 
2115
    case TYPE_MMXMOV:
2116
      return "movq\t{%1, %0|%0, %1}";
2117
 
2118
    case TYPE_SSELOG1:
2119
      return standard_sse_constant_opcode (insn, operands[1]);
2120
 
2121
    case TYPE_MMX:
2122
      return "pxor\t%0, %0";
2123
 
2124
    case TYPE_MULTI:
2125
      return "#";
2126
 
2127
    default:
2128
      gcc_unreachable ();
2129
    }
2130
}
2131
  [(set (attr "isa")
2132
     (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2133
              (const_string "sse2")
2134
            (eq_attr "alternative" "9,10,11,12")
2135
              (const_string "noavx")
2136
           ]
2137
           (const_string "*")))
2138
   (set (attr "type")
2139
     (cond [(eq_attr "alternative" "0,1")
2140
              (const_string "multi")
2141
            (eq_attr "alternative" "2")
2142
              (const_string "mmx")
2143
            (eq_attr "alternative" "3,4")
2144
              (const_string "mmxmov")
2145
            (eq_attr "alternative" "5,9")
2146
              (const_string "sselog1")
2147
            (eq_attr "alternative" "13,14")
2148
              (const_string "ssecvt")
2149
           ]
2150
           (const_string "ssemov")))
2151
   (set (attr "prefix")
2152
     (if_then_else (eq_attr "alternative" "5,6,7,8")
2153
       (const_string "maybe_vex")
2154
       (const_string "orig")))
2155
   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2156
 
2157
(define_split
2158
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
2159
        (match_operand:DI 1 "general_operand" ""))]
2160
  "!TARGET_64BIT && reload_completed
2161
   && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2162
   && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2163
  [(const_int 0)]
2164
  "ix86_split_long_move (operands); DONE;")
2165
 
2166
(define_insn "*movsi_internal"
2167
  [(set (match_operand:SI 0 "nonimmediate_operand"
2168
                        "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2169
        (match_operand:SI 1 "general_operand"
2170
                        "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2171
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2172
{
2173
  switch (get_attr_type (insn))
2174
    {
2175
    case TYPE_SSELOG1:
2176
      return standard_sse_constant_opcode (insn, operands[1]);
2177
 
2178
    case TYPE_SSEMOV:
2179
      switch (get_attr_mode (insn))
2180
        {
2181
        case MODE_TI:
2182
          return "%vmovdqa\t{%1, %0|%0, %1}";
2183
        case MODE_V4SF:
2184
          return "%vmovaps\t{%1, %0|%0, %1}";
2185
        case MODE_SI:
2186
          return "%vmovd\t{%1, %0|%0, %1}";
2187
        case MODE_SF:
2188
          return "%vmovss\t{%1, %0|%0, %1}";
2189
        default:
2190
          gcc_unreachable ();
2191
        }
2192
 
2193
    case TYPE_MMX:
2194
      return "pxor\t%0, %0";
2195
 
2196
    case TYPE_MMXMOV:
2197
      if (get_attr_mode (insn) == MODE_DI)
2198
        return "movq\t{%1, %0|%0, %1}";
2199
      return "movd\t{%1, %0|%0, %1}";
2200
 
2201
    case TYPE_LEA:
2202
      return "lea{l}\t{%a1, %0|%0, %a1}";
2203
 
2204
    default:
2205
      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2206
      if (ix86_use_lea_for_mov (insn, operands))
2207
        return "lea{l}\t{%a1, %0|%0, %a1}";
2208
      else
2209
        return "mov{l}\t{%1, %0|%0, %1}";
2210
    }
2211
}
2212
  [(set (attr "type")
2213
     (cond [(eq_attr "alternative" "2")
2214
              (const_string "mmx")
2215
            (eq_attr "alternative" "3,4,5")
2216
              (const_string "mmxmov")
2217
            (eq_attr "alternative" "6")
2218
              (const_string "sselog1")
2219
            (eq_attr "alternative" "7,8,9,10,11")
2220
              (const_string "ssemov")
2221
            (match_operand 1 "pic_32bit_operand" "")
2222
              (const_string "lea")
2223
           ]
2224
           (const_string "imov")))
2225
   (set (attr "prefix")
2226
     (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2227
       (const_string "orig")
2228
       (const_string "maybe_vex")))
2229
   (set (attr "prefix_data16")
2230
     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2231
       (const_string "1")
2232
       (const_string "*")))
2233
   (set (attr "mode")
2234
     (cond [(eq_attr "alternative" "2,3")
2235
              (const_string "DI")
2236
            (eq_attr "alternative" "6,7")
2237
              (if_then_else
2238
                (not (match_test "TARGET_SSE2"))
2239
                (const_string "V4SF")
2240
                (const_string "TI"))
2241
            (and (eq_attr "alternative" "8,9,10,11")
2242
                 (not (match_test "TARGET_SSE2")))
2243
              (const_string "SF")
2244
           ]
2245
           (const_string "SI")))])
2246
 
2247
(define_insn "*movhi_internal"
2248
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2249
        (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2250
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2251
{
2252
  switch (get_attr_type (insn))
2253
    {
2254
    case TYPE_IMOVX:
2255
      /* movzwl is faster than movw on p2 due to partial word stalls,
2256
         though not as fast as an aligned movl.  */
2257
      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2258
    default:
2259
      if (get_attr_mode (insn) == MODE_SI)
2260
        return "mov{l}\t{%k1, %k0|%k0, %k1}";
2261
      else
2262
        return "mov{w}\t{%1, %0|%0, %1}";
2263
    }
2264
}
2265
  [(set (attr "type")
2266
     (cond [(match_test "optimize_function_for_size_p (cfun)")
2267
              (const_string "imov")
2268
            (and (eq_attr "alternative" "0")
2269
                 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2270
                      (not (match_test "TARGET_HIMODE_MATH"))))
2271
              (const_string "imov")
2272
            (and (eq_attr "alternative" "1,2")
2273
                 (match_operand:HI 1 "aligned_operand" ""))
2274
              (const_string "imov")
2275
            (and (match_test "TARGET_MOVX")
2276
                 (eq_attr "alternative" "0,2"))
2277
              (const_string "imovx")
2278
           ]
2279
           (const_string "imov")))
2280
    (set (attr "mode")
2281
      (cond [(eq_attr "type" "imovx")
2282
               (const_string "SI")
2283
             (and (eq_attr "alternative" "1,2")
2284
                  (match_operand:HI 1 "aligned_operand" ""))
2285
               (const_string "SI")
2286
             (and (eq_attr "alternative" "0")
2287
                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2288
                       (not (match_test "TARGET_HIMODE_MATH"))))
2289
               (const_string "SI")
2290
            ]
2291
            (const_string "HI")))])
2292
 
2293
;; Situation is quite tricky about when to choose full sized (SImode) move
2294
;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2295
;; partial register dependency machines (such as AMD Athlon), where QImode
2296
;; moves issue extra dependency and for partial register stalls machines
2297
;; that don't use QImode patterns (and QImode move cause stall on the next
2298
;; instruction).
2299
;;
2300
;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2301
;; register stall machines with, where we use QImode instructions, since
2302
;; partial register stall can be caused there.  Then we use movzx.
2303
(define_insn "*movqi_internal"
2304
  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2305
        (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2306
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2307
{
2308
  switch (get_attr_type (insn))
2309
    {
2310
    case TYPE_IMOVX:
2311
      gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2312
      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2313
    default:
2314
      if (get_attr_mode (insn) == MODE_SI)
2315
        return "mov{l}\t{%k1, %k0|%k0, %k1}";
2316
      else
2317
        return "mov{b}\t{%1, %0|%0, %1}";
2318
    }
2319
}
2320
  [(set (attr "type")
2321
     (cond [(and (eq_attr "alternative" "5")
2322
                 (not (match_operand:QI 1 "aligned_operand" "")))
2323
              (const_string "imovx")
2324
            (match_test "optimize_function_for_size_p (cfun)")
2325
              (const_string "imov")
2326
            (and (eq_attr "alternative" "3")
2327
                 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2328
                      (not (match_test "TARGET_QIMODE_MATH"))))
2329
              (const_string "imov")
2330
            (eq_attr "alternative" "3,5")
2331
              (const_string "imovx")
2332
            (and (match_test "TARGET_MOVX")
2333
                 (eq_attr "alternative" "2"))
2334
              (const_string "imovx")
2335
           ]
2336
           (const_string "imov")))
2337
   (set (attr "mode")
2338
      (cond [(eq_attr "alternative" "3,4,5")
2339
               (const_string "SI")
2340
             (eq_attr "alternative" "6")
2341
               (const_string "QI")
2342
             (eq_attr "type" "imovx")
2343
               (const_string "SI")
2344
             (and (eq_attr "type" "imov")
2345
                  (and (eq_attr "alternative" "0,1")
2346
                       (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2347
                            (and (not (match_test "optimize_function_for_size_p (cfun)"))
2348
                                 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2349
               (const_string "SI")
2350
             ;; Avoid partial register stalls when not using QImode arithmetic
2351
             (and (eq_attr "type" "imov")
2352
                  (and (eq_attr "alternative" "0,1")
2353
                       (and (match_test "TARGET_PARTIAL_REG_STALL")
2354
                            (not (match_test "TARGET_QIMODE_MATH")))))
2355
               (const_string "SI")
2356
           ]
2357
           (const_string "QI")))])
2358
 
2359
;; Stores and loads of ax to arbitrary constant address.
2360
;; We fake an second form of instruction to force reload to load address
2361
;; into register when rax is not available
2362
(define_insn "*movabs_1"
2363
  [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2364
        (match_operand:SWI1248x 1 "nonmemory_operand" "a,r"))]
2365
  "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2366
  "@
2367
   movabs{}\t{%1, %P0|%P0, %1}
2368
   mov{}\t{%1, %a0|%a0, %1}"
2369
  [(set_attr "type" "imov")
2370
   (set_attr "modrm" "0,*")
2371
   (set_attr "length_address" "8,0")
2372
   (set_attr "length_immediate" "0,*")
2373
   (set_attr "memory" "store")
2374
   (set_attr "mode" "")])
2375
 
2376
(define_insn "*movabs_2"
2377
  [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2378
        (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2379
  "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2380
  "@
2381
   movabs{}\t{%P1, %0|%0, %P1}
2382
   mov{}\t{%a1, %0|%0, %a1}"
2383
  [(set_attr "type" "imov")
2384
   (set_attr "modrm" "0,*")
2385
   (set_attr "length_address" "8,0")
2386
   (set_attr "length_immediate" "0")
2387
   (set_attr "memory" "load")
2388
   (set_attr "mode" "")])
2389
 
2390
(define_insn "*swap"
2391
  [(set (match_operand:SWI48 0 "register_operand" "+r")
2392
        (match_operand:SWI48 1 "register_operand" "+r"))
2393
   (set (match_dup 1)
2394
        (match_dup 0))]
2395
  ""
2396
  "xchg{}\t%1, %0"
2397
  [(set_attr "type" "imov")
2398
   (set_attr "mode" "")
2399
   (set_attr "pent_pair" "np")
2400
   (set_attr "athlon_decode" "vector")
2401
   (set_attr "amdfam10_decode" "double")
2402
   (set_attr "bdver1_decode" "double")])
2403
 
2404
(define_insn "*swap_1"
2405
  [(set (match_operand:SWI12 0 "register_operand" "+r")
2406
        (match_operand:SWI12 1 "register_operand" "+r"))
2407
   (set (match_dup 1)
2408
        (match_dup 0))]
2409
  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2410
  "xchg{l}\t%k1, %k0"
2411
  [(set_attr "type" "imov")
2412
   (set_attr "mode" "SI")
2413
   (set_attr "pent_pair" "np")
2414
   (set_attr "athlon_decode" "vector")
2415
   (set_attr "amdfam10_decode" "double")
2416
   (set_attr "bdver1_decode" "double")])
2417
 
2418
;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2419
;; is disabled for AMDFAM10
2420
(define_insn "*swap_2"
2421
  [(set (match_operand:SWI12 0 "register_operand" "+")
2422
        (match_operand:SWI12 1 "register_operand" "+"))
2423
   (set (match_dup 1)
2424
        (match_dup 0))]
2425
  "TARGET_PARTIAL_REG_STALL"
2426
  "xchg{}\t%1, %0"
2427
  [(set_attr "type" "imov")
2428
   (set_attr "mode" "")
2429
   (set_attr "pent_pair" "np")
2430
   (set_attr "athlon_decode" "vector")])
2431
 
2432
(define_expand "movstrict"
2433
  [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2434
        (match_operand:SWI12 1 "general_operand" ""))]
2435
  ""
2436
{
2437
  if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2438
    FAIL;
2439
  if (GET_CODE (operands[0]) == SUBREG
2440
      && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2441
    FAIL;
2442
  /* Don't generate memory->memory moves, go through a register */
2443
  if (MEM_P (operands[0]) && MEM_P (operands[1]))
2444
    operands[1] = force_reg (mode, operands[1]);
2445
})
2446
 
2447
(define_insn "*movstrict_1"
2448
  [(set (strict_low_part
2449
          (match_operand:SWI12 0 "nonimmediate_operand" "+m,"))
2450
        (match_operand:SWI12 1 "general_operand" "n,m"))]
2451
  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2452
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2453
  "mov{}\t{%1, %0|%0, %1}"
2454
  [(set_attr "type" "imov")
2455
   (set_attr "mode" "")])
2456
 
2457
(define_insn "*movstrict_xor"
2458
  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+"))
2459
        (match_operand:SWI12 1 "const0_operand" ""))
2460
   (clobber (reg:CC FLAGS_REG))]
2461
  "reload_completed"
2462
  "xor{}\t%0, %0"
2463
  [(set_attr "type" "alu1")
2464
   (set_attr "mode" "")
2465
   (set_attr "length_immediate" "0")])
2466
 
2467
(define_insn "*mov_extv_1"
2468
  [(set (match_operand:SWI24 0 "register_operand" "=R")
2469
        (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2470
                            (const_int 8)
2471
                            (const_int 8)))]
2472
  ""
2473
  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2474
  [(set_attr "type" "imovx")
2475
   (set_attr "mode" "SI")])
2476
 
2477
(define_insn "*movqi_extv_1_rex64"
2478
  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2479
        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2480
                         (const_int 8)
2481
                         (const_int 8)))]
2482
  "TARGET_64BIT"
2483
{
2484
  switch (get_attr_type (insn))
2485
    {
2486
    case TYPE_IMOVX:
2487
      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2488
    default:
2489
      return "mov{b}\t{%h1, %0|%0, %h1}";
2490
    }
2491
}
2492
  [(set (attr "type")
2493
     (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2494
                        (match_test "TARGET_MOVX"))
2495
        (const_string "imovx")
2496
        (const_string "imov")))
2497
   (set (attr "mode")
2498
     (if_then_else (eq_attr "type" "imovx")
2499
        (const_string "SI")
2500
        (const_string "QI")))])
2501
 
2502
(define_insn "*movqi_extv_1"
2503
  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2504
        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2505
                         (const_int 8)
2506
                         (const_int 8)))]
2507
  "!TARGET_64BIT"
2508
{
2509
  switch (get_attr_type (insn))
2510
    {
2511
    case TYPE_IMOVX:
2512
      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2513
    default:
2514
      return "mov{b}\t{%h1, %0|%0, %h1}";
2515
    }
2516
}
2517
  [(set (attr "type")
2518
     (if_then_else (and (match_operand:QI 0 "register_operand" "")
2519
                        (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2520
                             (match_test "TARGET_MOVX")))
2521
        (const_string "imovx")
2522
        (const_string "imov")))
2523
   (set (attr "mode")
2524
     (if_then_else (eq_attr "type" "imovx")
2525
        (const_string "SI")
2526
        (const_string "QI")))])
2527
 
2528
(define_insn "*mov_extzv_1"
2529
  [(set (match_operand:SWI48 0 "register_operand" "=R")
2530
        (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2531
                            (const_int 8)
2532
                            (const_int 8)))]
2533
  ""
2534
  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2535
  [(set_attr "type" "imovx")
2536
   (set_attr "mode" "SI")])
2537
 
2538
(define_insn "*movqi_extzv_2_rex64"
2539
  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2540
        (subreg:QI
2541
          (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2542
                           (const_int 8)
2543
                           (const_int 8)) 0))]
2544
  "TARGET_64BIT"
2545
{
2546
  switch (get_attr_type (insn))
2547
    {
2548
    case TYPE_IMOVX:
2549
      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2550
    default:
2551
      return "mov{b}\t{%h1, %0|%0, %h1}";
2552
    }
2553
}
2554
  [(set (attr "type")
2555
     (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2556
                        (match_test "TARGET_MOVX"))
2557
        (const_string "imovx")
2558
        (const_string "imov")))
2559
   (set (attr "mode")
2560
     (if_then_else (eq_attr "type" "imovx")
2561
        (const_string "SI")
2562
        (const_string "QI")))])
2563
 
2564
(define_insn "*movqi_extzv_2"
2565
  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2566
        (subreg:QI
2567
          (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2568
                           (const_int 8)
2569
                           (const_int 8)) 0))]
2570
  "!TARGET_64BIT"
2571
{
2572
  switch (get_attr_type (insn))
2573
    {
2574
    case TYPE_IMOVX:
2575
      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2576
    default:
2577
      return "mov{b}\t{%h1, %0|%0, %h1}";
2578
    }
2579
}
2580
  [(set (attr "type")
2581
     (if_then_else (and (match_operand:QI 0 "register_operand" "")
2582
                        (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2583
                             (match_test "TARGET_MOVX")))
2584
        (const_string "imovx")
2585
        (const_string "imov")))
2586
   (set (attr "mode")
2587
     (if_then_else (eq_attr "type" "imovx")
2588
        (const_string "SI")
2589
        (const_string "QI")))])
2590
 
2591
(define_expand "mov_insv_1"
2592
  [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2593
                            (const_int 8)
2594
                            (const_int 8))
2595
        (match_operand:SWI48 1 "nonmemory_operand" ""))])
2596
 
2597
(define_insn "*mov_insv_1_rex64"
2598
  [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2599
                             (const_int 8)
2600
                             (const_int 8))
2601
        (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2602
  "TARGET_64BIT"
2603
  "mov{b}\t{%b1, %h0|%h0, %b1}"
2604
  [(set_attr "type" "imov")
2605
   (set_attr "mode" "QI")])
2606
 
2607
(define_insn "*movsi_insv_1"
2608
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2609
                         (const_int 8)
2610
                         (const_int 8))
2611
        (match_operand:SI 1 "general_operand" "Qmn"))]
2612
  "!TARGET_64BIT"
2613
  "mov{b}\t{%b1, %h0|%h0, %b1}"
2614
  [(set_attr "type" "imov")
2615
   (set_attr "mode" "QI")])
2616
 
2617
(define_insn "*movqi_insv_2"
2618
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2619
                         (const_int 8)
2620
                         (const_int 8))
2621
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2622
                     (const_int 8)))]
2623
  ""
2624
  "mov{b}\t{%h1, %h0|%h0, %h1}"
2625
  [(set_attr "type" "imov")
2626
   (set_attr "mode" "QI")])
2627
 
2628
;; Floating point push instructions.
2629
 
2630
(define_insn "*pushtf"
2631
  [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2632
        (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2633
  "TARGET_SSE2"
2634
{
2635
  /* This insn should be already split before reg-stack.  */
2636
  gcc_unreachable ();
2637
}
2638
  [(set_attr "type" "multi")
2639
   (set_attr "unit" "sse,*,*")
2640
   (set_attr "mode" "TF,SI,SI")])
2641
 
2642
;; %%% Kill this when call knows how to work this out.
2643
(define_split
2644
  [(set (match_operand:TF 0 "push_operand" "")
2645
        (match_operand:TF 1 "sse_reg_operand" ""))]
2646
  "TARGET_SSE2 && reload_completed"
2647
  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2648
   (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2649
 
2650
(define_insn "*pushxf"
2651
  [(set (match_operand:XF 0 "push_operand" "=<,<")
2652
        (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2653
  "optimize_function_for_speed_p (cfun)"
2654
{
2655
  /* This insn should be already split before reg-stack.  */
2656
  gcc_unreachable ();
2657
}
2658
  [(set_attr "type" "multi")
2659
   (set_attr "unit" "i387,*")
2660
   (set_attr "mode" "XF,SI")])
2661
 
2662
;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663
;; Size of pushxf using integer instructions is 3+3*memory operand size
2664
;; Pushing using integer instructions is longer except for constants
2665
;; and direct memory references (assuming that any given constant is pushed
2666
;; only once, but this ought to be handled elsewhere).
2667
 
2668
(define_insn "*pushxf_nointeger"
2669
  [(set (match_operand:XF 0 "push_operand" "=<,<")
2670
        (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2671
  "optimize_function_for_size_p (cfun)"
2672
{
2673
  /* This insn should be already split before reg-stack.  */
2674
  gcc_unreachable ();
2675
}
2676
  [(set_attr "type" "multi")
2677
   (set_attr "unit" "i387,*")
2678
   (set_attr "mode" "XF,SI")])
2679
 
2680
;; %%% Kill this when call knows how to work this out.
2681
(define_split
2682
  [(set (match_operand:XF 0 "push_operand" "")
2683
        (match_operand:XF 1 "fp_register_operand" ""))]
2684
  "reload_completed"
2685
  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2686
   (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2687
  "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2688
 
2689
(define_insn "*pushdf_rex64"
2690
  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2691
        (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2692
  "TARGET_64BIT"
2693
{
2694
  /* This insn should be already split before reg-stack.  */
2695
  gcc_unreachable ();
2696
}
2697
  [(set_attr "type" "multi")
2698
   (set_attr "unit" "i387,*,*")
2699
   (set_attr "mode" "DF,DI,DF")])
2700
 
2701
;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2702
;; Size of pushdf using integer instructions is 2+2*memory operand size
2703
;; On the average, pushdf using integers can be still shorter.
2704
 
2705
(define_insn "*pushdf"
2706
  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2707
        (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2708
  "!TARGET_64BIT"
2709
{
2710
  /* This insn should be already split before reg-stack.  */
2711
  gcc_unreachable ();
2712
}
2713
  [(set_attr "isa" "*,*,sse2")
2714
   (set_attr "type" "multi")
2715
   (set_attr "unit" "i387,*,*")
2716
   (set_attr "mode" "DF,DI,DF")])
2717
 
2718
;; %%% Kill this when call knows how to work this out.
2719
(define_split
2720
  [(set (match_operand:DF 0 "push_operand" "")
2721
        (match_operand:DF 1 "any_fp_register_operand" ""))]
2722
  "reload_completed"
2723
  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2724
   (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2725
 
2726
(define_insn "*pushsf_rex64"
2727
  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2728
        (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2729
  "TARGET_64BIT"
2730
{
2731
  /* Anything else should be already split before reg-stack.  */
2732
  gcc_assert (which_alternative == 1);
2733
  return "push{q}\t%q1";
2734
}
2735
  [(set_attr "type" "multi,push,multi")
2736
   (set_attr "unit" "i387,*,*")
2737
   (set_attr "mode" "SF,DI,SF")])
2738
 
2739
(define_insn "*pushsf"
2740
  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2741
        (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2742
  "!TARGET_64BIT"
2743
{
2744
  /* Anything else should be already split before reg-stack.  */
2745
  gcc_assert (which_alternative == 1);
2746
  return "push{l}\t%1";
2747
}
2748
  [(set_attr "type" "multi,push,multi")
2749
   (set_attr "unit" "i387,*,*")
2750
   (set_attr "mode" "SF,SI,SF")])
2751
 
2752
;; %%% Kill this when call knows how to work this out.
2753
(define_split
2754
  [(set (match_operand:SF 0 "push_operand" "")
2755
        (match_operand:SF 1 "any_fp_register_operand" ""))]
2756
  "reload_completed"
2757
  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2758
   (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2759
  "operands[2] = GEN_INT (-GET_MODE_SIZE (mode));")
2760
 
2761
(define_split
2762
  [(set (match_operand:SF 0 "push_operand" "")
2763
        (match_operand:SF 1 "memory_operand" ""))]
2764
  "reload_completed
2765
   && (operands[2] = find_constant_src (insn))"
2766
  [(set (match_dup 0) (match_dup 2))])
2767
 
2768
(define_split
2769
  [(set (match_operand 0 "push_operand" "")
2770
        (match_operand 1 "general_operand" ""))]
2771
  "reload_completed
2772
   && (GET_MODE (operands[0]) == TFmode
2773
       || GET_MODE (operands[0]) == XFmode
2774
       || GET_MODE (operands[0]) == DFmode)
2775
   && !ANY_FP_REG_P (operands[1])"
2776
  [(const_int 0)]
2777
  "ix86_split_long_move (operands); DONE;")
2778
 
2779
;; Floating point move instructions.
2780
 
2781
(define_expand "movtf"
2782
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2783
        (match_operand:TF 1 "nonimmediate_operand" ""))]
2784
  "TARGET_SSE2"
2785
{
2786
  ix86_expand_move (TFmode, operands);
2787
  DONE;
2788
})
2789
 
2790
(define_expand "mov"
2791
  [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2792
        (match_operand:X87MODEF 1 "general_operand" ""))]
2793
  ""
2794
  "ix86_expand_move (mode, operands); DONE;")
2795
 
2796
(define_insn "*movtf_internal"
2797
  [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2798
        (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,F*r"))]
2799
  "TARGET_SSE2
2800
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2801
   && (!can_create_pseudo_p ()
2802
       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2803
       || GET_CODE (operands[1]) != CONST_DOUBLE
2804
       || (optimize_function_for_size_p (cfun)
2805
           && standard_sse_constant_p (operands[1])
2806
           && !memory_operand (operands[0], TFmode))
2807
       || (!TARGET_MEMORY_MISMATCH_STALL
2808
           && memory_operand (operands[0], TFmode)))"
2809
{
2810
  switch (which_alternative)
2811
    {
2812
    case 0:
2813
    case 1:
2814
      /* Handle misaligned load/store since we
2815
         don't have movmisaligntf pattern. */
2816
      if (misaligned_operand (operands[0], TFmode)
2817
          || misaligned_operand (operands[1], TFmode))
2818
        {
2819
          if (get_attr_mode (insn) == MODE_V4SF)
2820
            return "%vmovups\t{%1, %0|%0, %1}";
2821
          else
2822
            return "%vmovdqu\t{%1, %0|%0, %1}";
2823
        }
2824
      else
2825
        {
2826
          if (get_attr_mode (insn) == MODE_V4SF)
2827
            return "%vmovaps\t{%1, %0|%0, %1}";
2828
          else
2829
            return "%vmovdqa\t{%1, %0|%0, %1}";
2830
        }
2831
 
2832
    case 2:
2833
      return standard_sse_constant_opcode (insn, operands[1]);
2834
 
2835
    case 3:
2836
    case 4:
2837
        return "#";
2838
 
2839
    default:
2840
      gcc_unreachable ();
2841
    }
2842
}
2843
  [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2844
   (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2845
   (set (attr "mode")
2846
        (cond [(eq_attr "alternative" "0,2")
2847
                 (if_then_else
2848
                   (match_test "optimize_function_for_size_p (cfun)")
2849
                   (const_string "V4SF")
2850
                   (const_string "TI"))
2851
               (eq_attr "alternative" "1")
2852
                 (if_then_else
2853
                   (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2854
                        (match_test "optimize_function_for_size_p (cfun)"))
2855
                   (const_string "V4SF")
2856
                   (const_string "TI"))]
2857
               (const_string "DI")))])
2858
 
2859
;; Possible store forwarding (partial memory) stall in alternative 4.
2860
(define_insn "*movxf_internal"
2861
  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2862
        (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
2863
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2864
   && (!can_create_pseudo_p ()
2865
       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2866
       || GET_CODE (operands[1]) != CONST_DOUBLE
2867
       || (optimize_function_for_size_p (cfun)
2868
           && standard_80387_constant_p (operands[1]) > 0
2869
           && !memory_operand (operands[0], XFmode))
2870
       || (!TARGET_MEMORY_MISMATCH_STALL
2871
           && memory_operand (operands[0], XFmode)))"
2872
{
2873
  switch (which_alternative)
2874
    {
2875
    case 0:
2876
    case 1:
2877
      return output_387_reg_move (insn, operands);
2878
 
2879
    case 2:
2880
      return standard_80387_constant_opcode (operands[1]);
2881
 
2882
    case 3:
2883
    case 4:
2884
      return "#";
2885
 
2886
    default:
2887
      gcc_unreachable ();
2888
    }
2889
}
2890
  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2891
   (set_attr "mode" "XF,XF,XF,SI,SI")])
2892
 
2893
(define_insn "*movdf_internal_rex64"
2894
  [(set (match_operand:DF 0 "nonimmediate_operand"
2895
                "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2896
        (match_operand:DF 1 "general_operand"
2897
                "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2898
  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2899
   && (!can_create_pseudo_p ()
2900
       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2901
       || GET_CODE (operands[1]) != CONST_DOUBLE
2902
       || (optimize_function_for_size_p (cfun)
2903
           && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2904
                && standard_80387_constant_p (operands[1]) > 0)
2905
               || (TARGET_SSE2 && TARGET_SSE_MATH
2906
                   && standard_sse_constant_p (operands[1]))))
2907
       || memory_operand (operands[0], DFmode))"
2908
{
2909
  switch (which_alternative)
2910
    {
2911
    case 0:
2912
    case 1:
2913
      return output_387_reg_move (insn, operands);
2914
 
2915
    case 2:
2916
      return standard_80387_constant_opcode (operands[1]);
2917
 
2918
    case 3:
2919
    case 4:
2920
      return "mov{q}\t{%1, %0|%0, %1}";
2921
 
2922
    case 5:
2923
      return "movabs{q}\t{%1, %0|%0, %1}";
2924
 
2925
    case 6:
2926
      return "#";
2927
 
2928
    case 7:
2929
      return standard_sse_constant_opcode (insn, operands[1]);
2930
 
2931
    case 8:
2932
    case 9:
2933
    case 10:
2934
      switch (get_attr_mode (insn))
2935
        {
2936
        case MODE_V2DF:
2937
          if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2938
            return "%vmovapd\t{%1, %0|%0, %1}";
2939
        case MODE_V4SF:
2940
          return "%vmovaps\t{%1, %0|%0, %1}";
2941
 
2942
        case MODE_DI:
2943
          return "%vmovq\t{%1, %0|%0, %1}";
2944
        case MODE_DF:
2945
          if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2946
            return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2947
          return "%vmovsd\t{%1, %0|%0, %1}";
2948
        case MODE_V1DF:
2949
          return "%vmovlpd\t{%1, %d0|%d0, %1}";
2950
        case MODE_V2SF:
2951
          return "%vmovlps\t{%1, %d0|%d0, %1}";
2952
        default:
2953
          gcc_unreachable ();
2954
        }
2955
 
2956
    case 11:
2957
    case 12:
2958
      /* Handle broken assemblers that require movd instead of movq.  */
2959
      return "%vmovd\t{%1, %0|%0, %1}";
2960
 
2961
    default:
2962
      gcc_unreachable();
2963
    }
2964
}
2965
  [(set (attr "type")
2966
        (cond [(eq_attr "alternative" "0,1,2")
2967
                 (const_string "fmov")
2968
               (eq_attr "alternative" "3,4,5")
2969
                 (const_string "imov")
2970
               (eq_attr "alternative" "6")
2971
                 (const_string "multi")
2972
               (eq_attr "alternative" "7")
2973
                 (const_string "sselog1")
2974
              ]
2975
              (const_string "ssemov")))
2976
   (set (attr "modrm")
2977
     (if_then_else
2978
       (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2979
         (const_string "0")
2980
         (const_string "*")))
2981
   (set (attr "length_immediate")
2982
     (if_then_else
2983
       (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2984
         (const_string "8")
2985
         (const_string "*")))
2986
   (set (attr "prefix")
2987
     (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2988
       (const_string "orig")
2989
       (const_string "maybe_vex")))
2990
   (set (attr "prefix_data16")
2991
     (if_then_else (eq_attr "mode" "V1DF")
2992
       (const_string "1")
2993
       (const_string "*")))
2994
   (set (attr "mode")
2995
        (cond [(eq_attr "alternative" "0,1,2")
2996
                 (const_string "DF")
2997
               (eq_attr "alternative" "3,4,5,6,11,12")
2998
                 (const_string "DI")
2999
 
3000
               /* xorps is one byte shorter.  */
3001
               (eq_attr "alternative" "7")
3002
                 (cond [(match_test "optimize_function_for_size_p (cfun)")
3003
                          (const_string "V4SF")
3004
                        (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3005
                          (const_string "TI")
3006
                       ]
3007
                       (const_string "V2DF"))
3008
 
3009
               /* For architectures resolving dependencies on
3010
                  whole SSE registers use APD move to break dependency
3011
                  chains, otherwise use short move to avoid extra work.
3012
 
3013
                  movaps encodes one byte shorter.  */
3014
               (eq_attr "alternative" "8")
3015
                 (cond
3016
                   [(match_test "optimize_function_for_size_p (cfun)")
3017
                      (const_string "V4SF")
3018
                    (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3019
                      (const_string "V2DF")
3020
                   ]
3021
                   (const_string "DF"))
3022
               /* For architectures resolving dependencies on register
3023
                  parts we may avoid extra work to zero out upper part
3024
                  of register.  */
3025
               (eq_attr "alternative" "9")
3026
                 (if_then_else
3027
                   (match_test "TARGET_SSE_SPLIT_REGS")
3028
                   (const_string "V1DF")
3029
                   (const_string "DF"))
3030
              ]
3031
              (const_string "DF")))])
3032
 
3033
;; Possible store forwarding (partial memory) stall in alternative 4.
3034
(define_insn "*movdf_internal"
3035
  [(set (match_operand:DF 0 "nonimmediate_operand"
3036
                "=f,m,f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3037
        (match_operand:DF 1 "general_operand"
3038
                "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3039
  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3040
   && (!can_create_pseudo_p ()
3041
       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3042
       || GET_CODE (operands[1]) != CONST_DOUBLE
3043
       || (optimize_function_for_size_p (cfun)
3044
           && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3045
                && standard_80387_constant_p (operands[1]) > 0)
3046
               || (TARGET_SSE2 && TARGET_SSE_MATH
3047
                   && standard_sse_constant_p (operands[1])))
3048
           && !memory_operand (operands[0], DFmode))
3049
       || (!TARGET_MEMORY_MISMATCH_STALL
3050
           && memory_operand (operands[0], DFmode)))"
3051
{
3052
  switch (which_alternative)
3053
    {
3054
    case 0:
3055
    case 1:
3056
      return output_387_reg_move (insn, operands);
3057
 
3058
    case 2:
3059
      return standard_80387_constant_opcode (operands[1]);
3060
 
3061
    case 3:
3062
    case 4:
3063
      return "#";
3064
 
3065
    case 5:
3066
    case 9:
3067
      return standard_sse_constant_opcode (insn, operands[1]);
3068
 
3069
    case 6:
3070
    case 7:
3071
    case 8:
3072
    case 10:
3073
    case 11:
3074
    case 12:
3075
      switch (get_attr_mode (insn))
3076
        {
3077
        case MODE_V2DF:
3078
          if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3079
            return "%vmovapd\t{%1, %0|%0, %1}";
3080
        case MODE_V4SF:
3081
          return "%vmovaps\t{%1, %0|%0, %1}";
3082
 
3083
        case MODE_DI:
3084
          return "%vmovq\t{%1, %0|%0, %1}";
3085
        case MODE_DF:
3086
          if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3087
            return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3088
          return "%vmovsd\t{%1, %0|%0, %1}";
3089
        case MODE_V1DF:
3090
          return "%vmovlpd\t{%1, %d0|%d0, %1}";
3091
        case MODE_V2SF:
3092
          return "%vmovlps\t{%1, %d0|%d0, %1}";
3093
        default:
3094
          gcc_unreachable ();
3095
        }
3096
 
3097
    default:
3098
      gcc_unreachable ();
3099
    }
3100
}
3101
  [(set (attr "isa")
3102
     (if_then_else (eq_attr "alternative" "5,6,7,8")
3103
       (const_string "sse2")
3104
       (const_string "*")))
3105
   (set (attr "type")
3106
        (cond [(eq_attr "alternative" "0,1,2")
3107
                 (const_string "fmov")
3108
               (eq_attr "alternative" "3,4")
3109
                 (const_string "multi")
3110
               (eq_attr "alternative" "5,9")
3111
                 (const_string "sselog1")
3112
              ]
3113
              (const_string "ssemov")))
3114
   (set (attr "prefix")
3115
     (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3116
       (const_string "orig")
3117
       (const_string "maybe_vex")))
3118
   (set (attr "prefix_data16")
3119
     (if_then_else (eq_attr "mode" "V1DF")
3120
       (const_string "1")
3121
       (const_string "*")))
3122
   (set (attr "mode")
3123
        (cond [(eq_attr "alternative" "0,1,2")
3124
                 (const_string "DF")
3125
               (eq_attr "alternative" "3,4")
3126
                 (const_string "SI")
3127
 
3128
               /* For SSE1, we have many fewer alternatives.  */
3129
               (not (match_test "TARGET_SSE2"))
3130
                 (if_then_else
3131
                   (eq_attr "alternative" "5,6,9,10")
3132
                   (const_string "V4SF")
3133
                   (const_string "V2SF"))
3134
 
3135
               /* xorps is one byte shorter.  */
3136
               (eq_attr "alternative" "5,9")
3137
                 (cond [(match_test "optimize_function_for_size_p (cfun)")
3138
                          (const_string "V4SF")
3139
                        (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3140
                          (const_string "TI")
3141
                       ]
3142
                       (const_string "V2DF"))
3143
 
3144
               /* For architectures resolving dependencies on
3145
                  whole SSE registers use APD move to break dependency
3146
                  chains, otherwise use short move to avoid extra work.
3147
 
3148
                  movaps encodes one byte shorter.  */
3149
               (eq_attr "alternative" "6,10")
3150
                 (cond
3151
                   [(match_test "optimize_function_for_size_p (cfun)")
3152
                      (const_string "V4SF")
3153
                    (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3154
                      (const_string "V2DF")
3155
                   ]
3156
                   (const_string "DF"))
3157
               /* For architectures resolving dependencies on register
3158
                  parts we may avoid extra work to zero out upper part
3159
                  of register.  */
3160
               (eq_attr "alternative" "7,11")
3161
                 (if_then_else
3162
                   (match_test "TARGET_SSE_SPLIT_REGS")
3163
                   (const_string "V1DF")
3164
                   (const_string "DF"))
3165
              ]
3166
              (const_string "DF")))])
3167
 
3168
(define_insn "*movsf_internal"
3169
  [(set (match_operand:SF 0 "nonimmediate_operand"
3170
          "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3171
        (match_operand:SF 1 "general_operand"
3172
          "fm,f,G,rmF,Fr,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3173
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3174
   && (!can_create_pseudo_p ()
3175
       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3176
       || GET_CODE (operands[1]) != CONST_DOUBLE
3177
       || (optimize_function_for_size_p (cfun)
3178
           && ((!TARGET_SSE_MATH
3179
                && standard_80387_constant_p (operands[1]) > 0)
3180
               || (TARGET_SSE_MATH
3181
                   && standard_sse_constant_p (operands[1]))))
3182
       || memory_operand (operands[0], SFmode))"
3183
{
3184
  switch (which_alternative)
3185
    {
3186
    case 0:
3187
    case 1:
3188
      return output_387_reg_move (insn, operands);
3189
 
3190
    case 2:
3191
      return standard_80387_constant_opcode (operands[1]);
3192
 
3193
    case 3:
3194
    case 4:
3195
      return "mov{l}\t{%1, %0|%0, %1}";
3196
 
3197
    case 5:
3198
      return standard_sse_constant_opcode (insn, operands[1]);
3199
 
3200
    case 6:
3201
      if (get_attr_mode (insn) == MODE_V4SF)
3202
        return "%vmovaps\t{%1, %0|%0, %1}";
3203
      if (TARGET_AVX)
3204
        return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3205
 
3206
    case 7:
3207
    case 8:
3208
      return "%vmovss\t{%1, %0|%0, %1}";
3209
 
3210
    case 9:
3211
    case 10:
3212
    case 14:
3213
    case 15:
3214
      return "movd\t{%1, %0|%0, %1}";
3215
 
3216
    case 11:
3217
      return "movq\t{%1, %0|%0, %1}";
3218
 
3219
    case 12:
3220
    case 13:
3221
      return "%vmovd\t{%1, %0|%0, %1}";
3222
 
3223
    default:
3224
      gcc_unreachable ();
3225
    }
3226
}
3227
  [(set (attr "type")
3228
        (cond [(eq_attr "alternative" "0,1,2")
3229
                 (const_string "fmov")
3230
               (eq_attr "alternative" "3,4")
3231
                 (const_string "multi")
3232
               (eq_attr "alternative" "5")
3233
                 (const_string "sselog1")
3234
               (eq_attr "alternative" "9,10,11,14,15")
3235
                 (const_string "mmxmov")
3236
              ]
3237
              (const_string "ssemov")))
3238
   (set (attr "prefix")
3239
     (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3240
       (const_string "maybe_vex")
3241
       (const_string "orig")))
3242
   (set (attr "mode")
3243
        (cond [(eq_attr "alternative" "3,4,9,10")
3244
                 (const_string "SI")
3245
               (eq_attr "alternative" "5")
3246
                 (if_then_else
3247
                   (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3248
                             (match_test "TARGET_SSE2"))
3249
                        (not (match_test "optimize_function_for_size_p (cfun)")))
3250
                   (const_string "TI")
3251
                   (const_string "V4SF"))
3252
               /* For architectures resolving dependencies on
3253
                  whole SSE registers use APS move to break dependency
3254
                  chains, otherwise use short move to avoid extra work.
3255
 
3256
                  Do the same for architectures resolving dependencies on
3257
                  the parts.  While in DF mode it is better to always handle
3258
                  just register parts, the SF mode is different due to lack
3259
                  of instructions to load just part of the register.  It is
3260
                  better to maintain the whole registers in single format
3261
                  to avoid problems on using packed logical operations.  */
3262
               (eq_attr "alternative" "6")
3263
                 (if_then_else
3264
                   (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3265
                        (match_test "TARGET_SSE_SPLIT_REGS"))
3266
                   (const_string "V4SF")
3267
                   (const_string "SF"))
3268
               (eq_attr "alternative" "11")
3269
                 (const_string "DI")]
3270
               (const_string "SF")))])
3271
 
3272
(define_split
3273
  [(set (match_operand 0 "any_fp_register_operand" "")
3274
        (match_operand 1 "memory_operand" ""))]
3275
  "reload_completed
3276
   && (GET_MODE (operands[0]) == TFmode
3277
       || GET_MODE (operands[0]) == XFmode
3278
       || GET_MODE (operands[0]) == DFmode
3279
       || GET_MODE (operands[0]) == SFmode)
3280
   && (operands[2] = find_constant_src (insn))"
3281
  [(set (match_dup 0) (match_dup 2))]
3282
{
3283
  rtx c = operands[2];
3284
  int r = REGNO (operands[0]);
3285
 
3286
  if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3287
      || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3288
    FAIL;
3289
})
3290
 
3291
(define_split
3292
  [(set (match_operand 0 "any_fp_register_operand" "")
3293
        (float_extend (match_operand 1 "memory_operand" "")))]
3294
  "reload_completed
3295
   && (GET_MODE (operands[0]) == TFmode
3296
       || GET_MODE (operands[0]) == XFmode
3297
       || GET_MODE (operands[0]) == DFmode)
3298
   && (operands[2] = find_constant_src (insn))"
3299
  [(set (match_dup 0) (match_dup 2))]
3300
{
3301
  rtx c = operands[2];
3302
  int r = REGNO (operands[0]);
3303
 
3304
  if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3305
      || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3306
    FAIL;
3307
})
3308
 
3309
;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3310
(define_split
3311
  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3312
        (match_operand:X87MODEF 1 "immediate_operand" ""))]
3313
  "reload_completed
3314
   && (standard_80387_constant_p (operands[1]) == 8
3315
       || standard_80387_constant_p (operands[1]) == 9)"
3316
  [(set (match_dup 0)(match_dup 1))
3317
   (set (match_dup 0)
3318
        (neg:X87MODEF (match_dup 0)))]
3319
{
3320
  REAL_VALUE_TYPE r;
3321
 
3322
  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3323
  if (real_isnegzero (&r))
3324
    operands[1] = CONST0_RTX (mode);
3325
  else
3326
    operands[1] = CONST1_RTX (mode);
3327
})
3328
 
3329
(define_split
3330
  [(set (match_operand 0 "nonimmediate_operand" "")
3331
        (match_operand 1 "general_operand" ""))]
3332
  "reload_completed
3333
   && (GET_MODE (operands[0]) == TFmode
3334
       || GET_MODE (operands[0]) == XFmode
3335
       || GET_MODE (operands[0]) == DFmode)
3336
   && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3337
  [(const_int 0)]
3338
  "ix86_split_long_move (operands); DONE;")
3339
 
3340
(define_insn "swapxf"
3341
  [(set (match_operand:XF 0 "register_operand" "+f")
3342
        (match_operand:XF 1 "register_operand" "+f"))
3343
   (set (match_dup 1)
3344
        (match_dup 0))]
3345
  "TARGET_80387"
3346
{
3347
  if (STACK_TOP_P (operands[0]))
3348
    return "fxch\t%1";
3349
  else
3350
    return "fxch\t%0";
3351
}
3352
  [(set_attr "type" "fxch")
3353
   (set_attr "mode" "XF")])
3354
 
3355
(define_insn "*swap"
3356
  [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3357
        (match_operand:MODEF 1 "fp_register_operand" "+f"))
3358
   (set (match_dup 1)
3359
        (match_dup 0))]
3360
  "TARGET_80387 || reload_completed"
3361
{
3362
  if (STACK_TOP_P (operands[0]))
3363
    return "fxch\t%1";
3364
  else
3365
    return "fxch\t%0";
3366
}
3367
  [(set_attr "type" "fxch")
3368
   (set_attr "mode" "")])
3369
 
3370
;; Zero extension instructions
3371
 
3372
(define_expand "zero_extendsidi2"
3373
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3374
        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3375
  ""
3376
{
3377
  if (!TARGET_64BIT)
3378
    {
3379
      emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3380
      DONE;
3381
    }
3382
})
3383
 
3384
(define_insn "*zero_extendsidi2_rex64"
3385
  [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*x")
3386
        (zero_extend:DI
3387
         (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3388
  "TARGET_64BIT"
3389
  "@
3390
   mov{l}\t{%1, %k0|%k0, %1}
3391
   #
3392
   movd\t{%1, %0|%0, %1}
3393
   movd\t{%1, %0|%0, %1}
3394
   %vmovd\t{%1, %0|%0, %1}
3395
   %vmovd\t{%1, %0|%0, %1}"
3396
  [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3397
   (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3398
   (set_attr "prefix_0f" "0,*,*,*,*,*")
3399
   (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3400
 
3401
(define_split
3402
  [(set (match_operand:DI 0 "memory_operand" "")
3403
        (zero_extend:DI (match_dup 0)))]
3404
  "TARGET_64BIT"
3405
  [(set (match_dup 4) (const_int 0))]
3406
  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3407
 
3408
;; %%% Kill me once multi-word ops are sane.
3409
(define_insn "zero_extendsidi2_1"
3410
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3411
        (zero_extend:DI
3412
         (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3413
   (clobber (reg:CC FLAGS_REG))]
3414
  "!TARGET_64BIT"
3415
  "@
3416
   #
3417
   #
3418
   #
3419
   movd\t{%1, %0|%0, %1}
3420
   movd\t{%1, %0|%0, %1}
3421
   %vmovd\t{%1, %0|%0, %1}
3422
   %vmovd\t{%1, %0|%0, %1}"
3423
  [(set_attr "isa" "*,*,*,*,*,*,sse2")
3424
   (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3425
   (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3426
   (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3427
 
3428
(define_split
3429
  [(set (match_operand:DI 0 "register_operand" "")
3430
        (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3431
   (clobber (reg:CC FLAGS_REG))]
3432
  "!TARGET_64BIT && reload_completed
3433
   && true_regnum (operands[0]) == true_regnum (operands[1])"
3434
  [(set (match_dup 4) (const_int 0))]
3435
  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3436
 
3437
(define_split
3438
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3439
        (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3440
   (clobber (reg:CC FLAGS_REG))]
3441
  "!TARGET_64BIT && reload_completed
3442
   && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3443
  [(set (match_dup 3) (match_dup 1))
3444
   (set (match_dup 4) (const_int 0))]
3445
  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3446
 
3447
(define_insn "zero_extenddi2"
3448
  [(set (match_operand:DI 0 "register_operand" "=r")
3449
        (zero_extend:DI
3450
         (match_operand:SWI12 1 "nonimmediate_operand" "m")))]
3451
  "TARGET_64BIT"
3452
  "movz{l|x}\t{%1, %k0|%k0, %1}"
3453
  [(set_attr "type" "imovx")
3454
   (set_attr "mode" "SI")])
3455
 
3456
(define_expand "zero_extendhisi2"
3457
  [(set (match_operand:SI 0 "register_operand" "")
3458
        (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3459
  ""
3460
{
3461
  if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3462
    {
3463
      operands[1] = force_reg (HImode, operands[1]);
3464
      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3465
      DONE;
3466
    }
3467
})
3468
 
3469
(define_insn_and_split "zero_extendhisi2_and"
3470
  [(set (match_operand:SI 0 "register_operand" "=r")
3471
        (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3472
   (clobber (reg:CC FLAGS_REG))]
3473
  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3474
  "#"
3475
  "&& reload_completed"
3476
  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3477
              (clobber (reg:CC FLAGS_REG))])]
3478
  ""
3479
  [(set_attr "type" "alu1")
3480
   (set_attr "mode" "SI")])
3481
 
3482
(define_insn "*zero_extendhisi2_movzwl"
3483
  [(set (match_operand:SI 0 "register_operand" "=r")
3484
        (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3485
  "!TARGET_ZERO_EXTEND_WITH_AND
3486
   || optimize_function_for_size_p (cfun)"
3487
  "movz{wl|x}\t{%1, %0|%0, %1}"
3488
  [(set_attr "type" "imovx")
3489
   (set_attr "mode" "SI")])
3490
 
3491
(define_expand "zero_extendqi2"
3492
  [(parallel
3493
    [(set (match_operand:SWI24 0 "register_operand" "")
3494
          (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3495
     (clobber (reg:CC FLAGS_REG))])])
3496
 
3497
(define_insn "*zero_extendqi2_and"
3498
  [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3499
        (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3500
   (clobber (reg:CC FLAGS_REG))]
3501
  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3502
  "#"
3503
  [(set_attr "type" "alu1")
3504
   (set_attr "mode" "")])
3505
 
3506
;; When source and destination does not overlap, clear destination
3507
;; first and then do the movb
3508
(define_split
3509
  [(set (match_operand:SWI24 0 "register_operand" "")
3510
        (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3511
   (clobber (reg:CC FLAGS_REG))]
3512
  "reload_completed
3513
   && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3514
   && ANY_QI_REG_P (operands[0])
3515
   && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3516
   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3517
  [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3518
{
3519
  operands[2] = gen_lowpart (QImode, operands[0]);
3520
  ix86_expand_clear (operands[0]);
3521
})
3522
 
3523
(define_insn "*zero_extendqi2_movzbl_and"
3524
  [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3525
        (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3526
   (clobber (reg:CC FLAGS_REG))]
3527
  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3528
  "#"
3529
  [(set_attr "type" "imovx,alu1")
3530
   (set_attr "mode" "")])
3531
 
3532
;; For the movzbl case strip only the clobber
3533
(define_split
3534
  [(set (match_operand:SWI24 0 "register_operand" "")
3535
        (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3536
   (clobber (reg:CC FLAGS_REG))]
3537
  "reload_completed
3538
   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3539
   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3540
  [(set (match_dup 0)
3541
        (zero_extend:SWI24 (match_dup 1)))])
3542
 
3543
; zero extend to SImode to avoid partial register stalls
3544
(define_insn "*zero_extendqi2_movzbl"
3545
  [(set (match_operand:SWI24 0 "register_operand" "=r")
3546
        (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3547
  "reload_completed
3548
   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3549
  "movz{bl|x}\t{%1, %k0|%k0, %1}"
3550
  [(set_attr "type" "imovx")
3551
   (set_attr "mode" "SI")])
3552
 
3553
;; Rest is handled by single and.
3554
(define_split
3555
  [(set (match_operand:SWI24 0 "register_operand" "")
3556
        (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3557
   (clobber (reg:CC FLAGS_REG))]
3558
  "reload_completed
3559
   && true_regnum (operands[0]) == true_regnum (operands[1])"
3560
  [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3561
              (clobber (reg:CC FLAGS_REG))])])
3562
 
3563
;; Sign extension instructions
3564
 
3565
(define_expand "extendsidi2"
3566
  [(set (match_operand:DI 0 "register_operand" "")
3567
        (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3568
  ""
3569
{
3570
  if (!TARGET_64BIT)
3571
    {
3572
      emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3573
      DONE;
3574
    }
3575
})
3576
 
3577
(define_insn "*extendsidi2_rex64"
3578
  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3579
        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3580
  "TARGET_64BIT"
3581
  "@
3582
   {cltq|cdqe}
3583
   movs{lq|x}\t{%1, %0|%0, %1}"
3584
  [(set_attr "type" "imovx")
3585
   (set_attr "mode" "DI")
3586
   (set_attr "prefix_0f" "0")
3587
   (set_attr "modrm" "0,1")])
3588
 
3589
(define_insn "extendsidi2_1"
3590
  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3591
        (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3592
   (clobber (reg:CC FLAGS_REG))
3593
   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3594
  "!TARGET_64BIT"
3595
  "#")
3596
 
3597
;; Extend to memory case when source register does die.
3598
(define_split
3599
  [(set (match_operand:DI 0 "memory_operand" "")
3600
        (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3601
   (clobber (reg:CC FLAGS_REG))
3602
   (clobber (match_operand:SI 2 "register_operand" ""))]
3603
  "(reload_completed
3604
    && dead_or_set_p (insn, operands[1])
3605
    && !reg_mentioned_p (operands[1], operands[0]))"
3606
  [(set (match_dup 3) (match_dup 1))
3607
   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3608
              (clobber (reg:CC FLAGS_REG))])
3609
   (set (match_dup 4) (match_dup 1))]
3610
  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3611
 
3612
;; Extend to memory case when source register does not die.
3613
(define_split
3614
  [(set (match_operand:DI 0 "memory_operand" "")
3615
        (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3616
   (clobber (reg:CC FLAGS_REG))
3617
   (clobber (match_operand:SI 2 "register_operand" ""))]
3618
  "reload_completed"
3619
  [(const_int 0)]
3620
{
3621
  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3622
 
3623
  emit_move_insn (operands[3], operands[1]);
3624
 
3625
  /* Generate a cltd if possible and doing so it profitable.  */
3626
  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3627
      && true_regnum (operands[1]) == AX_REG
3628
      && true_regnum (operands[2]) == DX_REG)
3629
    {
3630
      emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3631
    }
3632
  else
3633
    {
3634
      emit_move_insn (operands[2], operands[1]);
3635
      emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3636
    }
3637
  emit_move_insn (operands[4], operands[2]);
3638
  DONE;
3639
})
3640
 
3641
;; Extend to register case.  Optimize case where source and destination
3642
;; registers match and cases where we can use cltd.
3643
(define_split
3644
  [(set (match_operand:DI 0 "register_operand" "")
3645
        (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3646
   (clobber (reg:CC FLAGS_REG))
3647
   (clobber (match_scratch:SI 2 ""))]
3648
  "reload_completed"
3649
  [(const_int 0)]
3650
{
3651
  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3652
 
3653
  if (true_regnum (operands[3]) != true_regnum (operands[1]))
3654
    emit_move_insn (operands[3], operands[1]);
3655
 
3656
  /* Generate a cltd if possible and doing so it profitable.  */
3657
  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3658
      && true_regnum (operands[3]) == AX_REG
3659
      && true_regnum (operands[4]) == DX_REG)
3660
    {
3661
      emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3662
      DONE;
3663
    }
3664
 
3665
  if (true_regnum (operands[4]) != true_regnum (operands[1]))
3666
    emit_move_insn (operands[4], operands[1]);
3667
 
3668
  emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3669
  DONE;
3670
})
3671
 
3672
(define_insn "extenddi2"
3673
  [(set (match_operand:DI 0 "register_operand" "=r")
3674
        (sign_extend:DI
3675
         (match_operand:SWI12 1 "nonimmediate_operand" "m")))]
3676
  "TARGET_64BIT"
3677
  "movs{q|x}\t{%1, %0|%0, %1}"
3678
  [(set_attr "type" "imovx")
3679
   (set_attr "mode" "DI")])
3680
 
3681
(define_insn "extendhisi2"
3682
  [(set (match_operand:SI 0 "register_operand" "=*a,r")
3683
        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3684
  ""
3685
{
3686
  switch (get_attr_prefix_0f (insn))
3687
    {
3688
    case 0:
3689
      return "{cwtl|cwde}";
3690
    default:
3691
      return "movs{wl|x}\t{%1, %0|%0, %1}";
3692
    }
3693
}
3694
  [(set_attr "type" "imovx")
3695
   (set_attr "mode" "SI")
3696
   (set (attr "prefix_0f")
3697
     ;; movsx is short decodable while cwtl is vector decoded.
3698
     (if_then_else (and (eq_attr "cpu" "!k6")
3699
                        (eq_attr "alternative" "0"))
3700
        (const_string "0")
3701
        (const_string "1")))
3702
   (set (attr "modrm")
3703
     (if_then_else (eq_attr "prefix_0f" "0")
3704
        (const_string "0")
3705
        (const_string "1")))])
3706
 
3707
(define_insn "*extendhisi2_zext"
3708
  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3709
        (zero_extend:DI
3710
         (sign_extend:SI
3711
          (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3712
  "TARGET_64BIT"
3713
{
3714
  switch (get_attr_prefix_0f (insn))
3715
    {
3716
    case 0:
3717
      return "{cwtl|cwde}";
3718
    default:
3719
      return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3720
    }
3721
}
3722
  [(set_attr "type" "imovx")
3723
   (set_attr "mode" "SI")
3724
   (set (attr "prefix_0f")
3725
     ;; movsx is short decodable while cwtl is vector decoded.
3726
     (if_then_else (and (eq_attr "cpu" "!k6")
3727
                        (eq_attr "alternative" "0"))
3728
        (const_string "0")
3729
        (const_string "1")))
3730
   (set (attr "modrm")
3731
     (if_then_else (eq_attr "prefix_0f" "0")
3732
        (const_string "0")
3733
        (const_string "1")))])
3734
 
3735
(define_insn "extendqisi2"
3736
  [(set (match_operand:SI 0 "register_operand" "=r")
3737
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3738
  ""
3739
  "movs{bl|x}\t{%1, %0|%0, %1}"
3740
   [(set_attr "type" "imovx")
3741
    (set_attr "mode" "SI")])
3742
 
3743
(define_insn "*extendqisi2_zext"
3744
  [(set (match_operand:DI 0 "register_operand" "=r")
3745
        (zero_extend:DI
3746
          (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3747
  "TARGET_64BIT"
3748
  "movs{bl|x}\t{%1, %k0|%k0, %1}"
3749
   [(set_attr "type" "imovx")
3750
    (set_attr "mode" "SI")])
3751
 
3752
(define_insn "extendqihi2"
3753
  [(set (match_operand:HI 0 "register_operand" "=*a,r")
3754
        (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3755
  ""
3756
{
3757
  switch (get_attr_prefix_0f (insn))
3758
    {
3759
    case 0:
3760
      return "{cbtw|cbw}";
3761
    default:
3762
      return "movs{bw|x}\t{%1, %0|%0, %1}";
3763
    }
3764
}
3765
  [(set_attr "type" "imovx")
3766
   (set_attr "mode" "HI")
3767
   (set (attr "prefix_0f")
3768
     ;; movsx is short decodable while cwtl is vector decoded.
3769
     (if_then_else (and (eq_attr "cpu" "!k6")
3770
                        (eq_attr "alternative" "0"))
3771
        (const_string "0")
3772
        (const_string "1")))
3773
   (set (attr "modrm")
3774
     (if_then_else (eq_attr "prefix_0f" "0")
3775
        (const_string "0")
3776
        (const_string "1")))])
3777
 
3778
;; Conversions between float and double.
3779
 
3780
;; These are all no-ops in the model used for the 80387.
3781
;; So just emit moves.
3782
 
3783
;; %%% Kill these when call knows how to work out a DFmode push earlier.
3784
(define_split
3785
  [(set (match_operand:DF 0 "push_operand" "")
3786
        (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3787
  "reload_completed"
3788
  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3789
   (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3790
 
3791
(define_split
3792
  [(set (match_operand:XF 0 "push_operand" "")
3793
        (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3794
  "reload_completed"
3795
  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3796
   (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3797
  "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3798
 
3799
(define_expand "extendsfdf2"
3800
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3801
        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3802
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3803
{
3804
  /* ??? Needed for compress_float_constant since all fp constants
3805
     are TARGET_LEGITIMATE_CONSTANT_P.  */
3806
  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3807
    {
3808
      if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3809
          && standard_80387_constant_p (operands[1]) > 0)
3810
        {
3811
          operands[1] = simplify_const_unary_operation
3812
            (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3813
          emit_move_insn_1 (operands[0], operands[1]);
3814
          DONE;
3815
        }
3816
      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3817
    }
3818
})
3819
 
3820
/* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3821
   cvtss2sd:
3822
      unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3823
      cvtps2pd xmm2,xmm1
3824
   We do the conversion post reload to avoid producing of 128bit spills
3825
   that might lead to ICE on 32bit target.  The sequence unlikely combine
3826
   anyway.  */
3827
(define_split
3828
  [(set (match_operand:DF 0 "register_operand" "")
3829
        (float_extend:DF
3830
          (match_operand:SF 1 "nonimmediate_operand" "")))]
3831
  "TARGET_USE_VECTOR_FP_CONVERTS
3832
   && optimize_insn_for_speed_p ()
3833
   && reload_completed && SSE_REG_P (operands[0])"
3834
   [(set (match_dup 2)
3835
         (float_extend:V2DF
3836
           (vec_select:V2SF
3837
             (match_dup 3)
3838
             (parallel [(const_int 0) (const_int 1)]))))]
3839
{
3840
  operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3841
  operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3842
  /* Use movss for loading from memory, unpcklps reg, reg for registers.
3843
     Try to avoid move when unpacking can be done in source.  */
3844
  if (REG_P (operands[1]))
3845
    {
3846
      /* If it is unsafe to overwrite upper half of source, we need
3847
         to move to destination and unpack there.  */
3848
      if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3849
           || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3850
          && true_regnum (operands[0]) != true_regnum (operands[1]))
3851
        {
3852
          rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3853
          emit_move_insn (tmp, operands[1]);
3854
        }
3855
      else
3856
        operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3857
      emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3858
                                             operands[3]));
3859
    }
3860
  else
3861
    emit_insn (gen_vec_setv4sf_0 (operands[3],
3862
                                  CONST0_RTX (V4SFmode), operands[1]));
3863
})
3864
 
3865
(define_insn "*extendsfdf2_mixed"
3866
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3867
        (float_extend:DF
3868
          (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3869
  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3870
{
3871
  switch (which_alternative)
3872
    {
3873
    case 0:
3874
    case 1:
3875
      return output_387_reg_move (insn, operands);
3876
 
3877
    case 2:
3878
      return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3879
 
3880
    default:
3881
      gcc_unreachable ();
3882
    }
3883
}
3884
  [(set_attr "type" "fmov,fmov,ssecvt")
3885
   (set_attr "prefix" "orig,orig,maybe_vex")
3886
   (set_attr "mode" "SF,XF,DF")])
3887
 
3888
(define_insn "*extendsfdf2_sse"
3889
  [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3890
        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3891
  "TARGET_SSE2 && TARGET_SSE_MATH"
3892
  "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3893
  [(set_attr "type" "ssecvt")
3894
   (set_attr "prefix" "maybe_vex")
3895
   (set_attr "mode" "DF")])
3896
 
3897
(define_insn "*extendsfdf2_i387"
3898
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3899
        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3900
  "TARGET_80387"
3901
  "* return output_387_reg_move (insn, operands);"
3902
  [(set_attr "type" "fmov")
3903
   (set_attr "mode" "SF,XF")])
3904
 
3905
(define_expand "extendxf2"
3906
  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3907
        (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3908
  "TARGET_80387"
3909
{
3910
  /* ??? Needed for compress_float_constant since all fp constants
3911
     are TARGET_LEGITIMATE_CONSTANT_P.  */
3912
  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3913
    {
3914
      if (standard_80387_constant_p (operands[1]) > 0)
3915
        {
3916
          operands[1] = simplify_const_unary_operation
3917
            (FLOAT_EXTEND, XFmode, operands[1], mode);
3918
          emit_move_insn_1 (operands[0], operands[1]);
3919
          DONE;
3920
        }
3921
      operands[1] = validize_mem (force_const_mem (mode, operands[1]));
3922
    }
3923
})
3924
 
3925
(define_insn "*extendxf2_i387"
3926
  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3927
        (float_extend:XF
3928
          (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3929
  "TARGET_80387"
3930
  "* return output_387_reg_move (insn, operands);"
3931
  [(set_attr "type" "fmov")
3932
   (set_attr "mode" ",XF")])
3933
 
3934
;; %%% This seems bad bad news.
3935
;; This cannot output into an f-reg because there is no way to be sure
3936
;; of truncating in that case.  Otherwise this is just like a simple move
3937
;; insn.  So we pretend we can output to a reg in order to get better
3938
;; register preferencing, but we really use a stack slot.
3939
 
3940
;; Conversion from DFmode to SFmode.
3941
 
3942
(define_expand "truncdfsf2"
3943
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
3944
        (float_truncate:SF
3945
          (match_operand:DF 1 "nonimmediate_operand" "")))]
3946
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3947
{
3948
  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3949
    ;
3950
  else if (flag_unsafe_math_optimizations)
3951
    ;
3952
  else
3953
    {
3954
      enum ix86_stack_slot slot = (virtuals_instantiated
3955
                                   ? SLOT_TEMP
3956
                                   : SLOT_VIRTUAL);
3957
      rtx temp = assign_386_stack_local (SFmode, slot);
3958
      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3959
      DONE;
3960
    }
3961
})
3962
 
3963
/* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3964
   cvtsd2ss:
3965
      unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3966
      cvtpd2ps xmm2,xmm1
3967
   We do the conversion post reload to avoid producing of 128bit spills
3968
   that might lead to ICE on 32bit target.  The sequence unlikely combine
3969
   anyway.  */
3970
(define_split
3971
  [(set (match_operand:SF 0 "register_operand" "")
3972
        (float_truncate:SF
3973
          (match_operand:DF 1 "nonimmediate_operand" "")))]
3974
  "TARGET_USE_VECTOR_FP_CONVERTS
3975
   && optimize_insn_for_speed_p ()
3976
   && reload_completed && SSE_REG_P (operands[0])"
3977
   [(set (match_dup 2)
3978
         (vec_concat:V4SF
3979
           (float_truncate:V2SF
3980
             (match_dup 4))
3981
           (match_dup 3)))]
3982
{
3983
  operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3984
  operands[3] = CONST0_RTX (V2SFmode);
3985
  operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3986
  /* Use movsd for loading from memory, unpcklpd for registers.
3987
     Try to avoid move when unpacking can be done in source, or SSE3
3988
     movddup is available.  */
3989
  if (REG_P (operands[1]))
3990
    {
3991
      if (!TARGET_SSE3
3992
          && true_regnum (operands[0]) != true_regnum (operands[1])
3993
          && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3994
              || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3995
        {
3996
          rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3997
          emit_move_insn (tmp, operands[1]);
3998
          operands[1] = tmp;
3999
        }
4000
      else if (!TARGET_SSE3)
4001
        operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4002
      emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4003
    }
4004
  else
4005
    emit_insn (gen_sse2_loadlpd (operands[4],
4006
                                 CONST0_RTX (V2DFmode), operands[1]));
4007
})
4008
 
4009
(define_expand "truncdfsf2_with_temp"
4010
  [(parallel [(set (match_operand:SF 0 "" "")
4011
                   (float_truncate:SF (match_operand:DF 1 "" "")))
4012
              (clobber (match_operand:SF 2 "" ""))])])
4013
 
4014
(define_insn "*truncdfsf_fast_mixed"
4015
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4016
        (float_truncate:SF
4017
          (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4018
  "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4019
{
4020
  switch (which_alternative)
4021
    {
4022
    case 0:
4023
      return output_387_reg_move (insn, operands);
4024
    case 1:
4025
      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4026
    default:
4027
      gcc_unreachable ();
4028
    }
4029
}
4030
  [(set_attr "type" "fmov,ssecvt")
4031
   (set_attr "prefix" "orig,maybe_vex")
4032
   (set_attr "mode" "SF")])
4033
 
4034
;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4035
;; because nothing we do here is unsafe.
4036
(define_insn "*truncdfsf_fast_sse"
4037
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4038
        (float_truncate:SF
4039
          (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4040
  "TARGET_SSE2 && TARGET_SSE_MATH"
4041
  "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4042
  [(set_attr "type" "ssecvt")
4043
   (set_attr "prefix" "maybe_vex")
4044
   (set_attr "mode" "SF")])
4045
 
4046
(define_insn "*truncdfsf_fast_i387"
4047
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4048
        (float_truncate:SF
4049
          (match_operand:DF 1 "nonimmediate_operand" "f")))]
4050
  "TARGET_80387 && flag_unsafe_math_optimizations"
4051
  "* return output_387_reg_move (insn, operands);"
4052
  [(set_attr "type" "fmov")
4053
   (set_attr "mode" "SF")])
4054
 
4055
(define_insn "*truncdfsf_mixed"
4056
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4057
        (float_truncate:SF
4058
          (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4059
   (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4060
  "TARGET_MIX_SSE_I387"
4061
{
4062
  switch (which_alternative)
4063
    {
4064
    case 0:
4065
      return output_387_reg_move (insn, operands);
4066
    case 1:
4067
      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4068
 
4069
    default:
4070
      return "#";
4071
    }
4072
}
4073
  [(set_attr "isa" "*,sse2,*,*,*")
4074
   (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075
   (set_attr "unit" "*,*,i387,i387,i387")
4076
   (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077
   (set_attr "mode" "SF")])
4078
 
4079
(define_insn "*truncdfsf_i387"
4080
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4081
        (float_truncate:SF
4082
          (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083
   (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4084
  "TARGET_80387"
4085
{
4086
  switch (which_alternative)
4087
    {
4088
    case 0:
4089
      return output_387_reg_move (insn, operands);
4090
 
4091
    default:
4092
      return "#";
4093
    }
4094
}
4095
  [(set_attr "type" "fmov,multi,multi,multi")
4096
   (set_attr "unit" "*,i387,i387,i387")
4097
   (set_attr "mode" "SF")])
4098
 
4099
(define_insn "*truncdfsf2_i387_1"
4100
  [(set (match_operand:SF 0 "memory_operand" "=m")
4101
        (float_truncate:SF
4102
          (match_operand:DF 1 "register_operand" "f")))]
4103
  "TARGET_80387
4104
   && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105
   && !TARGET_MIX_SSE_I387"
4106
  "* return output_387_reg_move (insn, operands);"
4107
  [(set_attr "type" "fmov")
4108
   (set_attr "mode" "SF")])
4109
 
4110
(define_split
4111
  [(set (match_operand:SF 0 "register_operand" "")
4112
        (float_truncate:SF
4113
         (match_operand:DF 1 "fp_register_operand" "")))
4114
   (clobber (match_operand 2 "" ""))]
4115
  "reload_completed"
4116
  [(set (match_dup 2) (match_dup 1))
4117
   (set (match_dup 0) (match_dup 2))]
4118
  "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4119
 
4120
;; Conversion from XFmode to {SF,DF}mode
4121
 
4122
(define_expand "truncxf2"
4123
  [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4124
                   (float_truncate:MODEF
4125
                     (match_operand:XF 1 "register_operand" "")))
4126
              (clobber (match_dup 2))])]
4127
  "TARGET_80387"
4128
{
4129
  if (flag_unsafe_math_optimizations)
4130
    {
4131
      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (mode);
4132
      emit_insn (gen_truncxf2_i387_noop (reg, operands[1]));
4133
      if (reg != operands[0])
4134
        emit_move_insn (operands[0], reg);
4135
      DONE;
4136
    }
4137
  else
4138
    {
4139
      enum ix86_stack_slot slot = (virtuals_instantiated
4140
                                   ? SLOT_TEMP
4141
                                   : SLOT_VIRTUAL);
4142
      operands[2] = assign_386_stack_local (mode, slot);
4143
    }
4144
})
4145
 
4146
(define_insn "*truncxfsf2_mixed"
4147
  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4148
        (float_truncate:SF
4149
          (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4150
   (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4151
  "TARGET_80387"
4152
{
4153
  gcc_assert (!which_alternative);
4154
  return output_387_reg_move (insn, operands);
4155
}
4156
  [(set_attr "type" "fmov,multi,multi,multi")
4157
   (set_attr "unit" "*,i387,i387,i387")
4158
   (set_attr "mode" "SF")])
4159
 
4160
(define_insn "*truncxfdf2_mixed"
4161
  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4162
        (float_truncate:DF
4163
          (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4164
   (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4165
  "TARGET_80387"
4166
{
4167
  gcc_assert (!which_alternative);
4168
  return output_387_reg_move (insn, operands);
4169
}
4170
  [(set_attr "isa" "*,*,sse2,*")
4171
   (set_attr "type" "fmov,multi,multi,multi")
4172
   (set_attr "unit" "*,i387,i387,i387")
4173
   (set_attr "mode" "DF")])
4174
 
4175
(define_insn "truncxf2_i387_noop"
4176
  [(set (match_operand:MODEF 0 "register_operand" "=f")
4177
        (float_truncate:MODEF
4178
          (match_operand:XF 1 "register_operand" "f")))]
4179
  "TARGET_80387 && flag_unsafe_math_optimizations"
4180
  "* return output_387_reg_move (insn, operands);"
4181
  [(set_attr "type" "fmov")
4182
   (set_attr "mode" "")])
4183
 
4184
(define_insn "*truncxf2_i387"
4185
  [(set (match_operand:MODEF 0 "memory_operand" "=m")
4186
        (float_truncate:MODEF
4187
          (match_operand:XF 1 "register_operand" "f")))]
4188
  "TARGET_80387"
4189
  "* return output_387_reg_move (insn, operands);"
4190
  [(set_attr "type" "fmov")
4191
   (set_attr "mode" "")])
4192
 
4193
(define_split
4194
  [(set (match_operand:MODEF 0 "register_operand" "")
4195
        (float_truncate:MODEF
4196
          (match_operand:XF 1 "register_operand" "")))
4197
   (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4198
  "TARGET_80387 && reload_completed"
4199
  [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4200
   (set (match_dup 0) (match_dup 2))])
4201
 
4202
(define_split
4203
  [(set (match_operand:MODEF 0 "memory_operand" "")
4204
        (float_truncate:MODEF
4205
          (match_operand:XF 1 "register_operand" "")))
4206
   (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4207
  "TARGET_80387"
4208
  [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4209
 
4210
;; Signed conversion to DImode.
4211
 
4212
(define_expand "fix_truncxfdi2"
4213
  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4214
                   (fix:DI (match_operand:XF 1 "register_operand" "")))
4215
              (clobber (reg:CC FLAGS_REG))])]
4216
  "TARGET_80387"
4217
{
4218
  if (TARGET_FISTTP)
4219
   {
4220
     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4221
     DONE;
4222
   }
4223
})
4224
 
4225
(define_expand "fix_truncdi2"
4226
  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4227
                   (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4228
              (clobber (reg:CC FLAGS_REG))])]
4229
  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (mode))"
4230
{
4231
  if (TARGET_FISTTP
4232
      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))
4233
   {
4234
     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4235
     DONE;
4236
   }
4237
  if (TARGET_64BIT && SSE_FLOAT_MODE_P (mode))
4238
   {
4239
     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4240
     emit_insn (gen_fix_truncdi_sse (out, operands[1]));
4241
     if (out != operands[0])
4242
        emit_move_insn (operands[0], out);
4243
     DONE;
4244
   }
4245
})
4246
 
4247
;; Signed conversion to SImode.
4248
 
4249
(define_expand "fix_truncxfsi2"
4250
  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4251
                   (fix:SI (match_operand:XF 1 "register_operand" "")))
4252
              (clobber (reg:CC FLAGS_REG))])]
4253
  "TARGET_80387"
4254
{
4255
  if (TARGET_FISTTP)
4256
   {
4257
     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4258
     DONE;
4259
   }
4260
})
4261
 
4262
(define_expand "fix_truncsi2"
4263
  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4264
                   (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4265
              (clobber (reg:CC FLAGS_REG))])]
4266
  "TARGET_80387 || SSE_FLOAT_MODE_P (mode)"
4267
{
4268
  if (TARGET_FISTTP
4269
      && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))
4270
   {
4271
     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4272
     DONE;
4273
   }
4274
  if (SSE_FLOAT_MODE_P (mode))
4275
   {
4276
     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4277
     emit_insn (gen_fix_truncsi_sse (out, operands[1]));
4278
     if (out != operands[0])
4279
        emit_move_insn (operands[0], out);
4280
     DONE;
4281
   }
4282
})
4283
 
4284
;; Signed conversion to HImode.
4285
 
4286
(define_expand "fix_trunchi2"
4287
  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4288
                   (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4289
              (clobber (reg:CC FLAGS_REG))])]
4290
  "TARGET_80387
4291
   && !(SSE_FLOAT_MODE_P (mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4292
{
4293
  if (TARGET_FISTTP)
4294
   {
4295
     emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4296
     DONE;
4297
   }
4298
})
4299
 
4300
;; Unsigned conversion to SImode.
4301
 
4302
(define_expand "fixuns_truncsi2"
4303
  [(parallel
4304
    [(set (match_operand:SI 0 "register_operand" "")
4305
          (unsigned_fix:SI
4306
            (match_operand:MODEF 1 "nonimmediate_operand" "")))
4307
     (use (match_dup 2))
4308
     (clobber (match_scratch: 3 ""))
4309
     (clobber (match_scratch: 4 ""))])]
4310
  "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4311
{
4312
  enum machine_mode mode = mode;
4313
  enum machine_mode vecmode = mode;
4314
  REAL_VALUE_TYPE TWO31r;
4315
  rtx two31;
4316
 
4317
  if (optimize_insn_for_size_p ())
4318
    FAIL;
4319
 
4320
  real_ldexp (&TWO31r, &dconst1, 31);
4321
  two31 = const_double_from_real_value (TWO31r, mode);
4322
  two31 = ix86_build_const_vector (vecmode, true, two31);
4323
  operands[2] = force_reg (vecmode, two31);
4324
})
4325
 
4326
(define_insn_and_split "*fixuns_trunc_1"
4327
  [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4328
        (unsigned_fix:SI
4329
          (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4330
   (use (match_operand: 4  "nonimmediate_operand" "m,x"))
4331
   (clobber (match_scratch: 1 "=x,&x"))
4332
   (clobber (match_scratch: 2 "=x,x"))]
4333
  "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4334
   && optimize_function_for_speed_p (cfun)"
4335
  "#"
4336
  "&& reload_completed"
4337
  [(const_int 0)]
4338
{
4339
  ix86_split_convert_uns_si_sse (operands);
4340
  DONE;
4341
})
4342
 
4343
;; Unsigned conversion to HImode.
4344
;; Without these patterns, we'll try the unsigned SI conversion which
4345
;; is complex for SSE, rather than the signed SI conversion, which isn't.
4346
 
4347
(define_expand "fixuns_trunchi2"
4348
  [(set (match_dup 2)
4349
        (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4350
   (set (match_operand:HI 0 "nonimmediate_operand" "")
4351
        (subreg:HI (match_dup 2) 0))]
4352
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
4353
  "operands[2] = gen_reg_rtx (SImode);")
4354
 
4355
;; When SSE is available, it is always faster to use it!
4356
(define_insn "fix_truncdi_sse"
4357
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4358
        (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4359
  "TARGET_64BIT && SSE_FLOAT_MODE_P (mode)
4360
   && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4361
  "%vcvtt2si{q}\t{%1, %0|%0, %1}"
4362
  [(set_attr "type" "sseicvt")
4363
   (set_attr "prefix" "maybe_vex")
4364
   (set_attr "prefix_rex" "1")
4365
   (set_attr "mode" "")
4366
   (set_attr "athlon_decode" "double,vector")
4367
   (set_attr "amdfam10_decode" "double,double")
4368
   (set_attr "bdver1_decode" "double,double")])
4369
 
4370
(define_insn "fix_truncsi_sse"
4371
  [(set (match_operand:SI 0 "register_operand" "=r,r")
4372
        (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4373
  "SSE_FLOAT_MODE_P (mode)
4374
   && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4375
  "%vcvtt2si\t{%1, %0|%0, %1}"
4376
  [(set_attr "type" "sseicvt")
4377
   (set_attr "prefix" "maybe_vex")
4378
   (set_attr "mode" "")
4379
   (set_attr "athlon_decode" "double,vector")
4380
   (set_attr "amdfam10_decode" "double,double")
4381
   (set_attr "bdver1_decode" "double,double")])
4382
 
4383
;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4384
(define_peephole2
4385
  [(set (match_operand:MODEF 0 "register_operand" "")
4386
        (match_operand:MODEF 1 "memory_operand" ""))
4387
   (set (match_operand:SWI48x 2 "register_operand" "")
4388
        (fix:SWI48x (match_dup 0)))]
4389
  "TARGET_SHORTEN_X87_SSE
4390
   && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4391
   && peep2_reg_dead_p (2, operands[0])"
4392
  [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4393
 
4394
;; Avoid vector decoded forms of the instruction.
4395
(define_peephole2
4396
  [(match_scratch:DF 2 "x")
4397
   (set (match_operand:SWI48x 0 "register_operand" "")
4398
        (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4399
  "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4400
  [(set (match_dup 2) (match_dup 1))
4401
   (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4402
 
4403
(define_peephole2
4404
  [(match_scratch:SF 2 "x")
4405
   (set (match_operand:SWI48x 0 "register_operand" "")
4406
        (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4407
  "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4408
  [(set (match_dup 2) (match_dup 1))
4409
   (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4410
 
4411
(define_insn_and_split "fix_trunc_fisttp_i387_1"
4412
  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4413
        (fix:SWI248x (match_operand 1 "register_operand" "")))]
4414
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4415
   && TARGET_FISTTP
4416
   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4417
         && (TARGET_64BIT || mode != DImode))
4418
        && TARGET_SSE_MATH)
4419
   && can_create_pseudo_p ()"
4420
  "#"
4421
  "&& 1"
4422
  [(const_int 0)]
4423
{
4424
  if (memory_operand (operands[0], VOIDmode))
4425
    emit_insn (gen_fix_trunc_i387_fisttp (operands[0], operands[1]));
4426
  else
4427
    {
4428
      operands[2] = assign_386_stack_local (mode, SLOT_TEMP);
4429
      emit_insn (gen_fix_trunc_i387_fisttp_with_temp (operands[0],
4430
                                                            operands[1],
4431
                                                            operands[2]));
4432
    }
4433
  DONE;
4434
}
4435
  [(set_attr "type" "fisttp")
4436
   (set_attr "mode" "")])
4437
 
4438
(define_insn "fix_trunc_i387_fisttp"
4439
  [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4440
        (fix:SWI248x (match_operand 1 "register_operand" "f")))
4441
   (clobber (match_scratch:XF 2 "=&1f"))]
4442
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4443
   && TARGET_FISTTP
4444
   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4445
         && (TARGET_64BIT || mode != DImode))
4446
        && TARGET_SSE_MATH)"
4447
  "* return output_fix_trunc (insn, operands, true);"
4448
  [(set_attr "type" "fisttp")
4449
   (set_attr "mode" "")])
4450
 
4451
(define_insn "fix_trunc_i387_fisttp_with_temp"
4452
  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4453
        (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4454
   (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4455
   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4456
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4457
   && TARGET_FISTTP
4458
   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4459
        && (TARGET_64BIT || mode != DImode))
4460
        && TARGET_SSE_MATH)"
4461
  "#"
4462
  [(set_attr "type" "fisttp")
4463
   (set_attr "mode" "")])
4464
 
4465
(define_split
4466
  [(set (match_operand:SWI248x 0 "register_operand" "")
4467
        (fix:SWI248x (match_operand 1 "register_operand" "")))
4468
   (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4469
   (clobber (match_scratch 3 ""))]
4470
  "reload_completed"
4471
  [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4472
              (clobber (match_dup 3))])
4473
   (set (match_dup 0) (match_dup 2))])
4474
 
4475
(define_split
4476
  [(set (match_operand:SWI248x 0 "memory_operand" "")
4477
        (fix:SWI248x (match_operand 1 "register_operand" "")))
4478
   (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4479
   (clobber (match_scratch 3 ""))]
4480
  "reload_completed"
4481
  [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4482
              (clobber (match_dup 3))])])
4483
 
4484
;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4485
;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4486
;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4487
;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4488
;; function in i386.c.
4489
(define_insn_and_split "*fix_trunc_i387_1"
4490
  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4491
        (fix:SWI248x (match_operand 1 "register_operand" "")))
4492
   (clobber (reg:CC FLAGS_REG))]
4493
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4494
   && !TARGET_FISTTP
4495
   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4496
         && (TARGET_64BIT || mode != DImode))
4497
   && can_create_pseudo_p ()"
4498
  "#"
4499
  "&& 1"
4500
  [(const_int 0)]
4501
{
4502
  ix86_optimize_mode_switching[I387_TRUNC] = 1;
4503
 
4504
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4505
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4506
  if (memory_operand (operands[0], VOIDmode))
4507
    emit_insn (gen_fix_trunc_i387 (operands[0], operands[1],
4508
                                         operands[2], operands[3]));
4509
  else
4510
    {
4511
      operands[4] = assign_386_stack_local (mode, SLOT_TEMP);
4512
      emit_insn (gen_fix_trunc_i387_with_temp (operands[0], operands[1],
4513
                                                     operands[2], operands[3],
4514
                                                     operands[4]));
4515
    }
4516
  DONE;
4517
}
4518
  [(set_attr "type" "fistp")
4519
   (set_attr "i387_cw" "trunc")
4520
   (set_attr "mode" "")])
4521
 
4522
(define_insn "fix_truncdi_i387"
4523
  [(set (match_operand:DI 0 "memory_operand" "=m")
4524
        (fix:DI (match_operand 1 "register_operand" "f")))
4525
   (use (match_operand:HI 2 "memory_operand" "m"))
4526
   (use (match_operand:HI 3 "memory_operand" "m"))
4527
   (clobber (match_scratch:XF 4 "=&1f"))]
4528
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529
   && !TARGET_FISTTP
4530
   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4531
  "* return output_fix_trunc (insn, operands, false);"
4532
  [(set_attr "type" "fistp")
4533
   (set_attr "i387_cw" "trunc")
4534
   (set_attr "mode" "DI")])
4535
 
4536
(define_insn "fix_truncdi_i387_with_temp"
4537
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4538
        (fix:DI (match_operand 1 "register_operand" "f,f")))
4539
   (use (match_operand:HI 2 "memory_operand" "m,m"))
4540
   (use (match_operand:HI 3 "memory_operand" "m,m"))
4541
   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4542
   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4543
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4544
   && !TARGET_FISTTP
4545
   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4546
  "#"
4547
  [(set_attr "type" "fistp")
4548
   (set_attr "i387_cw" "trunc")
4549
   (set_attr "mode" "DI")])
4550
 
4551
(define_split
4552
  [(set (match_operand:DI 0 "register_operand" "")
4553
        (fix:DI (match_operand 1 "register_operand" "")))
4554
   (use (match_operand:HI 2 "memory_operand" ""))
4555
   (use (match_operand:HI 3 "memory_operand" ""))
4556
   (clobber (match_operand:DI 4 "memory_operand" ""))
4557
   (clobber (match_scratch 5 ""))]
4558
  "reload_completed"
4559
  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4560
              (use (match_dup 2))
4561
              (use (match_dup 3))
4562
              (clobber (match_dup 5))])
4563
   (set (match_dup 0) (match_dup 4))])
4564
 
4565
(define_split
4566
  [(set (match_operand:DI 0 "memory_operand" "")
4567
        (fix:DI (match_operand 1 "register_operand" "")))
4568
   (use (match_operand:HI 2 "memory_operand" ""))
4569
   (use (match_operand:HI 3 "memory_operand" ""))
4570
   (clobber (match_operand:DI 4 "memory_operand" ""))
4571
   (clobber (match_scratch 5 ""))]
4572
  "reload_completed"
4573
  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4574
              (use (match_dup 2))
4575
              (use (match_dup 3))
4576
              (clobber (match_dup 5))])])
4577
 
4578
(define_insn "fix_trunc_i387"
4579
  [(set (match_operand:SWI24 0 "memory_operand" "=m")
4580
        (fix:SWI24 (match_operand 1 "register_operand" "f")))
4581
   (use (match_operand:HI 2 "memory_operand" "m"))
4582
   (use (match_operand:HI 3 "memory_operand" "m"))]
4583
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4584
   && !TARGET_FISTTP
4585
   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4586
  "* return output_fix_trunc (insn, operands, false);"
4587
  [(set_attr "type" "fistp")
4588
   (set_attr "i387_cw" "trunc")
4589
   (set_attr "mode" "")])
4590
 
4591
(define_insn "fix_trunc_i387_with_temp"
4592
  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4593
        (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4594
   (use (match_operand:HI 2 "memory_operand" "m,m"))
4595
   (use (match_operand:HI 3 "memory_operand" "m,m"))
4596
   (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4597
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4598
   && !TARGET_FISTTP
4599
   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4600
  "#"
4601
  [(set_attr "type" "fistp")
4602
   (set_attr "i387_cw" "trunc")
4603
   (set_attr "mode" "")])
4604
 
4605
(define_split
4606
  [(set (match_operand:SWI24 0 "register_operand" "")
4607
        (fix:SWI24 (match_operand 1 "register_operand" "")))
4608
   (use (match_operand:HI 2 "memory_operand" ""))
4609
   (use (match_operand:HI 3 "memory_operand" ""))
4610
   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4611
  "reload_completed"
4612
  [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4613
              (use (match_dup 2))
4614
              (use (match_dup 3))])
4615
   (set (match_dup 0) (match_dup 4))])
4616
 
4617
(define_split
4618
  [(set (match_operand:SWI24 0 "memory_operand" "")
4619
        (fix:SWI24 (match_operand 1 "register_operand" "")))
4620
   (use (match_operand:HI 2 "memory_operand" ""))
4621
   (use (match_operand:HI 3 "memory_operand" ""))
4622
   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4623
  "reload_completed"
4624
  [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4625
              (use (match_dup 2))
4626
              (use (match_dup 3))])])
4627
 
4628
(define_insn "x86_fnstcw_1"
4629
  [(set (match_operand:HI 0 "memory_operand" "=m")
4630
        (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4631
  "TARGET_80387"
4632
  "fnstcw\t%0"
4633
  [(set (attr "length")
4634
        (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4635
   (set_attr "mode" "HI")
4636
   (set_attr "unit" "i387")
4637
   (set_attr "bdver1_decode" "vector")])
4638
 
4639
(define_insn "x86_fldcw_1"
4640
  [(set (reg:HI FPCR_REG)
4641
        (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4642
  "TARGET_80387"
4643
  "fldcw\t%0"
4644
  [(set (attr "length")
4645
        (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4646
   (set_attr "mode" "HI")
4647
   (set_attr "unit" "i387")
4648
   (set_attr "athlon_decode" "vector")
4649
   (set_attr "amdfam10_decode" "vector")
4650
   (set_attr "bdver1_decode" "vector")])
4651
 
4652
;; Conversion between fixed point and floating point.
4653
 
4654
;; Even though we only accept memory inputs, the backend _really_
4655
;; wants to be able to do this between registers.
4656
 
4657
(define_expand "floathi2"
4658
  [(set (match_operand:X87MODEF 0 "register_operand" "")
4659
        (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4660
  "TARGET_80387
4661
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
4662
       || TARGET_MIX_SSE_I387)")
4663
 
4664
;; Pre-reload splitter to add memory clobber to the pattern.
4665
(define_insn_and_split "*floathi2_1"
4666
  [(set (match_operand:X87MODEF 0 "register_operand" "")
4667
        (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4668
  "TARGET_80387
4669
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
4670
       || TARGET_MIX_SSE_I387)
4671
   && can_create_pseudo_p ()"
4672
  "#"
4673
  "&& 1"
4674
  [(parallel [(set (match_dup 0)
4675
              (float:X87MODEF (match_dup 1)))
4676
   (clobber (match_dup 2))])]
4677
  "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4678
 
4679
(define_insn "*floathi2_i387_with_temp"
4680
  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4681
        (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4682
  (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4683
  "TARGET_80387
4684
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
4685
       || TARGET_MIX_SSE_I387)"
4686
  "#"
4687
  [(set_attr "type" "fmov,multi")
4688
   (set_attr "mode" "")
4689
   (set_attr "unit" "*,i387")
4690
   (set_attr "fp_int_src" "true")])
4691
 
4692
(define_insn "*floathi2_i387"
4693
  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4694
        (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4695
  "TARGET_80387
4696
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
4697
       || TARGET_MIX_SSE_I387)"
4698
  "fild%Z1\t%1"
4699
  [(set_attr "type" "fmov")
4700
   (set_attr "mode" "")
4701
   (set_attr "fp_int_src" "true")])
4702
 
4703
(define_split
4704
  [(set (match_operand:X87MODEF 0 "register_operand" "")
4705
        (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4706
   (clobber (match_operand:HI 2 "memory_operand" ""))]
4707
  "TARGET_80387
4708
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
4709
       || TARGET_MIX_SSE_I387)
4710
   && reload_completed"
4711
  [(set (match_dup 2) (match_dup 1))
4712
   (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4713
 
4714
(define_split
4715
  [(set (match_operand:X87MODEF 0 "register_operand" "")
4716
        (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4717
   (clobber (match_operand:HI 2 "memory_operand" ""))]
4718
   "TARGET_80387
4719
    && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
4720
        || TARGET_MIX_SSE_I387)
4721
    && reload_completed"
4722
  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4723
 
4724
(define_expand "float2"
4725
  [(set (match_operand:X87MODEF 0 "register_operand" "")
4726
        (float:X87MODEF
4727
          (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4728
  "TARGET_80387
4729
   || ((mode != DImode || TARGET_64BIT)
4730
       && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
4731
{
4732
  if (!((mode != DImode || TARGET_64BIT)
4733
        && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
4734
      && !X87_ENABLE_FLOAT (mode, mode))
4735
    {
4736
      rtx reg = gen_reg_rtx (XFmode);
4737
      rtx (*insn)(rtx, rtx);
4738
 
4739
      emit_insn (gen_floatxf2 (reg, operands[1]));
4740
 
4741
      if (mode == SFmode)
4742
        insn = gen_truncxfsf2;
4743
      else if (mode == DFmode)
4744
        insn = gen_truncxfdf2;
4745
      else
4746
        gcc_unreachable ();
4747
 
4748
      emit_insn (insn (operands[0], reg));
4749
      DONE;
4750
    }
4751
})
4752
 
4753
;; Pre-reload splitter to add memory clobber to the pattern.
4754
(define_insn_and_split "*float2_1"
4755
  [(set (match_operand:X87MODEF 0 "register_operand" "")
4756
        (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4757
  "((TARGET_80387
4758
     && X87_ENABLE_FLOAT (mode, mode)
4759
     && (!((mode != DImode || TARGET_64BIT)
4760
           && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
4761
         || TARGET_MIX_SSE_I387))
4762
    || ((mode != DImode || TARGET_64BIT)
4763
        && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
4764
        && ((mode == SImode
4765
             && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4766
             && optimize_function_for_speed_p (cfun)
4767
             && flag_trapping_math)
4768
            || !(TARGET_INTER_UNIT_CONVERSIONS
4769
                 || optimize_function_for_size_p (cfun)))))
4770
   && can_create_pseudo_p ()"
4771
  "#"
4772
  "&& 1"
4773
  [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4774
              (clobber (match_dup 2))])]
4775
{
4776
  operands[2] = assign_386_stack_local (mode, SLOT_TEMP);
4777
 
4778
  /* Avoid store forwarding (partial memory) stall penalty
4779
     by passing DImode value through XMM registers.  */
4780
  if (mode == DImode && !TARGET_64BIT
4781
      && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4782
      && optimize_function_for_speed_p (cfun))
4783
    {
4784
      emit_insn (gen_floatdi2_i387_with_xmm (operands[0],
4785
                                                            operands[1],
4786
                                                            operands[2]));
4787
      DONE;
4788
    }
4789
})
4790
 
4791
(define_insn "*floatsi2_vector_mixed_with_temp"
4792
  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4793
        (float:MODEF
4794
          (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4795
   (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4796
  "TARGET_SSE2 && TARGET_MIX_SSE_I387
4797
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4798
  "#"
4799
  [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4800
   (set_attr "mode" ",,,,")
4801
   (set_attr "unit" "*,i387,*,*,*")
4802
   (set_attr "athlon_decode" "*,*,double,direct,double")
4803
   (set_attr "amdfam10_decode" "*,*,vector,double,double")
4804
   (set_attr "bdver1_decode" "*,*,double,direct,double")
4805
   (set_attr "fp_int_src" "true")])
4806
 
4807
(define_insn "*floatsi2_vector_mixed"
4808
  [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4809
        (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4810
  "TARGET_SSE2 && TARGET_MIX_SSE_I387
4811
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4812
  "@
4813
   fild%Z1\t%1
4814
   #"
4815
  [(set_attr "type" "fmov,sseicvt")
4816
   (set_attr "mode" ",")
4817
   (set_attr "unit" "i387,*")
4818
   (set_attr "athlon_decode" "*,direct")
4819
   (set_attr "amdfam10_decode" "*,double")
4820
   (set_attr "bdver1_decode" "*,direct")
4821
   (set_attr "fp_int_src" "true")])
4822
 
4823
(define_insn "*float2_mixed_with_temp"
4824
  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4825
        (float:MODEF
4826
          (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4827
   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4828
  "(mode != DImode || TARGET_64BIT)
4829
   && SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387"
4830
  "#"
4831
  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4832
   (set_attr "mode" "")
4833
   (set_attr "unit" "*,i387,*,*")
4834
   (set_attr "athlon_decode" "*,*,double,direct")
4835
   (set_attr "amdfam10_decode" "*,*,vector,double")
4836
   (set_attr "bdver1_decode" "*,*,double,direct")
4837
   (set_attr "fp_int_src" "true")])
4838
 
4839
(define_split
4840
  [(set (match_operand:MODEF 0 "register_operand" "")
4841
        (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4842
   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4843
  "(mode != DImode || TARGET_64BIT)
4844
   && SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
4845
   && TARGET_INTER_UNIT_CONVERSIONS
4846
   && reload_completed
4847
   && (SSE_REG_P (operands[0])
4848
       || (GET_CODE (operands[0]) == SUBREG
4849
           && SSE_REG_P (SUBREG_REG (operands[0]))))"
4850
  [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4851
 
4852
(define_split
4853
  [(set (match_operand:MODEF 0 "register_operand" "")
4854
        (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4855
   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4856
  "(mode != DImode || TARGET_64BIT)
4857
   && SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
4858
   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4859
   && reload_completed
4860
   && (SSE_REG_P (operands[0])
4861
       || (GET_CODE (operands[0]) == SUBREG
4862
           && SSE_REG_P (SUBREG_REG (operands[0]))))"
4863
  [(set (match_dup 2) (match_dup 1))
4864
   (set (match_dup 0) (float:MODEF (match_dup 2)))])
4865
 
4866
(define_insn "*float2_mixed_interunit"
4867
  [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4868
        (float:MODEF
4869
          (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4870
  "(mode != DImode || TARGET_64BIT)
4871
   && SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
4872
   && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4873
  "@
4874
   fild%Z1\t%1
4875
   %vcvtsi2\t{%1, %d0|%d0, %1}
4876
   %vcvtsi2\t{%1, %d0|%d0, %1}"
4877
  [(set_attr "type" "fmov,sseicvt,sseicvt")
4878
   (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4879
   (set_attr "mode" "")
4880
   (set (attr "prefix_rex")
4881
     (if_then_else
4882
       (and (eq_attr "prefix" "maybe_vex")
4883
            (match_test "mode == DImode"))
4884
       (const_string "1")
4885
       (const_string "*")))
4886
   (set_attr "unit" "i387,*,*")
4887
   (set_attr "athlon_decode" "*,double,direct")
4888
   (set_attr "amdfam10_decode" "*,vector,double")
4889
   (set_attr "bdver1_decode" "*,double,direct")
4890
   (set_attr "fp_int_src" "true")])
4891
 
4892
(define_insn "*float2_mixed_nointerunit"
4893
  [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4894
        (float:MODEF
4895
          (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4896
  "(mode != DImode || TARGET_64BIT)
4897
   && SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
4898
   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4899
  "@
4900
   fild%Z1\t%1
4901
   %vcvtsi2\t{%1, %d0|%d0, %1}"
4902
  [(set_attr "type" "fmov,sseicvt")
4903
   (set_attr "prefix" "orig,maybe_vex")
4904
   (set_attr "mode" "")
4905
   (set (attr "prefix_rex")
4906
     (if_then_else
4907
       (and (eq_attr "prefix" "maybe_vex")
4908
            (match_test "mode == DImode"))
4909
       (const_string "1")
4910
       (const_string "*")))
4911
   (set_attr "athlon_decode" "*,direct")
4912
   (set_attr "amdfam10_decode" "*,double")
4913
   (set_attr "bdver1_decode" "*,direct")
4914
   (set_attr "fp_int_src" "true")])
4915
 
4916
(define_insn "*floatsi2_vector_sse_with_temp"
4917
  [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4918
        (float:MODEF
4919
          (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4920
   (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4921
  "TARGET_SSE2 && TARGET_SSE_MATH
4922
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4923
  "#"
4924
  [(set_attr "type" "sseicvt")
4925
   (set_attr "mode" ",,")
4926
   (set_attr "athlon_decode" "double,direct,double")
4927
   (set_attr "amdfam10_decode" "vector,double,double")
4928
   (set_attr "bdver1_decode" "double,direct,double")
4929
   (set_attr "fp_int_src" "true")])
4930
 
4931
(define_insn "*floatsi2_vector_sse"
4932
  [(set (match_operand:MODEF 0 "register_operand" "=x")
4933
        (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4934
  "TARGET_SSE2 && TARGET_SSE_MATH
4935
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4936
  "#"
4937
  [(set_attr "type" "sseicvt")
4938
   (set_attr "mode" "")
4939
   (set_attr "athlon_decode" "direct")
4940
   (set_attr "amdfam10_decode" "double")
4941
   (set_attr "bdver1_decode" "direct")
4942
   (set_attr "fp_int_src" "true")])
4943
 
4944
(define_split
4945
  [(set (match_operand:MODEF 0 "register_operand" "")
4946
        (float:MODEF (match_operand:SI 1 "register_operand" "")))
4947
   (clobber (match_operand:SI 2 "memory_operand" ""))]
4948
  "TARGET_SSE2 && TARGET_SSE_MATH
4949
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4950
   && reload_completed
4951
   && (SSE_REG_P (operands[0])
4952
       || (GET_CODE (operands[0]) == SUBREG
4953
           && SSE_REG_P (SUBREG_REG (operands[0]))))"
4954
  [(const_int 0)]
4955
{
4956
  rtx op1 = operands[1];
4957
 
4958
  operands[3] = simplify_gen_subreg (mode, operands[0],
4959
                                     mode, 0);
4960
  if (GET_CODE (op1) == SUBREG)
4961
    op1 = SUBREG_REG (op1);
4962
 
4963
  if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4964
    {
4965
      operands[4] = simplify_gen_subreg (V4SImode, operands[0], mode, 0);
4966
      emit_insn (gen_sse2_loadld (operands[4],
4967
                                  CONST0_RTX (V4SImode), operands[1]));
4968
    }
4969
  /* We can ignore possible trapping value in the
4970
     high part of SSE register for non-trapping math. */
4971
  else if (SSE_REG_P (op1) && !flag_trapping_math)
4972
    operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4973
  else
4974
    {
4975
      operands[4] = simplify_gen_subreg (V4SImode, operands[0], mode, 0);
4976
      emit_move_insn (operands[2], operands[1]);
4977
      emit_insn (gen_sse2_loadld (operands[4],
4978
                                  CONST0_RTX (V4SImode), operands[2]));
4979
    }
4980
  if (mode == V4SFmode)
4981
    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4982
  else
4983
    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4984
  DONE;
4985
})
4986
 
4987
(define_split
4988
  [(set (match_operand:MODEF 0 "register_operand" "")
4989
        (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4990
   (clobber (match_operand:SI 2 "memory_operand" ""))]
4991
  "TARGET_SSE2 && TARGET_SSE_MATH
4992
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4993
   && reload_completed
4994
   && (SSE_REG_P (operands[0])
4995
       || (GET_CODE (operands[0]) == SUBREG
4996
           && SSE_REG_P (SUBREG_REG (operands[0]))))"
4997
  [(const_int 0)]
4998
{
4999
  operands[3] = simplify_gen_subreg (mode, operands[0],
5000
                                     mode, 0);
5001
  operands[4] = simplify_gen_subreg (V4SImode, operands[0], mode, 0);
5002
 
5003
  emit_insn (gen_sse2_loadld (operands[4],
5004
                              CONST0_RTX (V4SImode), operands[1]));
5005
  if (mode == V4SFmode)
5006
    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5007
  else
5008
    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5009
  DONE;
5010
})
5011
 
5012
(define_split
5013
  [(set (match_operand:MODEF 0 "register_operand" "")
5014
        (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5015
  "TARGET_SSE2 && TARGET_SSE_MATH
5016
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5017
   && reload_completed
5018
   && (SSE_REG_P (operands[0])
5019
       || (GET_CODE (operands[0]) == SUBREG
5020
           && SSE_REG_P (SUBREG_REG (operands[0]))))"
5021
  [(const_int 0)]
5022
{
5023
  rtx op1 = operands[1];
5024
 
5025
  operands[3] = simplify_gen_subreg (mode, operands[0],
5026
                                     mode, 0);
5027
  if (GET_CODE (op1) == SUBREG)
5028
    op1 = SUBREG_REG (op1);
5029
 
5030
  if (GENERAL_REG_P (op1))
5031
    {
5032
      operands[4] = simplify_gen_subreg (V4SImode, operands[0], mode, 0);
5033
      if (TARGET_INTER_UNIT_MOVES)
5034
        emit_insn (gen_sse2_loadld (operands[4],
5035
                                    CONST0_RTX (V4SImode), operands[1]));
5036
      else
5037
        {
5038
          operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5039
                                              operands[1]);
5040
          emit_insn (gen_sse2_loadld (operands[4],
5041
                                      CONST0_RTX (V4SImode), operands[5]));
5042
          ix86_free_from_memory (GET_MODE (operands[1]));
5043
        }
5044
    }
5045
  /* We can ignore possible trapping value in the
5046
     high part of SSE register for non-trapping math. */
5047
  else if (SSE_REG_P (op1) && !flag_trapping_math)
5048
    operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5049
  else
5050
    gcc_unreachable ();
5051
  if (mode == V4SFmode)
5052
    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5053
  else
5054
    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5055
  DONE;
5056
})
5057
 
5058
(define_split
5059
  [(set (match_operand:MODEF 0 "register_operand" "")
5060
        (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5061
  "TARGET_SSE2 && TARGET_SSE_MATH
5062
   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5063
   && reload_completed
5064
   && (SSE_REG_P (operands[0])
5065
       || (GET_CODE (operands[0]) == SUBREG
5066
           && SSE_REG_P (SUBREG_REG (operands[0]))))"
5067
  [(const_int 0)]
5068
{
5069
  operands[3] = simplify_gen_subreg (mode, operands[0],
5070
                                     mode, 0);
5071
  operands[4] = simplify_gen_subreg (V4SImode, operands[0], mode, 0);
5072
 
5073
  emit_insn (gen_sse2_loadld (operands[4],
5074
                              CONST0_RTX (V4SImode), operands[1]));
5075
  if (mode == V4SFmode)
5076
    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5077
  else
5078
    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5079
  DONE;
5080
})
5081
 
5082
(define_insn "*float2_sse_with_temp"
5083
  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5084
        (float:MODEF
5085
          (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5086
  (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5087
  "(mode != DImode || TARGET_64BIT)
5088
   && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
5089
  "#"
5090
  [(set_attr "type" "sseicvt")
5091
   (set_attr "mode" "")
5092
   (set_attr "athlon_decode" "double,direct")
5093
   (set_attr "amdfam10_decode" "vector,double")
5094
   (set_attr "bdver1_decode" "double,direct")
5095
   (set_attr "fp_int_src" "true")])
5096
 
5097
(define_insn "*float2_sse_interunit"
5098
  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5099
        (float:MODEF
5100
          (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5101
  "(mode != DImode || TARGET_64BIT)
5102
   && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
5103
   && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5104
  "%vcvtsi2\t{%1, %d0|%d0, %1}"
5105
  [(set_attr "type" "sseicvt")
5106
   (set_attr "prefix" "maybe_vex")
5107
   (set_attr "mode" "")
5108
   (set (attr "prefix_rex")
5109
     (if_then_else
5110
       (and (eq_attr "prefix" "maybe_vex")
5111
            (match_test "mode == DImode"))
5112
       (const_string "1")
5113
       (const_string "*")))
5114
   (set_attr "athlon_decode" "double,direct")
5115
   (set_attr "amdfam10_decode" "vector,double")
5116
   (set_attr "bdver1_decode" "double,direct")
5117
   (set_attr "fp_int_src" "true")])
5118
 
5119
(define_split
5120
  [(set (match_operand:MODEF 0 "register_operand" "")
5121
        (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5122
   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5123
  "(mode != DImode || TARGET_64BIT)
5124
   && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
5125
   && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5126
   && reload_completed
5127
   && (SSE_REG_P (operands[0])
5128
       || (GET_CODE (operands[0]) == SUBREG
5129
           && SSE_REG_P (SUBREG_REG (operands[0]))))"
5130
  [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5131
 
5132
(define_insn "*float2_sse_nointerunit"
5133
  [(set (match_operand:MODEF 0 "register_operand" "=x")
5134
        (float:MODEF
5135
          (match_operand:SWI48x 1 "memory_operand" "m")))]
5136
  "(mode != DImode || TARGET_64BIT)
5137
   && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
5138
   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5139
  "%vcvtsi2\t{%1, %d0|%d0, %1}"
5140
  [(set_attr "type" "sseicvt")
5141
   (set_attr "prefix" "maybe_vex")
5142
   (set_attr "mode" "")
5143
   (set (attr "prefix_rex")
5144
     (if_then_else
5145
       (and (eq_attr "prefix" "maybe_vex")
5146
            (match_test "mode == DImode"))
5147
       (const_string "1")
5148
       (const_string "*")))
5149
   (set_attr "athlon_decode" "direct")
5150
   (set_attr "amdfam10_decode" "double")
5151
   (set_attr "bdver1_decode" "direct")
5152
   (set_attr "fp_int_src" "true")])
5153
 
5154
(define_split
5155
  [(set (match_operand:MODEF 0 "register_operand" "")
5156
        (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5157
   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5158
  "(mode != DImode || TARGET_64BIT)
5159
   && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
5160
   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5161
   && reload_completed
5162
   && (SSE_REG_P (operands[0])
5163
       || (GET_CODE (operands[0]) == SUBREG
5164
           && SSE_REG_P (SUBREG_REG (operands[0]))))"
5165
  [(set (match_dup 2) (match_dup 1))
5166
   (set (match_dup 0) (float:MODEF (match_dup 2)))])
5167
 
5168
(define_split
5169
  [(set (match_operand:MODEF 0 "register_operand" "")
5170
        (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5171
   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5172
  "(mode != DImode || TARGET_64BIT)
5173
   && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
5174
   && reload_completed
5175
   && (SSE_REG_P (operands[0])
5176
       || (GET_CODE (operands[0]) == SUBREG
5177
           && SSE_REG_P (SUBREG_REG (operands[0]))))"
5178
  [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5179
 
5180
(define_insn "*float2_i387_with_temp"
5181
  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5182
        (float:X87MODEF
5183
          (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5184
  (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5185
  "TARGET_80387
5186
   && X87_ENABLE_FLOAT (mode, mode)"
5187
  "@
5188
   fild%Z1\t%1
5189
   #"
5190
  [(set_attr "type" "fmov,multi")
5191
   (set_attr "mode" "")
5192
   (set_attr "unit" "*,i387")
5193
   (set_attr "fp_int_src" "true")])
5194
 
5195
(define_insn "*float2_i387"
5196
  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5197
        (float:X87MODEF
5198
          (match_operand:SWI48x 1 "memory_operand" "m")))]
5199
  "TARGET_80387
5200
   && X87_ENABLE_FLOAT (mode, mode)"
5201
  "fild%Z1\t%1"
5202
  [(set_attr "type" "fmov")
5203
   (set_attr "mode" "")
5204
   (set_attr "fp_int_src" "true")])
5205
 
5206
(define_split
5207
  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5208
        (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5209
   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5210
  "TARGET_80387
5211
   && X87_ENABLE_FLOAT (mode, mode)
5212
   && reload_completed"
5213
  [(set (match_dup 2) (match_dup 1))
5214
   (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5215
 
5216
(define_split
5217
  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5218
        (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5219
   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5220
  "TARGET_80387
5221
   && X87_ENABLE_FLOAT (mode, mode)
5222
   && reload_completed"
5223
  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5224
 
5225
;; Avoid store forwarding (partial memory) stall penalty
5226
;; by passing DImode value through XMM registers.  */
5227
 
5228
(define_insn "floatdi2_i387_with_xmm"
5229
  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5230
        (float:X87MODEF
5231
          (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5232
   (clobber (match_scratch:V4SI 3 "=X,x"))
5233
   (clobber (match_scratch:V4SI 4 "=X,x"))
5234
   (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5235
  "TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5236
   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5237
   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5238
  "#"
5239
  [(set_attr "type" "multi")
5240
   (set_attr "mode" "")
5241
   (set_attr "unit" "i387")
5242
   (set_attr "fp_int_src" "true")])
5243
 
5244
(define_split
5245
  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5246
        (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5247
   (clobber (match_scratch:V4SI 3 ""))
5248
   (clobber (match_scratch:V4SI 4 ""))
5249
   (clobber (match_operand:DI 2 "memory_operand" ""))]
5250
  "TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5251
   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5252
   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5253
   && reload_completed"
5254
  [(set (match_dup 2) (match_dup 3))
5255
   (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5256
{
5257
  /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5258
     Assemble the 64-bit DImode value in an xmm register.  */
5259
  emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5260
                              gen_rtx_SUBREG (SImode, operands[1], 0)));
5261
  emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5262
                              gen_rtx_SUBREG (SImode, operands[1], 4)));
5263
  emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5264
                                         operands[4]));
5265
 
5266
  operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5267
})
5268
 
5269
(define_split
5270
  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5271
        (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5272
   (clobber (match_scratch:V4SI 3 ""))
5273
   (clobber (match_scratch:V4SI 4 ""))
5274
   (clobber (match_operand:DI 2 "memory_operand" ""))]
5275
  "TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5276
   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5277
   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5278
   && reload_completed"
5279
  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5280
 
5281
;; Avoid store forwarding (partial memory) stall penalty by extending
5282
;; SImode value to DImode through XMM register instead of pushing two
5283
;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5284
;; targets benefit from this optimization. Also note that fild
5285
;; loads from memory only.
5286
 
5287
(define_insn "*floatunssi2_1"
5288
  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5289
        (unsigned_float:X87MODEF
5290
          (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5291
   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5292
   (clobber (match_scratch:SI 3 "=X,x"))]
5293
  "!TARGET_64BIT
5294
   && TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5295
   && TARGET_SSE"
5296
  "#"
5297
  [(set_attr "type" "multi")
5298
   (set_attr "mode" "")])
5299
 
5300
(define_split
5301
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5302
        (unsigned_float:X87MODEF
5303
          (match_operand:SI 1 "register_operand" "")))
5304
   (clobber (match_operand:DI 2 "memory_operand" ""))
5305
   (clobber (match_scratch:SI 3 ""))]
5306
  "!TARGET_64BIT
5307
   && TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5308
   && TARGET_SSE
5309
   && reload_completed"
5310
  [(set (match_dup 2) (match_dup 1))
5311
   (set (match_dup 0)
5312
        (float:X87MODEF (match_dup 2)))]
5313
  "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5314
 
5315
(define_split
5316
  [(set (match_operand:X87MODEF 0 "register_operand" "")
5317
        (unsigned_float:X87MODEF
5318
          (match_operand:SI 1 "memory_operand" "")))
5319
   (clobber (match_operand:DI 2 "memory_operand" ""))
5320
   (clobber (match_scratch:SI 3 ""))]
5321
  "!TARGET_64BIT
5322
   && TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5323
   && TARGET_SSE
5324
   && reload_completed"
5325
  [(set (match_dup 2) (match_dup 3))
5326
   (set (match_dup 0)
5327
        (float:X87MODEF (match_dup 2)))]
5328
{
5329
  emit_move_insn (operands[3], operands[1]);
5330
  operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5331
})
5332
 
5333
(define_expand "floatunssi2"
5334
  [(parallel
5335
     [(set (match_operand:X87MODEF 0 "register_operand" "")
5336
           (unsigned_float:X87MODEF
5337
             (match_operand:SI 1 "nonimmediate_operand" "")))
5338
      (clobber (match_dup 2))
5339
      (clobber (match_scratch:SI 3 ""))])]
5340
  "!TARGET_64BIT
5341
   && ((TARGET_80387 && X87_ENABLE_FLOAT (mode, DImode)
5342
        && TARGET_SSE)
5343
       || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))"
5344
{
5345
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
5346
    {
5347
      ix86_expand_convert_uns_si_sse (operands[0], operands[1]);
5348
      DONE;
5349
    }
5350
  else
5351
    {
5352
      enum ix86_stack_slot slot = (virtuals_instantiated
5353
                                   ? SLOT_TEMP
5354
                                   : SLOT_VIRTUAL);
5355
      operands[2] = assign_386_stack_local (DImode, slot);
5356
    }
5357
})
5358
 
5359
(define_expand "floatunsdisf2"
5360
  [(use (match_operand:SF 0 "register_operand" ""))
5361
   (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5362
  "TARGET_64BIT && TARGET_SSE_MATH"
5363
  "x86_emit_floatuns (operands); DONE;")
5364
 
5365
(define_expand "floatunsdidf2"
5366
  [(use (match_operand:DF 0 "register_operand" ""))
5367
   (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5368
  "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5369
   && TARGET_SSE2 && TARGET_SSE_MATH"
5370
{
5371
  if (TARGET_64BIT)
5372
    x86_emit_floatuns (operands);
5373
  else
5374
    ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5375
  DONE;
5376
})
5377
 
5378
;; Add instructions
5379
 
5380
(define_expand "add3"
5381
  [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5382
        (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5383
                    (match_operand:SDWIM 2 "" "")))]
5384
  ""
5385
  "ix86_expand_binary_operator (PLUS, mode, operands); DONE;")
5386
 
5387
(define_insn_and_split "*add3_doubleword"
5388
  [(set (match_operand: 0 "nonimmediate_operand" "=r,o")
5389
        (plus:
5390
          (match_operand: 1 "nonimmediate_operand" "%0,0")
5391
          (match_operand: 2 "" "ro,r")))
5392
   (clobber (reg:CC FLAGS_REG))]
5393
  "ix86_binary_operator_ok (PLUS, mode, operands)"
5394
  "#"
5395
  "reload_completed"
5396
  [(parallel [(set (reg:CC FLAGS_REG)
5397
                   (unspec:CC [(match_dup 1) (match_dup 2)]
5398
                              UNSPEC_ADD_CARRY))
5399
              (set (match_dup 0)
5400
                   (plus:DWIH (match_dup 1) (match_dup 2)))])
5401
   (parallel [(set (match_dup 3)
5402
                   (plus:DWIH
5403
                     (match_dup 4)
5404
                     (plus:DWIH
5405
                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5406
                       (match_dup 5))))
5407
              (clobber (reg:CC FLAGS_REG))])]
5408
  "split_double_mode (mode, &operands[0], 3, &operands[0], &operands[3]);")
5409
 
5410
(define_insn "*add3_cc"
5411
  [(set (reg:CC FLAGS_REG)
5412
        (unspec:CC
5413
          [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5414
           (match_operand:SWI48 2 "" "r,rm")]
5415
          UNSPEC_ADD_CARRY))
5416
   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5417
        (plus:SWI48 (match_dup 1) (match_dup 2)))]
5418
  "ix86_binary_operator_ok (PLUS, mode, operands)"
5419
  "add{}\t{%2, %0|%0, %2}"
5420
  [(set_attr "type" "alu")
5421
   (set_attr "mode" "")])
5422
 
5423
(define_insn "addqi3_cc"
5424
  [(set (reg:CC FLAGS_REG)
5425
        (unspec:CC
5426
          [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5427
           (match_operand:QI 2 "general_operand" "qn,qm")]
5428
          UNSPEC_ADD_CARRY))
5429
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5430
        (plus:QI (match_dup 1) (match_dup 2)))]
5431
  "ix86_binary_operator_ok (PLUS, QImode, operands)"
5432
  "add{b}\t{%2, %0|%0, %2}"
5433
  [(set_attr "type" "alu")
5434
   (set_attr "mode" "QI")])
5435
 
5436
(define_insn_and_split "*lea_1"
5437
  [(set (match_operand:SI 0 "register_operand" "=r")
5438
        (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5439
  "TARGET_64BIT"
5440
  "lea{l}\t{%a1, %0|%0, %a1}"
5441
  "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5442
  [(const_int 0)]
5443
{
5444
  ix86_split_lea_for_addr (operands, SImode);
5445
  DONE;
5446
}
5447
  [(set_attr "type" "lea")
5448
   (set_attr "mode" "SI")])
5449
 
5450
(define_insn_and_split "*lea_2"
5451
  [(set (match_operand:SWI48 0 "register_operand" "=r")
5452
        (match_operand:SWI48 1 "lea_address_operand" "p"))]
5453
  ""
5454
  "lea{}\t{%a1, %0|%0, %a1}"
5455
  "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5456
  [(const_int 0)]
5457
{
5458
  ix86_split_lea_for_addr (operands, mode);
5459
  DONE;
5460
}
5461
  [(set_attr "type" "lea")
5462
   (set_attr "mode" "")])
5463
 
5464
(define_insn "*lea_3_zext"
5465
  [(set (match_operand:DI 0 "register_operand" "=r")
5466
        (zero_extend:DI
5467
          (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5468
  "TARGET_64BIT"
5469
  "lea{l}\t{%a1, %k0|%k0, %a1}"
5470
  [(set_attr "type" "lea")
5471
   (set_attr "mode" "SI")])
5472
 
5473
(define_insn "*lea_4_zext"
5474
  [(set (match_operand:DI 0 "register_operand" "=r")
5475
        (zero_extend:DI
5476
          (match_operand:SI 1 "lea_address_operand" "j")))]
5477
  "TARGET_64BIT"
5478
  "lea{l}\t{%a1, %k0|%k0, %a1}"
5479
  [(set_attr "type" "lea")
5480
   (set_attr "mode" "SI")])
5481
 
5482
(define_insn "*lea_5_zext"
5483
  [(set (match_operand:DI 0 "register_operand" "=r")
5484
        (and:DI
5485
          (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5486
          (match_operand:DI 2 "const_32bit_mask" "n")))]
5487
  "TARGET_64BIT"
5488
  "lea{l}\t{%a1, %k0|%k0, %a1}"
5489
  [(set_attr "type" "lea")
5490
   (set_attr "mode" "SI")])
5491
 
5492
(define_insn "*lea_6_zext"
5493
  [(set (match_operand:DI 0 "register_operand" "=r")
5494
        (and:DI
5495
          (match_operand:DI 1 "lea_address_operand" "p")
5496
          (match_operand:DI 2 "const_32bit_mask" "n")))]
5497
  "TARGET_64BIT"
5498
  "lea{l}\t{%a1, %k0|%k0, %a1}"
5499
  [(set_attr "type" "lea")
5500
   (set_attr "mode" "SI")])
5501
 
5502
(define_insn "*add_1"
5503
  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5504
        (plus:SWI48
5505
          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5506
          (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5507
   (clobber (reg:CC FLAGS_REG))]
5508
  "ix86_binary_operator_ok (PLUS, mode, operands)"
5509
{
5510
  switch (get_attr_type (insn))
5511
    {
5512
    case TYPE_LEA:
5513
      return "#";
5514
 
5515
    case TYPE_INCDEC:
5516
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5517
      if (operands[2] == const1_rtx)
5518
        return "inc{}\t%0";
5519
      else
5520
        {
5521
          gcc_assert (operands[2] == constm1_rtx);
5522
          return "dec{}\t%0";
5523
        }
5524
 
5525
    default:
5526
      /* For most processors, ADD is faster than LEA.  This alternative
5527
         was added to use ADD as much as possible.  */
5528
      if (which_alternative == 2)
5529
        {
5530
          rtx tmp;
5531
          tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5532
        }
5533
 
5534
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5535
      if (x86_maybe_negate_const_int (&operands[2], mode))
5536
        return "sub{}\t{%2, %0|%0, %2}";
5537
 
5538
      return "add{}\t{%2, %0|%0, %2}";
5539
    }
5540
}
5541
  [(set (attr "type")
5542
     (cond [(eq_attr "alternative" "3")
5543
              (const_string "lea")
5544
            (match_operand:SWI48 2 "incdec_operand" "")
5545
              (const_string "incdec")
5546
           ]
5547
           (const_string "alu")))
5548
   (set (attr "length_immediate")
5549
      (if_then_else
5550
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5551
        (const_string "1")
5552
        (const_string "*")))
5553
   (set_attr "mode" "")])
5554
 
5555
;; It may seem that nonimmediate operand is proper one for operand 1.
5556
;; The addsi_1 pattern allows nonimmediate operand at that place and
5557
;; we take care in ix86_binary_operator_ok to not allow two memory
5558
;; operands so proper swapping will be done in reload.  This allow
5559
;; patterns constructed from addsi_1 to match.
5560
 
5561
(define_insn "addsi_1_zext"
5562
  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5563
        (zero_extend:DI
5564
          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5565
                   (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5566
   (clobber (reg:CC FLAGS_REG))]
5567
  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5568
{
5569
  switch (get_attr_type (insn))
5570
    {
5571
    case TYPE_LEA:
5572
      return "#";
5573
 
5574
    case TYPE_INCDEC:
5575
      if (operands[2] == const1_rtx)
5576
        return "inc{l}\t%k0";
5577
      else
5578
        {
5579
          gcc_assert (operands[2] == constm1_rtx);
5580
          return "dec{l}\t%k0";
5581
        }
5582
 
5583
    default:
5584
      /* For most processors, ADD is faster than LEA.  This alternative
5585
         was added to use ADD as much as possible.  */
5586
      if (which_alternative == 1)
5587
        {
5588
          rtx tmp;
5589
          tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5590
        }
5591
 
5592
      if (x86_maybe_negate_const_int (&operands[2], SImode))
5593
        return "sub{l}\t{%2, %k0|%k0, %2}";
5594
 
5595
      return "add{l}\t{%2, %k0|%k0, %2}";
5596
    }
5597
}
5598
  [(set (attr "type")
5599
     (cond [(eq_attr "alternative" "2")
5600
              (const_string "lea")
5601
            (match_operand:SI 2 "incdec_operand" "")
5602
              (const_string "incdec")
5603
           ]
5604
           (const_string "alu")))
5605
   (set (attr "length_immediate")
5606
      (if_then_else
5607
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5608
        (const_string "1")
5609
        (const_string "*")))
5610
   (set_attr "mode" "SI")])
5611
 
5612
(define_insn "*addhi_1"
5613
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5614
        (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5615
                 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5616
   (clobber (reg:CC FLAGS_REG))]
5617
  "ix86_binary_operator_ok (PLUS, HImode, operands)"
5618
{
5619
  switch (get_attr_type (insn))
5620
    {
5621
    case TYPE_LEA:
5622
      return "#";
5623
 
5624
    case TYPE_INCDEC:
5625
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5626
      if (operands[2] == const1_rtx)
5627
        return "inc{w}\t%0";
5628
      else
5629
        {
5630
          gcc_assert (operands[2] == constm1_rtx);
5631
          return "dec{w}\t%0";
5632
        }
5633
 
5634
    default:
5635
      /* For most processors, ADD is faster than LEA.  This alternative
5636
         was added to use ADD as much as possible.  */
5637
      if (which_alternative == 2)
5638
        {
5639
          rtx tmp;
5640
          tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5641
        }
5642
 
5643
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644
      if (x86_maybe_negate_const_int (&operands[2], HImode))
5645
        return "sub{w}\t{%2, %0|%0, %2}";
5646
 
5647
      return "add{w}\t{%2, %0|%0, %2}";
5648
    }
5649
}
5650
  [(set (attr "type")
5651
     (cond [(eq_attr "alternative" "3")
5652
              (const_string "lea")
5653
            (match_operand:HI 2 "incdec_operand" "")
5654
              (const_string "incdec")
5655
           ]
5656
           (const_string "alu")))
5657
   (set (attr "length_immediate")
5658
      (if_then_else
5659
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5660
        (const_string "1")
5661
        (const_string "*")))
5662
   (set_attr "mode" "HI,HI,HI,SI")])
5663
 
5664
;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5665
(define_insn "*addqi_1"
5666
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5667
        (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5668
                 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5669
   (clobber (reg:CC FLAGS_REG))]
5670
  "ix86_binary_operator_ok (PLUS, QImode, operands)"
5671
{
5672
  bool widen = (which_alternative == 3 || which_alternative == 4);
5673
 
5674
  switch (get_attr_type (insn))
5675
    {
5676
    case TYPE_LEA:
5677
      return "#";
5678
 
5679
    case TYPE_INCDEC:
5680
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681
      if (operands[2] == const1_rtx)
5682
        return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5683
      else
5684
        {
5685
          gcc_assert (operands[2] == constm1_rtx);
5686
          return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5687
        }
5688
 
5689
    default:
5690
      /* For most processors, ADD is faster than LEA.  These alternatives
5691
         were added to use ADD as much as possible.  */
5692
      if (which_alternative == 2 || which_alternative == 4)
5693
        {
5694
          rtx tmp;
5695
          tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5696
        }
5697
 
5698
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5699
      if (x86_maybe_negate_const_int (&operands[2], QImode))
5700
        {
5701
          if (widen)
5702
            return "sub{l}\t{%2, %k0|%k0, %2}";
5703
          else
5704
            return "sub{b}\t{%2, %0|%0, %2}";
5705
        }
5706
      if (widen)
5707
        return "add{l}\t{%k2, %k0|%k0, %k2}";
5708
      else
5709
        return "add{b}\t{%2, %0|%0, %2}";
5710
    }
5711
}
5712
  [(set (attr "type")
5713
     (cond [(eq_attr "alternative" "5")
5714
              (const_string "lea")
5715
            (match_operand:QI 2 "incdec_operand" "")
5716
              (const_string "incdec")
5717
           ]
5718
           (const_string "alu")))
5719
   (set (attr "length_immediate")
5720
      (if_then_else
5721
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5722
        (const_string "1")
5723
        (const_string "*")))
5724
   (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5725
 
5726
(define_insn "*addqi_1_slp"
5727
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5728
        (plus:QI (match_dup 0)
5729
                 (match_operand:QI 1 "general_operand" "qn,qm")))
5730
   (clobber (reg:CC FLAGS_REG))]
5731
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5732
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5733
{
5734
  switch (get_attr_type (insn))
5735
    {
5736
    case TYPE_INCDEC:
5737
      if (operands[1] == const1_rtx)
5738
        return "inc{b}\t%0";
5739
      else
5740
        {
5741
          gcc_assert (operands[1] == constm1_rtx);
5742
          return "dec{b}\t%0";
5743
        }
5744
 
5745
    default:
5746
      if (x86_maybe_negate_const_int (&operands[1], QImode))
5747
        return "sub{b}\t{%1, %0|%0, %1}";
5748
 
5749
      return "add{b}\t{%1, %0|%0, %1}";
5750
    }
5751
}
5752
  [(set (attr "type")
5753
     (if_then_else (match_operand:QI 1 "incdec_operand" "")
5754
        (const_string "incdec")
5755
        (const_string "alu1")))
5756
   (set (attr "memory")
5757
     (if_then_else (match_operand 1 "memory_operand" "")
5758
        (const_string "load")
5759
        (const_string "none")))
5760
   (set_attr "mode" "QI")])
5761
 
5762
;; Split non destructive adds if we cannot use lea.
5763
(define_split
5764
  [(set (match_operand:SWI48 0 "register_operand" "")
5765
        (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5766
              (match_operand:SWI48 2 "nonmemory_operand" "")))
5767
   (clobber (reg:CC FLAGS_REG))]
5768
  "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5769
  [(set (match_dup 0) (match_dup 1))
5770
   (parallel [(set (match_dup 0) (plus: (match_dup 0) (match_dup 2)))
5771
              (clobber (reg:CC FLAGS_REG))])])
5772
 
5773
;; Convert add to the lea pattern to avoid flags dependency.
5774
(define_split
5775
  [(set (match_operand:SWI 0 "register_operand" "")
5776
        (plus:SWI (match_operand:SWI 1 "register_operand" "")
5777
                  (match_operand:SWI 2 "" "")))
5778
   (clobber (reg:CC FLAGS_REG))]
5779
  "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5780
  [(const_int 0)]
5781
{
5782
  enum machine_mode mode = mode;
5783
  rtx pat;
5784
 
5785
  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5786
    {
5787
      mode = SImode;
5788
      operands[0] = gen_lowpart (mode, operands[0]);
5789
      operands[1] = gen_lowpart (mode, operands[1]);
5790
      operands[2] = gen_lowpart (mode, operands[2]);
5791
    }
5792
 
5793
  pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5794
 
5795
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5796
  DONE;
5797
})
5798
 
5799
;; Convert add to the lea pattern to avoid flags dependency.
5800
(define_split
5801
  [(set (match_operand:DI 0 "register_operand" "")
5802
        (zero_extend:DI
5803
          (plus:SI (match_operand:SI 1 "register_operand" "")
5804
                   (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5805
   (clobber (reg:CC FLAGS_REG))]
5806
  "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5807
  [(set (match_dup 0)
5808
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5809
 
5810
(define_insn "*add_2"
5811
  [(set (reg FLAGS_REG)
5812
        (compare
5813
          (plus:SWI
5814
            (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5815
            (match_operand:SWI 2 "" ","))
5816
          (const_int 0)))
5817
   (set (match_operand:SWI 0 "nonimmediate_operand" "=,m")
5818
        (plus:SWI (match_dup 1) (match_dup 2)))]
5819
  "ix86_match_ccmode (insn, CCGOCmode)
5820
   && ix86_binary_operator_ok (PLUS, mode, operands)"
5821
{
5822
  switch (get_attr_type (insn))
5823
    {
5824
    case TYPE_INCDEC:
5825
      if (operands[2] == const1_rtx)
5826
        return "inc{}\t%0";
5827
      else
5828
        {
5829
          gcc_assert (operands[2] == constm1_rtx);
5830
          return "dec{}\t%0";
5831
        }
5832
 
5833
    default:
5834
      if (x86_maybe_negate_const_int (&operands[2], mode))
5835
        return "sub{}\t{%2, %0|%0, %2}";
5836
 
5837
      return "add{}\t{%2, %0|%0, %2}";
5838
    }
5839
}
5840
  [(set (attr "type")
5841
     (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5842
        (const_string "incdec")
5843
        (const_string "alu")))
5844
   (set (attr "length_immediate")
5845
      (if_then_else
5846
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5847
        (const_string "1")
5848
        (const_string "*")))
5849
   (set_attr "mode" "")])
5850
 
5851
;; See comment for addsi_1_zext why we do use nonimmediate_operand
5852
(define_insn "*addsi_2_zext"
5853
  [(set (reg FLAGS_REG)
5854
        (compare
5855
          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5856
                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
5857
          (const_int 0)))
5858
   (set (match_operand:DI 0 "register_operand" "=r")
5859
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5860
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5861
   && ix86_binary_operator_ok (PLUS, SImode, operands)"
5862
{
5863
  switch (get_attr_type (insn))
5864
    {
5865
    case TYPE_INCDEC:
5866
      if (operands[2] == const1_rtx)
5867
        return "inc{l}\t%k0";
5868
      else
5869
        {
5870
          gcc_assert (operands[2] == constm1_rtx);
5871
          return "dec{l}\t%k0";
5872
        }
5873
 
5874
    default:
5875
      if (x86_maybe_negate_const_int (&operands[2], SImode))
5876
        return "sub{l}\t{%2, %k0|%k0, %2}";
5877
 
5878
      return "add{l}\t{%2, %k0|%k0, %2}";
5879
    }
5880
}
5881
  [(set (attr "type")
5882
     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5883
        (const_string "incdec")
5884
        (const_string "alu")))
5885
   (set (attr "length_immediate")
5886
      (if_then_else
5887
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5888
        (const_string "1")
5889
        (const_string "*")))
5890
   (set_attr "mode" "SI")])
5891
 
5892
(define_insn "*add_3"
5893
  [(set (reg FLAGS_REG)
5894
        (compare
5895
          (neg:SWI (match_operand:SWI 2 "" ""))
5896
          (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5897
   (clobber (match_scratch:SWI 0 "="))]
5898
  "ix86_match_ccmode (insn, CCZmode)
5899
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5900
{
5901
  switch (get_attr_type (insn))
5902
    {
5903
    case TYPE_INCDEC:
5904
      if (operands[2] == const1_rtx)
5905
        return "inc{}\t%0";
5906
      else
5907
        {
5908
          gcc_assert (operands[2] == constm1_rtx);
5909
          return "dec{}\t%0";
5910
        }
5911
 
5912
    default:
5913
      if (x86_maybe_negate_const_int (&operands[2], mode))
5914
        return "sub{}\t{%2, %0|%0, %2}";
5915
 
5916
      return "add{}\t{%2, %0|%0, %2}";
5917
    }
5918
}
5919
  [(set (attr "type")
5920
     (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5921
        (const_string "incdec")
5922
        (const_string "alu")))
5923
   (set (attr "length_immediate")
5924
      (if_then_else
5925
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5926
        (const_string "1")
5927
        (const_string "*")))
5928
   (set_attr "mode" "")])
5929
 
5930
;; See comment for addsi_1_zext why we do use nonimmediate_operand
5931
(define_insn "*addsi_3_zext"
5932
  [(set (reg FLAGS_REG)
5933
        (compare
5934
          (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5935
          (match_operand:SI 1 "nonimmediate_operand" "%0")))
5936
   (set (match_operand:DI 0 "register_operand" "=r")
5937
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5938
  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5939
   && ix86_binary_operator_ok (PLUS, SImode, operands)"
5940
{
5941
  switch (get_attr_type (insn))
5942
    {
5943
    case TYPE_INCDEC:
5944
      if (operands[2] == const1_rtx)
5945
        return "inc{l}\t%k0";
5946
      else
5947
        {
5948
          gcc_assert (operands[2] == constm1_rtx);
5949
          return "dec{l}\t%k0";
5950
        }
5951
 
5952
    default:
5953
      if (x86_maybe_negate_const_int (&operands[2], SImode))
5954
        return "sub{l}\t{%2, %k0|%k0, %2}";
5955
 
5956
      return "add{l}\t{%2, %k0|%k0, %2}";
5957
    }
5958
}
5959
  [(set (attr "type")
5960
     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5961
        (const_string "incdec")
5962
        (const_string "alu")))
5963
   (set (attr "length_immediate")
5964
      (if_then_else
5965
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5966
        (const_string "1")
5967
        (const_string "*")))
5968
   (set_attr "mode" "SI")])
5969
 
5970
; For comparisons against 1, -1 and 128, we may generate better code
5971
; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5972
; is matched then.  We can't accept general immediate, because for
5973
; case of overflows,  the result is messed up.
5974
; Also carry flag is reversed compared to cmp, so this conversion is valid
5975
; only for comparisons not depending on it.
5976
 
5977
(define_insn "*adddi_4"
5978
  [(set (reg FLAGS_REG)
5979
        (compare
5980
          (match_operand:DI 1 "nonimmediate_operand" "0")
5981
          (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5982
   (clobber (match_scratch:DI 0 "=rm"))]
5983
  "TARGET_64BIT
5984
   && ix86_match_ccmode (insn, CCGCmode)"
5985
{
5986
  switch (get_attr_type (insn))
5987
    {
5988
    case TYPE_INCDEC:
5989
      if (operands[2] == constm1_rtx)
5990
        return "inc{q}\t%0";
5991
      else
5992
        {
5993
          gcc_assert (operands[2] == const1_rtx);
5994
          return "dec{q}\t%0";
5995
        }
5996
 
5997
    default:
5998
      if (x86_maybe_negate_const_int (&operands[2], DImode))
5999
        return "add{q}\t{%2, %0|%0, %2}";
6000
 
6001
      return "sub{q}\t{%2, %0|%0, %2}";
6002
    }
6003
}
6004
  [(set (attr "type")
6005
     (if_then_else (match_operand:DI 2 "incdec_operand" "")
6006
        (const_string "incdec")
6007
        (const_string "alu")))
6008
   (set (attr "length_immediate")
6009
      (if_then_else
6010
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6011
        (const_string "1")
6012
        (const_string "*")))
6013
   (set_attr "mode" "DI")])
6014
 
6015
; For comparisons against 1, -1 and 128, we may generate better code
6016
; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6017
; is matched then.  We can't accept general immediate, because for
6018
; case of overflows,  the result is messed up.
6019
; Also carry flag is reversed compared to cmp, so this conversion is valid
6020
; only for comparisons not depending on it.
6021
 
6022
(define_insn "*add_4"
6023
  [(set (reg FLAGS_REG)
6024
        (compare
6025
          (match_operand:SWI124 1 "nonimmediate_operand" "0")
6026
          (match_operand:SWI124 2 "const_int_operand" "n")))
6027
   (clobber (match_scratch:SWI124 0 "=m"))]
6028
  "ix86_match_ccmode (insn, CCGCmode)"
6029
{
6030
  switch (get_attr_type (insn))
6031
    {
6032
    case TYPE_INCDEC:
6033
      if (operands[2] == constm1_rtx)
6034
        return "inc{}\t%0";
6035
      else
6036
        {
6037
          gcc_assert (operands[2] == const1_rtx);
6038
          return "dec{}\t%0";
6039
        }
6040
 
6041
    default:
6042
      if (x86_maybe_negate_const_int (&operands[2], mode))
6043
        return "add{}\t{%2, %0|%0, %2}";
6044
 
6045
      return "sub{}\t{%2, %0|%0, %2}";
6046
    }
6047
}
6048
  [(set (attr "type")
6049
     (if_then_else (match_operand: 2 "incdec_operand" "")
6050
        (const_string "incdec")
6051
        (const_string "alu")))
6052
   (set (attr "length_immediate")
6053
      (if_then_else
6054
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6055
        (const_string "1")
6056
        (const_string "*")))
6057
   (set_attr "mode" "")])
6058
 
6059
(define_insn "*add_5"
6060
  [(set (reg FLAGS_REG)
6061
        (compare
6062
          (plus:SWI
6063
            (match_operand:SWI 1 "nonimmediate_operand" "%0")
6064
            (match_operand:SWI 2 "" ""))
6065
          (const_int 0)))
6066
   (clobber (match_scratch:SWI 0 "="))]
6067
  "ix86_match_ccmode (insn, CCGOCmode)
6068
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6069
{
6070
  switch (get_attr_type (insn))
6071
    {
6072
    case TYPE_INCDEC:
6073
      if (operands[2] == const1_rtx)
6074
        return "inc{}\t%0";
6075
      else
6076
        {
6077
          gcc_assert (operands[2] == constm1_rtx);
6078
          return "dec{}\t%0";
6079
        }
6080
 
6081
    default:
6082
      if (x86_maybe_negate_const_int (&operands[2], mode))
6083
        return "sub{}\t{%2, %0|%0, %2}";
6084
 
6085
      return "add{}\t{%2, %0|%0, %2}";
6086
    }
6087
}
6088
  [(set (attr "type")
6089
     (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6090
        (const_string "incdec")
6091
        (const_string "alu")))
6092
   (set (attr "length_immediate")
6093
      (if_then_else
6094
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6095
        (const_string "1")
6096
        (const_string "*")))
6097
   (set_attr "mode" "")])
6098
 
6099
(define_insn "*addqi_ext_1_rex64"
6100
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6101
                         (const_int 8)
6102
                         (const_int 8))
6103
        (plus:SI
6104
          (zero_extract:SI
6105
            (match_operand 1 "ext_register_operand" "0")
6106
            (const_int 8)
6107
            (const_int 8))
6108
          (match_operand:QI 2 "nonmemory_operand" "Qn")))
6109
   (clobber (reg:CC FLAGS_REG))]
6110
  "TARGET_64BIT"
6111
{
6112
  switch (get_attr_type (insn))
6113
    {
6114
    case TYPE_INCDEC:
6115
      if (operands[2] == const1_rtx)
6116
        return "inc{b}\t%h0";
6117
      else
6118
        {
6119
          gcc_assert (operands[2] == constm1_rtx);
6120
          return "dec{b}\t%h0";
6121
        }
6122
 
6123
    default:
6124
      return "add{b}\t{%2, %h0|%h0, %2}";
6125
    }
6126
}
6127
  [(set (attr "type")
6128
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6129
        (const_string "incdec")
6130
        (const_string "alu")))
6131
   (set_attr "modrm" "1")
6132
   (set_attr "mode" "QI")])
6133
 
6134
(define_insn "addqi_ext_1"
6135
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6136
                         (const_int 8)
6137
                         (const_int 8))
6138
        (plus:SI
6139
          (zero_extract:SI
6140
            (match_operand 1 "ext_register_operand" "0")
6141
            (const_int 8)
6142
            (const_int 8))
6143
          (match_operand:QI 2 "general_operand" "Qmn")))
6144
   (clobber (reg:CC FLAGS_REG))]
6145
  "!TARGET_64BIT"
6146
{
6147
  switch (get_attr_type (insn))
6148
    {
6149
    case TYPE_INCDEC:
6150
      if (operands[2] == const1_rtx)
6151
        return "inc{b}\t%h0";
6152
      else
6153
        {
6154
          gcc_assert (operands[2] == constm1_rtx);
6155
          return "dec{b}\t%h0";
6156
        }
6157
 
6158
    default:
6159
      return "add{b}\t{%2, %h0|%h0, %2}";
6160
    }
6161
}
6162
  [(set (attr "type")
6163
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6164
        (const_string "incdec")
6165
        (const_string "alu")))
6166
   (set_attr "modrm" "1")
6167
   (set_attr "mode" "QI")])
6168
 
6169
(define_insn "*addqi_ext_2"
6170
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6171
                         (const_int 8)
6172
                         (const_int 8))
6173
        (plus:SI
6174
          (zero_extract:SI
6175
            (match_operand 1 "ext_register_operand" "%0")
6176
            (const_int 8)
6177
            (const_int 8))
6178
          (zero_extract:SI
6179
            (match_operand 2 "ext_register_operand" "Q")
6180
            (const_int 8)
6181
            (const_int 8))))
6182
   (clobber (reg:CC FLAGS_REG))]
6183
  ""
6184
  "add{b}\t{%h2, %h0|%h0, %h2}"
6185
  [(set_attr "type" "alu")
6186
   (set_attr "mode" "QI")])
6187
 
6188
;; The lea patterns for modes less than 32 bits need to be matched by
6189
;; several insns converted to real lea by splitters.
6190
 
6191
(define_insn_and_split "*lea_general_1"
6192
  [(set (match_operand 0 "register_operand" "=r")
6193
        (plus (plus (match_operand 1 "index_register_operand" "l")
6194
                    (match_operand 2 "register_operand" "r"))
6195
              (match_operand 3 "immediate_operand" "i")))]
6196
  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6197
   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6198
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6199
   && GET_MODE (operands[0]) == GET_MODE (operands[2])
6200
   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6201
       || GET_MODE (operands[3]) == VOIDmode)"
6202
  "#"
6203
  "&& reload_completed"
6204
  [(const_int 0)]
6205
{
6206
  enum machine_mode mode = SImode;
6207
  rtx pat;
6208
 
6209
  operands[0] = gen_lowpart (mode, operands[0]);
6210
  operands[1] = gen_lowpart (mode, operands[1]);
6211
  operands[2] = gen_lowpart (mode, operands[2]);
6212
  operands[3] = gen_lowpart (mode, operands[3]);
6213
 
6214
  pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6215
                      operands[3]);
6216
 
6217
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6218
  DONE;
6219
}
6220
  [(set_attr "type" "lea")
6221
   (set_attr "mode" "SI")])
6222
 
6223
(define_insn_and_split "*lea_general_2"
6224
  [(set (match_operand 0 "register_operand" "=r")
6225
        (plus (mult (match_operand 1 "index_register_operand" "l")
6226
                    (match_operand 2 "const248_operand" "n"))
6227
              (match_operand 3 "nonmemory_operand" "ri")))]
6228
  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6229
   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6230
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6231
   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6232
       || GET_MODE (operands[3]) == VOIDmode)"
6233
  "#"
6234
  "&& reload_completed"
6235
  [(const_int 0)]
6236
{
6237
  enum machine_mode mode = SImode;
6238
  rtx pat;
6239
 
6240
  operands[0] = gen_lowpart (mode, operands[0]);
6241
  operands[1] = gen_lowpart (mode, operands[1]);
6242
  operands[3] = gen_lowpart (mode, operands[3]);
6243
 
6244
  pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6245
                      operands[3]);
6246
 
6247
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6248
  DONE;
6249
}
6250
  [(set_attr "type" "lea")
6251
   (set_attr "mode" "SI")])
6252
 
6253
(define_insn_and_split "*lea_general_3"
6254
  [(set (match_operand 0 "register_operand" "=r")
6255
        (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6256
                          (match_operand 2 "const248_operand" "n"))
6257
                    (match_operand 3 "register_operand" "r"))
6258
              (match_operand 4 "immediate_operand" "i")))]
6259
  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6260
   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6261
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6262
   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6263
  "#"
6264
  "&& reload_completed"
6265
  [(const_int 0)]
6266
{
6267
  enum machine_mode mode = SImode;
6268
  rtx pat;
6269
 
6270
  operands[0] = gen_lowpart (mode, operands[0]);
6271
  operands[1] = gen_lowpart (mode, operands[1]);
6272
  operands[3] = gen_lowpart (mode, operands[3]);
6273
  operands[4] = gen_lowpart (mode, operands[4]);
6274
 
6275
  pat = gen_rtx_PLUS (mode,
6276
                      gen_rtx_PLUS (mode,
6277
                                    gen_rtx_MULT (mode, operands[1],
6278
                                                        operands[2]),
6279
                                    operands[3]),
6280
                      operands[4]);
6281
 
6282
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6283
  DONE;
6284
}
6285
  [(set_attr "type" "lea")
6286
   (set_attr "mode" "SI")])
6287
 
6288
(define_insn_and_split "*lea_general_4"
6289
  [(set (match_operand 0 "register_operand" "=r")
6290
        (any_or (ashift
6291
                  (match_operand 1 "index_register_operand" "l")
6292
                  (match_operand 2 "const_int_operand" "n"))
6293
                (match_operand 3 "const_int_operand" "n")))]
6294
  "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6295
      && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6296
    || GET_MODE (operands[0]) == SImode
6297
    || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6298
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6299
   && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6300
   && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6301
       < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6302
  "#"
6303
  "&& reload_completed"
6304
  [(const_int 0)]
6305
{
6306
  enum machine_mode mode = GET_MODE (operands[0]);
6307
  rtx pat;
6308
 
6309
  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6310
    {
6311
      mode = SImode;
6312
      operands[0] = gen_lowpart (mode, operands[0]);
6313
      operands[1] = gen_lowpart (mode, operands[1]);
6314
    }
6315
 
6316
  operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6317
 
6318
  pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6319
                       INTVAL (operands[3]));
6320
 
6321
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6322
  DONE;
6323
}
6324
  [(set_attr "type" "lea")
6325
   (set (attr "mode")
6326
      (if_then_else (match_operand:DI 0 "" "")
6327
        (const_string "DI")
6328
        (const_string "SI")))])
6329
 
6330
;; Subtract instructions
6331
 
6332
(define_expand "sub3"
6333
  [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6334
        (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6335
                     (match_operand:SDWIM 2 "" "")))]
6336
  ""
6337
  "ix86_expand_binary_operator (MINUS, mode, operands); DONE;")
6338
 
6339
(define_insn_and_split "*sub3_doubleword"
6340
  [(set (match_operand: 0 "nonimmediate_operand" "=r,o")
6341
        (minus:
6342
          (match_operand: 1 "nonimmediate_operand" "0,0")
6343
          (match_operand: 2 "" "ro,r")))
6344
   (clobber (reg:CC FLAGS_REG))]
6345
  "ix86_binary_operator_ok (MINUS, mode, operands)"
6346
  "#"
6347
  "reload_completed"
6348
  [(parallel [(set (reg:CC FLAGS_REG)
6349
                   (compare:CC (match_dup 1) (match_dup 2)))
6350
              (set (match_dup 0)
6351
                   (minus:DWIH (match_dup 1) (match_dup 2)))])
6352
   (parallel [(set (match_dup 3)
6353
                   (minus:DWIH
6354
                     (match_dup 4)
6355
                     (plus:DWIH
6356
                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6357
                       (match_dup 5))))
6358
              (clobber (reg:CC FLAGS_REG))])]
6359
  "split_double_mode (mode, &operands[0], 3, &operands[0], &operands[3]);")
6360
 
6361
(define_insn "*sub_1"
6362
  [(set (match_operand:SWI 0 "nonimmediate_operand" "=m,")
6363
        (minus:SWI
6364
          (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6365
          (match_operand:SWI 2 "" ",m")))
6366
   (clobber (reg:CC FLAGS_REG))]
6367
  "ix86_binary_operator_ok (MINUS, mode, operands)"
6368
  "sub{}\t{%2, %0|%0, %2}"
6369
  [(set_attr "type" "alu")
6370
   (set_attr "mode" "")])
6371
 
6372
(define_insn "*subsi_1_zext"
6373
  [(set (match_operand:DI 0 "register_operand" "=r")
6374
        (zero_extend:DI
6375
          (minus:SI (match_operand:SI 1 "register_operand" "0")
6376
                    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6377
   (clobber (reg:CC FLAGS_REG))]
6378
  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6379
  "sub{l}\t{%2, %k0|%k0, %2}"
6380
  [(set_attr "type" "alu")
6381
   (set_attr "mode" "SI")])
6382
 
6383
(define_insn "*subqi_1_slp"
6384
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6385
        (minus:QI (match_dup 0)
6386
                  (match_operand:QI 1 "general_operand" "qn,qm")))
6387
   (clobber (reg:CC FLAGS_REG))]
6388
  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6389
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6390
  "sub{b}\t{%1, %0|%0, %1}"
6391
  [(set_attr "type" "alu1")
6392
   (set_attr "mode" "QI")])
6393
 
6394
(define_insn "*sub_2"
6395
  [(set (reg FLAGS_REG)
6396
        (compare
6397
          (minus:SWI
6398
            (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6399
            (match_operand:SWI 2 "" ",m"))
6400
          (const_int 0)))
6401
   (set (match_operand:SWI 0 "nonimmediate_operand" "=m,")
6402
        (minus:SWI (match_dup 1) (match_dup 2)))]
6403
  "ix86_match_ccmode (insn, CCGOCmode)
6404
   && ix86_binary_operator_ok (MINUS, mode, operands)"
6405
  "sub{}\t{%2, %0|%0, %2}"
6406
  [(set_attr "type" "alu")
6407
   (set_attr "mode" "")])
6408
 
6409
(define_insn "*subsi_2_zext"
6410
  [(set (reg FLAGS_REG)
6411
        (compare
6412
          (minus:SI (match_operand:SI 1 "register_operand" "0")
6413
                    (match_operand:SI 2 "x86_64_general_operand" "rme"))
6414
          (const_int 0)))
6415
   (set (match_operand:DI 0 "register_operand" "=r")
6416
        (zero_extend:DI
6417
          (minus:SI (match_dup 1)
6418
                    (match_dup 2))))]
6419
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6420
   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6421
  "sub{l}\t{%2, %k0|%k0, %2}"
6422
  [(set_attr "type" "alu")
6423
   (set_attr "mode" "SI")])
6424
 
6425
(define_insn "*sub_3"
6426
  [(set (reg FLAGS_REG)
6427
        (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6428
                 (match_operand:SWI 2 "" ",m")))
6429
   (set (match_operand:SWI 0 "nonimmediate_operand" "=m,")
6430
        (minus:SWI (match_dup 1) (match_dup 2)))]
6431
  "ix86_match_ccmode (insn, CCmode)
6432
   && ix86_binary_operator_ok (MINUS, mode, operands)"
6433
  "sub{}\t{%2, %0|%0, %2}"
6434
  [(set_attr "type" "alu")
6435
   (set_attr "mode" "")])
6436
 
6437
(define_insn "*subsi_3_zext"
6438
  [(set (reg FLAGS_REG)
6439
        (compare (match_operand:SI 1 "register_operand" "0")
6440
                 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6441
   (set (match_operand:DI 0 "register_operand" "=r")
6442
        (zero_extend:DI
6443
          (minus:SI (match_dup 1)
6444
                    (match_dup 2))))]
6445
  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6446
   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6447
  "sub{l}\t{%2, %1|%1, %2}"
6448
  [(set_attr "type" "alu")
6449
   (set_attr "mode" "SI")])
6450
 
6451
;; Add with carry and subtract with borrow
6452
 
6453
(define_expand "3_carry"
6454
  [(parallel
6455
    [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6456
          (plusminus:SWI
6457
            (match_operand:SWI 1 "nonimmediate_operand" "")
6458
            (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6459
                       [(match_operand 3 "flags_reg_operand" "")
6460
                        (const_int 0)])
6461
                      (match_operand:SWI 2 "" ""))))
6462
     (clobber (reg:CC FLAGS_REG))])]
6463
  "ix86_binary_operator_ok (, mode, operands)")
6464
 
6465
(define_insn "*3_carry"
6466
  [(set (match_operand:SWI 0 "nonimmediate_operand" "=m,")
6467
        (plusminus:SWI
6468
          (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6469
          (plus:SWI
6470
            (match_operator 3 "ix86_carry_flag_operator"
6471
             [(reg FLAGS_REG) (const_int 0)])
6472
            (match_operand:SWI 2 "" ",m"))))
6473
   (clobber (reg:CC FLAGS_REG))]
6474
  "ix86_binary_operator_ok (PLUS, mode, operands)"
6475
  "{}\t{%2, %0|%0, %2}"
6476
  [(set_attr "type" "alu")
6477
   (set_attr "use_carry" "1")
6478
   (set_attr "pent_pair" "pu")
6479
   (set_attr "mode" "")])
6480
 
6481
(define_insn "*addsi3_carry_zext"
6482
  [(set (match_operand:DI 0 "register_operand" "=r")
6483
        (zero_extend:DI
6484
          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6485
                   (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6486
                             [(reg FLAGS_REG) (const_int 0)])
6487
                            (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6488
   (clobber (reg:CC FLAGS_REG))]
6489
  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6490
  "adc{l}\t{%2, %k0|%k0, %2}"
6491
  [(set_attr "type" "alu")
6492
   (set_attr "use_carry" "1")
6493
   (set_attr "pent_pair" "pu")
6494
   (set_attr "mode" "SI")])
6495
 
6496
(define_insn "*subsi3_carry_zext"
6497
  [(set (match_operand:DI 0 "register_operand" "=r")
6498
        (zero_extend:DI
6499
          (minus:SI (match_operand:SI 1 "register_operand" "0")
6500
                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6501
                              [(reg FLAGS_REG) (const_int 0)])
6502
                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6503
   (clobber (reg:CC FLAGS_REG))]
6504
  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6505
  "sbb{l}\t{%2, %k0|%k0, %2}"
6506
  [(set_attr "type" "alu")
6507
   (set_attr "pent_pair" "pu")
6508
   (set_attr "mode" "SI")])
6509
 
6510
;; Overflow setting add and subtract instructions
6511
 
6512
(define_insn "*add3_cconly_overflow"
6513
  [(set (reg:CCC FLAGS_REG)
6514
        (compare:CCC
6515
          (plus:SWI
6516
            (match_operand:SWI 1 "nonimmediate_operand" "%0")
6517
            (match_operand:SWI 2 "" ""))
6518
          (match_dup 1)))
6519
   (clobber (match_scratch:SWI 0 "="))]
6520
  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6521
  "add{}\t{%2, %0|%0, %2}"
6522
  [(set_attr "type" "alu")
6523
   (set_attr "mode" "")])
6524
 
6525
(define_insn "*sub3_cconly_overflow"
6526
  [(set (reg:CCC FLAGS_REG)
6527
        (compare:CCC
6528
          (minus:SWI
6529
            (match_operand:SWI 0 "nonimmediate_operand" "m,")
6530
            (match_operand:SWI 1 "" ",m"))
6531
          (match_dup 0)))]
6532
  ""
6533
  "cmp{}\t{%1, %0|%0, %1}"
6534
  [(set_attr "type" "icmp")
6535
   (set_attr "mode" "")])
6536
 
6537
(define_insn "*3_cc_overflow"
6538
  [(set (reg:CCC FLAGS_REG)
6539
        (compare:CCC
6540
            (plusminus:SWI
6541
                (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6542
                (match_operand:SWI 2 "" ",m"))
6543
            (match_dup 1)))
6544
   (set (match_operand:SWI 0 "nonimmediate_operand" "=m,")
6545
        (plusminus:SWI (match_dup 1) (match_dup 2)))]
6546
  "ix86_binary_operator_ok (, mode, operands)"
6547
  "{}\t{%2, %0|%0, %2}"
6548
  [(set_attr "type" "alu")
6549
   (set_attr "mode" "")])
6550
 
6551
(define_insn "*si3_zext_cc_overflow"
6552
  [(set (reg:CCC FLAGS_REG)
6553
        (compare:CCC
6554
          (plusminus:SI
6555
            (match_operand:SI 1 "nonimmediate_operand" "0")
6556
            (match_operand:SI 2 "x86_64_general_operand" "rme"))
6557
          (match_dup 1)))
6558
   (set (match_operand:DI 0 "register_operand" "=r")
6559
        (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6560
  "TARGET_64BIT && ix86_binary_operator_ok (, SImode, operands)"
6561
  "{l}\t{%2, %k0|%k0, %2}"
6562
  [(set_attr "type" "alu")
6563
   (set_attr "mode" "SI")])
6564
 
6565
;; The patterns that match these are at the end of this file.
6566
 
6567
(define_expand "xf3"
6568
  [(set (match_operand:XF 0 "register_operand" "")
6569
        (plusminus:XF
6570
          (match_operand:XF 1 "register_operand" "")
6571
          (match_operand:XF 2 "register_operand" "")))]
6572
  "TARGET_80387")
6573
 
6574
(define_expand "3"
6575
  [(set (match_operand:MODEF 0 "register_operand" "")
6576
        (plusminus:MODEF
6577
          (match_operand:MODEF 1 "register_operand" "")
6578
          (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6579
  "(TARGET_80387 && X87_ENABLE_ARITH (mode))
6580
    || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)")
6581
 
6582
;; Multiply instructions
6583
 
6584
(define_expand "mul3"
6585
  [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6586
                   (mult:SWIM248
6587
                     (match_operand:SWIM248 1 "register_operand" "")
6588
                     (match_operand:SWIM248 2 "" "")))
6589
              (clobber (reg:CC FLAGS_REG))])])
6590
 
6591
(define_expand "mulqi3"
6592
  [(parallel [(set (match_operand:QI 0 "register_operand" "")
6593
                   (mult:QI
6594
                     (match_operand:QI 1 "register_operand" "")
6595
                     (match_operand:QI 2 "nonimmediate_operand" "")))
6596
              (clobber (reg:CC FLAGS_REG))])]
6597
  "TARGET_QIMODE_MATH")
6598
 
6599
;; On AMDFAM10
6600
;; IMUL reg32/64, reg32/64, imm8        Direct
6601
;; IMUL reg32/64, mem32/64, imm8        VectorPath
6602
;; IMUL reg32/64, reg32/64, imm32       Direct
6603
;; IMUL reg32/64, mem32/64, imm32       VectorPath
6604
;; IMUL reg32/64, reg32/64              Direct
6605
;; IMUL reg32/64, mem32/64              Direct
6606
;;
6607
;; On BDVER1, all above IMULs use DirectPath
6608
 
6609
(define_insn "*mul3_1"
6610
  [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6611
        (mult:SWI48
6612
          (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6613
          (match_operand:SWI48 2 "" "K,,mr")))
6614
   (clobber (reg:CC FLAGS_REG))]
6615
  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6616
  "@
6617
   imul{}\t{%2, %1, %0|%0, %1, %2}
6618
   imul{}\t{%2, %1, %0|%0, %1, %2}
6619
   imul{}\t{%2, %0|%0, %2}"
6620
  [(set_attr "type" "imul")
6621
   (set_attr "prefix_0f" "0,0,1")
6622
   (set (attr "athlon_decode")
6623
        (cond [(eq_attr "cpu" "athlon")
6624
                  (const_string "vector")
6625
               (eq_attr "alternative" "1")
6626
                  (const_string "vector")
6627
               (and (eq_attr "alternative" "2")
6628
                    (match_operand 1 "memory_operand" ""))
6629
                  (const_string "vector")]
6630
              (const_string "direct")))
6631
   (set (attr "amdfam10_decode")
6632
        (cond [(and (eq_attr "alternative" "0,1")
6633
                    (match_operand 1 "memory_operand" ""))
6634
                  (const_string "vector")]
6635
              (const_string "direct")))
6636
   (set_attr "bdver1_decode" "direct")
6637
   (set_attr "mode" "")])
6638
 
6639
(define_insn "*mulsi3_1_zext"
6640
  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6641
        (zero_extend:DI
6642
          (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6643
                   (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6644
   (clobber (reg:CC FLAGS_REG))]
6645
  "TARGET_64BIT
6646
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6647
  "@
6648
   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6649
   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6650
   imul{l}\t{%2, %k0|%k0, %2}"
6651
  [(set_attr "type" "imul")
6652
   (set_attr "prefix_0f" "0,0,1")
6653
   (set (attr "athlon_decode")
6654
        (cond [(eq_attr "cpu" "athlon")
6655
                  (const_string "vector")
6656
               (eq_attr "alternative" "1")
6657
                  (const_string "vector")
6658
               (and (eq_attr "alternative" "2")
6659
                    (match_operand 1 "memory_operand" ""))
6660
                  (const_string "vector")]
6661
              (const_string "direct")))
6662
   (set (attr "amdfam10_decode")
6663
        (cond [(and (eq_attr "alternative" "0,1")
6664
                    (match_operand 1 "memory_operand" ""))
6665
                  (const_string "vector")]
6666
              (const_string "direct")))
6667
   (set_attr "bdver1_decode" "direct")
6668
   (set_attr "mode" "SI")])
6669
 
6670
;; On AMDFAM10
6671
;; IMUL reg16, reg16, imm8      VectorPath
6672
;; IMUL reg16, mem16, imm8      VectorPath
6673
;; IMUL reg16, reg16, imm16     VectorPath
6674
;; IMUL reg16, mem16, imm16     VectorPath
6675
;; IMUL reg16, reg16            Direct
6676
;; IMUL reg16, mem16            Direct
6677
;;
6678
;; On BDVER1, all HI MULs use DoublePath
6679
 
6680
(define_insn "*mulhi3_1"
6681
  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6682
        (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6683
                 (match_operand:HI 2 "general_operand" "K,n,mr")))
6684
   (clobber (reg:CC FLAGS_REG))]
6685
  "TARGET_HIMODE_MATH
6686
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6687
  "@
6688
   imul{w}\t{%2, %1, %0|%0, %1, %2}
6689
   imul{w}\t{%2, %1, %0|%0, %1, %2}
6690
   imul{w}\t{%2, %0|%0, %2}"
6691
  [(set_attr "type" "imul")
6692
   (set_attr "prefix_0f" "0,0,1")
6693
   (set (attr "athlon_decode")
6694
        (cond [(eq_attr "cpu" "athlon")
6695
                  (const_string "vector")
6696
               (eq_attr "alternative" "1,2")
6697
                  (const_string "vector")]
6698
              (const_string "direct")))
6699
   (set (attr "amdfam10_decode")
6700
        (cond [(eq_attr "alternative" "0,1")
6701
                  (const_string "vector")]
6702
              (const_string "direct")))
6703
   (set_attr "bdver1_decode" "double")
6704
   (set_attr "mode" "HI")])
6705
 
6706
;;On AMDFAM10 and BDVER1
6707
;; MUL reg8     Direct
6708
;; MUL mem8     Direct
6709
 
6710
(define_insn "*mulqi3_1"
6711
  [(set (match_operand:QI 0 "register_operand" "=a")
6712
        (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6713
                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6714
   (clobber (reg:CC FLAGS_REG))]
6715
  "TARGET_QIMODE_MATH
6716
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6717
  "mul{b}\t%2"
6718
  [(set_attr "type" "imul")
6719
   (set_attr "length_immediate" "0")
6720
   (set (attr "athlon_decode")
6721
     (if_then_else (eq_attr "cpu" "athlon")
6722
        (const_string "vector")
6723
        (const_string "direct")))
6724
   (set_attr "amdfam10_decode" "direct")
6725
   (set_attr "bdver1_decode" "direct")
6726
   (set_attr "mode" "QI")])
6727
 
6728
(define_expand "mul3"
6729
  [(parallel [(set (match_operand: 0 "register_operand" "")
6730
                   (mult:
6731
                     (any_extend:
6732
                       (match_operand:DWIH 1 "nonimmediate_operand" ""))
6733
                     (any_extend:
6734
                       (match_operand:DWIH 2 "register_operand" ""))))
6735
              (clobber (reg:CC FLAGS_REG))])])
6736
 
6737
(define_expand "mulqihi3"
6738
  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6739
                   (mult:HI
6740
                     (any_extend:HI
6741
                       (match_operand:QI 1 "nonimmediate_operand" ""))
6742
                     (any_extend:HI
6743
                       (match_operand:QI 2 "register_operand" ""))))
6744
              (clobber (reg:CC FLAGS_REG))])]
6745
  "TARGET_QIMODE_MATH")
6746
 
6747
(define_insn "*bmi2_umulditi3_1"
6748
  [(set (match_operand:DI 0 "register_operand" "=r")
6749
        (mult:DI
6750
          (match_operand:DI 2 "nonimmediate_operand" "%d")
6751
          (match_operand:DI 3 "nonimmediate_operand" "rm")))
6752
   (set (match_operand:DI 1 "register_operand" "=r")
6753
        (truncate:DI
6754
          (lshiftrt:TI
6755
            (mult:TI (zero_extend:TI (match_dup 2))
6756
                     (zero_extend:TI (match_dup 3)))
6757
            (const_int 64))))]
6758
  "TARGET_64BIT && TARGET_BMI2
6759
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6760
  "mulx\t{%3, %0, %1|%1, %0, %3}"
6761
  [(set_attr "type" "imulx")
6762
   (set_attr "prefix" "vex")
6763
   (set_attr "mode" "DI")])
6764
 
6765
(define_insn "*bmi2_umulsidi3_1"
6766
  [(set (match_operand:SI 0 "register_operand" "=r")
6767
        (mult:SI
6768
          (match_operand:SI 2 "nonimmediate_operand" "%d")
6769
          (match_operand:SI 3 "nonimmediate_operand" "rm")))
6770
   (set (match_operand:SI 1 "register_operand" "=r")
6771
        (truncate:SI
6772
          (lshiftrt:DI
6773
            (mult:DI (zero_extend:DI (match_dup 2))
6774
                     (zero_extend:DI (match_dup 3)))
6775
            (const_int 32))))]
6776
  "!TARGET_64BIT && TARGET_BMI2
6777
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6778
  "mulx\t{%3, %0, %1|%1, %0, %3}"
6779
  [(set_attr "type" "imulx")
6780
   (set_attr "prefix" "vex")
6781
   (set_attr "mode" "SI")])
6782
 
6783
(define_insn "*umul3_1"
6784
  [(set (match_operand: 0 "register_operand" "=A,r")
6785
        (mult:
6786
          (zero_extend:
6787
            (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6788
          (zero_extend:
6789
            (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6790
   (clobber (reg:CC FLAGS_REG))]
6791
  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6792
  "@
6793
   mul{}\t%2
6794
   #"
6795
  [(set_attr "isa" "*,bmi2")
6796
   (set_attr "type" "imul,imulx")
6797
   (set_attr "length_immediate" "0,*")
6798
   (set (attr "athlon_decode")
6799
        (cond [(eq_attr "alternative" "0")
6800
                 (if_then_else (eq_attr "cpu" "athlon")
6801
                   (const_string "vector")
6802
                   (const_string "double"))]
6803
              (const_string "*")))
6804
   (set_attr "amdfam10_decode" "double,*")
6805
   (set_attr "bdver1_decode" "direct,*")
6806
   (set_attr "prefix" "orig,vex")
6807
   (set_attr "mode" "")])
6808
 
6809
;; Convert mul to the mulx pattern to avoid flags dependency.
6810
(define_split
6811
 [(set (match_operand: 0 "register_operand" "")
6812
       (mult:
6813
         (zero_extend:
6814
           (match_operand:DWIH 1 "register_operand" ""))
6815
         (zero_extend:
6816
           (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6817
  (clobber (reg:CC FLAGS_REG))]
6818
 "TARGET_BMI2 && reload_completed
6819
  && true_regnum (operands[1]) == DX_REG"
6820
  [(parallel [(set (match_dup 3)
6821
                   (mult:DWIH (match_dup 1) (match_dup 2)))
6822
              (set (match_dup 4)
6823
                   (truncate:DWIH
6824
                     (lshiftrt:
6825
                       (mult: (zero_extend: (match_dup 1))
6826
                                   (zero_extend: (match_dup 2)))
6827
                       (match_dup 5))))])]
6828
{
6829
  split_double_mode (mode, &operands[0], 1, &operands[3], &operands[4]);
6830
 
6831
  operands[5] = GEN_INT (GET_MODE_BITSIZE (mode));
6832
})
6833
 
6834
(define_insn "*mul3_1"
6835
  [(set (match_operand: 0 "register_operand" "=A")
6836
        (mult:
6837
          (sign_extend:
6838
            (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6839
          (sign_extend:
6840
            (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6841
   (clobber (reg:CC FLAGS_REG))]
6842
  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6843
  "imul{}\t%2"
6844
  [(set_attr "type" "imul")
6845
   (set_attr "length_immediate" "0")
6846
   (set (attr "athlon_decode")
6847
     (if_then_else (eq_attr "cpu" "athlon")
6848
        (const_string "vector")
6849
        (const_string "double")))
6850
   (set_attr "amdfam10_decode" "double")
6851
   (set_attr "bdver1_decode" "direct")
6852
   (set_attr "mode" "")])
6853
 
6854
(define_insn "*mulqihi3_1"
6855
  [(set (match_operand:HI 0 "register_operand" "=a")
6856
        (mult:HI
6857
          (any_extend:HI
6858
            (match_operand:QI 1 "nonimmediate_operand" "%0"))
6859
          (any_extend:HI
6860
            (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6861
   (clobber (reg:CC FLAGS_REG))]
6862
  "TARGET_QIMODE_MATH
6863
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6864
  "mul{b}\t%2"
6865
  [(set_attr "type" "imul")
6866
   (set_attr "length_immediate" "0")
6867
   (set (attr "athlon_decode")
6868
     (if_then_else (eq_attr "cpu" "athlon")
6869
        (const_string "vector")
6870
        (const_string "direct")))
6871
   (set_attr "amdfam10_decode" "direct")
6872
   (set_attr "bdver1_decode" "direct")
6873
   (set_attr "mode" "QI")])
6874
 
6875
(define_expand "mul3_highpart"
6876
  [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6877
                   (truncate:SWI48
6878
                     (lshiftrt:
6879
                       (mult:
6880
                         (any_extend:
6881
                           (match_operand:SWI48 1 "nonimmediate_operand" ""))
6882
                         (any_extend:
6883
                           (match_operand:SWI48 2 "register_operand" "")))
6884
                       (match_dup 4))))
6885
              (clobber (match_scratch:SWI48 3 ""))
6886
              (clobber (reg:CC FLAGS_REG))])]
6887
  ""
6888
  "operands[4] = GEN_INT (GET_MODE_BITSIZE (mode));")
6889
 
6890
(define_insn "*muldi3_highpart_1"
6891
  [(set (match_operand:DI 0 "register_operand" "=d")
6892
        (truncate:DI
6893
          (lshiftrt:TI
6894
            (mult:TI
6895
              (any_extend:TI
6896
                (match_operand:DI 1 "nonimmediate_operand" "%a"))
6897
              (any_extend:TI
6898
                (match_operand:DI 2 "nonimmediate_operand" "rm")))
6899
            (const_int 64))))
6900
   (clobber (match_scratch:DI 3 "=1"))
6901
   (clobber (reg:CC FLAGS_REG))]
6902
  "TARGET_64BIT
6903
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6904
  "mul{q}\t%2"
6905
  [(set_attr "type" "imul")
6906
   (set_attr "length_immediate" "0")
6907
   (set (attr "athlon_decode")
6908
     (if_then_else (eq_attr "cpu" "athlon")
6909
        (const_string "vector")
6910
        (const_string "double")))
6911
   (set_attr "amdfam10_decode" "double")
6912
   (set_attr "bdver1_decode" "direct")
6913
   (set_attr "mode" "DI")])
6914
 
6915
(define_insn "*mulsi3_highpart_1"
6916
  [(set (match_operand:SI 0 "register_operand" "=d")
6917
        (truncate:SI
6918
          (lshiftrt:DI
6919
            (mult:DI
6920
              (any_extend:DI
6921
                (match_operand:SI 1 "nonimmediate_operand" "%a"))
6922
              (any_extend:DI
6923
                (match_operand:SI 2 "nonimmediate_operand" "rm")))
6924
            (const_int 32))))
6925
   (clobber (match_scratch:SI 3 "=1"))
6926
   (clobber (reg:CC FLAGS_REG))]
6927
  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6928
  "mul{l}\t%2"
6929
  [(set_attr "type" "imul")
6930
   (set_attr "length_immediate" "0")
6931
   (set (attr "athlon_decode")
6932
     (if_then_else (eq_attr "cpu" "athlon")
6933
        (const_string "vector")
6934
        (const_string "double")))
6935
   (set_attr "amdfam10_decode" "double")
6936
   (set_attr "bdver1_decode" "direct")
6937
   (set_attr "mode" "SI")])
6938
 
6939
(define_insn "*mulsi3_highpart_zext"
6940
  [(set (match_operand:DI 0 "register_operand" "=d")
6941
        (zero_extend:DI (truncate:SI
6942
          (lshiftrt:DI
6943
            (mult:DI (any_extend:DI
6944
                       (match_operand:SI 1 "nonimmediate_operand" "%a"))
6945
                     (any_extend:DI
6946
                       (match_operand:SI 2 "nonimmediate_operand" "rm")))
6947
            (const_int 32)))))
6948
   (clobber (match_scratch:SI 3 "=1"))
6949
   (clobber (reg:CC FLAGS_REG))]
6950
  "TARGET_64BIT
6951
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6952
  "mul{l}\t%2"
6953
  [(set_attr "type" "imul")
6954
   (set_attr "length_immediate" "0")
6955
   (set (attr "athlon_decode")
6956
     (if_then_else (eq_attr "cpu" "athlon")
6957
        (const_string "vector")
6958
        (const_string "double")))
6959
   (set_attr "amdfam10_decode" "double")
6960
   (set_attr "bdver1_decode" "direct")
6961
   (set_attr "mode" "SI")])
6962
 
6963
;; The patterns that match these are at the end of this file.
6964
 
6965
(define_expand "mulxf3"
6966
  [(set (match_operand:XF 0 "register_operand" "")
6967
        (mult:XF (match_operand:XF 1 "register_operand" "")
6968
                 (match_operand:XF 2 "register_operand" "")))]
6969
  "TARGET_80387")
6970
 
6971
(define_expand "mul3"
6972
  [(set (match_operand:MODEF 0 "register_operand" "")
6973
        (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6974
                    (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6975
  "(TARGET_80387 && X87_ENABLE_ARITH (mode))
6976
    || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)")
6977
 
6978
;; Divide instructions
6979
 
6980
;; The patterns that match these are at the end of this file.
6981
 
6982
(define_expand "divxf3"
6983
  [(set (match_operand:XF 0 "register_operand" "")
6984
        (div:XF (match_operand:XF 1 "register_operand" "")
6985
                (match_operand:XF 2 "register_operand" "")))]
6986
  "TARGET_80387")
6987
 
6988
(define_expand "divdf3"
6989
  [(set (match_operand:DF 0 "register_operand" "")
6990
        (div:DF (match_operand:DF 1 "register_operand" "")
6991
                (match_operand:DF 2 "nonimmediate_operand" "")))]
6992
   "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6993
    || (TARGET_SSE2 && TARGET_SSE_MATH)")
6994
 
6995
(define_expand "divsf3"
6996
  [(set (match_operand:SF 0 "register_operand" "")
6997
        (div:SF (match_operand:SF 1 "register_operand" "")
6998
                (match_operand:SF 2 "nonimmediate_operand" "")))]
6999
  "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7000
    || TARGET_SSE_MATH"
7001
{
7002
  if (TARGET_SSE_MATH
7003
      && TARGET_RECIP_DIV
7004
      && optimize_insn_for_speed_p ()
7005
      && flag_finite_math_only && !flag_trapping_math
7006
      && flag_unsafe_math_optimizations)
7007
    {
7008
      ix86_emit_swdivsf (operands[0], operands[1],
7009
                         operands[2], SFmode);
7010
      DONE;
7011
    }
7012
})
7013
 
7014
;; Divmod instructions.
7015
 
7016
(define_expand "divmod4"
7017
  [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7018
                   (div:SWIM248
7019
                     (match_operand:SWIM248 1 "register_operand" "")
7020
                     (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7021
              (set (match_operand:SWIM248 3 "register_operand" "")
7022
                   (mod:SWIM248 (match_dup 1) (match_dup 2)))
7023
              (clobber (reg:CC FLAGS_REG))])])
7024
 
7025
;; Split with 8bit unsigned divide:
7026
;;      if (dividend an divisor are in [0-255])
7027
;;         use 8bit unsigned integer divide
7028
;;       else
7029
;;         use original integer divide
7030
(define_split
7031
  [(set (match_operand:SWI48 0 "register_operand" "")
7032
        (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7033
                    (match_operand:SWI48 3 "nonimmediate_operand" "")))
7034
   (set (match_operand:SWI48 1 "register_operand" "")
7035
        (mod:SWI48 (match_dup 2) (match_dup 3)))
7036
   (clobber (reg:CC FLAGS_REG))]
7037
  "TARGET_USE_8BIT_IDIV
7038
   && TARGET_QIMODE_MATH
7039
   && can_create_pseudo_p ()
7040
   && !optimize_insn_for_size_p ()"
7041
  [(const_int 0)]
7042
  "ix86_split_idivmod (mode, operands, true); DONE;")
7043
 
7044
(define_insn_and_split "divmod4_1"
7045
  [(set (match_operand:SWI48 0 "register_operand" "=a")
7046
        (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7047
                   (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7048
   (set (match_operand:SWI48 1 "register_operand" "=&d")
7049
        (mod:SWI48 (match_dup 2) (match_dup 3)))
7050
   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7051
   (clobber (reg:CC FLAGS_REG))]
7052
  ""
7053
  "#"
7054
  "reload_completed"
7055
  [(parallel [(set (match_dup 1)
7056
                   (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7057
              (clobber (reg:CC FLAGS_REG))])
7058
   (parallel [(set (match_dup 0)
7059
                   (div:SWI48 (match_dup 2) (match_dup 3)))
7060
              (set (match_dup 1)
7061
                   (mod:SWI48 (match_dup 2) (match_dup 3)))
7062
              (use (match_dup 1))
7063
              (clobber (reg:CC FLAGS_REG))])]
7064
{
7065
  operands[5] = GEN_INT (GET_MODE_BITSIZE (mode)-1);
7066
 
7067
  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7068
    operands[4] = operands[2];
7069
  else
7070
    {
7071
      /* Avoid use of cltd in favor of a mov+shift.  */
7072
      emit_move_insn (operands[1], operands[2]);
7073
      operands[4] = operands[1];
7074
    }
7075
}
7076
  [(set_attr "type" "multi")
7077
   (set_attr "mode" "")])
7078
 
7079
(define_insn_and_split "*divmod4"
7080
  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7081
        (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7082
                    (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7083
   (set (match_operand:SWIM248 1 "register_operand" "=&d")
7084
        (mod:SWIM248 (match_dup 2) (match_dup 3)))
7085
   (clobber (reg:CC FLAGS_REG))]
7086
  ""
7087
  "#"
7088
  "reload_completed"
7089
  [(parallel [(set (match_dup 1)
7090
                   (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7091
              (clobber (reg:CC FLAGS_REG))])
7092
   (parallel [(set (match_dup 0)
7093
                   (div:SWIM248 (match_dup 2) (match_dup 3)))
7094
              (set (match_dup 1)
7095
                   (mod:SWIM248 (match_dup 2) (match_dup 3)))
7096
              (use (match_dup 1))
7097
              (clobber (reg:CC FLAGS_REG))])]
7098
{
7099
  operands[5] = GEN_INT (GET_MODE_BITSIZE (mode)-1);
7100
 
7101
  if (mode != HImode
7102
      && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7103
    operands[4] = operands[2];
7104
  else
7105
    {
7106
      /* Avoid use of cltd in favor of a mov+shift.  */
7107
      emit_move_insn (operands[1], operands[2]);
7108
      operands[4] = operands[1];
7109
    }
7110
}
7111
  [(set_attr "type" "multi")
7112
   (set_attr "mode" "")])
7113
 
7114
(define_insn "*divmod4_noext"
7115
  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7116
        (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7117
                    (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7118
   (set (match_operand:SWIM248 1 "register_operand" "=d")
7119
        (mod:SWIM248 (match_dup 2) (match_dup 3)))
7120
   (use (match_operand:SWIM248 4 "register_operand" "1"))
7121
   (clobber (reg:CC FLAGS_REG))]
7122
  ""
7123
  "idiv{}\t%3"
7124
  [(set_attr "type" "idiv")
7125
   (set_attr "mode" "")])
7126
 
7127
(define_expand "divmodqi4"
7128
  [(parallel [(set (match_operand:QI 0 "register_operand" "")
7129
                   (div:QI
7130
                     (match_operand:QI 1 "register_operand" "")
7131
                     (match_operand:QI 2 "nonimmediate_operand" "")))
7132
              (set (match_operand:QI 3 "register_operand" "")
7133
                   (mod:QI (match_dup 1) (match_dup 2)))
7134
              (clobber (reg:CC FLAGS_REG))])]
7135
  "TARGET_QIMODE_MATH"
7136
{
7137
  rtx div, mod, insn;
7138
  rtx tmp0, tmp1;
7139
 
7140
  tmp0 = gen_reg_rtx (HImode);
7141
  tmp1 = gen_reg_rtx (HImode);
7142
 
7143
  /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7144
     in AX.  */
7145
  emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7146
  emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7147
 
7148
  /* Extract remainder from AH.  */
7149
  tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7150
  insn = emit_move_insn (operands[3], tmp1);
7151
 
7152
  mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7153
  set_unique_reg_note (insn, REG_EQUAL, mod);
7154
 
7155
  /* Extract quotient from AL.  */
7156
  insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7157
 
7158
  div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7159
  set_unique_reg_note (insn, REG_EQUAL, div);
7160
 
7161
  DONE;
7162
})
7163
 
7164
;; Divide AX by r/m8, with result stored in
7165
;; AL <- Quotient
7166
;; AH <- Remainder
7167
;; Change div/mod to HImode and extend the second argument to HImode
7168
;; so that mode of div/mod matches with mode of arguments.  Otherwise
7169
;; combine may fail.
7170
(define_insn "divmodhiqi3"
7171
  [(set (match_operand:HI 0 "register_operand" "=a")
7172
        (ior:HI
7173
          (ashift:HI
7174
            (zero_extend:HI
7175
              (truncate:QI
7176
                (mod:HI (match_operand:HI 1 "register_operand" "0")
7177
                        (sign_extend:HI
7178
                          (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7179
            (const_int 8))
7180
          (zero_extend:HI
7181
            (truncate:QI
7182
              (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7183
   (clobber (reg:CC FLAGS_REG))]
7184
  "TARGET_QIMODE_MATH"
7185
  "idiv{b}\t%2"
7186
  [(set_attr "type" "idiv")
7187
   (set_attr "mode" "QI")])
7188
 
7189
(define_expand "udivmod4"
7190
  [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7191
                   (udiv:SWIM248
7192
                     (match_operand:SWIM248 1 "register_operand" "")
7193
                     (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7194
              (set (match_operand:SWIM248 3 "register_operand" "")
7195
                   (umod:SWIM248 (match_dup 1) (match_dup 2)))
7196
              (clobber (reg:CC FLAGS_REG))])])
7197
 
7198
;; Split with 8bit unsigned divide:
7199
;;      if (dividend an divisor are in [0-255])
7200
;;         use 8bit unsigned integer divide
7201
;;       else
7202
;;         use original integer divide
7203
(define_split
7204
  [(set (match_operand:SWI48 0 "register_operand" "")
7205
        (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7206
                    (match_operand:SWI48 3 "nonimmediate_operand" "")))
7207
   (set (match_operand:SWI48 1 "register_operand" "")
7208
        (umod:SWI48 (match_dup 2) (match_dup 3)))
7209
   (clobber (reg:CC FLAGS_REG))]
7210
  "TARGET_USE_8BIT_IDIV
7211
   && TARGET_QIMODE_MATH
7212
   && can_create_pseudo_p ()
7213
   && !optimize_insn_for_size_p ()"
7214
  [(const_int 0)]
7215
  "ix86_split_idivmod (mode, operands, false); DONE;")
7216
 
7217
(define_insn_and_split "udivmod4_1"
7218
  [(set (match_operand:SWI48 0 "register_operand" "=a")
7219
        (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7220
                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7221
   (set (match_operand:SWI48 1 "register_operand" "=&d")
7222
        (umod:SWI48 (match_dup 2) (match_dup 3)))
7223
   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7224
   (clobber (reg:CC FLAGS_REG))]
7225
  ""
7226
  "#"
7227
  "reload_completed"
7228
  [(set (match_dup 1) (const_int 0))
7229
   (parallel [(set (match_dup 0)
7230
                   (udiv:SWI48 (match_dup 2) (match_dup 3)))
7231
              (set (match_dup 1)
7232
                   (umod:SWI48 (match_dup 2) (match_dup 3)))
7233
              (use (match_dup 1))
7234
              (clobber (reg:CC FLAGS_REG))])]
7235
  ""
7236
  [(set_attr "type" "multi")
7237
   (set_attr "mode" "")])
7238
 
7239
(define_insn_and_split "*udivmod4"
7240
  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7241
        (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7242
                      (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7243
   (set (match_operand:SWIM248 1 "register_operand" "=&d")
7244
        (umod:SWIM248 (match_dup 2) (match_dup 3)))
7245
   (clobber (reg:CC FLAGS_REG))]
7246
  ""
7247
  "#"
7248
  "reload_completed"
7249
  [(set (match_dup 1) (const_int 0))
7250
   (parallel [(set (match_dup 0)
7251
                   (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7252
              (set (match_dup 1)
7253
                   (umod:SWIM248 (match_dup 2) (match_dup 3)))
7254
              (use (match_dup 1))
7255
              (clobber (reg:CC FLAGS_REG))])]
7256
  ""
7257
  [(set_attr "type" "multi")
7258
   (set_attr "mode" "")])
7259
 
7260
(define_insn "*udivmod4_noext"
7261
  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7262
        (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7263
                      (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7264
   (set (match_operand:SWIM248 1 "register_operand" "=d")
7265
        (umod:SWIM248 (match_dup 2) (match_dup 3)))
7266
   (use (match_operand:SWIM248 4 "register_operand" "1"))
7267
   (clobber (reg:CC FLAGS_REG))]
7268
  ""
7269
  "div{}\t%3"
7270
  [(set_attr "type" "idiv")
7271
   (set_attr "mode" "")])
7272
 
7273
(define_expand "udivmodqi4"
7274
  [(parallel [(set (match_operand:QI 0 "register_operand" "")
7275
                   (udiv:QI
7276
                     (match_operand:QI 1 "register_operand" "")
7277
                     (match_operand:QI 2 "nonimmediate_operand" "")))
7278
              (set (match_operand:QI 3 "register_operand" "")
7279
                   (umod:QI (match_dup 1) (match_dup 2)))
7280
              (clobber (reg:CC FLAGS_REG))])]
7281
  "TARGET_QIMODE_MATH"
7282
{
7283
  rtx div, mod, insn;
7284
  rtx tmp0, tmp1;
7285
 
7286
  tmp0 = gen_reg_rtx (HImode);
7287
  tmp1 = gen_reg_rtx (HImode);
7288
 
7289
  /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7290
     in AX.  */
7291
  emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7292
  emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7293
 
7294
  /* Extract remainder from AH.  */
7295
  tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7296
  tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7297
  insn = emit_move_insn (operands[3], tmp1);
7298
 
7299
  mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7300
  set_unique_reg_note (insn, REG_EQUAL, mod);
7301
 
7302
  /* Extract quotient from AL.  */
7303
  insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7304
 
7305
  div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7306
  set_unique_reg_note (insn, REG_EQUAL, div);
7307
 
7308
  DONE;
7309
})
7310
 
7311
(define_insn "udivmodhiqi3"
7312
  [(set (match_operand:HI 0 "register_operand" "=a")
7313
        (ior:HI
7314
          (ashift:HI
7315
            (zero_extend:HI
7316
              (truncate:QI
7317
                (mod:HI (match_operand:HI 1 "register_operand" "0")
7318
                        (zero_extend:HI
7319
                          (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7320
            (const_int 8))
7321
          (zero_extend:HI
7322
            (truncate:QI
7323
              (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7324
   (clobber (reg:CC FLAGS_REG))]
7325
  "TARGET_QIMODE_MATH"
7326
  "div{b}\t%2"
7327
  [(set_attr "type" "idiv")
7328
   (set_attr "mode" "QI")])
7329
 
7330
;; We cannot use div/idiv for double division, because it causes
7331
;; "division by zero" on the overflow and that's not what we expect
7332
;; from truncate.  Because true (non truncating) double division is
7333
;; never generated, we can't create this insn anyway.
7334
;
7335
;(define_insn ""
7336
;  [(set (match_operand:SI 0 "register_operand" "=a")
7337
;       (truncate:SI
7338
;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7339
;                  (zero_extend:DI
7340
;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7341
;   (set (match_operand:SI 3 "register_operand" "=d")
7342
;       (truncate:SI
7343
;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7344
;   (clobber (reg:CC FLAGS_REG))]
7345
;  ""
7346
;  "div{l}\t{%2, %0|%0, %2}"
7347
;  [(set_attr "type" "idiv")])
7348
 
7349
;;- Logical AND instructions
7350
 
7351
;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7352
;; Note that this excludes ah.
7353
 
7354
(define_expand "testsi_ccno_1"
7355
  [(set (reg:CCNO FLAGS_REG)
7356
        (compare:CCNO
7357
          (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7358
                  (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7359
          (const_int 0)))])
7360
 
7361
(define_expand "testqi_ccz_1"
7362
  [(set (reg:CCZ FLAGS_REG)
7363
        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7364
                             (match_operand:QI 1 "nonmemory_operand" ""))
7365
                 (const_int 0)))])
7366
 
7367
(define_expand "testdi_ccno_1"
7368
  [(set (reg:CCNO FLAGS_REG)
7369
        (compare:CCNO
7370
          (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7371
                  (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7372
          (const_int 0)))]
7373
  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7374
 
7375
(define_insn "*testdi_1"
7376
  [(set (reg FLAGS_REG)
7377
        (compare
7378
         (and:DI
7379
          (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7380
          (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7381
         (const_int 0)))]
7382
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7383
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7384
  "@
7385
   test{l}\t{%k1, %k0|%k0, %k1}
7386
   test{l}\t{%k1, %k0|%k0, %k1}
7387
   test{q}\t{%1, %0|%0, %1}
7388
   test{q}\t{%1, %0|%0, %1}
7389
   test{q}\t{%1, %0|%0, %1}"
7390
  [(set_attr "type" "test")
7391
   (set_attr "modrm" "0,1,0,1,1")
7392
   (set_attr "mode" "SI,SI,DI,DI,DI")])
7393
 
7394
(define_insn "*testqi_1_maybe_si"
7395
  [(set (reg FLAGS_REG)
7396
        (compare
7397
          (and:QI
7398
            (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7399
            (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7400
          (const_int 0)))]
7401
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7402
    && ix86_match_ccmode (insn,
7403
                         CONST_INT_P (operands[1])
7404
                         && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7405
{
7406
  if (which_alternative == 3)
7407
    {
7408
      if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7409
        operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7410
      return "test{l}\t{%1, %k0|%k0, %1}";
7411
    }
7412
  return "test{b}\t{%1, %0|%0, %1}";
7413
}
7414
  [(set_attr "type" "test")
7415
   (set_attr "modrm" "0,1,1,1")
7416
   (set_attr "mode" "QI,QI,QI,SI")
7417
   (set_attr "pent_pair" "uv,np,uv,np")])
7418
 
7419
(define_insn "*test_1"
7420
  [(set (reg FLAGS_REG)
7421
        (compare
7422
         (and:SWI124
7423
          (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,,m")
7424
          (match_operand:SWI124 1 "" ",,"))
7425
         (const_int 0)))]
7426
  "ix86_match_ccmode (insn, CCNOmode)
7427
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7428
  "test{}\t{%1, %0|%0, %1}"
7429
  [(set_attr "type" "test")
7430
   (set_attr "modrm" "0,1,1")
7431
   (set_attr "mode" "")
7432
   (set_attr "pent_pair" "uv,np,uv")])
7433
 
7434
(define_expand "testqi_ext_ccno_0"
7435
  [(set (reg:CCNO FLAGS_REG)
7436
        (compare:CCNO
7437
          (and:SI
7438
            (zero_extract:SI
7439
              (match_operand 0 "ext_register_operand" "")
7440
              (const_int 8)
7441
              (const_int 8))
7442
            (match_operand 1 "const_int_operand" ""))
7443
          (const_int 0)))])
7444
 
7445
(define_insn "*testqi_ext_0"
7446
  [(set (reg FLAGS_REG)
7447
        (compare
7448
          (and:SI
7449
            (zero_extract:SI
7450
              (match_operand 0 "ext_register_operand" "Q")
7451
              (const_int 8)
7452
              (const_int 8))
7453
            (match_operand 1 "const_int_operand" "n"))
7454
          (const_int 0)))]
7455
  "ix86_match_ccmode (insn, CCNOmode)"
7456
  "test{b}\t{%1, %h0|%h0, %1}"
7457
  [(set_attr "type" "test")
7458
   (set_attr "mode" "QI")
7459
   (set_attr "length_immediate" "1")
7460
   (set_attr "modrm" "1")
7461
   (set_attr "pent_pair" "np")])
7462
 
7463
(define_insn "*testqi_ext_1_rex64"
7464
  [(set (reg FLAGS_REG)
7465
        (compare
7466
          (and:SI
7467
            (zero_extract:SI
7468
              (match_operand 0 "ext_register_operand" "Q")
7469
              (const_int 8)
7470
              (const_int 8))
7471
            (zero_extend:SI
7472
              (match_operand:QI 1 "register_operand" "Q")))
7473
          (const_int 0)))]
7474
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7475
  "test{b}\t{%1, %h0|%h0, %1}"
7476
  [(set_attr "type" "test")
7477
   (set_attr "mode" "QI")])
7478
 
7479
(define_insn "*testqi_ext_1"
7480
  [(set (reg FLAGS_REG)
7481
        (compare
7482
          (and:SI
7483
            (zero_extract:SI
7484
              (match_operand 0 "ext_register_operand" "Q")
7485
              (const_int 8)
7486
              (const_int 8))
7487
            (zero_extend:SI
7488
              (match_operand:QI 1 "general_operand" "Qm")))
7489
          (const_int 0)))]
7490
  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7491
  "test{b}\t{%1, %h0|%h0, %1}"
7492
  [(set_attr "type" "test")
7493
   (set_attr "mode" "QI")])
7494
 
7495
(define_insn "*testqi_ext_2"
7496
  [(set (reg FLAGS_REG)
7497
        (compare
7498
          (and:SI
7499
            (zero_extract:SI
7500
              (match_operand 0 "ext_register_operand" "Q")
7501
              (const_int 8)
7502
              (const_int 8))
7503
            (zero_extract:SI
7504
              (match_operand 1 "ext_register_operand" "Q")
7505
              (const_int 8)
7506
              (const_int 8)))
7507
          (const_int 0)))]
7508
  "ix86_match_ccmode (insn, CCNOmode)"
7509
  "test{b}\t{%h1, %h0|%h0, %h1}"
7510
  [(set_attr "type" "test")
7511
   (set_attr "mode" "QI")])
7512
 
7513
(define_insn "*testqi_ext_3_rex64"
7514
  [(set (reg FLAGS_REG)
7515
        (compare (zero_extract:DI
7516
                   (match_operand 0 "nonimmediate_operand" "rm")
7517
                   (match_operand:DI 1 "const_int_operand" "")
7518
                   (match_operand:DI 2 "const_int_operand" ""))
7519
                 (const_int 0)))]
7520
  "TARGET_64BIT
7521
   && ix86_match_ccmode (insn, CCNOmode)
7522
   && INTVAL (operands[1]) > 0
7523
   && INTVAL (operands[2]) >= 0
7524
   /* Ensure that resulting mask is zero or sign extended operand.  */
7525
   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7526
       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7527
           && INTVAL (operands[1]) > 32))
7528
   && (GET_MODE (operands[0]) == SImode
7529
       || GET_MODE (operands[0]) == DImode
7530
       || GET_MODE (operands[0]) == HImode
7531
       || GET_MODE (operands[0]) == QImode)"
7532
  "#")
7533
 
7534
;; Combine likes to form bit extractions for some tests.  Humor it.
7535
(define_insn "*testqi_ext_3"
7536
  [(set (reg FLAGS_REG)
7537
        (compare (zero_extract:SI
7538
                   (match_operand 0 "nonimmediate_operand" "rm")
7539
                   (match_operand:SI 1 "const_int_operand" "")
7540
                   (match_operand:SI 2 "const_int_operand" ""))
7541
                 (const_int 0)))]
7542
  "ix86_match_ccmode (insn, CCNOmode)
7543
   && INTVAL (operands[1]) > 0
7544
   && INTVAL (operands[2]) >= 0
7545
   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7546
   && (GET_MODE (operands[0]) == SImode
7547
       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7548
       || GET_MODE (operands[0]) == HImode
7549
       || GET_MODE (operands[0]) == QImode)"
7550
  "#")
7551
 
7552
(define_split
7553
  [(set (match_operand 0 "flags_reg_operand" "")
7554
        (match_operator 1 "compare_operator"
7555
          [(zero_extract
7556
             (match_operand 2 "nonimmediate_operand" "")
7557
             (match_operand 3 "const_int_operand" "")
7558
             (match_operand 4 "const_int_operand" ""))
7559
           (const_int 0)]))]
7560
  "ix86_match_ccmode (insn, CCNOmode)"
7561
  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7562
{
7563
  rtx val = operands[2];
7564
  HOST_WIDE_INT len = INTVAL (operands[3]);
7565
  HOST_WIDE_INT pos = INTVAL (operands[4]);
7566
  HOST_WIDE_INT mask;
7567
  enum machine_mode mode, submode;
7568
 
7569
  mode = GET_MODE (val);
7570
  if (MEM_P (val))
7571
    {
7572
      /* ??? Combine likes to put non-volatile mem extractions in QImode
7573
         no matter the size of the test.  So find a mode that works.  */
7574
      if (! MEM_VOLATILE_P (val))
7575
        {
7576
          mode = smallest_mode_for_size (pos + len, MODE_INT);
7577
          val = adjust_address (val, mode, 0);
7578
        }
7579
    }
7580
  else if (GET_CODE (val) == SUBREG
7581
           && (submode = GET_MODE (SUBREG_REG (val)),
7582
               GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7583
           && pos + len <= GET_MODE_BITSIZE (submode)
7584
           && GET_MODE_CLASS (submode) == MODE_INT)
7585
    {
7586
      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7587
      mode = submode;
7588
      val = SUBREG_REG (val);
7589
    }
7590
  else if (mode == HImode && pos + len <= 8)
7591
    {
7592
      /* Small HImode tests can be converted to QImode.  */
7593
      mode = QImode;
7594
      val = gen_lowpart (QImode, val);
7595
    }
7596
 
7597
  if (len == HOST_BITS_PER_WIDE_INT)
7598
    mask = -1;
7599
  else
7600
    mask = ((HOST_WIDE_INT)1 << len) - 1;
7601
  mask <<= pos;
7602
 
7603
  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7604
})
7605
 
7606
;; Convert HImode/SImode test instructions with immediate to QImode ones.
7607
;; i386 does not allow to encode test with 8bit sign extended immediate, so
7608
;; this is relatively important trick.
7609
;; Do the conversion only post-reload to avoid limiting of the register class
7610
;; to QI regs.
7611
(define_split
7612
  [(set (match_operand 0 "flags_reg_operand" "")
7613
        (match_operator 1 "compare_operator"
7614
          [(and (match_operand 2 "register_operand" "")
7615
                (match_operand 3 "const_int_operand" ""))
7616
           (const_int 0)]))]
7617
   "reload_completed
7618
    && QI_REG_P (operands[2])
7619
    && GET_MODE (operands[2]) != QImode
7620
    && ((ix86_match_ccmode (insn, CCZmode)
7621
         && !(INTVAL (operands[3]) & ~(255 << 8)))
7622
        || (ix86_match_ccmode (insn, CCNOmode)
7623
            && !(INTVAL (operands[3]) & ~(127 << 8))))"
7624
  [(set (match_dup 0)
7625
        (match_op_dup 1
7626
          [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7627
                   (match_dup 3))
7628
           (const_int 0)]))]
7629
{
7630
  operands[2] = gen_lowpart (SImode, operands[2]);
7631
  operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7632
})
7633
 
7634
(define_split
7635
  [(set (match_operand 0 "flags_reg_operand" "")
7636
        (match_operator 1 "compare_operator"
7637
          [(and (match_operand 2 "nonimmediate_operand" "")
7638
                (match_operand 3 "const_int_operand" ""))
7639
           (const_int 0)]))]
7640
   "reload_completed
7641
    && GET_MODE (operands[2]) != QImode
7642
    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7643
    && ((ix86_match_ccmode (insn, CCZmode)
7644
         && !(INTVAL (operands[3]) & ~255))
7645
        || (ix86_match_ccmode (insn, CCNOmode)
7646
            && !(INTVAL (operands[3]) & ~127)))"
7647
  [(set (match_dup 0)
7648
        (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7649
                         (const_int 0)]))]
7650
{
7651
  operands[2] = gen_lowpart (QImode, operands[2]);
7652
  operands[3] = gen_lowpart (QImode, operands[3]);
7653
})
7654
 
7655
;; %%% This used to optimize known byte-wide and operations to memory,
7656
;; and sometimes to QImode registers.  If this is considered useful,
7657
;; it should be done with splitters.
7658
 
7659
(define_expand "and3"
7660
  [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7661
        (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7662
                  (match_operand:SWIM 2 "" "")))]
7663
  ""
7664
  "ix86_expand_binary_operator (AND, mode, operands); DONE;")
7665
 
7666
(define_insn "*anddi_1"
7667
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7668
        (and:DI
7669
         (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7670
         (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7671
   (clobber (reg:CC FLAGS_REG))]
7672
  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7673
{
7674
  switch (get_attr_type (insn))
7675
    {
7676
    case TYPE_IMOVX:
7677
      {
7678
        enum machine_mode mode;
7679
 
7680
        gcc_assert (CONST_INT_P (operands[2]));
7681
        if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7682
          mode = SImode;
7683
        else if (INTVAL (operands[2]) == 0xffff)
7684
          mode = HImode;
7685
        else
7686
          {
7687
            gcc_assert (INTVAL (operands[2]) == 0xff);
7688
            mode = QImode;
7689
          }
7690
 
7691
        operands[1] = gen_lowpart (mode, operands[1]);
7692
        if (mode == SImode)
7693
          return "mov{l}\t{%1, %k0|%k0, %1}";
7694
        else if (mode == HImode)
7695
          return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7696
        else
7697
          return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7698
      }
7699
 
7700
    default:
7701
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
7702
      if (get_attr_mode (insn) == MODE_SI)
7703
        return "and{l}\t{%k2, %k0|%k0, %k2}";
7704
      else
7705
        return "and{q}\t{%2, %0|%0, %2}";
7706
    }
7707
}
7708
  [(set_attr "type" "alu,alu,alu,imovx")
7709
   (set_attr "length_immediate" "*,*,*,0")
7710
   (set (attr "prefix_rex")
7711
     (if_then_else
7712
       (and (eq_attr "type" "imovx")
7713
            (and (match_test "INTVAL (operands[2]) == 0xff")
7714
                 (match_operand 1 "ext_QIreg_operand" "")))
7715
       (const_string "1")
7716
       (const_string "*")))
7717
   (set_attr "mode" "SI,DI,DI,SI")])
7718
 
7719
(define_insn "*andsi_1"
7720
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7721
        (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7722
                (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7723
   (clobber (reg:CC FLAGS_REG))]
7724
  "ix86_binary_operator_ok (AND, SImode, operands)"
7725
{
7726
  switch (get_attr_type (insn))
7727
    {
7728
    case TYPE_IMOVX:
7729
      {
7730
        enum machine_mode mode;
7731
 
7732
        gcc_assert (CONST_INT_P (operands[2]));
7733
        if (INTVAL (operands[2]) == 0xffff)
7734
          mode = HImode;
7735
        else
7736
          {
7737
            gcc_assert (INTVAL (operands[2]) == 0xff);
7738
            mode = QImode;
7739
          }
7740
 
7741
        operands[1] = gen_lowpart (mode, operands[1]);
7742
        if (mode == HImode)
7743
          return "movz{wl|x}\t{%1, %0|%0, %1}";
7744
        else
7745
          return "movz{bl|x}\t{%1, %0|%0, %1}";
7746
      }
7747
 
7748
    default:
7749
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
7750
      return "and{l}\t{%2, %0|%0, %2}";
7751
    }
7752
}
7753
  [(set_attr "type" "alu,alu,imovx")
7754
   (set (attr "prefix_rex")
7755
     (if_then_else
7756
       (and (eq_attr "type" "imovx")
7757
            (and (match_test "INTVAL (operands[2]) == 0xff")
7758
                 (match_operand 1 "ext_QIreg_operand" "")))
7759
       (const_string "1")
7760
       (const_string "*")))
7761
   (set_attr "length_immediate" "*,*,0")
7762
   (set_attr "mode" "SI")])
7763
 
7764
;; See comment for addsi_1_zext why we do use nonimmediate_operand
7765
(define_insn "*andsi_1_zext"
7766
  [(set (match_operand:DI 0 "register_operand" "=r")
7767
        (zero_extend:DI
7768
          (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7769
                  (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7770
   (clobber (reg:CC FLAGS_REG))]
7771
  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7772
  "and{l}\t{%2, %k0|%k0, %2}"
7773
  [(set_attr "type" "alu")
7774
   (set_attr "mode" "SI")])
7775
 
7776
(define_insn "*andhi_1"
7777
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7778
        (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7779
                (match_operand:HI 2 "general_operand" "rn,rm,L")))
7780
   (clobber (reg:CC FLAGS_REG))]
7781
  "ix86_binary_operator_ok (AND, HImode, operands)"
7782
{
7783
  switch (get_attr_type (insn))
7784
    {
7785
    case TYPE_IMOVX:
7786
      gcc_assert (CONST_INT_P (operands[2]));
7787
      gcc_assert (INTVAL (operands[2]) == 0xff);
7788
      return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7789
 
7790
    default:
7791
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
7792
 
7793
      return "and{w}\t{%2, %0|%0, %2}";
7794
    }
7795
}
7796
  [(set_attr "type" "alu,alu,imovx")
7797
   (set_attr "length_immediate" "*,*,0")
7798
   (set (attr "prefix_rex")
7799
     (if_then_else
7800
       (and (eq_attr "type" "imovx")
7801
            (match_operand 1 "ext_QIreg_operand" ""))
7802
       (const_string "1")
7803
       (const_string "*")))
7804
   (set_attr "mode" "HI,HI,SI")])
7805
 
7806
;; %%% Potential partial reg stall on alternative 2.  What to do?
7807
(define_insn "*andqi_1"
7808
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7809
        (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7810
                (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7811
   (clobber (reg:CC FLAGS_REG))]
7812
  "ix86_binary_operator_ok (AND, QImode, operands)"
7813
  "@
7814
   and{b}\t{%2, %0|%0, %2}
7815
   and{b}\t{%2, %0|%0, %2}
7816
   and{l}\t{%k2, %k0|%k0, %k2}"
7817
  [(set_attr "type" "alu")
7818
   (set_attr "mode" "QI,QI,SI")])
7819
 
7820
(define_insn "*andqi_1_slp"
7821
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7822
        (and:QI (match_dup 0)
7823
                (match_operand:QI 1 "general_operand" "qn,qmn")))
7824
   (clobber (reg:CC FLAGS_REG))]
7825
  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7826
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7827
  "and{b}\t{%1, %0|%0, %1}"
7828
  [(set_attr "type" "alu1")
7829
   (set_attr "mode" "QI")])
7830
 
7831
(define_split
7832
  [(set (match_operand 0 "register_operand" "")
7833
        (and (match_dup 0)
7834
             (const_int -65536)))
7835
   (clobber (reg:CC FLAGS_REG))]
7836
  "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7837
    || optimize_function_for_size_p (cfun)"
7838
  [(set (strict_low_part (match_dup 1)) (const_int 0))]
7839
  "operands[1] = gen_lowpart (HImode, operands[0]);")
7840
 
7841
(define_split
7842
  [(set (match_operand 0 "ext_register_operand" "")
7843
        (and (match_dup 0)
7844
             (const_int -256)))
7845
   (clobber (reg:CC FLAGS_REG))]
7846
  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7847
   && reload_completed"
7848
  [(set (strict_low_part (match_dup 1)) (const_int 0))]
7849
  "operands[1] = gen_lowpart (QImode, operands[0]);")
7850
 
7851
(define_split
7852
  [(set (match_operand 0 "ext_register_operand" "")
7853
        (and (match_dup 0)
7854
             (const_int -65281)))
7855
   (clobber (reg:CC FLAGS_REG))]
7856
  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7857
   && reload_completed"
7858
  [(parallel [(set (zero_extract:SI (match_dup 0)
7859
                                    (const_int 8)
7860
                                    (const_int 8))
7861
                   (xor:SI
7862
                     (zero_extract:SI (match_dup 0)
7863
                                      (const_int 8)
7864
                                      (const_int 8))
7865
                     (zero_extract:SI (match_dup 0)
7866
                                      (const_int 8)
7867
                                      (const_int 8))))
7868
              (clobber (reg:CC FLAGS_REG))])]
7869
  "operands[0] = gen_lowpart (SImode, operands[0]);")
7870
 
7871
(define_insn "*anddi_2"
7872
  [(set (reg FLAGS_REG)
7873
        (compare
7874
         (and:DI
7875
          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7876
          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7877
         (const_int 0)))
7878
   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7879
        (and:DI (match_dup 1) (match_dup 2)))]
7880
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7881
   && ix86_binary_operator_ok (AND, DImode, operands)"
7882
  "@
7883
   and{l}\t{%k2, %k0|%k0, %k2}
7884
   and{q}\t{%2, %0|%0, %2}
7885
   and{q}\t{%2, %0|%0, %2}"
7886
  [(set_attr "type" "alu")
7887
   (set_attr "mode" "SI,DI,DI")])
7888
 
7889
(define_insn "*andqi_2_maybe_si"
7890
  [(set (reg FLAGS_REG)
7891
        (compare (and:QI
7892
                  (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7893
                  (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7894
                 (const_int 0)))
7895
   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7896
        (and:QI (match_dup 1) (match_dup 2)))]
7897
  "ix86_binary_operator_ok (AND, QImode, operands)
7898
   && ix86_match_ccmode (insn,
7899
                         CONST_INT_P (operands[2])
7900
                         && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7901
{
7902
  if (which_alternative == 2)
7903
    {
7904
      if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7905
        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7906
      return "and{l}\t{%2, %k0|%k0, %2}";
7907
    }
7908
  return "and{b}\t{%2, %0|%0, %2}";
7909
}
7910
  [(set_attr "type" "alu")
7911
   (set_attr "mode" "QI,QI,SI")])
7912
 
7913
(define_insn "*and_2"
7914
  [(set (reg FLAGS_REG)
7915
        (compare (and:SWI124
7916
                  (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7917
                  (match_operand:SWI124 2 "" ","))
7918
                 (const_int 0)))
7919
   (set (match_operand:SWI124 0 "nonimmediate_operand" "=,m")
7920
        (and:SWI124 (match_dup 1) (match_dup 2)))]
7921
  "ix86_match_ccmode (insn, CCNOmode)
7922
   && ix86_binary_operator_ok (AND, mode, operands)"
7923
  "and{}\t{%2, %0|%0, %2}"
7924
  [(set_attr "type" "alu")
7925
   (set_attr "mode" "")])
7926
 
7927
;; See comment for addsi_1_zext why we do use nonimmediate_operand
7928
(define_insn "*andsi_2_zext"
7929
  [(set (reg FLAGS_REG)
7930
        (compare (and:SI
7931
                  (match_operand:SI 1 "nonimmediate_operand" "%0")
7932
                  (match_operand:SI 2 "x86_64_general_operand" "rme"))
7933
                 (const_int 0)))
7934
   (set (match_operand:DI 0 "register_operand" "=r")
7935
        (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7936
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7937
   && ix86_binary_operator_ok (AND, SImode, operands)"
7938
  "and{l}\t{%2, %k0|%k0, %2}"
7939
  [(set_attr "type" "alu")
7940
   (set_attr "mode" "SI")])
7941
 
7942
(define_insn "*andqi_2_slp"
7943
  [(set (reg FLAGS_REG)
7944
        (compare (and:QI
7945
                   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7946
                   (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7947
                 (const_int 0)))
7948
   (set (strict_low_part (match_dup 0))
7949
        (and:QI (match_dup 0) (match_dup 1)))]
7950
  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7951
   && ix86_match_ccmode (insn, CCNOmode)
7952
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7953
  "and{b}\t{%1, %0|%0, %1}"
7954
  [(set_attr "type" "alu1")
7955
   (set_attr "mode" "QI")])
7956
 
7957
;; ??? A bug in recog prevents it from recognizing a const_int as an
7958
;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7959
;; for a QImode operand, which of course failed.
7960
(define_insn "andqi_ext_0"
7961
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7962
                         (const_int 8)
7963
                         (const_int 8))
7964
        (and:SI
7965
          (zero_extract:SI
7966
            (match_operand 1 "ext_register_operand" "0")
7967
            (const_int 8)
7968
            (const_int 8))
7969
          (match_operand 2 "const_int_operand" "n")))
7970
   (clobber (reg:CC FLAGS_REG))]
7971
  ""
7972
  "and{b}\t{%2, %h0|%h0, %2}"
7973
  [(set_attr "type" "alu")
7974
   (set_attr "length_immediate" "1")
7975
   (set_attr "modrm" "1")
7976
   (set_attr "mode" "QI")])
7977
 
7978
;; Generated by peephole translating test to and.  This shows up
7979
;; often in fp comparisons.
7980
(define_insn "*andqi_ext_0_cc"
7981
  [(set (reg FLAGS_REG)
7982
        (compare
7983
          (and:SI
7984
            (zero_extract:SI
7985
              (match_operand 1 "ext_register_operand" "0")
7986
              (const_int 8)
7987
              (const_int 8))
7988
            (match_operand 2 "const_int_operand" "n"))
7989
          (const_int 0)))
7990
   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7991
                         (const_int 8)
7992
                         (const_int 8))
7993
        (and:SI
7994
          (zero_extract:SI
7995
            (match_dup 1)
7996
            (const_int 8)
7997
            (const_int 8))
7998
          (match_dup 2)))]
7999
  "ix86_match_ccmode (insn, CCNOmode)"
8000
  "and{b}\t{%2, %h0|%h0, %2}"
8001
  [(set_attr "type" "alu")
8002
   (set_attr "length_immediate" "1")
8003
   (set_attr "modrm" "1")
8004
   (set_attr "mode" "QI")])
8005
 
8006
(define_insn "*andqi_ext_1_rex64"
8007
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8008
                         (const_int 8)
8009
                         (const_int 8))
8010
        (and:SI
8011
          (zero_extract:SI
8012
            (match_operand 1 "ext_register_operand" "0")
8013
            (const_int 8)
8014
            (const_int 8))
8015
          (zero_extend:SI
8016
            (match_operand 2 "ext_register_operand" "Q"))))
8017
   (clobber (reg:CC FLAGS_REG))]
8018
  "TARGET_64BIT"
8019
  "and{b}\t{%2, %h0|%h0, %2}"
8020
  [(set_attr "type" "alu")
8021
   (set_attr "length_immediate" "0")
8022
   (set_attr "mode" "QI")])
8023
 
8024
(define_insn "*andqi_ext_1"
8025
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8026
                         (const_int 8)
8027
                         (const_int 8))
8028
        (and:SI
8029
          (zero_extract:SI
8030
            (match_operand 1 "ext_register_operand" "0")
8031
            (const_int 8)
8032
            (const_int 8))
8033
          (zero_extend:SI
8034
            (match_operand:QI 2 "general_operand" "Qm"))))
8035
   (clobber (reg:CC FLAGS_REG))]
8036
  "!TARGET_64BIT"
8037
  "and{b}\t{%2, %h0|%h0, %2}"
8038
  [(set_attr "type" "alu")
8039
   (set_attr "length_immediate" "0")
8040
   (set_attr "mode" "QI")])
8041
 
8042
(define_insn "*andqi_ext_2"
8043
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8044
                         (const_int 8)
8045
                         (const_int 8))
8046
        (and:SI
8047
          (zero_extract:SI
8048
            (match_operand 1 "ext_register_operand" "%0")
8049
            (const_int 8)
8050
            (const_int 8))
8051
          (zero_extract:SI
8052
            (match_operand 2 "ext_register_operand" "Q")
8053
            (const_int 8)
8054
            (const_int 8))))
8055
   (clobber (reg:CC FLAGS_REG))]
8056
  ""
8057
  "and{b}\t{%h2, %h0|%h0, %h2}"
8058
  [(set_attr "type" "alu")
8059
   (set_attr "length_immediate" "0")
8060
   (set_attr "mode" "QI")])
8061
 
8062
;; Convert wide AND instructions with immediate operand to shorter QImode
8063
;; equivalents when possible.
8064
;; Don't do the splitting with memory operands, since it introduces risk
8065
;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8066
;; for size, but that can (should?) be handled by generic code instead.
8067
(define_split
8068
  [(set (match_operand 0 "register_operand" "")
8069
        (and (match_operand 1 "register_operand" "")
8070
             (match_operand 2 "const_int_operand" "")))
8071
   (clobber (reg:CC FLAGS_REG))]
8072
   "reload_completed
8073
    && QI_REG_P (operands[0])
8074
    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8075
    && !(~INTVAL (operands[2]) & ~(255 << 8))
8076
    && GET_MODE (operands[0]) != QImode"
8077
  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8078
                   (and:SI (zero_extract:SI (match_dup 1)
8079
                                            (const_int 8) (const_int 8))
8080
                           (match_dup 2)))
8081
              (clobber (reg:CC FLAGS_REG))])]
8082
{
8083
  operands[0] = gen_lowpart (SImode, operands[0]);
8084
  operands[1] = gen_lowpart (SImode, operands[1]);
8085
  operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8086
})
8087
 
8088
;; Since AND can be encoded with sign extended immediate, this is only
8089
;; profitable when 7th bit is not set.
8090
(define_split
8091
  [(set (match_operand 0 "register_operand" "")
8092
        (and (match_operand 1 "general_operand" "")
8093
             (match_operand 2 "const_int_operand" "")))
8094
   (clobber (reg:CC FLAGS_REG))]
8095
   "reload_completed
8096
    && ANY_QI_REG_P (operands[0])
8097
    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8098
    && !(~INTVAL (operands[2]) & ~255)
8099
    && !(INTVAL (operands[2]) & 128)
8100
    && GET_MODE (operands[0]) != QImode"
8101
  [(parallel [(set (strict_low_part (match_dup 0))
8102
                   (and:QI (match_dup 1)
8103
                           (match_dup 2)))
8104
              (clobber (reg:CC FLAGS_REG))])]
8105
{
8106
  operands[0] = gen_lowpart (QImode, operands[0]);
8107
  operands[1] = gen_lowpart (QImode, operands[1]);
8108
  operands[2] = gen_lowpart (QImode, operands[2]);
8109
})
8110
 
8111
;; Logical inclusive and exclusive OR instructions
8112
 
8113
;; %%% This used to optimize known byte-wide and operations to memory.
8114
;; If this is considered useful, it should be done with splitters.
8115
 
8116
(define_expand "3"
8117
  [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8118
        (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8119
                     (match_operand:SWIM 2 "" "")))]
8120
  ""
8121
  "ix86_expand_binary_operator (, mode, operands); DONE;")
8122
 
8123
(define_insn "*_1"
8124
  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8125
        (any_or:SWI248
8126
         (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8127
         (match_operand:SWI248 2 "" ",r")))
8128
   (clobber (reg:CC FLAGS_REG))]
8129
  "ix86_binary_operator_ok (, mode, operands)"
8130
  "{}\t{%2, %0|%0, %2}"
8131
  [(set_attr "type" "alu")
8132
   (set_attr "mode" "")])
8133
 
8134
;; %%% Potential partial reg stall on alternative 2.  What to do?
8135
(define_insn "*qi_1"
8136
  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8137
        (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8138
                   (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8139
   (clobber (reg:CC FLAGS_REG))]
8140
  "ix86_binary_operator_ok (, QImode, operands)"
8141
  "@
8142
   {b}\t{%2, %0|%0, %2}
8143
   {b}\t{%2, %0|%0, %2}
8144
   {l}\t{%k2, %k0|%k0, %k2}"
8145
  [(set_attr "type" "alu")
8146
   (set_attr "mode" "QI,QI,SI")])
8147
 
8148
;; See comment for addsi_1_zext why we do use nonimmediate_operand
8149
(define_insn "*si_1_zext"
8150
  [(set (match_operand:DI 0 "register_operand" "=r")
8151
        (zero_extend:DI
8152
         (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8153
                    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8154
   (clobber (reg:CC FLAGS_REG))]
8155
  "TARGET_64BIT && ix86_binary_operator_ok (, SImode, operands)"
8156
  "{l}\t{%2, %k0|%k0, %2}"
8157
  [(set_attr "type" "alu")
8158
   (set_attr "mode" "SI")])
8159
 
8160
(define_insn "*si_1_zext_imm"
8161
  [(set (match_operand:DI 0 "register_operand" "=r")
8162
        (any_or:DI
8163
         (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8164
         (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8165
   (clobber (reg:CC FLAGS_REG))]
8166
  "TARGET_64BIT && ix86_binary_operator_ok (, SImode, operands)"
8167
  "{l}\t{%2, %k0|%k0, %2}"
8168
  [(set_attr "type" "alu")
8169
   (set_attr "mode" "SI")])
8170
 
8171
(define_insn "*qi_1_slp"
8172
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8173
        (any_or:QI (match_dup 0)
8174
                   (match_operand:QI 1 "general_operand" "qmn,qn")))
8175
   (clobber (reg:CC FLAGS_REG))]
8176
  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8177
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8178
  "{b}\t{%1, %0|%0, %1}"
8179
  [(set_attr "type" "alu1")
8180
   (set_attr "mode" "QI")])
8181
 
8182
(define_insn "*_2"
8183
  [(set (reg FLAGS_REG)
8184
        (compare (any_or:SWI
8185
                  (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8186
                  (match_operand:SWI 2 "" ","))
8187
                 (const_int 0)))
8188
   (set (match_operand:SWI 0 "nonimmediate_operand" "=,m")
8189
        (any_or:SWI (match_dup 1) (match_dup 2)))]
8190
  "ix86_match_ccmode (insn, CCNOmode)
8191
   && ix86_binary_operator_ok (, mode, operands)"
8192
  "{}\t{%2, %0|%0, %2}"
8193
  [(set_attr "type" "alu")
8194
   (set_attr "mode" "")])
8195
 
8196
;; See comment for addsi_1_zext why we do use nonimmediate_operand
8197
;; ??? Special case for immediate operand is missing - it is tricky.
8198
(define_insn "*si_2_zext"
8199
  [(set (reg FLAGS_REG)
8200
        (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8201
                            (match_operand:SI 2 "x86_64_general_operand" "rme"))
8202
                 (const_int 0)))
8203
   (set (match_operand:DI 0 "register_operand" "=r")
8204
        (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8205
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8206
   && ix86_binary_operator_ok (, SImode, operands)"
8207
  "{l}\t{%2, %k0|%k0, %2}"
8208
  [(set_attr "type" "alu")
8209
   (set_attr "mode" "SI")])
8210
 
8211
(define_insn "*si_2_zext_imm"
8212
  [(set (reg FLAGS_REG)
8213
        (compare (any_or:SI
8214
                  (match_operand:SI 1 "nonimmediate_operand" "%0")
8215
                  (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8216
                 (const_int 0)))
8217
   (set (match_operand:DI 0 "register_operand" "=r")
8218
        (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8219
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8220
   && ix86_binary_operator_ok (, SImode, operands)"
8221
  "{l}\t{%2, %k0|%k0, %2}"
8222
  [(set_attr "type" "alu")
8223
   (set_attr "mode" "SI")])
8224
 
8225
(define_insn "*qi_2_slp"
8226
  [(set (reg FLAGS_REG)
8227
        (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8228
                            (match_operand:QI 1 "general_operand" "qmn,qn"))
8229
                 (const_int 0)))
8230
   (set (strict_low_part (match_dup 0))
8231
        (any_or:QI (match_dup 0) (match_dup 1)))]
8232
  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8233
   && ix86_match_ccmode (insn, CCNOmode)
8234
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8235
  "{b}\t{%1, %0|%0, %1}"
8236
  [(set_attr "type" "alu1")
8237
   (set_attr "mode" "QI")])
8238
 
8239
(define_insn "*_3"
8240
  [(set (reg FLAGS_REG)
8241
        (compare (any_or:SWI
8242
                  (match_operand:SWI 1 "nonimmediate_operand" "%0")
8243
                  (match_operand:SWI 2 "" ""))
8244
                 (const_int 0)))
8245
   (clobber (match_scratch:SWI 0 "="))]
8246
  "ix86_match_ccmode (insn, CCNOmode)
8247
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8248
  "{}\t{%2, %0|%0, %2}"
8249
  [(set_attr "type" "alu")
8250
   (set_attr "mode" "")])
8251
 
8252
(define_insn "*qi_ext_0"
8253
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8254
                         (const_int 8)
8255
                         (const_int 8))
8256
        (any_or:SI
8257
          (zero_extract:SI
8258
            (match_operand 1 "ext_register_operand" "0")
8259
            (const_int 8)
8260
            (const_int 8))
8261
          (match_operand 2 "const_int_operand" "n")))
8262
   (clobber (reg:CC FLAGS_REG))]
8263
  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8264
  "{b}\t{%2, %h0|%h0, %2}"
8265
  [(set_attr "type" "alu")
8266
   (set_attr "length_immediate" "1")
8267
   (set_attr "modrm" "1")
8268
   (set_attr "mode" "QI")])
8269
 
8270
(define_insn "*qi_ext_1_rex64"
8271
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8272
                         (const_int 8)
8273
                         (const_int 8))
8274
        (any_or:SI
8275
          (zero_extract:SI
8276
            (match_operand 1 "ext_register_operand" "0")
8277
            (const_int 8)
8278
            (const_int 8))
8279
          (zero_extend:SI
8280
            (match_operand 2 "ext_register_operand" "Q"))))
8281
   (clobber (reg:CC FLAGS_REG))]
8282
  "TARGET_64BIT
8283
   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8284
  "{b}\t{%2, %h0|%h0, %2}"
8285
  [(set_attr "type" "alu")
8286
   (set_attr "length_immediate" "0")
8287
   (set_attr "mode" "QI")])
8288
 
8289
(define_insn "*qi_ext_1"
8290
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8291
                         (const_int 8)
8292
                         (const_int 8))
8293
        (any_or:SI
8294
          (zero_extract:SI
8295
            (match_operand 1 "ext_register_operand" "0")
8296
            (const_int 8)
8297
            (const_int 8))
8298
          (zero_extend:SI
8299
            (match_operand:QI 2 "general_operand" "Qm"))))
8300
   (clobber (reg:CC FLAGS_REG))]
8301
  "!TARGET_64BIT
8302
   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8303
  "{b}\t{%2, %h0|%h0, %2}"
8304
  [(set_attr "type" "alu")
8305
   (set_attr "length_immediate" "0")
8306
   (set_attr "mode" "QI")])
8307
 
8308
(define_insn "*qi_ext_2"
8309
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8310
                         (const_int 8)
8311
                         (const_int 8))
8312
        (any_or:SI
8313
          (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8314
                           (const_int 8)
8315
                           (const_int 8))
8316
          (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8317
                           (const_int 8)
8318
                           (const_int 8))))
8319
   (clobber (reg:CC FLAGS_REG))]
8320
  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8321
  "{b}\t{%h2, %h0|%h0, %h2}"
8322
  [(set_attr "type" "alu")
8323
   (set_attr "length_immediate" "0")
8324
   (set_attr "mode" "QI")])
8325
 
8326
(define_split
8327
  [(set (match_operand 0 "register_operand" "")
8328
        (any_or (match_operand 1 "register_operand" "")
8329
                (match_operand 2 "const_int_operand" "")))
8330
   (clobber (reg:CC FLAGS_REG))]
8331
   "reload_completed
8332
    && QI_REG_P (operands[0])
8333
    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8334
    && !(INTVAL (operands[2]) & ~(255 << 8))
8335
    && GET_MODE (operands[0]) != QImode"
8336
  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8337
                   (any_or:SI (zero_extract:SI (match_dup 1)
8338
                                               (const_int 8) (const_int 8))
8339
                              (match_dup 2)))
8340
              (clobber (reg:CC FLAGS_REG))])]
8341
{
8342
  operands[0] = gen_lowpart (SImode, operands[0]);
8343
  operands[1] = gen_lowpart (SImode, operands[1]);
8344
  operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8345
})
8346
 
8347
;; Since OR can be encoded with sign extended immediate, this is only
8348
;; profitable when 7th bit is set.
8349
(define_split
8350
  [(set (match_operand 0 "register_operand" "")
8351
        (any_or (match_operand 1 "general_operand" "")
8352
                (match_operand 2 "const_int_operand" "")))
8353
   (clobber (reg:CC FLAGS_REG))]
8354
   "reload_completed
8355
    && ANY_QI_REG_P (operands[0])
8356
    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8357
    && !(INTVAL (operands[2]) & ~255)
8358
    && (INTVAL (operands[2]) & 128)
8359
    && GET_MODE (operands[0]) != QImode"
8360
  [(parallel [(set (strict_low_part (match_dup 0))
8361
                   (any_or:QI (match_dup 1)
8362
                              (match_dup 2)))
8363
              (clobber (reg:CC FLAGS_REG))])]
8364
{
8365
  operands[0] = gen_lowpart (QImode, operands[0]);
8366
  operands[1] = gen_lowpart (QImode, operands[1]);
8367
  operands[2] = gen_lowpart (QImode, operands[2]);
8368
})
8369
 
8370
(define_expand "xorqi_cc_ext_1"
8371
  [(parallel [
8372
     (set (reg:CCNO FLAGS_REG)
8373
          (compare:CCNO
8374
            (xor:SI
8375
              (zero_extract:SI
8376
                (match_operand 1 "ext_register_operand" "")
8377
                (const_int 8)
8378
                (const_int 8))
8379
              (match_operand:QI 2 "general_operand" ""))
8380
            (const_int 0)))
8381
     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8382
                           (const_int 8)
8383
                           (const_int 8))
8384
          (xor:SI
8385
            (zero_extract:SI
8386
             (match_dup 1)
8387
             (const_int 8)
8388
             (const_int 8))
8389
            (match_dup 2)))])])
8390
 
8391
(define_insn "*xorqi_cc_ext_1_rex64"
8392
  [(set (reg FLAGS_REG)
8393
        (compare
8394
          (xor:SI
8395
            (zero_extract:SI
8396
              (match_operand 1 "ext_register_operand" "0")
8397
              (const_int 8)
8398
              (const_int 8))
8399
            (match_operand:QI 2 "nonmemory_operand" "Qn"))
8400
          (const_int 0)))
8401
   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8402
                         (const_int 8)
8403
                         (const_int 8))
8404
        (xor:SI
8405
          (zero_extract:SI
8406
           (match_dup 1)
8407
           (const_int 8)
8408
           (const_int 8))
8409
          (match_dup 2)))]
8410
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8411
  "xor{b}\t{%2, %h0|%h0, %2}"
8412
  [(set_attr "type" "alu")
8413
   (set_attr "modrm" "1")
8414
   (set_attr "mode" "QI")])
8415
 
8416
(define_insn "*xorqi_cc_ext_1"
8417
  [(set (reg FLAGS_REG)
8418
        (compare
8419
          (xor:SI
8420
            (zero_extract:SI
8421
              (match_operand 1 "ext_register_operand" "0")
8422
              (const_int 8)
8423
              (const_int 8))
8424
            (match_operand:QI 2 "general_operand" "qmn"))
8425
          (const_int 0)))
8426
   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8427
                         (const_int 8)
8428
                         (const_int 8))
8429
        (xor:SI
8430
          (zero_extract:SI
8431
           (match_dup 1)
8432
           (const_int 8)
8433
           (const_int 8))
8434
          (match_dup 2)))]
8435
  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8436
  "xor{b}\t{%2, %h0|%h0, %2}"
8437
  [(set_attr "type" "alu")
8438
   (set_attr "modrm" "1")
8439
   (set_attr "mode" "QI")])
8440
 
8441
;; Negation instructions
8442
 
8443
(define_expand "neg2"
8444
  [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8445
        (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8446
  ""
8447
  "ix86_expand_unary_operator (NEG, mode, operands); DONE;")
8448
 
8449
(define_insn_and_split "*neg2_doubleword"
8450
  [(set (match_operand: 0 "nonimmediate_operand" "=ro")
8451
        (neg: (match_operand: 1 "nonimmediate_operand" "0")))
8452
   (clobber (reg:CC FLAGS_REG))]
8453
  "ix86_unary_operator_ok (NEG, mode, operands)"
8454
  "#"
8455
  "reload_completed"
8456
  [(parallel
8457
    [(set (reg:CCZ FLAGS_REG)
8458
          (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8459
     (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8460
   (parallel
8461
    [(set (match_dup 2)
8462
          (plus:DWIH (match_dup 3)
8463
                     (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8464
                                (const_int 0))))
8465
     (clobber (reg:CC FLAGS_REG))])
8466
   (parallel
8467
    [(set (match_dup 2)
8468
          (neg:DWIH (match_dup 2)))
8469
     (clobber (reg:CC FLAGS_REG))])]
8470
  "split_double_mode (mode, &operands[0], 2, &operands[0], &operands[2]);")
8471
 
8472
(define_insn "*neg2_1"
8473
  [(set (match_operand:SWI 0 "nonimmediate_operand" "=m")
8474
        (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8475
   (clobber (reg:CC FLAGS_REG))]
8476
  "ix86_unary_operator_ok (NEG, mode, operands)"
8477
  "neg{}\t%0"
8478
  [(set_attr "type" "negnot")
8479
   (set_attr "mode" "")])
8480
 
8481
;; Combine is quite creative about this pattern.
8482
(define_insn "*negsi2_1_zext"
8483
  [(set (match_operand:DI 0 "register_operand" "=r")
8484
        (lshiftrt:DI
8485
          (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8486
                             (const_int 32)))
8487
        (const_int 32)))
8488
   (clobber (reg:CC FLAGS_REG))]
8489
  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8490
  "neg{l}\t%k0"
8491
  [(set_attr "type" "negnot")
8492
   (set_attr "mode" "SI")])
8493
 
8494
;; The problem with neg is that it does not perform (compare x 0),
8495
;; it really performs (compare 0 x), which leaves us with the zero
8496
;; flag being the only useful item.
8497
 
8498
(define_insn "*neg2_cmpz"
8499
  [(set (reg:CCZ FLAGS_REG)
8500
        (compare:CCZ
8501
          (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8502
                   (const_int 0)))
8503
   (set (match_operand:SWI 0 "nonimmediate_operand" "=m")
8504
        (neg:SWI (match_dup 1)))]
8505
  "ix86_unary_operator_ok (NEG, mode, operands)"
8506
  "neg{}\t%0"
8507
  [(set_attr "type" "negnot")
8508
   (set_attr "mode" "")])
8509
 
8510
(define_insn "*negsi2_cmpz_zext"
8511
  [(set (reg:CCZ FLAGS_REG)
8512
        (compare:CCZ
8513
          (lshiftrt:DI
8514
            (neg:DI (ashift:DI
8515
                      (match_operand:DI 1 "register_operand" "0")
8516
                      (const_int 32)))
8517
            (const_int 32))
8518
          (const_int 0)))
8519
   (set (match_operand:DI 0 "register_operand" "=r")
8520
        (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8521
                                        (const_int 32)))
8522
                     (const_int 32)))]
8523
  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8524
  "neg{l}\t%k0"
8525
  [(set_attr "type" "negnot")
8526
   (set_attr "mode" "SI")])
8527
 
8528
;; Changing of sign for FP values is doable using integer unit too.
8529
 
8530
(define_expand "2"
8531
  [(set (match_operand:X87MODEF 0 "register_operand" "")
8532
        (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8533
  "TARGET_80387 || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
8534
  "ix86_expand_fp_absneg_operator (, mode, operands); DONE;")
8535
 
8536
(define_insn "*absneg2_mixed"
8537
  [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8538
        (match_operator:MODEF 3 "absneg_operator"
8539
          [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8540
   (use (match_operand: 2 "nonimmediate_operand" "xm,0,X,X"))
8541
   (clobber (reg:CC FLAGS_REG))]
8542
  "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (mode)"
8543
  "#")
8544
 
8545
(define_insn "*absneg2_sse"
8546
  [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8547
        (match_operator:MODEF 3 "absneg_operator"
8548
          [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8549
   (use (match_operand: 2 "register_operand" "xm,0,X"))
8550
   (clobber (reg:CC FLAGS_REG))]
8551
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
8552
  "#")
8553
 
8554
(define_insn "*absneg2_i387"
8555
  [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8556
        (match_operator:X87MODEF 3 "absneg_operator"
8557
          [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8558
   (use (match_operand 2 "" ""))
8559
   (clobber (reg:CC FLAGS_REG))]
8560
  "TARGET_80387 && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
8561
  "#")
8562
 
8563
(define_expand "tf2"
8564
  [(set (match_operand:TF 0 "register_operand" "")
8565
        (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8566
  "TARGET_SSE2"
8567
  "ix86_expand_fp_absneg_operator (, TFmode, operands); DONE;")
8568
 
8569
(define_insn "*absnegtf2_sse"
8570
  [(set (match_operand:TF 0 "register_operand" "=x,x")
8571
        (match_operator:TF 3 "absneg_operator"
8572
          [(match_operand:TF 1 "register_operand" "0,x")]))
8573
   (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8574
   (clobber (reg:CC FLAGS_REG))]
8575
  "TARGET_SSE2"
8576
  "#")
8577
 
8578
;; Splitters for fp abs and neg.
8579
 
8580
(define_split
8581
  [(set (match_operand 0 "fp_register_operand" "")
8582
        (match_operator 1 "absneg_operator" [(match_dup 0)]))
8583
   (use (match_operand 2 "" ""))
8584
   (clobber (reg:CC FLAGS_REG))]
8585
  "reload_completed"
8586
  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8587
 
8588
(define_split
8589
  [(set (match_operand 0 "register_operand" "")
8590
        (match_operator 3 "absneg_operator"
8591
          [(match_operand 1 "register_operand" "")]))
8592
   (use (match_operand 2 "nonimmediate_operand" ""))
8593
   (clobber (reg:CC FLAGS_REG))]
8594
  "reload_completed && SSE_REG_P (operands[0])"
8595
  [(set (match_dup 0) (match_dup 3))]
8596
{
8597
  enum machine_mode mode = GET_MODE (operands[0]);
8598
  enum machine_mode vmode = GET_MODE (operands[2]);
8599
  rtx tmp;
8600
 
8601
  operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8602
  operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8603
  if (operands_match_p (operands[0], operands[2]))
8604
    {
8605
      tmp = operands[1];
8606
      operands[1] = operands[2];
8607
      operands[2] = tmp;
8608
    }
8609
  if (GET_CODE (operands[3]) == ABS)
8610
    tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8611
  else
8612
    tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8613
  operands[3] = tmp;
8614
})
8615
 
8616
(define_split
8617
  [(set (match_operand:SF 0 "register_operand" "")
8618
        (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8619
   (use (match_operand:V4SF 2 "" ""))
8620
   (clobber (reg:CC FLAGS_REG))]
8621
  "reload_completed"
8622
  [(parallel [(set (match_dup 0) (match_dup 1))
8623
              (clobber (reg:CC FLAGS_REG))])]
8624
{
8625
  rtx tmp;
8626
  operands[0] = gen_lowpart (SImode, operands[0]);
8627
  if (GET_CODE (operands[1]) == ABS)
8628
    {
8629
      tmp = gen_int_mode (0x7fffffff, SImode);
8630
      tmp = gen_rtx_AND (SImode, operands[0], tmp);
8631
    }
8632
  else
8633
    {
8634
      tmp = gen_int_mode (0x80000000, SImode);
8635
      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8636
    }
8637
  operands[1] = tmp;
8638
})
8639
 
8640
(define_split
8641
  [(set (match_operand:DF 0 "register_operand" "")
8642
        (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8643
   (use (match_operand 2 "" ""))
8644
   (clobber (reg:CC FLAGS_REG))]
8645
  "reload_completed"
8646
  [(parallel [(set (match_dup 0) (match_dup 1))
8647
              (clobber (reg:CC FLAGS_REG))])]
8648
{
8649
  rtx tmp;
8650
  if (TARGET_64BIT)
8651
    {
8652
      tmp = gen_lowpart (DImode, operands[0]);
8653
      tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8654
      operands[0] = tmp;
8655
 
8656
      if (GET_CODE (operands[1]) == ABS)
8657
        tmp = const0_rtx;
8658
      else
8659
        tmp = gen_rtx_NOT (DImode, tmp);
8660
    }
8661
  else
8662
    {
8663
      operands[0] = gen_highpart (SImode, operands[0]);
8664
      if (GET_CODE (operands[1]) == ABS)
8665
        {
8666
          tmp = gen_int_mode (0x7fffffff, SImode);
8667
          tmp = gen_rtx_AND (SImode, operands[0], tmp);
8668
        }
8669
      else
8670
        {
8671
          tmp = gen_int_mode (0x80000000, SImode);
8672
          tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8673
        }
8674
    }
8675
  operands[1] = tmp;
8676
})
8677
 
8678
(define_split
8679
  [(set (match_operand:XF 0 "register_operand" "")
8680
        (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8681
   (use (match_operand 2 "" ""))
8682
   (clobber (reg:CC FLAGS_REG))]
8683
  "reload_completed"
8684
  [(parallel [(set (match_dup 0) (match_dup 1))
8685
              (clobber (reg:CC FLAGS_REG))])]
8686
{
8687
  rtx tmp;
8688
  operands[0] = gen_rtx_REG (SImode,
8689
                             true_regnum (operands[0])
8690
                             + (TARGET_64BIT ? 1 : 2));
8691
  if (GET_CODE (operands[1]) == ABS)
8692
    {
8693
      tmp = GEN_INT (0x7fff);
8694
      tmp = gen_rtx_AND (SImode, operands[0], tmp);
8695
    }
8696
  else
8697
    {
8698
      tmp = GEN_INT (0x8000);
8699
      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8700
    }
8701
  operands[1] = tmp;
8702
})
8703
 
8704
;; Conditionalize these after reload. If they match before reload, we
8705
;; lose the clobber and ability to use integer instructions.
8706
 
8707
(define_insn "*2_1"
8708
  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8709
        (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8710
  "TARGET_80387
8711
   && (reload_completed
8712
       || !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))"
8713
  "f"
8714
  [(set_attr "type" "fsgn")
8715
   (set_attr "mode" "")])
8716
 
8717
(define_insn "*extendsfdf2"
8718
  [(set (match_operand:DF 0 "register_operand" "=f")
8719
        (absneg:DF (float_extend:DF
8720
                     (match_operand:SF 1 "register_operand" "0"))))]
8721
  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8722
  "f"
8723
  [(set_attr "type" "fsgn")
8724
   (set_attr "mode" "DF")])
8725
 
8726
(define_insn "*extendsfxf2"
8727
  [(set (match_operand:XF 0 "register_operand" "=f")
8728
        (absneg:XF (float_extend:XF
8729
                     (match_operand:SF 1 "register_operand" "0"))))]
8730
  "TARGET_80387"
8731
  "f"
8732
  [(set_attr "type" "fsgn")
8733
   (set_attr "mode" "XF")])
8734
 
8735
(define_insn "*extenddfxf2"
8736
  [(set (match_operand:XF 0 "register_operand" "=f")
8737
        (absneg:XF (float_extend:XF
8738
                     (match_operand:DF 1 "register_operand" "0"))))]
8739
  "TARGET_80387"
8740
  "f"
8741
  [(set_attr "type" "fsgn")
8742
   (set_attr "mode" "XF")])
8743
 
8744
;; Copysign instructions
8745
 
8746
(define_mode_iterator CSGNMODE [SF DF TF])
8747
(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8748
 
8749
(define_expand "copysign3"
8750
  [(match_operand:CSGNMODE 0 "register_operand" "")
8751
   (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8752
   (match_operand:CSGNMODE 2 "register_operand" "")]
8753
  "(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
8754
   || (TARGET_SSE2 && (mode == TFmode))"
8755
  "ix86_expand_copysign (operands); DONE;")
8756
 
8757
(define_insn_and_split "copysign3_const"
8758
  [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8759
        (unspec:CSGNMODE
8760
          [(match_operand: 1 "vector_move_operand" "xmC")
8761
           (match_operand:CSGNMODE 2 "register_operand" "0")
8762
           (match_operand: 3 "nonimmediate_operand" "xm")]
8763
          UNSPEC_COPYSIGN))]
8764
  "(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
8765
   || (TARGET_SSE2 && (mode == TFmode))"
8766
  "#"
8767
  "&& reload_completed"
8768
  [(const_int 0)]
8769
  "ix86_split_copysign_const (operands); DONE;")
8770
 
8771
(define_insn "copysign3_var"
8772
  [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8773
        (unspec:CSGNMODE
8774
          [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8775
           (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8776
           (match_operand: 4 "nonimmediate_operand" "X,xm,xm,0,0")
8777
           (match_operand: 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8778
          UNSPEC_COPYSIGN))
8779
   (clobber (match_scratch: 1 "=x,x,x,x,x"))]
8780
  "(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
8781
   || (TARGET_SSE2 && (mode == TFmode))"
8782
  "#")
8783
 
8784
(define_split
8785
  [(set (match_operand:CSGNMODE 0 "register_operand" "")
8786
        (unspec:CSGNMODE
8787
          [(match_operand:CSGNMODE 2 "register_operand" "")
8788
           (match_operand:CSGNMODE 3 "register_operand" "")
8789
           (match_operand: 4 "" "")
8790
           (match_operand: 5 "" "")]
8791
          UNSPEC_COPYSIGN))
8792
   (clobber (match_scratch: 1 ""))]
8793
  "((SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
8794
    || (TARGET_SSE2 && (mode == TFmode)))
8795
   && reload_completed"
8796
  [(const_int 0)]
8797
  "ix86_split_copysign_var (operands); DONE;")
8798
 
8799
;; One complement instructions
8800
 
8801
(define_expand "one_cmpl2"
8802
  [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8803
        (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8804
  ""
8805
  "ix86_expand_unary_operator (NOT, mode, operands); DONE;")
8806
 
8807
(define_insn "*one_cmpl2_1"
8808
  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8809
        (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8810
  "ix86_unary_operator_ok (NOT, mode, operands)"
8811
  "not{}\t%0"
8812
  [(set_attr "type" "negnot")
8813
   (set_attr "mode" "")])
8814
 
8815
;; %%% Potential partial reg stall on alternative 1.  What to do?
8816
(define_insn "*one_cmplqi2_1"
8817
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8818
        (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8819
  "ix86_unary_operator_ok (NOT, QImode, operands)"
8820
  "@
8821
   not{b}\t%0
8822
   not{l}\t%k0"
8823
  [(set_attr "type" "negnot")
8824
   (set_attr "mode" "QI,SI")])
8825
 
8826
;; ??? Currently never generated - xor is used instead.
8827
(define_insn "*one_cmplsi2_1_zext"
8828
  [(set (match_operand:DI 0 "register_operand" "=r")
8829
        (zero_extend:DI
8830
          (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8831
  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8832
  "not{l}\t%k0"
8833
  [(set_attr "type" "negnot")
8834
   (set_attr "mode" "SI")])
8835
 
8836
(define_insn "*one_cmpl2_2"
8837
  [(set (reg FLAGS_REG)
8838
        (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8839
                 (const_int 0)))
8840
   (set (match_operand:SWI 0 "nonimmediate_operand" "=m")
8841
        (not:SWI (match_dup 1)))]
8842
  "ix86_match_ccmode (insn, CCNOmode)
8843
   && ix86_unary_operator_ok (NOT, mode, operands)"
8844
  "#"
8845
  [(set_attr "type" "alu1")
8846
   (set_attr "mode" "")])
8847
 
8848
(define_split
8849
  [(set (match_operand 0 "flags_reg_operand" "")
8850
        (match_operator 2 "compare_operator"
8851
          [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8852
           (const_int 0)]))
8853
   (set (match_operand:SWI 1 "nonimmediate_operand" "")
8854
        (not:SWI (match_dup 3)))]
8855
  "ix86_match_ccmode (insn, CCNOmode)"
8856
  [(parallel [(set (match_dup 0)
8857
                   (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8858
                                    (const_int 0)]))
8859
              (set (match_dup 1)
8860
                   (xor:SWI (match_dup 3) (const_int -1)))])])
8861
 
8862
;; ??? Currently never generated - xor is used instead.
8863
(define_insn "*one_cmplsi2_2_zext"
8864
  [(set (reg FLAGS_REG)
8865
        (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8866
                 (const_int 0)))
8867
   (set (match_operand:DI 0 "register_operand" "=r")
8868
        (zero_extend:DI (not:SI (match_dup 1))))]
8869
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8870
   && ix86_unary_operator_ok (NOT, SImode, operands)"
8871
  "#"
8872
  [(set_attr "type" "alu1")
8873
   (set_attr "mode" "SI")])
8874
 
8875
(define_split
8876
  [(set (match_operand 0 "flags_reg_operand" "")
8877
        (match_operator 2 "compare_operator"
8878
          [(not:SI (match_operand:SI 3 "register_operand" ""))
8879
           (const_int 0)]))
8880
   (set (match_operand:DI 1 "register_operand" "")
8881
        (zero_extend:DI (not:SI (match_dup 3))))]
8882
  "ix86_match_ccmode (insn, CCNOmode)"
8883
  [(parallel [(set (match_dup 0)
8884
                   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8885
                                    (const_int 0)]))
8886
              (set (match_dup 1)
8887
                   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8888
 
8889
;; Shift instructions
8890
 
8891
;; DImode shifts are implemented using the i386 "shift double" opcode,
8892
;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8893
;; is variable, then the count is in %cl and the "imm" operand is dropped
8894
;; from the assembler input.
8895
;;
8896
;; This instruction shifts the target reg/mem as usual, but instead of
8897
;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8898
;; is a left shift double, bits are taken from the high order bits of
8899
;; reg, else if the insn is a shift right double, bits are taken from the
8900
;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8901
;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8902
;;
8903
;; Since sh[lr]d does not change the `reg' operand, that is done
8904
;; separately, making all shifts emit pairs of shift double and normal
8905
;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8906
;; support a 63 bit shift, each shift where the count is in a reg expands
8907
;; to a pair of shifts, a branch, a shift by 32 and a label.
8908
;;
8909
;; If the shift count is a constant, we need never emit more than one
8910
;; shift pair, instead using moves and sign extension for counts greater
8911
;; than 31.
8912
 
8913
(define_expand "ashl3"
8914
  [(set (match_operand:SDWIM 0 "" "")
8915
        (ashift:SDWIM (match_operand:SDWIM 1 "" "")
8916
                      (match_operand:QI 2 "nonmemory_operand" "")))]
8917
  ""
8918
  "ix86_expand_binary_operator (ASHIFT, mode, operands); DONE;")
8919
 
8920
(define_insn "*ashl3_doubleword"
8921
  [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8922
        (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8923
                    (match_operand:QI 2 "nonmemory_operand" "c,c")))
8924
   (clobber (reg:CC FLAGS_REG))]
8925
  ""
8926
  "#"
8927
  [(set_attr "type" "multi")])
8928
 
8929
(define_split
8930
  [(set (match_operand:DWI 0 "register_operand" "")
8931
        (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8932
                    (match_operand:QI 2 "nonmemory_operand" "")))
8933
   (clobber (reg:CC FLAGS_REG))]
8934
  "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8935
  [(const_int 0)]
8936
  "ix86_split_ashl (operands, NULL_RTX, mode); DONE;")
8937
 
8938
;; By default we don't ask for a scratch register, because when DWImode
8939
;; values are manipulated, registers are already at a premium.  But if
8940
;; we have one handy, we won't turn it away.
8941
 
8942
(define_peephole2
8943
  [(match_scratch:DWIH 3 "r")
8944
   (parallel [(set (match_operand: 0 "register_operand" "")
8945
                   (ashift:
8946
                     (match_operand: 1 "nonmemory_operand" "")
8947
                     (match_operand:QI 2 "nonmemory_operand" "")))
8948
              (clobber (reg:CC FLAGS_REG))])
8949
   (match_dup 3)]
8950
  "TARGET_CMOVE"
8951
  [(const_int 0)]
8952
  "ix86_split_ashl (operands, operands[3], mode); DONE;")
8953
 
8954
(define_insn "x86_64_shld"
8955
  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8956
        (ior:DI (ashift:DI (match_dup 0)
8957
                  (match_operand:QI 2 "nonmemory_operand" "Jc"))
8958
                (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8959
                  (minus:QI (const_int 64) (match_dup 2)))))
8960
   (clobber (reg:CC FLAGS_REG))]
8961
  "TARGET_64BIT"
8962
  "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8963
  [(set_attr "type" "ishift")
8964
   (set_attr "prefix_0f" "1")
8965
   (set_attr "mode" "DI")
8966
   (set_attr "athlon_decode" "vector")
8967
   (set_attr "amdfam10_decode" "vector")
8968
   (set_attr "bdver1_decode" "vector")])
8969
 
8970
(define_insn "x86_shld"
8971
  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8972
        (ior:SI (ashift:SI (match_dup 0)
8973
                  (match_operand:QI 2 "nonmemory_operand" "Ic"))
8974
                (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8975
                  (minus:QI (const_int 32) (match_dup 2)))))
8976
   (clobber (reg:CC FLAGS_REG))]
8977
  ""
8978
  "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8979
  [(set_attr "type" "ishift")
8980
   (set_attr "prefix_0f" "1")
8981
   (set_attr "mode" "SI")
8982
   (set_attr "pent_pair" "np")
8983
   (set_attr "athlon_decode" "vector")
8984
   (set_attr "amdfam10_decode" "vector")
8985
   (set_attr "bdver1_decode" "vector")])
8986
 
8987
(define_expand "x86_shift_adj_1"
8988
  [(set (reg:CCZ FLAGS_REG)
8989
        (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8990
                             (match_dup 4))
8991
                     (const_int 0)))
8992
   (set (match_operand:SWI48 0 "register_operand" "")
8993
        (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8994
                            (match_operand:SWI48 1 "register_operand" "")
8995
                            (match_dup 0)))
8996
   (set (match_dup 1)
8997
        (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8998
                            (match_operand:SWI48 3 "register_operand" "")
8999
                            (match_dup 1)))]
9000
  "TARGET_CMOVE"
9001
  "operands[4] = GEN_INT (GET_MODE_BITSIZE (mode));")
9002
 
9003
(define_expand "x86_shift_adj_2"
9004
  [(use (match_operand:SWI48 0 "register_operand" ""))
9005
   (use (match_operand:SWI48 1 "register_operand" ""))
9006
   (use (match_operand:QI 2 "register_operand" ""))]
9007
  ""
9008
{
9009
  rtx label = gen_label_rtx ();
9010
  rtx tmp;
9011
 
9012
  emit_insn (gen_testqi_ccz_1 (operands[2],
9013
                               GEN_INT (GET_MODE_BITSIZE (mode))));
9014
 
9015
  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9016
  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9017
  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9018
                              gen_rtx_LABEL_REF (VOIDmode, label),
9019
                              pc_rtx);
9020
  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9021
  JUMP_LABEL (tmp) = label;
9022
 
9023
  emit_move_insn (operands[0], operands[1]);
9024
  ix86_expand_clear (operands[1]);
9025
 
9026
  emit_label (label);
9027
  LABEL_NUSES (label) = 1;
9028
 
9029
  DONE;
9030
})
9031
 
9032
;; Avoid useless masking of count operand.
9033
(define_insn_and_split "*ashl3_mask"
9034
  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9035
        (ashift:SWI48
9036
          (match_operand:SWI48 1 "nonimmediate_operand" "0")
9037
          (subreg:QI
9038
            (and:SI
9039
              (match_operand:SI 2 "nonimmediate_operand" "c")
9040
              (match_operand:SI 3 "const_int_operand" "n")) 0)))
9041
   (clobber (reg:CC FLAGS_REG))]
9042
  "ix86_binary_operator_ok (ASHIFT, mode, operands)
9043
   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (mode)-1))
9044
      == GET_MODE_BITSIZE (mode)-1"
9045
  "#"
9046
  "&& 1"
9047
  [(parallel [(set (match_dup 0)
9048
                   (ashift:SWI48 (match_dup 1) (match_dup 2)))
9049
              (clobber (reg:CC FLAGS_REG))])]
9050
{
9051
  if (can_create_pseudo_p ())
9052
    operands [2] = force_reg (SImode, operands[2]);
9053
 
9054
  operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9055
}
9056
  [(set_attr "type" "ishift")
9057
   (set_attr "mode" "")])
9058
 
9059
(define_insn "*bmi2_ashl3_1"
9060
  [(set (match_operand:SWI48 0 "register_operand" "=r")
9061
        (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9062
                      (match_operand:SWI48 2 "register_operand" "r")))]
9063
  "TARGET_BMI2"
9064
  "shlx\t{%2, %1, %0|%0, %1, %2}"
9065
  [(set_attr "type" "ishiftx")
9066
   (set_attr "mode" "")])
9067
 
9068
(define_insn "*ashl3_1"
9069
  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9070
        (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9071
                      (match_operand:QI 2 "nonmemory_operand" "c,M,r")))
9072
   (clobber (reg:CC FLAGS_REG))]
9073
  "ix86_binary_operator_ok (ASHIFT, mode, operands)"
9074
{
9075
  switch (get_attr_type (insn))
9076
    {
9077
    case TYPE_LEA:
9078
    case TYPE_ISHIFTX:
9079
      return "#";
9080
 
9081
    case TYPE_ALU:
9082
      gcc_assert (operands[2] == const1_rtx);
9083
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
9084
      return "add{}\t%0, %0";
9085
 
9086
    default:
9087
      if (operands[2] == const1_rtx
9088
          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9089
        return "sal{}\t%0";
9090
      else
9091
        return "sal{}\t{%2, %0|%0, %2}";
9092
    }
9093
}
9094
  [(set_attr "isa" "*,*,bmi2")
9095
   (set (attr "type")
9096
     (cond [(eq_attr "alternative" "1")
9097
              (const_string "lea")
9098
            (eq_attr "alternative" "2")
9099
              (const_string "ishiftx")
9100
            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9101
                      (match_operand 0 "register_operand" ""))
9102
                 (match_operand 2 "const1_operand" ""))
9103
              (const_string "alu")
9104
           ]
9105
           (const_string "ishift")))
9106
   (set (attr "length_immediate")
9107
     (if_then_else
9108
       (ior (eq_attr "type" "alu")
9109
            (and (eq_attr "type" "ishift")
9110
                 (and (match_operand 2 "const1_operand" "")
9111
                      (ior (match_test "TARGET_SHIFT1")
9112
                           (match_test "optimize_function_for_size_p (cfun)")))))
9113
       (const_string "0")
9114
       (const_string "*")))
9115
   (set_attr "mode" "")])
9116
 
9117
;; Convert shift to the shiftx pattern to avoid flags dependency.
9118
(define_split
9119
  [(set (match_operand:SWI48 0 "register_operand" "")
9120
        (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9121
                      (match_operand:QI 2 "register_operand" "")))
9122
   (clobber (reg:CC FLAGS_REG))]
9123
  "TARGET_BMI2 && reload_completed"
9124
  [(set (match_dup 0)
9125
        (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9126
  "operands[2] = gen_lowpart (mode, operands[2]);")
9127
 
9128
(define_insn "*bmi2_ashlsi3_1_zext"
9129
  [(set (match_operand:DI 0 "register_operand" "=r")
9130
        (zero_extend:DI
9131
          (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9132
                     (match_operand:SI 2 "register_operand" "r"))))]
9133
  "TARGET_64BIT && TARGET_BMI2"
9134
  "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9135
  [(set_attr "type" "ishiftx")
9136
   (set_attr "mode" "SI")])
9137
 
9138
(define_insn "*ashlsi3_1_zext"
9139
  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9140
        (zero_extend:DI
9141
          (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9142
                     (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9143
   (clobber (reg:CC FLAGS_REG))]
9144
  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9145
{
9146
  switch (get_attr_type (insn))
9147
    {
9148
    case TYPE_LEA:
9149
    case TYPE_ISHIFTX:
9150
      return "#";
9151
 
9152
    case TYPE_ALU:
9153
      gcc_assert (operands[2] == const1_rtx);
9154
      return "add{l}\t%k0, %k0";
9155
 
9156
    default:
9157
      if (operands[2] == const1_rtx
9158
          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9159
        return "sal{l}\t%k0";
9160
      else
9161
        return "sal{l}\t{%2, %k0|%k0, %2}";
9162
    }
9163
}
9164
  [(set_attr "isa" "*,*,bmi2")
9165
   (set (attr "type")
9166
     (cond [(eq_attr "alternative" "1")
9167
              (const_string "lea")
9168
            (eq_attr "alternative" "2")
9169
              (const_string "ishiftx")
9170
            (and (match_test "TARGET_DOUBLE_WITH_ADD")
9171
                 (match_operand 2 "const1_operand" ""))
9172
              (const_string "alu")
9173
           ]
9174
           (const_string "ishift")))
9175
   (set (attr "length_immediate")
9176
     (if_then_else
9177
       (ior (eq_attr "type" "alu")
9178
            (and (eq_attr "type" "ishift")
9179
                 (and (match_operand 2 "const1_operand" "")
9180
                      (ior (match_test "TARGET_SHIFT1")
9181
                           (match_test "optimize_function_for_size_p (cfun)")))))
9182
       (const_string "0")
9183
       (const_string "*")))
9184
   (set_attr "mode" "SI")])
9185
 
9186
;; Convert shift to the shiftx pattern to avoid flags dependency.
9187
(define_split
9188
  [(set (match_operand:DI 0 "register_operand" "")
9189
        (zero_extend:DI
9190
          (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9191
                     (match_operand:QI 2 "register_operand" ""))))
9192
   (clobber (reg:CC FLAGS_REG))]
9193
  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9194
  [(set (match_dup 0)
9195
        (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9196
  "operands[2] = gen_lowpart (SImode, operands[2]);")
9197
 
9198
(define_insn "*ashlhi3_1"
9199
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9200
        (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9201
                   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9202
   (clobber (reg:CC FLAGS_REG))]
9203
  "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9204
{
9205
  switch (get_attr_type (insn))
9206
    {
9207
    case TYPE_LEA:
9208
      return "#";
9209
 
9210
    case TYPE_ALU:
9211
      gcc_assert (operands[2] == const1_rtx);
9212
      return "add{w}\t%0, %0";
9213
 
9214
    default:
9215
      if (operands[2] == const1_rtx
9216
          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9217
        return "sal{w}\t%0";
9218
      else
9219
        return "sal{w}\t{%2, %0|%0, %2}";
9220
    }
9221
}
9222
  [(set (attr "type")
9223
     (cond [(eq_attr "alternative" "1")
9224
              (const_string "lea")
9225
            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9226
                      (match_operand 0 "register_operand" ""))
9227
                 (match_operand 2 "const1_operand" ""))
9228
              (const_string "alu")
9229
           ]
9230
           (const_string "ishift")))
9231
   (set (attr "length_immediate")
9232
     (if_then_else
9233
       (ior (eq_attr "type" "alu")
9234
            (and (eq_attr "type" "ishift")
9235
                 (and (match_operand 2 "const1_operand" "")
9236
                      (ior (match_test "TARGET_SHIFT1")
9237
                           (match_test "optimize_function_for_size_p (cfun)")))))
9238
       (const_string "0")
9239
       (const_string "*")))
9240
   (set_attr "mode" "HI,SI")])
9241
 
9242
;; %%% Potential partial reg stall on alternative 1.  What to do?
9243
(define_insn "*ashlqi3_1"
9244
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9245
        (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9246
                   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9247
   (clobber (reg:CC FLAGS_REG))]
9248
  "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9249
{
9250
  switch (get_attr_type (insn))
9251
    {
9252
    case TYPE_LEA:
9253
      return "#";
9254
 
9255
    case TYPE_ALU:
9256
      gcc_assert (operands[2] == const1_rtx);
9257
      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9258
        return "add{l}\t%k0, %k0";
9259
      else
9260
        return "add{b}\t%0, %0";
9261
 
9262
    default:
9263
      if (operands[2] == const1_rtx
9264
          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265
        {
9266
          if (get_attr_mode (insn) == MODE_SI)
9267
            return "sal{l}\t%k0";
9268
          else
9269
            return "sal{b}\t%0";
9270
        }
9271
      else
9272
        {
9273
          if (get_attr_mode (insn) == MODE_SI)
9274
            return "sal{l}\t{%2, %k0|%k0, %2}";
9275
          else
9276
            return "sal{b}\t{%2, %0|%0, %2}";
9277
        }
9278
    }
9279
}
9280
  [(set (attr "type")
9281
     (cond [(eq_attr "alternative" "2")
9282
              (const_string "lea")
9283
            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9284
                      (match_operand 0 "register_operand" ""))
9285
                 (match_operand 2 "const1_operand" ""))
9286
              (const_string "alu")
9287
           ]
9288
           (const_string "ishift")))
9289
   (set (attr "length_immediate")
9290
     (if_then_else
9291
       (ior (eq_attr "type" "alu")
9292
            (and (eq_attr "type" "ishift")
9293
                 (and (match_operand 2 "const1_operand" "")
9294
                      (ior (match_test "TARGET_SHIFT1")
9295
                           (match_test "optimize_function_for_size_p (cfun)")))))
9296
       (const_string "0")
9297
       (const_string "*")))
9298
   (set_attr "mode" "QI,SI,SI")])
9299
 
9300
(define_insn "*ashlqi3_1_slp"
9301
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9302
        (ashift:QI (match_dup 0)
9303
                   (match_operand:QI 1 "nonmemory_operand" "cI")))
9304
   (clobber (reg:CC FLAGS_REG))]
9305
  "(optimize_function_for_size_p (cfun)
9306
    || !TARGET_PARTIAL_FLAG_REG_STALL
9307
    || (operands[1] == const1_rtx
9308
        && (TARGET_SHIFT1
9309
            || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9310
{
9311
  switch (get_attr_type (insn))
9312
    {
9313
    case TYPE_ALU:
9314
      gcc_assert (operands[1] == const1_rtx);
9315
      return "add{b}\t%0, %0";
9316
 
9317
    default:
9318
      if (operands[1] == const1_rtx
9319
          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9320
        return "sal{b}\t%0";
9321
      else
9322
        return "sal{b}\t{%1, %0|%0, %1}";
9323
    }
9324
}
9325
  [(set (attr "type")
9326
     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9327
                      (match_operand 0 "register_operand" ""))
9328
                 (match_operand 1 "const1_operand" ""))
9329
              (const_string "alu")
9330
           ]
9331
           (const_string "ishift1")))
9332
   (set (attr "length_immediate")
9333
     (if_then_else
9334
       (ior (eq_attr "type" "alu")
9335
            (and (eq_attr "type" "ishift1")
9336
                 (and (match_operand 1 "const1_operand" "")
9337
                      (ior (match_test "TARGET_SHIFT1")
9338
                           (match_test "optimize_function_for_size_p (cfun)")))))
9339
       (const_string "0")
9340
       (const_string "*")))
9341
   (set_attr "mode" "QI")])
9342
 
9343
;; Convert ashift to the lea pattern to avoid flags dependency.
9344
(define_split
9345
  [(set (match_operand 0 "register_operand" "")
9346
        (ashift (match_operand 1 "index_register_operand" "")
9347
                (match_operand:QI 2 "const_int_operand" "")))
9348
   (clobber (reg:CC FLAGS_REG))]
9349
  "GET_MODE (operands[0]) == GET_MODE (operands[1])
9350
   && reload_completed
9351
   && true_regnum (operands[0]) != true_regnum (operands[1])"
9352
  [(const_int 0)]
9353
{
9354
  enum machine_mode mode = GET_MODE (operands[0]);
9355
  rtx pat;
9356
 
9357
  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9358
    {
9359
      mode = SImode;
9360
      operands[0] = gen_lowpart (mode, operands[0]);
9361
      operands[1] = gen_lowpart (mode, operands[1]);
9362
    }
9363
 
9364
  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9365
 
9366
  pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9367
 
9368
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9369
  DONE;
9370
})
9371
 
9372
;; Convert ashift to the lea pattern to avoid flags dependency.
9373
(define_split
9374
  [(set (match_operand:DI 0 "register_operand" "")
9375
        (zero_extend:DI
9376
          (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9377
                     (match_operand:QI 2 "const_int_operand" ""))))
9378
   (clobber (reg:CC FLAGS_REG))]
9379
  "TARGET_64BIT && reload_completed
9380
   && true_regnum (operands[0]) != true_regnum (operands[1])"
9381
  [(set (match_dup 0)
9382
        (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9383
{
9384
  operands[1] = gen_lowpart (DImode, operands[1]);
9385
  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9386
})
9387
 
9388
;; This pattern can't accept a variable shift count, since shifts by
9389
;; zero don't affect the flags.  We assume that shifts by constant
9390
;; zero are optimized away.
9391
(define_insn "*ashl3_cmp"
9392
  [(set (reg FLAGS_REG)
9393
        (compare
9394
          (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9395
                      (match_operand:QI 2 "" ""))
9396
          (const_int 0)))
9397
   (set (match_operand:SWI 0 "nonimmediate_operand" "=m")
9398
        (ashift:SWI (match_dup 1) (match_dup 2)))]
9399
  "(optimize_function_for_size_p (cfun)
9400
    || !TARGET_PARTIAL_FLAG_REG_STALL
9401
    || (operands[2] == const1_rtx
9402
        && (TARGET_SHIFT1
9403
            || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9404
   && ix86_match_ccmode (insn, CCGOCmode)
9405
   && ix86_binary_operator_ok (ASHIFT, mode, operands)"
9406
{
9407
  switch (get_attr_type (insn))
9408
    {
9409
    case TYPE_ALU:
9410
      gcc_assert (operands[2] == const1_rtx);
9411
      return "add{}\t%0, %0";
9412
 
9413
    default:
9414
      if (operands[2] == const1_rtx
9415
          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9416
        return "sal{}\t%0";
9417
      else
9418
        return "sal{}\t{%2, %0|%0, %2}";
9419
    }
9420
}
9421
  [(set (attr "type")
9422
     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9423
                      (match_operand 0 "register_operand" ""))
9424
                 (match_operand 2 "const1_operand" ""))
9425
              (const_string "alu")
9426
           ]
9427
           (const_string "ishift")))
9428
   (set (attr "length_immediate")
9429
     (if_then_else
9430
       (ior (eq_attr "type" "alu")
9431
            (and (eq_attr "type" "ishift")
9432
                 (and (match_operand 2 "const1_operand" "")
9433
                      (ior (match_test "TARGET_SHIFT1")
9434
                           (match_test "optimize_function_for_size_p (cfun)")))))
9435
       (const_string "0")
9436
       (const_string "*")))
9437
   (set_attr "mode" "")])
9438
 
9439
(define_insn "*ashlsi3_cmp_zext"
9440
  [(set (reg FLAGS_REG)
9441
        (compare
9442
          (ashift:SI (match_operand:SI 1 "register_operand" "0")
9443
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
9444
          (const_int 0)))
9445
   (set (match_operand:DI 0 "register_operand" "=r")
9446
        (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9447
  "TARGET_64BIT
9448
   && (optimize_function_for_size_p (cfun)
9449
       || !TARGET_PARTIAL_FLAG_REG_STALL
9450
       || (operands[2] == const1_rtx
9451
           && (TARGET_SHIFT1
9452
               || TARGET_DOUBLE_WITH_ADD)))
9453
   && ix86_match_ccmode (insn, CCGOCmode)
9454
   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9455
{
9456
  switch (get_attr_type (insn))
9457
    {
9458
    case TYPE_ALU:
9459
      gcc_assert (operands[2] == const1_rtx);
9460
      return "add{l}\t%k0, %k0";
9461
 
9462
    default:
9463
      if (operands[2] == const1_rtx
9464
          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9465
        return "sal{l}\t%k0";
9466
      else
9467
        return "sal{l}\t{%2, %k0|%k0, %2}";
9468
    }
9469
}
9470
  [(set (attr "type")
9471
     (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9472
                 (match_operand 2 "const1_operand" ""))
9473
              (const_string "alu")
9474
           ]
9475
           (const_string "ishift")))
9476
   (set (attr "length_immediate")
9477
     (if_then_else
9478
       (ior (eq_attr "type" "alu")
9479
            (and (eq_attr "type" "ishift")
9480
                 (and (match_operand 2 "const1_operand" "")
9481
                      (ior (match_test "TARGET_SHIFT1")
9482
                           (match_test "optimize_function_for_size_p (cfun)")))))
9483
       (const_string "0")
9484
       (const_string "*")))
9485
   (set_attr "mode" "SI")])
9486
 
9487
(define_insn "*ashl3_cconly"
9488
  [(set (reg FLAGS_REG)
9489
        (compare
9490
          (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9491
                      (match_operand:QI 2 "" ""))
9492
          (const_int 0)))
9493
   (clobber (match_scratch:SWI 0 "="))]
9494
  "(optimize_function_for_size_p (cfun)
9495
    || !TARGET_PARTIAL_FLAG_REG_STALL
9496
    || (operands[2] == const1_rtx
9497
        && (TARGET_SHIFT1
9498
            || TARGET_DOUBLE_WITH_ADD)))
9499
   && ix86_match_ccmode (insn, CCGOCmode)"
9500
{
9501
  switch (get_attr_type (insn))
9502
    {
9503
    case TYPE_ALU:
9504
      gcc_assert (operands[2] == const1_rtx);
9505
      return "add{}\t%0, %0";
9506
 
9507
    default:
9508
      if (operands[2] == const1_rtx
9509
          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9510
        return "sal{}\t%0";
9511
      else
9512
        return "sal{}\t{%2, %0|%0, %2}";
9513
    }
9514
}
9515
  [(set (attr "type")
9516
     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9517
                      (match_operand 0 "register_operand" ""))
9518
                 (match_operand 2 "const1_operand" ""))
9519
              (const_string "alu")
9520
           ]
9521
           (const_string "ishift")))
9522
   (set (attr "length_immediate")
9523
     (if_then_else
9524
       (ior (eq_attr "type" "alu")
9525
            (and (eq_attr "type" "ishift")
9526
                 (and (match_operand 2 "const1_operand" "")
9527
                      (ior (match_test "TARGET_SHIFT1")
9528
                           (match_test "optimize_function_for_size_p (cfun)")))))
9529
       (const_string "0")
9530
       (const_string "*")))
9531
   (set_attr "mode" "")])
9532
 
9533
;; See comment above `ashl3' about how this works.
9534
 
9535
(define_expand "3"
9536
  [(set (match_operand:SDWIM 0 "" "")
9537
        (any_shiftrt:SDWIM (match_operand:SDWIM 1 "" "")
9538
                           (match_operand:QI 2 "nonmemory_operand" "")))]
9539
  ""
9540
  "ix86_expand_binary_operator (, mode, operands); DONE;")
9541
 
9542
;; Avoid useless masking of count operand.
9543
(define_insn_and_split "*3_mask"
9544
  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9545
        (any_shiftrt:SWI48
9546
          (match_operand:SWI48 1 "nonimmediate_operand" "0")
9547
          (subreg:QI
9548
            (and:SI
9549
              (match_operand:SI 2 "nonimmediate_operand" "c")
9550
              (match_operand:SI 3 "const_int_operand" "n")) 0)))
9551
   (clobber (reg:CC FLAGS_REG))]
9552
  "ix86_binary_operator_ok (, mode, operands)
9553
   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (mode)-1))
9554
      == GET_MODE_BITSIZE (mode)-1"
9555
  "#"
9556
  "&& 1"
9557
  [(parallel [(set (match_dup 0)
9558
                   (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9559
              (clobber (reg:CC FLAGS_REG))])]
9560
{
9561
  if (can_create_pseudo_p ())
9562
    operands [2] = force_reg (SImode, operands[2]);
9563
 
9564
  operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9565
}
9566
  [(set_attr "type" "ishift")
9567
   (set_attr "mode" "")])
9568
 
9569
(define_insn_and_split "*3_doubleword"
9570
  [(set (match_operand:DWI 0 "register_operand" "=r")
9571
        (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9572
                         (match_operand:QI 2 "nonmemory_operand" "c")))
9573
   (clobber (reg:CC FLAGS_REG))]
9574
  ""
9575
  "#"
9576
  "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9577
  [(const_int 0)]
9578
  "ix86_split_ (operands, NULL_RTX, mode); DONE;"
9579
  [(set_attr "type" "multi")])
9580
 
9581
;; By default we don't ask for a scratch register, because when DWImode
9582
;; values are manipulated, registers are already at a premium.  But if
9583
;; we have one handy, we won't turn it away.
9584
 
9585
(define_peephole2
9586
  [(match_scratch:DWIH 3 "r")
9587
   (parallel [(set (match_operand: 0 "register_operand" "")
9588
                   (any_shiftrt:
9589
                     (match_operand: 1 "register_operand" "")
9590
                     (match_operand:QI 2 "nonmemory_operand" "")))
9591
              (clobber (reg:CC FLAGS_REG))])
9592
   (match_dup 3)]
9593
  "TARGET_CMOVE"
9594
  [(const_int 0)]
9595
  "ix86_split_ (operands, operands[3], mode); DONE;")
9596
 
9597
(define_insn "x86_64_shrd"
9598
  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9599
        (ior:DI (ashiftrt:DI (match_dup 0)
9600
                  (match_operand:QI 2 "nonmemory_operand" "Jc"))
9601
                (ashift:DI (match_operand:DI 1 "register_operand" "r")
9602
                  (minus:QI (const_int 64) (match_dup 2)))))
9603
   (clobber (reg:CC FLAGS_REG))]
9604
  "TARGET_64BIT"
9605
  "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9606
  [(set_attr "type" "ishift")
9607
   (set_attr "prefix_0f" "1")
9608
   (set_attr "mode" "DI")
9609
   (set_attr "athlon_decode" "vector")
9610
   (set_attr "amdfam10_decode" "vector")
9611
   (set_attr "bdver1_decode" "vector")])
9612
 
9613
(define_insn "x86_shrd"
9614
  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9615
        (ior:SI (ashiftrt:SI (match_dup 0)
9616
                  (match_operand:QI 2 "nonmemory_operand" "Ic"))
9617
                (ashift:SI (match_operand:SI 1 "register_operand" "r")
9618
                  (minus:QI (const_int 32) (match_dup 2)))))
9619
   (clobber (reg:CC FLAGS_REG))]
9620
  ""
9621
  "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9622
  [(set_attr "type" "ishift")
9623
   (set_attr "prefix_0f" "1")
9624
   (set_attr "mode" "SI")
9625
   (set_attr "pent_pair" "np")
9626
   (set_attr "athlon_decode" "vector")
9627
   (set_attr "amdfam10_decode" "vector")
9628
   (set_attr "bdver1_decode" "vector")])
9629
 
9630
(define_insn "ashrdi3_cvt"
9631
  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9632
        (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9633
                     (match_operand:QI 2 "const_int_operand" "")))
9634
   (clobber (reg:CC FLAGS_REG))]
9635
  "TARGET_64BIT && INTVAL (operands[2]) == 63
9636
   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9637
   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9638
  "@
9639
   {cqto|cqo}
9640
   sar{q}\t{%2, %0|%0, %2}"
9641
  [(set_attr "type" "imovx,ishift")
9642
   (set_attr "prefix_0f" "0,*")
9643
   (set_attr "length_immediate" "0,*")
9644
   (set_attr "modrm" "0,1")
9645
   (set_attr "mode" "DI")])
9646
 
9647
(define_insn "ashrsi3_cvt"
9648
  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9649
        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9650
                     (match_operand:QI 2 "const_int_operand" "")))
9651
   (clobber (reg:CC FLAGS_REG))]
9652
  "INTVAL (operands[2]) == 31
9653
   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9654
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9655
  "@
9656
   {cltd|cdq}
9657
   sar{l}\t{%2, %0|%0, %2}"
9658
  [(set_attr "type" "imovx,ishift")
9659
   (set_attr "prefix_0f" "0,*")
9660
   (set_attr "length_immediate" "0,*")
9661
   (set_attr "modrm" "0,1")
9662
   (set_attr "mode" "SI")])
9663
 
9664
(define_insn "*ashrsi3_cvt_zext"
9665
  [(set (match_operand:DI 0 "register_operand" "=*d,r")
9666
        (zero_extend:DI
9667
          (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9668
                       (match_operand:QI 2 "const_int_operand" ""))))
9669
   (clobber (reg:CC FLAGS_REG))]
9670
  "TARGET_64BIT && INTVAL (operands[2]) == 31
9671
   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9672
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9673
  "@
9674
   {cltd|cdq}
9675
   sar{l}\t{%2, %k0|%k0, %2}"
9676
  [(set_attr "type" "imovx,ishift")
9677
   (set_attr "prefix_0f" "0,*")
9678
   (set_attr "length_immediate" "0,*")
9679
   (set_attr "modrm" "0,1")
9680
   (set_attr "mode" "SI")])
9681
 
9682
(define_expand "x86_shift_adj_3"
9683
  [(use (match_operand:SWI48 0 "register_operand" ""))
9684
   (use (match_operand:SWI48 1 "register_operand" ""))
9685
   (use (match_operand:QI 2 "register_operand" ""))]
9686
  ""
9687
{
9688
  rtx label = gen_label_rtx ();
9689
  rtx tmp;
9690
 
9691
  emit_insn (gen_testqi_ccz_1 (operands[2],
9692
                               GEN_INT (GET_MODE_BITSIZE (mode))));
9693
 
9694
  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9695
  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9696
  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9697
                              gen_rtx_LABEL_REF (VOIDmode, label),
9698
                              pc_rtx);
9699
  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9700
  JUMP_LABEL (tmp) = label;
9701
 
9702
  emit_move_insn (operands[0], operands[1]);
9703
  emit_insn (gen_ashr3_cvt (operands[1], operands[1],
9704
                                  GEN_INT (GET_MODE_BITSIZE (mode)-1)));
9705
  emit_label (label);
9706
  LABEL_NUSES (label) = 1;
9707
 
9708
  DONE;
9709
})
9710
 
9711
(define_insn "*bmi2_3_1"
9712
  [(set (match_operand:SWI48 0 "register_operand" "=r")
9713
        (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9714
                           (match_operand:SWI48 2 "register_operand" "r")))]
9715
  "TARGET_BMI2"
9716
  "x\t{%2, %1, %0|%0, %1, %2}"
9717
  [(set_attr "type" "ishiftx")
9718
   (set_attr "mode" "")])
9719
 
9720
(define_insn "*3_1"
9721
  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9722
        (any_shiftrt:SWI48
9723
          (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9724
          (match_operand:QI 2 "nonmemory_operand" "c,r")))
9725
   (clobber (reg:CC FLAGS_REG))]
9726
  "ix86_binary_operator_ok (, mode, operands)"
9727
{
9728
  switch (get_attr_type (insn))
9729
    {
9730
    case TYPE_ISHIFTX:
9731
      return "#";
9732
 
9733
    default:
9734
      if (operands[2] == const1_rtx
9735
          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9736
        return "{}\t%0";
9737
      else
9738
        return "{}\t{%2, %0|%0, %2}";
9739
    }
9740
}
9741
  [(set_attr "isa" "*,bmi2")
9742
   (set_attr "type" "ishift,ishiftx")
9743
   (set (attr "length_immediate")
9744
     (if_then_else
9745
       (and (match_operand 2 "const1_operand" "")
9746
            (ior (match_test "TARGET_SHIFT1")
9747
                 (match_test "optimize_function_for_size_p (cfun)")))
9748
       (const_string "0")
9749
       (const_string "*")))
9750
   (set_attr "mode" "")])
9751
 
9752
;; Convert shift to the shiftx pattern to avoid flags dependency.
9753
(define_split
9754
  [(set (match_operand:SWI48 0 "register_operand" "")
9755
        (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9756
                           (match_operand:QI 2 "register_operand" "")))
9757
   (clobber (reg:CC FLAGS_REG))]
9758
  "TARGET_BMI2 && reload_completed"
9759
  [(set (match_dup 0)
9760
        (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9761
  "operands[2] = gen_lowpart (mode, operands[2]);")
9762
 
9763
(define_insn "*bmi2_si3_1_zext"
9764
  [(set (match_operand:DI 0 "register_operand" "=r")
9765
        (zero_extend:DI
9766
          (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9767
                          (match_operand:SI 2 "register_operand" "r"))))]
9768
  "TARGET_64BIT && TARGET_BMI2"
9769
  "x\t{%2, %1, %k0|%k0, %1, %2}"
9770
  [(set_attr "type" "ishiftx")
9771
   (set_attr "mode" "SI")])
9772
 
9773
(define_insn "*si3_1_zext"
9774
  [(set (match_operand:DI 0 "register_operand" "=r,r")
9775
        (zero_extend:DI
9776
          (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9777
                          (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9778
   (clobber (reg:CC FLAGS_REG))]
9779
  "TARGET_64BIT && ix86_binary_operator_ok (, SImode, operands)"
9780
{
9781
  switch (get_attr_type (insn))
9782
    {
9783
    case TYPE_ISHIFTX:
9784
      return "#";
9785
 
9786
    default:
9787
      if (operands[2] == const1_rtx
9788
          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9789
        return "{l}\t%k0";
9790
      else
9791
        return "{l}\t{%2, %k0|%k0, %2}";
9792
    }
9793
}
9794
  [(set_attr "isa" "*,bmi2")
9795
   (set_attr "type" "ishift,ishiftx")
9796
   (set (attr "length_immediate")
9797
     (if_then_else
9798
       (and (match_operand 2 "const1_operand" "")
9799
            (ior (match_test "TARGET_SHIFT1")
9800
                 (match_test "optimize_function_for_size_p (cfun)")))
9801
       (const_string "0")
9802
       (const_string "*")))
9803
   (set_attr "mode" "SI")])
9804
 
9805
;; Convert shift to the shiftx pattern to avoid flags dependency.
9806
(define_split
9807
  [(set (match_operand:DI 0 "register_operand" "")
9808
        (zero_extend:DI
9809
          (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9810
                          (match_operand:QI 2 "register_operand" ""))))
9811
   (clobber (reg:CC FLAGS_REG))]
9812
  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9813
  [(set (match_dup 0)
9814
        (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9815
  "operands[2] = gen_lowpart (SImode, operands[2]);")
9816
 
9817
(define_insn "*3_1"
9818
  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=m")
9819
        (any_shiftrt:SWI12
9820
          (match_operand:SWI12 1 "nonimmediate_operand" "0")
9821
          (match_operand:QI 2 "nonmemory_operand" "c")))
9822
   (clobber (reg:CC FLAGS_REG))]
9823
  "ix86_binary_operator_ok (, mode, operands)"
9824
{
9825
  if (operands[2] == const1_rtx
9826
      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9827
    return "{}\t%0";
9828
  else
9829
    return "{}\t{%2, %0|%0, %2}";
9830
}
9831
  [(set_attr "type" "ishift")
9832
   (set (attr "length_immediate")
9833
     (if_then_else
9834
       (and (match_operand 2 "const1_operand" "")
9835
            (ior (match_test "TARGET_SHIFT1")
9836
                 (match_test "optimize_function_for_size_p (cfun)")))
9837
       (const_string "0")
9838
       (const_string "*")))
9839
   (set_attr "mode" "")])
9840
 
9841
(define_insn "*qi3_1_slp"
9842
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9843
        (any_shiftrt:QI (match_dup 0)
9844
                        (match_operand:QI 1 "nonmemory_operand" "cI")))
9845
   (clobber (reg:CC FLAGS_REG))]
9846
  "(optimize_function_for_size_p (cfun)
9847
    || !TARGET_PARTIAL_REG_STALL
9848
    || (operands[1] == const1_rtx
9849
        && TARGET_SHIFT1))"
9850
{
9851
  if (operands[1] == const1_rtx
9852
      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9853
    return "{b}\t%0";
9854
  else
9855
    return "{b}\t{%1, %0|%0, %1}";
9856
}
9857
  [(set_attr "type" "ishift1")
9858
   (set (attr "length_immediate")
9859
     (if_then_else
9860
       (and (match_operand 1 "const1_operand" "")
9861
            (ior (match_test "TARGET_SHIFT1")
9862
                 (match_test "optimize_function_for_size_p (cfun)")))
9863
       (const_string "0")
9864
       (const_string "*")))
9865
   (set_attr "mode" "QI")])
9866
 
9867
;; This pattern can't accept a variable shift count, since shifts by
9868
;; zero don't affect the flags.  We assume that shifts by constant
9869
;; zero are optimized away.
9870
(define_insn "*3_cmp"
9871
  [(set (reg FLAGS_REG)
9872
        (compare
9873
          (any_shiftrt:SWI
9874
            (match_operand:SWI 1 "nonimmediate_operand" "0")
9875
            (match_operand:QI 2 "" ""))
9876
          (const_int 0)))
9877
   (set (match_operand:SWI 0 "nonimmediate_operand" "=m")
9878
        (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9879
  "(optimize_function_for_size_p (cfun)
9880
    || !TARGET_PARTIAL_FLAG_REG_STALL
9881
    || (operands[2] == const1_rtx
9882
        && TARGET_SHIFT1))
9883
   && ix86_match_ccmode (insn, CCGOCmode)
9884
   && ix86_binary_operator_ok (, mode, operands)"
9885
{
9886
  if (operands[2] == const1_rtx
9887
      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9888
    return "{}\t%0";
9889
  else
9890
    return "{}\t{%2, %0|%0, %2}";
9891
}
9892
  [(set_attr "type" "ishift")
9893
   (set (attr "length_immediate")
9894
     (if_then_else
9895
       (and (match_operand 2 "const1_operand" "")
9896
            (ior (match_test "TARGET_SHIFT1")
9897
                 (match_test "optimize_function_for_size_p (cfun)")))
9898
       (const_string "0")
9899
       (const_string "*")))
9900
   (set_attr "mode" "")])
9901
 
9902
(define_insn "*si3_cmp_zext"
9903
  [(set (reg FLAGS_REG)
9904
        (compare
9905
          (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9906
                          (match_operand:QI 2 "const_1_to_31_operand" "I"))
9907
          (const_int 0)))
9908
   (set (match_operand:DI 0 "register_operand" "=r")
9909
        (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9910
  "TARGET_64BIT
9911
   && (optimize_function_for_size_p (cfun)
9912
       || !TARGET_PARTIAL_FLAG_REG_STALL
9913
       || (operands[2] == const1_rtx
9914
           && TARGET_SHIFT1))
9915
   && ix86_match_ccmode (insn, CCGOCmode)
9916
   && ix86_binary_operator_ok (, SImode, operands)"
9917
{
9918
  if (operands[2] == const1_rtx
9919
      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9920
    return "{l}\t%k0";
9921
  else
9922
    return "{l}\t{%2, %k0|%k0, %2}";
9923
}
9924
  [(set_attr "type" "ishift")
9925
   (set (attr "length_immediate")
9926
     (if_then_else
9927
       (and (match_operand 2 "const1_operand" "")
9928
            (ior (match_test "TARGET_SHIFT1")
9929
                 (match_test "optimize_function_for_size_p (cfun)")))
9930
       (const_string "0")
9931
       (const_string "*")))
9932
   (set_attr "mode" "SI")])
9933
 
9934
(define_insn "*3_cconly"
9935
  [(set (reg FLAGS_REG)
9936
        (compare
9937
          (any_shiftrt:SWI
9938
            (match_operand:SWI 1 "register_operand" "0")
9939
            (match_operand:QI 2 "" ""))
9940
          (const_int 0)))
9941
   (clobber (match_scratch:SWI 0 "="))]
9942
  "(optimize_function_for_size_p (cfun)
9943
    || !TARGET_PARTIAL_FLAG_REG_STALL
9944
    || (operands[2] == const1_rtx
9945
        && TARGET_SHIFT1))
9946
   && ix86_match_ccmode (insn, CCGOCmode)"
9947
{
9948
  if (operands[2] == const1_rtx
9949
      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9950
    return "{}\t%0";
9951
  else
9952
    return "{}\t{%2, %0|%0, %2}";
9953
}
9954
  [(set_attr "type" "ishift")
9955
   (set (attr "length_immediate")
9956
     (if_then_else
9957
       (and (match_operand 2 "const1_operand" "")
9958
            (ior (match_test "TARGET_SHIFT1")
9959
                 (match_test "optimize_function_for_size_p (cfun)")))
9960
       (const_string "0")
9961
       (const_string "*")))
9962
   (set_attr "mode" "")])
9963
 
9964
;; Rotate instructions
9965
 
9966
(define_expand "ti3"
9967
  [(set (match_operand:TI 0 "register_operand" "")
9968
        (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9969
                       (match_operand:QI 2 "nonmemory_operand" "")))]
9970
  "TARGET_64BIT"
9971
{
9972
  if (const_1_to_63_operand (operands[2], VOIDmode))
9973
    emit_insn (gen_ix86_ti3_doubleword
9974
                (operands[0], operands[1], operands[2]));
9975
  else
9976
    FAIL;
9977
 
9978
  DONE;
9979
})
9980
 
9981
(define_expand "di3"
9982
  [(set (match_operand:DI 0 "shiftdi_operand" "")
9983
        (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9984
                       (match_operand:QI 2 "nonmemory_operand" "")))]
9985
 ""
9986
{
9987
  if (TARGET_64BIT)
9988
    ix86_expand_binary_operator (, DImode, operands);
9989
  else if (const_1_to_31_operand (operands[2], VOIDmode))
9990
    emit_insn (gen_ix86_di3_doubleword
9991
                (operands[0], operands[1], operands[2]));
9992
  else
9993
    FAIL;
9994
 
9995
  DONE;
9996
})
9997
 
9998
(define_expand "3"
9999
  [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10000
        (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10001
                            (match_operand:QI 2 "nonmemory_operand" "")))]
10002
  ""
10003
  "ix86_expand_binary_operator (, mode, operands); DONE;")
10004
 
10005
;; Avoid useless masking of count operand.
10006
(define_insn_and_split "*3_mask"
10007
  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10008
        (any_rotate:SWI48
10009
          (match_operand:SWI48 1 "nonimmediate_operand" "0")
10010
          (subreg:QI
10011
            (and:SI
10012
              (match_operand:SI 2 "nonimmediate_operand" "c")
10013
              (match_operand:SI 3 "const_int_operand" "n")) 0)))
10014
   (clobber (reg:CC FLAGS_REG))]
10015
  "ix86_binary_operator_ok (, mode, operands)
10016
   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (mode)-1))
10017
      == GET_MODE_BITSIZE (mode)-1"
10018
  "#"
10019
  "&& 1"
10020
  [(parallel [(set (match_dup 0)
10021
                   (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10022
              (clobber (reg:CC FLAGS_REG))])]
10023
{
10024
  if (can_create_pseudo_p ())
10025
    operands [2] = force_reg (SImode, operands[2]);
10026
 
10027
  operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10028
}
10029
  [(set_attr "type" "rotate")
10030
   (set_attr "mode" "")])
10031
 
10032
;; Implement rotation using two double-precision
10033
;; shift instructions and a scratch register.
10034
 
10035
(define_insn_and_split "ix86_rotl3_doubleword"
10036
 [(set (match_operand: 0 "register_operand" "=r")
10037
       (rotate: (match_operand: 1 "register_operand" "0")
10038
                     (match_operand:QI 2 "" "")))
10039
  (clobber (reg:CC FLAGS_REG))
10040
  (clobber (match_scratch:DWIH 3 "=&r"))]
10041
 ""
10042
 "#"
10043
 "reload_completed"
10044
 [(set (match_dup 3) (match_dup 4))
10045
  (parallel
10046
   [(set (match_dup 4)
10047
         (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10048
                   (lshiftrt:DWIH (match_dup 5)
10049
                                  (minus:QI (match_dup 6) (match_dup 2)))))
10050
    (clobber (reg:CC FLAGS_REG))])
10051
  (parallel
10052
   [(set (match_dup 5)
10053
         (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10054
                   (lshiftrt:DWIH (match_dup 3)
10055
                                  (minus:QI (match_dup 6) (match_dup 2)))))
10056
    (clobber (reg:CC FLAGS_REG))])]
10057
{
10058
  operands[6] = GEN_INT (GET_MODE_BITSIZE (mode));
10059
 
10060
  split_double_mode (mode, &operands[0], 1, &operands[4], &operands[5]);
10061
})
10062
 
10063
(define_insn_and_split "ix86_rotr3_doubleword"
10064
 [(set (match_operand: 0 "register_operand" "=r")
10065
       (rotatert: (match_operand: 1 "register_operand" "0")
10066
                       (match_operand:QI 2 "" "")))
10067
  (clobber (reg:CC FLAGS_REG))
10068
  (clobber (match_scratch:DWIH 3 "=&r"))]
10069
 ""
10070
 "#"
10071
 "reload_completed"
10072
 [(set (match_dup 3) (match_dup 4))
10073
  (parallel
10074
   [(set (match_dup 4)
10075
         (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10076
                   (ashift:DWIH (match_dup 5)
10077
                                (minus:QI (match_dup 6) (match_dup 2)))))
10078
    (clobber (reg:CC FLAGS_REG))])
10079
  (parallel
10080
   [(set (match_dup 5)
10081
         (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10082
                   (ashift:DWIH (match_dup 3)
10083
                                (minus:QI (match_dup 6) (match_dup 2)))))
10084
    (clobber (reg:CC FLAGS_REG))])]
10085
{
10086
  operands[6] = GEN_INT (GET_MODE_BITSIZE (mode));
10087
 
10088
  split_double_mode (mode, &operands[0], 1, &operands[4], &operands[5]);
10089
})
10090
 
10091
(define_insn "*bmi2_rorx3_1"
10092
  [(set (match_operand:SWI48 0 "register_operand" "=r")
10093
        (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10094
                        (match_operand:QI 2 "immediate_operand" "")))]
10095
  "TARGET_BMI2"
10096
  "rorx\t{%2, %1, %0|%0, %1, %2}"
10097
  [(set_attr "type" "rotatex")
10098
   (set_attr "mode" "")])
10099
 
10100
(define_insn "*3_1"
10101
  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10102
        (any_rotate:SWI48
10103
          (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10104
          (match_operand:QI 2 "nonmemory_operand" "c,")))
10105
   (clobber (reg:CC FLAGS_REG))]
10106
  "ix86_binary_operator_ok (, mode, operands)"
10107
{
10108
  switch (get_attr_type (insn))
10109
    {
10110
    case TYPE_ROTATEX:
10111
      return "#";
10112
 
10113
    default:
10114
      if (operands[2] == const1_rtx
10115
          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10116
        return "{}\t%0";
10117
      else
10118
        return "{}\t{%2, %0|%0, %2}";
10119
    }
10120
}
10121
  [(set_attr "isa" "*,bmi2")
10122
   (set_attr "type" "rotate,rotatex")
10123
   (set (attr "length_immediate")
10124
     (if_then_else
10125
       (and (eq_attr "type" "rotate")
10126
            (and (match_operand 2 "const1_operand" "")
10127
                 (ior (match_test "TARGET_SHIFT1")
10128
                      (match_test "optimize_function_for_size_p (cfun)"))))
10129
       (const_string "0")
10130
       (const_string "*")))
10131
   (set_attr "mode" "")])
10132
 
10133
;; Convert rotate to the rotatex pattern to avoid flags dependency.
10134
(define_split
10135
  [(set (match_operand:SWI48 0 "register_operand" "")
10136
        (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10137
                      (match_operand:QI 2 "immediate_operand" "")))
10138
   (clobber (reg:CC FLAGS_REG))]
10139
  "TARGET_BMI2 && reload_completed"
10140
  [(set (match_dup 0)
10141
        (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10142
{
10143
  operands[2]
10144
    = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (operands[2]));
10145
})
10146
 
10147
(define_split
10148
  [(set (match_operand:SWI48 0 "register_operand" "")
10149
        (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10150
                        (match_operand:QI 2 "immediate_operand" "")))
10151
   (clobber (reg:CC FLAGS_REG))]
10152
  "TARGET_BMI2 && reload_completed"
10153
  [(set (match_dup 0)
10154
        (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10155
 
10156
(define_insn "*bmi2_rorxsi3_1_zext"
10157
  [(set (match_operand:DI 0 "register_operand" "=r")
10158
        (zero_extend:DI
10159
          (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10160
                       (match_operand:QI 2 "immediate_operand" "I"))))]
10161
  "TARGET_64BIT && TARGET_BMI2"
10162
  "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10163
  [(set_attr "type" "rotatex")
10164
   (set_attr "mode" "SI")])
10165
 
10166
(define_insn "*si3_1_zext"
10167
  [(set (match_operand:DI 0 "register_operand" "=r,r")
10168
        (zero_extend:DI
10169
          (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10170
                         (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10171
   (clobber (reg:CC FLAGS_REG))]
10172
  "TARGET_64BIT && ix86_binary_operator_ok (, SImode, operands)"
10173
{
10174
  switch (get_attr_type (insn))
10175
    {
10176
    case TYPE_ROTATEX:
10177
      return "#";
10178
 
10179
    default:
10180
      if (operands[2] == const1_rtx
10181
          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10182
        return "{l}\t%k0";
10183
      else
10184
        return "{l}\t{%2, %k0|%k0, %2}";
10185
    }
10186
}
10187
  [(set_attr "isa" "*,bmi2")
10188
   (set_attr "type" "rotate,rotatex")
10189
   (set (attr "length_immediate")
10190
     (if_then_else
10191
       (and (eq_attr "type" "rotate")
10192
            (and (match_operand 2 "const1_operand" "")
10193
                 (ior (match_test "TARGET_SHIFT1")
10194
                      (match_test "optimize_function_for_size_p (cfun)"))))
10195
       (const_string "0")
10196
       (const_string "*")))
10197
   (set_attr "mode" "SI")])
10198
 
10199
;; Convert rotate to the rotatex pattern to avoid flags dependency.
10200
(define_split
10201
  [(set (match_operand:DI 0 "register_operand" "")
10202
        (zero_extend:DI
10203
          (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10204
                     (match_operand:QI 2 "immediate_operand" ""))))
10205
   (clobber (reg:CC FLAGS_REG))]
10206
  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10207
  [(set (match_dup 0)
10208
        (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10209
{
10210
  operands[2]
10211
    = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10212
})
10213
 
10214
(define_split
10215
  [(set (match_operand:DI 0 "register_operand" "")
10216
        (zero_extend:DI
10217
          (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10218
                       (match_operand:QI 2 "immediate_operand" ""))))
10219
   (clobber (reg:CC FLAGS_REG))]
10220
  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10221
  [(set (match_dup 0)
10222
        (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10223
 
10224
(define_insn "*3_1"
10225
  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=m")
10226
        (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10227
                          (match_operand:QI 2 "nonmemory_operand" "c")))
10228
   (clobber (reg:CC FLAGS_REG))]
10229
  "ix86_binary_operator_ok (, mode, operands)"
10230
{
10231
  if (operands[2] == const1_rtx
10232
      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10233
    return "{}\t%0";
10234
  else
10235
    return "{}\t{%2, %0|%0, %2}";
10236
}
10237
  [(set_attr "type" "rotate")
10238
   (set (attr "length_immediate")
10239
     (if_then_else
10240
       (and (match_operand 2 "const1_operand" "")
10241
            (ior (match_test "TARGET_SHIFT1")
10242
                 (match_test "optimize_function_for_size_p (cfun)")))
10243
       (const_string "0")
10244
       (const_string "*")))
10245
   (set_attr "mode" "")])
10246
 
10247
(define_insn "*qi3_1_slp"
10248
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10249
        (any_rotate:QI (match_dup 0)
10250
                       (match_operand:QI 1 "nonmemory_operand" "cI")))
10251
   (clobber (reg:CC FLAGS_REG))]
10252
  "(optimize_function_for_size_p (cfun)
10253
    || !TARGET_PARTIAL_REG_STALL
10254
    || (operands[1] == const1_rtx
10255
        && TARGET_SHIFT1))"
10256
{
10257
  if (operands[1] == const1_rtx
10258
      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10259
    return "{b}\t%0";
10260
  else
10261
    return "{b}\t{%1, %0|%0, %1}";
10262
}
10263
  [(set_attr "type" "rotate1")
10264
   (set (attr "length_immediate")
10265
     (if_then_else
10266
       (and (match_operand 1 "const1_operand" "")
10267
            (ior (match_test "TARGET_SHIFT1")
10268
                 (match_test "optimize_function_for_size_p (cfun)")))
10269
       (const_string "0")
10270
       (const_string "*")))
10271
   (set_attr "mode" "QI")])
10272
 
10273
(define_split
10274
 [(set (match_operand:HI 0 "register_operand" "")
10275
       (any_rotate:HI (match_dup 0) (const_int 8)))
10276
  (clobber (reg:CC FLAGS_REG))]
10277
 "reload_completed
10278
  && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10279
 [(parallel [(set (strict_low_part (match_dup 0))
10280
                  (bswap:HI (match_dup 0)))
10281
             (clobber (reg:CC FLAGS_REG))])])
10282
 
10283
;; Bit set / bit test instructions
10284
 
10285
(define_expand "extv"
10286
  [(set (match_operand:SI 0 "register_operand" "")
10287
        (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10288
                         (match_operand:SI 2 "const8_operand" "")
10289
                         (match_operand:SI 3 "const8_operand" "")))]
10290
  ""
10291
{
10292
  /* Handle extractions from %ah et al.  */
10293
  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10294
    FAIL;
10295
 
10296
  /* From mips.md: extract_bit_field doesn't verify that our source
10297
     matches the predicate, so check it again here.  */
10298
  if (! ext_register_operand (operands[1], VOIDmode))
10299
    FAIL;
10300
})
10301
 
10302
(define_expand "extzv"
10303
  [(set (match_operand:SI 0 "register_operand" "")
10304
        (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10305
                         (match_operand:SI 2 "const8_operand" "")
10306
                         (match_operand:SI 3 "const8_operand" "")))]
10307
  ""
10308
{
10309
  /* Handle extractions from %ah et al.  */
10310
  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10311
    FAIL;
10312
 
10313
  /* From mips.md: extract_bit_field doesn't verify that our source
10314
     matches the predicate, so check it again here.  */
10315
  if (! ext_register_operand (operands[1], VOIDmode))
10316
    FAIL;
10317
})
10318
 
10319
(define_expand "insv"
10320
  [(set (zero_extract (match_operand 0 "register_operand" "")
10321
                      (match_operand 1 "const_int_operand" "")
10322
                      (match_operand 2 "const_int_operand" ""))
10323
        (match_operand 3 "register_operand" ""))]
10324
  ""
10325
{
10326
  rtx (*gen_mov_insv_1) (rtx, rtx);
10327
 
10328
  if (ix86_expand_pinsr (operands))
10329
    DONE;
10330
 
10331
  /* Handle insertions to %ah et al.  */
10332
  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10333
    FAIL;
10334
 
10335
  /* From mips.md: insert_bit_field doesn't verify that our source
10336
     matches the predicate, so check it again here.  */
10337
  if (! ext_register_operand (operands[0], VOIDmode))
10338
    FAIL;
10339
 
10340
  gen_mov_insv_1 = (TARGET_64BIT
10341
                    ? gen_movdi_insv_1 : gen_movsi_insv_1);
10342
 
10343
  emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10344
  DONE;
10345
})
10346
 
10347
;; %%% bts, btr, btc, bt.
10348
;; In general these instructions are *slow* when applied to memory,
10349
;; since they enforce atomic operation.  When applied to registers,
10350
;; it depends on the cpu implementation.  They're never faster than
10351
;; the corresponding and/ior/xor operations, so with 32-bit there's
10352
;; no point.  But in 64-bit, we can't hold the relevant immediates
10353
;; within the instruction itself, so operating on bits in the high
10354
;; 32-bits of a register becomes easier.
10355
;;
10356
;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10357
;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10358
;; negdf respectively, so they can never be disabled entirely.
10359
 
10360
(define_insn "*btsq"
10361
  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10362
                         (const_int 1)
10363
                         (match_operand:DI 1 "const_0_to_63_operand" ""))
10364
        (const_int 1))
10365
   (clobber (reg:CC FLAGS_REG))]
10366
  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10367
  "bts{q}\t{%1, %0|%0, %1}"
10368
  [(set_attr "type" "alu1")
10369
   (set_attr "prefix_0f" "1")
10370
   (set_attr "mode" "DI")])
10371
 
10372
(define_insn "*btrq"
10373
  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10374
                         (const_int 1)
10375
                         (match_operand:DI 1 "const_0_to_63_operand" ""))
10376
        (const_int 0))
10377
   (clobber (reg:CC FLAGS_REG))]
10378
  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10379
  "btr{q}\t{%1, %0|%0, %1}"
10380
  [(set_attr "type" "alu1")
10381
   (set_attr "prefix_0f" "1")
10382
   (set_attr "mode" "DI")])
10383
 
10384
(define_insn "*btcq"
10385
  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10386
                         (const_int 1)
10387
                         (match_operand:DI 1 "const_0_to_63_operand" ""))
10388
        (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10389
   (clobber (reg:CC FLAGS_REG))]
10390
  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10391
  "btc{q}\t{%1, %0|%0, %1}"
10392
  [(set_attr "type" "alu1")
10393
   (set_attr "prefix_0f" "1")
10394
   (set_attr "mode" "DI")])
10395
 
10396
;; Allow Nocona to avoid these instructions if a register is available.
10397
 
10398
(define_peephole2
10399
  [(match_scratch:DI 2 "r")
10400
   (parallel [(set (zero_extract:DI
10401
                     (match_operand:DI 0 "register_operand" "")
10402
                     (const_int 1)
10403
                     (match_operand:DI 1 "const_0_to_63_operand" ""))
10404
                   (const_int 1))
10405
              (clobber (reg:CC FLAGS_REG))])]
10406
  "TARGET_64BIT && !TARGET_USE_BT"
10407
  [(const_int 0)]
10408
{
10409
  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10410
  rtx op1;
10411
 
10412
  if (HOST_BITS_PER_WIDE_INT >= 64)
10413
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10414
  else if (i < HOST_BITS_PER_WIDE_INT)
10415
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10416
  else
10417
    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10418
 
10419
  op1 = immed_double_const (lo, hi, DImode);
10420
  if (i >= 31)
10421
    {
10422
      emit_move_insn (operands[2], op1);
10423
      op1 = operands[2];
10424
    }
10425
 
10426
  emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10427
  DONE;
10428
})
10429
 
10430
(define_peephole2
10431
  [(match_scratch:DI 2 "r")
10432
   (parallel [(set (zero_extract:DI
10433
                     (match_operand:DI 0 "register_operand" "")
10434
                     (const_int 1)
10435
                     (match_operand:DI 1 "const_0_to_63_operand" ""))
10436
                   (const_int 0))
10437
              (clobber (reg:CC FLAGS_REG))])]
10438
  "TARGET_64BIT && !TARGET_USE_BT"
10439
  [(const_int 0)]
10440
{
10441
  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10442
  rtx op1;
10443
 
10444
  if (HOST_BITS_PER_WIDE_INT >= 64)
10445
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10446
  else if (i < HOST_BITS_PER_WIDE_INT)
10447
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10448
  else
10449
    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10450
 
10451
  op1 = immed_double_const (~lo, ~hi, DImode);
10452
  if (i >= 32)
10453
    {
10454
      emit_move_insn (operands[2], op1);
10455
      op1 = operands[2];
10456
    }
10457
 
10458
  emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10459
  DONE;
10460
})
10461
 
10462
(define_peephole2
10463
  [(match_scratch:DI 2 "r")
10464
   (parallel [(set (zero_extract:DI
10465
                     (match_operand:DI 0 "register_operand" "")
10466
                     (const_int 1)
10467
                     (match_operand:DI 1 "const_0_to_63_operand" ""))
10468
              (not:DI (zero_extract:DI
10469
                        (match_dup 0) (const_int 1) (match_dup 1))))
10470
              (clobber (reg:CC FLAGS_REG))])]
10471
  "TARGET_64BIT && !TARGET_USE_BT"
10472
  [(const_int 0)]
10473
{
10474
  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10475
  rtx op1;
10476
 
10477
  if (HOST_BITS_PER_WIDE_INT >= 64)
10478
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10479
  else if (i < HOST_BITS_PER_WIDE_INT)
10480
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10481
  else
10482
    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10483
 
10484
  op1 = immed_double_const (lo, hi, DImode);
10485
  if (i >= 31)
10486
    {
10487
      emit_move_insn (operands[2], op1);
10488
      op1 = operands[2];
10489
    }
10490
 
10491
  emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10492
  DONE;
10493
})
10494
 
10495
(define_insn "*bt"
10496
  [(set (reg:CCC FLAGS_REG)
10497
        (compare:CCC
10498
          (zero_extract:SWI48
10499
            (match_operand:SWI48 0 "register_operand" "r")
10500
            (const_int 1)
10501
            (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10502
          (const_int 0)))]
10503
  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10504
  "bt{}\t{%1, %0|%0, %1}"
10505
  [(set_attr "type" "alu1")
10506
   (set_attr "prefix_0f" "1")
10507
   (set_attr "mode" "")])
10508
 
10509
;; Store-flag instructions.
10510
 
10511
;; For all sCOND expanders, also expand the compare or test insn that
10512
;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10513
 
10514
(define_insn_and_split "*setcc_di_1"
10515
  [(set (match_operand:DI 0 "register_operand" "=q")
10516
        (match_operator:DI 1 "ix86_comparison_operator"
10517
          [(reg FLAGS_REG) (const_int 0)]))]
10518
  "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10519
  "#"
10520
  "&& reload_completed"
10521
  [(set (match_dup 2) (match_dup 1))
10522
   (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10523
{
10524
  PUT_MODE (operands[1], QImode);
10525
  operands[2] = gen_lowpart (QImode, operands[0]);
10526
})
10527
 
10528
(define_insn_and_split "*setcc_si_1_and"
10529
  [(set (match_operand:SI 0 "register_operand" "=q")
10530
        (match_operator:SI 1 "ix86_comparison_operator"
10531
          [(reg FLAGS_REG) (const_int 0)]))
10532
   (clobber (reg:CC FLAGS_REG))]
10533
  "!TARGET_PARTIAL_REG_STALL
10534
   && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10535
  "#"
10536
  "&& reload_completed"
10537
  [(set (match_dup 2) (match_dup 1))
10538
   (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10539
              (clobber (reg:CC FLAGS_REG))])]
10540
{
10541
  PUT_MODE (operands[1], QImode);
10542
  operands[2] = gen_lowpart (QImode, operands[0]);
10543
})
10544
 
10545
(define_insn_and_split "*setcc_si_1_movzbl"
10546
  [(set (match_operand:SI 0 "register_operand" "=q")
10547
        (match_operator:SI 1 "ix86_comparison_operator"
10548
          [(reg FLAGS_REG) (const_int 0)]))]
10549
  "!TARGET_PARTIAL_REG_STALL
10550
   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10551
  "#"
10552
  "&& reload_completed"
10553
  [(set (match_dup 2) (match_dup 1))
10554
   (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10555
{
10556
  PUT_MODE (operands[1], QImode);
10557
  operands[2] = gen_lowpart (QImode, operands[0]);
10558
})
10559
 
10560
(define_insn "*setcc_qi"
10561
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10562
        (match_operator:QI 1 "ix86_comparison_operator"
10563
          [(reg FLAGS_REG) (const_int 0)]))]
10564
  ""
10565
  "set%C1\t%0"
10566
  [(set_attr "type" "setcc")
10567
   (set_attr "mode" "QI")])
10568
 
10569
(define_insn "*setcc_qi_slp"
10570
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10571
        (match_operator:QI 1 "ix86_comparison_operator"
10572
          [(reg FLAGS_REG) (const_int 0)]))]
10573
  ""
10574
  "set%C1\t%0"
10575
  [(set_attr "type" "setcc")
10576
   (set_attr "mode" "QI")])
10577
 
10578
;; In general it is not safe to assume too much about CCmode registers,
10579
;; so simplify-rtx stops when it sees a second one.  Under certain
10580
;; conditions this is safe on x86, so help combine not create
10581
;;
10582
;;      seta    %al
10583
;;      testb   %al, %al
10584
;;      sete    %al
10585
 
10586
(define_split
10587
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10588
        (ne:QI (match_operator 1 "ix86_comparison_operator"
10589
                 [(reg FLAGS_REG) (const_int 0)])
10590
            (const_int 0)))]
10591
  ""
10592
  [(set (match_dup 0) (match_dup 1))]
10593
  "PUT_MODE (operands[1], QImode);")
10594
 
10595
(define_split
10596
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10597
        (ne:QI (match_operator 1 "ix86_comparison_operator"
10598
                 [(reg FLAGS_REG) (const_int 0)])
10599
            (const_int 0)))]
10600
  ""
10601
  [(set (match_dup 0) (match_dup 1))]
10602
  "PUT_MODE (operands[1], QImode);")
10603
 
10604
(define_split
10605
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10606
        (eq:QI (match_operator 1 "ix86_comparison_operator"
10607
                 [(reg FLAGS_REG) (const_int 0)])
10608
            (const_int 0)))]
10609
  ""
10610
  [(set (match_dup 0) (match_dup 1))]
10611
{
10612
  rtx new_op1 = copy_rtx (operands[1]);
10613
  operands[1] = new_op1;
10614
  PUT_MODE (new_op1, QImode);
10615
  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10616
                                             GET_MODE (XEXP (new_op1, 0))));
10617
 
10618
  /* Make sure that (a) the CCmode we have for the flags is strong
10619
     enough for the reversed compare or (b) we have a valid FP compare.  */
10620
  if (! ix86_comparison_operator (new_op1, VOIDmode))
10621
    FAIL;
10622
})
10623
 
10624
(define_split
10625
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10626
        (eq:QI (match_operator 1 "ix86_comparison_operator"
10627
                 [(reg FLAGS_REG) (const_int 0)])
10628
            (const_int 0)))]
10629
  ""
10630
  [(set (match_dup 0) (match_dup 1))]
10631
{
10632
  rtx new_op1 = copy_rtx (operands[1]);
10633
  operands[1] = new_op1;
10634
  PUT_MODE (new_op1, QImode);
10635
  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10636
                                             GET_MODE (XEXP (new_op1, 0))));
10637
 
10638
  /* Make sure that (a) the CCmode we have for the flags is strong
10639
     enough for the reversed compare or (b) we have a valid FP compare.  */
10640
  if (! ix86_comparison_operator (new_op1, VOIDmode))
10641
    FAIL;
10642
})
10643
 
10644
;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10645
;; subsequent logical operations are used to imitate conditional moves.
10646
;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10647
;; it directly.
10648
 
10649
(define_insn "setcc__sse"
10650
  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10651
        (match_operator:MODEF 3 "sse_comparison_operator"
10652
          [(match_operand:MODEF 1 "register_operand" "0,x")
10653
           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10654
  "SSE_FLOAT_MODE_P (mode)"
10655
  "@
10656
   cmp%D3\t{%2, %0|%0, %2}
10657
   vcmp%D3\t{%2, %1, %0|%0, %1, %2}"
10658
  [(set_attr "isa" "noavx,avx")
10659
   (set_attr "type" "ssecmp")
10660
   (set_attr "length_immediate" "1")
10661
   (set_attr "prefix" "orig,vex")
10662
   (set_attr "mode" "")])
10663
 
10664
;; Basic conditional jump instructions.
10665
;; We ignore the overflow flag for signed branch instructions.
10666
 
10667
(define_insn "*jcc_1"
10668
  [(set (pc)
10669
        (if_then_else (match_operator 1 "ix86_comparison_operator"
10670
                                      [(reg FLAGS_REG) (const_int 0)])
10671
                      (label_ref (match_operand 0 "" ""))
10672
                      (pc)))]
10673
  ""
10674
  "%+j%C1\t%l0"
10675
  [(set_attr "type" "ibr")
10676
   (set_attr "modrm" "0")
10677
   (set (attr "length")
10678
           (if_then_else (and (ge (minus (match_dup 0) (pc))
10679
                                  (const_int -126))
10680
                              (lt (minus (match_dup 0) (pc))
10681
                                  (const_int 128)))
10682
             (const_int 2)
10683
             (const_int 6)))])
10684
 
10685
(define_insn "*jcc_2"
10686
  [(set (pc)
10687
        (if_then_else (match_operator 1 "ix86_comparison_operator"
10688
                                      [(reg FLAGS_REG) (const_int 0)])
10689
                      (pc)
10690
                      (label_ref (match_operand 0 "" ""))))]
10691
  ""
10692
  "%+j%c1\t%l0"
10693
  [(set_attr "type" "ibr")
10694
   (set_attr "modrm" "0")
10695
   (set (attr "length")
10696
           (if_then_else (and (ge (minus (match_dup 0) (pc))
10697
                                  (const_int -126))
10698
                              (lt (minus (match_dup 0) (pc))
10699
                                  (const_int 128)))
10700
             (const_int 2)
10701
             (const_int 6)))])
10702
 
10703
;; In general it is not safe to assume too much about CCmode registers,
10704
;; so simplify-rtx stops when it sees a second one.  Under certain
10705
;; conditions this is safe on x86, so help combine not create
10706
;;
10707
;;      seta    %al
10708
;;      testb   %al, %al
10709
;;      je      Lfoo
10710
 
10711
(define_split
10712
  [(set (pc)
10713
        (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10714
                                      [(reg FLAGS_REG) (const_int 0)])
10715
                          (const_int 0))
10716
                      (label_ref (match_operand 1 "" ""))
10717
                      (pc)))]
10718
  ""
10719
  [(set (pc)
10720
        (if_then_else (match_dup 0)
10721
                      (label_ref (match_dup 1))
10722
                      (pc)))]
10723
  "PUT_MODE (operands[0], VOIDmode);")
10724
 
10725
(define_split
10726
  [(set (pc)
10727
        (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10728
                                      [(reg FLAGS_REG) (const_int 0)])
10729
                          (const_int 0))
10730
                      (label_ref (match_operand 1 "" ""))
10731
                      (pc)))]
10732
  ""
10733
  [(set (pc)
10734
        (if_then_else (match_dup 0)
10735
                      (label_ref (match_dup 1))
10736
                      (pc)))]
10737
{
10738
  rtx new_op0 = copy_rtx (operands[0]);
10739
  operands[0] = new_op0;
10740
  PUT_MODE (new_op0, VOIDmode);
10741
  PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10742
                                             GET_MODE (XEXP (new_op0, 0))));
10743
 
10744
  /* Make sure that (a) the CCmode we have for the flags is strong
10745
     enough for the reversed compare or (b) we have a valid FP compare.  */
10746
  if (! ix86_comparison_operator (new_op0, VOIDmode))
10747
    FAIL;
10748
})
10749
 
10750
;; zero_extend in SImode is correct also for DImode, since this is what combine
10751
;; pass generates from shift insn with QImode operand.  Actually, the mode
10752
;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10753
;; appropriate modulo of the bit offset value.
10754
 
10755
(define_insn_and_split "*jcc_bt"
10756
  [(set (pc)
10757
        (if_then_else (match_operator 0 "bt_comparison_operator"
10758
                        [(zero_extract:SWI48
10759
                           (match_operand:SWI48 1 "register_operand" "r")
10760
                           (const_int 1)
10761
                           (zero_extend:SI
10762
                             (match_operand:QI 2 "register_operand" "r")))
10763
                         (const_int 0)])
10764
                      (label_ref (match_operand 3 "" ""))
10765
                      (pc)))
10766
   (clobber (reg:CC FLAGS_REG))]
10767
  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10768
  "#"
10769
  "&& 1"
10770
  [(set (reg:CCC FLAGS_REG)
10771
        (compare:CCC
10772
          (zero_extract:SWI48
10773
            (match_dup 1)
10774
            (const_int 1)
10775
            (match_dup 2))
10776
          (const_int 0)))
10777
   (set (pc)
10778
        (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10779
                      (label_ref (match_dup 3))
10780
                      (pc)))]
10781
{
10782
  operands[2] = simplify_gen_subreg (mode, operands[2], QImode, 0);
10783
 
10784
  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10785
})
10786
 
10787
;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10788
;; also for DImode, this is what combine produces.
10789
(define_insn_and_split "*jcc_bt_mask"
10790
  [(set (pc)
10791
        (if_then_else (match_operator 0 "bt_comparison_operator"
10792
                        [(zero_extract:SWI48
10793
                           (match_operand:SWI48 1 "register_operand" "r")
10794
                           (const_int 1)
10795
                           (and:SI
10796
                             (match_operand:SI 2 "register_operand" "r")
10797
                             (match_operand:SI 3 "const_int_operand" "n")))])
10798
                      (label_ref (match_operand 4 "" ""))
10799
                      (pc)))
10800
   (clobber (reg:CC FLAGS_REG))]
10801
  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10802
   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (mode)-1))
10803
      == GET_MODE_BITSIZE (mode)-1"
10804
  "#"
10805
  "&& 1"
10806
  [(set (reg:CCC FLAGS_REG)
10807
        (compare:CCC
10808
          (zero_extract:SWI48
10809
            (match_dup 1)
10810
            (const_int 1)
10811
            (match_dup 2))
10812
          (const_int 0)))
10813
   (set (pc)
10814
        (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10815
                      (label_ref (match_dup 4))
10816
                      (pc)))]
10817
{
10818
  operands[2] = simplify_gen_subreg (mode, operands[2], SImode, 0);
10819
 
10820
  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10821
})
10822
 
10823
(define_insn_and_split "*jcc_btsi_1"
10824
  [(set (pc)
10825
        (if_then_else (match_operator 0 "bt_comparison_operator"
10826
                        [(and:SI
10827
                           (lshiftrt:SI
10828
                             (match_operand:SI 1 "register_operand" "r")
10829
                             (match_operand:QI 2 "register_operand" "r"))
10830
                           (const_int 1))
10831
                         (const_int 0)])
10832
                      (label_ref (match_operand 3 "" ""))
10833
                      (pc)))
10834
   (clobber (reg:CC FLAGS_REG))]
10835
  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10836
  "#"
10837
  "&& 1"
10838
  [(set (reg:CCC FLAGS_REG)
10839
        (compare:CCC
10840
          (zero_extract:SI
10841
            (match_dup 1)
10842
            (const_int 1)
10843
            (match_dup 2))
10844
          (const_int 0)))
10845
   (set (pc)
10846
        (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10847
                      (label_ref (match_dup 3))
10848
                      (pc)))]
10849
{
10850
  operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10851
 
10852
  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10853
})
10854
 
10855
;; avoid useless masking of bit offset operand
10856
(define_insn_and_split "*jcc_btsi_mask_1"
10857
  [(set (pc)
10858
        (if_then_else
10859
          (match_operator 0 "bt_comparison_operator"
10860
            [(and:SI
10861
               (lshiftrt:SI
10862
                 (match_operand:SI 1 "register_operand" "r")
10863
                 (subreg:QI
10864
                   (and:SI
10865
                     (match_operand:SI 2 "register_operand" "r")
10866
                     (match_operand:SI 3 "const_int_operand" "n")) 0))
10867
               (const_int 1))
10868
             (const_int 0)])
10869
          (label_ref (match_operand 4 "" ""))
10870
          (pc)))
10871
   (clobber (reg:CC FLAGS_REG))]
10872
  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10873
   && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10874
  "#"
10875
  "&& 1"
10876
  [(set (reg:CCC FLAGS_REG)
10877
        (compare:CCC
10878
          (zero_extract:SI
10879
            (match_dup 1)
10880
            (const_int 1)
10881
            (match_dup 2))
10882
          (const_int 0)))
10883
   (set (pc)
10884
        (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10885
                      (label_ref (match_dup 4))
10886
                      (pc)))]
10887
  "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10888
 
10889
;; Define combination compare-and-branch fp compare instructions to help
10890
;; combine.
10891
 
10892
(define_insn "*fp_jcc_1_387"
10893
  [(set (pc)
10894
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10895
                        [(match_operand 1 "register_operand" "f")
10896
                         (match_operand 2 "nonimmediate_operand" "fm")])
10897
          (label_ref (match_operand 3 "" ""))
10898
          (pc)))
10899
   (clobber (reg:CCFP FPSR_REG))
10900
   (clobber (reg:CCFP FLAGS_REG))
10901
   (clobber (match_scratch:HI 4 "=a"))]
10902
  "TARGET_80387
10903
   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10904
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
10905
   && SELECT_CC_MODE (GET_CODE (operands[0]),
10906
                      operands[1], operands[2]) == CCFPmode
10907
   && !TARGET_CMOVE"
10908
  "#")
10909
 
10910
(define_insn "*fp_jcc_1r_387"
10911
  [(set (pc)
10912
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10913
                        [(match_operand 1 "register_operand" "f")
10914
                         (match_operand 2 "nonimmediate_operand" "fm")])
10915
          (pc)
10916
          (label_ref (match_operand 3 "" ""))))
10917
   (clobber (reg:CCFP FPSR_REG))
10918
   (clobber (reg:CCFP FLAGS_REG))
10919
   (clobber (match_scratch:HI 4 "=a"))]
10920
  "TARGET_80387
10921
   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10922
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
10923
   && SELECT_CC_MODE (GET_CODE (operands[0]),
10924
                      operands[1], operands[2]) == CCFPmode
10925
   && !TARGET_CMOVE"
10926
  "#")
10927
 
10928
(define_insn "*fp_jcc_2_387"
10929
  [(set (pc)
10930
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10931
                        [(match_operand 1 "register_operand" "f")
10932
                         (match_operand 2 "register_operand" "f")])
10933
          (label_ref (match_operand 3 "" ""))
10934
          (pc)))
10935
   (clobber (reg:CCFP FPSR_REG))
10936
   (clobber (reg:CCFP FLAGS_REG))
10937
   (clobber (match_scratch:HI 4 "=a"))]
10938
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10939
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
10940
   && !TARGET_CMOVE"
10941
  "#")
10942
 
10943
(define_insn "*fp_jcc_2r_387"
10944
  [(set (pc)
10945
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10946
                        [(match_operand 1 "register_operand" "f")
10947
                         (match_operand 2 "register_operand" "f")])
10948
          (pc)
10949
          (label_ref (match_operand 3 "" ""))))
10950
   (clobber (reg:CCFP FPSR_REG))
10951
   (clobber (reg:CCFP FLAGS_REG))
10952
   (clobber (match_scratch:HI 4 "=a"))]
10953
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10954
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
10955
   && !TARGET_CMOVE"
10956
  "#")
10957
 
10958
(define_insn "*fp_jcc_3_387"
10959
  [(set (pc)
10960
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10961
                        [(match_operand 1 "register_operand" "f")
10962
                         (match_operand 2 "const0_operand" "")])
10963
          (label_ref (match_operand 3 "" ""))
10964
          (pc)))
10965
   (clobber (reg:CCFP FPSR_REG))
10966
   (clobber (reg:CCFP FLAGS_REG))
10967
   (clobber (match_scratch:HI 4 "=a"))]
10968
  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10969
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
10970
   && SELECT_CC_MODE (GET_CODE (operands[0]),
10971
                      operands[1], operands[2]) == CCFPmode
10972
   && !TARGET_CMOVE"
10973
  "#")
10974
 
10975
(define_split
10976
  [(set (pc)
10977
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10978
                        [(match_operand 1 "register_operand" "")
10979
                         (match_operand 2 "nonimmediate_operand" "")])
10980
          (match_operand 3 "" "")
10981
          (match_operand 4 "" "")))
10982
   (clobber (reg:CCFP FPSR_REG))
10983
   (clobber (reg:CCFP FLAGS_REG))]
10984
  "reload_completed"
10985
  [(const_int 0)]
10986
{
10987
  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10988
                        operands[3], operands[4], NULL_RTX, NULL_RTX);
10989
  DONE;
10990
})
10991
 
10992
(define_split
10993
  [(set (pc)
10994
        (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10995
                        [(match_operand 1 "register_operand" "")
10996
                         (match_operand 2 "general_operand" "")])
10997
          (match_operand 3 "" "")
10998
          (match_operand 4 "" "")))
10999
   (clobber (reg:CCFP FPSR_REG))
11000
   (clobber (reg:CCFP FLAGS_REG))
11001
   (clobber (match_scratch:HI 5 "=a"))]
11002
  "reload_completed"
11003
  [(const_int 0)]
11004
{
11005
  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11006
                        operands[3], operands[4], operands[5], NULL_RTX);
11007
  DONE;
11008
})
11009
 
11010
;; The order of operands in *fp_jcc_4_387 is forced by combine in
11011
;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11012
;; with a precedence over other operators and is always put in the first
11013
;; place. Swap condition and operands to match ficom instruction.
11014
 
11015
(define_insn "*fp_jcc_4__387"
11016
  [(set (pc)
11017
        (if_then_else
11018
          (match_operator 0 "ix86_swapped_fp_comparison_operator"
11019
            [(match_operator 1 "float_operator"
11020
              [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11021
             (match_operand 3 "register_operand" "f,f")])
11022
          (label_ref (match_operand 4 "" ""))
11023
          (pc)))
11024
   (clobber (reg:CCFP FPSR_REG))
11025
   (clobber (reg:CCFP FLAGS_REG))
11026
   (clobber (match_scratch:HI 5 "=a,a"))]
11027
  "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11028
   && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))
11029
   && GET_MODE (operands[1]) == GET_MODE (operands[3])
11030
   && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11031
   && !TARGET_CMOVE"
11032
  "#")
11033
 
11034
(define_split
11035
  [(set (pc)
11036
        (if_then_else
11037
          (match_operator 0 "ix86_swapped_fp_comparison_operator"
11038
            [(match_operator 1 "float_operator"
11039
              [(match_operand:SWI24 2 "memory_operand" "")])
11040
             (match_operand 3 "register_operand" "")])
11041
          (match_operand 4 "" "")
11042
          (match_operand 5 "" "")))
11043
   (clobber (reg:CCFP FPSR_REG))
11044
   (clobber (reg:CCFP FLAGS_REG))
11045
   (clobber (match_scratch:HI 6 "=a"))]
11046
  "reload_completed"
11047
  [(const_int 0)]
11048
{
11049
  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11050
 
11051
  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11052
                        operands[3], operands[7],
11053
                        operands[4], operands[5], operands[6], NULL_RTX);
11054
  DONE;
11055
})
11056
 
11057
;; %%% Kill this when reload knows how to do it.
11058
(define_split
11059
  [(set (pc)
11060
        (if_then_else
11061
          (match_operator 0 "ix86_swapped_fp_comparison_operator"
11062
            [(match_operator 1 "float_operator"
11063
              [(match_operand:SWI24 2 "register_operand" "")])
11064
             (match_operand 3 "register_operand" "")])
11065
          (match_operand 4 "" "")
11066
          (match_operand 5 "" "")))
11067
   (clobber (reg:CCFP FPSR_REG))
11068
   (clobber (reg:CCFP FLAGS_REG))
11069
   (clobber (match_scratch:HI 6 "=a"))]
11070
  "reload_completed"
11071
  [(const_int 0)]
11072
{
11073
  operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11074
  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11075
 
11076
  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11077
                        operands[3], operands[7],
11078
                        operands[4], operands[5], operands[6], operands[2]);
11079
  DONE;
11080
})
11081
 
11082
;; Unconditional and other jump instructions
11083
 
11084
(define_insn "jump"
11085
  [(set (pc)
11086
        (label_ref (match_operand 0 "" "")))]
11087
  ""
11088
  "jmp\t%l0"
11089
  [(set_attr "type" "ibr")
11090
   (set (attr "length")
11091
           (if_then_else (and (ge (minus (match_dup 0) (pc))
11092
                                  (const_int -126))
11093
                              (lt (minus (match_dup 0) (pc))
11094
                                  (const_int 128)))
11095
             (const_int 2)
11096
             (const_int 5)))
11097
   (set_attr "modrm" "0")])
11098
 
11099
(define_expand "indirect_jump"
11100
  [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11101
 
11102
(define_insn "*indirect_jump"
11103
  [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11104
  ""
11105
  "jmp\t%A0"
11106
  [(set_attr "type" "ibr")
11107
   (set_attr "length_immediate" "0")])
11108
 
11109
(define_expand "tablejump"
11110
  [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11111
              (use (label_ref (match_operand 1 "" "")))])]
11112
  ""
11113
{
11114
  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11115
     relative.  Convert the relative address to an absolute address.  */
11116
  if (flag_pic)
11117
    {
11118
      rtx op0, op1;
11119
      enum rtx_code code;
11120
 
11121
      /* We can't use @GOTOFF for text labels on VxWorks;
11122
         see gotoff_operand.  */
11123
      if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11124
        {
11125
          code = PLUS;
11126
          op0 = operands[0];
11127
          op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11128
        }
11129
      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11130
        {
11131
          code = PLUS;
11132
          op0 = operands[0];
11133
          op1 = pic_offset_table_rtx;
11134
        }
11135
      else
11136
        {
11137
          code = MINUS;
11138
          op0 = pic_offset_table_rtx;
11139
          op1 = operands[0];
11140
        }
11141
 
11142
      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11143
                                         OPTAB_DIRECT);
11144
    }
11145
  else if (TARGET_X32)
11146
    operands[0] = convert_memory_address (Pmode, operands[0]);
11147
})
11148
 
11149
(define_insn "*tablejump_1"
11150
  [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11151
   (use (label_ref (match_operand 1 "" "")))]
11152
  ""
11153
  "jmp\t%A0"
11154
  [(set_attr "type" "ibr")
11155
   (set_attr "length_immediate" "0")])
11156
 
11157
;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11158
 
11159
(define_peephole2
11160
  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11161
   (set (match_operand:QI 1 "register_operand" "")
11162
        (match_operator:QI 2 "ix86_comparison_operator"
11163
          [(reg FLAGS_REG) (const_int 0)]))
11164
   (set (match_operand 3 "q_regs_operand" "")
11165
        (zero_extend (match_dup 1)))]
11166
  "(peep2_reg_dead_p (3, operands[1])
11167
    || operands_match_p (operands[1], operands[3]))
11168
   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11169
  [(set (match_dup 4) (match_dup 0))
11170
   (set (strict_low_part (match_dup 5))
11171
        (match_dup 2))]
11172
{
11173
  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11174
  operands[5] = gen_lowpart (QImode, operands[3]);
11175
  ix86_expand_clear (operands[3]);
11176
})
11177
 
11178
;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11179
 
11180
(define_peephole2
11181
  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11182
   (set (match_operand:QI 1 "register_operand" "")
11183
        (match_operator:QI 2 "ix86_comparison_operator"
11184
          [(reg FLAGS_REG) (const_int 0)]))
11185
   (parallel [(set (match_operand 3 "q_regs_operand" "")
11186
                   (zero_extend (match_dup 1)))
11187
              (clobber (reg:CC FLAGS_REG))])]
11188
  "(peep2_reg_dead_p (3, operands[1])
11189
    || operands_match_p (operands[1], operands[3]))
11190
   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11191
  [(set (match_dup 4) (match_dup 0))
11192
   (set (strict_low_part (match_dup 5))
11193
        (match_dup 2))]
11194
{
11195
  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11196
  operands[5] = gen_lowpart (QImode, operands[3]);
11197
  ix86_expand_clear (operands[3]);
11198
})
11199
 
11200
;; Call instructions.
11201
 
11202
;; The predicates normally associated with named expanders are not properly
11203
;; checked for calls.  This is a bug in the generic code, but it isn't that
11204
;; easy to fix.  Ignore it for now and be prepared to fix things up.
11205
 
11206
;; P6 processors will jump to the address after the decrement when %esp
11207
;; is used as a call operand, so they will execute return address as a code.
11208
;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11209
 
11210
;; Register constraint for call instruction.
11211
(define_mode_attr c [(SI "l") (DI "r")])
11212
 
11213
;; Call subroutine returning no value.
11214
 
11215
(define_expand "call"
11216
  [(call (match_operand:QI 0 "" "")
11217
         (match_operand 1 "" ""))
11218
   (use (match_operand 2 "" ""))]
11219
  ""
11220
{
11221
  ix86_expand_call (NULL, operands[0], operands[1],
11222
                    operands[2], NULL, false);
11223
  DONE;
11224
})
11225
 
11226
(define_expand "sibcall"
11227
  [(call (match_operand:QI 0 "" "")
11228
         (match_operand 1 "" ""))
11229
   (use (match_operand 2 "" ""))]
11230
  ""
11231
{
11232
  ix86_expand_call (NULL, operands[0], operands[1],
11233
                    operands[2], NULL, true);
11234
  DONE;
11235
})
11236
 
11237
(define_insn_and_split "*call_vzeroupper"
11238
  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "zw"))
11239
         (match_operand 1 "" ""))
11240
   (unspec [(match_operand 2 "const_int_operand" "")]
11241
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
11242
  "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11243
  "#"
11244
  "&& reload_completed"
11245
  [(const_int 0)]
11246
  "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11247
  [(set_attr "type" "call")])
11248
 
11249
(define_insn "*call"
11250
  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "zw"))
11251
         (match_operand 1 "" ""))]
11252
  "!SIBLING_CALL_P (insn)"
11253
  "* return ix86_output_call_insn (insn, operands[0]);"
11254
  [(set_attr "type" "call")])
11255
 
11256
(define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11257
  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11258
         (match_operand 1 "" ""))
11259
   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11260
   (clobber (reg:TI XMM6_REG))
11261
   (clobber (reg:TI XMM7_REG))
11262
   (clobber (reg:TI XMM8_REG))
11263
   (clobber (reg:TI XMM9_REG))
11264
   (clobber (reg:TI XMM10_REG))
11265
   (clobber (reg:TI XMM11_REG))
11266
   (clobber (reg:TI XMM12_REG))
11267
   (clobber (reg:TI XMM13_REG))
11268
   (clobber (reg:TI XMM14_REG))
11269
   (clobber (reg:TI XMM15_REG))
11270
   (clobber (reg:DI SI_REG))
11271
   (clobber (reg:DI DI_REG))
11272
   (unspec [(match_operand 2 "const_int_operand" "")]
11273
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
11274
  "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11275
  "#"
11276
  "&& reload_completed"
11277
  [(const_int 0)]
11278
  "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11279
  [(set_attr "type" "call")])
11280
 
11281
(define_insn "*call_rex64_ms_sysv"
11282
  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11283
         (match_operand 1 "" ""))
11284
   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11285
   (clobber (reg:TI XMM6_REG))
11286
   (clobber (reg:TI XMM7_REG))
11287
   (clobber (reg:TI XMM8_REG))
11288
   (clobber (reg:TI XMM9_REG))
11289
   (clobber (reg:TI XMM10_REG))
11290
   (clobber (reg:TI XMM11_REG))
11291
   (clobber (reg:TI XMM12_REG))
11292
   (clobber (reg:TI XMM13_REG))
11293
   (clobber (reg:TI XMM14_REG))
11294
   (clobber (reg:TI XMM15_REG))
11295
   (clobber (reg:DI SI_REG))
11296
   (clobber (reg:DI DI_REG))]
11297
  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11298
  "* return ix86_output_call_insn (insn, operands[0]);"
11299
  [(set_attr "type" "call")])
11300
 
11301
(define_insn_and_split "*sibcall_vzeroupper"
11302
  [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11303
         (match_operand 1 "" ""))
11304
   (unspec [(match_operand 2 "const_int_operand" "")]
11305
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
11306
  "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11307
  "#"
11308
  "&& reload_completed"
11309
  [(const_int 0)]
11310
  "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11311
  [(set_attr "type" "call")])
11312
 
11313
(define_insn "*sibcall"
11314
  [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11315
         (match_operand 1 "" ""))]
11316
  "SIBLING_CALL_P (insn)"
11317
  "* return ix86_output_call_insn (insn, operands[0]);"
11318
  [(set_attr "type" "call")])
11319
 
11320
(define_expand "call_pop"
11321
  [(parallel [(call (match_operand:QI 0 "" "")
11322
                    (match_operand:SI 1 "" ""))
11323
              (set (reg:SI SP_REG)
11324
                   (plus:SI (reg:SI SP_REG)
11325
                            (match_operand:SI 3 "" "")))])]
11326
  "!TARGET_64BIT"
11327
{
11328
  ix86_expand_call (NULL, operands[0], operands[1],
11329
                    operands[2], operands[3], false);
11330
  DONE;
11331
})
11332
 
11333
(define_insn_and_split "*call_pop_vzeroupper"
11334
  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11335
         (match_operand:SI 1 "" ""))
11336
   (set (reg:SI SP_REG)
11337
        (plus:SI (reg:SI SP_REG)
11338
                 (match_operand:SI 2 "immediate_operand" "i")))
11339
   (unspec [(match_operand 3 "const_int_operand" "")]
11340
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
11341
  "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11342
  "#"
11343
  "&& reload_completed"
11344
  [(const_int 0)]
11345
  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11346
  [(set_attr "type" "call")])
11347
 
11348
(define_insn "*call_pop"
11349
  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11350
         (match_operand 1 "" ""))
11351
   (set (reg:SI SP_REG)
11352
        (plus:SI (reg:SI SP_REG)
11353
                 (match_operand:SI 2 "immediate_operand" "i")))]
11354
  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11355
  "* return ix86_output_call_insn (insn, operands[0]);"
11356
  [(set_attr "type" "call")])
11357
 
11358
(define_insn_and_split "*sibcall_pop_vzeroupper"
11359
  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11360
         (match_operand 1 "" ""))
11361
   (set (reg:SI SP_REG)
11362
        (plus:SI (reg:SI SP_REG)
11363
                 (match_operand:SI 2 "immediate_operand" "i")))
11364
   (unspec [(match_operand 3 "const_int_operand" "")]
11365
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
11366
  "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11367
  "#"
11368
  "&& reload_completed"
11369
  [(const_int 0)]
11370
  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11371
  [(set_attr "type" "call")])
11372
 
11373
(define_insn "*sibcall_pop"
11374
  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11375
         (match_operand 1 "" ""))
11376
   (set (reg:SI SP_REG)
11377
        (plus:SI (reg:SI SP_REG)
11378
                 (match_operand:SI 2 "immediate_operand" "i")))]
11379
  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11380
  "* return ix86_output_call_insn (insn, operands[0]);"
11381
  [(set_attr "type" "call")])
11382
 
11383
;; Call subroutine, returning value in operand 0
11384
 
11385
(define_expand "call_value"
11386
  [(set (match_operand 0 "" "")
11387
        (call (match_operand:QI 1 "" "")
11388
              (match_operand 2 "" "")))
11389
   (use (match_operand 3 "" ""))]
11390
  ""
11391
{
11392
  ix86_expand_call (operands[0], operands[1], operands[2],
11393
                    operands[3], NULL, false);
11394
  DONE;
11395
})
11396
 
11397
(define_expand "sibcall_value"
11398
  [(set (match_operand 0 "" "")
11399
        (call (match_operand:QI 1 "" "")
11400
              (match_operand 2 "" "")))
11401
   (use (match_operand 3 "" ""))]
11402
  ""
11403
{
11404
  ix86_expand_call (operands[0], operands[1], operands[2],
11405
                    operands[3], NULL, true);
11406
  DONE;
11407
})
11408
 
11409
(define_insn_and_split "*call_value_vzeroupper"
11410
  [(set (match_operand 0 "" "")
11411
        (call (mem:QI (match_operand:P 1 "call_insn_operand" "zw"))
11412
              (match_operand 2 "" "")))
11413
   (unspec [(match_operand 3 "const_int_operand" "")]
11414
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
11415
  "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11416
  "#"
11417
  "&& reload_completed"
11418
  [(const_int 0)]
11419
  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11420
  [(set_attr "type" "callv")])
11421
 
11422
(define_insn "*call_value"
11423
  [(set (match_operand 0 "" "")
11424
        (call (mem:QI (match_operand:P 1 "call_insn_operand" "zw"))
11425
              (match_operand 2 "" "")))]
11426
  "!SIBLING_CALL_P (insn)"
11427
  "* return ix86_output_call_insn (insn, operands[1]);"
11428
  [(set_attr "type" "callv")])
11429
 
11430
(define_insn_and_split "*sibcall_value_vzeroupper"
11431
  [(set (match_operand 0 "" "")
11432
        (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11433
              (match_operand 2 "" "")))
11434
   (unspec [(match_operand 3 "const_int_operand" "")]
11435
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
11436
  "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11437
  "#"
11438
  "&& reload_completed"
11439
  [(const_int 0)]
11440
  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11441
  [(set_attr "type" "callv")])
11442
 
11443
(define_insn "*sibcall_value"
11444
  [(set (match_operand 0 "" "")
11445
        (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11446
              (match_operand 2 "" "")))]
11447
  "SIBLING_CALL_P (insn)"
11448
  "* return ix86_output_call_insn (insn, operands[1]);"
11449
  [(set_attr "type" "callv")])
11450
 
11451
(define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11452
  [(set (match_operand 0 "" "")
11453
        (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11454
              (match_operand 2 "" "")))
11455
   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11456
   (clobber (reg:TI XMM6_REG))
11457
   (clobber (reg:TI XMM7_REG))
11458
   (clobber (reg:TI XMM8_REG))
11459
   (clobber (reg:TI XMM9_REG))
11460
   (clobber (reg:TI XMM10_REG))
11461
   (clobber (reg:TI XMM11_REG))
11462
   (clobber (reg:TI XMM12_REG))
11463
   (clobber (reg:TI XMM13_REG))
11464
   (clobber (reg:TI XMM14_REG))
11465
   (clobber (reg:TI XMM15_REG))
11466
   (clobber (reg:DI SI_REG))
11467
   (clobber (reg:DI DI_REG))
11468
   (unspec [(match_operand 3 "const_int_operand" "")]
11469
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
11470
  "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11471
  "#"
11472
  "&& reload_completed"
11473
  [(const_int 0)]
11474
  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11475
  [(set_attr "type" "callv")])
11476
 
11477
(define_insn "*call_value_rex64_ms_sysv"
11478
  [(set (match_operand 0 "" "")
11479
        (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11480
              (match_operand 2 "" "")))
11481
   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11482
   (clobber (reg:TI XMM6_REG))
11483
   (clobber (reg:TI XMM7_REG))
11484
   (clobber (reg:TI XMM8_REG))
11485
   (clobber (reg:TI XMM9_REG))
11486
   (clobber (reg:TI XMM10_REG))
11487
   (clobber (reg:TI XMM11_REG))
11488
   (clobber (reg:TI XMM12_REG))
11489
   (clobber (reg:TI XMM13_REG))
11490
   (clobber (reg:TI XMM14_REG))
11491
   (clobber (reg:TI XMM15_REG))
11492
   (clobber (reg:DI SI_REG))
11493
   (clobber (reg:DI DI_REG))]
11494
  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11495
  "* return ix86_output_call_insn (insn, operands[1]);"
11496
  [(set_attr "type" "callv")])
11497
 
11498
(define_expand "call_value_pop"
11499
  [(parallel [(set (match_operand 0 "" "")
11500
                   (call (match_operand:QI 1 "" "")
11501
                         (match_operand:SI 2 "" "")))
11502
              (set (reg:SI SP_REG)
11503
                   (plus:SI (reg:SI SP_REG)
11504
                            (match_operand:SI 4 "" "")))])]
11505
  "!TARGET_64BIT"
11506
{
11507
  ix86_expand_call (operands[0], operands[1], operands[2],
11508
                    operands[3], operands[4], false);
11509
  DONE;
11510
})
11511
 
11512
(define_insn_and_split "*call_value_pop_vzeroupper"
11513
  [(set (match_operand 0 "" "")
11514
        (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11515
              (match_operand 2 "" "")))
11516
   (set (reg:SI SP_REG)
11517
        (plus:SI (reg:SI SP_REG)
11518
                 (match_operand:SI 3 "immediate_operand" "i")))
11519
   (unspec [(match_operand 4 "const_int_operand" "")]
11520
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
11521
  "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11522
  "#"
11523
  "&& reload_completed"
11524
  [(const_int 0)]
11525
  "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11526
  [(set_attr "type" "callv")])
11527
 
11528
(define_insn "*call_value_pop"
11529
  [(set (match_operand 0 "" "")
11530
        (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11531
              (match_operand 2 "" "")))
11532
   (set (reg:SI SP_REG)
11533
        (plus:SI (reg:SI SP_REG)
11534
                 (match_operand:SI 3 "immediate_operand" "i")))]
11535
  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11536
  "* return ix86_output_call_insn (insn, operands[1]);"
11537
  [(set_attr "type" "callv")])
11538
 
11539
(define_insn_and_split "*sibcall_value_pop_vzeroupper"
11540
  [(set (match_operand 0 "" "")
11541
        (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11542
              (match_operand 2 "" "")))
11543
   (set (reg:SI SP_REG)
11544
        (plus:SI (reg:SI SP_REG)
11545
                 (match_operand:SI 3 "immediate_operand" "i")))
11546
   (unspec [(match_operand 4 "const_int_operand" "")]
11547
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
11548
  "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11549
  "#"
11550
  "&& reload_completed"
11551
  [(const_int 0)]
11552
  "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11553
  [(set_attr "type" "callv")])
11554
 
11555
(define_insn "*sibcall_value_pop"
11556
  [(set (match_operand 0 "" "")
11557
        (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11558
              (match_operand 2 "" "")))
11559
   (set (reg:SI SP_REG)
11560
        (plus:SI (reg:SI SP_REG)
11561
                 (match_operand:SI 3 "immediate_operand" "i")))]
11562
  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11563
  "* return ix86_output_call_insn (insn, operands[1]);"
11564
  [(set_attr "type" "callv")])
11565
 
11566
;; Call subroutine returning any type.
11567
 
11568
(define_expand "untyped_call"
11569
  [(parallel [(call (match_operand 0 "" "")
11570
                    (const_int 0))
11571
              (match_operand 1 "" "")
11572
              (match_operand 2 "" "")])]
11573
  ""
11574
{
11575
  int i;
11576
 
11577
  /* In order to give reg-stack an easier job in validating two
11578
     coprocessor registers as containing a possible return value,
11579
     simply pretend the untyped call returns a complex long double
11580
     value.
11581
 
11582
     We can't use SSE_REGPARM_MAX here since callee is unprototyped
11583
     and should have the default ABI.  */
11584
 
11585
  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11586
                     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11587
                    operands[0], const0_rtx,
11588
                    GEN_INT ((TARGET_64BIT
11589
                              ? (ix86_abi == SYSV_ABI
11590
                                 ? X86_64_SSE_REGPARM_MAX
11591
                                 : X86_64_MS_SSE_REGPARM_MAX)
11592
                              : X86_32_SSE_REGPARM_MAX)
11593
                             - 1),
11594
                    NULL, false);
11595
 
11596
  for (i = 0; i < XVECLEN (operands[2], 0); i++)
11597
    {
11598
      rtx set = XVECEXP (operands[2], 0, i);
11599
      emit_move_insn (SET_DEST (set), SET_SRC (set));
11600
    }
11601
 
11602
  /* The optimizer does not know that the call sets the function value
11603
     registers we stored in the result block.  We avoid problems by
11604
     claiming that all hard registers are used and clobbered at this
11605
     point.  */
11606
  emit_insn (gen_blockage ());
11607
 
11608
  DONE;
11609
})
11610
 
11611
;; Prologue and epilogue instructions
11612
 
11613
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11614
;; all of memory.  This blocks insns from being moved across this point.
11615
 
11616
(define_insn "blockage"
11617
  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11618
  ""
11619
  ""
11620
  [(set_attr "length" "0")])
11621
 
11622
;; Do not schedule instructions accessing memory across this point.
11623
 
11624
(define_expand "memory_blockage"
11625
  [(set (match_dup 0)
11626
        (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11627
  ""
11628
{
11629
  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11630
  MEM_VOLATILE_P (operands[0]) = 1;
11631
})
11632
 
11633
(define_insn "*memory_blockage"
11634
  [(set (match_operand:BLK 0 "" "")
11635
        (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11636
  ""
11637
  ""
11638
  [(set_attr "length" "0")])
11639
 
11640
;; As USE insns aren't meaningful after reload, this is used instead
11641
;; to prevent deleting instructions setting registers for PIC code
11642
(define_insn "prologue_use"
11643
  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11644
  ""
11645
  ""
11646
  [(set_attr "length" "0")])
11647
 
11648
;; Insn emitted into the body of a function to return from a function.
11649
;; This is only done if the function's epilogue is known to be simple.
11650
;; See comments for ix86_can_use_return_insn_p in i386.c.
11651
 
11652
(define_expand "return"
11653
  [(simple_return)]
11654
  "ix86_can_use_return_insn_p ()"
11655
{
11656
  ix86_maybe_emit_epilogue_vzeroupper ();
11657
  if (crtl->args.pops_args)
11658
    {
11659
      rtx popc = GEN_INT (crtl->args.pops_args);
11660
      emit_jump_insn (gen_simple_return_pop_internal (popc));
11661
      DONE;
11662
    }
11663
})
11664
 
11665
;; We need to disable this for TARGET_SEH, as otherwise
11666
;; shrink-wrapped prologue gets enabled too.  This might exceed
11667
;; the maximum size of prologue in unwind information.
11668
 
11669
(define_expand "simple_return"
11670
  [(simple_return)]
11671
  "!TARGET_SEH"
11672
{
11673
  ix86_maybe_emit_epilogue_vzeroupper ();
11674
  if (crtl->args.pops_args)
11675
    {
11676
      rtx popc = GEN_INT (crtl->args.pops_args);
11677
      emit_jump_insn (gen_simple_return_pop_internal (popc));
11678
      DONE;
11679
    }
11680
})
11681
 
11682
(define_insn "simple_return_internal"
11683
  [(simple_return)]
11684
  "reload_completed"
11685
  "ret"
11686
  [(set_attr "length" "1")
11687
   (set_attr "atom_unit" "jeu")
11688
   (set_attr "length_immediate" "0")
11689
   (set_attr "modrm" "0")])
11690
 
11691
;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11692
;; instruction Athlon and K8 have.
11693
 
11694
(define_insn "simple_return_internal_long"
11695
  [(simple_return)
11696
   (unspec [(const_int 0)] UNSPEC_REP)]
11697
  "reload_completed"
11698
  "rep\;ret"
11699
  [(set_attr "length" "2")
11700
   (set_attr "atom_unit" "jeu")
11701
   (set_attr "length_immediate" "0")
11702
   (set_attr "prefix_rep" "1")
11703
   (set_attr "modrm" "0")])
11704
 
11705
(define_insn "simple_return_pop_internal"
11706
  [(simple_return)
11707
   (use (match_operand:SI 0 "const_int_operand" ""))]
11708
  "reload_completed"
11709
  "ret\t%0"
11710
  [(set_attr "length" "3")
11711
   (set_attr "atom_unit" "jeu")
11712
   (set_attr "length_immediate" "2")
11713
   (set_attr "modrm" "0")])
11714
 
11715
(define_insn "simple_return_indirect_internal"
11716
  [(simple_return)
11717
   (use (match_operand:SI 0 "register_operand" "r"))]
11718
  "reload_completed"
11719
  "jmp\t%A0"
11720
  [(set_attr "type" "ibr")
11721
   (set_attr "length_immediate" "0")])
11722
 
11723
(define_insn "nop"
11724
  [(const_int 0)]
11725
  ""
11726
  "nop"
11727
  [(set_attr "length" "1")
11728
   (set_attr "length_immediate" "0")
11729
   (set_attr "modrm" "0")])
11730
 
11731
;; Generate nops.  Operand 0 is the number of nops, up to 8.
11732
(define_insn "nops"
11733
  [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11734
                    UNSPECV_NOPS)]
11735
  "reload_completed"
11736
{
11737
  int num = INTVAL (operands[0]);
11738
 
11739
  gcc_assert (num >= 1 && num <= 8);
11740
 
11741
  while (num--)
11742
    fputs ("\tnop\n", asm_out_file);
11743
 
11744
  return "";
11745
}
11746
  [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11747
   (set_attr "length_immediate" "0")
11748
   (set_attr "modrm" "0")])
11749
 
11750
;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11751
;; branch prediction penalty for the third jump in a 16-byte
11752
;; block on K8.
11753
 
11754
(define_insn "pad"
11755
  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11756
  ""
11757
{
11758
#ifdef ASM_OUTPUT_MAX_SKIP_PAD
11759
  ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11760
#else
11761
  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11762
     The align insn is used to avoid 3 jump instructions in the row to improve
11763
     branch prediction and the benefits hardly outweigh the cost of extra 8
11764
     nops on the average inserted by full alignment pseudo operation.  */
11765
#endif
11766
  return "";
11767
}
11768
  [(set_attr "length" "16")])
11769
 
11770
(define_expand "prologue"
11771
  [(const_int 0)]
11772
  ""
11773
  "ix86_expand_prologue (); DONE;")
11774
 
11775
(define_insn "set_got"
11776
  [(set (match_operand:SI 0 "register_operand" "=r")
11777
        (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11778
   (clobber (reg:CC FLAGS_REG))]
11779
  "!TARGET_64BIT"
11780
  "* return output_set_got (operands[0], NULL_RTX);"
11781
  [(set_attr "type" "multi")
11782
   (set_attr "length" "12")])
11783
 
11784
(define_insn "set_got_labelled"
11785
  [(set (match_operand:SI 0 "register_operand" "=r")
11786
        (unspec:SI [(label_ref (match_operand 1 "" ""))]
11787
         UNSPEC_SET_GOT))
11788
   (clobber (reg:CC FLAGS_REG))]
11789
  "!TARGET_64BIT"
11790
  "* return output_set_got (operands[0], operands[1]);"
11791
  [(set_attr "type" "multi")
11792
   (set_attr "length" "12")])
11793
 
11794
(define_insn "set_got_rex64"
11795
  [(set (match_operand:DI 0 "register_operand" "=r")
11796
        (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11797
  "TARGET_64BIT"
11798
  "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11799
  [(set_attr "type" "lea")
11800
   (set_attr "length_address" "4")
11801
   (set_attr "mode" "DI")])
11802
 
11803
(define_insn "set_rip_rex64"
11804
  [(set (match_operand:DI 0 "register_operand" "=r")
11805
        (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11806
  "TARGET_64BIT"
11807
  "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11808
  [(set_attr "type" "lea")
11809
   (set_attr "length_address" "4")
11810
   (set_attr "mode" "DI")])
11811
 
11812
(define_insn "set_got_offset_rex64"
11813
  [(set (match_operand:DI 0 "register_operand" "=r")
11814
        (unspec:DI
11815
          [(label_ref (match_operand 1 "" ""))]
11816
          UNSPEC_SET_GOT_OFFSET))]
11817
  "TARGET_LP64"
11818
  "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11819
  [(set_attr "type" "imov")
11820
   (set_attr "length_immediate" "0")
11821
   (set_attr "length_address" "8")
11822
   (set_attr "mode" "DI")])
11823
 
11824
(define_expand "epilogue"
11825
  [(const_int 0)]
11826
  ""
11827
  "ix86_expand_epilogue (1); DONE;")
11828
 
11829
(define_expand "sibcall_epilogue"
11830
  [(const_int 0)]
11831
  ""
11832
  "ix86_expand_epilogue (0); DONE;")
11833
 
11834
(define_expand "eh_return"
11835
  [(use (match_operand 0 "register_operand" ""))]
11836
  ""
11837
{
11838
  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11839
 
11840
  /* Tricky bit: we write the address of the handler to which we will
11841
     be returning into someone else's stack frame, one word below the
11842
     stack address we wish to restore.  */
11843
  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11844
  tmp = plus_constant (tmp, -UNITS_PER_WORD);
11845
  tmp = gen_rtx_MEM (Pmode, tmp);
11846
  emit_move_insn (tmp, ra);
11847
 
11848
  emit_jump_insn (gen_eh_return_internal ());
11849
  emit_barrier ();
11850
  DONE;
11851
})
11852
 
11853
(define_insn_and_split "eh_return_internal"
11854
  [(eh_return)]
11855
  ""
11856
  "#"
11857
  "epilogue_completed"
11858
  [(const_int 0)]
11859
  "ix86_expand_epilogue (2); DONE;")
11860
 
11861
(define_insn "leave"
11862
  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11863
   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11864
   (clobber (mem:BLK (scratch)))]
11865
  "!TARGET_64BIT"
11866
  "leave"
11867
  [(set_attr "type" "leave")])
11868
 
11869
(define_insn "leave_rex64"
11870
  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11871
   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11872
   (clobber (mem:BLK (scratch)))]
11873
  "TARGET_64BIT"
11874
  "leave"
11875
  [(set_attr "type" "leave")])
11876
 
11877
;; Handle -fsplit-stack.
11878
 
11879
(define_expand "split_stack_prologue"
11880
  [(const_int 0)]
11881
  ""
11882
{
11883
  ix86_expand_split_stack_prologue ();
11884
  DONE;
11885
})
11886
 
11887
;; In order to support the call/return predictor, we use a return
11888
;; instruction which the middle-end doesn't see.
11889
(define_insn "split_stack_return"
11890
  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11891
                     UNSPECV_SPLIT_STACK_RETURN)]
11892
  ""
11893
{
11894
  if (operands[0] == const0_rtx)
11895
    return "ret";
11896
  else
11897
    return "ret\t%0";
11898
}
11899
  [(set_attr "atom_unit" "jeu")
11900
   (set_attr "modrm" "0")
11901
   (set (attr "length")
11902
        (if_then_else (match_operand:SI 0 "const0_operand" "")
11903
                      (const_int 1)
11904
                      (const_int 3)))
11905
   (set (attr "length_immediate")
11906
        (if_then_else (match_operand:SI 0 "const0_operand" "")
11907
                      (const_int 0)
11908
                      (const_int 2)))])
11909
 
11910
;; If there are operand 0 bytes available on the stack, jump to
11911
;; operand 1.
11912
 
11913
(define_expand "split_stack_space_check"
11914
  [(set (pc) (if_then_else
11915
              (ltu (minus (reg SP_REG)
11916
                          (match_operand 0 "register_operand" ""))
11917
                   (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11918
              (label_ref (match_operand 1 "" ""))
11919
              (pc)))]
11920
  ""
11921
{
11922
  rtx reg, size, limit;
11923
 
11924
  reg = gen_reg_rtx (Pmode);
11925
  size = force_reg (Pmode, operands[0]);
11926
  emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11927
  limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11928
                          UNSPEC_STACK_CHECK);
11929
  limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11930
  ix86_expand_branch (GEU, reg, limit, operands[1]);
11931
 
11932
  DONE;
11933
})
11934
 
11935
;; Bit manipulation instructions.
11936
 
11937
(define_expand "ffs2"
11938
  [(set (match_dup 2) (const_int -1))
11939
   (parallel [(set (reg:CCZ FLAGS_REG)
11940
                   (compare:CCZ
11941
                     (match_operand:SWI48 1 "nonimmediate_operand" "")
11942
                     (const_int 0)))
11943
              (set (match_operand:SWI48 0 "register_operand" "")
11944
                   (ctz:SWI48 (match_dup 1)))])
11945
   (set (match_dup 0) (if_then_else:SWI48
11946
                        (eq (reg:CCZ FLAGS_REG) (const_int 0))
11947
                        (match_dup 2)
11948
                        (match_dup 0)))
11949
   (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11950
              (clobber (reg:CC FLAGS_REG))])]
11951
  ""
11952
{
11953
  if (mode == SImode && !TARGET_CMOVE)
11954
    {
11955
      emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11956
      DONE;
11957
    }
11958
  operands[2] = gen_reg_rtx (mode);
11959
})
11960
 
11961
(define_insn_and_split "ffssi2_no_cmove"
11962
  [(set (match_operand:SI 0 "register_operand" "=r")
11963
        (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11964
   (clobber (match_scratch:SI 2 "=&q"))
11965
   (clobber (reg:CC FLAGS_REG))]
11966
  "!TARGET_CMOVE"
11967
  "#"
11968
  "&& reload_completed"
11969
  [(parallel [(set (reg:CCZ FLAGS_REG)
11970
                   (compare:CCZ (match_dup 1) (const_int 0)))
11971
              (set (match_dup 0) (ctz:SI (match_dup 1)))])
11972
   (set (strict_low_part (match_dup 3))
11973
        (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11974
   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11975
              (clobber (reg:CC FLAGS_REG))])
11976
   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11977
              (clobber (reg:CC FLAGS_REG))])
11978
   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11979
              (clobber (reg:CC FLAGS_REG))])]
11980
{
11981
  operands[3] = gen_lowpart (QImode, operands[2]);
11982
  ix86_expand_clear (operands[2]);
11983
})
11984
 
11985
(define_insn "*ffs_1"
11986
  [(set (reg:CCZ FLAGS_REG)
11987
        (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11988
                     (const_int 0)))
11989
   (set (match_operand:SWI48 0 "register_operand" "=r")
11990
        (ctz:SWI48 (match_dup 1)))]
11991
  ""
11992
  "bsf{}\t{%1, %0|%0, %1}"
11993
  [(set_attr "type" "alu1")
11994
   (set_attr "prefix_0f" "1")
11995
   (set_attr "mode" "")])
11996
 
11997
(define_insn "ctz2"
11998
  [(set (match_operand:SWI248 0 "register_operand" "=r")
11999
        (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12000
   (clobber (reg:CC FLAGS_REG))]
12001
  ""
12002
{
12003
  if (TARGET_BMI)
12004
    return "tzcnt{}\t{%1, %0|%0, %1}";
12005
  else
12006
    return "bsf{}\t{%1, %0|%0, %1}";
12007
}
12008
  [(set_attr "type" "alu1")
12009
   (set_attr "prefix_0f" "1")
12010
   (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12011
   (set_attr "mode" "")])
12012
 
12013
(define_expand "clz2"
12014
  [(parallel
12015
     [(set (match_operand:SWI248 0 "register_operand" "")
12016
           (minus:SWI248
12017
             (match_dup 2)
12018
             (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12019
      (clobber (reg:CC FLAGS_REG))])
12020
   (parallel
12021
     [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12022
      (clobber (reg:CC FLAGS_REG))])]
12023
  ""
12024
{
12025
  if (TARGET_LZCNT)
12026
    {
12027
      emit_insn (gen_clz2_lzcnt (operands[0], operands[1]));
12028
      DONE;
12029
    }
12030
  operands[2] = GEN_INT (GET_MODE_BITSIZE (mode)-1);
12031
})
12032
 
12033
(define_insn "clz2_lzcnt"
12034
  [(set (match_operand:SWI248 0 "register_operand" "=r")
12035
        (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12036
   (clobber (reg:CC FLAGS_REG))]
12037
  "TARGET_LZCNT"
12038
  "lzcnt{}\t{%1, %0|%0, %1}"
12039
  [(set_attr "prefix_rep" "1")
12040
   (set_attr "type" "bitmanip")
12041
   (set_attr "mode" "")])
12042
 
12043
;; BMI instructions.
12044
(define_insn "*bmi_andn_"
12045
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12046
        (and:SWI48
12047
          (not:SWI48
12048
            (match_operand:SWI48 1 "register_operand" "r"))
12049
            (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12050
   (clobber (reg:CC FLAGS_REG))]
12051
  "TARGET_BMI"
12052
  "andn\t{%2, %1, %0|%0, %1, %2}"
12053
  [(set_attr "type" "bitmanip")
12054
   (set_attr "mode" "")])
12055
 
12056
(define_insn "bmi_bextr_"
12057
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12058
        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12059
                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12060
                       UNSPEC_BEXTR))
12061
   (clobber (reg:CC FLAGS_REG))]
12062
  "TARGET_BMI"
12063
  "bextr\t{%2, %1, %0|%0, %1, %2}"
12064
  [(set_attr "type" "bitmanip")
12065
   (set_attr "mode" "")])
12066
 
12067
(define_insn "*bmi_blsi_"
12068
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12069
        (and:SWI48
12070
          (neg:SWI48
12071
            (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12072
          (match_dup 1)))
12073
   (clobber (reg:CC FLAGS_REG))]
12074
  "TARGET_BMI"
12075
  "blsi\t{%1, %0|%0, %1}"
12076
  [(set_attr "type" "bitmanip")
12077
   (set_attr "mode" "")])
12078
 
12079
(define_insn "*bmi_blsmsk_"
12080
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12081
        (xor:SWI48
12082
          (plus:SWI48
12083
            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12084
            (const_int -1))
12085
          (match_dup 1)))
12086
   (clobber (reg:CC FLAGS_REG))]
12087
  "TARGET_BMI"
12088
  "blsmsk\t{%1, %0|%0, %1}"
12089
  [(set_attr "type" "bitmanip")
12090
   (set_attr "mode" "")])
12091
 
12092
(define_insn "*bmi_blsr_"
12093
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12094
        (and:SWI48
12095
          (plus:SWI48
12096
            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12097
            (const_int -1))
12098
          (match_dup 1)))
12099
   (clobber (reg:CC FLAGS_REG))]
12100
   "TARGET_BMI"
12101
   "blsr\t{%1, %0|%0, %1}"
12102
  [(set_attr "type" "bitmanip")
12103
   (set_attr "mode" "")])
12104
 
12105
;; BMI2 instructions.
12106
(define_insn "bmi2_bzhi_3"
12107
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12108
        (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12109
                   (lshiftrt:SWI48 (const_int -1)
12110
                                   (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12111
   (clobber (reg:CC FLAGS_REG))]
12112
  "TARGET_BMI2"
12113
  "bzhi\t{%2, %1, %0|%0, %1, %2}"
12114
  [(set_attr "type" "bitmanip")
12115
   (set_attr "prefix" "vex")
12116
   (set_attr "mode" "")])
12117
 
12118
(define_insn "bmi2_pdep_3"
12119
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12120
        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12121
                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12122
                       UNSPEC_PDEP))]
12123
  "TARGET_BMI2"
12124
  "pdep\t{%2, %1, %0|%0, %1, %2}"
12125
  [(set_attr "type" "bitmanip")
12126
   (set_attr "prefix" "vex")
12127
   (set_attr "mode" "")])
12128
 
12129
(define_insn "bmi2_pext_3"
12130
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12131
        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12132
                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12133
                       UNSPEC_PEXT))]
12134
  "TARGET_BMI2"
12135
  "pext\t{%2, %1, %0|%0, %1, %2}"
12136
  [(set_attr "type" "bitmanip")
12137
   (set_attr "prefix" "vex")
12138
   (set_attr "mode" "")])
12139
 
12140
;; TBM instructions.
12141
(define_insn "tbm_bextri_"
12142
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12143
        (zero_extract:SWI48
12144
          (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12145
          (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12146
          (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12147
   (clobber (reg:CC FLAGS_REG))]
12148
   "TARGET_TBM"
12149
{
12150
  operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12151
  return "bextr\t{%2, %1, %0|%0, %1, %2}";
12152
}
12153
  [(set_attr "type" "bitmanip")
12154
   (set_attr "mode" "")])
12155
 
12156
(define_insn "*tbm_blcfill_"
12157
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12158
        (and:SWI48
12159
          (plus:SWI48
12160
            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12161
            (const_int 1))
12162
          (match_dup 1)))
12163
   (clobber (reg:CC FLAGS_REG))]
12164
   "TARGET_TBM"
12165
   "blcfill\t{%1, %0|%0, %1}"
12166
  [(set_attr "type" "bitmanip")
12167
   (set_attr "mode" "")])
12168
 
12169
(define_insn "*tbm_blci_"
12170
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12171
        (ior:SWI48
12172
          (not:SWI48
12173
            (plus:SWI48
12174
              (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12175
              (const_int 1)))
12176
          (match_dup 1)))
12177
   (clobber (reg:CC FLAGS_REG))]
12178
   "TARGET_TBM"
12179
   "blci\t{%1, %0|%0, %1}"
12180
  [(set_attr "type" "bitmanip")
12181
   (set_attr "mode" "")])
12182
 
12183
(define_insn "*tbm_blcic_"
12184
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12185
        (and:SWI48
12186
          (plus:SWI48
12187
            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12188
            (const_int 1))
12189
          (not:SWI48
12190
            (match_dup 1))))
12191
   (clobber (reg:CC FLAGS_REG))]
12192
   "TARGET_TBM"
12193
   "blcic\t{%1, %0|%0, %1}"
12194
  [(set_attr "type" "bitmanip")
12195
   (set_attr "mode" "")])
12196
 
12197
(define_insn "*tbm_blcmsk_"
12198
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12199
        (xor:SWI48
12200
          (plus:SWI48
12201
            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12202
            (const_int 1))
12203
          (match_dup 1)))
12204
   (clobber (reg:CC FLAGS_REG))]
12205
   "TARGET_TBM"
12206
   "blcmsk\t{%1, %0|%0, %1}"
12207
  [(set_attr "type" "bitmanip")
12208
   (set_attr "mode" "")])
12209
 
12210
(define_insn "*tbm_blcs_"
12211
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12212
        (ior:SWI48
12213
          (plus:SWI48
12214
            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12215
            (const_int 1))
12216
          (match_dup 1)))
12217
   (clobber (reg:CC FLAGS_REG))]
12218
   "TARGET_TBM"
12219
   "blcs\t{%1, %0|%0, %1}"
12220
  [(set_attr "type" "bitmanip")
12221
   (set_attr "mode" "")])
12222
 
12223
(define_insn "*tbm_blsfill_"
12224
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12225
        (ior:SWI48
12226
          (plus:SWI48
12227
            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12228
            (const_int -1))
12229
          (match_dup 1)))
12230
   (clobber (reg:CC FLAGS_REG))]
12231
   "TARGET_TBM"
12232
   "blsfill\t{%1, %0|%0, %1}"
12233
  [(set_attr "type" "bitmanip")
12234
   (set_attr "mode" "")])
12235
 
12236
(define_insn "*tbm_blsic_"
12237
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12238
        (ior:SWI48
12239
          (plus:SWI48
12240
            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12241
            (const_int -1))
12242
          (not:SWI48
12243
            (match_dup 1))))
12244
   (clobber (reg:CC FLAGS_REG))]
12245
   "TARGET_TBM"
12246
   "blsic\t{%1, %0|%0, %1}"
12247
  [(set_attr "type" "bitmanip")
12248
   (set_attr "mode" "")])
12249
 
12250
(define_insn "*tbm_t1mskc_"
12251
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12252
        (ior:SWI48
12253
          (plus:SWI48
12254
            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12255
            (const_int 1))
12256
          (not:SWI48
12257
            (match_dup 1))))
12258
   (clobber (reg:CC FLAGS_REG))]
12259
   "TARGET_TBM"
12260
   "t1mskc\t{%1, %0|%0, %1}"
12261
  [(set_attr "type" "bitmanip")
12262
   (set_attr "mode" "")])
12263
 
12264
(define_insn "*tbm_tzmsk_"
12265
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12266
        (and:SWI48
12267
          (plus:SWI48
12268
            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12269
            (const_int -1))
12270
          (not:SWI48
12271
            (match_dup 1))))
12272
   (clobber (reg:CC FLAGS_REG))]
12273
   "TARGET_TBM"
12274
   "tzmsk\t{%1, %0|%0, %1}"
12275
  [(set_attr "type" "bitmanip")
12276
   (set_attr "mode" "")])
12277
 
12278
(define_insn "bsr_rex64"
12279
  [(set (match_operand:DI 0 "register_operand" "=r")
12280
        (minus:DI (const_int 63)
12281
                  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12282
   (clobber (reg:CC FLAGS_REG))]
12283
  "TARGET_64BIT"
12284
  "bsr{q}\t{%1, %0|%0, %1}"
12285
  [(set_attr "type" "alu1")
12286
   (set_attr "prefix_0f" "1")
12287
   (set_attr "mode" "DI")])
12288
 
12289
(define_insn "bsr"
12290
  [(set (match_operand:SI 0 "register_operand" "=r")
12291
        (minus:SI (const_int 31)
12292
                  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12293
   (clobber (reg:CC FLAGS_REG))]
12294
  ""
12295
  "bsr{l}\t{%1, %0|%0, %1}"
12296
  [(set_attr "type" "alu1")
12297
   (set_attr "prefix_0f" "1")
12298
   (set_attr "mode" "SI")])
12299
 
12300
(define_insn "*bsrhi"
12301
  [(set (match_operand:HI 0 "register_operand" "=r")
12302
        (minus:HI (const_int 15)
12303
                  (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12304
   (clobber (reg:CC FLAGS_REG))]
12305
  ""
12306
  "bsr{w}\t{%1, %0|%0, %1}"
12307
  [(set_attr "type" "alu1")
12308
   (set_attr "prefix_0f" "1")
12309
   (set_attr "mode" "HI")])
12310
 
12311
(define_insn "popcount2"
12312
  [(set (match_operand:SWI248 0 "register_operand" "=r")
12313
        (popcount:SWI248
12314
          (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12315
   (clobber (reg:CC FLAGS_REG))]
12316
  "TARGET_POPCNT"
12317
{
12318
#if TARGET_MACHO
12319
  return "popcnt\t{%1, %0|%0, %1}";
12320
#else
12321
  return "popcnt{}\t{%1, %0|%0, %1}";
12322
#endif
12323
}
12324
  [(set_attr "prefix_rep" "1")
12325
   (set_attr "type" "bitmanip")
12326
   (set_attr "mode" "")])
12327
 
12328
(define_insn "*popcount2_cmp"
12329
  [(set (reg FLAGS_REG)
12330
        (compare
12331
          (popcount:SWI248
12332
            (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12333
          (const_int 0)))
12334
   (set (match_operand:SWI248 0 "register_operand" "=r")
12335
        (popcount:SWI248 (match_dup 1)))]
12336
  "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12337
{
12338
#if TARGET_MACHO
12339
  return "popcnt\t{%1, %0|%0, %1}";
12340
#else
12341
  return "popcnt{}\t{%1, %0|%0, %1}";
12342
#endif
12343
}
12344
  [(set_attr "prefix_rep" "1")
12345
   (set_attr "type" "bitmanip")
12346
   (set_attr "mode" "")])
12347
 
12348
(define_insn "*popcountsi2_cmp_zext"
12349
  [(set (reg FLAGS_REG)
12350
        (compare
12351
          (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12352
          (const_int 0)))
12353
   (set (match_operand:DI 0 "register_operand" "=r")
12354
        (zero_extend:DI(popcount:SI (match_dup 1))))]
12355
  "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12356
{
12357
#if TARGET_MACHO
12358
  return "popcnt\t{%1, %0|%0, %1}";
12359
#else
12360
  return "popcnt{l}\t{%1, %0|%0, %1}";
12361
#endif
12362
}
12363
  [(set_attr "prefix_rep" "1")
12364
   (set_attr "type" "bitmanip")
12365
   (set_attr "mode" "SI")])
12366
 
12367
(define_expand "bswap2"
12368
  [(set (match_operand:SWI48 0 "register_operand" "")
12369
        (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12370
  ""
12371
{
12372
  if (mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12373
    {
12374
      rtx x = operands[0];
12375
 
12376
      emit_move_insn (x, operands[1]);
12377
      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12378
      emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12379
      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12380
      DONE;
12381
    }
12382
})
12383
 
12384
(define_insn "*bswap2_movbe"
12385
  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12386
        (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12387
  "TARGET_MOVBE
12388
   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12389
  "@
12390
    bswap\t%0
12391
    movbe\t{%1, %0|%0, %1}
12392
    movbe\t{%1, %0|%0, %1}"
12393
  [(set_attr "type" "bitmanip,imov,imov")
12394
   (set_attr "modrm" "0,1,1")
12395
   (set_attr "prefix_0f" "*,1,1")
12396
   (set_attr "prefix_extra" "*,1,1")
12397
   (set_attr "mode" "")])
12398
 
12399
(define_insn "*bswap2_1"
12400
  [(set (match_operand:SWI48 0 "register_operand" "=r")
12401
        (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12402
  "TARGET_BSWAP"
12403
  "bswap\t%0"
12404
  [(set_attr "type" "bitmanip")
12405
   (set_attr "modrm" "0")
12406
   (set_attr "mode" "")])
12407
 
12408
(define_insn "*bswaphi_lowpart_1"
12409
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12410
        (bswap:HI (match_dup 0)))
12411
   (clobber (reg:CC FLAGS_REG))]
12412
  "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12413
  "@
12414
    xchg{b}\t{%h0, %b0|%b0, %h0}
12415
    rol{w}\t{$8, %0|%0, 8}"
12416
  [(set_attr "length" "2,4")
12417
   (set_attr "mode" "QI,HI")])
12418
 
12419
(define_insn "bswaphi_lowpart"
12420
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12421
        (bswap:HI (match_dup 0)))
12422
   (clobber (reg:CC FLAGS_REG))]
12423
  ""
12424
  "rol{w}\t{$8, %0|%0, 8}"
12425
  [(set_attr "length" "4")
12426
   (set_attr "mode" "HI")])
12427
 
12428
(define_expand "paritydi2"
12429
  [(set (match_operand:DI 0 "register_operand" "")
12430
        (parity:DI (match_operand:DI 1 "register_operand" "")))]
12431
  "! TARGET_POPCNT"
12432
{
12433
  rtx scratch = gen_reg_rtx (QImode);
12434
  rtx cond;
12435
 
12436
  emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12437
                                NULL_RTX, operands[1]));
12438
 
12439
  cond = gen_rtx_fmt_ee (ORDERED, QImode,
12440
                         gen_rtx_REG (CCmode, FLAGS_REG),
12441
                         const0_rtx);
12442
  emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12443
 
12444
  if (TARGET_64BIT)
12445
    emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12446
  else
12447
    {
12448
      rtx tmp = gen_reg_rtx (SImode);
12449
 
12450
      emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12451
      emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12452
    }
12453
  DONE;
12454
})
12455
 
12456
(define_expand "paritysi2"
12457
  [(set (match_operand:SI 0 "register_operand" "")
12458
        (parity:SI (match_operand:SI 1 "register_operand" "")))]
12459
  "! TARGET_POPCNT"
12460
{
12461
  rtx scratch = gen_reg_rtx (QImode);
12462
  rtx cond;
12463
 
12464
  emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12465
 
12466
  cond = gen_rtx_fmt_ee (ORDERED, QImode,
12467
                         gen_rtx_REG (CCmode, FLAGS_REG),
12468
                         const0_rtx);
12469
  emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12470
 
12471
  emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12472
  DONE;
12473
})
12474
 
12475
(define_insn_and_split "paritydi2_cmp"
12476
  [(set (reg:CC FLAGS_REG)
12477
        (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12478
                   UNSPEC_PARITY))
12479
   (clobber (match_scratch:DI 0 "=r"))
12480
   (clobber (match_scratch:SI 1 "=&r"))
12481
   (clobber (match_scratch:HI 2 "=Q"))]
12482
  "! TARGET_POPCNT"
12483
  "#"
12484
  "&& reload_completed"
12485
  [(parallel
12486
     [(set (match_dup 1)
12487
           (xor:SI (match_dup 1) (match_dup 4)))
12488
      (clobber (reg:CC FLAGS_REG))])
12489
   (parallel
12490
     [(set (reg:CC FLAGS_REG)
12491
           (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12492
      (clobber (match_dup 1))
12493
      (clobber (match_dup 2))])]
12494
{
12495
  operands[4] = gen_lowpart (SImode, operands[3]);
12496
 
12497
  if (TARGET_64BIT)
12498
    {
12499
      emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12500
      emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12501
    }
12502
  else
12503
    operands[1] = gen_highpart (SImode, operands[3]);
12504
})
12505
 
12506
(define_insn_and_split "paritysi2_cmp"
12507
  [(set (reg:CC FLAGS_REG)
12508
        (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12509
                   UNSPEC_PARITY))
12510
   (clobber (match_scratch:SI 0 "=r"))
12511
   (clobber (match_scratch:HI 1 "=&Q"))]
12512
  "! TARGET_POPCNT"
12513
  "#"
12514
  "&& reload_completed"
12515
  [(parallel
12516
     [(set (match_dup 1)
12517
           (xor:HI (match_dup 1) (match_dup 3)))
12518
      (clobber (reg:CC FLAGS_REG))])
12519
   (parallel
12520
     [(set (reg:CC FLAGS_REG)
12521
           (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12522
      (clobber (match_dup 1))])]
12523
{
12524
  operands[3] = gen_lowpart (HImode, operands[2]);
12525
 
12526
  emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12527
  emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12528
})
12529
 
12530
(define_insn "*parityhi2_cmp"
12531
  [(set (reg:CC FLAGS_REG)
12532
        (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12533
                   UNSPEC_PARITY))
12534
   (clobber (match_scratch:HI 0 "=Q"))]
12535
  "! TARGET_POPCNT"
12536
  "xor{b}\t{%h0, %b0|%b0, %h0}"
12537
  [(set_attr "length" "2")
12538
   (set_attr "mode" "HI")])
12539
 
12540
 
12541
;; Thread-local storage patterns for ELF.
12542
;;
12543
;; Note that these code sequences must appear exactly as shown
12544
;; in order to allow linker relaxation.
12545
 
12546
(define_insn "*tls_global_dynamic_32_gnu"
12547
  [(set (match_operand:SI 0 "register_operand" "=a")
12548
        (unspec:SI
12549
         [(match_operand:SI 1 "register_operand" "b")
12550
          (match_operand:SI 2 "tls_symbolic_operand" "")
12551
          (match_operand:SI 3 "constant_call_address_operand" "z")]
12552
         UNSPEC_TLS_GD))
12553
   (clobber (match_scratch:SI 4 "=d"))
12554
   (clobber (match_scratch:SI 5 "=c"))
12555
   (clobber (reg:CC FLAGS_REG))]
12556
  "!TARGET_64BIT && TARGET_GNU_TLS"
12557
{
12558
  output_asm_insn
12559
    ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12560
  if (TARGET_SUN_TLS)
12561
#ifdef HAVE_AS_IX86_TLSGDPLT
12562
    return "call\t%a2@tlsgdplt";
12563
#else
12564
    return "call\t%p3@plt";
12565
#endif
12566
  return "call\t%P3";
12567
}
12568
  [(set_attr "type" "multi")
12569
   (set_attr "length" "12")])
12570
 
12571
(define_expand "tls_global_dynamic_32"
12572
  [(parallel
12573
    [(set (match_operand:SI 0 "register_operand" "")
12574
          (unspec:SI [(match_operand:SI 2 "register_operand" "")
12575
                      (match_operand:SI 1 "tls_symbolic_operand" "")
12576
                      (match_operand:SI 3 "constant_call_address_operand" "")]
12577
                     UNSPEC_TLS_GD))
12578
     (clobber (match_scratch:SI 4 ""))
12579
     (clobber (match_scratch:SI 5 ""))
12580
     (clobber (reg:CC FLAGS_REG))])])
12581
 
12582
(define_insn "*tls_global_dynamic_64"
12583
  [(set (match_operand:DI 0 "register_operand" "=a")
12584
        (call:DI
12585
         (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12586
         (match_operand:DI 3 "" "")))
12587
   (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12588
              UNSPEC_TLS_GD)]
12589
  "TARGET_64BIT"
12590
{
12591
  if (!TARGET_X32)
12592
    fputs (ASM_BYTE "0x66\n", asm_out_file);
12593
  output_asm_insn
12594
    ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12595
  fputs (ASM_SHORT "0x6666\n", asm_out_file);
12596
  fputs ("\trex64\n", asm_out_file);
12597
  if (TARGET_SUN_TLS)
12598
    return "call\t%p2@plt";
12599
  return "call\t%P2";
12600
}
12601
  [(set_attr "type" "multi")
12602
   (set (attr "length")
12603
        (symbol_ref "TARGET_X32 ? 15 : 16"))])
12604
 
12605
(define_expand "tls_global_dynamic_64"
12606
  [(parallel
12607
    [(set (match_operand:DI 0 "register_operand" "")
12608
          (call:DI
12609
           (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12610
           (const_int 0)))
12611
     (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12612
                UNSPEC_TLS_GD)])])
12613
 
12614
(define_insn "*tls_local_dynamic_base_32_gnu"
12615
  [(set (match_operand:SI 0 "register_operand" "=a")
12616
        (unspec:SI
12617
         [(match_operand:SI 1 "register_operand" "b")
12618
          (match_operand:SI 2 "constant_call_address_operand" "z")]
12619
         UNSPEC_TLS_LD_BASE))
12620
   (clobber (match_scratch:SI 3 "=d"))
12621
   (clobber (match_scratch:SI 4 "=c"))
12622
   (clobber (reg:CC FLAGS_REG))]
12623
  "!TARGET_64BIT && TARGET_GNU_TLS"
12624
{
12625
  output_asm_insn
12626
    ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12627
  if (TARGET_SUN_TLS)
12628
#ifdef HAVE_AS_IX86_TLSLDMPLT
12629
    return "call\t%&@tlsldmplt";
12630
#else
12631
    return "call\t%p2@plt";
12632
#endif
12633
  return "call\t%P2";
12634
}
12635
  [(set_attr "type" "multi")
12636
   (set_attr "length" "11")])
12637
 
12638
(define_expand "tls_local_dynamic_base_32"
12639
  [(parallel
12640
     [(set (match_operand:SI 0 "register_operand" "")
12641
           (unspec:SI
12642
            [(match_operand:SI 1 "register_operand" "")
12643
             (match_operand:SI 2 "constant_call_address_operand" "")]
12644
            UNSPEC_TLS_LD_BASE))
12645
      (clobber (match_scratch:SI 3 ""))
12646
      (clobber (match_scratch:SI 4 ""))
12647
      (clobber (reg:CC FLAGS_REG))])])
12648
 
12649
(define_insn "*tls_local_dynamic_base_64"
12650
  [(set (match_operand:DI 0 "register_operand" "=a")
12651
        (call:DI
12652
         (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12653
         (match_operand:DI 2 "" "")))
12654
   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12655
  "TARGET_64BIT"
12656
{
12657
  output_asm_insn
12658
    ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12659
  if (TARGET_SUN_TLS)
12660
    return "call\t%p1@plt";
12661
  return "call\t%P1";
12662
}
12663
  [(set_attr "type" "multi")
12664
   (set_attr "length" "12")])
12665
 
12666
(define_expand "tls_local_dynamic_base_64"
12667
  [(parallel
12668
     [(set (match_operand:DI 0 "register_operand" "")
12669
           (call:DI
12670
            (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12671
            (const_int 0)))
12672
      (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12673
 
12674
;; Local dynamic of a single variable is a lose.  Show combine how
12675
;; to convert that back to global dynamic.
12676
 
12677
(define_insn_and_split "*tls_local_dynamic_32_once"
12678
  [(set (match_operand:SI 0 "register_operand" "=a")
12679
        (plus:SI
12680
         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12681
                     (match_operand:SI 2 "constant_call_address_operand" "z")]
12682
                    UNSPEC_TLS_LD_BASE)
12683
         (const:SI (unspec:SI
12684
                    [(match_operand:SI 3 "tls_symbolic_operand" "")]
12685
                    UNSPEC_DTPOFF))))
12686
   (clobber (match_scratch:SI 4 "=d"))
12687
   (clobber (match_scratch:SI 5 "=c"))
12688
   (clobber (reg:CC FLAGS_REG))]
12689
  ""
12690
  "#"
12691
  ""
12692
  [(parallel
12693
     [(set (match_dup 0)
12694
           (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12695
                      UNSPEC_TLS_GD))
12696
      (clobber (match_dup 4))
12697
      (clobber (match_dup 5))
12698
      (clobber (reg:CC FLAGS_REG))])])
12699
 
12700
;; Segment register for the thread base ptr load
12701
(define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12702
 
12703
;; Load and add the thread base pointer from %:0.
12704
(define_insn "*load_tp_x32"
12705
  [(set (match_operand:SI 0 "register_operand" "=r")
12706
        (unspec:SI [(const_int 0)] UNSPEC_TP))]
12707
  "TARGET_X32"
12708
  "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12709
  [(set_attr "type" "imov")
12710
   (set_attr "modrm" "0")
12711
   (set_attr "length" "7")
12712
   (set_attr "memory" "load")
12713
   (set_attr "imm_disp" "false")])
12714
 
12715
(define_insn "*load_tp_x32_zext"
12716
  [(set (match_operand:DI 0 "register_operand" "=r")
12717
        (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12718
  "TARGET_X32"
12719
  "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12720
  [(set_attr "type" "imov")
12721
   (set_attr "modrm" "0")
12722
   (set_attr "length" "7")
12723
   (set_attr "memory" "load")
12724
   (set_attr "imm_disp" "false")])
12725
 
12726
(define_insn "*load_tp_"
12727
  [(set (match_operand:P 0 "register_operand" "=r")
12728
        (unspec:P [(const_int 0)] UNSPEC_TP))]
12729
  "!TARGET_X32"
12730
  "mov{}\t{%%:0, %0|%0,  PTR :0}"
12731
  [(set_attr "type" "imov")
12732
   (set_attr "modrm" "0")
12733
   (set_attr "length" "7")
12734
   (set_attr "memory" "load")
12735
   (set_attr "imm_disp" "false")])
12736
 
12737
(define_insn "*add_tp_x32"
12738
  [(set (match_operand:SI 0 "register_operand" "=r")
12739
        (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12740
                 (match_operand:SI 1 "register_operand" "0")))
12741
   (clobber (reg:CC FLAGS_REG))]
12742
  "TARGET_X32"
12743
  "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12744
  [(set_attr "type" "alu")
12745
   (set_attr "modrm" "0")
12746
   (set_attr "length" "7")
12747
   (set_attr "memory" "load")
12748
   (set_attr "imm_disp" "false")])
12749
 
12750
(define_insn "*add_tp_x32_zext"
12751
  [(set (match_operand:DI 0 "register_operand" "=r")
12752
        (zero_extend:DI
12753
          (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12754
                   (match_operand:SI 1 "register_operand" "0"))))
12755
   (clobber (reg:CC FLAGS_REG))]
12756
  "TARGET_X32"
12757
  "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12758
  [(set_attr "type" "alu")
12759
   (set_attr "modrm" "0")
12760
   (set_attr "length" "7")
12761
   (set_attr "memory" "load")
12762
   (set_attr "imm_disp" "false")])
12763
 
12764
(define_insn "*add_tp_"
12765
  [(set (match_operand:P 0 "register_operand" "=r")
12766
        (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12767
                (match_operand:P 1 "register_operand" "0")))
12768
   (clobber (reg:CC FLAGS_REG))]
12769
  "!TARGET_X32"
12770
  "add{}\t{%%:0, %0|%0,  PTR :0}"
12771
  [(set_attr "type" "alu")
12772
   (set_attr "modrm" "0")
12773
   (set_attr "length" "7")
12774
   (set_attr "memory" "load")
12775
   (set_attr "imm_disp" "false")])
12776
 
12777
;; The Sun linker took the AMD64 TLS spec literally and can only handle
12778
;; %rax as destination of the initial executable code sequence.
12779
(define_insn "tls_initial_exec_64_sun"
12780
  [(set (match_operand:DI 0 "register_operand" "=a")
12781
        (unspec:DI
12782
         [(match_operand:DI 1 "tls_symbolic_operand" "")]
12783
         UNSPEC_TLS_IE_SUN))
12784
   (clobber (reg:CC FLAGS_REG))]
12785
  "TARGET_64BIT && TARGET_SUN_TLS"
12786
{
12787
  output_asm_insn
12788
    ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12789
  return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12790
}
12791
  [(set_attr "type" "multi")])
12792
 
12793
;; GNU2 TLS patterns can be split.
12794
 
12795
(define_expand "tls_dynamic_gnu2_32"
12796
  [(set (match_dup 3)
12797
        (plus:SI (match_operand:SI 2 "register_operand" "")
12798
                 (const:SI
12799
                  (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12800
                             UNSPEC_TLSDESC))))
12801
   (parallel
12802
    [(set (match_operand:SI 0 "register_operand" "")
12803
          (unspec:SI [(match_dup 1) (match_dup 3)
12804
                      (match_dup 2) (reg:SI SP_REG)]
12805
                      UNSPEC_TLSDESC))
12806
     (clobber (reg:CC FLAGS_REG))])]
12807
  "!TARGET_64BIT && TARGET_GNU2_TLS"
12808
{
12809
  operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12810
  ix86_tls_descriptor_calls_expanded_in_cfun = true;
12811
})
12812
 
12813
(define_insn "*tls_dynamic_gnu2_lea_32"
12814
  [(set (match_operand:SI 0 "register_operand" "=r")
12815
        (plus:SI (match_operand:SI 1 "register_operand" "b")
12816
                 (const:SI
12817
                  (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12818
                              UNSPEC_TLSDESC))))]
12819
  "!TARGET_64BIT && TARGET_GNU2_TLS"
12820
  "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12821
  [(set_attr "type" "lea")
12822
   (set_attr "mode" "SI")
12823
   (set_attr "length" "6")
12824
   (set_attr "length_address" "4")])
12825
 
12826
(define_insn "*tls_dynamic_gnu2_call_32"
12827
  [(set (match_operand:SI 0 "register_operand" "=a")
12828
        (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12829
                    (match_operand:SI 2 "register_operand" "0")
12830
                    ;; we have to make sure %ebx still points to the GOT
12831
                    (match_operand:SI 3 "register_operand" "b")
12832
                    (reg:SI SP_REG)]
12833
                   UNSPEC_TLSDESC))
12834
   (clobber (reg:CC FLAGS_REG))]
12835
  "!TARGET_64BIT && TARGET_GNU2_TLS"
12836
  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12837
  [(set_attr "type" "call")
12838
   (set_attr "length" "2")
12839
   (set_attr "length_address" "0")])
12840
 
12841
(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12842
  [(set (match_operand:SI 0 "register_operand" "=&a")
12843
        (plus:SI
12844
         (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12845
                     (match_operand:SI 4 "" "")
12846
                     (match_operand:SI 2 "register_operand" "b")
12847
                     (reg:SI SP_REG)]
12848
                    UNSPEC_TLSDESC)
12849
         (const:SI (unspec:SI
12850
                    [(match_operand:SI 1 "tls_symbolic_operand" "")]
12851
                    UNSPEC_DTPOFF))))
12852
   (clobber (reg:CC FLAGS_REG))]
12853
  "!TARGET_64BIT && TARGET_GNU2_TLS"
12854
  "#"
12855
  ""
12856
  [(set (match_dup 0) (match_dup 5))]
12857
{
12858
  operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12859
  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12860
})
12861
 
12862
(define_expand "tls_dynamic_gnu2_64"
12863
  [(set (match_dup 2)
12864
        (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12865
                   UNSPEC_TLSDESC))
12866
   (parallel
12867
    [(set (match_operand:DI 0 "register_operand" "")
12868
          (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12869
                     UNSPEC_TLSDESC))
12870
     (clobber (reg:CC FLAGS_REG))])]
12871
  "TARGET_64BIT && TARGET_GNU2_TLS"
12872
{
12873
  operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12874
  ix86_tls_descriptor_calls_expanded_in_cfun = true;
12875
})
12876
 
12877
(define_insn "*tls_dynamic_gnu2_lea_64"
12878
  [(set (match_operand:DI 0 "register_operand" "=r")
12879
        (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12880
                   UNSPEC_TLSDESC))]
12881
  "TARGET_64BIT && TARGET_GNU2_TLS"
12882
  "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12883
  [(set_attr "type" "lea")
12884
   (set_attr "mode" "DI")
12885
   (set_attr "length" "7")
12886
   (set_attr "length_address" "4")])
12887
 
12888
(define_insn "*tls_dynamic_gnu2_call_64"
12889
  [(set (match_operand:DI 0 "register_operand" "=a")
12890
        (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12891
                    (match_operand:DI 2 "register_operand" "0")
12892
                    (reg:DI SP_REG)]
12893
                   UNSPEC_TLSDESC))
12894
   (clobber (reg:CC FLAGS_REG))]
12895
  "TARGET_64BIT && TARGET_GNU2_TLS"
12896
  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12897
  [(set_attr "type" "call")
12898
   (set_attr "length" "2")
12899
   (set_attr "length_address" "0")])
12900
 
12901
(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12902
  [(set (match_operand:DI 0 "register_operand" "=&a")
12903
        (plus:DI
12904
         (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12905
                     (match_operand:DI 3 "" "")
12906
                     (reg:DI SP_REG)]
12907
                    UNSPEC_TLSDESC)
12908
         (const:DI (unspec:DI
12909
                    [(match_operand 1 "tls_symbolic_operand" "")]
12910
                    UNSPEC_DTPOFF))))
12911
   (clobber (reg:CC FLAGS_REG))]
12912
  "TARGET_64BIT && TARGET_GNU2_TLS"
12913
  "#"
12914
  ""
12915
  [(set (match_dup 0) (match_dup 4))]
12916
{
12917
  operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12918
  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12919
})
12920
 
12921
;; These patterns match the binary 387 instructions for addM3, subM3,
12922
;; mulM3 and divM3.  There are three patterns for each of DFmode and
12923
;; SFmode.  The first is the normal insn, the second the same insn but
12924
;; with one operand a conversion, and the third the same insn but with
12925
;; the other operand a conversion.  The conversion may be SFmode or
12926
;; SImode if the target mode DFmode, but only SImode if the target mode
12927
;; is SFmode.
12928
 
12929
;; Gcc is slightly more smart about handling normal two address instructions
12930
;; so use special patterns for add and mull.
12931
 
12932
(define_insn "*fop__comm_mixed"
12933
  [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12934
        (match_operator:MODEF 3 "binary_fp_operator"
12935
          [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12936
           (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12937
  "SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
12938
   && COMMUTATIVE_ARITH_P (operands[3])
12939
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12940
  "* return output_387_binary_op (insn, operands);"
12941
  [(set (attr "type")
12942
        (if_then_else (eq_attr "alternative" "1,2")
12943
           (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12944
              (const_string "ssemul")
12945
              (const_string "sseadd"))
12946
           (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12947
              (const_string "fmul")
12948
              (const_string "fop"))))
12949
   (set_attr "isa" "*,noavx,avx")
12950
   (set_attr "prefix" "orig,orig,vex")
12951
   (set_attr "mode" "")])
12952
 
12953
(define_insn "*fop__comm_sse"
12954
  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12955
        (match_operator:MODEF 3 "binary_fp_operator"
12956
          [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12957
           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12958
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
12959
   && COMMUTATIVE_ARITH_P (operands[3])
12960
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12961
  "* return output_387_binary_op (insn, operands);"
12962
  [(set (attr "type")
12963
        (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12964
           (const_string "ssemul")
12965
           (const_string "sseadd")))
12966
   (set_attr "isa" "noavx,avx")
12967
   (set_attr "prefix" "orig,vex")
12968
   (set_attr "mode" "")])
12969
 
12970
(define_insn "*fop__comm_i387"
12971
  [(set (match_operand:MODEF 0 "register_operand" "=f")
12972
        (match_operator:MODEF 3 "binary_fp_operator"
12973
          [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12974
           (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12975
  "TARGET_80387 && X87_ENABLE_ARITH (mode)
12976
   && COMMUTATIVE_ARITH_P (operands[3])
12977
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12978
  "* return output_387_binary_op (insn, operands);"
12979
  [(set (attr "type")
12980
        (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12981
           (const_string "fmul")
12982
           (const_string "fop")))
12983
   (set_attr "mode" "")])
12984
 
12985
(define_insn "*fop__1_mixed"
12986
  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12987
        (match_operator:MODEF 3 "binary_fp_operator"
12988
          [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12989
           (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12990
  "SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387
12991
   && !COMMUTATIVE_ARITH_P (operands[3])
12992
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12993
  "* return output_387_binary_op (insn, operands);"
12994
  [(set (attr "type")
12995
        (cond [(and (eq_attr "alternative" "2,3")
12996
                    (match_operand:MODEF 3 "mult_operator" ""))
12997
                 (const_string "ssemul")
12998
               (and (eq_attr "alternative" "2,3")
12999
                    (match_operand:MODEF 3 "div_operator" ""))
13000
                 (const_string "ssediv")
13001
               (eq_attr "alternative" "2,3")
13002
                 (const_string "sseadd")
13003
               (match_operand:MODEF 3 "mult_operator" "")
13004
                 (const_string "fmul")
13005
               (match_operand:MODEF 3 "div_operator" "")
13006
                 (const_string "fdiv")
13007
              ]
13008
              (const_string "fop")))
13009
   (set_attr "isa" "*,*,noavx,avx")
13010
   (set_attr "prefix" "orig,orig,orig,vex")
13011
   (set_attr "mode" "")])
13012
 
13013
(define_insn "*rcpsf2_sse"
13014
  [(set (match_operand:SF 0 "register_operand" "=x")
13015
        (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13016
                   UNSPEC_RCP))]
13017
  "TARGET_SSE_MATH"
13018
  "%vrcpss\t{%1, %d0|%d0, %1}"
13019
  [(set_attr "type" "sse")
13020
   (set_attr "atom_sse_attr" "rcp")
13021
   (set_attr "prefix" "maybe_vex")
13022
   (set_attr "mode" "SF")])
13023
 
13024
(define_insn "*fop__1_sse"
13025
  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13026
        (match_operator:MODEF 3 "binary_fp_operator"
13027
          [(match_operand:MODEF 1 "register_operand" "0,x")
13028
           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13029
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
13030
   && !COMMUTATIVE_ARITH_P (operands[3])"
13031
  "* return output_387_binary_op (insn, operands);"
13032
  [(set (attr "type")
13033
        (cond [(match_operand:MODEF 3 "mult_operator" "")
13034
                 (const_string "ssemul")
13035
               (match_operand:MODEF 3 "div_operator" "")
13036
                 (const_string "ssediv")
13037
              ]
13038
              (const_string "sseadd")))
13039
   (set_attr "isa" "noavx,avx")
13040
   (set_attr "prefix" "orig,vex")
13041
   (set_attr "mode" "")])
13042
 
13043
;; This pattern is not fully shadowed by the pattern above.
13044
(define_insn "*fop__1_i387"
13045
  [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13046
        (match_operator:MODEF 3 "binary_fp_operator"
13047
          [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13048
           (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13049
  "TARGET_80387 && X87_ENABLE_ARITH (mode)
13050
   && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13051
   && !COMMUTATIVE_ARITH_P (operands[3])
13052
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13053
  "* return output_387_binary_op (insn, operands);"
13054
  [(set (attr "type")
13055
        (cond [(match_operand:MODEF 3 "mult_operator" "")
13056
                 (const_string "fmul")
13057
               (match_operand:MODEF 3 "div_operator" "")
13058
                 (const_string "fdiv")
13059
              ]
13060
              (const_string "fop")))
13061
   (set_attr "mode" "")])
13062
 
13063
;; ??? Add SSE splitters for these!
13064
(define_insn "*fop__2_i387"
13065
  [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13066
        (match_operator:MODEF 3 "binary_fp_operator"
13067
          [(float:MODEF
13068
             (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13069
           (match_operand:MODEF 2 "register_operand" "0,0")]))]
13070
  "TARGET_80387 && X87_ENABLE_FLOAT (mode, mode)
13071
   && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13072
   && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))"
13073
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13074
  [(set (attr "type")
13075
        (cond [(match_operand:MODEF 3 "mult_operator" "")
13076
                 (const_string "fmul")
13077
               (match_operand:MODEF 3 "div_operator" "")
13078
                 (const_string "fdiv")
13079
              ]
13080
              (const_string "fop")))
13081
   (set_attr "fp_int_src" "true")
13082
   (set_attr "mode" "")])
13083
 
13084
(define_insn "*fop__3_i387"
13085
  [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13086
        (match_operator:MODEF 3 "binary_fp_operator"
13087
          [(match_operand:MODEF 1 "register_operand" "0,0")
13088
           (float:MODEF
13089
             (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13090
  "TARGET_80387 && X87_ENABLE_FLOAT (mode, mode)
13091
   && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13092
   && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))"
13093
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13094
  [(set (attr "type")
13095
        (cond [(match_operand:MODEF 3 "mult_operator" "")
13096
                 (const_string "fmul")
13097
               (match_operand:MODEF 3 "div_operator" "")
13098
                 (const_string "fdiv")
13099
              ]
13100
              (const_string "fop")))
13101
   (set_attr "fp_int_src" "true")
13102
   (set_attr "mode" "")])
13103
 
13104
(define_insn "*fop_df_4_i387"
13105
  [(set (match_operand:DF 0 "register_operand" "=f,f")
13106
        (match_operator:DF 3 "binary_fp_operator"
13107
           [(float_extend:DF
13108
             (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13109
            (match_operand:DF 2 "register_operand" "0,f")]))]
13110
  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13111
   && !(TARGET_SSE2 && TARGET_SSE_MATH)
13112
   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13113
  "* return output_387_binary_op (insn, operands);"
13114
  [(set (attr "type")
13115
        (cond [(match_operand:DF 3 "mult_operator" "")
13116
                 (const_string "fmul")
13117
               (match_operand:DF 3 "div_operator" "")
13118
                 (const_string "fdiv")
13119
              ]
13120
              (const_string "fop")))
13121
   (set_attr "mode" "SF")])
13122
 
13123
(define_insn "*fop_df_5_i387"
13124
  [(set (match_operand:DF 0 "register_operand" "=f,f")
13125
        (match_operator:DF 3 "binary_fp_operator"
13126
          [(match_operand:DF 1 "register_operand" "0,f")
13127
           (float_extend:DF
13128
            (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13129
  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13130
   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13131
  "* return output_387_binary_op (insn, operands);"
13132
  [(set (attr "type")
13133
        (cond [(match_operand:DF 3 "mult_operator" "")
13134
                 (const_string "fmul")
13135
               (match_operand:DF 3 "div_operator" "")
13136
                 (const_string "fdiv")
13137
              ]
13138
              (const_string "fop")))
13139
   (set_attr "mode" "SF")])
13140
 
13141
(define_insn "*fop_df_6_i387"
13142
  [(set (match_operand:DF 0 "register_operand" "=f,f")
13143
        (match_operator:DF 3 "binary_fp_operator"
13144
          [(float_extend:DF
13145
            (match_operand:SF 1 "register_operand" "0,f"))
13146
           (float_extend:DF
13147
            (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13148
  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13149
   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13150
  "* return output_387_binary_op (insn, operands);"
13151
  [(set (attr "type")
13152
        (cond [(match_operand:DF 3 "mult_operator" "")
13153
                 (const_string "fmul")
13154
               (match_operand:DF 3 "div_operator" "")
13155
                 (const_string "fdiv")
13156
              ]
13157
              (const_string "fop")))
13158
   (set_attr "mode" "SF")])
13159
 
13160
(define_insn "*fop_xf_comm_i387"
13161
  [(set (match_operand:XF 0 "register_operand" "=f")
13162
        (match_operator:XF 3 "binary_fp_operator"
13163
                        [(match_operand:XF 1 "register_operand" "%0")
13164
                         (match_operand:XF 2 "register_operand" "f")]))]
13165
  "TARGET_80387
13166
   && COMMUTATIVE_ARITH_P (operands[3])"
13167
  "* return output_387_binary_op (insn, operands);"
13168
  [(set (attr "type")
13169
        (if_then_else (match_operand:XF 3 "mult_operator" "")
13170
           (const_string "fmul")
13171
           (const_string "fop")))
13172
   (set_attr "mode" "XF")])
13173
 
13174
(define_insn "*fop_xf_1_i387"
13175
  [(set (match_operand:XF 0 "register_operand" "=f,f")
13176
        (match_operator:XF 3 "binary_fp_operator"
13177
                        [(match_operand:XF 1 "register_operand" "0,f")
13178
                         (match_operand:XF 2 "register_operand" "f,0")]))]
13179
  "TARGET_80387
13180
   && !COMMUTATIVE_ARITH_P (operands[3])"
13181
  "* return output_387_binary_op (insn, operands);"
13182
  [(set (attr "type")
13183
        (cond [(match_operand:XF 3 "mult_operator" "")
13184
                 (const_string "fmul")
13185
               (match_operand:XF 3 "div_operator" "")
13186
                 (const_string "fdiv")
13187
              ]
13188
              (const_string "fop")))
13189
   (set_attr "mode" "XF")])
13190
 
13191
(define_insn "*fop_xf_2_i387"
13192
  [(set (match_operand:XF 0 "register_operand" "=f,f")
13193
        (match_operator:XF 3 "binary_fp_operator"
13194
          [(float:XF
13195
             (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13196
           (match_operand:XF 2 "register_operand" "0,0")]))]
13197
  "TARGET_80387 && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))"
13198
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13199
  [(set (attr "type")
13200
        (cond [(match_operand:XF 3 "mult_operator" "")
13201
                 (const_string "fmul")
13202
               (match_operand:XF 3 "div_operator" "")
13203
                 (const_string "fdiv")
13204
              ]
13205
              (const_string "fop")))
13206
   (set_attr "fp_int_src" "true")
13207
   (set_attr "mode" "")])
13208
 
13209
(define_insn "*fop_xf_3_i387"
13210
  [(set (match_operand:XF 0 "register_operand" "=f,f")
13211
        (match_operator:XF 3 "binary_fp_operator"
13212
          [(match_operand:XF 1 "register_operand" "0,0")
13213
           (float:XF
13214
             (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13215
  "TARGET_80387 && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))"
13216
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13217
  [(set (attr "type")
13218
        (cond [(match_operand:XF 3 "mult_operator" "")
13219
                 (const_string "fmul")
13220
               (match_operand:XF 3 "div_operator" "")
13221
                 (const_string "fdiv")
13222
              ]
13223
              (const_string "fop")))
13224
   (set_attr "fp_int_src" "true")
13225
   (set_attr "mode" "")])
13226
 
13227
(define_insn "*fop_xf_4_i387"
13228
  [(set (match_operand:XF 0 "register_operand" "=f,f")
13229
        (match_operator:XF 3 "binary_fp_operator"
13230
           [(float_extend:XF
13231
              (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13232
            (match_operand:XF 2 "register_operand" "0,f")]))]
13233
  "TARGET_80387"
13234
  "* return output_387_binary_op (insn, operands);"
13235
  [(set (attr "type")
13236
        (cond [(match_operand:XF 3 "mult_operator" "")
13237
                 (const_string "fmul")
13238
               (match_operand:XF 3 "div_operator" "")
13239
                 (const_string "fdiv")
13240
              ]
13241
              (const_string "fop")))
13242
   (set_attr "mode" "")])
13243
 
13244
(define_insn "*fop_xf_5_i387"
13245
  [(set (match_operand:XF 0 "register_operand" "=f,f")
13246
        (match_operator:XF 3 "binary_fp_operator"
13247
          [(match_operand:XF 1 "register_operand" "0,f")
13248
           (float_extend:XF
13249
             (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13250
  "TARGET_80387"
13251
  "* return output_387_binary_op (insn, operands);"
13252
  [(set (attr "type")
13253
        (cond [(match_operand:XF 3 "mult_operator" "")
13254
                 (const_string "fmul")
13255
               (match_operand:XF 3 "div_operator" "")
13256
                 (const_string "fdiv")
13257
              ]
13258
              (const_string "fop")))
13259
   (set_attr "mode" "")])
13260
 
13261
(define_insn "*fop_xf_6_i387"
13262
  [(set (match_operand:XF 0 "register_operand" "=f,f")
13263
        (match_operator:XF 3 "binary_fp_operator"
13264
          [(float_extend:XF
13265
             (match_operand:MODEF 1 "register_operand" "0,f"))
13266
           (float_extend:XF
13267
             (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13268
  "TARGET_80387"
13269
  "* return output_387_binary_op (insn, operands);"
13270
  [(set (attr "type")
13271
        (cond [(match_operand:XF 3 "mult_operator" "")
13272
                 (const_string "fmul")
13273
               (match_operand:XF 3 "div_operator" "")
13274
                 (const_string "fdiv")
13275
              ]
13276
              (const_string "fop")))
13277
   (set_attr "mode" "")])
13278
 
13279
(define_split
13280
  [(set (match_operand 0 "register_operand" "")
13281
        (match_operator 3 "binary_fp_operator"
13282
           [(float (match_operand:SWI24 1 "register_operand" ""))
13283
            (match_operand 2 "register_operand" "")]))]
13284
  "reload_completed
13285
   && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13286
   && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13287
  [(const_int 0)]
13288
{
13289
  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13290
  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13291
  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13292
                          gen_rtx_fmt_ee (GET_CODE (operands[3]),
13293
                                          GET_MODE (operands[3]),
13294
                                          operands[4],
13295
                                          operands[2])));
13296
  ix86_free_from_memory (GET_MODE (operands[1]));
13297
  DONE;
13298
})
13299
 
13300
(define_split
13301
  [(set (match_operand 0 "register_operand" "")
13302
        (match_operator 3 "binary_fp_operator"
13303
           [(match_operand 1 "register_operand" "")
13304
            (float (match_operand:SWI24 2 "register_operand" ""))]))]
13305
  "reload_completed
13306
   && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13307
   && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13308
  [(const_int 0)]
13309
{
13310
  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13311
  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13312
  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13313
                          gen_rtx_fmt_ee (GET_CODE (operands[3]),
13314
                                          GET_MODE (operands[3]),
13315
                                          operands[1],
13316
                                          operands[4])));
13317
  ix86_free_from_memory (GET_MODE (operands[2]));
13318
  DONE;
13319
})
13320
 
13321
;; FPU special functions.
13322
 
13323
;; This pattern implements a no-op XFmode truncation for
13324
;; all fancy i386 XFmode math functions.
13325
 
13326
(define_insn "truncxf2_i387_noop_unspec"
13327
  [(set (match_operand:MODEF 0 "register_operand" "=f")
13328
        (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13329
        UNSPEC_TRUNC_NOOP))]
13330
  "TARGET_USE_FANCY_MATH_387"
13331
  "* return output_387_reg_move (insn, operands);"
13332
  [(set_attr "type" "fmov")
13333
   (set_attr "mode" "")])
13334
 
13335
(define_insn "sqrtxf2"
13336
  [(set (match_operand:XF 0 "register_operand" "=f")
13337
        (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13338
  "TARGET_USE_FANCY_MATH_387"
13339
  "fsqrt"
13340
  [(set_attr "type" "fpspc")
13341
   (set_attr "mode" "XF")
13342
   (set_attr "athlon_decode" "direct")
13343
   (set_attr "amdfam10_decode" "direct")
13344
   (set_attr "bdver1_decode" "direct")])
13345
 
13346
(define_insn "sqrt_extendxf2_i387"
13347
  [(set (match_operand:XF 0 "register_operand" "=f")
13348
        (sqrt:XF
13349
          (float_extend:XF
13350
            (match_operand:MODEF 1 "register_operand" "0"))))]
13351
  "TARGET_USE_FANCY_MATH_387"
13352
  "fsqrt"
13353
  [(set_attr "type" "fpspc")
13354
   (set_attr "mode" "XF")
13355
   (set_attr "athlon_decode" "direct")
13356
   (set_attr "amdfam10_decode" "direct")
13357
   (set_attr "bdver1_decode" "direct")])
13358
 
13359
(define_insn "*rsqrtsf2_sse"
13360
  [(set (match_operand:SF 0 "register_operand" "=x")
13361
        (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13362
                   UNSPEC_RSQRT))]
13363
  "TARGET_SSE_MATH"
13364
  "%vrsqrtss\t{%1, %d0|%d0, %1}"
13365
  [(set_attr "type" "sse")
13366
   (set_attr "atom_sse_attr" "rcp")
13367
   (set_attr "prefix" "maybe_vex")
13368
   (set_attr "mode" "SF")])
13369
 
13370
(define_expand "rsqrtsf2"
13371
  [(set (match_operand:SF 0 "register_operand" "")
13372
        (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13373
                   UNSPEC_RSQRT))]
13374
  "TARGET_SSE_MATH"
13375
{
13376
  ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13377
  DONE;
13378
})
13379
 
13380
(define_insn "*sqrt2_sse"
13381
  [(set (match_operand:MODEF 0 "register_operand" "=x")
13382
        (sqrt:MODEF
13383
          (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13384
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
13385
  "%vsqrt\t{%1, %d0|%d0, %1}"
13386
  [(set_attr "type" "sse")
13387
   (set_attr "atom_sse_attr" "sqrt")
13388
   (set_attr "prefix" "maybe_vex")
13389
   (set_attr "mode" "")
13390
   (set_attr "athlon_decode" "*")
13391
   (set_attr "amdfam10_decode" "*")
13392
   (set_attr "bdver1_decode" "*")])
13393
 
13394
(define_expand "sqrt2"
13395
  [(set (match_operand:MODEF 0 "register_operand" "")
13396
        (sqrt:MODEF
13397
          (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13398
  "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (mode))
13399
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
13400
{
13401
  if (mode == SFmode
13402
      && TARGET_SSE_MATH
13403
      && TARGET_RECIP_SQRT
13404
      && !optimize_function_for_size_p (cfun)
13405
      && flag_finite_math_only && !flag_trapping_math
13406
      && flag_unsafe_math_optimizations)
13407
    {
13408
      ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13409
      DONE;
13410
    }
13411
 
13412
  if (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))
13413
    {
13414
      rtx op0 = gen_reg_rtx (XFmode);
13415
      rtx op1 = force_reg (mode, operands[1]);
13416
 
13417
      emit_insn (gen_sqrt_extendxf2_i387 (op0, op1));
13418
      emit_insn (gen_truncxf2_i387_noop_unspec (operands[0], op0));
13419
      DONE;
13420
   }
13421
})
13422
 
13423
(define_insn "fpremxf4_i387"
13424
  [(set (match_operand:XF 0 "register_operand" "=f")
13425
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13426
                    (match_operand:XF 3 "register_operand" "1")]
13427
                   UNSPEC_FPREM_F))
13428
   (set (match_operand:XF 1 "register_operand" "=u")
13429
        (unspec:XF [(match_dup 2) (match_dup 3)]
13430
                   UNSPEC_FPREM_U))
13431
   (set (reg:CCFP FPSR_REG)
13432
        (unspec:CCFP [(match_dup 2) (match_dup 3)]
13433
                     UNSPEC_C2_FLAG))]
13434
  "TARGET_USE_FANCY_MATH_387"
13435
  "fprem"
13436
  [(set_attr "type" "fpspc")
13437
   (set_attr "mode" "XF")])
13438
 
13439
(define_expand "fmodxf3"
13440
  [(use (match_operand:XF 0 "register_operand" ""))
13441
   (use (match_operand:XF 1 "general_operand" ""))
13442
   (use (match_operand:XF 2 "general_operand" ""))]
13443
  "TARGET_USE_FANCY_MATH_387"
13444
{
13445
  rtx label = gen_label_rtx ();
13446
 
13447
  rtx op1 = gen_reg_rtx (XFmode);
13448
  rtx op2 = gen_reg_rtx (XFmode);
13449
 
13450
  emit_move_insn (op2, operands[2]);
13451
  emit_move_insn (op1, operands[1]);
13452
 
13453
  emit_label (label);
13454
  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13455
  ix86_emit_fp_unordered_jump (label);
13456
  LABEL_NUSES (label) = 1;
13457
 
13458
  emit_move_insn (operands[0], op1);
13459
  DONE;
13460
})
13461
 
13462
(define_expand "fmod3"
13463
  [(use (match_operand:MODEF 0 "register_operand" ""))
13464
   (use (match_operand:MODEF 1 "general_operand" ""))
13465
   (use (match_operand:MODEF 2 "general_operand" ""))]
13466
  "TARGET_USE_FANCY_MATH_387"
13467
{
13468
  rtx (*gen_truncxf) (rtx, rtx);
13469
 
13470
  rtx label = gen_label_rtx ();
13471
 
13472
  rtx op1 = gen_reg_rtx (XFmode);
13473
  rtx op2 = gen_reg_rtx (XFmode);
13474
 
13475
  emit_insn (gen_extendxf2 (op2, operands[2]));
13476
  emit_insn (gen_extendxf2 (op1, operands[1]));
13477
 
13478
  emit_label (label);
13479
  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13480
  ix86_emit_fp_unordered_jump (label);
13481
  LABEL_NUSES (label) = 1;
13482
 
13483
  /* Truncate the result properly for strict SSE math.  */
13484
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
13485
      && !TARGET_MIX_SSE_I387)
13486
    gen_truncxf = gen_truncxf2;
13487
  else
13488
    gen_truncxf = gen_truncxf2_i387_noop_unspec;
13489
 
13490
  emit_insn (gen_truncxf (operands[0], op1));
13491
  DONE;
13492
})
13493
 
13494
(define_insn "fprem1xf4_i387"
13495
  [(set (match_operand:XF 0 "register_operand" "=f")
13496
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13497
                    (match_operand:XF 3 "register_operand" "1")]
13498
                   UNSPEC_FPREM1_F))
13499
   (set (match_operand:XF 1 "register_operand" "=u")
13500
        (unspec:XF [(match_dup 2) (match_dup 3)]
13501
                   UNSPEC_FPREM1_U))
13502
   (set (reg:CCFP FPSR_REG)
13503
        (unspec:CCFP [(match_dup 2) (match_dup 3)]
13504
                     UNSPEC_C2_FLAG))]
13505
  "TARGET_USE_FANCY_MATH_387"
13506
  "fprem1"
13507
  [(set_attr "type" "fpspc")
13508
   (set_attr "mode" "XF")])
13509
 
13510
(define_expand "remainderxf3"
13511
  [(use (match_operand:XF 0 "register_operand" ""))
13512
   (use (match_operand:XF 1 "general_operand" ""))
13513
   (use (match_operand:XF 2 "general_operand" ""))]
13514
  "TARGET_USE_FANCY_MATH_387"
13515
{
13516
  rtx label = gen_label_rtx ();
13517
 
13518
  rtx op1 = gen_reg_rtx (XFmode);
13519
  rtx op2 = gen_reg_rtx (XFmode);
13520
 
13521
  emit_move_insn (op2, operands[2]);
13522
  emit_move_insn (op1, operands[1]);
13523
 
13524
  emit_label (label);
13525
  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13526
  ix86_emit_fp_unordered_jump (label);
13527
  LABEL_NUSES (label) = 1;
13528
 
13529
  emit_move_insn (operands[0], op1);
13530
  DONE;
13531
})
13532
 
13533
(define_expand "remainder3"
13534
  [(use (match_operand:MODEF 0 "register_operand" ""))
13535
   (use (match_operand:MODEF 1 "general_operand" ""))
13536
   (use (match_operand:MODEF 2 "general_operand" ""))]
13537
  "TARGET_USE_FANCY_MATH_387"
13538
{
13539
  rtx (*gen_truncxf) (rtx, rtx);
13540
 
13541
  rtx label = gen_label_rtx ();
13542
 
13543
  rtx op1 = gen_reg_rtx (XFmode);
13544
  rtx op2 = gen_reg_rtx (XFmode);
13545
 
13546
  emit_insn (gen_extendxf2 (op2, operands[2]));
13547
  emit_insn (gen_extendxf2 (op1, operands[1]));
13548
 
13549
  emit_label (label);
13550
 
13551
  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13552
  ix86_emit_fp_unordered_jump (label);
13553
  LABEL_NUSES (label) = 1;
13554
 
13555
  /* Truncate the result properly for strict SSE math.  */
13556
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
13557
      && !TARGET_MIX_SSE_I387)
13558
    gen_truncxf = gen_truncxf2;
13559
  else
13560
    gen_truncxf = gen_truncxf2_i387_noop_unspec;
13561
 
13562
  emit_insn (gen_truncxf (operands[0], op1));
13563
  DONE;
13564
})
13565
 
13566
(define_insn "*sinxf2_i387"
13567
  [(set (match_operand:XF 0 "register_operand" "=f")
13568
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13569
  "TARGET_USE_FANCY_MATH_387
13570
   && flag_unsafe_math_optimizations"
13571
  "fsin"
13572
  [(set_attr "type" "fpspc")
13573
   (set_attr "mode" "XF")])
13574
 
13575
(define_insn "*sin_extendxf2_i387"
13576
  [(set (match_operand:XF 0 "register_operand" "=f")
13577
        (unspec:XF [(float_extend:XF
13578
                      (match_operand:MODEF 1 "register_operand" "0"))]
13579
                   UNSPEC_SIN))]
13580
  "TARGET_USE_FANCY_MATH_387
13581
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13582
       || TARGET_MIX_SSE_I387)
13583
   && flag_unsafe_math_optimizations"
13584
  "fsin"
13585
  [(set_attr "type" "fpspc")
13586
   (set_attr "mode" "XF")])
13587
 
13588
(define_insn "*cosxf2_i387"
13589
  [(set (match_operand:XF 0 "register_operand" "=f")
13590
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13591
  "TARGET_USE_FANCY_MATH_387
13592
   && flag_unsafe_math_optimizations"
13593
  "fcos"
13594
  [(set_attr "type" "fpspc")
13595
   (set_attr "mode" "XF")])
13596
 
13597
(define_insn "*cos_extendxf2_i387"
13598
  [(set (match_operand:XF 0 "register_operand" "=f")
13599
        (unspec:XF [(float_extend:XF
13600
                      (match_operand:MODEF 1 "register_operand" "0"))]
13601
                   UNSPEC_COS))]
13602
  "TARGET_USE_FANCY_MATH_387
13603
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13604
       || TARGET_MIX_SSE_I387)
13605
   && flag_unsafe_math_optimizations"
13606
  "fcos"
13607
  [(set_attr "type" "fpspc")
13608
   (set_attr "mode" "XF")])
13609
 
13610
;; When sincos pattern is defined, sin and cos builtin functions will be
13611
;; expanded to sincos pattern with one of its outputs left unused.
13612
;; CSE pass will figure out if two sincos patterns can be combined,
13613
;; otherwise sincos pattern will be split back to sin or cos pattern,
13614
;; depending on the unused output.
13615
 
13616
(define_insn "sincosxf3"
13617
  [(set (match_operand:XF 0 "register_operand" "=f")
13618
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13619
                   UNSPEC_SINCOS_COS))
13620
   (set (match_operand:XF 1 "register_operand" "=u")
13621
        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13622
  "TARGET_USE_FANCY_MATH_387
13623
   && flag_unsafe_math_optimizations"
13624
  "fsincos"
13625
  [(set_attr "type" "fpspc")
13626
   (set_attr "mode" "XF")])
13627
 
13628
(define_split
13629
  [(set (match_operand:XF 0 "register_operand" "")
13630
        (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13631
                   UNSPEC_SINCOS_COS))
13632
   (set (match_operand:XF 1 "register_operand" "")
13633
        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13634
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13635
   && can_create_pseudo_p ()"
13636
  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13637
 
13638
(define_split
13639
  [(set (match_operand:XF 0 "register_operand" "")
13640
        (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13641
                   UNSPEC_SINCOS_COS))
13642
   (set (match_operand:XF 1 "register_operand" "")
13643
        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13644
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13645
   && can_create_pseudo_p ()"
13646
  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13647
 
13648
(define_insn "sincos_extendxf3_i387"
13649
  [(set (match_operand:XF 0 "register_operand" "=f")
13650
        (unspec:XF [(float_extend:XF
13651
                      (match_operand:MODEF 2 "register_operand" "0"))]
13652
                   UNSPEC_SINCOS_COS))
13653
   (set (match_operand:XF 1 "register_operand" "=u")
13654
        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13655
  "TARGET_USE_FANCY_MATH_387
13656
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13657
       || TARGET_MIX_SSE_I387)
13658
   && flag_unsafe_math_optimizations"
13659
  "fsincos"
13660
  [(set_attr "type" "fpspc")
13661
   (set_attr "mode" "XF")])
13662
 
13663
(define_split
13664
  [(set (match_operand:XF 0 "register_operand" "")
13665
        (unspec:XF [(float_extend:XF
13666
                      (match_operand:MODEF 2 "register_operand" ""))]
13667
                   UNSPEC_SINCOS_COS))
13668
   (set (match_operand:XF 1 "register_operand" "")
13669
        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13670
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13671
   && can_create_pseudo_p ()"
13672
  [(set (match_dup 1)
13673
        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13674
 
13675
(define_split
13676
  [(set (match_operand:XF 0 "register_operand" "")
13677
        (unspec:XF [(float_extend:XF
13678
                      (match_operand:MODEF 2 "register_operand" ""))]
13679
                   UNSPEC_SINCOS_COS))
13680
   (set (match_operand:XF 1 "register_operand" "")
13681
        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13682
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13683
   && can_create_pseudo_p ()"
13684
  [(set (match_dup 0)
13685
        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13686
 
13687
(define_expand "sincos3"
13688
  [(use (match_operand:MODEF 0 "register_operand" ""))
13689
   (use (match_operand:MODEF 1 "register_operand" ""))
13690
   (use (match_operand:MODEF 2 "register_operand" ""))]
13691
  "TARGET_USE_FANCY_MATH_387
13692
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13693
       || TARGET_MIX_SSE_I387)
13694
   && flag_unsafe_math_optimizations"
13695
{
13696
  rtx op0 = gen_reg_rtx (XFmode);
13697
  rtx op1 = gen_reg_rtx (XFmode);
13698
 
13699
  emit_insn (gen_sincos_extendxf3_i387 (op0, op1, operands[2]));
13700
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
13701
  emit_insn (gen_truncxf2_i387_noop (operands[1], op1));
13702
  DONE;
13703
})
13704
 
13705
(define_insn "fptanxf4_i387"
13706
  [(set (match_operand:XF 0 "register_operand" "=f")
13707
        (match_operand:XF 3 "const_double_operand" "F"))
13708
   (set (match_operand:XF 1 "register_operand" "=u")
13709
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13710
                   UNSPEC_TAN))]
13711
  "TARGET_USE_FANCY_MATH_387
13712
   && flag_unsafe_math_optimizations
13713
   && standard_80387_constant_p (operands[3]) == 2"
13714
  "fptan"
13715
  [(set_attr "type" "fpspc")
13716
   (set_attr "mode" "XF")])
13717
 
13718
(define_insn "fptan_extendxf4_i387"
13719
  [(set (match_operand:MODEF 0 "register_operand" "=f")
13720
        (match_operand:MODEF 3 "const_double_operand" "F"))
13721
   (set (match_operand:XF 1 "register_operand" "=u")
13722
        (unspec:XF [(float_extend:XF
13723
                      (match_operand:MODEF 2 "register_operand" "0"))]
13724
                   UNSPEC_TAN))]
13725
  "TARGET_USE_FANCY_MATH_387
13726
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13727
       || TARGET_MIX_SSE_I387)
13728
   && flag_unsafe_math_optimizations
13729
   && standard_80387_constant_p (operands[3]) == 2"
13730
  "fptan"
13731
  [(set_attr "type" "fpspc")
13732
   (set_attr "mode" "XF")])
13733
 
13734
(define_expand "tanxf2"
13735
  [(use (match_operand:XF 0 "register_operand" ""))
13736
   (use (match_operand:XF 1 "register_operand" ""))]
13737
  "TARGET_USE_FANCY_MATH_387
13738
   && flag_unsafe_math_optimizations"
13739
{
13740
  rtx one = gen_reg_rtx (XFmode);
13741
  rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13742
 
13743
  emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13744
  DONE;
13745
})
13746
 
13747
(define_expand "tan2"
13748
  [(use (match_operand:MODEF 0 "register_operand" ""))
13749
   (use (match_operand:MODEF 1 "register_operand" ""))]
13750
  "TARGET_USE_FANCY_MATH_387
13751
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13752
       || TARGET_MIX_SSE_I387)
13753
   && flag_unsafe_math_optimizations"
13754
{
13755
  rtx op0 = gen_reg_rtx (XFmode);
13756
 
13757
  rtx one = gen_reg_rtx (mode);
13758
  rtx op2 = CONST1_RTX (mode); /* fld1 */
13759
 
13760
  emit_insn (gen_fptan_extendxf4_i387 (one, op0,
13761
                                             operands[1], op2));
13762
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
13763
  DONE;
13764
})
13765
 
13766
(define_insn "*fpatanxf3_i387"
13767
  [(set (match_operand:XF 0 "register_operand" "=f")
13768
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13769
                    (match_operand:XF 2 "register_operand" "u")]
13770
                   UNSPEC_FPATAN))
13771
   (clobber (match_scratch:XF 3 "=2"))]
13772
  "TARGET_USE_FANCY_MATH_387
13773
   && flag_unsafe_math_optimizations"
13774
  "fpatan"
13775
  [(set_attr "type" "fpspc")
13776
   (set_attr "mode" "XF")])
13777
 
13778
(define_insn "fpatan_extendxf3_i387"
13779
  [(set (match_operand:XF 0 "register_operand" "=f")
13780
        (unspec:XF [(float_extend:XF
13781
                      (match_operand:MODEF 1 "register_operand" "0"))
13782
                    (float_extend:XF
13783
                      (match_operand:MODEF 2 "register_operand" "u"))]
13784
                   UNSPEC_FPATAN))
13785
   (clobber (match_scratch:XF 3 "=2"))]
13786
  "TARGET_USE_FANCY_MATH_387
13787
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13788
       || TARGET_MIX_SSE_I387)
13789
   && flag_unsafe_math_optimizations"
13790
  "fpatan"
13791
  [(set_attr "type" "fpspc")
13792
   (set_attr "mode" "XF")])
13793
 
13794
(define_expand "atan2xf3"
13795
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
13796
                   (unspec:XF [(match_operand:XF 2 "register_operand" "")
13797
                               (match_operand:XF 1 "register_operand" "")]
13798
                              UNSPEC_FPATAN))
13799
              (clobber (match_scratch:XF 3 ""))])]
13800
  "TARGET_USE_FANCY_MATH_387
13801
   && flag_unsafe_math_optimizations")
13802
 
13803
(define_expand "atan23"
13804
  [(use (match_operand:MODEF 0 "register_operand" ""))
13805
   (use (match_operand:MODEF 1 "register_operand" ""))
13806
   (use (match_operand:MODEF 2 "register_operand" ""))]
13807
  "TARGET_USE_FANCY_MATH_387
13808
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13809
       || TARGET_MIX_SSE_I387)
13810
   && flag_unsafe_math_optimizations"
13811
{
13812
  rtx op0 = gen_reg_rtx (XFmode);
13813
 
13814
  emit_insn (gen_fpatan_extendxf3_i387 (op0, operands[2], operands[1]));
13815
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
13816
  DONE;
13817
})
13818
 
13819
(define_expand "atanxf2"
13820
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
13821
                   (unspec:XF [(match_dup 2)
13822
                               (match_operand:XF 1 "register_operand" "")]
13823
                              UNSPEC_FPATAN))
13824
              (clobber (match_scratch:XF 3 ""))])]
13825
  "TARGET_USE_FANCY_MATH_387
13826
   && flag_unsafe_math_optimizations"
13827
{
13828
  operands[2] = gen_reg_rtx (XFmode);
13829
  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13830
})
13831
 
13832
(define_expand "atan2"
13833
  [(use (match_operand:MODEF 0 "register_operand" ""))
13834
   (use (match_operand:MODEF 1 "register_operand" ""))]
13835
  "TARGET_USE_FANCY_MATH_387
13836
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13837
       || TARGET_MIX_SSE_I387)
13838
   && flag_unsafe_math_optimizations"
13839
{
13840
  rtx op0 = gen_reg_rtx (XFmode);
13841
 
13842
  rtx op2 = gen_reg_rtx (mode);
13843
  emit_move_insn (op2, CONST1_RTX (mode));  /* fld1 */
13844
 
13845
  emit_insn (gen_fpatan_extendxf3_i387 (op0, op2, operands[1]));
13846
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
13847
  DONE;
13848
})
13849
 
13850
(define_expand "asinxf2"
13851
  [(set (match_dup 2)
13852
        (mult:XF (match_operand:XF 1 "register_operand" "")
13853
                 (match_dup 1)))
13854
   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13855
   (set (match_dup 5) (sqrt:XF (match_dup 4)))
13856
   (parallel [(set (match_operand:XF 0 "register_operand" "")
13857
                   (unspec:XF [(match_dup 5) (match_dup 1)]
13858
                              UNSPEC_FPATAN))
13859
              (clobber (match_scratch:XF 6 ""))])]
13860
  "TARGET_USE_FANCY_MATH_387
13861
   && flag_unsafe_math_optimizations"
13862
{
13863
  int i;
13864
 
13865
  if (optimize_insn_for_size_p ())
13866
    FAIL;
13867
 
13868
  for (i = 2; i < 6; i++)
13869
    operands[i] = gen_reg_rtx (XFmode);
13870
 
13871
  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13872
})
13873
 
13874
(define_expand "asin2"
13875
  [(use (match_operand:MODEF 0 "register_operand" ""))
13876
   (use (match_operand:MODEF 1 "general_operand" ""))]
13877
 "TARGET_USE_FANCY_MATH_387
13878
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13879
       || TARGET_MIX_SSE_I387)
13880
   && flag_unsafe_math_optimizations"
13881
{
13882
  rtx op0 = gen_reg_rtx (XFmode);
13883
  rtx op1 = gen_reg_rtx (XFmode);
13884
 
13885
  if (optimize_insn_for_size_p ())
13886
    FAIL;
13887
 
13888
  emit_insn (gen_extendxf2 (op1, operands[1]));
13889
  emit_insn (gen_asinxf2 (op0, op1));
13890
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
13891
  DONE;
13892
})
13893
 
13894
(define_expand "acosxf2"
13895
  [(set (match_dup 2)
13896
        (mult:XF (match_operand:XF 1 "register_operand" "")
13897
                 (match_dup 1)))
13898
   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13899
   (set (match_dup 5) (sqrt:XF (match_dup 4)))
13900
   (parallel [(set (match_operand:XF 0 "register_operand" "")
13901
                   (unspec:XF [(match_dup 1) (match_dup 5)]
13902
                              UNSPEC_FPATAN))
13903
              (clobber (match_scratch:XF 6 ""))])]
13904
  "TARGET_USE_FANCY_MATH_387
13905
   && flag_unsafe_math_optimizations"
13906
{
13907
  int i;
13908
 
13909
  if (optimize_insn_for_size_p ())
13910
    FAIL;
13911
 
13912
  for (i = 2; i < 6; i++)
13913
    operands[i] = gen_reg_rtx (XFmode);
13914
 
13915
  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13916
})
13917
 
13918
(define_expand "acos2"
13919
  [(use (match_operand:MODEF 0 "register_operand" ""))
13920
   (use (match_operand:MODEF 1 "general_operand" ""))]
13921
 "TARGET_USE_FANCY_MATH_387
13922
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13923
       || TARGET_MIX_SSE_I387)
13924
   && flag_unsafe_math_optimizations"
13925
{
13926
  rtx op0 = gen_reg_rtx (XFmode);
13927
  rtx op1 = gen_reg_rtx (XFmode);
13928
 
13929
  if (optimize_insn_for_size_p ())
13930
    FAIL;
13931
 
13932
  emit_insn (gen_extendxf2 (op1, operands[1]));
13933
  emit_insn (gen_acosxf2 (op0, op1));
13934
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
13935
  DONE;
13936
})
13937
 
13938
(define_insn "fyl2xxf3_i387"
13939
  [(set (match_operand:XF 0 "register_operand" "=f")
13940
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13941
                    (match_operand:XF 2 "register_operand" "u")]
13942
                   UNSPEC_FYL2X))
13943
   (clobber (match_scratch:XF 3 "=2"))]
13944
  "TARGET_USE_FANCY_MATH_387
13945
   && flag_unsafe_math_optimizations"
13946
  "fyl2x"
13947
  [(set_attr "type" "fpspc")
13948
   (set_attr "mode" "XF")])
13949
 
13950
(define_insn "fyl2x_extendxf3_i387"
13951
  [(set (match_operand:XF 0 "register_operand" "=f")
13952
        (unspec:XF [(float_extend:XF
13953
                      (match_operand:MODEF 1 "register_operand" "0"))
13954
                    (match_operand:XF 2 "register_operand" "u")]
13955
                   UNSPEC_FYL2X))
13956
   (clobber (match_scratch:XF 3 "=2"))]
13957
  "TARGET_USE_FANCY_MATH_387
13958
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13959
       || TARGET_MIX_SSE_I387)
13960
   && flag_unsafe_math_optimizations"
13961
  "fyl2x"
13962
  [(set_attr "type" "fpspc")
13963
   (set_attr "mode" "XF")])
13964
 
13965
(define_expand "logxf2"
13966
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
13967
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
13968
                               (match_dup 2)] UNSPEC_FYL2X))
13969
              (clobber (match_scratch:XF 3 ""))])]
13970
  "TARGET_USE_FANCY_MATH_387
13971
   && flag_unsafe_math_optimizations"
13972
{
13973
  operands[2] = gen_reg_rtx (XFmode);
13974
  emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13975
})
13976
 
13977
(define_expand "log2"
13978
  [(use (match_operand:MODEF 0 "register_operand" ""))
13979
   (use (match_operand:MODEF 1 "register_operand" ""))]
13980
  "TARGET_USE_FANCY_MATH_387
13981
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
13982
       || TARGET_MIX_SSE_I387)
13983
   && flag_unsafe_math_optimizations"
13984
{
13985
  rtx op0 = gen_reg_rtx (XFmode);
13986
 
13987
  rtx op2 = gen_reg_rtx (XFmode);
13988
  emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13989
 
13990
  emit_insn (gen_fyl2x_extendxf3_i387 (op0, operands[1], op2));
13991
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
13992
  DONE;
13993
})
13994
 
13995
(define_expand "log10xf2"
13996
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
13997
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
13998
                               (match_dup 2)] UNSPEC_FYL2X))
13999
              (clobber (match_scratch:XF 3 ""))])]
14000
  "TARGET_USE_FANCY_MATH_387
14001
   && flag_unsafe_math_optimizations"
14002
{
14003
  operands[2] = gen_reg_rtx (XFmode);
14004
  emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14005
})
14006
 
14007
(define_expand "log102"
14008
  [(use (match_operand:MODEF 0 "register_operand" ""))
14009
   (use (match_operand:MODEF 1 "register_operand" ""))]
14010
  "TARGET_USE_FANCY_MATH_387
14011
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14012
       || TARGET_MIX_SSE_I387)
14013
   && flag_unsafe_math_optimizations"
14014
{
14015
  rtx op0 = gen_reg_rtx (XFmode);
14016
 
14017
  rtx op2 = gen_reg_rtx (XFmode);
14018
  emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14019
 
14020
  emit_insn (gen_fyl2x_extendxf3_i387 (op0, operands[1], op2));
14021
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
14022
  DONE;
14023
})
14024
 
14025
(define_expand "log2xf2"
14026
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
14027
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
14028
                               (match_dup 2)] UNSPEC_FYL2X))
14029
              (clobber (match_scratch:XF 3 ""))])]
14030
  "TARGET_USE_FANCY_MATH_387
14031
   && flag_unsafe_math_optimizations"
14032
{
14033
  operands[2] = gen_reg_rtx (XFmode);
14034
  emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14035
})
14036
 
14037
(define_expand "log22"
14038
  [(use (match_operand:MODEF 0 "register_operand" ""))
14039
   (use (match_operand:MODEF 1 "register_operand" ""))]
14040
  "TARGET_USE_FANCY_MATH_387
14041
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14042
       || TARGET_MIX_SSE_I387)
14043
   && flag_unsafe_math_optimizations"
14044
{
14045
  rtx op0 = gen_reg_rtx (XFmode);
14046
 
14047
  rtx op2 = gen_reg_rtx (XFmode);
14048
  emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14049
 
14050
  emit_insn (gen_fyl2x_extendxf3_i387 (op0, operands[1], op2));
14051
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
14052
  DONE;
14053
})
14054
 
14055
(define_insn "fyl2xp1xf3_i387"
14056
  [(set (match_operand:XF 0 "register_operand" "=f")
14057
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14058
                    (match_operand:XF 2 "register_operand" "u")]
14059
                   UNSPEC_FYL2XP1))
14060
   (clobber (match_scratch:XF 3 "=2"))]
14061
  "TARGET_USE_FANCY_MATH_387
14062
   && flag_unsafe_math_optimizations"
14063
  "fyl2xp1"
14064
  [(set_attr "type" "fpspc")
14065
   (set_attr "mode" "XF")])
14066
 
14067
(define_insn "fyl2xp1_extendxf3_i387"
14068
  [(set (match_operand:XF 0 "register_operand" "=f")
14069
        (unspec:XF [(float_extend:XF
14070
                      (match_operand:MODEF 1 "register_operand" "0"))
14071
                    (match_operand:XF 2 "register_operand" "u")]
14072
                   UNSPEC_FYL2XP1))
14073
   (clobber (match_scratch:XF 3 "=2"))]
14074
  "TARGET_USE_FANCY_MATH_387
14075
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14076
       || TARGET_MIX_SSE_I387)
14077
   && flag_unsafe_math_optimizations"
14078
  "fyl2xp1"
14079
  [(set_attr "type" "fpspc")
14080
   (set_attr "mode" "XF")])
14081
 
14082
(define_expand "log1pxf2"
14083
  [(use (match_operand:XF 0 "register_operand" ""))
14084
   (use (match_operand:XF 1 "register_operand" ""))]
14085
  "TARGET_USE_FANCY_MATH_387
14086
   && flag_unsafe_math_optimizations"
14087
{
14088
  if (optimize_insn_for_size_p ())
14089
    FAIL;
14090
 
14091
  ix86_emit_i387_log1p (operands[0], operands[1]);
14092
  DONE;
14093
})
14094
 
14095
(define_expand "log1p2"
14096
  [(use (match_operand:MODEF 0 "register_operand" ""))
14097
   (use (match_operand:MODEF 1 "register_operand" ""))]
14098
  "TARGET_USE_FANCY_MATH_387
14099
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14100
       || TARGET_MIX_SSE_I387)
14101
   && flag_unsafe_math_optimizations"
14102
{
14103
  rtx op0;
14104
 
14105
  if (optimize_insn_for_size_p ())
14106
    FAIL;
14107
 
14108
  op0 = gen_reg_rtx (XFmode);
14109
 
14110
  operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14111
 
14112
  ix86_emit_i387_log1p (op0, operands[1]);
14113
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
14114
  DONE;
14115
})
14116
 
14117
(define_insn "fxtractxf3_i387"
14118
  [(set (match_operand:XF 0 "register_operand" "=f")
14119
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14120
                   UNSPEC_XTRACT_FRACT))
14121
   (set (match_operand:XF 1 "register_operand" "=u")
14122
        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14123
  "TARGET_USE_FANCY_MATH_387
14124
   && flag_unsafe_math_optimizations"
14125
  "fxtract"
14126
  [(set_attr "type" "fpspc")
14127
   (set_attr "mode" "XF")])
14128
 
14129
(define_insn "fxtract_extendxf3_i387"
14130
  [(set (match_operand:XF 0 "register_operand" "=f")
14131
        (unspec:XF [(float_extend:XF
14132
                      (match_operand:MODEF 2 "register_operand" "0"))]
14133
                   UNSPEC_XTRACT_FRACT))
14134
   (set (match_operand:XF 1 "register_operand" "=u")
14135
        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14136
  "TARGET_USE_FANCY_MATH_387
14137
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14138
       || TARGET_MIX_SSE_I387)
14139
   && flag_unsafe_math_optimizations"
14140
  "fxtract"
14141
  [(set_attr "type" "fpspc")
14142
   (set_attr "mode" "XF")])
14143
 
14144
(define_expand "logbxf2"
14145
  [(parallel [(set (match_dup 2)
14146
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14147
                              UNSPEC_XTRACT_FRACT))
14148
              (set (match_operand:XF 0 "register_operand" "")
14149
                   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14150
  "TARGET_USE_FANCY_MATH_387
14151
   && flag_unsafe_math_optimizations"
14152
  "operands[2] = gen_reg_rtx (XFmode);")
14153
 
14154
(define_expand "logb2"
14155
  [(use (match_operand:MODEF 0 "register_operand" ""))
14156
   (use (match_operand:MODEF 1 "register_operand" ""))]
14157
  "TARGET_USE_FANCY_MATH_387
14158
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14159
       || TARGET_MIX_SSE_I387)
14160
   && flag_unsafe_math_optimizations"
14161
{
14162
  rtx op0 = gen_reg_rtx (XFmode);
14163
  rtx op1 = gen_reg_rtx (XFmode);
14164
 
14165
  emit_insn (gen_fxtract_extendxf3_i387 (op0, op1, operands[1]));
14166
  emit_insn (gen_truncxf2_i387_noop (operands[0], op1));
14167
  DONE;
14168
})
14169
 
14170
(define_expand "ilogbxf2"
14171
  [(use (match_operand:SI 0 "register_operand" ""))
14172
   (use (match_operand:XF 1 "register_operand" ""))]
14173
  "TARGET_USE_FANCY_MATH_387
14174
   && flag_unsafe_math_optimizations"
14175
{
14176
  rtx op0, op1;
14177
 
14178
  if (optimize_insn_for_size_p ())
14179
    FAIL;
14180
 
14181
  op0 = gen_reg_rtx (XFmode);
14182
  op1 = gen_reg_rtx (XFmode);
14183
 
14184
  emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14185
  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14186
  DONE;
14187
})
14188
 
14189
(define_expand "ilogb2"
14190
  [(use (match_operand:SI 0 "register_operand" ""))
14191
   (use (match_operand:MODEF 1 "register_operand" ""))]
14192
  "TARGET_USE_FANCY_MATH_387
14193
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14194
       || TARGET_MIX_SSE_I387)
14195
   && flag_unsafe_math_optimizations"
14196
{
14197
  rtx op0, op1;
14198
 
14199
  if (optimize_insn_for_size_p ())
14200
    FAIL;
14201
 
14202
  op0 = gen_reg_rtx (XFmode);
14203
  op1 = gen_reg_rtx (XFmode);
14204
 
14205
  emit_insn (gen_fxtract_extendxf3_i387 (op0, op1, operands[1]));
14206
  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14207
  DONE;
14208
})
14209
 
14210
(define_insn "*f2xm1xf2_i387"
14211
  [(set (match_operand:XF 0 "register_operand" "=f")
14212
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14213
                   UNSPEC_F2XM1))]
14214
  "TARGET_USE_FANCY_MATH_387
14215
   && flag_unsafe_math_optimizations"
14216
  "f2xm1"
14217
  [(set_attr "type" "fpspc")
14218
   (set_attr "mode" "XF")])
14219
 
14220
(define_insn "*fscalexf4_i387"
14221
  [(set (match_operand:XF 0 "register_operand" "=f")
14222
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14223
                    (match_operand:XF 3 "register_operand" "1")]
14224
                   UNSPEC_FSCALE_FRACT))
14225
   (set (match_operand:XF 1 "register_operand" "=u")
14226
        (unspec:XF [(match_dup 2) (match_dup 3)]
14227
                   UNSPEC_FSCALE_EXP))]
14228
  "TARGET_USE_FANCY_MATH_387
14229
   && flag_unsafe_math_optimizations"
14230
  "fscale"
14231
  [(set_attr "type" "fpspc")
14232
   (set_attr "mode" "XF")])
14233
 
14234
(define_expand "expNcorexf3"
14235
  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14236
                               (match_operand:XF 2 "register_operand" "")))
14237
   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14238
   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14239
   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14240
   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14241
   (parallel [(set (match_operand:XF 0 "register_operand" "")
14242
                   (unspec:XF [(match_dup 8) (match_dup 4)]
14243
                              UNSPEC_FSCALE_FRACT))
14244
              (set (match_dup 9)
14245
                   (unspec:XF [(match_dup 8) (match_dup 4)]
14246
                              UNSPEC_FSCALE_EXP))])]
14247
  "TARGET_USE_FANCY_MATH_387
14248
   && flag_unsafe_math_optimizations"
14249
{
14250
  int i;
14251
 
14252
  if (optimize_insn_for_size_p ())
14253
    FAIL;
14254
 
14255
  for (i = 3; i < 10; i++)
14256
    operands[i] = gen_reg_rtx (XFmode);
14257
 
14258
  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14259
})
14260
 
14261
(define_expand "expxf2"
14262
  [(use (match_operand:XF 0 "register_operand" ""))
14263
   (use (match_operand:XF 1 "register_operand" ""))]
14264
  "TARGET_USE_FANCY_MATH_387
14265
   && flag_unsafe_math_optimizations"
14266
{
14267
  rtx op2;
14268
 
14269
  if (optimize_insn_for_size_p ())
14270
    FAIL;
14271
 
14272
  op2 = gen_reg_rtx (XFmode);
14273
  emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14274
 
14275
  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14276
  DONE;
14277
})
14278
 
14279
(define_expand "exp2"
14280
  [(use (match_operand:MODEF 0 "register_operand" ""))
14281
   (use (match_operand:MODEF 1 "general_operand" ""))]
14282
 "TARGET_USE_FANCY_MATH_387
14283
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14284
       || TARGET_MIX_SSE_I387)
14285
   && flag_unsafe_math_optimizations"
14286
{
14287
  rtx op0, op1;
14288
 
14289
  if (optimize_insn_for_size_p ())
14290
    FAIL;
14291
 
14292
  op0 = gen_reg_rtx (XFmode);
14293
  op1 = gen_reg_rtx (XFmode);
14294
 
14295
  emit_insn (gen_extendxf2 (op1, operands[1]));
14296
  emit_insn (gen_expxf2 (op0, op1));
14297
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
14298
  DONE;
14299
})
14300
 
14301
(define_expand "exp10xf2"
14302
  [(use (match_operand:XF 0 "register_operand" ""))
14303
   (use (match_operand:XF 1 "register_operand" ""))]
14304
  "TARGET_USE_FANCY_MATH_387
14305
   && flag_unsafe_math_optimizations"
14306
{
14307
  rtx op2;
14308
 
14309
  if (optimize_insn_for_size_p ())
14310
    FAIL;
14311
 
14312
  op2 = gen_reg_rtx (XFmode);
14313
  emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14314
 
14315
  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14316
  DONE;
14317
})
14318
 
14319
(define_expand "exp102"
14320
  [(use (match_operand:MODEF 0 "register_operand" ""))
14321
   (use (match_operand:MODEF 1 "general_operand" ""))]
14322
 "TARGET_USE_FANCY_MATH_387
14323
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14324
       || TARGET_MIX_SSE_I387)
14325
   && flag_unsafe_math_optimizations"
14326
{
14327
  rtx op0, op1;
14328
 
14329
  if (optimize_insn_for_size_p ())
14330
    FAIL;
14331
 
14332
  op0 = gen_reg_rtx (XFmode);
14333
  op1 = gen_reg_rtx (XFmode);
14334
 
14335
  emit_insn (gen_extendxf2 (op1, operands[1]));
14336
  emit_insn (gen_exp10xf2 (op0, op1));
14337
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
14338
  DONE;
14339
})
14340
 
14341
(define_expand "exp2xf2"
14342
  [(use (match_operand:XF 0 "register_operand" ""))
14343
   (use (match_operand:XF 1 "register_operand" ""))]
14344
  "TARGET_USE_FANCY_MATH_387
14345
   && flag_unsafe_math_optimizations"
14346
{
14347
  rtx op2;
14348
 
14349
  if (optimize_insn_for_size_p ())
14350
    FAIL;
14351
 
14352
  op2 = gen_reg_rtx (XFmode);
14353
  emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14354
 
14355
  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14356
  DONE;
14357
})
14358
 
14359
(define_expand "exp22"
14360
  [(use (match_operand:MODEF 0 "register_operand" ""))
14361
   (use (match_operand:MODEF 1 "general_operand" ""))]
14362
 "TARGET_USE_FANCY_MATH_387
14363
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14364
       || TARGET_MIX_SSE_I387)
14365
   && flag_unsafe_math_optimizations"
14366
{
14367
  rtx op0, op1;
14368
 
14369
  if (optimize_insn_for_size_p ())
14370
    FAIL;
14371
 
14372
  op0 = gen_reg_rtx (XFmode);
14373
  op1 = gen_reg_rtx (XFmode);
14374
 
14375
  emit_insn (gen_extendxf2 (op1, operands[1]));
14376
  emit_insn (gen_exp2xf2 (op0, op1));
14377
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
14378
  DONE;
14379
})
14380
 
14381
(define_expand "expm1xf2"
14382
  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14383
                               (match_dup 2)))
14384
   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14385
   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14386
   (set (match_dup 9) (float_extend:XF (match_dup 13)))
14387
   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14388
   (parallel [(set (match_dup 7)
14389
                   (unspec:XF [(match_dup 6) (match_dup 4)]
14390
                              UNSPEC_FSCALE_FRACT))
14391
              (set (match_dup 8)
14392
                   (unspec:XF [(match_dup 6) (match_dup 4)]
14393
                              UNSPEC_FSCALE_EXP))])
14394
   (parallel [(set (match_dup 10)
14395
                   (unspec:XF [(match_dup 9) (match_dup 8)]
14396
                              UNSPEC_FSCALE_FRACT))
14397
              (set (match_dup 11)
14398
                   (unspec:XF [(match_dup 9) (match_dup 8)]
14399
                              UNSPEC_FSCALE_EXP))])
14400
   (set (match_dup 12) (minus:XF (match_dup 10)
14401
                                 (float_extend:XF (match_dup 13))))
14402
   (set (match_operand:XF 0 "register_operand" "")
14403
        (plus:XF (match_dup 12) (match_dup 7)))]
14404
  "TARGET_USE_FANCY_MATH_387
14405
   && flag_unsafe_math_optimizations"
14406
{
14407
  int i;
14408
 
14409
  if (optimize_insn_for_size_p ())
14410
    FAIL;
14411
 
14412
  for (i = 2; i < 13; i++)
14413
    operands[i] = gen_reg_rtx (XFmode);
14414
 
14415
  operands[13]
14416
    = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14417
 
14418
  emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14419
})
14420
 
14421
(define_expand "expm12"
14422
  [(use (match_operand:MODEF 0 "register_operand" ""))
14423
   (use (match_operand:MODEF 1 "general_operand" ""))]
14424
 "TARGET_USE_FANCY_MATH_387
14425
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14426
       || TARGET_MIX_SSE_I387)
14427
   && flag_unsafe_math_optimizations"
14428
{
14429
  rtx op0, op1;
14430
 
14431
  if (optimize_insn_for_size_p ())
14432
    FAIL;
14433
 
14434
  op0 = gen_reg_rtx (XFmode);
14435
  op1 = gen_reg_rtx (XFmode);
14436
 
14437
  emit_insn (gen_extendxf2 (op1, operands[1]));
14438
  emit_insn (gen_expm1xf2 (op0, op1));
14439
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
14440
  DONE;
14441
})
14442
 
14443
(define_expand "ldexpxf3"
14444
  [(set (match_dup 3)
14445
        (float:XF (match_operand:SI 2 "register_operand" "")))
14446
   (parallel [(set (match_operand:XF 0 " register_operand" "")
14447
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
14448
                               (match_dup 3)]
14449
                              UNSPEC_FSCALE_FRACT))
14450
              (set (match_dup 4)
14451
                   (unspec:XF [(match_dup 1) (match_dup 3)]
14452
                              UNSPEC_FSCALE_EXP))])]
14453
  "TARGET_USE_FANCY_MATH_387
14454
   && flag_unsafe_math_optimizations"
14455
{
14456
  if (optimize_insn_for_size_p ())
14457
    FAIL;
14458
 
14459
  operands[3] = gen_reg_rtx (XFmode);
14460
  operands[4] = gen_reg_rtx (XFmode);
14461
})
14462
 
14463
(define_expand "ldexp3"
14464
  [(use (match_operand:MODEF 0 "register_operand" ""))
14465
   (use (match_operand:MODEF 1 "general_operand" ""))
14466
   (use (match_operand:SI 2 "register_operand" ""))]
14467
 "TARGET_USE_FANCY_MATH_387
14468
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14469
       || TARGET_MIX_SSE_I387)
14470
   && flag_unsafe_math_optimizations"
14471
{
14472
  rtx op0, op1;
14473
 
14474
  if (optimize_insn_for_size_p ())
14475
    FAIL;
14476
 
14477
  op0 = gen_reg_rtx (XFmode);
14478
  op1 = gen_reg_rtx (XFmode);
14479
 
14480
  emit_insn (gen_extendxf2 (op1, operands[1]));
14481
  emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14482
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
14483
  DONE;
14484
})
14485
 
14486
(define_expand "scalbxf3"
14487
  [(parallel [(set (match_operand:XF 0 " register_operand" "")
14488
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
14489
                               (match_operand:XF 2 "register_operand" "")]
14490
                              UNSPEC_FSCALE_FRACT))
14491
              (set (match_dup 3)
14492
                   (unspec:XF [(match_dup 1) (match_dup 2)]
14493
                              UNSPEC_FSCALE_EXP))])]
14494
  "TARGET_USE_FANCY_MATH_387
14495
   && flag_unsafe_math_optimizations"
14496
{
14497
  if (optimize_insn_for_size_p ())
14498
    FAIL;
14499
 
14500
  operands[3] = gen_reg_rtx (XFmode);
14501
})
14502
 
14503
(define_expand "scalb3"
14504
  [(use (match_operand:MODEF 0 "register_operand" ""))
14505
   (use (match_operand:MODEF 1 "general_operand" ""))
14506
   (use (match_operand:MODEF 2 "general_operand" ""))]
14507
 "TARGET_USE_FANCY_MATH_387
14508
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14509
       || TARGET_MIX_SSE_I387)
14510
   && flag_unsafe_math_optimizations"
14511
{
14512
  rtx op0, op1, op2;
14513
 
14514
  if (optimize_insn_for_size_p ())
14515
    FAIL;
14516
 
14517
  op0 = gen_reg_rtx (XFmode);
14518
  op1 = gen_reg_rtx (XFmode);
14519
  op2 = gen_reg_rtx (XFmode);
14520
 
14521
  emit_insn (gen_extendxf2 (op1, operands[1]));
14522
  emit_insn (gen_extendxf2 (op2, operands[2]));
14523
  emit_insn (gen_scalbxf3 (op0, op1, op2));
14524
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
14525
  DONE;
14526
})
14527
 
14528
(define_expand "significandxf2"
14529
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
14530
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14531
                              UNSPEC_XTRACT_FRACT))
14532
              (set (match_dup 2)
14533
                   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14534
  "TARGET_USE_FANCY_MATH_387
14535
   && flag_unsafe_math_optimizations"
14536
  "operands[2] = gen_reg_rtx (XFmode);")
14537
 
14538
(define_expand "significand2"
14539
  [(use (match_operand:MODEF 0 "register_operand" ""))
14540
   (use (match_operand:MODEF 1 "register_operand" ""))]
14541
  "TARGET_USE_FANCY_MATH_387
14542
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14543
       || TARGET_MIX_SSE_I387)
14544
   && flag_unsafe_math_optimizations"
14545
{
14546
  rtx op0 = gen_reg_rtx (XFmode);
14547
  rtx op1 = gen_reg_rtx (XFmode);
14548
 
14549
  emit_insn (gen_fxtract_extendxf3_i387 (op0, op1, operands[1]));
14550
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
14551
  DONE;
14552
})
14553
 
14554
 
14555
(define_insn "sse4_1_round2"
14556
  [(set (match_operand:MODEF 0 "register_operand" "=x")
14557
        (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14558
                       (match_operand:SI 2 "const_0_to_15_operand" "n")]
14559
                      UNSPEC_ROUND))]
14560
  "TARGET_ROUND"
14561
  "%vround\t{%2, %1, %d0|%d0, %1, %2}"
14562
  [(set_attr "type" "ssecvt")
14563
   (set_attr "prefix_extra" "1")
14564
   (set_attr "prefix" "maybe_vex")
14565
   (set_attr "mode" "")])
14566
 
14567
(define_insn "rintxf2"
14568
  [(set (match_operand:XF 0 "register_operand" "=f")
14569
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14570
                   UNSPEC_FRNDINT))]
14571
  "TARGET_USE_FANCY_MATH_387
14572
   && flag_unsafe_math_optimizations"
14573
  "frndint"
14574
  [(set_attr "type" "fpspc")
14575
   (set_attr "mode" "XF")])
14576
 
14577
(define_expand "rint2"
14578
  [(use (match_operand:MODEF 0 "register_operand" ""))
14579
   (use (match_operand:MODEF 1 "register_operand" ""))]
14580
  "(TARGET_USE_FANCY_MATH_387
14581
    && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14582
        || TARGET_MIX_SSE_I387)
14583
    && flag_unsafe_math_optimizations)
14584
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
14585
       && !flag_trapping_math)"
14586
{
14587
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
14588
      && !flag_trapping_math)
14589
    {
14590
      if (TARGET_ROUND)
14591
        emit_insn (gen_sse4_1_round2
14592
                   (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14593
      else if (optimize_insn_for_size_p ())
14594
        FAIL;
14595
      else
14596
        ix86_expand_rint (operands[0], operands[1]);
14597
    }
14598
  else
14599
    {
14600
      rtx op0 = gen_reg_rtx (XFmode);
14601
      rtx op1 = gen_reg_rtx (XFmode);
14602
 
14603
      emit_insn (gen_extendxf2 (op1, operands[1]));
14604
      emit_insn (gen_rintxf2 (op0, op1));
14605
 
14606
      emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
14607
    }
14608
  DONE;
14609
})
14610
 
14611
(define_expand "round2"
14612
  [(match_operand:X87MODEF 0 "register_operand" "")
14613
   (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14614
  "(TARGET_USE_FANCY_MATH_387
14615
    && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14616
        || TARGET_MIX_SSE_I387)
14617
    && flag_unsafe_math_optimizations)
14618
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
14619
       && !flag_trapping_math && !flag_rounding_math)"
14620
{
14621
  if (optimize_insn_for_size_p ())
14622
    FAIL;
14623
 
14624
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
14625
      && !flag_trapping_math && !flag_rounding_math)
14626
    {
14627
      if (TARGET_ROUND)
14628
        {
14629
          operands[1] = force_reg (mode, operands[1]);
14630
          ix86_expand_round_sse4 (operands[0], operands[1]);
14631
        }
14632
      else if (TARGET_64BIT || (mode != DFmode))
14633
        ix86_expand_round (operands[0], operands[1]);
14634
      else
14635
        ix86_expand_rounddf_32 (operands[0], operands[1]);
14636
    }
14637
  else
14638
    {
14639
      operands[1] = force_reg (mode, operands[1]);
14640
      ix86_emit_i387_round (operands[0], operands[1]);
14641
    }
14642
  DONE;
14643
})
14644
 
14645
(define_insn_and_split "*fistdi2_1"
14646
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
14647
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14648
                   UNSPEC_FIST))]
14649
  "TARGET_USE_FANCY_MATH_387
14650
   && can_create_pseudo_p ()"
14651
  "#"
14652
  "&& 1"
14653
  [(const_int 0)]
14654
{
14655
  if (memory_operand (operands[0], VOIDmode))
14656
    emit_insn (gen_fistdi2 (operands[0], operands[1]));
14657
  else
14658
    {
14659
      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14660
      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14661
                                         operands[2]));
14662
    }
14663
  DONE;
14664
}
14665
  [(set_attr "type" "fpspc")
14666
   (set_attr "mode" "DI")])
14667
 
14668
(define_insn "fistdi2"
14669
  [(set (match_operand:DI 0 "memory_operand" "=m")
14670
        (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14671
                   UNSPEC_FIST))
14672
   (clobber (match_scratch:XF 2 "=&1f"))]
14673
  "TARGET_USE_FANCY_MATH_387"
14674
  "* return output_fix_trunc (insn, operands, false);"
14675
  [(set_attr "type" "fpspc")
14676
   (set_attr "mode" "DI")])
14677
 
14678
(define_insn "fistdi2_with_temp"
14679
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14680
        (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14681
                   UNSPEC_FIST))
14682
   (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14683
   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14684
  "TARGET_USE_FANCY_MATH_387"
14685
  "#"
14686
  [(set_attr "type" "fpspc")
14687
   (set_attr "mode" "DI")])
14688
 
14689
(define_split
14690
  [(set (match_operand:DI 0 "register_operand" "")
14691
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14692
                   UNSPEC_FIST))
14693
   (clobber (match_operand:DI 2 "memory_operand" ""))
14694
   (clobber (match_scratch 3 ""))]
14695
  "reload_completed"
14696
  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14697
              (clobber (match_dup 3))])
14698
   (set (match_dup 0) (match_dup 2))])
14699
 
14700
(define_split
14701
  [(set (match_operand:DI 0 "memory_operand" "")
14702
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14703
                   UNSPEC_FIST))
14704
   (clobber (match_operand:DI 2 "memory_operand" ""))
14705
   (clobber (match_scratch 3 ""))]
14706
  "reload_completed"
14707
  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14708
              (clobber (match_dup 3))])])
14709
 
14710
(define_insn_and_split "*fist2_1"
14711
  [(set (match_operand:SWI24 0 "register_operand" "")
14712
        (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14713
                      UNSPEC_FIST))]
14714
  "TARGET_USE_FANCY_MATH_387
14715
   && can_create_pseudo_p ()"
14716
  "#"
14717
  "&& 1"
14718
  [(const_int 0)]
14719
{
14720
  operands[2] = assign_386_stack_local (mode, SLOT_TEMP);
14721
  emit_insn (gen_fist2_with_temp (operands[0], operands[1],
14722
                                        operands[2]));
14723
  DONE;
14724
}
14725
  [(set_attr "type" "fpspc")
14726
   (set_attr "mode" "")])
14727
 
14728
(define_insn "fist2"
14729
  [(set (match_operand:SWI24 0 "memory_operand" "=m")
14730
        (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14731
                      UNSPEC_FIST))]
14732
  "TARGET_USE_FANCY_MATH_387"
14733
  "* return output_fix_trunc (insn, operands, false);"
14734
  [(set_attr "type" "fpspc")
14735
   (set_attr "mode" "")])
14736
 
14737
(define_insn "fist2_with_temp"
14738
  [(set (match_operand:SWI24 0 "register_operand" "=r")
14739
        (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14740
                      UNSPEC_FIST))
14741
   (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14742
  "TARGET_USE_FANCY_MATH_387"
14743
  "#"
14744
  [(set_attr "type" "fpspc")
14745
   (set_attr "mode" "")])
14746
 
14747
(define_split
14748
  [(set (match_operand:SWI24 0 "register_operand" "")
14749
        (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14750
                      UNSPEC_FIST))
14751
   (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14752
  "reload_completed"
14753
  [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14754
   (set (match_dup 0) (match_dup 2))])
14755
 
14756
(define_split
14757
  [(set (match_operand:SWI24 0 "memory_operand" "")
14758
        (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14759
                      UNSPEC_FIST))
14760
   (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14761
  "reload_completed"
14762
  [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14763
 
14764
(define_expand "lrintxf2"
14765
  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14766
     (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14767
                     UNSPEC_FIST))]
14768
  "TARGET_USE_FANCY_MATH_387")
14769
 
14770
(define_expand "lrint2"
14771
  [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14772
     (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14773
                        UNSPEC_FIX_NOTRUNC))]
14774
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
14775
   && ((mode != DImode) || TARGET_64BIT)")
14776
 
14777
(define_expand "lround2"
14778
  [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14779
   (match_operand:X87MODEF 1 "register_operand" "")]
14780
  "(TARGET_USE_FANCY_MATH_387
14781
    && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14782
        || TARGET_MIX_SSE_I387)
14783
    && flag_unsafe_math_optimizations)
14784
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
14785
       && mode != HImode
14786
       && ((mode != DImode) || TARGET_64BIT)
14787
       && !flag_trapping_math && !flag_rounding_math)"
14788
{
14789
  if (optimize_insn_for_size_p ())
14790
    FAIL;
14791
 
14792
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
14793
      && mode != HImode
14794
      && ((mode != DImode) || TARGET_64BIT)
14795
      && !flag_trapping_math && !flag_rounding_math)
14796
    ix86_expand_lround (operands[0], operands[1]);
14797
  else
14798
    ix86_emit_i387_round (operands[0], operands[1]);
14799
  DONE;
14800
})
14801
 
14802
;; Rounding mode control word calculation could clobber FLAGS_REG.
14803
(define_insn_and_split "frndintxf2_floor"
14804
  [(set (match_operand:XF 0 "register_operand" "")
14805
        (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14806
         UNSPEC_FRNDINT_FLOOR))
14807
   (clobber (reg:CC FLAGS_REG))]
14808
  "TARGET_USE_FANCY_MATH_387
14809
   && flag_unsafe_math_optimizations
14810
   && can_create_pseudo_p ()"
14811
  "#"
14812
  "&& 1"
14813
  [(const_int 0)]
14814
{
14815
  ix86_optimize_mode_switching[I387_FLOOR] = 1;
14816
 
14817
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14818
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14819
 
14820
  emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14821
                                        operands[2], operands[3]));
14822
  DONE;
14823
}
14824
  [(set_attr "type" "frndint")
14825
   (set_attr "i387_cw" "floor")
14826
   (set_attr "mode" "XF")])
14827
 
14828
(define_insn "frndintxf2_floor_i387"
14829
  [(set (match_operand:XF 0 "register_operand" "=f")
14830
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14831
         UNSPEC_FRNDINT_FLOOR))
14832
   (use (match_operand:HI 2 "memory_operand" "m"))
14833
   (use (match_operand:HI 3 "memory_operand" "m"))]
14834
  "TARGET_USE_FANCY_MATH_387
14835
   && flag_unsafe_math_optimizations"
14836
  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14837
  [(set_attr "type" "frndint")
14838
   (set_attr "i387_cw" "floor")
14839
   (set_attr "mode" "XF")])
14840
 
14841
(define_expand "floorxf2"
14842
  [(use (match_operand:XF 0 "register_operand" ""))
14843
   (use (match_operand:XF 1 "register_operand" ""))]
14844
  "TARGET_USE_FANCY_MATH_387
14845
   && flag_unsafe_math_optimizations"
14846
{
14847
  if (optimize_insn_for_size_p ())
14848
    FAIL;
14849
  emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14850
  DONE;
14851
})
14852
 
14853
(define_expand "floor2"
14854
  [(use (match_operand:MODEF 0 "register_operand" ""))
14855
   (use (match_operand:MODEF 1 "register_operand" ""))]
14856
  "(TARGET_USE_FANCY_MATH_387
14857
    && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
14858
        || TARGET_MIX_SSE_I387)
14859
    && flag_unsafe_math_optimizations)
14860
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
14861
       && !flag_trapping_math)"
14862
{
14863
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
14864
      && !flag_trapping_math)
14865
    {
14866
      if (TARGET_ROUND)
14867
        emit_insn (gen_sse4_1_round2
14868
                   (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14869
      else if (optimize_insn_for_size_p ())
14870
        FAIL;
14871
      else if (TARGET_64BIT || (mode != DFmode))
14872
        ix86_expand_floorceil (operands[0], operands[1], true);
14873
      else
14874
        ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14875
    }
14876
  else
14877
    {
14878
      rtx op0, op1;
14879
 
14880
      if (optimize_insn_for_size_p ())
14881
        FAIL;
14882
 
14883
      op0 = gen_reg_rtx (XFmode);
14884
      op1 = gen_reg_rtx (XFmode);
14885
      emit_insn (gen_extendxf2 (op1, operands[1]));
14886
      emit_insn (gen_frndintxf2_floor (op0, op1));
14887
 
14888
      emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
14889
    }
14890
  DONE;
14891
})
14892
 
14893
(define_insn_and_split "*fist2_floor_1"
14894
  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14895
        (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14896
                        UNSPEC_FIST_FLOOR))
14897
   (clobber (reg:CC FLAGS_REG))]
14898
  "TARGET_USE_FANCY_MATH_387
14899
   && flag_unsafe_math_optimizations
14900
   && can_create_pseudo_p ()"
14901
  "#"
14902
  "&& 1"
14903
  [(const_int 0)]
14904
{
14905
  ix86_optimize_mode_switching[I387_FLOOR] = 1;
14906
 
14907
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14908
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14909
  if (memory_operand (operands[0], VOIDmode))
14910
    emit_insn (gen_fist2_floor (operands[0], operands[1],
14911
                                      operands[2], operands[3]));
14912
  else
14913
    {
14914
      operands[4] = assign_386_stack_local (mode, SLOT_TEMP);
14915
      emit_insn (gen_fist2_floor_with_temp (operands[0], operands[1],
14916
                                                  operands[2], operands[3],
14917
                                                  operands[4]));
14918
    }
14919
  DONE;
14920
}
14921
  [(set_attr "type" "fistp")
14922
   (set_attr "i387_cw" "floor")
14923
   (set_attr "mode" "")])
14924
 
14925
(define_insn "fistdi2_floor"
14926
  [(set (match_operand:DI 0 "memory_operand" "=m")
14927
        (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14928
                   UNSPEC_FIST_FLOOR))
14929
   (use (match_operand:HI 2 "memory_operand" "m"))
14930
   (use (match_operand:HI 3 "memory_operand" "m"))
14931
   (clobber (match_scratch:XF 4 "=&1f"))]
14932
  "TARGET_USE_FANCY_MATH_387
14933
   && flag_unsafe_math_optimizations"
14934
  "* return output_fix_trunc (insn, operands, false);"
14935
  [(set_attr "type" "fistp")
14936
   (set_attr "i387_cw" "floor")
14937
   (set_attr "mode" "DI")])
14938
 
14939
(define_insn "fistdi2_floor_with_temp"
14940
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14941
        (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14942
                   UNSPEC_FIST_FLOOR))
14943
   (use (match_operand:HI 2 "memory_operand" "m,m"))
14944
   (use (match_operand:HI 3 "memory_operand" "m,m"))
14945
   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14946
   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14947
  "TARGET_USE_FANCY_MATH_387
14948
   && flag_unsafe_math_optimizations"
14949
  "#"
14950
  [(set_attr "type" "fistp")
14951
   (set_attr "i387_cw" "floor")
14952
   (set_attr "mode" "DI")])
14953
 
14954
(define_split
14955
  [(set (match_operand:DI 0 "register_operand" "")
14956
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14957
                   UNSPEC_FIST_FLOOR))
14958
   (use (match_operand:HI 2 "memory_operand" ""))
14959
   (use (match_operand:HI 3 "memory_operand" ""))
14960
   (clobber (match_operand:DI 4 "memory_operand" ""))
14961
   (clobber (match_scratch 5 ""))]
14962
  "reload_completed"
14963
  [(parallel [(set (match_dup 4)
14964
                   (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14965
              (use (match_dup 2))
14966
              (use (match_dup 3))
14967
              (clobber (match_dup 5))])
14968
   (set (match_dup 0) (match_dup 4))])
14969
 
14970
(define_split
14971
  [(set (match_operand:DI 0 "memory_operand" "")
14972
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14973
                   UNSPEC_FIST_FLOOR))
14974
   (use (match_operand:HI 2 "memory_operand" ""))
14975
   (use (match_operand:HI 3 "memory_operand" ""))
14976
   (clobber (match_operand:DI 4 "memory_operand" ""))
14977
   (clobber (match_scratch 5 ""))]
14978
  "reload_completed"
14979
  [(parallel [(set (match_dup 0)
14980
                   (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14981
              (use (match_dup 2))
14982
              (use (match_dup 3))
14983
              (clobber (match_dup 5))])])
14984
 
14985
(define_insn "fist2_floor"
14986
  [(set (match_operand:SWI24 0 "memory_operand" "=m")
14987
        (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14988
                      UNSPEC_FIST_FLOOR))
14989
   (use (match_operand:HI 2 "memory_operand" "m"))
14990
   (use (match_operand:HI 3 "memory_operand" "m"))]
14991
  "TARGET_USE_FANCY_MATH_387
14992
   && flag_unsafe_math_optimizations"
14993
  "* return output_fix_trunc (insn, operands, false);"
14994
  [(set_attr "type" "fistp")
14995
   (set_attr "i387_cw" "floor")
14996
   (set_attr "mode" "")])
14997
 
14998
(define_insn "fist2_floor_with_temp"
14999
  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15000
        (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15001
                      UNSPEC_FIST_FLOOR))
15002
   (use (match_operand:HI 2 "memory_operand" "m,m"))
15003
   (use (match_operand:HI 3 "memory_operand" "m,m"))
15004
   (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15005
  "TARGET_USE_FANCY_MATH_387
15006
   && flag_unsafe_math_optimizations"
15007
  "#"
15008
  [(set_attr "type" "fistp")
15009
   (set_attr "i387_cw" "floor")
15010
   (set_attr "mode" "")])
15011
 
15012
(define_split
15013
  [(set (match_operand:SWI24 0 "register_operand" "")
15014
        (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15015
                      UNSPEC_FIST_FLOOR))
15016
   (use (match_operand:HI 2 "memory_operand" ""))
15017
   (use (match_operand:HI 3 "memory_operand" ""))
15018
   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15019
  "reload_completed"
15020
  [(parallel [(set (match_dup 4)
15021
                   (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15022
              (use (match_dup 2))
15023
              (use (match_dup 3))])
15024
   (set (match_dup 0) (match_dup 4))])
15025
 
15026
(define_split
15027
  [(set (match_operand:SWI24 0 "memory_operand" "")
15028
        (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15029
                      UNSPEC_FIST_FLOOR))
15030
   (use (match_operand:HI 2 "memory_operand" ""))
15031
   (use (match_operand:HI 3 "memory_operand" ""))
15032
   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15033
  "reload_completed"
15034
  [(parallel [(set (match_dup 0)
15035
                   (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15036
              (use (match_dup 2))
15037
              (use (match_dup 3))])])
15038
 
15039
(define_expand "lfloorxf2"
15040
  [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15041
                   (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15042
                                   UNSPEC_FIST_FLOOR))
15043
              (clobber (reg:CC FLAGS_REG))])]
15044
  "TARGET_USE_FANCY_MATH_387
15045
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15046
   && flag_unsafe_math_optimizations")
15047
 
15048
(define_expand "lfloor2"
15049
  [(match_operand:SWI48 0 "nonimmediate_operand" "")
15050
   (match_operand:MODEF 1 "register_operand" "")]
15051
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
15052
   && !flag_trapping_math"
15053
{
15054
  if (TARGET_64BIT && optimize_insn_for_size_p ())
15055
    FAIL;
15056
  ix86_expand_lfloorceil (operands[0], operands[1], true);
15057
  DONE;
15058
})
15059
 
15060
;; Rounding mode control word calculation could clobber FLAGS_REG.
15061
(define_insn_and_split "frndintxf2_ceil"
15062
  [(set (match_operand:XF 0 "register_operand" "")
15063
        (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15064
         UNSPEC_FRNDINT_CEIL))
15065
   (clobber (reg:CC FLAGS_REG))]
15066
  "TARGET_USE_FANCY_MATH_387
15067
   && flag_unsafe_math_optimizations
15068
   && can_create_pseudo_p ()"
15069
  "#"
15070
  "&& 1"
15071
  [(const_int 0)]
15072
{
15073
  ix86_optimize_mode_switching[I387_CEIL] = 1;
15074
 
15075
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15076
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15077
 
15078
  emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15079
                                       operands[2], operands[3]));
15080
  DONE;
15081
}
15082
  [(set_attr "type" "frndint")
15083
   (set_attr "i387_cw" "ceil")
15084
   (set_attr "mode" "XF")])
15085
 
15086
(define_insn "frndintxf2_ceil_i387"
15087
  [(set (match_operand:XF 0 "register_operand" "=f")
15088
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15089
         UNSPEC_FRNDINT_CEIL))
15090
   (use (match_operand:HI 2 "memory_operand" "m"))
15091
   (use (match_operand:HI 3 "memory_operand" "m"))]
15092
  "TARGET_USE_FANCY_MATH_387
15093
   && flag_unsafe_math_optimizations"
15094
  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15095
  [(set_attr "type" "frndint")
15096
   (set_attr "i387_cw" "ceil")
15097
   (set_attr "mode" "XF")])
15098
 
15099
(define_expand "ceilxf2"
15100
  [(use (match_operand:XF 0 "register_operand" ""))
15101
   (use (match_operand:XF 1 "register_operand" ""))]
15102
  "TARGET_USE_FANCY_MATH_387
15103
   && flag_unsafe_math_optimizations"
15104
{
15105
  if (optimize_insn_for_size_p ())
15106
    FAIL;
15107
  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15108
  DONE;
15109
})
15110
 
15111
(define_expand "ceil2"
15112
  [(use (match_operand:MODEF 0 "register_operand" ""))
15113
   (use (match_operand:MODEF 1 "register_operand" ""))]
15114
  "(TARGET_USE_FANCY_MATH_387
15115
    && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15116
        || TARGET_MIX_SSE_I387)
15117
    && flag_unsafe_math_optimizations)
15118
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
15119
       && !flag_trapping_math)"
15120
{
15121
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
15122
      && !flag_trapping_math)
15123
    {
15124
      if (TARGET_ROUND)
15125
        emit_insn (gen_sse4_1_round2
15126
                   (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15127
      else if (optimize_insn_for_size_p ())
15128
        FAIL;
15129
      else if (TARGET_64BIT || (mode != DFmode))
15130
        ix86_expand_floorceil (operands[0], operands[1], false);
15131
      else
15132
        ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15133
    }
15134
  else
15135
    {
15136
      rtx op0, op1;
15137
 
15138
      if (optimize_insn_for_size_p ())
15139
        FAIL;
15140
 
15141
      op0 = gen_reg_rtx (XFmode);
15142
      op1 = gen_reg_rtx (XFmode);
15143
      emit_insn (gen_extendxf2 (op1, operands[1]));
15144
      emit_insn (gen_frndintxf2_ceil (op0, op1));
15145
 
15146
      emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
15147
    }
15148
  DONE;
15149
})
15150
 
15151
(define_insn_and_split "*fist2_ceil_1"
15152
  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15153
        (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15154
                        UNSPEC_FIST_CEIL))
15155
   (clobber (reg:CC FLAGS_REG))]
15156
  "TARGET_USE_FANCY_MATH_387
15157
   && flag_unsafe_math_optimizations
15158
   && can_create_pseudo_p ()"
15159
  "#"
15160
  "&& 1"
15161
  [(const_int 0)]
15162
{
15163
  ix86_optimize_mode_switching[I387_CEIL] = 1;
15164
 
15165
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15166
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15167
  if (memory_operand (operands[0], VOIDmode))
15168
    emit_insn (gen_fist2_ceil (operands[0], operands[1],
15169
                                     operands[2], operands[3]));
15170
  else
15171
    {
15172
      operands[4] = assign_386_stack_local (mode, SLOT_TEMP);
15173
      emit_insn (gen_fist2_ceil_with_temp (operands[0], operands[1],
15174
                                                 operands[2], operands[3],
15175
                                                 operands[4]));
15176
    }
15177
  DONE;
15178
}
15179
  [(set_attr "type" "fistp")
15180
   (set_attr "i387_cw" "ceil")
15181
   (set_attr "mode" "")])
15182
 
15183
(define_insn "fistdi2_ceil"
15184
  [(set (match_operand:DI 0 "memory_operand" "=m")
15185
        (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15186
                   UNSPEC_FIST_CEIL))
15187
   (use (match_operand:HI 2 "memory_operand" "m"))
15188
   (use (match_operand:HI 3 "memory_operand" "m"))
15189
   (clobber (match_scratch:XF 4 "=&1f"))]
15190
  "TARGET_USE_FANCY_MATH_387
15191
   && flag_unsafe_math_optimizations"
15192
  "* return output_fix_trunc (insn, operands, false);"
15193
  [(set_attr "type" "fistp")
15194
   (set_attr "i387_cw" "ceil")
15195
   (set_attr "mode" "DI")])
15196
 
15197
(define_insn "fistdi2_ceil_with_temp"
15198
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15199
        (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15200
                   UNSPEC_FIST_CEIL))
15201
   (use (match_operand:HI 2 "memory_operand" "m,m"))
15202
   (use (match_operand:HI 3 "memory_operand" "m,m"))
15203
   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15204
   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15205
  "TARGET_USE_FANCY_MATH_387
15206
   && flag_unsafe_math_optimizations"
15207
  "#"
15208
  [(set_attr "type" "fistp")
15209
   (set_attr "i387_cw" "ceil")
15210
   (set_attr "mode" "DI")])
15211
 
15212
(define_split
15213
  [(set (match_operand:DI 0 "register_operand" "")
15214
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15215
                   UNSPEC_FIST_CEIL))
15216
   (use (match_operand:HI 2 "memory_operand" ""))
15217
   (use (match_operand:HI 3 "memory_operand" ""))
15218
   (clobber (match_operand:DI 4 "memory_operand" ""))
15219
   (clobber (match_scratch 5 ""))]
15220
  "reload_completed"
15221
  [(parallel [(set (match_dup 4)
15222
                   (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15223
              (use (match_dup 2))
15224
              (use (match_dup 3))
15225
              (clobber (match_dup 5))])
15226
   (set (match_dup 0) (match_dup 4))])
15227
 
15228
(define_split
15229
  [(set (match_operand:DI 0 "memory_operand" "")
15230
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15231
                   UNSPEC_FIST_CEIL))
15232
   (use (match_operand:HI 2 "memory_operand" ""))
15233
   (use (match_operand:HI 3 "memory_operand" ""))
15234
   (clobber (match_operand:DI 4 "memory_operand" ""))
15235
   (clobber (match_scratch 5 ""))]
15236
  "reload_completed"
15237
  [(parallel [(set (match_dup 0)
15238
                   (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15239
              (use (match_dup 2))
15240
              (use (match_dup 3))
15241
              (clobber (match_dup 5))])])
15242
 
15243
(define_insn "fist2_ceil"
15244
  [(set (match_operand:SWI24 0 "memory_operand" "=m")
15245
        (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15246
                      UNSPEC_FIST_CEIL))
15247
   (use (match_operand:HI 2 "memory_operand" "m"))
15248
   (use (match_operand:HI 3 "memory_operand" "m"))]
15249
  "TARGET_USE_FANCY_MATH_387
15250
   && flag_unsafe_math_optimizations"
15251
  "* return output_fix_trunc (insn, operands, false);"
15252
  [(set_attr "type" "fistp")
15253
   (set_attr "i387_cw" "ceil")
15254
   (set_attr "mode" "")])
15255
 
15256
(define_insn "fist2_ceil_with_temp"
15257
  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15258
        (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15259
                      UNSPEC_FIST_CEIL))
15260
   (use (match_operand:HI 2 "memory_operand" "m,m"))
15261
   (use (match_operand:HI 3 "memory_operand" "m,m"))
15262
   (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15263
  "TARGET_USE_FANCY_MATH_387
15264
   && flag_unsafe_math_optimizations"
15265
  "#"
15266
  [(set_attr "type" "fistp")
15267
   (set_attr "i387_cw" "ceil")
15268
   (set_attr "mode" "")])
15269
 
15270
(define_split
15271
  [(set (match_operand:SWI24 0 "register_operand" "")
15272
        (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15273
                      UNSPEC_FIST_CEIL))
15274
   (use (match_operand:HI 2 "memory_operand" ""))
15275
   (use (match_operand:HI 3 "memory_operand" ""))
15276
   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15277
  "reload_completed"
15278
  [(parallel [(set (match_dup 4)
15279
                   (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15280
              (use (match_dup 2))
15281
              (use (match_dup 3))])
15282
   (set (match_dup 0) (match_dup 4))])
15283
 
15284
(define_split
15285
  [(set (match_operand:SWI24 0 "memory_operand" "")
15286
        (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15287
                      UNSPEC_FIST_CEIL))
15288
   (use (match_operand:HI 2 "memory_operand" ""))
15289
   (use (match_operand:HI 3 "memory_operand" ""))
15290
   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15291
  "reload_completed"
15292
  [(parallel [(set (match_dup 0)
15293
                   (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15294
              (use (match_dup 2))
15295
              (use (match_dup 3))])])
15296
 
15297
(define_expand "lceilxf2"
15298
  [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15299
                   (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15300
                                   UNSPEC_FIST_CEIL))
15301
              (clobber (reg:CC FLAGS_REG))])]
15302
  "TARGET_USE_FANCY_MATH_387
15303
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15304
   && flag_unsafe_math_optimizations")
15305
 
15306
(define_expand "lceil2"
15307
  [(match_operand:SWI48 0 "nonimmediate_operand" "")
15308
   (match_operand:MODEF 1 "register_operand" "")]
15309
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
15310
   && !flag_trapping_math"
15311
{
15312
  ix86_expand_lfloorceil (operands[0], operands[1], false);
15313
  DONE;
15314
})
15315
 
15316
;; Rounding mode control word calculation could clobber FLAGS_REG.
15317
(define_insn_and_split "frndintxf2_trunc"
15318
  [(set (match_operand:XF 0 "register_operand" "")
15319
        (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15320
         UNSPEC_FRNDINT_TRUNC))
15321
   (clobber (reg:CC FLAGS_REG))]
15322
  "TARGET_USE_FANCY_MATH_387
15323
   && flag_unsafe_math_optimizations
15324
   && can_create_pseudo_p ()"
15325
  "#"
15326
  "&& 1"
15327
  [(const_int 0)]
15328
{
15329
  ix86_optimize_mode_switching[I387_TRUNC] = 1;
15330
 
15331
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15332
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15333
 
15334
  emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15335
                                        operands[2], operands[3]));
15336
  DONE;
15337
}
15338
  [(set_attr "type" "frndint")
15339
   (set_attr "i387_cw" "trunc")
15340
   (set_attr "mode" "XF")])
15341
 
15342
(define_insn "frndintxf2_trunc_i387"
15343
  [(set (match_operand:XF 0 "register_operand" "=f")
15344
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15345
         UNSPEC_FRNDINT_TRUNC))
15346
   (use (match_operand:HI 2 "memory_operand" "m"))
15347
   (use (match_operand:HI 3 "memory_operand" "m"))]
15348
  "TARGET_USE_FANCY_MATH_387
15349
   && flag_unsafe_math_optimizations"
15350
  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15351
  [(set_attr "type" "frndint")
15352
   (set_attr "i387_cw" "trunc")
15353
   (set_attr "mode" "XF")])
15354
 
15355
(define_expand "btruncxf2"
15356
  [(use (match_operand:XF 0 "register_operand" ""))
15357
   (use (match_operand:XF 1 "register_operand" ""))]
15358
  "TARGET_USE_FANCY_MATH_387
15359
   && flag_unsafe_math_optimizations"
15360
{
15361
  if (optimize_insn_for_size_p ())
15362
    FAIL;
15363
  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15364
  DONE;
15365
})
15366
 
15367
(define_expand "btrunc2"
15368
  [(use (match_operand:MODEF 0 "register_operand" ""))
15369
   (use (match_operand:MODEF 1 "register_operand" ""))]
15370
  "(TARGET_USE_FANCY_MATH_387
15371
    && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15372
        || TARGET_MIX_SSE_I387)
15373
    && flag_unsafe_math_optimizations)
15374
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
15375
       && !flag_trapping_math)"
15376
{
15377
  if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
15378
      && !flag_trapping_math)
15379
    {
15380
      if (TARGET_ROUND)
15381
        emit_insn (gen_sse4_1_round2
15382
                   (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15383
      else if (optimize_insn_for_size_p ())
15384
        FAIL;
15385
      else if (TARGET_64BIT || (mode != DFmode))
15386
        ix86_expand_trunc (operands[0], operands[1]);
15387
      else
15388
        ix86_expand_truncdf_32 (operands[0], operands[1]);
15389
    }
15390
  else
15391
    {
15392
      rtx op0, op1;
15393
 
15394
      if (optimize_insn_for_size_p ())
15395
        FAIL;
15396
 
15397
      op0 = gen_reg_rtx (XFmode);
15398
      op1 = gen_reg_rtx (XFmode);
15399
      emit_insn (gen_extendxf2 (op1, operands[1]));
15400
      emit_insn (gen_frndintxf2_trunc (op0, op1));
15401
 
15402
      emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
15403
    }
15404
  DONE;
15405
})
15406
 
15407
;; Rounding mode control word calculation could clobber FLAGS_REG.
15408
(define_insn_and_split "frndintxf2_mask_pm"
15409
  [(set (match_operand:XF 0 "register_operand" "")
15410
        (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15411
         UNSPEC_FRNDINT_MASK_PM))
15412
   (clobber (reg:CC FLAGS_REG))]
15413
  "TARGET_USE_FANCY_MATH_387
15414
   && flag_unsafe_math_optimizations
15415
   && can_create_pseudo_p ()"
15416
  "#"
15417
  "&& 1"
15418
  [(const_int 0)]
15419
{
15420
  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15421
 
15422
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15423
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15424
 
15425
  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15426
                                          operands[2], operands[3]));
15427
  DONE;
15428
}
15429
  [(set_attr "type" "frndint")
15430
   (set_attr "i387_cw" "mask_pm")
15431
   (set_attr "mode" "XF")])
15432
 
15433
(define_insn "frndintxf2_mask_pm_i387"
15434
  [(set (match_operand:XF 0 "register_operand" "=f")
15435
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15436
         UNSPEC_FRNDINT_MASK_PM))
15437
   (use (match_operand:HI 2 "memory_operand" "m"))
15438
   (use (match_operand:HI 3 "memory_operand" "m"))]
15439
  "TARGET_USE_FANCY_MATH_387
15440
   && flag_unsafe_math_optimizations"
15441
  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15442
  [(set_attr "type" "frndint")
15443
   (set_attr "i387_cw" "mask_pm")
15444
   (set_attr "mode" "XF")])
15445
 
15446
(define_expand "nearbyintxf2"
15447
  [(use (match_operand:XF 0 "register_operand" ""))
15448
   (use (match_operand:XF 1 "register_operand" ""))]
15449
  "TARGET_USE_FANCY_MATH_387
15450
   && flag_unsafe_math_optimizations"
15451
{
15452
  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15453
  DONE;
15454
})
15455
 
15456
(define_expand "nearbyint2"
15457
  [(use (match_operand:MODEF 0 "register_operand" ""))
15458
   (use (match_operand:MODEF 1 "register_operand" ""))]
15459
  "TARGET_USE_FANCY_MATH_387
15460
   && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
15461
       || TARGET_MIX_SSE_I387)
15462
   && flag_unsafe_math_optimizations"
15463
{
15464
  rtx op0 = gen_reg_rtx (XFmode);
15465
  rtx op1 = gen_reg_rtx (XFmode);
15466
 
15467
  emit_insn (gen_extendxf2 (op1, operands[1]));
15468
  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15469
 
15470
  emit_insn (gen_truncxf2_i387_noop (operands[0], op0));
15471
  DONE;
15472
})
15473
 
15474
(define_insn "fxam2_i387"
15475
  [(set (match_operand:HI 0 "register_operand" "=a")
15476
        (unspec:HI
15477
          [(match_operand:X87MODEF 1 "register_operand" "f")]
15478
          UNSPEC_FXAM))]
15479
  "TARGET_USE_FANCY_MATH_387"
15480
  "fxam\n\tfnstsw\t%0"
15481
  [(set_attr "type" "multi")
15482
   (set_attr "length" "4")
15483
   (set_attr "unit" "i387")
15484
   (set_attr "mode" "")])
15485
 
15486
(define_insn_and_split "fxam2_i387_with_temp"
15487
  [(set (match_operand:HI 0 "register_operand" "")
15488
        (unspec:HI
15489
          [(match_operand:MODEF 1 "memory_operand" "")]
15490
          UNSPEC_FXAM_MEM))]
15491
  "TARGET_USE_FANCY_MATH_387
15492
   && can_create_pseudo_p ()"
15493
  "#"
15494
  "&& 1"
15495
  [(set (match_dup 2)(match_dup 1))
15496
   (set (match_dup 0)
15497
        (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15498
{
15499
  operands[2] = gen_reg_rtx (mode);
15500
 
15501
  MEM_VOLATILE_P (operands[1]) = 1;
15502
}
15503
  [(set_attr "type" "multi")
15504
   (set_attr "unit" "i387")
15505
   (set_attr "mode" "")])
15506
 
15507
(define_expand "isinfxf2"
15508
  [(use (match_operand:SI 0 "register_operand" ""))
15509
   (use (match_operand:XF 1 "register_operand" ""))]
15510
  "TARGET_USE_FANCY_MATH_387
15511
   && TARGET_C99_FUNCTIONS"
15512
{
15513
  rtx mask = GEN_INT (0x45);
15514
  rtx val = GEN_INT (0x05);
15515
 
15516
  rtx cond;
15517
 
15518
  rtx scratch = gen_reg_rtx (HImode);
15519
  rtx res = gen_reg_rtx (QImode);
15520
 
15521
  emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15522
 
15523
  emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15524
  emit_insn (gen_cmpqi_ext_3 (scratch, val));
15525
  cond = gen_rtx_fmt_ee (EQ, QImode,
15526
                         gen_rtx_REG (CCmode, FLAGS_REG),
15527
                         const0_rtx);
15528
  emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15529
  emit_insn (gen_zero_extendqisi2 (operands[0], res));
15530
  DONE;
15531
})
15532
 
15533
(define_expand "isinf2"
15534
  [(use (match_operand:SI 0 "register_operand" ""))
15535
   (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15536
  "TARGET_USE_FANCY_MATH_387
15537
   && TARGET_C99_FUNCTIONS
15538
   && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
15539
{
15540
  rtx mask = GEN_INT (0x45);
15541
  rtx val = GEN_INT (0x05);
15542
 
15543
  rtx cond;
15544
 
15545
  rtx scratch = gen_reg_rtx (HImode);
15546
  rtx res = gen_reg_rtx (QImode);
15547
 
15548
  /* Remove excess precision by forcing value through memory. */
15549
  if (memory_operand (operands[1], VOIDmode))
15550
    emit_insn (gen_fxam2_i387_with_temp (scratch, operands[1]));
15551
  else
15552
    {
15553
      enum ix86_stack_slot slot = (virtuals_instantiated
15554
                                   ? SLOT_TEMP
15555
                                   : SLOT_VIRTUAL);
15556
      rtx temp = assign_386_stack_local (mode, slot);
15557
 
15558
      emit_move_insn (temp, operands[1]);
15559
      emit_insn (gen_fxam2_i387_with_temp (scratch, temp));
15560
    }
15561
 
15562
  emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15563
  emit_insn (gen_cmpqi_ext_3 (scratch, val));
15564
  cond = gen_rtx_fmt_ee (EQ, QImode,
15565
                         gen_rtx_REG (CCmode, FLAGS_REG),
15566
                         const0_rtx);
15567
  emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15568
  emit_insn (gen_zero_extendqisi2 (operands[0], res));
15569
  DONE;
15570
})
15571
 
15572
(define_expand "signbitxf2"
15573
  [(use (match_operand:SI 0 "register_operand" ""))
15574
   (use (match_operand:XF 1 "register_operand" ""))]
15575
  "TARGET_USE_FANCY_MATH_387"
15576
{
15577
  rtx scratch = gen_reg_rtx (HImode);
15578
 
15579
  emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15580
  emit_insn (gen_andsi3 (operands[0],
15581
             gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15582
  DONE;
15583
})
15584
 
15585
(define_insn "movmsk_df"
15586
  [(set (match_operand:SI 0 "register_operand" "=r")
15587
        (unspec:SI
15588
          [(match_operand:DF 1 "register_operand" "x")]
15589
          UNSPEC_MOVMSK))]
15590
  "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15591
  "%vmovmskpd\t{%1, %0|%0, %1}"
15592
  [(set_attr "type" "ssemov")
15593
   (set_attr "prefix" "maybe_vex")
15594
   (set_attr "mode" "DF")])
15595
 
15596
;; Use movmskpd in SSE mode to avoid store forwarding stall
15597
;; for 32bit targets and movq+shrq sequence for 64bit targets.
15598
(define_expand "signbitdf2"
15599
  [(use (match_operand:SI 0 "register_operand" ""))
15600
   (use (match_operand:DF 1 "register_operand" ""))]
15601
  "TARGET_USE_FANCY_MATH_387
15602
   || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15603
{
15604
  if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15605
    {
15606
      emit_insn (gen_movmsk_df (operands[0], operands[1]));
15607
      emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15608
    }
15609
  else
15610
    {
15611
      rtx scratch = gen_reg_rtx (HImode);
15612
 
15613
      emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15614
      emit_insn (gen_andsi3 (operands[0],
15615
                 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15616
    }
15617
  DONE;
15618
})
15619
 
15620
(define_expand "signbitsf2"
15621
  [(use (match_operand:SI 0 "register_operand" ""))
15622
   (use (match_operand:SF 1 "register_operand" ""))]
15623
  "TARGET_USE_FANCY_MATH_387
15624
   && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15625
{
15626
  rtx scratch = gen_reg_rtx (HImode);
15627
 
15628
  emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15629
  emit_insn (gen_andsi3 (operands[0],
15630
             gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15631
  DONE;
15632
})
15633
 
15634
;; Block operation instructions
15635
 
15636
(define_insn "cld"
15637
  [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15638
  ""
15639
  "cld"
15640
  [(set_attr "length" "1")
15641
   (set_attr "length_immediate" "0")
15642
   (set_attr "modrm" "0")])
15643
 
15644
(define_expand "movmem"
15645
  [(use (match_operand:BLK 0 "memory_operand" ""))
15646
   (use (match_operand:BLK 1 "memory_operand" ""))
15647
   (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15648
   (use (match_operand:SWI48 3 "const_int_operand" ""))
15649
   (use (match_operand:SI 4 "const_int_operand" ""))
15650
   (use (match_operand:SI 5 "const_int_operand" ""))]
15651
  ""
15652
{
15653
 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15654
                         operands[4], operands[5]))
15655
   DONE;
15656
 else
15657
   FAIL;
15658
})
15659
 
15660
;; Most CPUs don't like single string operations
15661
;; Handle this case here to simplify previous expander.
15662
 
15663
(define_expand "strmov"
15664
  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15665
   (set (match_operand 1 "memory_operand" "") (match_dup 4))
15666
   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15667
              (clobber (reg:CC FLAGS_REG))])
15668
   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15669
              (clobber (reg:CC FLAGS_REG))])]
15670
  ""
15671
{
15672
  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15673
 
15674
  /* If .md ever supports :P for Pmode, these can be directly
15675
     in the pattern above.  */
15676
  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15677
  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15678
 
15679
  /* Can't use this if the user has appropriated esi or edi.  */
15680
  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15681
      && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15682
    {
15683
      emit_insn (gen_strmov_singleop (operands[0], operands[1],
15684
                                      operands[2], operands[3],
15685
                                      operands[5], operands[6]));
15686
      DONE;
15687
    }
15688
 
15689
  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15690
})
15691
 
15692
(define_expand "strmov_singleop"
15693
  [(parallel [(set (match_operand 1 "memory_operand" "")
15694
                   (match_operand 3 "memory_operand" ""))
15695
              (set (match_operand 0 "register_operand" "")
15696
                   (match_operand 4 "" ""))
15697
              (set (match_operand 2 "register_operand" "")
15698
                   (match_operand 5 "" ""))])]
15699
  ""
15700
  "ix86_current_function_needs_cld = 1;")
15701
 
15702
(define_insn "*strmovdi_rex_1"
15703
  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15704
        (mem:DI (match_operand:DI 3 "register_operand" "1")))
15705
   (set (match_operand:DI 0 "register_operand" "=D")
15706
        (plus:DI (match_dup 2)
15707
                 (const_int 8)))
15708
   (set (match_operand:DI 1 "register_operand" "=S")
15709
        (plus:DI (match_dup 3)
15710
                 (const_int 8)))]
15711
  "TARGET_64BIT
15712
   && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15713
  "movsq"
15714
  [(set_attr "type" "str")
15715
   (set_attr "memory" "both")
15716
   (set_attr "mode" "DI")])
15717
 
15718
(define_insn "*strmovsi_1"
15719
  [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15720
        (mem:SI (match_operand:P 3 "register_operand" "1")))
15721
   (set (match_operand:P 0 "register_operand" "=D")
15722
        (plus:P (match_dup 2)
15723
                (const_int 4)))
15724
   (set (match_operand:P 1 "register_operand" "=S")
15725
        (plus:P (match_dup 3)
15726
                (const_int 4)))]
15727
  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15728
  "movs{l|d}"
15729
  [(set_attr "type" "str")
15730
   (set_attr "memory" "both")
15731
   (set_attr "mode" "SI")])
15732
 
15733
(define_insn "*strmovhi_1"
15734
  [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15735
        (mem:HI (match_operand:P 3 "register_operand" "1")))
15736
   (set (match_operand:P 0 "register_operand" "=D")
15737
        (plus:P (match_dup 2)
15738
                (const_int 2)))
15739
   (set (match_operand:P 1 "register_operand" "=S")
15740
        (plus:P (match_dup 3)
15741
                (const_int 2)))]
15742
  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15743
  "movsw"
15744
  [(set_attr "type" "str")
15745
   (set_attr "memory" "both")
15746
   (set_attr "mode" "HI")])
15747
 
15748
(define_insn "*strmovqi_1"
15749
  [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15750
        (mem:QI (match_operand:P 3 "register_operand" "1")))
15751
   (set (match_operand:P 0 "register_operand" "=D")
15752
        (plus:P (match_dup 2)
15753
                (const_int 1)))
15754
   (set (match_operand:P 1 "register_operand" "=S")
15755
        (plus:P (match_dup 3)
15756
                (const_int 1)))]
15757
  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15758
  "movsb"
15759
  [(set_attr "type" "str")
15760
   (set_attr "memory" "both")
15761
   (set (attr "prefix_rex")
15762
        (if_then_else
15763
          (match_test "mode == DImode")
15764
          (const_string "0")
15765
          (const_string "*")))
15766
   (set_attr "mode" "QI")])
15767
 
15768
(define_expand "rep_mov"
15769
  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15770
              (set (match_operand 0 "register_operand" "")
15771
                   (match_operand 5 "" ""))
15772
              (set (match_operand 2 "register_operand" "")
15773
                   (match_operand 6 "" ""))
15774
              (set (match_operand 1 "memory_operand" "")
15775
                   (match_operand 3 "memory_operand" ""))
15776
              (use (match_dup 4))])]
15777
  ""
15778
  "ix86_current_function_needs_cld = 1;")
15779
 
15780
(define_insn "*rep_movdi_rex64"
15781
  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15782
   (set (match_operand:DI 0 "register_operand" "=D")
15783
        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15784
                            (const_int 3))
15785
                 (match_operand:DI 3 "register_operand" "0")))
15786
   (set (match_operand:DI 1 "register_operand" "=S")
15787
        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15788
                 (match_operand:DI 4 "register_operand" "1")))
15789
   (set (mem:BLK (match_dup 3))
15790
        (mem:BLK (match_dup 4)))
15791
   (use (match_dup 5))]
15792
  "TARGET_64BIT
15793
   && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15794
  "rep{%;} movsq"
15795
  [(set_attr "type" "str")
15796
   (set_attr "prefix_rep" "1")
15797
   (set_attr "memory" "both")
15798
   (set_attr "mode" "DI")])
15799
 
15800
(define_insn "*rep_movsi"
15801
  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15802
   (set (match_operand:P 0 "register_operand" "=D")
15803
        (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15804
                          (const_int 2))
15805
                 (match_operand:P 3 "register_operand" "0")))
15806
   (set (match_operand:P 1 "register_operand" "=S")
15807
        (plus:P (ashift:P (match_dup 5) (const_int 2))
15808
                (match_operand:P 4 "register_operand" "1")))
15809
   (set (mem:BLK (match_dup 3))
15810
        (mem:BLK (match_dup 4)))
15811
   (use (match_dup 5))]
15812
  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15813
  "rep{%;} movs{l|d}"
15814
  [(set_attr "type" "str")
15815
   (set_attr "prefix_rep" "1")
15816
   (set_attr "memory" "both")
15817
   (set_attr "mode" "SI")])
15818
 
15819
(define_insn "*rep_movqi"
15820
  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15821
   (set (match_operand:P 0 "register_operand" "=D")
15822
        (plus:P (match_operand:P 3 "register_operand" "0")
15823
                (match_operand:P 5 "register_operand" "2")))
15824
   (set (match_operand:P 1 "register_operand" "=S")
15825
        (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15826
   (set (mem:BLK (match_dup 3))
15827
        (mem:BLK (match_dup 4)))
15828
   (use (match_dup 5))]
15829
  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15830
  "rep{%;} movsb"
15831
  [(set_attr "type" "str")
15832
   (set_attr "prefix_rep" "1")
15833
   (set_attr "memory" "both")
15834
   (set_attr "mode" "QI")])
15835
 
15836
(define_expand "setmem"
15837
   [(use (match_operand:BLK 0 "memory_operand" ""))
15838
    (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15839
    (use (match_operand:QI 2 "nonmemory_operand" ""))
15840
    (use (match_operand 3 "const_int_operand" ""))
15841
    (use (match_operand:SI 4 "const_int_operand" ""))
15842
    (use (match_operand:SI 5 "const_int_operand" ""))]
15843
  ""
15844
{
15845
 if (ix86_expand_setmem (operands[0], operands[1],
15846
                         operands[2], operands[3],
15847
                         operands[4], operands[5]))
15848
   DONE;
15849
 else
15850
   FAIL;
15851
})
15852
 
15853
;; Most CPUs don't like single string operations
15854
;; Handle this case here to simplify previous expander.
15855
 
15856
(define_expand "strset"
15857
  [(set (match_operand 1 "memory_operand" "")
15858
        (match_operand 2 "register_operand" ""))
15859
   (parallel [(set (match_operand 0 "register_operand" "")
15860
                   (match_dup 3))
15861
              (clobber (reg:CC FLAGS_REG))])]
15862
  ""
15863
{
15864
  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15865
    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15866
 
15867
  /* If .md ever supports :P for Pmode, this can be directly
15868
     in the pattern above.  */
15869
  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15870
                              GEN_INT (GET_MODE_SIZE (GET_MODE
15871
                                                      (operands[2]))));
15872
  /* Can't use this if the user has appropriated eax or edi.  */
15873
  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15874
      && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15875
    {
15876
      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15877
                                      operands[3]));
15878
      DONE;
15879
    }
15880
})
15881
 
15882
(define_expand "strset_singleop"
15883
  [(parallel [(set (match_operand 1 "memory_operand" "")
15884
                   (match_operand 2 "register_operand" ""))
15885
              (set (match_operand 0 "register_operand" "")
15886
                   (match_operand 3 "" ""))])]
15887
  ""
15888
  "ix86_current_function_needs_cld = 1;")
15889
 
15890
(define_insn "*strsetdi_rex_1"
15891
  [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15892
        (match_operand:DI 2 "register_operand" "a"))
15893
   (set (match_operand:DI 0 "register_operand" "=D")
15894
        (plus:DI (match_dup 1)
15895
                 (const_int 8)))]
15896
  "TARGET_64BIT
15897
   && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15898
  "stosq"
15899
  [(set_attr "type" "str")
15900
   (set_attr "memory" "store")
15901
   (set_attr "mode" "DI")])
15902
 
15903
(define_insn "*strsetsi_1"
15904
  [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15905
        (match_operand:SI 2 "register_operand" "a"))
15906
   (set (match_operand:P 0 "register_operand" "=D")
15907
        (plus:P (match_dup 1)
15908
                (const_int 4)))]
15909
  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15910
  "stos{l|d}"
15911
  [(set_attr "type" "str")
15912
   (set_attr "memory" "store")
15913
   (set_attr "mode" "SI")])
15914
 
15915
(define_insn "*strsethi_1"
15916
  [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15917
        (match_operand:HI 2 "register_operand" "a"))
15918
   (set (match_operand:P 0 "register_operand" "=D")
15919
        (plus:P (match_dup 1)
15920
                (const_int 2)))]
15921
  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15922
  "stosw"
15923
  [(set_attr "type" "str")
15924
   (set_attr "memory" "store")
15925
   (set_attr "mode" "HI")])
15926
 
15927
(define_insn "*strsetqi_1"
15928
  [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15929
        (match_operand:QI 2 "register_operand" "a"))
15930
   (set (match_operand:P 0 "register_operand" "=D")
15931
        (plus:P (match_dup 1)
15932
                (const_int 1)))]
15933
  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15934
  "stosb"
15935
  [(set_attr "type" "str")
15936
   (set_attr "memory" "store")
15937
   (set (attr "prefix_rex")
15938
        (if_then_else
15939
          (match_test "mode == DImode")
15940
          (const_string "0")
15941
          (const_string "*")))
15942
   (set_attr "mode" "QI")])
15943
 
15944
(define_expand "rep_stos"
15945
  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15946
              (set (match_operand 0 "register_operand" "")
15947
                   (match_operand 4 "" ""))
15948
              (set (match_operand 2 "memory_operand" "") (const_int 0))
15949
              (use (match_operand 3 "register_operand" ""))
15950
              (use (match_dup 1))])]
15951
  ""
15952
  "ix86_current_function_needs_cld = 1;")
15953
 
15954
(define_insn "*rep_stosdi_rex64"
15955
  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15956
   (set (match_operand:DI 0 "register_operand" "=D")
15957
        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15958
                            (const_int 3))
15959
                 (match_operand:DI 3 "register_operand" "0")))
15960
   (set (mem:BLK (match_dup 3))
15961
        (const_int 0))
15962
   (use (match_operand:DI 2 "register_operand" "a"))
15963
   (use (match_dup 4))]
15964
  "TARGET_64BIT
15965
   && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15966
  "rep{%;} stosq"
15967
  [(set_attr "type" "str")
15968
   (set_attr "prefix_rep" "1")
15969
   (set_attr "memory" "store")
15970
   (set_attr "mode" "DI")])
15971
 
15972
(define_insn "*rep_stossi"
15973
  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15974
   (set (match_operand:P 0 "register_operand" "=D")
15975
        (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15976
                          (const_int 2))
15977
                 (match_operand:P 3 "register_operand" "0")))
15978
   (set (mem:BLK (match_dup 3))
15979
        (const_int 0))
15980
   (use (match_operand:SI 2 "register_operand" "a"))
15981
   (use (match_dup 4))]
15982
  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15983
  "rep{%;} stos{l|d}"
15984
  [(set_attr "type" "str")
15985
   (set_attr "prefix_rep" "1")
15986
   (set_attr "memory" "store")
15987
   (set_attr "mode" "SI")])
15988
 
15989
(define_insn "*rep_stosqi"
15990
  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15991
   (set (match_operand:P 0 "register_operand" "=D")
15992
        (plus:P (match_operand:P 3 "register_operand" "0")
15993
                (match_operand:P 4 "register_operand" "1")))
15994
   (set (mem:BLK (match_dup 3))
15995
        (const_int 0))
15996
   (use (match_operand:QI 2 "register_operand" "a"))
15997
   (use (match_dup 4))]
15998
  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15999
  "rep{%;} stosb"
16000
  [(set_attr "type" "str")
16001
   (set_attr "prefix_rep" "1")
16002
   (set_attr "memory" "store")
16003
   (set (attr "prefix_rex")
16004
        (if_then_else
16005
          (match_test "mode == DImode")
16006
          (const_string "0")
16007
          (const_string "*")))
16008
   (set_attr "mode" "QI")])
16009
 
16010
(define_expand "cmpstrnsi"
16011
  [(set (match_operand:SI 0 "register_operand" "")
16012
        (compare:SI (match_operand:BLK 1 "general_operand" "")
16013
                    (match_operand:BLK 2 "general_operand" "")))
16014
   (use (match_operand 3 "general_operand" ""))
16015
   (use (match_operand 4 "immediate_operand" ""))]
16016
  ""
16017
{
16018
  rtx addr1, addr2, out, outlow, count, countreg, align;
16019
 
16020
  if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16021
    FAIL;
16022
 
16023
  /* Can't use this if the user has appropriated ecx, esi or edi.  */
16024
  if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16025
    FAIL;
16026
 
16027
  out = operands[0];
16028
  if (!REG_P (out))
16029
    out = gen_reg_rtx (SImode);
16030
 
16031
  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16032
  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16033
  if (addr1 != XEXP (operands[1], 0))
16034
    operands[1] = replace_equiv_address_nv (operands[1], addr1);
16035
  if (addr2 != XEXP (operands[2], 0))
16036
    operands[2] = replace_equiv_address_nv (operands[2], addr2);
16037
 
16038
  count = operands[3];
16039
  countreg = ix86_zero_extend_to_Pmode (count);
16040
 
16041
  /* %%% Iff we are testing strict equality, we can use known alignment
16042
     to good advantage.  This may be possible with combine, particularly
16043
     once cc0 is dead.  */
16044
  align = operands[4];
16045
 
16046
  if (CONST_INT_P (count))
16047
    {
16048
      if (INTVAL (count) == 0)
16049
        {
16050
          emit_move_insn (operands[0], const0_rtx);
16051
          DONE;
16052
        }
16053
      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16054
                                     operands[1], operands[2]));
16055
    }
16056
  else
16057
    {
16058
      rtx (*gen_cmp) (rtx, rtx);
16059
 
16060
      gen_cmp = (TARGET_64BIT
16061
                 ? gen_cmpdi_1 : gen_cmpsi_1);
16062
 
16063
      emit_insn (gen_cmp (countreg, countreg));
16064
      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16065
                                  operands[1], operands[2]));
16066
    }
16067
 
16068
  outlow = gen_lowpart (QImode, out);
16069
  emit_insn (gen_cmpintqi (outlow));
16070
  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16071
 
16072
  if (operands[0] != out)
16073
    emit_move_insn (operands[0], out);
16074
 
16075
  DONE;
16076
})
16077
 
16078
;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16079
 
16080
(define_expand "cmpintqi"
16081
  [(set (match_dup 1)
16082
        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16083
   (set (match_dup 2)
16084
        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16085
   (parallel [(set (match_operand:QI 0 "register_operand" "")
16086
                   (minus:QI (match_dup 1)
16087
                             (match_dup 2)))
16088
              (clobber (reg:CC FLAGS_REG))])]
16089
  ""
16090
{
16091
  operands[1] = gen_reg_rtx (QImode);
16092
  operands[2] = gen_reg_rtx (QImode);
16093
})
16094
 
16095
;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16096
;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16097
 
16098
(define_expand "cmpstrnqi_nz_1"
16099
  [(parallel [(set (reg:CC FLAGS_REG)
16100
                   (compare:CC (match_operand 4 "memory_operand" "")
16101
                               (match_operand 5 "memory_operand" "")))
16102
              (use (match_operand 2 "register_operand" ""))
16103
              (use (match_operand:SI 3 "immediate_operand" ""))
16104
              (clobber (match_operand 0 "register_operand" ""))
16105
              (clobber (match_operand 1 "register_operand" ""))
16106
              (clobber (match_dup 2))])]
16107
  ""
16108
  "ix86_current_function_needs_cld = 1;")
16109
 
16110
(define_insn "*cmpstrnqi_nz_1"
16111
  [(set (reg:CC FLAGS_REG)
16112
        (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16113
                    (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16114
   (use (match_operand:P 6 "register_operand" "2"))
16115
   (use (match_operand:SI 3 "immediate_operand" "i"))
16116
   (clobber (match_operand:P 0 "register_operand" "=S"))
16117
   (clobber (match_operand:P 1 "register_operand" "=D"))
16118
   (clobber (match_operand:P 2 "register_operand" "=c"))]
16119
  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16120
  "repz{%;} cmpsb"
16121
  [(set_attr "type" "str")
16122
   (set_attr "mode" "QI")
16123
   (set (attr "prefix_rex")
16124
        (if_then_else
16125
          (match_test "mode == DImode")
16126
          (const_string "0")
16127
          (const_string "*")))
16128
   (set_attr "prefix_rep" "1")])
16129
 
16130
;; The same, but the count is not known to not be zero.
16131
 
16132
(define_expand "cmpstrnqi_1"
16133
  [(parallel [(set (reg:CC FLAGS_REG)
16134
                (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16135
                                     (const_int 0))
16136
                  (compare:CC (match_operand 4 "memory_operand" "")
16137
                              (match_operand 5 "memory_operand" ""))
16138
                  (const_int 0)))
16139
              (use (match_operand:SI 3 "immediate_operand" ""))
16140
              (use (reg:CC FLAGS_REG))
16141
              (clobber (match_operand 0 "register_operand" ""))
16142
              (clobber (match_operand 1 "register_operand" ""))
16143
              (clobber (match_dup 2))])]
16144
  ""
16145
  "ix86_current_function_needs_cld = 1;")
16146
 
16147
(define_insn "*cmpstrnqi_1"
16148
  [(set (reg:CC FLAGS_REG)
16149
        (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16150
                             (const_int 0))
16151
          (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16152
                      (mem:BLK (match_operand:P 5 "register_operand" "1")))
16153
          (const_int 0)))
16154
   (use (match_operand:SI 3 "immediate_operand" "i"))
16155
   (use (reg:CC FLAGS_REG))
16156
   (clobber (match_operand:P 0 "register_operand" "=S"))
16157
   (clobber (match_operand:P 1 "register_operand" "=D"))
16158
   (clobber (match_operand:P 2 "register_operand" "=c"))]
16159
  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16160
  "repz{%;} cmpsb"
16161
  [(set_attr "type" "str")
16162
   (set_attr "mode" "QI")
16163
   (set (attr "prefix_rex")
16164
        (if_then_else
16165
          (match_test "mode == DImode")
16166
          (const_string "0")
16167
          (const_string "*")))
16168
   (set_attr "prefix_rep" "1")])
16169
 
16170
(define_expand "strlen"
16171
  [(set (match_operand:P 0 "register_operand" "")
16172
        (unspec:P [(match_operand:BLK 1 "general_operand" "")
16173
                   (match_operand:QI 2 "immediate_operand" "")
16174
                   (match_operand 3 "immediate_operand" "")]
16175
                  UNSPEC_SCAS))]
16176
  ""
16177
{
16178
 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16179
   DONE;
16180
 else
16181
   FAIL;
16182
})
16183
 
16184
(define_expand "strlenqi_1"
16185
  [(parallel [(set (match_operand 0 "register_operand" "")
16186
                   (match_operand 2 "" ""))
16187
              (clobber (match_operand 1 "register_operand" ""))
16188
              (clobber (reg:CC FLAGS_REG))])]
16189
  ""
16190
  "ix86_current_function_needs_cld = 1;")
16191
 
16192
(define_insn "*strlenqi_1"
16193
  [(set (match_operand:P 0 "register_operand" "=&c")
16194
        (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16195
                   (match_operand:QI 2 "register_operand" "a")
16196
                   (match_operand:P 3 "immediate_operand" "i")
16197
                   (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16198
   (clobber (match_operand:P 1 "register_operand" "=D"))
16199
   (clobber (reg:CC FLAGS_REG))]
16200
  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16201
  "repnz{%;} scasb"
16202
  [(set_attr "type" "str")
16203
   (set_attr "mode" "QI")
16204
   (set (attr "prefix_rex")
16205
        (if_then_else
16206
          (match_test "mode == DImode")
16207
          (const_string "0")
16208
          (const_string "*")))
16209
   (set_attr "prefix_rep" "1")])
16210
 
16211
;; Peephole optimizations to clean up after cmpstrn*.  This should be
16212
;; handled in combine, but it is not currently up to the task.
16213
;; When used for their truth value, the cmpstrn* expanders generate
16214
;; code like this:
16215
;;
16216
;;   repz cmpsb
16217
;;   seta       %al
16218
;;   setb       %dl
16219
;;   cmpb       %al, %dl
16220
;;   jcc        label
16221
;;
16222
;; The intermediate three instructions are unnecessary.
16223
 
16224
;; This one handles cmpstrn*_nz_1...
16225
(define_peephole2
16226
  [(parallel[
16227
     (set (reg:CC FLAGS_REG)
16228
          (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16229
                      (mem:BLK (match_operand 5 "register_operand" ""))))
16230
     (use (match_operand 6 "register_operand" ""))
16231
     (use (match_operand:SI 3 "immediate_operand" ""))
16232
     (clobber (match_operand 0 "register_operand" ""))
16233
     (clobber (match_operand 1 "register_operand" ""))
16234
     (clobber (match_operand 2 "register_operand" ""))])
16235
   (set (match_operand:QI 7 "register_operand" "")
16236
        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16237
   (set (match_operand:QI 8 "register_operand" "")
16238
        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16239
   (set (reg FLAGS_REG)
16240
        (compare (match_dup 7) (match_dup 8)))
16241
  ]
16242
  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16243
  [(parallel[
16244
     (set (reg:CC FLAGS_REG)
16245
          (compare:CC (mem:BLK (match_dup 4))
16246
                      (mem:BLK (match_dup 5))))
16247
     (use (match_dup 6))
16248
     (use (match_dup 3))
16249
     (clobber (match_dup 0))
16250
     (clobber (match_dup 1))
16251
     (clobber (match_dup 2))])])
16252
 
16253
;; ...and this one handles cmpstrn*_1.
16254
(define_peephole2
16255
  [(parallel[
16256
     (set (reg:CC FLAGS_REG)
16257
          (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16258
                               (const_int 0))
16259
            (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16260
                        (mem:BLK (match_operand 5 "register_operand" "")))
16261
            (const_int 0)))
16262
     (use (match_operand:SI 3 "immediate_operand" ""))
16263
     (use (reg:CC FLAGS_REG))
16264
     (clobber (match_operand 0 "register_operand" ""))
16265
     (clobber (match_operand 1 "register_operand" ""))
16266
     (clobber (match_operand 2 "register_operand" ""))])
16267
   (set (match_operand:QI 7 "register_operand" "")
16268
        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16269
   (set (match_operand:QI 8 "register_operand" "")
16270
        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16271
   (set (reg FLAGS_REG)
16272
        (compare (match_dup 7) (match_dup 8)))
16273
  ]
16274
  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16275
  [(parallel[
16276
     (set (reg:CC FLAGS_REG)
16277
          (if_then_else:CC (ne (match_dup 6)
16278
                               (const_int 0))
16279
            (compare:CC (mem:BLK (match_dup 4))
16280
                        (mem:BLK (match_dup 5)))
16281
            (const_int 0)))
16282
     (use (match_dup 3))
16283
     (use (reg:CC FLAGS_REG))
16284
     (clobber (match_dup 0))
16285
     (clobber (match_dup 1))
16286
     (clobber (match_dup 2))])])
16287
 
16288
;; Conditional move instructions.
16289
 
16290
(define_expand "movcc"
16291
  [(set (match_operand:SWIM 0 "register_operand" "")
16292
        (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16293
                           (match_operand:SWIM 2 "" "")
16294
                           (match_operand:SWIM 3 "" "")))]
16295
  ""
16296
  "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16297
 
16298
;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16299
;; the register first winds up with `sbbl $0,reg', which is also weird.
16300
;; So just document what we're doing explicitly.
16301
 
16302
(define_expand "x86_movcc_0_m1"
16303
  [(parallel
16304
    [(set (match_operand:SWI48 0 "register_operand" "")
16305
          (if_then_else:SWI48
16306
            (match_operator:SWI48 2 "ix86_carry_flag_operator"
16307
             [(match_operand 1 "flags_reg_operand" "")
16308
              (const_int 0)])
16309
            (const_int -1)
16310
            (const_int 0)))
16311
     (clobber (reg:CC FLAGS_REG))])])
16312
 
16313
(define_insn "*x86_movcc_0_m1"
16314
  [(set (match_operand:SWI48 0 "register_operand" "=r")
16315
        (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16316
                             [(reg FLAGS_REG) (const_int 0)])
16317
          (const_int -1)
16318
          (const_int 0)))
16319
   (clobber (reg:CC FLAGS_REG))]
16320
  ""
16321
  "sbb{}\t%0, %0"
16322
  ; Since we don't have the proper number of operands for an alu insn,
16323
  ; fill in all the blanks.
16324
  [(set_attr "type" "alu")
16325
   (set_attr "use_carry" "1")
16326
   (set_attr "pent_pair" "pu")
16327
   (set_attr "memory" "none")
16328
   (set_attr "imm_disp" "false")
16329
   (set_attr "mode" "")
16330
   (set_attr "length_immediate" "0")])
16331
 
16332
(define_insn "*x86_movcc_0_m1_se"
16333
  [(set (match_operand:SWI48 0 "register_operand" "=r")
16334
        (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16335
                             [(reg FLAGS_REG) (const_int 0)])
16336
                            (const_int 1)
16337
                            (const_int 0)))
16338
   (clobber (reg:CC FLAGS_REG))]
16339
  ""
16340
  "sbb{}\t%0, %0"
16341
  [(set_attr "type" "alu")
16342
   (set_attr "use_carry" "1")
16343
   (set_attr "pent_pair" "pu")
16344
   (set_attr "memory" "none")
16345
   (set_attr "imm_disp" "false")
16346
   (set_attr "mode" "")
16347
   (set_attr "length_immediate" "0")])
16348
 
16349
(define_insn "*x86_movcc_0_m1_neg"
16350
  [(set (match_operand:SWI48 0 "register_operand" "=r")
16351
        (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16352
                    [(reg FLAGS_REG) (const_int 0)])))]
16353
  ""
16354
  "sbb{}\t%0, %0"
16355
  [(set_attr "type" "alu")
16356
   (set_attr "use_carry" "1")
16357
   (set_attr "pent_pair" "pu")
16358
   (set_attr "memory" "none")
16359
   (set_attr "imm_disp" "false")
16360
   (set_attr "mode" "")
16361
   (set_attr "length_immediate" "0")])
16362
 
16363
(define_insn "*movcc_noc"
16364
  [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16365
        (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16366
                               [(reg FLAGS_REG) (const_int 0)])
16367
          (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16368
          (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16369
  "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16370
  "@
16371
   cmov%O2%C1\t{%2, %0|%0, %2}
16372
   cmov%O2%c1\t{%3, %0|%0, %3}"
16373
  [(set_attr "type" "icmov")
16374
   (set_attr "mode" "")])
16375
 
16376
(define_insn_and_split "*movqicc_noc"
16377
  [(set (match_operand:QI 0 "register_operand" "=r,r")
16378
        (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16379
                           [(match_operand 4 "flags_reg_operand" "")
16380
                            (const_int 0)])
16381
                      (match_operand:QI 2 "register_operand" "r,0")
16382
                      (match_operand:QI 3 "register_operand" "0,r")))]
16383
  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16384
  "#"
16385
  "&& reload_completed"
16386
  [(set (match_dup 0)
16387
        (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16388
                      (match_dup 2)
16389
                      (match_dup 3)))]
16390
  "operands[0] = gen_lowpart (SImode, operands[0]);
16391
   operands[2] = gen_lowpart (SImode, operands[2]);
16392
   operands[3] = gen_lowpart (SImode, operands[3]);"
16393
  [(set_attr "type" "icmov")
16394
   (set_attr "mode" "SI")])
16395
 
16396
(define_expand "movcc"
16397
  [(set (match_operand:X87MODEF 0 "register_operand" "")
16398
        (if_then_else:X87MODEF
16399
          (match_operand 1 "ix86_fp_comparison_operator" "")
16400
          (match_operand:X87MODEF 2 "register_operand" "")
16401
          (match_operand:X87MODEF 3 "register_operand" "")))]
16402
  "(TARGET_80387 && TARGET_CMOVE)
16403
   || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)"
16404
  "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16405
 
16406
(define_insn "*movxfcc_1"
16407
  [(set (match_operand:XF 0 "register_operand" "=f,f")
16408
        (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16409
                                [(reg FLAGS_REG) (const_int 0)])
16410
                      (match_operand:XF 2 "register_operand" "f,0")
16411
                      (match_operand:XF 3 "register_operand" "0,f")))]
16412
  "TARGET_80387 && TARGET_CMOVE"
16413
  "@
16414
   fcmov%F1\t{%2, %0|%0, %2}
16415
   fcmov%f1\t{%3, %0|%0, %3}"
16416
  [(set_attr "type" "fcmov")
16417
   (set_attr "mode" "XF")])
16418
 
16419
(define_insn "*movdfcc_1_rex64"
16420
  [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16421
        (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16422
                                [(reg FLAGS_REG) (const_int 0)])
16423
                      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16424
                      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16425
  "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16426
   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16427
  "@
16428
   fcmov%F1\t{%2, %0|%0, %2}
16429
   fcmov%f1\t{%3, %0|%0, %3}
16430
   cmov%O2%C1\t{%2, %0|%0, %2}
16431
   cmov%O2%c1\t{%3, %0|%0, %3}"
16432
  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16433
   (set_attr "mode" "DF,DF,DI,DI")])
16434
 
16435
(define_insn "*movdfcc_1"
16436
  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16437
        (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16438
                                [(reg FLAGS_REG) (const_int 0)])
16439
                      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16440
                      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16441
  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16442
   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16443
  "@
16444
   fcmov%F1\t{%2, %0|%0, %2}
16445
   fcmov%f1\t{%3, %0|%0, %3}
16446
   #
16447
   #"
16448
  [(set_attr "type" "fcmov,fcmov,multi,multi")
16449
   (set_attr "mode" "DF,DF,DI,DI")])
16450
 
16451
(define_split
16452
  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16453
        (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16454
                                [(match_operand 4 "flags_reg_operand" "")
16455
                                 (const_int 0)])
16456
                      (match_operand:DF 2 "nonimmediate_operand" "")
16457
                      (match_operand:DF 3 "nonimmediate_operand" "")))]
16458
  "!TARGET_64BIT && reload_completed"
16459
  [(set (match_dup 2)
16460
        (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16461
                      (match_dup 5)
16462
                      (match_dup 6)))
16463
   (set (match_dup 3)
16464
        (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16465
                      (match_dup 7)
16466
                      (match_dup 8)))]
16467
{
16468
  split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16469
  split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16470
})
16471
 
16472
(define_insn "*movsfcc_1_387"
16473
  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16474
        (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16475
                                [(reg FLAGS_REG) (const_int 0)])
16476
                      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16477
                      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16478
  "TARGET_80387 && TARGET_CMOVE
16479
   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16480
  "@
16481
   fcmov%F1\t{%2, %0|%0, %2}
16482
   fcmov%f1\t{%3, %0|%0, %3}
16483
   cmov%O2%C1\t{%2, %0|%0, %2}
16484
   cmov%O2%c1\t{%3, %0|%0, %3}"
16485
  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16486
   (set_attr "mode" "SF,SF,SI,SI")])
16487
 
16488
;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16489
;; the scalar versions to have only XMM registers as operands.
16490
 
16491
;; XOP conditional move
16492
(define_insn "*xop_pcmov_"
16493
  [(set (match_operand:MODEF 0 "register_operand" "=x")
16494
        (if_then_else:MODEF
16495
          (match_operand:MODEF 1 "register_operand" "x")
16496
          (match_operand:MODEF 2 "register_operand" "x")
16497
          (match_operand:MODEF 3 "register_operand" "x")))]
16498
  "TARGET_XOP"
16499
  "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16500
  [(set_attr "type" "sse4arg")])
16501
 
16502
;; These versions of the min/max patterns are intentionally ignorant of
16503
;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16504
;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16505
;; are undefined in this condition, we're certain this is correct.
16506
 
16507
(define_insn "3"
16508
  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16509
        (smaxmin:MODEF
16510
          (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16511
          (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16512
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
16513
  "@
16514
   \t{%2, %0|%0, %2}
16515
   v\t{%2, %1, %0|%0, %1, %2}"
16516
  [(set_attr "isa" "noavx,avx")
16517
   (set_attr "prefix" "orig,vex")
16518
   (set_attr "type" "sseadd")
16519
   (set_attr "mode" "")])
16520
 
16521
;; These versions of the min/max patterns implement exactly the operations
16522
;;   min = (op1 < op2 ? op1 : op2)
16523
;;   max = (!(op1 < op2) ? op1 : op2)
16524
;; Their operands are not commutative, and thus they may be used in the
16525
;; presence of -0.0 and NaN.
16526
 
16527
(define_insn "*ieee_smin3"
16528
  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16529
        (unspec:MODEF
16530
          [(match_operand:MODEF 1 "register_operand" "0,x")
16531
           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16532
         UNSPEC_IEEE_MIN))]
16533
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
16534
  "@
16535
   min\t{%2, %0|%0, %2}
16536
   vmin\t{%2, %1, %0|%0, %1, %2}"
16537
  [(set_attr "isa" "noavx,avx")
16538
   (set_attr "prefix" "orig,vex")
16539
   (set_attr "type" "sseadd")
16540
   (set_attr "mode" "")])
16541
 
16542
(define_insn "*ieee_smax3"
16543
  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16544
        (unspec:MODEF
16545
          [(match_operand:MODEF 1 "register_operand" "0,x")
16546
           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16547
         UNSPEC_IEEE_MAX))]
16548
  "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH"
16549
  "@
16550
   max\t{%2, %0|%0, %2}
16551
   vmax\t{%2, %1, %0|%0, %1, %2}"
16552
  [(set_attr "isa" "noavx,avx")
16553
   (set_attr "prefix" "orig,vex")
16554
   (set_attr "type" "sseadd")
16555
   (set_attr "mode" "")])
16556
 
16557
;; Make two stack loads independent:
16558
;;   fld aa              fld aa
16559
;;   fld %st(0)     ->   fld bb
16560
;;   fmul bb             fmul %st(1), %st
16561
;;
16562
;; Actually we only match the last two instructions for simplicity.
16563
(define_peephole2
16564
  [(set (match_operand 0 "fp_register_operand" "")
16565
        (match_operand 1 "fp_register_operand" ""))
16566
   (set (match_dup 0)
16567
        (match_operator 2 "binary_fp_operator"
16568
           [(match_dup 0)
16569
            (match_operand 3 "memory_operand" "")]))]
16570
  "REGNO (operands[0]) != REGNO (operands[1])"
16571
  [(set (match_dup 0) (match_dup 3))
16572
   (set (match_dup 0) (match_dup 4))]
16573
 
16574
  ;; The % modifier is not operational anymore in peephole2's, so we have to
16575
  ;; swap the operands manually in the case of addition and multiplication.
16576
{
16577
  rtx op0, op1;
16578
 
16579
  if (COMMUTATIVE_ARITH_P (operands[2]))
16580
    op0 = operands[0], op1 = operands[1];
16581
  else
16582
    op0 = operands[1], op1 = operands[0];
16583
 
16584
  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16585
                                GET_MODE (operands[2]),
16586
                                op0, op1);
16587
})
16588
 
16589
;; Conditional addition patterns
16590
(define_expand "addcc"
16591
  [(match_operand:SWI 0 "register_operand" "")
16592
   (match_operand 1 "ordered_comparison_operator" "")
16593
   (match_operand:SWI 2 "register_operand" "")
16594
   (match_operand:SWI 3 "const_int_operand" "")]
16595
  ""
16596
  "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16597
 
16598
;; Misc patterns (?)
16599
 
16600
;; This pattern exists to put a dependency on all ebp-based memory accesses.
16601
;; Otherwise there will be nothing to keep
16602
;;
16603
;; [(set (reg ebp) (reg esp))]
16604
;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16605
;;  (clobber (eflags)]
16606
;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16607
;;
16608
;; in proper program order.
16609
 
16610
(define_insn "pro_epilogue_adjust_stack__add"
16611
  [(set (match_operand:P 0 "register_operand" "=r,r")
16612
        (plus:P (match_operand:P 1 "register_operand" "0,r")
16613
                (match_operand:P 2 "" "r,l")))
16614
   (clobber (reg:CC FLAGS_REG))
16615
   (clobber (mem:BLK (scratch)))]
16616
  ""
16617
{
16618
  switch (get_attr_type (insn))
16619
    {
16620
    case TYPE_IMOV:
16621
      return "mov{}\t{%1, %0|%0, %1}";
16622
 
16623
    case TYPE_ALU:
16624
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
16625
      if (x86_maybe_negate_const_int (&operands[2], mode))
16626
        return "sub{}\t{%2, %0|%0, %2}";
16627
 
16628
      return "add{}\t{%2, %0|%0, %2}";
16629
 
16630
    default:
16631
      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16632
      return "lea{}\t{%a2, %0|%0, %a2}";
16633
    }
16634
}
16635
  [(set (attr "type")
16636
        (cond [(and (eq_attr "alternative" "0")
16637
                    (not (match_test "TARGET_OPT_AGU")))
16638
                 (const_string "alu")
16639
               (match_operand: 2 "const0_operand" "")
16640
                 (const_string "imov")
16641
              ]
16642
              (const_string "lea")))
16643
   (set (attr "length_immediate")
16644
        (cond [(eq_attr "type" "imov")
16645
                 (const_string "0")
16646
               (and (eq_attr "type" "alu")
16647
                    (match_operand 2 "const128_operand" ""))
16648
                 (const_string "1")
16649
              ]
16650
              (const_string "*")))
16651
   (set_attr "mode" "")])
16652
 
16653
(define_insn "pro_epilogue_adjust_stack__sub"
16654
  [(set (match_operand:P 0 "register_operand" "=r")
16655
        (minus:P (match_operand:P 1 "register_operand" "0")
16656
                 (match_operand:P 2 "register_operand" "r")))
16657
   (clobber (reg:CC FLAGS_REG))
16658
   (clobber (mem:BLK (scratch)))]
16659
  ""
16660
  "sub{}\t{%2, %0|%0, %2}"
16661
  [(set_attr "type" "alu")
16662
   (set_attr "mode" "")])
16663
 
16664
(define_insn "allocate_stack_worker_probe_"
16665
  [(set (match_operand:P 0 "register_operand" "=a")
16666
        (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16667
                            UNSPECV_STACK_PROBE))
16668
   (clobber (reg:CC FLAGS_REG))]
16669
  "ix86_target_stack_probe ()"
16670
  "call\t___chkstk_ms"
16671
  [(set_attr "type" "multi")
16672
   (set_attr "length" "5")])
16673
 
16674
(define_expand "allocate_stack"
16675
  [(match_operand 0 "register_operand" "")
16676
   (match_operand 1 "general_operand" "")]
16677
  "ix86_target_stack_probe ()"
16678
{
16679
  rtx x;
16680
 
16681
#ifndef CHECK_STACK_LIMIT
16682
#define CHECK_STACK_LIMIT 0
16683
#endif
16684
 
16685
  if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16686
      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16687
    {
16688
      x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16689
                               stack_pointer_rtx, 0, OPTAB_DIRECT);
16690
      if (x != stack_pointer_rtx)
16691
        emit_move_insn (stack_pointer_rtx, x);
16692
    }
16693
  else
16694
    {
16695
      x = copy_to_mode_reg (Pmode, operands[1]);
16696
      if (TARGET_64BIT)
16697
        emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16698
      else
16699
        emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16700
      x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16701
                               stack_pointer_rtx, 0, OPTAB_DIRECT);
16702
      if (x != stack_pointer_rtx)
16703
        emit_move_insn (stack_pointer_rtx, x);
16704
    }
16705
 
16706
  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16707
  DONE;
16708
})
16709
 
16710
;; Use IOR for stack probes, this is shorter.
16711
(define_expand "probe_stack"
16712
  [(match_operand 0 "memory_operand" "")]
16713
  ""
16714
{
16715
  rtx (*gen_ior3) (rtx, rtx, rtx);
16716
 
16717
  gen_ior3 = (GET_MODE (operands[0]) == DImode
16718
              ? gen_iordi3 : gen_iorsi3);
16719
 
16720
  emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16721
  DONE;
16722
})
16723
 
16724
(define_insn "adjust_stack_and_probe"
16725
  [(set (match_operand:P 0 "register_operand" "=r")
16726
        (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16727
                            UNSPECV_PROBE_STACK_RANGE))
16728
   (set (reg:P SP_REG)
16729
        (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16730
   (clobber (reg:CC FLAGS_REG))
16731
   (clobber (mem:BLK (scratch)))]
16732
  ""
16733
  "* return output_adjust_stack_and_probe (operands[0]);"
16734
  [(set_attr "type" "multi")])
16735
 
16736
(define_insn "probe_stack_range"
16737
  [(set (match_operand:P 0 "register_operand" "=r")
16738
        (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16739
                            (match_operand:P 2 "const_int_operand" "n")]
16740
                            UNSPECV_PROBE_STACK_RANGE))
16741
   (clobber (reg:CC FLAGS_REG))]
16742
  ""
16743
  "* return output_probe_stack_range (operands[0], operands[2]);"
16744
  [(set_attr "type" "multi")])
16745
 
16746
(define_expand "builtin_setjmp_receiver"
16747
  [(label_ref (match_operand 0 "" ""))]
16748
  "!TARGET_64BIT && flag_pic"
16749
{
16750
#if TARGET_MACHO
16751
  if (TARGET_MACHO)
16752
    {
16753
      rtx xops[3];
16754
      rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16755
      rtx label_rtx = gen_label_rtx ();
16756
      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16757
      xops[0] = xops[1] = picreg;
16758
      xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16759
      ix86_expand_binary_operator (MINUS, SImode, xops);
16760
    }
16761
  else
16762
#endif
16763
    emit_insn (gen_set_got (pic_offset_table_rtx));
16764
  DONE;
16765
})
16766
 
16767
;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16768
 
16769
(define_split
16770
  [(set (match_operand 0 "register_operand" "")
16771
        (match_operator 3 "promotable_binary_operator"
16772
           [(match_operand 1 "register_operand" "")
16773
            (match_operand 2 "aligned_operand" "")]))
16774
   (clobber (reg:CC FLAGS_REG))]
16775
  "! TARGET_PARTIAL_REG_STALL && reload_completed
16776
   && ((GET_MODE (operands[0]) == HImode
16777
        && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16778
            /* ??? next two lines just !satisfies_constraint_K (...) */
16779
            || !CONST_INT_P (operands[2])
16780
            || satisfies_constraint_K (operands[2])))
16781
       || (GET_MODE (operands[0]) == QImode
16782
           && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16783
  [(parallel [(set (match_dup 0)
16784
                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16785
              (clobber (reg:CC FLAGS_REG))])]
16786
{
16787
  operands[0] = gen_lowpart (SImode, operands[0]);
16788
  operands[1] = gen_lowpart (SImode, operands[1]);
16789
  if (GET_CODE (operands[3]) != ASHIFT)
16790
    operands[2] = gen_lowpart (SImode, operands[2]);
16791
  PUT_MODE (operands[3], SImode);
16792
})
16793
 
16794
; Promote the QImode tests, as i386 has encoding of the AND
16795
; instruction with 32-bit sign-extended immediate and thus the
16796
; instruction size is unchanged, except in the %eax case for
16797
; which it is increased by one byte, hence the ! optimize_size.
16798
(define_split
16799
  [(set (match_operand 0 "flags_reg_operand" "")
16800
        (match_operator 2 "compare_operator"
16801
          [(and (match_operand 3 "aligned_operand" "")
16802
                (match_operand 4 "const_int_operand" ""))
16803
           (const_int 0)]))
16804
   (set (match_operand 1 "register_operand" "")
16805
        (and (match_dup 3) (match_dup 4)))]
16806
  "! TARGET_PARTIAL_REG_STALL && reload_completed
16807
   && optimize_insn_for_speed_p ()
16808
   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16809
       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16810
   /* Ensure that the operand will remain sign-extended immediate.  */
16811
   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16812
  [(parallel [(set (match_dup 0)
16813
                   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16814
                                    (const_int 0)]))
16815
              (set (match_dup 1)
16816
                   (and:SI (match_dup 3) (match_dup 4)))])]
16817
{
16818
  operands[4]
16819
    = gen_int_mode (INTVAL (operands[4])
16820
                    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16821
  operands[1] = gen_lowpart (SImode, operands[1]);
16822
  operands[3] = gen_lowpart (SImode, operands[3]);
16823
})
16824
 
16825
; Don't promote the QImode tests, as i386 doesn't have encoding of
16826
; the TEST instruction with 32-bit sign-extended immediate and thus
16827
; the instruction size would at least double, which is not what we
16828
; want even with ! optimize_size.
16829
(define_split
16830
  [(set (match_operand 0 "flags_reg_operand" "")
16831
        (match_operator 1 "compare_operator"
16832
          [(and (match_operand:HI 2 "aligned_operand" "")
16833
                (match_operand:HI 3 "const_int_operand" ""))
16834
           (const_int 0)]))]
16835
  "! TARGET_PARTIAL_REG_STALL && reload_completed
16836
   && ! TARGET_FAST_PREFIX
16837
   && optimize_insn_for_speed_p ()
16838
   /* Ensure that the operand will remain sign-extended immediate.  */
16839
   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16840
  [(set (match_dup 0)
16841
        (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16842
                         (const_int 0)]))]
16843
{
16844
  operands[3]
16845
    = gen_int_mode (INTVAL (operands[3])
16846
                    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16847
  operands[2] = gen_lowpart (SImode, operands[2]);
16848
})
16849
 
16850
(define_split
16851
  [(set (match_operand 0 "register_operand" "")
16852
        (neg (match_operand 1 "register_operand" "")))
16853
   (clobber (reg:CC FLAGS_REG))]
16854
  "! TARGET_PARTIAL_REG_STALL && reload_completed
16855
   && (GET_MODE (operands[0]) == HImode
16856
       || (GET_MODE (operands[0]) == QImode
16857
           && (TARGET_PROMOTE_QImode
16858
               || optimize_insn_for_size_p ())))"
16859
  [(parallel [(set (match_dup 0)
16860
                   (neg:SI (match_dup 1)))
16861
              (clobber (reg:CC FLAGS_REG))])]
16862
{
16863
  operands[0] = gen_lowpart (SImode, operands[0]);
16864
  operands[1] = gen_lowpart (SImode, operands[1]);
16865
})
16866
 
16867
(define_split
16868
  [(set (match_operand 0 "register_operand" "")
16869
        (not (match_operand 1 "register_operand" "")))]
16870
  "! TARGET_PARTIAL_REG_STALL && reload_completed
16871
   && (GET_MODE (operands[0]) == HImode
16872
       || (GET_MODE (operands[0]) == QImode
16873
           && (TARGET_PROMOTE_QImode
16874
               || optimize_insn_for_size_p ())))"
16875
  [(set (match_dup 0)
16876
        (not:SI (match_dup 1)))]
16877
{
16878
  operands[0] = gen_lowpart (SImode, operands[0]);
16879
  operands[1] = gen_lowpart (SImode, operands[1]);
16880
})
16881
 
16882
(define_split
16883
  [(set (match_operand 0 "register_operand" "")
16884
        (if_then_else (match_operator 1 "ordered_comparison_operator"
16885
                                [(reg FLAGS_REG) (const_int 0)])
16886
                      (match_operand 2 "register_operand" "")
16887
                      (match_operand 3 "register_operand" "")))]
16888
  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16889
   && (GET_MODE (operands[0]) == HImode
16890
       || (GET_MODE (operands[0]) == QImode
16891
           && (TARGET_PROMOTE_QImode
16892
               || optimize_insn_for_size_p ())))"
16893
  [(set (match_dup 0)
16894
        (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16895
{
16896
  operands[0] = gen_lowpart (SImode, operands[0]);
16897
  operands[2] = gen_lowpart (SImode, operands[2]);
16898
  operands[3] = gen_lowpart (SImode, operands[3]);
16899
})
16900
 
16901
;; RTL Peephole optimizations, run before sched2.  These primarily look to
16902
;; transform a complex memory operation into two memory to register operations.
16903
 
16904
;; Don't push memory operands
16905
(define_peephole2
16906
  [(set (match_operand:SWI 0 "push_operand" "")
16907
        (match_operand:SWI 1 "memory_operand" ""))
16908
   (match_scratch:SWI 2 "")]
16909
  "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16910
   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16911
  [(set (match_dup 2) (match_dup 1))
16912
   (set (match_dup 0) (match_dup 2))])
16913
 
16914
;; We need to handle SFmode only, because DFmode and XFmode are split to
16915
;; SImode pushes.
16916
(define_peephole2
16917
  [(set (match_operand:SF 0 "push_operand" "")
16918
        (match_operand:SF 1 "memory_operand" ""))
16919
   (match_scratch:SF 2 "r")]
16920
  "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16921
   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16922
  [(set (match_dup 2) (match_dup 1))
16923
   (set (match_dup 0) (match_dup 2))])
16924
 
16925
;; Don't move an immediate directly to memory when the instruction
16926
;; gets too big.
16927
(define_peephole2
16928
  [(match_scratch:SWI124 1 "")
16929
   (set (match_operand:SWI124 0 "memory_operand" "")
16930
        (const_int 0))]
16931
  "optimize_insn_for_speed_p ()
16932
   && !TARGET_USE_MOV0
16933
   && TARGET_SPLIT_LONG_MOVES
16934
   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16935
   && peep2_regno_dead_p (0, FLAGS_REG)"
16936
  [(parallel [(set (match_dup 2) (const_int 0))
16937
              (clobber (reg:CC FLAGS_REG))])
16938
   (set (match_dup 0) (match_dup 1))]
16939
  "operands[2] = gen_lowpart (SImode, operands[1]);")
16940
 
16941
(define_peephole2
16942
  [(match_scratch:SWI124 2 "")
16943
   (set (match_operand:SWI124 0 "memory_operand" "")
16944
        (match_operand:SWI124 1 "immediate_operand" ""))]
16945
  "optimize_insn_for_speed_p ()
16946
   && TARGET_SPLIT_LONG_MOVES
16947
   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16948
  [(set (match_dup 2) (match_dup 1))
16949
   (set (match_dup 0) (match_dup 2))])
16950
 
16951
;; Don't compare memory with zero, load and use a test instead.
16952
(define_peephole2
16953
  [(set (match_operand 0 "flags_reg_operand" "")
16954
        (match_operator 1 "compare_operator"
16955
          [(match_operand:SI 2 "memory_operand" "")
16956
           (const_int 0)]))
16957
   (match_scratch:SI 3 "r")]
16958
  "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16959
  [(set (match_dup 3) (match_dup 2))
16960
   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16961
 
16962
;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16963
;; Don't split NOTs with a displacement operand, because resulting XOR
16964
;; will not be pairable anyway.
16965
;;
16966
;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16967
;; represented using a modRM byte.  The XOR replacement is long decoded,
16968
;; so this split helps here as well.
16969
;;
16970
;; Note: Can't do this as a regular split because we can't get proper
16971
;; lifetime information then.
16972
 
16973
(define_peephole2
16974
  [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16975
        (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16976
  "optimize_insn_for_speed_p ()
16977
   && ((TARGET_NOT_UNPAIRABLE
16978
        && (!MEM_P (operands[0])
16979
            || !memory_displacement_operand (operands[0], mode)))
16980
       || (TARGET_NOT_VECTORMODE
16981
           && long_memory_operand (operands[0], mode)))
16982
   && peep2_regno_dead_p (0, FLAGS_REG)"
16983
  [(parallel [(set (match_dup 0)
16984
                   (xor:SWI124 (match_dup 1) (const_int -1)))
16985
              (clobber (reg:CC FLAGS_REG))])])
16986
 
16987
;; Non pairable "test imm, reg" instructions can be translated to
16988
;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16989
;; byte opcode instead of two, have a short form for byte operands),
16990
;; so do it for other CPUs as well.  Given that the value was dead,
16991
;; this should not create any new dependencies.  Pass on the sub-word
16992
;; versions if we're concerned about partial register stalls.
16993
 
16994
(define_peephole2
16995
  [(set (match_operand 0 "flags_reg_operand" "")
16996
        (match_operator 1 "compare_operator"
16997
          [(and:SI (match_operand:SI 2 "register_operand" "")
16998
                   (match_operand:SI 3 "immediate_operand" ""))
16999
           (const_int 0)]))]
17000
  "ix86_match_ccmode (insn, CCNOmode)
17001
   && (true_regnum (operands[2]) != AX_REG
17002
       || satisfies_constraint_K (operands[3]))
17003
   && peep2_reg_dead_p (1, operands[2])"
17004
  [(parallel
17005
     [(set (match_dup 0)
17006
           (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17007
                            (const_int 0)]))
17008
      (set (match_dup 2)
17009
           (and:SI (match_dup 2) (match_dup 3)))])])
17010
 
17011
;; We don't need to handle HImode case, because it will be promoted to SImode
17012
;; on ! TARGET_PARTIAL_REG_STALL
17013
 
17014
(define_peephole2
17015
  [(set (match_operand 0 "flags_reg_operand" "")
17016
        (match_operator 1 "compare_operator"
17017
          [(and:QI (match_operand:QI 2 "register_operand" "")
17018
                   (match_operand:QI 3 "immediate_operand" ""))
17019
           (const_int 0)]))]
17020
  "! TARGET_PARTIAL_REG_STALL
17021
   && ix86_match_ccmode (insn, CCNOmode)
17022
   && true_regnum (operands[2]) != AX_REG
17023
   && peep2_reg_dead_p (1, operands[2])"
17024
  [(parallel
17025
     [(set (match_dup 0)
17026
           (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17027
                            (const_int 0)]))
17028
      (set (match_dup 2)
17029
           (and:QI (match_dup 2) (match_dup 3)))])])
17030
 
17031
(define_peephole2
17032
  [(set (match_operand 0 "flags_reg_operand" "")
17033
        (match_operator 1 "compare_operator"
17034
          [(and:SI
17035
             (zero_extract:SI
17036
               (match_operand 2 "ext_register_operand" "")
17037
               (const_int 8)
17038
               (const_int 8))
17039
             (match_operand 3 "const_int_operand" ""))
17040
           (const_int 0)]))]
17041
  "! TARGET_PARTIAL_REG_STALL
17042
   && ix86_match_ccmode (insn, CCNOmode)
17043
   && true_regnum (operands[2]) != AX_REG
17044
   && peep2_reg_dead_p (1, operands[2])"
17045
  [(parallel [(set (match_dup 0)
17046
                   (match_op_dup 1
17047
                     [(and:SI
17048
                        (zero_extract:SI
17049
                          (match_dup 2)
17050
                          (const_int 8)
17051
                          (const_int 8))
17052
                        (match_dup 3))
17053
                      (const_int 0)]))
17054
              (set (zero_extract:SI (match_dup 2)
17055
                                    (const_int 8)
17056
                                    (const_int 8))
17057
                   (and:SI
17058
                     (zero_extract:SI
17059
                       (match_dup 2)
17060
                       (const_int 8)
17061
                       (const_int 8))
17062
                     (match_dup 3)))])])
17063
 
17064
;; Don't do logical operations with memory inputs.
17065
(define_peephole2
17066
  [(match_scratch:SI 2 "r")
17067
   (parallel [(set (match_operand:SI 0 "register_operand" "")
17068
                   (match_operator:SI 3 "arith_or_logical_operator"
17069
                     [(match_dup 0)
17070
                      (match_operand:SI 1 "memory_operand" "")]))
17071
              (clobber (reg:CC FLAGS_REG))])]
17072
  "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17073
  [(set (match_dup 2) (match_dup 1))
17074
   (parallel [(set (match_dup 0)
17075
                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17076
              (clobber (reg:CC FLAGS_REG))])])
17077
 
17078
(define_peephole2
17079
  [(match_scratch:SI 2 "r")
17080
   (parallel [(set (match_operand:SI 0 "register_operand" "")
17081
                   (match_operator:SI 3 "arith_or_logical_operator"
17082
                     [(match_operand:SI 1 "memory_operand" "")
17083
                      (match_dup 0)]))
17084
              (clobber (reg:CC FLAGS_REG))])]
17085
  "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17086
  [(set (match_dup 2) (match_dup 1))
17087
   (parallel [(set (match_dup 0)
17088
                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17089
              (clobber (reg:CC FLAGS_REG))])])
17090
 
17091
;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17092
;; refers to the destination of the load!
17093
 
17094
(define_peephole2
17095
  [(set (match_operand:SI 0 "register_operand" "")
17096
        (match_operand:SI 1 "register_operand" ""))
17097
   (parallel [(set (match_dup 0)
17098
                   (match_operator:SI 3 "commutative_operator"
17099
                     [(match_dup 0)
17100
                      (match_operand:SI 2 "memory_operand" "")]))
17101
              (clobber (reg:CC FLAGS_REG))])]
17102
  "REGNO (operands[0]) != REGNO (operands[1])
17103
   && GENERAL_REGNO_P (REGNO (operands[0]))
17104
   && GENERAL_REGNO_P (REGNO (operands[1]))"
17105
  [(set (match_dup 0) (match_dup 4))
17106
   (parallel [(set (match_dup 0)
17107
                   (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17108
              (clobber (reg:CC FLAGS_REG))])]
17109
  "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17110
 
17111
(define_peephole2
17112
  [(set (match_operand 0 "register_operand" "")
17113
        (match_operand 1 "register_operand" ""))
17114
   (set (match_dup 0)
17115
                   (match_operator 3 "commutative_operator"
17116
                     [(match_dup 0)
17117
                      (match_operand 2 "memory_operand" "")]))]
17118
  "REGNO (operands[0]) != REGNO (operands[1])
17119
   && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17120
       || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17121
  [(set (match_dup 0) (match_dup 2))
17122
   (set (match_dup 0)
17123
        (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17124
 
17125
; Don't do logical operations with memory outputs
17126
;
17127
; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17128
; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17129
; the same decoder scheduling characteristics as the original.
17130
 
17131
(define_peephole2
17132
  [(match_scratch:SI 2 "r")
17133
   (parallel [(set (match_operand:SI 0 "memory_operand" "")
17134
                   (match_operator:SI 3 "arith_or_logical_operator"
17135
                     [(match_dup 0)
17136
                      (match_operand:SI 1 "nonmemory_operand" "")]))
17137
              (clobber (reg:CC FLAGS_REG))])]
17138
  "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17139
   /* Do not split stack checking probes.  */
17140
   && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17141
  [(set (match_dup 2) (match_dup 0))
17142
   (parallel [(set (match_dup 2)
17143
                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17144
              (clobber (reg:CC FLAGS_REG))])
17145
   (set (match_dup 0) (match_dup 2))])
17146
 
17147
(define_peephole2
17148
  [(match_scratch:SI 2 "r")
17149
   (parallel [(set (match_operand:SI 0 "memory_operand" "")
17150
                   (match_operator:SI 3 "arith_or_logical_operator"
17151
                     [(match_operand:SI 1 "nonmemory_operand" "")
17152
                      (match_dup 0)]))
17153
              (clobber (reg:CC FLAGS_REG))])]
17154
  "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17155
   /* Do not split stack checking probes.  */
17156
   && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17157
  [(set (match_dup 2) (match_dup 0))
17158
   (parallel [(set (match_dup 2)
17159
                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17160
              (clobber (reg:CC FLAGS_REG))])
17161
   (set (match_dup 0) (match_dup 2))])
17162
 
17163
;; Attempt to use arith or logical operations with memory outputs with
17164
;; setting of flags.
17165
(define_peephole2
17166
  [(set (match_operand:SWI 0 "register_operand" "")
17167
        (match_operand:SWI 1 "memory_operand" ""))
17168
   (parallel [(set (match_dup 0)
17169
                   (match_operator:SWI 3 "plusminuslogic_operator"
17170
                     [(match_dup 0)
17171
                      (match_operand:SWI 2 "" "")]))
17172
              (clobber (reg:CC FLAGS_REG))])
17173
   (set (match_dup 1) (match_dup 0))
17174
   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17175
  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17176
   && peep2_reg_dead_p (4, operands[0])
17177
   && !reg_overlap_mentioned_p (operands[0], operands[1])
17178
   && ix86_match_ccmode (peep2_next_insn (3),
17179
                         (GET_CODE (operands[3]) == PLUS
17180
                          || GET_CODE (operands[3]) == MINUS)
17181
                         ? CCGOCmode : CCNOmode)"
17182
  [(parallel [(set (match_dup 4) (match_dup 5))
17183
              (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17184
                                                  (match_dup 2)]))])]
17185
{
17186
  operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17187
  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), mode,
17188
                                copy_rtx (operands[1]),
17189
                                copy_rtx (operands[2]));
17190
  operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17191
                                 operands[5], const0_rtx);
17192
})
17193
 
17194
(define_peephole2
17195
  [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17196
                   (match_operator:SWI 2 "plusminuslogic_operator"
17197
                     [(match_dup 0)
17198
                      (match_operand:SWI 1 "memory_operand" "")]))
17199
              (clobber (reg:CC FLAGS_REG))])
17200
   (set (match_dup 1) (match_dup 0))
17201
   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17202
  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17203
   && GET_CODE (operands[2]) != MINUS
17204
   && peep2_reg_dead_p (3, operands[0])
17205
   && !reg_overlap_mentioned_p (operands[0], operands[1])
17206
   && ix86_match_ccmode (peep2_next_insn (2),
17207
                         GET_CODE (operands[2]) == PLUS
17208
                         ? CCGOCmode : CCNOmode)"
17209
  [(parallel [(set (match_dup 3) (match_dup 4))
17210
              (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17211
                                                  (match_dup 0)]))])]
17212
{
17213
  operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17214
  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), mode,
17215
                                copy_rtx (operands[1]),
17216
                                copy_rtx (operands[0]));
17217
  operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17218
                                 operands[4], const0_rtx);
17219
})
17220
 
17221
(define_peephole2
17222
  [(set (match_operand:SWI12 0 "register_operand" "")
17223
        (match_operand:SWI12 1 "memory_operand" ""))
17224
   (parallel [(set (match_operand:SI 4 "register_operand" "")
17225
                   (match_operator:SI 3 "plusminuslogic_operator"
17226
                     [(match_dup 4)
17227
                      (match_operand:SI 2 "nonmemory_operand" "")]))
17228
              (clobber (reg:CC FLAGS_REG))])
17229
   (set (match_dup 1) (match_dup 0))
17230
   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17231
  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17232
   && REG_P (operands[0]) && REG_P (operands[4])
17233
   && REGNO (operands[0]) == REGNO (operands[4])
17234
   && peep2_reg_dead_p (4, operands[0])
17235
   && (mode != QImode
17236
       || immediate_operand (operands[2], SImode)
17237
       || q_regs_operand (operands[2], SImode))
17238
   && !reg_overlap_mentioned_p (operands[0], operands[1])
17239
   && ix86_match_ccmode (peep2_next_insn (3),
17240
                         (GET_CODE (operands[3]) == PLUS
17241
                          || GET_CODE (operands[3]) == MINUS)
17242
                         ? CCGOCmode : CCNOmode)"
17243
  [(parallel [(set (match_dup 4) (match_dup 5))
17244
              (set (match_dup 1) (match_dup 6))])]
17245
{
17246
  operands[2] = gen_lowpart (mode, operands[2]);
17247
  operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17248
  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), mode,
17249
                                copy_rtx (operands[1]), operands[2]);
17250
  operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17251
                                 operands[5], const0_rtx);
17252
  operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), mode,
17253
                                copy_rtx (operands[1]),
17254
                                copy_rtx (operands[2]));
17255
})
17256
 
17257
;; Attempt to always use XOR for zeroing registers.
17258
(define_peephole2
17259
  [(set (match_operand 0 "register_operand" "")
17260
        (match_operand 1 "const0_operand" ""))]
17261
  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17262
   && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17263
   && GENERAL_REG_P (operands[0])
17264
   && peep2_regno_dead_p (0, FLAGS_REG)"
17265
  [(parallel [(set (match_dup 0) (const_int 0))
17266
              (clobber (reg:CC FLAGS_REG))])]
17267
  "operands[0] = gen_lowpart (word_mode, operands[0]);")
17268
 
17269
(define_peephole2
17270
  [(set (strict_low_part (match_operand 0 "register_operand" ""))
17271
        (const_int 0))]
17272
  "(GET_MODE (operands[0]) == QImode
17273
    || GET_MODE (operands[0]) == HImode)
17274
   && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17275
   && peep2_regno_dead_p (0, FLAGS_REG)"
17276
  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17277
              (clobber (reg:CC FLAGS_REG))])])
17278
 
17279
;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17280
(define_peephole2
17281
  [(set (match_operand:SWI248 0 "register_operand" "")
17282
        (const_int -1))]
17283
  "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17284
   && peep2_regno_dead_p (0, FLAGS_REG)"
17285
  [(parallel [(set (match_dup 0) (const_int -1))
17286
              (clobber (reg:CC FLAGS_REG))])]
17287
{
17288
  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
17289
    operands[0] = gen_lowpart (SImode, operands[0]);
17290
})
17291
 
17292
;; Attempt to convert simple lea to add/shift.
17293
;; These can be created by move expanders.
17294
 
17295
(define_peephole2
17296
  [(set (match_operand:SWI48 0 "register_operand" "")
17297
        (plus:SWI48 (match_dup 0)
17298
                    (match_operand:SWI48 1 "" "")))]
17299
  "peep2_regno_dead_p (0, FLAGS_REG)"
17300
  [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17301
              (clobber (reg:CC FLAGS_REG))])])
17302
 
17303
(define_peephole2
17304
  [(set (match_operand:SI 0 "register_operand" "")
17305
        (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17306
                            (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17307
  "TARGET_64BIT
17308
   && peep2_regno_dead_p (0, FLAGS_REG)
17309
   && REGNO (operands[0]) == REGNO (operands[1])"
17310
  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17311
              (clobber (reg:CC FLAGS_REG))])]
17312
  "operands[2] = gen_lowpart (SImode, operands[2]);")
17313
 
17314
(define_peephole2
17315
  [(set (match_operand:SWI48 0 "register_operand" "")
17316
        (mult:SWI48 (match_dup 0)
17317
                    (match_operand:SWI48 1 "const_int_operand" "")))]
17318
  "exact_log2 (INTVAL (operands[1])) >= 0
17319
   && peep2_regno_dead_p (0, FLAGS_REG)"
17320
  [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17321
              (clobber (reg:CC FLAGS_REG))])]
17322
  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17323
 
17324
(define_peephole2
17325
  [(set (match_operand:SI 0 "register_operand" "")
17326
        (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17327
                   (match_operand:DI 2 "const_int_operand" "")) 0))]
17328
  "TARGET_64BIT
17329
   && exact_log2 (INTVAL (operands[2])) >= 0
17330
   && REGNO (operands[0]) == REGNO (operands[1])
17331
   && peep2_regno_dead_p (0, FLAGS_REG)"
17332
  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17333
              (clobber (reg:CC FLAGS_REG))])]
17334
  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17335
 
17336
;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17337
;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17338
;; On many CPUs it is also faster, since special hardware to avoid esp
17339
;; dependencies is present.
17340
 
17341
;; While some of these conversions may be done using splitters, we use
17342
;; peepholes in order to allow combine_stack_adjustments pass to see
17343
;; nonobfuscated RTL.
17344
 
17345
;; Convert prologue esp subtractions to push.
17346
;; We need register to push.  In order to keep verify_flow_info happy we have
17347
;; two choices
17348
;; - use scratch and clobber it in order to avoid dependencies
17349
;; - use already live register
17350
;; We can't use the second way right now, since there is no reliable way how to
17351
;; verify that given register is live.  First choice will also most likely in
17352
;; fewer dependencies.  On the place of esp adjustments it is very likely that
17353
;; call clobbered registers are dead.  We may want to use base pointer as an
17354
;; alternative when no register is available later.
17355
 
17356
(define_peephole2
17357
  [(match_scratch:P 1 "r")
17358
   (parallel [(set (reg:P SP_REG)
17359
                   (plus:P (reg:P SP_REG)
17360
                           (match_operand:P 0 "const_int_operand" "")))
17361
              (clobber (reg:CC FLAGS_REG))
17362
              (clobber (mem:BLK (scratch)))])]
17363
  "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17364
   && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17365
  [(clobber (match_dup 1))
17366
   (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17367
              (clobber (mem:BLK (scratch)))])])
17368
 
17369
(define_peephole2
17370
  [(match_scratch:P 1 "r")
17371
   (parallel [(set (reg:P SP_REG)
17372
                   (plus:P (reg:P SP_REG)
17373
                           (match_operand:P 0 "const_int_operand" "")))
17374
              (clobber (reg:CC FLAGS_REG))
17375
              (clobber (mem:BLK (scratch)))])]
17376
  "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17377
   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17378
  [(clobber (match_dup 1))
17379
   (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17380
   (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17381
              (clobber (mem:BLK (scratch)))])])
17382
 
17383
;; Convert esp subtractions to push.
17384
(define_peephole2
17385
  [(match_scratch:P 1 "r")
17386
   (parallel [(set (reg:P SP_REG)
17387
                   (plus:P (reg:P SP_REG)
17388
                           (match_operand:P 0 "const_int_operand" "")))
17389
              (clobber (reg:CC FLAGS_REG))])]
17390
  "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17391
   && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17392
  [(clobber (match_dup 1))
17393
   (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17394
 
17395
(define_peephole2
17396
  [(match_scratch:P 1 "r")
17397
   (parallel [(set (reg:P SP_REG)
17398
                   (plus:P (reg:P SP_REG)
17399
                           (match_operand:P 0 "const_int_operand" "")))
17400
              (clobber (reg:CC FLAGS_REG))])]
17401
  "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17402
   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17403
  [(clobber (match_dup 1))
17404
   (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17405
   (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17406
 
17407
;; Convert epilogue deallocator to pop.
17408
(define_peephole2
17409
  [(match_scratch:P 1 "r")
17410
   (parallel [(set (reg:P SP_REG)
17411
                   (plus:P (reg:P SP_REG)
17412
                           (match_operand:P 0 "const_int_operand" "")))
17413
              (clobber (reg:CC FLAGS_REG))
17414
              (clobber (mem:BLK (scratch)))])]
17415
  "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17416
   && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17417
  [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17418
              (clobber (mem:BLK (scratch)))])])
17419
 
17420
;; Two pops case is tricky, since pop causes dependency
17421
;; on destination register.  We use two registers if available.
17422
(define_peephole2
17423
  [(match_scratch:P 1 "r")
17424
   (match_scratch:P 2 "r")
17425
   (parallel [(set (reg:P SP_REG)
17426
                   (plus:P (reg:P SP_REG)
17427
                           (match_operand:P 0 "const_int_operand" "")))
17428
              (clobber (reg:CC FLAGS_REG))
17429
              (clobber (mem:BLK (scratch)))])]
17430
  "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17431
   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17432
  [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17433
              (clobber (mem:BLK (scratch)))])
17434
   (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17435
 
17436
(define_peephole2
17437
  [(match_scratch:P 1 "r")
17438
   (parallel [(set (reg:P SP_REG)
17439
                   (plus:P (reg:P SP_REG)
17440
                           (match_operand:P 0 "const_int_operand" "")))
17441
              (clobber (reg:CC FLAGS_REG))
17442
              (clobber (mem:BLK (scratch)))])]
17443
  "optimize_insn_for_size_p ()
17444
   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17445
  [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17446
              (clobber (mem:BLK (scratch)))])
17447
   (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17448
 
17449
;; Convert esp additions to pop.
17450
(define_peephole2
17451
  [(match_scratch:P 1 "r")
17452
   (parallel [(set (reg:P SP_REG)
17453
                   (plus:P (reg:P SP_REG)
17454
                           (match_operand:P 0 "const_int_operand" "")))
17455
              (clobber (reg:CC FLAGS_REG))])]
17456
  "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17457
  [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17458
 
17459
;; Two pops case is tricky, since pop causes dependency
17460
;; on destination register.  We use two registers if available.
17461
(define_peephole2
17462
  [(match_scratch:P 1 "r")
17463
   (match_scratch:P 2 "r")
17464
   (parallel [(set (reg:P SP_REG)
17465
                   (plus:P (reg:P SP_REG)
17466
                           (match_operand:P 0 "const_int_operand" "")))
17467
              (clobber (reg:CC FLAGS_REG))])]
17468
  "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17469
  [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17470
   (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17471
 
17472
(define_peephole2
17473
  [(match_scratch:P 1 "r")
17474
   (parallel [(set (reg:P SP_REG)
17475
                   (plus:P (reg:P SP_REG)
17476
                           (match_operand:P 0 "const_int_operand" "")))
17477
              (clobber (reg:CC FLAGS_REG))])]
17478
  "optimize_insn_for_size_p ()
17479
   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17480
  [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17481
   (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17482
 
17483
;; Convert compares with 1 to shorter inc/dec operations when CF is not
17484
;; required and register dies.  Similarly for 128 to -128.
17485
(define_peephole2
17486
  [(set (match_operand 0 "flags_reg_operand" "")
17487
        (match_operator 1 "compare_operator"
17488
          [(match_operand 2 "register_operand" "")
17489
           (match_operand 3 "const_int_operand" "")]))]
17490
  "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17491
     && incdec_operand (operands[3], GET_MODE (operands[3])))
17492
    || (!TARGET_FUSE_CMP_AND_BRANCH
17493
        && INTVAL (operands[3]) == 128))
17494
   && ix86_match_ccmode (insn, CCGCmode)
17495
   && peep2_reg_dead_p (1, operands[2])"
17496
  [(parallel [(set (match_dup 0)
17497
                   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17498
              (clobber (match_dup 2))])])
17499
 
17500
;; Convert imul by three, five and nine into lea
17501
(define_peephole2
17502
  [(parallel
17503
    [(set (match_operand:SWI48 0 "register_operand" "")
17504
          (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17505
                      (match_operand:SWI48 2 "const359_operand" "")))
17506
     (clobber (reg:CC FLAGS_REG))])]
17507
  "!TARGET_PARTIAL_REG_STALL
17508
   || mode == SImode
17509
   || optimize_function_for_size_p (cfun)"
17510
  [(set (match_dup 0)
17511
        (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17512
                    (match_dup 1)))]
17513
  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17514
 
17515
(define_peephole2
17516
  [(parallel
17517
    [(set (match_operand:SWI48 0 "register_operand" "")
17518
          (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17519
                      (match_operand:SWI48 2 "const359_operand" "")))
17520
     (clobber (reg:CC FLAGS_REG))])]
17521
  "optimize_insn_for_speed_p ()
17522
   && (!TARGET_PARTIAL_REG_STALL || mode == SImode)"
17523
  [(set (match_dup 0) (match_dup 1))
17524
   (set (match_dup 0)
17525
        (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17526
                    (match_dup 0)))]
17527
  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17528
 
17529
;; imul $32bit_imm, mem, reg is vector decoded, while
17530
;; imul $32bit_imm, reg, reg is direct decoded.
17531
(define_peephole2
17532
  [(match_scratch:SWI48 3 "r")
17533
   (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17534
                   (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17535
                               (match_operand:SWI48 2 "immediate_operand" "")))
17536
              (clobber (reg:CC FLAGS_REG))])]
17537
  "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17538
   && !satisfies_constraint_K (operands[2])"
17539
  [(set (match_dup 3) (match_dup 1))
17540
   (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17541
              (clobber (reg:CC FLAGS_REG))])])
17542
 
17543
(define_peephole2
17544
  [(match_scratch:SI 3 "r")
17545
   (parallel [(set (match_operand:DI 0 "register_operand" "")
17546
                   (zero_extend:DI
17547
                     (mult:SI (match_operand:SI 1 "memory_operand" "")
17548
                              (match_operand:SI 2 "immediate_operand" ""))))
17549
              (clobber (reg:CC FLAGS_REG))])]
17550
  "TARGET_64BIT
17551
   && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17552
   && !satisfies_constraint_K (operands[2])"
17553
  [(set (match_dup 3) (match_dup 1))
17554
   (parallel [(set (match_dup 0)
17555
                   (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17556
              (clobber (reg:CC FLAGS_REG))])])
17557
 
17558
;; imul $8/16bit_imm, regmem, reg is vector decoded.
17559
;; Convert it into imul reg, reg
17560
;; It would be better to force assembler to encode instruction using long
17561
;; immediate, but there is apparently no way to do so.
17562
(define_peephole2
17563
  [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17564
                   (mult:SWI248
17565
                    (match_operand:SWI248 1 "nonimmediate_operand" "")
17566
                    (match_operand:SWI248 2 "const_int_operand" "")))
17567
              (clobber (reg:CC FLAGS_REG))])
17568
   (match_scratch:SWI248 3 "r")]
17569
  "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17570
   && satisfies_constraint_K (operands[2])"
17571
  [(set (match_dup 3) (match_dup 2))
17572
   (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17573
              (clobber (reg:CC FLAGS_REG))])]
17574
{
17575
  if (!rtx_equal_p (operands[0], operands[1]))
17576
    emit_move_insn (operands[0], operands[1]);
17577
})
17578
 
17579
;; After splitting up read-modify operations, array accesses with memory
17580
;; operands might end up in form:
17581
;;  sall    $2, %eax
17582
;;  movl    4(%esp), %edx
17583
;;  addl    %edx, %eax
17584
;; instead of pre-splitting:
17585
;;  sall    $2, %eax
17586
;;  addl    4(%esp), %eax
17587
;; Turn it into:
17588
;;  movl    4(%esp), %edx
17589
;;  leal    (%edx,%eax,4), %eax
17590
 
17591
(define_peephole2
17592
  [(match_scratch:P 5 "r")
17593
   (parallel [(set (match_operand 0 "register_operand" "")
17594
                   (ashift (match_operand 1 "register_operand" "")
17595
                           (match_operand 2 "const_int_operand" "")))
17596
               (clobber (reg:CC FLAGS_REG))])
17597
   (parallel [(set (match_operand 3 "register_operand" "")
17598
                   (plus (match_dup 0)
17599
                         (match_operand 4 "x86_64_general_operand" "")))
17600
                   (clobber (reg:CC FLAGS_REG))])]
17601
  "IN_RANGE (INTVAL (operands[2]), 1, 3)
17602
   /* Validate MODE for lea.  */
17603
   && ((!TARGET_PARTIAL_REG_STALL
17604
        && (GET_MODE (operands[0]) == QImode
17605
            || GET_MODE (operands[0]) == HImode))
17606
       || GET_MODE (operands[0]) == SImode
17607
       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17608
   && (rtx_equal_p (operands[0], operands[3])
17609
       || peep2_reg_dead_p (2, operands[0]))
17610
   /* We reorder load and the shift.  */
17611
   && !reg_overlap_mentioned_p (operands[0], operands[4])"
17612
  [(set (match_dup 5) (match_dup 4))
17613
   (set (match_dup 0) (match_dup 1))]
17614
{
17615
  enum machine_mode op1mode = GET_MODE (operands[1]);
17616
  enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17617
  int scale = 1 << INTVAL (operands[2]);
17618
  rtx index = gen_lowpart (Pmode, operands[1]);
17619
  rtx base = gen_lowpart (Pmode, operands[5]);
17620
  rtx dest = gen_lowpart (mode, operands[3]);
17621
 
17622
  operands[1] = gen_rtx_PLUS (Pmode, base,
17623
                              gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17624
  operands[5] = base;
17625
  if (mode != Pmode)
17626
    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17627
  if (op1mode != Pmode)
17628
    operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17629
  operands[0] = dest;
17630
})
17631
 
17632
;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17633
;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17634
;; caught for use by garbage collectors and the like.  Using an insn that
17635
;; maps to SIGILL makes it more likely the program will rightfully die.
17636
;; Keeping with tradition, "6" is in honor of #UD.
17637
(define_insn "trap"
17638
  [(trap_if (const_int 1) (const_int 6))]
17639
  ""
17640
  { return ASM_SHORT "0x0b0f"; }
17641
  [(set_attr "length" "2")])
17642
 
17643
(define_expand "prefetch"
17644
  [(prefetch (match_operand 0 "address_operand" "")
17645
             (match_operand:SI 1 "const_int_operand" "")
17646
             (match_operand:SI 2 "const_int_operand" ""))]
17647
  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17648
{
17649
  int rw = INTVAL (operands[1]);
17650
  int locality = INTVAL (operands[2]);
17651
 
17652
  gcc_assert (rw == 0 || rw == 1);
17653
  gcc_assert (locality >= 0 && locality <= 3);
17654
  gcc_assert (GET_MODE (operands[0]) == Pmode
17655
              || GET_MODE (operands[0]) == VOIDmode);
17656
 
17657
  /* Use 3dNOW prefetch in case we are asking for write prefetch not
17658
     supported by SSE counterpart or the SSE prefetch is not available
17659
     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17660
     of locality.  */
17661
  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17662
    operands[2] = GEN_INT (3);
17663
  else
17664
    operands[1] = const0_rtx;
17665
})
17666
 
17667
(define_insn "*prefetch_sse_"
17668
  [(prefetch (match_operand:P 0 "address_operand" "p")
17669
             (const_int 0)
17670
             (match_operand:SI 1 "const_int_operand" ""))]
17671
  "TARGET_PREFETCH_SSE"
17672
{
17673
  static const char * const patterns[4] = {
17674
   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17675
  };
17676
 
17677
  int locality = INTVAL (operands[1]);
17678
  gcc_assert (locality >= 0 && locality <= 3);
17679
 
17680
  return patterns[locality];
17681
}
17682
  [(set_attr "type" "sse")
17683
   (set_attr "atom_sse_attr" "prefetch")
17684
   (set (attr "length_address")
17685
        (symbol_ref "memory_address_length (operands[0])"))
17686
   (set_attr "memory" "none")])
17687
 
17688
(define_insn "*prefetch_3dnow_"
17689
  [(prefetch (match_operand:P 0 "address_operand" "p")
17690
             (match_operand:SI 1 "const_int_operand" "n")
17691
             (const_int 3))]
17692
  "TARGET_3DNOW"
17693
{
17694
  if (INTVAL (operands[1]) == 0)
17695
    return "prefetch\t%a0";
17696
  else
17697
    return "prefetchw\t%a0";
17698
}
17699
  [(set_attr "type" "mmx")
17700
   (set (attr "length_address")
17701
        (symbol_ref "memory_address_length (operands[0])"))
17702
   (set_attr "memory" "none")])
17703
 
17704
(define_expand "stack_protect_set"
17705
  [(match_operand 0 "memory_operand" "")
17706
   (match_operand 1 "memory_operand" "")]
17707
  ""
17708
{
17709
  rtx (*insn)(rtx, rtx);
17710
 
17711
#ifdef TARGET_THREAD_SSP_OFFSET
17712
  operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17713
  insn = (TARGET_LP64
17714
          ? gen_stack_tls_protect_set_di
17715
          : gen_stack_tls_protect_set_si);
17716
#else
17717
  insn = (TARGET_LP64
17718
          ? gen_stack_protect_set_di
17719
          : gen_stack_protect_set_si);
17720
#endif
17721
 
17722
  emit_insn (insn (operands[0], operands[1]));
17723
  DONE;
17724
})
17725
 
17726
(define_insn "stack_protect_set_"
17727
  [(set (match_operand:PTR 0 "memory_operand" "=m")
17728
        (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17729
                    UNSPEC_SP_SET))
17730
   (set (match_scratch:PTR 2 "=&r") (const_int 0))
17731
   (clobber (reg:CC FLAGS_REG))]
17732
  ""
17733
  "mov{}\t{%1, %2|%2, %1}\;mov{}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17734
  [(set_attr "type" "multi")])
17735
 
17736
(define_insn "stack_tls_protect_set_"
17737
  [(set (match_operand:PTR 0 "memory_operand" "=m")
17738
        (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17739
                    UNSPEC_SP_TLS_SET))
17740
   (set (match_scratch:PTR 2 "=&r") (const_int 0))
17741
   (clobber (reg:CC FLAGS_REG))]
17742
  ""
17743
  "mov{}\t{%@:%P1, %2|%2,  PTR %@:%P1}\;mov{}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17744
  [(set_attr "type" "multi")])
17745
 
17746
(define_expand "stack_protect_test"
17747
  [(match_operand 0 "memory_operand" "")
17748
   (match_operand 1 "memory_operand" "")
17749
   (match_operand 2 "" "")]
17750
  ""
17751
{
17752
  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17753
 
17754
  rtx (*insn)(rtx, rtx, rtx);
17755
 
17756
#ifdef TARGET_THREAD_SSP_OFFSET
17757
  operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17758
  insn = (TARGET_LP64
17759
          ? gen_stack_tls_protect_test_di
17760
          : gen_stack_tls_protect_test_si);
17761
#else
17762
  insn = (TARGET_LP64
17763
          ? gen_stack_protect_test_di
17764
          : gen_stack_protect_test_si);
17765
#endif
17766
 
17767
  emit_insn (insn (flags, operands[0], operands[1]));
17768
 
17769
  emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17770
                                  flags, const0_rtx, operands[2]));
17771
  DONE;
17772
})
17773
 
17774
(define_insn "stack_protect_test_"
17775
  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17776
        (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17777
                     (match_operand:PTR 2 "memory_operand" "m")]
17778
                    UNSPEC_SP_TEST))
17779
   (clobber (match_scratch:PTR 3 "=&r"))]
17780
  ""
17781
  "mov{}\t{%1, %3|%3, %1}\;xor{}\t{%2, %3|%3, %2}"
17782
  [(set_attr "type" "multi")])
17783
 
17784
(define_insn "stack_tls_protect_test_"
17785
  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17786
        (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17787
                     (match_operand:PTR 2 "const_int_operand" "i")]
17788
                    UNSPEC_SP_TLS_TEST))
17789
   (clobber (match_scratch:PTR 3 "=r"))]
17790
  ""
17791
  "mov{}\t{%1, %3|%3, %1}\;xor{}\t{%@:%P2, %3|%3,  PTR %@:%P2}"
17792
  [(set_attr "type" "multi")])
17793
 
17794
(define_insn "sse4_2_crc32"
17795
  [(set (match_operand:SI 0 "register_operand" "=r")
17796
        (unspec:SI
17797
          [(match_operand:SI 1 "register_operand" "0")
17798
           (match_operand:SWI124 2 "nonimmediate_operand" "m")]
17799
          UNSPEC_CRC32))]
17800
  "TARGET_SSE4_2 || TARGET_CRC32"
17801
  "crc32{}\t{%2, %0|%0, %2}"
17802
  [(set_attr "type" "sselog1")
17803
   (set_attr "prefix_rep" "1")
17804
   (set_attr "prefix_extra" "1")
17805
   (set (attr "prefix_data16")
17806
     (if_then_else (match_operand:HI 2 "" "")
17807
       (const_string "1")
17808
       (const_string "*")))
17809
   (set (attr "prefix_rex")
17810
     (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17811
       (const_string "1")
17812
       (const_string "*")))
17813
   (set_attr "mode" "SI")])
17814
 
17815
(define_insn "sse4_2_crc32di"
17816
  [(set (match_operand:DI 0 "register_operand" "=r")
17817
        (unspec:DI
17818
          [(match_operand:DI 1 "register_operand" "0")
17819
           (match_operand:DI 2 "nonimmediate_operand" "rm")]
17820
          UNSPEC_CRC32))]
17821
  "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17822
  "crc32{q}\t{%2, %0|%0, %2}"
17823
  [(set_attr "type" "sselog1")
17824
   (set_attr "prefix_rep" "1")
17825
   (set_attr "prefix_extra" "1")
17826
   (set_attr "mode" "DI")])
17827
 
17828
(define_expand "rdpmc"
17829
  [(match_operand:DI 0 "register_operand" "")
17830
   (match_operand:SI 1 "register_operand" "")]
17831
  ""
17832
{
17833
  rtx reg = gen_reg_rtx (DImode);
17834
  rtx si;
17835
 
17836
  /* Force operand 1 into ECX.  */
17837
  rtx ecx = gen_rtx_REG (SImode, CX_REG);
17838
  emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17839
  si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17840
                                UNSPECV_RDPMC);
17841
 
17842
  if (TARGET_64BIT)
17843
    {
17844
      rtvec vec = rtvec_alloc (2);
17845
      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17846
      rtx upper = gen_reg_rtx (DImode);
17847
      rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17848
                                        gen_rtvec (1, const0_rtx),
17849
                                        UNSPECV_RDPMC);
17850
      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17851
      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17852
      emit_insn (load);
17853
      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17854
                                   NULL, 1, OPTAB_DIRECT);
17855
      reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17856
                                 OPTAB_DIRECT);
17857
    }
17858
  else
17859
    emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17860
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17861
  DONE;
17862
})
17863
 
17864
(define_insn "*rdpmc"
17865
  [(set (match_operand:DI 0 "register_operand" "=A")
17866
        (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17867
                            UNSPECV_RDPMC))]
17868
  "!TARGET_64BIT"
17869
  "rdpmc"
17870
  [(set_attr "type" "other")
17871
   (set_attr "length" "2")])
17872
 
17873
(define_insn "*rdpmc_rex64"
17874
  [(set (match_operand:DI 0 "register_operand" "=a")
17875
        (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17876
                            UNSPECV_RDPMC))
17877
  (set (match_operand:DI 1 "register_operand" "=d")
17878
       (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17879
  "TARGET_64BIT"
17880
  "rdpmc"
17881
  [(set_attr "type" "other")
17882
   (set_attr "length" "2")])
17883
 
17884
(define_expand "rdtsc"
17885
  [(set (match_operand:DI 0 "register_operand" "")
17886
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17887
  ""
17888
{
17889
  if (TARGET_64BIT)
17890
    {
17891
      rtvec vec = rtvec_alloc (2);
17892
      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17893
      rtx upper = gen_reg_rtx (DImode);
17894
      rtx lower = gen_reg_rtx (DImode);
17895
      rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17896
                                         gen_rtvec (1, const0_rtx),
17897
                                         UNSPECV_RDTSC);
17898
      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17899
      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17900
      emit_insn (load);
17901
      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17902
                                   NULL, 1, OPTAB_DIRECT);
17903
      lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17904
                                   OPTAB_DIRECT);
17905
      emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17906
      DONE;
17907
    }
17908
})
17909
 
17910
(define_insn "*rdtsc"
17911
  [(set (match_operand:DI 0 "register_operand" "=A")
17912
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17913
  "!TARGET_64BIT"
17914
  "rdtsc"
17915
  [(set_attr "type" "other")
17916
   (set_attr "length" "2")])
17917
 
17918
(define_insn "*rdtsc_rex64"
17919
  [(set (match_operand:DI 0 "register_operand" "=a")
17920
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17921
   (set (match_operand:DI 1 "register_operand" "=d")
17922
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17923
  "TARGET_64BIT"
17924
  "rdtsc"
17925
  [(set_attr "type" "other")
17926
   (set_attr "length" "2")])
17927
 
17928
(define_expand "rdtscp"
17929
  [(match_operand:DI 0 "register_operand" "")
17930
   (match_operand:SI 1 "memory_operand" "")]
17931
  ""
17932
{
17933
  rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17934
                                    gen_rtvec (1, const0_rtx),
17935
                                    UNSPECV_RDTSCP);
17936
  rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17937
                                    gen_rtvec (1, const0_rtx),
17938
                                    UNSPECV_RDTSCP);
17939
  rtx reg = gen_reg_rtx (DImode);
17940
  rtx tmp = gen_reg_rtx (SImode);
17941
 
17942
  if (TARGET_64BIT)
17943
    {
17944
      rtvec vec = rtvec_alloc (3);
17945
      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17946
      rtx upper = gen_reg_rtx (DImode);
17947
      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17948
      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17949
      RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17950
      emit_insn (load);
17951
      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17952
                                   NULL, 1, OPTAB_DIRECT);
17953
      reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17954
                                 OPTAB_DIRECT);
17955
    }
17956
  else
17957
    {
17958
      rtvec vec = rtvec_alloc (2);
17959
      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17960
      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17961
      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17962
      emit_insn (load);
17963
    }
17964
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17965
  emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17966
  DONE;
17967
})
17968
 
17969
(define_insn "*rdtscp"
17970
  [(set (match_operand:DI 0 "register_operand" "=A")
17971
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17972
   (set (match_operand:SI 1 "register_operand" "=c")
17973
        (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17974
  "!TARGET_64BIT"
17975
  "rdtscp"
17976
  [(set_attr "type" "other")
17977
   (set_attr "length" "3")])
17978
 
17979
(define_insn "*rdtscp_rex64"
17980
  [(set (match_operand:DI 0 "register_operand" "=a")
17981
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17982
   (set (match_operand:DI 1 "register_operand" "=d")
17983
        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17984
   (set (match_operand:SI 2 "register_operand" "=c")
17985
        (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17986
  "TARGET_64BIT"
17987
  "rdtscp"
17988
  [(set_attr "type" "other")
17989
   (set_attr "length" "3")])
17990
 
17991
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17992
;;
17993
;; LWP instructions
17994
;;
17995
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17996
 
17997
(define_expand "lwp_llwpcb"
17998
  [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17999
                    UNSPECV_LLWP_INTRINSIC)]
18000
  "TARGET_LWP")
18001
 
18002
(define_insn "*lwp_llwpcb1"
18003
  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18004
                    UNSPECV_LLWP_INTRINSIC)]
18005
  "TARGET_LWP"
18006
  "llwpcb\t%0"
18007
  [(set_attr "type" "lwp")
18008
   (set_attr "mode" "")
18009
   (set_attr "length" "5")])
18010
 
18011
(define_expand "lwp_slwpcb"
18012
  [(set (match_operand 0 "register_operand" "=r")
18013
        (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18014
  "TARGET_LWP"
18015
{
18016
  rtx (*insn)(rtx);
18017
 
18018
  insn = (TARGET_64BIT
18019
          ? gen_lwp_slwpcbdi
18020
          : gen_lwp_slwpcbsi);
18021
 
18022
  emit_insn (insn (operands[0]));
18023
  DONE;
18024
})
18025
 
18026
(define_insn "lwp_slwpcb"
18027
  [(set (match_operand:P 0 "register_operand" "=r")
18028
        (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18029
  "TARGET_LWP"
18030
  "slwpcb\t%0"
18031
  [(set_attr "type" "lwp")
18032
   (set_attr "mode" "")
18033
   (set_attr "length" "5")])
18034
 
18035
(define_expand "lwp_lwpval3"
18036
  [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18037
                     (match_operand:SI 2 "nonimmediate_operand" "rm")
18038
                     (match_operand:SI 3 "const_int_operand" "i")]
18039
                    UNSPECV_LWPVAL_INTRINSIC)]
18040
  "TARGET_LWP"
18041
  ;; Avoid unused variable warning.
18042
  "(void) operands[0];")
18043
 
18044
(define_insn "*lwp_lwpval3_1"
18045
  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18046
                     (match_operand:SI 1 "nonimmediate_operand" "rm")
18047
                     (match_operand:SI 2 "const_int_operand" "i")]
18048
                    UNSPECV_LWPVAL_INTRINSIC)]
18049
  "TARGET_LWP"
18050
  "lwpval\t{%2, %1, %0|%0, %1, %2}"
18051
  [(set_attr "type" "lwp")
18052
   (set_attr "mode" "")
18053
   (set (attr "length")
18054
        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18055
 
18056
(define_expand "lwp_lwpins3"
18057
  [(set (reg:CCC FLAGS_REG)
18058
        (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18059
                              (match_operand:SI 2 "nonimmediate_operand" "rm")
18060
                              (match_operand:SI 3 "const_int_operand" "i")]
18061
                             UNSPECV_LWPINS_INTRINSIC))
18062
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18063
        (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18064
  "TARGET_LWP")
18065
 
18066
(define_insn "*lwp_lwpins3_1"
18067
  [(set (reg:CCC FLAGS_REG)
18068
        (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18069
                              (match_operand:SI 1 "nonimmediate_operand" "rm")
18070
                              (match_operand:SI 2 "const_int_operand" "i")]
18071
                             UNSPECV_LWPINS_INTRINSIC))]
18072
  "TARGET_LWP"
18073
  "lwpins\t{%2, %1, %0|%0, %1, %2}"
18074
  [(set_attr "type" "lwp")
18075
   (set_attr "mode" "")
18076
   (set (attr "length")
18077
        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18078
 
18079
(define_insn "rdfsbase"
18080
  [(set (match_operand:SWI48 0 "register_operand" "=r")
18081
        (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18082
  "TARGET_64BIT && TARGET_FSGSBASE"
18083
  "rdfsbase %0"
18084
  [(set_attr "type" "other")
18085
   (set_attr "prefix_extra" "2")])
18086
 
18087
(define_insn "rdgsbase"
18088
  [(set (match_operand:SWI48 0 "register_operand" "=r")
18089
        (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18090
  "TARGET_64BIT && TARGET_FSGSBASE"
18091
  "rdgsbase %0"
18092
  [(set_attr "type" "other")
18093
   (set_attr "prefix_extra" "2")])
18094
 
18095
(define_insn "wrfsbase"
18096
  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18097
                    UNSPECV_WRFSBASE)]
18098
  "TARGET_64BIT && TARGET_FSGSBASE"
18099
  "wrfsbase %0"
18100
  [(set_attr "type" "other")
18101
   (set_attr "prefix_extra" "2")])
18102
 
18103
(define_insn "wrgsbase"
18104
  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18105
                    UNSPECV_WRGSBASE)]
18106
  "TARGET_64BIT && TARGET_FSGSBASE"
18107
  "wrgsbase %0"
18108
  [(set_attr "type" "other")
18109
   (set_attr "prefix_extra" "2")])
18110
 
18111
(define_insn "rdrand_1"
18112
  [(set (match_operand:SWI248 0 "register_operand" "=r")
18113
        (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18114
   (set (reg:CCC FLAGS_REG)
18115
        (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18116
  "TARGET_RDRND"
18117
  "rdrand\t%0"
18118
  [(set_attr "type" "other")
18119
   (set_attr "prefix_extra" "1")])
18120
 
18121
(define_expand "pause"
18122
  [(set (match_dup 0)
18123
        (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18124
  ""
18125
{
18126
  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18127
  MEM_VOLATILE_P (operands[0]) = 1;
18128
})
18129
 
18130
;; Use "rep; nop", instead of "pause", to support older assemblers.
18131
;; They have the same encoding.
18132
(define_insn "*pause"
18133
  [(set (match_operand:BLK 0 "" "")
18134
        (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18135
  ""
18136
  "rep; nop"
18137
  [(set_attr "length" "2")
18138
   (set_attr "memory" "unknown")])
18139
 
18140
(include "mmx.md")
18141
(include "sse.md")
18142
(include "sync.md")

powered by: WebSVN 2.1.0

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